mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-10 23:24:38 +00:00
i2c: uniphier-f: use readl_poll_timeout() to poll registers
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>
This commit is contained in:
parent
800acb850e
commit
68578582ab
1 changed files with 10 additions and 24 deletions
|
@ -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;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
udelay(1);
|
||||
irq = readl(&dev->regs->intr);
|
||||
} while (!(irq & flags) && wait--);
|
||||
|
||||
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");
|
||||
|
||||
|
|
Loading…
Reference in a new issue