Lines Matching +full:power +full:- +full:off

1 /*-
40 * ACPI power resource management.
42 * Power resource behaviour is slightly complicated by the fact that
43 * a single power resource may provide power for more than one device.
44 * Thus, we must track the device(s) being powered by a given power
48 * ugly case where we may turn off power to a device which is in use because
53 * on, turned off, etc.
56 static MALLOC_DEFINE(M_ACPIPWR, "acpipwr", "ACPI power resources");
62 /* Return values from _STA on a power resource */
66 /* A relationship between a power resource and a consumer. */
74 /* A power-managed device. */
83 /* A power resource. */
96 ACPI_SERIAL_DECL(powerres, "ACPI power resources");
117 * Register a power resource.
144 TAILQ_INIT(&rp->ap_references); in acpi_pwr_register_resource()
145 rp->ap_resource = res; in acpi_pwr_register_resource()
147 /* Get the Power Resource object */ in acpi_pwr_register_resource()
150 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "no power resource object\n")); in acpi_pwr_register_resource()
154 if (obj->Type != ACPI_TYPE_POWER) { in acpi_pwr_register_resource()
156 "questionable power resource object %s\n", in acpi_pwr_register_resource()
161 rp->ap_systemlevel = obj->PowerResource.SystemLevel; in acpi_pwr_register_resource()
162 rp->ap_order = obj->PowerResource.ResourceOrder; in acpi_pwr_register_resource()
167 if (srp == NULL || rp->ap_order < srp->ap_order) { in acpi_pwr_register_resource()
172 if (rp->ap_order < srp->ap_order) { in acpi_pwr_register_resource()
181 "registered power resource %s\n", acpi_name(res))); in acpi_pwr_register_resource()
193 * Deregister a power resource.
210 if (TAILQ_FIRST(&rp->ap_references) != NULL) in acpi_pwr_deregister_resource()
213 /* Pull it off the list and free it */ in acpi_pwr_deregister_resource()
217 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "deregistered power resource %s\n", in acpi_pwr_deregister_resource()
225 * Register a power consumer.
241 /* Allocate a new power consumer */ in acpi_pwr_register_consumer()
245 TAILQ_INIT(&pc->ac_references); in acpi_pwr_register_consumer()
246 pc->ac_consumer = consumer; in acpi_pwr_register_consumer()
249 pc->ac_state = ACPI_STATE_UNKNOWN; in acpi_pwr_register_consumer()
251 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "registered power consumer %s\n", in acpi_pwr_register_consumer()
259 * Deregister a power consumer.
261 * This should only be done once the consumer has been powered off.
277 if (TAILQ_FIRST(&pc->ac_references) != NULL) in acpi_pwr_deregister_consumer()
280 /* Pull the consumer off the list and free it */ in acpi_pwr_deregister_consumer()
284 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "deregistered power consumer %s\n", in acpi_pwr_deregister_consumer()
292 * Set a power consumer to a particular power state.
306 /* It's never ok to switch a non-existent consumer. */ in acpi_pwr_switch_consumer()
318 panic("acpi added power consumer but can't find it"); in acpi_pwr_switch_consumer()
321 /* Stop here if we're already at the target D-state. */ in acpi_pwr_switch_consumer()
322 if (pc->ac_state == state) { in acpi_pwr_switch_consumer()
331 * doing these transitions is whether or not the power resources for _PR3 in acpi_pwr_switch_consumer()
332 * are on for devices which support D3cold, and turning these power in acpi_pwr_switch_consumer()
333 * resources on/off is always perfectly fine (ACPI 7.3.11). in acpi_pwr_switch_consumer()
336 if (pc->ac_state == ACPI_STATE_D3_HOT && state != ACPI_STATE_D0 && in acpi_pwr_switch_consumer()
339 if (pc->ac_state == ACPI_STATE_D3_COLD && state != ACPI_STATE_D0 && in acpi_pwr_switch_consumer()
368 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "setup to switch %s %s -> %s\n", in acpi_pwr_switch_consumer()
369 acpi_name(consumer), acpi_d_state_to_str(pc->ac_state), in acpi_pwr_switch_consumer()
389 pc->ac_state = ACPI_STATE_D0; in acpi_pwr_switch_consumer()
403 * Turn off the resources listed in _PR0 to go to D3. If there is in acpi_pwr_switch_consumer()
404 * no _PR0 method, this object doesn't support ACPI power states. in acpi_pwr_switch_consumer()
435 * Check that we can actually fetch the list of power resources in acpi_pwr_switch_consumer()
448 if (reslist_object->Type != ACPI_TYPE_PACKAGE) { in acpi_pwr_switch_consumer()
451 reslist_object->Type)); in acpi_pwr_switch_consumer()
458 * Now we are ready to switch, so kill off any current power in acpi_pwr_switch_consumer()
464 * Add new power resource references, if we have any. Traverse the in acpi_pwr_switch_consumer()
470 reslist_object->Package.Count)); in acpi_pwr_switch_consumer()
488 /* Invoke power state switch method (if present) */ in acpi_pwr_switch_consumer()
495 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "failed to set state - %s\n", in acpi_pwr_switch_consumer()
497 pc->ac_state = ACPI_STATE_UNKNOWN; in acpi_pwr_switch_consumer()
505 pc->ac_state = state; in acpi_pwr_switch_consumer()
515 /* Enable or disable a power resource for wake */
534 panic("acpi wake added power consumer but can't find it"); in acpi_pwr_wake_enable()
555 * Called to create a reference between a power consumer and a power resource
573 "can't create a power reference for object type %d\n", in acpi_pwr_reference_resource()
574 obj->Type)); in acpi_pwr_reference_resource()
581 "couldn't register power resource %s - %s\n", in acpi_pwr_reference_resource()
582 obj->String.Pointer, AcpiFormatException(status))); in acpi_pwr_reference_resource()
586 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "power resource list corrupted\n")); in acpi_pwr_reference_resource()
589 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "found power resource %s\n", in acpi_pwr_reference_resource()
590 acpi_name(rp->ap_resource))); in acpi_pwr_reference_resource()
595 "allocation failed for a power consumer reference\n")); in acpi_pwr_reference_resource()
598 pr->ar_consumer = pc; in acpi_pwr_reference_resource()
599 pr->ar_resource = rp; in acpi_pwr_reference_resource()
600 TAILQ_INSERT_TAIL(&pc->ac_references, pr, ar_clink); in acpi_pwr_reference_resource()
601 TAILQ_INSERT_TAIL(&rp->ap_references, pr, ar_rlink); in acpi_pwr_reference_resource()
616 while ((pr = TAILQ_FIRST(&pc->ac_references)) != NULL) { in acpi_pwr_dereference_resource()
618 acpi_name(pr->ar_resource->ap_resource))); in acpi_pwr_dereference_resource()
619 TAILQ_REMOVE(&pr->ar_resource->ap_references, pr, ar_rlink); in acpi_pwr_dereference_resource()
620 TAILQ_REMOVE(&pc->ac_references, pr, ar_clink); in acpi_pwr_dereference_resource()
629 * Switch power resources to conform to the desired state.
631 * Consumers may have modified the power resource list in an arbitrary
648 if (TAILQ_FIRST(&rp->ap_references) == NULL) { in acpi_pwr_switch_power()
651 acpi_name(rp->ap_resource))); in acpi_pwr_switch_power()
655 status = acpi_GetInteger(rp->ap_resource, "_STA", &cur); in acpi_pwr_switch_power()
657 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "can't get status of %s - %d\n", in acpi_pwr_switch_power()
658 acpi_name(rp->ap_resource), status)); in acpi_pwr_switch_power()
669 status = AcpiEvaluateObject(rp->ap_resource, "_ON", NULL, NULL); in acpi_pwr_switch_power()
672 "failed to switch %s on - %s\n", in acpi_pwr_switch_power()
673 acpi_name(rp->ap_resource), in acpi_pwr_switch_power()
677 acpi_name(rp->ap_resource))); in acpi_pwr_switch_power()
681 acpi_name(rp->ap_resource))); in acpi_pwr_switch_power()
685 /* Sweep the list backwards turning things off. */ in acpi_pwr_switch_power()
688 if (TAILQ_FIRST(&rp->ap_references) != NULL) { in acpi_pwr_switch_power()
690 "%s has references, not turning off\n", in acpi_pwr_switch_power()
691 acpi_name(rp->ap_resource))); in acpi_pwr_switch_power()
695 status = acpi_GetInteger(rp->ap_resource, "_STA", &cur); in acpi_pwr_switch_power()
697 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "can't get status of %s - %d\n", in acpi_pwr_switch_power()
698 acpi_name(rp->ap_resource), status)); in acpi_pwr_switch_power()
709 status = AcpiEvaluateObject(rp->ap_resource, "_OFF", NULL, NULL); in acpi_pwr_switch_power()
712 "failed to switch %s off - %s\n", in acpi_pwr_switch_power()
713 acpi_name(rp->ap_resource), in acpi_pwr_switch_power()
716 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "switched %s off\n", in acpi_pwr_switch_power()
717 acpi_name(rp->ap_resource))); in acpi_pwr_switch_power()
720 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "%s is already off\n", in acpi_pwr_switch_power()
721 acpi_name(rp->ap_resource))); in acpi_pwr_switch_power()
729 * Find a power resource's control structure.
740 if (rp->ap_resource == res) in acpi_pwr_find_resource()
748 * Find a power consumer's control structure.
759 if (pc->ac_consumer == consumer) in acpi_pwr_find_consumer()