diff options
| author | Mark Brown <broonie@kernel.org> | 2026-07-16 15:25:13 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-07-16 15:25:13 +0100 |
| commit | 1d3302efe653df4c66a47126e9b8abcfdb027ee5 (patch) | |
| tree | 67d20a2244224b4f11c866e831c73eb7381aaa69 | |
| parent | 7dcf091da4b4596f7dbfb403d946ee4aac423af3 (diff) | |
| parent | e0bffb63a2eda0af82ed7e6357ac67c2db990c21 (diff) | |
ASoC: cs35l56: Fixes for deadlock/hang during component_probe()
Richard Fitzgerald <rf@opensource.cirrus.com> says:
This series fixes two problems found in the probing process that
can cause a deadlock (patch #1) or a hang (patch #2) during
component_probe() until the wait for init_completion times out.
Link: https://patch.msgid.link/20260716132045.1469156-1-rf@opensource.cirrus.com
| -rw-r--r-- | sound/soc/codecs/cs35l56-i2c.c | 4 | ||||
| -rw-r--r-- | sound/soc/codecs/cs35l56-spi.c | 4 | ||||
| -rw-r--r-- | sound/soc/codecs/cs35l56.c | 17 |
3 files changed, 18 insertions, 7 deletions
diff --git a/sound/soc/codecs/cs35l56-i2c.c b/sound/soc/codecs/cs35l56-i2c.c index 0f64ab628b03..4f6ddf1c5a3f 100644 --- a/sound/soc/codecs/cs35l56-i2c.c +++ b/sound/soc/codecs/cs35l56-i2c.c @@ -55,9 +55,7 @@ static int cs35l56_i2c_probe(struct i2c_client *client) if (ret != 0) return ret; - ret = cs35l56_init(cs35l56); - if (ret == 0) - ret = cs35l56_irq_request(&cs35l56->base, client->irq); + ret = cs35l56_irq_request(&cs35l56->base, client->irq); if (ret < 0) cs35l56_remove(cs35l56); diff --git a/sound/soc/codecs/cs35l56-spi.c b/sound/soc/codecs/cs35l56-spi.c index 9bc9b7c98390..b1eb924a5b6c 100644 --- a/sound/soc/codecs/cs35l56-spi.c +++ b/sound/soc/codecs/cs35l56-spi.c @@ -44,9 +44,7 @@ static int cs35l56_spi_probe(struct spi_device *spi) if (ret != 0) return ret; - ret = cs35l56_init(cs35l56); - if (ret == 0) - ret = cs35l56_irq_request(&cs35l56->base, spi->irq); + ret = cs35l56_irq_request(&cs35l56->base, spi->irq); if (ret < 0) cs35l56_remove(cs35l56); diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c index 570a68829ccd..063ef7a70de0 100644 --- a/sound/soc/codecs/cs35l56.c +++ b/sound/soc/codecs/cs35l56.c @@ -2008,6 +2008,16 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56) goto err; } + /* + * On SoundWire the cs35l56_init() cannot be run until after the + * device has been enumerated by the SoundWire core. + */ + if (!cs35l56->sdw_peripheral) { + ret = cs35l56_init(cs35l56); + if (ret) + goto err_remove_wm_adsp; + } + ret = snd_soc_register_component(cs35l56->base.dev, &soc_component_dev_cs35l56, cs35l56_dai, ARRAY_SIZE(cs35l56_dai)); @@ -2022,6 +2032,11 @@ err_remove_wm_adsp: wm_adsp2_remove(&cs35l56->dsp); err: + if (pm_runtime_enabled(cs35l56->base.dev)) { + pm_runtime_dont_use_autosuspend(cs35l56->base.dev); + pm_runtime_disable(cs35l56->base.dev); + } + gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(cs35l56->supplies), cs35l56->supplies); @@ -2108,7 +2123,7 @@ post_soft_reset: return dev_err_probe(cs35l56->base.dev, ret, "Failed to write ASP1_CONTROL3\n"); cs35l56->base.init_done = true; - complete(&cs35l56->init_completion); + complete_all(&cs35l56->init_completion); return 0; } |
