X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=kernel%2Fpower%2Fmain.c;h=6a6d5eb3524e7d2f219aeaa894e70981b3a706fb;hb=30e0e178193d4221abc9926b07a4c7661c7cc4a9;hp=84e1ae63bb8c5aea8e020bb53ac95184c87a638f;hpb=0e7d56e3d9d7e37c79d0e05ffb3994e34beb3bbc;p=linux-2.6 diff --git a/kernel/power/main.c b/kernel/power/main.c index 84e1ae63bb..6a6d5eb352 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -24,13 +24,35 @@ #include "power.h" -BLOCKING_NOTIFIER_HEAD(pm_chain_head); - DEFINE_MUTEX(pm_mutex); unsigned int pm_flags; EXPORT_SYMBOL(pm_flags); +#ifdef CONFIG_PM_SLEEP + +/* Routines for PM-transition notifications */ + +static BLOCKING_NOTIFIER_HEAD(pm_chain_head); + +int register_pm_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&pm_chain_head, nb); +} +EXPORT_SYMBOL_GPL(register_pm_notifier); + +int unregister_pm_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&pm_chain_head, nb); +} +EXPORT_SYMBOL_GPL(unregister_pm_notifier); + +int pm_notifier_call_chain(unsigned long val) +{ + return (blocking_notifier_call_chain(&pm_chain_head, val, NULL) + == NOTIFY_BAD) ? -EINVAL : 0; +} + #ifdef CONFIG_PM_DEBUG int pm_test_level = TEST_NONE; @@ -53,7 +75,8 @@ static const char * const pm_tests[__TEST_AFTER_LAST] = { [TEST_FREEZER] = "freezer", }; -static ssize_t pm_test_show(struct kset *kset, char *buf) +static ssize_t pm_test_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) { char *s = buf; int level; @@ -73,7 +96,8 @@ static ssize_t pm_test_show(struct kset *kset, char *buf) return (s - buf); } -static ssize_t pm_test_store(struct kset *kset, const char *buf, size_t n) +static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n) { const char * const *s; int level; @@ -104,6 +128,8 @@ power_attr(pm_test); static inline int suspend_test(int level) { return 0; } #endif /* !CONFIG_PM_DEBUG */ +#endif /* CONFIG_PM_SLEEP */ + #ifdef CONFIG_SUSPEND /* This is just an arbitrary number */ @@ -149,13 +175,13 @@ static int suspend_prepare(void) if (!suspend_ops || !suspend_ops->enter) return -EPERM; + pm_prepare_console(); + error = pm_notifier_call_chain(PM_SUSPEND_PREPARE); if (error) goto Finish; - pm_prepare_console(); - - if (freeze_processes()) { + if (suspend_freeze_processes()) { error = -EAGAIN; goto Thaw; } @@ -173,10 +199,10 @@ static int suspend_prepare(void) return 0; Thaw: - thaw_processes(); - pm_restore_console(); + suspend_thaw_processes(); Finish: pm_notifier_call_chain(PM_POST_SUSPEND); + pm_restore_console(); return error; } @@ -206,7 +232,7 @@ static int suspend_enter(suspend_state_t state) BUG_ON(!irqs_disabled()); if ((error = device_power_down(PMSG_SUSPEND))) { - printk(KERN_ERR "Some devices failed to power down\n"); + printk(KERN_ERR "PM: Some devices failed to power down\n"); goto Done; } @@ -221,8 +247,8 @@ static int suspend_enter(suspend_state_t state) } /** - * suspend_devices_and_enter - suspend devices and enter the desired system sleep - * state. + * suspend_devices_and_enter - suspend devices and enter the desired system + * sleep state. * @state: state to enter */ int suspend_devices_and_enter(suspend_state_t state) @@ -232,15 +258,15 @@ int suspend_devices_and_enter(suspend_state_t state) if (!suspend_ops) return -ENOSYS; - if (suspend_ops->set_target) { - error = suspend_ops->set_target(state); + if (suspend_ops->begin) { + error = suspend_ops->begin(state); if (error) - return error; + goto Close; } suspend_console(); error = device_suspend(PMSG_SUSPEND); if (error) { - printk(KERN_ERR "Some devices failed to suspend\n"); + printk(KERN_ERR "PM: Some devices failed to suspend\n"); goto Resume_console; } @@ -268,6 +294,9 @@ int suspend_devices_and_enter(suspend_state_t state) device_resume(); Resume_console: resume_console(); + Close: + if (suspend_ops->end) + suspend_ops->end(); return error; } @@ -279,9 +308,9 @@ int suspend_devices_and_enter(suspend_state_t state) */ static void suspend_finish(void) { - thaw_processes(); - pm_restore_console(); + suspend_thaw_processes(); pm_notifier_call_chain(PM_POST_SUSPEND); + pm_restore_console(); } @@ -323,7 +352,7 @@ static int enter_state(suspend_state_t state) if (!mutex_trylock(&pm_mutex)) return -EBUSY; - printk("Syncing filesystems ... "); + printk(KERN_INFO "PM: Syncing filesystems ... "); sys_sync(); printk("done.\n"); @@ -466,7 +495,7 @@ static struct attribute * g[] = { #ifdef CONFIG_PM_TRACE &pm_trace_attr.attr, #endif -#ifdef CONFIG_PM_DEBUG +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PM_DEBUG) &pm_test_attr.attr, #endif NULL,