aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/power.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/power.c')
-rw-r--r--drivers/acpi/power.c91
1 files changed, 33 insertions, 58 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");
58#define ACPI_POWER_RESOURCE_STATE_ON 0x01 58#define ACPI_POWER_RESOURCE_STATE_ON 0x01
59#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF 59#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
60 60
61static inline int acpi_power_add(struct acpi_device *device) { return 0; }
62
63static const struct acpi_device_id power_device_ids[] = {
64 {ACPI_POWER_HID, 0},
65 {"", 0},
66};
67MODULE_DEVICE_TABLE(acpi, power_device_ids);
68
69#ifdef CONFIG_PM_SLEEP
70static int acpi_power_resume(struct device *dev);
71#endif
72static SIMPLE_DEV_PM_OPS(acpi_power_pm, NULL, acpi_power_resume);
73
74static struct acpi_driver acpi_power_driver = {
75 .name = "power",
76 .class = ACPI_POWER_CLASS,
77 .ids = power_device_ids,
78 .ops.add = acpi_power_add,
79 .drv.pm = &acpi_power_pm,
80};
81
82struct acpi_power_dependent_device { 61struct acpi_power_dependent_device {
83 struct list_head node; 62 struct list_head node;
84 struct acpi_device *adev; 63 struct acpi_device *adev;
@@ -87,6 +66,7 @@ struct acpi_power_dependent_device {
87 66
88struct acpi_power_resource { 67struct acpi_power_resource {
89 struct acpi_device device; 68 struct acpi_device device;
69 struct list_head list_node;
90 struct list_head dependent; 70 struct list_head dependent;
91 char *name; 71 char *name;
92 u32 system_level; 72 u32 system_level;
@@ -95,7 +75,8 @@ struct acpi_power_resource {
95 struct mutex resource_lock; 75 struct mutex resource_lock;
96}; 76};
97 77
98static struct list_head acpi_power_resource_list; 78static LIST_HEAD(acpi_power_resource_list);
79static DEFINE_MUTEX(power_resource_list_lock);
99 80
100/* -------------------------------------------------------------------------- 81/* --------------------------------------------------------------------------
101 Power Resource Management 82 Power Resource Management
@@ -643,8 +624,13 @@ static void acpi_release_power_resource(struct device *dev)
643 struct acpi_device *device = to_acpi_device(dev); 624 struct acpi_device *device = to_acpi_device(dev);
644 struct acpi_power_resource *resource; 625 struct acpi_power_resource *resource;
645 626
646 acpi_free_ids(device);
647 resource = container_of(device, struct acpi_power_resource, device); 627 resource = container_of(device, struct acpi_power_resource, device);
628
629 mutex_lock(&power_resource_list_lock);
630 list_del(&resource->list_node);
631 mutex_unlock(&power_resource_list_lock);
632
633 acpi_free_ids(device);
648 kfree(resource); 634 kfree(resource);
649} 635}
650 636
@@ -677,14 +663,14 @@ void acpi_add_power_resource(acpi_handle handle)
677 /* Evalute the object to get the system level and resource order. */ 663 /* Evalute the object to get the system level and resource order. */
678 status = acpi_evaluate_object(handle, NULL, NULL, &buffer); 664 status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
679 if (ACPI_FAILURE(status)) 665 if (ACPI_FAILURE(status))
680 goto out; 666 goto err;
681 667
682 resource->system_level = acpi_object.power_resource.system_level; 668 resource->system_level = acpi_object.power_resource.system_level;
683 resource->order = acpi_object.power_resource.resource_order; 669 resource->order = acpi_object.power_resource.resource_order;
684 670
685 result = acpi_power_get_state(handle, &state); 671 result = acpi_power_get_state(handle, &state);
686 if (result) 672 if (result)
687 goto out; 673 goto err;
688 674
689 switch (state) { 675 switch (state) {
690 case ACPI_POWER_RESOURCE_STATE_ON: 676 case ACPI_POWER_RESOURCE_STATE_ON:
@@ -702,51 +688,40 @@ void acpi_add_power_resource(acpi_handle handle)
702 688
703 device->flags.match_driver = true; 689 device->flags.match_driver = true;
704 result = acpi_device_register(device, acpi_release_power_resource); 690 result = acpi_device_register(device, acpi_release_power_resource);
705
706 out:
707 if (result) 691 if (result)
708 acpi_release_power_resource(&device->dev); 692 goto err;
709 693
694 mutex_lock(&power_resource_list_lock);
695 list_add(&resource->list_node, &acpi_power_resource_list);
696 mutex_unlock(&power_resource_list_lock);
710 return; 697 return;
711}
712 698
713/* -------------------------------------------------------------------------- 699 err:
714 Driver Interface 700 acpi_release_power_resource(&device->dev);
715 -------------------------------------------------------------------------- */ 701}
716 702
717#ifdef CONFIG_PM_SLEEP 703#ifdef CONFIG_ACPI_SLEEP
718static int acpi_power_resume(struct device *dev) 704void acpi_resume_power_resources(void)
719{ 705{
720 int result = 0, state;
721 struct acpi_device *device;
722 struct acpi_power_resource *resource; 706 struct acpi_power_resource *resource;
723 707
724 if (!dev) 708 mutex_lock(&power_resource_list_lock);
725 return -EINVAL;
726 709
727 device = to_acpi_device(dev); 710 list_for_each_entry(resource, &acpi_power_resource_list, list_node) {
728 resource = acpi_driver_data(device); 711 int result, state;
729 if (!resource)
730 return -EINVAL;
731
732 mutex_lock(&resource->resource_lock);
733 712
734 result = acpi_power_get_state(device->handle, &state); 713 mutex_lock(&resource->resource_lock);
735 if (result)
736 goto unlock;
737 714
738 if (state == ACPI_POWER_RESOURCE_STATE_OFF && resource->ref_count) 715 result = acpi_power_get_state(resource->device.handle, &state);
739 result = __acpi_power_on(resource); 716 if (!result && state == ACPI_POWER_RESOURCE_STATE_OFF
717 && resource->ref_count) {
718 dev_info(&resource->device.dev, "Turning ON\n");
719 __acpi_power_on(resource);
720 }
740 721
741 unlock: 722 mutex_unlock(&resource->resource_lock);
742 mutex_unlock(&resource->resource_lock); 723 }
743 724
744 return result; 725 mutex_unlock(&power_resource_list_lock);
745} 726}
746#endif 727#endif
747
748int __init acpi_power_init(void)
749{
750 INIT_LIST_HEAD(&acpi_power_resource_list);
751 return acpi_bus_register_driver(&acpi_power_driver);
752}