Commit 8490fdf9 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

PM / sleep: Move platform suspend operations to separate functions

After the introduction of freeze_ops it makes more sense to move
all of the platform suspend operations to separate functions that
each will do all of the necessary checks and choose the right
callback to execute istead of doing all that in the core code
which makes it generally harder to follow.
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent d431cbc5
...@@ -36,12 +36,6 @@ const char *pm_states[PM_SUSPEND_MAX]; ...@@ -36,12 +36,6 @@ const char *pm_states[PM_SUSPEND_MAX];
static const struct platform_suspend_ops *suspend_ops; static const struct platform_suspend_ops *suspend_ops;
static const struct platform_freeze_ops *freeze_ops; static const struct platform_freeze_ops *freeze_ops;
static bool need_suspend_ops(suspend_state_t state)
{
return state > PM_SUSPEND_FREEZE;
}
static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head); static DECLARE_WAIT_QUEUE_HEAD(suspend_freeze_wait_head);
static bool suspend_freeze_wake; static bool suspend_freeze_wake;
...@@ -139,6 +133,65 @@ int suspend_valid_only_mem(suspend_state_t state) ...@@ -139,6 +133,65 @@ int suspend_valid_only_mem(suspend_state_t state)
} }
EXPORT_SYMBOL_GPL(suspend_valid_only_mem); EXPORT_SYMBOL_GPL(suspend_valid_only_mem);
static bool sleep_state_supported(suspend_state_t state)
{
return state == PM_SUSPEND_FREEZE || (suspend_ops && suspend_ops->enter);
}
static int platform_suspend_prepare(suspend_state_t state)
{
return state != PM_SUSPEND_FREEZE && suspend_ops->prepare ?
suspend_ops->prepare() : 0;
}
static int platform_suspend_prepare_late(suspend_state_t state)
{
return state != PM_SUSPEND_FREEZE && suspend_ops->prepare_late ?
suspend_ops->prepare_late() : 0;
}
static void platform_suspend_wake(suspend_state_t state)
{
if (state != PM_SUSPEND_FREEZE && suspend_ops->wake)
suspend_ops->wake();
}
static void platform_suspend_finish(suspend_state_t state)
{
if (state != PM_SUSPEND_FREEZE && suspend_ops->finish)
suspend_ops->finish();
}
static int platform_suspend_begin(suspend_state_t state)
{
if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->begin)
return freeze_ops->begin();
else if (suspend_ops->begin)
return suspend_ops->begin(state);
else
return 0;
}
static void platform_suspend_end(suspend_state_t state)
{
if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->end)
freeze_ops->end();
else if (suspend_ops->end)
suspend_ops->end();
}
static void platform_suspend_recover(suspend_state_t state)
{
if (state != PM_SUSPEND_FREEZE && suspend_ops->recover)
suspend_ops->recover();
}
static bool platform_suspend_again(suspend_state_t state)
{
return state != PM_SUSPEND_FREEZE && suspend_ops->suspend_again ?
suspend_ops->suspend_again() : false;
}
static int suspend_test(int level) static int suspend_test(int level)
{ {
#ifdef CONFIG_PM_DEBUG #ifdef CONFIG_PM_DEBUG
...@@ -162,7 +215,7 @@ static int suspend_prepare(suspend_state_t state) ...@@ -162,7 +215,7 @@ static int suspend_prepare(suspend_state_t state)
{ {
int error; int error;
if (need_suspend_ops(state) && (!suspend_ops || !suspend_ops->enter)) if (!sleep_state_supported(state))
return -EPERM; return -EPERM;
pm_prepare_console(); pm_prepare_console();
...@@ -208,23 +261,18 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) ...@@ -208,23 +261,18 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
{ {
int error; int error;
if (need_suspend_ops(state) && suspend_ops->prepare) { error = platform_suspend_prepare(state);
error = suspend_ops->prepare(); if (error)
if (error) goto Platform_finish;
goto Platform_finish;
}
error = dpm_suspend_end(PMSG_SUSPEND); error = dpm_suspend_end(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 Platform_finish; goto Platform_finish;
} }
error = platform_suspend_prepare_late(state);
if (need_suspend_ops(state) && suspend_ops->prepare_late) { if (error)
error = suspend_ops->prepare_late(); goto Platform_wake;
if (error)
goto Platform_wake;
}
if (suspend_test(TEST_PLATFORM)) if (suspend_test(TEST_PLATFORM))
goto Platform_wake; goto Platform_wake;
...@@ -272,15 +320,11 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) ...@@ -272,15 +320,11 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
ftrace_start(); ftrace_start();
Platform_wake: Platform_wake:
if (need_suspend_ops(state) && suspend_ops->wake) platform_suspend_wake(state);
suspend_ops->wake();
dpm_resume_start(PMSG_RESUME); dpm_resume_start(PMSG_RESUME);
Platform_finish: Platform_finish:
if (need_suspend_ops(state) && suspend_ops->finish) platform_suspend_finish(state);
suspend_ops->finish();
return error; return error;
} }
...@@ -293,18 +337,13 @@ int suspend_devices_and_enter(suspend_state_t state) ...@@ -293,18 +337,13 @@ int suspend_devices_and_enter(suspend_state_t state)
int error; int error;
bool wakeup = false; bool wakeup = false;
if (need_suspend_ops(state) && !suspend_ops) if (!sleep_state_supported(state))
return -ENOSYS; return -ENOSYS;
if (need_suspend_ops(state) && suspend_ops->begin) { error = platform_suspend_begin(state);
error = suspend_ops->begin(state); if (error)
if (error) goto Close;
goto Close;
} else if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->begin) {
error = freeze_ops->begin();
if (error)
goto Close;
}
suspend_console(); suspend_console();
suspend_test_start(); suspend_test_start();
error = dpm_suspend_start(PMSG_SUSPEND); error = dpm_suspend_start(PMSG_SUSPEND);
...@@ -318,25 +357,20 @@ int suspend_devices_and_enter(suspend_state_t state) ...@@ -318,25 +357,20 @@ int suspend_devices_and_enter(suspend_state_t state)
do { do {
error = suspend_enter(state, &wakeup); error = suspend_enter(state, &wakeup);
} while (!error && !wakeup && need_suspend_ops(state) } while (!error && !wakeup && platform_suspend_again(state));
&& suspend_ops->suspend_again && suspend_ops->suspend_again());
Resume_devices: Resume_devices:
suspend_test_start(); suspend_test_start();
dpm_resume_end(PMSG_RESUME); dpm_resume_end(PMSG_RESUME);
suspend_test_finish("resume devices"); suspend_test_finish("resume devices");
resume_console(); resume_console();
Close:
if (need_suspend_ops(state) && suspend_ops->end)
suspend_ops->end();
else if (state == PM_SUSPEND_FREEZE && freeze_ops && freeze_ops->end)
freeze_ops->end();
Close:
platform_suspend_end(state);
return error; return error;
Recover_platform: Recover_platform:
if (need_suspend_ops(state) && suspend_ops->recover) platform_suspend_recover(state);
suspend_ops->recover();
goto Resume_devices; goto Resume_devices;
} }
......
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