diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/msi.c | 151 | ||||
-rw-r--r-- | drivers/pci/pci.c | 14 | ||||
-rw-r--r-- | drivers/pci/pci.h | 2 | ||||
-rw-r--r-- | drivers/pci/pcie/portdrv_pci.c | 2 | ||||
-rw-r--r-- | drivers/pci/probe.c | 45 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 18 |
6 files changed, 53 insertions, 179 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 01869b1782e..435c1958a7b 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -94,12 +94,14 @@ static void msi_set_mask_bit(unsigned int irq, int flag) | |||
94 | int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + | 94 | int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + |
95 | PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET; | 95 | PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET; |
96 | writel(flag, entry->mask_base + offset); | 96 | writel(flag, entry->mask_base + offset); |
97 | readl(entry->mask_base + offset); | ||
97 | break; | 98 | break; |
98 | } | 99 | } |
99 | default: | 100 | default: |
100 | BUG(); | 101 | BUG(); |
101 | break; | 102 | break; |
102 | } | 103 | } |
104 | entry->msi_attrib.masked = !!flag; | ||
103 | } | 105 | } |
104 | 106 | ||
105 | void read_msi_msg(unsigned int irq, struct msi_msg *msg) | 107 | void read_msi_msg(unsigned int irq, struct msi_msg *msg) |
@@ -179,6 +181,7 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg) | |||
179 | default: | 181 | default: |
180 | BUG(); | 182 | BUG(); |
181 | } | 183 | } |
184 | entry->msg = *msg; | ||
182 | } | 185 | } |
183 | 186 | ||
184 | void mask_msi_irq(unsigned int irq) | 187 | void mask_msi_irq(unsigned int irq) |
@@ -225,164 +228,60 @@ static struct msi_desc* alloc_msi_entry(void) | |||
225 | } | 228 | } |
226 | 229 | ||
227 | #ifdef CONFIG_PM | 230 | #ifdef CONFIG_PM |
228 | static int __pci_save_msi_state(struct pci_dev *dev) | ||
229 | { | ||
230 | int pos, i = 0; | ||
231 | u16 control; | ||
232 | struct pci_cap_saved_state *save_state; | ||
233 | u32 *cap; | ||
234 | |||
235 | if (!dev->msi_enabled) | ||
236 | return 0; | ||
237 | |||
238 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | ||
239 | if (pos <= 0) | ||
240 | return 0; | ||
241 | |||
242 | save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u32) * 5, | ||
243 | GFP_KERNEL); | ||
244 | if (!save_state) { | ||
245 | printk(KERN_ERR "Out of memory in pci_save_msi_state\n"); | ||
246 | return -ENOMEM; | ||
247 | } | ||
248 | cap = &save_state->data[0]; | ||
249 | |||
250 | pci_read_config_dword(dev, pos, &cap[i++]); | ||
251 | control = cap[0] >> 16; | ||
252 | pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, &cap[i++]); | ||
253 | if (control & PCI_MSI_FLAGS_64BIT) { | ||
254 | pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, &cap[i++]); | ||
255 | pci_read_config_dword(dev, pos + PCI_MSI_DATA_64, &cap[i++]); | ||
256 | } else | ||
257 | pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, &cap[i++]); | ||
258 | if (control & PCI_MSI_FLAGS_MASKBIT) | ||
259 | pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, &cap[i++]); | ||
260 | save_state->cap_nr = PCI_CAP_ID_MSI; | ||
261 | pci_add_saved_cap(dev, save_state); | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static void __pci_restore_msi_state(struct pci_dev *dev) | 231 | static void __pci_restore_msi_state(struct pci_dev *dev) |
266 | { | 232 | { |
267 | int i = 0, pos; | 233 | int pos; |
268 | u16 control; | 234 | u16 control; |
269 | struct pci_cap_saved_state *save_state; | 235 | struct msi_desc *entry; |
270 | u32 *cap; | ||
271 | 236 | ||
272 | if (!dev->msi_enabled) | 237 | if (!dev->msi_enabled) |
273 | return; | 238 | return; |
274 | 239 | ||
275 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSI); | 240 | entry = get_irq_msi(dev->irq); |
276 | pos = pci_find_capability(dev, PCI_CAP_ID_MSI); | 241 | pos = entry->msi_attrib.pos; |
277 | if (!save_state || pos <= 0) | ||
278 | return; | ||
279 | cap = &save_state->data[0]; | ||
280 | 242 | ||
281 | pci_intx(dev, 0); /* disable intx */ | 243 | pci_intx(dev, 0); /* disable intx */ |
282 | control = cap[i++] >> 16; | ||
283 | msi_set_enable(dev, 0); | 244 | msi_set_enable(dev, 0); |
284 | pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, cap[i++]); | 245 | write_msi_msg(dev->irq, &entry->msg); |
285 | if (control & PCI_MSI_FLAGS_64BIT) { | 246 | if (entry->msi_attrib.maskbit) |
286 | pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, cap[i++]); | 247 | msi_set_mask_bit(dev->irq, entry->msi_attrib.masked); |
287 | pci_write_config_dword(dev, pos + PCI_MSI_DATA_64, cap[i++]); | 248 | |
288 | } else | 249 | pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); |
289 | pci_write_config_dword(dev, pos + PCI_MSI_DATA_32, cap[i++]); | 250 | control &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE); |
290 | if (control & PCI_MSI_FLAGS_MASKBIT) | 251 | if (entry->msi_attrib.maskbit || !entry->msi_attrib.masked) |
291 | pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT, cap[i++]); | 252 | control |= PCI_MSI_FLAGS_ENABLE; |
292 | pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); | 253 | pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); |
293 | pci_remove_saved_cap(save_state); | ||
294 | kfree(save_state); | ||
295 | } | ||
296 | |||
297 | static int __pci_save_msix_state(struct pci_dev *dev) | ||
298 | { | ||
299 | int pos; | ||
300 | int irq, head, tail = 0; | ||
301 | u16 control; | ||
302 | struct pci_cap_saved_state *save_state; | ||
303 | |||
304 | if (!dev->msix_enabled) | ||
305 | return 0; | ||
306 | |||
307 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | ||
308 | if (pos <= 0) | ||
309 | return 0; | ||
310 | |||
311 | /* save the capability */ | ||
312 | pci_read_config_word(dev, msi_control_reg(pos), &control); | ||
313 | save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u16), | ||
314 | GFP_KERNEL); | ||
315 | if (!save_state) { | ||
316 | printk(KERN_ERR "Out of memory in pci_save_msix_state\n"); | ||
317 | return -ENOMEM; | ||
318 | } | ||
319 | *((u16 *)&save_state->data[0]) = control; | ||
320 | |||
321 | /* save the table */ | ||
322 | irq = head = dev->first_msi_irq; | ||
323 | while (head != tail) { | ||
324 | struct msi_desc *entry; | ||
325 | |||
326 | entry = get_irq_msi(irq); | ||
327 | read_msi_msg(irq, &entry->msg_save); | ||
328 | |||
329 | tail = entry->link.tail; | ||
330 | irq = tail; | ||
331 | } | ||
332 | |||
333 | save_state->cap_nr = PCI_CAP_ID_MSIX; | ||
334 | pci_add_saved_cap(dev, save_state); | ||
335 | return 0; | ||
336 | } | ||
337 | |||
338 | int pci_save_msi_state(struct pci_dev *dev) | ||
339 | { | ||
340 | int rc; | ||
341 | |||
342 | rc = __pci_save_msi_state(dev); | ||
343 | if (rc) | ||
344 | return rc; | ||
345 | |||
346 | rc = __pci_save_msix_state(dev); | ||
347 | |||
348 | return rc; | ||
349 | } | 254 | } |
350 | 255 | ||
351 | static void __pci_restore_msix_state(struct pci_dev *dev) | 256 | static void __pci_restore_msix_state(struct pci_dev *dev) |
352 | { | 257 | { |
353 | u16 save; | ||
354 | int pos; | 258 | int pos; |
355 | int irq, head, tail = 0; | 259 | int irq, head, tail = 0; |
356 | struct msi_desc *entry; | 260 | struct msi_desc *entry; |
357 | struct pci_cap_saved_state *save_state; | 261 | u16 control; |
358 | 262 | ||
359 | if (!dev->msix_enabled) | 263 | if (!dev->msix_enabled) |
360 | return; | 264 | return; |
361 | 265 | ||
362 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX); | ||
363 | if (!save_state) | ||
364 | return; | ||
365 | save = *((u16 *)&save_state->data[0]); | ||
366 | pci_remove_saved_cap(save_state); | ||
367 | kfree(save_state); | ||
368 | |||
369 | pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); | ||
370 | if (pos <= 0) | ||
371 | return; | ||
372 | |||
373 | /* route the table */ | 266 | /* route the table */ |
374 | pci_intx(dev, 0); /* disable intx */ | 267 | pci_intx(dev, 0); /* disable intx */ |
375 | msix_set_enable(dev, 0); | 268 | msix_set_enable(dev, 0); |
376 | irq = head = dev->first_msi_irq; | 269 | irq = head = dev->first_msi_irq; |
270 | entry = get_irq_msi(irq); | ||
271 | pos = entry->msi_attrib.pos; | ||
377 | while (head != tail) { | 272 | while (head != tail) { |
378 | entry = get_irq_msi(irq); | 273 | entry = get_irq_msi(irq); |
379 | write_msi_msg(irq, &entry->msg_save); | 274 | write_msi_msg(irq, &entry->msg); |
275 | msi_set_mask_bit(irq, entry->msi_attrib.masked); | ||
380 | 276 | ||
381 | tail = entry->link.tail; | 277 | tail = entry->link.tail; |
382 | irq = tail; | 278 | irq = tail; |
383 | } | 279 | } |
384 | 280 | ||
385 | pci_write_config_word(dev, msi_control_reg(pos), save); | 281 | pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); |
282 | control &= ~PCI_MSIX_FLAGS_MASKALL; | ||
283 | control |= PCI_MSIX_FLAGS_ENABLE; | ||
284 | pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); | ||
386 | } | 285 | } |
387 | 286 | ||
388 | void pci_restore_msi_state(struct pci_dev *dev) | 287 | void pci_restore_msi_state(struct pci_dev *dev) |
@@ -420,6 +319,7 @@ static int msi_capability_init(struct pci_dev *dev) | |||
420 | entry->msi_attrib.is_64 = is_64bit_address(control); | 319 | entry->msi_attrib.is_64 = is_64bit_address(control); |
421 | entry->msi_attrib.entry_nr = 0; | 320 | entry->msi_attrib.entry_nr = 0; |
422 | entry->msi_attrib.maskbit = is_mask_bit_support(control); | 321 | entry->msi_attrib.maskbit = is_mask_bit_support(control); |
322 | entry->msi_attrib.masked = 1; | ||
423 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ | 323 | entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ |
424 | entry->msi_attrib.pos = pos; | 324 | entry->msi_attrib.pos = pos; |
425 | if (is_mask_bit_support(control)) { | 325 | if (is_mask_bit_support(control)) { |
@@ -507,6 +407,7 @@ static int msix_capability_init(struct pci_dev *dev, | |||
507 | entry->msi_attrib.is_64 = 1; | 407 | entry->msi_attrib.is_64 = 1; |
508 | entry->msi_attrib.entry_nr = j; | 408 | entry->msi_attrib.entry_nr = j; |
509 | entry->msi_attrib.maskbit = 1; | 409 | entry->msi_attrib.maskbit = 1; |
410 | entry->msi_attrib.masked = 1; | ||
510 | entry->msi_attrib.default_irq = dev->irq; | 411 | entry->msi_attrib.default_irq = dev->irq; |
511 | entry->msi_attrib.pos = pos; | 412 | entry->msi_attrib.pos = pos; |
512 | entry->dev = dev; | 413 | entry->dev = dev; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index a32db062815..d3eab057b2d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -551,7 +551,9 @@ static int pci_save_pcie_state(struct pci_dev *dev) | |||
551 | if (pos <= 0) | 551 | if (pos <= 0) |
552 | return 0; | 552 | return 0; |
553 | 553 | ||
554 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL); | 554 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); |
555 | if (!save_state) | ||
556 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL); | ||
555 | if (!save_state) { | 557 | if (!save_state) { |
556 | dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); | 558 | dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); |
557 | return -ENOMEM; | 559 | return -ENOMEM; |
@@ -582,8 +584,6 @@ static void pci_restore_pcie_state(struct pci_dev *dev) | |||
582 | pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]); | 584 | pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]); |
583 | pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); | 585 | pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); |
584 | pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); | 586 | pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); |
585 | pci_remove_saved_cap(save_state); | ||
586 | kfree(save_state); | ||
587 | } | 587 | } |
588 | 588 | ||
589 | 589 | ||
@@ -597,7 +597,9 @@ static int pci_save_pcix_state(struct pci_dev *dev) | |||
597 | if (pos <= 0) | 597 | if (pos <= 0) |
598 | return 0; | 598 | return 0; |
599 | 599 | ||
600 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL); | 600 | save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); |
601 | if (!save_state) | ||
602 | save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL); | ||
601 | if (!save_state) { | 603 | if (!save_state) { |
602 | dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); | 604 | dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); |
603 | return -ENOMEM; | 605 | return -ENOMEM; |
@@ -622,8 +624,6 @@ static void pci_restore_pcix_state(struct pci_dev *dev) | |||
622 | cap = (u16 *)&save_state->data[0]; | 624 | cap = (u16 *)&save_state->data[0]; |
623 | 625 | ||
624 | pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]); | 626 | pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]); |
625 | pci_remove_saved_cap(save_state); | ||
626 | kfree(save_state); | ||
627 | } | 627 | } |
628 | 628 | ||
629 | 629 | ||
@@ -638,8 +638,6 @@ pci_save_state(struct pci_dev *dev) | |||
638 | /* XXX: 100% dword access ok here? */ | 638 | /* XXX: 100% dword access ok here? */ |
639 | for (i = 0; i < 16; i++) | 639 | for (i = 0; i < 16; i++) |
640 | pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); | 640 | pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); |
641 | if ((i = pci_save_msi_state(dev)) != 0) | ||
642 | return i; | ||
643 | if ((i = pci_save_pcie_state(dev)) != 0) | 641 | if ((i = pci_save_pcie_state(dev)) != 0) |
644 | return i; | 642 | return i; |
645 | if ((i = pci_save_pcix_state(dev)) != 0) | 643 | if ((i = pci_save_pcix_state(dev)) != 0) |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index ae7a975995a..62ea04c8af6 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -52,10 +52,8 @@ static inline void pci_no_msi(void) { } | |||
52 | #endif | 52 | #endif |
53 | 53 | ||
54 | #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM) | 54 | #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM) |
55 | int pci_save_msi_state(struct pci_dev *dev); | ||
56 | void pci_restore_msi_state(struct pci_dev *dev); | 55 | void pci_restore_msi_state(struct pci_dev *dev); |
57 | #else | 56 | #else |
58 | static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; } | ||
59 | static inline void pci_restore_msi_state(struct pci_dev *dev) {} | 57 | static inline void pci_restore_msi_state(struct pci_dev *dev) {} |
60 | #endif | 58 | #endif |
61 | 59 | ||
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 0be5a0b3072..df383645e36 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -93,7 +93,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, | |||
93 | if (!dev->irq && dev->pin) { | 93 | if (!dev->irq && dev->pin) { |
94 | printk(KERN_WARNING | 94 | printk(KERN_WARNING |
95 | "%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", | 95 | "%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n", |
96 | __FUNCTION__, dev->device, dev->vendor); | 96 | __FUNCTION__, dev->vendor, dev->device); |
97 | } | 97 | } |
98 | if (pcie_port_device_register(dev)) { | 98 | if (pcie_port_device_register(dev)) { |
99 | pci_disable_device(dev); | 99 | pci_disable_device(dev); |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index a4a96826d9e..2fe1d690eb1 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -682,34 +682,7 @@ static void pci_read_irq(struct pci_dev *dev) | |||
682 | dev->irq = irq; | 682 | dev->irq = irq; |
683 | } | 683 | } |
684 | 684 | ||
685 | static void change_legacy_io_resource(struct pci_dev * dev, unsigned index, | 685 | #define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED) |
686 | unsigned start, unsigned end) | ||
687 | { | ||
688 | unsigned base = start & PCI_BASE_ADDRESS_IO_MASK; | ||
689 | unsigned len = (end | ~PCI_BASE_ADDRESS_IO_MASK) - base + 1; | ||
690 | |||
691 | /* | ||
692 | * Some X versions get confused when the BARs reported through | ||
693 | * /sys or /proc differ from those seen in config space, thus | ||
694 | * try to update the config space values, too. | ||
695 | */ | ||
696 | if (!(pci_resource_flags(dev, index) & IORESOURCE_IO)) | ||
697 | printk(KERN_WARNING "%s: cannot adjust BAR%u (not I/O)\n", | ||
698 | pci_name(dev), index); | ||
699 | else if (pci_resource_len(dev, index) != len) | ||
700 | printk(KERN_WARNING "%s: cannot adjust BAR%u (size %04X)\n", | ||
701 | pci_name(dev), index, (unsigned)pci_resource_len(dev, index)); | ||
702 | else { | ||
703 | printk(KERN_INFO "%s: trying to change BAR%u from %04X to %04X\n", | ||
704 | pci_name(dev), index, | ||
705 | (unsigned)pci_resource_start(dev, index), base); | ||
706 | pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + index * 4, base); | ||
707 | } | ||
708 | pci_resource_start(dev, index) = start; | ||
709 | pci_resource_end(dev, index) = end; | ||
710 | pci_resource_flags(dev, index) = | ||
711 | IORESOURCE_IO | IORESOURCE_PCI_FIXED | PCI_BASE_ADDRESS_SPACE_IO; | ||
712 | } | ||
713 | 686 | ||
714 | /** | 687 | /** |
715 | * pci_setup_device - fill in class and map information of a device | 688 | * pci_setup_device - fill in class and map information of a device |
@@ -762,12 +735,20 @@ static int pci_setup_device(struct pci_dev * dev) | |||
762 | u8 progif; | 735 | u8 progif; |
763 | pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); | 736 | pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); |
764 | if ((progif & 1) == 0) { | 737 | if ((progif & 1) == 0) { |
765 | change_legacy_io_resource(dev, 0, 0x1F0, 0x1F7); | 738 | dev->resource[0].start = 0x1F0; |
766 | change_legacy_io_resource(dev, 1, 0x3F6, 0x3F6); | 739 | dev->resource[0].end = 0x1F7; |
740 | dev->resource[0].flags = LEGACY_IO_RESOURCE; | ||
741 | dev->resource[1].start = 0x3F6; | ||
742 | dev->resource[1].end = 0x3F6; | ||
743 | dev->resource[1].flags = LEGACY_IO_RESOURCE; | ||
767 | } | 744 | } |
768 | if ((progif & 4) == 0) { | 745 | if ((progif & 4) == 0) { |
769 | change_legacy_io_resource(dev, 2, 0x170, 0x177); | 746 | dev->resource[2].start = 0x170; |
770 | change_legacy_io_resource(dev, 3, 0x376, 0x376); | 747 | dev->resource[2].end = 0x177; |
748 | dev->resource[2].flags = LEGACY_IO_RESOURCE; | ||
749 | dev->resource[3].start = 0x376; | ||
750 | dev->resource[3].end = 0x376; | ||
751 | dev->resource[3].flags = LEGACY_IO_RESOURCE; | ||
771 | } | 752 | } |
772 | } | 753 | } |
773 | break; | 754 | break; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 7f94fc098cd..65d6f23ead4 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -963,6 +963,13 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_ho | |||
963 | * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it | 963 | * bridge. Unfortunately, this device has no subvendor/subdevice ID. So it |
964 | * becomes necessary to do this tweak in two steps -- I've chosen the Host | 964 | * becomes necessary to do this tweak in two steps -- I've chosen the Host |
965 | * bridge as trigger. | 965 | * bridge as trigger. |
966 | * | ||
967 | * Note that we used to unhide the SMBus that way on Toshiba laptops | ||
968 | * (Satellite A40 and Tecra M2) but then found that the thermal management | ||
969 | * was done by SMM code, which could cause unsynchronized concurrent | ||
970 | * accesses to the SMBus registers, with potentially bad effects. Thus you | ||
971 | * should be very careful when adding new entries: if SMM is accessing the | ||
972 | * Intel SMBus, this is a very good reason to leave it hidden. | ||
966 | */ | 973 | */ |
967 | static int asus_hides_smbus; | 974 | static int asus_hides_smbus; |
968 | 975 | ||
@@ -1040,17 +1047,6 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) | |||
1040 | case 0x099c: /* HP Compaq nx6110 */ | 1047 | case 0x099c: /* HP Compaq nx6110 */ |
1041 | asus_hides_smbus = 1; | 1048 | asus_hides_smbus = 1; |
1042 | } | 1049 | } |
1043 | } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_TOSHIBA)) { | ||
1044 | if (dev->device == PCI_DEVICE_ID_INTEL_82855GM_HB) | ||
1045 | switch(dev->subsystem_device) { | ||
1046 | case 0x0001: /* Toshiba Satellite A40 */ | ||
1047 | asus_hides_smbus = 1; | ||
1048 | } | ||
1049 | else if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) | ||
1050 | switch(dev->subsystem_device) { | ||
1051 | case 0x0001: /* Toshiba Tecra M2 */ | ||
1052 | asus_hides_smbus = 1; | ||
1053 | } | ||
1054 | } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG)) { | 1050 | } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG)) { |
1055 | if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) | 1051 | if (dev->device == PCI_DEVICE_ID_INTEL_82855PM_HB) |
1056 | switch(dev->subsystem_device) { | 1052 | switch(dev->subsystem_device) { |