From patchwork Fri Feb 1 09:48:30 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Liu X-Patchwork-Id: 2077971 Return-Path: X-Original-To: patchwork-linux-mmc@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id 8E2B940106 for ; Fri, 1 Feb 2013 09:47:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756590Ab3BAJr1 (ORCPT ); Fri, 1 Feb 2013 04:47:27 -0500 Received: from na3sys009aog133.obsmtp.com ([74.125.149.82]:45804 "EHLO na3sys009aog133.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755721Ab3BAJrL (ORCPT ); Fri, 1 Feb 2013 04:47:11 -0500 Received: from MSI-MTA.marvell.com ([65.219.4.132]) (using TLSv1) by na3sys009aob133.postini.com ([74.125.148.12]) with SMTP ID DSNKUQuPCtTXcUjkA6YJIkm4/gCUEGCUWYVg@postini.com; Fri, 01 Feb 2013 01:47:11 PST Received: from maili.marvell.com ([10.68.76.210]) by MSI-MTA.marvell.com with Microsoft SMTPSVC(6.0.3790.4675); Fri, 1 Feb 2013 01:46:49 -0800 Received: from kliu5-desktop.marvell.com (unknown [10.38.36.240]) by maili.marvell.com (Postfix) with ESMTP id 564F04E517; Fri, 1 Feb 2013 01:46:45 -0800 (PST) From: Kevin Liu To: linux-mmc@vger.kernel.org, Chris Ball , Sujit Reddy Thumma , Jaehoon Chung , Andy Shevchenko , Aaron Lu , Ulf Hansson , Alexander Stein Cc: Nicolas Pitre , Adrian Hunter , Philip Rakity , Shawn Guo , Johan Rudholm , Daniel Drake , Guennadi Liakhovetski , Jerry Huang , Girish K S , Haijun Zhang , Viresh Kumar , Heiko Stuebner , Thomas Abraham , Chander Kashyap , Sebastian Hesselbarth , Zhangfei Gao , Haojian Zhuang , Chao Xie , Kevin Liu , Kevin Liu , Jialing Fu Subject: [PATCH RESEND v2] mmc: sdhci-pxav3: add pm runtime support Date: Fri, 1 Feb 2013 17:48:30 +0800 Message-Id: <1359712110-20452-1-git-send-email-kliu5@marvell.com> X-Mailer: git-send-email 1.7.9.5 X-OriginalArrivalTime: 01 Feb 2013 09:46:49.0878 (UTC) FILETIME=[0EB34360:01CE0061] Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org Change-Id: Iacc46aedfb9cd4ee0ddeb1866f90f857541beb3f Signed-off-by: Jialing Fu Signed-off-by: Kevin Liu --- drivers/mmc/host/sdhci-pxav3.c | 97 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 3d20c10..62dcf61 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c @@ -32,10 +32,14 @@ #include #include #include +#include +#include #include "sdhci.h" #include "sdhci-pltfm.h" +#define PXAV3_RPM_DELAY_MS 50 + #define SD_CLOCK_BURST_SIZE_SETUP 0x10A #define SDCLK_SEL 0x100 #define SDCLK_DELAY_SHIFT 9 @@ -303,9 +307,19 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) sdhci_get_of_property(pdev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, + PXAV3_RPM_DELAY_MS); + pm_runtime_use_autosuspend(&pdev->dev); + pm_suspend_ignore_children(&pdev->dev, 1); + pm_runtime_get_noresume(&pdev->dev); + ret = sdhci_add_host(host); if (ret) { dev_err(&pdev->dev, "failed to add host\n"); + pm_runtime_forbid(&pdev->dev); + pm_runtime_disable(&pdev->dev); goto err_add_host; } @@ -318,6 +332,8 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); } + pm_runtime_put_autosuspend(&pdev->dev); + return 0; err_add_host: @@ -336,7 +352,9 @@ static int sdhci_pxav3_remove(struct platform_device *pdev) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_pxa *pxa = pltfm_host->priv; + pm_runtime_get_sync(&pdev->dev); sdhci_remove_host(host, 1); + pm_runtime_disable(&pdev->dev); clk_disable_unprepare(pltfm_host->clk); clk_put(pltfm_host->clk); @@ -349,6 +367,83 @@ static int sdhci_pxav3_remove(struct platform_device *pdev) return 0; } +#ifdef CONFIG_PM_SLEEP +static int sdhci_pxav3_suspend(struct device *dev) +{ + int ret; + struct sdhci_host *host = dev_get_drvdata(dev); + + pm_runtime_get_sync(dev); + ret = sdhci_suspend_host(host); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return ret; +} + +static int sdhci_pxav3_resume(struct device *dev) +{ + int ret; + struct sdhci_host *host = dev_get_drvdata(dev); + + pm_runtime_get_sync(dev); + ret = sdhci_resume_host(host); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return ret; +} +#endif + +#ifdef CONFIG_PM_RUNTIME +static int sdhci_pxav3_runtime_suspend(struct device *dev) +{ + struct sdhci_host *host = dev_get_drvdata(dev); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + unsigned long flags; + + if (pltfm_host->clk) { + spin_lock_irqsave(&host->lock, flags); + host->runtime_suspended = true; + spin_unlock_irqrestore(&host->lock, flags); + + clk_disable_unprepare(pltfm_host->clk); + } + + return 0; +} + +static int sdhci_pxav3_runtime_resume(struct device *dev) +{ + struct sdhci_host *host = dev_get_drvdata(dev); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + unsigned long flags; + + if (pltfm_host->clk) { + clk_prepare_enable(pltfm_host->clk); + + spin_lock_irqsave(&host->lock, flags); + host->runtime_suspended = false; + spin_unlock_irqrestore(&host->lock, flags); + } + + return 0; +} +#endif + +#ifdef CONFIG_PM +static const struct dev_pm_ops sdhci_pxav3_pmops = { + SET_SYSTEM_SLEEP_PM_OPS(sdhci_pxav3_suspend, sdhci_pxav3_resume) + SET_RUNTIME_PM_OPS(sdhci_pxav3_runtime_suspend, + sdhci_pxav3_runtime_resume, NULL) +}; + +#define SDHCI_PXAV3_PMOPS (&sdhci_pxav3_pmops) + +#else +#define SDHCI_PXAV3_PMOPS NULL +#endif + static struct platform_driver sdhci_pxav3_driver = { .driver = { .name = "sdhci-pxav3", @@ -356,7 +451,7 @@ static struct platform_driver sdhci_pxav3_driver = { .of_match_table = sdhci_pxav3_of_match, #endif .owner = THIS_MODULE, - .pm = SDHCI_PLTFM_PMOPS, + .pm = SDHCI_PXAV3_PMOPS, }, .probe = sdhci_pxav3_probe, .remove = sdhci_pxav3_remove,