From patchwork Thu Oct 27 15:48:44 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulf Hansson X-Patchwork-Id: 4863 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 90C8D23E0E for ; Thu, 27 Oct 2011 15:49:16 +0000 (UTC) Received: from mail-fx0-f52.google.com (mail-fx0-f52.google.com [209.85.161.52]) by fiordland.canonical.com (Postfix) with ESMTP id 7C2ABA184CB for ; Thu, 27 Oct 2011 15:49:16 +0000 (UTC) Received: by faan26 with SMTP id n26so4072177faa.11 for ; Thu, 27 Oct 2011 08:49:16 -0700 (PDT) Received: by 10.223.16.82 with SMTP id n18mr67510918faa.2.1319730554851; Thu, 27 Oct 2011 08:49:14 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.152.1.71 with SMTP id 7cs49810lak; Thu, 27 Oct 2011 08:49:14 -0700 (PDT) Received: by 10.213.25.82 with SMTP id y18mr3813861ebb.130.1319730553916; Thu, 27 Oct 2011 08:49:13 -0700 (PDT) Received: from eu1sys200aog110.obsmtp.com (eu1sys200aog110.obsmtp.com. [207.126.144.129]) by mx.google.com with SMTP id 39si1912595eev.125.2011.10.27.08.49.04 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 27 Oct 2011 08:49:13 -0700 (PDT) Received-SPF: neutral (google.com: 207.126.144.129 is neither permitted nor denied by best guess record for domain of ulf.hansson@stericsson.com) client-ip=207.126.144.129; Authentication-Results: mx.google.com; spf=neutral (google.com: 207.126.144.129 is neither permitted nor denied by best guess record for domain of ulf.hansson@stericsson.com) smtp.mail=ulf.hansson@stericsson.com Received: from beta.dmz-ap.st.com ([138.198.100.35]) (using TLSv1) by eu1sys200aob110.postini.com ([207.126.147.11]) with SMTP; Thu, 27 Oct 2011 15:49:13 UTC Received: from zeta.dmz-ap.st.com (ns6.st.com [138.198.234.13]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 7862FD1; Thu, 27 Oct 2011 15:40:25 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-ap.st.com (STMicroelectronics) with ESMTP id A10C1778; Thu, 27 Oct 2011 15:48:51 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id 8BDA8A8096; Thu, 27 Oct 2011 17:48:44 +0200 (CEST) Received: from localhost.localdomain (10.230.100.153) by smtp.stericsson.com (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.3.83.0; Thu, 27 Oct 2011 17:48:50 +0200 From: Ulf Hansson To: Russell King , Cc: , "Rafael J. Wysocki" , Magnus Damm , Ulf Hansson Subject: [PATCH] AMBA: Use suspend_noriq to force devices into runtime suspend Date: Thu, 27 Oct 2011 17:48:44 +0200 Message-ID: <1319730524-29483-1-git-send-email-ulf.hansson@stericsson.com> X-Mailer: git-send-email 1.7.5.4 MIME-Version: 1.0 To be able to make sure devices are put into runtime suspend after a suspend sequence, the suspend_noirq callback is used. Previously it was was possible for drivers doing pm_runtime_suspend and pm_runtime_put_sync directly from it's suspend callbacks. This is now not possible due to the following commit, which solve a race issue: PM: Limit race conditions between runtime PM and system sleep (v2) Signed-off-by: Ulf Hansson --- drivers/amba/bus.c | 113 ++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 79 insertions(+), 34 deletions(-) diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index bd230e8..7ba523a 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -135,6 +135,79 @@ static void amba_pm_complete(struct device *dev) #endif /* !CONFIG_PM_SLEEP */ +#ifdef CONFIG_PM_RUNTIME +/* + * Hooks to provide runtime PM of the pclk (bus clock). It is safe to + * enable/disable the bus clock at runtime PM suspend/resume as this + * does not result in loss of context. However, disabling vcore power + * would do, so we leave that to the driver. + */ +static int amba_pm_runtime_suspend(struct device *dev) +{ + struct amba_device *pcdev = to_amba_device(dev); + int ret = pm_generic_runtime_suspend(dev); + + if (ret == 0 && dev->driver) + clk_disable(pcdev->pclk); + + return ret; +} + +static int amba_pm_runtime_suspend_noirq(struct device *dev) +{ + int ret = 0; + + /* + * If the amba device is not already runtime suspended + * force it into this state to save power. + */ + if (!pm_runtime_status_suspended(dev)) + ret = amba_pm_runtime_suspend(dev); + + return ret; +} + +static int amba_pm_runtime_resume(struct device *dev) +{ + struct amba_device *pcdev = to_amba_device(dev); + int ret; + + if (dev->driver) { + ret = clk_enable(pcdev->pclk); + /* Failure is probably fatal to the system, but... */ + if (ret) + return ret; + } + + return pm_generic_runtime_resume(dev); +} + +static int amba_pm_runtime_resume_noirq(struct device *dev) +{ + int ret = 0; + + /* + * If the amba device has been forced into runtime suspend state, + * we must make sure to restore it back into runtime resumed state. + */ + if (!pm_runtime_status_suspended(dev)) + ret = amba_pm_runtime_resume(dev); + + return ret; +} +#else /* !CONFIG_PM_RUNTIME */ + +static int amba_pm_runtime_suspend_noirq(struct device *dev) +{ + return 0; +} +static int amba_pm_runtime_resume_noirq(struct device *dev) +{ + return 0; +} + +#endif /* !CONFIG_PM_RUNTIME */ + #ifdef CONFIG_SUSPEND static int amba_pm_suspend(struct device *dev) @@ -163,7 +236,9 @@ static int amba_pm_suspend_noirq(struct device *dev) if (!drv) return 0; - if (drv->pm) { + ret = amba_pm_runtime_suspend_noirq(dev); + + if (!ret && drv->pm) { if (drv->pm->suspend_noirq) ret = drv->pm->suspend_noirq(dev); } @@ -202,6 +277,9 @@ static int amba_pm_resume_noirq(struct device *dev) ret = drv->pm->resume_noirq(dev); } + if (!ret) + ret = amba_pm_runtime_resume_noirq(dev); + return ret; } @@ -365,39 +443,6 @@ static int amba_pm_restore_noirq(struct device *dev) #endif /* !CONFIG_HIBERNATE_CALLBACKS */ -#ifdef CONFIG_PM_RUNTIME -/* - * Hooks to provide runtime PM of the pclk (bus clock). It is safe to - * enable/disable the bus clock at runtime PM suspend/resume as this - * does not result in loss of context. However, disabling vcore power - * would do, so we leave that to the driver. - */ -static int amba_pm_runtime_suspend(struct device *dev) -{ - struct amba_device *pcdev = to_amba_device(dev); - int ret = pm_generic_runtime_suspend(dev); - - if (ret == 0 && dev->driver) - clk_disable(pcdev->pclk); - - return ret; -} - -static int amba_pm_runtime_resume(struct device *dev) -{ - struct amba_device *pcdev = to_amba_device(dev); - int ret; - - if (dev->driver) { - ret = clk_enable(pcdev->pclk); - /* Failure is probably fatal to the system, but... */ - if (ret) - return ret; - } - - return pm_generic_runtime_resume(dev); -} -#endif #ifdef CONFIG_PM