lkml.org 
[lkml]   [2023]   [May]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v1 1/1] mmc: sdhci-of-dwcmshc: Add runtime PM operations for BlueField-3
    Date
    This commit implements the runtime PM operations for BlueField-3 SoC
    to disable eMMC card clock when idle.

    Reviewed-by: David Thompson <davthompson@nvidia.com>
    Signed-off-by: Liming Sun <limings@nvidia.com>
    ---
    drivers/mmc/host/sdhci-of-dwcmshc.c | 76 ++++++++++++++++++++++++++++-
    1 file changed, 74 insertions(+), 2 deletions(-)

    diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c
    index e68cd87998c8..19ce058fc5f0 100644
    --- a/drivers/mmc/host/sdhci-of-dwcmshc.c
    +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
    @@ -15,6 +15,7 @@
    #include <linux/module.h>
    #include <linux/of.h>
    #include <linux/of_device.h>
    +#include <linux/pm_runtime.h>
    #include <linux/reset.h>
    #include <linux/sizes.h>

    @@ -542,8 +543,10 @@ static int dwcmshc_probe(struct platform_device *pdev)
    }

    #ifdef CONFIG_ACPI
    - if (pltfm_data == &sdhci_dwcmshc_bf3_pdata)
    + if (pltfm_data == &sdhci_dwcmshc_bf3_pdata) {
    sdhci_enable_v4_mode(host);
    + pm_runtime_enable(dev);
    + }
    #endif

    host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
    @@ -646,7 +649,76 @@ static int dwcmshc_resume(struct device *dev)
    }
    #endif

    -static SIMPLE_DEV_PM_OPS(dwcmshc_pmops, dwcmshc_suspend, dwcmshc_resume);
    +#ifdef CONFIG_PM
    +
    +#ifdef CONFIG_ACPI
    +static void dwcmshc_enable_card_clk(struct sdhci_host *host)
    +{
    + u16 ctrl;
    +
    + ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
    + ctrl |= SDHCI_CLOCK_CARD_EN;
    + sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL);
    +}
    +
    +static void dwcmshc_disable_card_clk(struct sdhci_host *host)
    +{
    + u16 ctrl;
    +
    + ctrl = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
    + ctrl &= ~SDHCI_CLOCK_CARD_EN;
    + sdhci_writew(host, ctrl, SDHCI_CLOCK_CONTROL);
    +}
    +#endif
    +
    +static int dwcmshc_runtime_suspend(struct device *dev)
    +{
    + struct sdhci_host *host = dev_get_drvdata(dev);
    + const struct sdhci_pltfm_data *pltfm_data;
    + int ret = 0;
    +
    + pltfm_data = device_get_match_data(dev);
    + if (!pltfm_data)
    + return -ENODEV;
    +
    +#ifdef CONFIG_ACPI
    + if (pltfm_data == &sdhci_dwcmshc_bf3_pdata) {
    + ret = sdhci_runtime_suspend_host(host);
    + if (!ret)
    + dwcmshc_disable_card_clk(host);
    + }
    +#endif
    +
    + return ret;
    +}
    +
    +static int dwcmshc_runtime_resume(struct device *dev)
    +{
    + struct sdhci_host *host = dev_get_drvdata(dev);
    + const struct sdhci_pltfm_data *pltfm_data;
    + int ret = 0;
    +
    + pltfm_data = device_get_match_data(dev);
    + if (!pltfm_data)
    + return -ENODEV;
    +
    +#ifdef CONFIG_ACPI
    + if (pltfm_data == &sdhci_dwcmshc_bf3_pdata) {
    + dwcmshc_enable_card_clk(host);
    + ret = sdhci_runtime_resume_host(host, 0);
    + }
    +#endif
    +
    + return ret;
    +}
    +
    +#endif
    +
    +static const struct dev_pm_ops dwcmshc_pmops = {
    + SET_SYSTEM_SLEEP_PM_OPS(dwcmshc_suspend, dwcmshc_resume)
    + SET_RUNTIME_PM_OPS(dwcmshc_runtime_suspend,
    + dwcmshc_runtime_resume, NULL)
    +};

    static struct platform_driver sdhci_dwcmshc_driver = {
    .driver = {
    --
    2.30.1
    \
     
     \ /
      Last update: 2023-05-11 21:04    [W:4.163 / U:0.088 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site