diff mbox series

[16/16] i2c: uniphier-f: use readl_poll_timeout() to poll registers

Message ID 1485554036-29320-17-git-send-email-yamada.masahiro@socionext.com
State Accepted
Commit 68578582ab956691ecce174057b52600f52d7d09
Headers show
Series ARM: uniphier: UniPhier SoC updates for v2017.03 (3rd round) | expand

Commit Message

Masahiro Yamada Jan. 27, 2017, 9:53 p.m. UTC
The readl_poll_timeout() is a useful helper to poll registers
and error out if the condition is not met.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

---

 drivers/i2c/i2c-uniphier-f.c | 34 ++++++++++------------------------
 1 file changed, 10 insertions(+), 24 deletions(-)

-- 
2.7.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Comments

Heiko Schocher Jan. 31, 2017, 5:09 a.m. UTC | #1
Hello Masahiro,

Am 27.01.2017 um 22:53 schrieb Masahiro Yamada:
> The readl_poll_timeout() is a useful helper to poll registers

> and error out if the condition is not met.

>

> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>

> ---

>

>   drivers/i2c/i2c-uniphier-f.c | 34 ++++++++++------------------------

>   1 file changed, 10 insertions(+), 24 deletions(-)


Reviewed-by: Heiko Schocher <hs@denx.de>


bye,
Heiko
>

> diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c

> index e212c13..9f0df59 100644

> --- a/drivers/i2c/i2c-uniphier-f.c

> +++ b/drivers/i2c/i2c-uniphier-f.c

> @@ -9,6 +9,7 @@

>   #include <common.h>

>   #include <linux/types.h>

>   #include <linux/io.h>

> +#include <linux/iopoll.h>

>   #include <linux/sizes.h>

>   #include <linux/errno.h>

>   #include <dm/device.h>

> @@ -69,26 +70,14 @@ struct uniphier_fi2c_dev {

>   	unsigned long timeout;			/* time out (us) */

>   };

>

> -static int poll_status(u32 __iomem *reg, u32 flag)

> -{

> -	int wait = 1000000; /* 1 sec is long enough */

> -

> -	while (readl(reg) & flag) {

> -		if (wait-- < 0)

> -			return -EREMOTEIO;

> -		udelay(1);

> -	}

> -

> -	return 0;

> -}

> -

>   static int reset_bus(struct uniphier_fi2c_regs __iomem *regs)

>   {

> +	u32 val;

>   	int ret;

>

>   	/* bus forcible reset */

>   	writel(I2C_RST_RST, &regs->rst);

> -	ret = poll_status(&regs->rst, I2C_RST_RST);

> +	ret = readl_poll_timeout(&regs->rst, val, !(val & I2C_RST_RST), 1);

>   	if (ret < 0)

>   		debug("error: fail to reset I2C controller\n");

>

> @@ -97,9 +86,10 @@ static int reset_bus(struct uniphier_fi2c_regs __iomem *regs)

>

>   static int check_device_busy(struct uniphier_fi2c_regs __iomem *regs)

>   {

> +	u32 val;

>   	int ret;

>

> -	ret = poll_status(&regs->sr, I2C_SR_DB);

> +	ret = readl_poll_timeout(&regs->sr, val, !(val & I2C_SR_DB), 100);

>   	if (ret < 0) {

>   		debug("error: device busy too long. reset...\n");

>   		ret = reset_bus(regs);

> @@ -138,15 +128,11 @@ static int wait_for_irq(struct uniphier_fi2c_dev *dev, u32 flags,

>   			bool *stop)

>   {

>   	u32 irq;

> -	unsigned long wait = dev->timeout;

> -	int ret = -EREMOTEIO;

> -

> -	do {

> -		udelay(1);

> -		irq = readl(&dev->regs->intr);

> -	} while (!(irq & flags) && wait--);

> +	int ret;

>

> -	if (wait < 0) {

> +	ret = readl_poll_timeout(&dev->regs->intr, irq, irq & flags,

> +				 dev->timeout);

> +	if (ret < 0) {

>   		debug("error: time out\n");

>   		return ret;

>   	}

> @@ -172,7 +158,7 @@ static int issue_stop(struct uniphier_fi2c_dev *dev, int old_ret)

>   	debug("stop condition\n");

>   	writel(I2C_CR_MST | I2C_CR_STO, &dev->regs->cr);

>

> -	ret = poll_status(&dev->regs->sr, I2C_SR_DB);

> +	ret = check_device_busy(dev->regs);

>   	if (ret < 0)

>   		debug("error: device busy after operation\n");

>

>


-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot
diff mbox series

Patch

diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c
index e212c13..9f0df59 100644
--- a/drivers/i2c/i2c-uniphier-f.c
+++ b/drivers/i2c/i2c-uniphier-f.c
@@ -9,6 +9,7 @@ 
 #include <common.h>
 #include <linux/types.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/sizes.h>
 #include <linux/errno.h>
 #include <dm/device.h>
@@ -69,26 +70,14 @@  struct uniphier_fi2c_dev {
 	unsigned long timeout;			/* time out (us) */
 };
 
-static int poll_status(u32 __iomem *reg, u32 flag)
-{
-	int wait = 1000000; /* 1 sec is long enough */
-
-	while (readl(reg) & flag) {
-		if (wait-- < 0)
-			return -EREMOTEIO;
-		udelay(1);
-	}
-
-	return 0;
-}
-
 static int reset_bus(struct uniphier_fi2c_regs __iomem *regs)
 {
+	u32 val;
 	int ret;
 
 	/* bus forcible reset */
 	writel(I2C_RST_RST, &regs->rst);
-	ret = poll_status(&regs->rst, I2C_RST_RST);
+	ret = readl_poll_timeout(&regs->rst, val, !(val & I2C_RST_RST), 1);
 	if (ret < 0)
 		debug("error: fail to reset I2C controller\n");
 
@@ -97,9 +86,10 @@  static int reset_bus(struct uniphier_fi2c_regs __iomem *regs)
 
 static int check_device_busy(struct uniphier_fi2c_regs __iomem *regs)
 {
+	u32 val;
 	int ret;
 
-	ret = poll_status(&regs->sr, I2C_SR_DB);
+	ret = readl_poll_timeout(&regs->sr, val, !(val & I2C_SR_DB), 100);
 	if (ret < 0) {
 		debug("error: device busy too long. reset...\n");
 		ret = reset_bus(regs);
@@ -138,15 +128,11 @@  static int wait_for_irq(struct uniphier_fi2c_dev *dev, u32 flags,
 			bool *stop)
 {
 	u32 irq;
-	unsigned long wait = dev->timeout;
-	int ret = -EREMOTEIO;
-
-	do {
-		udelay(1);
-		irq = readl(&dev->regs->intr);
-	} while (!(irq & flags) && wait--);
+	int ret;
 
-	if (wait < 0) {
+	ret = readl_poll_timeout(&dev->regs->intr, irq, irq & flags,
+				 dev->timeout);
+	if (ret < 0) {
 		debug("error: time out\n");
 		return ret;
 	}
@@ -172,7 +158,7 @@  static int issue_stop(struct uniphier_fi2c_dev *dev, int old_ret)
 	debug("stop condition\n");
 	writel(I2C_CR_MST | I2C_CR_STO, &dev->regs->cr);
 
-	ret = poll_status(&dev->regs->sr, I2C_SR_DB);
+	ret = check_device_busy(dev->regs);
 	if (ret < 0)
 		debug("error: device busy after operation\n");