Skip to content

Commit b5d46ed

Browse files
Ajay Kumar NandamRaviHothi
authored andcommitted
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>
1 parent 0d3a682 commit b5d46ed

1 file changed

Lines changed: 54 additions & 66 deletions

File tree

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

Lines changed: 54 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/of_platform.h>
1212
#include <linux/platform_device.h>
1313
#include <linux/pm_runtime.h>
14+
#include <linux/pm_clock.h>
1415
#include <linux/regmap.h>
1516
#include <linux/regulator/consumer.h>
1617
#include <sound/soc.h>
@@ -1348,18 +1349,22 @@ static int fsgen_gate_enable(struct clk_hw *hw)
13481349
struct regmap *regmap = va->regmap;
13491350
int ret;
13501351

1351-
if (va->has_swr_master) {
1352-
ret = clk_prepare_enable(va->mclk);
1353-
if (ret)
1354-
return ret;
1352+
ret = pm_runtime_get_sync(va->dev);
1353+
if (ret < 0) {
1354+
pm_runtime_put_noidle(va->dev);
1355+
return ret;
13551356
}
13561357

13571358
ret = va_macro_mclk_enable(va, true);
1359+
if (ret) {
1360+
pm_runtime_put_noidle(va->dev);
1361+
return ret;
1362+
}
13581363
if (va->has_swr_master)
13591364
regmap_update_bits(regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
13601365
CDC_VA_SWR_CLK_EN_MASK, CDC_VA_SWR_CLK_ENABLE);
13611366

1362-
return ret;
1367+
return 0;
13631368
}
13641369

13651370
static void fsgen_gate_disable(struct clk_hw *hw)
@@ -1372,8 +1377,24 @@ static void fsgen_gate_disable(struct clk_hw *hw)
13721377
CDC_VA_SWR_CLK_EN_MASK, 0x0);
13731378

13741379
va_macro_mclk_enable(va, false);
1375-
if (va->has_swr_master)
1376-
clk_disable_unprepare(va->mclk);
1380+
1381+
pm_runtime_mark_last_busy(va->dev);
1382+
pm_runtime_put_autosuspend(va->dev);
1383+
}
1384+
1385+
static int va_macro_setup_pm_clocks(struct device *dev, struct va_macro *va)
1386+
{
1387+
int ret;
1388+
1389+
ret = devm_pm_clk_create(dev);
1390+
if (ret)
1391+
return ret;
1392+
1393+
ret = of_pm_clk_add_clks(dev);
1394+
if (ret < 0)
1395+
return ret;
1396+
1397+
return 0;
13771398
}
13781399

13791400
static int fsgen_gate_is_enabled(struct clk_hw *hw)
@@ -1534,6 +1555,7 @@ static int va_macro_probe(struct platform_device *pdev)
15341555
void __iomem *base;
15351556
u32 sample_rate = 0;
15361557
int ret;
1558+
int rpm_ret;
15371559

15381560
va = devm_kzalloc(dev, sizeof(*va), GFP_KERNEL);
15391561
if (!va)
@@ -1601,22 +1623,18 @@ static int va_macro_probe(struct platform_device *pdev)
16011623
clk_set_rate(va->npl, 2 * VA_MACRO_MCLK_FREQ);
16021624
}
16031625

1604-
ret = clk_prepare_enable(va->macro);
1605-
if (ret)
1606-
goto err;
1607-
1608-
ret = clk_prepare_enable(va->dcodec);
1626+
ret = va_macro_setup_pm_clocks(dev, va);
16091627
if (ret)
1610-
goto err_dcodec;
1628+
goto err_rpm_disable;
16111629

1612-
ret = clk_prepare_enable(va->mclk);
1613-
if (ret)
1614-
goto err_mclk;
1630+
pm_runtime_set_autosuspend_delay(dev, 3000);
1631+
pm_runtime_use_autosuspend(dev);
1632+
pm_runtime_enable(dev);
16151633

1616-
if (va->has_npl_clk) {
1617-
ret = clk_prepare_enable(va->npl);
1618-
if (ret)
1619-
goto err_npl;
1634+
rpm_ret = pm_runtime_resume_and_get(dev);
1635+
if (rpm_ret < 0) {
1636+
ret = rpm_ret;
1637+
goto err_rpm_disable;
16201638
}
16211639

16221640
/**
@@ -1629,7 +1647,7 @@ static int va_macro_probe(struct platform_device *pdev)
16291647
/* read version from register */
16301648
ret = va_macro_set_lpass_codec_version(va);
16311649
if (ret)
1632-
goto err_clkout;
1650+
goto err_rpm_put;
16331651
}
16341652

16351653
if (va->has_swr_master) {
@@ -1659,35 +1677,27 @@ static int va_macro_probe(struct platform_device *pdev)
16591677
va_macro_dais,
16601678
ARRAY_SIZE(va_macro_dais));
16611679
if (ret)
1662-
goto err_clkout;
1663-
1664-
pm_runtime_set_autosuspend_delay(dev, 3000);
1665-
pm_runtime_use_autosuspend(dev);
1666-
pm_runtime_mark_last_busy(dev);
1667-
pm_runtime_set_active(dev);
1668-
pm_runtime_enable(dev);
1680+
goto err_rpm_put;
16691681

16701682
ret = va_macro_register_fsgen_output(va);
16711683
if (ret)
1672-
goto err_clkout;
1684+
goto err_rpm_put;
16731685

16741686
va->fsgen = devm_clk_hw_get_clk(dev, &va->hw, "fsgen");
16751687
if (IS_ERR(va->fsgen)) {
16761688
ret = PTR_ERR(va->fsgen);
1677-
goto err_clkout;
1689+
goto err_rpm_put;
16781690
}
16791691

1692+
pm_runtime_mark_last_busy(dev);
1693+
pm_runtime_put_autosuspend(dev);
1694+
16801695
return 0;
16811696

1682-
err_clkout:
1683-
if (va->has_npl_clk)
1684-
clk_disable_unprepare(va->npl);
1685-
err_npl:
1686-
clk_disable_unprepare(va->mclk);
1687-
err_mclk:
1688-
clk_disable_unprepare(va->dcodec);
1689-
err_dcodec:
1690-
clk_disable_unprepare(va->macro);
1697+
err_rpm_put:
1698+
pm_runtime_put_noidle(dev);
1699+
err_rpm_disable:
1700+
pm_runtime_disable(dev);
16911701
err:
16921702
lpass_macro_pds_exit(va->pds);
16931703

@@ -1698,12 +1708,7 @@ static void va_macro_remove(struct platform_device *pdev)
16981708
{
16991709
struct va_macro *va = dev_get_drvdata(&pdev->dev);
17001710

1701-
if (va->has_npl_clk)
1702-
clk_disable_unprepare(va->npl);
1703-
1704-
clk_disable_unprepare(va->mclk);
1705-
clk_disable_unprepare(va->dcodec);
1706-
clk_disable_unprepare(va->macro);
1711+
pm_runtime_disable(&pdev->dev);
17071712

17081713
lpass_macro_pds_exit(va->pds);
17091714
}
@@ -1715,38 +1720,21 @@ static int va_macro_runtime_suspend(struct device *dev)
17151720
regcache_cache_only(va->regmap, true);
17161721
regcache_mark_dirty(va->regmap);
17171722

1718-
if (va->has_npl_clk)
1719-
clk_disable_unprepare(va->npl);
1720-
1721-
clk_disable_unprepare(va->mclk);
1722-
1723-
return 0;
1723+
return pm_clk_suspend(dev);
17241724
}
17251725

17261726
static int va_macro_runtime_resume(struct device *dev)
17271727
{
17281728
struct va_macro *va = dev_get_drvdata(dev);
17291729
int ret;
17301730

1731-
ret = clk_prepare_enable(va->mclk);
1732-
if (ret) {
1733-
dev_err(va->dev, "unable to prepare mclk\n");
1731+
ret = pm_clk_resume(dev);
1732+
if (ret)
17341733
return ret;
1735-
}
1736-
1737-
if (va->has_npl_clk) {
1738-
ret = clk_prepare_enable(va->npl);
1739-
if (ret) {
1740-
clk_disable_unprepare(va->mclk);
1741-
dev_err(va->dev, "unable to prepare npl\n");
1742-
return ret;
1743-
}
1744-
}
17451734

17461735
regcache_cache_only(va->regmap, false);
1747-
regcache_sync(va->regmap);
17481736

1749-
return 0;
1737+
return regcache_sync(va->regmap);
17501738
}
17511739

17521740

0 commit comments

Comments
 (0)