From 564b905ab10d17fb42f86aa8b7b9b796276d1336 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 23 Jun 2011 01:52:55 +0200 Subject: PM / Domains: Rename struct dev_power_domain to struct dev_pm_domain The naming convention used by commit 7538e3db6e015e890825fbd9f86599b (PM: Add support for device power domains), which introduced the struct dev_power_domain type for representing device power domains, evidently confuses some developers who tend to think that objects of this type must correspond to "power domains" as defined by hardware, which is not the case. Namely, at the kernel level, a struct dev_power_domain object can represent arbitrary set of devices that are mutually dependent power management-wise and need not belong to one hardware power domain. To avoid that confusion, rename struct dev_power_domain to struct dev_pm_domain and rename the related pointers in struct device and struct pm_clk_notifier_block from pwr_domain to pm_domain. Signed-off-by: Rafael J. Wysocki Acked-by: Kevin Hilman --- include/linux/pm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/pm.h') diff --git a/include/linux/pm.h b/include/linux/pm.h index 411e4f4be52..e3963208aa9 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -472,7 +472,7 @@ extern void update_pm_runtime_accounting(struct device *dev); * hibernation, system resume and during runtime PM transitions along with * subsystem-level and driver-level callbacks. */ -struct dev_power_domain { +struct dev_pm_domain { struct dev_pm_ops ops; }; -- cgit v1.2.3-70-g09d2 From dc6e4e56e6ef473a696a1ab24f80b79b9aceb92d Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 23 Jun 2011 01:53:04 +0200 Subject: PM: subsys_data in struct dev_pm_info need not depend on RM_RUNTIME The subsys_data field of struct dev_pm_info, introduced by commit 1d2b71f61b6a10216274e27b717becf9ae101fc7 (PM / Runtime: Add subsystem data field to struct dev_pm_info), is going to be used even if CONFIG_PM_RUNTIME is not set, so move it from under the #ifdef. Signed-off-by: Rafael J. Wysocki --- include/linux/pm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux/pm.h') diff --git a/include/linux/pm.h b/include/linux/pm.h index e3963208aa9..7e8f0763d1e 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -461,8 +461,8 @@ struct dev_pm_info { unsigned long active_jiffies; unsigned long suspended_jiffies; unsigned long accounting_timestamp; - void *subsys_data; /* Owned by the subsystem. */ #endif + void *subsys_data; /* Owned by the subsystem. */ }; extern void update_pm_runtime_accounting(struct device *dev); -- cgit v1.2.3-70-g09d2 From e5291928839877f8e73c2643ee1d3fe0bcdcaf5c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 1 Jul 2011 22:12:59 +0200 Subject: PM: Introduce generic "noirq" callback routines for subsystems (v2) Introduce generic "noirq" power management callback routines for subsystems in addition to the "regular" generic PM callback routines. The new routines will be used, among other things, for implementing system-wide PM transitions support for generic PM domains. Signed-off-by: Rafael J. Wysocki --- Documentation/power/runtime_pm.txt | 32 ++++++++++++- drivers/base/power/generic_ops.c | 98 ++++++++++++++++++++++++++++++++------ include/linux/pm.h | 6 +++ 3 files changed, 119 insertions(+), 17 deletions(-) (limited to 'include/linux/pm.h') diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index b24875b1ced..4b011b171be 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -606,32 +606,60 @@ driver/base/power/generic_ops.c: callback provided by its driver and return its result, or return 0 if not defined + int pm_generic_suspend_noirq(struct device *dev); + - if pm_runtime_suspended(dev) returns "false", invoke the ->suspend_noirq() + callback provided by the device's driver and return its result, or return + 0 if not defined + int pm_generic_resume(struct device *dev); - invoke the ->resume() callback provided by the driver of this device and, if successful, change the device's runtime PM status to 'active' + int pm_generic_resume_noirq(struct device *dev); + - invoke the ->resume_noirq() callback provided by the driver of this device + int pm_generic_freeze(struct device *dev); - if the device has not been suspended at run time, invoke the ->freeze() callback provided by its driver and return its result, or return 0 if not defined + int pm_generic_freeze_noirq(struct device *dev); + - if pm_runtime_suspended(dev) returns "false", invoke the ->freeze_noirq() + callback provided by the device's driver and return its result, or return + 0 if not defined + int pm_generic_thaw(struct device *dev); - if the device has not been suspended at run time, invoke the ->thaw() callback provided by its driver and return its result, or return 0 if not defined + int pm_generic_thaw_noirq(struct device *dev); + - if pm_runtime_suspended(dev) returns "false", invoke the ->thaw_noirq() + callback provided by the device's driver and return its result, or return + 0 if not defined + int pm_generic_poweroff(struct device *dev); - if the device has not been suspended at run time, invoke the ->poweroff() callback provided by its driver and return its result, or return 0 if not defined + int pm_generic_poweroff_noirq(struct device *dev); + - if pm_runtime_suspended(dev) returns "false", run the ->poweroff_noirq() + callback provided by the device's driver and return its result, or return + 0 if not defined + int pm_generic_restore(struct device *dev); - invoke the ->restore() callback provided by the driver of this device and, if successful, change the device's runtime PM status to 'active' + int pm_generic_restore_noirq(struct device *dev); + - invoke the ->restore_noirq() callback provided by the device's driver + These functions can be assigned to the ->runtime_idle(), ->runtime_suspend(), -->runtime_resume(), ->suspend(), ->resume(), ->freeze(), ->thaw(), ->poweroff(), -or ->restore() callback pointers in the subsystem-level dev_pm_ops structures. +->runtime_resume(), ->suspend(), ->suspend_noirq(), ->resume(), +->resume_noirq(), ->freeze(), ->freeze_noirq(), ->thaw(), ->thaw_noirq(), +->poweroff(), ->poweroff_noirq(), ->restore(), ->restore_noirq() callback +pointers in the subsystem-level dev_pm_ops structures. If a subsystem wishes to use all of them at the same time, it can simply assign the GENERIC_SUBSYS_PM_OPS macro, defined in include/linux/pm.h, to its diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c index cb3bb368681..9508df71274 100644 --- a/drivers/base/power/generic_ops.c +++ b/drivers/base/power/generic_ops.c @@ -94,12 +94,13 @@ int pm_generic_prepare(struct device *dev) * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback. * @dev: Device to handle. * @event: PM transition of the system under way. + * @bool: Whether or not this is the "noirq" stage. * * If the device has not been suspended at run time, execute the * suspend/freeze/poweroff/thaw callback provided by its driver, if defined, and * return its error code. Otherwise, return zero. */ -static int __pm_generic_call(struct device *dev, int event) +static int __pm_generic_call(struct device *dev, int event, bool noirq) { const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; int (*callback)(struct device *); @@ -109,16 +110,16 @@ static int __pm_generic_call(struct device *dev, int event) switch (event) { case PM_EVENT_SUSPEND: - callback = pm->suspend; + callback = noirq ? pm->suspend_noirq : pm->suspend; break; case PM_EVENT_FREEZE: - callback = pm->freeze; + callback = noirq ? pm->freeze_noirq : pm->freeze; break; case PM_EVENT_HIBERNATE: - callback = pm->poweroff; + callback = noirq ? pm->poweroff_noirq : pm->poweroff; break; case PM_EVENT_THAW: - callback = pm->thaw; + callback = noirq ? pm->thaw_noirq : pm->thaw; break; default: callback = NULL; @@ -128,43 +129,83 @@ static int __pm_generic_call(struct device *dev, int event) return callback ? callback(dev) : 0; } +/** + * pm_generic_suspend_noirq - Generic suspend_noirq callback for subsystems. + * @dev: Device to suspend. + */ +int pm_generic_suspend_noirq(struct device *dev) +{ + return __pm_generic_call(dev, PM_EVENT_SUSPEND, true); +} +EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq); + /** * pm_generic_suspend - Generic suspend callback for subsystems. * @dev: Device to suspend. */ int pm_generic_suspend(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_SUSPEND); + return __pm_generic_call(dev, PM_EVENT_SUSPEND, false); } EXPORT_SYMBOL_GPL(pm_generic_suspend); +/** + * pm_generic_freeze_noirq - Generic freeze_noirq callback for subsystems. + * @dev: Device to freeze. + */ +int pm_generic_freeze_noirq(struct device *dev) +{ + return __pm_generic_call(dev, PM_EVENT_FREEZE, true); +} +EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq); + /** * pm_generic_freeze - Generic freeze callback for subsystems. * @dev: Device to freeze. */ int pm_generic_freeze(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_FREEZE); + return __pm_generic_call(dev, PM_EVENT_FREEZE, false); } EXPORT_SYMBOL_GPL(pm_generic_freeze); +/** + * pm_generic_poweroff_noirq - Generic poweroff_noirq callback for subsystems. + * @dev: Device to handle. + */ +int pm_generic_poweroff_noirq(struct device *dev) +{ + return __pm_generic_call(dev, PM_EVENT_HIBERNATE, true); +} +EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq); + /** * pm_generic_poweroff - Generic poweroff callback for subsystems. * @dev: Device to handle. */ int pm_generic_poweroff(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_HIBERNATE); + return __pm_generic_call(dev, PM_EVENT_HIBERNATE, false); } EXPORT_SYMBOL_GPL(pm_generic_poweroff); +/** + * pm_generic_thaw_noirq - Generic thaw_noirq callback for subsystems. + * @dev: Device to thaw. + */ +int pm_generic_thaw_noirq(struct device *dev) +{ + return __pm_generic_call(dev, PM_EVENT_THAW, true); +} +EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq); + /** * pm_generic_thaw - Generic thaw callback for subsystems. * @dev: Device to thaw. */ int pm_generic_thaw(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_THAW); + return __pm_generic_call(dev, PM_EVENT_THAW, false); } EXPORT_SYMBOL_GPL(pm_generic_thaw); @@ -172,12 +213,13 @@ EXPORT_SYMBOL_GPL(pm_generic_thaw); * __pm_generic_resume - Generic resume/restore callback for subsystems. * @dev: Device to handle. * @event: PM transition of the system under way. + * @bool: Whether or not this is the "noirq" stage. * * Execute the resume/resotre callback provided by the @dev's driver, if * defined. If it returns 0, change the device's runtime PM status to 'active'. * Return the callback's error code. */ -static int __pm_generic_resume(struct device *dev, int event) +static int __pm_generic_resume(struct device *dev, int event, bool noirq) { const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; int (*callback)(struct device *); @@ -188,10 +230,10 @@ static int __pm_generic_resume(struct device *dev, int event) switch (event) { case PM_EVENT_RESUME: - callback = pm->resume; + callback = noirq ? pm->resume_noirq : pm->resume; break; case PM_EVENT_RESTORE: - callback = pm->restore; + callback = noirq ? pm->restore_noirq : pm->restore; break; default: callback = NULL; @@ -202,7 +244,7 @@ static int __pm_generic_resume(struct device *dev, int event) return 0; ret = callback(dev); - if (!ret && pm_runtime_enabled(dev)) { + if (!ret && !noirq && pm_runtime_enabled(dev)) { pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); @@ -211,23 +253,43 @@ static int __pm_generic_resume(struct device *dev, int event) return ret; } +/** + * pm_generic_resume_noirq - Generic resume_noirq callback for subsystems. + * @dev: Device to resume. + */ +int pm_generic_resume_noirq(struct device *dev) +{ + return __pm_generic_resume(dev, PM_EVENT_RESUME, true); +} +EXPORT_SYMBOL_GPL(pm_generic_resume_noirq); + /** * pm_generic_resume - Generic resume callback for subsystems. * @dev: Device to resume. */ int pm_generic_resume(struct device *dev) { - return __pm_generic_resume(dev, PM_EVENT_RESUME); + return __pm_generic_resume(dev, PM_EVENT_RESUME, false); } EXPORT_SYMBOL_GPL(pm_generic_resume); +/** + * pm_generic_restore_noirq - Generic restore_noirq callback for subsystems. + * @dev: Device to restore. + */ +int pm_generic_restore_noirq(struct device *dev) +{ + return __pm_generic_resume(dev, PM_EVENT_RESTORE, true); +} +EXPORT_SYMBOL_GPL(pm_generic_restore_noirq); + /** * pm_generic_restore - Generic restore callback for subsystems. * @dev: Device to restore. */ int pm_generic_restore(struct device *dev) { - return __pm_generic_resume(dev, PM_EVENT_RESTORE); + return __pm_generic_resume(dev, PM_EVENT_RESTORE, false); } EXPORT_SYMBOL_GPL(pm_generic_restore); @@ -256,11 +318,17 @@ struct dev_pm_ops generic_subsys_pm_ops = { #ifdef CONFIG_PM_SLEEP .prepare = pm_generic_prepare, .suspend = pm_generic_suspend, + .suspend_noirq = pm_generic_suspend_noirq, .resume = pm_generic_resume, + .resume_noirq = pm_generic_resume_noirq, .freeze = pm_generic_freeze, + .freeze_noirq = pm_generic_freeze_noirq, .thaw = pm_generic_thaw, + .thaw_noirq = pm_generic_thaw_noirq, .poweroff = pm_generic_poweroff, + .poweroff_noirq = pm_generic_poweroff_noirq, .restore = pm_generic_restore, + .restore_noirq = pm_generic_restore_noirq, .complete = pm_generic_complete, #endif #ifdef CONFIG_PM_RUNTIME diff --git a/include/linux/pm.h b/include/linux/pm.h index 7e8f0763d1e..f7c84c9abd3 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -553,11 +553,17 @@ extern void __suspend_report_result(const char *function, void *fn, int ret); extern int device_pm_wait_for_dev(struct device *sub, struct device *dev); extern int pm_generic_prepare(struct device *dev); +extern int pm_generic_suspend_noirq(struct device *dev); extern int pm_generic_suspend(struct device *dev); +extern int pm_generic_resume_noirq(struct device *dev); extern int pm_generic_resume(struct device *dev); +extern int pm_generic_freeze_noirq(struct device *dev); extern int pm_generic_freeze(struct device *dev); +extern int pm_generic_thaw_noirq(struct device *dev); extern int pm_generic_thaw(struct device *dev); +extern int pm_generic_restore_noirq(struct device *dev); extern int pm_generic_restore(struct device *dev); +extern int pm_generic_poweroff_noirq(struct device *dev); extern int pm_generic_poweroff(struct device *dev); extern void pm_generic_complete(struct device *dev); -- cgit v1.2.3-70-g09d2