* [PATCH v6 2/3] ASoC: codecs: lpass-va-macro: Switch to PM clock framework for runtime PM
@ 2026-06-23 7:17 Ajay Kumar Nandam
2026-06-23 10:39 ` Konrad Dybcio
0 siblings, 1 reply; 4+ messages in thread
From: Ajay Kumar Nandam @ 2026-06-23 7:17 UTC (permalink / raw)
To: broonie, lgirdwood, perex, tiwai, srini
Cc: linux-sound, linux-arm-msm, linux-kernel
Convert the LPASS VA macro codec driver to runtime PM clock management by
using the PM clock framework.
Replace manual macro/dcodec/mclk/npl clock handling with PM clock helpers
and runtime PM callbacks, and keep runtime PM references around fsgen clock
gating so PM-clock-managed clocks remain active while fsgen is enabled.
Set autosuspend delay to 100 ms so PM-clock-managed votes are dropped soon
after idle while still avoiding suspend/resume churn on short gaps.
Add a PM_CLK dependency to SND_SOC_LPASS_VA_MACRO since this patch
introduces PM clock APIs.
Improve failure unwind paths: handle runtime PM put errors in probe/fsgen
paths and restore regcache state correctly on resume failure.
Signed-off-by: Ajay Kumar Nandam <ajay.nandam@oss.qualcomm.com>
---
sound/soc/codecs/Kconfig | 1 +
sound/soc/codecs/lpass-va-macro.c | 142 +++++++++++++++++-------------
2 files changed, 80 insertions(+), 63 deletions(-)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 458ea62ad983..72a973dab84d 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -2896,6 +2896,7 @@ config SND_SOC_LPASS_WSA_MACRO
config SND_SOC_LPASS_VA_MACRO
depends on COMMON_CLK
+ depends on PM_CLK
select REGMAP_MMIO
select SND_SOC_LPASS_MACRO_COMMON
tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)"
diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c
index 528d5b167ecf..6e822e47c863 100644
--- a/sound/soc/codecs/lpass-va-macro.c
+++ b/sound/soc/codecs/lpass-va-macro.c
@@ -11,6 +11,7 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/pm_clock.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <sound/soc.h>
@@ -1346,34 +1347,58 @@ static int fsgen_gate_enable(struct clk_hw *hw)
{
struct va_macro *va = to_va_macro(hw);
struct regmap *regmap = va->regmap;
- int ret;
+ int ret, rpm_ret;
- if (va->has_swr_master) {
- ret = clk_prepare_enable(va->mclk);
- if (ret)
- return ret;
- }
+ ret = pm_runtime_resume_and_get(va->dev);
+ if (ret < 0)
+ return ret;
ret = va_macro_mclk_enable(va, true);
+ if (ret) {
+ rpm_ret = pm_runtime_put_autosuspend(va->dev);
+ if (rpm_ret < 0)
+ dev_warn(va->dev,
+ "runtime PM put failed in fsgen enable unwind: %d\n",
+ rpm_ret);
+ return ret;
+ }
if (va->has_swr_master)
regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
CDC_VA_SWR_CLK_EN_MASK, CDC_VA_SWR_CLK_ENABLE);
- return ret;
+ return 0;
}
static void fsgen_gate_disable(struct clk_hw *hw)
{
struct va_macro *va = to_va_macro(hw);
struct regmap *regmap = va->regmap;
+ int ret;
if (va->has_swr_master)
regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
CDC_VA_SWR_CLK_EN_MASK, 0x0);
va_macro_mclk_enable(va, false);
- if (va->has_swr_master)
- clk_disable_unprepare(va->mclk);
+
+ ret = pm_runtime_put_autosuspend(va->dev);
+ if (ret < 0)
+ dev_warn(va->dev, "runtime PM put failed in fsgen disable: %d\n", ret);
+}
+
+static int va_macro_setup_pm_clocks(struct device *dev)
+{
+ int ret;
+
+ ret = devm_pm_clk_create(dev);
+ if (ret)
+ return ret;
+
+ ret = of_pm_clk_add_clks(dev);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
static int fsgen_gate_is_enabled(struct clk_hw *hw)
@@ -1534,6 +1559,7 @@ static int va_macro_probe(struct platform_device *pdev)
void __iomem *base;
u32 sample_rate = 0;
int ret;
+ int rpm_ret;
va = devm_kzalloc(dev, sizeof(*va), GFP_KERNEL);
if (!va)
@@ -1601,22 +1627,20 @@ static int va_macro_probe(struct platform_device *pdev)
clk_set_rate(va->npl, 2 * VA_MACRO_MCLK_FREQ);
}
- ret = clk_prepare_enable(va->macro);
+ ret = va_macro_setup_pm_clocks(dev);
if (ret)
goto err;
- ret = clk_prepare_enable(va->dcodec);
- if (ret)
- goto err_dcodec;
-
- ret = clk_prepare_enable(va->mclk);
+ pm_runtime_set_autosuspend_delay(dev, 100);
+ pm_runtime_use_autosuspend(dev);
+ ret = devm_pm_runtime_enable(dev);
if (ret)
- goto err_mclk;
+ goto err;
- if (va->has_npl_clk) {
- ret = clk_prepare_enable(va->npl);
- if (ret)
- goto err_npl;
+ rpm_ret = pm_runtime_resume_and_get(dev);
+ if (rpm_ret < 0) {
+ ret = rpm_ret;
+ goto err;
}
/**
@@ -1629,7 +1653,7 @@ static int va_macro_probe(struct platform_device *pdev)
/* read version from register */
ret = va_macro_set_lpass_codec_version(va);
if (ret)
- goto err_clkout;
+ goto err_rpm_put;
}
if (va->has_swr_master) {
@@ -1659,35 +1683,28 @@ static int va_macro_probe(struct platform_device *pdev)
va_macro_dais,
ARRAY_SIZE(va_macro_dais));
if (ret)
- goto err_clkout;
-
- pm_runtime_set_autosuspend_delay(dev, 3000);
- pm_runtime_use_autosuspend(dev);
- pm_runtime_mark_last_busy(dev);
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
+ goto err_rpm_put;
ret = va_macro_register_fsgen_output(va);
if (ret)
- goto err_clkout;
+ goto err_rpm_put;
va->fsgen = devm_clk_hw_get_clk(dev, &va->hw, "fsgen");
if (IS_ERR(va->fsgen)) {
ret = PTR_ERR(va->fsgen);
- goto err_clkout;
+ goto err_rpm_put;
}
+ rpm_ret = pm_runtime_put_autosuspend(dev);
+ if (rpm_ret < 0)
+ dev_warn(dev, "runtime PM put failed after probe: %d\n", rpm_ret);
+
return 0;
-err_clkout:
- if (va->has_npl_clk)
- clk_disable_unprepare(va->npl);
-err_npl:
- clk_disable_unprepare(va->mclk);
-err_mclk:
- clk_disable_unprepare(va->dcodec);
-err_dcodec:
- clk_disable_unprepare(va->macro);
+err_rpm_put:
+ rpm_ret = pm_runtime_put_sync_suspend(dev);
+ if (rpm_ret < 0)
+ dev_warn(dev, "runtime PM sync suspend failed in probe unwind: %d\n", rpm_ret);
err:
lpass_macro_pds_exit(va->pds);
@@ -1698,27 +1715,23 @@ static void va_macro_remove(struct platform_device *pdev)
{
struct va_macro *va = dev_get_drvdata(&pdev->dev);
- if (va->has_npl_clk)
- clk_disable_unprepare(va->npl);
-
- clk_disable_unprepare(va->mclk);
- clk_disable_unprepare(va->dcodec);
- clk_disable_unprepare(va->macro);
-
lpass_macro_pds_exit(va->pds);
}
static int va_macro_runtime_suspend(struct device *dev)
{
struct va_macro *va = dev_get_drvdata(dev);
+ int ret;
regcache_cache_only(va->regmap, true);
- regcache_mark_dirty(va->regmap);
- if (va->has_npl_clk)
- clk_disable_unprepare(va->npl);
+ ret = pm_clk_suspend(dev);
+ if (ret) {
+ regcache_cache_only(va->regmap, false);
+ return ret;
+ }
- clk_disable_unprepare(va->mclk);
+ regcache_mark_dirty(va->regmap);
return 0;
}
@@ -1726,25 +1739,28 @@ static int va_macro_runtime_suspend(struct device *dev)
static int va_macro_runtime_resume(struct device *dev)
{
struct va_macro *va = dev_get_drvdata(dev);
- int ret;
+ int ret, sret;
- ret = clk_prepare_enable(va->mclk);
+ ret = pm_clk_resume(dev);
if (ret) {
- dev_err(va->dev, "unable to prepare mclk\n");
+ regcache_cache_only(va->regmap, true);
+ regcache_mark_dirty(va->regmap);
return ret;
}
- if (va->has_npl_clk) {
- ret = clk_prepare_enable(va->npl);
- if (ret) {
- clk_disable_unprepare(va->mclk);
- dev_err(va->dev, "unable to prepare npl\n");
- return ret;
- }
- }
-
regcache_cache_only(va->regmap, false);
- regcache_sync(va->regmap);
+
+ ret = regcache_sync(va->regmap);
+ if (ret) {
+ regcache_cache_only(va->regmap, true);
+ regcache_mark_dirty(va->regmap);
+ sret = pm_clk_suspend(dev);
+ if (sret)
+ dev_err(va->dev,
+ "failed to suspend clocks after regcache sync failure: %d\n",
+ sret);
+ return ret;
+ }
return 0;
}
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH v6 2/3] ASoC: codecs: lpass-va-macro: Switch to PM clock framework for runtime PM
2026-06-23 7:17 [PATCH v6 2/3] ASoC: codecs: lpass-va-macro: Switch to PM clock framework for runtime PM Ajay Kumar Nandam
@ 2026-06-23 10:39 ` Konrad Dybcio
2026-06-23 11:59 ` Ajay Kumar Nandam
0 siblings, 1 reply; 4+ messages in thread
From: Konrad Dybcio @ 2026-06-23 10:39 UTC (permalink / raw)
To: Ajay Kumar Nandam, broonie, lgirdwood, perex, tiwai, srini
Cc: linux-sound, linux-arm-msm, linux-kernel
On 6/23/26 9:17 AM, Ajay Kumar Nandam wrote:
> Convert the LPASS VA macro codec driver to runtime PM clock management by
> using the PM clock framework.
>
> Replace manual macro/dcodec/mclk/npl clock handling with PM clock helpers
> and runtime PM callbacks, and keep runtime PM references around fsgen clock
> gating so PM-clock-managed clocks remain active while fsgen is enabled.
>
> Set autosuspend delay to 100 ms so PM-clock-managed votes are dropped soon
> after idle while still avoiding suspend/resume churn on short gaps.
>
> Add a PM_CLK dependency to SND_SOC_LPASS_VA_MACRO since this patch
> introduces PM clock APIs.
>
> Improve failure unwind paths: handle runtime PM put errors in probe/fsgen
> paths and restore regcache state correctly on resume failure.
>
> Signed-off-by: Ajay Kumar Nandam <ajay.nandam@oss.qualcomm.com>
> ---
[...]
> --- a/sound/soc/codecs/lpass-va-macro.c
> +++ b/sound/soc/codecs/lpass-va-macro.c
> @@ -11,6 +11,7 @@
> #include <linux/of_platform.h>
> #include <linux/platform_device.h>
> #include <linux/pm_runtime.h>
> +#include <linux/pm_clock.h>
includes should be sorted
[...]
> +static int va_macro_setup_pm_clocks(struct device *dev)
> +{
> + int ret;
> +
> + ret = devm_pm_clk_create(dev);
> + if (ret)
> + return ret;
> +
> + ret = of_pm_clk_add_clks(dev);
> + if (ret < 0)
> + return ret;
> +
> + return 0;
> }
Can't these 2 calls simply be part of .probe()?
Konrad
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH v6 2/3] ASoC: codecs: lpass-va-macro: Switch to PM clock framework for runtime PM
2026-06-23 10:39 ` Konrad Dybcio
@ 2026-06-23 11:59 ` Ajay Kumar Nandam
0 siblings, 0 replies; 4+ messages in thread
From: Ajay Kumar Nandam @ 2026-06-23 11:59 UTC (permalink / raw)
To: Konrad Dybcio, broonie, lgirdwood, perex, tiwai, srini
Cc: linux-sound, linux-arm-msm, linux-kernel
On 6/23/2026 4:09 PM, Konrad Dybcio wrote:
>> Convert the LPASS VA macro codec driver to runtime PM clock management by
>> using the PM clock framework.
>>
>> Replace manual macro/dcodec/mclk/npl clock handling with PM clock helpers
>> and runtime PM callbacks, and keep runtime PM references around fsgen clock
>> gating so PM-clock-managed clocks remain active while fsgen is enabled.
>>
>> Set autosuspend delay to 100 ms so PM-clock-managed votes are dropped soon
>> after idle while still avoiding suspend/resume churn on short gaps.
>>
>> Add a PM_CLK dependency to SND_SOC_LPASS_VA_MACRO since this patch
>> introduces PM clock APIs.
>>
>> Improve failure unwind paths: handle runtime PM put errors in probe/fsgen
>> paths and restore regcache state correctly on resume failure.
>>
>> Signed-off-by: Ajay Kumar Nandam<ajay.nandam@oss.qualcomm.com>
>> ---
> [...]
>
>> --- a/sound/soc/codecs/lpass-va-macro.c
>> +++ b/sound/soc/codecs/lpass-va-macro.c
>> @@ -11,6 +11,7 @@
>> #include <linux/of_platform.h>
>> #include <linux/platform_device.h>
>> #include <linux/pm_runtime.h>
>> +#include <linux/pm_clock.h>
> includes should be sorted
>
ACK, I’ll fix the include ordering in the next version
> [...]
>
>> +static int va_macro_setup_pm_clocks(struct device *dev)
>> +{
>> + int ret;
>> +
>> + ret = devm_pm_clk_create(dev);
>> + if (ret)
>> + return ret;
>> +
>> + ret = of_pm_clk_add_clks(dev);
>> + if (ret < 0)
>> + return ret;
>> +
>> + return 0;
>> }
> Can't these 2 calls simply be part of .probe()?
The helper was added to keep the PM clock setup isolated, but I agree
it’s simple enough to inline into probe(). I’ll move it there in the
next revision.
Ajay Kumar Nandam
>
> Konrad
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v6 0/3] ASoC: qcom: lpass: Switch VA/WSA macros to PM clock framework
@ 2026-06-04 12:48 Ajay Kumar Nandam
2026-06-04 12:48 ` [PATCH v6 2/3] ASoC: codecs: lpass-va-macro: Switch to PM clock framework for runtime PM Ajay Kumar Nandam
0 siblings, 1 reply; 4+ messages in thread
From: Ajay Kumar Nandam @ 2026-06-04 12:48 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
Srinivas Kandagatla
Cc: linux-sound, linux-kernel, linux-arm-msm, mohammad.rafi.shaik,
ajay.nandam
Hi,
This series converts LPASS WSA and VA macro codec drivers to the PM clock
framework for runtime PM clock handling, and keeps WSA MCLK-output clock
registration resource-managed.
Changes since v5:
- Rebased to current linux-next/master and regenerated as a standalone
series that applies cleanly.
- Added `depends on PM_CLK` for `SND_SOC_LPASS_WSA_MACRO` and
`SND_SOC_LPASS_VA_MACRO` since PM clock APIs are used.
- Improved runtime-PM probe/resume unwind handling in WSA/VA error paths.
- Kept runtime autosuspend delay at 100 ms in both PM-clock conversion
patches.
Ajay Kumar Nandam (3):
ASoC: codecs: lpass-wsa-macro: Switch to PM clock framework for
runtime PM
ASoC: codecs: lpass-va-macro: Switch to PM clock framework for runtime
PM
ASoC: codecs: lpass-wsa-macro: Use devm_clk_hw_register() for MCLK
output
sound/soc/codecs/Kconfig | 2 +
sound/soc/codecs/lpass-va-macro.c | 142 ++++++++++++++++-------------
sound/soc/codecs/lpass-wsa-macro.c | 128 +++++++++++---------------
3 files changed, 134 insertions(+), 138 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH v6 2/3] ASoC: codecs: lpass-va-macro: Switch to PM clock framework for runtime PM
2026-06-04 12:48 [PATCH v6 0/3] ASoC: qcom: lpass: Switch VA/WSA macros to PM clock framework Ajay Kumar Nandam
@ 2026-06-04 12:48 ` Ajay Kumar Nandam
0 siblings, 0 replies; 4+ messages in thread
From: Ajay Kumar Nandam @ 2026-06-04 12:48 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
Srinivas Kandagatla
Cc: linux-sound, linux-kernel, linux-arm-msm, mohammad.rafi.shaik,
ajay.nandam
Convert the LPASS VA macro codec driver to runtime PM clock management by
using the PM clock framework.
Replace manual macro/dcodec/mclk/npl clock handling with PM clock helpers
and runtime PM callbacks, and keep runtime PM references around fsgen clock
gating so PM-clock-managed clocks remain active while fsgen is enabled.
Set autosuspend delay to 100 ms so PM-clock-managed votes are dropped soon
after idle while still avoiding suspend/resume churn on short gaps.
Add a PM_CLK dependency to SND_SOC_LPASS_VA_MACRO since this patch
introduces PM clock APIs.
Improve failure unwind paths: handle runtime PM put errors in probe/fsgen
paths and restore regcache state correctly on resume failure.
Signed-off-by: Ajay Kumar Nandam <ajay.nandam@oss.qualcomm.com>
---
sound/soc/codecs/Kconfig | 1 +
sound/soc/codecs/lpass-va-macro.c | 142 +++++++++++++++++-------------
2 files changed, 80 insertions(+), 63 deletions(-)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 458ea62ad983..72a973dab84d 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -2896,6 +2896,7 @@ config SND_SOC_LPASS_WSA_MACRO
config SND_SOC_LPASS_VA_MACRO
depends on COMMON_CLK
+ depends on PM_CLK
select REGMAP_MMIO
select SND_SOC_LPASS_MACRO_COMMON
tristate "Qualcomm VA Macro in LPASS(Low Power Audio SubSystem)"
diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c
index 528d5b167ecf..6e822e47c863 100644
--- a/sound/soc/codecs/lpass-va-macro.c
+++ b/sound/soc/codecs/lpass-va-macro.c
@@ -11,6 +11,7 @@
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/pm_clock.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <sound/soc.h>
@@ -1346,34 +1347,58 @@ static int fsgen_gate_enable(struct clk_hw *hw)
{
struct va_macro *va = to_va_macro(hw);
struct regmap *regmap = va->regmap;
- int ret;
+ int ret, rpm_ret;
- if (va->has_swr_master) {
- ret = clk_prepare_enable(va->mclk);
- if (ret)
- return ret;
- }
+ ret = pm_runtime_resume_and_get(va->dev);
+ if (ret < 0)
+ return ret;
ret = va_macro_mclk_enable(va, true);
+ if (ret) {
+ rpm_ret = pm_runtime_put_autosuspend(va->dev);
+ if (rpm_ret < 0)
+ dev_warn(va->dev,
+ "runtime PM put failed in fsgen enable unwind: %d\n",
+ rpm_ret);
+ return ret;
+ }
if (va->has_swr_master)
regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
CDC_VA_SWR_CLK_EN_MASK, CDC_VA_SWR_CLK_ENABLE);
- return ret;
+ return 0;
}
static void fsgen_gate_disable(struct clk_hw *hw)
{
struct va_macro *va = to_va_macro(hw);
struct regmap *regmap = va->regmap;
+ int ret;
if (va->has_swr_master)
regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
CDC_VA_SWR_CLK_EN_MASK, 0x0);
va_macro_mclk_enable(va, false);
- if (va->has_swr_master)
- clk_disable_unprepare(va->mclk);
+
+ ret = pm_runtime_put_autosuspend(va->dev);
+ if (ret < 0)
+ dev_warn(va->dev, "runtime PM put failed in fsgen disable: %d\n", ret);
+}
+
+static int va_macro_setup_pm_clocks(struct device *dev)
+{
+ int ret;
+
+ ret = devm_pm_clk_create(dev);
+ if (ret)
+ return ret;
+
+ ret = of_pm_clk_add_clks(dev);
+ if (ret < 0)
+ return ret;
+
+ return 0;
}
static int fsgen_gate_is_enabled(struct clk_hw *hw)
@@ -1534,6 +1559,7 @@ static int va_macro_probe(struct platform_device *pdev)
void __iomem *base;
u32 sample_rate = 0;
int ret;
+ int rpm_ret;
va = devm_kzalloc(dev, sizeof(*va), GFP_KERNEL);
if (!va)
@@ -1601,22 +1627,20 @@ static int va_macro_probe(struct platform_device *pdev)
clk_set_rate(va->npl, 2 * VA_MACRO_MCLK_FREQ);
}
- ret = clk_prepare_enable(va->macro);
+ ret = va_macro_setup_pm_clocks(dev);
if (ret)
goto err;
- ret = clk_prepare_enable(va->dcodec);
- if (ret)
- goto err_dcodec;
-
- ret = clk_prepare_enable(va->mclk);
+ pm_runtime_set_autosuspend_delay(dev, 100);
+ pm_runtime_use_autosuspend(dev);
+ ret = devm_pm_runtime_enable(dev);
if (ret)
- goto err_mclk;
+ goto err;
- if (va->has_npl_clk) {
- ret = clk_prepare_enable(va->npl);
- if (ret)
- goto err_npl;
+ rpm_ret = pm_runtime_resume_and_get(dev);
+ if (rpm_ret < 0) {
+ ret = rpm_ret;
+ goto err;
}
/**
@@ -1629,7 +1653,7 @@ static int va_macro_probe(struct platform_device *pdev)
/* read version from register */
ret = va_macro_set_lpass_codec_version(va);
if (ret)
- goto err_clkout;
+ goto err_rpm_put;
}
if (va->has_swr_master) {
@@ -1659,35 +1683,28 @@ static int va_macro_probe(struct platform_device *pdev)
va_macro_dais,
ARRAY_SIZE(va_macro_dais));
if (ret)
- goto err_clkout;
-
- pm_runtime_set_autosuspend_delay(dev, 3000);
- pm_runtime_use_autosuspend(dev);
- pm_runtime_mark_last_busy(dev);
- pm_runtime_set_active(dev);
- pm_runtime_enable(dev);
+ goto err_rpm_put;
ret = va_macro_register_fsgen_output(va);
if (ret)
- goto err_clkout;
+ goto err_rpm_put;
va->fsgen = devm_clk_hw_get_clk(dev, &va->hw, "fsgen");
if (IS_ERR(va->fsgen)) {
ret = PTR_ERR(va->fsgen);
- goto err_clkout;
+ goto err_rpm_put;
}
+ rpm_ret = pm_runtime_put_autosuspend(dev);
+ if (rpm_ret < 0)
+ dev_warn(dev, "runtime PM put failed after probe: %d\n", rpm_ret);
+
return 0;
-err_clkout:
- if (va->has_npl_clk)
- clk_disable_unprepare(va->npl);
-err_npl:
- clk_disable_unprepare(va->mclk);
-err_mclk:
- clk_disable_unprepare(va->dcodec);
-err_dcodec:
- clk_disable_unprepare(va->macro);
+err_rpm_put:
+ rpm_ret = pm_runtime_put_sync_suspend(dev);
+ if (rpm_ret < 0)
+ dev_warn(dev, "runtime PM sync suspend failed in probe unwind: %d\n", rpm_ret);
err:
lpass_macro_pds_exit(va->pds);
@@ -1698,27 +1715,23 @@ static void va_macro_remove(struct platform_device *pdev)
{
struct va_macro *va = dev_get_drvdata(&pdev->dev);
- if (va->has_npl_clk)
- clk_disable_unprepare(va->npl);
-
- clk_disable_unprepare(va->mclk);
- clk_disable_unprepare(va->dcodec);
- clk_disable_unprepare(va->macro);
-
lpass_macro_pds_exit(va->pds);
}
static int va_macro_runtime_suspend(struct device *dev)
{
struct va_macro *va = dev_get_drvdata(dev);
+ int ret;
regcache_cache_only(va->regmap, true);
- regcache_mark_dirty(va->regmap);
- if (va->has_npl_clk)
- clk_disable_unprepare(va->npl);
+ ret = pm_clk_suspend(dev);
+ if (ret) {
+ regcache_cache_only(va->regmap, false);
+ return ret;
+ }
- clk_disable_unprepare(va->mclk);
+ regcache_mark_dirty(va->regmap);
return 0;
}
@@ -1726,25 +1739,28 @@ static int va_macro_runtime_suspend(struct device *dev)
static int va_macro_runtime_resume(struct device *dev)
{
struct va_macro *va = dev_get_drvdata(dev);
- int ret;
+ int ret, sret;
- ret = clk_prepare_enable(va->mclk);
+ ret = pm_clk_resume(dev);
if (ret) {
- dev_err(va->dev, "unable to prepare mclk\n");
+ regcache_cache_only(va->regmap, true);
+ regcache_mark_dirty(va->regmap);
return ret;
}
- if (va->has_npl_clk) {
- ret = clk_prepare_enable(va->npl);
- if (ret) {
- clk_disable_unprepare(va->mclk);
- dev_err(va->dev, "unable to prepare npl\n");
- return ret;
- }
- }
-
regcache_cache_only(va->regmap, false);
- regcache_sync(va->regmap);
+
+ ret = regcache_sync(va->regmap);
+ if (ret) {
+ regcache_cache_only(va->regmap, true);
+ regcache_mark_dirty(va->regmap);
+ sret = pm_clk_suspend(dev);
+ if (sret)
+ dev_err(va->dev,
+ "failed to suspend clocks after regcache sync failure: %d\n",
+ sret);
+ return ret;
+ }
return 0;
}
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-06-23 11:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-23 7:17 [PATCH v6 2/3] ASoC: codecs: lpass-va-macro: Switch to PM clock framework for runtime PM Ajay Kumar Nandam
2026-06-23 10:39 ` Konrad Dybcio
2026-06-23 11:59 ` Ajay Kumar Nandam
-- strict thread matches above, loose matches on Subject: below --
2026-06-04 12:48 [PATCH v6 0/3] ASoC: qcom: lpass: Switch VA/WSA macros to PM clock framework Ajay Kumar Nandam
2026-06-04 12:48 ` [PATCH v6 2/3] ASoC: codecs: lpass-va-macro: Switch to PM clock framework for runtime PM Ajay Kumar Nandam
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®