diff mbox

[PATCH/RFC,4/6] ARM: move SH-mobile runtime PM to arm/common for sharing with other platforms

Message ID 1302134569-22825-5-git-send-email-khilman@ti.com (mailing list archive)
State RFC
Headers show

Commit Message

Kevin Hilman April 7, 2011, 12:02 a.m. UTC
There is really nothing SH-mobile specific about this runtime PM
implementation.  Any platform wanting to implement runtime PM based on
simple clock gating can use this implementation.

Signed-off-by: Kevin Hilman <khilman@ti.com>
---
 arch/arm/common/Makefile            |    1 +
 arch/arm/common/pm_runtime_clock.c  |  176 ++++++++++++++++++++++++++++++++++
 arch/arm/include/asm/pm_runtime.h   |   17 ++++
 arch/arm/mach-shmobile/pm_runtime.c |  179 -----------------------------------
 4 files changed, 194 insertions(+), 179 deletions(-)
 create mode 100644 arch/arm/common/pm_runtime_clock.c
 create mode 100644 arch/arm/include/asm/pm_runtime.h
 delete mode 100644 arch/arm/mach-shmobile/pm_runtime.c

Comments

Paul Mundt April 7, 2011, 4:56 p.m. UTC | #1
On Wed, Apr 06, 2011 at 05:02:47PM -0700, Kevin Hilman wrote:
> There is really nothing SH-mobile specific about this runtime PM
> implementation.  Any platform wanting to implement runtime PM based on
> simple clock gating can use this implementation.
> 
> Signed-off-by: Kevin Hilman <khilman@ti.com>

This observation is wholly architecture agnostic, so it's not clear that
keeping it in arch/arm/common is any better. It seems that this would be
better suited for drivers/base/power/ with a generic Kconfig symbol.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kevin Hilman April 7, 2011, 5:08 p.m. UTC | #2
Paul Mundt <lethal@linux-sh.org> writes:

> On Wed, Apr 06, 2011 at 05:02:47PM -0700, Kevin Hilman wrote:
>> There is really nothing SH-mobile specific about this runtime PM
>> implementation.  Any platform wanting to implement runtime PM based on
>> simple clock gating can use this implementation.
>> 
>> Signed-off-by: Kevin Hilman <khilman@ti.com>
>
> This observation is wholly architecture agnostic, so it's not clear that
> keeping it in arch/arm/common is any better. It seems that this would be
> better suited for drivers/base/power/ with a generic Kconfig symbol.

Sounds fine to me.

Thanks for the review,

Kevin
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rafael Wysocki April 7, 2011, 10:35 p.m. UTC | #3
On Thursday, April 07, 2011, Kevin Hilman wrote:
> Paul Mundt <lethal@linux-sh.org> writes:
> 
> > On Wed, Apr 06, 2011 at 05:02:47PM -0700, Kevin Hilman wrote:
> >> There is really nothing SH-mobile specific about this runtime PM
> >> implementation.  Any platform wanting to implement runtime PM based on
> >> simple clock gating can use this implementation.
> >> 
> >> Signed-off-by: Kevin Hilman <khilman@ti.com>
> >
> > This observation is wholly architecture agnostic, so it's not clear that
> > keeping it in arch/arm/common is any better. It seems that this would be
> > better suited for drivers/base/power/ with a generic Kconfig symbol.
> 
> Sounds fine to me.

Well, what platforms is the clock framework available on?

Rafael
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kevin Hilman April 8, 2011, 12:38 a.m. UTC | #4
"Rafael J. Wysocki" <rjw@sisk.pl> writes:

> On Thursday, April 07, 2011, Kevin Hilman wrote:
>> Paul Mundt <lethal@linux-sh.org> writes:
>> 
>> > On Wed, Apr 06, 2011 at 05:02:47PM -0700, Kevin Hilman wrote:
>> >> There is really nothing SH-mobile specific about this runtime PM
>> >> implementation.  Any platform wanting to implement runtime PM based on
>> >> simple clock gating can use this implementation.
>> >> 
>> >> Signed-off-by: Kevin Hilman <khilman@ti.com>
>> >
>> > This observation is wholly architecture agnostic, so it's not clear that
>> > keeping it in arch/arm/common is any better. It seems that this would be
>> > better suited for drivers/base/power/ with a generic Kconfig symbol.
>> 
>> Sounds fine to me.
>
> Well, what platforms is the clock framework available on?

Well, the majority of implementations of <linux/clk.h> are certainly in
ARM, but I know it's also implemented for SH, and a quick grep shows
implementations in powerpc, mips and m68k also.

Kevin
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paul Mundt April 8, 2011, 5:01 a.m. UTC | #5
On Thu, Apr 07, 2011 at 05:38:38PM -0700, Kevin Hilman wrote:
> "Rafael J. Wysocki" <rjw@sisk.pl> writes:
> > On Thursday, April 07, 2011, Kevin Hilman wrote:
> >> Paul Mundt <lethal@linux-sh.org> writes:
> >> > This observation is wholly architecture agnostic, so it's not clear that
> >> > keeping it in arch/arm/common is any better. It seems that this would be
> >> > better suited for drivers/base/power/ with a generic Kconfig symbol.
> >> 
> >> Sounds fine to me.
> >
> > Well, what platforms is the clock framework available on?
> 
> Well, the majority of implementations of <linux/clk.h> are certainly in
> ARM, but I know it's also implemented for SH, and a quick grep shows
> implementations in powerpc, mips and m68k also.
> 
We also have CONFIG_HAVE_CLK that can be used as a dependency. In any
event, anything simply focusing on the clock bits can be completely
generic. On SH we still have these things lumped together with hwblk IDs,
but this is something we can likely transition off of with power domains.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
index e7521bca..efa79c7 100644
--- a/arch/arm/common/Makefile
+++ b/arch/arm/common/Makefile
@@ -18,3 +18,4 @@  obj-$(CONFIG_ARCH_IXP23XX)	+= uengine.o
 obj-$(CONFIG_PCI_HOST_ITE8152)  += it8152.o
 obj-$(CONFIG_COMMON_CLKDEV)	+= clkdev.o
 obj-$(CONFIG_ARM_TIMER_SP804)	+= timer-sp.o
+obj-$(CONFIG_PM_RUNTIME)	+= pm_runtime_clock.o
diff --git a/arch/arm/common/pm_runtime_clock.c b/arch/arm/common/pm_runtime_clock.c
new file mode 100644
index 0000000..453fc95
--- /dev/null
+++ b/arch/arm/common/pm_runtime_clock.c
@@ -0,0 +1,176 @@ 
+/*
+ * Generic Runtime PM support code for managing device clocks
+ *
+ *  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.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/bitmap.h>
+#include <linux/err.h>
+
+#ifdef CONFIG_PM_RUNTIME
+#define BIT_ONCE 0
+#define BIT_ACTIVE 1
+#define BIT_CLK_ENABLED 2
+
+struct pm_runtime_data {
+	unsigned long flags;
+	struct clk *clk;
+};
+
+static void __devres_release(struct device *dev, void *res)
+{
+	struct pm_runtime_data *prd = res;
+
+	dev_dbg(dev, "__devres_release()\n");
+
+	if (test_bit(BIT_CLK_ENABLED, &prd->flags))
+		clk_disable(prd->clk);
+
+	if (test_bit(BIT_ACTIVE, &prd->flags))
+		clk_put(prd->clk);
+}
+
+static struct pm_runtime_data *__to_prd(struct device *dev)
+{
+	return devres_find(dev, __devres_release, NULL, NULL);
+}
+
+static void platform_pm_runtime_init(struct device *dev,
+				     struct pm_runtime_data *prd)
+{
+	if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) {
+		prd->clk = clk_get(dev, NULL);
+		if (!IS_ERR(prd->clk)) {
+			set_bit(BIT_ACTIVE, &prd->flags);
+			dev_info(dev, "clocks managed by runtime pm\n");
+		}
+	}
+}
+
+static void platform_pm_runtime_bug(struct device *dev,
+				    struct pm_runtime_data *prd)
+{
+	if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags))
+		dev_err(dev, "runtime pm suspend before resume\n");
+}
+
+static int platform_pm_runtime_suspend(struct device *dev)
+{
+	struct pm_runtime_data *prd = __to_prd(dev);
+
+	dev_dbg(dev, "platform_pm_runtime_suspend()\n");
+
+	platform_pm_runtime_bug(dev, prd);
+
+	if (prd && test_bit(BIT_ACTIVE, &prd->flags)) {
+		clk_disable(prd->clk);
+		clear_bit(BIT_CLK_ENABLED, &prd->flags);
+	}
+
+	return 0;
+}
+
+static int platform_pm_runtime_resume(struct device *dev)
+{
+	struct pm_runtime_data *prd = __to_prd(dev);
+
+	dev_dbg(dev, "platform_pm_runtime_resume()\n");
+
+	platform_pm_runtime_init(dev, prd);
+
+	if (prd && test_bit(BIT_ACTIVE, &prd->flags)) {
+		clk_enable(prd->clk);
+		set_bit(BIT_CLK_ENABLED, &prd->flags);
+	}
+
+	return 0;
+}
+
+static int platform_pm_runtime_idle(struct device *dev)
+{
+	/* suspend synchronously to disable clocks immediately */
+	return pm_runtime_suspend(dev);
+}
+
+static struct dev_power_domain platform_pm_power_domain = {
+	.ops = {
+		.runtime_suspend = platform_pm_runtime_suspend,
+		.runtime_resume = platform_pm_runtime_resume,
+		.runtime_idle = platform_pm_runtime_idle,
+	},
+};
+
+static int platform_bus_notify(struct notifier_block *nb,
+			       unsigned long action, void *data)
+{
+	struct device *dev = data;
+	struct pm_runtime_data *prd;
+
+	dev_dbg(dev, "platform_bus_notify() %ld !\n", action);
+
+	if (action == BUS_NOTIFY_BIND_DRIVER) {
+		prd = devres_alloc(__devres_release, sizeof(*prd), GFP_KERNEL);
+		if (prd) {
+			devres_add(dev, prd);
+			dev->pwr_domain = &platform_pm_power_domain;
+		} else {
+			dev_err(dev, "unable to alloc memory for runtime pm\n");
+		}
+	}
+
+	return 0;
+}
+
+#else /* CONFIG_PM_RUNTIME */
+
+static int platform_bus_notify(struct notifier_block *nb,
+			       unsigned long action, void *data)
+{
+	struct device *dev = data;
+	struct clk *clk;
+
+	dev_dbg(dev, "platform_bus_notify() %ld !\n", action);
+
+	switch (action) {
+	case BUS_NOTIFY_BIND_DRIVER:
+		clk = clk_get(dev, NULL);
+		if (!IS_ERR(clk)) {
+			clk_enable(clk);
+			clk_put(clk);
+			dev_info(dev, "runtime pm disabled, clock forced on\n");
+		}
+		break;
+	case BUS_NOTIFY_UNBOUND_DRIVER:
+		clk = clk_get(dev, NULL);
+		if (!IS_ERR(clk)) {
+			clk_disable(clk);
+			clk_put(clk);
+			dev_info(dev, "runtime pm disabled, clock forced off\n");
+		}
+		break;
+	}
+
+	return 0;
+}
+
+#endif /* CONFIG_PM_RUNTIME */
+
+static struct notifier_block platform_bus_notifier = {
+	.notifier_call = platform_bus_notify
+};
+
+int __init pm_runtime_clock_init(void)
+{
+	bus_register_notifier(&platform_bus_type, &platform_bus_notifier);
+	return 0;
+}
diff --git a/arch/arm/include/asm/pm_runtime.h b/arch/arm/include/asm/pm_runtime.h
new file mode 100644
index 0000000..0c54b07
--- /dev/null
+++ b/arch/arm/include/asm/pm_runtime.h
@@ -0,0 +1,17 @@ 
+/*
+ * ARM common runtime PM definitions/prototypes
+ *
+ * Author: Kevin Hilman
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+#ifndef __ASM_PM_RUNTIME_H__
+#define __ASM_PM_RUNTIME_H__
+
+int __init pm_runtime_clock_init(void);
+
+#endif /* __ASM_PM_RUNTIME_H__ */
diff --git a/arch/arm/mach-shmobile/pm_runtime.c b/arch/arm/mach-shmobile/pm_runtime.c
deleted file mode 100644
index 6c75c3f..0000000
--- a/arch/arm/mach-shmobile/pm_runtime.c
+++ /dev/null
@@ -1,179 +0,0 @@ 
-/*
- * 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.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/pm_runtime.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/sh_clk.h>
-#include <linux/bitmap.h>
-
-#ifdef CONFIG_PM_RUNTIME
-#define BIT_ONCE 0
-#define BIT_ACTIVE 1
-#define BIT_CLK_ENABLED 2
-
-struct pm_runtime_data {
-	unsigned long flags;
-	struct clk *clk;
-};
-
-static void __devres_release(struct device *dev, void *res)
-{
-	struct pm_runtime_data *prd = res;
-
-	dev_dbg(dev, "__devres_release()\n");
-
-	if (test_bit(BIT_CLK_ENABLED, &prd->flags))
-		clk_disable(prd->clk);
-
-	if (test_bit(BIT_ACTIVE, &prd->flags))
-		clk_put(prd->clk);
-}
-
-static struct pm_runtime_data *__to_prd(struct device *dev)
-{
-	return devres_find(dev, __devres_release, NULL, NULL);
-}
-
-static void platform_pm_runtime_init(struct device *dev,
-				     struct pm_runtime_data *prd)
-{
-	if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) {
-		prd->clk = clk_get(dev, NULL);
-		if (!IS_ERR(prd->clk)) {
-			set_bit(BIT_ACTIVE, &prd->flags);
-			dev_info(dev, "clocks managed by runtime pm\n");
-		}
-	}
-}
-
-static void platform_pm_runtime_bug(struct device *dev,
-				    struct pm_runtime_data *prd)
-{
-	if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags))
-		dev_err(dev, "runtime pm suspend before resume\n");
-}
-
-static int platform_pm_runtime_suspend(struct device *dev)
-{
-	struct pm_runtime_data *prd = __to_prd(dev);
-
-	dev_dbg(dev, "platform_pm_runtime_suspend()\n");
-
-	platform_pm_runtime_bug(dev, prd);
-
-	if (prd && test_bit(BIT_ACTIVE, &prd->flags)) {
-		clk_disable(prd->clk);
-		clear_bit(BIT_CLK_ENABLED, &prd->flags);
-	}
-
-	return 0;
-}
-
-static int platform_pm_runtime_resume(struct device *dev)
-{
-	struct pm_runtime_data *prd = __to_prd(dev);
-
-	dev_dbg(dev, "platform_pm_runtime_resume()\n");
-
-	platform_pm_runtime_init(dev, prd);
-
-	if (prd && test_bit(BIT_ACTIVE, &prd->flags)) {
-		clk_enable(prd->clk);
-		set_bit(BIT_CLK_ENABLED, &prd->flags);
-	}
-
-	return 0;
-}
-
-static int platform_pm_runtime_idle(struct device *dev)
-{
-	/* suspend synchronously to disable clocks immediately */
-	return pm_runtime_suspend(dev);
-}
-
-static struct dev_power_domain platform_pm_power_domain = {
-	.ops = {
-		.runtime_suspend = platform_pm_runtime_suspend,
-		.runtime_resume = platform_pm_runtime_resume,
-		.runtime_idle = platform_pm_runtime_idle,
-	},
-};
-
-static int platform_bus_notify(struct notifier_block *nb,
-			       unsigned long action, void *data)
-{
-	struct device *dev = data;
-	struct pm_runtime_data *prd;
-
-	dev_dbg(dev, "platform_bus_notify() %ld !\n", action);
-
-	if (action == BUS_NOTIFY_BIND_DRIVER) {
-		prd = devres_alloc(__devres_release, sizeof(*prd), GFP_KERNEL);
-		if (prd) {
-			devres_add(dev, prd);
-			dev->pwr_domain = &platform_pm_power_domain;
-		} else {
-			dev_err(dev, "unable to alloc memory for runtime pm\n");
-		}
-	}
-
-	return 0;
-}
-
-#else /* CONFIG_PM_RUNTIME */
-
-static int platform_bus_notify(struct notifier_block *nb,
-			       unsigned long action, void *data)
-{
-	struct device *dev = data;
-	struct clk *clk;
-
-	dev_dbg(dev, "platform_bus_notify() %ld !\n", action);
-
-	switch (action) {
-	case BUS_NOTIFY_BIND_DRIVER:
-		clk = clk_get(dev, NULL);
-		if (!IS_ERR(clk)) {
-			clk_enable(clk);
-			clk_put(clk);
-			dev_info(dev, "runtime pm disabled, clock forced on\n");
-		}
-		break;
-	case BUS_NOTIFY_UNBOUND_DRIVER:
-		clk = clk_get(dev, NULL);
-		if (!IS_ERR(clk)) {
-			clk_disable(clk);
-			clk_put(clk);
-			dev_info(dev, "runtime pm disabled, clock forced off\n");
-		}
-		break;
-	}
-
-	return 0;
-}
-
-#endif /* CONFIG_PM_RUNTIME */
-
-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);