aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/kernel/mpparse.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index ed6a5588146d..9c5aa2a790c7 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -906,11 +906,20 @@ void __init mp_config_acpi_legacy_irqs (void)
906 return; 906 return;
907} 907}
908 908
909#define MAX_GSI_NUM 4096
910
909int mp_register_gsi(u32 gsi, int edge_level, int active_high_low) 911int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
910{ 912{
911 int ioapic = -1; 913 int ioapic = -1;
912 int ioapic_pin = 0; 914 int ioapic_pin = 0;
913 int idx, bit = 0; 915 int idx, bit = 0;
916 static int pci_irq = 16;
917 /*
918 * Mapping between Global System Interrupts, which
919 * represent all possible interrupts, to the IRQs
920 * assigned to actual devices.
921 */
922 static int gsi_to_irq[MAX_GSI_NUM];
914 923
915 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) 924 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
916 return gsi; 925 return gsi;
@@ -945,11 +954,21 @@ int mp_register_gsi(u32 gsi, int edge_level, int active_high_low)
945 if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { 954 if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
946 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", 955 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
947 mp_ioapic_routing[ioapic].apic_id, ioapic_pin); 956 mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
948 return gsi; 957 return gsi_to_irq[gsi];
949 } 958 }
950 959
951 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); 960 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
952 961
962 if (edge_level) {
963 /*
964 * For PCI devices assign IRQs in order, avoiding gaps
965 * due to unused I/O APIC pins.
966 */
967 int irq = gsi;
968 gsi = pci_irq++;
969 gsi_to_irq[irq] = gsi;
970 }
971
953 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, 972 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
954 edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1, 973 edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
955 active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1); 974 active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);