summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/power.c91
-rw-r--r--drivers/acpi/scan.c1
-rw-r--r--drivers/acpi/sleep.c2
-rw-r--r--drivers/acpi/sleep.h2
4 files changed, 37 insertions, 59 deletions
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index b12933fd2e56..29803857a2ef 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -58,27 +58,6 @@ ACPI_MODULE_NAME("power");
#define ACPI_POWER_RESOURCE_STATE_ON 0x01
#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
-static inline int acpi_power_add(struct acpi_device *device) { return 0; }
-
-static const struct acpi_device_id power_device_ids[] = {
- {ACPI_POWER_HID, 0},
- {"", 0},
-};
-MODULE_DEVICE_TABLE(acpi, power_device_ids);
-
-#ifdef CONFIG_PM_SLEEP
-static int acpi_power_resume(struct device *dev);
-#endif
-static SIMPLE_DEV_PM_OPS(acpi_power_pm, NULL, acpi_power_resume);
-
-static struct acpi_driver acpi_power_driver = {
- .name = "power",
- .class = ACPI_POWER_CLASS,
- .ids = power_device_ids,
- .ops.add = acpi_power_add,
- .drv.pm = &acpi_power_pm,
-};
-
struct acpi_power_dependent_device {
struct list_head node;
struct acpi_device *adev;
@@ -87,6 +66,7 @@ struct acpi_power_dependent_device {
struct acpi_power_resource {
struct acpi_device device;
+ struct list_head list_node;
struct list_head dependent;
char *name;
u32 system_level;
@@ -95,7 +75,8 @@ struct acpi_power_resource {
struct mutex resource_lock;
};
-static struct list_head acpi_power_resource_list;
+static LIST_HEAD(acpi_power_resource_list);
+static DEFINE_MUTEX(power_resource_list_lock);
/* --------------------------------------------------------------------------
Power Resource Management
@@ -643,8 +624,13 @@ static void acpi_release_power_resource(struct device *dev)
struct acpi_device *device = to_acpi_device(dev);
struct acpi_power_resource *resource;
- acpi_free_ids(device);
resource = container_of(device, struct acpi_power_resource, device);
+
+ mutex_lock(&power_resource_list_lock);
+ list_del(&resource->list_node);
+ mutex_unlock(&power_resource_list_lock);
+
+ acpi_free_ids(device);
kfree(resource);
}
@@ -677,14 +663,14 @@ void acpi_add_power_resource(acpi_handle handle)
/* Evalute the object to get the system level and resource order. */
status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
if (ACPI_FAILURE(status))
- goto out;
+ goto err;
resource->system_level = acpi_object.power_resource.system_level;
resource->order = acpi_object.power_resource.resource_order;
result = acpi_power_get_state(handle, &state);
if (result)
- goto out;
+ goto err;
switch (state) {
case ACPI_POWER_RESOURCE_STATE_ON:
@@ -702,51 +688,40 @@ void acpi_add_power_resource(acpi_handle handle)
device->flags.match_driver = true;
result = acpi_device_register(device, acpi_release_power_resource);
-
- out:
if (result)
- acpi_release_power_resource(&device->dev);
+ goto err;
+ mutex_lock(&power_resource_list_lock);
+ list_add(&resource->list_node, &acpi_power_resource_list);
+ mutex_unlock(&power_resource_list_lock);
return;
-}
-/* --------------------------------------------------------------------------
- Driver Interface
- -------------------------------------------------------------------------- */
+ err:
+ acpi_release_power_resource(&device->dev);
+}
-#ifdef CONFIG_PM_SLEEP
-static int acpi_power_resume(struct device *dev)
+#ifdef CONFIG_ACPI_SLEEP
+void acpi_resume_power_resources(void)
{
- int result = 0, state;
- struct acpi_device *device;
struct acpi_power_resource *resource;
- if (!dev)
- return -EINVAL;
+ mutex_lock(&power_resource_list_lock);
- device = to_acpi_device(dev);
- resource = acpi_driver_data(device);
- if (!resource)
- return -EINVAL;
-
- mutex_lock(&resource->resource_lock);
+ list_for_each_entry(resource, &acpi_power_resource_list, list_node) {
+ int result, state;
- result = acpi_power_get_state(device->handle, &state);
- if (result)
- goto unlock;
+ mutex_lock(&resource->resource_lock);
- if (state == ACPI_POWER_RESOURCE_STATE_OFF && resource->ref_count)
- result = __acpi_power_on(resource);
+ result = acpi_power_get_state(resource->device.handle, &state);
+ if (!result && state == ACPI_POWER_RESOURCE_STATE_OFF
+ && resource->ref_count) {
+ dev_info(&resource->device.dev, "Turning ON\n");
+ __acpi_power_on(resource);
+ }
- unlock:
- mutex_unlock(&resource->resource_lock);
+ mutex_unlock(&resource->resource_lock);
+ }
- return result;
+ mutex_unlock(&power_resource_list_lock);
}
#endif
-
-int __init acpi_power_init(void)
-{
- INIT_LIST_HEAD(&acpi_power_resource_list);
- return acpi_bus_register_driver(&acpi_power_driver);
-}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 952b08af91de..c7ea9c2649a4 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1636,7 +1636,6 @@ int __init acpi_scan_init(void)
printk(KERN_ERR PREFIX "Could not register bus type\n");
}
- acpi_power_init();
acpi_pci_root_init();
/*
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 2fcc67d34b11..4ef0328579cc 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -386,6 +386,8 @@ static void acpi_pm_finish(void)
acpi_target_sleep_state = ACPI_STATE_S0;
+ acpi_resume_power_resources();
+
/* If we were woken with the fixed power button, provide a small
* hint to userspace in the form of a wakeup event on the fixed power
* button device (if it can be found).
diff --git a/drivers/acpi/sleep.h b/drivers/acpi/sleep.h
index 74d59c8f4678..0143540a2519 100644
--- a/drivers/acpi/sleep.h
+++ b/drivers/acpi/sleep.h
@@ -6,3 +6,5 @@ extern void acpi_disable_wakeup_devices(u8 sleep_state);
extern struct list_head acpi_wakeup_device_list;
extern struct mutex acpi_device_lock;
+
+extern void acpi_resume_power_resources(void);