aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/power.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-17 08:11:06 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-01-17 08:11:06 -0500
commit781d737c7466845035e5ce02885c7436b5278b90 (patch)
tree74b21fe070ac2899b3c5a3a9c612db655b4a1d60 /drivers/acpi/power.c
parent82c7d5efaadf99fb4a26500cd5b59b6fd7659772 (diff)
ACPI: Drop power resources driver
The ACPI power resources driver is not very useful, because the only thing it really does is to restore the state of the power resources that were "on" before system suspend or hibernation, but that may be achieved in a different way. Drop the ACPI power resources driver entirely and add acpi_resume_power_resources() that will walk the list of all registered power resources during system resume and turn on the ones that were "on" before the preceding system suspend or hibernation. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
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}