diff options
Diffstat (limited to 'arch/i386/kernel/mpparse.c')
-rw-r--r-- | arch/i386/kernel/mpparse.c | 41 |
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 */ |
69 | unsigned int boot_cpu_physical_apicid = -1U; | 69 | unsigned int boot_cpu_physical_apicid = -1U; |
70 | unsigned int boot_cpu_logical_apicid = -1U; | ||
71 | /* Internal processor count */ | 70 | /* Internal processor count */ |
72 | static unsigned int __initdata num_processors; | 71 | static 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 | |||
1058 | int mp_register_gsi (u32 gsi, int edge_level, int active_high_low) | 1061 | int 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); |