diff options
author | Vikram Pandita <vikram.pandita@ti.com> | 2012-07-31 12:41:48 +0300 |
---|---|---|
committer | Dmytro Kedrovskyi <x0169235@ti.com> | 2012-08-03 18:20:44 +0300 |
commit | 13a9e5db99427e186c637d94eba50c0b114104fd (patch) | |
tree | 1af5b297c960213c860ceff75873dd65da60c347 | |
parent | 400e44f3fccb7df91e220044e1cf9453938b2303 (diff) | |
download | kernel_samsung_espresso10-13a9e5db99427e186c637d94eba50c0b114104fd.tar.gz kernel_samsung_espresso10-13a9e5db99427e186c637d94eba50c0b114104fd.tar.bz2 kernel_samsung_espresso10-13a9e5db99427e186c637d94eba50c0b114104fd.zip |
i2c: omap: implement shutdown handler
Once i2c driver shutdown has been called, ignore any more
transfer requests. This patch adds the missing callback.
Leave the PMIC i2c (i2c-1) alive, since power_off case needs it
well after shutdown handlers have been called for power_off case.
Change-Id: I4f4553327e5c024f78acb8501864dd9beb1883c3
Signed-off-by: Semen Protsenko <semen.protsenko@ti.com>
Signed-off-by: Vikram Pandita <vikram.pandita@ti.com>
-rw-r--r-- | drivers/i2c/busses/i2c-omap.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 496946d73d4..aa8fbd95135 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -191,6 +191,7 @@ struct omap_i2c_dev { * if set, should be trsh+1 */ u8 rev; + bool shutdown; unsigned b_hw:1; /* bad h/w fixes */ unsigned idle:1; u16 iestate; /* Saved interrupt register */ @@ -779,6 +780,9 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) pdata = pdev->dev.platform_data; #endif + if (dev->shutdown) + return -EPERM; + r = omap_i2c_hwspinlock_lock(dev); /* To-Do: if we are unable to acquire the lock, we must try to recover somehow */ @@ -989,7 +993,7 @@ omap_i2c_isr(int this_irq, void *dev_id) u16 stat, w; int err, count = 0; - if (dev->idle) + if (dev->idle || dev->shutdown) return IRQ_NONE; while ((stat = (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG))) & dev->iestate) { @@ -1350,6 +1354,30 @@ omap_i2c_remove(struct platform_device *pdev) return 0; } +#define PMIC_I2C_NAME "omap_i2c.1" +static void +omap_i2c_shutdown(struct platform_device *pdev) +{ + struct omap_i2c_dev *dev = platform_get_drvdata(pdev); + + /* Keep pmic i2c alive - for pm_power_off case */ + if (!strcmp(dev_name(dev->dev), PMIC_I2C_NAME)) + return; + + /* Shutdown all other i2c controllers */ + pm_runtime_get_sync(&pdev->dev); + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); + /* Keep interrupts disabled */ + free_irq(dev->irq, dev); + if (cpu_is_omap44xx() && dev->rev >= OMAP_I2C_REV_ON_4430) + omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 0x6FFF); + else + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); + pm_runtime_put_sync(&pdev->dev); + + dev->shutdown = true; +} + #ifdef CONFIG_SUSPEND static int omap_i2c_suspend(struct device *dev) { @@ -1384,6 +1412,7 @@ static struct platform_driver omap_i2c_driver = { .owner = THIS_MODULE, .pm = OMAP_I2C_PM_OPS, }, + .shutdown = omap_i2c_shutdown, }; /* I2C may be needed to bring up other drivers */ |