From 9ce4e607111764673f7a59d7bc87a16ade5c7bba Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 17 Jan 2013 14:11:08 +0100 Subject: ACPI / PM: Move device power management functions to device_pm.c Move ACPI device power management functions from drivers/acpi/bus.c to drivers/acpi/device_pm.c. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/bus.c | 293 ----------------------------------------------------- 1 file changed, 293 deletions(-) (limited to 'drivers/acpi/bus.c') diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 6c9b16c16660..01708a165368 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -178,299 +178,6 @@ int acpi_bus_get_private_data(acpi_handle handle, void **data) } EXPORT_SYMBOL(acpi_bus_get_private_data); -/* -------------------------------------------------------------------------- - Power Management - -------------------------------------------------------------------------- */ - -/** - * acpi_power_state_string - String representation of ACPI device power state. - * @state: ACPI device power state to return the string representation of. - */ -const char *acpi_power_state_string(int state) -{ - switch (state) { - case ACPI_STATE_D0: - return "D0"; - case ACPI_STATE_D1: - return "D1"; - case ACPI_STATE_D2: - return "D2"; - case ACPI_STATE_D3_HOT: - return "D3hot"; - case ACPI_STATE_D3_COLD: - return "D3"; - default: - return "(unknown)"; - } -} - -/** - * acpi_device_get_power - Get power state of an ACPI device. - * @device: Device to get the power state of. - * @state: Place to store the power state of the device. - * - * This function does not update the device's power.state field, but it may - * update its parent's power.state field (when the parent's power state is - * unknown and the device's power state turns out to be D0). - */ -int acpi_device_get_power(struct acpi_device *device, int *state) -{ - int result = ACPI_STATE_UNKNOWN; - - if (!device || !state) - return -EINVAL; - - 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; - } - - /* - * If we were unsure about the device parent's power state up to this - * point, the fact that the device is in D0 implies that the parent has - * to be in D0 too. - */ - if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN - && result == ACPI_STATE_D0) - device->parent->power.state = ACPI_STATE_D0; - - *state = result; - - out: - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is %s\n", - device->pnp.bus_id, acpi_power_state_string(*state))); - - return 0; -} - - -/** - * acpi_device_set_power - Set power state of an ACPI device. - * @device: Device to set the power state of. - * @state: New power state to set. - * - * Callers must ensure that the device is power manageable before using this - * function. - */ -int acpi_device_set_power(struct acpi_device *device, int state) -{ - int result = 0; - acpi_status status = AE_OK; - char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; - bool cut_power = false; - - if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) - return -EINVAL; - - /* Make sure this is a valid target state */ - - if (state == device->power.state) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at %s\n", - acpi_power_state_string(state))); - return 0; - } - - if (!device->power.states[state].flags.valid) { - printk(KERN_WARNING PREFIX "Device does not support %s\n", - acpi_power_state_string(state)); - return -ENODEV; - } - if (device->parent && (state < device->parent->power.state)) { - printk(KERN_WARNING PREFIX - "Cannot set device to a higher-powered" - " state than parent\n"); - return -ENODEV; - } - - /* For D3cold we should first transition into D3hot. */ - if (state == ACPI_STATE_D3_COLD - && device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible) { - state = ACPI_STATE_D3_HOT; - object_name[3] = '3'; - cut_power = true; - } - - /* - * Transition Power - * ---------------- - * On transitions to a high-powered state we first apply power (via - * power resources) then evalute _PSx. Conversly for transitions to - * a lower-powered state. - */ - if (state < device->power.state) { - if (device->power.state >= ACPI_STATE_D3_HOT && - state != ACPI_STATE_D0) { - printk(KERN_WARNING PREFIX - "Cannot transition to non-D0 state from D3\n"); - return -ENODEV; - } - if (device->power.flags.power_resources) { - result = acpi_power_transition(device, state); - if (result) - goto end; - } - if (device->power.states[state].flags.explicit_set) { - status = acpi_evaluate_object(device->handle, - object_name, NULL, NULL); - if (ACPI_FAILURE(status)) { - result = -ENODEV; - goto end; - } - } - } else { - if (device->power.states[state].flags.explicit_set) { - status = acpi_evaluate_object(device->handle, - object_name, NULL, NULL); - if (ACPI_FAILURE(status)) { - result = -ENODEV; - goto end; - } - } - if (device->power.flags.power_resources) { - result = acpi_power_transition(device, state); - if (result) - goto end; - } - } - - if (cut_power) - result = acpi_power_transition(device, ACPI_STATE_D3_COLD); - - end: - if (result) - printk(KERN_WARNING PREFIX - "Device [%s] failed to transition to %s\n", - device->pnp.bus_id, - acpi_power_state_string(state)); - else { - device->power.state = state; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Device [%s] transitioned to %s\n", - device->pnp.bus_id, - acpi_power_state_string(state))); - } - - return result; -} -EXPORT_SYMBOL(acpi_device_set_power); - - -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; - } - - return acpi_device_set_power(device, state); -} -EXPORT_SYMBOL(acpi_bus_set_power); - - -int acpi_bus_init_power(struct acpi_device *device) -{ - int state; - int result; - - if (!device) - return -EINVAL; - - device->power.state = ACPI_STATE_UNKNOWN; - - result = acpi_device_get_power(device, &state); - if (result) - return result; - - if (device->power.flags.power_resources) - result = acpi_power_on_resources(device, state); - - if (!result) - device->power.state = state; - - return result; -} - - -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_device_get_power(device, &state); - if (result) - return result; - - result = acpi_device_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; - int result; - - result = acpi_bus_get_device(handle, &device); - return result ? false : device->flags.power_manageable; -} - -EXPORT_SYMBOL(acpi_bus_power_manageable); - -bool acpi_bus_can_wakeup(acpi_handle handle) -{ - struct acpi_device *device; - int result; - - result = acpi_bus_get_device(handle, &device); - return result ? false : device->wakeup.flags.valid; -} - -EXPORT_SYMBOL(acpi_bus_can_wakeup); - static void acpi_print_osc_error(acpi_handle handle, struct acpi_osc_context *context, char *error) { -- cgit v1.2.3