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.c78
1 files changed, 42 insertions, 36 deletions
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index ef882a8a094e..16945c2ba2ca 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -654,19 +654,40 @@ 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 /* 82C686 is special */
665 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8235), 16 }, 665 via_vlink_dev_lo = 7;
666 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237), 15 }, 666 via_vlink_dev_hi = 7;
667 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237A), 15 }, 667 break;
668 { 0, }, 668 case PCI_DEVICE_ID_VIA_8237:
669}; 669 case PCI_DEVICE_ID_VIA_8237A:
670 via_vlink_dev_lo = 15;
671 break;
672 case PCI_DEVICE_ID_VIA_8235:
673 via_vlink_dev_lo = 16;
674 break;
675 case PCI_DEVICE_ID_VIA_8231:
676 case PCI_DEVICE_ID_VIA_8233_0:
677 case PCI_DEVICE_ID_VIA_8233A:
678 case PCI_DEVICE_ID_VIA_8233C_0:
679 via_vlink_dev_lo = 17;
680 break;
681 }
682}
683DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_bridge);
684DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, quirk_via_bridge);
685DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_0, quirk_via_bridge);
686DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233A, quirk_via_bridge);
687DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233C_0, quirk_via_bridge);
688DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_via_bridge);
689DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_bridge);
690DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237A, quirk_via_bridge);
670 691
671/** 692/**
672 * quirk_via_vlink - VIA VLink IRQ number update 693 * quirk_via_vlink - VIA VLink IRQ number update
@@ -675,35 +696,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 696 * 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 697 * ensure that the IRQ line register which usually is not relevant
677 * for PCI cards, is actually written so that interrupts get sent 698 * for PCI cards, is actually written so that interrupts get sent
678 * to the right place 699 * to the right place.
700 * We only do this on systems where a VIA south bridge was detected,
701 * and only for VIA devices on the motherboard (see quirk_via_bridge
702 * above).
679 */ 703 */
680 704
681static void quirk_via_vlink(struct pci_dev *dev) 705static void quirk_via_vlink(struct pci_dev *dev)
682{ 706{
683 const struct pci_device_id *via_vlink_fixup;
684 static int dev_lo = -1, dev_hi = 18;
685 u8 irq, new_irq; 707 u8 irq, new_irq;
686 708
687 /* Check if we have VLink and cache the result */ 709 /* Check if we have VLink at all */
688 710 if (via_vlink_dev_lo == -1)
689 /* Checked already - no */
690 if (dev_lo == -2)
691 return; 711 return;
692 712
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; 713 new_irq = dev->irq;
708 714
709 /* Don't quirk interrupts outside the legacy IRQ range */ 715 /* Don't quirk interrupts outside the legacy IRQ range */
@@ -711,8 +717,8 @@ static void quirk_via_vlink(struct pci_dev *dev)
711 return; 717 return;
712 718
713 /* Internal device ? */ 719 /* Internal device ? */
714 if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > dev_hi || 720 if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > via_vlink_dev_hi ||
715 PCI_SLOT(dev->devfn) < dev_lo) 721 PCI_SLOT(dev->devfn) < via_vlink_dev_lo)
716 return; 722 return;
717 723
718 /* This is an internal VLink device on a PIC interrupt. The BIOS 724 /* This is an internal VLink device on a PIC interrupt. The BIOS