Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/suspend-2.6:
  PM/Suspend: Introduce two new platform callbacks to avoid breakage
This commit is contained in:
Linus Torvalds 2009-04-20 08:43:06 -07:00
commit a939b96ccc
3 changed files with 47 additions and 21 deletions

View file

@ -300,9 +300,9 @@ static int acpi_suspend_state_valid(suspend_state_t pm_state)
static struct platform_suspend_ops acpi_suspend_ops = {
.valid = acpi_suspend_state_valid,
.begin = acpi_suspend_begin,
.prepare = acpi_pm_prepare,
.prepare_late = acpi_pm_prepare,
.enter = acpi_suspend_enter,
.finish = acpi_pm_finish,
.wake = acpi_pm_finish,
.end = acpi_pm_end,
};
@ -328,9 +328,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state)
static struct platform_suspend_ops acpi_suspend_ops_old = {
.valid = acpi_suspend_state_valid,
.begin = acpi_suspend_begin_old,
.prepare = acpi_pm_disable_gpes,
.prepare_late = acpi_pm_disable_gpes,
.enter = acpi_suspend_enter,
.finish = acpi_pm_finish,
.wake = acpi_pm_finish,
.end = acpi_pm_end,
.recover = acpi_pm_finish,
};

View file

@ -58,10 +58,17 @@ typedef int __bitwise suspend_state_t;
* by @begin().
* @prepare() is called right after devices have been suspended (ie. the
* appropriate .suspend() method has been executed for each device) and
* before the nonboot CPUs are disabled (it is executed with IRQs enabled).
* This callback is optional. It returns 0 on success or a negative
* error code otherwise, in which case the system cannot enter the desired
* sleep state (@enter() and @finish() will not be called in that case).
* before device drivers' late suspend callbacks are executed. It returns
* 0 on success or a negative error code otherwise, in which case the
* system cannot enter the desired sleep state (@prepare_late(), @enter(),
* @wake(), and @finish() will not be called in that case).
*
* @prepare_late: Finish preparing the platform for entering the system sleep
* state indicated by @begin().
* @prepare_late is called before disabling nonboot CPUs and after
* device drivers' late suspend callbacks have been executed. It returns
* 0 on success or a negative error code otherwise, in which case the
* system cannot enter the desired sleep state (@enter() and @wake()).
*
* @enter: Enter the system sleep state indicated by @begin() or represented by
* the argument if @begin() is not implemented.
@ -69,19 +76,26 @@ typedef int __bitwise suspend_state_t;
* error code otherwise, in which case the system cannot enter the desired
* sleep state.
*
* @finish: Called when the system has just left a sleep state, right after
* the nonboot CPUs have been enabled and before devices are resumed (it is
* executed with IRQs enabled).
* @wake: Called when the system has just left a sleep state, right after
* the nonboot CPUs have been enabled and before device drivers' early
* resume callbacks are executed.
* This callback is optional, but should be implemented by the platforms
* that implement @prepare_late(). If implemented, it is always called
* after @enter(), even if @enter() fails.
*
* @finish: Finish wake-up of the platform.
* @finish is called right prior to calling device drivers' regular suspend
* callbacks.
* This callback is optional, but should be implemented by the platforms
* that implement @prepare(). If implemented, it is always called after
* @enter() (even if @enter() fails).
* @enter() and @wake(), if implemented, even if any of them fails.
*
* @end: Called by the PM core right after resuming devices, to indicate to
* the platform that the system has returned to the working state or
* the transition to the sleep state has been aborted.
* This callback is optional, but should be implemented by the platforms
* that implement @begin(), but platforms implementing @begin() should
* also provide a @end() which cleans up transitions aborted before
* that implement @begin(). Accordingly, platforms implementing @begin()
* should also provide a @end() which cleans up transitions aborted before
* @enter().
*
* @recover: Recover the platform from a suspend failure.
@ -93,7 +107,9 @@ struct platform_suspend_ops {
int (*valid)(suspend_state_t state);
int (*begin)(suspend_state_t state);
int (*prepare)(void);
int (*prepare_late)(void);
int (*enter)(suspend_state_t state);
void (*wake)(void);
void (*finish)(void);
void (*end)(void);
void (*recover)(void);

View file

@ -291,20 +291,26 @@ static int suspend_enter(suspend_state_t state)
device_pm_lock();
if (suspend_ops->prepare) {
error = suspend_ops->prepare();
if (error)
goto Done;
}
error = device_power_down(PMSG_SUSPEND);
if (error) {
printk(KERN_ERR "PM: Some devices failed to power down\n");
goto Done;
goto Platfrom_finish;
}
if (suspend_ops->prepare) {
error = suspend_ops->prepare();
if (suspend_ops->prepare_late) {
error = suspend_ops->prepare_late();
if (error)
goto Power_up_devices;
}
if (suspend_test(TEST_PLATFORM))
goto Platfrom_finish;
goto Platform_wake;
error = disable_nonboot_cpus();
if (error || suspend_test(TEST_CPUS))
@ -326,13 +332,17 @@ static int suspend_enter(suspend_state_t state)
Enable_cpus:
enable_nonboot_cpus();
Platfrom_finish:
if (suspend_ops->finish)
suspend_ops->finish();
Platform_wake:
if (suspend_ops->wake)
suspend_ops->wake();
Power_up_devices:
device_power_up(PMSG_RESUME);
Platfrom_finish:
if (suspend_ops->finish)
suspend_ops->finish();
Done:
device_pm_unlock();