All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Len Brown <lenb@kernel.org>
Cc: ACPI Devel Maling List <linux-acpi@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Linux-pm mailing list <linux-pm@lists.linux-foundation.org>,
	Matthew Garrett <mjg59@srcf.ucam.org>,
	Maciej Rutecki <maciej.rutecki@gmail.com>
Subject: [PATCH 8/13] ACPI / PM: Add function for updating device power state consistently
Date: Thu, 25 Nov 2010 00:09:15 +0100	[thread overview]
Message-ID: <201011250009.15501.rjw@sisk.pl> (raw)
In-Reply-To: <201011250001.11297.rjw@sisk.pl>

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

Add function acpi_bus_update_power() for reading the actual power
state of an ACPI device and updating its device->power.state field
in such a way that its power resources' reference counters will
remain consistent with that field.

For this purpose introduce __acpi_bus_set_power() setting the
power state of an ACPI device without updating its
device->power.state field and make acpi_bus_set_power() and
acpi_bus_update_power() use it (acpi_bus_set_power() retains the
current behavior for now).

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
 drivers/acpi/bus.c      |   90 ++++++++++++++++++++++++++++++++----------------
 include/acpi/acpi_bus.h |    1 
 2 files changed, 62 insertions(+), 29 deletions(-)

Index: linux-2.6/drivers/acpi/bus.c
===================================================================
--- linux-2.6.orig/drivers/acpi/bus.c
+++ linux-2.6/drivers/acpi/bus.c
@@ -255,44 +255,17 @@ int acpi_bus_get_power(acpi_handle handl
 EXPORT_SYMBOL(acpi_bus_get_power);
 
 
-int acpi_bus_set_power(acpi_handle handle, int state)
+static int __acpi_bus_set_power(struct acpi_device *device, int state)
 {
 	int result = 0;
 	acpi_status status = AE_OK;
-	struct acpi_device *device = NULL;
 	char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
 
-
-	result = acpi_bus_get_device(handle, &device);
-	if (result)
-		return result;
-
-	if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
+	if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
 		return -EINVAL;
 
 	/* Make sure this is a valid target state */
 
-	if (!device->flags.power_manageable) {
-		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n",
-				kobject_name(&device->dev.kobj)));
-		return -ENODEV;
-	}
-	/*
-	 * Get device's current power state
-	 */
-	if (!acpi_power_nocheck) {
-		/*
-		 * Maybe the incorrect power state is returned on the bogus
-		 * bios, which is different with the real power state.
-		 * For example: the bios returns D0 state and the real power
-		 * state is D3. OS expects to set the device to D0 state. In
-		 * such case if OS uses the power state returned by the BIOS,
-		 * the device can't be transisted to the correct power state.
-		 * So if the acpi_power_nocheck is set, it is unnecessary to
-		 * get the power state by calling acpi_bus_get_power.
-		 */
-		acpi_bus_get_power(device->handle, &device->power.state);
-	}
 	if ((state == device->power.state) && !device->flags.force_power_state) {
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
 				  state));
@@ -362,6 +335,42 @@ int acpi_bus_set_power(acpi_handle handl
 	return result;
 }
 
+
+int acpi_bus_set_power(acpi_handle handle, int state)
+{
+	struct acpi_device *device;
+	int result;
+
+	result = acpi_bus_get_device(handle, &device);
+	if (result)
+		return result;
+
+	if (!device->flags.power_manageable) {
+		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+				"Device [%s] is not power manageable\n",
+				dev_name(&device->dev)));
+		return -ENODEV;
+	}
+
+	/*
+	 * Get device's current power state
+	 */
+	if (!acpi_power_nocheck) {
+		/*
+		 * Maybe the incorrect power state is returned on the bogus
+		 * bios, which is different with the real power state.
+		 * For example: the bios returns D0 state and the real power
+		 * state is D3. OS expects to set the device to D0 state. In
+		 * such case if OS uses the power state returned by the BIOS,
+		 * the device can't be transisted to the correct power state.
+		 * So if the acpi_power_nocheck is set, it is unnecessary to
+		 * get the power state by calling acpi_bus_get_power.
+		 */
+		__acpi_bus_get_power(device, &device->power.state);
+	}
+
+	return __acpi_bus_set_power(device, state);
+}
 EXPORT_SYMBOL(acpi_bus_set_power);
 
 
@@ -389,6 +398,29 @@ int acpi_bus_init_power(struct acpi_devi
 }
 
 
+int acpi_bus_update_power(acpi_handle handle, int *state_p)
+{
+	struct acpi_device *device;
+	int state;
+	int result;
+
+	result = acpi_bus_get_device(handle, &device);
+	if (result)
+		return result;
+
+	result = __acpi_bus_get_power(device, &state);
+	if (result)
+		return result;
+
+	result = __acpi_bus_set_power(device, state);
+	if (!result && state_p)
+		*state_p = state;
+
+	return result;
+}
+EXPORT_SYMBOL_GPL(acpi_bus_update_power);
+
+
 bool acpi_bus_power_manageable(acpi_handle handle)
 {
 	struct acpi_device *device;
Index: linux-2.6/include/acpi/acpi_bus.h
===================================================================
--- linux-2.6.orig/include/acpi/acpi_bus.h
+++ linux-2.6/include/acpi/acpi_bus.h
@@ -330,6 +330,7 @@ acpi_status acpi_bus_get_status_handle(a
 int acpi_bus_get_status(struct acpi_device *device);
 int acpi_bus_get_power(acpi_handle handle, int *state);
 int acpi_bus_set_power(acpi_handle handle, int state);
+int acpi_bus_update_power(acpi_handle handle, int *state_p);
 bool acpi_bus_power_manageable(acpi_handle handle);
 bool acpi_bus_can_wakeup(acpi_handle handle);
 #ifdef CONFIG_ACPI_PROC_EVENT

  parent reply	other threads:[~2010-11-24 23:09 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-24 23:01 [PATCH 0/13] ACPI / PM: Rework power resources management Rafael J. Wysocki
2010-11-24 23:02 ` [PATCH 1/13] ACPI / PM: Check device state before refcounting power resources Rafael J. Wysocki
2010-11-24 23:02 ` Rafael J. Wysocki
2010-11-24 23:03 ` [PATCH 2/13] ACPI / PM: Do not refcount power resources that can't be turned on Rafael J. Wysocki
2010-11-24 23:03   ` Rafael J. Wysocki
2010-11-24 23:05 ` [PATCH 3/13] ACPI / PM: Prevent acpi_power_get_inferred_state() from making changes Rafael J. Wysocki
2010-11-24 23:05 ` Rafael J. Wysocki
2010-11-24 23:06 ` [PATCH 4/13] ACPI / PM: Add functions for manipulating lists of power resources Rafael J. Wysocki
2010-11-24 23:06 ` Rafael J. Wysocki
2010-11-24 23:06 ` [PATCH 5/13] ACPI / PM: Introduce function for refcounting device " Rafael J. Wysocki
2010-11-24 23:06   ` Rafael J. Wysocki
2010-11-24 23:07 ` [PATCH 6/13] ACPI / PM: Introduce __acpi_bus_get_power() Rafael J. Wysocki
2010-11-24 23:07   ` Rafael J. Wysocki
2010-11-24 23:08 ` [PATCH 7/13] ACPI / PM: Add function for device power state initialization Rafael J. Wysocki
2010-11-24 23:08 ` Rafael J. Wysocki
2010-11-24 23:09 ` Rafael J. Wysocki [this message]
2010-11-24 23:09 ` [PATCH 8/13] ACPI / PM: Add function for updating device power state consistently Rafael J. Wysocki
2010-11-24 23:10 ` [PATCH 9/13] ACPI / PM: Register acpi_power_driver early Rafael J. Wysocki
2010-11-24 23:10 ` Rafael J. Wysocki
2010-11-24 23:10 ` [PATCH 10/13] ACPI / PM: Register power resource devices as soon as they are needed Rafael J. Wysocki
2010-11-24 23:10 ` Rafael J. Wysocki
2010-11-24 23:11 ` [PATCH 11/13] ACPI / Fan: Rework the handling of power resources Rafael J. Wysocki
2010-11-24 23:11   ` Rafael J. Wysocki
2010-11-24 23:12 ` [PATCH 12/13] ACPI / PM: Drop acpi_bus_get_power() Rafael J. Wysocki
2010-11-24 23:12 ` Rafael J. Wysocki
2010-12-01 22:02   ` Len Brown
2010-12-01 22:02   ` Len Brown
2010-12-01 22:07     ` Rafael J. Wysocki
2010-12-01 22:07     ` Rafael J. Wysocki
2010-12-01 22:07       ` Rafael J. Wysocki
2010-11-24 23:12 ` [PATCH 13/13] ACPI / PM: Drop acpi_power_nocheck Rafael J. Wysocki
2010-11-24 23:12 ` Rafael J. Wysocki
2010-11-26 21:55 ` [PATCH] Platform / x86: Make fujitsu_laptop use acpi_bus_update_power() Rafael J. Wysocki
2010-12-01 22:07   ` Len Brown
2010-12-01 22:07   ` Len Brown
2010-11-26 21:55 ` 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=201011250009.15501.rjw@sisk.pl \
    --to=rjw@sisk.pl \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@lists.linux-foundation.org \
    --cc=maciej.rutecki@gmail.com \
    --cc=mjg59@srcf.ucam.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.