aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/mpparse.c
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2005-06-25 09:27:27 -0400
committerAnton Altaparmakov <aia21@cantab.net>2005-06-25 09:27:27 -0400
commit38b22b6e9f46ab8f73ef5734f0e0a000766a9258 (patch)
tree2ccc41ef55918d3af43e444bde7648562a031559 /arch/i386/kernel/mpparse.c
parent3357d4c75f1fb67e7304998c4ad4e9a9fed66fa4 (diff)
parentb3e112bcc19abd8e9657dca34a87316786e096f3 (diff)
Automerge with /usr/src/ntfs-2.6.git.
Diffstat (limited to 'arch/i386/kernel/mpparse.c')
-rw-r--r--arch/i386/kernel/mpparse.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 1347ab4939e7..383a11600d2c 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -914,7 +914,10 @@ void __init mp_register_ioapic (
914 mp_ioapics[idx].mpc_apicaddr = address; 914 mp_ioapics[idx].mpc_apicaddr = address;
915 915
916 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); 916 set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
917 mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id); 917 if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15))
918 mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
919 else
920 mp_ioapics[idx].mpc_apicid = id;
918 mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); 921 mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
919 922
920 /* 923 /*
@@ -1055,11 +1058,20 @@ void __init mp_config_acpi_legacy_irqs (void)
1055 } 1058 }
1056} 1059}
1057 1060
1061#define MAX_GSI_NUM 4096
1062
1058int mp_register_gsi (u32 gsi, int edge_level, int active_high_low) 1063int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
1059{ 1064{
1060 int ioapic = -1; 1065 int ioapic = -1;
1061 int ioapic_pin = 0; 1066 int ioapic_pin = 0;
1062 int idx, bit = 0; 1067 int idx, bit = 0;
1068 static int pci_irq = 16;
1069 /*
1070 * Mapping between Global System Interrups, which
1071 * represent all possible interrupts, and IRQs
1072 * assigned to actual devices.
1073 */
1074 static int gsi_to_irq[MAX_GSI_NUM];
1063 1075
1064#ifdef CONFIG_ACPI_BUS 1076#ifdef CONFIG_ACPI_BUS
1065 /* Don't set up the ACPI SCI because it's already set up */ 1077 /* Don't set up the ACPI SCI because it's already set up */
@@ -1094,11 +1106,26 @@ int mp_register_gsi (u32 gsi, int edge_level, int active_high_low)
1094 if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) { 1106 if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
1095 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n", 1107 Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
1096 mp_ioapic_routing[ioapic].apic_id, ioapic_pin); 1108 mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
1097 return gsi; 1109 return gsi_to_irq[gsi];
1098 } 1110 }
1099 1111
1100 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit); 1112 mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
1101 1113
1114 if (edge_level) {
1115 /*
1116 * For PCI devices assign IRQs in order, avoiding gaps
1117 * due to unused I/O APIC pins.
1118 */
1119 int irq = gsi;
1120 if (gsi < MAX_GSI_NUM) {
1121 gsi = pci_irq++;
1122 gsi_to_irq[irq] = gsi;
1123 } else {
1124 printk(KERN_ERR "GSI %u is too high\n", gsi);
1125 return gsi;
1126 }
1127 }
1128
1102 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi, 1129 io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
1103 edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1, 1130 edge_level == ACPI_EDGE_SENSITIVE ? 0 : 1,
1104 active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1); 1131 active_high_low == ACPI_ACTIVE_HIGH ? 0 : 1);