forked from Minki/linux
Merge branch 'i2c-fixes-rc4' of git://aeryn.fluff.org.uk/bjdooks/linux
* 'i2c-fixes-rc4' of git://aeryn.fluff.org.uk/bjdooks/linux: i2c-omap: OMAP3430 Silicon Errata 1.153 i2c-omap: In case of a NACK|ARDY|AL return from the ISR i2c-omap: Bug in reading the RXSTAT/TXSTAT values from the I2C_BUFFSTAT register i2c-sh_mobile: change module_init() to subsys_initcall() i2c: strncpy does not null terminate string i2c-s3c2410: s3c24xx_i2c_init: don't clobber IICLC value
This commit is contained in:
commit
658874f05d
@ -672,9 +672,10 @@ omap_i2c_isr(int this_irq, void *dev_id)
|
||||
break;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
complete:
|
||||
omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat);
|
||||
|
||||
err = 0;
|
||||
if (stat & OMAP_I2C_STAT_NACK) {
|
||||
err |= OMAP_I2C_STAT_NACK;
|
||||
omap_i2c_write_reg(dev, OMAP_I2C_CON_REG,
|
||||
@ -685,16 +686,19 @@ omap_i2c_isr(int this_irq, void *dev_id)
|
||||
err |= OMAP_I2C_STAT_AL;
|
||||
}
|
||||
if (stat & (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK |
|
||||
OMAP_I2C_STAT_AL))
|
||||
OMAP_I2C_STAT_AL)) {
|
||||
omap_i2c_complete_cmd(dev, err);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
if (stat & (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) {
|
||||
u8 num_bytes = 1;
|
||||
if (dev->fifo_size) {
|
||||
if (stat & OMAP_I2C_STAT_RRDY)
|
||||
num_bytes = dev->fifo_size;
|
||||
else
|
||||
num_bytes = omap_i2c_read_reg(dev,
|
||||
OMAP_I2C_BUFSTAT_REG);
|
||||
else /* read RXSTAT on RDR interrupt */
|
||||
num_bytes = (omap_i2c_read_reg(dev,
|
||||
OMAP_I2C_BUFSTAT_REG)
|
||||
>> 8) & 0x3F;
|
||||
}
|
||||
while (num_bytes) {
|
||||
num_bytes--;
|
||||
@ -731,9 +735,10 @@ omap_i2c_isr(int this_irq, void *dev_id)
|
||||
if (dev->fifo_size) {
|
||||
if (stat & OMAP_I2C_STAT_XRDY)
|
||||
num_bytes = dev->fifo_size;
|
||||
else
|
||||
else /* read TXSTAT on XDR interrupt */
|
||||
num_bytes = omap_i2c_read_reg(dev,
|
||||
OMAP_I2C_BUFSTAT_REG);
|
||||
OMAP_I2C_BUFSTAT_REG)
|
||||
& 0x3F;
|
||||
}
|
||||
while (num_bytes) {
|
||||
num_bytes--;
|
||||
@ -760,6 +765,27 @@ omap_i2c_isr(int this_irq, void *dev_id)
|
||||
"data to send\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* OMAP3430 Errata 1.153: When an XRDY/XDR
|
||||
* is hit, wait for XUDF before writing data
|
||||
* to DATA_REG. Otherwise some data bytes can
|
||||
* be lost while transferring them from the
|
||||
* memory to the I2C interface.
|
||||
*/
|
||||
|
||||
if (cpu_is_omap34xx()) {
|
||||
while (!(stat & OMAP_I2C_STAT_XUDF)) {
|
||||
if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
|
||||
omap_i2c_ack_stat(dev, stat & (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR));
|
||||
err |= OMAP_I2C_STAT_XUDF;
|
||||
goto complete;
|
||||
}
|
||||
cpu_relax();
|
||||
stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
|
||||
}
|
||||
}
|
||||
|
||||
omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
|
||||
}
|
||||
omap_i2c_ack_stat(dev,
|
||||
@ -879,7 +905,7 @@ omap_i2c_probe(struct platform_device *pdev)
|
||||
i2c_set_adapdata(adap, dev);
|
||||
adap->owner = THIS_MODULE;
|
||||
adap->class = I2C_CLASS_HWMON;
|
||||
strncpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
|
||||
strlcpy(adap->name, "OMAP I2C adapter", sizeof(adap->name));
|
||||
adap->algo = &omap_i2c_algo;
|
||||
adap->dev.parent = &pdev->dev;
|
||||
|
||||
|
@ -763,11 +763,6 @@ static int s3c24xx_i2c_init(struct s3c24xx_i2c *i2c)
|
||||
dev_info(i2c->dev, "bus frequency set to %d KHz\n", freq);
|
||||
dev_dbg(i2c->dev, "S3C2410_IICCON=0x%02lx\n", iicon);
|
||||
|
||||
/* check for s3c2440 i2c controller */
|
||||
|
||||
if (s3c24xx_i2c_is2440(i2c))
|
||||
writel(0x0, i2c->regs + S3C2440_IICLC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -637,7 +637,7 @@ static void __exit sh_mobile_i2c_adap_exit(void)
|
||||
platform_driver_unregister(&sh_mobile_i2c_driver);
|
||||
}
|
||||
|
||||
module_init(sh_mobile_i2c_adap_init);
|
||||
subsys_initcall(sh_mobile_i2c_adap_init);
|
||||
module_exit(sh_mobile_i2c_adap_exit);
|
||||
|
||||
MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver");
|
||||
|
Loading…
Reference in New Issue
Block a user