From: Len Brown <lenb@kernel.org>
To: linux-acpi@vger.kernel.org, linux-pm@lists.linux-foundation.org
Cc: linux-kernel@vger.kernel.org, "Rafael J. Wysocki" <rjw@sisk.pl>
Subject: [PATCH 06/15] ACPI / PM: Make __acpi_bus_get_power() cover D3cold correctly
Date: Mon, 4 Jun 2012 01:39:57 -0400 [thread overview]
Message-ID: <38c92fff988d518fe80dc23d0d44d66bd7e47ddd.1338786831.git.len.brown@intel.com> (raw)
In-Reply-To: <1338788406-29981-1-git-send-email-lenb@kernel.org>
In-Reply-To: <c5971456964290da7e98222892797b71ef793e62.1338786831.git.len.brown@intel.com>
From: "Rafael J. Wysocki" <rjw@sisk.pl>
After recent changes of the ACPI device power states definitions, if
power resources are not used for the device's power management, the
state returned by __acpi_bus_get_power() cannot exceed D3hot, because
the return values of _PSC are 0 through 3. However, if the _PR3
method is not present for the device and _PS3 returns 3, we have to
assume that the device is in D3cold, so the value returned by
__acpi_bus_get_power() in that case should be 4.
Similarly, acpi_power_get_inferred_state() should take the power
resources for the D3hot state into account in general, so that it
can return 3 if those resources are "on" or 4 (D3cold) otherwise.
Fix the the above two issues and make sure that if both _PSC and
_PR3 are present for the device, the power resources listed by _PR3
will be used to determine if the number 3 returned by _PSC is meant
to represent D3cold or D3hot.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/acpi/bus.c | 51 +++++++++++++++++++++++++++++----------------------
drivers/acpi/power.c | 2 +-
2 files changed, 30 insertions(+), 23 deletions(-)
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index a41be56..adceafd 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -202,37 +202,44 @@ static const char *state_string(int state)
static int __acpi_bus_get_power(struct acpi_device *device, int *state)
{
- int result = 0;
- acpi_status status = 0;
- unsigned long long psc = 0;
+ int result = ACPI_STATE_UNKNOWN;
if (!device || !state)
return -EINVAL;
- *state = ACPI_STATE_UNKNOWN;
-
- if (device->flags.power_manageable) {
- /*
- * Get the device's power state either directly (via _PSC) or
- * indirectly (via power resources).
- */
- if (device->power.flags.power_resources) {
- result = acpi_power_get_inferred_state(device, state);
- if (result)
- return result;
- } else if (device->power.flags.explicit_get) {
- status = acpi_evaluate_integer(device->handle, "_PSC",
- NULL, &psc);
- if (ACPI_FAILURE(status))
- return -ENODEV;
- *state = (int)psc;
- }
- } else {
+ if (!device->flags.power_manageable) {
/* TBD: Non-recursive algorithm for walking up hierarchy. */
*state = device->parent ?
device->parent->power.state : ACPI_STATE_D0;
+ goto out;
+ }
+
+ /*
+ * Get the device's power state either directly (via _PSC) or
+ * indirectly (via power resources).
+ */
+ if (device->power.flags.explicit_get) {
+ unsigned long long psc;
+ acpi_status status = acpi_evaluate_integer(device->handle,
+ "_PSC", NULL, &psc);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+
+ result = psc;
+ }
+ /* The test below covers ACPI_STATE_UNKNOWN too. */
+ if (result <= ACPI_STATE_D2) {
+ ; /* Do nothing. */
+ } else if (device->power.flags.power_resources) {
+ int error = acpi_power_get_inferred_state(device, &result);
+ if (error)
+ return error;
+ } else if (result == ACPI_STATE_D3_HOT) {
+ result = ACPI_STATE_D3;
}
+ *state = result;
+ out:
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is %s\n",
device->pnp.bus_id, state_string(*state)));
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 0500f71..dd6d6a3 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -631,7 +631,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
* We know a device's inferred power state when all the resources
* required for a given D-state are 'on'.
*/
- for (i = ACPI_STATE_D0; i < ACPI_STATE_D3_HOT; i++) {
+ for (i = ACPI_STATE_D0; i <= ACPI_STATE_D3_HOT; i++) {
list = &device->power.states[i].resources;
if (list->count < 1)
continue;
--
1.7.11.rc0.100.g5498c5f
next prev parent reply other threads:[~2012-06-04 5:40 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-04 5:39 ACPI & Power Management Patches for Linux 3.5-rc1 Len Brown
2012-06-04 5:39 ` [PATCH 01/15] ACPI battery: only refresh the sysfs files when pertinent information changes Len Brown
2012-06-04 5:39 ` [PATCH 02/15] ACPI: Ignore invalid _PSS entries, but use valid ones Len Brown
2012-06-04 5:39 ` [PATCH 03/15] ACPI / PM: Generate wakeup events on fixed power button Len Brown
2012-06-04 5:39 ` [PATCH 04/15] rtc-cmos / PM: report wakeup event on ACPI RTC alarm Len Brown
2012-06-04 5:39 ` [PATCH 05/15] ACPI / PM: Fix error messages in drivers/acpi/bus.c Len Brown
2012-06-04 5:39 ` Len Brown [this message]
2012-06-04 5:39 ` [PATCH 07/15] ACPI / PM: Make acpi_pm_device_sleep_state() follow the specification Len Brown
2012-06-04 5:39 ` [PATCH 08/15] acpi_video: fix leaking PCI references Len Brown
2012-06-04 5:40 ` [PATCH 09/15] acpi_video: Intel video is not always i915 Len Brown
2012-06-04 5:40 ` [PATCH 10/15] gma500: don't register the ACPI video bus Len Brown
2012-06-04 5:40 ` [PATCH 11/15] ACPI video: use after input_unregister_device() Len Brown
2012-06-04 5:40 ` [PATCH 12/15] tools/power turbostat: fix un-intended affinity of forked program Len Brown
2012-06-04 5:40 ` [PATCH 13/15] tools/power turbostat: fix IVB support Len Brown
2012-06-04 5:40 ` [PATCH 14/15] drivers: acpi: Fix dependency for ACPI_HOTPLUG_CPU Len Brown
2012-06-04 5:40 ` [PATCH 15/15] ACPI: fix acpi_bus.h build warnings when ACPI is not enabled Len Brown
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=38c92fff988d518fe80dc23d0d44d66bd7e47ddd.1338786831.git.len.brown@intel.com \
--to=lenb@kernel.org \
--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
all inboxes | Powered by JetHome®