Skip to content

Commit 67e6db1

Browse files
Pramod Guravstorulf
authored andcommitted
mmc: sdhci-msm: Add pm_runtime and system PM support
Provides runtime PM callbacks to enable and disable clock resources when idle. Also support system PM callbacks to be called during system suspend and resume. Reviewed-by: Ritesh Harjani <[email protected]> Reviewed-by: Georgi Djakov <[email protected]> Tested-by: Ritesh Harjani <[email protected]> Signed-off-by: Pramod Gurav <[email protected]> Signed-off-by: Ulf Hansson <[email protected]>
1 parent 424feb5 commit 67e6db1

File tree

1 file changed

+67
-1
lines changed

1 file changed

+67
-1
lines changed

drivers/mmc/host/sdhci-msm.c

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <linux/of_device.h>
1919
#include <linux/delay.h>
2020
#include <linux/mmc/mmc.h>
21+
#include <linux/pm_runtime.h>
2122
#include <linux/slab.h>
2223

2324
#include "sdhci-pltfm.h"
@@ -68,6 +69,7 @@
6869
#define CMUX_SHIFT_PHASE_SHIFT 24
6970
#define CMUX_SHIFT_PHASE_MASK (7 << CMUX_SHIFT_PHASE_SHIFT)
7071

72+
#define MSM_MMC_AUTOSUSPEND_DELAY_MS 50
7173
struct sdhci_msm_host {
7274
struct platform_device *pdev;
7375
void __iomem *core_mem; /* MSM SDCC mapped address */
@@ -659,12 +661,26 @@ static int sdhci_msm_probe(struct platform_device *pdev)
659661
goto clk_disable;
660662
}
661663

664+
pm_runtime_get_noresume(&pdev->dev);
665+
pm_runtime_set_active(&pdev->dev);
666+
pm_runtime_enable(&pdev->dev);
667+
pm_runtime_set_autosuspend_delay(&pdev->dev,
668+
MSM_MMC_AUTOSUSPEND_DELAY_MS);
669+
pm_runtime_use_autosuspend(&pdev->dev);
670+
662671
ret = sdhci_add_host(host);
663672
if (ret)
664-
goto clk_disable;
673+
goto pm_runtime_disable;
674+
675+
pm_runtime_mark_last_busy(&pdev->dev);
676+
pm_runtime_put_autosuspend(&pdev->dev);
665677

666678
return 0;
667679

680+
pm_runtime_disable:
681+
pm_runtime_disable(&pdev->dev);
682+
pm_runtime_set_suspended(&pdev->dev);
683+
pm_runtime_put_noidle(&pdev->dev);
668684
clk_disable:
669685
clk_disable_unprepare(msm_host->clk);
670686
pclk_disable:
@@ -686,6 +702,11 @@ static int sdhci_msm_remove(struct platform_device *pdev)
686702
0xffffffff);
687703

688704
sdhci_remove_host(host, dead);
705+
706+
pm_runtime_get_sync(&pdev->dev);
707+
pm_runtime_disable(&pdev->dev);
708+
pm_runtime_put_noidle(&pdev->dev);
709+
689710
clk_disable_unprepare(msm_host->clk);
690711
clk_disable_unprepare(msm_host->pclk);
691712
if (!IS_ERR(msm_host->bus_clk))
@@ -694,12 +715,57 @@ static int sdhci_msm_remove(struct platform_device *pdev)
694715
return 0;
695716
}
696717

718+
#ifdef CONFIG_PM
719+
static int sdhci_msm_runtime_suspend(struct device *dev)
720+
{
721+
struct sdhci_host *host = dev_get_drvdata(dev);
722+
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
723+
struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
724+
725+
clk_disable_unprepare(msm_host->clk);
726+
clk_disable_unprepare(msm_host->pclk);
727+
728+
return 0;
729+
}
730+
731+
static int sdhci_msm_runtime_resume(struct device *dev)
732+
{
733+
struct sdhci_host *host = dev_get_drvdata(dev);
734+
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
735+
struct sdhci_msm_host *msm_host = sdhci_pltfm_priv(pltfm_host);
736+
int ret;
737+
738+
ret = clk_prepare_enable(msm_host->clk);
739+
if (ret) {
740+
dev_err(dev, "clk_enable failed for core_clk: %d\n", ret);
741+
return ret;
742+
}
743+
ret = clk_prepare_enable(msm_host->pclk);
744+
if (ret) {
745+
dev_err(dev, "clk_enable failed for iface_clk: %d\n", ret);
746+
clk_disable_unprepare(msm_host->clk);
747+
return ret;
748+
}
749+
750+
return 0;
751+
}
752+
#endif
753+
754+
static const struct dev_pm_ops sdhci_msm_pm_ops = {
755+
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
756+
pm_runtime_force_resume)
757+
SET_RUNTIME_PM_OPS(sdhci_msm_runtime_suspend,
758+
sdhci_msm_runtime_resume,
759+
NULL)
760+
};
761+
697762
static struct platform_driver sdhci_msm_driver = {
698763
.probe = sdhci_msm_probe,
699764
.remove = sdhci_msm_remove,
700765
.driver = {
701766
.name = "sdhci_msm",
702767
.of_match_table = sdhci_msm_dt_match,
768+
.pm = &sdhci_msm_pm_ops,
703769
},
704770
};
705771

0 commit comments

Comments
 (0)