Re: [PATCH] staging: vc04_services: vchiq_arm: replace bitshift with BIT macro

2020-06-19 Thread Dan Carpenter
On Thu, Jun 18, 2020 at 06:02:59PM +0200, Garrit Franke wrote:
> This should prevent possible overflowing bits by using the BIT macro in
> vchiq_core

There is no reason to think that these will overflow.  For that to
happen we would need to be using a 64bit with a 1 << 31 shift.

if (flags & BIT(i)) {
^
Is "flags" a 64 bit and can "i" go up to 31?  Just say that it's a clean
up.

> 
> Signed-off-by: Garrit Franke 
> ---
>  .../interface/vchiq_arm/vchiq_core.c  | 22 +--
>  1 file changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c 
> b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
> index ae9183db44ee..5a6d2bd59ec0 100644
> --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
> +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
> @@ -39,9 +39,9 @@ struct vchiq_openack_payload {
>  };
>  
>  enum {
> - QMFLAGS_IS_BLOCKING = (1 << 0),
> - QMFLAGS_NO_MUTEX_LOCK   = (1 << 1),
> - QMFLAGS_NO_MUTEX_UNLOCK = (1 << 2)
> + QMFLAGS_IS_BLOCKING = BIT(0),
> + QMFLAGS_NO_MUTEX_LOCK   = BIT(1),
> + QMFLAGS_NO_MUTEX_UNLOCK = BIT(2)
>  };
>  
>  /* we require this for consistency between endpoints */
> @@ -526,14 +526,14 @@ request_poll(struct vchiq_state *state, struct 
> vchiq_service *service,
>   do {
>   value = atomic_read(&service->poll_flags);
>   } while (atomic_cmpxchg(&service->poll_flags, value,
> - value | (1 << poll_type)) != value);
> + value | BIT(poll_type)) != value);
>  
>   do {
>   value = atomic_read(&state->poll_services[
>   service->localport>>5]);
>   } while (atomic_cmpxchg(
>   &state->poll_services[service->localport>>5],
> - value, value | (1 << (service->localport & 0x1f)))
> + value, value | BIT((service->localport & 0x1f)))
   ^ ^
Too many parentheses.

Otherwise it looks fine.

regards,
dan carpenter

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: gasket: replace symbolic permissions

2020-06-19 Thread Rodolfo C Villordo
On Thu, Jun 18, 2020 at 09:47:50AM +0200, Greg Kroah-Hartman wrote:
> On Mon, Jun 01, 2020 at 12:52:40AM +, Rodolfo C. Villordo wrote:
> > WARNING: Symbolic permissions 'S_IRUGO' are not preferred. Consider using 
> > octal permissions '0444'.
> > +   .attr = __ATTR(_name, S_IRUGO, _show_function, NULL),   
> >\
> > warning detected by checkpatch.pl
> > 
> > Signed-off-by: Rodolfo C. Villordo 
> > ---
> >  drivers/staging/gasket/gasket_sysfs.h | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/staging/gasket/gasket_sysfs.h 
> > b/drivers/staging/gasket/gasket_sysfs.h
> > index ab5aa351d555..d5e167dfbe76 100644
> > --- a/drivers/staging/gasket/gasket_sysfs.h
> > +++ b/drivers/staging/gasket/gasket_sysfs.h
> > @@ -71,7 +71,7 @@ struct gasket_sysfs_attribute {
> >  
> >  #define GASKET_SYSFS_RO(_name, _show_function, _attr_type) 
> > \
> > {  \
> > -   .attr = __ATTR(_name, S_IRUGO, _show_function, NULL),  \
> > +   .attr = __ATTR(_name, 0444, _show_function, NULL),  \
> 
> What about using __ATTR_RO() instead?
> 

I'm not sure if __ATTR_RO() is a good match here. The
GASKET_SYSFS_RO() is invoked with different show functions across the
code. These functions don't follow the name pattern attr_name_show
used in __ATTR_RO(). Please correct me if I misunderstood anything.

### from include/linux/sysfs.h ###
#define __ATTR_RO(_name) {  \
.attr   = { .name = __stringify(_name), .mode = 0444 }, \
.show   = _name##_show, \
}
###

### macro usage across the driver: ###
$ grep GASKET_SYSFS_RO drivers/staging/gasket/*
drivers/staging/gasket/apex_driver.c:   
GASKET_SYSFS_RO(node_0_page_table_entries, sysfs_show,
drivers/staging/gasket/apex_driver.c:   
GASKET_SYSFS_RO(node_0_simple_page_table_entries, sysfs_show,
drivers/staging/gasket/apex_driver.c:   
GASKET_SYSFS_RO(node_0_num_mapped_pages, sysfs_show,
drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(bar_offsets, 
gasket_sysfs_data_show, ATTR_BAR_OFFSETS),
drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(bar_sizes, 
gasket_sysfs_data_show, ATTR_BAR_SIZES),
drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(driver_version, 
gasket_sysfs_data_show,
drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(framework_version, 
gasket_sysfs_data_show,
drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(device_type, 
gasket_sysfs_data_show, ATTR_DEVICE_TYPE),
drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(revision, 
gasket_sysfs_data_show,
drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(pci_address, 
gasket_sysfs_data_show, ATTR_PCI_ADDRESS),
drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(status, 
gasket_sysfs_data_show, ATTR_STATUS),
drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(is_device_owned, 
gasket_sysfs_data_show,
drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(device_owner, 
gasket_sysfs_data_show,
drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(write_open_count, 
gasket_sysfs_data_show,
drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(reset_count, 
gasket_sysfs_data_show, ATTR_RESET_COUNT),
drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(user_mem_ranges, 
gasket_sysfs_data_show,
drivers/staging/gasket/gasket_interrupt.c:  
GASKET_SYSFS_RO(interrupt_counts, interrupt_sysfs_show,
###

Thank you!

> thanks,
> 
> greg k-h
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH] staging: gasket: replace symbolic permissions

2020-06-19 Thread Greg Kroah-Hartman
On Fri, Jun 19, 2020 at 08:27:14AM +, Rodolfo C Villordo wrote:
> On Thu, Jun 18, 2020 at 09:47:50AM +0200, Greg Kroah-Hartman wrote:
> > On Mon, Jun 01, 2020 at 12:52:40AM +, Rodolfo C. Villordo wrote:
> > > WARNING: Symbolic permissions 'S_IRUGO' are not preferred. Consider using 
> > > octal permissions '0444'.
> > > +   .attr = __ATTR(_name, S_IRUGO, _show_function, NULL), 
> > >  \
> > > warning detected by checkpatch.pl
> > > 
> > > Signed-off-by: Rodolfo C. Villordo 
> > > ---
> > >  drivers/staging/gasket/gasket_sysfs.h | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/staging/gasket/gasket_sysfs.h 
> > > b/drivers/staging/gasket/gasket_sysfs.h
> > > index ab5aa351d555..d5e167dfbe76 100644
> > > --- a/drivers/staging/gasket/gasket_sysfs.h
> > > +++ b/drivers/staging/gasket/gasket_sysfs.h
> > > @@ -71,7 +71,7 @@ struct gasket_sysfs_attribute {
> > >  
> > >  #define GASKET_SYSFS_RO(_name, _show_function, _attr_type)   
> > >   \
> > >   {  \
> > > - .attr = __ATTR(_name, S_IRUGO, _show_function, NULL),  \
> > > + .attr = __ATTR(_name, 0444, _show_function, NULL),  \
> > 
> > What about using __ATTR_RO() instead?
> > 
> 
> I'm not sure if __ATTR_RO() is a good match here. The
> GASKET_SYSFS_RO() is invoked with different show functions across the
> code. These functions don't follow the name pattern attr_name_show
> used in __ATTR_RO(). Please correct me if I misunderstood anything.
> 
> ### from include/linux/sysfs.h ###
> #define __ATTR_RO(_name) {  \
> .attr   = { .name = __stringify(_name), .mode = 0444 }, \
> .show   = _name##_show, \
> }
> ###
> 
> ### macro usage across the driver: ###
> $ grep GASKET_SYSFS_RO drivers/staging/gasket/*
> drivers/staging/gasket/apex_driver.c:   
> GASKET_SYSFS_RO(node_0_page_table_entries, sysfs_show,
> drivers/staging/gasket/apex_driver.c:   
> GASKET_SYSFS_RO(node_0_simple_page_table_entries, sysfs_show,
> drivers/staging/gasket/apex_driver.c:   
> GASKET_SYSFS_RO(node_0_num_mapped_pages, sysfs_show,
> drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(bar_offsets, 
> gasket_sysfs_data_show, ATTR_BAR_OFFSETS),
> drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(bar_sizes, 
> gasket_sysfs_data_show, ATTR_BAR_SIZES),
> drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(driver_version, 
> gasket_sysfs_data_show,
> drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(framework_version, 
> gasket_sysfs_data_show,
> drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(device_type, 
> gasket_sysfs_data_show, ATTR_DEVICE_TYPE),
> drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(revision, 
> gasket_sysfs_data_show,
> drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(pci_address, 
> gasket_sysfs_data_show, ATTR_PCI_ADDRESS),
> drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(status, 
> gasket_sysfs_data_show, ATTR_STATUS),
> drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(is_device_owned, 
> gasket_sysfs_data_show,
> drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(device_owner, 
> gasket_sysfs_data_show,
> drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(write_open_count, 
> gasket_sysfs_data_show,
> drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(reset_count, 
> gasket_sysfs_data_show, ATTR_RESET_COUNT),
> drivers/staging/gasket/gasket_core.c:   GASKET_SYSFS_RO(user_mem_ranges, 
> gasket_sysfs_data_show,
> drivers/staging/gasket/gasket_interrupt.c:  
> GASKET_SYSFS_RO(interrupt_counts, interrupt_sysfs_show,
> ###

Ugh, you are right, that's a mess.  Your original patch is fine, can you
resend it and say in the changelog why it's not ok to use __ATTR_RO()?

thanks,

greg k-h
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v5 6/9] media: adv748x: prepare/enable mclk when the audio is used

2020-06-19 Thread Alex Riesen
Kieran Bingham, Thu, Jun 18, 2020 18:23:14 +0200:
> On 02/04/2020 19:34, Alex Riesen wrote:
> > --- a/drivers/media/i2c/adv748x/adv748x-dai.c
> > +++ b/drivers/media/i2c/adv748x/adv748x-dai.c
> > @@ -117,11 +117,22 @@ static int adv748x_dai_set_fmt(struct snd_soc_dai 
> > *dai, unsigned int fmt)
> >  
> >  static int adv748x_dai_startup(struct snd_pcm_substream *sub, struct 
> > snd_soc_dai *dai)
> >  {
> > +   int ret;
> > struct adv748x_state *state = state_of(dai);
> >  
> > if (sub->stream != SNDRV_PCM_STREAM_CAPTURE)
> > return -EINVAL;
> this looks quite bunched up so :
> 
> Newline...

Will do.

> > -   return set_audio_pads_state(state, 1);
> > +   ret = set_audio_pads_state(state, 1);
> > +   if (ret)
> > +   goto fail;
> 
> With no action required to cleanup here, I would just
>   return ret;
> and remove the fail: label.

Of course.

> > +   ret = clk_prepare_enable(mclk_of(state));
> > +   if (ret)
> > +   goto fail_pwdn;
> 
> newline...
> 
> > +   return 0;
> 
> newline...
> 
> Other than that:
> 
> Reviewed-by: Kieran Bingham 

Thanks!

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v5 7/9] media: adv748x: only activate DAI if it is described in device tree

2020-06-19 Thread Alex Riesen
Kieran Bingham, Thu, Jun 18, 2020 18:17:04 +0200:
> On 02/04/2020 19:34, Alex Riesen wrote:
> > To avoid setting it up even if the hardware is not actually connected
> > to anything physically.
> > 
> > Besides, the bindings explicitly notes that port definitions are
> > "optional if they are not connected to anything at the hardware level".
> > 
> > Signed-off-by: Alexander Riesen 
> > ---
> >  drivers/media/i2c/adv748x/adv748x-dai.c | 5 +
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/drivers/media/i2c/adv748x/adv748x-dai.c 
> > b/drivers/media/i2c/adv748x/adv748x-dai.c
> > index 185f78023e91..f9cc47fa9ad1 100644
> > --- a/drivers/media/i2c/adv748x/adv748x-dai.c
> > +++ b/drivers/media/i2c/adv748x/adv748x-dai.c
> > @@ -216,6 +216,11 @@ int adv748x_dai_init(struct adv748x_dai *dai)
> > int ret;
> > struct adv748x_state *state = adv748x_dai_to_state(dai);
> >  
> > +   if (!state->endpoints[ADV748X_PORT_I2S]) {
> > +   adv_info(state, "no I2S port, DAI disabled\n");
> > +   ret = 0;
> > +   goto fail;
> 
> How about just 'return 0'?

Indeed. In the retrospect, the whole event of loading the DAI driver does not
feel that important anymore to warrant logging on info prio.

> Reviewed-by: Kieran Bingham 
> 
> This could also be folded into 5/9 too I guess?, though it is easier to
> review the sequential additions, rather than the one-big-feature
> addition ;-)

I would prefer to have it separately, if you don't mind: maybe not a big one,
but loading a driver without hardware for it *is* an event.

Thanks,
Alex
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v5 9/9] arm64: dts: renesas: salvator: add a connection from adv748x codec (HDMI input) to the R-Car SoC

2020-06-19 Thread Alex Riesen
Kieran Bingham, Thu, Jun 18, 2020 18:32:55 +0200:
> On 02/04/2020 19:35, Alex Riesen wrote:
> > --- a/arch/arm64/boot/dts/renesas/r8a77950-salvator-x.dts
> > +++ b/arch/arm64/boot/dts/renesas/r8a77950-salvator-x.dts
> > @@ -146,7 +146,8 @@ &sata {
> >  &sound_card {
> > dais = <&rsnd_port0 /* ak4613 */
> > &rsnd_port1 /* HDMI0  */
> > -   &rsnd_port2>;   /* HDMI1  */
> > +   &rsnd_port2 /* HDMI1  */
> > +   &rsnd_port3>;   /* adv7482 hdmi-in  */
> 
> Ah - that was confusing at first... but HDMI0 and HDMI1 are *outputs*,
> where of course the adv7482 is an input ;-)

And ak4613 is both... Why? Are the "dais" of a sound_card more commonly
outputs than inputs?

> Otherwise, I can't spot anything else yet so:
> 
> Reviewed-by: Kieran Bingham 
> 
> But I fear there may have been some churn around here, so it would be
> good to see a rebase too.

Just rebased the series on top of linux-media/master and the only conflict was
in adding ssi4 node to rcar_sound,ssi in r8a77961.dtsi, as there was an
addition of ssi2 in the same line.

Thanks,
Alex

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v7 31/36] staging: tegra-vde: fix common struct sg_table related issues

2020-06-19 Thread Marek Szyprowski
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function
returns the number of the created entries in the DMA address space.
However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and
dma_unmap_sg must be called with the original number of the entries
passed to the dma_map_sg().

struct sg_table is a common structure used for describing a non-contiguous
memory buffer, used commonly in the DRM and graphics subsystems. It
consists of a scatterlist with memory pages and DMA addresses (sgl entry),
as well as the number of scatterlist entries: CPU pages (orig_nents entry)
and DMA mapped pages (nents entry).

It turned out that it was a common mistake to misuse nents and orig_nents
entries, calling DMA-mapping functions with a wrong number of entries or
ignoring the number of mapped entries returned by the dma_map_sg()
function.

To avoid such issues, lets use a common dma-mapping wrappers operating
directly on the struct sg_table objects and use scatterlist page
iterators where possible. This, almost always, hides references to the
nents and orig_nents entries, making the code robust, easier to follow
and copy/paste safe.

Signed-off-by: Marek Szyprowski 
Reviewed-by: Dmitry Osipenko 
---
 drivers/staging/media/tegra-vde/iommu.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/tegra-vde/iommu.c 
b/drivers/staging/media/tegra-vde/iommu.c
index 6af863d92123..adf8dc7ee25c 100644
--- a/drivers/staging/media/tegra-vde/iommu.c
+++ b/drivers/staging/media/tegra-vde/iommu.c
@@ -36,8 +36,8 @@ int tegra_vde_iommu_map(struct tegra_vde *vde,
 
addr = iova_dma_addr(&vde->iova, iova);
 
-   size = iommu_map_sg(vde->domain, addr, sgt->sgl, sgt->nents,
-   IOMMU_READ | IOMMU_WRITE);
+   size = iommu_map_sgtable(vde->domain, addr, sgt,
+IOMMU_READ | IOMMU_WRITE);
if (!size) {
__free_iova(&vde->iova, iova);
return -ENXIO;
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v7 30/36] staging: ion: fix common struct sg_table related issues

2020-06-19 Thread Marek Szyprowski
The Documentation/DMA-API-HOWTO.txt states that the dma_map_sg() function
returns the number of the created entries in the DMA address space.
However the subsequent calls to the dma_sync_sg_for_{device,cpu}() and
dma_unmap_sg must be called with the original number of the entries
passed to the dma_map_sg().

struct sg_table is a common structure used for describing a non-contiguous
memory buffer, used commonly in the DRM and graphics subsystems. It
consists of a scatterlist with memory pages and DMA addresses (sgl entry),
as well as the number of scatterlist entries: CPU pages (orig_nents entry)
and DMA mapped pages (nents entry).

It turned out that it was a common mistake to misuse nents and orig_nents
entries, calling DMA-mapping functions with a wrong number of entries or
ignoring the number of mapped entries returned by the dma_map_sg()
function.

To avoid such issues, lets use a common dma-mapping wrappers operating
directly on the struct sg_table objects and use scatterlist page
iterators where possible. This, almost always, hides references to the
nents and orig_nents entries, making the code robust, easier to follow
and copy/paste safe.

Signed-off-by: Marek Szyprowski 
---
 drivers/staging/android/ion/ion.c | 25 +--
 drivers/staging/android/ion/ion_heap.c| 44 ++-
 drivers/staging/android/ion/ion_system_heap.c |  2 +-
 3 files changed, 25 insertions(+), 46 deletions(-)

diff --git a/drivers/staging/android/ion/ion.c 
b/drivers/staging/android/ion/ion.c
index 38b51eace4f9..3c9f09506ffa 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -147,14 +147,14 @@ static struct sg_table *dup_sg_table(struct sg_table 
*table)
if (!new_table)
return ERR_PTR(-ENOMEM);
 
-   ret = sg_alloc_table(new_table, table->nents, GFP_KERNEL);
+   ret = sg_alloc_table(new_table, table->orig_nents, GFP_KERNEL);
if (ret) {
kfree(new_table);
return ERR_PTR(-ENOMEM);
}
 
new_sg = new_table->sgl;
-   for_each_sg(table->sgl, sg, table->nents, i) {
+   for_each_sgtable_sg(table, sg, i) {
memcpy(new_sg, sg, sizeof(*sg));
new_sg->dma_address = 0;
new_sg = sg_next(new_sg);
@@ -224,12 +224,13 @@ static struct sg_table *ion_map_dma_buf(struct 
dma_buf_attachment *attachment,
 {
struct ion_dma_buf_attachment *a = attachment->priv;
struct sg_table *table;
+   int ret;
 
table = a->table;
 
-   if (!dma_map_sg(attachment->dev, table->sgl, table->nents,
-   direction))
-   return ERR_PTR(-ENOMEM);
+   ret = dma_map_sgtable(attachment->dev, table, direction, 0);
+   if (ret)
+   return ERR_PTR(ret);
 
return table;
 }
@@ -238,7 +239,7 @@ static void ion_unmap_dma_buf(struct dma_buf_attachment 
*attachment,
  struct sg_table *table,
  enum dma_data_direction direction)
 {
-   dma_unmap_sg(attachment->dev, table->sgl, table->nents, direction);
+   dma_unmap_sgtable(attachment->dev, table, direction, 0);
 }
 
 static int ion_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
@@ -296,10 +297,8 @@ static int ion_dma_buf_begin_cpu_access(struct dma_buf 
*dmabuf,
}
 
mutex_lock(&buffer->lock);
-   list_for_each_entry(a, &buffer->attachments, list) {
-   dma_sync_sg_for_cpu(a->dev, a->table->sgl, a->table->nents,
-   direction);
-   }
+   list_for_each_entry(a, &buffer->attachments, list)
+   dma_sync_sgtable_for_cpu(a->dev, a->table, direction);
 
 unlock:
mutex_unlock(&buffer->lock);
@@ -319,10 +318,8 @@ static int ion_dma_buf_end_cpu_access(struct dma_buf 
*dmabuf,
}
 
mutex_lock(&buffer->lock);
-   list_for_each_entry(a, &buffer->attachments, list) {
-   dma_sync_sg_for_device(a->dev, a->table->sgl, a->table->nents,
-  direction);
-   }
+   list_for_each_entry(a, &buffer->attachments, list)
+   dma_sync_sgtable_for_device(a->dev, a->table, direction);
mutex_unlock(&buffer->lock);
 
return 0;
diff --git a/drivers/staging/android/ion/ion_heap.c 
b/drivers/staging/android/ion/ion_heap.c
index 9c23b2382a1e..79f27949edda 100644
--- a/drivers/staging/android/ion/ion_heap.c
+++ b/drivers/staging/android/ion/ion_heap.c
@@ -20,8 +20,7 @@
 void *ion_heap_map_kernel(struct ion_heap *heap,
  struct ion_buffer *buffer)
 {
-   struct scatterlist *sg;
-   int i, j;
+   struct sg_page_iter piter;
void *vaddr;
pgprot_t pgprot;
struct sg_table *table = buffer->sg_table;
@@ -38,14 +37,11 @@ void *ion_heap_map_kernel(struct ion_heap *heap,
else
pgprot = pgprot_writecombine(PAGE_KERNEL);
 
-   for_each_s

[PATCH v7 29/36] staging: ion: remove dead code

2020-06-19 Thread Marek Szyprowski
ion_heap_pages_zero() function is not used at all, so remove it to
simplify the ion_heap_sglist_zero() function later.

Signed-off-by: Marek Szyprowski 
---
 drivers/staging/android/ion/ion.h  | 1 -
 drivers/staging/android/ion/ion_heap.c | 9 -
 2 files changed, 10 deletions(-)

diff --git a/drivers/staging/android/ion/ion.h 
b/drivers/staging/android/ion/ion.h
index 74914a266e25..c199e88afc6c 100644
--- a/drivers/staging/android/ion/ion.h
+++ b/drivers/staging/android/ion/ion.h
@@ -177,7 +177,6 @@ void ion_heap_unmap_kernel(struct ion_heap *heap, struct 
ion_buffer *buffer);
 int ion_heap_map_user(struct ion_heap *heap, struct ion_buffer *buffer,
  struct vm_area_struct *vma);
 int ion_heap_buffer_zero(struct ion_buffer *buffer);
-int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot);
 
 /**
  * ion_heap_init_shrinker
diff --git a/drivers/staging/android/ion/ion_heap.c 
b/drivers/staging/android/ion/ion_heap.c
index 0755b11348ed..9c23b2382a1e 100644
--- a/drivers/staging/android/ion/ion_heap.c
+++ b/drivers/staging/android/ion/ion_heap.c
@@ -145,15 +145,6 @@ int ion_heap_buffer_zero(struct ion_buffer *buffer)
return ion_heap_sglist_zero(table->sgl, table->nents, pgprot);
 }
 
-int ion_heap_pages_zero(struct page *page, size_t size, pgprot_t pgprot)
-{
-   struct scatterlist sg;
-
-   sg_init_table(&sg, 1);
-   sg_set_page(&sg, page, size, 0);
-   return ion_heap_sglist_zero(&sg, 1, pgprot);
-}
-
 void ion_heap_freelist_add(struct ion_heap *heap, struct ion_buffer *buffer)
 {
spin_lock(&heap->free_lock);
-- 
2.17.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 1/6] staging: greybus: audio: Update snd_jack FW usage as per new APIs

2020-06-19 Thread Vaibhav Agarwal
snd_soc_jack APIs are modified in recent kernel versions. This patch
updates the codec driver to resolve the compilation errors related to
jack framework.

Signed-off-by: Vaibhav Agarwal 
Reviewed-by: Dan Carpenter 
---
 drivers/staging/greybus/audio_codec.c | 54 +--
 1 file changed, 42 insertions(+), 12 deletions(-)

diff --git a/drivers/staging/greybus/audio_codec.c 
b/drivers/staging/greybus/audio_codec.c
index 08746c85dea6..5d3a5e6a8fe6 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -709,17 +709,26 @@ static struct snd_soc_dai_driver gbaudio_dai[] = {
 };
 
 static int gbaudio_init_jack(struct gbaudio_module_info *module,
-struct snd_soc_codec *codec)
+struct snd_soc_card *card)
 {
int ret;
+   struct snd_soc_jack_pin *headset, *button;
 
if (!module->jack_mask)
return 0;
 
snprintf(module->jack_name, NAME_SIZE, "GB %d Headset Jack",
 module->dev_id);
-   ret = snd_soc_jack_new(codec, module->jack_name, module->jack_mask,
-  &module->headset_jack);
+
+   headset = devm_kzalloc(module->dev, sizeof(*headset), GFP_KERNEL);
+   if (!headset)
+   return -ENOMEM;
+
+   headset->pin = module->jack_name;
+   headset->mask = module->jack_mask;
+
+   ret = snd_soc_card_jack_new(card, module->jack_name, module->jack_mask,
+   &module->headset_jack, headset, 1);
if (ret) {
dev_err(module->dev, "Failed to create new jack\n");
return ret;
@@ -730,11 +739,21 @@ static int gbaudio_init_jack(struct gbaudio_module_info 
*module,
 
snprintf(module->button_name, NAME_SIZE, "GB %d Button Jack",
 module->dev_id);
-   ret = snd_soc_jack_new(codec, module->button_name, module->button_mask,
-  &module->button_jack);
+   button = devm_kzalloc(module->dev, sizeof(*button), GFP_KERNEL);
+   if (!button) {
+   ret = -ENOMEM;
+   goto free_headset;
+   }
+
+   button->pin = module->button_name;
+   button->mask = module->button_mask;
+
+   ret = snd_soc_card_jack_new(card, module->button_name,
+   module->button_mask, &module->button_jack,
+   button, 1);
if (ret) {
dev_err(module->dev, "Failed to create button jack\n");
-   return ret;
+   goto free_headset;
}
 
/*
@@ -750,7 +769,7 @@ static int gbaudio_init_jack(struct gbaudio_module_info 
*module,
   KEY_MEDIA);
if (ret) {
dev_err(module->dev, "Failed to set BTN_0\n");
-   return ret;
+   goto free_button;
}
}
 
@@ -759,7 +778,7 @@ static int gbaudio_init_jack(struct gbaudio_module_info 
*module,
   KEY_VOICECOMMAND);
if (ret) {
dev_err(module->dev, "Failed to set BTN_1\n");
-   return ret;
+   goto free_button;
}
}
 
@@ -768,7 +787,7 @@ static int gbaudio_init_jack(struct gbaudio_module_info 
*module,
   KEY_VOLUMEUP);
if (ret) {
dev_err(module->dev, "Failed to set BTN_2\n");
-   return ret;
+   goto free_button;
}
}
 
@@ -777,7 +796,7 @@ static int gbaudio_init_jack(struct gbaudio_module_info 
*module,
   KEY_VOLUMEDOWN);
if (ret) {
dev_err(module->dev, "Failed to set BTN_0\n");
-   return ret;
+   goto free_button;
}
}
 
@@ -788,6 +807,16 @@ static int gbaudio_init_jack(struct gbaudio_module_info 
*module,
*/
 
return 0;
+
+free_button:
+   snd_device_free(card->snd_card, module->button_jack.jack);
+   list_del(&module->button_jack.list);
+
+free_headset:
+   snd_device_free(card->snd_card, module->headset_jack.jack);
+   list_del(&module->headset_jack.list);
+
+   return ret;
 }
 
 int gbaudio_register_module(struct gbaudio_module_info *module)
@@ -815,7 +844,7 @@ int gbaudio_register_module(struct gbaudio_module_info 
*module)
return -EINVAL;
}
 
-   ret = gbaudio_init_jack(module, codec);
+   ret = gbaudio_init_jack(module, component->card);
if (ret) {
up_write(&card->controls_rwsem);
return ret;
@@ -942,7 +971,8 @@ void gbaudio_unregister_module(struct gbaudio_module_info 
*module)
 
 #ifdef CONFIG_SND_JACK
/* free jack devices for this module from codec->jack_

[PATCH v3 0/6] Enable Greybus Audio codec driver

2020-06-19 Thread Vaibhav Agarwal
The existing GB Audio codec driver is dependent on MSM8994 Audio driver.
During the development stage, this dependency was configured due to
various changes involved in MSM Audio driver to enable addtional codec
card and some of the changes proposed in mainline ASoC framework.
However, these are not the real dependencies and some of them can be
easily removed.

The folowing patch series includes the changes to resolve unnecessary
depedencies and make the codec driver functional with the latest kernel.

Patch 1,2: Incudes jack framework related changes.
Patch 3,4,5: Resolves compilation error observed with the latest kernel and
also provides helper APIs required to allow dynamic addition/removal of
modules.
Patch 6: Finally provides config options and related Makefile changes to
enable GB Codec driver.

Thanks to Alexandre for raising the headsup [1] and motivating me to provide
the necessary changes.

This patchset is intended to resolve the componentization issue only.
And as per the suggestion [2] from Mark, I'll share a separate patch series
aligned to ASoC tree. Once the relevant changes are accepted in snd-soc
framework, I'll share relevant patches to pull GB Audio out of the
staging tree.

[1] 
https://lore.kernel.org/lkml/20200507212912.599433-1-alexandre.bell...@bootlin.com/
[2] https://lore.kernel.org/alsa-devel/20200612160620.gk5...@sirena.org.uk/

v1:
- Include the changes for the review comments suggested by Dan
- Rebase to latest staging-next

v2:
- Avoid defining unused 'update' pointer
- Fix the missing connect bool value required during mixer_update_power
- Added Reviewed-by tag from Dan
- Rebase to latest staging-next

Vaibhav Agarwal (6):
  staging: greybus: audio: Update snd_jack FW usage as per new APIs
  staging: greybus: audio: Maintain jack list within GB Audio module
  staging: greybus: audio: Resolve compilation errors for GB codec
module
  staging: greybus: audio: Resolve compilation error in topology parser
  staging: greybus: audio: Add helper APIs for dynamic audio modules
  staging: greybus: audio: Enable GB codec, audio module compilation.

 drivers/staging/greybus/Kconfig  |  14 +-
 drivers/staging/greybus/Makefile |   6 +-
 drivers/staging/greybus/audio_codec.c| 178 +++-
 drivers/staging/greybus/audio_codec.h|  12 +-
 drivers/staging/greybus/audio_helper.c   | 197 +++
 drivers/staging/greybus/audio_helper.h   |  17 ++
 drivers/staging/greybus/audio_module.c   |  15 +-
 drivers/staging/greybus/audio_topology.c | 123 +++---
 8 files changed, 409 insertions(+), 153 deletions(-)
 create mode 100644 drivers/staging/greybus/audio_helper.c
 create mode 100644 drivers/staging/greybus/audio_helper.h


base-commit: 98fe05e21a6e0ca242e974650ed58b64813cb2dc
-- 
2.26.2

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 4/6] staging: greybus: audio: Resolve compilation error in topology parser

2020-06-19 Thread Vaibhav Agarwal
Fix compilation errors for GB Audio topology parser code with recent
kernel versions.

Signed-off-by: Vaibhav Agarwal 
Reviewed-by: Dan Carpenter 
---
 drivers/staging/greybus/audio_topology.c | 123 +++
 1 file changed, 57 insertions(+), 66 deletions(-)

diff --git a/drivers/staging/greybus/audio_topology.c 
b/drivers/staging/greybus/audio_topology.c
index 4ac30accf226..ad88d3127a60 100644
--- a/drivers/staging/greybus/audio_topology.c
+++ b/drivers/staging/greybus/audio_topology.c
@@ -5,8 +5,8 @@
  * Copyright 2015-2016 Linaro Ltd.
  */
 
+#include 
 #include "audio_codec.h"
-#include "greybus_protocols.h"
 
 #define GBAUDIO_INVALID_ID 0xFF
 
@@ -165,15 +165,15 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol 
*kcontrol,
struct gbaudio_ctl_pvt *data;
struct gb_audio_ctl_elem_info *info;
struct gbaudio_module_info *module;
-   struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-   struct gbaudio_codec_info *gbcodec = snd_soc_codec_get_drvdata(codec);
+   struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+   struct gbaudio_codec_info *gbcodec = 
snd_soc_component_get_drvdata(comp);
 
-   dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
+   dev_dbg(comp->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
data = (struct gbaudio_ctl_pvt *)kcontrol->private_value;
info = (struct gb_audio_ctl_elem_info *)data->info;
 
if (!info) {
-   dev_err(codec->dev, "NULL info for %s\n", uinfo->id.name);
+   dev_err(comp->dev, "NULL info for %s\n", uinfo->id.name);
return -EINVAL;
}
 
@@ -201,7 +201,7 @@ static int gbcodec_mixer_ctl_info(struct snd_kcontrol 
*kcontrol,
strlcpy(uinfo->value.enumerated.name, name, NAME_SIZE);
break;
default:
-   dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
+   dev_err(comp->dev, "Invalid type: %d for %s:kcontrol\n",
info->type, kcontrol->id.name);
break;
}
@@ -216,11 +216,11 @@ static int gbcodec_mixer_ctl_get(struct snd_kcontrol 
*kcontrol,
struct gbaudio_ctl_pvt *data;
struct gb_audio_ctl_elem_value gbvalue;
struct gbaudio_module_info *module;
-   struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-   struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+   struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+   struct gbaudio_codec_info *gb = snd_soc_component_get_drvdata(comp);
struct gb_bundle *bundle;
 
-   dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
+   dev_dbg(comp->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
module = find_gb_module(gb, kcontrol->id.name);
if (!module)
return -EINVAL;
@@ -239,7 +239,7 @@ static int gbcodec_mixer_ctl_get(struct snd_kcontrol 
*kcontrol,
gb_pm_runtime_put_autosuspend(bundle);
 
if (ret) {
-   dev_err_ratelimited(codec->dev, "%d:Error in %s for %s\n", ret,
+   dev_err_ratelimited(comp->dev, "%d:Error in %s for %s\n", ret,
__func__, kcontrol->id.name);
return ret;
}
@@ -262,7 +262,7 @@ static int gbcodec_mixer_ctl_get(struct snd_kcontrol 
*kcontrol,
le32_to_cpu(gbvalue.value.enumerated_item[1]);
break;
default:
-   dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
+   dev_err(comp->dev, "Invalid type: %d for %s:kcontrol\n",
info->type, kcontrol->id.name);
ret = -EINVAL;
break;
@@ -278,11 +278,11 @@ static int gbcodec_mixer_ctl_put(struct snd_kcontrol 
*kcontrol,
struct gbaudio_ctl_pvt *data;
struct gb_audio_ctl_elem_value gbvalue;
struct gbaudio_module_info *module;
-   struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
-   struct gbaudio_codec_info *gb = snd_soc_codec_get_drvdata(codec);
+   struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol);
+   struct gbaudio_codec_info *gb = snd_soc_component_get_drvdata(comp);
struct gb_bundle *bundle;
 
-   dev_dbg(codec->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
+   dev_dbg(comp->dev, "Entered %s:%s\n", __func__, kcontrol->id.name);
module = find_gb_module(gb, kcontrol->id.name);
if (!module)
return -EINVAL;
@@ -309,7 +309,7 @@ static int gbcodec_mixer_ctl_put(struct snd_kcontrol 
*kcontrol,
cpu_to_le32(ucontrol->value.enumerated.item[1]);
break;
default:
-   dev_err(codec->dev, "Invalid type: %d for %s:kcontrol\n",
+   dev_err(comp->dev, "Invalid type: %d for %s:kcontrol\n",
   

[PATCH v3 6/6] staging: greybus: audio: Enable GB codec, audio module compilation.

2020-06-19 Thread Vaibhav Agarwal
Currently you can't enable the Gey Bus Audio Codec because there is no
entry for it in the Kconfig file. Originally the config name was going
to be AUDIO_MSM8994 but that's not correct because other types of
hardware are supported now. I have chosen the name AUDIO_APB_CODEC
instead.  Also I had to update the dependencies for GREYBUS_AUDIO to
make the compile work.

Signed-off-by: Vaibhav Agarwal 
Reviewed-by: Dan Carpenter 
---
 drivers/staging/greybus/Kconfig  | 14 +-
 drivers/staging/greybus/Makefile |  4 ++--
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/drivers/staging/greybus/Kconfig b/drivers/staging/greybus/Kconfig
index 9389e7a922fa..927cfa4bc989 100644
--- a/drivers/staging/greybus/Kconfig
+++ b/drivers/staging/greybus/Kconfig
@@ -3,7 +3,7 @@ if GREYBUS
 
 config GREYBUS_AUDIO
tristate "Greybus Audio Class driver"
-   depends on SOUND
+   depends on SOUND && SND_SOC
help
  Select this option if you have a device that follows the
  Greybus Audio Class specification.
@@ -11,6 +11,18 @@ config GREYBUS_AUDIO
  To compile this code as a module, chose M here: the module
  will be called gb-audio.ko
 
+config GREYBUS_AUDIO_APB_CODEC
+   tristate "Greybus APBridge Audio codec driver"
+   depends on SND_SOC && GREYBUS_AUDIO
+   help
+ Select this option if you have a Toshiba APB device that has I2S
+  ports and acts as a Greybus "Dummy codec". This device is a
+  bridge from an APB-I2S port to a Unipro network.
+
+ To compile this code as a module, chose M here: the module
+ will be called gb-audio-codec.ko
+
+
 config GREYBUS_BOOTROM
tristate "Greybus Bootrom Class driver"
help
diff --git a/drivers/staging/greybus/Makefile b/drivers/staging/greybus/Makefile
index 3b4b6cabff19..7c5e89622334 100644
--- a/drivers/staging/greybus/Makefile
+++ b/drivers/staging/greybus/Makefile
@@ -40,8 +40,8 @@ gb-audio-manager-y:= audio_manager.o 
audio_manager_module.o
 #ccflags-y += -DGB_AUDIO_MANAGER_SYSFS
 #endif
 
-obj-$(CONFIG_GREYBUS_AUDIO_MSM8994)+= gb-audio-codec.o
-obj-$(CONFIG_GREYBUS_AUDIO_MSM8994)+= gb-audio-module.o
+obj-$(CONFIG_GREYBUS_AUDIO_APB_CODEC)  += gb-audio-codec.o
+obj-$(CONFIG_GREYBUS_AUDIO_APB_CODEC)  += gb-audio-module.o
 obj-$(CONFIG_GREYBUS_AUDIO)+= gb-audio-gb.o
 obj-$(CONFIG_GREYBUS_AUDIO)+= gb-audio-apbridgea.o
 obj-$(CONFIG_GREYBUS_AUDIO)+= gb-audio-manager.o
-- 
2.26.2

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 5/6] staging: greybus: audio: Add helper APIs for dynamic audio modules

2020-06-19 Thread Vaibhav Agarwal
Greybus Codec driver allows modules to be dynamically added and removed,
which further requires updating the DAPM configurations as well.

With current snd_soc architecture, dynamic audio modules is not yet
supported. This patch provides helper APIs to update DAPM configurations
in response to modules which are dynamically added or removed. The
source is primarily based on snd_dapm.c

Signed-off-by: Vaibhav Agarwal 
Reviewed-by: Dan Carpenter 
---
 drivers/staging/greybus/Makefile   |   2 +-
 drivers/staging/greybus/audio_codec.c  |  12 +-
 drivers/staging/greybus/audio_helper.c | 197 +
 drivers/staging/greybus/audio_helper.h |  17 +++
 4 files changed, 223 insertions(+), 5 deletions(-)
 create mode 100644 drivers/staging/greybus/audio_helper.c
 create mode 100644 drivers/staging/greybus/audio_helper.h

diff --git a/drivers/staging/greybus/Makefile b/drivers/staging/greybus/Makefile
index 627e44f2a983..3b4b6cabff19 100644
--- a/drivers/staging/greybus/Makefile
+++ b/drivers/staging/greybus/Makefile
@@ -28,7 +28,7 @@ obj-$(CONFIG_GREYBUS_VIBRATOR)+= gb-vibrator.o
 
 # Greybus Audio is a bunch of modules
 gb-audio-module-y  := audio_module.o audio_topology.o
-gb-audio-codec-y   := audio_codec.o
+gb-audio-codec-y   := audio_codec.o audio_helper.o
 gb-audio-gb-y  := audio_gb.o
 gb-audio-apbridgea-y   := audio_apbridgea.o
 gb-audio-manager-y := audio_manager.o audio_manager_module.o
diff --git a/drivers/staging/greybus/audio_codec.c 
b/drivers/staging/greybus/audio_codec.c
index 0ecdba27086b..74538f8c5fa4 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -14,6 +14,7 @@
 #include "audio_codec.h"
 #include "audio_apbridgea.h"
 #include "audio_manager.h"
+#include "audio_helper.h"
 
 static struct gbaudio_codec_info *gbcodec;
 
@@ -865,7 +866,7 @@ int gbaudio_register_module(struct gbaudio_module_info 
*module)
 
/* card already instantiated, create widgets here only */
if (comp->card->instantiated) {
-   snd_soc_dapm_link_component_dai_widgets(comp->card,
+   gbaudio_dapm_link_component_dai_widgets(comp->card,
&comp->dapm);
 #ifdef CONFIG_SND_JACK
/*
@@ -999,13 +1000,16 @@ void gbaudio_unregister_module(struct 
gbaudio_module_info *module)
if (module->controls) {
dev_dbg(comp->dev, "Removing %d controls\n",
module->num_controls);
-   snd_soc_remove_codec_controls(comp, module->controls,
- module->num_controls);
+   /* release control semaphore */
+   up_write(&card->controls_rwsem);
+   gbaudio_remove_component_controls(comp, module->controls,
+ module->num_controls);
+   down_write(&card->controls_rwsem);
}
if (module->dapm_widgets) {
dev_dbg(comp->dev, "Removing %d widgets\n",
module->num_dapm_widgets);
-   snd_soc_dapm_free_controls(&comp->dapm, module->dapm_widgets,
+   gbaudio_dapm_free_controls(&comp->dapm, module->dapm_widgets,
   module->num_dapm_widgets);
}
 
diff --git a/drivers/staging/greybus/audio_helper.c 
b/drivers/staging/greybus/audio_helper.c
new file mode 100644
index ..faaa39708118
--- /dev/null
+++ b/drivers/staging/greybus/audio_helper.c
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Greybus Audio Sound SoC helper APIs
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#define gbaudio_dapm_for_each_direction(dir) \
+   for ((dir) = SND_SOC_DAPM_DIR_IN; (dir) <= SND_SOC_DAPM_DIR_OUT; \
+   (dir)++)
+
+static void gbaudio_dapm_link_dai_widget(struct snd_soc_dapm_widget *dai_w,
+struct snd_soc_card *card)
+{
+   struct snd_soc_dapm_widget *w;
+   struct snd_soc_dapm_widget *src, *sink;
+   struct snd_soc_dai *dai = dai_w->priv;
+
+   /* ...find all widgets with the same stream and link them */
+   list_for_each_entry(w, &card->widgets, list) {
+   if (w->dapm != dai_w->dapm)
+   continue;
+
+   switch (w->id) {
+   case snd_soc_dapm_dai_in:
+   case snd_soc_dapm_dai_out:
+   continue;
+   default:
+   break;
+   }
+
+   if (!w->sname || !strstr(w->sname, dai_w->sname))
+   continue;
+
+   /*
+* check if widget is already linked,
+* if (w->linked)
+*  return;
+*/
+
+   if (dai_w->id == snd_soc_dapm_dai_in) {
+   src = dai_w;
+   sink = w;
+   } else {

[PATCH v3 2/6] staging: greybus: audio: Maintain jack list within GB Audio module

2020-06-19 Thread Vaibhav Agarwal
As per the current implementation for GB codec driver, a jack list is
maintained for each module. And it expects the list to be populated by
the snd_soc_jack structure which would require modifications in
mainstream code.

However, this is not a necessary requirement and the list can be easily
maintained within gbaudio_module_info as well. This patch provides the
relevant changes for the same.

Signed-off-by: Vaibhav Agarwal 
Reviewed-by: Dan Carpenter 
---
 drivers/staging/greybus/audio_codec.c  | 74 +-
 drivers/staging/greybus/audio_codec.h  | 10 +++-
 drivers/staging/greybus/audio_module.c | 15 +++---
 3 files changed, 53 insertions(+), 46 deletions(-)

diff --git a/drivers/staging/greybus/audio_codec.c 
b/drivers/staging/greybus/audio_codec.c
index 5d3a5e6a8fe6..6dc4ee2bfb37 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -712,6 +712,7 @@ static int gbaudio_init_jack(struct gbaudio_module_info 
*module,
 struct snd_soc_card *card)
 {
int ret;
+   struct gbaudio_jack *jack, *n;
struct snd_soc_jack_pin *headset, *button;
 
if (!module->jack_mask)
@@ -726,14 +727,16 @@ static int gbaudio_init_jack(struct gbaudio_module_info 
*module,
 
headset->pin = module->jack_name;
headset->mask = module->jack_mask;
-
ret = snd_soc_card_jack_new(card, module->jack_name, module->jack_mask,
-   &module->headset_jack, headset, 1);
+   &module->headset.jack, headset, 1);
if (ret) {
dev_err(module->dev, "Failed to create new jack\n");
return ret;
}
 
+   /* Add to module's jack list */
+   list_add(&module->headset.list, &module->jack_list);
+
if (!module->button_mask)
return 0;
 
@@ -742,20 +745,22 @@ static int gbaudio_init_jack(struct gbaudio_module_info 
*module,
button = devm_kzalloc(module->dev, sizeof(*button), GFP_KERNEL);
if (!button) {
ret = -ENOMEM;
-   goto free_headset;
+   goto free_jacks;
}
 
button->pin = module->button_name;
button->mask = module->button_mask;
-
ret = snd_soc_card_jack_new(card, module->button_name,
-   module->button_mask, &module->button_jack,
+   module->button_mask, &module->button.jack,
button, 1);
if (ret) {
dev_err(module->dev, "Failed to create button jack\n");
-   goto free_headset;
+   goto free_jacks;
}
 
+   /* Add to module's jack list */
+   list_add(&module->button.list, &module->jack_list);
+
/*
 * Currently, max 4 buttons are supported with following key mapping
 * BTN_0 = KEY_MEDIA
@@ -765,56 +770,54 @@ static int gbaudio_init_jack(struct gbaudio_module_info 
*module,
 */
 
if (module->button_mask & SND_JACK_BTN_0) {
-   ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_0,
+   ret = snd_jack_set_key(module->button.jack.jack, SND_JACK_BTN_0,
   KEY_MEDIA);
if (ret) {
dev_err(module->dev, "Failed to set BTN_0\n");
-   goto free_button;
+   goto free_jacks;
}
}
 
if (module->button_mask & SND_JACK_BTN_1) {
-   ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_1,
+   ret = snd_jack_set_key(module->button.jack.jack, SND_JACK_BTN_1,
   KEY_VOICECOMMAND);
if (ret) {
dev_err(module->dev, "Failed to set BTN_1\n");
-   goto free_button;
+   goto free_jacks;
}
}
 
if (module->button_mask & SND_JACK_BTN_2) {
-   ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_2,
+   ret = snd_jack_set_key(module->button.jack.jack, SND_JACK_BTN_2,
   KEY_VOLUMEUP);
if (ret) {
dev_err(module->dev, "Failed to set BTN_2\n");
-   goto free_button;
+   goto free_jacks;
}
}
 
if (module->button_mask & SND_JACK_BTN_3) {
-   ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_3,
+   ret = snd_jack_set_key(module->button.jack.jack, SND_JACK_BTN_3,
   KEY_VOLUMEDOWN);
if (ret) {
dev_err(module->dev, "Failed to set BTN_0\n");
-   goto free_button;
+   goto free_jacks;
}
}
 
/* FIXME
 * verify if this is 

[PATCH v3 3/6] staging: greybus: audio: Resolve compilation errors for GB codec module

2020-06-19 Thread Vaibhav Agarwal
Due to dependencies on ASoC framework changes, GB dummy codec module
compilation is currently disabled. This patch updates codec driver as
per the latest ASoC APIs.

Signed-off-by: Vaibhav Agarwal 
Reviewed-by: Dan Carpenter 
---
 drivers/staging/greybus/audio_codec.c | 88 +--
 drivers/staging/greybus/audio_codec.h |  2 +-
 2 files changed, 44 insertions(+), 46 deletions(-)

diff --git a/drivers/staging/greybus/audio_codec.c 
b/drivers/staging/greybus/audio_codec.c
index 6dc4ee2bfb37..0ecdba27086b 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -825,7 +825,7 @@ static int gbaudio_init_jack(struct gbaudio_module_info 
*module,
 int gbaudio_register_module(struct gbaudio_module_info *module)
 {
int ret;
-   struct snd_soc_codec *codec;
+   struct snd_soc_component *comp;
struct snd_card *card;
struct gbaudio_jack *jack = NULL;
 
@@ -834,8 +834,8 @@ int gbaudio_register_module(struct gbaudio_module_info 
*module)
return -EAGAIN;
}
 
-   codec = gbcodec->codec;
-   card = codec->card->snd_card;
+   comp = gbcodec->component;
+   card = comp->card->snd_card;
 
down_write(&card->controls_rwsem);
 
@@ -847,33 +847,33 @@ int gbaudio_register_module(struct gbaudio_module_info 
*module)
return -EINVAL;
}
 
-   ret = gbaudio_init_jack(module, component->card);
+   ret = gbaudio_init_jack(module, comp->card);
if (ret) {
up_write(&card->controls_rwsem);
return ret;
}
 
if (module->dapm_widgets)
-   snd_soc_dapm_new_controls(&codec->dapm, module->dapm_widgets,
+   snd_soc_dapm_new_controls(&comp->dapm, module->dapm_widgets,
  module->num_dapm_widgets);
if (module->controls)
-   snd_soc_add_codec_controls(codec, module->controls,
-  module->num_controls);
+   snd_soc_add_component_controls(comp, module->controls,
+  module->num_controls);
if (module->dapm_routes)
-   snd_soc_dapm_add_routes(&codec->dapm, module->dapm_routes,
+   snd_soc_dapm_add_routes(&comp->dapm, module->dapm_routes,
module->num_dapm_routes);
 
/* card already instantiated, create widgets here only */
-   if (codec->card->instantiated) {
-   snd_soc_dapm_link_component_dai_widgets(codec->card,
-   &codec->dapm);
+   if (comp->card->instantiated) {
+   snd_soc_dapm_link_component_dai_widgets(comp->card,
+   &comp->dapm);
 #ifdef CONFIG_SND_JACK
/*
 * register jack devices for this module
 * from codec->jack_list
 */
list_for_each_entry(jack, &module->jack_list, list) {
-   snd_device_register(codec->card->snd_card,
+   snd_device_register(comp->card->snd_card,
jack->jack.jack);
}
 #endif
@@ -883,9 +883,9 @@ int gbaudio_register_module(struct gbaudio_module_info 
*module)
list_add(&module->list, &gbcodec->module_list);
mutex_unlock(&gbcodec->lock);
 
-   if (codec->card->instantiated)
-   ret = snd_soc_dapm_new_widgets(&codec->dapm);
-   dev_dbg(codec->dev, "Registered %s module\n", module->name);
+   if (comp->card->instantiated)
+   ret = snd_soc_dapm_new_widgets(comp->card);
+   dev_dbg(comp->dev, "Registered %s module\n", module->name);
 
up_write(&card->controls_rwsem);
return ret;
@@ -956,18 +956,18 @@ static void gbaudio_codec_cleanup(struct 
gbaudio_module_info *module)
 
 void gbaudio_unregister_module(struct gbaudio_module_info *module)
 {
-   struct snd_soc_codec *codec = gbcodec->codec;
-   struct snd_card *card = codec->card->snd_card;
+   struct snd_soc_component *comp = gbcodec->component;
+   struct snd_card *card = comp->card->snd_card;
struct gbaudio_jack *jack, *n;
int mask;
 
-   dev_dbg(codec->dev, "Unregister %s module\n", module->name);
+   dev_dbg(comp->dev, "Unregister %s module\n", module->name);
 
down_write(&card->controls_rwsem);
mutex_lock(&gbcodec->lock);
gbaudio_codec_cleanup(module);
list_del(&module->list);
-   dev_dbg(codec->dev, "Process Unregister %s module\n", module->name);
+   dev_dbg(comp->dev, "Process Unregister %s module\n", module->name);
mutex_unlock(&gbcodec->lock);
 
 #ifdef CONFIG_SND_JACK
@@ -983,99 +983,97 @@ void gbaudio_unregister_module(struct gbaudio_module_info 
*module)
dev_dbg(module->dev, "Report %s removal\n",
  

[PATCH] media: allegro: Fix some NULL vs IS_ERR() checks in probe

2020-06-19 Thread Dan Carpenter
The devm_ioremap() function doesn't return error pointers, it returns
NULL on error.

Fixes: f20387dfd065 ("media: allegro: add Allegro DVT video IP core driver")
Signed-off-by: Dan Carpenter 
---
 drivers/staging/media/allegro-dvt/allegro-core.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/media/allegro-dvt/allegro-core.c 
b/drivers/staging/media/allegro-dvt/allegro-core.c
index 70f133a842dd..3ed66aae741d 100644
--- a/drivers/staging/media/allegro-dvt/allegro-core.c
+++ b/drivers/staging/media/allegro-dvt/allegro-core.c
@@ -3065,9 +3065,9 @@ static int allegro_probe(struct platform_device *pdev)
return -EINVAL;
}
regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
-   if (IS_ERR(regs)) {
+   if (!regs) {
dev_err(&pdev->dev, "failed to map registers\n");
-   return PTR_ERR(regs);
+   return -ENOMEM;
}
dev->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
&allegro_regmap_config);
@@ -3085,9 +3085,9 @@ static int allegro_probe(struct platform_device *pdev)
sram_regs = devm_ioremap(&pdev->dev,
 sram_res->start,
 resource_size(sram_res));
-   if (IS_ERR(sram_regs)) {
+   if (!sram_regs) {
dev_err(&pdev->dev, "failed to map sram\n");
-   return PTR_ERR(sram_regs);
+   return -ENOMEM;
}
dev->sram = devm_regmap_init_mmio(&pdev->dev, sram_regs,
  &allegro_sram_config);
-- 
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[bug report] staging: vchiq_arm: use list_for_each_entry when accessing bulk_waiter_list

2020-06-19 Thread Dan Carpenter
Hello Nicolas Saenz Julienne,

The patch 46e4b9ec4fa4: "staging: vchiq_arm: use list_for_each_entry
when accessing bulk_waiter_list" from Nov 20, 2018, leads to the
following static checker warning:

drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c:427 
vchiq_blocking_bulk_transfer()
warn: iterator used outside loop: 'waiter'

drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
   417  mutex_lock(&instance->bulk_waiter_list_mutex);
   418  list_for_each_entry(waiter, &instance->bulk_waiter_list, list) {
^^
The list iterator is always non-NULL.

   419  if (waiter->pid == current->pid) {
   420  list_del(&waiter->list);
   421  break;
   422  }
   423  }
   424  mutex_unlock(&instance->bulk_waiter_list_mutex);
   425  
   426  if (waiter) {
^^
In the original code "waiter" was only non-NULL if we found the correct
pid, but now it's always non-NULL.

   427  struct vchiq_bulk *bulk = waiter->bulk_waiter.bulk;
   428  
   429  if (bulk) {
   430  /* This thread has an outstanding bulk 
transfer. */
   431  if ((bulk->data != data) ||
   432  (bulk->size != size)) {
   433  /* This is not a retry of the previous 
one.
   434   * Cancel the signal when the transfer
   435   * completes.
   436   */
   437  spin_lock(&bulk_waiter_spinlock);
   438  bulk->userdata = NULL;
   439  spin_unlock(&bulk_waiter_spinlock);
   440  }
   441  }
   442  }
   443  
   444  if (!waiter) {
^^^
This is dead code now.  I'm a bit surprised this bug didn't show up
during testing.

   445  waiter = kzalloc(sizeof(struct bulk_waiter_node), 
GFP_KERNEL);
   446  if (!waiter) {
   447  vchiq_log_error(vchiq_core_log_level,
   448  "%s - out of memory", __func__);
   449  return VCHIQ_ERROR;
   450  }
   451  }
   452  
   453  status = vchiq_bulk_transfer(handle, data, size, 
&waiter->bulk_waiter,

regards,
dan carpenter
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: rtl8188eu: use common packet header constants

2020-06-19 Thread Michael Straube
The driver replicates the definitions of rfc1042_header and
bridge_tunnel_header available from cfg80211.h. Use the common
ones from cfg80211.h.

Signed-off-by: Michael Straube 
---
 drivers/staging/rtl8188eu/core/rtw_recv.c | 18 +-
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c 
b/drivers/staging/rtl8188eu/core/rtw_recv.c
index a036ef104198..0257e56b551a 100644
--- a/drivers/staging/rtl8188eu/core/rtw_recv.c
+++ b/drivers/staging/rtl8188eu/core/rtw_recv.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #define ETHERNET_HEADER_SIZE   14  /*  Ethernet Header Length */
 #define LLC_HEADER_SIZE6   /*  LLC Header Length */
@@ -22,15 +23,6 @@
 static u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37};
 static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3};
 
-/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
-static u8 rtw_bridge_tunnel_header[] = {
-   0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8
-};
-
-static u8 rtw_rfc1042_header[] = {
-   0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00
-};
-
 static void rtw_signal_stat_timer_hdl(struct timer_list *t);
 
 void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
@@ -1277,10 +1269,10 @@ static int wlanhdr_to_ethhdr(struct recv_frame 
*precvframe)
psnap = (struct ieee80211_snap_hdr *)(ptr+pattrib->hdrlen + 
pattrib->iv_len);
psnap_type = ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE;
/* convert hdr + possible LLC headers into Ethernet header */
-   if ((!memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) &&
+   if ((!memcmp(psnap, rfc1042_header, SNAP_SIZE) &&
 memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) &&
 memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2)) ||
-!memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) {
+!memcmp(psnap, bridge_tunnel_header, SNAP_SIZE)) {
/* remove RFC1042 or Bridge-Tunnel encapsulation and replace 
EtherType */
bsnaphdr = true;
} else {
@@ -1560,9 +1552,9 @@ static int amsdu_to_msdu(struct adapter *padapter, struct 
recv_frame *prframe)
/* convert hdr + possible LLC headers into Ethernet header */
eth_type = get_unaligned_be16(&sub_skb->data[6]);
if (sub_skb->len >= 8 &&
-   ((!memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE) &&
+   ((!memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) &&
  eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
-!memcmp(sub_skb->data, rtw_bridge_tunnel_header, 
SNAP_SIZE))) {
+!memcmp(sub_skb->data, bridge_tunnel_header, 
SNAP_SIZE))) {
/* remove RFC1042 or Bridge-Tunnel encapsulation and 
replace EtherType */
skb_pull(sub_skb, SNAP_SIZE);
memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, 
ETH_ALEN);
-- 
2.27.0

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v3 6/6] staging: greybus: audio: Enable GB codec, audio module compilation.

2020-06-19 Thread kernel test robot
Hi Vaibhav,

I love your patch! Perhaps something to improve:

[auto build test WARNING on 98fe05e21a6e0ca242e974650ed58b64813cb2dc]

url:
https://github.com/0day-ci/linux/commits/Vaibhav-Agarwal/Enable-Greybus-Audio-codec-driver/20200619-192443
base:98fe05e21a6e0ca242e974650ed58b64813cb2dc
config: nds32-randconfig-r002-20200619 (attached as .config)
compiler: nds32le-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross 
ARCH=nds32 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>, old ones prefixed by <<):

>> drivers/staging/greybus/audio_helper.c:59:5: warning: no previous prototype 
>> for 'gbaudio_dapm_link_component_dai_widgets' [-Wmissing-prototypes]
59 | int gbaudio_dapm_link_component_dai_widgets(struct snd_soc_card *card,
| ^~~
>> drivers/staging/greybus/audio_helper.c:112:5: warning: no previous prototype 
>> for 'gbaudio_dapm_free_controls' [-Wmissing-prototypes]
112 | int gbaudio_dapm_free_controls(struct snd_soc_dapm_context *dapm,
| ^~
>> drivers/staging/greybus/audio_helper.c:189:5: warning: no previous prototype 
>> for 'gbaudio_remove_component_controls' [-Wmissing-prototypes]
189 | int gbaudio_remove_component_controls(struct snd_soc_component *component,
| ^
--
drivers/staging/greybus/audio_topology.c: In function 'find_gb_module':
>> drivers/staging/greybus/audio_topology.c:31:14: warning: variable 'ret' set 
>> but not used [-Wunused-but-set-variable]
31 |  int dev_id, ret;
|  ^~~
drivers/staging/greybus/audio_topology.c: In function 
'gbcodec_mixer_dapm_ctl_get':
>> drivers/staging/greybus/audio_topology.c:380:33: warning: variable 'info' 
>> set but not used [-Wunused-but-set-variable]
380 |  struct gb_audio_ctl_elem_info *info;
| ^~~~

vim +/gbaudio_dapm_link_component_dai_widgets +59 
drivers/staging/greybus/audio_helper.c

1939631ddc545a7 Vaibhav Agarwal 2020-06-19   58  
1939631ddc545a7 Vaibhav Agarwal 2020-06-19  @59  int 
gbaudio_dapm_link_component_dai_widgets(struct snd_soc_card *card,
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   60 
struct snd_soc_dapm_context *dapm)
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   61  {
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   62 struct 
snd_soc_dapm_widget *dai_w;
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   63  
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   64 /* For each DAI 
widget... */
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   65 
list_for_each_entry(dai_w, &card->widgets, list) {
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   66 if (dai_w->dapm 
!= dapm)
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   67 
continue;
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   68 switch 
(dai_w->id) {
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   69 case 
snd_soc_dapm_dai_in:
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   70 case 
snd_soc_dapm_dai_out:
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   71 break;
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   72 default:
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   73 
continue;
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   74 }
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   75 
gbaudio_dapm_link_dai_widget(dai_w, card);
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   76 }
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   77  
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   78 return 0;
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   79  }
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   80  
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   81  static void 
gbaudio_dapm_free_path(struct snd_soc_dapm_path *path)
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   82  {
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   83 
list_del(&path->list_node[SND_SOC_DAPM_DIR_IN]);
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   84 
list_del(&path->list_node[SND_SOC_DAPM_DIR_OUT]);
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   85 
list_del(&path->list_kcontrol);
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   86 list_del(&path->list);
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   87 kfree(path);
1939631ddc545a7 Vaibhav Agarwal 2020-06-19   88  }
1939631ddc545a7 Vaibhav Agarwal