Commit d2ef555b authored by Rafael J. Wysocki's avatar Rafael J. Wysocki Committed by Len Brown

ACPI / PM: Add functions for manipulating lists of power resources

ACPI device power resources should be reference counted during
device initialization, so that their reference counters are always
up to date.  It is convenient to do that with the help of a function
that will reference count and possibly turn on power resources in
a given list, so introduce that function, acpi_power_on_list().
For symmetry, introduce acpi_power_off_list() for performing the
reverse operation and use the both of them to simplify
acpi_power_transition().
Signed-off-by: default avatarRafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 32a00d27
...@@ -266,6 +266,35 @@ static int acpi_power_off_device(acpi_handle handle) ...@@ -266,6 +266,35 @@ static int acpi_power_off_device(acpi_handle handle)
return result; return result;
} }
static void __acpi_power_off_list(struct acpi_handle_list *list, int num_res)
{
int i;
for (i = num_res - 1; i >= 0 ; i--)
acpi_power_off_device(list->handles[i]);
}
static void acpi_power_off_list(struct acpi_handle_list *list)
{
__acpi_power_off_list(list, list->count);
}
static int acpi_power_on_list(struct acpi_handle_list *list)
{
int result = 0;
int i;
for (i = 0; i < list->count; i++) {
result = acpi_power_on(list->handles[i]);
if (result) {
__acpi_power_off_list(list, i);
break;
}
}
return result;
}
/** /**
* acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in
* ACPI 3.0) _PSW (Power State Wake) * ACPI 3.0) _PSW (Power State Wake)
...@@ -458,10 +487,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state) ...@@ -458,10 +487,7 @@ int acpi_power_get_inferred_state(struct acpi_device *device, int *state)
int acpi_power_transition(struct acpi_device *device, int state) int acpi_power_transition(struct acpi_device *device, int state)
{ {
int result = 0; int result;
struct acpi_handle_list *cl = NULL; /* Current Resources */
struct acpi_handle_list *tl = NULL; /* Target Resources */
int i = 0;
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
return -EINVAL; return -EINVAL;
...@@ -473,37 +499,20 @@ int acpi_power_transition(struct acpi_device *device, int state) ...@@ -473,37 +499,20 @@ int acpi_power_transition(struct acpi_device *device, int state)
|| (device->power.state > ACPI_STATE_D3)) || (device->power.state > ACPI_STATE_D3))
return -ENODEV; return -ENODEV;
cl = &device->power.states[device->power.state].resources;
tl = &device->power.states[state].resources;
/* TBD: Resources must be ordered. */ /* TBD: Resources must be ordered. */
/* /*
* First we reference all power resources required in the target list * First we reference all power resources required in the target list
* (e.g. so the device doesn't lose power while transitioning). * (e.g. so the device doesn't lose power while transitioning). Then,
* we dereference all power resources used in the current list.
*/ */
for (i = 0; i < tl->count; i++) { result = acpi_power_on_list(&device->power.states[state].resources);
result = acpi_power_on(tl->handles[i]); if (!result)
if (result) acpi_power_off_list(
goto end; &device->power.states[device->power.state].resources);
}
/* /* We shouldn't change the state unless the above operations succeed. */
* Then we dereference all power resources used in the current list. device->power.state = result ? ACPI_STATE_UNKNOWN : state;
*/
for (i = 0; i < cl->count; i++) {
result = acpi_power_off_device(cl->handles[i]);
if (result)
goto end;
}
end:
if (result)
device->power.state = ACPI_STATE_UNKNOWN;
else {
/* We shouldn't change the state till all above operations succeed */
device->power.state = state;
}
return result; return result;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment