summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-11-11 15:41:50 +0900
committerPaul Mundt <lethal@linux-sh.org>2011-11-11 15:41:50 +0900
commit750a7eee7395492960a7aeb3a3a1aa74158ec326 (patch)
treed45a73dd3acc59493d8d0fdd8f9e912ad4bb4422 /drivers
parent5e442a493fc59fa536c76db1fff5b49ca36a88c5 (diff)
downloadlinux-750a7eee7395492960a7aeb3a3a1aa74158ec326.tar.bz2
drivers: sh: Generalize runtime PM platform stub.
The runtime PM platform support stub in use by ARM-based SH/R-Mobile platforms contains nothing that's specifically ARM-related and instead of wholly generic to anything using the clock framework. The recent runtime PM changes interact rather badly with the lazy disabling of clocks late in the boot process through the clock framework, leading to situations where the runtime suspend/resume paths are entered without a clock being actively driven due to having been lazily gated off. In order to correct this we can trivially tie in the aforementioned stub as a general fallback for all SH platforms that don't presently have their own runtime PM implementations (the corner case being SH-based SH-Mobile platforms, which have their own stub through the hwblk API -- which in turn has bitrotted and will be subsequently adapted to use the same stub as everyone else), regardless of whether the platforms choose to define power domains of their own or not. This fixes up regressions for clock framework users who also build in runtime PM support without any specific power domains of their own, which was previously causing the serial console to be lost when warring with lazy clock disabling. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/sh/Makefile8
-rw-r--r--drivers/sh/pm_runtime.c67
2 files changed, 75 insertions, 0 deletions
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile
index 24e6cec0ae8d..67e272ab1623 100644
--- a/drivers/sh/Makefile
+++ b/drivers/sh/Makefile
@@ -7,3 +7,11 @@ obj-$(CONFIG_HAVE_CLK) += clk/
obj-$(CONFIG_MAPLE) += maple/
obj-$(CONFIG_SUPERHYWAY) += superhyway/
obj-$(CONFIG_GENERIC_GPIO) += pfc.o
+
+#
+# For the moment we only use this framework for ARM-based SH/R-Mobile
+# platforms and generic SH. SH-based SH-Mobile platforms are still using
+# an older framework that is pending up-porting, at which point this
+# special casing can go away.
+#
+obj-$(CONFIG_SUPERH)$(CONFIG_ARCH_SHMOBILE) += pm_runtime.o
diff --git a/drivers/sh/pm_runtime.c b/drivers/sh/pm_runtime.c
new file mode 100644
index 000000000000..bd5c6a3b8c55
--- /dev/null
+++ b/drivers/sh/pm_runtime.c
@@ -0,0 +1,67 @@
+/*
+ * 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/pm_domain.h>
+#include <linux/pm_clock.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/sh_clk.h>
+#include <linux/bitmap.h>
+#include <linux/slab.h>
+
+#ifdef CONFIG_PM_RUNTIME
+
+static int default_platform_runtime_idle(struct device *dev)
+{
+ /* suspend synchronously to disable clocks immediately */
+ return pm_runtime_suspend(dev);
+}
+
+static struct dev_pm_domain default_pm_domain = {
+ .ops = {
+ .runtime_suspend = pm_clk_suspend,
+ .runtime_resume = pm_clk_resume,
+ .runtime_idle = default_platform_runtime_idle,
+ USE_PLATFORM_PM_SLEEP_OPS
+ },
+};
+
+#define DEFAULT_PM_DOMAIN_PTR (&default_pm_domain)
+
+#else
+
+#define DEFAULT_PM_DOMAIN_PTR NULL
+
+#endif /* CONFIG_PM_RUNTIME */
+
+static struct pm_clk_notifier_block platform_bus_notifier = {
+ .pm_domain = DEFAULT_PM_DOMAIN_PTR,
+ .con_ids = { NULL, },
+};
+
+static int __init sh_pm_runtime_init(void)
+{
+ pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
+ return 0;
+}
+core_initcall(sh_pm_runtime_init);
+
+static int __init sh_pm_runtime_late_init(void)
+{
+ pm_genpd_poweroff_unused();
+ return 0;
+}
+late_initcall(sh_pm_runtime_late_init);