static int acpi_power_get_list_state ( struct acpi_handle_list *list, int *state) { int result = 0; struct acpi_power_resource *resource = NULL; u32 i = 0; ACPI_FUNCTION_TRACE("acpi_power_get_list_state"); if (!list || !state) return_VALUE(-EINVAL); /* The state of the list is 'on' IFF all resources are 'on'. */ for (i=0; i<list->count; i++) { result = acpi_power_get_context(list->handles[i], &resource); if (result) return_VALUE(result); result = acpi_power_get_state(resource); if (result) return_VALUE(result); *state = resource->state; if (*state != ACPI_POWER_RESOURCE_STATE_ON) break; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n", *state?"on":"off")); return_VALUE(result); }
static int acpi_power_resume(struct acpi_device *device) { int result = 0, state; struct acpi_power_resource *resource; if (!device) return -EINVAL; resource = acpi_driver_data(device); if (!resource) return -EINVAL; mutex_lock(&resource->resource_lock); result = acpi_power_get_state(device->handle, &state); if (result) goto unlock; if (state == ACPI_POWER_RESOURCE_STATE_OFF && resource->ref_count) result = __acpi_power_on(resource); unlock: mutex_unlock(&resource->resource_lock); return result; }
static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) { int result = 0, state1; u32 i = 0; if (!list || !state) return -EINVAL; /* The state of the list is 'on' IFF all resources are 'on'. */ for (i = 0; i < list->count; i++) { /* * The state of the power resource can be obtained by * using the ACPI handle. In such case it is unnecessary to * get the Power resource first and then get its state again. */ result = acpi_power_get_state(list->handles[i], &state1); if (result) return result; *state = state1; if (*state != ACPI_POWER_RESOURCE_STATE_ON) break; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n", *state ? "on" : "off")); return result; }
static int acpi_power_add(struct acpi_device *device) { int result = 0, state; acpi_status status = AE_OK; struct acpi_power_resource *resource = NULL; union acpi_object acpi_object; struct acpi_buffer buffer = { sizeof(acpi_object), &acpi_object }; if (!device) return -EINVAL; resource = kzalloc(sizeof(struct acpi_power_resource), GFP_KERNEL); if (!resource) return -ENOMEM; resource->device = device; mutex_init(&resource->resource_lock); mutex_init(&resource->devices_lock); strcpy(resource->name, device->pnp.bus_id); strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_POWER_CLASS); device->driver_data = resource; /* Evalute the object to get the system level and resource order. */ status = acpi_evaluate_object(device->handle, NULL, NULL, &buffer); if (ACPI_FAILURE(status)) { result = -ENODEV; goto end; } resource->system_level = acpi_object.power_resource.system_level; resource->order = acpi_object.power_resource.resource_order; result = acpi_power_get_state(device->handle, &state); if (result) goto end; switch (state) { case ACPI_POWER_RESOURCE_STATE_ON: device->power.state = ACPI_STATE_D0; break; case ACPI_POWER_RESOURCE_STATE_OFF: device->power.state = ACPI_STATE_D3; break; default: device->power.state = ACPI_STATE_UNKNOWN; break; } printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), acpi_device_bid(device), state ? "on" : "off"); end: if (result) kfree(resource); return result; }
static int acpi_power_off_device ( acpi_handle handle) { int result = 0; acpi_status status = AE_OK; struct acpi_device *device = NULL; struct acpi_power_resource *resource = NULL; ACPI_FUNCTION_TRACE("acpi_power_off_device"); result = acpi_power_get_context(handle, &resource); if (result) return_VALUE(result); if (resource->references) resource->references--; if (resource->references) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is still in use, dereferencing\n", device->pnp.bus_id)); return_VALUE(0); } if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n", device->pnp.bus_id)); return_VALUE(0); } status = acpi_evaluate_object(resource->handle, "_OFF", NULL, NULL); if (ACPI_FAILURE(status)) return_VALUE(-ENODEV); result = acpi_power_get_state(resource); if (result) return_VALUE(result); if (resource->state != ACPI_POWER_RESOURCE_STATE_OFF) return_VALUE(-ENOEXEC); /* Update the power resource's _device_ power state */ result = acpi_bus_get_device(resource->handle, &device); if (result) return_VALUE(result); device->power.state = ACPI_STATE_D3; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned off\n", resource->name)); return_VALUE(0); }
static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state) { int cur_state; int i = 0; if (!list || !state) return -EINVAL; /* The state of the list is 'on' IFF all resources are 'on'. */ for (i = 0; i < list->count; i++) { struct acpi_power_resource *resource; acpi_handle handle = list->handles[i]; int result; result = acpi_power_get_context(handle, &resource); if (result) return result; mutex_lock(&resource->resource_lock); result = acpi_power_get_state(handle, &cur_state); mutex_unlock(&resource->resource_lock); if (result) return result; if (cur_state != ACPI_POWER_RESOURCE_STATE_ON) break; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource list is %s\n", cur_state ? "on" : "off")); *state = cur_state; return 0; }
int acpi_power_add ( struct acpi_device *device) { int result = 0; acpi_status status = AE_OK; struct acpi_power_resource *resource = NULL; union acpi_object acpi_object; struct acpi_buffer buffer = {sizeof(acpi_object), &acpi_object}; ACPI_FUNCTION_TRACE("acpi_power_add"); if (!device) return_VALUE(-EINVAL); resource = kmalloc(sizeof(struct acpi_power_resource), GFP_KERNEL); if (!resource) return_VALUE(-ENOMEM); memset(resource, 0, sizeof(struct acpi_power_resource)); resource->handle = device->handle; sprintf(resource->name, "%s", device->pnp.bus_id); sprintf(acpi_device_name(device), "%s", ACPI_POWER_DEVICE_NAME); sprintf(acpi_device_class(device), "%s", ACPI_POWER_CLASS); acpi_driver_data(device) = resource; /* Evalute the object to get the system level and resource order. */ status = acpi_evaluate_object(resource->handle, NULL, NULL, &buffer); if (ACPI_FAILURE(status)) { result = -ENODEV; goto end; } resource->system_level = acpi_object.power_resource.system_level; resource->order = acpi_object.power_resource.resource_order; result = acpi_power_get_state(resource); if (result) goto end; switch (resource->state) { case ACPI_POWER_RESOURCE_STATE_ON: device->power.state = ACPI_STATE_D0; break; case ACPI_POWER_RESOURCE_STATE_OFF: device->power.state = ACPI_STATE_D3; break; default: device->power.state = ACPI_STATE_UNKNOWN; break; } result = acpi_power_add_fs(device); if (result) goto end; printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device), acpi_device_bid(device), resource->state?"on":"off"); end: if (result) kfree(resource); return_VALUE(result); }