aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/pci/fixup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/pci/fixup.c')
-rw-r--r--arch/i386/pci/fixup.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index 8e8e895e1b5a..330fd2b68075 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -2,6 +2,8 @@
2 * Exceptions for specific devices. Usually work-arounds for fatal design flaws. 2 * Exceptions for specific devices. Usually work-arounds for fatal design flaws.
3 */ 3 */
4 4
5#include <linux/delay.h>
6#include <linux/dmi.h>
5#include <linux/pci.h> 7#include <linux/pci.h>
6#include <linux/init.h> 8#include <linux/init.h>
7#include "pci.h" 9#include "pci.h"
@@ -384,3 +386,60 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
384 } 386 }
385} 387}
386DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); 388DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video);
389
390/*
391 * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A.
392 *
393 * We pretend to bring them out of full D3 state, and restore the proper
394 * IRQ, PCI cache line size, and BARs, otherwise the device won't function
395 * properly. In some cases, the device will generate an interrupt on
396 * the wrong IRQ line, causing any devices sharing the the line it's
397 * *supposed* to use to be disabled by the kernel's IRQ debug code.
398 */
399static u16 toshiba_line_size;
400
401static struct dmi_system_id __devinit toshiba_ohci1394_dmi_table[] = {
402 {
403 .ident = "Toshiba PS5 based laptop",
404 .matches = {
405 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
406 DMI_MATCH(DMI_PRODUCT_VERSION, "PS5"),
407 },
408 },
409 {
410 .ident = "Toshiba PSM4 based laptop",
411 .matches = {
412 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
413 DMI_MATCH(DMI_PRODUCT_VERSION, "PSM4"),
414 },
415 },
416 { }
417};
418
419static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
420{
421 if (!dmi_check_system(toshiba_ohci1394_dmi_table))
422 return; /* only applies to certain Toshibas (so far) */
423
424 dev->current_state = PCI_D3cold;
425 pci_read_config_word(dev, PCI_CACHE_LINE_SIZE, &toshiba_line_size);
426}
427DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, 0x8032,
428 pci_pre_fixup_toshiba_ohci1394);
429
430static void __devinit pci_post_fixup_toshiba_ohci1394(struct pci_dev *dev)
431{
432 if (!dmi_check_system(toshiba_ohci1394_dmi_table))
433 return; /* only applies to certain Toshibas (so far) */
434
435 /* Restore config space on Toshiba laptops */
436 mdelay(10);
437 pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, toshiba_line_size);
438 pci_write_config_word(dev, PCI_INTERRUPT_LINE, dev->irq);
439 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0,
440 pci_resource_start(dev, 0));
441 pci_write_config_dword(dev, PCI_BASE_ADDRESS_1,
442 pci_resource_start(dev, 1));
443}
444DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032,
445 pci_post_fixup_toshiba_ohci1394);