diff options
| author | Kevin Hilman <khilman@ti.com> | 2011-07-12 16:48:19 -0400 |
|---|---|---|
| committer | Rafael J. Wysocki <rjw@sisk.pl> | 2011-07-12 16:48:19 -0400 |
| commit | c03f007a8bf0e092caeb6856a5c8a850df10b974 (patch) | |
| tree | 9c75aca05734dcdf04f7203851c78254703dee5e | |
| parent | 256a5435975e344b975f89c5434aa6f6eeb03fa1 (diff) | |
OMAP: PM: omap_device: add system PM methods for PM domain handling
In the omap_device PM domain callbacks, use omap_device idle/enable to
automatically manage device idle states during system suspend/resume.
If an omap_device has not already been runtime suspended, the
->suspend_noirq() method of the PM domain will use omap_device_idle()
to idle the HW after calling the driver's ->runtime_suspend()
callback. Similarily, upon resume, if the device was suspended during
->suspend_noirq(), the ->resume_noirq() method of the PM domain will
use omap_device_enable() to enable the HW and then call the driver's
->runtime_resume() callback.
If a device has already been runtime suspended, the noirq methods of
the PM domain leave the device runtime suspended by default.
However, if a driver needs to runtime resume a device during suspend
(for example, to change its wakeup settings), it may do so using
pm_runtime_get* in it's ->suspend() callback.
Signed-off-by: Kevin Hilman <khilman@ti.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
| -rw-r--r-- | arch/arm/plat-omap/include/plat/omap_device.h | 4 | ||||
| -rw-r--r-- | arch/arm/plat-omap/omap_device.c | 36 |
2 files changed, 40 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h index e4c349ff9fd8..bc36d05e13e4 100644 --- a/arch/arm/plat-omap/include/plat/omap_device.h +++ b/arch/arm/plat-omap/include/plat/omap_device.h | |||
| @@ -44,6 +44,9 @@ extern struct device omap_device_parent; | |||
| 44 | #define OMAP_DEVICE_STATE_IDLE 2 | 44 | #define OMAP_DEVICE_STATE_IDLE 2 |
| 45 | #define OMAP_DEVICE_STATE_SHUTDOWN 3 | 45 | #define OMAP_DEVICE_STATE_SHUTDOWN 3 |
| 46 | 46 | ||
| 47 | /* omap_device.flags values */ | ||
| 48 | #define OMAP_DEVICE_SUSPENDED BIT(0) | ||
| 49 | |||
| 47 | /** | 50 | /** |
| 48 | * struct omap_device - omap_device wrapper for platform_devices | 51 | * struct omap_device - omap_device wrapper for platform_devices |
| 49 | * @pdev: platform_device | 52 | * @pdev: platform_device |
| @@ -73,6 +76,7 @@ struct omap_device { | |||
| 73 | s8 pm_lat_level; | 76 | s8 pm_lat_level; |
| 74 | u8 hwmods_cnt; | 77 | u8 hwmods_cnt; |
| 75 | u8 _state; | 78 | u8 _state; |
| 79 | u8 flags; | ||
| 76 | }; | 80 | }; |
| 77 | 81 | ||
| 78 | /* Device driver interface (call via platform_data fn ptrs) */ | 82 | /* Device driver interface (call via platform_data fn ptrs) */ |
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c index f7d2ff77008a..b93cfdc9a366 100644 --- a/arch/arm/plat-omap/omap_device.c +++ b/arch/arm/plat-omap/omap_device.c | |||
| @@ -566,11 +566,47 @@ static int _od_runtime_resume(struct device *dev) | |||
| 566 | } | 566 | } |
| 567 | #endif | 567 | #endif |
| 568 | 568 | ||
| 569 | #ifdef CONFIG_SUSPEND | ||
| 570 | static int _od_suspend_noirq(struct device *dev) | ||
| 571 | { | ||
| 572 | struct platform_device *pdev = to_platform_device(dev); | ||
| 573 | struct omap_device *od = to_omap_device(pdev); | ||
| 574 | int ret; | ||
| 575 | |||
| 576 | ret = pm_generic_suspend_noirq(dev); | ||
| 577 | |||
| 578 | if (!ret && !pm_runtime_status_suspended(dev)) { | ||
| 579 | if (pm_generic_runtime_suspend(dev) == 0) { | ||
| 580 | omap_device_idle(pdev); | ||
| 581 | od->flags |= OMAP_DEVICE_SUSPENDED; | ||
| 582 | } | ||
| 583 | } | ||
| 584 | |||
| 585 | return ret; | ||
| 586 | } | ||
| 587 | |||
| 588 | static int _od_resume_noirq(struct device *dev) | ||
| 589 | { | ||
| 590 | struct platform_device *pdev = to_platform_device(dev); | ||
| 591 | struct omap_device *od = to_omap_device(pdev); | ||
| 592 | |||
| 593 | if ((od->flags & OMAP_DEVICE_SUSPENDED) && | ||
| 594 | !pm_runtime_status_suspended(dev)) { | ||
| 595 | od->flags &= ~OMAP_DEVICE_SUSPENDED; | ||
| 596 | omap_device_enable(pdev); | ||
| 597 | pm_generic_runtime_resume(dev); | ||
| 598 | } | ||
| 599 | |||
| 600 | return pm_generic_resume_noirq(dev); | ||
| 601 | } | ||
| 602 | #endif | ||
| 603 | |||
| 569 | static struct dev_pm_domain omap_device_pm_domain = { | 604 | static struct dev_pm_domain omap_device_pm_domain = { |
| 570 | .ops = { | 605 | .ops = { |
| 571 | SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume, | 606 | SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume, |
| 572 | _od_runtime_idle) | 607 | _od_runtime_idle) |
| 573 | USE_PLATFORM_PM_SLEEP_OPS | 608 | USE_PLATFORM_PM_SLEEP_OPS |
| 609 | SET_SYSTEM_SLEEP_PM_OPS(_od_suspend_noirq, _od_resume_noirq) | ||
| 574 | } | 610 | } |
| 575 | }; | 611 | }; |
| 576 | 612 | ||
