From d690b2cd222afc75320b9b8e9da7df02e9e630ca Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sat, 6 Mar 2010 21:28:37 +0100 Subject: PM: Provide generic subsystem-level callbacks There are subsystems whose power management callbacks only need to invoke the callbacks provided by device drivers. Still, their system sleep PM callbacks should play well with the runtime PM callbacks, so that devices suspended at run time can be left in that state for a system sleep transition. Provide a set of generic PM callbacks for such subsystems and define convenience macros for populating dev_pm_ops structures. Signed-off-by: Rafael J. Wysocki --- include/linux/pm.h | 51 ++++++++++++++++++++++++++++++++++++++++------ include/linux/pm_runtime.h | 6 ++++++ 2 files changed, 51 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/linux/pm.h b/include/linux/pm.h index e80df06ad22a..8e258c727971 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -215,20 +215,59 @@ struct dev_pm_ops { int (*runtime_idle)(struct device *dev); }; +#ifdef CONFIG_PM_SLEEP +#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ + .suspend = suspend_fn, \ + .resume = resume_fn, \ + .freeze = suspend_fn, \ + .thaw = resume_fn, \ + .poweroff = suspend_fn, \ + .restore = resume_fn, +#else +#define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) +#endif + +#ifdef CONFIG_PM_RUNTIME +#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ + .runtime_suspend = suspend_fn, \ + .runtime_resume = resume_fn, \ + .runtime_idle = idle_fn, +#else +#define SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) +#endif + /* * Use this if you want to use the same suspend and resume callbacks for suspend * to RAM and hibernation. */ #define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ const struct dev_pm_ops name = { \ - .suspend = suspend_fn, \ - .resume = resume_fn, \ - .freeze = suspend_fn, \ - .thaw = resume_fn, \ - .poweroff = suspend_fn, \ - .restore = resume_fn, \ + SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ +} + +/* + * Use this for defining a set of PM operations to be used in all situations + * (sustem suspend, hibernation or runtime PM). + */ +#define UNIVERSAL_DEV_PM_OPS(name, suspend_fn, resume_fn, idle_fn) \ +const struct dev_pm_ops name = { \ + SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) \ + SET_RUNTIME_PM_OPS(suspend_fn, resume_fn, idle_fn) \ } +/* + * Use this for subsystems (bus types, device types, device classes) that don't + * need any special suspend/resume handling in addition to invoking the PM + * callbacks provided by device drivers supporting both the system sleep PM and + * runtime PM, make the pm member point to generic_subsys_pm_ops. + */ +#ifdef CONFIG_PM_OPS +extern struct dev_pm_ops generic_subsys_pm_ops; +#define GENERIC_SUBSYS_PM_OPS (&generic_subsys_pm_ops) +#else +#define GENERIC_SUBSYS_PM_OPS NULL +#endif + /** * PM_EVENT_ messages * diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 7d773aac5314..b776db737244 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -62,6 +62,11 @@ static inline void device_set_run_wake(struct device *dev, bool enable) dev->power.run_wake = enable; } +static inline bool pm_runtime_suspended(struct device *dev) +{ + return dev->power.runtime_status == RPM_SUSPENDED; +} + #else /* !CONFIG_PM_RUNTIME */ static inline int pm_runtime_idle(struct device *dev) { return -ENOSYS; } @@ -89,6 +94,7 @@ static inline void pm_runtime_get_noresume(struct device *dev) {} static inline void pm_runtime_put_noidle(struct device *dev) {} static inline bool device_run_wake(struct device *dev) { return false; } static inline void device_set_run_wake(struct device *dev, bool enable) {} +static inline bool pm_runtime_suspended(struct device *dev) { return false; } #endif /* !CONFIG_PM_RUNTIME */ -- cgit v1.2.2