|
@@ -847,11 +847,15 @@ complete:
|
|
|
dev_err(dev->dev, "Arbitration lost\n");
|
|
|
err |= OMAP_I2C_STAT_AL;
|
|
|
}
|
|
|
+ /*
|
|
|
+ * ProDB0017052: Clear ARDY bit twice
|
|
|
+ */
|
|
|
if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
|
|
|
OMAP_I2C_STAT_AL)) {
|
|
|
omap_i2c_ack_stat(dev, stat &
|
|
|
(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR |
|
|
|
- OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
|
|
|
+ OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR |
|
|
|
+ OMAP_I2C_STAT_ARDY));
|
|
|
omap_i2c_complete_cmd(dev, err);
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
@@ -1137,12 +1141,41 @@ omap_i2c_remove(struct platform_device *pdev)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_SUSPEND
|
|
|
+static int omap_i2c_suspend(struct device *dev)
|
|
|
+{
|
|
|
+ if (!pm_runtime_suspended(dev))
|
|
|
+ if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_suspend)
|
|
|
+ dev->bus->pm->runtime_suspend(dev);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int omap_i2c_resume(struct device *dev)
|
|
|
+{
|
|
|
+ if (!pm_runtime_suspended(dev))
|
|
|
+ if (dev->bus && dev->bus->pm && dev->bus->pm->runtime_resume)
|
|
|
+ dev->bus->pm->runtime_resume(dev);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static struct dev_pm_ops omap_i2c_pm_ops = {
|
|
|
+ .suspend = omap_i2c_suspend,
|
|
|
+ .resume = omap_i2c_resume,
|
|
|
+};
|
|
|
+#define OMAP_I2C_PM_OPS (&omap_i2c_pm_ops)
|
|
|
+#else
|
|
|
+#define OMAP_I2C_PM_OPS NULL
|
|
|
+#endif
|
|
|
+
|
|
|
static struct platform_driver omap_i2c_driver = {
|
|
|
.probe = omap_i2c_probe,
|
|
|
.remove = omap_i2c_remove,
|
|
|
.driver = {
|
|
|
.name = "omap_i2c",
|
|
|
.owner = THIS_MODULE,
|
|
|
+ .pm = OMAP_I2C_PM_OPS,
|
|
|
},
|
|
|
};
|
|
|
|