aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/mpparse.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/mpparse.c')
-rw-r--r--arch/i386/kernel/mpparse.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 1347ab4939e7..ce838abb27d8 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -67,7 +67,6 @@ unsigned long mp_lapic_addr;
67 67
68/* Processor that is doing the boot up */ 68/* Processor that is doing the boot up */
69unsigned int boot_cpu_physical_apicid = -1U; 69unsigned int boot_cpu_physical_apicid = -1U;
70unsigned int boot_cpu_logical_apicid = -1U;
71/* Internal processor count */ 70/* Internal processor count */
72static unsigned int __initdata num_processors; 71static unsigned int __initdata num_processors;
73 72
@@ -180,7 +179,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
180 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { 179 if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
181 Dprintk(" Bootup CPU\n"); 180 Dprintk(" Bootup CPU\n");
182 boot_cpu_physical_apicid = m->mpc_apicid; 181 boot_cpu_physical_apicid = m->mpc_apicid;
183 boot_cpu_logical_apicid = apicid;
184 } 182 }
185 183
186 if (num_processors >= NR_CPUS) { 184 if (num_processors >= NR_CPUS) {
@@ -914,7 +912,10 @@ void __init mp_register_ioapic (
914 mp_ioapics[idx].mpc_apicaddr = address; 912 mp_ioapics[idx].mpc_apicaddr = address;
915 913
916 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); 914 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
917 mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id); 915 if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15))
916 mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
917 else
918 mp_ioapics[idx].mpc_apicid = id;
918 mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); 919 mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
919 920
920 /* 921 /*
@@ -1055,11 +1056,20 @@ void __init mp_config_acpi_legacy_irqs (void)
1055 } 1056 }
1056} 1057}
1057 1058
1059#define MAX_GSI_NUM 4096
1060
1058int mp_register_gsi (u32 gsi, int edge_level, int active_high_low) 1061int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
1059{ 1062{
1060 int ioapic = -1; 1063 int ioapic = -1;
1061 int ioapic_pin = 0; 1064 int ioapic_pin = 0;
1062 int idx, bit = 0; 1065 int idx, bit = 0;
1066 static int pci_irq = 16;
1067 /*
1068 * Mapping between Global System Interrups, which
1069 * represent all possible interrupts, and IRQs
1070 * assigned to actual devices.
1071 */
1072 static int gsi_to_irq[MAX_GSI_NUM];
1063 1073
1064#ifdef CONFIG_ACPI_BUS 1074#ifdef CONFIG_ACPI_BUS
1065 /* Don't set up the ACPI SCI because it's already set up */ 1075 /* Don't set up the ACPI SCI because it's already set up */
@@ -1094,11 +1104,34 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
1094 if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { 1104 if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
1095 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", 1105 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
1096 mp_ioapic_routing[ioapic].apic_id, ioapic_pin); 1106 mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
1097 return gsi; 1107 return gsi_to_irq[gsi];
1098 } 1108 }
1099 1109
1100 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); 1110 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
1101 1111
1112 if (edge_level) {
1113 /*
1114 * For PCI devices assign IRQs in order, avoiding gaps
1115 * due to unused I/O APIC pins.
1116 */
1117 int irq = gsi;
1118 if (gsi < MAX_GSI_NUM) {
1119 if (gsi > 15)
1120 gsi = pci_irq++;
1121#ifdef CONFIG_ACPI_BUS
1122 /*
1123 * Don't assign IRQ used by ACPI SCI
1124 */
1125 if (gsi == acpi_fadt.sci_int)
1126 gsi = pci_irq++;
1127#endif
1128 gsi_to_irq[irq] = gsi;
1129 } else {
1130 printk(KERN_ERR "GSI %u is too high\n", gsi);
1131 return gsi;
1132 }
1133 }
1134
1102 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, 1135 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
1103 edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1, 1136 edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
1104 active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1); 1137 active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);