aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/quirks.c
diff options
context:
space:
mode:
authorJean Delvare <jdelvare@suse.de>2007-01-30 17:36:09 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-01-30 19:01:35 -0500
commitc06bb5d49d8b240876c7c5019197e6a7bd33bcf7 (patch)
tree278f7a6bc61d0ec20c1e8eeb2e2a7d1597b29f8a /drivers/pci/quirks.c
parentab40c5c6b6861ee71fd97f2611027b01e9ec4da0 (diff)
[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>
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