aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c/busses/i2c-piix4.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/i2c/busses/i2c-piix4.c')
-rw-r--r--drivers/i2c/busses/i2c-piix4.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index fdc9ad805e35..ac9165968587 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -104,10 +104,31 @@ 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
110static struct dmi_system_id __devinitdata piix4_dmi_table[] = { 111static struct dmi_system_id __devinitdata piix4_dmi_blacklist[] = {
112 {
113 .ident = "Sapphire AM2RD790",
114 .matches = {
115 DMI_MATCH(DMI_BOARD_VENDOR, "SAPPHIRE Inc."),
116 DMI_MATCH(DMI_BOARD_NAME, "PC-AM2RD790"),
117 },
118 },
119 {
120 .ident = "DFI Lanparty UT 790FX",
121 .matches = {
122 DMI_MATCH(DMI_BOARD_VENDOR, "DFI Inc."),
123 DMI_MATCH(DMI_BOARD_NAME, "LP UT 790FX"),
124 },
125 },
126 { }
127};
128
129/* The IBM entry is in a separate table because we only check it
130 on Intel-based systems */
131static struct dmi_system_id __devinitdata piix4_dmi_ibm[] = {
111 { 132 {
112 .ident = "IBM", 133 .ident = "IBM",
113 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, 134 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
@@ -122,8 +143,20 @@ static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
122 143
123 dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev)); 144 dev_info(&PIIX4_dev->dev, "Found %s device\n", pci_name(PIIX4_dev));
124 145
146 if ((PIIX4_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
147 (PIIX4_dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5))
148 srvrworks_csb5_delay = 1;
149
150 /* On some motherboards, it was reported that accessing the SMBus
151 caused severe hardware problems */
152 if (dmi_check_system(piix4_dmi_blacklist)) {
153 dev_err(&PIIX4_dev->dev,
154 "Accessing the SMBus on this system is unsafe!\n");
155 return -EPERM;
156 }
157
125 /* Don't access SMBus on IBM systems which get corrupted eeproms */ 158 /* Don't access SMBus on IBM systems which get corrupted eeproms */
126 if (dmi_check_system(piix4_dmi_table) && 159 if (dmi_check_system(piix4_dmi_ibm) &&
127 PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) { 160 PIIX4_dev->vendor == PCI_VENDOR_ID_INTEL) {
128 dev_err(&PIIX4_dev->dev, "IBM system detected; this module " 161 dev_err(&PIIX4_dev->dev, "IBM system detected; this module "
129 "may corrupt your serial eeprom! Refusing to load " 162 "may corrupt your serial eeprom! Refusing to load "
@@ -230,10 +263,14 @@ static int piix4_transaction(void)
230 outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT); 263 outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);
231 264
232 /* We will always wait for a fraction of a second! (See PIIX4 docs errata) */ 265 /* We will always wait for a fraction of a second! (See PIIX4 docs errata) */
233 do { 266 if (srvrworks_csb5_delay) /* Extra delay for SERVERWORKS_CSB5 */
267 msleep(2);
268 else
269 msleep(1);
270
271 while ((timeout++ < MAX_TIMEOUT) &&
272 ((temp = inb_p(SMBHSTSTS)) & 0x01))
234 msleep(1); 273 msleep(1);
235 temp = inb_p(SMBHSTSTS);
236 } while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));
237 274
238 /* If the SMBus is still busy, we give up */ 275 /* If the SMBus is still busy, we give up */
239 if (timeout >= MAX_TIMEOUT) { 276 if (timeout >= MAX_TIMEOUT) {