diff options
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r-- | drivers/pci/quirks.c | 84 |
1 files changed, 46 insertions, 38 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ef882a8a094e..c913ea4e545c 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -654,19 +654,42 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vi | |||
654 | * VIA bridges which have VLink | 654 | * VIA bridges which have VLink |
655 | */ | 655 | */ |
656 | 656 | ||
657 | static const struct pci_device_id via_vlink_fixup_tbl[] = { | 657 | static int via_vlink_dev_lo = -1, via_vlink_dev_hi = 18; |
658 | /* Internal devices need IRQ line routing, pre VLink */ | 658 | |
659 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686), 0 }, | 659 | static void quirk_via_bridge(struct pci_dev *dev) |
660 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8231), 17 }, | 660 | { |
661 | /* Devices with VLink */ | 661 | /* See what bridge we have and find the device ranges */ |
662 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233_0), 17}, | 662 | switch (dev->device) { |
663 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233A), 17 }, | 663 | case PCI_DEVICE_ID_VIA_82C686: |
664 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233C_0), 17 }, | 664 | /* The VT82C686 is special, it attaches to PCI and can have |
665 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8235), 16 }, | 665 | any device number. All its subdevices are functions of |
666 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237), 15 }, | 666 | that single device. */ |
667 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237A), 15 }, | 667 | via_vlink_dev_lo = PCI_SLOT(dev->devfn); |
668 | { 0, }, | 668 | via_vlink_dev_hi = PCI_SLOT(dev->devfn); |
669 | }; | 669 | break; |
670 | case PCI_DEVICE_ID_VIA_8237: | ||
671 | case PCI_DEVICE_ID_VIA_8237A: | ||
672 | via_vlink_dev_lo = 15; | ||
673 | break; | ||
674 | case PCI_DEVICE_ID_VIA_8235: | ||
675 | via_vlink_dev_lo = 16; | ||
676 | break; | ||
677 | case PCI_DEVICE_ID_VIA_8231: | ||
678 | case PCI_DEVICE_ID_VIA_8233_0: | ||
679 | case PCI_DEVICE_ID_VIA_8233A: | ||
680 | case PCI_DEVICE_ID_VIA_8233C_0: | ||
681 | via_vlink_dev_lo = 17; | ||
682 | break; | ||
683 | } | ||
684 | } | ||
685 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_bridge); | ||
686 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, quirk_via_bridge); | ||
687 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_0, quirk_via_bridge); | ||
688 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233A, quirk_via_bridge); | ||
689 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233C_0, quirk_via_bridge); | ||
690 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_via_bridge); | ||
691 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_bridge); | ||
692 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237A, quirk_via_bridge); | ||
670 | 693 | ||
671 | /** | 694 | /** |
672 | * quirk_via_vlink - VIA VLink IRQ number update | 695 | * quirk_via_vlink - VIA VLink IRQ number update |
@@ -675,35 +698,20 @@ static const struct pci_device_id via_vlink_fixup_tbl[] = { | |||
675 | * If the device we are dealing with is on a PIC IRQ we need to | 698 | * If the device we are dealing with is on a PIC IRQ we need to |
676 | * ensure that the IRQ line register which usually is not relevant | 699 | * ensure that the IRQ line register which usually is not relevant |
677 | * for PCI cards, is actually written so that interrupts get sent | 700 | * for PCI cards, is actually written so that interrupts get sent |
678 | * to the right place | 701 | * to the right place. |
702 | * We only do this on systems where a VIA south bridge was detected, | ||
703 | * and only for VIA devices on the motherboard (see quirk_via_bridge | ||
704 | * above). | ||
679 | */ | 705 | */ |
680 | 706 | ||
681 | static void quirk_via_vlink(struct pci_dev *dev) | 707 | static void quirk_via_vlink(struct pci_dev *dev) |
682 | { | 708 | { |
683 | const struct pci_device_id *via_vlink_fixup; | ||
684 | static int dev_lo = -1, dev_hi = 18; | ||
685 | u8 irq, new_irq; | 709 | u8 irq, new_irq; |
686 | 710 | ||
687 | /* Check if we have VLink and cache the result */ | 711 | /* Check if we have VLink at all */ |
688 | 712 | if (via_vlink_dev_lo == -1) | |
689 | /* Checked already - no */ | ||
690 | if (dev_lo == -2) | ||
691 | return; | 713 | return; |
692 | 714 | ||
693 | /* Not checked - see what bridge we have and find the device | ||
694 | ranges */ | ||
695 | |||
696 | if (dev_lo == -1) { | ||
697 | via_vlink_fixup = pci_find_present(via_vlink_fixup_tbl); | ||
698 | if (via_vlink_fixup == NULL) { | ||
699 | dev_lo = -2; | ||
700 | return; | ||
701 | } | ||
702 | dev_lo = via_vlink_fixup->driver_data; | ||
703 | /* 82C686 is special - 0/0 */ | ||
704 | if (dev_lo == 0) | ||
705 | dev_hi = 0; | ||
706 | } | ||
707 | new_irq = dev->irq; | 715 | new_irq = dev->irq; |
708 | 716 | ||
709 | /* Don't quirk interrupts outside the legacy IRQ range */ | 717 | /* Don't quirk interrupts outside the legacy IRQ range */ |
@@ -711,8 +719,8 @@ static void quirk_via_vlink(struct pci_dev *dev) | |||
711 | return; | 719 | return; |
712 | 720 | ||
713 | /* Internal device ? */ | 721 | /* Internal device ? */ |
714 | if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > dev_hi || | 722 | if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > via_vlink_dev_hi || |
715 | PCI_SLOT(dev->devfn) < dev_lo) | 723 | PCI_SLOT(dev->devfn) < via_vlink_dev_lo) |
716 | return; | 724 | return; |
717 | 725 | ||
718 | /* This is an internal VLink device on a PIC interrupt. The BIOS | 726 | /* This is an internal VLink device on a PIC interrupt. The BIOS |
@@ -1254,8 +1262,8 @@ static void quirk_jmicron_dualfn(struct pci_dev *pdev) | |||
1254 | pci_read_config_dword(pdev, 0x40, &conf); | 1262 | pci_read_config_dword(pdev, 0x40, &conf); |
1255 | /* Enable dual function mode, AHCI on fn 0, IDE fn1 */ | 1263 | /* Enable dual function mode, AHCI on fn 0, IDE fn1 */ |
1256 | /* Set the class codes correctly and then direct IDE 0 */ | 1264 | /* Set the class codes correctly and then direct IDE 0 */ |
1257 | conf &= ~0x000F0200; /* Clear bit 9 and 16-19 */ | 1265 | conf &= ~0x000FF200; /* Clear bit 9 and 12-19 */ |
1258 | conf |= 0x00C20002; /* Set bit 1, 17, 22, 23 */ | 1266 | conf |= 0x00C2A102; /* Set 1, 8, 13, 15, 17, 22, 23 */ |
1259 | pci_write_config_dword(pdev, 0x40, conf); | 1267 | pci_write_config_dword(pdev, 0x40, conf); |
1260 | 1268 | ||
1261 | /* Reconfigure so that the PCI scanner discovers the | 1269 | /* Reconfigure so that the PCI scanner discovers the |