From f1ee329ba8ea8811e640d4bf8057d0f403ed2b00 Mon Sep 17 00:00:00 2001 From: Merlin Hughes Date: Tue, 30 Apr 2002 15:55:29 +0000 Subject: [PATCH] mh: Increase AMD 7x6 timeout to 500ms from 100ms, add code to abort/clear the bus on timeout. Appears? to improve reliability. git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@1362 7894878c-1315-0410-8ee3-d5d059ff63e0 --- kernel/busses/i2c-amd756.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/kernel/busses/i2c-amd756.c b/kernel/busses/i2c-amd756.c index 35bd6fc1..903f0e3a 100644 --- a/kernel/busses/i2c-amd756.c +++ b/kernel/busses/i2c-amd756.c @@ -83,7 +83,7 @@ static int supported[] = {PCI_DEVICE_ID_AMD_756, #define SMBREV 0x008 /* Other settings */ -#define MAX_TIMEOUT 100 +#define MAX_TIMEOUT 500 /* AMD756 constants */ #define AMD756_QUICK 0x00 @@ -234,6 +234,15 @@ void amd756_do_pause(unsigned int amount) #define GE_CYC_TYPE_MASK (7) #define GE_HOST_STC (1 << 3) +#define GE_ABORT (1 << 5) + +void amd756_abort(void) +{ + printk("i2c-amd756.o: Sending abort.\n"); + outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE); + amd756_do_pause(100); + outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS); +} int amd756_transaction(void) { @@ -261,8 +270,8 @@ int amd756_transaction(void) (timeout++ < MAX_TIMEOUT)); /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { - printk("i2c-amd756.o: Busy wait timeout! (%04x)\n", - temp); + printk("i2c-amd756.o: Busy wait timeout! (%04x)\n", temp); + amd756_abort(); return(-1); } timeout = 0; @@ -280,6 +289,7 @@ int amd756_transaction(void) /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { printk("i2c-amd756.o: Completion timeout!\n"); + amd756_abort (); return(-1); } @@ -293,7 +303,6 @@ int amd756_transaction(void) if (temp & GS_COL_STS) { result = -1; printk("i2c-amd756.o: SMBus collision!\n"); - /* TODO: Clear Collision Status with a 1 */ } if (temp & GS_TO_STS) {