|
Lines 654-672
Link Here
|
| 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 |
|
Lines 675-709
Link Here
|
| 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 */ |
|
Lines 711-718
Link Here
|
| 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 |