public inbox for linux-acpi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ACPI / PM: Add check preventing transitioning to non-D0 state from D3.
@ 2012-11-15  4:25 Lv Zheng
  2012-11-16  1:49 ` Rafael J. Wysocki
  2013-01-30 17:53 ` Peter Wu
  0 siblings, 2 replies; 7+ messages in thread
From: Lv Zheng @ 2012-11-15  4:25 UTC (permalink / raw)
  To: Len Brown, Rafael J Wysocki; +Cc: linux-acpi, Lv Zheng

No power transitioning from D3 state to a non-D0 state is allowed.
This patch also cleans up device power updating code in the
acpi_device_set_power() as it should already been updated in the
acpi_power_transition().

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
---
 drivers/acpi/bus.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 07a20ee..12c1b51 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -293,6 +293,12 @@ int acpi_device_set_power(struct acpi_device *device, int state)
 			      " state than parent\n");
 		return -ENODEV;
 	}
+	if (device->parent->power.state >= ACPI_STATE_D3_HOT &&
+	    state != ACPI_STATE_D0) {
+		printk(KERN_WARNING PREFIX
+			      "Cannot transition to non-D0 state from D3\n");
+		return -ENODEV;
+	}
 
 	/* For D3cold we should execute _PS3, not _PS4. */
 	if (state == ACPI_STATE_D3_COLD)
@@ -341,7 +347,6 @@ int acpi_device_set_power(struct acpi_device *device, int state)
 			      "Device [%s] failed to transition to %s\n",
 			      device->pnp.bus_id, state_string(state));
 	else {
-		device->power.state = state;
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 				  "Device [%s] transitioned to %s\n",
 				  device->pnp.bus_id, state_string(state)));
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] ACPI / PM: Add check preventing transitioning to non-D0 state from D3.
  2012-11-15  4:25 [PATCH] ACPI / PM: Add check preventing transitioning to non-D0 state from D3 Lv Zheng
@ 2012-11-16  1:49 ` Rafael J. Wysocki
  2012-11-19  2:31   ` Zheng, Lv
  2013-01-30 17:53 ` Peter Wu
  1 sibling, 1 reply; 7+ messages in thread
From: Rafael J. Wysocki @ 2012-11-16  1:49 UTC (permalink / raw)
  To: Lv Zheng; +Cc: Len Brown, Rafael J Wysocki, linux-acpi, Len Brown

On Thursday, November 15, 2012 12:25:01 PM Lv Zheng wrote:
> No power transitioning from D3 state to a non-D0 state is allowed.
> This patch also cleans up device power updating code in the
> acpi_device_set_power() as it should already been updated in the
> acpi_power_transition().
> 
> Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> ---
>  drivers/acpi/bus.c |    7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
> index 07a20ee..12c1b51 100644
> --- a/drivers/acpi/bus.c
> +++ b/drivers/acpi/bus.c
> @@ -293,6 +293,12 @@ int acpi_device_set_power(struct acpi_device *device, int state)
>  			      " state than parent\n");
>  		return -ENODEV;
>  	}
> +	if (device->parent->power.state >= ACPI_STATE_D3_HOT &&

Why parent?  The device's own power state shouldn't be D3, right?

> +	    state != ACPI_STATE_D0) {
> +		printk(KERN_WARNING PREFIX
> +			      "Cannot transition to non-D0 state from D3\n");
> +		return -ENODEV;
> +	}

I fixed up the check and moved it into the (state < device->power.state)
block, because otherwise it would prevent transitions from D3_HOT to
D3_COLD from being carried out, but they are allowed.

>  	/* For D3cold we should execute _PS3, not _PS4. */
>  	if (state == ACPI_STATE_D3_COLD)
> @@ -341,7 +347,6 @@ int acpi_device_set_power(struct acpi_device *device, int state)
>  			      "Device [%s] failed to transition to %s\n",
>  			      device->pnp.bus_id, state_string(state));
>  	else {
> -		device->power.state = state;
>  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
>  				  "Device [%s] transitioned to %s\n",
>  				  device->pnp.bus_id, state_string(state)));
> 

Please check the linux-next branch of linux-pm.git and see if that's what you
wanted. :-)

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH] ACPI / PM: Add check preventing transitioning to non-D0 state from D3.
  2012-11-16  1:49 ` Rafael J. Wysocki
@ 2012-11-19  2:31   ` Zheng, Lv
  0 siblings, 0 replies; 7+ messages in thread
From: Zheng, Lv @ 2012-11-19  2:31 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Brown, Len, Wysocki, Rafael J, linux-acpi@vger.kernel.org,
	Len Brown

> Please check the linux-next branch of linux-pm.git and see if that's what you
> wanted. :-)

Lots of bugs in my patch...
Thanks for fixing them.  I found it in the linux-next branch.

Best regards/Lv Zheng

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] ACPI / PM: Add check preventing transitioning to non-D0 state from D3.
  2012-11-15  4:25 [PATCH] ACPI / PM: Add check preventing transitioning to non-D0 state from D3 Lv Zheng
  2012-11-16  1:49 ` Rafael J. Wysocki
@ 2013-01-30 17:53 ` Peter Wu
  2013-01-30 21:55   ` Rafael J. Wysocki
  1 sibling, 1 reply; 7+ messages in thread
From: Peter Wu @ 2013-01-30 17:53 UTC (permalink / raw)
  To: Lv Zheng; +Cc: Len Brown, Rafael J Wysocki, linux-acpi

Hi Lv Zheng,

I encounter a regression with your patch (Linux 3.8-rc5). On my Nvidia Optimus 
laptop, I use the bbswitch[1] kernel module to trigger a _PS3 ACPI method call 
to turn the video card off.

After this patch, I got the following in my kernel log:

    pci 0000:01:00.0: Refused to change power state, currently in D0
    ACPI: Cannot transition to non-D0 state from D3
    bbswitch: Succesfully loaded. Discrete card 0000:01:00.0 is on

The expected output would be "Discrete card 0000:01:00.0 is  off". Printing the 
contents of (acpi_device) device->power.state shows FF (ACPI_STATE_UNKNOWN). 
Should this condition be excluded from your check or is my hacky module 
outdated?

I currently workaround this issue by checking for ACPI_STATE_UNKNOWN. If that 
is the value, I assume on (overwrite device->power.state with ACPI_STATE_D0). 
Then I call pci_set_power_state(pci_dev, PCI_D3cold).

Regards,
Peter

 [1]: https://github.com/Bumblebee-Project/bbswitch

On Thursday 15 November 2012 12:25:01 Lv Zheng wrote:
> No power transitioning from D3 state to a non-D0 state is allowed.
> This patch also cleans up device power updating code in the
> acpi_device_set_power() as it should already been updated in the
> acpi_power_transition().
> 
> Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> ---
>  drivers/acpi/bus.c |    7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
> index 07a20ee..12c1b51 100644
> --- a/drivers/acpi/bus.c
> +++ b/drivers/acpi/bus.c
> @@ -293,6 +293,12 @@ int acpi_device_set_power(struct acpi_device *device,
> int state) " state than parent\n");
>  		return -ENODEV;
>  	}
> +	if (device->parent->power.state >= ACPI_STATE_D3_HOT &&
> +	    state != ACPI_STATE_D0) {
> +		printk(KERN_WARNING PREFIX
> +			      "Cannot transition to non-D0 state from D3\n");
> +		return -ENODEV;
> +	}
> 
>  	/* For D3cold we should execute _PS3, not _PS4. */
>  	if (state == ACPI_STATE_D3_COLD)
> @@ -341,7 +347,6 @@ int acpi_device_set_power(struct acpi_device *device,
> int state) "Device [%s] failed to transition to %s\n",
>  			      device->pnp.bus_id, state_string(state));
>  	else {
> -		device->power.state = state;
>  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
>  				  "Device [%s] transitioned to %s\n",
>  				  device->pnp.bus_id, state_string(state)));

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] ACPI / PM: Add check preventing transitioning to non-D0 state from D3.
  2013-01-30 17:53 ` Peter Wu
@ 2013-01-30 21:55   ` Rafael J. Wysocki
  2013-01-30 23:27     ` Rafael J. Wysocki
  0 siblings, 1 reply; 7+ messages in thread
From: Rafael J. Wysocki @ 2013-01-30 21:55 UTC (permalink / raw)
  To: Peter Wu; +Cc: Lv Zheng, Len Brown, Rafael J Wysocki, linux-acpi

On Wednesday, January 30, 2013 06:53:46 PM Peter Wu wrote:
> Hi Lv Zheng,
> 
> I encounter a regression with your patch (Linux 3.8-rc5). On my Nvidia Optimus 
> laptop, I use the bbswitch[1] kernel module to trigger a _PS3 ACPI method call 
> to turn the video card off.
> 
> After this patch, I got the following in my kernel log:
> 
>     pci 0000:01:00.0: Refused to change power state, currently in D0
>     ACPI: Cannot transition to non-D0 state from D3
>     bbswitch: Succesfully loaded. Discrete card 0000:01:00.0 is on
> 
> The expected output would be "Discrete card 0000:01:00.0 is  off". Printing the 
> contents of (acpi_device) device->power.state shows FF (ACPI_STATE_UNKNOWN). 
> Should this condition be excluded from your check or is my hacky module 
> outdated?
> 
> I currently workaround this issue by checking for ACPI_STATE_UNKNOWN. If that 
> is the value, I assume on (overwrite device->power.state with ACPI_STATE_D0). 
> Then I call pci_set_power_state(pci_dev, PCI_D3cold).

You shouldn't ever be transitioning from an uknown state to D3cold directly.
Please first transition to D0 and then to D3cold.

Can you please test the linux-next branch of the linux-pm.git tree and check
if you see this problem in there too?

Rafael


>  [1]: https://github.com/Bumblebee-Project/bbswitch
> 
> On Thursday 15 November 2012 12:25:01 Lv Zheng wrote:
> > No power transitioning from D3 state to a non-D0 state is allowed.
> > This patch also cleans up device power updating code in the
> > acpi_device_set_power() as it should already been updated in the
> > acpi_power_transition().
> > 
> > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > ---
> >  drivers/acpi/bus.c |    7 ++++++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
> > index 07a20ee..12c1b51 100644
> > --- a/drivers/acpi/bus.c
> > +++ b/drivers/acpi/bus.c
> > @@ -293,6 +293,12 @@ int acpi_device_set_power(struct acpi_device *device,
> > int state) " state than parent\n");
> >  		return -ENODEV;
> >  	}
> > +	if (device->parent->power.state >= ACPI_STATE_D3_HOT &&
> > +	    state != ACPI_STATE_D0) {
> > +		printk(KERN_WARNING PREFIX
> > +			      "Cannot transition to non-D0 state from D3\n");
> > +		return -ENODEV;
> > +	}
> > 
> >  	/* For D3cold we should execute _PS3, not _PS4. */
> >  	if (state == ACPI_STATE_D3_COLD)
> > @@ -341,7 +347,6 @@ int acpi_device_set_power(struct acpi_device *device,
> > int state) "Device [%s] failed to transition to %s\n",
> >  			      device->pnp.bus_id, state_string(state));
> >  	else {
> > -		device->power.state = state;
> >  		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
> >  				  "Device [%s] transitioned to %s\n",
> >  				  device->pnp.bus_id, state_string(state)));
> --
> 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
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] ACPI / PM: Add check preventing transitioning to non-D0 state from D3.
  2013-01-30 21:55   ` Rafael J. Wysocki
@ 2013-01-30 23:27     ` Rafael J. Wysocki
  2013-01-31  0:58       ` Rafael J. Wysocki
  0 siblings, 1 reply; 7+ messages in thread
From: Rafael J. Wysocki @ 2013-01-30 23:27 UTC (permalink / raw)
  To: Peter Wu; +Cc: Lv Zheng, Len Brown, Rafael J Wysocki, linux-acpi

On Wednesday, January 30, 2013 10:55:17 PM Rafael J. Wysocki wrote:
> On Wednesday, January 30, 2013 06:53:46 PM Peter Wu wrote:
> > Hi Lv Zheng,
> > 
> > I encounter a regression with your patch (Linux 3.8-rc5). On my Nvidia Optimus 
> > laptop, I use the bbswitch[1] kernel module to trigger a _PS3 ACPI method call 
> > to turn the video card off.
> > 
> > After this patch, I got the following in my kernel log:
> > 
> >     pci 0000:01:00.0: Refused to change power state, currently in D0
> >     ACPI: Cannot transition to non-D0 state from D3
> >     bbswitch: Succesfully loaded. Discrete card 0000:01:00.0 is on
> > 
> > The expected output would be "Discrete card 0000:01:00.0 is  off". Printing the 
> > contents of (acpi_device) device->power.state shows FF (ACPI_STATE_UNKNOWN). 
> > Should this condition be excluded from your check or is my hacky module 
> > outdated?
> > 
> > I currently workaround this issue by checking for ACPI_STATE_UNKNOWN. If that 
> > is the value, I assume on (overwrite device->power.state with ACPI_STATE_D0). 
> > Then I call pci_set_power_state(pci_dev, PCI_D3cold).
> 
> You shouldn't ever be transitioning from an uknown state to D3cold directly.
> Please first transition to D0 and then to D3cold.
> 
> Can you please test the linux-next branch of the linux-pm.git tree and check
> if you see this problem in there too?

To be more precise, I wonder why you get ACPI_STATE_UNKNOWN in
device->power.state if the device is power-manageable.  In theory
acpi_bus_init_power() should change that to something meaningful and if it
doesn't, then there's a bug either in acpi_bus_init_power() or in the BIOS.

We may just need to try to force D0 in acpi_bus_init_power() if _PSC is missing,
for example.

Thanks,
Rafael


-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] ACPI / PM: Add check preventing transitioning to non-D0 state from D3.
  2013-01-30 23:27     ` Rafael J. Wysocki
@ 2013-01-31  0:58       ` Rafael J. Wysocki
  0 siblings, 0 replies; 7+ messages in thread
From: Rafael J. Wysocki @ 2013-01-31  0:58 UTC (permalink / raw)
  To: Peter Wu, linux-acpi; +Cc: Lv Zheng, Len Brown

On Thursday, January 31, 2013 12:27:25 AM Rafael J. Wysocki wrote:
> On Wednesday, January 30, 2013 10:55:17 PM Rafael J. Wysocki wrote:
> > On Wednesday, January 30, 2013 06:53:46 PM Peter Wu wrote:
> > > Hi Lv Zheng,
> > > 
> > > I encounter a regression with your patch (Linux 3.8-rc5). On my Nvidia Optimus 
> > > laptop, I use the bbswitch[1] kernel module to trigger a _PS3 ACPI method call 
> > > to turn the video card off.
> > > 
> > > After this patch, I got the following in my kernel log:
> > > 
> > >     pci 0000:01:00.0: Refused to change power state, currently in D0
> > >     ACPI: Cannot transition to non-D0 state from D3
> > >     bbswitch: Succesfully loaded. Discrete card 0000:01:00.0 is on
> > > 
> > > The expected output would be "Discrete card 0000:01:00.0 is  off". Printing the 
> > > contents of (acpi_device) device->power.state shows FF (ACPI_STATE_UNKNOWN). 
> > > Should this condition be excluded from your check or is my hacky module 
> > > outdated?
> > > 
> > > I currently workaround this issue by checking for ACPI_STATE_UNKNOWN. If that 
> > > is the value, I assume on (overwrite device->power.state with ACPI_STATE_D0). 
> > > Then I call pci_set_power_state(pci_dev, PCI_D3cold).
> > 
> > You shouldn't ever be transitioning from an uknown state to D3cold directly.
> > Please first transition to D0 and then to D3cold.
> > 
> > Can you please test the linux-next branch of the linux-pm.git tree and check
> > if you see this problem in there too?
> 
> To be more precise, I wonder why you get ACPI_STATE_UNKNOWN in
> device->power.state if the device is power-manageable.  In theory
> acpi_bus_init_power() should change that to something meaningful and if it
> doesn't, then there's a bug either in acpi_bus_init_power() or in the BIOS.
> 
> We may just need to try to force D0 in acpi_bus_init_power() if _PSC is missing,
> for example.

So, I'm pondering the appended patch (on top of linux-pm/linux-next).

Thanks,
Rafael

---
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Subject: ACPI / PM: Do not power manage devices in unknown initial states

In general, for ACPI device power management to work, the initial
power states of devices must be known (otherwise, we wouldn't be able
to keep track of power resources, for example).  Hence, if it is
impossible to determine the initial ACPI power states of some
devices, they can't be regarded as power-manageable using ACPI.

For this reason, modify acpi_bus_get_power_flags() to clear the
power_manageable flag if acpi_bus_init_power() fails and add some
extra fallback code to acpi_bus_init_power() to cover broken
BIOSes that provide _PS0/_PS3 without _PSC for some devices.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/device_pm.c |    6 ++++++
 drivers/acpi/scan.c      |    5 ++++-
 2 files changed, 10 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
@@ -330,6 +330,12 @@ int acpi_bus_init_power(struct acpi_devi
 		result = acpi_dev_pm_explicit_set(device, state);
 		if (result)
 			return result;
+	} else if (state == ACPI_STATE_UNKNOWN) {
+		/* No power resources and missing _PSC? Try to force D0. */
+		state = ACPI_STATE_D0;
+		result = acpi_dev_pm_explicit_set(device, state);
+		if (result)
+			return result;
 	}
 	device->power.state = state;
 	return 0;
Index: linux-pm/drivers/acpi/scan.c
===================================================================
--- linux-pm.orig/drivers/acpi/scan.c
+++ linux-pm/drivers/acpi/scan.c
@@ -1175,7 +1175,10 @@ static void acpi_bus_get_power_flags(str
 			device->power.flags.power_resources)
 		device->power.states[ACPI_STATE_D3_COLD].flags.os_accessible = 1;
 
-	acpi_bus_init_power(device);
+	if (acpi_bus_init_power(device)) {
+		acpi_free_power_resources_lists(device);
+		device->flags.power_manageable = 0;
+	}
 }
 
 static void acpi_bus_get_flags(struct acpi_device *device)

-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-01-31  0:52 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-15  4:25 [PATCH] ACPI / PM: Add check preventing transitioning to non-D0 state from D3 Lv Zheng
2012-11-16  1:49 ` Rafael J. Wysocki
2012-11-19  2:31   ` Zheng, Lv
2013-01-30 17:53 ` Peter Wu
2013-01-30 21:55   ` Rafael J. Wysocki
2013-01-30 23:27     ` Rafael J. Wysocki
2013-01-31  0:58       ` Rafael J. Wysocki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox