15
15
#include <linux/module.h>
16
16
#include <linux/of.h>
17
17
#include <linux/platform_device.h>
18
+ #include <linux/pm_runtime.h>
18
19
#include <linux/reset.h>
19
20
#include <linux/sizes.h>
20
21
@@ -548,9 +549,13 @@ static int dwcmshc_probe(struct platform_device *pdev)
548
549
549
550
host -> mmc -> caps |= MMC_CAP_WAIT_WHILE_BUSY ;
550
551
552
+ pm_runtime_get_noresume (dev );
553
+ pm_runtime_set_active (dev );
554
+ pm_runtime_enable (dev );
555
+
551
556
err = sdhci_setup_host (host );
552
557
if (err )
553
- goto err_clk ;
558
+ goto err_rpm ;
554
559
555
560
if (rk_priv )
556
561
dwcmshc_rk35xx_postinit (host , priv );
@@ -559,10 +564,15 @@ static int dwcmshc_probe(struct platform_device *pdev)
559
564
if (err )
560
565
goto err_setup_host ;
561
566
567
+ pm_runtime_put (dev );
568
+
562
569
return 0 ;
563
570
564
571
err_setup_host :
565
572
sdhci_cleanup_host (host );
573
+ err_rpm :
574
+ pm_runtime_disable (dev );
575
+ pm_runtime_put_noidle (dev );
566
576
err_clk :
567
577
clk_disable_unprepare (pltfm_host -> clk );
568
578
clk_disable_unprepare (priv -> bus_clk );
@@ -600,6 +610,8 @@ static int dwcmshc_suspend(struct device *dev)
600
610
struct rk35xx_priv * rk_priv = priv -> priv ;
601
611
int ret ;
602
612
613
+ pm_runtime_resume (dev );
614
+
603
615
ret = sdhci_suspend_host (host );
604
616
if (ret )
605
617
return ret ;
@@ -659,7 +671,55 @@ static int dwcmshc_resume(struct device *dev)
659
671
}
660
672
#endif
661
673
662
- static SIMPLE_DEV_PM_OPS (dwcmshc_pmops , dwcmshc_suspend , dwcmshc_resume ) ;
674
+ #ifdef CONFIG_PM
675
+
676
+ static void dwcmshc_enable_card_clk (struct sdhci_host * host )
677
+ {
678
+ u16 ctrl ;
679
+
680
+ ctrl = sdhci_readw (host , SDHCI_CLOCK_CONTROL );
681
+ if ((ctrl & SDHCI_CLOCK_INT_EN ) && !(ctrl & SDHCI_CLOCK_CARD_EN )) {
682
+ ctrl |= SDHCI_CLOCK_CARD_EN ;
683
+ sdhci_writew (host , ctrl , SDHCI_CLOCK_CONTROL );
684
+ }
685
+ }
686
+
687
+ static void dwcmshc_disable_card_clk (struct sdhci_host * host )
688
+ {
689
+ u16 ctrl ;
690
+
691
+ ctrl = sdhci_readw (host , SDHCI_CLOCK_CONTROL );
692
+ if (ctrl & SDHCI_CLOCK_CARD_EN ) {
693
+ ctrl &= ~SDHCI_CLOCK_CARD_EN ;
694
+ sdhci_writew (host , ctrl , SDHCI_CLOCK_CONTROL );
695
+ }
696
+ }
697
+
698
+ static int dwcmshc_runtime_suspend (struct device * dev )
699
+ {
700
+ struct sdhci_host * host = dev_get_drvdata (dev );
701
+
702
+ dwcmshc_disable_card_clk (host );
703
+
704
+ return 0 ;
705
+ }
706
+
707
+ static int dwcmshc_runtime_resume (struct device * dev )
708
+ {
709
+ struct sdhci_host * host = dev_get_drvdata (dev );
710
+
711
+ dwcmshc_enable_card_clk (host );
712
+
713
+ return 0 ;
714
+ }
715
+
716
+ #endif
717
+
718
+ static const struct dev_pm_ops dwcmshc_pmops = {
719
+ SET_SYSTEM_SLEEP_PM_OPS (dwcmshc_suspend , dwcmshc_resume )
720
+ SET_RUNTIME_PM_OPS (dwcmshc_runtime_suspend ,
721
+ dwcmshc_runtime_resume , NULL )
722
+ };
663
723
664
724
static struct platform_driver sdhci_dwcmshc_driver = {
665
725
.driver = {
0 commit comments