mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
i2c-omap: fix I2C timeouts due to recursive omap_i2c_{un,}idle()
omap_i2c_unidle() and omap_i2c_idle() are called recursively during
omap_i2c_probe(). This is evidently unexpected and will wipe
out the I2C interrupt enable register the second time that
omap_i2c_idle() is called consecutively. Any I2C transactions
following a probe of a bus with at least one device on it will then
time out.
Fix by moving omap_i2c_idle() further up in omap_i2c_probe(). Ensure
the I2C controller is marked as idle before the probe starts. Also
attempt to catch future reappearances of this bug early in development
by warning in omap_i2c_{un,}idle() when they are called recursively.
Problem reported by David Brownell <[email protected]>.
Tested on 3430SDP and 2430SDP.
Signed-off-by: Paul Walmsley <[email protected]>
Cc: David Brownell <[email protected]>
Cc: Richard Woodruff <[email protected]>
Acked-by; Steve Sakoman <[email protected]>
Signed-off-by: Tony Lindgren <[email protected]>
This commit is contained in:
parent
c1a473bde4
commit
3831f15441
1 changed files with 7 additions and 2 deletions
|
|
@ -191,6 +191,8 @@ static void omap_i2c_put_clocks(struct omap_i2c_dev *dev)
|
|||
|
||||
static void omap_i2c_unidle(struct omap_i2c_dev *dev)
|
||||
{
|
||||
WARN_ON(!dev->idle);
|
||||
|
||||
if (dev->iclk != NULL)
|
||||
clk_enable(dev->iclk);
|
||||
clk_enable(dev->fclk);
|
||||
|
|
@ -203,6 +205,8 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev)
|
|||
{
|
||||
u16 iv;
|
||||
|
||||
WARN_ON(dev->idle);
|
||||
|
||||
dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
|
||||
omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
|
||||
if (dev->rev1) {
|
||||
|
|
@ -740,6 +744,7 @@ omap_i2c_probe(struct platform_device *pdev)
|
|||
speed = 100; /* Defualt speed */
|
||||
|
||||
dev->speed = speed;
|
||||
dev->idle = 1;
|
||||
dev->dev = &pdev->dev;
|
||||
dev->irq = irq->start;
|
||||
dev->base = ioremap(mem->start, mem->end - mem->start + 1);
|
||||
|
|
@ -788,6 +793,8 @@ omap_i2c_probe(struct platform_device *pdev)
|
|||
dev_info(dev->dev, "bus %d rev%d.%d at %d kHz\n",
|
||||
pdev->id, r >> 4, r & 0xf, dev->speed);
|
||||
|
||||
omap_i2c_idle(dev);
|
||||
|
||||
adap = &dev->adapter;
|
||||
i2c_set_adapdata(adap, dev);
|
||||
adap->owner = THIS_MODULE;
|
||||
|
|
@ -804,8 +811,6 @@ omap_i2c_probe(struct platform_device *pdev)
|
|||
goto err_free_irq;
|
||||
}
|
||||
|
||||
omap_i2c_idle(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_irq:
|
||||
|
|
|
|||
Loading…
Reference in a new issue