linux-i2c.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] ACPI power management support for I2C and SPI devices
@ 2013-10-09 14:04 Mika Westerberg
  2013-10-09 14:04 ` [PATCH 1/3] ACPI / PM: allow child devices to ignore parent power state Mika Westerberg
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Mika Westerberg @ 2013-10-09 14:04 UTC (permalink / raw)
  To: linux-acpi-u79uwXL29TY76Z2rM5mHXA
  Cc: Wolfram Sang, Mark Brown, Rafael J. Wysocki, Aaron Lu, Lv Zheng,
	Mika Westerberg, linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

Hi,

We originally tried to add runtime PM support for I2C adapter devices in
order to have runtime PM core to power on the I2C host controller device
automatically whenever any of its children I2C device is powered on (See
[1] for the last patch series).

The rationale was that it is what the ACPI 5.0 specification requires: the
parent device cannot be lower power states than its children.

However, it looks like Windows can put the I2C controller device to low
power states independently of its children power states, just like Linux
does.

This patch series only adds I2C and SPI devices to the ACPI power domain
and make sure that the parent device power state is ignored when
transitioning child device to a different power states.

Since patches [2-3/3] depend on patch [1/3] it would be good if these all
could be merged together.

[1] http://lwn.net/Articles/568961/

Lv Zheng (1):
  i2c: attach/detach I2C client device to the ACPI power domain

Mika Westerberg (2):
  ACPI / PM: allow child devices to ignore parent power state
  spi: attach/detach SPI device to the ACPI power domain

 drivers/acpi/device_pm.c |  8 +++++---
 drivers/i2c/i2c-core.c   | 10 ++++++++++
 drivers/spi/spi.c        | 20 ++++++++++++++++++--
 include/acpi/acpi_bus.h  |  3 ++-
 4 files changed, 35 insertions(+), 6 deletions(-)

-- 
1.8.4.rc3

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

* [PATCH 1/3] ACPI / PM: allow child devices to ignore parent power state
  2013-10-09 14:04 [PATCH 0/3] ACPI power management support for I2C and SPI devices Mika Westerberg
@ 2013-10-09 14:04 ` Mika Westerberg
       [not found] ` <1381327461-10562-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2013-10-09 14:04 UTC (permalink / raw)
  To: linux-acpi
  Cc: Wolfram Sang, Mark Brown, Rafael J. Wysocki, Aaron Lu, Lv Zheng,
	Mika Westerberg, linux-i2c, linux-kernel

Some serial buses like I2C and SPI don't require that the parent device is
in D0 before any of its children transitions to D0, but instead the parent
device can control its own power independently from the children.

This does not follow the ACPI specification as it requires the parent to be
powered on before its children. However, Windows seems to ignore this
requirement so I think we can do the same in Linux.

Implement this by adding a new power flag 'ignore_parent' to struct
acpi_device.  If this flag is set the ACPI core ignores checking of the
parent device power state when the device is powered on/off.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/acpi/device_pm.c | 8 +++++---
 include/acpi/acpi_bus.h  | 3 ++-
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 59d3202..ca723a4 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -118,9 +118,10 @@ int acpi_device_get_power(struct acpi_device *device, int *state)
 	/*
 	 * If we were unsure about the device parent's power state up to this
 	 * point, the fact that the device is in D0 implies that the parent has
-	 * to be in D0 too.
+	 * to be in D0 too, except if ignore_parent is set.
 	 */
-	if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN
+	if (!device->power.flags.ignore_parent && device->parent
+	    && device->parent->power.state == ACPI_STATE_UNKNOWN
 	    && result == ACPI_STATE_D0)
 		device->parent->power.state = ACPI_STATE_D0;
 
@@ -177,7 +178,8 @@ int acpi_device_set_power(struct acpi_device *device, int state)
 			 acpi_power_state_string(state));
 		return -ENODEV;
 	}
-	if (device->parent && (state < device->parent->power.state)) {
+	if (!device->power.flags.ignore_parent &&
+	    device->parent && (state < device->parent->power.state)) {
 		dev_warn(&device->dev,
 			 "Cannot transition to power state %s for parent in %s\n",
 			 acpi_power_state_string(state),
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 02e113b..e830ab0 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -222,7 +222,8 @@ struct acpi_device_power_flags {
 	u32 power_resources:1;	/* Power resources */
 	u32 inrush_current:1;	/* Serialize Dx->D0 */
 	u32 power_removed:1;	/* Optimize Dx->D0 */
-	u32 reserved:28;
+	u32 ignore_parent:1;	/* Power is independent of parent power state */
+	u32 reserved:27;
 };
 
 struct acpi_device_power_state {
-- 
1.8.4.rc3

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

* [PATCH 2/3] i2c: attach/detach I2C client device to the ACPI power domain
       [not found] ` <1381327461-10562-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
@ 2013-10-09 14:04   ` Mika Westerberg
  2013-10-10  8:09     ` Wolfram Sang
  0 siblings, 1 reply; 14+ messages in thread
From: Mika Westerberg @ 2013-10-09 14:04 UTC (permalink / raw)
  To: linux-acpi-u79uwXL29TY76Z2rM5mHXA
  Cc: Wolfram Sang, Mark Brown, Rafael J. Wysocki, Aaron Lu, Lv Zheng,
	Mika Westerberg, linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

From: Lv Zheng <lv.zheng-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>

If the I2C client device is enumerated from ACPI namespace it might have
ACPI methods that needs to be called in order to transition the device to
different power states (such as _PSx).

Implement this for I2C client devices by checking if the device has an ACPI
handle and if that's the case, attach it to the ACPI power domain. In
addition we make sure that the device is fully powered when its ->probe()
function gets called.

For non-ACPI devices this patch is a no-op.

Signed-off-by: Lv Zheng <lv.zheng-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
 drivers/i2c/i2c-core.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 29d3f04..f25dee3 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -254,10 +254,16 @@ static int i2c_device_probe(struct device *dev)
 					client->flags & I2C_CLIENT_WAKE);
 	dev_dbg(dev, "probe\n");
 
+	if (ACPI_HANDLE(&client->dev))
+		acpi_dev_pm_attach(&client->dev, true);
+
 	status = driver->probe(client, i2c_match_id(driver->id_table, client));
 	if (status) {
 		client->driver = NULL;
 		i2c_set_clientdata(client, NULL);
+
+		if (ACPI_HANDLE(&client->dev))
+			acpi_dev_pm_detach(&client->dev, true);
 	}
 	return status;
 }
@@ -283,6 +289,8 @@ static int i2c_device_remove(struct device *dev)
 		client->driver = NULL;
 		i2c_set_clientdata(client, NULL);
 	}
+	if (ACPI_HANDLE(&client->dev))
+		acpi_dev_pm_detach(&client->dev, true);
 	return status;
 }
 
@@ -1111,8 +1119,10 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
 	if (ret < 0 || !info.addr)
 		return AE_OK;
 
+	adev->power.flags.ignore_parent = true;
 	strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type));
 	if (!i2c_new_device(adapter, &info)) {
+		adev->power.flags.ignore_parent = false;
 		dev_err(&adapter->dev,
 			"failed to add I2C device %s from ACPI\n",
 			dev_name(&adev->dev));
-- 
1.8.4.rc3

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

* [PATCH 3/3] spi: attach/detach SPI device to the ACPI power domain
  2013-10-09 14:04 [PATCH 0/3] ACPI power management support for I2C and SPI devices Mika Westerberg
  2013-10-09 14:04 ` [PATCH 1/3] ACPI / PM: allow child devices to ignore parent power state Mika Westerberg
       [not found] ` <1381327461-10562-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
@ 2013-10-09 14:04 ` Mika Westerberg
       [not found]   ` <1381327461-10562-4-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
  2013-10-10 10:28 ` [PATCH v2 0/3] ACPI power management support for I2C and SPI devices Mika Westerberg
  3 siblings, 1 reply; 14+ messages in thread
From: Mika Westerberg @ 2013-10-09 14:04 UTC (permalink / raw)
  To: linux-acpi
  Cc: Wolfram Sang, Mark Brown, Rafael J. Wysocki, Aaron Lu, Lv Zheng,
	Mika Westerberg, linux-i2c, linux-kernel

If the SPI device is enumerated from ACPI namespace (it has an ACPI handle)
it might have ACPI methods that needs to be called in order to transition
the device to different power states (such as _PSx).

We follow what has been done for platform and I2C buses here and attach the
SPI device to the ACPI power domain if the device has an ACPI handle. This
makes sure that the device is powered on when its ->probe() is called.

For non-ACPI devices this patch is a no-op.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/spi/spi.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 9e039c6..c522aa1 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -240,15 +240,29 @@ EXPORT_SYMBOL_GPL(spi_bus_type);
 static int spi_drv_probe(struct device *dev)
 {
 	const struct spi_driver		*sdrv = to_spi_driver(dev->driver);
+	struct spi_device		*spi = to_spi_device(dev);
+	int ret;
+
+	if (ACPI_HANDLE(&spi->dev))
+		acpi_dev_pm_attach(&spi->dev, true);
+	ret = sdrv->probe(spi);
+	if (ret && ACPI_HANDLE(&spi->dev))
+		acpi_dev_pm_detach(&spi->dev, true);
 
-	return sdrv->probe(to_spi_device(dev));
+	return ret;
 }
 
 static int spi_drv_remove(struct device *dev)
 {
 	const struct spi_driver		*sdrv = to_spi_driver(dev->driver);
+	struct spi_device		*spi = to_spi_device(dev);
+	int ret;
+
+	ret = sdrv->remove(spi);
+	if (ACPI_HANDLE(&spi->dev))
+		acpi_dev_pm_detach(&spi->dev, true);
 
-	return sdrv->remove(to_spi_device(dev));
+	return ret;
 }
 
 static void spi_drv_shutdown(struct device *dev)
@@ -1025,8 +1039,10 @@ static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level,
 		return AE_OK;
 	}
 
+	adev->power.flags.ignore_parent = true;
 	strlcpy(spi->modalias, dev_name(&adev->dev), sizeof(spi->modalias));
 	if (spi_add_device(spi)) {
+		adev->power.flags.ignore_parent = false;
 		dev_err(&master->dev, "failed to add SPI device %s from ACPI\n",
 			dev_name(&adev->dev));
 		spi_dev_put(spi);
-- 
1.8.4.rc3

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

* Re: [PATCH 3/3] spi: attach/detach SPI device to the ACPI power domain
       [not found]   ` <1381327461-10562-4-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
@ 2013-10-09 17:55     ` Mark Brown
  2013-10-10  6:12       ` Mika Westerberg
  0 siblings, 1 reply; 14+ messages in thread
From: Mark Brown @ 2013-10-09 17:55 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-acpi-u79uwXL29TY76Z2rM5mHXA, Wolfram Sang,
	Rafael J. Wysocki, Aaron Lu, Lv Zheng,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 578 bytes --]

On Wed, Oct 09, 2013 at 05:04:21PM +0300, Mika Westerberg wrote:
> If the SPI device is enumerated from ACPI namespace (it has an ACPI handle)
> it might have ACPI methods that needs to be called in order to transition
> the device to different power states (such as _PSx).

Acked-by: Mark Brown <broonie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>

> +	if (ACPI_HANDLE(&spi->dev))
> +		acpi_dev_pm_attach(&spi->dev, true);

Though I do wonder if it wouldn't be sensible to push the if () here
inside acpi_dev_pm_attach() and similarly for _detach().  Terribly
trivial either way.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 3/3] spi: attach/detach SPI device to the ACPI power domain
  2013-10-09 17:55     ` Mark Brown
@ 2013-10-10  6:12       ` Mika Westerberg
       [not found]         ` <20131010061256.GB3521-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Mika Westerberg @ 2013-10-10  6:12 UTC (permalink / raw)
  To: Mark Brown
  Cc: linux-acpi, Wolfram Sang, Rafael J. Wysocki, Aaron Lu, Lv Zheng,
	linux-i2c, linux-kernel

On Wed, Oct 09, 2013 at 06:55:28PM +0100, Mark Brown wrote:
> On Wed, Oct 09, 2013 at 05:04:21PM +0300, Mika Westerberg wrote:
> > If the SPI device is enumerated from ACPI namespace (it has an ACPI handle)
> > it might have ACPI methods that needs to be called in order to transition
> > the device to different power states (such as _PSx).
> 
> Acked-by: Mark Brown <broonie@linaro.org>

Thanks!

> > +	if (ACPI_HANDLE(&spi->dev))
> > +		acpi_dev_pm_attach(&spi->dev, true);
> 
> Though I do wonder if it wouldn't be sensible to push the if () here
> inside acpi_dev_pm_attach() and similarly for _detach().  Terribly
> trivial either way.

Actually, the check is already there in acpi_dev_pm_attach()/detach(). The
above code follows what Rafael did for platform bus previously. I think the
idea is to have visual hint that this is only for ACPI enumerated devices.

If preferred, I can drop the if() checks, though.

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

* Re: [PATCH 2/3] i2c: attach/detach I2C client device to the ACPI power domain
  2013-10-09 14:04   ` [PATCH 2/3] i2c: attach/detach I2C client device to the ACPI power domain Mika Westerberg
@ 2013-10-10  8:09     ` Wolfram Sang
  2013-10-10  8:26       ` Mika Westerberg
  0 siblings, 1 reply; 14+ messages in thread
From: Wolfram Sang @ 2013-10-10  8:09 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-acpi, Mark Brown, Rafael J. Wysocki, Aaron Lu, Lv Zheng,
	linux-i2c, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1388 bytes --]

On Wed, Oct 09, 2013 at 05:04:20PM +0300, Mika Westerberg wrote:
> From: Lv Zheng <lv.zheng@intel.com>
> 
> If the I2C client device is enumerated from ACPI namespace it might have
> ACPI methods that needs to be called in order to transition the device to
> different power states (such as _PSx).
> 
> Implement this for I2C client devices by checking if the device has an ACPI
> handle and if that's the case, attach it to the ACPI power domain. In
> addition we make sure that the device is fully powered when its ->probe()
> function gets called.
> 
> For non-ACPI devices this patch is a no-op.
> 
> Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> ---
>  drivers/i2c/i2c-core.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> index 29d3f04..f25dee3 100644
> --- a/drivers/i2c/i2c-core.c
> +++ b/drivers/i2c/i2c-core.c
> @@ -254,10 +254,16 @@ static int i2c_device_probe(struct device *dev)
>  					client->flags & I2C_CLIENT_WAKE);
>  	dev_dbg(dev, "probe\n");
>  
> +	if (ACPI_HANDLE(&client->dev))
> +		acpi_dev_pm_attach(&client->dev, true);

I'd prefer to drop the 'if's in case they are checked inside the acpi_*
calls anyway. Not a show-stopper, though, so:

Acked-by: Wolfram Sang <wsa@the-dreams.de>


[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [PATCH 2/3] i2c: attach/detach I2C client device to the ACPI power domain
  2013-10-10  8:09     ` Wolfram Sang
@ 2013-10-10  8:26       ` Mika Westerberg
  0 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2013-10-10  8:26 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: linux-acpi, Mark Brown, Rafael J. Wysocki, Aaron Lu, Lv Zheng,
	linux-i2c, linux-kernel

On Thu, Oct 10, 2013 at 10:09:19AM +0200, Wolfram Sang wrote:
> On Wed, Oct 09, 2013 at 05:04:20PM +0300, Mika Westerberg wrote:
> > From: Lv Zheng <lv.zheng@intel.com>
> > 
> > If the I2C client device is enumerated from ACPI namespace it might have
> > ACPI methods that needs to be called in order to transition the device to
> > different power states (such as _PSx).
> > 
> > Implement this for I2C client devices by checking if the device has an ACPI
> > handle and if that's the case, attach it to the ACPI power domain. In
> > addition we make sure that the device is fully powered when its ->probe()
> > function gets called.
> > 
> > For non-ACPI devices this patch is a no-op.
> > 
> > Signed-off-by: Lv Zheng <lv.zheng@intel.com>
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > ---
> >  drivers/i2c/i2c-core.c | 10 ++++++++++
> >  1 file changed, 10 insertions(+)
> > 
> > diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> > index 29d3f04..f25dee3 100644
> > --- a/drivers/i2c/i2c-core.c
> > +++ b/drivers/i2c/i2c-core.c
> > @@ -254,10 +254,16 @@ static int i2c_device_probe(struct device *dev)
> >  					client->flags & I2C_CLIENT_WAKE);
> >  	dev_dbg(dev, "probe\n");
> >  
> > +	if (ACPI_HANDLE(&client->dev))
> > +		acpi_dev_pm_attach(&client->dev, true);
> 
> I'd prefer to drop the 'if's in case they are checked inside the acpi_*
> calls anyway. Not a show-stopper, though, so:

OK, I'll drop them then from the final version.

> Acked-by: Wolfram Sang <wsa@the-dreams.de>
> 

Thanks!

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

* Re: [PATCH 3/3] spi: attach/detach SPI device to the ACPI power domain
       [not found]         ` <20131010061256.GB3521-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
@ 2013-10-10  9:38           ` Mark Brown
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Brown @ 2013-10-10  9:38 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-acpi-u79uwXL29TY76Z2rM5mHXA, Wolfram Sang,
	Rafael J. Wysocki, Aaron Lu, Lv Zheng,
	linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 820 bytes --]

On Thu, Oct 10, 2013 at 09:12:56AM +0300, Mika Westerberg wrote:
> On Wed, Oct 09, 2013 at 06:55:28PM +0100, Mark Brown wrote:
> > On Wed, Oct 09, 2013 at 05:04:21PM +0300, Mika Westerberg wrote:

> > > +	if (ACPI_HANDLE(&spi->dev))
> > > +		acpi_dev_pm_attach(&spi->dev, true);

> > Though I do wonder if it wouldn't be sensible to push the if () here
> > inside acpi_dev_pm_attach() and similarly for _detach().  Terribly
> > trivial either way.

> Actually, the check is already there in acpi_dev_pm_attach()/detach(). The
> above code follows what Rafael did for platform bus previously. I think the
> idea is to have visual hint that this is only for ACPI enumerated devices.

> If preferred, I can drop the if() checks, though.

It'd seem neater - the fact that the function is acpi_ ought to be
enough of a hint.

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* [PATCH v2 0/3] ACPI power management support for I2C and SPI devices
  2013-10-09 14:04 [PATCH 0/3] ACPI power management support for I2C and SPI devices Mika Westerberg
                   ` (2 preceding siblings ...)
  2013-10-09 14:04 ` [PATCH 3/3] spi: attach/detach SPI " Mika Westerberg
@ 2013-10-10 10:28 ` Mika Westerberg
  2013-10-10 10:28   ` [PATCH v2 1/3] ACPI / PM: allow child devices to ignore parent power state Mika Westerberg
                     ` (2 more replies)
  3 siblings, 3 replies; 14+ messages in thread
From: Mika Westerberg @ 2013-10-10 10:28 UTC (permalink / raw)
  To: linux-acpi
  Cc: Rafael J. Wysocki, Wolfram Sang, Mark Brown, Aaron Lu, Lv Zheng,
	Mika Westerberg, linux-i2c, linux-kernel

Here is an updated version. I added acks from Mark and Wolfram and dropped
if (ACPI_HANDLE()) checks as requested. This is already handled by
acpi_dev_pm_attach()/detach().

Rafael,

If you are OK with these, could you merge the series to your ACPI tree?

Thanks!

Lv Zheng (1):
  i2c: attach/detach I2C client device to the ACPI power domain

Mika Westerberg (2):
  ACPI / PM: allow child devices to ignore parent power state
  spi: attach/detach SPI device to the ACPI power domain

 drivers/acpi/device_pm.c |  8 +++++---
 drivers/i2c/i2c-core.c   |  5 +++++
 drivers/spi/spi.c        | 18 ++++++++++++++++--
 include/acpi/acpi_bus.h  |  3 ++-
 4 files changed, 28 insertions(+), 6 deletions(-)

-- 
1.8.4.rc3

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

* [PATCH v2 1/3] ACPI / PM: allow child devices to ignore parent power state
  2013-10-10 10:28 ` [PATCH v2 0/3] ACPI power management support for I2C and SPI devices Mika Westerberg
@ 2013-10-10 10:28   ` Mika Westerberg
  2013-10-10 10:28   ` [PATCH v2 2/3] i2c: attach/detach I2C client device to the ACPI power domain Mika Westerberg
       [not found]   ` <1381400928-2689-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
  2 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2013-10-10 10:28 UTC (permalink / raw)
  To: linux-acpi
  Cc: Rafael J. Wysocki, Wolfram Sang, Mark Brown, Aaron Lu, Lv Zheng,
	Mika Westerberg, linux-i2c, linux-kernel

Some serial buses like I2C and SPI don't require that the parent device is
in D0 before any of its children transitions to D0, but instead the parent
device can control its own power independently from the children.

This does not follow the ACPI specification as it requires the parent to be
powered on before its children. However, Windows seems to ignore this
requirement so I think we can do the same in Linux.

Implement this by adding a new power flag 'ignore_parent' to struct
acpi_device.  If this flag is set the ACPI core ignores checking of the
parent device power state when the device is powered on/off.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/acpi/device_pm.c | 8 +++++---
 include/acpi/acpi_bus.h  | 3 ++-
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
index 59d3202..ca723a4 100644
--- a/drivers/acpi/device_pm.c
+++ b/drivers/acpi/device_pm.c
@@ -118,9 +118,10 @@ int acpi_device_get_power(struct acpi_device *device, int *state)
 	/*
 	 * If we were unsure about the device parent's power state up to this
 	 * point, the fact that the device is in D0 implies that the parent has
-	 * to be in D0 too.
+	 * to be in D0 too, except if ignore_parent is set.
 	 */
-	if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN
+	if (!device->power.flags.ignore_parent && device->parent
+	    && device->parent->power.state == ACPI_STATE_UNKNOWN
 	    && result == ACPI_STATE_D0)
 		device->parent->power.state = ACPI_STATE_D0;
 
@@ -177,7 +178,8 @@ int acpi_device_set_power(struct acpi_device *device, int state)
 			 acpi_power_state_string(state));
 		return -ENODEV;
 	}
-	if (device->parent && (state < device->parent->power.state)) {
+	if (!device->power.flags.ignore_parent &&
+	    device->parent && (state < device->parent->power.state)) {
 		dev_warn(&device->dev,
 			 "Cannot transition to power state %s for parent in %s\n",
 			 acpi_power_state_string(state),
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 02e113b..e830ab0 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -222,7 +222,8 @@ struct acpi_device_power_flags {
 	u32 power_resources:1;	/* Power resources */
 	u32 inrush_current:1;	/* Serialize Dx->D0 */
 	u32 power_removed:1;	/* Optimize Dx->D0 */
-	u32 reserved:28;
+	u32 ignore_parent:1;	/* Power is independent of parent power state */
+	u32 reserved:27;
 };
 
 struct acpi_device_power_state {
-- 
1.8.4.rc3

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

* [PATCH v2 2/3] i2c: attach/detach I2C client device to the ACPI power domain
  2013-10-10 10:28 ` [PATCH v2 0/3] ACPI power management support for I2C and SPI devices Mika Westerberg
  2013-10-10 10:28   ` [PATCH v2 1/3] ACPI / PM: allow child devices to ignore parent power state Mika Westerberg
@ 2013-10-10 10:28   ` Mika Westerberg
       [not found]   ` <1381400928-2689-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
  2 siblings, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2013-10-10 10:28 UTC (permalink / raw)
  To: linux-acpi
  Cc: Rafael J. Wysocki, Wolfram Sang, Mark Brown, Aaron Lu, Lv Zheng,
	Mika Westerberg, linux-i2c, linux-kernel

From: Lv Zheng <lv.zheng@intel.com>

If the I2C client device is enumerated from ACPI namespace it might have
ACPI methods that needs to be called in order to transition the device to
different power states (such as _PSx).

Implement this for I2C client devices by checking if the device has an ACPI
handle and if that's the case, attach it to the ACPI power domain. In
addition we make sure that the device is fully powered when its ->probe()
function gets called.

For non-ACPI devices this patch is a no-op.

Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Acked-by: Wolfram Sang <wsa@the-dreams.de>
---
 drivers/i2c/i2c-core.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 29d3f04..03a8ae6 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -254,10 +254,12 @@ static int i2c_device_probe(struct device *dev)
 					client->flags & I2C_CLIENT_WAKE);
 	dev_dbg(dev, "probe\n");
 
+	acpi_dev_pm_attach(&client->dev, true);
 	status = driver->probe(client, i2c_match_id(driver->id_table, client));
 	if (status) {
 		client->driver = NULL;
 		i2c_set_clientdata(client, NULL);
+		acpi_dev_pm_detach(&client->dev, true);
 	}
 	return status;
 }
@@ -283,6 +285,7 @@ static int i2c_device_remove(struct device *dev)
 		client->driver = NULL;
 		i2c_set_clientdata(client, NULL);
 	}
+	acpi_dev_pm_detach(&client->dev, true);
 	return status;
 }
 
@@ -1111,8 +1114,10 @@ static acpi_status acpi_i2c_add_device(acpi_handle handle, u32 level,
 	if (ret < 0 || !info.addr)
 		return AE_OK;
 
+	adev->power.flags.ignore_parent = true;
 	strlcpy(info.type, dev_name(&adev->dev), sizeof(info.type));
 	if (!i2c_new_device(adapter, &info)) {
+		adev->power.flags.ignore_parent = false;
 		dev_err(&adapter->dev,
 			"failed to add I2C device %s from ACPI\n",
 			dev_name(&adev->dev));
-- 
1.8.4.rc3

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

* [PATCH v2 3/3] spi: attach/detach SPI device to the ACPI power domain
       [not found]   ` <1381400928-2689-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
@ 2013-10-10 10:28     ` Mika Westerberg
  2013-10-10 13:02     ` [PATCH v2 0/3] ACPI power management support for I2C and SPI devices Rafael J. Wysocki
  1 sibling, 0 replies; 14+ messages in thread
From: Mika Westerberg @ 2013-10-10 10:28 UTC (permalink / raw)
  To: linux-acpi-u79uwXL29TY76Z2rM5mHXA
  Cc: Rafael J. Wysocki, Wolfram Sang, Mark Brown, Aaron Lu, Lv Zheng,
	Mika Westerberg, linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

If the SPI device is enumerated from ACPI namespace (it has an ACPI handle)
it might have ACPI methods that needs to be called in order to transition
the device to different power states (such as _PSx).

We follow what has been done for platform and I2C buses here and attach the
SPI device to the ACPI power domain if the device has an ACPI handle. This
makes sure that the device is powered on when its ->probe() is called.

For non-ACPI devices this patch is a no-op.

Signed-off-by: Mika Westerberg <mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Acked-by: Mark Brown <broonie-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
---
 drivers/spi/spi.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 9e039c6..740f9dd 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -240,15 +240,27 @@ EXPORT_SYMBOL_GPL(spi_bus_type);
 static int spi_drv_probe(struct device *dev)
 {
 	const struct spi_driver		*sdrv = to_spi_driver(dev->driver);
+	struct spi_device		*spi = to_spi_device(dev);
+	int ret;
+
+	acpi_dev_pm_attach(&spi->dev, true);
+	ret = sdrv->probe(spi);
+	if (ret)
+		acpi_dev_pm_detach(&spi->dev, true);
 
-	return sdrv->probe(to_spi_device(dev));
+	return ret;
 }
 
 static int spi_drv_remove(struct device *dev)
 {
 	const struct spi_driver		*sdrv = to_spi_driver(dev->driver);
+	struct spi_device		*spi = to_spi_device(dev);
+	int ret;
+
+	ret = sdrv->remove(spi);
+	acpi_dev_pm_detach(&spi->dev, true);
 
-	return sdrv->remove(to_spi_device(dev));
+	return ret;
 }
 
 static void spi_drv_shutdown(struct device *dev)
@@ -1025,8 +1037,10 @@ static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level,
 		return AE_OK;
 	}
 
+	adev->power.flags.ignore_parent = true;
 	strlcpy(spi->modalias, dev_name(&adev->dev), sizeof(spi->modalias));
 	if (spi_add_device(spi)) {
+		adev->power.flags.ignore_parent = false;
 		dev_err(&master->dev, "failed to add SPI device %s from ACPI\n",
 			dev_name(&adev->dev));
 		spi_dev_put(spi);
-- 
1.8.4.rc3

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

* Re: [PATCH v2 0/3] ACPI power management support for I2C and SPI devices
       [not found]   ` <1381400928-2689-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
  2013-10-10 10:28     ` [PATCH v2 3/3] spi: attach/detach SPI " Mika Westerberg
@ 2013-10-10 13:02     ` Rafael J. Wysocki
  1 sibling, 0 replies; 14+ messages in thread
From: Rafael J. Wysocki @ 2013-10-10 13:02 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-acpi-u79uwXL29TY76Z2rM5mHXA, Wolfram Sang, Mark Brown,
	Aaron Lu, Lv Zheng, linux-i2c-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

On Thursday, October 10, 2013 01:28:45 PM Mika Westerberg wrote:
> Here is an updated version. I added acks from Mark and Wolfram and dropped
> if (ACPI_HANDLE()) checks as requested. This is already handled by
> acpi_dev_pm_attach()/detach().
> 
> Rafael,
> 
> If you are OK with these, could you merge the series to your ACPI tree?
> 
> Thanks!

I will, thanks!

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

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

end of thread, other threads:[~2013-10-10 13:02 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-09 14:04 [PATCH 0/3] ACPI power management support for I2C and SPI devices Mika Westerberg
2013-10-09 14:04 ` [PATCH 1/3] ACPI / PM: allow child devices to ignore parent power state Mika Westerberg
     [not found] ` <1381327461-10562-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2013-10-09 14:04   ` [PATCH 2/3] i2c: attach/detach I2C client device to the ACPI power domain Mika Westerberg
2013-10-10  8:09     ` Wolfram Sang
2013-10-10  8:26       ` Mika Westerberg
2013-10-09 14:04 ` [PATCH 3/3] spi: attach/detach SPI " Mika Westerberg
     [not found]   ` <1381327461-10562-4-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2013-10-09 17:55     ` Mark Brown
2013-10-10  6:12       ` Mika Westerberg
     [not found]         ` <20131010061256.GB3521-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2013-10-10  9:38           ` Mark Brown
2013-10-10 10:28 ` [PATCH v2 0/3] ACPI power management support for I2C and SPI devices Mika Westerberg
2013-10-10 10:28   ` [PATCH v2 1/3] ACPI / PM: allow child devices to ignore parent power state Mika Westerberg
2013-10-10 10:28   ` [PATCH v2 2/3] i2c: attach/detach I2C client device to the ACPI power domain Mika Westerberg
     [not found]   ` <1381400928-2689-1-git-send-email-mika.westerberg-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2013-10-10 10:28     ` [PATCH v2 3/3] spi: attach/detach SPI " Mika Westerberg
2013-10-10 13:02     ` [PATCH v2 0/3] ACPI power management support for I2C and SPI devices 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;
as well as URLs for NNTP newsgroup(s).