diff options
Diffstat (limited to 'drivers/i2c')
-rw-r--r-- | drivers/i2c/at91_i2c.c | 18 | ||||
-rw-r--r-- | drivers/i2c/designware_i2c.c | 23 |
2 files changed, 18 insertions, 23 deletions
diff --git a/drivers/i2c/at91_i2c.c b/drivers/i2c/at91_i2c.c index d71f75c5faa..4bc54eea596 100644 --- a/drivers/i2c/at91_i2c.c +++ b/drivers/i2c/at91_i2c.c @@ -176,37 +176,21 @@ static void at91_calc_i2c_clock(struct udevice *dev, int i2c_clk) static int at91_i2c_enable_clk(struct udevice *dev) { struct at91_i2c_bus *bus = dev_get_priv(dev); - struct udevice *dev_clk; struct clk clk; ulong clk_rate; - int periph; int ret; ret = clk_get_by_index(dev, 0, &clk); if (ret) return -EINVAL; - periph = fdtdec_get_uint(gd->fdt_blob, clk.dev->of_offset, "reg", -1); - if (periph < 0) - return -EINVAL; - - dev_clk = dev_get_parent(clk.dev); - ret = clk_request(dev_clk, &clk); - if (ret) - return ret; - - clk.id = periph; ret = clk_enable(&clk); if (ret) return ret; - ret = clk_get_by_index(dev_clk, 0, &clk); - if (ret) - return ret; - clk_rate = clk_get_rate(&clk); if (!clk_rate) - return -ENODEV; + return -EINVAL; bus->bus_clk_rate = clk_rate; diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index e60fd0a4190..c68ff6420b2 100644 --- a/drivers/i2c/designware_i2c.c +++ b/drivers/i2c/designware_i2c.c @@ -249,6 +249,7 @@ static int __dw_i2c_read(struct i2c_regs *i2c_base, u8 dev, uint addr, int alen, u8 *buffer, int len) { unsigned long start_time_rx; + unsigned int active = 0; #ifdef CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW /* @@ -274,18 +275,28 @@ static int __dw_i2c_read(struct i2c_regs *i2c_base, u8 dev, uint addr, start_time_rx = get_timer(0); while (len) { - if (len == 1) - writel(IC_CMD | IC_STOP, &i2c_base->ic_cmd_data); - else - writel(IC_CMD, &i2c_base->ic_cmd_data); + if (!active) { + /* + * Avoid writing to ic_cmd_data multiple times + * in case this loop spins too quickly and the + * ic_status RFNE bit isn't set after the first + * write. Subsequent writes to ic_cmd_data can + * trigger spurious i2c transfer. + */ + if (len == 1) + writel(IC_CMD | IC_STOP, &i2c_base->ic_cmd_data); + else + writel(IC_CMD, &i2c_base->ic_cmd_data); + active = 1; + } if (readl(&i2c_base->ic_status) & IC_STATUS_RFNE) { *buffer++ = (uchar)readl(&i2c_base->ic_cmd_data); len--; start_time_rx = get_timer(0); - + active = 0; } else if (get_timer(start_time_rx) > I2C_BYTE_TO) { - return 1; + return 1; } } |