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.masah...@socionext.com>
---

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

Reviewed-by: Heiko Schocher <h...@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

Reply via email to