From bb3c847523f951315f212047ab26363f9928d569 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 25 May 2026 22:17:59 +0200 Subject: [PATCH 1/3] ASoC: codecs: pcm3168a: Prevent regulator double-disable in S4 The SLEEP_PM_OPS are unset for the driver. Hibernation (S4) causes no resume (skipped thanks to smart_suspend=true) yet still performs the suspend sequence unconditionally, see device_complete() in drivers/base/power/main.c. If S4 runs for already suspended pcm3168a device, we end up with "unbalanced disables" warning from the regulators. Assigning the operations fixes the problem. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20260525201801.1336936-2-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/pcm3168a.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index c8617a488b11..7f8d64fb0e57 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -907,6 +907,7 @@ static int pcm3168a_rt_suspend(struct device *dev) EXPORT_GPL_DEV_PM_OPS(pcm3168a_pm_ops) = { RUNTIME_PM_OPS(pcm3168a_rt_suspend, pcm3168a_rt_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; MODULE_DESCRIPTION("PCM3168A codec driver"); From 2c734439be9ca5968f39a3c5c10b65986f41d766 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 25 May 2026 22:18:00 +0200 Subject: [PATCH 2/3] ASoC: codecs: pcm3168a: Drop redundant pm_runtime_idle() Device-driver core runs pm_request_idle() right after the probing sequence already, see __driver_probe_device(). Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20260525201801.1336936-3-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/pcm3168a.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index 7f8d64fb0e57..977b8ed45f2e 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -799,7 +799,6 @@ int pcm3168a_probe(struct device *dev, struct regmap *regmap) pm_runtime_set_active(dev); pm_runtime_enable(dev); - pm_runtime_idle(dev); memcpy(pcm3168a->dai_drv, pcm3168a_dais, sizeof(pcm3168a->dai_drv)); ret = devm_snd_soc_register_component(dev, &pcm3168a_driver, From eb7107264da8545ba7381a76818bae553e1fd1e4 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Mon, 25 May 2026 22:18:01 +0200 Subject: [PATCH 3/3] ASoC: codecs: pcm3168a: Drop CONFIG_PM-conditional preproc directive Revert changes done in commit 489db5d94150 ("ASoC: pcm3168a: Don't disable pcm3168a when CONFIG_PM defined") and add pm_runtime_status_suspended() check. The suspended-check addresses regulator's "unbalanced disables" warning during driver removal even when CONFIG_PM is enabled. Signed-off-by: Cezary Rojewski Link: https://patch.msgid.link/20260525201801.1336936-4-cezary.rojewski@intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/pcm3168a.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index 977b8ed45f2e..4503f2f0724e 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -821,15 +821,6 @@ int pcm3168a_probe(struct device *dev, struct regmap *regmap) } EXPORT_SYMBOL_GPL(pcm3168a_probe); -static void pcm3168a_disable(struct device *dev) -{ - struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev); - - regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies), - pcm3168a->supplies); - clk_disable_unprepare(pcm3168a->scki); -} - void pcm3168a_remove(struct device *dev) { struct pcm3168a_priv *pcm3168a = dev_get_drvdata(dev); @@ -841,10 +832,12 @@ void pcm3168a_remove(struct device *dev) * The asserted level of GPIO_ACTIVE_LOW is LOW. */ gpiod_set_value_cansleep(pcm3168a->gpio_rst, 1); + pm_runtime_disable(dev); -#ifndef CONFIG_PM - pcm3168a_disable(dev); -#endif + if (!pm_runtime_status_suspended(dev)) { + regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies), pcm3168a->supplies); + clk_disable_unprepare(pcm3168a->scki); + } } EXPORT_SYMBOL_GPL(pcm3168a_remove); @@ -899,7 +892,8 @@ static int pcm3168a_rt_suspend(struct device *dev) regcache_cache_only(pcm3168a->regmap, true); - pcm3168a_disable(dev); + regulator_bulk_disable(ARRAY_SIZE(pcm3168a->supplies), pcm3168a->supplies); + clk_disable_unprepare(pcm3168a->scki); return 0; }