diff options
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 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, | |||
104 | static int piix4_transaction(void); | 104 | static int piix4_transaction(void); |
105 | 105 | ||
106 | static unsigned short piix4_smba; | 106 | static unsigned short piix4_smba; |
107 | static int srvrworks_csb5_delay; | ||
107 | static struct pci_driver piix4_driver; | 108 | static struct pci_driver piix4_driver; |
108 | static struct i2c_adapter piix4_adapter; | 109 | static struct i2c_adapter piix4_adapter; |
109 | 110 | ||
110 | static struct dmi_system_id __devinitdata piix4_dmi_table[] = { | 111 | static 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 */ | ||
131 | static 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) { |