summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-23 18:27:51 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-23 18:27:51 -0800
commit431047166883101a93e9c713d54bd62466dd6ab9 (patch)
tree7ff0f2ce7ad273f01e0bc567f439e576b0ba8891
parentf51671fc85562cdcc64ca59fe92719863c7c25f1 (diff)
parent57eb81b14e35a14df64ac3597bc90c26ce04a9b4 (diff)
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
-rw-r--r--drivers/i2c/busses/i2c-bfin-twi.c6
-rw-r--r--drivers/i2c/busses/i2c-omap.c13
2 files changed, 15 insertions, 4 deletions
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c
index b309ac2c3d5c..fe3fb567317d 100644
--- a/drivers/i2c/busses/i2c-bfin-twi.c
+++ b/drivers/i2c/busses/i2c-bfin-twi.c
@@ -693,13 +693,13 @@ static int i2c_bfin_twi_probe(struct platform_device *pdev)
}
/* 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
- * 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 */
write_CLKDIV(iface, (clkhilow << 8) | clkhilow);
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 75bf3ad18099..0037e31076ba 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -247,7 +247,13 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN);
}
dev->idle = 0;
- omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+
+ /*
+ * 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);
}
static void omap_i2c_idle(struct omap_i2c_dev *dev)
@@ -280,6 +286,11 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
unsigned long internal_clk = 0;
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);
/* For some reason we need to set the EN bit before the
* reset done bit gets set. */