Skip to content

Commit

Permalink
Hibernation: Introduce begin() and end() callbacks
Browse files Browse the repository at this point in the history
Introduce global hibernation callback .end() and rename global
hibernation callback .start() to .begin(), in analogy with the
recent modifications of the global suspend callbacks.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>
  • Loading branch information
Rafael J. Wysocki authored and Len Brown committed Feb 1, 2008
1 parent 60417f5 commit caea99e
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 16 deletions.
14 changes: 12 additions & 2 deletions drivers/acpi/sleep/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
#endif /* CONFIG_SUSPEND */

#ifdef CONFIG_HIBERNATION
static int acpi_hibernation_start(void)
static int acpi_hibernation_begin(void)
{
acpi_target_sleep_state = ACPI_STATE_S4;
return 0;
Expand Down Expand Up @@ -341,6 +341,15 @@ static void acpi_hibernation_finish(void)
acpi_target_sleep_state = ACPI_STATE_S0;
}

static void acpi_hibernation_end(void)
{
/*
* This is necessary in case acpi_hibernation_finish() is not called
* during a failing transition to the sleep state.
*/
acpi_target_sleep_state = ACPI_STATE_S0;
}

static int acpi_hibernation_pre_restore(void)
{
acpi_status status;
Expand All @@ -356,7 +365,8 @@ static void acpi_hibernation_restore_cleanup(void)
}

static struct platform_hibernation_ops acpi_hibernation_ops = {
.start = acpi_hibernation_start,
.begin = acpi_hibernation_begin,
.end = acpi_hibernation_end,
.pre_snapshot = acpi_hibernation_prepare,
.finish = acpi_hibernation_finish,
.prepare = acpi_hibernation_prepare,
Expand Down
14 changes: 9 additions & 5 deletions include/linux/suspend.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,14 +136,17 @@ extern void mark_free_pages(struct zone *zone);
/**
* struct platform_hibernation_ops - hibernation platform support
*
* The methods in this structure allow a platform to override the default
* mechanism of shutting down the machine during a hibernation transition.
* The methods in this structure allow a platform to carry out special
* operations required by it during a hibernation transition.
*
* All three methods must be assigned.
* All the methods below must be implemented.
*
* @start: Tell the platform driver that we're starting hibernation.
* @begin: Tell the platform driver that we're starting hibernation.
* Called right after shrinking memory and before freezing devices.
*
* @end: Called by the PM core right after resuming devices, to indicate to
* the platform that the system has returned to the working state.
*
* @pre_snapshot: Prepare the platform for creating the hibernation image.
* Called right after devices have been frozen and before the nonboot
* CPUs are disabled (runs with IRQs on).
Expand Down Expand Up @@ -178,7 +181,8 @@ extern void mark_free_pages(struct zone *zone);
* thawing devices (runs with IRQs on).
*/
struct platform_hibernation_ops {
int (*start)(void);
int (*begin)(void);
void (*end)(void);
int (*pre_snapshot)(void);
void (*finish)(void);
int (*prepare)(void);
Expand Down
33 changes: 24 additions & 9 deletions kernel/power/disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ static struct platform_hibernation_ops *hibernation_ops;

void hibernation_set_ops(struct platform_hibernation_ops *ops)
{
if (ops && !(ops->start && ops->pre_snapshot && ops->finish
&& ops->prepare && ops->enter && ops->pre_restore
if (ops && !(ops->begin && ops->end && ops->pre_snapshot
&& ops->prepare && ops->finish && ops->enter && ops->pre_restore
&& ops->restore_cleanup)) {
WARN_ON(1);
return;
Expand Down Expand Up @@ -100,14 +100,25 @@ static int hibernation_test(int level) { return 0; }
#endif /* !CONFIG_PM_DEBUG */

/**
* platform_start - tell the platform driver that we're starting
* platform_begin - tell the platform driver that we're starting
* hibernation
*/

static int platform_start(int platform_mode)
static int platform_begin(int platform_mode)
{
return (platform_mode && hibernation_ops) ?
hibernation_ops->start() : 0;
hibernation_ops->begin() : 0;
}

/**
* platform_end - tell the platform driver that we've entered the
* working state
*/

static void platform_end(int platform_mode)
{
if (platform_mode && hibernation_ops)
hibernation_ops->end();
}

/**
Expand Down Expand Up @@ -237,9 +248,9 @@ int hibernation_snapshot(int platform_mode)
if (error)
return error;

error = platform_start(platform_mode);
error = platform_begin(platform_mode);
if (error)
return error;
goto Close;

suspend_console();
error = device_suspend(PMSG_FREEZE);
Expand Down Expand Up @@ -272,6 +283,8 @@ int hibernation_snapshot(int platform_mode)
device_resume();
Resume_console:
resume_console();
Close:
platform_end(platform_mode);
return error;
}

Expand Down Expand Up @@ -373,9 +386,9 @@ int hibernation_platform_enter(void)
* hibernation_ops->finish() before saving the image, so we should let
* the firmware know that we're going to enter the sleep state after all
*/
error = hibernation_ops->start();
error = hibernation_ops->begin();
if (error)
return error;
goto Close;

suspend_console();
error = device_suspend(PMSG_SUSPEND);
Expand Down Expand Up @@ -409,6 +422,8 @@ int hibernation_platform_enter(void)
device_resume();
Resume_console:
resume_console();
Close:
hibernation_ops->end();
return error;
}

Expand Down

0 comments on commit caea99e

Please sign in to comment.