aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorFelipe Balbi <balbi@ti.com>2012-09-12 06:58:01 -0400
committerWolfram Sang <w.sang@pengutronix.de>2012-09-12 09:02:28 -0400
commit4151e74177b68c40079d8fe98f2fda4b9792a998 (patch)
treed8848fe19d195f8fcb0f5a543d8e98cecbae0f25 /drivers/i2c
parent6d9939f651419a63e091105663821f9c7d3fec37 (diff)
i2c: omap: improve i462 errata handling
Make it not depend on ISR's local variables in order to make it easier to re-factor the transmit data loop. Also since we are waiting for XUDF(Transmitter underflow) just before writing data lets not flag the underflow. This is anyways going to go once we write the data. Signed-off-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-omap.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 815577b1c89f..fb5722186d95 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -725,27 +725,30 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id)
725 * data to DATA_REG. Otherwise some data bytes can be lost while transferring 725 * data to DATA_REG. Otherwise some data bytes can be lost while transferring
726 * them from the memory to the I2C interface. 726 * them from the memory to the I2C interface.
727 */ 727 */
728static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err) 728static int errata_omap3_i462(struct omap_i2c_dev *dev)
729{ 729{
730 unsigned long timeout = 10000; 730 unsigned long timeout = 10000;
731 u16 stat;
731 732
732 while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) { 733 do {
733 if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { 734 stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
735 if (stat & OMAP_I2C_STAT_XUDF)
736 break;
737
738 if (stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
734 omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY | 739 omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY |
735 OMAP_I2C_STAT_XDR)); 740 OMAP_I2C_STAT_XDR));
736 return -ETIMEDOUT; 741 return -EIO;
737 } 742 }
738 743
739 cpu_relax(); 744 cpu_relax();
740 *stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); 745 } while (--timeout);
741 }
742 746
743 if (!timeout) { 747 if (!timeout) {
744 dev_err(dev->dev, "timeout waiting on XUDF bit\n"); 748 dev_err(dev->dev, "timeout waiting on XUDF bit\n");
745 return 0; 749 return 0;
746 } 750 }
747 751
748 *err |= OMAP_I2C_STAT_XUDF;
749 return 0; 752 return 0;
750} 753}
751 754
@@ -903,9 +906,16 @@ complete:
903 } 906 }
904 } 907 }
905 908
906 if ((dev->errata & I2C_OMAP_ERRATA_I462) && 909 if (dev->errata & I2C_OMAP_ERRATA_I462) {
907 errata_omap3_i462(dev, &stat, &err)) 910 int ret;
908 goto complete; 911
912 ret = errata_omap3_i462(dev);
913 stat = omap_i2c_read_reg(dev,
914 OMAP_I2C_STAT_REG);
915
916 if (ret < 0)
917 goto complete;
918 }
909 919
910 omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); 920 omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
911 } 921 }
@@ -943,9 +953,16 @@ complete:
943 } 953 }
944 } 954 }
945 955
946 if ((dev->errata & I2C_OMAP_ERRATA_I462) && 956 if (dev->errata & I2C_OMAP_ERRATA_I462) {
947 errata_omap3_i462(dev, &stat, &err)) 957 int ret;
948 goto complete; 958
959 ret = errata_omap3_i462(dev);
960 stat = omap_i2c_read_reg(dev,
961 OMAP_I2C_STAT_REG);
962
963 if (ret < 0)
964 goto complete;
965 }
949 966
950 omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); 967 omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w);
951 } 968 }