diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-11 17:09:24 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-11 17:09:24 -0700 |
commit | 57014123512633ab0c38a4fea4140bf156f6a3a0 (patch) | |
tree | a46e864f9c508d8228e79928519742af6a42b7e4 /drivers/i2c/busses/i2c-piix4.c | |
parent | c3921ab71507b108d51a0f1ee960f80cd668a93d (diff) | |
parent | ae429083efe996ca2c569c44fd6fea440676dc33 (diff) |
Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
* 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6:
i2c: Convert some more new-style drivers to use module aliasing
i2c: Match dummy devices by type
i2c-sibyte: Mark i2c_sibyte_add_bus() as static
i2c-sibyte: Correct a comment about frequency
i2c: Improve the functionality documentation
i2c: Improve smbus-protocol documentation
i2c-piix4: Blacklist two mainboards
i2c-piix4: Increase the intitial delay for the ServerWorks CSB5
i2c-mpc: Compare to NO_IRQ instead of zero
Diffstat (limited to 'drivers/i2c/busses/i2c-piix4.c')
-rw-r--r-- | drivers/i2c/busses/i2c-piix4.c | 47 |
1 files changed, 42 insertions, 5 deletions
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index fdc9ad805e3..ac916596858 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -104,10 +104,31 @@ MODULE_PARM_DESC(force_addr, static int piix4_transaction(void); static unsigned short piix4_smba; +static int srvrworks_csb5_delay; static struct pci_driver piix4_driver; static struct i2c_adapter piix4_adapter; -static struct dmi_system_id __devinitdata piix4_dmi_table[] = { +static struct dmi_system_id __devinitdata piix4_dmi_blacklist[] = { + { + .ident = "Sapphire AM2RD790", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "SAPPHIRE Inc."), + DMI_MATCH(DMI_BOARD_NAME, "PC-AM2RD790"), + }, + }, + { + .ident = "DFI Lanparty UT 790FX", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "DFI Inc."), + DMI_MATCH(DMI_BOARD_NAME, "LP UT 790FX"), + }, + }, + { } +}; + +/* The IBM entry is in a separate table because we only check it + on Intel-based systems */ +static struct dmi_system_id __devinitdata piix4_dmi_ibm[] = { { .ident = "IBM", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, @@ -122,8 +143,20 @@ static int __devinit piix4_setup(struct pci_dev *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; + + /* On some motherboards, it was reported that accessing the SMBus + caused severe hardware problems */ + if (dmi_check_system(piix4_dmi_blacklist)) { + dev_err(&PIIX4_dev->dev, + "Accessing the SMBus on this system is unsafe!\n"); + return -EPERM; + } + /* Don't access SMBus on IBM systems which get corrupted eeproms */ - if (dmi_check_system(piix4_dmi_table) && + if (dmi_check_system(piix4_dmi_ibm) && PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) { dev_err(&PIIX4_dev->dev, "IBM system detected; this module " "may corrupt your serial eeprom! Refusing to load " @@ -230,10 +263,14 @@ static int piix4_transaction(void) outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); /* 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); - temp = inb_p(SMBHSTSTS); - } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT)); /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { |