aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2005-03-30 22:28:46 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2005-03-30 22:28:46 -0800
commit79e63ffa339d60d47cdc4c5711009e2ef26e54fb (patch)
tree1c3925b947234624b8c377ca8e113f9e99cf9a45
parentcce0115c7b01dc9ed2b7be85eb9940db384de65f (diff)
downloadhistory-79e63ffa339d60d47cdc4c5711009e2ef26e54fb.tar.gz
[PATCH] I2C: Avoid repeated resets of i2c-viapro
It was reported that the i2c-viapro SMBus driver sometimes has trouble on recent systems (VT8237 south bridge). The "Host Status" register has at least one additional bit used when compared with older south bridges of this family. The driver currently considers this additional bit as an error condition when it's set, causing repeated bus resets and sometimes read failures. This patch makes the driver ignore the bits of the "Host Status" register for which no definition is known. I wish I had a datasheet for the VIA VT8237, so that I could check what the additional bit is supposed to mean, but I don't. If someone has a datasheet or good contacts at VIA, please let me know. The patch was reported to fix the problem on a system with the VT8237, and was also tested not to break the driver on older VIA south bridges, so it seems to be safe. Thanks to Aurelien Jarno for the tests. Additionally, the patch makes the post-transaction bus reset slightly more efficient by sparing a few unneeded I/O operations. Signed-off-by: Jean Delvare <khali@linux-fr.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/i2c/busses/i2c-viapro.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index c872c2849a0bf2..0bb60a636e166a 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -121,12 +121,12 @@ static int vt596_transaction(void)
inb_p(SMBHSTDAT1));
/* Make sure the SMBus host is ready to start transmitting */
- if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
+ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). "
"Resetting...\n", temp);
outb_p(temp, SMBHSTSTS);
- if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
+ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
dev_dbg(&vt596_adapter.dev, "Failed! (0x%02x)\n", temp);
return -1;
@@ -168,13 +168,14 @@ static int vt596_transaction(void)
dev_dbg(&vt596_adapter.dev, "Error: no response!\n");
}
- if (inb_p(SMBHSTSTS) != 0x00)
- outb_p(inb(SMBHSTSTS), SMBHSTSTS);
-
- if ((temp = inb_p(SMBHSTSTS)) != 0x00) {
- dev_dbg(&vt596_adapter.dev, "Failed reset at end of "
- "transaction (%02x)\n", temp);
+ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
+ outb_p(temp, SMBHSTSTS);
+ if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
+ dev_warn(&vt596_adapter.dev, "Failed reset at end "
+ "of transaction (%02x)\n", temp);
+ }
}
+
dev_dbg(&vt596_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, "
"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),