aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/quirks.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/quirks.c')
-rw-r--r--drivers/pci/quirks.c84
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
657static const struct pci_device_id via_vlink_fixup_tbl[] = { 657static 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 }, 659static 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}
685DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_bridge);
686DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, quirk_via_bridge);
687DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_0, quirk_via_bridge);
688DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233A, quirk_via_bridge);
689DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233C_0, quirk_via_bridge);
690DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_via_bridge);
691DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_bridge);
692DECLARE_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
681static void quirk_via_vlink(struct pci_dev *dev) 707static 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