[U-Boot] [PATCH 16/16] i2c: uniphier-f: use readl_poll_timeout() to poll registers
Heiko Schocher
hs at denx.de
Tue Jan 31 06:09:18 CET 2017
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 at socionext.com>
> ---
>
> drivers/i2c/i2c-uniphier-f.c | 34 ++++++++++------------------------
> 1 file changed, 10 insertions(+), 24 deletions(-)
Reviewed-by: Heiko Schocher <hs at 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, ®s->rst);
> - ret = poll_status(®s->rst, I2C_RST_RST);
> + ret = readl_poll_timeout(®s->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(®s->sr, I2C_SR_DB);
> + ret = readl_poll_timeout(®s->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
More information about the U-Boot
mailing list