All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v2.1 04/13] drm: Add data transmission order bus flag
From: Thierry Reding @ 2017-01-04  7:06 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: dri-devel, linux-renesas-soc, Stefan Agner
In-Reply-To: <20170104003926.29683-1-laurent.pinchart+renesas@ideasonboard.com>

[-- Attachment #1: Type: text/plain, Size: 1566 bytes --]

On Wed, Jan 04, 2017 at 02:39:26AM +0200, Laurent Pinchart wrote:
> The flags indicate whether data is transmitted lsb to msb or msb to lsb
> on the bus.
> 
> The exact meaning is bus-type dependent. For instance, for LVDS buses
> the flags indicate whether the seven data bits transmitted in a clock
> pulse are sent in normal order (msb to lsb, slots 0 to 6) or reverse
> order (lsb to msb, slots 6 to 0).
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
> Changes since v2:
> 
> - Rename the flag to DRM_BUS_FLAG_DATA_LSB_TO_MSB and add a
>   corresponding DRM_BUS_FLAG_DATA_MSB_TO_LSB flag.
> ---
>  include/drm/drm_connector.h | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index a9b95246e26e..712f255577ea 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -160,6 +160,10 @@ struct drm_display_info {
>  #define DRM_BUS_FLAG_PIXDATA_POSEDGE	(1<<2)
>  /* drive data on neg. edge */
>  #define DRM_BUS_FLAG_PIXDATA_NEGEDGE	(1<<3)
> +/* data is transmitted msb to lsb on the bus */
> +#define DRM_BUS_FLAG_DATA_MSB_TO_LSB	(1<<4)
> +/* data is transmitted lsb to msb on the bus */
> +#define DRM_BUS_FLAG_DATA_LSB_TO_MSB	(1<<5)

Nit: "LSB" and "MSB" because they're abbreviations. If I end up applying
this I'll probably do that myself, and I leave it up to whoever else
might apply it whether or not they want to be pedantic, so:

Reviewed-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v2.1 04/13] drm: Add data transmission order bus flag
From: Thierry Reding @ 2017-01-04  7:06 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, dri-devel
In-Reply-To: <20170104003926.29683-1-laurent.pinchart+renesas@ideasonboard.com>


[-- Attachment #1.1: Type: text/plain, Size: 1566 bytes --]

On Wed, Jan 04, 2017 at 02:39:26AM +0200, Laurent Pinchart wrote:
> The flags indicate whether data is transmitted lsb to msb or msb to lsb
> on the bus.
> 
> The exact meaning is bus-type dependent. For instance, for LVDS buses
> the flags indicate whether the seven data bits transmitted in a clock
> pulse are sent in normal order (msb to lsb, slots 0 to 6) or reverse
> order (lsb to msb, slots 6 to 0).
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
> Changes since v2:
> 
> - Rename the flag to DRM_BUS_FLAG_DATA_LSB_TO_MSB and add a
>   corresponding DRM_BUS_FLAG_DATA_MSB_TO_LSB flag.
> ---
>  include/drm/drm_connector.h | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index a9b95246e26e..712f255577ea 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -160,6 +160,10 @@ struct drm_display_info {
>  #define DRM_BUS_FLAG_PIXDATA_POSEDGE	(1<<2)
>  /* drive data on neg. edge */
>  #define DRM_BUS_FLAG_PIXDATA_NEGEDGE	(1<<3)
> +/* data is transmitted msb to lsb on the bus */
> +#define DRM_BUS_FLAG_DATA_MSB_TO_LSB	(1<<4)
> +/* data is transmitted lsb to msb on the bus */
> +#define DRM_BUS_FLAG_DATA_LSB_TO_MSB	(1<<5)

Nit: "LSB" and "MSB" because they're abbreviations. If I end up applying
this I'll probably do that myself, and I leave it up to whoever else
might apply it whether or not they want to be pedantic, so:

Reviewed-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Re: [PATCH v3] IB/umem: Release pid in error and ODP flow
From: Kenneth Lee @ 2017-01-04  7:07 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w, robin.murphy-5wv7dgnIgG8,
	jroedel-l3A5Bk7waGM, egtvedt-BrfabpQBY5qlHtIdYg32fQ,
	vgupta-HKixBCOQz3hWk0Htik3J/w, dave.hansen-VuQAYsv1563Yd54FQh9/CA,
	lstoakes-Re5JQEeQqe8AvxtiuMwx3w, krzk-DgEjT+Ai2ygdnm+yROfE0A,
	sebott-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	markb-VPRAkNaXOzVWk0Htik3J/w, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170103101224.GH12077-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org>

On Tue, Jan 03, 2017 at 12:12:24PM +0200, Leon Romanovsky wrote:
> Date: Tue, 3 Jan 2017 12:12:24 +0200
> From: Leon Romanovsky <leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> To: Kenneth Lee <liguozhu-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
> CC: dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org, sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org, hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
>  robin.murphy-5wv7dgnIgG8@public.gmane.org, jroedel-l3A5Bk7waGM@public.gmane.org, egtvedt-BrfabpQBY5qlHtIdYg32fQ@public.gmane.org,
>  vgupta-HKixBCOQz3hWk0Htik3J/w@public.gmane.org, dave.hansen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org, lstoakes-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
>  krzk-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org, sebott-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org, markb-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org,
>  linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Subject: Re: [PATCH v3] IB/umem: Release pid in error and ODP flow
> User-Agent: Mutt/1.7.2 (2016-11-26)
> Message-ID: <20170103101224.GH12077-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org>
> 
> On Tue, Jan 03, 2017 at 10:32:50AM +0800, Kenneth Lee wrote:
> > On Sun, Jan 01, 2017 at 08:47:12AM +0200, Leon Romanovsky wrote:
> > > Date: Sun, 1 Jan 2017 08:47:12 +0200
> > > From: Leon Romanovsky <leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > > To: Kenneth Lee <liguozhu-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
> > > CC: dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org, sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org, hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
> > >  robin.murphy-5wv7dgnIgG8@public.gmane.org, jroedel-l3A5Bk7waGM@public.gmane.org, egtvedt-BrfabpQBY5qlHtIdYg32fQ@public.gmane.org,
> > >  vgupta-HKixBCOQz3hWk0Htik3J/w@public.gmane.org, dave.hansen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org, lstoakes-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
> > >  krzk-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org, sebott-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org, markb-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org,
> > >  linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > > Subject: Re: [PATCH v3] IB/umem: Release pid in error and ODP flow
> > > User-Agent: Mutt/1.7.2 (2016-11-26)
> > > Message-ID: <20170101064712.GQ26885-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org>
> > >
> > > On Fri, Dec 30, 2016 at 06:18:29PM +0800, Kenneth Lee wrote:
> > > > There are two bugfixes in this patch:
> > > >
> > > > Fixes: 87773dd56d54 ("IB: ib_umem_release() should decrement mm->pinned_vm from ib_umem_get")
> > > > 	This patch introduce the get_task_pid but not put it back on all error
> > > > 	path
> > > >
> > > > Fixes: 8ada2c1c0c1d ("IB/core: Add support for on demand paging regions")
> > > > 	This patch introduce a ODP flow without release pid before enter it
> > > >
> > > >
> > > > Signed-off-by: Kenneth Lee <liguozhu-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
> > > > Reviewed-by: Haggai Eran <haggaie-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> > > > ---
> > > > Change from v1 to v2:
> > > >   Correcting the patch title and description
> > > > Change from v2 to v3:
> > > >   Update the title and add "Fixes" fields in the description
> > >
> > > OK,
> > >
> > > I see that you still didn't read Documentation/SubmittingPatches. You
> > > must read that document before you are sending patches.
> > >
> > > But I'll stop here, the code is correct (it fixes bugs) and commit message
> > > more usefull than before.
> > >
> > >
> > > >
> > > >  drivers/infiniband/core/umem.c | 2 ++
> > > >  1 file changed, 2 insertions(+)
> > > >
> > > > diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
> > > > index 1e62a5f..4609b92 100644
> > > > --- a/drivers/infiniband/core/umem.c
> > > > +++ b/drivers/infiniband/core/umem.c
> > > > @@ -134,6 +134,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
> > > >  		 IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_MW_BIND));
> > > >
> > > >  	if (access & IB_ACCESS_ON_DEMAND) {
> > > > +		put_pid(umem->pid);
> > > >  		ret = ib_umem_odp_get(context, umem);
> > > >  		if (ret) {
> > > >  			kfree(umem);
> > > > @@ -149,6 +150,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
> > > >
> > > >  	page_list = (struct page **) __get_free_page(GFP_KERNEL);
> > > >  	if (!page_list) {
> > > > +		put_pid(umem->pid);
> > > >  		kfree(umem);
> > > >  		return ERR_PTR(-ENOMEM);
> > > >  	}
> > > > --
> > > > 1.9.1
> > > >
> > > > --
> > > > To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> > > > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > > > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >
> > Thanks,
> >
> > I did read the doc, but maybe I mis-understant some points. Could you please
> > point it out?
> 
> Fixes line should be placed above bottom signatures.
> 
> As an example of properly written patch, you can take a look on the
> following patch [1] from Steve.
> 
> [1] http://marc.info/?l=linux-rdma&m=148244272205411&w=2

Thank you. A sample help a lot.

But please allow me to argue a little:
Documentation/process/submitting-patches.rst does really not mention where Fixes
tags should be put:)

> 
> >
> > And sorry. please ignore the last message. I forget to use a bottom-post style.
> >
> >
> >
> > --
> > 			-Kenneth(Hisilicon)



-- 
			-Kenneth(Hisilicon)
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [dm-crypt] TrueCrypt is discontinued - here are the alternatives
From: Milan Broz @ 2017-01-04  7:08 UTC (permalink / raw)
  To: Laurence Darby; +Cc: dm-crypt
In-Reply-To: <20170103204932.d185584f1e0f33bae9c8a6df@tuffmail.com>

On 01/03/2017 09:49 PM, Laurence Darby wrote:
> 
> I'm not sure if that was true before but it's not now.  
> 
> The original point of this thread is that cryptsetup's man page is
> still linking http://www.truecrypt.org as if that was still useful,
> it's not spam at all.

Yes, this one reference was missed. I changed it so it points to wikipedia
now, there are links to other projects derived from TrueCrypt.

Thanks,
Milan

^ permalink raw reply

* Re: [PATCH v3] IB/umem: Release pid in error and ODP flow
From: Leon Romanovsky @ 2017-01-04  7:08 UTC (permalink / raw)
  To: Kenneth Lee
  Cc: dledford-H+wXaHxf7aLQT0dZR+AlfA,
	sean.hefty-ral2JQCrhuEAvxtiuMwx3w,
	hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w, robin.murphy-5wv7dgnIgG8,
	jroedel-l3A5Bk7waGM, egtvedt-BrfabpQBY5qlHtIdYg32fQ,
	vgupta-HKixBCOQz3hWk0Htik3J/w, dave.hansen-VuQAYsv1563Yd54FQh9/CA,
	lstoakes-Re5JQEeQqe8AvxtiuMwx3w, krzk-DgEjT+Ai2ygdnm+yROfE0A,
	sebott-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8,
	markb-VPRAkNaXOzVWk0Htik3J/w, linux-rdma-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170104070704.GC228559@Turing-Arch-b>

[-- Attachment #1: Type: text/plain, Size: 6058 bytes --]

On Wed, Jan 04, 2017 at 03:07:04PM +0800, Kenneth Lee wrote:
> On Tue, Jan 03, 2017 at 12:12:24PM +0200, Leon Romanovsky wrote:
> > Date: Tue, 3 Jan 2017 12:12:24 +0200
> > From: Leon Romanovsky <leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > To: Kenneth Lee <liguozhu-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
> > CC: dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org, sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org, hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
> >  robin.murphy-5wv7dgnIgG8@public.gmane.org, jroedel-l3A5Bk7waGM@public.gmane.org, egtvedt-BrfabpQBY5qlHtIdYg32fQ@public.gmane.org,
> >  vgupta-HKixBCOQz3hWk0Htik3J/w@public.gmane.org, dave.hansen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org, lstoakes-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
> >  krzk-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org, sebott-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org, markb-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org,
> >  linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > Subject: Re: [PATCH v3] IB/umem: Release pid in error and ODP flow
> > User-Agent: Mutt/1.7.2 (2016-11-26)
> > Message-ID: <20170103101224.GH12077-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org>
> >
> > On Tue, Jan 03, 2017 at 10:32:50AM +0800, Kenneth Lee wrote:
> > > On Sun, Jan 01, 2017 at 08:47:12AM +0200, Leon Romanovsky wrote:
> > > > Date: Sun, 1 Jan 2017 08:47:12 +0200
> > > > From: Leon Romanovsky <leon-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > > > To: Kenneth Lee <liguozhu-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
> > > > CC: dledford-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org, sean.hefty-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org, hal.rosenstock-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
> > > >  robin.murphy-5wv7dgnIgG8@public.gmane.org, jroedel-l3A5Bk7waGM@public.gmane.org, egtvedt-BrfabpQBY5qlHtIdYg32fQ@public.gmane.org,
> > > >  vgupta-HKixBCOQz3hWk0Htik3J/w@public.gmane.org, dave.hansen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org, lstoakes-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
> > > >  krzk-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org, sebott-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org, markb-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org,
> > > >  linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > > > Subject: Re: [PATCH v3] IB/umem: Release pid in error and ODP flow
> > > > User-Agent: Mutt/1.7.2 (2016-11-26)
> > > > Message-ID: <20170101064712.GQ26885-U/DQcQFIOTAAJjI8aNfphQ@public.gmane.org>
> > > >
> > > > On Fri, Dec 30, 2016 at 06:18:29PM +0800, Kenneth Lee wrote:
> > > > > There are two bugfixes in this patch:
> > > > >
> > > > > Fixes: 87773dd56d54 ("IB: ib_umem_release() should decrement mm->pinned_vm from ib_umem_get")
> > > > > 	This patch introduce the get_task_pid but not put it back on all error
> > > > > 	path
> > > > >
> > > > > Fixes: 8ada2c1c0c1d ("IB/core: Add support for on demand paging regions")
> > > > > 	This patch introduce a ODP flow without release pid before enter it
> > > > >
> > > > >
> > > > > Signed-off-by: Kenneth Lee <liguozhu-C8/M+/jPZTeaMJb+Lgu22Q@public.gmane.org>
> > > > > Reviewed-by: Haggai Eran <haggaie-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
> > > > > ---
> > > > > Change from v1 to v2:
> > > > >   Correcting the patch title and description
> > > > > Change from v2 to v3:
> > > > >   Update the title and add "Fixes" fields in the description
> > > >
> > > > OK,
> > > >
> > > > I see that you still didn't read Documentation/SubmittingPatches. You
> > > > must read that document before you are sending patches.
> > > >
> > > > But I'll stop here, the code is correct (it fixes bugs) and commit message
> > > > more usefull than before.
> > > >
> > > >
> > > > >
> > > > >  drivers/infiniband/core/umem.c | 2 ++
> > > > >  1 file changed, 2 insertions(+)
> > > > >
> > > > > diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
> > > > > index 1e62a5f..4609b92 100644
> > > > > --- a/drivers/infiniband/core/umem.c
> > > > > +++ b/drivers/infiniband/core/umem.c
> > > > > @@ -134,6 +134,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
> > > > >  		 IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_MW_BIND));
> > > > >
> > > > >  	if (access & IB_ACCESS_ON_DEMAND) {
> > > > > +		put_pid(umem->pid);
> > > > >  		ret = ib_umem_odp_get(context, umem);
> > > > >  		if (ret) {
> > > > >  			kfree(umem);
> > > > > @@ -149,6 +150,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
> > > > >
> > > > >  	page_list = (struct page **) __get_free_page(GFP_KERNEL);
> > > > >  	if (!page_list) {
> > > > > +		put_pid(umem->pid);
> > > > >  		kfree(umem);
> > > > >  		return ERR_PTR(-ENOMEM);
> > > > >  	}
> > > > > --
> > > > > 1.9.1
> > > > >
> > > > > --
> > > > > To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> > > > > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > > > > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > >
> > > Thanks,
> > >
> > > I did read the doc, but maybe I mis-understant some points. Could you please
> > > point it out?
> >
> > Fixes line should be placed above bottom signatures.
> >
> > As an example of properly written patch, you can take a look on the
> > following patch [1] from Steve.
> >
> > [1] http://marc.info/?l=linux-rdma&m=148244272205411&w=2
>
> Thank you. A sample help a lot.
>
> But please allow me to argue a little:
> Documentation/process/submitting-patches.rst does really not mention where Fixes
> tags should be put:)

Sure, you can't and don't want to document everything. There is section named
"2) Describe your changes" which has very extensive description about
commit message. If you had followed it, you would find that it is very
natural to place Fixes at the bottom.

Thanks

>
> >
> > >
> > > And sorry. please ignore the last message. I forget to use a bottom-post style.
> > >
> > >
> > >
> > > --
> > > 			-Kenneth(Hisilicon)
>
>
>
> --
> 			-Kenneth(Hisilicon)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v3] IB/umem: Release pid in error and ODP flow
From: Leon Romanovsky @ 2017-01-04  7:08 UTC (permalink / raw)
  To: Kenneth Lee
  Cc: dledford, sean.hefty, hal.rosenstock, robin.murphy, jroedel,
	egtvedt, vgupta, dave.hansen, lstoakes, krzk, sebott, markb,
	linux-rdma, linux-kernel
In-Reply-To: <20170104070704.GC228559@Turing-Arch-b>

[-- Attachment #1: Type: text/plain, Size: 5077 bytes --]

On Wed, Jan 04, 2017 at 03:07:04PM +0800, Kenneth Lee wrote:
> On Tue, Jan 03, 2017 at 12:12:24PM +0200, Leon Romanovsky wrote:
> > Date: Tue, 3 Jan 2017 12:12:24 +0200
> > From: Leon Romanovsky <leon@kernel.org>
> > To: Kenneth Lee <liguozhu@hisilicon.com>
> > CC: dledford@redhat.com, sean.hefty@intel.com, hal.rosenstock@gmail.com,
> >  robin.murphy@arm.com, jroedel@suse.de, egtvedt@samfundet.no,
> >  vgupta@synopsys.com, dave.hansen@linux.intel.com, lstoakes@gmail.com,
> >  krzk@kernel.org, sebott@linux.vnet.ibm.com, markb@mellanox.com,
> >  linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org
> > Subject: Re: [PATCH v3] IB/umem: Release pid in error and ODP flow
> > User-Agent: Mutt/1.7.2 (2016-11-26)
> > Message-ID: <20170103101224.GH12077@mtr-leonro.local>
> >
> > On Tue, Jan 03, 2017 at 10:32:50AM +0800, Kenneth Lee wrote:
> > > On Sun, Jan 01, 2017 at 08:47:12AM +0200, Leon Romanovsky wrote:
> > > > Date: Sun, 1 Jan 2017 08:47:12 +0200
> > > > From: Leon Romanovsky <leon@kernel.org>
> > > > To: Kenneth Lee <liguozhu@hisilicon.com>
> > > > CC: dledford@redhat.com, sean.hefty@intel.com, hal.rosenstock@gmail.com,
> > > >  robin.murphy@arm.com, jroedel@suse.de, egtvedt@samfundet.no,
> > > >  vgupta@synopsys.com, dave.hansen@linux.intel.com, lstoakes@gmail.com,
> > > >  krzk@kernel.org, sebott@linux.vnet.ibm.com, markb@mellanox.com,
> > > >  linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org
> > > > Subject: Re: [PATCH v3] IB/umem: Release pid in error and ODP flow
> > > > User-Agent: Mutt/1.7.2 (2016-11-26)
> > > > Message-ID: <20170101064712.GQ26885@mtr-leonro.local>
> > > >
> > > > On Fri, Dec 30, 2016 at 06:18:29PM +0800, Kenneth Lee wrote:
> > > > > There are two bugfixes in this patch:
> > > > >
> > > > > Fixes: 87773dd56d54 ("IB: ib_umem_release() should decrement mm->pinned_vm from ib_umem_get")
> > > > > 	This patch introduce the get_task_pid but not put it back on all error
> > > > > 	path
> > > > >
> > > > > Fixes: 8ada2c1c0c1d ("IB/core: Add support for on demand paging regions")
> > > > > 	This patch introduce a ODP flow without release pid before enter it
> > > > >
> > > > >
> > > > > Signed-off-by: Kenneth Lee <liguozhu@hisilicon.com>
> > > > > Reviewed-by: Haggai Eran <haggaie@mellanox.com>
> > > > > ---
> > > > > Change from v1 to v2:
> > > > >   Correcting the patch title and description
> > > > > Change from v2 to v3:
> > > > >   Update the title and add "Fixes" fields in the description
> > > >
> > > > OK,
> > > >
> > > > I see that you still didn't read Documentation/SubmittingPatches. You
> > > > must read that document before you are sending patches.
> > > >
> > > > But I'll stop here, the code is correct (it fixes bugs) and commit message
> > > > more usefull than before.
> > > >
> > > >
> > > > >
> > > > >  drivers/infiniband/core/umem.c | 2 ++
> > > > >  1 file changed, 2 insertions(+)
> > > > >
> > > > > diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
> > > > > index 1e62a5f..4609b92 100644
> > > > > --- a/drivers/infiniband/core/umem.c
> > > > > +++ b/drivers/infiniband/core/umem.c
> > > > > @@ -134,6 +134,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
> > > > >  		 IB_ACCESS_REMOTE_ATOMIC | IB_ACCESS_MW_BIND));
> > > > >
> > > > >  	if (access & IB_ACCESS_ON_DEMAND) {
> > > > > +		put_pid(umem->pid);
> > > > >  		ret = ib_umem_odp_get(context, umem);
> > > > >  		if (ret) {
> > > > >  			kfree(umem);
> > > > > @@ -149,6 +150,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
> > > > >
> > > > >  	page_list = (struct page **) __get_free_page(GFP_KERNEL);
> > > > >  	if (!page_list) {
> > > > > +		put_pid(umem->pid);
> > > > >  		kfree(umem);
> > > > >  		return ERR_PTR(-ENOMEM);
> > > > >  	}
> > > > > --
> > > > > 1.9.1
> > > > >
> > > > > --
> > > > > To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> > > > > the body of a message to majordomo@vger.kernel.org
> > > > > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > >
> > > Thanks,
> > >
> > > I did read the doc, but maybe I mis-understant some points. Could you please
> > > point it out?
> >
> > Fixes line should be placed above bottom signatures.
> >
> > As an example of properly written patch, you can take a look on the
> > following patch [1] from Steve.
> >
> > [1] http://marc.info/?l=linux-rdma&m=148244272205411&w=2
>
> Thank you. A sample help a lot.
>
> But please allow me to argue a little:
> Documentation/process/submitting-patches.rst does really not mention where Fixes
> tags should be put:)

Sure, you can't and don't want to document everything. There is section named
"2) Describe your changes" which has very extensive description about
commit message. If you had followed it, you would find that it is very
natural to place Fixes at the bottom.

Thanks

>
> >
> > >
> > > And sorry. please ignore the last message. I forget to use a bottom-post style.
> > >
> > >
> > >
> > > --
> > > 			-Kenneth(Hisilicon)
>
>
>
> --
> 			-Kenneth(Hisilicon)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v2 05/13] drm: panels: Constify device node argument to of_drm_find_panel()
From: Thierry Reding @ 2017-01-04  7:09 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-renesas-soc, Tomi Valkeinen, dri-devel
In-Reply-To: <1479526093-7014-6-git-send-email-laurent.pinchart+renesas@ideasonboard.com>


[-- Attachment #1.1: Type: text/plain, Size: 387 bytes --]

On Sat, Nov 19, 2016 at 05:28:05AM +0200, Laurent Pinchart wrote:
> The argument is never modified by the function, make it const.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/drm_panel.c | 2 +-
>  include/drm/drm_panel.h     | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)

Applied, thanks.

Thierry

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply

* Add ALC299 support
From: Kailang @ 2017-01-04  7:09 UTC (permalink / raw)
  To: Takashi Iwai (tiwai@suse.de),  (alsa-devel@alsa-project.org)

[-- Attachment #1: Type: text/plain, Size: 107 bytes --]

Hi Takashi,

We had new codec ALC299.
It was similar as ALC225.
Attach was the patch.

BR,
Kailang

[-- Attachment #2: 0000-add-alc299-support.patch --]
[-- Type: application/octet-stream, Size: 3236 bytes --]

From 22539987dd8556287c8def2aa9bf9f516bfc4a29 Mon Sep 17 00:00:00 2001
From: Kailang Yang <kailang@realtek.com>
Date: Wed, 4 Jan 2017 14:49:07 +0800
Subject: [PATCH] ALSA: hda/realtek - Add new codec ID ALC299

ALC299 was similar as ALC225.
Add headset support for ALC299.
ALC3271 was for Dell rename.

Signed-off-by: Kailang Yang <kailang@realtek.com>

diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 1ae29fd..3c69647 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -337,6 +337,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
 	case 0x10ec0288:
 	case 0x10ec0295:
 	case 0x10ec0298:
+	case 0x10ec0299:
 		alc_update_coef_idx(codec, 0x10, 1<<9, 0);
 		break;
 	case 0x10ec0285:
@@ -912,6 +913,7 @@ struct alc_codec_rename_pci_table {
 	{ 0x10ec0256, 0x1028, 0, "ALC3246" },
 	{ 0x10ec0225, 0x1028, 0, "ALC3253" },
 	{ 0x10ec0295, 0x1028, 0, "ALC3254" },
+	{ 0x10ec0299, 0x1028, 0, "ALC3271" },
 	{ 0x10ec0670, 0x1025, 0, "ALC669X" },
 	{ 0x10ec0676, 0x1025, 0, "ALC679X" },
 	{ 0x10ec0282, 0x1043, 0, "ALC3229" },
@@ -3716,6 +3718,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
 		break;
 	case 0x10ec0225:
 	case 0x10ec0295:
+	case 0x10ec0299:
 		alc_process_coef_fw(codec, coef0225);
 		break;
 	case 0x10ec0867:
@@ -3823,6 +3826,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
 		break;
 	case 0x10ec0225:
 	case 0x10ec0295:
+	case 0x10ec0299:
 		alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
 		alc_process_coef_fw(codec, coef0225);
@@ -3881,6 +3885,7 @@ static void alc_headset_mode_default(struct hda_codec *codec)
 	switch (codec->core.vendor_id) {
 	case 0x10ec0225:
 	case 0x10ec0295:
+	case 0x10ec0299:
 		alc_process_coef_fw(codec, coef0225);
 		break;
 	case 0x10ec0255:
@@ -3996,6 +4001,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
 		break;
 	case 0x10ec0225:
 	case 0x10ec0295:
+	case 0x10ec0299:
 		alc_process_coef_fw(codec, coef0225);
 		break;
 	case 0x10ec0867:
@@ -4089,6 +4095,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
 		break;
 	case 0x10ec0225:
 	case 0x10ec0295:
+	case 0x10ec0299:
 		alc_process_coef_fw(codec, coef0225);
 		break;
 	}
@@ -4173,6 +4180,7 @@ static void alc_determine_headset_type(struct hda_codec *codec)
 		break;
 	case 0x10ec0225:
 	case 0x10ec0295:
+	case 0x10ec0299:
 		alc_process_coef_fw(codec, coef0225);
 		msleep(800);
 		val = alc_read_coef_idx(codec, 0x46);
@@ -6219,6 +6227,7 @@ static int patch_alc269(struct hda_codec *codec)
 		break;
 	case 0x10ec0225:
 	case 0x10ec0295:
+	case 0x10ec0299:
 		spec->codec_variant = ALC269_TYPE_ALC225;
 		break;
 	case 0x10ec0234:
@@ -7256,6 +7265,7 @@ static int patch_alc680(struct hda_codec *codec)
 	HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
 	HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
+	HDA_CODEC_ENTRY(0x10ec0299, "ALC299", patch_alc269),
 	HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
 	HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
 	HDA_CODEC_ENTRY(0x10ec0861, "ALC861", patch_alc861),

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply related

* [PATCH v3 0/3] dmaengine: xilinx_dma: Bug fixes
From: Kedareswara rao Appana @ 2017-01-04  6:54 UTC (permalink / raw)
  To: robh+dt, mark.rutland, dan.j.williams, vinod.koul, michal.simek,
	soren.brinkmann, appanad, moritz.fischer, laurent.pinchart, luis,
	Jose.Abreu
  Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree

This patch series fixes below bugs in DMA and VDMA IP's
---> Do not start VDMA until frame buffer is processed by the h/w Fix 
---> bug in Multi frame sotres handling in VDMA Fix issues w.r.to multi 
---> frame descriptors submit with AXI DMA S2MM(recv) Side.

Kedareswara rao Appana (3):
  dmaengine: xilinx_dma: Check for channel idle state before submitting
    dma descriptor
  dmaeninge: xilinx_dma: Fix bug in multiple frame stores scenario in
    vdma
  dmaengine: xilinx_dma: Fix race condition in the driver for multiple
    descriptor scenario

 .../devicetree/bindings/dma/xilinx/xilinx_dma.txt  |   2 +
 drivers/dma/xilinx/xilinx_dma.c                    | 265 ++++++++++++---------
 2 files changed, 156 insertions(+), 111 deletions(-)

-- 
2.1.2

^ permalink raw reply

* [PATCH v3 2/3] dmaeninge: xilinx_dma: Fix bug in multiple frame stores scenario in vdma
From: Kedareswara rao Appana @ 2017-01-04  6:54 UTC (permalink / raw)
  To: robh+dt, mark.rutland, dan.j.williams, vinod.koul, michal.simek,
	soren.brinkmann, appanad, moritz.fischer, laurent.pinchart, luis,
	Jose.Abreu
  Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree
In-Reply-To: <1483512847-25710-1-git-send-email-appanad@xilinx.com>

When VDMA is configured for more than one frame in the h/w
for example h/w is configured for n number of frames and user
Submits n number of frames and triggered the DMA using issue_pending API.
In the current driver flow we are submitting one frame at a time
but we should submit all the n number of frames at one time as the h/w
Is configured for n number of frames.

This patch fixes this issue.

Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
Changes for v3:
---> Added Checks for frame store configuration. If frame store
     Configuration is not present at the h/w level and user
     Submits less frames added debug prints in the driver as relevant.
Changes for v2:
---> Fixed race conditions in the driver as suggested by Jose Abreu
---> Fixed unnecessray if else checks in the vdma_start_transfer
     as suggested by Laurent Pinchart.

 .../devicetree/bindings/dma/xilinx/xilinx_dma.txt  |  2 +
 drivers/dma/xilinx/xilinx_dma.c                    | 78 +++++++++++++++-------
 2 files changed, 57 insertions(+), 23 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
index a2b8bfa..1f65e09 100644
--- a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
+++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt
@@ -66,6 +66,8 @@ Optional child node properties:
 Optional child node properties for VDMA:
 - xlnx,genlock-mode: Tells Genlock synchronization is
 	enabled/disabled in hardware.
+- xlnx,fstore-config: Tells Whether Frame Store Configuration is
+	enabled/disabled in hardware.
 Optional child node properties for AXI DMA:
 -dma-channels: Number of dma channels in child node.
 
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index be7eb41..7cd8e08 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -322,6 +322,7 @@ struct xilinx_dma_tx_descriptor {
  * @genlock: Support genlock mode
  * @err: Channel has errors
  * @idle: Check for channel idle
+ * @has_fstoreconfig: Check for frame store configuration
  * @tasklet: Cleanup work after irq
  * @config: Device configuration info
  * @flush_on_fsync: Flush on Frame sync
@@ -353,6 +354,7 @@ struct xilinx_dma_chan {
 	bool genlock;
 	bool err;
 	bool idle;
+	bool has_fstoreconfig;
 	struct tasklet_struct tasklet;
 	struct xilinx_vdma_config config;
 	bool flush_on_fsync;
@@ -990,6 +992,26 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
 	if (list_empty(&chan->pending_list))
 		return;
 
+	/*
+	 * Note: When VDMA is built with default h/w configuration
+	 * On the S2MM(recv) side user should submit frames upto
+	 * H/W configured. If users submits less than h/w configured
+	 * VDMA engine tries to write to a invalid location
+	 * Results undefined behaviour/memory corruption.
+	 *
+	 * If user would like to submit frames less than h/w capable
+	 * On S2MM side please enable debug info 13 at the h/w level
+	 * It will allows the frame buffers numbers to be modified at runtime.
+	 */
+	if (!chan->has_fstoreconfig && chan->direction == DMA_DEV_TO_MEM &&
+	    chan->desc_pendingcount < chan->num_frms) {
+		dev_dbg(chan->dev, "Frame Store Configuration is not enabled at the");
+		dev_dbg(chan->dev, " H/w level enable Debug info 13 at the h/w level");
+		dev_dbg(chan->dev, " OR Submit the frames upto h/w Capable\n\r");
+
+		return;
+	}
+
 	desc = list_first_entry(&chan->pending_list,
 				struct xilinx_dma_tx_descriptor, node);
 	tail_desc = list_last_entry(&chan->pending_list,
@@ -1052,25 +1074,38 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
 	if (chan->has_sg) {
 		dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC,
 				tail_segment->phys);
+		list_splice_tail_init(&chan->pending_list, &chan->active_list);
+		chan->desc_pendingcount = 0;
 	} else {
 		struct xilinx_vdma_tx_segment *segment, *last = NULL;
-		int i = 0;
+		int i = 0, j = 0;
 
 		if (chan->desc_submitcount < chan->num_frms)
 			i = chan->desc_submitcount;
 
-		list_for_each_entry(segment, &desc->segments, node) {
-			if (chan->ext_addr)
-				vdma_desc_write_64(chan,
-					XILINX_VDMA_REG_START_ADDRESS_64(i++),
-					segment->hw.buf_addr,
-					segment->hw.buf_addr_msb);
-			else
-				vdma_desc_write(chan,
-					XILINX_VDMA_REG_START_ADDRESS(i++),
-					segment->hw.buf_addr);
-
-			last = segment;
+		for (j = 0; j < chan->num_frms; ) {
+			list_for_each_entry(segment, &desc->segments, node) {
+				if (chan->ext_addr)
+					vdma_desc_write_64(chan,
+					  XILINX_VDMA_REG_START_ADDRESS_64(i++),
+					  segment->hw.buf_addr,
+					  segment->hw.buf_addr_msb);
+				else
+					vdma_desc_write(chan,
+					    XILINX_VDMA_REG_START_ADDRESS(i++),
+					    segment->hw.buf_addr);
+
+				last = segment;
+			}
+			list_del(&desc->node);
+			list_add_tail(&desc->node, &chan->active_list);
+			j++;
+			if (list_empty(&chan->pending_list) ||
+			    (i == chan->num_frms))
+				break;
+			desc = list_first_entry(&chan->pending_list,
+						struct xilinx_dma_tx_descriptor,
+						node);
 		}
 
 		if (!last)
@@ -1081,20 +1116,14 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
 		vdma_desc_write(chan, XILINX_DMA_REG_FRMDLY_STRIDE,
 				last->hw.stride);
 		vdma_desc_write(chan, XILINX_DMA_REG_VSIZE, last->hw.vsize);
-	}
 
-	chan->idle = false;
-	if (!chan->has_sg) {
-		list_del(&desc->node);
-		list_add_tail(&desc->node, &chan->active_list);
-		chan->desc_submitcount++;
-		chan->desc_pendingcount--;
+		chan->desc_submitcount += j;
+		chan->desc_pendingcount -= j;
 		if (chan->desc_submitcount == chan->num_frms)
 			chan->desc_submitcount = 0;
-	} else {
-		list_splice_tail_init(&chan->pending_list, &chan->active_list);
-		chan->desc_pendingcount = 0;
 	}
+
+	chan->idle = false;
 }
 
 /**
@@ -1342,6 +1371,7 @@ static int xilinx_dma_reset(struct xilinx_dma_chan *chan)
 
 	chan->err = false;
 	chan->idle = true;
+	chan->desc_submitcount = 0;
 
 	return err;
 }
@@ -2315,6 +2345,8 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
 	has_dre = of_property_read_bool(node, "xlnx,include-dre");
 
 	chan->genlock = of_property_read_bool(node, "xlnx,genlock-mode");
+	chan->has_fstoreconfig = of_property_read_bool(node,
+						       "xlnx,fstore-config");
 
 	err = of_property_read_u32(node, "xlnx,datawidth", &value);
 	if (err) {
-- 
2.1.2

^ permalink raw reply related

* [PATCH v3 3/3] dmaengine: xilinx_dma: Fix race condition in the driver for multiple descriptor scenario
From: Kedareswara rao Appana @ 2017-01-04  6:54 UTC (permalink / raw)
  To: robh+dt, mark.rutland, dan.j.williams, vinod.koul, michal.simek,
	soren.brinkmann, appanad, moritz.fischer, laurent.pinchart, luis,
	Jose.Abreu
  Cc: dmaengine, linux-arm-kernel, linux-kernel, devicetree
In-Reply-To: <1483512847-25710-1-git-send-email-appanad@xilinx.com>

When driver is handling AXI DMA SoftIP
When user submits multiple descriptors back to back on the S2MM(recv)
side with the current driver flow the last buffer descriptor next bd
points to a invalid location resulting the invalid data or errors in the
DMA engine.

This patch fixes this issue by creating a BD Chain during
channel allocation itself and use those BD's.

Signed-off-by: Kedareswara rao Appana <appanad@xilinx.com>
---
Changes for v3:
---> None.
Changes for v2:
---> None.

 drivers/dma/xilinx/xilinx_dma.c | 133 +++++++++++++++++++++++++---------------
 1 file changed, 83 insertions(+), 50 deletions(-)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 7cd8e08..822ccf00 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -163,6 +163,7 @@
 #define XILINX_DMA_BD_SOP		BIT(27)
 #define XILINX_DMA_BD_EOP		BIT(26)
 #define XILINX_DMA_COALESCE_MAX		255
+#define XILINX_DMA_NUM_DESCS		255
 #define XILINX_DMA_NUM_APP_WORDS	5
 
 /* Multi-Channel DMA Descriptor offsets*/
@@ -310,6 +311,7 @@ struct xilinx_dma_tx_descriptor {
  * @pending_list: Descriptors waiting
  * @active_list: Descriptors ready to submit
  * @done_list: Complete descriptors
+ * @free_seg_list: Free descriptors
  * @common: DMA common channel
  * @desc_pool: Descriptors pool
  * @dev: The dma device
@@ -331,7 +333,9 @@ struct xilinx_dma_tx_descriptor {
  * @desc_submitcount: Descriptor h/w submitted count
  * @residue: Residue for AXI DMA
  * @seg_v: Statically allocated segments base
+ * @seg_p: Physical allocated segments base
  * @cyclic_seg_v: Statically allocated segment base for cyclic transfers
+ * @cyclic_seg_p: Physical allocated segments base for cyclic dma
  * @start_transfer: Differentiate b/w DMA IP's transfer
  */
 struct xilinx_dma_chan {
@@ -342,6 +346,7 @@ struct xilinx_dma_chan {
 	struct list_head pending_list;
 	struct list_head active_list;
 	struct list_head done_list;
+	struct list_head free_seg_list;
 	struct dma_chan common;
 	struct dma_pool *desc_pool;
 	struct device *dev;
@@ -363,7 +368,9 @@ struct xilinx_dma_chan {
 	u32 desc_submitcount;
 	u32 residue;
 	struct xilinx_axidma_tx_segment *seg_v;
+	dma_addr_t seg_p;
 	struct xilinx_axidma_tx_segment *cyclic_seg_v;
+	dma_addr_t cyclic_seg_p;
 	void (*start_transfer)(struct xilinx_dma_chan *chan);
 	u16 tdest;
 };
@@ -569,17 +576,31 @@ static struct xilinx_axidma_tx_segment *
 xilinx_axidma_alloc_tx_segment(struct xilinx_dma_chan *chan)
 {
 	struct xilinx_axidma_tx_segment *segment;
-	dma_addr_t phys;
-
-	segment = dma_pool_zalloc(chan->desc_pool, GFP_ATOMIC, &phys);
-	if (!segment)
-		return NULL;
+	unsigned long flags;
 
-	segment->phys = phys;
+	spin_lock_irqsave(&chan->lock, flags);
+	if (!list_empty(&chan->free_seg_list)) {
+		segment = list_first_entry(&chan->free_seg_list,
+					   struct xilinx_axidma_tx_segment,
+					   node);
+		list_del(&segment->node);
+	}
+	spin_unlock_irqrestore(&chan->lock, flags);
 
 	return segment;
 }
 
+static void xilinx_dma_clean_hw_desc(struct xilinx_axidma_desc_hw *hw)
+{
+	u32 next_desc = hw->next_desc;
+	u32 next_desc_msb = hw->next_desc_msb;
+
+	memset(hw, 0, sizeof(struct xilinx_axidma_desc_hw));
+
+	hw->next_desc = next_desc;
+	hw->next_desc_msb = next_desc_msb;
+}
+
 /**
  * xilinx_dma_free_tx_segment - Free transaction segment
  * @chan: Driver specific DMA channel
@@ -588,7 +609,9 @@ xilinx_axidma_alloc_tx_segment(struct xilinx_dma_chan *chan)
 static void xilinx_dma_free_tx_segment(struct xilinx_dma_chan *chan,
 				struct xilinx_axidma_tx_segment *segment)
 {
-	dma_pool_free(chan->desc_pool, segment, segment->phys);
+	xilinx_dma_clean_hw_desc(&segment->hw);
+
+	list_add_tail(&segment->node, &chan->free_seg_list);
 }
 
 /**
@@ -713,16 +736,26 @@ static void xilinx_dma_free_descriptors(struct xilinx_dma_chan *chan)
 static void xilinx_dma_free_chan_resources(struct dma_chan *dchan)
 {
 	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	unsigned long flags;
 
 	dev_dbg(chan->dev, "Free all channel resources.\n");
 
 	xilinx_dma_free_descriptors(chan);
+
 	if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
-		xilinx_dma_free_tx_segment(chan, chan->cyclic_seg_v);
-		xilinx_dma_free_tx_segment(chan, chan->seg_v);
+		spin_lock_irqsave(&chan->lock, flags);
+		INIT_LIST_HEAD(&chan->free_seg_list);
+		spin_unlock_irqrestore(&chan->lock, flags);
+
+		/* Free Memory that is allocated for cyclic DMA Mode */
+		dma_free_coherent(chan->dev, sizeof(*chan->cyclic_seg_v),
+				  chan->cyclic_seg_v, chan->cyclic_seg_p);
+	}
+
+	if (chan->xdev->dma_config->dmatype != XDMA_TYPE_AXIDMA) {
+		dma_pool_destroy(chan->desc_pool);
+		chan->desc_pool = NULL;
 	}
-	dma_pool_destroy(chan->desc_pool);
-	chan->desc_pool = NULL;
 }
 
 /**
@@ -805,6 +838,7 @@ static void xilinx_dma_do_tasklet(unsigned long data)
 static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
 {
 	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
+	int i;
 
 	/* Has this channel already been allocated? */
 	if (chan->desc_pool)
@@ -815,11 +849,30 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
 	 * for meeting Xilinx VDMA specification requirement.
 	 */
 	if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
-		chan->desc_pool = dma_pool_create("xilinx_dma_desc_pool",
-				   chan->dev,
-				   sizeof(struct xilinx_axidma_tx_segment),
-				   __alignof__(struct xilinx_axidma_tx_segment),
-				   0);
+		/* Allocate the buffer descriptors. */
+		chan->seg_v = dma_zalloc_coherent(chan->dev,
+						  sizeof(*chan->seg_v) *
+						  XILINX_DMA_NUM_DESCS,
+						  &chan->seg_p, GFP_KERNEL);
+		if (!chan->seg_v) {
+			dev_err(chan->dev,
+				"unable to allocate channel %d descriptors\n",
+				chan->id);
+			return -ENOMEM;
+		}
+
+		for (i = 0; i < XILINX_DMA_NUM_DESCS; i++) {
+			chan->seg_v[i].hw.next_desc =
+			lower_32_bits(chan->seg_p + sizeof(*chan->seg_v) *
+				((i + 1) % XILINX_DMA_NUM_DESCS));
+			chan->seg_v[i].hw.next_desc_msb =
+			upper_32_bits(chan->seg_p + sizeof(*chan->seg_v) *
+				((i + 1) % XILINX_DMA_NUM_DESCS));
+			chan->seg_v[i].phys = chan->seg_p +
+				sizeof(*chan->seg_v) * i;
+			list_add_tail(&chan->seg_v[i].node,
+				      &chan->free_seg_list);
+		}
 	} else if (chan->xdev->dma_config->dmatype == XDMA_TYPE_CDMA) {
 		chan->desc_pool = dma_pool_create("xilinx_cdma_desc_pool",
 				   chan->dev,
@@ -834,7 +887,8 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
 				     0);
 	}
 
-	if (!chan->desc_pool) {
+	if (!chan->desc_pool &&
+	    (chan->xdev->dma_config->dmatype != XDMA_TYPE_AXIDMA)) {
 		dev_err(chan->dev,
 			"unable to allocate channel %d descriptor pool\n",
 			chan->id);
@@ -843,22 +897,20 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan)
 
 	if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) {
 		/*
-		 * For AXI DMA case after submitting a pending_list, keep
-		 * an extra segment allocated so that the "next descriptor"
-		 * pointer on the tail descriptor always points to a
-		 * valid descriptor, even when paused after reaching taildesc.
-		 * This way, it is possible to issue additional
-		 * transfers without halting and restarting the channel.
-		 */
-		chan->seg_v = xilinx_axidma_alloc_tx_segment(chan);
-
-		/*
 		 * For cyclic DMA mode we need to program the tail Descriptor
 		 * register with a value which is not a part of the BD chain
 		 * so allocating a desc segment during channel allocation for
 		 * programming tail descriptor.
 		 */
-		chan->cyclic_seg_v = xilinx_axidma_alloc_tx_segment(chan);
+		chan->cyclic_seg_v = dma_zalloc_coherent(chan->dev,
+					sizeof(*chan->cyclic_seg_v),
+					&chan->cyclic_seg_p, GFP_KERNEL);
+		if (!chan->cyclic_seg_v) {
+			dev_err(chan->dev,
+				"unable to allocate desc segment for cyclic DMA\n");
+			return -ENOMEM;
+		}
+		chan->cyclic_seg_v->phys = chan->cyclic_seg_p;
 	}
 
 	dma_cookie_init(dchan);
@@ -1197,7 +1249,7 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan)
 static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
 {
 	struct xilinx_dma_tx_descriptor *head_desc, *tail_desc;
-	struct xilinx_axidma_tx_segment *tail_segment, *old_head, *new_head;
+	struct xilinx_axidma_tx_segment *tail_segment;
 	u32 reg;
 
 	if (chan->err)
@@ -1216,21 +1268,6 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan)
 	tail_segment = list_last_entry(&tail_desc->segments,
 				       struct xilinx_axidma_tx_segment, node);
 
-	if (chan->has_sg && !chan->xdev->mcdma) {
-		old_head = list_first_entry(&head_desc->segments,
-					struct xilinx_axidma_tx_segment, node);
-		new_head = chan->seg_v;
-		/* Copy Buffer Descriptor fields. */
-		new_head->hw = old_head->hw;
-
-		/* Swap and save new reserve */
-		list_replace_init(&old_head->node, &new_head->node);
-		chan->seg_v = old_head;
-
-		tail_segment->hw.next_desc = chan->seg_v->phys;
-		head_desc->async_tx.phys = new_head->phys;
-	}
-
 	reg = dma_ctrl_read(chan, XILINX_DMA_REG_DMACR);
 
 	if (chan->desc_pendingcount <= XILINX_DMA_COALESCE_MAX) {
@@ -1728,7 +1765,7 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
 {
 	struct xilinx_dma_chan *chan = to_xilinx_chan(dchan);
 	struct xilinx_dma_tx_descriptor *desc;
-	struct xilinx_axidma_tx_segment *segment = NULL, *prev = NULL;
+	struct xilinx_axidma_tx_segment *segment = NULL;
 	u32 *app_w = (u32 *)context;
 	struct scatterlist *sg;
 	size_t copy;
@@ -1779,10 +1816,6 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
 					       XILINX_DMA_NUM_APP_WORDS);
 			}
 
-			if (prev)
-				prev->hw.next_desc = segment->phys;
-
-			prev = segment;
 			sg_used += copy;
 
 			/*
@@ -1796,7 +1829,6 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg(
 	segment = list_first_entry(&desc->segments,
 				   struct xilinx_axidma_tx_segment, node);
 	desc->async_tx.phys = segment->phys;
-	prev->hw.next_desc = segment->phys;
 
 	/* For the last DMA_MEM_TO_DEV transfer, set EOP */
 	if (chan->direction == DMA_MEM_TO_DEV) {
@@ -2340,6 +2372,7 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
 	INIT_LIST_HEAD(&chan->pending_list);
 	INIT_LIST_HEAD(&chan->done_list);
 	INIT_LIST_HEAD(&chan->active_list);
+	INIT_LIST_HEAD(&chan->free_seg_list);
 
 	/* Retrieve the channel properties from the device tree */
 	has_dre = of_property_read_bool(node, "xlnx,include-dre");
-- 
2.1.2

^ permalink raw reply related

* [PATCH v4 2/3] ARM: dts: imx6: Support Savageboard dual
From: Milo Kim @ 2017-01-04  7:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20170104045553.26576-3-woogyom.kim@gmail.com>


On 01/04/2017 01:55 PM, Milo Kim wrote:
> Common savageboard DT file is used for board support.
> Add the vendor name and specify the dtb file for i.MX6Q build.
>
> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
> Signed-off-by: Milo Kim <woogyom.kim@gmail.com>
> ---
>  .../devicetree/bindings/vendor-prefixes.txt        |  1 +
>  arch/arm/boot/dts/Makefile                         |  1 +
>  arch/arm/boot/dts/imx6dl-savageboard.dts           | 51 ++++++++++++++++++++++
>  3 files changed, 53 insertions(+)
>  create mode 100644 arch/arm/boot/dts/imx6dl-savageboard.dts
>
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
> index 16d3b5e7f5d1..88c33d827e51 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> @@ -227,6 +227,7 @@ pine64	Pine64
>  pixcir  PIXCIR MICROELECTRONICS Co., Ltd
>  plathome	Plat'Home Co., Ltd.
>  plda	PLDA
> +poslab  Poslab Technology Co., Ltd.

I should input tab here instead of spaces, so updated single patch was 
just sent. Please refer to the patch named "[PATCH resend v4 2/3] ARM: 
dts: imx6: Support Savageboard dual".

Sorry for the inconvenience.

Best regards,
Milo

^ permalink raw reply

* Re: [PATCH v4 2/3] ARM: dts: imx6: Support Savageboard dual
From: Milo Kim @ 2017-01-04  7:12 UTC (permalink / raw)
  To: Shawn Guo, Sascha Hauer
  Cc: Fabio Estevam, devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <20170104045553.26576-3-woogyom.kim@gmail.com>


On 01/04/2017 01:55 PM, Milo Kim wrote:
> Common savageboard DT file is used for board support.
> Add the vendor name and specify the dtb file for i.MX6Q build.
>
> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
> Signed-off-by: Milo Kim <woogyom.kim@gmail.com>
> ---
>  .../devicetree/bindings/vendor-prefixes.txt        |  1 +
>  arch/arm/boot/dts/Makefile                         |  1 +
>  arch/arm/boot/dts/imx6dl-savageboard.dts           | 51 ++++++++++++++++++++++
>  3 files changed, 53 insertions(+)
>  create mode 100644 arch/arm/boot/dts/imx6dl-savageboard.dts
>
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
> index 16d3b5e7f5d1..88c33d827e51 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> @@ -227,6 +227,7 @@ pine64	Pine64
>  pixcir  PIXCIR MICROELECTRONICS Co., Ltd
>  plathome	Plat'Home Co., Ltd.
>  plda	PLDA
> +poslab  Poslab Technology Co., Ltd.

I should input tab here instead of spaces, so updated single patch was 
just sent. Please refer to the patch named "[PATCH resend v4 2/3] ARM: 
dts: imx6: Support Savageboard dual".

Sorry for the inconvenience.

Best regards,
Milo

^ permalink raw reply

* [PATCH] memory: tegra: Add a missing 'of_node_put()' call
From: Christophe JAILLET @ 2017-01-04  7:13 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q,
	thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	gnurou-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kernel-janitors-u79uwXL29TY76Z2rM5mHXA, Christophe JAILLET

If 'of_find_device_by_node()' fails, an 'of_node_put()' call is missing in
the error handling path.
Fix it by reordering the code.

While at it, remove some empty lines in a more or less similar construction
a few lines below.

Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
---
 drivers/memory/tegra/tegra124-emc.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index 06cc781ebac1..392dc8dd481f 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -1115,11 +1115,10 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	}
 
 	mc = of_find_device_by_node(np);
+	of_node_put(np);
 	if (!mc)
 		return -ENOENT;
 
-	of_node_put(np);
-
 	emc->mc = platform_get_drvdata(mc);
 	if (!emc->mc)
 		return -EPROBE_DEFER;
@@ -1135,9 +1134,7 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	}
 
 	err = tegra_emc_load_timings_from_dt(emc, np);
-
 	of_node_put(np);
-
 	if (err)
 		return err;
 
-- 
2.9.3


^ permalink raw reply related

* [PATCH] memory: tegra: Add a missing 'of_node_put()' call
From: Christophe JAILLET @ 2017-01-04  7:13 UTC (permalink / raw)
  To: swarren-3lzwWm7+Weoh9ZMKESR00Q,
	thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
	gnurou-Re5JQEeQqe8AvxtiuMwx3w
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	kernel-janitors-u79uwXL29TY76Z2rM5mHXA, Christophe JAILLET

If 'of_find_device_by_node()' fails, an 'of_node_put()' call is missing in
the error handling path.
Fix it by reordering the code.

While at it, remove some empty lines in a more or less similar construction
a few lines below.

Signed-off-by: Christophe JAILLET <christophe.jaillet-39ZsbGIQGT5GWvitb5QawA@public.gmane.org>
---
 drivers/memory/tegra/tegra124-emc.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index 06cc781ebac1..392dc8dd481f 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -1115,11 +1115,10 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	}
 
 	mc = of_find_device_by_node(np);
+	of_node_put(np);
 	if (!mc)
 		return -ENOENT;
 
-	of_node_put(np);
-
 	emc->mc = platform_get_drvdata(mc);
 	if (!emc->mc)
 		return -EPROBE_DEFER;
@@ -1135,9 +1134,7 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	}
 
 	err = tegra_emc_load_timings_from_dt(emc, np);
-
 	of_node_put(np);
-
 	if (err)
 		return err;
 
-- 
2.9.3

^ permalink raw reply related

* [RESEND,PATCH v7 1/2] soc: qcom: Add SoC info driver
From: Imran Khan @ 2017-01-04  7:13 UTC (permalink / raw)
  To: andy.gross
  Cc: lee.jones, Imran Khan, David Brown, open list,
	open list:ARM/QUALCOMM SUPPORT, open list:ARM/QUALCOMM SUPPORT

The SoC info driver provides information such as Chip ID,
Chip family, serial number and other such details about
Qualcomm SoCs to user space, so that if needed some user
space utility(like antutu) can query such information
using sysfs interface.

Signed-off-by: Imran Khan <kimran@codeaurora.org>
---
v6 --> v7:
 - Some minor style changes
 - Rather than showing string for h/w types, just show the
   number obtained from SMEM. The reader of this number
   is supposed to parse this into a human readable string 
   as this information may be different for different ODMs
 - Create an attribute 'qcom_odm' depending on the presence
   of corresponding property in SMEM DT entry. This information
   can be used for ODM specific interpretation of SMEM socinfo
   content
 - Read machine value from DT, rather than using soc-id as index
   in an ever increasing array of machine names

v5 --> v6:
 - use dev_ext_attribute to represent SMEM image items
 - Avoid redundant function calls
 - Avoid use of unnecessary global variables
 - Remove redundant enums
 - Avoid redundant checking of socinfo being NULL or not
 - Avoid redundant checking of socinfo format version
 - Rename show/store function of attributes as _show/_store
   rather than _get/_set
 - Use an array to represent socinfo attributes and create
   attribute files in a loop depending on the minimum 
   socinfo format version for which these attributes are 
   supported
 - if obtained socinfo format version is greater than the
   maximum known version return an error rather than falling
   back to maximum known version
 
v4 --> v5:
 - Removed redundant function socinfo_print

v3 --> v4:
 - Corrected makefile so that smem and socinfo are treated as one module
 - Moved the code snippet to get socinfo smem item into socinfo.c
 - Removed redundant use of socinfo major version as it is always zero
 - Removed unused enums
 - Removed redundant indirections
 - Use image_version object to store information about each entry in the
   smem image table
 - Replaced usage of snprintf with sprintf and scnprintf
 - Get the address of image version table at the beginning and setup
   image version attributes only if image version table is available
 - Do the same for platform_subtype
 - Make different type of image version objects read only or readable/
   writable depending on their types. For example apps image attributes
   can be modified via sysfs but the same can't be done for modem image
 - Show PMIC model in a human readable form rather than a numeric number
 - Avoid using table in single sysfs entry
 - Removed checkpatch warnings about S_IRUGO

v2 --> v3:
 - Add support to toss soc information data into entropy pool
 - Since socinfo is rolled into smem driver, compile the
   relevant portion of socinfo driver with smem driver
 
v1 --> v2:
 - Removed inclusion of system_misc.h
 - merged socinfo.h into socinfo.c
 - made platform type and subtype arrays static
 - replaced uint32_t with u32
 - made functions static to avoid exposing vendor specific interface
 - Replaced usage of IS_ERR_OR_NULL with IS_ERR.
 - Remove raw-id attribute usage as human readable soc-id will suffice here
 - Avoid using a separate platform driver for socinfo by rolling it into smem driver itself.
   The sysfs setup is being done in a separate file (socinfo.c)
 - Replaced macro BUILD_ID_LENGTH with  SMEM_SOCINFO_BUILD_ID_LENGTH.
 - For failure cases where socinfo can not be read use a single dummy socinfo with error values.
 - Removed usage of early_machine_is_xxx.


 drivers/soc/qcom/Kconfig   |   1 +
 drivers/soc/qcom/Makefile  |   3 +-
 drivers/soc/qcom/smem.c    |   5 +
 drivers/soc/qcom/socinfo.c | 515 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 523 insertions(+), 1 deletion(-)
 create mode 100644 drivers/soc/qcom/socinfo.c

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 461b387..f89d34d 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -24,6 +24,7 @@ config QCOM_SMEM
 	tristate "Qualcomm Shared Memory Manager (SMEM)"
 	depends on ARCH_QCOM
 	depends on HWSPINLOCK
+	select SOC_BUS
 	help
 	  Say y here to enable support for the Qualcomm Shared Memory Manager.
 	  The driver provides an interface to items in a heap shared among all
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index fdd664e..438efec 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -2,7 +2,8 @@ obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
 obj-$(CONFIG_QCOM_PM)	+=	spm.o
 obj-$(CONFIG_QCOM_SMD) +=	smd.o
 obj-$(CONFIG_QCOM_SMD_RPM)	+= smd-rpm.o
-obj-$(CONFIG_QCOM_SMEM) +=	smem.o
+obj-$(CONFIG_QCOM_SMEM) +=	qcom_smem.o
+qcom_smem-y := smem.o socinfo.o
 obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
 obj-$(CONFIG_QCOM_SMP2P)	+= smp2p.o
 obj-$(CONFIG_QCOM_SMSM)	+= smsm.o
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 18ec52f..4f0ccf8 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -85,6 +85,9 @@
 /* Max number of processors/hosts in a system */
 #define SMEM_HOST_COUNT		9
 
+
+extern void qcom_socinfo_init(struct device *device);
+
 /**
   * struct smem_proc_comm - proc_comm communication struct (legacy)
   * @command:	current command to be executed
@@ -751,6 +754,8 @@ static int qcom_smem_probe(struct platform_device *pdev)
 
 	__smem = smem;
 
+	qcom_socinfo_init(&pdev->dev);
+
 	return 0;
 }
 
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
new file mode 100644
index 0000000..8eb3252
--- /dev/null
+++ b/drivers/soc/qcom/socinfo.c
@@ -0,0 +1,515 @@
+/*
+ * Copyright (c) 2009-2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/platform_device.h>
+#include <linux/sys_soc.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/random.h>
+#include <linux/soc/qcom/smem.h>
+
+/*
+ * SOC version type with major number in the upper 16 bits and minor
+ * number in the lower 16 bits.  For example:
+ *   1.0 -> 0x00010000
+ *   2.3 -> 0x00020003
+ */
+#define SOC_VER_MAJ(ver) (((ver) & 0xffff0000) >> 16)
+#define SOC_VER_MIN(ver) ((ver) & 0x0000ffff)
+#define SOCINFO_VERSION_MAJOR	SOC_VER_MAJ
+#define SOCINFO_VERSION_MINOR	SOC_VER_MIN
+
+#define SMEM_SOCINFO_BUILD_ID_LENGTH		32
+#define SMEM_IMAGE_VERSION_BLOCKS_COUNT		32
+#define SMEM_IMAGE_VERSION_SIZE			4096
+#define SMEM_IMAGE_VERSION_NAME_SIZE		75
+#define SMEM_IMAGE_VERSION_VARIANT_SIZE		20
+#define SMEM_IMAGE_VERSION_OEM_SIZE		32
+
+/*
+ * SMEM item ids, used to acquire handles to respective
+ * SMEM region.
+ */
+#define SMEM_IMAGE_VERSION_TABLE	469
+#define SMEM_HW_SW_BUILD_ID		137
+
+/*
+ * SMEM Image table indices
+ */
+#define SMEM_IMAGE_TABLE_BOOT_INDEX	0
+#define SMEM_IMAGE_TABLE_TZ_INDEX	1
+#define SMEM_IMAGE_TABLE_RPM_INDEX	3
+#define SMEM_IMAGE_TABLE_APPS_INDEX	10
+#define SMEM_IMAGE_TABLE_MPSS_INDEX	11
+#define SMEM_IMAGE_TABLE_ADSP_INDEX	12
+#define SMEM_IMAGE_TABLE_CNSS_INDEX	13
+#define SMEM_IMAGE_TABLE_VIDEO_INDEX	14
+
+static const char *odm_name;
+
+struct qcom_socinfo_attr {
+	struct device_attribute attr;
+	int min_ver;
+};
+
+#define QCOM_SOCINFO_ATTR(_name, _show, _min_ver) \
+	{ __ATTR(_name, 0444, _show, NULL), _min_ver }
+
+
+struct smem_image_attribute {
+	struct device_attribute version;
+	struct device_attribute variant;
+	struct device_attribute crm;
+	int index;
+};
+
+#define QCOM_SMEM_IMG_ITEM(_name, _mode, _index) \
+	static struct smem_image_attribute _name##_image_attrs = { \
+		__ATTR(_name##_image_version, _mode, \
+			qcom_show_image_version, qcom_store_image_version), \
+		__ATTR(_name##_image_variant, _mode, \
+			qcom_show_image_variant, qcom_store_image_variant), \
+		__ATTR(_name##_image_crm, _mode, \
+			qcom_show_image_crm, qcom_store_image_crm), \
+		_index \
+	}; \
+	static struct attribute_group _name##_image_attr_group = { \
+		.attrs = (struct attribute*[]) { \
+			&_name##_image_attrs.version.attr, \
+			&_name##_image_attrs.variant.attr, \
+			&_name##_image_attrs.crm.attr, \
+			NULL \
+		} \
+	}
+
+static const char *const pmic_model[] = {
+	[0]  = "Unknown PMIC model",
+	[13] = "PM8058",
+	[14] = "PM8028",
+	[15] = "PM8901",
+	[16] = "PM8027",
+	[17] = "ISL9519",
+	[18] = "PM8921",
+	[19] = "PM8018",
+	[20] = "PM8015",
+	[21] = "PM8014",
+	[22] = "PM8821",
+	[23] = "PM8038",
+	[24] = "PM8922",
+	[25] = "PM8917",
+};
+
+struct smem_image_version {
+	char name[SMEM_IMAGE_VERSION_NAME_SIZE];
+	char variant[SMEM_IMAGE_VERSION_VARIANT_SIZE];
+	char pad;
+	char oem[SMEM_IMAGE_VERSION_OEM_SIZE];
+};
+
+/* Used to parse shared memory. Must match the modem. */
+struct socinfo_v0_1 {
+	__le32 fmt;
+	__le32 id;
+	__le32 ver;
+	char build_id[SMEM_SOCINFO_BUILD_ID_LENGTH];
+};
+
+struct socinfo_v0_2 {
+	struct socinfo_v0_1 v0_1;
+	__le32 raw_ver;
+};
+
+struct socinfo_v0_3 {
+	struct socinfo_v0_2 v0_2;
+	__le32 hw_plat;
+};
+
+struct socinfo_v0_4 {
+	struct socinfo_v0_3 v0_3;
+	__le32 plat_ver;
+};
+
+struct socinfo_v0_5 {
+	struct socinfo_v0_4 v0_4;
+	__le32 accsry_chip;
+};
+
+struct socinfo_v0_6 {
+	struct socinfo_v0_5 v0_5;
+	__le32 hw_plat_subtype;
+};
+
+struct socinfo_v0_7 {
+	struct socinfo_v0_6 v0_6;
+	__le32 pmic_model;
+	__le32 pmic_die_rev;
+};
+
+struct socinfo_v0_8 {
+	struct socinfo_v0_7 v0_7;
+	__le32 pmic_model_1;
+	__le32 pmic_die_rev_1;
+	__le32 pmic_model_2;
+	__le32 pmic_die_rev_2;
+};
+
+struct socinfo_v0_9 {
+	struct socinfo_v0_8 v0_8;
+	__le32 fndry_id;
+};
+
+struct socinfo_v0_10 {
+	struct socinfo_v0_9 v0_9;
+	__le32 srl_num;
+};
+
+struct socinfo_v0_11 {
+	struct socinfo_v0_10 v0_10;
+	__le32 num_pmics;
+	__le32 pmic_array_offset;
+};
+
+struct socinfo_v0_12 {
+	struct socinfo_v0_11 v0_11;
+	__le32 chip_family;
+	__le32 raw_dev_fam;
+	__le32 raw_dev_num;
+};
+
+static union {
+	struct socinfo_v0_1 v0_1;
+	struct socinfo_v0_2 v0_2;
+	struct socinfo_v0_3 v0_3;
+	struct socinfo_v0_4 v0_4;
+	struct socinfo_v0_5 v0_5;
+	struct socinfo_v0_6 v0_6;
+	struct socinfo_v0_7 v0_7;
+	struct socinfo_v0_8 v0_8;
+	struct socinfo_v0_9 v0_9;
+	struct socinfo_v0_10 v0_10;
+	struct socinfo_v0_11 v0_11;
+	struct socinfo_v0_12 v0_12;
+} *socinfo;
+
+static struct smem_image_version *smem_image_version;
+
+/* max socinfo format version supported */
+#define MAX_SOCINFO_FORMAT 12
+
+/* socinfo: sysfs functions */
+
+static ssize_t
+qcom_odm_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return scnprintf(buf, PAGE_SIZE, "%s\n", odm_name);
+}
+DEVICE_ATTR_RO(qcom_odm);
+
+static ssize_t
+qcom_show_vendor(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%s", "Qualcomm\n");
+}
+
+static ssize_t
+qcom_show_raw_version(struct device *dev, struct device_attribute *attr,
+		     char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_2.raw_ver));
+}
+
+static ssize_t
+qcom_show_build_id(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return scnprintf(buf, PAGE_SIZE, "%s\n", socinfo->v0_1.build_id);
+}
+
+static ssize_t
+qcom_show_hw_platform(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_3.hw_plat));
+}
+
+static ssize_t
+qcom_show_platform_version(struct device *dev, struct device_attribute *attr,
+				char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_4.plat_ver));
+}
+
+static ssize_t
+qcom_show_accessory_chip(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_5.accsry_chip));
+}
+
+static ssize_t
+qcom_show_platform_subtype(struct device *dev, struct device_attribute *attr,
+				char *buf)
+{
+	u32 subtype = le32_to_cpu(socinfo->v0_6.hw_plat_subtype);
+
+	if (subtype < 0)
+		return -EINVAL;
+
+	return sprintf(buf, "%u\n", subtype);
+}
+
+static ssize_t
+qcom_show_foundry_id(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_9.fndry_id));
+}
+
+static ssize_t
+qcom_show_serial_number(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_10.srl_num));
+}
+
+static ssize_t
+qcom_show_chip_family(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	return sprintf(buf, "0x%x\n", le32_to_cpu(socinfo->v0_12.chip_family));
+}
+
+static ssize_t
+qcom_show_raw_device_family(struct device *dev, struct device_attribute *attr,
+				char *buf)
+{
+	return sprintf(buf, "0x%x\n", le32_to_cpu(socinfo->v0_12.raw_dev_fam));
+}
+
+static ssize_t
+qcom_show_raw_device_number(struct device *dev, struct device_attribute *attr,
+				char *buf)
+{
+	return sprintf(buf, "0x%x\n", le32_to_cpu(socinfo->v0_12.raw_dev_num));
+}
+
+static ssize_t
+qcom_show_pmic_model(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	return sprintf(buf, "%s\n",
+			pmic_model[le32_to_cpu(socinfo->v0_7.pmic_model)]);
+}
+
+static ssize_t
+qcom_show_pmic_die_revision(struct device *dev, struct device_attribute *attr,
+				char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_7.pmic_die_rev));
+}
+
+static ssize_t
+qcom_show_image_version(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	struct smem_image_attribute *smem_attr;
+
+	smem_attr = container_of(attr, struct smem_image_attribute, version);
+	return scnprintf(buf, PAGE_SIZE, "%s\n",
+			smem_image_version[smem_attr->index].name);
+}
+
+static ssize_t
+qcom_store_image_version(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t size)
+{
+	struct smem_image_attribute *smem_attr;
+
+	smem_attr = container_of(attr, struct smem_image_attribute, version);
+	return strlcpy(smem_image_version[smem_attr->index].name, buf,
+			SMEM_IMAGE_VERSION_NAME_SIZE);
+}
+
+static ssize_t
+qcom_show_image_variant(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	struct smem_image_attribute *smem_attr;
+
+	smem_attr = container_of(attr, struct smem_image_attribute, variant);
+	return scnprintf(buf, PAGE_SIZE, "%s\n",
+			smem_image_version[smem_attr->index].variant);
+}
+
+static ssize_t
+qcom_store_image_variant(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t size)
+{
+	struct smem_image_attribute *smem_attr;
+
+	smem_attr = container_of(attr, struct smem_image_attribute, variant);
+	return strlcpy(smem_image_version[smem_attr->index].variant, buf,
+			SMEM_IMAGE_VERSION_VARIANT_SIZE);
+}
+
+static ssize_t
+qcom_show_image_crm(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	struct smem_image_attribute *smem_attr;
+
+	smem_attr = container_of(attr, struct smem_image_attribute, crm);
+	return scnprintf(buf, PAGE_SIZE, "%s\n",
+			smem_image_version[smem_attr->index].oem);
+}
+
+static ssize_t
+qcom_store_image_crm(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t size)
+{
+	struct smem_image_attribute *smem_attr;
+
+	smem_attr = container_of(attr, struct smem_image_attribute, crm);
+	return strlcpy(smem_image_version[smem_attr->index].oem, buf,
+			SMEM_IMAGE_VERSION_OEM_SIZE);
+}
+
+static const struct qcom_socinfo_attr socinfo_attrs[] = {
+	QCOM_SOCINFO_ATTR(chip_family, qcom_show_chip_family, 12),
+	QCOM_SOCINFO_ATTR(raw_device_family, qcom_show_raw_device_family, 12),
+	QCOM_SOCINFO_ATTR(raw_device_number, qcom_show_raw_device_number, 12),
+	QCOM_SOCINFO_ATTR(serial_number, qcom_show_serial_number, 10),
+	QCOM_SOCINFO_ATTR(foundry_id, qcom_show_foundry_id, 9),
+	QCOM_SOCINFO_ATTR(pmic_model, qcom_show_pmic_model, 7),
+	QCOM_SOCINFO_ATTR(pmic_die_revision, qcom_show_pmic_die_revision, 7),
+	QCOM_SOCINFO_ATTR(platform_subtype, qcom_show_platform_subtype, 6),
+	QCOM_SOCINFO_ATTR(accessory_chip, qcom_show_accessory_chip, 5),
+	QCOM_SOCINFO_ATTR(platform_version, qcom_show_platform_version, 4),
+	QCOM_SOCINFO_ATTR(hw_platform, qcom_show_hw_platform, 3),
+	QCOM_SOCINFO_ATTR(raw_version, qcom_show_raw_version, 2),
+	QCOM_SOCINFO_ATTR(build_id, qcom_show_build_id, 1),
+	QCOM_SOCINFO_ATTR(vendor, qcom_show_vendor, 0),
+};
+
+QCOM_SMEM_IMG_ITEM(boot, 0444, SMEM_IMAGE_TABLE_BOOT_INDEX);
+QCOM_SMEM_IMG_ITEM(tz, 0444, SMEM_IMAGE_TABLE_TZ_INDEX);
+QCOM_SMEM_IMG_ITEM(rpm, 0444, SMEM_IMAGE_TABLE_RPM_INDEX);
+QCOM_SMEM_IMG_ITEM(apps, 0644, SMEM_IMAGE_TABLE_APPS_INDEX);
+QCOM_SMEM_IMG_ITEM(mpss, 0444, SMEM_IMAGE_TABLE_MPSS_INDEX);
+QCOM_SMEM_IMG_ITEM(adsp, 0444, SMEM_IMAGE_TABLE_ADSP_INDEX);
+QCOM_SMEM_IMG_ITEM(cnss, 0444, SMEM_IMAGE_TABLE_CNSS_INDEX);
+QCOM_SMEM_IMG_ITEM(video, 0444, SMEM_IMAGE_TABLE_VIDEO_INDEX);
+
+static const struct attribute_group
+	*smem_img_tbl[SMEM_IMAGE_VERSION_BLOCKS_COUNT] = {
+		[SMEM_IMAGE_TABLE_BOOT_INDEX] = &boot_image_attr_group,
+		[SMEM_IMAGE_TABLE_TZ_INDEX] = &tz_image_attr_group,
+		[SMEM_IMAGE_TABLE_RPM_INDEX] = &rpm_image_attr_group,
+		[SMEM_IMAGE_TABLE_APPS_INDEX] = &apps_image_attr_group,
+		[SMEM_IMAGE_TABLE_MPSS_INDEX] = &mpss_image_attr_group,
+		[SMEM_IMAGE_TABLE_ADSP_INDEX] = &adsp_image_attr_group,
+		[SMEM_IMAGE_TABLE_CNSS_INDEX] = &cnss_image_attr_group,
+		[SMEM_IMAGE_TABLE_VIDEO_INDEX] = &video_image_attr_group,
+};
+
+void qcom_socinfo_init(struct device *device)
+{
+	struct soc_device_attribute *attr;
+	struct soc_device *soc_dev;
+	const char *machine;
+	struct device *dev;
+	size_t item_size;
+	size_t size;
+	int i;
+
+	socinfo = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_HW_SW_BUILD_ID,
+			&item_size);
+	if (IS_ERR(socinfo)) {
+		dev_err(device, "Coudn't find socinfo\n");
+		return;
+	}
+
+	if ((SOCINFO_VERSION_MAJOR(le32_to_cpu(socinfo->v0_1.fmt)) != 0) ||
+	(SOCINFO_VERSION_MINOR(le32_to_cpu(socinfo->v0_1.fmt)) < 0) ||
+	(le32_to_cpu(socinfo->v0_1.fmt) > MAX_SOCINFO_FORMAT)) {
+		dev_err(device, "Wrong socinfo format\n");
+		return;
+	}
+
+	if (!le32_to_cpu(socinfo->v0_1.id))
+		dev_err(device, "socinfo: Unknown SoC ID!\n");
+
+	smem_image_version = qcom_smem_get(QCOM_SMEM_HOST_ANY,
+				SMEM_IMAGE_VERSION_TABLE,
+				&size);
+	if (IS_ERR(smem_image_version) || (size != SMEM_IMAGE_VERSION_SIZE)) {
+		dev_dbg(device, "Image version table absent\n");
+		smem_image_version = NULL;
+	}
+
+	attr = kzalloc(sizeof(*attr), GFP_KERNEL);
+	if (!attr)
+		return;
+
+	attr->soc_id = kasprintf(GFP_KERNEL, "%d",
+				le32_to_cpu(socinfo->v0_1.id));
+	attr->family = "Snapdragon";
+	machine = of_flat_dt_get_machine_name();
+	if (machine)
+		attr->machine = kasprintf(GFP_KERNEL, "%s", machine);
+
+	attr->revision = kasprintf(GFP_KERNEL, "%u.%u",
+				SOC_VER_MAJ(le32_to_cpu(socinfo->v0_1.ver)),
+				SOC_VER_MIN(le32_to_cpu(socinfo->v0_1.ver)));
+
+	soc_dev = soc_device_register(attr);
+	if (IS_ERR(soc_dev)) {
+		kfree(attr);
+		return;
+	}
+
+	dev = soc_device_to_device(soc_dev);
+
+	/*
+	 * Expose SMEM_IMAGE_TABLE to sysfs only when we have IMAGE_TABLE
+	 * available in SMEM. As IMAGE_TABLE and SOCINFO are two separate
+	 * items within SMEM, we expose the remaining soc information(i.e
+	 * only the SOCINFO item available in SMEM) to sysfs even in the
+	 * absence of an IMAGE_TABLE.
+	 */
+	if (smem_image_version) {
+		for (i = 0; i < SMEM_IMAGE_VERSION_BLOCKS_COUNT; i++) {
+			if (smem_img_tbl[i])
+				WARN_ON(sysfs_create_group(&dev->kobj,
+					smem_img_tbl[i]));
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(socinfo_attrs); i++) {
+		if (socinfo_attrs[i].min_ver <=	le32_to_cpu(socinfo->v0_1.fmt))
+			device_create_file(dev, &socinfo_attrs[i].attr);
+	}
+
+	odm_name = of_get_property(device->of_node, "qcom,odm", NULL);
+	if (odm_name)
+		device_create_file(dev, &dev_attr_qcom_odm);
+
+	/* Feed the soc specific unique data into entropy pool */
+	add_device_randomness(socinfo, item_size);
+}
+EXPORT_SYMBOL(qcom_socinfo_init);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related

* [RESEND,PATCH v7 0/2] soc: qcom: Add SoC info driver
From: Imran Khan @ 2017-01-04  7:13 UTC (permalink / raw)
  To: andy.gross; +Cc: lee.jones, linux-kernel, linux-arm-msm, Imran Khan

This is patchset v7 which takes care of review comments
received for patchset v6. Resending the patch set as
the last one had a compilation error. 

Major changes with respect to patch v6 are as below:
 - Rather than showing string for h/w types, just show the
   number obtained from SMEM. The reader of this number
   is supposed to parse this into a human readable string 
   as this information may be different for different ODMs
 - Create an attribute 'qcom_odm' depending on the presence
   of corresponding property in SMEM DT entry. This information
   can be used for ODM specific interpretation of SMEM socinfo
   content
 - Read machine value from DT, rather than using soc-id as index
   in an ever increasing array of machine names

Imran Khan (2):
  soc: qcom: Add SoC info driver
  Documentation/ABI: Add ABI information for QCOM socinfo driver

 Documentation/ABI/stable/sysfs-driver-qcom_socinfo | 147 ++++++
 drivers/soc/qcom/Kconfig                           |   1 +
 drivers/soc/qcom/Makefile                          |   3 +-
 drivers/soc/qcom/smem.c                            |   5 +
 drivers/soc/qcom/socinfo.c                         | 515 +++++++++++++++++++++
 5 files changed, 670 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/stable/sysfs-driver-qcom_socinfo
 create mode 100644 drivers/soc/qcom/socinfo.c

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply

* Re: [PATCH v4 2/3] ARM: dts: imx6: Support Savageboard dual
From: Milo Kim @ 2017-01-04  7:12 UTC (permalink / raw)
  To: Shawn Guo, Sascha Hauer
  Cc: Fabio Estevam, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <20170104045553.26576-3-woogyom.kim@gmail.com>


On 01/04/2017 01:55 PM, Milo Kim wrote:
> Common savageboard DT file is used for board support.
> Add the vendor name and specify the dtb file for i.MX6Q build.
>
> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
> Signed-off-by: Milo Kim <woogyom.kim@gmail.com>
> ---
>  .../devicetree/bindings/vendor-prefixes.txt        |  1 +
>  arch/arm/boot/dts/Makefile                         |  1 +
>  arch/arm/boot/dts/imx6dl-savageboard.dts           | 51 ++++++++++++++++++++++
>  3 files changed, 53 insertions(+)
>  create mode 100644 arch/arm/boot/dts/imx6dl-savageboard.dts
>
> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
> index 16d3b5e7f5d1..88c33d827e51 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> @@ -227,6 +227,7 @@ pine64	Pine64
>  pixcir  PIXCIR MICROELECTRONICS Co., Ltd
>  plathome	Plat'Home Co., Ltd.
>  plda	PLDA
> +poslab  Poslab Technology Co., Ltd.

I should input tab here instead of spaces, so updated single patch was 
just sent. Please refer to the patch named "[PATCH resend v4 2/3] ARM: 
dts: imx6: Support Savageboard dual".

Sorry for the inconvenience.

Best regards,
Milo

^ permalink raw reply

* [RESEND,PATCH v7 1/2] soc: qcom: Add SoC info driver
From: Imran Khan @ 2017-01-04  7:13 UTC (permalink / raw)
  To: andy.gross
  Cc: lee.jones, Imran Khan, David Brown, open list,
	open list:ARM/QUALCOMM SUPPORT, open list:ARM/QUALCOMM SUPPORT

The SoC info driver provides information such as Chip ID,
Chip family, serial number and other such details about
Qualcomm SoCs to user space, so that if needed some user
space utility(like antutu) can query such information
using sysfs interface.

Signed-off-by: Imran Khan <kimran@codeaurora.org>
---
v6 --> v7:
 - Some minor style changes
 - Rather than showing string for h/w types, just show the
   number obtained from SMEM. The reader of this number
   is supposed to parse this into a human readable string 
   as this information may be different for different ODMs
 - Create an attribute 'qcom_odm' depending on the presence
   of corresponding property in SMEM DT entry. This information
   can be used for ODM specific interpretation of SMEM socinfo
   content
 - Read machine value from DT, rather than using soc-id as index
   in an ever increasing array of machine names

v5 --> v6:
 - use dev_ext_attribute to represent SMEM image items
 - Avoid redundant function calls
 - Avoid use of unnecessary global variables
 - Remove redundant enums
 - Avoid redundant checking of socinfo being NULL or not
 - Avoid redundant checking of socinfo format version
 - Rename show/store function of attributes as _show/_store
   rather than _get/_set
 - Use an array to represent socinfo attributes and create
   attribute files in a loop depending on the minimum 
   socinfo format version for which these attributes are 
   supported
 - if obtained socinfo format version is greater than the
   maximum known version return an error rather than falling
   back to maximum known version
 
v4 --> v5:
 - Removed redundant function socinfo_print

v3 --> v4:
 - Corrected makefile so that smem and socinfo are treated as one module
 - Moved the code snippet to get socinfo smem item into socinfo.c
 - Removed redundant use of socinfo major version as it is always zero
 - Removed unused enums
 - Removed redundant indirections
 - Use image_version object to store information about each entry in the
   smem image table
 - Replaced usage of snprintf with sprintf and scnprintf
 - Get the address of image version table at the beginning and setup
   image version attributes only if image version table is available
 - Do the same for platform_subtype
 - Make different type of image version objects read only or readable/
   writable depending on their types. For example apps image attributes
   can be modified via sysfs but the same can't be done for modem image
 - Show PMIC model in a human readable form rather than a numeric number
 - Avoid using table in single sysfs entry
 - Removed checkpatch warnings about S_IRUGO

v2 --> v3:
 - Add support to toss soc information data into entropy pool
 - Since socinfo is rolled into smem driver, compile the
   relevant portion of socinfo driver with smem driver
 
v1 --> v2:
 - Removed inclusion of system_misc.h
 - merged socinfo.h into socinfo.c
 - made platform type and subtype arrays static
 - replaced uint32_t with u32
 - made functions static to avoid exposing vendor specific interface
 - Replaced usage of IS_ERR_OR_NULL with IS_ERR.
 - Remove raw-id attribute usage as human readable soc-id will suffice here
 - Avoid using a separate platform driver for socinfo by rolling it into smem driver itself.
   The sysfs setup is being done in a separate file (socinfo.c)
 - Replaced macro BUILD_ID_LENGTH with  SMEM_SOCINFO_BUILD_ID_LENGTH.
 - For failure cases where socinfo can not be read use a single dummy socinfo with error values.
 - Removed usage of early_machine_is_xxx.


 drivers/soc/qcom/Kconfig   |   1 +
 drivers/soc/qcom/Makefile  |   3 +-
 drivers/soc/qcom/smem.c    |   5 +
 drivers/soc/qcom/socinfo.c | 515 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 523 insertions(+), 1 deletion(-)
 create mode 100644 drivers/soc/qcom/socinfo.c

diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig
index 461b387..f89d34d 100644
--- a/drivers/soc/qcom/Kconfig
+++ b/drivers/soc/qcom/Kconfig
@@ -24,6 +24,7 @@ config QCOM_SMEM
 	tristate "Qualcomm Shared Memory Manager (SMEM)"
 	depends on ARCH_QCOM
 	depends on HWSPINLOCK
+	select SOC_BUS
 	help
 	  Say y here to enable support for the Qualcomm Shared Memory Manager.
 	  The driver provides an interface to items in a heap shared among all
diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile
index fdd664e..438efec 100644
--- a/drivers/soc/qcom/Makefile
+++ b/drivers/soc/qcom/Makefile
@@ -2,7 +2,8 @@ obj-$(CONFIG_QCOM_GSBI)	+=	qcom_gsbi.o
 obj-$(CONFIG_QCOM_PM)	+=	spm.o
 obj-$(CONFIG_QCOM_SMD) +=	smd.o
 obj-$(CONFIG_QCOM_SMD_RPM)	+= smd-rpm.o
-obj-$(CONFIG_QCOM_SMEM) +=	smem.o
+obj-$(CONFIG_QCOM_SMEM) +=	qcom_smem.o
+qcom_smem-y := smem.o socinfo.o
 obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
 obj-$(CONFIG_QCOM_SMP2P)	+= smp2p.o
 obj-$(CONFIG_QCOM_SMSM)	+= smsm.o
diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c
index 18ec52f..4f0ccf8 100644
--- a/drivers/soc/qcom/smem.c
+++ b/drivers/soc/qcom/smem.c
@@ -85,6 +85,9 @@
 /* Max number of processors/hosts in a system */
 #define SMEM_HOST_COUNT		9
 
+
+extern void qcom_socinfo_init(struct device *device);
+
 /**
   * struct smem_proc_comm - proc_comm communication struct (legacy)
   * @command:	current command to be executed
@@ -751,6 +754,8 @@ static int qcom_smem_probe(struct platform_device *pdev)
 
 	__smem = smem;
 
+	qcom_socinfo_init(&pdev->dev);
+
 	return 0;
 }
 
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
new file mode 100644
index 0000000..8eb3252
--- /dev/null
+++ b/drivers/soc/qcom/socinfo.c
@@ -0,0 +1,515 @@
+/*
+ * Copyright (c) 2009-2016, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/export.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/platform_device.h>
+#include <linux/sys_soc.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/random.h>
+#include <linux/soc/qcom/smem.h>
+
+/*
+ * SOC version type with major number in the upper 16 bits and minor
+ * number in the lower 16 bits.  For example:
+ *   1.0 -> 0x00010000
+ *   2.3 -> 0x00020003
+ */
+#define SOC_VER_MAJ(ver) (((ver) & 0xffff0000) >> 16)
+#define SOC_VER_MIN(ver) ((ver) & 0x0000ffff)
+#define SOCINFO_VERSION_MAJOR	SOC_VER_MAJ
+#define SOCINFO_VERSION_MINOR	SOC_VER_MIN
+
+#define SMEM_SOCINFO_BUILD_ID_LENGTH		32
+#define SMEM_IMAGE_VERSION_BLOCKS_COUNT		32
+#define SMEM_IMAGE_VERSION_SIZE			4096
+#define SMEM_IMAGE_VERSION_NAME_SIZE		75
+#define SMEM_IMAGE_VERSION_VARIANT_SIZE		20
+#define SMEM_IMAGE_VERSION_OEM_SIZE		32
+
+/*
+ * SMEM item ids, used to acquire handles to respective
+ * SMEM region.
+ */
+#define SMEM_IMAGE_VERSION_TABLE	469
+#define SMEM_HW_SW_BUILD_ID		137
+
+/*
+ * SMEM Image table indices
+ */
+#define SMEM_IMAGE_TABLE_BOOT_INDEX	0
+#define SMEM_IMAGE_TABLE_TZ_INDEX	1
+#define SMEM_IMAGE_TABLE_RPM_INDEX	3
+#define SMEM_IMAGE_TABLE_APPS_INDEX	10
+#define SMEM_IMAGE_TABLE_MPSS_INDEX	11
+#define SMEM_IMAGE_TABLE_ADSP_INDEX	12
+#define SMEM_IMAGE_TABLE_CNSS_INDEX	13
+#define SMEM_IMAGE_TABLE_VIDEO_INDEX	14
+
+static const char *odm_name;
+
+struct qcom_socinfo_attr {
+	struct device_attribute attr;
+	int min_ver;
+};
+
+#define QCOM_SOCINFO_ATTR(_name, _show, _min_ver) \
+	{ __ATTR(_name, 0444, _show, NULL), _min_ver }
+
+
+struct smem_image_attribute {
+	struct device_attribute version;
+	struct device_attribute variant;
+	struct device_attribute crm;
+	int index;
+};
+
+#define QCOM_SMEM_IMG_ITEM(_name, _mode, _index) \
+	static struct smem_image_attribute _name##_image_attrs = { \
+		__ATTR(_name##_image_version, _mode, \
+			qcom_show_image_version, qcom_store_image_version), \
+		__ATTR(_name##_image_variant, _mode, \
+			qcom_show_image_variant, qcom_store_image_variant), \
+		__ATTR(_name##_image_crm, _mode, \
+			qcom_show_image_crm, qcom_store_image_crm), \
+		_index \
+	}; \
+	static struct attribute_group _name##_image_attr_group = { \
+		.attrs = (struct attribute*[]) { \
+			&_name##_image_attrs.version.attr, \
+			&_name##_image_attrs.variant.attr, \
+			&_name##_image_attrs.crm.attr, \
+			NULL \
+		} \
+	}
+
+static const char *const pmic_model[] = {
+	[0]  = "Unknown PMIC model",
+	[13] = "PM8058",
+	[14] = "PM8028",
+	[15] = "PM8901",
+	[16] = "PM8027",
+	[17] = "ISL9519",
+	[18] = "PM8921",
+	[19] = "PM8018",
+	[20] = "PM8015",
+	[21] = "PM8014",
+	[22] = "PM8821",
+	[23] = "PM8038",
+	[24] = "PM8922",
+	[25] = "PM8917",
+};
+
+struct smem_image_version {
+	char name[SMEM_IMAGE_VERSION_NAME_SIZE];
+	char variant[SMEM_IMAGE_VERSION_VARIANT_SIZE];
+	char pad;
+	char oem[SMEM_IMAGE_VERSION_OEM_SIZE];
+};
+
+/* Used to parse shared memory. Must match the modem. */
+struct socinfo_v0_1 {
+	__le32 fmt;
+	__le32 id;
+	__le32 ver;
+	char build_id[SMEM_SOCINFO_BUILD_ID_LENGTH];
+};
+
+struct socinfo_v0_2 {
+	struct socinfo_v0_1 v0_1;
+	__le32 raw_ver;
+};
+
+struct socinfo_v0_3 {
+	struct socinfo_v0_2 v0_2;
+	__le32 hw_plat;
+};
+
+struct socinfo_v0_4 {
+	struct socinfo_v0_3 v0_3;
+	__le32 plat_ver;
+};
+
+struct socinfo_v0_5 {
+	struct socinfo_v0_4 v0_4;
+	__le32 accsry_chip;
+};
+
+struct socinfo_v0_6 {
+	struct socinfo_v0_5 v0_5;
+	__le32 hw_plat_subtype;
+};
+
+struct socinfo_v0_7 {
+	struct socinfo_v0_6 v0_6;
+	__le32 pmic_model;
+	__le32 pmic_die_rev;
+};
+
+struct socinfo_v0_8 {
+	struct socinfo_v0_7 v0_7;
+	__le32 pmic_model_1;
+	__le32 pmic_die_rev_1;
+	__le32 pmic_model_2;
+	__le32 pmic_die_rev_2;
+};
+
+struct socinfo_v0_9 {
+	struct socinfo_v0_8 v0_8;
+	__le32 fndry_id;
+};
+
+struct socinfo_v0_10 {
+	struct socinfo_v0_9 v0_9;
+	__le32 srl_num;
+};
+
+struct socinfo_v0_11 {
+	struct socinfo_v0_10 v0_10;
+	__le32 num_pmics;
+	__le32 pmic_array_offset;
+};
+
+struct socinfo_v0_12 {
+	struct socinfo_v0_11 v0_11;
+	__le32 chip_family;
+	__le32 raw_dev_fam;
+	__le32 raw_dev_num;
+};
+
+static union {
+	struct socinfo_v0_1 v0_1;
+	struct socinfo_v0_2 v0_2;
+	struct socinfo_v0_3 v0_3;
+	struct socinfo_v0_4 v0_4;
+	struct socinfo_v0_5 v0_5;
+	struct socinfo_v0_6 v0_6;
+	struct socinfo_v0_7 v0_7;
+	struct socinfo_v0_8 v0_8;
+	struct socinfo_v0_9 v0_9;
+	struct socinfo_v0_10 v0_10;
+	struct socinfo_v0_11 v0_11;
+	struct socinfo_v0_12 v0_12;
+} *socinfo;
+
+static struct smem_image_version *smem_image_version;
+
+/* max socinfo format version supported */
+#define MAX_SOCINFO_FORMAT 12
+
+/* socinfo: sysfs functions */
+
+static ssize_t
+qcom_odm_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return scnprintf(buf, PAGE_SIZE, "%s\n", odm_name);
+}
+DEVICE_ATTR_RO(qcom_odm);
+
+static ssize_t
+qcom_show_vendor(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%s", "Qualcomm\n");
+}
+
+static ssize_t
+qcom_show_raw_version(struct device *dev, struct device_attribute *attr,
+		     char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_2.raw_ver));
+}
+
+static ssize_t
+qcom_show_build_id(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return scnprintf(buf, PAGE_SIZE, "%s\n", socinfo->v0_1.build_id);
+}
+
+static ssize_t
+qcom_show_hw_platform(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_3.hw_plat));
+}
+
+static ssize_t
+qcom_show_platform_version(struct device *dev, struct device_attribute *attr,
+				char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_4.plat_ver));
+}
+
+static ssize_t
+qcom_show_accessory_chip(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_5.accsry_chip));
+}
+
+static ssize_t
+qcom_show_platform_subtype(struct device *dev, struct device_attribute *attr,
+				char *buf)
+{
+	u32 subtype = le32_to_cpu(socinfo->v0_6.hw_plat_subtype);
+
+	if (subtype < 0)
+		return -EINVAL;
+
+	return sprintf(buf, "%u\n", subtype);
+}
+
+static ssize_t
+qcom_show_foundry_id(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_9.fndry_id));
+}
+
+static ssize_t
+qcom_show_serial_number(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_10.srl_num));
+}
+
+static ssize_t
+qcom_show_chip_family(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	return sprintf(buf, "0x%x\n", le32_to_cpu(socinfo->v0_12.chip_family));
+}
+
+static ssize_t
+qcom_show_raw_device_family(struct device *dev, struct device_attribute *attr,
+				char *buf)
+{
+	return sprintf(buf, "0x%x\n", le32_to_cpu(socinfo->v0_12.raw_dev_fam));
+}
+
+static ssize_t
+qcom_show_raw_device_number(struct device *dev, struct device_attribute *attr,
+				char *buf)
+{
+	return sprintf(buf, "0x%x\n", le32_to_cpu(socinfo->v0_12.raw_dev_num));
+}
+
+static ssize_t
+qcom_show_pmic_model(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	return sprintf(buf, "%s\n",
+			pmic_model[le32_to_cpu(socinfo->v0_7.pmic_model)]);
+}
+
+static ssize_t
+qcom_show_pmic_die_revision(struct device *dev, struct device_attribute *attr,
+				char *buf)
+{
+	return sprintf(buf, "%u\n", le32_to_cpu(socinfo->v0_7.pmic_die_rev));
+}
+
+static ssize_t
+qcom_show_image_version(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	struct smem_image_attribute *smem_attr;
+
+	smem_attr = container_of(attr, struct smem_image_attribute, version);
+	return scnprintf(buf, PAGE_SIZE, "%s\n",
+			smem_image_version[smem_attr->index].name);
+}
+
+static ssize_t
+qcom_store_image_version(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t size)
+{
+	struct smem_image_attribute *smem_attr;
+
+	smem_attr = container_of(attr, struct smem_image_attribute, version);
+	return strlcpy(smem_image_version[smem_attr->index].name, buf,
+			SMEM_IMAGE_VERSION_NAME_SIZE);
+}
+
+static ssize_t
+qcom_show_image_variant(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	struct smem_image_attribute *smem_attr;
+
+	smem_attr = container_of(attr, struct smem_image_attribute, variant);
+	return scnprintf(buf, PAGE_SIZE, "%s\n",
+			smem_image_version[smem_attr->index].variant);
+}
+
+static ssize_t
+qcom_store_image_variant(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t size)
+{
+	struct smem_image_attribute *smem_attr;
+
+	smem_attr = container_of(attr, struct smem_image_attribute, variant);
+	return strlcpy(smem_image_version[smem_attr->index].variant, buf,
+			SMEM_IMAGE_VERSION_VARIANT_SIZE);
+}
+
+static ssize_t
+qcom_show_image_crm(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	struct smem_image_attribute *smem_attr;
+
+	smem_attr = container_of(attr, struct smem_image_attribute, crm);
+	return scnprintf(buf, PAGE_SIZE, "%s\n",
+			smem_image_version[smem_attr->index].oem);
+}
+
+static ssize_t
+qcom_store_image_crm(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t size)
+{
+	struct smem_image_attribute *smem_attr;
+
+	smem_attr = container_of(attr, struct smem_image_attribute, crm);
+	return strlcpy(smem_image_version[smem_attr->index].oem, buf,
+			SMEM_IMAGE_VERSION_OEM_SIZE);
+}
+
+static const struct qcom_socinfo_attr socinfo_attrs[] = {
+	QCOM_SOCINFO_ATTR(chip_family, qcom_show_chip_family, 12),
+	QCOM_SOCINFO_ATTR(raw_device_family, qcom_show_raw_device_family, 12),
+	QCOM_SOCINFO_ATTR(raw_device_number, qcom_show_raw_device_number, 12),
+	QCOM_SOCINFO_ATTR(serial_number, qcom_show_serial_number, 10),
+	QCOM_SOCINFO_ATTR(foundry_id, qcom_show_foundry_id, 9),
+	QCOM_SOCINFO_ATTR(pmic_model, qcom_show_pmic_model, 7),
+	QCOM_SOCINFO_ATTR(pmic_die_revision, qcom_show_pmic_die_revision, 7),
+	QCOM_SOCINFO_ATTR(platform_subtype, qcom_show_platform_subtype, 6),
+	QCOM_SOCINFO_ATTR(accessory_chip, qcom_show_accessory_chip, 5),
+	QCOM_SOCINFO_ATTR(platform_version, qcom_show_platform_version, 4),
+	QCOM_SOCINFO_ATTR(hw_platform, qcom_show_hw_platform, 3),
+	QCOM_SOCINFO_ATTR(raw_version, qcom_show_raw_version, 2),
+	QCOM_SOCINFO_ATTR(build_id, qcom_show_build_id, 1),
+	QCOM_SOCINFO_ATTR(vendor, qcom_show_vendor, 0),
+};
+
+QCOM_SMEM_IMG_ITEM(boot, 0444, SMEM_IMAGE_TABLE_BOOT_INDEX);
+QCOM_SMEM_IMG_ITEM(tz, 0444, SMEM_IMAGE_TABLE_TZ_INDEX);
+QCOM_SMEM_IMG_ITEM(rpm, 0444, SMEM_IMAGE_TABLE_RPM_INDEX);
+QCOM_SMEM_IMG_ITEM(apps, 0644, SMEM_IMAGE_TABLE_APPS_INDEX);
+QCOM_SMEM_IMG_ITEM(mpss, 0444, SMEM_IMAGE_TABLE_MPSS_INDEX);
+QCOM_SMEM_IMG_ITEM(adsp, 0444, SMEM_IMAGE_TABLE_ADSP_INDEX);
+QCOM_SMEM_IMG_ITEM(cnss, 0444, SMEM_IMAGE_TABLE_CNSS_INDEX);
+QCOM_SMEM_IMG_ITEM(video, 0444, SMEM_IMAGE_TABLE_VIDEO_INDEX);
+
+static const struct attribute_group
+	*smem_img_tbl[SMEM_IMAGE_VERSION_BLOCKS_COUNT] = {
+		[SMEM_IMAGE_TABLE_BOOT_INDEX] = &boot_image_attr_group,
+		[SMEM_IMAGE_TABLE_TZ_INDEX] = &tz_image_attr_group,
+		[SMEM_IMAGE_TABLE_RPM_INDEX] = &rpm_image_attr_group,
+		[SMEM_IMAGE_TABLE_APPS_INDEX] = &apps_image_attr_group,
+		[SMEM_IMAGE_TABLE_MPSS_INDEX] = &mpss_image_attr_group,
+		[SMEM_IMAGE_TABLE_ADSP_INDEX] = &adsp_image_attr_group,
+		[SMEM_IMAGE_TABLE_CNSS_INDEX] = &cnss_image_attr_group,
+		[SMEM_IMAGE_TABLE_VIDEO_INDEX] = &video_image_attr_group,
+};
+
+void qcom_socinfo_init(struct device *device)
+{
+	struct soc_device_attribute *attr;
+	struct soc_device *soc_dev;
+	const char *machine;
+	struct device *dev;
+	size_t item_size;
+	size_t size;
+	int i;
+
+	socinfo = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_HW_SW_BUILD_ID,
+			&item_size);
+	if (IS_ERR(socinfo)) {
+		dev_err(device, "Coudn't find socinfo\n");
+		return;
+	}
+
+	if ((SOCINFO_VERSION_MAJOR(le32_to_cpu(socinfo->v0_1.fmt)) != 0) ||
+	(SOCINFO_VERSION_MINOR(le32_to_cpu(socinfo->v0_1.fmt)) < 0) ||
+	(le32_to_cpu(socinfo->v0_1.fmt) > MAX_SOCINFO_FORMAT)) {
+		dev_err(device, "Wrong socinfo format\n");
+		return;
+	}
+
+	if (!le32_to_cpu(socinfo->v0_1.id))
+		dev_err(device, "socinfo: Unknown SoC ID!\n");
+
+	smem_image_version = qcom_smem_get(QCOM_SMEM_HOST_ANY,
+				SMEM_IMAGE_VERSION_TABLE,
+				&size);
+	if (IS_ERR(smem_image_version) || (size != SMEM_IMAGE_VERSION_SIZE)) {
+		dev_dbg(device, "Image version table absent\n");
+		smem_image_version = NULL;
+	}
+
+	attr = kzalloc(sizeof(*attr), GFP_KERNEL);
+	if (!attr)
+		return;
+
+	attr->soc_id = kasprintf(GFP_KERNEL, "%d",
+				le32_to_cpu(socinfo->v0_1.id));
+	attr->family = "Snapdragon";
+	machine = of_flat_dt_get_machine_name();
+	if (machine)
+		attr->machine = kasprintf(GFP_KERNEL, "%s", machine);
+
+	attr->revision = kasprintf(GFP_KERNEL, "%u.%u",
+				SOC_VER_MAJ(le32_to_cpu(socinfo->v0_1.ver)),
+				SOC_VER_MIN(le32_to_cpu(socinfo->v0_1.ver)));
+
+	soc_dev = soc_device_register(attr);
+	if (IS_ERR(soc_dev)) {
+		kfree(attr);
+		return;
+	}
+
+	dev = soc_device_to_device(soc_dev);
+
+	/*
+	 * Expose SMEM_IMAGE_TABLE to sysfs only when we have IMAGE_TABLE
+	 * available in SMEM. As IMAGE_TABLE and SOCINFO are two separate
+	 * items within SMEM, we expose the remaining soc information(i.e
+	 * only the SOCINFO item available in SMEM) to sysfs even in the
+	 * absence of an IMAGE_TABLE.
+	 */
+	if (smem_image_version) {
+		for (i = 0; i < SMEM_IMAGE_VERSION_BLOCKS_COUNT; i++) {
+			if (smem_img_tbl[i])
+				WARN_ON(sysfs_create_group(&dev->kobj,
+					smem_img_tbl[i]));
+		}
+	}
+
+	for (i = 0; i < ARRAY_SIZE(socinfo_attrs); i++) {
+		if (socinfo_attrs[i].min_ver <=	le32_to_cpu(socinfo->v0_1.fmt))
+			device_create_file(dev, &socinfo_attrs[i].attr);
+	}
+
+	odm_name = of_get_property(device->of_node, "qcom,odm", NULL);
+	if (odm_name)
+		device_create_file(dev, &dev_attr_qcom_odm);
+
+	/* Feed the soc specific unique data into entropy pool */
+	add_device_randomness(socinfo, item_size);
+}
+EXPORT_SYMBOL(qcom_socinfo_init);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply related

* [PATCH] memory: tegra: Add a missing 'of_node_put()' call
From: Christophe JAILLET @ 2017-01-04  7:13 UTC (permalink / raw)
  To: swarren, thierry.reding, gnurou
  Cc: linux-tegra, linux-kernel, kernel-janitors, Christophe JAILLET

If 'of_find_device_by_node()' fails, an 'of_node_put()' call is missing in
the error handling path.
Fix it by reordering the code.

While at it, remove some empty lines in a more or less similar construction
a few lines below.

Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
---
 drivers/memory/tegra/tegra124-emc.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index 06cc781ebac1..392dc8dd481f 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -1115,11 +1115,10 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	}
 
 	mc = of_find_device_by_node(np);
+	of_node_put(np);
 	if (!mc)
 		return -ENOENT;
 
-	of_node_put(np);
-
 	emc->mc = platform_get_drvdata(mc);
 	if (!emc->mc)
 		return -EPROBE_DEFER;
@@ -1135,9 +1134,7 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	}
 
 	err = tegra_emc_load_timings_from_dt(emc, np);
-
 	of_node_put(np);
-
 	if (err)
 		return err;
 
-- 
2.9.3

^ permalink raw reply related

* Re: [PATCH v2 05/13] drm: panels: Constify device node argument to of_drm_find_panel()
From: Thierry Reding @ 2017-01-04  7:09 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: dri-devel, linux-renesas-soc, Tomi Valkeinen
In-Reply-To: <1479526093-7014-6-git-send-email-laurent.pinchart+renesas@ideasonboard.com>

[-- Attachment #1: Type: text/plain, Size: 387 bytes --]

On Sat, Nov 19, 2016 at 05:28:05AM +0200, Laurent Pinchart wrote:
> The argument is never modified by the function, make it const.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
> ---
>  drivers/gpu/drm/drm_panel.c | 2 +-
>  include/drm/drm_panel.h     | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)

Applied, thanks.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v4 2/3] drm/panel: Add support for S6E3HA2 panel driver on TM2 board
From: Chanwoo Choi @ 2017-01-04  7:18 UTC (permalink / raw)
  To: Hoegeun Kwon, robh, thierry.reding, airlied, kgene, krzk,
	inki.dae
  Cc: dri-devel, linux-kernel, devicetree, linux-samsung-soc, a.hajda,
	jh80.chung, Donghwa Lee, Hyungwon Hwang
In-Reply-To: <1483513115-3068-3-git-send-email-hoegeun.kwon@samsung.com>

Hi Hoegeun,

I tested this patch on Exynos5433-TM2 board. It is well working

Tested-by: Chanwoo Choi <cw00.choi@samsung.com>

Regards,
Chanwoo Choi

On 2017년 01월 04일 15:58, Hoegeun Kwon wrote:
> This patch add support for MIPI-DSI based S6E3HA2 AMOLED panel
> driver. This panel has 1440x2560 resolution in 5.7-inch physical
> panel in the TM2 device.
> 
> Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
> Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com>
> Signed-off-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
> ---
>  .../bindings/display/panel/samsung,s6e3ha2.txt     |  40 ++
>  drivers/gpu/drm/panel/Kconfig                      |   6 +
>  drivers/gpu/drm/panel/Makefile                     |   1 +
>  drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c      | 741 +++++++++++++++++++++
>  4 files changed, 788 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
>  create mode 100644 drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c
> 
> diff --git a/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt b/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
> new file mode 100644
> index 0000000..6879f51
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/display/panel/samsung,s6e3ha2.txt
> @@ -0,0 +1,40 @@
> +Samsung S6E3HA2 5.7" 1440x2560 AMOLED panel
> +
> +Required properties:
> +  - compatible: "samsung,s6e3ha2"
> +  - reg: the virtual channel number of a DSI peripheral
> +  - vdd3-supply: I/O voltage supply
> +  - vci-supply: voltage supply for analog circuits
> +  - reset-gpios: a GPIO spec for the reset pin (active low)
> +  - enable-gpios: a GPIO spec for the panel enable pin (active high)
> +  - te-gpios: a GPIO spec for the tearing effect synchronization signal
> +    gpio pin (active high)
> +
> +The device node can contain one 'port' child node with one child
> +'endpoint' node, according to the bindings defined in [1]. This
> +node should describe panel's video bus.
> +
> +[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
> +
> +Example:
> +
> +&dsi {
> +	...
> +
> +	panel@0 {
> +		compatible = "samsung,s6e3ha2";
> +		reg = <0>;
> +		vdd3-supply = <&ldo27_reg>;
> +		vci-supply = <&ldo28_reg>;
> +		reset-gpios = <&gpg0 0 GPIO_ACTIVE_LOW>;
> +		enable-gpios = <&gpf1 5 GPIO_ACTIVE_HIGH>;
> +		te-gpios = <&gpf1 3 GPIO_ACTIVE_HIGH>;
> +
> +		port {
> +			panel_in: endpoint {
> +				remote-endpoint = <&dsi_out>;
> +			};
> +		};
> +	};
> +};
> +
> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> index 62aba97..eea2902 100644
> --- a/drivers/gpu/drm/panel/Kconfig
> +++ b/drivers/gpu/drm/panel/Kconfig
> @@ -52,6 +52,12 @@ config DRM_PANEL_PANASONIC_VVX10F034N00
>  	  WUXGA (1920x1200) Novatek NT1397-based DSI panel as found in some
>  	  Xperia Z2 tablets
>  
> +config DRM_PANEL_SAMSUNG_S6E3HA2
> +	tristate "Samsung S6E3HA2 DSI video mode panel"
> +	depends on OF
> +	depends on  DRM_MIPI_DSI
> +	select VIDEOMODE_HELPERS
> +
>  config DRM_PANEL_SAMSUNG_S6E8AA0
>  	tristate "Samsung S6E8AA0 DSI video mode panel"
>  	depends on OF
> diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
> index a5c7ec0..1d483b0 100644
> --- a/drivers/gpu/drm/panel/Makefile
> +++ b/drivers/gpu/drm/panel/Makefile
> @@ -3,6 +3,7 @@ obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
>  obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
>  obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
>  obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o
> +obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
>  obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
>  obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
>  obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
> diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c
> new file mode 100644
> index 0000000..8c5a1c2
> --- /dev/null
> +++ b/drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c
> @@ -0,0 +1,741 @@
> +/*
> + * MIPI-DSI based s6e3ha2 AMOLED 5.7 inch panel driver.
> + *
> + * Copyright (c) 2016 Samsung Electronics Co., Ltd.
> + * Donghwa Lee <dh09.lee@samsung.com>
> + * Hyungwon Hwang <human.hwang@samsung.com>
> + * Hoegeun Kwon <hoegeun.kwon@samsung.com>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include <drm/drmP.h>
> +#include <drm/drm_mipi_dsi.h>
> +#include <drm/drm_panel.h>
> +#include <linux/backlight.h>
> +#include <linux/gpio/consumer.h>
> +#include <linux/regulator/consumer.h>
> +
> +#define S6E3HA2_MIN_BRIGHTNESS		0
> +#define S6E3HA2_MAX_BRIGHTNESS		100
> +#define S6E3HA2_DEFAULT_BRIGHTNESS	80
> +
> +#define S6E3HA2_NUM_GAMMA_STEPS		46
> +#define S6E3HA2_GAMMA_CMD_CNT		35
> +#define S6E3HA2_VINT_STATUS_MAX		10
> +
> +static const u8 gamma_tbl[S6E3HA2_NUM_GAMMA_STEPS][S6E3HA2_GAMMA_CMD_CNT] = {
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x82, 0x83,
> +	  0x85, 0x88, 0x8b, 0x8b, 0x84, 0x88, 0x82, 0x82, 0x89, 0x86, 0x8c,
> +	  0x94, 0x84, 0xb1, 0xaf, 0x8e, 0xcf, 0xad, 0xc9, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x84, 0x84,
> +	  0x85, 0x87, 0x8b, 0x8a, 0x84, 0x88, 0x82, 0x82, 0x89, 0x86, 0x8a,
> +	  0x93, 0x84, 0xb0, 0xae, 0x8e, 0xc9, 0xa8, 0xc5, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
> +	  0x85, 0x86, 0x8a, 0x8a, 0x84, 0x88, 0x81, 0x84, 0x8a, 0x88, 0x8a,
> +	  0x91, 0x84, 0xb1, 0xae, 0x8b, 0xd5, 0xb2, 0xcc, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
> +	  0x85, 0x86, 0x8a, 0x8a, 0x84, 0x87, 0x81, 0x84, 0x8a, 0x87, 0x8a,
> +	  0x91, 0x85, 0xae, 0xac, 0x8a, 0xc3, 0xa3, 0xc0, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x85, 0x85,
> +	  0x86, 0x85, 0x88, 0x89, 0x84, 0x89, 0x82, 0x84, 0x87, 0x85, 0x8b,
> +	  0x91, 0x88, 0xad, 0xab, 0x8a, 0xb7, 0x9b, 0xb6, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
> +	  0x85, 0x86, 0x89, 0x8a, 0x84, 0x89, 0x83, 0x83, 0x86, 0x84, 0x8b,
> +	  0x90, 0x84, 0xb0, 0xae, 0x8b, 0xce, 0xad, 0xc8, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
> +	  0x85, 0x87, 0x89, 0x8a, 0x83, 0x87, 0x82, 0x85, 0x88, 0x87, 0x89,
> +	  0x8f, 0x84, 0xac, 0xaa, 0x89, 0xb1, 0x98, 0xaf, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
> +	  0x85, 0x86, 0x88, 0x89, 0x84, 0x88, 0x83, 0x82, 0x85, 0x84, 0x8c,
> +	  0x91, 0x86, 0xac, 0xaa, 0x89, 0xc2, 0xa5, 0xbd, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> +	  0x85, 0x87, 0x89, 0x8a, 0x83, 0x87, 0x82, 0x85, 0x88, 0x87, 0x88,
> +	  0x8b, 0x82, 0xad, 0xaa, 0x8a, 0xc2, 0xa5, 0xbd, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x89, 0x87, 0x87, 0x83, 0x83,
> +	  0x85, 0x86, 0x87, 0x89, 0x84, 0x88, 0x83, 0x82, 0x85, 0x84, 0x8a,
> +	  0x8e, 0x84, 0xae, 0xac, 0x89, 0xda, 0xb7, 0xd0, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> +	  0x85, 0x86, 0x87, 0x89, 0x84, 0x88, 0x83, 0x80, 0x83, 0x82, 0x8b,
> +	  0x8e, 0x85, 0xac, 0xaa, 0x89, 0xc8, 0xaa, 0xc1, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> +	  0x85, 0x86, 0x87, 0x89, 0x81, 0x85, 0x81, 0x84, 0x86, 0x84, 0x8c,
> +	  0x8c, 0x84, 0xa9, 0xa8, 0x87, 0xa3, 0x92, 0xa1, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> +	  0x85, 0x86, 0x87, 0x89, 0x84, 0x86, 0x83, 0x80, 0x83, 0x81, 0x8c,
> +	  0x8d, 0x84, 0xaa, 0xaa, 0x89, 0xce, 0xaf, 0xc5, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> +	  0x85, 0x86, 0x87, 0x89, 0x81, 0x83, 0x80, 0x83, 0x85, 0x85, 0x8c,
> +	  0x8c, 0x84, 0xa8, 0xa8, 0x88, 0xb5, 0x9f, 0xb0, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> +	  0x86, 0x86, 0x87, 0x88, 0x81, 0x83, 0x80, 0x83, 0x85, 0x85, 0x8c,
> +	  0x8b, 0x84, 0xab, 0xa8, 0x86, 0xd4, 0xb4, 0xc9, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> +	  0x86, 0x86, 0x87, 0x88, 0x81, 0x83, 0x80, 0x84, 0x84, 0x85, 0x8b,
> +	  0x8a, 0x83, 0xa6, 0xa5, 0x84, 0xbb, 0xa4, 0xb3, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x84, 0x84,
> +	  0x86, 0x85, 0x86, 0x86, 0x82, 0x85, 0x81, 0x82, 0x83, 0x84, 0x8e,
> +	  0x8b, 0x83, 0xa4, 0xa3, 0x8a, 0xa1, 0x93, 0x9d, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
> +	  0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x82, 0x82, 0x84, 0x8e,
> +	  0x8b, 0x83, 0xa4, 0xa2, 0x86, 0xc1, 0xa9, 0xb7, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
> +	  0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x82, 0x82, 0x84, 0x8d,
> +	  0x89, 0x82, 0xa2, 0xa1, 0x84, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xb1, 0x88, 0x86, 0x87, 0x83, 0x83,
> +	  0x85, 0x86, 0x87, 0x87, 0x82, 0x85, 0x81, 0x83, 0x83, 0x85, 0x8c,
> +	  0x87, 0x7f, 0xa2, 0x9d, 0x88, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xbb, 0x00, 0xc5, 0x00, 0xb4, 0x87, 0x86, 0x86, 0x84, 0x83,
> +	  0x86, 0x87, 0x87, 0x87, 0x80, 0x82, 0x7f, 0x86, 0x86, 0x88, 0x8a,
> +	  0x84, 0x7e, 0x9d, 0x9c, 0x82, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xbd, 0x00, 0xc7, 0x00, 0xb7, 0x87, 0x85, 0x85, 0x84, 0x83,
> +	  0x86, 0x86, 0x86, 0x88, 0x81, 0x83, 0x80, 0x83, 0x84, 0x85, 0x8a,
> +	  0x85, 0x7e, 0x9c, 0x9b, 0x85, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xc0, 0x00, 0xca, 0x00, 0xbb, 0x87, 0x86, 0x85, 0x83, 0x83,
> +	  0x85, 0x86, 0x86, 0x88, 0x81, 0x83, 0x80, 0x84, 0x85, 0x86, 0x89,
> +	  0x83, 0x7d, 0x9c, 0x99, 0x87, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xc4, 0x00, 0xcd, 0x00, 0xbe, 0x87, 0x86, 0x85, 0x83, 0x83,
> +	  0x86, 0x85, 0x85, 0x87, 0x81, 0x82, 0x80, 0x82, 0x82, 0x83, 0x8a,
> +	  0x85, 0x7f, 0x9f, 0x9b, 0x86, 0xb4, 0xa1, 0xac, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xc7, 0x00, 0xd0, 0x00, 0xc2, 0x87, 0x85, 0x85, 0x83, 0x82,
> +	  0x85, 0x85, 0x85, 0x86, 0x82, 0x83, 0x80, 0x82, 0x82, 0x84, 0x87,
> +	  0x86, 0x80, 0x9e, 0x9a, 0x87, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xca, 0x00, 0xd2, 0x00, 0xc5, 0x87, 0x85, 0x84, 0x82, 0x82,
> +	  0x84, 0x85, 0x85, 0x86, 0x81, 0x82, 0x7f, 0x82, 0x82, 0x84, 0x88,
> +	  0x86, 0x81, 0x9d, 0x98, 0x86, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xce, 0x00, 0xd6, 0x00, 0xca, 0x86, 0x85, 0x84, 0x83, 0x83,
> +	  0x85, 0x84, 0x84, 0x85, 0x81, 0x82, 0x80, 0x81, 0x81, 0x82, 0x89,
> +	  0x86, 0x81, 0x9c, 0x97, 0x86, 0xa7, 0x98, 0xa1, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xd1, 0x00, 0xd9, 0x00, 0xce, 0x86, 0x84, 0x83, 0x83, 0x82,
> +	  0x85, 0x85, 0x85, 0x86, 0x81, 0x83, 0x81, 0x82, 0x82, 0x83, 0x86,
> +	  0x83, 0x7f, 0x99, 0x95, 0x86, 0xbb, 0xa4, 0xb3, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xd4, 0x00, 0xdb, 0x00, 0xd1, 0x86, 0x85, 0x83, 0x83, 0x82,
> +	  0x85, 0x84, 0x84, 0x85, 0x80, 0x83, 0x82, 0x80, 0x80, 0x81, 0x87,
> +	  0x84, 0x81, 0x98, 0x93, 0x85, 0xae, 0x9c, 0xa8, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xd8, 0x00, 0xde, 0x00, 0xd6, 0x86, 0x84, 0x83, 0x81, 0x81,
> +	  0x83, 0x85, 0x85, 0x85, 0x82, 0x83, 0x81, 0x81, 0x81, 0x83, 0x86,
> +	  0x84, 0x80, 0x98, 0x91, 0x85, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xdc, 0x00, 0xe2, 0x00, 0xda, 0x85, 0x84, 0x83, 0x82, 0x82,
> +	  0x84, 0x84, 0x84, 0x85, 0x81, 0x82, 0x82, 0x80, 0x80, 0x81, 0x83,
> +	  0x82, 0x7f, 0x99, 0x93, 0x86, 0x94, 0x8b, 0x92, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xdf, 0x00, 0xe5, 0x00, 0xde, 0x85, 0x84, 0x82, 0x82, 0x82,
> +	  0x84, 0x83, 0x83, 0x84, 0x81, 0x81, 0x80, 0x83, 0x82, 0x84, 0x82,
> +	  0x81, 0x7f, 0x99, 0x92, 0x86, 0x7b, 0x7b, 0x7c, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
> +	  0x82, 0x83, 0x83, 0x84, 0x80, 0x81, 0x80, 0x83, 0x83, 0x84, 0x80,
> +	  0x81, 0x7c, 0x99, 0x92, 0x87, 0xa1, 0x93, 0x9d, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x85, 0x84, 0x83, 0x81, 0x81,
> +	  0x82, 0x82, 0x82, 0x83, 0x80, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83,
> +	  0x82, 0x80, 0x91, 0x8d, 0x83, 0x9a, 0x90, 0x96, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
> +	  0x82, 0x83, 0x83, 0x84, 0x80, 0x81, 0x80, 0x81, 0x80, 0x82, 0x83,
> +	  0x81, 0x7f, 0x91, 0x8c, 0x82, 0x8d, 0x88, 0x8b, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
> +	  0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x82, 0x82,
> +	  0x82, 0x7f, 0x94, 0x89, 0x84, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
> +	  0x82, 0x83, 0x83, 0x83, 0x82, 0x82, 0x81, 0x81, 0x80, 0x82, 0x83,
> +	  0x82, 0x7f, 0x91, 0x85, 0x81, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x81, 0x81,
> +	  0x82, 0x83, 0x83, 0x83, 0x80, 0x80, 0x7f, 0x83, 0x82, 0x84, 0x83,
> +	  0x82, 0x7f, 0x90, 0x84, 0x81, 0x9a, 0x90, 0x96, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xe4, 0x00, 0xe9, 0x00, 0xe3, 0x84, 0x83, 0x82, 0x80, 0x80,
> +	  0x82, 0x83, 0x83, 0x83, 0x80, 0x80, 0x7f, 0x80, 0x80, 0x81, 0x81,
> +	  0x82, 0x83, 0x7e, 0x80, 0x7c, 0xa4, 0x97, 0x9f, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xe9, 0x00, 0xec, 0x00, 0xe8, 0x84, 0x83, 0x82, 0x81, 0x81,
> +	  0x82, 0x82, 0x82, 0x83, 0x7f, 0x7f, 0x7f, 0x81, 0x80, 0x82, 0x83,
> +	  0x83, 0x84, 0x79, 0x7c, 0x79, 0xb1, 0xa0, 0xaa, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xed, 0x00, 0xf0, 0x00, 0xec, 0x83, 0x83, 0x82, 0x80, 0x80,
> +	  0x81, 0x82, 0x82, 0x82, 0x7f, 0x7f, 0x7e, 0x81, 0x81, 0x82, 0x80,
> +	  0x81, 0x81, 0x84, 0x84, 0x83, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xf1, 0x00, 0xf4, 0x00, 0xf1, 0x83, 0x82, 0x82, 0x80, 0x80,
> +	  0x81, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, 0x7d,
> +	  0x7e, 0x7f, 0x84, 0x84, 0x83, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xf6, 0x00, 0xf7, 0x00, 0xf5, 0x82, 0x82, 0x81, 0x80, 0x80,
> +	  0x80, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x7f, 0x7f, 0x7f, 0x82,
> +	  0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x00, 0xfa, 0x00, 0xfb, 0x00, 0xfa, 0x81, 0x81, 0x81, 0x80, 0x80,
> +	  0x80, 0x82, 0x82, 0x82, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
> +	  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80,
> +	  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
> +	  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 },
> +	{ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80,
> +	  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
> +	  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
> +	  0x00, 0x00 }
> +};
> +
> +unsigned char vint_table[S6E3HA2_VINT_STATUS_MAX] = {
> +	0x18, 0x19, 0x1a, 0x1b, 0x1c,
> +	0x1d, 0x1e, 0x1f, 0x20, 0x21
> +};
> +
> +struct s6e3ha2 {
> +	struct device *dev;
> +	struct drm_panel panel;
> +	struct backlight_device *bl_dev;
> +
> +	struct regulator_bulk_data supplies[2];
> +	struct gpio_desc *reset_gpio;
> +	struct gpio_desc *enable_gpio;
> +
> +	/* This field is tested by functions directly accessing DSI bus before
> +	 * transfer, transfer is skipped if it is set. In case of transfer
> +	 * failure or unexpected response the field is set to error value.
> +	 * Such construct allows to eliminate many checks in higher level
> +	 * functions.
> +	 */
> +	int error;
> +};
> +
> +static int  s6e3ha2_clear_error(struct s6e3ha2 *ctx)
> +{
> +	int ret = ctx->error;
> +
> +	ctx->error = 0;
> +	return ret;
> +}
> +
> +static void s6e3ha2_dcs_write(struct s6e3ha2 *ctx, const void *data, size_t len)
> +{
> +	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
> +	ssize_t ret;
> +
> +	if (ctx->error < 0)
> +		return;
> +
> +	ret = mipi_dsi_dcs_write_buffer(dsi, data, len);
> +	if (ret < 0) {
> +		dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n",
> +						ret, (int)len, data);
> +		ctx->error = ret;
> +	}
> +}
> +
> +#define s6e3ha2_dcs_write_seq_static(ctx, seq...) do {	\
> +	static const u8 d[] = { seq };			\
> +	s6e3ha2_dcs_write(ctx, d, ARRAY_SIZE(d));	\
> +} while (0)
> +
> +static void s6e3ha2_test_key_on_f0(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xf0, 0x5a, 0x5a);
> +}
> +
> +static void s6e3ha2_test_key_off_f0(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xf0, 0xa5, 0xa5);
> +}
> +
> +static void s6e3ha2_test_key_on_fc(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xfc, 0x5a, 0x5a);
> +}
> +
> +static void s6e3ha2_test_key_off_fc(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xfc, 0xa5, 0xa5);
> +}
> +
> +static void s6e3ha2_single_dsi_set(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xf2, 0x67);
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xf9, 0x09);
> +}
> +
> +static void s6e3ha2_freq_calibration(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xfd, 0x1c);
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x20, 0x39);
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0xa0);
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x20);
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xce, 0x03, 0x3b, 0x12, 0x62,
> +		0x40, 0x80, 0xc0, 0x28, 0x28, 0x28, 0x28, 0x39, 0xc5);
> +}
> +
> +static void s6e3ha2_aor_control(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xb2, 0x03, 0x10);
> +}
> +
> +static void s6e3ha2_caps_elvss_set(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xb6, 0x9c, 0x0a);
> +}
> +
> +static void s6e3ha2_acl_off(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0x55, 0x00);
> +}
> +
> +static void s6e3ha2_acl_off_opr(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xb5, 0x40);
> +}
> +
> +static void s6e3ha2_test_global(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xb0, 0x07);
> +}
> +
> +static void s6e3ha2_test(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xb8, 0x19);
> +}
> +
> +static void s6e3ha2_touch_hsync_on1(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx,
> +			0xbd, 0x33, 0x11, 0x02, 0x16, 0x02, 0x16);
> +}
> +
> +static void s6e3ha2_pentile_control(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xc0, 0x00, 0x00, 0xd8, 0xd8);
> +}
> +
> +static void s6e3ha2_poc_global(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xb0, 0x20);
> +}
> +
> +static void s6e3ha2_poc_setting(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xfe, 0x08);
> +}
> +
> +static void s6e3ha2_pcd_set_off(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xcc, 0x40, 0x51);
> +}
> +
> +static void s6e3ha2_err_fg_set(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xed, 0x44);
> +}
> +
> +static void s6e3ha2_hbm_off(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0x53, 0x00);
> +}
> +
> +static void s6e3ha2_te_start_setting(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xb9, 0x10, 0x09, 0xff, 0x00, 0x09);
> +}
> +
> +static void s6e3ha2_gamma_update(struct s6e3ha2 *ctx)
> +{
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xf7, 0x03);
> +	ndelay(100); /* need for 100ns delay */
> +	s6e3ha2_dcs_write_seq_static(ctx, 0xf7, 0x00);
> +}
> +
> +static int s6e3ha2_get_brightness(struct backlight_device *bl_dev)
> +{
> +	return bl_dev->props.brightness;
> +}
> +
> +static void s6e3ha2_set_vint(struct s6e3ha2 *ctx)
> +{
> +	struct backlight_device *bl_dev = ctx->bl_dev;
> +	unsigned int brightness = bl_dev->props.brightness;
> +	unsigned char data[] = { 0xf4, 0x8b,
> +			vint_table[brightness * (S6E3HA2_VINT_STATUS_MAX - 1) /
> +			S6E3HA2_MAX_BRIGHTNESS] };
> +
> +	s6e3ha2_dcs_write(ctx, data, 3);
> +}
> +
> +static unsigned int s6e3ha2_get_brightness_index(unsigned int brightness)
> +{
> +	return (brightness * (S6E3HA2_NUM_GAMMA_STEPS - 1)) /
> +		S6E3HA2_MAX_BRIGHTNESS;
> +}
> +
> +static int s6e3ha2_update_gamma(struct s6e3ha2 *ctx, unsigned int brightness)
> +{
> +	struct backlight_device *bl_dev = ctx->bl_dev;
> +	unsigned int index = s6e3ha2_get_brightness_index(brightness);
> +	u8 data[S6E3HA2_GAMMA_CMD_CNT + 1] = { 0xca, };
> +
> +	memcpy(data + 1, gamma_tbl + index, S6E3HA2_GAMMA_CMD_CNT);
> +	s6e3ha2_dcs_write(ctx, data, ARRAY_SIZE(data));
> +
> +	s6e3ha2_gamma_update(ctx);
> +	bl_dev->props.brightness = brightness;
> +
> +	return 0;
> +}
> +
> +static int s6e3ha2_set_brightness(struct backlight_device *bl_dev)
> +{
> +	struct s6e3ha2 *ctx = (struct s6e3ha2 *)bl_get_data(bl_dev);
> +	unsigned int brightness = bl_dev->props.brightness;
> +
> +	if (brightness < S6E3HA2_MIN_BRIGHTNESS ||
> +		brightness > bl_dev->props.max_brightness) {
> +		dev_err(ctx->dev, "Invalid brightness: %u\n", brightness);
> +		return -EINVAL;
> +	}
> +
> +	if (bl_dev->props.power > FB_BLANK_NORMAL)
> +		return -EPERM;
> +
> +	s6e3ha2_test_key_on_f0(ctx);
> +	s6e3ha2_update_gamma(ctx, brightness);
> +	s6e3ha2_aor_control(ctx);
> +	s6e3ha2_set_vint(ctx);
> +	s6e3ha2_test_key_off_f0(ctx);
> +
> +	return ctx->error;
> +}
> +
> +static const struct backlight_ops s6e3ha2_bl_ops = {
> +	.get_brightness = s6e3ha2_get_brightness,
> +	.update_status = s6e3ha2_set_brightness,
> +};
> +
> +static void s6e3ha2_panel_init(struct s6e3ha2 *ctx)
> +{
> +	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
> +
> +	mipi_dsi_dcs_exit_sleep_mode(dsi);
> +	usleep_range(5000, 6000);
> +
> +	s6e3ha2_test_key_on_f0(ctx);
> +	s6e3ha2_single_dsi_set(ctx);
> +	s6e3ha2_test_key_on_fc(ctx);
> +	s6e3ha2_freq_calibration(ctx);
> +	s6e3ha2_test_key_off_fc(ctx);
> +	s6e3ha2_test_key_off_f0(ctx);
> +}
> +
> +static int s6e3ha2_power_off(struct s6e3ha2 *ctx)
> +{
> +	return regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
> +}
> +
> +static int s6e3ha2_disable(struct drm_panel *panel)
> +{
> +	struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
> +	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
> +
> +	mipi_dsi_dcs_enter_sleep_mode(dsi);
> +	if (ctx->error != 0)
> +		goto err;
> +
> +	mipi_dsi_dcs_set_display_off(dsi);
> +	if (ctx->error != 0)
> +		goto err;
> +
> +	msleep(40);
> +	ctx->bl_dev->props.power = FB_BLANK_NORMAL;
> +
> +	return 0;
> +err:
> +	return ctx->error;
> +}
> +
> +static int s6e3ha2_unprepare(struct drm_panel *panel)
> +{
> +	struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
> +	int ret;
> +
> +	ret = s6e3ha2_clear_error(ctx);
> +	if (!ret)
> +		ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
> +
> +	return s6e3ha2_power_off(ctx);
> +}
> +
> +static int s6e3ha2_power_on(struct s6e3ha2 *ctx)
> +{
> +	int ret;
> +
> +	ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
> +	if (ret < 0)
> +		return ret;
> +
> +	msleep(120);
> +
> +	gpiod_set_value(ctx->enable_gpio, 0);
> +	usleep_range(5000, 6000);
> +	gpiod_set_value(ctx->enable_gpio, 1);
> +
> +	gpiod_set_value(ctx->reset_gpio, 1);
> +	usleep_range(5000, 6000);
> +	gpiod_set_value(ctx->reset_gpio, 0);
> +	usleep_range(5000, 6000);
> +
> +	return 0;
> +}
> +static int s6e3ha2_prepare(struct drm_panel *panel)
> +{
> +	struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
> +	int ret;
> +
> +	ret = s6e3ha2_power_on(ctx);
> +	if (ret < 0)
> +		return ret;
> +
> +	s6e3ha2_panel_init(ctx);
> +
> +	ret = s6e3ha2_clear_error(ctx);
> +	if (ret < 0) {
> +		s6e3ha2_power_off(ctx);
> +		return ret;
> +	}
> +
> +	ctx->bl_dev->props.power = FB_BLANK_NORMAL;
> +
> +	return 0;
> +}
> +
> +static int s6e3ha2_enable(struct drm_panel *panel)
> +{
> +	struct s6e3ha2 *ctx = container_of(panel, struct s6e3ha2, panel);
> +	struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
> +
> +	/* common setting */
> +	mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
> +
> +	s6e3ha2_test_key_on_f0(ctx);
> +	s6e3ha2_test_key_on_fc(ctx);
> +	s6e3ha2_touch_hsync_on1(ctx);
> +	s6e3ha2_pentile_control(ctx);
> +	s6e3ha2_poc_global(ctx);
> +	s6e3ha2_poc_setting(ctx);
> +	s6e3ha2_test_key_off_fc(ctx);
> +
> +	/* pcd setting off for TB */
> +	s6e3ha2_pcd_set_off(ctx);
> +	s6e3ha2_err_fg_set(ctx);
> +	s6e3ha2_te_start_setting(ctx);
> +
> +	/* brightness setting */
> +	s6e3ha2_set_brightness(ctx->bl_dev);
> +	s6e3ha2_aor_control(ctx);
> +	s6e3ha2_caps_elvss_set(ctx);
> +	s6e3ha2_gamma_update(ctx);
> +	s6e3ha2_acl_off(ctx);
> +	s6e3ha2_acl_off_opr(ctx);
> +	s6e3ha2_hbm_off(ctx);
> +
> +	/* elvss temp compensation */
> +	s6e3ha2_test_global(ctx);
> +	s6e3ha2_test(ctx);
> +	s6e3ha2_test_key_off_f0(ctx);
> +
> +	mipi_dsi_dcs_set_display_on(dsi);
> +	if (ctx->error != 0)
> +		return ctx->error;
> +
> +	ctx->bl_dev->props.power = FB_BLANK_UNBLANK;
> +
> +	return 0;
> +}
> +
> +static const struct drm_display_mode default_mode = {
> +	.clock = 14874,
> +	.hdisplay = 1440,
> +	.hsync_start = 1440 + 1,
> +	.hsync_end = 1440 + 1 + 1,
> +	.htotal = 1440 + 1 + 1 + 1,
> +	.vdisplay = 2560,
> +	.vsync_start = 2560 + 1,
> +	.vsync_end = 2560 + 1 + 1,
> +	.vtotal = 2560 + 1 + 1 + 15,
> +	.vrefresh = 60,
> +	.flags = 0,
> +};
> +
> +static int s6e3ha2_get_modes(struct drm_panel *panel)
> +{
> +	struct drm_connector *connector = panel->connector;
> +	struct drm_display_mode *mode;
> +
> +	mode = drm_mode_duplicate(panel->drm, &default_mode);
> +	if (!mode) {
> +		DRM_ERROR("failed to create a new display mode\n");
> +		DRM_ERROR("failed to add mode %ux%ux@%u\n",
> +				default_mode.hdisplay, default_mode.vdisplay,
> +				default_mode.vrefresh);
> +		return -ENOMEM;
> +	}
> +
> +	drm_mode_set_name(mode);
> +
> +	mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
> +	drm_mode_probed_add(connector, mode);
> +
> +	connector->display_info.width_mm = 71;
> +	connector->display_info.height_mm = 125;
> +
> +	return 1;
> +}
> +
> +static const struct drm_panel_funcs s6e3ha2_drm_funcs = {
> +	.disable = s6e3ha2_disable,
> +	.unprepare = s6e3ha2_unprepare,
> +	.prepare = s6e3ha2_prepare,
> +	.enable = s6e3ha2_enable,
> +	.get_modes = s6e3ha2_get_modes,
> +};
> +
> +static int s6e3ha2_probe(struct mipi_dsi_device *dsi)
> +{
> +	struct device *dev = &dsi->dev;
> +	struct s6e3ha2 *ctx;
> +	int ret;
> +
> +	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
> +	if (!ctx)
> +		return -ENOMEM;
> +
> +	mipi_dsi_set_drvdata(dsi, ctx);
> +
> +	ctx->dev = dev;
> +
> +	dsi->lanes = 4;
> +	dsi->format = MIPI_DSI_FMT_RGB888;
> +	dsi->mode_flags = MIPI_DSI_CLOCK_NON_CONTINUOUS;
> +
> +	ctx->supplies[0].supply = "vdd3";
> +	ctx->supplies[1].supply = "vci";
> +
> +	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
> +				      ctx->supplies);
> +	if (ret < 0) {
> +		dev_err(dev, "failed to get regulators: %d\n", ret);
> +		return ret;
> +	}
> +
> +	ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
> +	if (IS_ERR(ctx->reset_gpio)) {
> +		dev_err(dev, "cannot get reset-gpios %ld\n",
> +			PTR_ERR(ctx->reset_gpio));
> +		return PTR_ERR(ctx->reset_gpio);
> +	}
> +
> +	ctx->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH);
> +	if (IS_ERR(ctx->enable_gpio)) {
> +		dev_err(dev, "cannot get enable-gpios %ld\n",
> +			PTR_ERR(ctx->enable_gpio));
> +		return PTR_ERR(ctx->enable_gpio);
> +	}
> +
> +	ctx->bl_dev = backlight_device_register("s6e3ha2", dev, ctx,
> +						&s6e3ha2_bl_ops, NULL);
> +	if (IS_ERR(ctx->bl_dev)) {
> +		dev_err(dev, "failed to register backlight device\n");
> +		return PTR_ERR(ctx->bl_dev);
> +	}
> +
> +	ctx->bl_dev->props.max_brightness = S6E3HA2_MAX_BRIGHTNESS;
> +	ctx->bl_dev->props.brightness = S6E3HA2_DEFAULT_BRIGHTNESS;
> +	ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
> +
> +	drm_panel_init(&ctx->panel);
> +	ctx->panel.dev = dev;
> +	ctx->panel.funcs = &s6e3ha2_drm_funcs;
> +
> +	ret = drm_panel_add(&ctx->panel);
> +	if (ret < 0)
> +		goto unregister_backlight;
> +
> +	ret = mipi_dsi_attach(dsi);
> +	if (ret < 0)
> +		goto remove_panel;
> +
> +	return ret;
> +
> +remove_panel:
> +	drm_panel_remove(&ctx->panel);
> +
> +unregister_backlight:
> +	backlight_device_unregister(ctx->bl_dev);
> +
> +	return ret;
> +}
> +
> +static int s6e3ha2_remove(struct mipi_dsi_device *dsi)
> +{
> +	struct s6e3ha2 *ctx = mipi_dsi_get_drvdata(dsi);
> +
> +	mipi_dsi_detach(dsi);
> +	drm_panel_remove(&ctx->panel);
> +	backlight_device_unregister(ctx->bl_dev);
> +
> +	return 0;
> +}
> +
> +static const struct of_device_id s6e3ha2_of_match[] = {
> +	{ .compatible = "samsung,s6e3ha2" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, s6e3ha2_of_match);
> +
> +static struct mipi_dsi_driver s6e3ha2_driver = {
> +	.probe = s6e3ha2_probe,
> +	.remove = s6e3ha2_remove,
> +	.driver = {
> +		.name = "panel-samsung-s6e3ha2",
> +		.of_match_table = s6e3ha2_of_match,
> +	},
> +};
> +module_mipi_dsi_driver(s6e3ha2_driver);
> +
> +MODULE_AUTHOR("Donghwa Lee <dh09.lee@samsung.com>");
> +MODULE_AUTHOR("Hyungwon Hwang <human.hwang@samsung.com>");
> +MODULE_AUTHOR("Hoegeun Kwon <hoegeun.kwon@samsung.com>");
> +MODULE_DESCRIPTION("MIPI-DSI based s6e3ha2 AMOLED Panel Driver");
> +MODULE_LICENSE("GPL v2");
> 

^ permalink raw reply

* Re: [PATCH] dax: fix deadlock with DAX 4k holes
From: Jan Kara @ 2017-01-04  7:18 UTC (permalink / raw)
  To: Ross Zwisler
  Cc: Jan Kara, linux-nvdimm, Dave Chinner, linux-kernel, stable,
	Christoph Hellwig, linux-mm, Dave Hansen, Andrew Morton
In-Reply-To: <1483479365-13607-1-git-send-email-ross.zwisler@linux.intel.com>

On Tue 03-01-17 14:36:05, Ross Zwisler wrote:
> Currently in DAX if we have three read faults on the same hole address we
> can end up with the following:
> 
> Thread 0		Thread 1		Thread 2
> --------		--------		--------
> dax_iomap_fault
>  grab_mapping_entry
>   lock_slot
>    <locks empty DAX entry>
> 
>   			dax_iomap_fault
> 			 grab_mapping_entry
> 			  get_unlocked_mapping_entry
> 			   <sleeps on empty DAX entry>
> 
> 						dax_iomap_fault
> 						 grab_mapping_entry
> 						  get_unlocked_mapping_entry
> 						   <sleeps on empty DAX entry>
>   dax_load_hole
>    find_or_create_page
>    ...
>     page_cache_tree_insert
>      dax_wake_mapping_entry_waiter
>       <wakes one sleeper>
>      __radix_tree_replace
>       <swaps empty DAX entry with 4k zero page>
> 
> 			<wakes>
> 			get_page
> 			lock_page
> 			...
> 			put_locked_mapping_entry
> 			unlock_page
> 			put_page
> 
> 						<sleeps forever on the DAX
> 						 wait queue>
> 
> The crux of the problem is that once we insert a 4k zero page, all locking
> from then on is done in terms of that 4k zero page and any additional
> threads sleeping on the empty DAX entry will never be woken.  Fix this by
> waking all sleepers when we replace the DAX radix tree entry with a 4k zero
> page.  This will allow all sleeping threads to successfully transition from
> locking based on the DAX empty entry to locking on the 4k zero page.
> 
> With the test case reported by Xiong this happens very regularly in my test
> setup, with some runs resulting in 9+ threads in this deadlocked state.
> With this fix I've been able to run that same test dozens of times in a
> loop without issue.
> 
> Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
> Reported-by: Xiong Zhou <xzhou@redhat.com>
> Fixes: commit ac401cc78242 ("dax: New fault locking")
> Cc: Jan Kara <jack@suse.cz>
> Cc: stable@vger.kernel.org # 4.7+

Ah, very good catch. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

I wonder why I was not able to reproduce this... Probably the timing didn't
work out right on my test machine.

								Honza

> ---
> 
> This issue exists as far back as v4.7, and I was easly able to reproduce it
> with v4.7 using the same test.
> 
> Unfortunately this patch won't apply cleanly to the stable trees, but the
> change is very simple and should be easy to replicate by hand.  Please ping
> me if you'd like patches that apply cleanly to the v4.9 and v4.8.15 trees.
> 
> ---
>  mm/filemap.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/mm/filemap.c b/mm/filemap.c
> index d0e4d10..b772a33 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -138,7 +138,7 @@ static int page_cache_tree_insert(struct address_space *mapping,
>  				dax_radix_locked_entry(0, RADIX_DAX_EMPTY));
>  			/* Wakeup waiters for exceptional entry lock */
>  			dax_wake_mapping_entry_waiter(mapping, page->index, p,
> -						      false);
> +						      true);
>  		}
>  	}
>  	__radix_tree_replace(&mapping->page_tree, node, slot, page,
> -- 
> 2.7.4
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply

* Re: [PATCH] dax: fix deadlock with DAX 4k holes
From: Jan Kara @ 2017-01-04  7:18 UTC (permalink / raw)
  To: Ross Zwisler
  Cc: Xiong Zhou, stable, linux-kernel, Andrew Morton,
	Christoph Hellwig, Dan Williams, Dave Chinner, Dave Hansen,
	Jan Kara, linux-mm, linux-nvdimm
In-Reply-To: <1483479365-13607-1-git-send-email-ross.zwisler@linux.intel.com>

On Tue 03-01-17 14:36:05, Ross Zwisler wrote:
> Currently in DAX if we have three read faults on the same hole address we
> can end up with the following:
> 
> Thread 0		Thread 1		Thread 2
> --------		--------		--------
> dax_iomap_fault
>  grab_mapping_entry
>   lock_slot
>    <locks empty DAX entry>
> 
>   			dax_iomap_fault
> 			 grab_mapping_entry
> 			  get_unlocked_mapping_entry
> 			   <sleeps on empty DAX entry>
> 
> 						dax_iomap_fault
> 						 grab_mapping_entry
> 						  get_unlocked_mapping_entry
> 						   <sleeps on empty DAX entry>
>   dax_load_hole
>    find_or_create_page
>    ...
>     page_cache_tree_insert
>      dax_wake_mapping_entry_waiter
>       <wakes one sleeper>
>      __radix_tree_replace
>       <swaps empty DAX entry with 4k zero page>
> 
> 			<wakes>
> 			get_page
> 			lock_page
> 			...
> 			put_locked_mapping_entry
> 			unlock_page
> 			put_page
> 
> 						<sleeps forever on the DAX
> 						 wait queue>
> 
> The crux of the problem is that once we insert a 4k zero page, all locking
> from then on is done in terms of that 4k zero page and any additional
> threads sleeping on the empty DAX entry will never be woken.  Fix this by
> waking all sleepers when we replace the DAX radix tree entry with a 4k zero
> page.  This will allow all sleeping threads to successfully transition from
> locking based on the DAX empty entry to locking on the 4k zero page.
> 
> With the test case reported by Xiong this happens very regularly in my test
> setup, with some runs resulting in 9+ threads in this deadlocked state.
> With this fix I've been able to run that same test dozens of times in a
> loop without issue.
> 
> Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
> Reported-by: Xiong Zhou <xzhou@redhat.com>
> Fixes: commit ac401cc78242 ("dax: New fault locking")
> Cc: Jan Kara <jack@suse.cz>
> Cc: stable@vger.kernel.org # 4.7+

Ah, very good catch. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

I wonder why I was not able to reproduce this... Probably the timing didn't
work out right on my test machine.

								Honza

> ---
> 
> This issue exists as far back as v4.7, and I was easly able to reproduce it
> with v4.7 using the same test.
> 
> Unfortunately this patch won't apply cleanly to the stable trees, but the
> change is very simple and should be easy to replicate by hand.  Please ping
> me if you'd like patches that apply cleanly to the v4.9 and v4.8.15 trees.
> 
> ---
>  mm/filemap.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/mm/filemap.c b/mm/filemap.c
> index d0e4d10..b772a33 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -138,7 +138,7 @@ static int page_cache_tree_insert(struct address_space *mapping,
>  				dax_radix_locked_entry(0, RADIX_DAX_EMPTY));
>  			/* Wakeup waiters for exceptional entry lock */
>  			dax_wake_mapping_entry_waiter(mapping, page->index, p,
> -						      false);
> +						      true);
>  		}
>  	}
>  	__radix_tree_replace(&mapping->page_tree, node, slot, page,
> -- 
> 2.7.4
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH] dax: fix deadlock with DAX 4k holes
From: Jan Kara @ 2017-01-04  7:18 UTC (permalink / raw)
  To: Ross Zwisler
  Cc: Xiong Zhou, stable, linux-kernel, Andrew Morton,
	Christoph Hellwig, Dan Williams, Dave Chinner, Dave Hansen,
	Jan Kara, linux-mm, linux-nvdimm
In-Reply-To: <1483479365-13607-1-git-send-email-ross.zwisler@linux.intel.com>

On Tue 03-01-17 14:36:05, Ross Zwisler wrote:
> Currently in DAX if we have three read faults on the same hole address we
> can end up with the following:
> 
> Thread 0		Thread 1		Thread 2
> --------		--------		--------
> dax_iomap_fault
>  grab_mapping_entry
>   lock_slot
>    <locks empty DAX entry>
> 
>   			dax_iomap_fault
> 			 grab_mapping_entry
> 			  get_unlocked_mapping_entry
> 			   <sleeps on empty DAX entry>
> 
> 						dax_iomap_fault
> 						 grab_mapping_entry
> 						  get_unlocked_mapping_entry
> 						   <sleeps on empty DAX entry>
>   dax_load_hole
>    find_or_create_page
>    ...
>     page_cache_tree_insert
>      dax_wake_mapping_entry_waiter
>       <wakes one sleeper>
>      __radix_tree_replace
>       <swaps empty DAX entry with 4k zero page>
> 
> 			<wakes>
> 			get_page
> 			lock_page
> 			...
> 			put_locked_mapping_entry
> 			unlock_page
> 			put_page
> 
> 						<sleeps forever on the DAX
> 						 wait queue>
> 
> The crux of the problem is that once we insert a 4k zero page, all locking
> from then on is done in terms of that 4k zero page and any additional
> threads sleeping on the empty DAX entry will never be woken.  Fix this by
> waking all sleepers when we replace the DAX radix tree entry with a 4k zero
> page.  This will allow all sleeping threads to successfully transition from
> locking based on the DAX empty entry to locking on the 4k zero page.
> 
> With the test case reported by Xiong this happens very regularly in my test
> setup, with some runs resulting in 9+ threads in this deadlocked state.
> With this fix I've been able to run that same test dozens of times in a
> loop without issue.
> 
> Signed-off-by: Ross Zwisler <ross.zwisler@linux.intel.com>
> Reported-by: Xiong Zhou <xzhou@redhat.com>
> Fixes: commit ac401cc78242 ("dax: New fault locking")
> Cc: Jan Kara <jack@suse.cz>
> Cc: stable@vger.kernel.org # 4.7+

Ah, very good catch. You can add:

Reviewed-by: Jan Kara <jack@suse.cz>

I wonder why I was not able to reproduce this... Probably the timing didn't
work out right on my test machine.

								Honza

> ---
> 
> This issue exists as far back as v4.7, and I was easly able to reproduce it
> with v4.7 using the same test.
> 
> Unfortunately this patch won't apply cleanly to the stable trees, but the
> change is very simple and should be easy to replicate by hand.  Please ping
> me if you'd like patches that apply cleanly to the v4.9 and v4.8.15 trees.
> 
> ---
>  mm/filemap.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/mm/filemap.c b/mm/filemap.c
> index d0e4d10..b772a33 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -138,7 +138,7 @@ static int page_cache_tree_insert(struct address_space *mapping,
>  				dax_radix_locked_entry(0, RADIX_DAX_EMPTY));
>  			/* Wakeup waiters for exceptional entry lock */
>  			dax_wake_mapping_entry_waiter(mapping, page->index, p,
> -						      false);
> +						      true);
>  		}
>  	}
>  	__radix_tree_replace(&mapping->page_tree, node, slot, page,
> -- 
> 2.7.4
> 
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.