Commit a939b96c authored by Linus Torvalds's avatar Linus Torvalds

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
parents 5cab3856 6a7c7eaf
...@@ -300,9 +300,9 @@ static int acpi_suspend_state_valid(suspend_state_t pm_state) ...@@ -300,9 +300,9 @@ static int acpi_suspend_state_valid(suspend_state_t pm_state)
static struct platform_suspend_ops acpi_suspend_ops = { static struct platform_suspend_ops acpi_suspend_ops = {
.valid = acpi_suspend_state_valid, .valid = acpi_suspend_state_valid,
.begin = acpi_suspend_begin, .begin = acpi_suspend_begin,
.prepare = acpi_pm_prepare, .prepare_late = acpi_pm_prepare,
.enter = acpi_suspend_enter, .enter = acpi_suspend_enter,
.finish = acpi_pm_finish, .wake = acpi_pm_finish,
.end = acpi_pm_end, .end = acpi_pm_end,
}; };
...@@ -328,9 +328,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state) ...@@ -328,9 +328,9 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state)
static struct platform_suspend_ops acpi_suspend_ops_old = { static struct platform_suspend_ops acpi_suspend_ops_old = {
.valid = acpi_suspend_state_valid, .valid = acpi_suspend_state_valid,
.begin = acpi_suspend_begin_old, .begin = acpi_suspend_begin_old,
.prepare = acpi_pm_disable_gpes, .prepare_late = acpi_pm_disable_gpes,
.enter = acpi_suspend_enter, .enter = acpi_suspend_enter,
.finish = acpi_pm_finish, .wake = acpi_pm_finish,
.end = acpi_pm_end, .end = acpi_pm_end,
.recover = acpi_pm_finish, .recover = acpi_pm_finish,
}; };
......
...@@ -58,10 +58,17 @@ typedef int __bitwise suspend_state_t; ...@@ -58,10 +58,17 @@ typedef int __bitwise suspend_state_t;
* by @begin(). * by @begin().
* @prepare() is called right after devices have been suspended (ie. the * @prepare() is called right after devices have been suspended (ie. the
* appropriate .suspend() method has been executed for each device) and * appropriate .suspend() method has been executed for each device) and
* before the nonboot CPUs are disabled (it is executed with IRQs enabled). * before device drivers' late suspend callbacks are executed. It returns
* This callback is optional. It returns 0 on success or a negative * 0 on success or a negative error code otherwise, in which case the
* error code otherwise, in which case the system cannot enter the desired * system cannot enter the desired sleep state (@prepare_late(), @enter(),
* sleep state (@enter() and @finish() will not be called in that case). * @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 * @enter: Enter the system sleep state indicated by @begin() or represented by
* the argument if @begin() is not implemented. * the argument if @begin() is not implemented.
...@@ -69,19 +76,26 @@ typedef int __bitwise suspend_state_t; ...@@ -69,19 +76,26 @@ typedef int __bitwise suspend_state_t;
* error code otherwise, in which case the system cannot enter the desired * error code otherwise, in which case the system cannot enter the desired
* sleep state. * sleep state.
* *
* @finish: Called when the system has just left a sleep state, right after * @wake: 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 * the nonboot CPUs have been enabled and before device drivers' early
* executed with IRQs enabled). * 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 * This callback is optional, but should be implemented by the platforms
* that implement @prepare(). If implemented, it is always called after * 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 * @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 platform that the system has returned to the working state or
* the transition to the sleep state has been aborted. * the transition to the sleep state has been aborted.
* This callback is optional, but should be implemented by the platforms * This callback is optional, but should be implemented by the platforms
* that implement @begin(), but platforms implementing @begin() should * that implement @begin(). Accordingly, platforms implementing @begin()
* also provide a @end() which cleans up transitions aborted before * should also provide a @end() which cleans up transitions aborted before
* @enter(). * @enter().
* *
* @recover: Recover the platform from a suspend failure. * @recover: Recover the platform from a suspend failure.
...@@ -93,7 +107,9 @@ struct platform_suspend_ops { ...@@ -93,7 +107,9 @@ struct platform_suspend_ops {
int (*valid)(suspend_state_t state); int (*valid)(suspend_state_t state);
int (*begin)(suspend_state_t state); int (*begin)(suspend_state_t state);
int (*prepare)(void); int (*prepare)(void);
int (*prepare_late)(void);
int (*enter)(suspend_state_t state); int (*enter)(suspend_state_t state);
void (*wake)(void);
void (*finish)(void); void (*finish)(void);
void (*end)(void); void (*end)(void);
void (*recover)(void); void (*recover)(void);
......
...@@ -291,20 +291,26 @@ static int suspend_enter(suspend_state_t state) ...@@ -291,20 +291,26 @@ static int suspend_enter(suspend_state_t state)
device_pm_lock(); device_pm_lock();
if (suspend_ops->prepare) {
error = suspend_ops->prepare();
if (error)
goto Done;
}
error = device_power_down(PMSG_SUSPEND); error = device_power_down(PMSG_SUSPEND);
if (error) { if (error) {
printk(KERN_ERR "PM: Some devices failed to power down\n"); printk(KERN_ERR "PM: Some devices failed to power down\n");
goto Done; goto Platfrom_finish;
} }
if (suspend_ops->prepare) { if (suspend_ops->prepare_late) {
error = suspend_ops->prepare(); error = suspend_ops->prepare_late();
if (error) if (error)
goto Power_up_devices; goto Power_up_devices;
} }
if (suspend_test(TEST_PLATFORM)) if (suspend_test(TEST_PLATFORM))
goto Platfrom_finish; goto Platform_wake;
error = disable_nonboot_cpus(); error = disable_nonboot_cpus();
if (error || suspend_test(TEST_CPUS)) if (error || suspend_test(TEST_CPUS))
...@@ -326,13 +332,17 @@ static int suspend_enter(suspend_state_t state) ...@@ -326,13 +332,17 @@ static int suspend_enter(suspend_state_t state)
Enable_cpus: Enable_cpus:
enable_nonboot_cpus(); enable_nonboot_cpus();
Platfrom_finish: Platform_wake:
if (suspend_ops->finish) if (suspend_ops->wake)
suspend_ops->finish(); suspend_ops->wake();
Power_up_devices: Power_up_devices:
device_power_up(PMSG_RESUME); device_power_up(PMSG_RESUME);
Platfrom_finish:
if (suspend_ops->finish)
suspend_ops->finish();
Done: Done:
device_pm_unlock(); device_pm_unlock();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment