return __raw_readw(i2c_dev->base + reg);
}
-static int omap_i2c_get_clocks(struct omap_i2c_dev *dev)
+static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
{
if (cpu_is_omap16xx() || cpu_class_is_omap2()) {
dev->iclk = clk_get(dev->dev, "i2c_ick");
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)
iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
else
omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
+ /*
+ * The wmb() is to ensure that the I2C interrupt mask write
+ * reaches the I2C controller before the dev->idle store
+ * occurs.
+ */
+ wmb();
+ dev->idle = 1;
clk_disable(dev->fclk);
if (dev->iclk != NULL)
clk_disable(dev->iclk);
omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat);
}
+/* rev1 devices are apparently only on some 15xx */
+#ifdef CONFIG_ARCH_OMAP15XX
+
static irqreturn_t
omap_i2c_rev1_isr(int this_irq, void *dev_id)
{
return IRQ_HANDLED;
}
+#else
+#define omap_i2c_rev1_isr 0
+#endif
static irqreturn_t
omap_i2c_isr(int this_irq, void *dev_id)
}
}
omap_i2c_ack_stat(dev, stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR));
+ continue;
}
if (stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) {
u8 num_bytes = 1;
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
}
omap_i2c_ack_stat(dev, stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
+ continue;
}
if (stat & OMAP_I2C_STAT_ROVR) {
dev_err(dev->dev, "Receive overrun\n");
dev->cmd_err |= OMAP_I2C_STAT_ROVR;
}
if (stat & OMAP_I2C_STAT_XUDF) {
- dev_err(dev->dev, "Transmit overflow\n");
+ dev_err(dev->dev, "Transmit underflow\n");
dev->cmd_err |= OMAP_I2C_STAT_XUDF;
}
}
.functionality = omap_i2c_func,
};
-static int
+static int __init
omap_i2c_probe(struct platform_device *pdev)
{
struct omap_i2c_dev *dev;
};
/* I2C may be needed to bring up other drivers */
-static int __init
+static int __devinit
omap_i2c_init_driver(void)
{
return platform_driver_register(&omap_i2c_driver);
}
subsys_initcall(omap_i2c_init_driver);
-static void __exit omap_i2c_exit_driver(void)
+static void __devexit omap_i2c_exit_driver(void)
{
platform_driver_unregister(&omap_i2c_driver);
}