linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/2] runtime PM support for I2C clients
@ 2013-08-20 14:03 Mika Westerberg
  2013-08-20 14:03 ` [RFC PATCH 1/2] i2c: prepare runtime PM support for I2C client devices Mika Westerberg
  2013-08-20 14:03 ` [RFC PATCH 2/2] i2c: attach/detach I2C client device to the ACPI power domain Mika Westerberg
  0 siblings, 2 replies; 7+ messages in thread
From: Mika Westerberg @ 2013-08-20 14:03 UTC (permalink / raw)
  To: linux-i2c
  Cc: Wolfram Sang, Rafael J. Wysocki, linux-acpi, linux-kernel,
	Lv Zheng, Aaron Lu, Mika Westerberg

Hi all,

With the advent of ACPI 5.0 we are starting to see I2C client devices
described in ACPI namespace that support power management by the means of
standard ACPI _PSx-methods. For example Intel Haswell based platforms might
have touch screen or sensor-hub connected to the I2C bus that can be
powered on and off by calling _PS0 and _PS3 -methods.

In order to support such I2C client devices, we decided to hook the ACPI
power management for these to the standard Linux runtime PM framework.

These patches implement runtime PM support for I2C client devices in a
similar way that is done already for the PCI bus. Just before a driver is
bound to an I2C client device the device runtime PM is being prepared for
that device.

If the device in question has an ACPI handle we attach it to the ACPI power
domain that then makes sure that the right _PSx methods are called in
response to runtime PM events the driver generates.

A driver that wants to participate in runtime PM and power manage its
device should:
 1) Implement device specific runtime PM callbacks if needed.
 2) Call pm_runtime_put() (or some variant of that) to decrease the runtime
    PM reference count.

If the driver doesn't do anything the device is regarded as runtime PM
active and powered on.

Even though this series has been developed specifically for ACPI enumerated
I2C client devices, I believe it can be useful for other I2C client drivers
because the I2C core now prepares the runtime PM on behalf of the driver
and thus reduces the amount of code a driver writer needs to add.

Aaron Lu (1):
  i2c: prepare runtime PM support for I2C client devices

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

 drivers/i2c/i2c-core.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 56 insertions(+), 1 deletion(-)

-- 
1.8.4.rc2


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

* [RFC PATCH 1/2] i2c: prepare runtime PM support for I2C client devices
  2013-08-20 14:03 [RFC PATCH 0/2] runtime PM support for I2C clients Mika Westerberg
@ 2013-08-20 14:03 ` Mika Westerberg
  2013-08-20 14:16   ` Rafael J. Wysocki
  2013-08-28  9:38   ` Wolfram Sang
  2013-08-20 14:03 ` [RFC PATCH 2/2] i2c: attach/detach I2C client device to the ACPI power domain Mika Westerberg
  1 sibling, 2 replies; 7+ messages in thread
From: Mika Westerberg @ 2013-08-20 14:03 UTC (permalink / raw)
  To: linux-i2c
  Cc: Wolfram Sang, Rafael J. Wysocki, linux-acpi, linux-kernel,
	Lv Zheng, Aaron Lu, Mika Westerberg

From: Aaron Lu <aaron.lu@intel.com>

This patch adds runtime PM support for the I2C bus in a similar way that
has been done for PCI bus already. This means that the I2C bus core
prepares runtime PM for a client device just before a driver is about to be
bound to it. Devices that are not bound to any driver are not prepared for
runtime PM.

In order to take advantage of this runtime PM support, the client device
driver needs drop the device runtime PM reference count by calling
pm_runtime_put() in its ->probe() callback and possibly implement rest of
the runtime PM callbacks.

However, this does not yet make runtime PM happen for the device, it has to
be explicitly allowed from userspace per each I2C client device. The
reason for this is that things like HID over I2C might not work as smoothly
when runtime PM is active. So we leave it to the user to balance between
performance and power efficiency.

User can allow runtime PM for the client device by running:

	# echo auto > /sys/bus/i2c/devices/<device>/power/control

and it can be forbidden again by:

	# echo on > /sys/bus/i2c/devices/<device>/power/control

Status of the device can be monitored by reading files under the device
power directory.

If the driver doesn't support runtime PM (like most of the existing I2C
client drivers), the device in question is regarded as being runtime PM
active and powered on.

The patch adds also runtime PM support for the adapter device because it is
needed to be able to runtime power manage the I2C controller device. The
adapter device is handled along with the I2C controller device (it uses
pm_runtime_no_callbacks()).

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/i2c/i2c-core.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 3d44292..8fad5ac 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -254,11 +254,34 @@ static int i2c_device_probe(struct device *dev)
 					client->flags & I2C_CLIENT_WAKE);
 	dev_dbg(dev, "probe\n");
 
+	/* Make sure the adapter is active */
+	pm_runtime_get_sync(&client->adapter->dev);
+
+	/*
+	 * Enable runtime PM for the client device. If the client wants to
+	 * participate on runtime PM it should call pm_runtime_put() in its
+	 * probe() callback.
+	 *
+	 * User still needs to allow the PM runtime before it can actually
+	 * happen.
+	 */
+	pm_runtime_forbid(&client->dev);
+	pm_runtime_get_noresume(&client->dev);
+	pm_runtime_set_active(&client->dev);
+	pm_runtime_enable(&client->dev);
+
 	status = driver->probe(client, i2c_match_id(driver->id_table, client));
 	if (status) {
 		client->driver = NULL;
 		i2c_set_clientdata(client, NULL);
+
+		pm_runtime_disable(&client->dev);
+		pm_runtime_set_suspended(&client->dev);
+		pm_runtime_put_noidle(&client->dev);
 	}
+
+	pm_runtime_put(&client->adapter->dev);
+
 	return status;
 }
 
@@ -271,6 +294,8 @@ static int i2c_device_remove(struct device *dev)
 	if (!client || !dev->driver)
 		return 0;
 
+	pm_runtime_get_sync(&client->adapter->dev);
+
 	driver = to_i2c_driver(dev->driver);
 	if (driver->remove) {
 		dev_dbg(dev, "remove\n");
@@ -283,6 +308,13 @@ static int i2c_device_remove(struct device *dev)
 		client->driver = NULL;
 		i2c_set_clientdata(client, NULL);
 	}
+
+	/* Undo the runtime PM done in i2c_probe() */
+	pm_runtime_disable(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
+	pm_runtime_put_noidle(&client->dev);
+
+	pm_runtime_put(&client->adapter->dev);
 	return status;
 }
 
@@ -294,8 +326,11 @@ static void i2c_device_shutdown(struct device *dev)
 	if (!client || !dev->driver)
 		return;
 	driver = to_i2c_driver(dev->driver);
-	if (driver->shutdown)
+	if (driver->shutdown) {
+		pm_runtime_get_sync(&client->adapter->dev);
 		driver->shutdown(client);
+		pm_runtime_put(&client->adapter->dev);
+	}
 }
 
 #ifdef CONFIG_PM_SLEEP
@@ -1263,6 +1298,15 @@ exit_recovery:
 	bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
 	mutex_unlock(&core_lock);
 
+	/*
+	 * Make sure the adapter runtime PM follows the parent device (the
+	 * host controller) so that we can suspend it once there aren't any
+	 * active clients anymore.
+	 */
+	pm_runtime_set_active(&adap->dev);
+	pm_runtime_no_callbacks(&adap->dev);
+	pm_runtime_enable(&adap->dev);
+
 	return 0;
 
 out_list:
@@ -1427,6 +1471,8 @@ void i2c_del_adapter(struct i2c_adapter *adap)
 		return;
 	}
 
+	pm_runtime_disable(&adap->dev);
+
 	/* Tell drivers about this removal */
 	mutex_lock(&core_lock);
 	bus_for_each_drv(&i2c_bus_type, NULL, adap,
-- 
1.8.4.rc2


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

* [RFC PATCH 2/2] i2c: attach/detach I2C client device to the ACPI power domain
  2013-08-20 14:03 [RFC PATCH 0/2] runtime PM support for I2C clients Mika Westerberg
  2013-08-20 14:03 ` [RFC PATCH 1/2] i2c: prepare runtime PM support for I2C client devices Mika Westerberg
@ 2013-08-20 14:03 ` Mika Westerberg
  2013-08-20 14:16   ` Rafael J. Wysocki
  1 sibling, 1 reply; 7+ messages in thread
From: Mika Westerberg @ 2013-08-20 14:03 UTC (permalink / raw)
  To: linux-i2c
  Cc: Wolfram Sang, Rafael J. Wysocki, linux-acpi, linux-kernel,
	Lv Zheng, Aaron Lu, Mika Westerberg

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
a 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 | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 8fad5ac..fdf086b 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -257,6 +257,9 @@ static int i2c_device_probe(struct device *dev)
 	/* Make sure the adapter is active */
 	pm_runtime_get_sync(&client->adapter->dev);
 
+	if (ACPI_HANDLE(&client->dev))
+		acpi_dev_pm_attach(&client->dev, true);
+
 	/*
 	 * Enable runtime PM for the client device. If the client wants to
 	 * participate on runtime PM it should call pm_runtime_put() in its
@@ -278,6 +281,9 @@ static int i2c_device_probe(struct device *dev)
 		pm_runtime_disable(&client->dev);
 		pm_runtime_set_suspended(&client->dev);
 		pm_runtime_put_noidle(&client->dev);
+
+		if (ACPI_HANDLE(&client->dev))
+			acpi_dev_pm_detach(&client->dev, true);
 	}
 
 	pm_runtime_put(&client->adapter->dev);
@@ -314,6 +320,9 @@ static int i2c_device_remove(struct device *dev)
 	pm_runtime_set_suspended(&client->dev);
 	pm_runtime_put_noidle(&client->dev);
 
+	if (ACPI_HANDLE(&client->dev))
+		acpi_dev_pm_detach(&client->dev, true);
+
 	pm_runtime_put(&client->adapter->dev);
 	return status;
 }
-- 
1.8.4.rc2


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

* Re: [RFC PATCH 1/2] i2c: prepare runtime PM support for I2C client devices
  2013-08-20 14:03 ` [RFC PATCH 1/2] i2c: prepare runtime PM support for I2C client devices Mika Westerberg
@ 2013-08-20 14:16   ` Rafael J. Wysocki
  2013-08-28  9:38   ` Wolfram Sang
  1 sibling, 0 replies; 7+ messages in thread
From: Rafael J. Wysocki @ 2013-08-20 14:16 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-i2c, Wolfram Sang, Rafael J. Wysocki, linux-acpi,
	linux-kernel, Lv Zheng, Aaron Lu

On Tuesday, August 20, 2013 05:03:35 PM Mika Westerberg wrote:
> From: Aaron Lu <aaron.lu@intel.com>
> 
> This patch adds runtime PM support for the I2C bus in a similar way that
> has been done for PCI bus already. This means that the I2C bus core
> prepares runtime PM for a client device just before a driver is about to be
> bound to it. Devices that are not bound to any driver are not prepared for
> runtime PM.
> 
> In order to take advantage of this runtime PM support, the client device
> driver needs drop the device runtime PM reference count by calling
> pm_runtime_put() in its ->probe() callback and possibly implement rest of
> the runtime PM callbacks.
> 
> However, this does not yet make runtime PM happen for the device, it has to
> be explicitly allowed from userspace per each I2C client device. The
> reason for this is that things like HID over I2C might not work as smoothly
> when runtime PM is active. So we leave it to the user to balance between
> performance and power efficiency.
> 
> User can allow runtime PM for the client device by running:
> 
> 	# echo auto > /sys/bus/i2c/devices/<device>/power/control
> 
> and it can be forbidden again by:
> 
> 	# echo on > /sys/bus/i2c/devices/<device>/power/control
> 
> Status of the device can be monitored by reading files under the device
> power directory.
> 
> If the driver doesn't support runtime PM (like most of the existing I2C
> client drivers), the device in question is regarded as being runtime PM
> active and powered on.
> 
> The patch adds also runtime PM support for the adapter device because it is
> needed to be able to runtime power manage the I2C controller device. The
> adapter device is handled along with the I2C controller device (it uses
> pm_runtime_no_callbacks()).
> 
> Signed-off-by: Aaron Lu <aaron.lu@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/i2c/i2c-core.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 47 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> index 3d44292..8fad5ac 100644
> --- a/drivers/i2c/i2c-core.c
> +++ b/drivers/i2c/i2c-core.c
> @@ -254,11 +254,34 @@ static int i2c_device_probe(struct device *dev)
>  					client->flags & I2C_CLIENT_WAKE);
>  	dev_dbg(dev, "probe\n");
>  
> +	/* Make sure the adapter is active */
> +	pm_runtime_get_sync(&client->adapter->dev);
> +
> +	/*
> +	 * Enable runtime PM for the client device. If the client wants to
> +	 * participate on runtime PM it should call pm_runtime_put() in its
> +	 * probe() callback.
> +	 *
> +	 * User still needs to allow the PM runtime before it can actually
> +	 * happen.
> +	 */
> +	pm_runtime_forbid(&client->dev);
> +	pm_runtime_get_noresume(&client->dev);
> +	pm_runtime_set_active(&client->dev);
> +	pm_runtime_enable(&client->dev);
> +
>  	status = driver->probe(client, i2c_match_id(driver->id_table, client));
>  	if (status) {
>  		client->driver = NULL;
>  		i2c_set_clientdata(client, NULL);
> +
> +		pm_runtime_disable(&client->dev);
> +		pm_runtime_set_suspended(&client->dev);
> +		pm_runtime_put_noidle(&client->dev);
>  	}
> +
> +	pm_runtime_put(&client->adapter->dev);
> +
>  	return status;
>  }
>  
> @@ -271,6 +294,8 @@ static int i2c_device_remove(struct device *dev)
>  	if (!client || !dev->driver)
>  		return 0;
>  
> +	pm_runtime_get_sync(&client->adapter->dev);
> +
>  	driver = to_i2c_driver(dev->driver);
>  	if (driver->remove) {
>  		dev_dbg(dev, "remove\n");
> @@ -283,6 +308,13 @@ static int i2c_device_remove(struct device *dev)
>  		client->driver = NULL;
>  		i2c_set_clientdata(client, NULL);
>  	}
> +
> +	/* Undo the runtime PM done in i2c_probe() */
> +	pm_runtime_disable(&client->dev);
> +	pm_runtime_set_suspended(&client->dev);
> +	pm_runtime_put_noidle(&client->dev);
> +
> +	pm_runtime_put(&client->adapter->dev);
>  	return status;
>  }
>  
> @@ -294,8 +326,11 @@ static void i2c_device_shutdown(struct device *dev)
>  	if (!client || !dev->driver)
>  		return;
>  	driver = to_i2c_driver(dev->driver);
> -	if (driver->shutdown)
> +	if (driver->shutdown) {
> +		pm_runtime_get_sync(&client->adapter->dev);
>  		driver->shutdown(client);
> +		pm_runtime_put(&client->adapter->dev);
> +	}
>  }
>  
>  #ifdef CONFIG_PM_SLEEP
> @@ -1263,6 +1298,15 @@ exit_recovery:
>  	bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
>  	mutex_unlock(&core_lock);
>  
> +	/*
> +	 * Make sure the adapter runtime PM follows the parent device (the
> +	 * host controller) so that we can suspend it once there aren't any
> +	 * active clients anymore.
> +	 */
> +	pm_runtime_set_active(&adap->dev);
> +	pm_runtime_no_callbacks(&adap->dev);
> +	pm_runtime_enable(&adap->dev);
> +
>  	return 0;
>  
>  out_list:
> @@ -1427,6 +1471,8 @@ void i2c_del_adapter(struct i2c_adapter *adap)
>  		return;
>  	}
>  
> +	pm_runtime_disable(&adap->dev);
> +
>  	/* Tell drivers about this removal */
>  	mutex_lock(&core_lock);
>  	bus_for_each_drv(&i2c_bus_type, NULL, adap,
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

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

On Tuesday, August 20, 2013 05:03:36 PM 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
> a 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: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

> ---
>  drivers/i2c/i2c-core.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> index 8fad5ac..fdf086b 100644
> --- a/drivers/i2c/i2c-core.c
> +++ b/drivers/i2c/i2c-core.c
> @@ -257,6 +257,9 @@ static int i2c_device_probe(struct device *dev)
>  	/* Make sure the adapter is active */
>  	pm_runtime_get_sync(&client->adapter->dev);
>  
> +	if (ACPI_HANDLE(&client->dev))
> +		acpi_dev_pm_attach(&client->dev, true);
> +
>  	/*
>  	 * Enable runtime PM for the client device. If the client wants to
>  	 * participate on runtime PM it should call pm_runtime_put() in its
> @@ -278,6 +281,9 @@ static int i2c_device_probe(struct device *dev)
>  		pm_runtime_disable(&client->dev);
>  		pm_runtime_set_suspended(&client->dev);
>  		pm_runtime_put_noidle(&client->dev);
> +
> +		if (ACPI_HANDLE(&client->dev))
> +			acpi_dev_pm_detach(&client->dev, true);
>  	}
>  
>  	pm_runtime_put(&client->adapter->dev);
> @@ -314,6 +320,9 @@ static int i2c_device_remove(struct device *dev)
>  	pm_runtime_set_suspended(&client->dev);
>  	pm_runtime_put_noidle(&client->dev);
>  
> +	if (ACPI_HANDLE(&client->dev))
> +		acpi_dev_pm_detach(&client->dev, true);
> +
>  	pm_runtime_put(&client->adapter->dev);
>  	return status;
>  }
> 
-- 
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.

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

* Re: [RFC PATCH 1/2] i2c: prepare runtime PM support for I2C client devices
  2013-08-20 14:03 ` [RFC PATCH 1/2] i2c: prepare runtime PM support for I2C client devices Mika Westerberg
  2013-08-20 14:16   ` Rafael J. Wysocki
@ 2013-08-28  9:38   ` Wolfram Sang
  2013-09-02 10:56     ` Mika Westerberg
  1 sibling, 1 reply; 7+ messages in thread
From: Wolfram Sang @ 2013-08-28  9:38 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: linux-i2c, Rafael J. Wysocki, linux-acpi, linux-kernel, Lv Zheng,
	Aaron Lu, linux-arm-kernel

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

On Tue, Aug 20, 2013 at 05:03:35PM +0300, Mika Westerberg wrote:
> From: Aaron Lu <aaron.lu@intel.com>
> 
> This patch adds runtime PM support for the I2C bus in a similar way that
> has been done for PCI bus already. This means that the I2C bus core
> prepares runtime PM for a client device just before a driver is about to be
> bound to it. Devices that are not bound to any driver are not prepared for
> runtime PM.
> 
> In order to take advantage of this runtime PM support, the client device
> driver needs drop the device runtime PM reference count by calling
> pm_runtime_put() in its ->probe() callback and possibly implement rest of
> the runtime PM callbacks.
> 
> However, this does not yet make runtime PM happen for the device, it has to
> be explicitly allowed from userspace per each I2C client device. The
> reason for this is that things like HID over I2C might not work as smoothly
> when runtime PM is active. So we leave it to the user to balance between
> performance and power efficiency.
> 
> User can allow runtime PM for the client device by running:
> 
> 	# echo auto > /sys/bus/i2c/devices/<device>/power/control
> 
> and it can be forbidden again by:
> 
> 	# echo on > /sys/bus/i2c/devices/<device>/power/control
> 
> Status of the device can be monitored by reading files under the device
> power directory.
> 
> If the driver doesn't support runtime PM (like most of the existing I2C
> client drivers), the device in question is regarded as being runtime PM
> active and powered on.
> 
> The patch adds also runtime PM support for the adapter device because it is
> needed to be able to runtime power manage the I2C controller device. The
> adapter device is handled along with the I2C controller device (it uses
> pm_runtime_no_callbacks()).
> 
> Signed-off-by: Aaron Lu <aaron.lu@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

CCing ALKML. Would appreciate comments/tags from the runtime-PM users of
the ARM world.

> ---
>  drivers/i2c/i2c-core.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 47 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> index 3d44292..8fad5ac 100644
> --- a/drivers/i2c/i2c-core.c
> +++ b/drivers/i2c/i2c-core.c
> @@ -254,11 +254,34 @@ static int i2c_device_probe(struct device *dev)
>  					client->flags & I2C_CLIENT_WAKE);
>  	dev_dbg(dev, "probe\n");
>  
> +	/* Make sure the adapter is active */
> +	pm_runtime_get_sync(&client->adapter->dev);
> +
> +	/*
> +	 * Enable runtime PM for the client device. If the client wants to
> +	 * participate on runtime PM it should call pm_runtime_put() in its
> +	 * probe() callback.
> +	 *
> +	 * User still needs to allow the PM runtime before it can actually
> +	 * happen.
> +	 */
> +	pm_runtime_forbid(&client->dev);
> +	pm_runtime_get_noresume(&client->dev);
> +	pm_runtime_set_active(&client->dev);
> +	pm_runtime_enable(&client->dev);
> +
>  	status = driver->probe(client, i2c_match_id(driver->id_table, client));
>  	if (status) {
>  		client->driver = NULL;
>  		i2c_set_clientdata(client, NULL);
> +
> +		pm_runtime_disable(&client->dev);
> +		pm_runtime_set_suspended(&client->dev);
> +		pm_runtime_put_noidle(&client->dev);
>  	}
> +
> +	pm_runtime_put(&client->adapter->dev);
> +
>  	return status;
>  }
>  
> @@ -271,6 +294,8 @@ static int i2c_device_remove(struct device *dev)
>  	if (!client || !dev->driver)
>  		return 0;
>  
> +	pm_runtime_get_sync(&client->adapter->dev);
> +
>  	driver = to_i2c_driver(dev->driver);
>  	if (driver->remove) {
>  		dev_dbg(dev, "remove\n");
> @@ -283,6 +308,13 @@ static int i2c_device_remove(struct device *dev)
>  		client->driver = NULL;
>  		i2c_set_clientdata(client, NULL);
>  	}
> +
> +	/* Undo the runtime PM done in i2c_probe() */
> +	pm_runtime_disable(&client->dev);
> +	pm_runtime_set_suspended(&client->dev);
> +	pm_runtime_put_noidle(&client->dev);
> +
> +	pm_runtime_put(&client->adapter->dev);
>  	return status;
>  }
>  
> @@ -294,8 +326,11 @@ static void i2c_device_shutdown(struct device *dev)
>  	if (!client || !dev->driver)
>  		return;
>  	driver = to_i2c_driver(dev->driver);
> -	if (driver->shutdown)
> +	if (driver->shutdown) {
> +		pm_runtime_get_sync(&client->adapter->dev);
>  		driver->shutdown(client);
> +		pm_runtime_put(&client->adapter->dev);
> +	}
>  }
>  
>  #ifdef CONFIG_PM_SLEEP
> @@ -1263,6 +1298,15 @@ exit_recovery:
>  	bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
>  	mutex_unlock(&core_lock);
>  
> +	/*
> +	 * Make sure the adapter runtime PM follows the parent device (the
> +	 * host controller) so that we can suspend it once there aren't any
> +	 * active clients anymore.
> +	 */
> +	pm_runtime_set_active(&adap->dev);
> +	pm_runtime_no_callbacks(&adap->dev);
> +	pm_runtime_enable(&adap->dev);
> +
>  	return 0;
>  
>  out_list:
> @@ -1427,6 +1471,8 @@ void i2c_del_adapter(struct i2c_adapter *adap)
>  		return;
>  	}
>  
> +	pm_runtime_disable(&adap->dev);
> +
>  	/* Tell drivers about this removal */
>  	mutex_lock(&core_lock);
>  	bus_for_each_drv(&i2c_bus_type, NULL, adap,
> -- 
> 1.8.4.rc2
> 

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

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

* Re: [RFC PATCH 1/2] i2c: prepare runtime PM support for I2C client devices
  2013-08-28  9:38   ` Wolfram Sang
@ 2013-09-02 10:56     ` Mika Westerberg
  0 siblings, 0 replies; 7+ messages in thread
From: Mika Westerberg @ 2013-09-02 10:56 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: linux-i2c, Rafael J. Wysocki, linux-acpi, linux-kernel, Lv Zheng,
	Aaron Lu, linux-arm-kernel

On Wed, Aug 28, 2013 at 11:38:58AM +0200, Wolfram Sang wrote:
> On Tue, Aug 20, 2013 at 05:03:35PM +0300, Mika Westerberg wrote:
> > From: Aaron Lu <aaron.lu@intel.com>
> > 
> > This patch adds runtime PM support for the I2C bus in a similar way that
> > has been done for PCI bus already. This means that the I2C bus core
> > prepares runtime PM for a client device just before a driver is about to be
> > bound to it. Devices that are not bound to any driver are not prepared for
> > runtime PM.
> > 
> > In order to take advantage of this runtime PM support, the client device
> > driver needs drop the device runtime PM reference count by calling
> > pm_runtime_put() in its ->probe() callback and possibly implement rest of
> > the runtime PM callbacks.
> > 
> > However, this does not yet make runtime PM happen for the device, it has to
> > be explicitly allowed from userspace per each I2C client device. The
> > reason for this is that things like HID over I2C might not work as smoothly
> > when runtime PM is active. So we leave it to the user to balance between
> > performance and power efficiency.
> > 
> > User can allow runtime PM for the client device by running:
> > 
> > 	# echo auto > /sys/bus/i2c/devices/<device>/power/control
> > 
> > and it can be forbidden again by:
> > 
> > 	# echo on > /sys/bus/i2c/devices/<device>/power/control
> > 
> > Status of the device can be monitored by reading files under the device
> > power directory.
> > 
> > If the driver doesn't support runtime PM (like most of the existing I2C
> > client drivers), the device in question is regarded as being runtime PM
> > active and powered on.
> > 
> > The patch adds also runtime PM support for the adapter device because it is
> > needed to be able to runtime power manage the I2C controller device. The
> > adapter device is handled along with the I2C controller device (it uses
> > pm_runtime_no_callbacks()).
> > 
> > Signed-off-by: Aaron Lu <aaron.lu@intel.com>
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> CCing ALKML. Would appreciate comments/tags from the runtime-PM users of
> the ARM world.

Any comments on this?

I can resend the whole series with ALKML included if that helps.

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

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

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-20 14:03 [RFC PATCH 0/2] runtime PM support for I2C clients Mika Westerberg
2013-08-20 14:03 ` [RFC PATCH 1/2] i2c: prepare runtime PM support for I2C client devices Mika Westerberg
2013-08-20 14:16   ` Rafael J. Wysocki
2013-08-28  9:38   ` Wolfram Sang
2013-09-02 10:56     ` Mika Westerberg
2013-08-20 14:03 ` [RFC PATCH 2/2] i2c: attach/detach I2C client device to the ACPI power domain Mika Westerberg
2013-08-20 14:16   ` 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).