aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses
diff options
context:
space:
mode:
authorAlexander Shishkin <virtuoso@slind.org>2010-05-11 14:35:17 -0400
committerBen Dooks <ben-linux@fluff.org>2010-05-19 19:18:59 -0400
commite9f59b9c9bc5730152b6a94c47dd90b730a07e35 (patch)
treeee00d5f5995a47dbb61d119967b4091a79c45580 /drivers/i2c/busses
parent2dd151ab2792cd27a2268a6e4f3248193beed504 (diff)
omap: i2c: add a timeout to the busy waiting
The errata 1.153 workaround is busy waiting on XUDF bit in interrupt context, which may lead to kernel hangs. The problem can be reproduced by running the bus with wrong (too high) speed. Signed-off-by: Alexander Shishkin <virtuoso@slind.org> Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r--drivers/i2c/busses/i2c-omap.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index ef73483efb84..00fd02ec1b65 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -763,17 +763,25 @@ omap_i2c_rev1_isr(int this_irq, void *dev_id)
763 */ 763 */
764static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err) 764static int errata_omap3_1p153(struct omap_i2c_dev *dev, u16 *stat, int *err)
765{ 765{
766 while (!(*stat & OMAP_I2C_STAT_XUDF)) { 766 unsigned long timeout = 10000;
767
768 while (--timeout && !(*stat & OMAP_I2C_STAT_XUDF)) {
767 if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { 769 if (*stat & (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) {
768 omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY | 770 omap_i2c_ack_stat(dev, *stat & (OMAP_I2C_STAT_XRDY |
769 OMAP_I2C_STAT_XDR)); 771 OMAP_I2C_STAT_XDR));
770 *err |= OMAP_I2C_STAT_XUDF; 772 *err |= OMAP_I2C_STAT_XUDF;
771 return -ETIMEDOUT; 773 return -ETIMEDOUT;
772 } 774 }
775
773 cpu_relax(); 776 cpu_relax();
774 *stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); 777 *stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG);
775 } 778 }
776 779
780 if (!timeout) {
781 dev_err(dev->dev, "timeout waiting on XUDF bit\n");
782 return 0;
783 }
784
777 return 0; 785 return 0;
778} 786}
779 787