]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/i2c/busses/i2c-omap.c
i2c-omap: Close suspected race between omap_i2c_idle() and omap_i2c_isr()
[linux-2.6-omap-h63xx.git] / drivers / i2c / busses / i2c-omap.c
index 17476ecd97829ccf1849ee253f7d992da0d7dab7..5ca0e0010a0e76ea6909374fda900ce65214e40b 100644 (file)
@@ -181,22 +181,26 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev)
        if (dev->iclk != NULL)
                clk_enable(dev->iclk);
        clk_enable(dev->fclk);
+       dev->idle = 0;
        if (dev->iestate)
                omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
-       dev->idle = 0;
 }
 
 static void omap_i2c_idle(struct omap_i2c_dev *dev)
 {
        u16 iv;
 
-       dev->idle = 1;
        dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
        omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
-       if (dev->rev1)
+       if (dev->rev1) {
                iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);   /* Read clears */
-       else
+       } else {
                omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
+
+               /* Flush posted write before the dev->idle store occurs */
+               omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
+       }
+       dev->idle = 1;
        clk_disable(dev->fclk);
        if (dev->iclk != NULL)
                clk_disable(dev->iclk);