diff options
| -rw-r--r-- | arch/i386/pci/fixup.c | 59 |
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 | } |
| 386 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); | 388 | DECLARE_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 | */ | ||
| 399 | static u16 toshiba_line_size; | ||
| 400 | |||
| 401 | static 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 | |||
| 419 | static 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 | } | ||
| 427 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, 0x8032, | ||
| 428 | pci_pre_fixup_toshiba_ohci1394); | ||
| 429 | |||
| 430 | static 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 | } | ||
| 444 | DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032, | ||
| 445 | pci_post_fixup_toshiba_ohci1394); | ||
