diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pci/quirks.c | 78 |
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 | ||
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 | /* 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 | } | ||
683 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_bridge); | ||
684 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, quirk_via_bridge); | ||
685 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_0, quirk_via_bridge); | ||
686 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233A, quirk_via_bridge); | ||
687 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233C_0, quirk_via_bridge); | ||
688 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_via_bridge); | ||
689 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_bridge); | ||
690 | DECLARE_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 | ||
681 | static void quirk_via_vlink(struct pci_dev *dev) | 705 | static 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 |