linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] i2c/at91: add support PM functions
@ 2014-10-20  3:42 Wenyou Yang
  2014-10-20  3:42 ` [PATCH 1/3] i2c/at91: add support for runtime PM Wenyou Yang
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Wenyou Yang @ 2014-10-20  3:42 UTC (permalink / raw)
  To: wsa, ludovic.desroches
  Cc: linux-i2c, linux-kernel, nicolas.ferre, linux-arm-kernel, wenyou.yang

Hi Wolfram,

The patches is to add support to PM functions for the at91 i2c controller.

It is based on the i2c/for-next branch of 
git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git.

Could you help review it?

Best Regards,
Wenyou Yang

Wenyou Yang (3):
  i2c/at91: add support for runtime PM
  i2c/at91: add support for system PM
  i2c/at91: adopt pinctrl support

 drivers/i2c/busses/i2c-at91.c |   86 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 77 insertions(+), 9 deletions(-)

-- 
1.7.9.5


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

* [PATCH 1/3] i2c/at91: add support for runtime PM
  2014-10-20  3:42 [PATCH 0/3] i2c/at91: add support PM functions Wenyou Yang
@ 2014-10-20  3:42 ` Wenyou Yang
  2014-10-20 12:39   ` Ludovic Desroches
  2014-10-20  3:42 ` [PATCH 2/3] i2c/at91: add support for system PM Wenyou Yang
  2014-10-20  3:42 ` [PATCH 3/3] i2c/at91: adopt pinctrl support Wenyou Yang
  2 siblings, 1 reply; 13+ messages in thread
From: Wenyou Yang @ 2014-10-20  3:42 UTC (permalink / raw)
  To: wsa, ludovic.desroches
  Cc: linux-i2c, linux-kernel, nicolas.ferre, linux-arm-kernel, wenyou.yang

Drivers should put the device into low power states proactively whenever the
device is not in use. Thus implement support for runtime PM and use the
autosuspend feature to make sure that we can still perform well in case we see
lots of i2c traffic within short period of time.

Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
---
 drivers/i2c/busses/i2c-at91.c |   48 ++++++++++++++++++++++++++++++++---------
 1 file changed, 38 insertions(+), 10 deletions(-)

diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index 917d545..03b9f48 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -31,10 +31,12 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/platform_data/dma-atmel.h>
+#include <linux/pm_runtime.h>
 
 #define DEFAULT_TWI_CLK_HZ		100000		/* max 400 Kbits/s */
 #define AT91_I2C_TIMEOUT	msecs_to_jiffies(100)	/* transfer timeout */
 #define AT91_I2C_DMA_THRESHOLD	8			/* enable DMA if transfer size is bigger than this threshold */
+#define AUTOSUSPEND_TIMEOUT		2000
 
 /* AT91 TWI register definitions */
 #define	AT91_TWI_CR		0x0000	/* Control Register */
@@ -475,12 +477,16 @@ error:
 static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
 {
 	struct at91_twi_dev *dev = i2c_get_adapdata(adap);
-	int ret;
+	int ret = 0;
 	unsigned int_addr_flag = 0;
 	struct i2c_msg *m_start = msg;
 
 	dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num);
 
+	ret = pm_runtime_get_sync(dev->dev);
+	if (ret < 0)
+		goto out;
+
 	/*
 	 * The hardware can handle at most two messages concatenated by a
 	 * repeated start via it's internal address feature.
@@ -488,18 +494,21 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
 	if (num > 2) {
 		dev_err(dev->dev,
 			"cannot handle more than two concatenated messages.\n");
-		return 0;
+		ret = 0;
+		goto out;
 	} else if (num == 2) {
 		int internal_address = 0;
 		int i;
 
 		if (msg->flags & I2C_M_RD) {
 			dev_err(dev->dev, "first transfer must be write.\n");
-			return -EINVAL;
+			ret = -EINVAL;
+			goto out;
 		}
 		if (msg->len > 3) {
 			dev_err(dev->dev, "first message size must be <= 3.\n");
-			return -EINVAL;
+			ret = -EINVAL;
+			goto out;
 		}
 
 		/* 1st msg is put into the internal address, start with 2nd */
@@ -523,7 +532,13 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
 
 	ret = at91_do_twi_transfer(dev);
 
-	return (ret < 0) ? ret : num;
+	if (ret == 0)
+		ret = num;
+out:
+	pm_runtime_mark_last_busy(dev->dev);
+	pm_runtime_put_autosuspend(dev->dev);
+
+	return ret;
 }
 
 static u32 at91_twi_func(struct i2c_adapter *adapter)
@@ -795,11 +810,20 @@ static int at91_twi_probe(struct platform_device *pdev)
 	dev->adapter.timeout = AT91_I2C_TIMEOUT;
 	dev->adapter.dev.of_node = pdev->dev.of_node;
 
+	pm_runtime_set_autosuspend_delay(dev->dev, AUTOSUSPEND_TIMEOUT);
+	pm_runtime_use_autosuspend(dev->dev);
+	pm_runtime_set_active(dev->dev);
+	pm_runtime_enable(dev->dev);
+
 	rc = i2c_add_numbered_adapter(&dev->adapter);
 	if (rc) {
 		dev_err(dev->dev, "Adapter %s registration failed\n",
 			dev->adapter.name);
 		clk_disable_unprepare(dev->clk);
+
+		pm_runtime_disable(dev->dev);
+		pm_runtime_set_suspended(dev->dev);
+
 		return rc;
 	}
 
@@ -814,16 +838,19 @@ static int at91_twi_remove(struct platform_device *pdev)
 	i2c_del_adapter(&dev->adapter);
 	clk_disable_unprepare(dev->clk);
 
+	pm_runtime_disable(dev->dev);
+	pm_runtime_set_suspended(dev->dev);
+
 	return 0;
 }
 
 #ifdef CONFIG_PM
-
+#ifdef CONFIG_PM_RUNTIME
 static int at91_twi_runtime_suspend(struct device *dev)
 {
 	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
 
-	clk_disable(twi_dev->clk);
+	clk_disable_unprepare(twi_dev->clk);
 
 	return 0;
 }
@@ -832,12 +859,13 @@ static int at91_twi_runtime_resume(struct device *dev)
 {
 	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
 
-	return clk_enable(twi_dev->clk);
+	return clk_prepare_enable(twi_dev->clk);
 }
+#endif
 
 static const struct dev_pm_ops at91_twi_pm = {
-	.runtime_suspend	= at91_twi_runtime_suspend,
-	.runtime_resume		= at91_twi_runtime_resume,
+	SET_RUNTIME_PM_OPS(at91_twi_runtime_suspend,
+				at91_twi_runtime_resume, NULL)
 };
 
 #define at91_twi_pm_ops (&at91_twi_pm)
-- 
1.7.9.5


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

* [PATCH 2/3] i2c/at91: add support for system PM
  2014-10-20  3:42 [PATCH 0/3] i2c/at91: add support PM functions Wenyou Yang
  2014-10-20  3:42 ` [PATCH 1/3] i2c/at91: add support for runtime PM Wenyou Yang
@ 2014-10-20  3:42 ` Wenyou Yang
  2014-10-20 12:42   ` Ludovic Desroches
  2014-10-20 18:15   ` Kevin Hilman
  2014-10-20  3:42 ` [PATCH 3/3] i2c/at91: adopt pinctrl support Wenyou Yang
  2 siblings, 2 replies; 13+ messages in thread
From: Wenyou Yang @ 2014-10-20  3:42 UTC (permalink / raw)
  To: wsa, ludovic.desroches
  Cc: linux-i2c, linux-kernel, nicolas.ferre, linux-arm-kernel, wenyou.yang

Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
---
 drivers/i2c/busses/i2c-at91.c |   30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index 03b9f48..8f408f8 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -845,6 +845,35 @@ static int at91_twi_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
+static int at91_twi_suspend(struct device *dev)
+{
+	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
+
+	if (!pm_runtime_suspended(dev))
+		clk_disable_unprepare(twi_dev->clk);
+
+	return 0;
+}
+
+static int at91_twi_resume(struct device *dev)
+{
+	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
+	int ret;
+
+	if (!pm_runtime_suspended(dev)) {
+		ret = clk_prepare_enable(twi_dev->clk);
+		if (ret)
+			return ret;
+	}
+
+	pm_runtime_mark_last_busy(dev);
+	pm_request_autosuspend(dev);
+
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_PM_RUNTIME
 static int at91_twi_runtime_suspend(struct device *dev)
 {
@@ -864,6 +893,7 @@ static int at91_twi_runtime_resume(struct device *dev)
 #endif
 
 static const struct dev_pm_ops at91_twi_pm = {
+	SET_SYSTEM_SLEEP_PM_OPS(at91_twi_suspend, at91_twi_resume)
 	SET_RUNTIME_PM_OPS(at91_twi_runtime_suspend,
 				at91_twi_runtime_resume, NULL)
 };
-- 
1.7.9.5


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

* [PATCH 3/3] i2c/at91: adopt pinctrl support
  2014-10-20  3:42 [PATCH 0/3] i2c/at91: add support PM functions Wenyou Yang
  2014-10-20  3:42 ` [PATCH 1/3] i2c/at91: add support for runtime PM Wenyou Yang
  2014-10-20  3:42 ` [PATCH 2/3] i2c/at91: add support for system PM Wenyou Yang
@ 2014-10-20  3:42 ` Wenyou Yang
  2014-10-20 12:43   ` Ludovic Desroches
  2014-10-20 18:17   ` Kevin Hilman
  2 siblings, 2 replies; 13+ messages in thread
From: Wenyou Yang @ 2014-10-20  3:42 UTC (permalink / raw)
  To: wsa, ludovic.desroches
  Cc: linux-i2c, linux-kernel, nicolas.ferre, linux-arm-kernel, wenyou.yang

Amend the i2c at91 pin controller to optionally take a pin control
handle and set the state of the pins to:

- "default" on boot, resume and before performing an transfer
- "sleep" on suspend()

This should make it possible to optimize energy usage for the pins
both for the suspend/resume cycle

Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
---
 drivers/i2c/busses/i2c-at91.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index 8f408f8..ed2c382 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -32,6 +32,7 @@
 #include <linux/slab.h>
 #include <linux/platform_data/dma-atmel.h>
 #include <linux/pm_runtime.h>
+#include <linux/pinctrl/consumer.h>
 
 #define DEFAULT_TWI_CLK_HZ		100000		/* max 400 Kbits/s */
 #define AT91_I2C_TIMEOUT	msecs_to_jiffies(100)	/* transfer timeout */
@@ -748,6 +749,8 @@ static int at91_twi_probe(struct platform_device *pdev)
 	u32 phy_addr;
 	u32 bus_clk_rate;
 
+	pinctrl_pm_select_default_state(&pdev->dev);
+
 	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
 	if (!dev)
 		return -ENOMEM;
@@ -850,8 +853,10 @@ static int at91_twi_suspend(struct device *dev)
 {
 	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
 
-	if (!pm_runtime_suspended(dev))
+	if (!pm_runtime_suspended(dev)) {
 		clk_disable_unprepare(twi_dev->clk);
+		pinctrl_pm_select_sleep_state(dev);
+	}
 
 	return 0;
 }
@@ -862,6 +867,7 @@ static int at91_twi_resume(struct device *dev)
 	int ret;
 
 	if (!pm_runtime_suspended(dev)) {
+		pinctrl_pm_select_default_state(dev);
 		ret = clk_prepare_enable(twi_dev->clk);
 		if (ret)
 			return ret;
@@ -881,6 +887,8 @@ static int at91_twi_runtime_suspend(struct device *dev)
 
 	clk_disable_unprepare(twi_dev->clk);
 
+	pinctrl_pm_select_sleep_state(dev);
+
 	return 0;
 }
 
@@ -888,6 +896,8 @@ static int at91_twi_runtime_resume(struct device *dev)
 {
 	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
 
+	pinctrl_pm_select_default_state(dev);
+
 	return clk_prepare_enable(twi_dev->clk);
 }
 #endif
-- 
1.7.9.5


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

* Re: [PATCH 1/3] i2c/at91: add support for runtime PM
  2014-10-20  3:42 ` [PATCH 1/3] i2c/at91: add support for runtime PM Wenyou Yang
@ 2014-10-20 12:39   ` Ludovic Desroches
  2014-10-20 13:14     ` Ludovic Desroches
  2014-10-21  0:56     ` Yang, Wenyou
  0 siblings, 2 replies; 13+ messages in thread
From: Ludovic Desroches @ 2014-10-20 12:39 UTC (permalink / raw)
  To: Wenyou Yang
  Cc: wsa, ludovic.desroches, linux-i2c, linux-kernel, nicolas.ferre,
	linux-arm-kernel

Hi Wenyou,

On Mon, Oct 20, 2014 at 11:42:12AM +0800, Wenyou Yang wrote:
> Drivers should put the device into low power states proactively whenever the
> device is not in use. Thus implement support for runtime PM and use the
> autosuspend feature to make sure that we can still perform well in case we see
> lots of i2c traffic within short period of time.
> 
> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
> ---
>  drivers/i2c/busses/i2c-at91.c |   48 ++++++++++++++++++++++++++++++++---------
>  1 file changed, 38 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
> index 917d545..03b9f48 100644
> --- a/drivers/i2c/busses/i2c-at91.c
> +++ b/drivers/i2c/busses/i2c-at91.c
> @@ -31,10 +31,12 @@
>  #include <linux/platform_device.h>
>  #include <linux/slab.h>
>  #include <linux/platform_data/dma-atmel.h>
> +#include <linux/pm_runtime.h>
>  
>  #define DEFAULT_TWI_CLK_HZ		100000		/* max 400 Kbits/s */
>  #define AT91_I2C_TIMEOUT	msecs_to_jiffies(100)	/* transfer timeout */
>  #define AT91_I2C_DMA_THRESHOLD	8			/* enable DMA if transfer size is bigger than this threshold */
> +#define AUTOSUSPEND_TIMEOUT		2000
>  
>  /* AT91 TWI register definitions */
>  #define	AT91_TWI_CR		0x0000	/* Control Register */
> @@ -475,12 +477,16 @@ error:
>  static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
>  {
>  	struct at91_twi_dev *dev = i2c_get_adapdata(adap);
> -	int ret;
> +	int ret = 0;

Not necessary.

>  	unsigned int_addr_flag = 0;
>  	struct i2c_msg *m_start = msg;
>  
>  	dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num);
>  
> +	ret = pm_runtime_get_sync(dev->dev);
> +	if (ret < 0)
> +		goto out;
> +
>  	/*
>  	 * The hardware can handle at most two messages concatenated by a
>  	 * repeated start via it's internal address feature.
> @@ -488,18 +494,21 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
>  	if (num > 2) {
>  		dev_err(dev->dev,
>  			"cannot handle more than two concatenated messages.\n");
> -		return 0;
> +		ret = 0;
> +		goto out;
>  	} else if (num == 2) {
>  		int internal_address = 0;
>  		int i;
>  
>  		if (msg->flags & I2C_M_RD) {
>  			dev_err(dev->dev, "first transfer must be write.\n");
> -			return -EINVAL;
> +			ret = -EINVAL;
> +			goto out;
>  		}
>  		if (msg->len > 3) {
>  			dev_err(dev->dev, "first message size must be <= 3.\n");
> -			return -EINVAL;
> +			ret = -EINVAL;
> +			goto out;
>  		}
>  
>  		/* 1st msg is put into the internal address, start with 2nd */
> @@ -523,7 +532,13 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
>  
>  	ret = at91_do_twi_transfer(dev);
>  
> -	return (ret < 0) ? ret : num;
> +	if (ret == 0)

I don't figure out why you've changed this condition.

> +		ret = num;
> +out:
> +	pm_runtime_mark_last_busy(dev->dev);
> +	pm_runtime_put_autosuspend(dev->dev);
> +
> +	return ret;
>  }
>  
>  static u32 at91_twi_func(struct i2c_adapter *adapter)
> @@ -795,11 +810,20 @@ static int at91_twi_probe(struct platform_device *pdev)
>  	dev->adapter.timeout = AT91_I2C_TIMEOUT;
>  	dev->adapter.dev.of_node = pdev->dev.of_node;
>  
> +	pm_runtime_set_autosuspend_delay(dev->dev, AUTOSUSPEND_TIMEOUT);
> +	pm_runtime_use_autosuspend(dev->dev);
> +	pm_runtime_set_active(dev->dev);
> +	pm_runtime_enable(dev->dev);
> +
>  	rc = i2c_add_numbered_adapter(&dev->adapter);
>  	if (rc) {
>  		dev_err(dev->dev, "Adapter %s registration failed\n",
>  			dev->adapter.name);
>  		clk_disable_unprepare(dev->clk);
> +
> +		pm_runtime_disable(dev->dev);
> +		pm_runtime_set_suspended(dev->dev);
> +
>  		return rc;
>  	}
>  
> @@ -814,16 +838,19 @@ static int at91_twi_remove(struct platform_device *pdev)
>  	i2c_del_adapter(&dev->adapter);
>  	clk_disable_unprepare(dev->clk);
>  
> +	pm_runtime_disable(dev->dev);
> +	pm_runtime_set_suspended(dev->dev);
> +
>  	return 0;
>  }
>  
>  #ifdef CONFIG_PM
> -
> +#ifdef CONFIG_PM_RUNTIME
>  static int at91_twi_runtime_suspend(struct device *dev)
>  {
>  	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
>  
> -	clk_disable(twi_dev->clk);
> +	clk_disable_unprepare(twi_dev->clk);
>  
>  	return 0;
>  }
> @@ -832,12 +859,13 @@ static int at91_twi_runtime_resume(struct device *dev)
>  {
>  	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
>  
> -	return clk_enable(twi_dev->clk);
> +	return clk_prepare_enable(twi_dev->clk);
>  }
> +#endif
>  
>  static const struct dev_pm_ops at91_twi_pm = {
> -	.runtime_suspend	= at91_twi_runtime_suspend,
> -	.runtime_resume		= at91_twi_runtime_resume,
> +	SET_RUNTIME_PM_OPS(at91_twi_runtime_suspend,
> +				at91_twi_runtime_resume, NULL)
>  };
>  
>  #define at91_twi_pm_ops (&at91_twi_pm)
> -- 
> 1.7.9.5
> 


Regards

Ludovic

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

* Re: [PATCH 2/3] i2c/at91: add support for system PM
  2014-10-20  3:42 ` [PATCH 2/3] i2c/at91: add support for system PM Wenyou Yang
@ 2014-10-20 12:42   ` Ludovic Desroches
  2014-10-20 13:15     ` Ludovic Desroches
  2014-10-20 18:15   ` Kevin Hilman
  1 sibling, 1 reply; 13+ messages in thread
From: Ludovic Desroches @ 2014-10-20 12:42 UTC (permalink / raw)
  To: Wenyou Yang
  Cc: wsa, ludovic.desroches, linux-i2c, linux-kernel, nicolas.ferre,
	linux-arm-kernel

On Mon, Oct 20, 2014 at 11:42:13AM +0800, Wenyou Yang wrote:
> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>

Acked by: Ludovic Desroches <ludovic.desroches@atmel.com>

> ---
>  drivers/i2c/busses/i2c-at91.c |   30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
> index 03b9f48..8f408f8 100644
> --- a/drivers/i2c/busses/i2c-at91.c
> +++ b/drivers/i2c/busses/i2c-at91.c
> @@ -845,6 +845,35 @@ static int at91_twi_remove(struct platform_device *pdev)
>  }
>  
>  #ifdef CONFIG_PM
> +#ifdef CONFIG_PM_SLEEP
> +static int at91_twi_suspend(struct device *dev)
> +{
> +	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
> +
> +	if (!pm_runtime_suspended(dev))
> +		clk_disable_unprepare(twi_dev->clk);
> +
> +	return 0;
> +}
> +
> +static int at91_twi_resume(struct device *dev)
> +{
> +	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
> +	int ret;
> +
> +	if (!pm_runtime_suspended(dev)) {
> +		ret = clk_prepare_enable(twi_dev->clk);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	pm_runtime_mark_last_busy(dev);
> +	pm_request_autosuspend(dev);
> +
> +	return 0;
> +}
> +#endif
> +
>  #ifdef CONFIG_PM_RUNTIME
>  static int at91_twi_runtime_suspend(struct device *dev)
>  {
> @@ -864,6 +893,7 @@ static int at91_twi_runtime_resume(struct device *dev)
>  #endif
>  
>  static const struct dev_pm_ops at91_twi_pm = {
> +	SET_SYSTEM_SLEEP_PM_OPS(at91_twi_suspend, at91_twi_resume)
>  	SET_RUNTIME_PM_OPS(at91_twi_runtime_suspend,
>  				at91_twi_runtime_resume, NULL)
>  };
> -- 
> 1.7.9.5
> 

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

* Re: [PATCH 3/3] i2c/at91: adopt pinctrl support
  2014-10-20  3:42 ` [PATCH 3/3] i2c/at91: adopt pinctrl support Wenyou Yang
@ 2014-10-20 12:43   ` Ludovic Desroches
  2014-10-20 18:17   ` Kevin Hilman
  1 sibling, 0 replies; 13+ messages in thread
From: Ludovic Desroches @ 2014-10-20 12:43 UTC (permalink / raw)
  To: Wenyou Yang
  Cc: wsa, ludovic.desroches, linux-i2c, linux-kernel, nicolas.ferre,
	linux-arm-kernel

On Mon, Oct 20, 2014 at 11:42:14AM +0800, Wenyou Yang wrote:
> Amend the i2c at91 pin controller to optionally take a pin control
> handle and set the state of the pins to:
> 
> - "default" on boot, resume and before performing an transfer
> - "sleep" on suspend()
> 
> This should make it possible to optimize energy usage for the pins
> both for the suspend/resume cycle
> 
> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>

Acked by: Ludovic Desroches <ludovic.desroches@atmel.com>

> ---
>  drivers/i2c/busses/i2c-at91.c |   12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
> index 8f408f8..ed2c382 100644
> --- a/drivers/i2c/busses/i2c-at91.c
> +++ b/drivers/i2c/busses/i2c-at91.c
> @@ -32,6 +32,7 @@
>  #include <linux/slab.h>
>  #include <linux/platform_data/dma-atmel.h>
>  #include <linux/pm_runtime.h>
> +#include <linux/pinctrl/consumer.h>
>  
>  #define DEFAULT_TWI_CLK_HZ		100000		/* max 400 Kbits/s */
>  #define AT91_I2C_TIMEOUT	msecs_to_jiffies(100)	/* transfer timeout */
> @@ -748,6 +749,8 @@ static int at91_twi_probe(struct platform_device *pdev)
>  	u32 phy_addr;
>  	u32 bus_clk_rate;
>  
> +	pinctrl_pm_select_default_state(&pdev->dev);
> +
>  	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
>  	if (!dev)
>  		return -ENOMEM;
> @@ -850,8 +853,10 @@ static int at91_twi_suspend(struct device *dev)
>  {
>  	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
>  
> -	if (!pm_runtime_suspended(dev))
> +	if (!pm_runtime_suspended(dev)) {
>  		clk_disable_unprepare(twi_dev->clk);
> +		pinctrl_pm_select_sleep_state(dev);
> +	}
>  
>  	return 0;
>  }
> @@ -862,6 +867,7 @@ static int at91_twi_resume(struct device *dev)
>  	int ret;
>  
>  	if (!pm_runtime_suspended(dev)) {
> +		pinctrl_pm_select_default_state(dev);
>  		ret = clk_prepare_enable(twi_dev->clk);
>  		if (ret)
>  			return ret;
> @@ -881,6 +887,8 @@ static int at91_twi_runtime_suspend(struct device *dev)
>  
>  	clk_disable_unprepare(twi_dev->clk);
>  
> +	pinctrl_pm_select_sleep_state(dev);
> +
>  	return 0;
>  }
>  
> @@ -888,6 +896,8 @@ static int at91_twi_runtime_resume(struct device *dev)
>  {
>  	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
>  
> +	pinctrl_pm_select_default_state(dev);
> +
>  	return clk_prepare_enable(twi_dev->clk);
>  }
>  #endif
> -- 
> 1.7.9.5
> 

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

* Re: [PATCH 1/3] i2c/at91: add support for runtime PM
  2014-10-20 12:39   ` Ludovic Desroches
@ 2014-10-20 13:14     ` Ludovic Desroches
  2014-10-21  0:56     ` Yang, Wenyou
  1 sibling, 0 replies; 13+ messages in thread
From: Ludovic Desroches @ 2014-10-20 13:14 UTC (permalink / raw)
  To: Wenyou Yang, wsa, linux-i2c, linux-kernel, nicolas.ferre,
	linux-arm-kernel
  Cc: khilman

Adding Kevin in the CC list since he had some comments about the PM
runtime support for the SPI driver.

On Mon, Oct 20, 2014 at 02:39:14PM +0200, Ludovic Desroches wrote:
> Hi Wenyou,
> 
> On Mon, Oct 20, 2014 at 11:42:12AM +0800, Wenyou Yang wrote:
> > Drivers should put the device into low power states proactively whenever the
> > device is not in use. Thus implement support for runtime PM and use the
> > autosuspend feature to make sure that we can still perform well in case we see
> > lots of i2c traffic within short period of time.
> > 
> > Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
> > ---
> >  drivers/i2c/busses/i2c-at91.c |   48 ++++++++++++++++++++++++++++++++---------
> >  1 file changed, 38 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
> > index 917d545..03b9f48 100644
> > --- a/drivers/i2c/busses/i2c-at91.c
> > +++ b/drivers/i2c/busses/i2c-at91.c
> > @@ -31,10 +31,12 @@
> >  #include <linux/platform_device.h>
> >  #include <linux/slab.h>
> >  #include <linux/platform_data/dma-atmel.h>
> > +#include <linux/pm_runtime.h>
> >  
> >  #define DEFAULT_TWI_CLK_HZ		100000		/* max 400 Kbits/s */
> >  #define AT91_I2C_TIMEOUT	msecs_to_jiffies(100)	/* transfer timeout */
> >  #define AT91_I2C_DMA_THRESHOLD	8			/* enable DMA if transfer size is bigger than this threshold */
> > +#define AUTOSUSPEND_TIMEOUT		2000
> >  
> >  /* AT91 TWI register definitions */
> >  #define	AT91_TWI_CR		0x0000	/* Control Register */
> > @@ -475,12 +477,16 @@ error:
> >  static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
> >  {
> >  	struct at91_twi_dev *dev = i2c_get_adapdata(adap);
> > -	int ret;
> > +	int ret = 0;
> 
> Not necessary.
> 
> >  	unsigned int_addr_flag = 0;
> >  	struct i2c_msg *m_start = msg;
> >  
> >  	dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num);
> >  
> > +	ret = pm_runtime_get_sync(dev->dev);
> > +	if (ret < 0)
> > +		goto out;
> > +
> >  	/*
> >  	 * The hardware can handle at most two messages concatenated by a
> >  	 * repeated start via it's internal address feature.
> > @@ -488,18 +494,21 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
> >  	if (num > 2) {
> >  		dev_err(dev->dev,
> >  			"cannot handle more than two concatenated messages.\n");
> > -		return 0;
> > +		ret = 0;
> > +		goto out;
> >  	} else if (num == 2) {
> >  		int internal_address = 0;
> >  		int i;
> >  
> >  		if (msg->flags & I2C_M_RD) {
> >  			dev_err(dev->dev, "first transfer must be write.\n");
> > -			return -EINVAL;
> > +			ret = -EINVAL;
> > +			goto out;
> >  		}
> >  		if (msg->len > 3) {
> >  			dev_err(dev->dev, "first message size must be <= 3.\n");
> > -			return -EINVAL;
> > +			ret = -EINVAL;
> > +			goto out;
> >  		}
> >  
> >  		/* 1st msg is put into the internal address, start with 2nd */
> > @@ -523,7 +532,13 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, int num)
> >  
> >  	ret = at91_do_twi_transfer(dev);
> >  
> > -	return (ret < 0) ? ret : num;
> > +	if (ret == 0)
> 
> I don't figure out why you've changed this condition.
> 
> > +		ret = num;
> > +out:
> > +	pm_runtime_mark_last_busy(dev->dev);
> > +	pm_runtime_put_autosuspend(dev->dev);
> > +
> > +	return ret;
> >  }
> >  
> >  static u32 at91_twi_func(struct i2c_adapter *adapter)
> > @@ -795,11 +810,20 @@ static int at91_twi_probe(struct platform_device *pdev)
> >  	dev->adapter.timeout = AT91_I2C_TIMEOUT;
> >  	dev->adapter.dev.of_node = pdev->dev.of_node;
> >  
> > +	pm_runtime_set_autosuspend_delay(dev->dev, AUTOSUSPEND_TIMEOUT);
> > +	pm_runtime_use_autosuspend(dev->dev);
> > +	pm_runtime_set_active(dev->dev);
> > +	pm_runtime_enable(dev->dev);
> > +
> >  	rc = i2c_add_numbered_adapter(&dev->adapter);
> >  	if (rc) {
> >  		dev_err(dev->dev, "Adapter %s registration failed\n",
> >  			dev->adapter.name);
> >  		clk_disable_unprepare(dev->clk);
> > +
> > +		pm_runtime_disable(dev->dev);
> > +		pm_runtime_set_suspended(dev->dev);
> > +
> >  		return rc;
> >  	}
> >  
> > @@ -814,16 +838,19 @@ static int at91_twi_remove(struct platform_device *pdev)
> >  	i2c_del_adapter(&dev->adapter);
> >  	clk_disable_unprepare(dev->clk);
> >  
> > +	pm_runtime_disable(dev->dev);
> > +	pm_runtime_set_suspended(dev->dev);
> > +
> >  	return 0;
> >  }
> >  
> >  #ifdef CONFIG_PM
> > -
> > +#ifdef CONFIG_PM_RUNTIME
> >  static int at91_twi_runtime_suspend(struct device *dev)
> >  {
> >  	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
> >  
> > -	clk_disable(twi_dev->clk);
> > +	clk_disable_unprepare(twi_dev->clk);
> >  
> >  	return 0;
> >  }
> > @@ -832,12 +859,13 @@ static int at91_twi_runtime_resume(struct device *dev)
> >  {
> >  	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
> >  
> > -	return clk_enable(twi_dev->clk);
> > +	return clk_prepare_enable(twi_dev->clk);
> >  }
> > +#endif
> >  
> >  static const struct dev_pm_ops at91_twi_pm = {
> > -	.runtime_suspend	= at91_twi_runtime_suspend,
> > -	.runtime_resume		= at91_twi_runtime_resume,
> > +	SET_RUNTIME_PM_OPS(at91_twi_runtime_suspend,
> > +				at91_twi_runtime_resume, NULL)
> >  };
> >  
> >  #define at91_twi_pm_ops (&at91_twi_pm)
> > -- 
> > 1.7.9.5
> > 
> 
> 
> Regards
> 
> Ludovic

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

* Re: [PATCH 2/3] i2c/at91: add support for system PM
  2014-10-20 12:42   ` Ludovic Desroches
@ 2014-10-20 13:15     ` Ludovic Desroches
  0 siblings, 0 replies; 13+ messages in thread
From: Ludovic Desroches @ 2014-10-20 13:15 UTC (permalink / raw)
  To: Wenyou Yang, wsa, linux-i2c, linux-kernel, nicolas.ferre,
	linux-arm-kernel
  Cc: khilman

Adding Kevin in the CC list since he had some comments about the PM
runtime support for the SPI driver.

On Mon, Oct 20, 2014 at 02:42:42PM +0200, Ludovic Desroches wrote:
> On Mon, Oct 20, 2014 at 11:42:13AM +0800, Wenyou Yang wrote:
> > Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
> 
> Acked by: Ludovic Desroches <ludovic.desroches@atmel.com>
> 
> > ---
> >  drivers/i2c/busses/i2c-at91.c |   30 ++++++++++++++++++++++++++++++
> >  1 file changed, 30 insertions(+)
> > 
> > diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
> > index 03b9f48..8f408f8 100644
> > --- a/drivers/i2c/busses/i2c-at91.c
> > +++ b/drivers/i2c/busses/i2c-at91.c
> > @@ -845,6 +845,35 @@ static int at91_twi_remove(struct platform_device *pdev)
> >  }
> >  
> >  #ifdef CONFIG_PM
> > +#ifdef CONFIG_PM_SLEEP
> > +static int at91_twi_suspend(struct device *dev)
> > +{
> > +	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
> > +
> > +	if (!pm_runtime_suspended(dev))
> > +		clk_disable_unprepare(twi_dev->clk);
> > +
> > +	return 0;
> > +}
> > +
> > +static int at91_twi_resume(struct device *dev)
> > +{
> > +	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
> > +	int ret;
> > +
> > +	if (!pm_runtime_suspended(dev)) {
> > +		ret = clk_prepare_enable(twi_dev->clk);
> > +		if (ret)
> > +			return ret;
> > +	}
> > +
> > +	pm_runtime_mark_last_busy(dev);
> > +	pm_request_autosuspend(dev);
> > +
> > +	return 0;
> > +}
> > +#endif
> > +
> >  #ifdef CONFIG_PM_RUNTIME
> >  static int at91_twi_runtime_suspend(struct device *dev)
> >  {
> > @@ -864,6 +893,7 @@ static int at91_twi_runtime_resume(struct device *dev)
> >  #endif
> >  
> >  static const struct dev_pm_ops at91_twi_pm = {
> > +	SET_SYSTEM_SLEEP_PM_OPS(at91_twi_suspend, at91_twi_resume)
> >  	SET_RUNTIME_PM_OPS(at91_twi_runtime_suspend,
> >  				at91_twi_runtime_resume, NULL)
> >  };
> > -- 
> > 1.7.9.5
> > 

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

* Re: [PATCH 2/3] i2c/at91: add support for system PM
  2014-10-20  3:42 ` [PATCH 2/3] i2c/at91: add support for system PM Wenyou Yang
  2014-10-20 12:42   ` Ludovic Desroches
@ 2014-10-20 18:15   ` Kevin Hilman
  2014-10-21  1:25     ` Yang, Wenyou
  1 sibling, 1 reply; 13+ messages in thread
From: Kevin Hilman @ 2014-10-20 18:15 UTC (permalink / raw)
  To: Wenyou Yang
  Cc: wsa, ludovic.desroches, linux-i2c, linux-kernel, nicolas.ferre,
	linux-arm-kernel

Wenyou Yang <wenyou.yang@atmel.com> writes:

Add a changelog here describing what you're doing, and why.

> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
> ---
>  drivers/i2c/busses/i2c-at91.c |   30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
>
> diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
> index 03b9f48..8f408f8 100644
> --- a/drivers/i2c/busses/i2c-at91.c
> +++ b/drivers/i2c/busses/i2c-at91.c
> @@ -845,6 +845,35 @@ static int at91_twi_remove(struct platform_device *pdev)
>  }
>  
>  #ifdef CONFIG_PM
> +#ifdef CONFIG_PM_SLEEP
> +static int at91_twi_suspend(struct device *dev)
> +{
> +	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
> +
> +	if (!pm_runtime_suspended(dev))
> +		clk_disable_unprepare(twi_dev->clk);

I would just call at91_twi_runtime_suspend() here.

Then, if you need to add additional steps, you only have to add them in
once place.  This also makes it obvious that ->suspend and
->runtime_suspend are doing the exact same thing.

NOTE: you'll need to wrap the runtime_suspend|resume functions in just
CONFIG_PM instead of CONFIG_PM_RUNTIME for this to work.

Kevin

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

* Re: [PATCH 3/3] i2c/at91: adopt pinctrl support
  2014-10-20  3:42 ` [PATCH 3/3] i2c/at91: adopt pinctrl support Wenyou Yang
  2014-10-20 12:43   ` Ludovic Desroches
@ 2014-10-20 18:17   ` Kevin Hilman
  1 sibling, 0 replies; 13+ messages in thread
From: Kevin Hilman @ 2014-10-20 18:17 UTC (permalink / raw)
  To: Wenyou Yang
  Cc: wsa, ludovic.desroches, linux-i2c, linux-kernel, nicolas.ferre,
	linux-arm-kernel

Wenyou Yang <wenyou.yang@atmel.com> writes:

> Amend the i2c at91 pin controller to optionally take a pin control
> handle and set the state of the pins to:
>
> - "default" on boot, resume and before performing an transfer
> - "sleep" on suspend()
>
> This should make it possible to optimize energy usage for the pins
> both for the suspend/resume cycle
>
> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>

This patch is a good example of why you should just have the ->suspend
function call the same function as ->runtime_suspend.

If you do that, rather than having to add the pinctrl_pm* calls bo both
system PM and runtime PM functions, you could've just added them to the
runtime PM functions.

Kevin

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

* RE: [PATCH 1/3] i2c/at91: add support for runtime PM
  2014-10-20 12:39   ` Ludovic Desroches
  2014-10-20 13:14     ` Ludovic Desroches
@ 2014-10-21  0:56     ` Yang, Wenyou
  1 sibling, 0 replies; 13+ messages in thread
From: Yang, Wenyou @ 2014-10-21  0:56 UTC (permalink / raw)
  To: Desroches, Ludovic
  Cc: wsa, Desroches, Ludovic, linux-i2c, linux-kernel, Ferre, Nicolas,
	linux-arm-kernel

Hi Ludovic,

Thanks a lot.

> -----Original Message-----
> From: Ludovic Desroches [mailto:ludovic.desroches@atmel.com]
> Sent: Monday, October 20, 2014 8:39 PM
> To: Yang, Wenyou
> Cc: wsa@the-dreams.de; Desroches, Ludovic; linux-i2c@vger.kernel.org; linux-
> kernel@vger.kernel.org; Ferre, Nicolas; linux-arm-kernel@lists.infradead.org
> Subject: Re: [PATCH 1/3] i2c/at91: add support for runtime PM
> 
> Hi Wenyou,
> 
> On Mon, Oct 20, 2014 at 11:42:12AM +0800, Wenyou Yang wrote:
> > Drivers should put the device into low power states proactively
> > whenever the device is not in use. Thus implement support for runtime
> > PM and use the autosuspend feature to make sure that we can still
> > perform well in case we see lots of i2c traffic within short period of time.
> >
> > Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
> > ---
> >  drivers/i2c/busses/i2c-at91.c |   48 ++++++++++++++++++++++++++++++++---
> ------
> >  1 file changed, 38 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/i2c/busses/i2c-at91.c
> > b/drivers/i2c/busses/i2c-at91.c index 917d545..03b9f48 100644
> > --- a/drivers/i2c/busses/i2c-at91.c
> > +++ b/drivers/i2c/busses/i2c-at91.c
> > @@ -31,10 +31,12 @@
> >  #include <linux/platform_device.h>
> >  #include <linux/slab.h>
> >  #include <linux/platform_data/dma-atmel.h>
> > +#include <linux/pm_runtime.h>
> >
> >  #define DEFAULT_TWI_CLK_HZ		100000		/* max 400 Kbits/s
> */
> >  #define AT91_I2C_TIMEOUT	msecs_to_jiffies(100)	/* transfer timeout */
> >  #define AT91_I2C_DMA_THRESHOLD	8			/* enable
> DMA if transfer size is bigger than this threshold */
> > +#define AUTOSUSPEND_TIMEOUT		2000
> >
> >  /* AT91 TWI register definitions */
> >  #define	AT91_TWI_CR		0x0000	/* Control Register */
> > @@ -475,12 +477,16 @@ error:
> >  static int at91_twi_xfer(struct i2c_adapter *adap, struct i2c_msg
> > *msg, int num)  {
> >  	struct at91_twi_dev *dev = i2c_get_adapdata(adap);
> > -	int ret;
> > +	int ret = 0;
> 
> Not necessary.
> 
> >  	unsigned int_addr_flag = 0;
> >  	struct i2c_msg *m_start = msg;
> >
> >  	dev_dbg(&adap->dev, "at91_xfer: processing %d messages:\n", num);
> >
> > +	ret = pm_runtime_get_sync(dev->dev);
> > +	if (ret < 0)
> > +		goto out;
> > +
> >  	/*
> >  	 * The hardware can handle at most two messages concatenated by a
> >  	 * repeated start via it's internal address feature.
> > @@ -488,18 +494,21 @@ static int at91_twi_xfer(struct i2c_adapter *adap, struct
> i2c_msg *msg, int num)
> >  	if (num > 2) {
> >  		dev_err(dev->dev,
> >  			"cannot handle more than two concatenated messages.\n");
> > -		return 0;
> > +		ret = 0;
> > +		goto out;
> >  	} else if (num == 2) {
> >  		int internal_address = 0;
> >  		int i;
> >
> >  		if (msg->flags & I2C_M_RD) {
> >  			dev_err(dev->dev, "first transfer must be write.\n");
> > -			return -EINVAL;
> > +			ret = -EINVAL;
> > +			goto out;
> >  		}
> >  		if (msg->len > 3) {
> >  			dev_err(dev->dev, "first message size must be <= 3.\n");
> > -			return -EINVAL;
> > +			ret = -EINVAL;
> > +			goto out;
> >  		}
> >
> >  		/* 1st msg is put into the internal address, start with 2nd */ @@
> > -523,7 +532,13 @@ static int at91_twi_xfer(struct i2c_adapter *adap,
> > struct i2c_msg *msg, int num)
> >
> >  	ret = at91_do_twi_transfer(dev);
> >
> > -	return (ret < 0) ? ret : num;
> > +	if (ret == 0)
> 
> I don't figure out why you've changed this condition.

Right, I will change it.
> 
> > +		ret = num;
> > +out:
> > +	pm_runtime_mark_last_busy(dev->dev);
> > +	pm_runtime_put_autosuspend(dev->dev);
> > +
> > +	return ret;
> >  }
> >
> >  static u32 at91_twi_func(struct i2c_adapter *adapter) @@ -795,11
> > +810,20 @@ static int at91_twi_probe(struct platform_device *pdev)
> >  	dev->adapter.timeout = AT91_I2C_TIMEOUT;
> >  	dev->adapter.dev.of_node = pdev->dev.of_node;
> >
> > +	pm_runtime_set_autosuspend_delay(dev->dev,
> AUTOSUSPEND_TIMEOUT);
> > +	pm_runtime_use_autosuspend(dev->dev);
> > +	pm_runtime_set_active(dev->dev);
> > +	pm_runtime_enable(dev->dev);
> > +
> >  	rc = i2c_add_numbered_adapter(&dev->adapter);
> >  	if (rc) {
> >  		dev_err(dev->dev, "Adapter %s registration failed\n",
> >  			dev->adapter.name);
> >  		clk_disable_unprepare(dev->clk);
> > +
> > +		pm_runtime_disable(dev->dev);
> > +		pm_runtime_set_suspended(dev->dev);
> > +
> >  		return rc;
> >  	}
> >
> > @@ -814,16 +838,19 @@ static int at91_twi_remove(struct platform_device
> *pdev)
> >  	i2c_del_adapter(&dev->adapter);
> >  	clk_disable_unprepare(dev->clk);
> >
> > +	pm_runtime_disable(dev->dev);
> > +	pm_runtime_set_suspended(dev->dev);
> > +
> >  	return 0;
> >  }
> >
> >  #ifdef CONFIG_PM
> > -
> > +#ifdef CONFIG_PM_RUNTIME
> >  static int at91_twi_runtime_suspend(struct device *dev)  {
> >  	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
> >
> > -	clk_disable(twi_dev->clk);
> > +	clk_disable_unprepare(twi_dev->clk);
> >
> >  	return 0;
> >  }
> > @@ -832,12 +859,13 @@ static int at91_twi_runtime_resume(struct device
> > *dev)  {
> >  	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
> >
> > -	return clk_enable(twi_dev->clk);
> > +	return clk_prepare_enable(twi_dev->clk);
> >  }
> > +#endif
> >
> >  static const struct dev_pm_ops at91_twi_pm = {
> > -	.runtime_suspend	= at91_twi_runtime_suspend,
> > -	.runtime_resume		= at91_twi_runtime_resume,
> > +	SET_RUNTIME_PM_OPS(at91_twi_runtime_suspend,
> > +				at91_twi_runtime_resume, NULL)
> >  };
> >
> >  #define at91_twi_pm_ops (&at91_twi_pm)
> > --
> > 1.7.9.5
> >
> 
> 
> Regards
> 
> Ludovic

Best Regards,
Wenyou Yang

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

* RE: [PATCH 2/3] i2c/at91: add support for system PM
  2014-10-20 18:15   ` Kevin Hilman
@ 2014-10-21  1:25     ` Yang, Wenyou
  0 siblings, 0 replies; 13+ messages in thread
From: Yang, Wenyou @ 2014-10-21  1:25 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: wsa, Desroches, Ludovic, linux-i2c, linux-kernel, Ferre, Nicolas,
	linux-arm-kernel

Hi Kevin,

> -----Original Message-----
> From: Kevin Hilman [mailto:khilman@kernel.org]
> Sent: Tuesday, October 21, 2014 2:16 AM
> To: Yang, Wenyou
> Cc: wsa@the-dreams.de; Desroches, Ludovic; linux-i2c@vger.kernel.org; linux-
> kernel@vger.kernel.org; Ferre, Nicolas; linux-arm-kernel@lists.infradead.org
> Subject: Re: [PATCH 2/3] i2c/at91: add support for system PM
> 
> Wenyou Yang <wenyou.yang@atmel.com> writes:
> 
> Add a changelog here describing what you're doing, and why.
> 
> > Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
> > ---
> >  drivers/i2c/busses/i2c-at91.c |   30 ++++++++++++++++++++++++++++++
> >  1 file changed, 30 insertions(+)
> >
> > diff --git a/drivers/i2c/busses/i2c-at91.c
> > b/drivers/i2c/busses/i2c-at91.c index 03b9f48..8f408f8 100644
> > --- a/drivers/i2c/busses/i2c-at91.c
> > +++ b/drivers/i2c/busses/i2c-at91.c
> > @@ -845,6 +845,35 @@ static int at91_twi_remove(struct platform_device
> > *pdev)  }
> >
> >  #ifdef CONFIG_PM
> > +#ifdef CONFIG_PM_SLEEP
> > +static int at91_twi_suspend(struct device *dev) {
> > +	struct at91_twi_dev *twi_dev = dev_get_drvdata(dev);
> > +
> > +	if (!pm_runtime_suspended(dev))
> > +		clk_disable_unprepare(twi_dev->clk);
> 
> I would just call at91_twi_runtime_suspend() here.
> 
> Then, if you need to add additional steps, you only have to add them in once
> place.  This also makes it obvious that ->suspend and
> ->runtime_suspend are doing the exact same thing.
> 
> NOTE: you'll need to wrap the runtime_suspend|resume functions in just
> CONFIG_PM instead of CONFIG_PM_RUNTIME for this to work.
Thanks a lot, I will modify it.

> 
> Kevin

Best Regards,
Wenyou Yang

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

end of thread, other threads:[~2014-10-21  1:28 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-20  3:42 [PATCH 0/3] i2c/at91: add support PM functions Wenyou Yang
2014-10-20  3:42 ` [PATCH 1/3] i2c/at91: add support for runtime PM Wenyou Yang
2014-10-20 12:39   ` Ludovic Desroches
2014-10-20 13:14     ` Ludovic Desroches
2014-10-21  0:56     ` Yang, Wenyou
2014-10-20  3:42 ` [PATCH 2/3] i2c/at91: add support for system PM Wenyou Yang
2014-10-20 12:42   ` Ludovic Desroches
2014-10-20 13:15     ` Ludovic Desroches
2014-10-20 18:15   ` Kevin Hilman
2014-10-21  1:25     ` Yang, Wenyou
2014-10-20  3:42 ` [PATCH 3/3] i2c/at91: adopt pinctrl support Wenyou Yang
2014-10-20 12:43   ` Ludovic Desroches
2014-10-20 18:17   ` Kevin Hilman

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).