All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] OMAP: add runtime PM support at bus-level
@ 2010-06-23 23:37 ` Kevin Hilman
  0 siblings, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2010-06-23 23:37 UTC (permalink / raw)
  To: linux-omap; +Cc: linux-arm-kernel

This series introduces runtime PM support at the platform bus level
for OMAP.

In a nutshell, when using the runtime PM API for any device with an
assocated omap_device (and hwmod), the omap device API will be used to
handle the hardware-level power management of that device, including
managing clocks, etc.

Today, most drivers handle this by manually enabling/disabling their
clocks when needed.  With this series (and an omap_device/hwmod for
each device) direct clock managment can be removed from the driver in
favor of using the runtime PM API.

This series applies on top v2.6.35-rc2 + Tony's omap-fixes branch and
is also available in the pm-wip/runtime branch of my linux-omap-pm git
tree:

  git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm.git

Kevin Hilman (3):
  OMAP: PM: initial runtime PM core support
  OMAP: PM: use omap_device API for suspend/resume
  OMAP1: PM: add simple runtime PM layer to manage clocks

 arch/arm/mach-omap1/Makefile |    2 +-
 arch/arm/mach-omap1/pm_bus.c |   77 ++++++++++++++++++++++++
 arch/arm/mach-omap2/Makefile |    7 ++-
 arch/arm/mach-omap2/pm_bus.c |  133 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 217 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/mach-omap1/pm_bus.c
 create mode 100644 arch/arm/mach-omap2/pm_bus.c


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 0/3] OMAP: add runtime PM support at bus-level
@ 2010-06-23 23:37 ` Kevin Hilman
  0 siblings, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2010-06-23 23:37 UTC (permalink / raw)
  To: linux-arm-kernel

This series introduces runtime PM support at the platform bus level
for OMAP.

In a nutshell, when using the runtime PM API for any device with an
assocated omap_device (and hwmod), the omap device API will be used to
handle the hardware-level power management of that device, including
managing clocks, etc.

Today, most drivers handle this by manually enabling/disabling their
clocks when needed.  With this series (and an omap_device/hwmod for
each device) direct clock managment can be removed from the driver in
favor of using the runtime PM API.

This series applies on top v2.6.35-rc2 + Tony's omap-fixes branch and
is also available in the pm-wip/runtime branch of my linux-omap-pm git
tree:

  git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm.git

Kevin Hilman (3):
  OMAP: PM: initial runtime PM core support
  OMAP: PM: use omap_device API for suspend/resume
  OMAP1: PM: add simple runtime PM layer to manage clocks

 arch/arm/mach-omap1/Makefile |    2 +-
 arch/arm/mach-omap1/pm_bus.c |   77 ++++++++++++++++++++++++
 arch/arm/mach-omap2/Makefile |    7 ++-
 arch/arm/mach-omap2/pm_bus.c |  133 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 217 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/mach-omap1/pm_bus.c
 create mode 100644 arch/arm/mach-omap2/pm_bus.c

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/3] OMAP: PM: initial runtime PM core support
  2010-06-23 23:37 ` Kevin Hilman
@ 2010-06-23 23:37   ` Kevin Hilman
  -1 siblings, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2010-06-23 23:37 UTC (permalink / raw)
  To: linux-omap; +Cc: linux-arm-kernel

Implement the new runtime PM framework as a thin layer on top of the
omap_device API.  Since we don't have an OMAP-specific bus, override
the runtime PM hooks for the platform_bus for the OMAP specific
implementation.

While the runtime PM API has three main states (idle, suspend, resume)
This version treats idle and suspend the same way by implementing both
on top of omap_device_disable(), which follows closely with how driver
are currently using clock enable/disable calls. Longer-termm
pm_runtime_idle() could take other constraints into consideration to
make the decision, but the current

Device driver ->runtime_suspend() hooks are called just before the
device is disabled (via omap_device_idle()), and device driver
->runtime_resume() hooks are called just after device has been
enabled (via omap_device_enable().)

Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/Makefile |    7 +++-
 arch/arm/mach-omap2/pm_bus.c |   72 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap2/pm_bus.c

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index ea52b03..8ed47ea 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -46,12 +46,17 @@ obj-$(CONFIG_ARCH_OMAP2)		+= sdrc2xxx.o
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
 obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
-obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o cpuidle34xx.o
+obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o cpuidle34xx.o \
+					   pm_bus.o
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
 
 AFLAGS_sleep24xx.o			:=-Wa,-march=armv6
 AFLAGS_sleep34xx.o			:=-Wa,-march=armv7-a
 
+ifeq ($(CONFIG_PM_VERBOSE),y)
+CFLAGS_pm_bus.o				+= -DDEBUG
+endif
+
 endif
 
 # PRCM
diff --git a/arch/arm/mach-omap2/pm_bus.c b/arch/arm/mach-omap2/pm_bus.c
new file mode 100644
index 0000000..69acaa5
--- /dev/null
+++ b/arch/arm/mach-omap2/pm_bus.c
@@ -0,0 +1,72 @@
+/*
+ * Runtime PM support code for OMAP
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+
+#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
+
+#ifdef CONFIG_PM_RUNTIME
+int platform_pm_runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *odev = to_omap_device(pdev);
+	int r, ret = 0;
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	if (dev->driver->pm && dev->driver->pm->runtime_suspend)
+		ret = dev->driver->pm->runtime_suspend(dev);
+	if (!ret && omap_device_is_valid(odev)) {
+		r = omap_device_idle(pdev);
+		WARN_ON(r);
+	}
+
+	return ret;
+};
+
+int platform_pm_runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *odev = to_omap_device(pdev);
+	int r, ret = 0;
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	if (omap_device_is_valid(odev)) {
+		r = omap_device_enable(pdev);
+		WARN_ON(r);
+	}
+
+	if (dev->driver->pm && dev->driver->pm->runtime_resume)
+		ret = dev->driver->pm->runtime_resume(dev);
+
+	return ret;
+};
+
+int platform_pm_runtime_idle(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *odev = to_omap_device(pdev);
+	int ret;
+
+	ret = pm_runtime_suspend(dev);
+	dev_dbg(dev, "%s [%d]\n", __func__, ret);
+
+	return 0;
+};
+#endif /* CONFIG_PM_RUNTIME */
+
-- 
1.7.0.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 1/3] OMAP: PM: initial runtime PM core support
@ 2010-06-23 23:37   ` Kevin Hilman
  0 siblings, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2010-06-23 23:37 UTC (permalink / raw)
  To: linux-arm-kernel

Implement the new runtime PM framework as a thin layer on top of the
omap_device API.  Since we don't have an OMAP-specific bus, override
the runtime PM hooks for the platform_bus for the OMAP specific
implementation.

While the runtime PM API has three main states (idle, suspend, resume)
This version treats idle and suspend the same way by implementing both
on top of omap_device_disable(), which follows closely with how driver
are currently using clock enable/disable calls. Longer-termm
pm_runtime_idle() could take other constraints into consideration to
make the decision, but the current

Device driver ->runtime_suspend() hooks are called just before the
device is disabled (via omap_device_idle()), and device driver
->runtime_resume() hooks are called just after device has been
enabled (via omap_device_enable().)

Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/Makefile |    7 +++-
 arch/arm/mach-omap2/pm_bus.c |   72 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap2/pm_bus.c

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index ea52b03..8ed47ea 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -46,12 +46,17 @@ obj-$(CONFIG_ARCH_OMAP2)		+= sdrc2xxx.o
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
 obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
-obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o cpuidle34xx.o
+obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o cpuidle34xx.o \
+					   pm_bus.o
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
 
 AFLAGS_sleep24xx.o			:=-Wa,-march=armv6
 AFLAGS_sleep34xx.o			:=-Wa,-march=armv7-a
 
+ifeq ($(CONFIG_PM_VERBOSE),y)
+CFLAGS_pm_bus.o				+= -DDEBUG
+endif
+
 endif
 
 # PRCM
diff --git a/arch/arm/mach-omap2/pm_bus.c b/arch/arm/mach-omap2/pm_bus.c
new file mode 100644
index 0000000..69acaa5
--- /dev/null
+++ b/arch/arm/mach-omap2/pm_bus.c
@@ -0,0 +1,72 @@
+/*
+ * Runtime PM support code for OMAP
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+
+#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
+
+#ifdef CONFIG_PM_RUNTIME
+int platform_pm_runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *odev = to_omap_device(pdev);
+	int r, ret = 0;
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	if (dev->driver->pm && dev->driver->pm->runtime_suspend)
+		ret = dev->driver->pm->runtime_suspend(dev);
+	if (!ret && omap_device_is_valid(odev)) {
+		r = omap_device_idle(pdev);
+		WARN_ON(r);
+	}
+
+	return ret;
+};
+
+int platform_pm_runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *odev = to_omap_device(pdev);
+	int r, ret = 0;
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	if (omap_device_is_valid(odev)) {
+		r = omap_device_enable(pdev);
+		WARN_ON(r);
+	}
+
+	if (dev->driver->pm && dev->driver->pm->runtime_resume)
+		ret = dev->driver->pm->runtime_resume(dev);
+
+	return ret;
+};
+
+int platform_pm_runtime_idle(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *odev = to_omap_device(pdev);
+	int ret;
+
+	ret = pm_runtime_suspend(dev);
+	dev_dbg(dev, "%s [%d]\n", __func__, ret);
+
+	return 0;
+};
+#endif /* CONFIG_PM_RUNTIME */
+
-- 
1.7.0.2

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/3] OMAP: PM: use omap_device API for suspend/resume
  2010-06-23 23:37 ` Kevin Hilman
@ 2010-06-23 23:37   ` Kevin Hilman
  -1 siblings, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2010-06-23 23:37 UTC (permalink / raw)
  To: linux-omap; +Cc: linux-arm-kernel

Hook into the platform bus methods for suspend and resume and
use the omap_device API to automatically idle and enable the
device on suspend and resume.

This allows device drivers to get rid of direct management of their
clocks in their suspend/resume paths, and let omap_device do it for
them.

We currently use the _noirq (late suspend, early resume) versions of
the suspend/resume methods to ensure that the device is not disabled
too early for any drivers also using the _noirq methods.

NOTE: only works for devices with omap_hwmod support.

Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm_bus.c |   61 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm_bus.c b/arch/arm/mach-omap2/pm_bus.c
index 69acaa5..3787da8 100644
--- a/arch/arm/mach-omap2/pm_bus.c
+++ b/arch/arm/mach-omap2/pm_bus.c
@@ -70,3 +70,64 @@ int platform_pm_runtime_idle(struct device *dev)
 };
 #endif /* CONFIG_PM_RUNTIME */
 
+#ifdef CONFIG_SUSPEND
+int platform_pm_suspend_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *odev = to_omap_device(pdev);
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->suspend_noirq)
+			ret = drv->pm->suspend_noirq(dev);
+	}
+
+	if (omap_device_is_valid(odev)) {
+		if (odev->flags & OMAP_DEVICE_NO_BUS_SUSPEND) {
+			dev_dbg(dev, "no automatic bus-level system resume.\n");
+			return 0;
+		}
+
+		dev_dbg(dev, "%s\n", __func__);
+		omap_device_idle(pdev);
+	} else {
+		dev_dbg(dev, "not an omap_device\n");
+	}
+
+	return ret;
+}
+
+int platform_pm_resume_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *odev = to_omap_device(pdev);
+	int ret = 0;
+
+	if (omap_device_is_valid(odev)) {
+		if (odev->flags & OMAP_DEVICE_NO_BUS_SUSPEND) {
+			dev_dbg(dev, "no automatic bus-level system resume.\n");
+			return 0;
+		}
+
+		dev_dbg(dev, "%s\n", __func__);
+		omap_device_enable(pdev);
+	} else {
+		dev_dbg(dev, "not an omap_device\n");
+	}
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->resume_noirq)
+			ret = drv->pm->resume_noirq(dev);
+	}
+
+	return ret;
+}
+#endif /* CONFIG_SUSPEND */
-- 
1.7.0.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/3] OMAP: PM: use omap_device API for suspend/resume
@ 2010-06-23 23:37   ` Kevin Hilman
  0 siblings, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2010-06-23 23:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hook into the platform bus methods for suspend and resume and
use the omap_device API to automatically idle and enable the
device on suspend and resume.

This allows device drivers to get rid of direct management of their
clocks in their suspend/resume paths, and let omap_device do it for
them.

We currently use the _noirq (late suspend, early resume) versions of
the suspend/resume methods to ensure that the device is not disabled
too early for any drivers also using the _noirq methods.

NOTE: only works for devices with omap_hwmod support.

Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/pm_bus.c |   61 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/pm_bus.c b/arch/arm/mach-omap2/pm_bus.c
index 69acaa5..3787da8 100644
--- a/arch/arm/mach-omap2/pm_bus.c
+++ b/arch/arm/mach-omap2/pm_bus.c
@@ -70,3 +70,64 @@ int platform_pm_runtime_idle(struct device *dev)
 };
 #endif /* CONFIG_PM_RUNTIME */
 
+#ifdef CONFIG_SUSPEND
+int platform_pm_suspend_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *odev = to_omap_device(pdev);
+	int ret = 0;
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->suspend_noirq)
+			ret = drv->pm->suspend_noirq(dev);
+	}
+
+	if (omap_device_is_valid(odev)) {
+		if (odev->flags & OMAP_DEVICE_NO_BUS_SUSPEND) {
+			dev_dbg(dev, "no automatic bus-level system resume.\n");
+			return 0;
+		}
+
+		dev_dbg(dev, "%s\n", __func__);
+		omap_device_idle(pdev);
+	} else {
+		dev_dbg(dev, "not an omap_device\n");
+	}
+
+	return ret;
+}
+
+int platform_pm_resume_noirq(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct omap_device *odev = to_omap_device(pdev);
+	int ret = 0;
+
+	if (omap_device_is_valid(odev)) {
+		if (odev->flags & OMAP_DEVICE_NO_BUS_SUSPEND) {
+			dev_dbg(dev, "no automatic bus-level system resume.\n");
+			return 0;
+		}
+
+		dev_dbg(dev, "%s\n", __func__);
+		omap_device_enable(pdev);
+	} else {
+		dev_dbg(dev, "not an omap_device\n");
+	}
+
+	if (!drv)
+		return 0;
+
+	if (drv->pm) {
+		if (drv->pm->resume_noirq)
+			ret = drv->pm->resume_noirq(dev);
+	}
+
+	return ret;
+}
+#endif /* CONFIG_SUSPEND */
-- 
1.7.0.2

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/3] OMAP1: PM: add simple runtime PM layer to manage clocks
  2010-06-23 23:37 ` Kevin Hilman
@ 2010-06-23 23:37   ` Kevin Hilman
  -1 siblings, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2010-06-23 23:37 UTC (permalink / raw)
  To: linux-omap; +Cc: linux-arm-kernel

On OMAP1, we do not have omap_device + omap_hwmod to manage the
device-specific idle, enable and shutdown.  Instead, just
enable/disable device clocks automatically at the runtime PM level.

This allows drivers to not have any OMAP1 specific clock management
and allows them to simply use the runtime PM API to manage clocks.

Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap1/Makefile |    2 +-
 arch/arm/mach-omap1/pm_bus.c |   77 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap1/pm_bus.c

diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index ea231c7..fd4df71 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_OMAP_MPU_TIMER)	+= time.o
 obj-$(CONFIG_OMAP_32K_TIMER)	+= timer32k.o
 
 # Power Management
-obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_PM) += pm.o sleep.o pm_bus.o
 
 # DSP
 obj-$(CONFIG_OMAP_MBOX_FWK)	+= mailbox_mach.o
diff --git a/arch/arm/mach-omap1/pm_bus.c b/arch/arm/mach-omap1/pm_bus.c
new file mode 100644
index 0000000..29d651a
--- /dev/null
+++ b/arch/arm/mach-omap1/pm_bus.c
@@ -0,0 +1,77 @@
+/*
+ * Runtime PM support code for OMAP1
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+
+#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
+
+#ifdef CONFIG_PM_RUNTIME
+int platform_pm_runtime_suspend(struct device *dev)
+{
+	struct clk *iclk, *fclk;
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	if (dev->driver->pm && dev->driver->pm->runtime_suspend)
+		ret = dev->driver->pm->runtime_suspend(dev);
+
+	fclk = clk_get(dev, "fck");
+	if (!IS_ERR(fclk)) {
+		clk_disable(fclk);
+		clk_put(fclk);
+	}
+
+	iclk = clk_get(dev, "ick");
+	if (!IS_ERR(iclk)) {
+		clk_disable(iclk);
+		clk_put(iclk);
+	}
+
+	return 0;
+};
+
+int platform_pm_runtime_resume(struct device *dev)
+{
+	int r, ret = 0;
+	struct clk *iclk, *fclk;
+
+	iclk = clk_get(dev, "ick");
+	if (!IS_ERR(iclk)) {
+		clk_enable(iclk);
+		clk_put(iclk);
+	}
+
+	fclk = clk_get(dev, "fck");
+	if (!IS_ERR(fclk)) {
+		clk_enable(fclk);
+		clk_put(fclk);
+	}
+
+	if (dev->driver->pm && dev->driver->pm->runtime_resume)
+		ret = dev->driver->pm->runtime_resume(dev);
+
+	return ret;
+};
+
+int platform_pm_runtime_idle(struct device *dev)
+{
+	ret = pm_runtime_suspend(dev);
+	dev_dbg(dev, "%s [%d]\n", __func__, ret);
+
+	return 0;
+};
+#endif /* CONFIG_PM_RUNTIME */
-- 
1.7.0.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/3] OMAP1: PM: add simple runtime PM layer to manage clocks
@ 2010-06-23 23:37   ` Kevin Hilman
  0 siblings, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2010-06-23 23:37 UTC (permalink / raw)
  To: linux-arm-kernel

On OMAP1, we do not have omap_device + omap_hwmod to manage the
device-specific idle, enable and shutdown.  Instead, just
enable/disable device clocks automatically at the runtime PM level.

This allows drivers to not have any OMAP1 specific clock management
and allows them to simply use the runtime PM API to manage clocks.

Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap1/Makefile |    2 +-
 arch/arm/mach-omap1/pm_bus.c |   77 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap1/pm_bus.c

diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index ea231c7..fd4df71 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_OMAP_MPU_TIMER)	+= time.o
 obj-$(CONFIG_OMAP_32K_TIMER)	+= timer32k.o
 
 # Power Management
-obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_PM) += pm.o sleep.o pm_bus.o
 
 # DSP
 obj-$(CONFIG_OMAP_MBOX_FWK)	+= mailbox_mach.o
diff --git a/arch/arm/mach-omap1/pm_bus.c b/arch/arm/mach-omap1/pm_bus.c
new file mode 100644
index 0000000..29d651a
--- /dev/null
+++ b/arch/arm/mach-omap1/pm_bus.c
@@ -0,0 +1,77 @@
+/*
+ * Runtime PM support code for OMAP1
+ *
+ * Author: Kevin Hilman, Deep Root Systems, LLC
+ *
+ * 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.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+
+#include <plat/omap_device.h>
+#include <plat/omap-pm.h>
+
+#ifdef CONFIG_PM_RUNTIME
+int platform_pm_runtime_suspend(struct device *dev)
+{
+	struct clk *iclk, *fclk;
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	if (dev->driver->pm && dev->driver->pm->runtime_suspend)
+		ret = dev->driver->pm->runtime_suspend(dev);
+
+	fclk = clk_get(dev, "fck");
+	if (!IS_ERR(fclk)) {
+		clk_disable(fclk);
+		clk_put(fclk);
+	}
+
+	iclk = clk_get(dev, "ick");
+	if (!IS_ERR(iclk)) {
+		clk_disable(iclk);
+		clk_put(iclk);
+	}
+
+	return 0;
+};
+
+int platform_pm_runtime_resume(struct device *dev)
+{
+	int r, ret = 0;
+	struct clk *iclk, *fclk;
+
+	iclk = clk_get(dev, "ick");
+	if (!IS_ERR(iclk)) {
+		clk_enable(iclk);
+		clk_put(iclk);
+	}
+
+	fclk = clk_get(dev, "fck");
+	if (!IS_ERR(fclk)) {
+		clk_enable(fclk);
+		clk_put(fclk);
+	}
+
+	if (dev->driver->pm && dev->driver->pm->runtime_resume)
+		ret = dev->driver->pm->runtime_resume(dev);
+
+	return ret;
+};
+
+int platform_pm_runtime_idle(struct device *dev)
+{
+	ret = pm_runtime_suspend(dev);
+	dev_dbg(dev, "%s [%d]\n", __func__, ret);
+
+	return 0;
+};
+#endif /* CONFIG_PM_RUNTIME */
-- 
1.7.0.2

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/3] OMAP: PM: use omap_device API for suspend/resume
  2010-06-23 23:37   ` Kevin Hilman
@ 2010-06-24  6:30     ` Paul Walmsley
  -1 siblings, 0 replies; 12+ messages in thread
From: Paul Walmsley @ 2010-06-24  6:30 UTC (permalink / raw)
  To: Kevin Hilman; +Cc: linux-omap, linux-arm-kernel

Hi Kevin,

aside from these comments:

   http://marc.info/?l=linux-omap&m=127735008820992&w=2

one other minor issue -

On Wed, 23 Jun 2010, Kevin Hilman wrote:

> Hook into the platform bus methods for suspend and resume and
> use the omap_device API to automatically idle and enable the
> device on suspend and resume.
> 
> This allows device drivers to get rid of direct management of their
> clocks in their suspend/resume paths, and let omap_device do it for
> them.
> 
> We currently use the _noirq (late suspend, early resume) versions of
> the suspend/resume methods to ensure that the device is not disabled
> too early for any drivers also using the _noirq methods.
> 
> NOTE: only works for devices with omap_hwmod support.
> 
> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
> ---
>  arch/arm/mach-omap2/pm_bus.c |   61 ++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 61 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/pm_bus.c b/arch/arm/mach-omap2/pm_bus.c
> index 69acaa5..3787da8 100644
> --- a/arch/arm/mach-omap2/pm_bus.c
> +++ b/arch/arm/mach-omap2/pm_bus.c
> @@ -70,3 +70,64 @@ int platform_pm_runtime_idle(struct device *dev)
>  };
>  #endif /* CONFIG_PM_RUNTIME */
>  
> +#ifdef CONFIG_SUSPEND
> +int platform_pm_suspend_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct omap_device *odev = to_omap_device(pdev);
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->suspend_noirq)
> +			ret = drv->pm->suspend_noirq(dev);
> +	}
> +
> +	if (omap_device_is_valid(odev)) {
> +		if (odev->flags & OMAP_DEVICE_NO_BUS_SUSPEND) {
> +			dev_dbg(dev, "no automatic bus-level system resume.\n");

I guess this should read "suspend" above?

> +			return 0;
> +		}
> +
> +		dev_dbg(dev, "%s\n", __func__);
> +		omap_device_idle(pdev);
> +	} else {
> +		dev_dbg(dev, "not an omap_device\n");
> +	}
> +
> +	return ret;
> +}
> +
> +int platform_pm_resume_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct omap_device *odev = to_omap_device(pdev);
> +	int ret = 0;
> +
> +	if (omap_device_is_valid(odev)) {
> +		if (odev->flags & OMAP_DEVICE_NO_BUS_SUSPEND) {
> +			dev_dbg(dev, "no automatic bus-level system resume.\n");
> +			return 0;
> +		}
> +
> +		dev_dbg(dev, "%s\n", __func__);
> +		omap_device_enable(pdev);
> +	} else {
> +		dev_dbg(dev, "not an omap_device\n");
> +	}
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->resume_noirq)
> +			ret = drv->pm->resume_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +#endif /* CONFIG_SUSPEND */
> -- 
> 1.7.0.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


- Paul

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/3] OMAP: PM: use omap_device API for suspend/resume
@ 2010-06-24  6:30     ` Paul Walmsley
  0 siblings, 0 replies; 12+ messages in thread
From: Paul Walmsley @ 2010-06-24  6:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Kevin,

aside from these comments:

   http://marc.info/?l=linux-omap&m=127735008820992&w=2

one other minor issue -

On Wed, 23 Jun 2010, Kevin Hilman wrote:

> Hook into the platform bus methods for suspend and resume and
> use the omap_device API to automatically idle and enable the
> device on suspend and resume.
> 
> This allows device drivers to get rid of direct management of their
> clocks in their suspend/resume paths, and let omap_device do it for
> them.
> 
> We currently use the _noirq (late suspend, early resume) versions of
> the suspend/resume methods to ensure that the device is not disabled
> too early for any drivers also using the _noirq methods.
> 
> NOTE: only works for devices with omap_hwmod support.
> 
> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
> ---
>  arch/arm/mach-omap2/pm_bus.c |   61 ++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 61 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/pm_bus.c b/arch/arm/mach-omap2/pm_bus.c
> index 69acaa5..3787da8 100644
> --- a/arch/arm/mach-omap2/pm_bus.c
> +++ b/arch/arm/mach-omap2/pm_bus.c
> @@ -70,3 +70,64 @@ int platform_pm_runtime_idle(struct device *dev)
>  };
>  #endif /* CONFIG_PM_RUNTIME */
>  
> +#ifdef CONFIG_SUSPEND
> +int platform_pm_suspend_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct omap_device *odev = to_omap_device(pdev);
> +	int ret = 0;
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->suspend_noirq)
> +			ret = drv->pm->suspend_noirq(dev);
> +	}
> +
> +	if (omap_device_is_valid(odev)) {
> +		if (odev->flags & OMAP_DEVICE_NO_BUS_SUSPEND) {
> +			dev_dbg(dev, "no automatic bus-level system resume.\n");

I guess this should read "suspend" above?

> +			return 0;
> +		}
> +
> +		dev_dbg(dev, "%s\n", __func__);
> +		omap_device_idle(pdev);
> +	} else {
> +		dev_dbg(dev, "not an omap_device\n");
> +	}
> +
> +	return ret;
> +}
> +
> +int platform_pm_resume_noirq(struct device *dev)
> +{
> +	struct device_driver *drv = dev->driver;
> +	struct platform_device *pdev = to_platform_device(dev);
> +	struct omap_device *odev = to_omap_device(pdev);
> +	int ret = 0;
> +
> +	if (omap_device_is_valid(odev)) {
> +		if (odev->flags & OMAP_DEVICE_NO_BUS_SUSPEND) {
> +			dev_dbg(dev, "no automatic bus-level system resume.\n");
> +			return 0;
> +		}
> +
> +		dev_dbg(dev, "%s\n", __func__);
> +		omap_device_enable(pdev);
> +	} else {
> +		dev_dbg(dev, "not an omap_device\n");
> +	}
> +
> +	if (!drv)
> +		return 0;
> +
> +	if (drv->pm) {
> +		if (drv->pm->resume_noirq)
> +			ret = drv->pm->resume_noirq(dev);
> +	}
> +
> +	return ret;
> +}
> +#endif /* CONFIG_SUSPEND */
> -- 
> 1.7.0.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


- Paul

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/3] OMAP: PM: use omap_device API for suspend/resume
  2010-06-24  6:30     ` Paul Walmsley
@ 2010-06-24 17:34       ` Kevin Hilman
  -1 siblings, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2010-06-24 17:34 UTC (permalink / raw)
  To: Paul Walmsley; +Cc: linux-omap, linux-arm-kernel

Paul Walmsley <paul@pwsan.com> writes:

> Hi Kevin,
>
> aside from these comments:
>
>    http://marc.info/?l=linux-omap&m=127735008820992&w=2
>
> one other minor issue -
>
> On Wed, 23 Jun 2010, Kevin Hilman wrote:
>
>> Hook into the platform bus methods for suspend and resume and
>> use the omap_device API to automatically idle and enable the
>> device on suspend and resume.
>> 
>> This allows device drivers to get rid of direct management of their
>> clocks in their suspend/resume paths, and let omap_device do it for
>> them.
>> 
>> We currently use the _noirq (late suspend, early resume) versions of
>> the suspend/resume methods to ensure that the device is not disabled
>> too early for any drivers also using the _noirq methods.
>> 
>> NOTE: only works for devices with omap_hwmod support.
>> 
>> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
>> ---
>>  arch/arm/mach-omap2/pm_bus.c |   61 ++++++++++++++++++++++++++++++++++++++++++
>>  1 files changed, 61 insertions(+), 0 deletions(-)
>> 
>> diff --git a/arch/arm/mach-omap2/pm_bus.c b/arch/arm/mach-omap2/pm_bus.c
>> index 69acaa5..3787da8 100644
>> --- a/arch/arm/mach-omap2/pm_bus.c
>> +++ b/arch/arm/mach-omap2/pm_bus.c
>> @@ -70,3 +70,64 @@ int platform_pm_runtime_idle(struct device *dev)
>>  };
>>  #endif /* CONFIG_PM_RUNTIME */
>>  
>> +#ifdef CONFIG_SUSPEND
>> +int platform_pm_suspend_noirq(struct device *dev)
>> +{
>> +	struct device_driver *drv = dev->driver;
>> +	struct platform_device *pdev = to_platform_device(dev);
>> +	struct omap_device *odev = to_omap_device(pdev);
>> +	int ret = 0;
>> +
>> +	if (!drv)
>> +		return 0;
>> +
>> +	if (drv->pm) {
>> +		if (drv->pm->suspend_noirq)
>> +			ret = drv->pm->suspend_noirq(dev);
>> +	}
>> +
>> +	if (omap_device_is_valid(odev)) {
>> +		if (odev->flags & OMAP_DEVICE_NO_BUS_SUSPEND) {
>> +			dev_dbg(dev, "no automatic bus-level system resume.\n");
>
> I guess this should read "suspend" above?
>

Yup, thanks.

Kevin

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 2/3] OMAP: PM: use omap_device API for suspend/resume
@ 2010-06-24 17:34       ` Kevin Hilman
  0 siblings, 0 replies; 12+ messages in thread
From: Kevin Hilman @ 2010-06-24 17:34 UTC (permalink / raw)
  To: linux-arm-kernel

Paul Walmsley <paul@pwsan.com> writes:

> Hi Kevin,
>
> aside from these comments:
>
>    http://marc.info/?l=linux-omap&m=127735008820992&w=2
>
> one other minor issue -
>
> On Wed, 23 Jun 2010, Kevin Hilman wrote:
>
>> Hook into the platform bus methods for suspend and resume and
>> use the omap_device API to automatically idle and enable the
>> device on suspend and resume.
>> 
>> This allows device drivers to get rid of direct management of their
>> clocks in their suspend/resume paths, and let omap_device do it for
>> them.
>> 
>> We currently use the _noirq (late suspend, early resume) versions of
>> the suspend/resume methods to ensure that the device is not disabled
>> too early for any drivers also using the _noirq methods.
>> 
>> NOTE: only works for devices with omap_hwmod support.
>> 
>> Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
>> ---
>>  arch/arm/mach-omap2/pm_bus.c |   61 ++++++++++++++++++++++++++++++++++++++++++
>>  1 files changed, 61 insertions(+), 0 deletions(-)
>> 
>> diff --git a/arch/arm/mach-omap2/pm_bus.c b/arch/arm/mach-omap2/pm_bus.c
>> index 69acaa5..3787da8 100644
>> --- a/arch/arm/mach-omap2/pm_bus.c
>> +++ b/arch/arm/mach-omap2/pm_bus.c
>> @@ -70,3 +70,64 @@ int platform_pm_runtime_idle(struct device *dev)
>>  };
>>  #endif /* CONFIG_PM_RUNTIME */
>>  
>> +#ifdef CONFIG_SUSPEND
>> +int platform_pm_suspend_noirq(struct device *dev)
>> +{
>> +	struct device_driver *drv = dev->driver;
>> +	struct platform_device *pdev = to_platform_device(dev);
>> +	struct omap_device *odev = to_omap_device(pdev);
>> +	int ret = 0;
>> +
>> +	if (!drv)
>> +		return 0;
>> +
>> +	if (drv->pm) {
>> +		if (drv->pm->suspend_noirq)
>> +			ret = drv->pm->suspend_noirq(dev);
>> +	}
>> +
>> +	if (omap_device_is_valid(odev)) {
>> +		if (odev->flags & OMAP_DEVICE_NO_BUS_SUSPEND) {
>> +			dev_dbg(dev, "no automatic bus-level system resume.\n");
>
> I guess this should read "suspend" above?
>

Yup, thanks.

Kevin

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2010-06-24 17:34 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-23 23:37 [PATCH 0/3] OMAP: add runtime PM support at bus-level Kevin Hilman
2010-06-23 23:37 ` Kevin Hilman
2010-06-23 23:37 ` [PATCH 1/3] OMAP: PM: initial runtime PM core support Kevin Hilman
2010-06-23 23:37   ` Kevin Hilman
2010-06-23 23:37 ` [PATCH 2/3] OMAP: PM: use omap_device API for suspend/resume Kevin Hilman
2010-06-23 23:37   ` Kevin Hilman
2010-06-24  6:30   ` Paul Walmsley
2010-06-24  6:30     ` Paul Walmsley
2010-06-24 17:34     ` Kevin Hilman
2010-06-24 17:34       ` Kevin Hilman
2010-06-23 23:37 ` [PATCH 3/3] OMAP1: PM: add simple runtime PM layer to manage clocks Kevin Hilman
2010-06-23 23:37   ` Kevin Hilman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.