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
13651370static 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
13791400static 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 );
16911701err :
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
17261726static 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