提交 ff0c4194 编写于 作者: R Rafael J. Wysocki

ACPI / PM: Change the way power transitions to D3cold are carried out

During power transitions into D3cold from any shallower power states
we are supposed to transition the device into D3hot and remove power
from it afterward, but the current code in acpi_device_set_power()
doesn't work this way.

At the same time, though, we need to be careful enough to preserve
backwards compatibility for systems that don't distinguish between
D3hot and D3cold (e.g. designed before ACPI 4).

Modify acpi_device_set_power() so that it works in accordance with
the expectations in both cases.
Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
上级 0596a52b
...@@ -270,6 +270,7 @@ int acpi_device_set_power(struct acpi_device *device, int state) ...@@ -270,6 +270,7 @@ int acpi_device_set_power(struct acpi_device *device, int state)
int result = 0; int result = 0;
acpi_status status = AE_OK; acpi_status status = AE_OK;
char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
bool cut_power = false;
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD)) if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
return -EINVAL; return -EINVAL;
...@@ -294,9 +295,13 @@ int acpi_device_set_power(struct acpi_device *device, int state) ...@@ -294,9 +295,13 @@ int acpi_device_set_power(struct acpi_device *device, int state)
return -ENODEV; return -ENODEV;
} }
/* For D3cold we should execute _PS3, not _PS4. */ /* For D3cold we should first transition into D3hot. */
if (state == ACPI_STATE_D3_COLD) if (state == ACPI_STATE_D3_COLD
&& device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible) {
state = ACPI_STATE_D3_HOT;
object_name[3] = '3'; object_name[3] = '3';
cut_power = true;
}
/* /*
* Transition Power * Transition Power
...@@ -341,6 +346,9 @@ int acpi_device_set_power(struct acpi_device *device, int state) ...@@ -341,6 +346,9 @@ int acpi_device_set_power(struct acpi_device *device, int state)
} }
} }
if (cut_power)
result = acpi_power_transition(device, ACPI_STATE_D3_COLD);
end: end:
if (result) if (result)
printk(KERN_WARNING PREFIX printk(KERN_WARNING PREFIX
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册