diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-23 21:27:51 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-12-23 21:27:51 -0500 |
commit | 431047166883101a93e9c713d54bd62466dd6ab9 (patch) | |
tree | 7ff0f2ce7ad273f01e0bc567f439e576b0ba8891 | |
parent | f51671fc85562cdcc64ca59fe92719863c7c25f1 (diff) | |
parent | 57eb81b14e35a14df64ac3597bc90c26ce04a9b4 (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.c | 6 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-omap.c | 13 |
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) | |||
693 | } | 693 | } |
694 | 694 | ||
695 | /* Set TWI internal clock as 10MHz */ | 695 | /* Set TWI internal clock as 10MHz */ |
696 | write_CONTROL(iface, ((get_sclk() / 1024 / 1024 + 5) / 10) & 0x7F); | 696 | write_CONTROL(iface, ((get_sclk() / 1000 / 1000 + 5) / 10) & 0x7F); |
697 | 697 | ||
698 | /* | 698 | /* |
699 | * We will not end up with a CLKDIV=0 because no one will specify | 699 | * We will not end up with a CLKDIV=0 because no one will specify |
700 | * 20kHz SCL or less in Kconfig now. (5 * 1024 / 20 = 0x100) | 700 | * 20kHz SCL or less in Kconfig now. (5 * 1000 / 20 = 250) |
701 | */ | 701 | */ |
702 | clkhilow = 5 * 1024 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ; | 702 | clkhilow = ((10 * 1000 / CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ) + 1) / 2; |
703 | 703 | ||
704 | /* Set Twi interface clock as specified */ | 704 | /* Set Twi interface clock as specified */ |
705 | write_CLKDIV(iface, (clkhilow << 8) | clkhilow); | 705 | 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) | |||
247 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); | 247 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); |
248 | } | 248 | } |
249 | dev->idle = 0; | 249 | dev->idle = 0; |
250 | omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); | 250 | |
251 | /* | ||
252 | * Don't write to this register if the IE state is 0 as it can | ||
253 | * cause deadlock. | ||
254 | */ | ||
255 | if (dev->iestate) | ||
256 | omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate); | ||
251 | } | 257 | } |
252 | 258 | ||
253 | static void omap_i2c_idle(struct omap_i2c_dev *dev) | 259 | static void omap_i2c_idle(struct omap_i2c_dev *dev) |
@@ -280,6 +286,11 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) | |||
280 | unsigned long internal_clk = 0; | 286 | unsigned long internal_clk = 0; |
281 | 287 | ||
282 | if (dev->rev >= OMAP_I2C_REV_2) { | 288 | if (dev->rev >= OMAP_I2C_REV_2) { |
289 | /* Disable I2C controller before soft reset */ | ||
290 | omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, | ||
291 | omap_i2c_read_reg(dev, OMAP_I2C_CON_REG) & | ||
292 | ~(OMAP_I2C_CON_EN)); | ||
293 | |||
283 | omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, SYSC_SOFTRESET_MASK); | 294 | omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, SYSC_SOFTRESET_MASK); |
284 | /* For some reason we need to set the EN bit before the | 295 | /* For some reason we need to set the EN bit before the |
285 | * reset done bit gets set. */ | 296 | * reset done bit gets set. */ |