diff options
Diffstat (limited to 'drivers/acpi/power.c')
-rw-r--r-- | drivers/acpi/power.c | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index e0bcfb642b52..93eac53b5110 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -684,7 +684,8 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state) | |||
684 | } | 684 | } |
685 | } | 685 | } |
686 | 686 | ||
687 | *state = ACPI_STATE_D3_COLD; | 687 | *state = device->power.states[ACPI_STATE_D3_COLD].flags.valid ? |
688 | ACPI_STATE_D3_COLD : ACPI_STATE_D3_HOT; | ||
688 | return 0; | 689 | return 0; |
689 | } | 690 | } |
690 | 691 | ||
@@ -710,8 +711,6 @@ int acpi_power_transition(struct acpi_device *device, int state) | |||
710 | || (device->power.state > ACPI_STATE_D3_COLD)) | 711 | || (device->power.state > ACPI_STATE_D3_COLD)) |
711 | return -ENODEV; | 712 | return -ENODEV; |
712 | 713 | ||
713 | /* TBD: Resources must be ordered. */ | ||
714 | |||
715 | /* | 714 | /* |
716 | * First we reference all power resources required in the target list | 715 | * First we reference all power resources required in the target list |
717 | * (e.g. so the device doesn't lose power while transitioning). Then, | 716 | * (e.g. so the device doesn't lose power while transitioning). Then, |
@@ -761,6 +760,25 @@ static void acpi_power_sysfs_remove(struct acpi_device *device) | |||
761 | device_remove_file(&device->dev, &dev_attr_resource_in_use); | 760 | device_remove_file(&device->dev, &dev_attr_resource_in_use); |
762 | } | 761 | } |
763 | 762 | ||
763 | static void acpi_power_add_resource_to_list(struct acpi_power_resource *resource) | ||
764 | { | ||
765 | mutex_lock(&power_resource_list_lock); | ||
766 | |||
767 | if (!list_empty(&acpi_power_resource_list)) { | ||
768 | struct acpi_power_resource *r; | ||
769 | |||
770 | list_for_each_entry(r, &acpi_power_resource_list, list_node) | ||
771 | if (r->order > resource->order) { | ||
772 | list_add_tail(&resource->list_node, &r->list_node); | ||
773 | goto out; | ||
774 | } | ||
775 | } | ||
776 | list_add_tail(&resource->list_node, &acpi_power_resource_list); | ||
777 | |||
778 | out: | ||
779 | mutex_unlock(&power_resource_list_lock); | ||
780 | } | ||
781 | |||
764 | int acpi_add_power_resource(acpi_handle handle) | 782 | int acpi_add_power_resource(acpi_handle handle) |
765 | { | 783 | { |
766 | struct acpi_power_resource *resource; | 784 | struct acpi_power_resource *resource; |
@@ -811,9 +829,7 @@ int acpi_add_power_resource(acpi_handle handle) | |||
811 | if (!device_create_file(&device->dev, &dev_attr_resource_in_use)) | 829 | if (!device_create_file(&device->dev, &dev_attr_resource_in_use)) |
812 | device->remove = acpi_power_sysfs_remove; | 830 | device->remove = acpi_power_sysfs_remove; |
813 | 831 | ||
814 | mutex_lock(&power_resource_list_lock); | 832 | acpi_power_add_resource_to_list(resource); |
815 | list_add(&resource->list_node, &acpi_power_resource_list); | ||
816 | mutex_unlock(&power_resource_list_lock); | ||
817 | acpi_device_add_finalize(device); | 833 | acpi_device_add_finalize(device); |
818 | return 0; | 834 | return 0; |
819 | 835 | ||
@@ -844,7 +860,22 @@ void acpi_resume_power_resources(void) | |||
844 | && resource->ref_count) { | 860 | && resource->ref_count) { |
845 | dev_info(&resource->device.dev, "Turning ON\n"); | 861 | dev_info(&resource->device.dev, "Turning ON\n"); |
846 | __acpi_power_on(resource); | 862 | __acpi_power_on(resource); |
847 | } else if (state == ACPI_POWER_RESOURCE_STATE_ON | 863 | } |
864 | |||
865 | mutex_unlock(&resource->resource_lock); | ||
866 | } | ||
867 | list_for_each_entry_reverse(resource, &acpi_power_resource_list, list_node) { | ||
868 | int result, state; | ||
869 | |||
870 | mutex_lock(&resource->resource_lock); | ||
871 | |||
872 | result = acpi_power_get_state(resource->device.handle, &state); | ||
873 | if (result) { | ||
874 | mutex_unlock(&resource->resource_lock); | ||
875 | continue; | ||
876 | } | ||
877 | |||
878 | if (state == ACPI_POWER_RESOURCE_STATE_ON | ||
848 | && !resource->ref_count) { | 879 | && !resource->ref_count) { |
849 | dev_info(&resource->device.dev, "Turning OFF\n"); | 880 | dev_info(&resource->device.dev, "Turning OFF\n"); |
850 | __acpi_power_off(resource); | 881 | __acpi_power_off(resource); |