forked from luck/tmp_suning_uos_patched
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>
This commit is contained in:
parent
256a543597
commit
c03f007a8b
@ -44,6 +44,9 @@ extern struct device omap_device_parent;
|
||||
#define OMAP_DEVICE_STATE_IDLE 2
|
||||
#define OMAP_DEVICE_STATE_SHUTDOWN 3
|
||||
|
||||
/* omap_device.flags values */
|
||||
#define OMAP_DEVICE_SUSPENDED BIT(0)
|
||||
|
||||
/**
|
||||
* struct omap_device - omap_device wrapper for platform_devices
|
||||
* @pdev: platform_device
|
||||
@ -73,6 +76,7 @@ struct omap_device {
|
||||
s8 pm_lat_level;
|
||||
u8 hwmods_cnt;
|
||||
u8 _state;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
/* Device driver interface (call via platform_data fn ptrs) */
|
||||
|
@ -566,11 +566,47 @@ static int _od_runtime_resume(struct device *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
static int _od_suspend_noirq(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct omap_device *od = to_omap_device(pdev);
|
||||
int ret;
|
||||
|
||||
ret = pm_generic_suspend_noirq(dev);
|
||||
|
||||
if (!ret && !pm_runtime_status_suspended(dev)) {
|
||||
if (pm_generic_runtime_suspend(dev) == 0) {
|
||||
omap_device_idle(pdev);
|
||||
od->flags |= OMAP_DEVICE_SUSPENDED;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _od_resume_noirq(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct omap_device *od = to_omap_device(pdev);
|
||||
|
||||
if ((od->flags & OMAP_DEVICE_SUSPENDED) &&
|
||||
!pm_runtime_status_suspended(dev)) {
|
||||
od->flags &= ~OMAP_DEVICE_SUSPENDED;
|
||||
omap_device_enable(pdev);
|
||||
pm_generic_runtime_resume(dev);
|
||||
}
|
||||
|
||||
return pm_generic_resume_noirq(dev);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct dev_pm_domain omap_device_pm_domain = {
|
||||
.ops = {
|
||||
SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
|
||||
_od_runtime_idle)
|
||||
USE_PLATFORM_PM_SLEEP_OPS
|
||||
SET_SYSTEM_SLEEP_PM_OPS(_od_suspend_noirq, _od_resume_noirq)
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user