Skip to content
Snippets Groups Projects
Commit b1c1759c authored by David Milburn's avatar David Milburn Committed by Jean Delvare
Browse files

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: default avatarDavid Milburn <dmilburn@redhat.com>
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
parent f5fff360
No related branches found
No related tags found
No related merge requests found
...@@ -104,6 +104,7 @@ MODULE_PARM_DESC(force_addr, ...@@ -104,6 +104,7 @@ MODULE_PARM_DESC(force_addr,
static int piix4_transaction(void); static int piix4_transaction(void);
static unsigned short piix4_smba; static unsigned short piix4_smba;
static int srvrworks_csb5_delay;
static struct pci_driver piix4_driver; static struct pci_driver piix4_driver;
static struct i2c_adapter piix4_adapter; static struct i2c_adapter piix4_adapter;
...@@ -122,6 +123,10 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev, ...@@ -122,6 +123,10 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev)); dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev));
if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
(PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5))
srvrworks_csb5_delay = 1;
/* Don't access SMBus on IBM systems which get corrupted eeproms */ /* Don't access SMBus on IBM systems which get corrupted eeproms */
if (dmi_check_system(piix4_dmi_table) && if (dmi_check_system(piix4_dmi_table) &&
PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) { PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
...@@ -230,10 +235,14 @@ static int piix4_transaction(void) ...@@ -230,10 +235,14 @@ static int piix4_transaction(void)
outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
/* We will always wait for a fraction of a second! (See PIIX4 docs errata) */ /* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
do { if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
msleep(2);
else
msleep(1);
while ((timeout++ < MAX_TIMEOUT) &&
((temp = inb_p(SMBHSTSTS)) & 0x01))
msleep(1); msleep(1);
temp = inb_p(SMBHSTSTS);
} while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
/* If the SMBus is still busy, we give up */ /* If the SMBus is still busy, we give up */
if (timeout >= MAX_TIMEOUT) { if (timeout >= MAX_TIMEOUT) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment