[PATCH] Fix VIA quirks

Fix VIA quirks that were recently broken by Alan Cox in the upstream
kernel (commit 1597cacbe39802d86656d1f2e6329895bd2ef531).

My understanding is that pci_find_present() doesn't work yet at the time
the quirks are run. So I used a two-step quirk as is done for some other
quirks already. First we detect the VIA south bridges and set the right
low and high device limits, then we are ready to actually run the quirks on
the affected devices.

Signed-off-by: Jean Delvare <jdelvare@suse.de>
Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
Acked-by: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Jean Delvare and committed by Linus Torvalds c06bb5d4 ab40c5c6

+42 -36
+42 -36
drivers/pci/quirks.c
··· 654 * VIA bridges which have VLink 655 */ 656 657 - static const struct pci_device_id via_vlink_fixup_tbl[] = { 658 - /* Internal devices need IRQ line routing, pre VLink */ 659 - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686), 0 }, 660 - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8231), 17 }, 661 - /* Devices with VLink */ 662 - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233_0), 17}, 663 - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233A), 17 }, 664 - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233C_0), 17 }, 665 - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8235), 16 }, 666 - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237), 15 }, 667 - { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237A), 15 }, 668 - { 0, }, 669 - }; 670 671 /** 672 * quirk_via_vlink - VIA VLink IRQ number update ··· 696 * If the device we are dealing with is on a PIC IRQ we need to 697 * ensure that the IRQ line register which usually is not relevant 698 * for PCI cards, is actually written so that interrupts get sent 699 - * to the right place 700 */ 701 702 static void quirk_via_vlink(struct pci_dev *dev) 703 { 704 - const struct pci_device_id *via_vlink_fixup; 705 - static int dev_lo = -1, dev_hi = 18; 706 u8 irq, new_irq; 707 708 - /* Check if we have VLink and cache the result */ 709 - 710 - /* Checked already - no */ 711 - if (dev_lo == -2) 712 return; 713 714 - /* Not checked - see what bridge we have and find the device 715 - ranges */ 716 - 717 - if (dev_lo == -1) { 718 - via_vlink_fixup = pci_find_present(via_vlink_fixup_tbl); 719 - if (via_vlink_fixup == NULL) { 720 - dev_lo = -2; 721 - return; 722 - } 723 - dev_lo = via_vlink_fixup->driver_data; 724 - /* 82C686 is special - 0/0 */ 725 - if (dev_lo == 0) 726 - dev_hi = 0; 727 - } 728 new_irq = dev->irq; 729 730 /* Don't quirk interrupts outside the legacy IRQ range */ ··· 717 return; 718 719 /* Internal device ? */ 720 - if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > dev_hi || 721 - PCI_SLOT(dev->devfn) < dev_lo) 722 return; 723 724 /* This is an internal VLink device on a PIC interrupt. The BIOS
··· 654 * VIA bridges which have VLink 655 */ 656 657 + static int via_vlink_dev_lo = -1, via_vlink_dev_hi = 18; 658 + 659 + static void quirk_via_bridge(struct pci_dev *dev) 660 + { 661 + /* See what bridge we have and find the device ranges */ 662 + switch (dev->device) { 663 + case PCI_DEVICE_ID_VIA_82C686: 664 + /* 82C686 is special */ 665 + via_vlink_dev_lo = 7; 666 + via_vlink_dev_hi = 7; 667 + break; 668 + case PCI_DEVICE_ID_VIA_8237: 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); 691 692 /** 693 * quirk_via_vlink - VIA VLink IRQ number update ··· 675 * 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 677 * for PCI cards, is actually written so that interrupts get sent 678 + * to the right place. 679 + * We only do this on systems where a VIA south bridge was detected, 680 + * and only for VIA devices on the motherboard (see quirk_via_bridge 681 + * above). 682 */ 683 684 static void quirk_via_vlink(struct pci_dev *dev) 685 { 686 u8 irq, new_irq; 687 688 + /* Check if we have VLink at all */ 689 + if (via_vlink_dev_lo == -1) 690 return; 691 692 new_irq = dev->irq; 693 694 /* Don't quirk interrupts outside the legacy IRQ range */ ··· 711 return; 712 713 /* Internal device ? */ 714 + if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > via_vlink_dev_hi || 715 + PCI_SLOT(dev->devfn) < via_vlink_dev_lo) 716 return; 717 718 /* This is an internal VLink device on a PIC interrupt. The BIOS