diff options
Diffstat (limited to 'drivers/pci/quirks.c')
| -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 |
