From ae1fbdff6dbcdfee9daee69fa1e7d26d1f31d1c7 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 30 Jun 2017 17:17:35 -0500 Subject: ASoC: imx-ssi: add check on platform_get_irq return value Check return value from call to platform_get_irq(), so in case of failure print error message and propagate the return value. Signed-off-by: Gustavo A. R. Silva Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/imx-ssi.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index b95132e2f9dc..06790615e04e 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c @@ -527,6 +527,10 @@ static int imx_ssi_probe(struct platform_device *pdev) } ssi->irq = platform_get_irq(pdev, 0); + if (ssi->irq < 0) { + dev_err(&pdev->dev, "Failed to get IRQ: %d\n", ssi->irq); + return ssi->irq; + } ssi->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(ssi->clk)) { -- cgit v1.2.3 From ac1ca3ba9faae7e32f189edda14f6f147053d719 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 9 Jul 2017 21:30:32 +0200 Subject: ASoC: pxa: SND_PXA2XX_SOC should depend on HAS_DMA If NO_DMA=y: ERROR: "bad_dma_ops" [sound/soc/pxa/snd-soc-pxa2xx.ko] undefined! ERROR: "bad_dma_ops" [sound/arm/snd-pxa2xx-lib.ko] undefined! ERROR: "dma_common_mmap" [sound/arm/snd-pxa2xx-lib.ko] undefined! Add a dependency on HAS_DMA to fix this. Fixes: 73d7ee2e831f106c ("ASoC: pxa: add COMPILE_TEST on SND_PXA2XX_SOC") Signed-off-by: Geert Uytterhoeven Acked-by: Robert Jarzmik Signed-off-by: Mark Brown --- sound/soc/pxa/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/soc') diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 960744e46edc..484ab3c2ad67 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -1,6 +1,7 @@ config SND_PXA2XX_SOC tristate "SoC Audio for the Intel PXA2xx chip" depends on ARCH_PXA || COMPILE_TEST + depends on HAS_DMA select SND_PXA2XX_LIB help Say Y or M if you want to add support for codecs attached to -- cgit v1.2.3 From b1cd2e34c69a2f3988786af451b6e17967c293a0 Mon Sep 17 00:00:00 2001 From: Banajit Goswami Date: Fri, 14 Jul 2017 23:15:05 -0700 Subject: ASoC: do not close shared backend dailink Multiple frontend dailinks may be connected to a backend dailink at the same time. When one of frontend dailinks is closed, the associated backend dailink should not be closed if it is connected to other active frontend dailinks. Change ensures that backend dailink is closed only after all connected frontend dailinks are closed. Signed-off-by: Gopikrishnaiah Anandan Signed-off-by: Banajit Goswami Signed-off-by: Patrick Lai Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/soc-pcm.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index dcc5ece08668..93999b8a87d3 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -181,6 +181,10 @@ int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, dev_dbg(be->dev, "ASoC: BE %s event %d dir %d\n", be->dai_link->name, event, dir); + if ((event == SND_SOC_DAPM_STREAM_STOP) && + (be->dpcm[dir].users >= 1)) + continue; + snd_soc_dapm_stream_event(be, dir, event); } -- cgit v1.2.3 From c641e5b207ed7dfaa692820aeb5b6dde3de3e9b0 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 12 Jul 2017 17:55:29 +0200 Subject: ASoC: fix pcm-creation regression This reverts commit 99b04f4c4051 ("ASoC: add Component level pcm_new/pcm_free"), which started calling the pcm_new callback for every component in a *card* when creating a new pcm, something which does not seem to make any sense. This specifically led to memory leaks in systems with more than one platform component and where DMA memory is allocated in the platform-driver callback. For example, when both mcasp devices are being used on an am335x board, DMA memory would be allocated twice for every DAI link during probe. When CONFIG_SND_VERBOSE_PROCFS was set this fortunately also led to warnings such as: WARNING: CPU: 0 PID: 565 at ../fs/proc/generic.c:346 proc_register+0x110/0x154 proc_dir_entry 'sub0/prealloc' already registered Since there seems to be no users of the new component callbacks, and the current implementation introduced a regression, let's revert the offending commit for now. Fixes: 99b04f4c4051 ("ASoC: add Component level pcm_new/pcm_free") Signed-off-by: Johan Hovold Reviewed-by: Linus Walleij Tested-by: Linus Walleij Signed-off-by: Mark Brown Cc: stable # 4.10 --- include/sound/soc.h | 6 ------ sound/soc/soc-core.c | 25 ------------------------- sound/soc/soc-pcm.c | 32 +++++++++----------------------- 3 files changed, 9 insertions(+), 54 deletions(-) (limited to 'sound/soc') diff --git a/include/sound/soc.h b/include/sound/soc.h index 9c94b97c17f8..c4a8b1947566 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -795,10 +795,6 @@ struct snd_soc_component_driver { int (*suspend)(struct snd_soc_component *); int (*resume)(struct snd_soc_component *); - /* pcm creation and destruction */ - int (*pcm_new)(struct snd_soc_pcm_runtime *); - void (*pcm_free)(struct snd_pcm *); - /* DT */ int (*of_xlate_dai_name)(struct snd_soc_component *component, struct of_phandle_args *args, @@ -874,8 +870,6 @@ struct snd_soc_component { void (*remove)(struct snd_soc_component *); int (*suspend)(struct snd_soc_component *); int (*resume)(struct snd_soc_component *); - int (*pcm_new)(struct snd_soc_pcm_runtime *); - void (*pcm_free)(struct snd_pcm *); /* machine specific init */ int (*init)(struct snd_soc_component *component); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 921622a01944..c240e13ba057 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3171,8 +3171,6 @@ static int snd_soc_component_initialize(struct snd_soc_component *component, component->remove = component->driver->remove; component->suspend = component->driver->suspend; component->resume = component->driver->resume; - component->pcm_new = component->driver->pcm_new; - component->pcm_free = component->driver->pcm_free; dapm = &component->dapm; dapm->dev = dev; @@ -3360,25 +3358,6 @@ static void snd_soc_platform_drv_remove(struct snd_soc_component *component) platform->driver->remove(platform); } -static int snd_soc_platform_drv_pcm_new(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_platform *platform = rtd->platform; - - if (platform->driver->pcm_new) - return platform->driver->pcm_new(rtd); - else - return 0; -} - -static void snd_soc_platform_drv_pcm_free(struct snd_pcm *pcm) -{ - struct snd_soc_pcm_runtime *rtd = pcm->private_data; - struct snd_soc_platform *platform = rtd->platform; - - if (platform->driver->pcm_free) - platform->driver->pcm_free(pcm); -} - /** * snd_soc_add_platform - Add a platform to the ASoC core * @dev: The parent device for the platform @@ -3402,10 +3381,6 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, platform->component.probe = snd_soc_platform_drv_probe; if (platform_drv->remove) platform->component.remove = snd_soc_platform_drv_remove; - if (platform_drv->pcm_new) - platform->component.pcm_new = snd_soc_platform_drv_pcm_new; - if (platform_drv->pcm_free) - platform->component.pcm_free = snd_soc_platform_drv_pcm_free; #ifdef CONFIG_DEBUG_FS platform->component.debugfs_prefix = "platform"; diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index dcc5ece08668..553f7a76743c 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2628,25 +2628,12 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream) return ret; } -static void soc_pcm_free(struct snd_pcm *pcm) -{ - struct snd_soc_pcm_runtime *rtd = pcm->private_data; - struct snd_soc_component *component; - - list_for_each_entry(component, &rtd->card->component_dev_list, - card_list) { - if (component->pcm_free) - component->pcm_free(pcm); - } -} - /* create a new pcm */ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) { struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_component *component; struct snd_pcm *pcm; char new_name[64]; int ret = 0, playback = 0, capture = 0; @@ -2756,18 +2743,17 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) if (capture) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops); - list_for_each_entry(component, &rtd->card->component_dev_list, card_list) { - if (component->pcm_new) { - ret = component->pcm_new(rtd); - if (ret < 0) { - dev_err(component->dev, - "ASoC: pcm constructor failed: %d\n", - ret); - return ret; - } + if (platform->driver->pcm_new) { + ret = platform->driver->pcm_new(rtd); + if (ret < 0) { + dev_err(platform->dev, + "ASoC: pcm constructor failed: %d\n", + ret); + return ret; } } - pcm->private_free = soc_pcm_free; + + pcm->private_free = platform->driver->pcm_free; out: dev_info(rtd->card->dev, "%s <-> %s mapping ok\n", (rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name, -- cgit v1.2.3 From 651e9268fb9b9944e063d731b09c0d2ad339bedb Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 12 Jul 2017 17:55:30 +0200 Subject: ASoC: ux500: Restore platform DAI assignments This reverts commit f1013cdeeeb9 ("ASoC: ux500: drop platform DAI assignments"), which seems to have been based on a misunderstanding and prevents the platform driver callbacks from being made (e.g. to preallocate DMA memory). The real culprit for the warnings about attempts to create duplicate procfs entries was commit 99b04f4c4051 ("ASoC: add Component level pcm_new/pcm_free" that broke PCM creation on systems that use more than one platform component. Fixes: f1013cdeeeb9 ("ASoC: ux500: drop platform DAI assignments") Signed-off-by: Johan Hovold Reviewed-by: Linus Walleij Tested-by: Linus Walleij Signed-off-by: Mark Brown Cc: stable # 4.11 --- sound/soc/ux500/mop500.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sound/soc') diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index b50f68a439ce..ba9fc099cf67 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c @@ -33,6 +33,7 @@ static struct snd_soc_dai_link mop500_dai_links[] = { .stream_name = "ab8500_0", .cpu_dai_name = "ux500-msp-i2s.1", .codec_dai_name = "ab8500-codec-dai.0", + .platform_name = "ux500-msp-i2s.1", .codec_name = "ab8500-codec.0", .init = mop500_ab8500_machine_init, .ops = mop500_ab8500_ops, @@ -42,6 +43,7 @@ static struct snd_soc_dai_link mop500_dai_links[] = { .stream_name = "ab8500_1", .cpu_dai_name = "ux500-msp-i2s.3", .codec_dai_name = "ab8500-codec-dai.1", + .platform_name = "ux500-msp-i2s.3", .codec_name = "ab8500-codec.0", .init = NULL, .ops = mop500_ab8500_ops, @@ -85,6 +87,8 @@ static int mop500_of_probe(struct platform_device *pdev, for (i = 0; i < 2; i++) { mop500_dai_links[i].cpu_of_node = msp_np[i]; mop500_dai_links[i].cpu_dai_name = NULL; + mop500_dai_links[i].platform_of_node = msp_np[i]; + mop500_dai_links[i].platform_name = NULL; mop500_dai_links[i].codec_of_node = codec_np; mop500_dai_links[i].codec_name = NULL; } -- cgit v1.2.3 From deab4563ad6a7f4668024455fa61b87f1d25ff73 Mon Sep 17 00:00:00 2001 From: Damien Riegel Date: Tue, 25 Jul 2017 13:51:24 -0400 Subject: ASoC: codecs: msm8916-analog: fix DIG_CLK_CTL_RXD3_CLK_EN define The wrong bit is assigned to DIG_CLK_CTL_RXD3_CLK_EN, change it for the correct one. Signed-off-by: Damien Riegel Acked-by: Srinivas Kandagatla Signed-off-by: Mark Brown --- sound/soc/codecs/msm8916-wcd-analog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index a78802920c3c..5710fd440bcd 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c @@ -36,7 +36,7 @@ #define CDC_D_CDC_DIG_CLK_CTL (0xf04A) #define DIG_CLK_CTL_RXD1_CLK_EN BIT(0) #define DIG_CLK_CTL_RXD2_CLK_EN BIT(1) -#define DIG_CLK_CTL_RXD3_CLK_EN BIT(3) +#define DIG_CLK_CTL_RXD3_CLK_EN BIT(2) #define DIG_CLK_CTL_TXD_CLK_EN BIT(4) #define DIG_CLK_CTL_NCP_CLK_EN_MASK BIT(6) #define DIG_CLK_CTL_NCP_CLK_EN BIT(6) -- cgit v1.2.3 From c0a480d1acf7dc184f9f3e7cf724483b0d28dc2e Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Fri, 28 Jul 2017 01:23:15 -0700 Subject: device property: Fix usecount for of_graph_get_port_parent() Fix inconsistent use of of_graph_get_port_parent() where asoc_simple_card_parse_graph_dai() does of_node_get() before calling it while other callers do not. We can fix this by not trashing the node passed to of_graph_get_port_parent(). Let's also make sure the callers have correct refcounts and remove related incorrect of_node_put() calls for of_for_each_phandle as that's done by of_phandle_iterator_next() except when we break out of the loop early. Let's fix both issues with a single patch to avoid kobject refcounts getting messed up more if two patches are merged separately. Otherwise strange issues can happen caused by memory corruption caused by too many kobject_del() calls such as: BUG: sleeping function called from invalid context at kernel/locking/mutex.c:747 ... (___might_sleep) (__mutex_lock) (mutex_lock_nested) (kernfs_remove) (kobject_del) (kobject_put) (of_get_next_parent) (of_graph_get_port_parent) (asoc_simple_card_parse_graph_dai [snd_soc_simple_card_utils]) (asoc_graph_card_probe [snd_soc_audio_graph_card]) Fixes: 0ef472a973eb ("of_graph: add of_graph_get_port_parent()") Fixes: 2692c1c63c29 ("ASoC: add audio-graph-card support") Fixes: 1689333f8311 ("ASoC: simple-card-utils: add asoc_simple_card_parse_graph_dai()") Signed-off-by: Tony Lindgren Reviewed-by: Rob Herring Tested-by: Antonio Borneo Tested-by: Kuninori Morimoto Signed-off-by: Mark Brown --- drivers/of/property.c | 17 +++++++++++++++-- sound/soc/generic/audio-graph-card.c | 10 +++++----- sound/soc/generic/audio-graph-scu-card.c | 15 +++++++++------ sound/soc/generic/simple-card-utils.c | 8 +++----- sound/soc/soc-core.c | 2 ++ 5 files changed, 34 insertions(+), 18 deletions(-) (limited to 'sound/soc') diff --git a/drivers/of/property.c b/drivers/of/property.c index eda50b4be934..067f9fab7b77 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -708,6 +708,15 @@ struct device_node *of_graph_get_port_parent(struct device_node *node) { unsigned int depth; + if (!node) + return NULL; + + /* + * Preserve usecount for passed in node as of_get_next_parent() + * will do of_node_put() on it. + */ + of_node_get(node); + /* Walk 3 levels up only if there is 'ports' node. */ for (depth = 3; depth && node; depth--) { node = of_get_next_parent(node); @@ -728,12 +737,16 @@ EXPORT_SYMBOL(of_graph_get_port_parent); struct device_node *of_graph_get_remote_port_parent( const struct device_node *node) { - struct device_node *np; + struct device_node *np, *pp; /* Get remote endpoint node. */ np = of_graph_get_remote_endpoint(node); - return of_graph_get_port_parent(np); + pp = of_graph_get_port_parent(np); + + of_node_put(np); + + return pp; } EXPORT_SYMBOL(of_graph_get_remote_port_parent); diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 105ec3a6e30d..de2550c7a96b 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -224,9 +224,11 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) of_for_each_phandle(&it, rc, node, "dais", NULL, 0) { ret = asoc_graph_card_dai_link_of(it.node, priv, idx++); - of_node_put(it.node); - if (ret < 0) + if (ret < 0) { + of_node_put(it.node); + return ret; + } } return asoc_simple_card_parse_card_name(card, NULL); @@ -239,10 +241,8 @@ static int asoc_graph_get_dais_count(struct device *dev) int count = 0; int rc; - of_for_each_phandle(&it, rc, node, "dais", NULL, 0) { + of_for_each_phandle(&it, rc, node, "dais", NULL, 0) count++; - of_node_put(it.node); - } return count; } diff --git a/sound/soc/generic/audio-graph-scu-card.c b/sound/soc/generic/audio-graph-scu-card.c index dcd2df37bc3b..758ac06f3a99 100644 --- a/sound/soc/generic/audio-graph-scu-card.c +++ b/sound/soc/generic/audio-graph-scu-card.c @@ -215,7 +215,6 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) codec_ep = of_graph_get_remote_endpoint(cpu_ep); rcpu_ep = of_graph_get_remote_endpoint(codec_ep); - of_node_put(cpu_port); of_node_put(cpu_ep); of_node_put(codec_ep); of_node_put(rcpu_ep); @@ -232,8 +231,10 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) ret = asoc_simple_card_parse_daifmt(dev, cpu_ep, codec_ep, NULL, &daifmt); - if (ret < 0) + if (ret < 0) { + of_node_put(cpu_port); goto parse_of_err; + } } dai_idx = 0; @@ -250,7 +251,6 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) codec_ep = of_graph_get_remote_endpoint(cpu_ep); codec_port = of_graph_get_port_parent(codec_ep); - of_node_put(cpu_port); of_node_put(cpu_ep); of_node_put(codec_ep); of_node_put(codec_port); @@ -266,13 +266,17 @@ static int asoc_graph_card_parse_of(struct graph_card_data *priv) /* Back-End (= Codec) */ ret = asoc_graph_card_dai_link_of(codec_ep, priv, daifmt, dai_idx++, 0); - if (ret < 0) + if (ret < 0) { + of_node_put(cpu_port); goto parse_of_err; + } } else { /* Front-End (= CPU) */ ret = asoc_graph_card_dai_link_of(cpu_ep, priv, daifmt, dai_idx++, 1); - if (ret < 0) + if (ret < 0) { + of_node_put(cpu_port); goto parse_of_err; + } } } } @@ -306,7 +310,6 @@ static int asoc_graph_get_dais_count(struct device *dev) codec_ep = of_graph_get_remote_endpoint(cpu_ep); codec_port = of_graph_get_port_parent(codec_ep); - of_node_put(cpu_port); of_node_put(cpu_ep); of_node_put(codec_ep); of_node_put(codec_port); diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index 26d64fa40c9c..7d7ab4aee42e 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -263,6 +263,9 @@ static int asoc_simple_card_get_dai_id(struct device_node *ep) id = i; i++; } + + of_node_put(node); + if (id < 0) return -ENODEV; @@ -282,11 +285,6 @@ int asoc_simple_card_parse_graph_dai(struct device_node *ep, if (!dai_name) return 0; - /* - * of_graph_get_port_parent() will call - * of_node_put(). So, call of_node_get() here - */ - of_node_get(ep); node = of_graph_get_port_parent(ep); /* Get dai->name */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 921622a01944..0cf8498fa36c 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4113,6 +4113,8 @@ int snd_soc_get_dai_id(struct device_node *ep) } mutex_unlock(&client_mutex); + of_node_put(node); + return ret; } EXPORT_SYMBOL_GPL(snd_soc_get_dai_id); -- cgit v1.2.3