aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-piix4.c
diff options
context:
space:
mode:
authorDavid Milburn <dmilburn@redhat.com>2008-05-11 14:37:05 -0400
committerJean Delvare <khali@hyperion.delvare>2008-05-11 14:37:05 -0400
commitb1c1759cd192fe1d27989f986c7f6b2939905e0c (patch)
treebd8cc93f5ba349c39fb7cdcfbbdae627d8ece515 /drivers/i2c/busses/i2c-piix4.c
parentf5fff3602a67ff8c98fccdbf15959780be542802 (diff)
i2c-piix4: Increase the intitial delay for the ServerWorks CSB5
Per the PIIX4 errata, there maybe a delay between setting the start bit in the Smbus Host Controller Register and the transaction actually starting. If the driver doesn't delay long enough, it may appear that the transaction is complete when actually it hasn't started, this may lead to bus collisions. While 1 ms appears to be enough for most chips, the ServerWorks CSB5 wants 2 ms. Signed-off-by: David Milburn <dmilburn@redhat.com> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/i2c/busses/i2c-piix4.c')
-rw-r--r--drivers/i2c/busses/i2c-piix4.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index fdc9ad805e35..7217410f4251 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -104,6 +104,7 @@ MODULE_PARM_DESC(force_addr,
104static int piix4_transaction(void); 104static int piix4_transaction(void);
105 105
106static unsigned short piix4_smba; 106static unsigned short piix4_smba;
107static int srvrworks_csb5_delay;
107static struct pci_driver piix4_driver; 108static struct pci_driver piix4_driver;
108static struct i2c_adapter piix4_adapter; 109static struct i2c_adapter piix4_adapter;
109 110
@@ -122,6 +123,10 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
122 123
123 dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev)); 124 dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev));
124 125
126 if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
127 (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5))
128 srvrworks_csb5_delay = 1;
129
125 /* Don't access SMBus on IBM systems which get corrupted eeproms */ 130 /* Don't access SMBus on IBM systems which get corrupted eeproms */
126 if (dmi_check_system(piix4_dmi_table) && 131 if (dmi_check_system(piix4_dmi_table) &&
127 PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) { 132 PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
@@ -230,10 +235,14 @@ static int piix4_transaction(void)
230 outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); 235 outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
231 236
232 /* We will always wait for a fraction of a second! (See PIIX4 docs errata) */ 237 /* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
233 do { 238 if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
239 msleep(2);
240 else
241 msleep(1);
242
243 while ((timeout++ < MAX_TIMEOUT) &&
244 ((temp = inb_p(SMBHSTSTS)) & 0x01))
234 msleep(1); 245 msleep(1);
235 temp = inb_p(SMBHSTSTS);
236 } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
237 246
238 /* If the SMBus is still busy, we give up */ 247 /* If the SMBus is still busy, we give up */
239 if (timeout >= MAX_TIMEOUT) { 248 if (timeout >= MAX_TIMEOUT) {