> -----Original Message----- > From: Kai-Heng Feng <kai.heng.feng@xxxxxxxxxxxxx> > 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@xxxxxxxxxxxxx> wrote: > > > From: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > > > > 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@xxxxxxxxxxxxx> > > Reported-by: Mario Limonciello <mario.limonciello@xxxxxxxx> > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@xxxxxxxxx> > > Tested-by: Kai-Heng Feng <kai.heng.feng@xxxxxxxxxxxxx> Tested-by: Mario Limonciello <mario.limonciello@xxxxxxxx> > > > --- > > 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. */ >