summary refs log tree commit diff
path: root/drivers/i2c/busses/i2c-au1550.c
diff options
context:
space:
mode:
authorDomen Puncer <domen.puncer@ultra.si>2006-08-13 23:35:40 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-26 15:38:50 -0700
commit8859942ede8154c1e90e3b0d1b60aecf0cfaa169 (patch)
treeb71e1447c4bce6ce4b7dfca581430cacdfc95533 /drivers/i2c/busses/i2c-au1550.c
parent643bd3fbd9dc73ed3dc1e4f6980e6f15fdbb9bb6 (diff)
downloadlinux-8859942ede8154c1e90e3b0d1b60aecf0cfaa169.tar.gz
i2c-au1550: Fix timeout problem
i2c-au1550: Fix timeout problem

Fix from Jordan Crouse:
If the transmit and recieve FIFOS are not empty, forceably flush them
rather then waiting for them to drain on their own.

This solves at least a problem reported by Clem Taylor:
http://www.linux-mips.org/archives/linux-mips/2006-05/msg00240.html
(1% of I2C transactions would timeout)

Signed-off-by: Domen Puncer <domen.puncer@ultra.si>
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Diffstat (limited to 'drivers/i2c/busses/i2c-au1550.c')
-rw-r--r--drivers/i2c/busses/i2c-au1550.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
index d06edce03bf4..02a359ebc0f0 100644
--- a/drivers/i2c/busses/i2c-au1550.c
+++ b/drivers/i2c/busses/i2c-au1550.c
@@ -118,13 +118,19 @@ do_address(struct i2c_au1550_data *adap, unsigned int addr, int rd)
 
 	/* Reset the FIFOs, clear events.
 	*/
-	sp->psc_smbpcr = PSC_SMBPCR_DC;
+	stat = sp->psc_smbstat;
 	sp->psc_smbevnt = PSC_SMBEVNT_ALLCLR;
 	au_sync();
-	do {
-		stat = sp->psc_smbpcr;
+
+	if (!(stat & PSC_SMBSTAT_TE) || !(stat & PSC_SMBSTAT_RE)) {
+		sp->psc_smbpcr = PSC_SMBPCR_DC;
 		au_sync();
-	} while ((stat & PSC_SMBPCR_DC) != 0);
+		do {
+			stat = sp->psc_smbpcr;
+			au_sync();
+		} while ((stat & PSC_SMBPCR_DC) != 0);
+		udelay(50);
+	}
 
 	/* Write out the i2c chip address and specify operation
 	*/