History

ACPI / LPSS: Power up LPSS devices during enumeration

Commit 7cd8407 (ACPI / PM: Do not execute _PS0 for devices without _PSC during initialization) introduced a regression on some systems with Intel Lynxpoint Low-Power Subsystem (LPSS) where some devices need to be powered up during initialization, but their device objects in the ACPI namespace have _PS0 and _PS3 only (without _PSC or power resources). To work around this problem, make the ACPI LPSS driver power up devices it knows about by using a new helper function acpi_device_fix_up_power() that does all of the necessary sanity checks and calls acpi_dev_pm_explicit_set() to put the device into D0.

Rafael J. Wysocki committed 13 years ago

Commit b9e95fc1 parent 6ee22e93 files · +36 −6Browse files

Unified · Split

3 files
  1. drivers/acpi/acpi_lpss.c +15 −6
  2. drivers/acpi/device_pm.c +20 −0
  3. include/acpi/acpi_bus.h +1 −0
drivers/acpi/acpi_lpss.c+15−6
@@ -164,15 +164,24 @@ static int acpi_lpss_create_device(struct acpi_device *adev, · 163 unmodified lines
164 if (dev_desc->clk_required) {164 if (dev_desc->clk_required) {
165 ret = register_device_clock(adev, pdata);165 ret = register_device_clock(adev, pdata);
166 if (ret) {166 if (ret) {
167 /*167 /* Skip the device, but continue the namespace scan. */
168 * Skip the device, but don't terminate the namespace168 ret = 0;
169 * scan.169 goto err_out;
170 */
171 kfree(pdata);
172 return 0;
173 }170 }
174 }171 }
175 172
173 /*
174 * This works around a known issue in ACPI tables where LPSS devices
175 * have _PS0 and _PS3 without _PSC (and no power resources), so
176 * acpi_bus_init_power() will assume that the BIOS has put them into D0.
177 */
178 ret = acpi_device_fix_up_power(adev);
179 if (ret) {
180 /* Skip the device, but continue the namespace scan. */
181 ret = 0;
182 goto err_out;
183 }
184
176 adev->driver_data = pdata;185 adev->driver_data = pdata;
177 ret = acpi_create_platform_device(adev, id);186 ret = acpi_create_platform_device(adev, id);
178 if (ret > 0)187 if (ret > 0)
drivers/acpi/device_pm.c+20−0
@@ -290,6 +290,26 @@ int acpi_bus_init_power(struct acpi_device *device) · 289 unmodified lines
290 return 0;290 return 0;
291}291}
292 292
293/**
294 * acpi_device_fix_up_power - Force device with missing _PSC into D0.
295 * @device: Device object whose power state is to be fixed up.
296 *
297 * Devices without power resources and _PSC, but having _PS0 and _PS3 defined,
298 * are assumed to be put into D0 by the BIOS. However, in some cases that may
299 * not be the case and this function should be used then.
300 */
301int acpi_device_fix_up_power(struct acpi_device *device)
302{
303 int ret = 0;
304
305 if (!device->power.flags.power_resources
306 && !device->power.flags.explicit_get
307 && device->power.state == ACPI_STATE_D0)
308 ret = acpi_dev_pm_explicit_set(device, ACPI_STATE_D0);
309
310 return ret;
311}
312
293int acpi_bus_update_power(acpi_handle handle, int *state_p)313int acpi_bus_update_power(acpi_handle handle, int *state_p)
294{314{
295 struct acpi_device *device;315 struct acpi_device *device;
include/acpi/acpi_bus.h+1−0
@@ -382,6 +382,7 @@ const char *acpi_power_state_string(int state); · 381 unmodified lines
382int acpi_device_get_power(struct acpi_device *device, int *state);382int acpi_device_get_power(struct acpi_device *device, int *state);
383int acpi_device_set_power(struct acpi_device *device, int state);383int acpi_device_set_power(struct acpi_device *device, int state);
384int acpi_bus_init_power(struct acpi_device *device);384int acpi_bus_init_power(struct acpi_device *device);
385int acpi_device_fix_up_power(struct acpi_device *device);
385int acpi_bus_update_power(acpi_handle handle, int *state_p);386int acpi_bus_update_power(acpi_handle handle, int *state_p);
386bool acpi_bus_power_manageable(acpi_handle handle);387bool acpi_bus_power_manageable(acpi_handle handle);
387 388