Message ID | 4199592.UtrPOv3ZmA@kreacher (mailing list archive) |
---|---|
State | Mainlined, archived |
Commit | 42787ed79638dc7f0f8d5c164caba1e87bfab50f |
Headers | show |
Series | ACPI: PM: Fix regression in acpi_device_set_power() | expand |
at 07:31, Rafael J. Wysocki <rjw@rjwysocki.net> wrote: > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > Commit f850a48a0799 ("ACPI: PM: Allow transitions to D0 to occur in > special cases") overlooked the fact that acpi_power_transition() may > change the power.state value for the target device and if that > happens, it may confuse acpi_device_set_power() and cause it to > omit the _PS0 evaluation which on some systems is necessary to > change power states of devices from low-power to D0. > > Fix that by saving the current value of power.state for the > target device before passing it to acpi_power_transition() and > using the saved value in a subsequent check. > > Fixes: f850a48a0799 ("ACPI: PM: Allow transitions to D0 to occur in > special cases") > Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com> > Reported-by: Mario Limonciello <mario.limonciello@dell.com> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com> > --- > drivers/acpi/device_pm.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > Index: linux-pm/drivers/acpi/device_pm.c > =================================================================== > --- linux-pm.orig/drivers/acpi/device_pm.c > +++ linux-pm/drivers/acpi/device_pm.c > @@ -236,13 +236,15 @@ int acpi_device_set_power(struct acpi_de > if (device->power.flags.power_resources) > result = acpi_power_transition(device, target_state); > } else { > + int cur_state = device->power.state; > + > if (device->power.flags.power_resources) { > result = acpi_power_transition(device, ACPI_STATE_D0); > if (result) > goto end; > } > > - if (device->power.state == ACPI_STATE_D0) { > + if (cur_state == ACPI_STATE_D0) { > int psc; > > /* Nothing to do here if _PSC is not present. */
> -----Original Message----- > From: Kai-Heng Feng <kai.heng.feng@canonical.com> > Sent: Thursday, August 1, 2019 1:11 AM > To: Rafael J. Wysocki > Cc: Linux ACPI; Linux PM; Linux PCI; LKML; Mika Westerberg; Bjorn Helgaas; > Limonciello, Mario > Subject: Re: [PATCH] ACPI: PM: Fix regression in acpi_device_set_power() > > > at 07:31, Rafael J. Wysocki <rjw@rjwysocki.net> wrote: > > > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > > > Commit f850a48a0799 ("ACPI: PM: Allow transitions to D0 to occur in > > special cases") overlooked the fact that acpi_power_transition() may > > change the power.state value for the target device and if that > > happens, it may confuse acpi_device_set_power() and cause it to > > omit the _PS0 evaluation which on some systems is necessary to > > change power states of devices from low-power to D0. > > > > Fix that by saving the current value of power.state for the > > target device before passing it to acpi_power_transition() and > > using the saved value in a subsequent check. > > > > Fixes: f850a48a0799 ("ACPI: PM: Allow transitions to D0 to occur in > > special cases") > > Reported-by: Kai-Heng Feng <kai.heng.feng@canonical.com> > > Reported-by: Mario Limonciello <mario.limonciello@dell.com> > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com> Tested-by: Mario Limonciello <mario.limonciello@dell.com> > > > --- > > drivers/acpi/device_pm.c | 4 +++- > > 1 file changed, 3 insertions(+), 1 deletion(-) > > > > Index: linux-pm/drivers/acpi/device_pm.c > > > ============================================================== > ===== > > --- linux-pm.orig/drivers/acpi/device_pm.c > > +++ linux-pm/drivers/acpi/device_pm.c > > @@ -236,13 +236,15 @@ int acpi_device_set_power(struct acpi_de > > if (device->power.flags.power_resources) > > result = acpi_power_transition(device, target_state); > > } else { > > + int cur_state = device->power.state; > > + > > if (device->power.flags.power_resources) { > > result = acpi_power_transition(device, ACPI_STATE_D0); > > if (result) > > goto end; > > } > > > > - if (device->power.state == ACPI_STATE_D0) { > > + if (cur_state == ACPI_STATE_D0) { > > int psc; > > > > /* Nothing to do here if _PSC is not present. */ >
Index: linux-pm/drivers/acpi/device_pm.c =================================================================== --- linux-pm.orig/drivers/acpi/device_pm.c +++ linux-pm/drivers/acpi/device_pm.c @@ -236,13 +236,15 @@ int acpi_device_set_power(struct acpi_de if (device->power.flags.power_resources) result = acpi_power_transition(device, target_state); } else { + int cur_state = device->power.state; + if (device->power.flags.power_resources) { result = acpi_power_transition(device, ACPI_STATE_D0); if (result) goto end; } - if (device->power.state == ACPI_STATE_D0) { + if (cur_state == ACPI_STATE_D0) { int psc; /* Nothing to do here if _PSC is not present. */