From patchwork Mon Jul 5 09:21:22 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Magnus Damm X-Patchwork-Id: 110200 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o659TA8e026358 for ; Mon, 5 Jul 2010 09:29:13 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752061Ab0GEJ3J (ORCPT ); Mon, 5 Jul 2010 05:29:09 -0400 Received: from mail-pw0-f46.google.com ([209.85.160.46]:38273 "EHLO mail-pw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752316Ab0GEJ3J (ORCPT ); Mon, 5 Jul 2010 05:29:09 -0400 Received: by pwi5 with SMTP id 5so1409192pwi.19 for ; Mon, 05 Jul 2010 02:29:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:date:message-id :subject; bh=cynCR8CPESuxb9OQ/MApFOICFVVSmBG9a14DypMCkMw=; b=LWlJPWI/kcLYR/RmDRkgK6e5kX8T4en4DQ8hF2opGel4Q9r/pRwX6oFI+SJZnT4B4j JOiSx4RV53hnkEmq2ipbC9Bx/NygxVNbRP9Td6yf8LF+WDkGuf8SZl6KPF+/DT1VZidS SIo6D2lFqYIX2FwAIis773hsFiyEU/TNlLYsQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:date:message-id:subject; b=q3zpyqHeSteIS9Bg8Pv6DCft8L3E0k6IQriAjQCLacT7krLi0KdcUGlh3+5Jn7AM9h tnN01Vb148+IYNIa8/9OVfUfeiYLulnVeQCE3WC0tbG0USEA4ij0Tdh1aQjUF/hwu6AP g0+aLpdHoAcwcAh2DRZ9TT53pRKBLsgzI9cE0= Received: by 10.142.100.16 with SMTP id x16mr3017203wfb.245.1278321667378; Mon, 05 Jul 2010 02:21:07 -0700 (PDT) Received: from [127.0.0.1] (49.14.32.202.bf.2iij.net [202.32.14.49]) by mx.google.com with ESMTPS id y16sm4350607wff.14.2010.07.05.02.21.06 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 05 Jul 2010 02:21:07 -0700 (PDT) From: Magnus Damm To: linux-sh@vger.kernel.org Cc: Magnus Damm , lethal@linux-sh.org Date: Mon, 05 Jul 2010 18:21:22 +0900 Message-Id: <20100705092122.22936.76406.sendpatchset@t400s> Subject: [PATCH] ARM: mach-shmobile: Runtime PM prototype Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Mon, 05 Jul 2010 09:29:23 +0000 (UTC) --- 0001/arch/arm/include/asm/device.h +++ work/arch/arm/include/asm/device.h 2010-07-05 15:36:34.000000000 +0900 @@ -13,6 +13,9 @@ struct dev_archdata { }; struct pdev_archdata { +#ifdef CONFIG_ARCH_SHMOBILE + struct clk *clk; +#endif }; #endif --- 0001/arch/arm/mach-shmobile/Kconfig +++ work/arch/arm/mach-shmobile/Kconfig 2010-07-05 15:36:34.000000000 +0900 @@ -25,6 +25,8 @@ config ARCH_SH7372 select COMMON_CLKDEV select SH_CLK_CPG select GENERIC_CLOCKEVENTS + select PM + select PM_RUNTIME comment "SH-Mobile Board Type" --- 0001/arch/arm/mach-shmobile/Makefile +++ work/arch/arm/mach-shmobile/Makefile 2010-07-05 15:36:55.000000000 +0900 @@ -3,7 +3,7 @@ # # Common objects -obj-y := timer.o console.o clock.o +obj-y := timer.o console.o clock.o pm_runtime.o # CPU objects obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o --- 0001/arch/arm/mach-shmobile/clock-sh7372.c +++ work/arch/arm/mach-shmobile/clock-sh7372.c 2010-07-05 15:37:50.000000000 +0900 @@ -274,7 +274,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ - [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, CLK_ENABLE_ON_INIT), /* FSIA */ + [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSIA */ [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ --- /dev/null +++ work/arch/arm/mach-shmobile/pm_runtime.c 2010-07-05 16:21:52.000000000 +0900 @@ -0,0 +1,109 @@ +/* + * arch/arm/mach-shmobile/pm_runtime.c + * + * Runtime PM support code for SuperH Mobile ARM + * + * Copyright (C) 2009-2010 Magnus Damm + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + */ +//#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include + +static struct clk uninitialized_clock; + +static void platform_pm_init_once(struct platform_device *pdev) +{ + if (pdev->archdata.clk == &uninitialized_clock) { + pdev->archdata.clk = clk_get(&pdev->dev, NULL); + dev_info(&pdev->dev, "clocks managed by runtime pm\n"); + } +} + +static void platform_pm_init_bug(struct platform_device *pdev) +{ + if (pdev->archdata.clk == &uninitialized_clock) { + pdev->archdata.clk = NULL; + dev_info(&pdev->dev, "incorrect runtime pm usage\n"); + } +} + +int platform_pm_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + + dev_dbg(dev, "platform_pm_runtime_suspend()\n"); + + platform_pm_init_bug(pdev); + + if (pdev->archdata.clk) + clk_disable(pdev->archdata.clk); + + return 0; +} + +int platform_pm_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + + dev_dbg(dev, "platform_pm_runtime_resume()\n"); + + platform_pm_init_once(pdev); + + if (pdev->archdata.clk) + clk_enable(pdev->archdata.clk); + + return 0; +} + +int platform_pm_runtime_idle(struct device *dev) +{ + /* suspend synchronously to disable clocks immediately */ + return pm_runtime_suspend(dev); +} + +static int platform_bus_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct device *dev = data; + struct platform_device *pdev = to_platform_device(dev); + + dev_dbg(dev, "platform_bus_notify() %ld !\n", action); + + switch (action) { + case BUS_NOTIFY_ADD_DEVICE: + pdev->archdata.clk = &uninitialized_clock; + + break; + case BUS_NOTIFY_DEL_DEVICE: + if (pdev->archdata.clk && + pdev->archdata.clk != &uninitialized_clock) + clk_put(pdev->archdata.clk); + + pdev->archdata.clk = NULL; + break; + } + + + return 0; +} + +static struct notifier_block platform_bus_notifier = { + .notifier_call = platform_bus_notify +}; + +static int __init sh_pm_runtime_init(void) +{ + bus_register_notifier(&platform_bus_type, &platform_bus_notifier); + return 0; +} +core_initcall(sh_pm_runtime_init);