From patchwork Sat Jun 11 20:40:11 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Wysocki X-Patchwork-Id: 872472 Received: from smtp1.linux-foundation.org (smtp1.linux-foundation.org [140.211.169.13]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p5BKi7LQ029863 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Sat, 11 Jun 2011 20:44:27 GMT Received: from daredevil.linux-foundation.org (localhost [127.0.0.1]) by smtp1.linux-foundation.org (8.14.2/8.13.5/Debian-3ubuntu1.1) with ESMTP id p5BKgggI019308; Sat, 11 Jun 2011 13:42:44 -0700 Received: from ogre.sisk.pl (ogre.sisk.pl [217.79.144.158]) by smtp1.linux-foundation.org (8.14.2/8.13.5/Debian-3ubuntu1.1) with ESMTP id p5BKeet0018695 for ; Sat, 11 Jun 2011 13:40:42 -0700 Received: from localhost (localhost.localdomain [127.0.0.1]) by ogre.sisk.pl (Postfix) with ESMTP id A0B3E1B1EC7; Sat, 11 Jun 2011 22:23:34 +0200 (CEST) Received: from ogre.sisk.pl ([127.0.0.1]) by localhost (ogre.sisk.pl [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 27800-09; Sat, 11 Jun 2011 22:23:07 +0200 (CEST) Received: from ferrari.rjw.lan (220-bem-13.acn.waw.pl [82.210.184.220]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ogre.sisk.pl (Postfix) with ESMTP id C01561B2064; Sat, 11 Jun 2011 22:22:30 +0200 (CEST) From: "Rafael J. Wysocki" To: Linux PM mailing list Date: Sat, 11 Jun 2011 22:40:11 +0200 User-Agent: KMail/1.13.6 (Linux/2.6.39+; KDE/4.6.0; x86_64; ; ) References: <201106112223.04972.rjw@sisk.pl> In-Reply-To: <201106112223.04972.rjw@sisk.pl> MIME-Version: 1.0 Message-Id: <201106112240.11621.rjw@sisk.pl> X-Virus-Scanned: amavisd-new at ogre.sisk.pl using MkS_Vir for Linux Received-SPF: pass (localhost is always allowed.) X-Spam-Status: No, hits=-3.935 required=5 tests=AWL, BAYES_00, OSDL_HEADER_SUBJECT_BRACKETED X-Spam-Checker-Version: SpamAssassin 3.2.4-osdl_revision__1.47__ X-MIMEDefang-Filter: lf$Revision: 1.188 $ X-Scanned-By: MIMEDefang 2.63 on 140.211.169.21 Cc: linux-sh@vger.kernel.org, Greg Kroah-Hartman , LKML Subject: [linux-pm] [PATCH 8/8] ARM / shmobile: Support for I/O PM domains for SH7372 (v5) X-BeenThere: linux-pm@lists.linux-foundation.org X-Mailman-Version: 2.1.9 Precedence: list List-Id: Linux power management List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-pm-bounces@lists.linux-foundation.org Errors-To: linux-pm-bounces@lists.linux-foundation.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Sat, 11 Jun 2011 20:44:27 +0000 (UTC) From: Rafael J. Wysocki Use the generic power domains support introduced by the previous patch to implement support for power domains on SH7372. Signed-off-by: Rafael J. Wysocki --- arch/arm/mach-shmobile/Kconfig | 1 arch/arm/mach-shmobile/Makefile | 4 + arch/arm/mach-shmobile/board-mackerel.c | 3 + arch/arm/mach-shmobile/include/mach/sh7372.h | 16 +++++ arch/arm/mach-shmobile/pm-sh7372.c | 81 +++++++++++++++++++++++++++ 5 files changed, 105 insertions(+) Index: linux-2.6/arch/arm/mach-shmobile/board-mackerel.c =================================================================== --- linux-2.6.orig/arch/arm/mach-shmobile/board-mackerel.c +++ linux-2.6/arch/arm/mach-shmobile/board-mackerel.c @@ -1496,6 +1496,9 @@ static void __init mackerel_init(void) platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices)); + sh7372_add_device_to_domain(SH7372_A4LC, &lcdc_device); + sh7372_add_device_to_domain(SH7372_A4LC, &hdmi_lcdc_device); + hdmi_init_pm_clock(); sh7372_pm_init(); } Index: linux-2.6/arch/arm/mach-shmobile/include/mach/sh7372.h =================================================================== --- linux-2.6.orig/arch/arm/mach-shmobile/include/mach/sh7372.h +++ linux-2.6/arch/arm/mach-shmobile/include/mach/sh7372.h @@ -12,6 +12,7 @@ #define __ASM_SH7372_H__ #include +#include /* * Pin Function Controller: @@ -470,4 +471,19 @@ extern struct clk sh7372_fsibck_clk; extern struct clk sh7372_fsidiva_clk; extern struct clk sh7372_fsidivb_clk; +struct platform_device; + +#ifdef CONFIG_PM +extern struct generic_pm_domain sh7372_a4lc_domain; +#define SH7372_A4LC (&sh7372_a4lc_domain) + +extern void sh7372_add_device_to_domain(struct generic_pm_domain *domain, + struct platform_device *pdev); +#else +#define SH7372_A4LC NULL + +static inline void sh7372_add_device_to_domain(struct generic_pm_domain *dom, + struct platform_device *pd) {} +#endif /* CONFIG_PM */ + #endif /* __ASM_SH7372_H__ */ Index: linux-2.6/arch/arm/mach-shmobile/Makefile =================================================================== --- linux-2.6.orig/arch/arm/mach-shmobile/Makefile +++ linux-2.6/arch/arm/mach-shmobile/Makefile @@ -42,6 +42,10 @@ obj-$(CONFIG_MACH_AP4EVB) += board-ap4ev obj-$(CONFIG_MACH_AG5EVM) += board-ag5evm.o obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o +# PM objects +pm-$(CONFIG_ARCH_SH7372) += pm-sh7372.o + # Framework support obj-$(CONFIG_SMP) += $(smp-y) obj-$(CONFIG_GENERIC_GPIO) += $(pfc-y) +obj-$(CONFIG_PM) += $(pm-y) Index: linux-2.6/arch/arm/mach-shmobile/Kconfig =================================================================== --- linux-2.6.orig/arch/arm/mach-shmobile/Kconfig +++ linux-2.6/arch/arm/mach-shmobile/Kconfig @@ -19,6 +19,7 @@ config ARCH_SH7372 select CPU_V7 select SH_CLK_CPG select ARCH_WANT_OPTIONAL_GPIOLIB + select PM_GENERIC_DOMAINS config ARCH_SH73A0 bool "SH-Mobile AG5 (R8A73A00)" Index: linux-2.6/arch/arm/mach-shmobile/pm-sh7372.c =================================================================== --- linux-2.6.orig/arch/arm/mach-shmobile/pm-sh7372.c +++ linux-2.6/arch/arm/mach-shmobile/pm-sh7372.c @@ -15,16 +15,97 @@ #include #include #include +#include +#include #include #include #include #include +#include #define SMFRAM 0xe6a70000 #define SYSTBCR 0xe6150024 #define SBAR 0xe6180020 #define APARMBAREA 0xe6f10020 +#define SPDCR 0xe6180008 +#define SWUCR 0xe6180014 +#define PSTR 0xe6180080 + +struct sh7372_domain_data { + unsigned int bit_shift; +}; + +static int pd_power_down(struct dev_pm_domain *domain) +{ + struct sh7372_domain_data *dd = domain->platform_data; + unsigned int mask = 1 << dd->bit_shift; + + if (__raw_readl(PSTR) & mask) { + __raw_writel(mask, SPDCR); + + while (__raw_readl(SPDCR) & mask) {} + + pr_debug("sh7372 power domain down 0x%08x -> PSTR = 0x%08x\n", + mask, __raw_readl(PSTR)); + } + + return 0; +} + +static int pd_power_up(struct dev_pm_domain *domain) +{ + struct sh7372_domain_data *dd = domain->platform_data; + unsigned int mask = 1 << dd->bit_shift; + + if (!(__raw_readl(PSTR) & mask)) { + __raw_writel(mask, SWUCR); + + while (__raw_readl(SWUCR) & mask) {} + + pr_debug("sh7372 power domain up 0x%08x -> PSTR = 0x%08x\n", + mask, __raw_readl(PSTR)); + } + + return 0; +} + +static void sh7372_init_domain(struct generic_pm_domain *domain, + struct sh7372_domain_data *pdata) +{ + pm_genpd_init(domain, NULL, false); + domain->domain.platform_data = pdata; + domain->stop_device = pm_runtime_clk_suspend; + domain->start_device = pm_runtime_clk_resume; + domain->power_off = pd_power_down; + domain->power_on = pd_power_up; +} + +void sh7372_add_device_to_domain(struct generic_pm_domain *domain, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + if (!dev->power.subsys_data) { + pm_runtime_clk_init(dev); + pm_runtime_clk_add(dev, NULL); + } + pm_genpd_add_device(domain, dev); +} + +static struct sh7372_domain_data sh7372_a4lc_domain_data = { + .bit_shift = 1, +}; + +struct generic_pm_domain sh7372_a4lc_domain; + +static int __init sh7372_power_domains_init(void) +{ + sh7372_init_domain(&sh7372_a4lc_domain, &sh7372_a4lc_domain_data); + return 0; +} +core_initcall(sh7372_power_domains_init); + static void sh7372_enter_core_standby(void) { void __iomem *smfram = (void __iomem *)SMFRAM;