Skip to content

Commit 579a1e2

Browse files
committed
FROMLIST: ASoC: codecs: lpass-va-macro: Switch to PM clock framework for runtime PM
Convert the LPASS VA macro codec driver to use the PM clock framework for runtime power management. The driver now relies on pm_clk helpers and runtime PM instead of manually enabling and disabling macro, dcodec, mclk, and npl clocks. All clock control during runtime suspend and resume is delegated to the PM core via pm_clk_suspend() and pm_clk_resume(). This change ensures clocks are only enabled when the VA macro is active, improves power efficiency on LPASS platforms supporting LPI/island modes, and aligns the driver with common ASoC runtime PM patterns used across Qualcomm LPASS codec drivers. Link: https://lore.kernel.org/all/20260413121824.375473-3-ajay.nandam@oss.qualcomm.com/ Signed-off-by: Ajay Kumar Nandam <ajay.nandam@oss.qualcomm.com> Signed-off-by: Ravi Hothi <ravi.hothi@oss.qualcomm.com>
1 parent bfc4922 commit 579a1e2

1 file changed

Lines changed: 53 additions & 64 deletions

File tree

sound/soc/codecs/lpass-va-macro.c

Lines changed: 53 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <linux/of_platform.h>
1111
#include <linux/platform_device.h>
1212
#include <linux/pm_runtime.h>
13+
#include <linux/pm_clock.h>
1314
#include <linux/regmap.h>
1415
#include <linux/regulator/consumer.h>
1516
#include <sound/soc.h>
@@ -1343,18 +1344,22 @@ static int fsgen_gate_enable(struct clk_hw *hw)
13431344
struct regmap *regmap = va->regmap;
13441345
int ret;
13451346

1346-
if (va->has_swr_master) {
1347-
ret = clk_prepare_enable(va->mclk);
1348-
if (ret)
1349-
return ret;
1347+
ret = pm_runtime_get_sync(va->dev);
1348+
if (ret < 0) {
1349+
pm_runtime_put_noidle(va->dev);
1350+
return ret;
13501351
}
13511352

13521353
ret = va_macro_mclk_enable(va, true);
1354+
if (ret) {
1355+
pm_runtime_put_noidle(va->dev);
1356+
return ret;
1357+
}
13531358
if (va->has_swr_master)
13541359
regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
13551360
CDC_VA_SWR_CLK_EN_MASK, CDC_VA_SWR_CLK_ENABLE);
13561361

1357-
return ret;
1362+
return 0;
13581363
}
13591364

13601365
static void fsgen_gate_disable(struct clk_hw *hw)
@@ -1367,8 +1372,24 @@ static void fsgen_gate_disable(struct clk_hw *hw)
13671372
CDC_VA_SWR_CLK_EN_MASK, 0x0);
13681373

13691374
va_macro_mclk_enable(va, false);
1370-
if (va->has_swr_master)
1371-
clk_disable_unprepare(va->mclk);
1375+
1376+
pm_runtime_mark_last_busy(va->dev);
1377+
pm_runtime_put_autosuspend(va->dev);
1378+
}
1379+
1380+
static int va_macro_setup_pm_clocks(struct device *dev, struct va_macro *va)
1381+
{
1382+
int ret;
1383+
1384+
ret = devm_pm_clk_create(dev);
1385+
if (ret)
1386+
return ret;
1387+
1388+
ret = of_pm_clk_add_clks(dev);
1389+
if (ret < 0)
1390+
return ret;
1391+
1392+
return 0;
13721393
}
13731394

13741395
static int fsgen_gate_is_enabled(struct clk_hw *hw)
@@ -1505,6 +1526,7 @@ static int va_macro_probe(struct platform_device *pdev)
15051526
void __iomem *base;
15061527
u32 sample_rate = 0;
15071528
int ret;
1529+
int rpm_ret;
15081530

15091531
va = devm_kzalloc(dev, sizeof(*va), GFP_KERNEL);
15101532
if (!va)
@@ -1572,22 +1594,18 @@ static int va_macro_probe(struct platform_device *pdev)
15721594
clk_set_rate(va->npl, 2 * VA_MACRO_MCLK_FREQ);
15731595
}
15741596

1575-
ret = clk_prepare_enable(va->macro);
1576-
if (ret)
1577-
goto err;
1578-
1579-
ret = clk_prepare_enable(va->dcodec);
1597+
ret = va_macro_setup_pm_clocks(dev, va);
15801598
if (ret)
1581-
goto err_dcodec;
1599+
goto err_rpm_disable;
15821600

1583-
ret = clk_prepare_enable(va->mclk);
1584-
if (ret)
1585-
goto err_mclk;
1601+
pm_runtime_set_autosuspend_delay(dev, 3000);
1602+
pm_runtime_use_autosuspend(dev);
1603+
pm_runtime_enable(dev);
15861604

1587-
if (va->has_npl_clk) {
1588-
ret = clk_prepare_enable(va->npl);
1589-
if (ret)
1590-
goto err_npl;
1605+
rpm_ret = pm_runtime_resume_and_get(dev);
1606+
if (rpm_ret < 0) {
1607+
ret = rpm_ret;
1608+
goto err_rpm_disable;
15911609
}
15921610

15931611
/**
@@ -1626,35 +1644,27 @@ static int va_macro_probe(struct platform_device *pdev)
16261644
va_macro_dais,
16271645
ARRAY_SIZE(va_macro_dais));
16281646
if (ret)
1629-
goto err_clkout;
1630-
1631-
pm_runtime_set_autosuspend_delay(dev, 3000);
1632-
pm_runtime_use_autosuspend(dev);
1633-
pm_runtime_mark_last_busy(dev);
1634-
pm_runtime_set_active(dev);
1635-
pm_runtime_enable(dev);
1647+
goto err_rpm_put;
16361648

16371649
ret = va_macro_register_fsgen_output(va);
16381650
if (ret)
1639-
goto err_clkout;
1651+
goto err_rpm_put;
16401652

16411653
va->fsgen = devm_clk_hw_get_clk(dev, &va->hw, "fsgen");
16421654
if (IS_ERR(va->fsgen)) {
16431655
ret = PTR_ERR(va->fsgen);
1644-
goto err_clkout;
1656+
goto err_rpm_put;
16451657
}
16461658

1659+
pm_runtime_mark_last_busy(dev);
1660+
pm_runtime_put_autosuspend(dev);
1661+
16471662
return 0;
16481663

1649-
err_clkout:
1650-
if (va->has_npl_clk)
1651-
clk_disable_unprepare(va->npl);
1652-
err_npl:
1653-
clk_disable_unprepare(va->mclk);
1654-
err_mclk:
1655-
clk_disable_unprepare(va->dcodec);
1656-
err_dcodec:
1657-
clk_disable_unprepare(va->macro);
1664+
err_rpm_put:
1665+
pm_runtime_put_noidle(dev);
1666+
err_rpm_disable:
1667+
pm_runtime_disable(dev);
16581668
err:
16591669
lpass_macro_pds_exit(va->pds);
16601670

@@ -1665,12 +1675,7 @@ static void va_macro_remove(struct platform_device *pdev)
16651675
{
16661676
struct va_macro *va = dev_get_drvdata(&pdev->dev);
16671677

1668-
if (va->has_npl_clk)
1669-
clk_disable_unprepare(va->npl);
1670-
1671-
clk_disable_unprepare(va->mclk);
1672-
clk_disable_unprepare(va->dcodec);
1673-
clk_disable_unprepare(va->macro);
1678+
pm_runtime_disable(&pdev->dev);
16741679

16751680
lpass_macro_pds_exit(va->pds);
16761681
}
@@ -1682,38 +1687,22 @@ static int va_macro_runtime_suspend(struct device *dev)
16821687
regcache_cache_only(va->regmap, true);
16831688
regcache_mark_dirty(va->regmap);
16841689

1685-
if (va->has_npl_clk)
1686-
clk_disable_unprepare(va->npl);
1687-
1688-
clk_disable_unprepare(va->mclk);
1689-
1690-
return 0;
1690+
return pm_clk_suspend(dev);
16911691
}
16921692

16931693
static int va_macro_runtime_resume(struct device *dev)
16941694
{
16951695
struct va_macro *va = dev_get_drvdata(dev);
16961696
int ret;
16971697

1698-
ret = clk_prepare_enable(va->mclk);
1699-
if (ret) {
1700-
dev_err(va->dev, "unable to prepare mclk\n");
1698+
ret = pm_clk_resume(dev);
1699+
if (ret)
17011700
return ret;
1702-
}
17031701

1704-
if (va->has_npl_clk) {
1705-
ret = clk_prepare_enable(va->npl);
1706-
if (ret) {
1707-
clk_disable_unprepare(va->mclk);
1708-
dev_err(va->dev, "unable to prepare npl\n");
1709-
return ret;
1710-
}
1711-
}
17121702

17131703
regcache_cache_only(va->regmap, false);
1714-
regcache_sync(va->regmap);
17151704

1716-
return 0;
1705+
return regcache_sync(va->regmap);
17171706
}
17181707

17191708

0 commit comments

Comments
 (0)