]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/i2c/busses/i2c-omap.c
Merge branch 'sched-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[mv-sheeva.git] / drivers / i2c / busses / i2c-omap.c
index 9d090833e245a7a6cbe48dceedb2de60343ef58a..58a58c7eaa17d6eb7fac8b2ca6014110e0e3f225 100644 (file)
@@ -378,9 +378,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev)
                         * REVISIT: Some wkup sources might not be needed.
                         */
                        dev->westate = OMAP_I2C_WE_ALL;
-                       if (dev->rev < OMAP_I2C_REV_ON_4430)
-                               omap_i2c_write_reg(dev, OMAP_I2C_WE_REG,
-                                                               dev->westate);
+                       omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate);
                }
        }
        omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
@@ -598,12 +596,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap,
         * REVISIT: We should abort the transfer on signals, but the bus goes
         * into arbitration and we're currently unable to recover from it.
         */
-       if (dev->set_mpu_wkup_lat != NULL)
-               dev->set_mpu_wkup_lat(dev->dev, dev->latency);
        r = wait_for_completion_timeout(&dev->cmd_complete,
                                        OMAP_I2C_TIMEOUT);
-       if (dev->set_mpu_wkup_lat != NULL)
-               dev->set_mpu_wkup_lat(dev->dev, -1);
        dev->buf_len = 0;
        if (r < 0)
                return r;
@@ -654,12 +648,18 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
        if (r < 0)
                goto out;
 
+       if (dev->set_mpu_wkup_lat != NULL)
+               dev->set_mpu_wkup_lat(dev->dev, dev->latency);
+
        for (i = 0; i < num; i++) {
                r = omap_i2c_xfer_msg(adap, &msgs[i], (i == (num - 1)));
                if (r != 0)
                        break;
        }
 
+       if (dev->set_mpu_wkup_lat != NULL)
+               dev->set_mpu_wkup_lat(dev->dev, -1);
+
        if (r == 0)
                r = num;
 
@@ -845,11 +845,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;
                }
@@ -1135,12 +1139,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,
        },
 };