Skip to content

Commit f8977d0

Browse files
jbarnes993gregkh
authored andcommitted
[PATCH] PCI fixup for Toshiba laptops and ohci1394
This is a fix for a bug I see on my Toshiba laptop, where the ohci1394 controller gets initialized improperly. The patch adds two PCI fixups to arch/i386/pci/fixup.c, one that happens early on to cache the value of the PCI_CACHE_LINE_SIZE config register, and another that later restores the value, along with a valid IRQ number and some BAR values. I've tested it on my laptop, and it prevents me from running into what I consider to be a major bug: IRQ 11 is disabled by the IRQ debug code, causing my wireless to break. Thanks to Rob for the original patch to ohci1394.c and Stefan for lots of proofreading (and a last minute bug caught in review!) and additional information collection. I think the DMI system list is correct, but we may need to add some more PCI IDs to the PCI_FIXUP macros over time. Signed-off-by: Jesse Barnes <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 2f02823 commit f8977d0

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

arch/i386/pci/fixup.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
* Exceptions for specific devices. Usually work-arounds for fatal design flaws.
33
*/
44

5+
#include <linux/delay.h>
6+
#include <linux/dmi.h>
57
#include <linux/pci.h>
68
#include <linux/init.h>
79
#include "pci.h"
@@ -384,3 +386,60 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
384386
}
385387
}
386388
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);

0 commit comments

Comments
 (0)