aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVikram Pandita <vikram.pandita@ti.com>2012-07-31 12:41:48 +0300
committerDmytro Kedrovskyi <x0169235@ti.com>2012-08-03 18:20:44 +0300
commit13a9e5db99427e186c637d94eba50c0b114104fd (patch)
tree1af5b297c960213c860ceff75873dd65da60c347
parent400e44f3fccb7df91e220044e1cf9453938b2303 (diff)
downloadkernel_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.c31
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 */