* [PATCH] ACPI / PCI / PM: Fix device PM regression related to D3hot/D3cold
@ 2012-05-17 22:39 ` Rafael J. Wysocki
0 siblings, 0 replies; 5+ messages in thread
From: Rafael J. Wysocki @ 2012-05-17 22:39 UTC (permalink / raw)
To: Linus Torvalds
Cc: Len Brown, Lekensteyn, LKML, Linux PM list,
ACPI Devel Mailing List, Lin Ming, Cristian Rodríguez, rocko
From: Rafael J. Wysocki <rjw@sisk.pl>
Commit 1cc0c998fdf2cb665d625fb565a0d6db5c81c639 (ACPI: Fix D3hot
v D3cold confusion) introduced a bug in __acpi_bus_set_power() and
changed the behavior of acpi_pci_set_power_state() in such a way that
it generally doesn't work as expected if PCI_D3hot is passed to it
as the second argument.
First off, if ACPI_STATE_D3 (equal to ACPI_STATE_D3_COLD) is passed
to __acpi_bus_set_power() and the explicit_set flag is set for the
D3cold state, the function will try to execute AML method called
"_PS4", which doesn't exist.
Fix this by adding a check to ensure that the name of the AML method
to execute for transitions to ACPI_STATE_D3_COLD is correct in
__acpi_bus_set_power(). Also make sure that the explicit_set flag
for ACPI_STATE_D3_COLD will be set if _PS3 is present and modify
acpi_power_transition() to avoid accessing power resources for
ACPI_STATE_D3_COLD, because they don't exist.
Second, if PCI_D3hot is passed to acpi_pci_set_power_state() as the
target state, the function will request a transition to
ACPI_STATE_D3_HOT instead of ACPI_STATE_D3. However,
ACPI_STATE_D3_HOT is now only marked as supported if the _PR3 AML
method is defined for the given device, which is rare. This causes
problems to happen on systems where devices were successfully put
into ACPI D3 by pci_set_power_state(PCI_D3hot) which doesn't work
now. In particular, some unused graphics adapters are not turned
off as a result.
To fix this issue restore the old behavior of
acpi_pci_set_power_state(), which is to request a transition to
ACPI_STATE_D3 (equal to ACPI_STATE_D3_COLD) if either PCI_D3hot or
PCI_D3cold is passed to it as the argument.
This approach is not ideal, because generally power should not
be removed from devices if PCI_D3hot is the target power state,
but since this behavior is relied on, we have no choice but to
restore it at the moment and spend more time on designing a
better solution in the future.
References: https://bugzilla.kernel.org/show_bug.cgi?id=43228
Reported-by: rocko <rockorequin@hotmail.com>
Reported-by: Cristian Rodríguez <crrodriguez@opensuse.org>
Reported-and-tested-by: Peter <lekensteyn@gmail.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
Hi Linus,
Could you please take this one directly? It fixes obvious bugs and
makes pci_set_power_state(PCI_D3hot) work the same way as it did in
v3.3 and before, which is quite a big deal IMO.
Thanks,
Rafael
---
drivers/acpi/bus.c | 4 ++++
drivers/acpi/power.c | 9 ++++++---
drivers/acpi/scan.c | 4 ++++
drivers/pci/pci-acpi.c | 2 +-
4 files changed, 15 insertions(+), 4 deletions(-)
Index: linux/drivers/pci/pci-acpi.c
===================================================================
--- linux.orig/drivers/pci/pci-acpi.c
+++ linux/drivers/pci/pci-acpi.c
@@ -223,7 +223,7 @@ static int acpi_pci_set_power_state(stru
[PCI_D0] = ACPI_STATE_D0,
[PCI_D1] = ACPI_STATE_D1,
[PCI_D2] = ACPI_STATE_D2,
- [PCI_D3hot] = ACPI_STATE_D3_HOT,
+ [PCI_D3hot] = ACPI_STATE_D3,
[PCI_D3cold] = ACPI_STATE_D3
};
int error = -EINVAL;
Index: linux/drivers/acpi/bus.c
===================================================================
--- linux.orig/drivers/acpi/bus.c
+++ linux/drivers/acpi/bus.c
@@ -250,6 +250,10 @@ static int __acpi_bus_set_power(struct a
return -ENODEV;
}
+ /* For D3cold we should execute _PS3, not _PS4. */
+ if (state == ACPI_STATE_D3_COLD)
+ object_name[3] = '3';
+
/*
* Transition Power
* ----------------
Index: linux/drivers/acpi/scan.c
===================================================================
--- linux.orig/drivers/acpi/scan.c
+++ linux/drivers/acpi/scan.c
@@ -908,6 +908,10 @@ static int acpi_bus_get_power_flags(stru
device->power.states[ACPI_STATE_D3].flags.valid = 1;
device->power.states[ACPI_STATE_D3].power = 0;
+ /* Set D3cold's explicit_set flag if _PS3 exists. */
+ if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set)
+ device->power.states[ACPI_STATE_D3_COLD].flags.explicit_set = 1;
+
acpi_bus_init_power(device);
return 0;
Index: linux/drivers/acpi/power.c
===================================================================
--- linux.orig/drivers/acpi/power.c
+++ linux/drivers/acpi/power.c
@@ -660,7 +660,7 @@ int acpi_power_on_resources(struct acpi_
int acpi_power_transition(struct acpi_device *device, int state)
{
- int result;
+ int result = 0;
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
return -EINVAL;
@@ -679,8 +679,11 @@ int acpi_power_transition(struct acpi_de
* (e.g. so the device doesn't lose power while transitioning). Then,
* we dereference all power resources used in the current list.
*/
- result = acpi_power_on_list(&device->power.states[state].resources);
- if (!result)
+ if (state < ACPI_STATE_D3_COLD)
+ result = acpi_power_on_list(
+ &device->power.states[state].resources);
+
+ if (!result && device->power.state < ACPI_STATE_D3_COLD)
acpi_power_off_list(
&device->power.states[device->power.state].resources);
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH] ACPI / PCI / PM: Fix device PM regression related to D3hot/D3cold
@ 2012-05-17 22:39 ` Rafael J. Wysocki
0 siblings, 0 replies; 5+ messages in thread
From: Rafael J. Wysocki @ 2012-05-17 22:39 UTC (permalink / raw)
To: Linus Torvalds
Cc: Len Brown, Lekensteyn, LKML, Linux PM list,
ACPI Devel Mailing List, Lin Ming, Cristian Rodríguez, rocko
From: Rafael J. Wysocki <rjw@sisk.pl>
Commit 1cc0c998fdf2cb665d625fb565a0d6db5c81c639 (ACPI: Fix D3hot
v D3cold confusion) introduced a bug in __acpi_bus_set_power() and
changed the behavior of acpi_pci_set_power_state() in such a way that
it generally doesn't work as expected if PCI_D3hot is passed to it
as the second argument.
First off, if ACPI_STATE_D3 (equal to ACPI_STATE_D3_COLD) is passed
to __acpi_bus_set_power() and the explicit_set flag is set for the
D3cold state, the function will try to execute AML method called
"_PS4", which doesn't exist.
Fix this by adding a check to ensure that the name of the AML method
to execute for transitions to ACPI_STATE_D3_COLD is correct in
__acpi_bus_set_power(). Also make sure that the explicit_set flag
for ACPI_STATE_D3_COLD will be set if _PS3 is present and modify
acpi_power_transition() to avoid accessing power resources for
ACPI_STATE_D3_COLD, because they don't exist.
Second, if PCI_D3hot is passed to acpi_pci_set_power_state() as the
target state, the function will request a transition to
ACPI_STATE_D3_HOT instead of ACPI_STATE_D3. However,
ACPI_STATE_D3_HOT is now only marked as supported if the _PR3 AML
method is defined for the given device, which is rare. This causes
problems to happen on systems where devices were successfully put
into ACPI D3 by pci_set_power_state(PCI_D3hot) which doesn't work
now. In particular, some unused graphics adapters are not turned
off as a result.
To fix this issue restore the old behavior of
acpi_pci_set_power_state(), which is to request a transition to
ACPI_STATE_D3 (equal to ACPI_STATE_D3_COLD) if either PCI_D3hot or
PCI_D3cold is passed to it as the argument.
This approach is not ideal, because generally power should not
be removed from devices if PCI_D3hot is the target power state,
but since this behavior is relied on, we have no choice but to
restore it at the moment and spend more time on designing a
better solution in the future.
References: https://bugzilla.kernel.org/show_bug.cgi?id=43228
Reported-by: rocko <rockorequin@hotmail.com>
Reported-by: Cristian Rodríguez <crrodriguez@opensuse.org>
Reported-and-tested-by: Peter <lekensteyn@gmail.com>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
Hi Linus,
Could you please take this one directly? It fixes obvious bugs and
makes pci_set_power_state(PCI_D3hot) work the same way as it did in
v3.3 and before, which is quite a big deal IMO.
Thanks,
Rafael
---
drivers/acpi/bus.c | 4 ++++
drivers/acpi/power.c | 9 ++++++---
drivers/acpi/scan.c | 4 ++++
drivers/pci/pci-acpi.c | 2 +-
4 files changed, 15 insertions(+), 4 deletions(-)
Index: linux/drivers/pci/pci-acpi.c
===================================================================
--- linux.orig/drivers/pci/pci-acpi.c
+++ linux/drivers/pci/pci-acpi.c
@@ -223,7 +223,7 @@ static int acpi_pci_set_power_state(stru
[PCI_D0] = ACPI_STATE_D0,
[PCI_D1] = ACPI_STATE_D1,
[PCI_D2] = ACPI_STATE_D2,
- [PCI_D3hot] = ACPI_STATE_D3_HOT,
+ [PCI_D3hot] = ACPI_STATE_D3,
[PCI_D3cold] = ACPI_STATE_D3
};
int error = -EINVAL;
Index: linux/drivers/acpi/bus.c
===================================================================
--- linux.orig/drivers/acpi/bus.c
+++ linux/drivers/acpi/bus.c
@@ -250,6 +250,10 @@ static int __acpi_bus_set_power(struct a
return -ENODEV;
}
+ /* For D3cold we should execute _PS3, not _PS4. */
+ if (state == ACPI_STATE_D3_COLD)
+ object_name[3] = '3';
+
/*
* Transition Power
* ----------------
Index: linux/drivers/acpi/scan.c
===================================================================
--- linux.orig/drivers/acpi/scan.c
+++ linux/drivers/acpi/scan.c
@@ -908,6 +908,10 @@ static int acpi_bus_get_power_flags(stru
device->power.states[ACPI_STATE_D3].flags.valid = 1;
device->power.states[ACPI_STATE_D3].power = 0;
+ /* Set D3cold's explicit_set flag if _PS3 exists. */
+ if (device->power.states[ACPI_STATE_D3_HOT].flags.explicit_set)
+ device->power.states[ACPI_STATE_D3_COLD].flags.explicit_set = 1;
+
acpi_bus_init_power(device);
return 0;
Index: linux/drivers/acpi/power.c
===================================================================
--- linux.orig/drivers/acpi/power.c
+++ linux/drivers/acpi/power.c
@@ -660,7 +660,7 @@ int acpi_power_on_resources(struct acpi_
int acpi_power_transition(struct acpi_device *device, int state)
{
- int result;
+ int result = 0;
if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
return -EINVAL;
@@ -679,8 +679,11 @@ int acpi_power_transition(struct acpi_de
* (e.g. so the device doesn't lose power while transitioning). Then,
* we dereference all power resources used in the current list.
*/
- result = acpi_power_on_list(&device->power.states[state].resources);
- if (!result)
+ if (state < ACPI_STATE_D3_COLD)
+ result = acpi_power_on_list(
+ &device->power.states[state].resources);
+
+ if (!result && device->power.state < ACPI_STATE_D3_COLD)
acpi_power_off_list(
&device->power.states[device->power.state].resources);
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] ACPI / PCI / PM: Fix device PM regression related to D3hot/D3cold
2012-05-17 22:39 ` Rafael J. Wysocki
@ 2012-05-18 5:56 ` Cristian Rodríguez
-1 siblings, 0 replies; 5+ messages in thread
From: Cristian Rodríguez @ 2012-05-18 5:56 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linus Torvalds, Len Brown, Lekensteyn, LKML, Linux PM list,
ACPI Devel Mailing List, Lin Ming, rocko
On 17/05/12 18:39, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki<rjw@sisk.pl>
>
> Commit 1cc0c998fdf2cb665d625fb565a0d6db5c81c639 (ACPI: Fix D3hot
> v D3cold confusion) introduced a bug in __acpi_bus_set_power() and
> changed the behavior of acpi_pci_set_power_state() in such a way that
> it generally doesn't work as expected if PCI_D3hot is passed to it
> as the second argument.
>
> First off, if ACPI_STATE_D3 (equal to ACPI_STATE_D3_COLD) is passed
> to __acpi_bus_set_power() and the explicit_set flag is set for the
> D3cold state, the function will try to execute AML method called
> "_PS4", which doesn't exist.
>
> Fix this by adding a check to ensure that the name of the AML method
> to execute for transitions to ACPI_STATE_D3_COLD is correct in
> __acpi_bus_set_power(). Also make sure that the explicit_set flag
> for ACPI_STATE_D3_COLD will be set if _PS3 is present and modify
> acpi_power_transition() to avoid accessing power resources for
> ACPI_STATE_D3_COLD, because they don't exist.
>
> Second, if PCI_D3hot is passed to acpi_pci_set_power_state() as the
> target state, the function will request a transition to
> ACPI_STATE_D3_HOT instead of ACPI_STATE_D3. However,
> ACPI_STATE_D3_HOT is now only marked as supported if the _PR3 AML
> method is defined for the given device, which is rare. This causes
> problems to happen on systems where devices were successfully put
> into ACPI D3 by pci_set_power_state(PCI_D3hot) which doesn't work
> now. In particular, some unused graphics adapters are not turned
> off as a result.
>
> To fix this issue restore the old behavior of
> acpi_pci_set_power_state(), which is to request a transition to
> ACPI_STATE_D3 (equal to ACPI_STATE_D3_COLD) if either PCI_D3hot or
> PCI_D3cold is passed to it as the argument.
>
> This approach is not ideal, because generally power should not
> be removed from devices if PCI_D3hot is the target power state,
> but since this behavior is relied on, we have no choice but to
> restore it at the moment and spend more time on designing a
> better solution in the future.
>
> References: https://bugzilla.kernel.org/show_bug.cgi?id=43228
> Reported-by: rocko<rockorequin@hotmail.com>
> Reported-by: Cristian Rodríguez<crrodriguez@opensuse.org>
> Reported-and-tested-by: Peter<lekensteyn@gmail.com>
> Signed-off-by: Rafael J. Wysocki<rjw@sisk.pl>
> ---
Ok, tested this one in the affected box, it works.
echo OFF > /sys/kernel/debug/vgaswitcheroo/switch
[ 77.436767] VGA switcheroo: switched nouveau off
[ 77.437004] [drm] nouveau 0000:01:00.0: Disabling display...
[ 77.437110] [drm] nouveau 0000:01:00.0: Disabling fbcon...
[ 77.437113] [drm] nouveau 0000:01:00.0: Unpinning framebuffer(s)...
[ 77.437157] [drm] nouveau 0000:01:00.0: Evicting buffers...
[ 77.439175] [drm] nouveau 0000:01:00.0: Idling channels...
[ 77.439316] [drm] nouveau 0000:01:00.0: Suspending GPU objects...
[ 77.771133] [drm] nouveau 0000:01:00.0: And we're gone!
[ 78.082258] nouveau 0000:01:00.0: power state changed by ACPI to D3
laptop's fan is silent again :-) , thanks for fixing it !
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] ACPI / PCI / PM: Fix device PM regression related to D3hot/D3cold
@ 2012-05-18 5:56 ` Cristian Rodríguez
0 siblings, 0 replies; 5+ messages in thread
From: Cristian Rodríguez @ 2012-05-18 5:56 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Linus Torvalds, Len Brown, Lekensteyn, LKML, Linux PM list,
ACPI Devel Mailing List, Lin Ming, rocko
On 17/05/12 18:39, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki<rjw@sisk.pl>
>
> Commit 1cc0c998fdf2cb665d625fb565a0d6db5c81c639 (ACPI: Fix D3hot
> v D3cold confusion) introduced a bug in __acpi_bus_set_power() and
> changed the behavior of acpi_pci_set_power_state() in such a way that
> it generally doesn't work as expected if PCI_D3hot is passed to it
> as the second argument.
>
> First off, if ACPI_STATE_D3 (equal to ACPI_STATE_D3_COLD) is passed
> to __acpi_bus_set_power() and the explicit_set flag is set for the
> D3cold state, the function will try to execute AML method called
> "_PS4", which doesn't exist.
>
> Fix this by adding a check to ensure that the name of the AML method
> to execute for transitions to ACPI_STATE_D3_COLD is correct in
> __acpi_bus_set_power(). Also make sure that the explicit_set flag
> for ACPI_STATE_D3_COLD will be set if _PS3 is present and modify
> acpi_power_transition() to avoid accessing power resources for
> ACPI_STATE_D3_COLD, because they don't exist.
>
> Second, if PCI_D3hot is passed to acpi_pci_set_power_state() as the
> target state, the function will request a transition to
> ACPI_STATE_D3_HOT instead of ACPI_STATE_D3. However,
> ACPI_STATE_D3_HOT is now only marked as supported if the _PR3 AML
> method is defined for the given device, which is rare. This causes
> problems to happen on systems where devices were successfully put
> into ACPI D3 by pci_set_power_state(PCI_D3hot) which doesn't work
> now. In particular, some unused graphics adapters are not turned
> off as a result.
>
> To fix this issue restore the old behavior of
> acpi_pci_set_power_state(), which is to request a transition to
> ACPI_STATE_D3 (equal to ACPI_STATE_D3_COLD) if either PCI_D3hot or
> PCI_D3cold is passed to it as the argument.
>
> This approach is not ideal, because generally power should not
> be removed from devices if PCI_D3hot is the target power state,
> but since this behavior is relied on, we have no choice but to
> restore it at the moment and spend more time on designing a
> better solution in the future.
>
> References: https://bugzilla.kernel.org/show_bug.cgi?id=43228
> Reported-by: rocko<rockorequin@hotmail.com>
> Reported-by: Cristian Rodríguez<crrodriguez@opensuse.org>
> Reported-and-tested-by: Peter<lekensteyn@gmail.com>
> Signed-off-by: Rafael J. Wysocki<rjw@sisk.pl>
> ---
Ok, tested this one in the affected box, it works.
echo OFF > /sys/kernel/debug/vgaswitcheroo/switch
[ 77.436767] VGA switcheroo: switched nouveau off
[ 77.437004] [drm] nouveau 0000:01:00.0: Disabling display...
[ 77.437110] [drm] nouveau 0000:01:00.0: Disabling fbcon...
[ 77.437113] [drm] nouveau 0000:01:00.0: Unpinning framebuffer(s)...
[ 77.437157] [drm] nouveau 0000:01:00.0: Evicting buffers...
[ 77.439175] [drm] nouveau 0000:01:00.0: Idling channels...
[ 77.439316] [drm] nouveau 0000:01:00.0: Suspending GPU objects...
[ 77.771133] [drm] nouveau 0000:01:00.0: And we're gone!
[ 78.082258] nouveau 0000:01:00.0: power state changed by ACPI to D3
laptop's fan is silent again :-) , thanks for fixing it !
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] acpi: fix regression on D3hot detection
@ 2012-05-15 15:28 Lekensteyn
2012-05-15 17:28 ` Rafael J. Wysocki
0 siblings, 1 reply; 5+ messages in thread
From: Lekensteyn @ 2012-05-15 15:28 UTC (permalink / raw)
To: Len Brown; +Cc: linux-acpi
Commit 1cc0c998fdf2cb665d625fb565a0d6db5c81c639 tried clear up some confusion
around D3hot and D3cold but accidentally changed behaviour on validating device
power states. It added an extra condition: i < ACPI_STATE_D3_HOT which means
that only states D0, D1 and D2 are accepted if there are no power resources but
the _PSx method exist. D3(hot) is missing here.
This fixes https://bugzilla.kernel.org/show_bug.cgi?id=43228
Reported-by: rockorequin@hotmail.com
Signed-off-by: Peter Lekensteyn <lekensteyn@gmail.com>
Tested-by: rockorequin@hotmail.com
---
drivers/acpi/scan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 7417267..932c427 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -895,7 +895,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device)
* D3hot is only valid if _PR3 present.
*/
if (ps->resources.count ||
- (ps->flags.explicit_set && i < ACPI_STATE_D3_HOT))
+ (ps->flags.explicit_set && i <= ACPI_STATE_D3_HOT))
ps->flags.valid = 1;
ps->power = -1; /* Unknown - driver assigned */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] acpi: fix regression on D3hot detection
@ 2012-05-15 17:28 ` Rafael J. Wysocki
2012-05-16 10:24 ` Rafael J. Wysocki
0 siblings, 1 reply; 5+ messages in thread
From: Rafael J. Wysocki @ 2012-05-15 17:28 UTC (permalink / raw)
To: Lekensteyn; +Cc: ACPI Devel Mailing List, Len Brown, Lin Ming, Linux PM list
On Tuesday, May 15, 2012, Lekensteyn wrote:
> On Tuesday 15 May 2012 17:47:43 you wrote:
> > On Tuesday, May 15, 2012, Lekensteyn wrote:
> > > Commit 1cc0c998fdf2cb665d625fb565a0d6db5c81c639 tried clear up some
> > > confusion around D3hot and D3cold but accidentally changed behaviour on
> > > validating device power states. It added an extra condition: i <
> > > ACPI_STATE_D3_HOT which means that only states D0, D1 and D2 are accepted
> > > if there are no power resources but the _PSx method exist. D3(hot) is
> > > missing here.
> >
> > Which is intentional (that follows from the ACPI spec.).
> Now that I am reading it back, this patch invalidates the comment in the code
> and could be achieved by removing the whole i < ... condition (because that is
> the for-loop condition too). In the ACPI spec [1], I cannot find a statement
> that D3 is invalid if there is no _PR3 state. Do you have a reference for the
> behaviour?
Yes, pretty much. ACPI 4.0 Section 7.2.10 _PR3 (Power Resources for D3hot)
says:
"Platform/drivers must assume that the device will have power completely
removed when the device is place[d] into "D3" via _PS3."
This basically means that if _PR3 is not present, we must assume that _PS3
puts the device into D3cold.
> About the linked bug, I do not see any _PR3 methods on at least 258 Optimus
> machines (acpidumps for a lot hybrid graphics machines [2]) although the _PS3
> methods on those machines really put the device in a lower power state.
That's correct and that state is D3cold.
Thanks,
Rafael
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] acpi: fix regression on D3hot detection
2012-05-15 17:28 ` Rafael J. Wysocki
@ 2012-05-16 10:24 ` Rafael J. Wysocki
2012-05-16 20:15 ` [PATCH] ACPI / PCI / PM: Fix device PM regression related to D3hot/D3cold Rafael J. Wysocki
0 siblings, 1 reply; 5+ messages in thread
From: Rafael J. Wysocki @ 2012-05-16 10:24 UTC (permalink / raw)
To: Lekensteyn, rockorequin, Cristian Rodríguez
Cc: ACPI Devel Mailing List, Len Brown, Lin Ming, Linux PM list
On Tuesday, May 15, 2012, Rafael J. Wysocki wrote:
> On Tuesday, May 15, 2012, Lekensteyn wrote:
> > On Tuesday 15 May 2012 17:47:43 you wrote:
> > > On Tuesday, May 15, 2012, Lekensteyn wrote:
> > > > Commit 1cc0c998fdf2cb665d625fb565a0d6db5c81c639 tried clear up some
> > > > confusion around D3hot and D3cold but accidentally changed behaviour on
> > > > validating device power states. It added an extra condition: i <
> > > > ACPI_STATE_D3_HOT which means that only states D0, D1 and D2 are accepted
> > > > if there are no power resources but the _PSx method exist. D3(hot) is
> > > > missing here.
> > >
> > > Which is intentional (that follows from the ACPI spec.).
> > Now that I am reading it back, this patch invalidates the comment in the code
> > and could be achieved by removing the whole i < ... condition (because that is
> > the for-loop condition too). In the ACPI spec [1], I cannot find a statement
> > that D3 is invalid if there is no _PR3 state. Do you have a reference for the
> > behaviour?
>
> Yes, pretty much. ACPI 4.0 Section 7.2.10 _PR3 (Power Resources for D3hot)
> says:
>
> "Platform/drivers must assume that the device will have power completely
> removed when the device is place[d] into "D3" via _PS3."
>
> This basically means that if _PR3 is not present, we must assume that _PS3
> puts the device into D3cold.
>
> > About the linked bug, I do not see any _PR3 methods on at least 258 Optimus
> > machines (acpidumps for a lot hybrid graphics machines [2]) although the _PS3
> > methods on those machines really put the device in a lower power state.
>
> That's correct and that state is D3cold.
So, I believe the patch below should fix the problem and I'll appreciate it
if someone who can reproduce it can test.
Thanks,
Rafael
---
From: Rafael J. Wysocki <rjw@sisk.pl>
Subject: ACPI / PCI / PM: Restore old behavior of acpi_pci_set_power_state()
Commit 1cc0c998fdf2cb665d625fb565a0d6db5c81c639 (ACPI: Fix D3hot
v D3cold confusion) changed the behavior of
acpi_pci_set_power_state() in such a way that if PCI_D3hot is
passed to it, the function will request a transition to
ACPI_STATE_D3_HOT instead of ACPI_STATE_D3, but ACPI_STATE_D3_HOT
is only supported if the _PR3 AML method is defined for the given
device, which is rare. This causes problems to happen on systems
where devices were successfully put into ACPI D3 by
pci_set_power_state(PCI_D3hot) which doesn't work now. In
particular, some unused graphics adapters are not turned off as a
result.
To fix this issue restore the old behavior of
acpi_pci_set_power_state(), which is to request a transition to
ACPI_STATE_D3 (defined to be the same as ACPI_STATE_D3_COLD) if
either PCI_D3hot or PCI_D3cold is passed to it as the argument.
This approach is not ideal, because generally power should not
be removed from devices if PCI_D3hot is the target power state,
but since this behavior is relied on, we have no choice but to
restore it at the moment and spend more time on providing a
better solution in the future.
References: https://bugzilla.kernel.org/show_bug.cgi?id=43228
Reported-by: rocko <rockorequin@hotmail.com>
Reported-by: Cristian Rodríguez <crrodriguez@opensuse.org>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
drivers/pci/pci-acpi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux/drivers/pci/pci-acpi.c
===================================================================
--- linux.orig/drivers/pci/pci-acpi.c
+++ linux/drivers/pci/pci-acpi.c
@@ -223,7 +223,7 @@ static int acpi_pci_set_power_state(stru
[PCI_D0] = ACPI_STATE_D0,
[PCI_D1] = ACPI_STATE_D1,
[PCI_D2] = ACPI_STATE_D2,
- [PCI_D3hot] = ACPI_STATE_D3_HOT,
+ [PCI_D3hot] = ACPI_STATE_D3,
[PCI_D3cold] = ACPI_STATE_D3
};
int error = -EINVAL;
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] ACPI / PCI / PM: Fix device PM regression related to D3hot/D3cold
2012-05-16 10:24 ` Rafael J. Wysocki
@ 2012-05-16 20:15 ` Rafael J. Wysocki
0 siblings, 0 replies; 5+ messages in thread
From: Rafael J. Wysocki @ 2012-05-16 20:15 UTC (permalink / raw)
To: Lekensteyn
Cc: rockorequin, Cristian Rodríguez, ACPI Devel Mailing List,
Len Brown, Lin Ming, Linux PM list
From: Rafael J. Wysocki <rjw@sisk.pl>
Commit 1cc0c998fdf2cb665d625fb565a0d6db5c81c639 (ACPI: Fix D3hot
v D3cold confusion) introduced a bug in __acpi_bus_set_power() and
changed the behavior of acpi_pci_set_power_state() in such a way that
it generally doesn't work as expected if PCI_D3hot is passed to it
as the second argument.
First off, if ACPI_STATE_D3 (equal to ACPI_STATE_D3_COLD) is passed
to __acpi_bus_set_power() and the explicit_set flag is set for the
D3cold state, the function will try to execute AML method called
"_PS4", which doesn't exist.
Fix this by adding a check to ensure that the name of the AML method
to execute for transitions to ACPI_STATE_D3_COLD is correct in
__acpi_bus_set_power().
Second, if PCI_D3hot is passed to acpi_pci_set_power_state() as the
target state, the function will request a transition to
ACPI_STATE_D3_HOT instead of ACPI_STATE_D3. However,
ACPI_STATE_D3_HOT is now only marked as supported if the _PR3 AML
method is defined for the given device, which is rare. This causes
problems to happen on systems where devices were successfully put
into ACPI D3 by pci_set_power_state(PCI_D3hot) which doesn't work
now. In particular, some unused graphics adapters are not turned
off as a result.
To fix this issue restore the old behavior of
acpi_pci_set_power_state(), which is to request a transition to
ACPI_STATE_D3 (equal to ACPI_STATE_D3_COLD) if either PCI_D3hot or
PCI_D3cold is passed to it as the argument.
This approach is not ideal, because generally power should not
be removed from devices if PCI_D3hot is the target power state,
but since this behavior is relied on, we have no choice but to
restore it at the moment and spend more time on designing a
better solution in the future.
References: https://bugzilla.kernel.org/show_bug.cgi?id=43228
Reported-by: rocko <rockorequin@hotmail.com>
Reported-by: Lekensteyn <lekensteyn@gmail.com>
Reported-by: Cristian Rodríguez <crrodriguez@opensuse.org>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
---
Hi all,
The previous patch was incomplete, so please test this one instead.
Thanks,
Rafael
---
drivers/acpi/bus.c | 4 ++++
drivers/pci/pci-acpi.c | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
Index: linux/drivers/pci/pci-acpi.c
===================================================================
--- linux.orig/drivers/pci/pci-acpi.c
+++ linux/drivers/pci/pci-acpi.c
@@ -223,7 +223,7 @@ static int acpi_pci_set_power_state(stru
[PCI_D0] = ACPI_STATE_D0,
[PCI_D1] = ACPI_STATE_D1,
[PCI_D2] = ACPI_STATE_D2,
- [PCI_D3hot] = ACPI_STATE_D3_HOT,
+ [PCI_D3hot] = ACPI_STATE_D3,
[PCI_D3cold] = ACPI_STATE_D3
};
int error = -EINVAL;
Index: linux/drivers/acpi/bus.c
===================================================================
--- linux.orig/drivers/acpi/bus.c
+++ linux/drivers/acpi/bus.c
@@ -250,6 +250,10 @@ static int __acpi_bus_set_power(struct a
return -ENODEV;
}
+ /* _PS3 should be executed for transitions into D3cold. */
+ if (state == ACPI_STATE_D3_COLD)
+ object_name[3] = '3';
+
/*
* Transition Power
* ----------------
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-05-18 5:56 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-05-17 22:39 [PATCH] ACPI / PCI / PM: Fix device PM regression related to D3hot/D3cold Rafael J. Wysocki
2012-05-17 22:39 ` Rafael J. Wysocki
2012-05-18 5:56 ` Cristian Rodríguez
2012-05-18 5:56 ` Cristian Rodríguez
-- strict thread matches above, loose matches on Subject: below --
2012-05-15 15:28 [PATCH] acpi: fix regression on D3hot detection Lekensteyn
2012-05-15 17:28 ` Rafael J. Wysocki
2012-05-16 10:24 ` Rafael J. Wysocki
2012-05-16 20:15 ` [PATCH] ACPI / PCI / PM: Fix device PM regression related to D3hot/D3cold Rafael J. Wysocki
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.