public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
From: Len Brown <lenb@kernel.org>
To: linux-pm@lists.linux-foundation.org
Cc: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org,
	"Rafael J. Wysocki" <rjw@sisk.pl>,
	Len Brown <len.brown@intel.com>
Subject: [PATCH 26/37] Suspend: Introduce begin() and end() callbacks
Date: Thu, 31 Jan 2008 23:36:57 -0500	[thread overview]
Message-ID: <68db114effdf54dd7fc0c724ab2aef5bc98d9c79.1201840183.git.len.brown@intel.com> (raw)
In-Reply-To: <1201840628-23136-1-git-send-email-lenb@kernel.org>
In-Reply-To: <edae89f5d1eb1fbe1cab74333db5a8e29776900e.1201840183.git.len.brown@intel.com>

From: Rafael J. Wysocki <rjw@sisk.pl>

On ACPI systems the target state set by acpi_pm_set_target() is
reset by acpi_pm_finish(), but that need not be called if the
suspend fails.  All platforms that use the .set_target() global
suspend callback are affected by analogous issues.

For this reason, we need an additional global suspend callback that
will reset the target state regardless of whether or not the suspend
is successful.  Also, it is reasonable to rename the .set_target()
callback, since it will be used for a different purpose on ACPI
systems (due to ACPI 1.0x code ordering requirements).

Introduce the global suspend callback .end() to be executed at the
end of the suspend sequence and rename the .set_target() global
suspend callback to .begin().

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 arch/arm/mach-at91/pm.c                   |   17 +++++++++++++----
 arch/powerpc/platforms/52xx/lite5200_pm.c |   10 ++++++++--
 drivers/acpi/sleep/main.c                 |   22 ++++++++++++++++++----
 include/linux/suspend.h                   |   29 ++++++++++++++++++-----------
 kernel/power/main.c                       |    9 ++++++---
 5 files changed, 63 insertions(+), 24 deletions(-)

diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 4b120cc..a67defd 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -52,7 +52,7 @@ static suspend_state_t target_state;
 /*
  * Called after processes are frozen, but before we shutdown devices.
  */
-static int at91_pm_set_target(suspend_state_t state)
+static int at91_pm_begin(suspend_state_t state)
 {
 	target_state = state;
 	return 0;
@@ -202,11 +202,20 @@ error:
 	return 0;
 }
 
+/*
+ * Called right prior to thawing processes.
+ */
+static void at91_pm_end(void)
+{
+	target_state = PM_SUSPEND_ON;
+}
+
 
 static struct platform_suspend_ops at91_pm_ops ={
-	.valid		= at91_pm_valid_state,
-	.set_target	= at91_pm_set_target,
-	.enter		= at91_pm_enter,
+	.valid	= at91_pm_valid_state,
+	.begin	= at91_pm_begin,
+	.enter	= at91_pm_enter,
+	.end	= at91_pm_end,
 };
 
 static int __init at91_pm_init(void)
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c
index c0f13e8..41c7fd9 100644
--- a/arch/powerpc/platforms/52xx/lite5200_pm.c
+++ b/arch/powerpc/platforms/52xx/lite5200_pm.c
@@ -31,7 +31,7 @@ static int lite5200_pm_valid(suspend_state_t state)
 	}
 }
 
-static int lite5200_pm_set_target(suspend_state_t state)
+static int lite5200_pm_begin(suspend_state_t state)
 {
 	if (lite5200_pm_valid(state)) {
 		lite5200_pm_target_state = state;
@@ -219,12 +219,18 @@ static void lite5200_pm_finish(void)
 		mpc52xx_pm_finish();
 }
 
+static void lite5200_pm_end(void)
+{
+	lite5200_pm_target_state = PM_SUSPEND_ON;
+}
+
 static struct platform_suspend_ops lite5200_pm_ops = {
 	.valid		= lite5200_pm_valid,
-	.set_target	= lite5200_pm_set_target,
+	.begin		= lite5200_pm_begin,
 	.prepare	= lite5200_pm_prepare,
 	.enter		= lite5200_pm_enter,
 	.finish		= lite5200_pm_finish,
+	.end		= lite5200_pm_end,
 };
 
 int __init lite5200_pm_init(void)
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 96d23b3..e2e4e61 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -63,11 +63,11 @@ static u32 acpi_suspend_states[] = {
 static int init_8259A_after_S1;
 
 /**
- *	acpi_pm_set_target - Set the target system sleep state to the state
+ *	acpi_pm_begin - Set the target system sleep state to the state
  *		associated with given @pm_state, if supported.
  */
 
-static int acpi_pm_set_target(suspend_state_t pm_state)
+static int acpi_pm_begin(suspend_state_t pm_state)
 {
 	u32 acpi_state = acpi_suspend_states[pm_state];
 	int error = 0;
@@ -164,7 +164,7 @@ static int acpi_pm_enter(suspend_state_t pm_state)
 }
 
 /**
- *	acpi_pm_finish - Finish up suspend sequence.
+ *	acpi_pm_finish - Instruct the platform to leave a sleep state.
  *
  *	This is called after we wake back up (or if entering the sleep state
  *	failed). 
@@ -190,6 +190,19 @@ static void acpi_pm_finish(void)
 #endif
 }
 
+/**
+ *	acpi_pm_end - Finish up suspend sequence.
+ */
+
+static void acpi_pm_end(void)
+{
+	/*
+	 * This is necessary in case acpi_pm_finish() is not called during a
+	 * failing transition to a sleep state.
+	 */
+	acpi_target_sleep_state = ACPI_STATE_S0;
+}
+
 static int acpi_pm_state_valid(suspend_state_t pm_state)
 {
 	u32 acpi_state;
@@ -208,10 +221,11 @@ static int acpi_pm_state_valid(suspend_state_t pm_state)
 
 static struct platform_suspend_ops acpi_pm_ops = {
 	.valid = acpi_pm_state_valid,
-	.set_target = acpi_pm_set_target,
+	.begin = acpi_pm_begin,
 	.prepare = acpi_pm_prepare,
 	.enter = acpi_pm_enter,
 	.finish = acpi_pm_finish,
+	.end = acpi_pm_end,
 };
 
 /*
diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 51283e0..a0b1dbb 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -38,18 +38,16 @@ typedef int __bitwise suspend_state_t;
  *	There is the %suspend_valid_only_mem function available that can be
  *	assigned to this if the platform only supports mem sleep.
  *
- * @set_target: Tell the platform which system sleep state is going to be
- *	entered.
- *	@set_target() is executed right prior to suspending devices.  The
- *	information conveyed to the platform code by @set_target() should be
- *	disregarded by the platform as soon as @finish() is executed and if
- *	@prepare() fails.  If @set_target() fails (ie. returns nonzero),
+ * @begin: Initialise a transition to given system sleep state.
+ *	@begin() is executed right prior to suspending devices.  The information
+ *	conveyed to the platform code by @begin() should be disregarded by it as
+ *	soon as @end() is executed.  If @begin() fails (ie. returns nonzero),
  *	@prepare(), @enter() and @finish() will not be called by the PM core.
  *	This callback is optional.  However, if it is implemented, the argument
- *	passed to @enter() is meaningless and should be ignored.
+ *	passed to @enter() is redundant and should be ignored.
  *
  * @prepare: Prepare the platform for entering the system sleep state indicated
- *	by @set_target().
+ *	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).
@@ -57,8 +55,8 @@ typedef int __bitwise suspend_state_t;
  *	error code otherwise, in which case the system cannot enter the desired
  *	sleep state (@enter() and @finish() will not be called in that case).
  *
- * @enter: Enter the system sleep state indicated by @set_target() or
- *	represented by the argument if @set_target() is not implemented.
+ * @enter: Enter the system sleep state indicated by @begin() or represented by
+ *	the argument if @begin() is not implemented.
  *	This callback is mandatory.  It returns 0 on success or a negative
  *	error code otherwise, in which case the system cannot enter the desired
  *	sleep state.
@@ -69,13 +67,22 @@ typedef int __bitwise suspend_state_t;
  *	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).
+ *
+ * @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
+ *	@enter().
  */
 struct platform_suspend_ops {
 	int (*valid)(suspend_state_t state);
-	int (*set_target)(suspend_state_t state);
+	int (*begin)(suspend_state_t state);
 	int (*prepare)(void);
 	int (*enter)(suspend_state_t state);
 	void (*finish)(void);
+	void (*end)(void);
 };
 
 #ifdef CONFIG_SUSPEND
diff --git a/kernel/power/main.c b/kernel/power/main.c
index 050a607..d9bba45 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -258,10 +258,10 @@ 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);
@@ -294,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;
 }
 
-- 
1.5.4.rc5.16.gc0279

-
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2008-02-01  4:41 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-01  4:36 suspend patches for 2.6.25-rc0 Len Brown
2008-02-01  4:36 ` [PATCH 01/37] Hibernation: Introduce SNAPSHOT_GET_IMAGE_SIZE ioctl Len Brown
2008-02-01  4:36   ` [PATCH 02/37] Hibernation: Rework platform support ioctls (rev. 2) Len Brown
2008-02-01  4:36   ` [PATCH 03/37] Hibernation: Mark SNAPSHOT_SET_SWAP_FILE ioctl as deprecated " Len Brown
2008-02-01  4:36   ` [PATCH 04/37] Hibernation: Correct definitions of some ioctls " Len Brown
2008-02-01  4:36   ` [PATCH 05/37] Hibernation: Introduce exportable suspend ioctls header " Len Brown
2008-02-01  4:36   ` [PATCH 06/37] ACPI: Fix mismerge in acpi_hibernation_finish Len Brown
2008-02-01  4:36   ` [PATCH 07/37] Hibernation: Move function prototypes to header Len Brown
2008-02-01  4:36   ` [PATCH 08/37] Hibernation: Add PM_RESTORE_PREPARE and PM_POST_RESTORE notifiers (rev. 2) Len Brown
2008-02-01  4:36   ` [PATCH 09/37] Suspend: Testing facility " Len Brown
2008-02-01  4:36   ` [PATCH 10/37] suspend: build fix responding to 2.6.25 kset change Len Brown
2008-02-01  4:36   ` [PATCH 11/37] Hibernation: New testing facility (rev. 2) Len Brown
2008-02-01  4:36   ` [PATCH 12/37] PM: Suspend/hibernation debug documentation update " Len Brown
2008-02-01  4:36   ` [PATCH 13/37] PM: Make PM_TRACE more architecture independent Len Brown
2008-02-01  4:36   ` [PATCH 14/37] PM: Convert PM notifiers to out-of-line code Len Brown
2008-02-01  4:36   ` [PATCH 15/37] Suspend: Fix compilation warning for CONFIG_SUSPEND unset Len Brown
2008-02-01  4:36   ` [PATCH 16/37] Hibernation: Move low level resume to disk.c Len Brown
2008-02-01  4:36   ` [PATCH 17/37] Suspend: Fix comment in main.c Len Brown
2008-02-01  4:36   ` [PATCH 18/37] Hibernation: Fix comment in disk.c Len Brown
2008-02-01  4:36   ` [PATCH 19/37] Hibernation: Remove unnecessary variable declaration Len Brown
2008-02-01  4:36   ` [PATCH 20/37] Suspend: Use common prefix in messages Len Brown
2008-02-01  4:36   ` [PATCH 21/37] Hibernation: Update messages Len Brown
2008-02-01  4:36   ` [PATCH 22/37] Hibernation: Clean up Kconfig (V2) Len Brown
2008-02-01  4:36   ` [PATCH 23/37] Suspend: " Len Brown
2008-02-01  9:05     ` Bryan Wu
2008-02-04 14:59     ` Pavel Machek
2008-02-01  4:36   ` [PATCH 24/37] ACPI: clear GPE earily in resume to avoid warning Len Brown
2008-02-01  4:36   ` [PATCH 25/37] suspend: fix ia64 allmodconfig build Len Brown
2008-02-01  4:36   ` Len Brown [this message]
2008-02-01  4:36   ` [PATCH 27/37] ACPI: Separate invocations of _GTS and _BFS from _PTS and _WAK Len Brown
2008-02-01  4:36   ` [PATCH 28/37] ACPI: Separate disabling of GPEs from _PTS Len Brown
2008-02-01  4:37   ` [PATCH 29/37] ACPI suspend: Call _PTS before suspending devices Len Brown
2008-02-01  4:37   ` [PATCH 30/37] Hibernation: Introduce begin() and end() callbacks Len Brown
2008-02-01  4:37   ` [PATCH 31/37] ACPI hibernation: Call _PTS before suspending devices Len Brown
2008-02-01  4:37   ` [PATCH 32/37] ACPI: Print message before calling _PTS Len Brown
2008-02-01  4:37   ` [PATCH 33/37] Suspend: Add config option to disable the freezer if architecture wants that Len Brown
2008-02-01  4:37   ` [PATCH 34/37] Suspend: Clean up suspend_64.c Len Brown
2008-02-01  4:37   ` [PATCH 35/37] Suspend: Invoke suspend notifications after console switch Len Brown
2008-02-01  4:37   ` [PATCH 36/37] Hibernation: " Len Brown
2008-02-01  4:37   ` [PATCH 37/37] PM: Remove obsolete /sys/devices/.../power/state docs Len Brown
2008-02-01  5:48 ` [PATCH] feature-removal: Document suspend/hibernate deprecations Harvey Harrison
2008-02-01 10:54   ` Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=68db114effdf54dd7fc0c724ab2aef5bc98d9c79.1201840183.git.len.brown@intel.com \
    --to=lenb@kernel.org \
    --cc=len.brown@intel.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@lists.linux-foundation.org \
    --cc=rjw@sisk.pl \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox