mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-21 14:39:30 -04:00
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
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56)
|
||||
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 @@ int cs35l56_init(struct cs35l56_private *cs35l56)
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user