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
13601365static 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
13741395static 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 );
16581668err :
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
16931693static 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