Commit 43104716 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'i2c-fixes' of git://git.fluff.org/bjdooks/linux

* 'i2c-fixes' of git://git.fluff.org/bjdooks/linux:
  i2c-omap: OMAP3: Fix I2C lockup during timeout/error cases
  i2c-omap: Don't write IE state in unidle if 0
  i2c-bfin-twi: fix CLKDIV calculation
parents f51671fc 57eb81b1
...@@ -693,13 +693,13 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev) ...@@ -693,13 +693,13 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
} }
/* Set TWI internal clock as 10MHz */ /* Set TWI internal clock as 10MHz */
write_CONTROL(iface, ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F); write_CONTROL(iface, ((get_sclk() / 1000 / 1000 + 5) / 10) & 0x7F);
/* /*
* We will not end up with a CLKDIV=0 because no one will specify * We will not end up with a CLKDIV=0 because no one will specify
* 20kHz SCL or less in Kconfig now. (5 * 1024 / 20 = 0x100) * 20kHz SCL or less in Kconfig now. (5 * 1000 / 20 = 250)
*/ */
clkhilow = 5 * 1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ; clkhilow = ((10 * 1000 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ) + 1) / 2;
/* Set Twi interface clock as specified */ /* Set Twi interface clock as specified */
write_CLKDIV(iface, (clkhilow << 8) | clkhilow); write_CLKDIV(iface, (clkhilow << 8) | clkhilow);
......
...@@ -247,6 +247,12 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev) ...@@ -247,6 +247,12 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
} }
dev->idle = 0; dev->idle = 0;
/*
* Don't write to this register if the IE state is 0 as it can
* cause deadlock.
*/
if (dev->iestate)
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
} }
...@@ -280,6 +286,11 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) ...@@ -280,6 +286,11 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
unsigned long internal_clk = 0; unsigned long internal_clk = 0;
if (dev->rev >= OMAP_I2C_REV_2) { if (dev->rev >= OMAP_I2C_REV_2) {
/* Disable I2C controller before soft reset */
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
omap_i2c_read_reg(dev, OMAP_I2C_CON_REG) &
~(OMAP_I2C_CON_EN));
omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, SYSC_SOFTRESET_MASK); omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, SYSC_SOFTRESET_MASK);
/* For some reason we need to set the EN bit before the /* For some reason we need to set the EN bit before the
* reset done bit gets set. */ * reset done bit gets set. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment