[PATCH 1/2] ASoC: codecs: sn624x: enable runtime PM on first attach
Qianghua Wang <[email protected]>
| Newsgroups | org.kernel.vger.linux-sound |
|---|---|
| Message-ID | <[email protected]> |
Runtime PM was enabled unconditionally from probe after register_component(). set_jack() can run in that window and touch RPM before it is enabled, leading to mismatched get/put counts. remove() only called pm_runtime_disable() when first_hw_init was set, which did not match the probe enable. Enable runtime PM from io_init() on first ATTACHED instead, and do not use runtime PM from set_jack() until then. If set_jack() ran early, take the long-lived jack PM reference once io_init() has enabled RPM. Signed-off-by: Qianghua Wang <[email protected]> --- sound/soc/codecs/sn624x-sdca-sdw.c | 63 ++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/sound/soc/codecs/sn624x-sdca-sdw.c b/sound/soc/codecs/sn624x-sdca-sdw.c index cd18936037e9..8fd37f18fe5e 100644 --- a/sound/soc/codecs/sn624x-sdca-sdw.c +++ b/sound/soc/codecs/sn624x-sdca-sdw.c @@ -869,12 +869,16 @@ static int sn624x_jack_rpm_get(struct sn624x_sdca_priv *sn624x) dev = sn624x->component->dev; ret = pm_runtime_resume_and_get(dev); - if (ret < 0 && ret != -EACCES) { - dev_err(dev, "sn624x: jack rpm get failed (%d)\n", ret); - return ret; + if (ret < 0) { + if (ret != -EACCES) { + dev_err(dev, "sn624x: jack rpm get failed (%d)\n", ret); + return ret; + } + /* pm_runtime not enabled yet (before first ATTACHED io_init) */ + return 0; } - if (ret >= 0) - sn624x->jack_rpm = true; + + sn624x->jack_rpm = true; return 0; } @@ -988,6 +992,18 @@ static int sn624x_sdca_set_jack_detect(struct snd_soc_component *component, return 0; } + /* + * Component registration happens before runtime PM is enabled (RPM is + * enabled from io_init on first ATTACHED). Do not touch runtime PM + * until then, or get/put counts can go out of sync. + */ + if (!sn624x->first_hw_init) { + sn624x->hs_jack = hs_jack; + sn624x->jack_type_last = -1; + sn624x_jack_schedule_poll(sn624x); + return 0; + } + /* * Take the runtime PM reference before publishing hs_jack, so a * failed get cannot leave jack detection marked as enabled. @@ -998,13 +1014,6 @@ static int sn624x_sdca_set_jack_detect(struct snd_soc_component *component, sn624x->hs_jack = hs_jack; sn624x->jack_type_last = -1; - - /* set_jack may run before io_init; poll waits until hw_init. */ - if (!sn624x->first_hw_init) { - sn624x_jack_schedule_poll(sn624x); - return 0; - } - sn624x_sdca_jack_init(sn624x); return 0; } @@ -1122,13 +1131,30 @@ static int sn624x_sdca_io_init(struct device *dev, struct sdw_slave *slave) sn624x_sdca_sdca_irq_mask_all(sn624x); regcache_cache_only(sn624x->regmap, false); + if (!sn624x->first_hw_init) { + /* + * PM runtime is only enabled when a Slave reports as Attached + * (same pattern as rt722). + */ + pm_runtime_set_autosuspend_delay(dev, 3000); + pm_runtime_use_autosuspend(dev); + pm_runtime_set_active(dev); + pm_runtime_mark_last_busy(dev); + pm_runtime_enable(dev); + } pm_runtime_get_noresume(dev); sn624x_uaj_apply_io_defaults(sn624x); - if (sn624x->hs_jack) + /* + * set_jack() may have run before RPM was enabled (-EACCES). Take the + * long-lived jack PM ref now that runtime PM is active. + */ + if (sn624x->hs_jack) { + sn624x_jack_rpm_get(sn624x); sn624x_sdca_jack_init(sn624x); + } ret = sn624x_sdca_jack_function_init(dev, sn624x); if (ret < 0) { @@ -1149,8 +1175,6 @@ static int sn624x_sdca_io_init(struct device *dev, struct sdw_slave *slave) if (sn624x->first_hw_init) regcache_mark_dirty(sn624x->regmap); - pm_runtime_set_active(dev); - sn624x->hw_init = true; sn624x->first_hw_init = true; @@ -1692,11 +1716,10 @@ int sn624x_sdca_init(struct device *dev, struct regmap *regmap, if (ret < 0) return ret; - pm_runtime_set_autosuspend_delay(dev, 3000); - pm_runtime_use_autosuspend(dev); - pm_runtime_mark_last_busy(dev); - pm_runtime_enable(dev); - + /* + * Do not enable runtime PM here. SoundWire slaves are only powered / + * accessible after ATTACHED; enable RPM from io_init() then. + */ SN624X_DBG(dev, "snd_soc_register_component OK (DAI sn624x-sdca-aif)\n"); return 0; } -- 2.47.3