summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica/acpi_powerres.c
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2004-09-07 16:58:12 +0000
committernjl <njl@FreeBSD.org>2004-09-07 16:58:12 +0000
commitacf1aa5821afe297535449a0ea8674cbd4dfe70d (patch)
tree6eee5705b12d33a1af1233c05eec8e39dc1b4a51 /sys/dev/acpica/acpi_powerres.c
parentd0dc76864cfbe22ec2294583c2e0bd44b5042327 (diff)
downloadFreeBSD-src-acf1aa5821afe297535449a0ea8674cbd4dfe70d.zip
FreeBSD-src-acf1aa5821afe297535449a0ea8674cbd4dfe70d.tar.gz
Instead of trusting _STA from power resources, cache the first value
returned and then infer the state from calls to _ON/_OFF. This works around a problem in systems that don't correctly report the state (i.e. the HP Omnibook 500 reports "on" for its fan always after it has been turned on once).
Diffstat (limited to 'sys/dev/acpica/acpi_powerres.c')
-rw-r--r--sys/dev/acpica/acpi_powerres.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/dev/acpica/acpi_powerres.c b/sys/dev/acpica/acpi_powerres.c
index 11262c0..624fc54 100644
--- a/sys/dev/acpica/acpi_powerres.c
+++ b/sys/dev/acpica/acpi_powerres.c
@@ -62,6 +62,7 @@ ACPI_MODULE_NAME("POWERRES")
/* Return values from _STA on a power resource */
#define ACPI_PWR_OFF 0
#define ACPI_PWR_ON 1
+#define ACPI_PWR_UNK (-1)
/* A relationship between a power resource and a consumer. */
struct acpi_powerreference {
@@ -87,6 +88,7 @@ struct acpi_powerresource {
ACPI_HANDLE ap_resource;
ACPI_INTEGER ap_systemlevel;
ACPI_INTEGER ap_order;
+ int ap_state;
};
static TAILQ_HEAD(acpi_powerresource_list, acpi_powerresource)
@@ -169,6 +171,7 @@ acpi_pwr_register_resource(ACPI_HANDLE res)
}
rp->ap_systemlevel = obj->PowerResource.SystemLevel;
rp->ap_order = obj->PowerResource.ResourceOrder;
+ rp->ap_state = ACPI_PWR_UNK;
/* Sort the resource into the list */
status = AE_OK;
@@ -640,17 +643,17 @@ acpi_pwr_switch_power(void)
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "can't get status of %s - %d\n",
acpi_name(rp->ap_resource), status));
-
/* XXX is this correct? Always switch if in doubt? */
continue;
- }
+ } else if (rp->ap_state == ACPI_PWR_UNK)
+ rp->ap_state = cur;
/*
* Switch if required. Note that we ignore the result of the switch
* effort; we don't know what to do if it fails, so checking wouldn't
* help much.
*/
- if (cur != ACPI_PWR_ON) {
+ if (rp->ap_state != ACPI_PWR_ON) {
status = AcpiEvaluateObject(rp->ap_resource, "_ON", NULL, NULL);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
@@ -658,6 +661,7 @@ acpi_pwr_switch_power(void)
acpi_name(rp->ap_resource),
AcpiFormatException(status)));
} else {
+ rp->ap_state = ACPI_PWR_ON;
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "switched %s on\n",
acpi_name(rp->ap_resource)));
}
@@ -685,14 +689,15 @@ acpi_pwr_switch_power(void)
acpi_name(rp->ap_resource), status));
/* XXX is this correct? Always switch if in doubt? */
continue;
- }
+ } else if (rp->ap_state == ACPI_PWR_UNK)
+ rp->ap_state = cur;
/*
* Switch if required. Note that we ignore the result of the switch
* effort; we don't know what to do if it fails, so checking wouldn't
* help much.
*/
- if (cur != ACPI_PWR_OFF) {
+ if (rp->ap_state != ACPI_PWR_OFF) {
status = AcpiEvaluateObject(rp->ap_resource, "_OFF", NULL, NULL);
if (ACPI_FAILURE(status)) {
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS,
@@ -700,6 +705,7 @@ acpi_pwr_switch_power(void)
acpi_name(rp->ap_resource),
AcpiFormatException(status)));
} else {
+ rp->ap_state = ACPI_PWR_OFF;
ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "switched %s off\n",
acpi_name(rp->ap_resource)));
}
OpenPOWER on IntegriCloud