From 47c4cc08cb5b34e93ab337b924c5ede77ca3c936 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 4 Apr 2019 17:27:20 +0100 Subject: [PATCH 01/11] ASoC: cs35l35: Disable regulators on driver removal The chips main power supplies VA and VP are enabled during probe but then never disabled, this will cause warnings from the regulator framework on driver removal. Fix this by adding a remove callback and disabling the supplies, whilst doing so follow best practice and put the chip back into reset as well. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l35.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/codecs/cs35l35.c b/sound/soc/codecs/cs35l35.c index 9f4a59871cee..c71696146c5e 100644 --- a/sound/soc/codecs/cs35l35.c +++ b/sound/soc/codecs/cs35l35.c @@ -1635,6 +1635,16 @@ err: return ret; } +static int cs35l35_i2c_remove(struct i2c_client *i2c_client) +{ + struct cs35l35_private *cs35l35 = i2c_get_clientdata(i2c_client); + + regulator_bulk_disable(cs35l35->num_supplies, cs35l35->supplies); + gpiod_set_value_cansleep(cs35l35->reset_gpio, 0); + + return 0; +} + static const struct of_device_id cs35l35_of_match[] = { {.compatible = "cirrus,cs35l35"}, {}, @@ -1655,6 +1665,7 @@ static struct i2c_driver cs35l35_i2c_driver = { }, .id_table = cs35l35_id, .probe = cs35l35_i2c_probe, + .remove = cs35l35_i2c_remove, }; module_i2c_driver(cs35l35_i2c_driver); From 2e05ddd2c9f8000751d52fcf35b8318da46026bc Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 4 Apr 2019 17:30:39 -0700 Subject: [PATCH 02/11] ASoC: intel: skylake: add remove() callback for component driver Topology is not unloaded in the core during unregister_component() anymore. So, add the remove() callback that will unload the topology. Signed-off-by: Ranjani Sridharan Signed-off-by: Mark Brown --- sound/soc/intel/skylake/skl-pcm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 56099db8f86d..57031b6d4d45 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -1462,9 +1462,16 @@ static int skl_platform_soc_probe(struct snd_soc_component *component) return 0; } +static void skl_pcm_remove(struct snd_soc_component *component) +{ + /* remove topology */ + snd_soc_tplg_component_remove(component, SND_SOC_TPLG_INDEX_ALL); +} + static const struct snd_soc_component_driver skl_component = { .name = "pcm", .probe = skl_platform_soc_probe, + .remove = skl_pcm_remove, .ops = &skl_platform_ops, .pcm_new = skl_pcm_new, .pcm_free = skl_pcm_free, From 54f8844e3f6cf898450a6c85f70fa997f0aa72b9 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 4 Apr 2019 19:48:33 -0700 Subject: [PATCH 03/11] ASoC: topology: Use the correct dobj to free enum control values and texts The control values and texts of the enum kcontrol associated with a widget need to be freed when the widget is removed. However, both struct snd_soc_dapm_widget and struct soc_enum contain a dobj member, which resulted in a confusion. The existing code generates a null pointer dereference by attempting to free the values and texts from the dobj which belongs to the widget instead of the dobj belonging to the enum kcontrol. The suggested fix is to use the correct dobj member (se->dobj) of the enum kcontrol. Signed-off-by: Ranjani Sridharan Signed-off-by: Mark Brown --- sound/soc/soc-topology.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index 25fca7055464..96852d250619 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -482,10 +482,11 @@ static void remove_widget(struct snd_soc_component *comp, snd_ctl_remove(card, kcontrol); - kfree(dobj->control.dvalues); + /* free enum kcontrol's dvalues and dtexts */ + kfree(se->dobj.control.dvalues); for (j = 0; j < se->items; j++) - kfree(dobj->control.dtexts[j]); - kfree(dobj->control.dtexts); + kfree(se->dobj.control.dtexts[j]); + kfree(se->dobj.control.dtexts); kfree(se); kfree(w->kcontrol_news[i].name); From 17d3069ccf06970e2db3f7cbf4335f207524279e Mon Sep 17 00:00:00 2001 From: Arnaud Pouliquen Date: Fri, 5 Apr 2019 11:19:11 +0200 Subject: [PATCH 04/11] ASoC: stm32: fix sai driver name initialisation This patch fixes the sai driver structure overwriting which results in a cpu dai name equal NULL. Fixes: 3e086ed ("ASoC: stm32: add SAI driver") Signed-off-by: Arnaud Pouliquen Signed-off-by: Mark Brown --- sound/soc/stm/stm32_sai_sub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/stm/stm32_sai_sub.c b/sound/soc/stm/stm32_sai_sub.c index 55d802f51c15..83d8a7ac56f4 100644 --- a/sound/soc/stm/stm32_sai_sub.c +++ b/sound/soc/stm/stm32_sai_sub.c @@ -1419,7 +1419,6 @@ static int stm32_sai_sub_dais_init(struct platform_device *pdev, if (!sai->cpu_dai_drv) return -ENOMEM; - sai->cpu_dai_drv->name = dev_name(&pdev->dev); if (STM_SAI_IS_PLAYBACK(sai)) { memcpy(sai->cpu_dai_drv, &stm32_sai_playback_dai, sizeof(stm32_sai_playback_dai)); @@ -1429,6 +1428,7 @@ static int stm32_sai_sub_dais_init(struct platform_device *pdev, sizeof(stm32_sai_capture_dai)); sai->cpu_dai_drv->capture.stream_name = sai->cpu_dai_drv->name; } + sai->cpu_dai_drv->name = dev_name(&pdev->dev); return 0; } From b4ed6b51f356224c6c71540ed94087f7f09b84af Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Fri, 5 Apr 2019 09:57:08 -0700 Subject: [PATCH 05/11] ASoC: core: conditionally increase module refcount on component open Recently, for Intel platforms the "ignore_module_refcount" field was introduced for the component driver. In order to avoid a deadlock preventing the PCI modules from being removed even when the card was idle, the refcounts were not incremented for the device driver module during component probe. However, this change introduced a nasty side effect: the device driver module can be unloaded while a pcm stream is open. This patch proposes to change the field to be renamed as "module_get_upon_open". When this field is set, the module refcount should be incremented on pcm open amd decremented upon pcm close. This will enable modules to be removed when no PCM playback/capture happens and prevent removal when the component is actually in use. Also, align with the skylake component driver with the new name. Fixes: b450b878('ASoC: core: don't increase component module refcount unconditionally' Signed-off-by: Ranjani Sridharan Acked-by: Pierre-Louis Bossart Signed-off-by: Mark Brown --- include/sound/soc.h | 9 +++++++-- sound/soc/intel/skylake/skl-pcm.c | 2 +- sound/soc/soc-core.c | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 1e2be35ed36f..482b4ea87c3c 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -802,8 +802,13 @@ struct snd_soc_component_driver { int probe_order; int remove_order; - /* signal if the module handling the component cannot be removed */ - unsigned int ignore_module_refcount:1; + /* + * signal if the module handling the component should not be removed + * if a pcm is open. Setting this would prevent the module + * refcount being incremented in probe() but allow it be incremented + * when a pcm is opened and decremented when it is closed. + */ + unsigned int module_get_upon_open:1; /* bits */ unsigned int idle_bias_on:1; diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 57031b6d4d45..9735e2412251 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c @@ -1475,7 +1475,7 @@ static const struct snd_soc_component_driver skl_component = { .ops = &skl_platform_ops, .pcm_new = skl_pcm_new, .pcm_free = skl_pcm_free, - .ignore_module_refcount = 1, /* do not increase the refcount in core */ + .module_get_upon_open = 1, /* increment refcount when a pcm is opened */ }; int skl_platform_register(struct device *dev) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d88757659729..46e3ab0fced4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -947,7 +947,7 @@ static void soc_cleanup_component(struct snd_soc_component *component) snd_soc_dapm_free(snd_soc_component_get_dapm(component)); soc_cleanup_component_debugfs(component); component->card = NULL; - if (!component->driver->ignore_module_refcount) + if (!component->driver->module_get_upon_open) module_put(component->dev->driver->owner); } @@ -1381,7 +1381,7 @@ static int soc_probe_component(struct snd_soc_card *card, return 0; } - if (!component->driver->ignore_module_refcount && + if (!component->driver->module_get_upon_open && !try_module_get(component->dev->driver->owner)) return -ENODEV; From 52034add758e268c39110f33d46e2a9492e82aef Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Fri, 5 Apr 2019 09:57:09 -0700 Subject: [PATCH 06/11] ASoC: pcm: update module refcount if module_get_upon_open is set Setting the module_get_upon_open field for component driver prevents the module refcount from being incremented during component probe(). This could lead to the module being allowed to be unloaded when a pcm stream is open. So, if this field is set, the module's refcount should be incremented during pcm open to prevent module removal when the component is in use. And, the refcount should be decremented upon pcm close. Signed-off-by: Ranjani Sridharan Acked-by: Pierre-Louis Bossart Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 2d5d5cac4ba6..d21247546f7f 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -463,6 +464,9 @@ static int soc_pcm_components_close(struct snd_pcm_substream *substream, continue; component->driver->ops->close(substream); + + if (component->driver->module_get_upon_open) + module_put(component->dev->driver->owner); } return 0; @@ -513,6 +517,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) !component->driver->ops->open) continue; + if (component->driver->module_get_upon_open && + !try_module_get(component->dev->driver->owner)) + return -ENODEV; + ret = component->driver->ops->open(substream); if (ret < 0) { dev_err(component->dev, From 01c8327667c249818d3712c3e25c7ad2aca7f389 Mon Sep 17 00:00:00 2001 From: Libin Yang Date: Sat, 13 Apr 2019 21:18:12 +0800 Subject: [PATCH 07/11] ASoC: codec: hdac_hdmi add device_link to card device In resume from S3, HDAC HDMI codec driver dapm event callback may be operated before HDMI codec driver turns on the display audio power domain because of the contest between display driver and hdmi codec driver. This patch adds the device_link between soc card device (consumer) and hdmi codec device (supplier) to make sure the sequence is always correct. Signed-off-by: Libin Yang Reviewed-by: Takashi Iwai Acked-by: Pierre-Louis Bossart Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/codecs/hdac_hdmi.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 5eeb0fe836a9..4de1fbfa8827 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -1854,6 +1854,17 @@ static int hdmi_codec_probe(struct snd_soc_component *component) /* Imp: Store the card pointer in hda_codec */ hdmi->card = dapm->card->snd_card; + /* + * Setup a device_link between card device and HDMI codec device. + * The card device is the consumer and the HDMI codec device is + * the supplier. With this setting, we can make sure that the audio + * domain in display power will be always turned on before operating + * on the HDMI audio codec registers. + * Let's use the flag DL_FLAG_AUTOREMOVE_CONSUMER. This can make + * sure the device link is freed when the machine driver is removed. + */ + device_link_add(component->card->dev, &hdev->dev, DL_FLAG_RPM_ACTIVE | + DL_FLAG_AUTOREMOVE_CONSUMER); /* * hdac_device core already sets the state to active and calls * get_noresume. So enable runtime and set the device to suspend. From 66287def435315d9d8de740da4c543e37630b897 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 25 Apr 2019 15:16:58 +0900 Subject: [PATCH 08/11] ASoC: rsnd: fixup 6ch settings to 8ch rsnd need to use 8ch clock settings for 6ch for TDM. Otherwise, it can't work correctly. This patch fixup it. Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/core.c | 18 +++++++++++++----- sound/soc/sh/rcar/rsnd.h | 1 + sound/soc/sh/rcar/ssi.c | 2 ++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 4fe83e611c01..37cb61553d5f 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -300,6 +300,18 @@ int rsnd_runtime_channel_after_ctu_with_params(struct rsnd_dai_stream *io, return chan; } +int rsnd_channel_normalization(int chan) +{ + if ((chan > 8) || (chan < 0)) + return 0; + + /* TDM Extend Mode needs 8ch */ + if (chan == 6) + chan = 8; + + return chan; +} + int rsnd_runtime_channel_for_ssi_with_params(struct rsnd_dai_stream *io, struct snd_pcm_hw_params *params) { @@ -312,11 +324,7 @@ int rsnd_runtime_channel_for_ssi_with_params(struct rsnd_dai_stream *io, if (rsnd_runtime_is_multi_ssi(io)) chan /= rsnd_rdai_ssi_lane_get(rdai); - /* TDM Extend Mode needs 8ch */ - if (chan == 6) - chan = 8; - - return chan; + return rsnd_channel_normalization(chan); } int rsnd_runtime_is_multi_ssi(struct rsnd_dai_stream *io) diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 0e6ef4e18400..7727add3eb1a 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h @@ -446,6 +446,7 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai, struct device_node *playback, struct device_node *capture); +int rsnd_channel_normalization(int chan); #define rsnd_runtime_channel_original(io) \ rsnd_runtime_channel_original_with_params(io, NULL) int rsnd_runtime_channel_original_with_params(struct rsnd_dai_stream *io, diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index f5afab631abb..44bda210256e 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -303,6 +303,8 @@ static int rsnd_ssi_master_clk_start(struct rsnd_mod *mod, if (rsnd_runtime_is_tdm_split(io)) chan = rsnd_io_converted_chan(io); + chan = rsnd_channel_normalization(chan); + main_rate = rsnd_ssi_clk_query(rdai, rate, chan, &idx); if (!main_rate) { dev_err(dev, "unsupported clock rate\n"); From 0bbf4084e0cfbbbff8673f3b9867778d5d4b1d6f Mon Sep 17 00:00:00 2001 From: Fabien Dessenne Date: Wed, 24 Apr 2019 17:28:44 +0200 Subject: [PATCH 09/11] ASoC: stm32: i2s: return the get_irq error During probe, return the "get_irq" error value instead of -ENOENT. This allows the driver to be deferred probed if needed. Signed-off-by: Fabien Dessenne Signed-off-by: Mark Brown --- sound/soc/stm/stm32_i2s.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c index 8968458eec62..e707d28cb203 100644 --- a/sound/soc/stm/stm32_i2s.c +++ b/sound/soc/stm/stm32_i2s.c @@ -845,8 +845,9 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev, /* Get irqs */ irq = platform_get_irq(pdev, 0); if (irq < 0) { - dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); - return -ENOENT; + if (irq != -EPROBE_DEFER) + dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); + return irq; } ret = devm_request_irq(&pdev->dev, irq, stm32_i2s_isr, IRQF_ONESHOT, From c46ab1510de1d3dd9871ae36fbec0da3e0d2d6c5 Mon Sep 17 00:00:00 2001 From: Xun Zhang Date: Fri, 19 Apr 2019 15:53:49 -0500 Subject: [PATCH 10/11] ASoC: codecs: rt5682: initialize mutex before using In rt5682 codec driver, a mutex called "calibrate_mutex" is used in rt5682_calibrate() before initialization, which causes warning in lock debug. Move the initialization before the usage of mutex. Signed-off-by: Xun Zhang Signed-off-by: Pierre-Louis Bossart Signed-off-by: Mark Brown --- sound/soc/codecs/rt5682.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index 86a7fa31c294..505fb3d7b1c5 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -2588,6 +2588,7 @@ static int rt5682_i2c_probe(struct i2c_client *i2c, rt5682_reset(rt5682->regmap); + mutex_init(&rt5682->calibrate_mutex); rt5682_calibrate(rt5682); ret = regmap_multi_reg_write(rt5682->regmap, patch_list, @@ -2654,7 +2655,6 @@ static int rt5682_i2c_probe(struct i2c_client *i2c, INIT_DELAYED_WORK(&rt5682->jd_check_work, rt5682_jd_check_handler); - mutex_init(&rt5682->calibrate_mutex); if (i2c->irq) { ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, From 780f202f2bf48aaa09282efc4dd6c39a146cc1f3 Mon Sep 17 00:00:00 2001 From: KaiChieh Chuang Date: Fri, 26 Apr 2019 10:09:43 +0800 Subject: [PATCH 11/11] ASoC: mediatek: btcvsd fix irq mask disable = 1 enable = 0 prevent AP wake up, when not AP BTSCO scenario Signed-off-by: KaiChieh Chuang Signed-off-by: Mark Brown --- sound/soc/mediatek/common/mtk-btcvsd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/mediatek/common/mtk-btcvsd.c b/sound/soc/mediatek/common/mtk-btcvsd.c index 9a163d7064d1..bd55c546e790 100644 --- a/sound/soc/mediatek/common/mtk-btcvsd.c +++ b/sound/soc/mediatek/common/mtk-btcvsd.c @@ -193,13 +193,13 @@ static const u8 table_msbc_silence[SCO_PACKET_180] = { static void mtk_btcvsd_snd_irq_enable(struct mtk_btcvsd_snd *bt) { regmap_update_bits(bt->infra, bt->infra_misc_offset, - bt->conn_bt_cvsd_mask, bt->conn_bt_cvsd_mask); + bt->conn_bt_cvsd_mask, 0); } static void mtk_btcvsd_snd_irq_disable(struct mtk_btcvsd_snd *bt) { regmap_update_bits(bt->infra, bt->infra_misc_offset, - bt->conn_bt_cvsd_mask, 0); + bt->conn_bt_cvsd_mask, bt->conn_bt_cvsd_mask); } static void mtk_btcvsd_snd_set_state(struct mtk_btcvsd_snd *bt,