diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2006-10-04 05:16:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 10:55:28 -0400 |
commit | ace80ab796ae30d2c9ee8a84ab6f608a61f8b87b (patch) | |
tree | 05eb2c68e534af4982ad82c459b1a65e3e712faf /arch/i386/kernel/io_apic.c | |
parent | 04b9267b15206fc902a18de1f78de6c82ca47716 (diff) |
[PATCH] genirq: i386 irq: Remove the msi assumption that irq == vector
This patch removes the change in behavior of the irq allocation code when
CONFIG_PCI_MSI is defined. Removing all instances of the assumption that irq
== vector.
create_irq is rewritten to first allocate a free irq and then to assign that
irq a vector.
assign_irq_vector is made static and the AUTO_ASSIGN case which allocates an
vector not bound to an irq is removed.
The ioapic vector methods are removed, and everything now works with irqs.
The definition of NR_IRQS no longer depends on CONFIG_PCI_MSI
[akpm@osdl.org: cleanup]
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rajesh Shah <rajesh.shah@intel.com>
Cc: Andi Kleen <ak@muc.de>
Cc: "Protasevich, Natalie" <Natalie.Protasevich@UNISYS.com>
Cc: "Luck, Tony" <tony.luck@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/io_apic.c')
-rw-r--r-- | arch/i386/kernel/io_apic.c | 181 |
1 files changed, 49 insertions, 132 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 85e7d5d465a2..03e7606be6e6 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -88,15 +88,6 @@ static struct irq_pin_list { | |||
88 | int apic, pin, next; | 88 | int apic, pin, next; |
89 | } irq_2_pin[PIN_MAP_SIZE]; | 89 | } irq_2_pin[PIN_MAP_SIZE]; |
90 | 90 | ||
91 | int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1}; | ||
92 | #ifdef CONFIG_PCI_MSI | ||
93 | #define vector_to_irq(vector) \ | ||
94 | (platform_legacy_irq(vector) ? vector : vector_irq[vector]) | ||
95 | #else | ||
96 | #define vector_to_irq(vector) (vector) | ||
97 | #endif | ||
98 | |||
99 | |||
100 | union entry_union { | 91 | union entry_union { |
101 | struct { u32 w1, w2; }; | 92 | struct { u32 w1, w2; }; |
102 | struct IO_APIC_route_entry entry; | 93 | struct IO_APIC_route_entry entry; |
@@ -282,7 +273,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) | |||
282 | break; | 273 | break; |
283 | entry = irq_2_pin + entry->next; | 274 | entry = irq_2_pin + entry->next; |
284 | } | 275 | } |
285 | set_irq_info(irq, cpumask); | 276 | set_native_irq_info(irq, cpumask); |
286 | spin_unlock_irqrestore(&ioapic_lock, flags); | 277 | spin_unlock_irqrestore(&ioapic_lock, flags); |
287 | } | 278 | } |
288 | 279 | ||
@@ -1183,44 +1174,44 @@ static inline int IO_APIC_irq_trigger(int irq) | |||
1183 | /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ | 1174 | /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ |
1184 | u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; | 1175 | u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; |
1185 | 1176 | ||
1186 | int assign_irq_vector(int irq) | 1177 | static int __assign_irq_vector(int irq) |
1187 | { | 1178 | { |
1188 | static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; | 1179 | static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; |
1189 | unsigned long flags; | ||
1190 | int vector; | 1180 | int vector; |
1191 | 1181 | ||
1192 | BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS); | 1182 | BUG_ON((unsigned)irq >= NR_IRQ_VECTORS); |
1193 | |||
1194 | spin_lock_irqsave(&vector_lock, flags); | ||
1195 | 1183 | ||
1196 | if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) { | 1184 | if (IO_APIC_VECTOR(irq) > 0) |
1197 | spin_unlock_irqrestore(&vector_lock, flags); | ||
1198 | return IO_APIC_VECTOR(irq); | 1185 | return IO_APIC_VECTOR(irq); |
1199 | } | 1186 | |
1200 | next: | ||
1201 | current_vector += 8; | 1187 | current_vector += 8; |
1202 | if (current_vector == SYSCALL_VECTOR) | 1188 | if (current_vector == SYSCALL_VECTOR) |
1203 | goto next; | 1189 | current_vector += 8; |
1204 | 1190 | ||
1205 | if (current_vector >= FIRST_SYSTEM_VECTOR) { | 1191 | if (current_vector >= FIRST_SYSTEM_VECTOR) { |
1206 | offset++; | 1192 | offset++; |
1207 | if (!(offset%8)) { | 1193 | if (!(offset % 8)) |
1208 | spin_unlock_irqrestore(&vector_lock, flags); | ||
1209 | return -ENOSPC; | 1194 | return -ENOSPC; |
1210 | } | ||
1211 | current_vector = FIRST_DEVICE_VECTOR + offset; | 1195 | current_vector = FIRST_DEVICE_VECTOR + offset; |
1212 | } | 1196 | } |
1213 | 1197 | ||
1214 | vector = current_vector; | 1198 | vector = current_vector; |
1215 | vector_irq[vector] = irq; | 1199 | IO_APIC_VECTOR(irq) = vector; |
1216 | if (irq != AUTO_ASSIGN) | 1200 | |
1217 | IO_APIC_VECTOR(irq) = vector; | 1201 | return vector; |
1202 | } | ||
1218 | 1203 | ||
1204 | static int assign_irq_vector(int irq) | ||
1205 | { | ||
1206 | unsigned long flags; | ||
1207 | int vector; | ||
1208 | |||
1209 | spin_lock_irqsave(&vector_lock, flags); | ||
1210 | vector = __assign_irq_vector(irq); | ||
1219 | spin_unlock_irqrestore(&vector_lock, flags); | 1211 | spin_unlock_irqrestore(&vector_lock, flags); |
1220 | 1212 | ||
1221 | return vector; | 1213 | return vector; |
1222 | } | 1214 | } |
1223 | |||
1224 | static struct irq_chip ioapic_chip; | 1215 | static struct irq_chip ioapic_chip; |
1225 | 1216 | ||
1226 | #define IOAPIC_AUTO -1 | 1217 | #define IOAPIC_AUTO -1 |
@@ -1229,18 +1220,14 @@ static struct irq_chip ioapic_chip; | |||
1229 | 1220 | ||
1230 | static void ioapic_register_intr(int irq, int vector, unsigned long trigger) | 1221 | static void ioapic_register_intr(int irq, int vector, unsigned long trigger) |
1231 | { | 1222 | { |
1232 | unsigned idx; | ||
1233 | |||
1234 | idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq; | ||
1235 | |||
1236 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || | 1223 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || |
1237 | trigger == IOAPIC_LEVEL) | 1224 | trigger == IOAPIC_LEVEL) |
1238 | set_irq_chip_and_handler(idx, &ioapic_chip, | 1225 | set_irq_chip_and_handler(irq, &ioapic_chip, |
1239 | handle_fasteoi_irq); | 1226 | handle_fasteoi_irq); |
1240 | else | 1227 | else |
1241 | set_irq_chip_and_handler(idx, &ioapic_chip, | 1228 | set_irq_chip_and_handler(irq, &ioapic_chip, |
1242 | handle_edge_irq); | 1229 | handle_edge_irq); |
1243 | set_intr_gate(vector, interrupt[idx]); | 1230 | set_intr_gate(vector, interrupt[irq]); |
1244 | } | 1231 | } |
1245 | 1232 | ||
1246 | static void __init setup_IO_APIC_irqs(void) | 1233 | static void __init setup_IO_APIC_irqs(void) |
@@ -1485,17 +1472,12 @@ void __init print_IO_APIC(void) | |||
1485 | ); | 1472 | ); |
1486 | } | 1473 | } |
1487 | } | 1474 | } |
1488 | if (use_pci_vector()) | ||
1489 | printk(KERN_INFO "Using vector-based indexing\n"); | ||
1490 | printk(KERN_DEBUG "IRQ to pin mappings:\n"); | 1475 | printk(KERN_DEBUG "IRQ to pin mappings:\n"); |
1491 | for (i = 0; i < NR_IRQS; i++) { | 1476 | for (i = 0; i < NR_IRQS; i++) { |
1492 | struct irq_pin_list *entry = irq_2_pin + i; | 1477 | struct irq_pin_list *entry = irq_2_pin + i; |
1493 | if (entry->pin < 0) | 1478 | if (entry->pin < 0) |
1494 | continue; | 1479 | continue; |
1495 | if (use_pci_vector() && !platform_legacy_irq(i)) | 1480 | printk(KERN_DEBUG "IRQ%d ", i); |
1496 | printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i)); | ||
1497 | else | ||
1498 | printk(KERN_DEBUG "IRQ%d ", i); | ||
1499 | for (;;) { | 1481 | for (;;) { |
1500 | printk("-> %d:%d", entry->apic, entry->pin); | 1482 | printk("-> %d:%d", entry->apic, entry->pin); |
1501 | if (!entry->next) | 1483 | if (!entry->next) |
@@ -1953,7 +1935,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq) | |||
1953 | 1935 | ||
1954 | static void ack_ioapic_irq(unsigned int irq) | 1936 | static void ack_ioapic_irq(unsigned int irq) |
1955 | { | 1937 | { |
1956 | move_irq(irq); | 1938 | move_native_irq(irq); |
1957 | ack_APIC_irq(); | 1939 | ack_APIC_irq(); |
1958 | } | 1940 | } |
1959 | 1941 | ||
@@ -1962,7 +1944,7 @@ static void ack_ioapic_quirk_irq(unsigned int irq) | |||
1962 | unsigned long v; | 1944 | unsigned long v; |
1963 | int i; | 1945 | int i; |
1964 | 1946 | ||
1965 | move_irq(irq); | 1947 | move_native_irq(irq); |
1966 | /* | 1948 | /* |
1967 | * It appears there is an erratum which affects at least version 0x11 | 1949 | * It appears there is an erratum which affects at least version 0x11 |
1968 | * of I/O APIC (that's the 82093AA and cores integrated into various | 1950 | * of I/O APIC (that's the 82093AA and cores integrated into various |
@@ -1997,63 +1979,8 @@ static void ack_ioapic_quirk_irq(unsigned int irq) | |||
1997 | } | 1979 | } |
1998 | } | 1980 | } |
1999 | 1981 | ||
2000 | static unsigned int startup_ioapic_vector(unsigned int vector) | 1982 | static int ioapic_retrigger_irq(unsigned int irq) |
2001 | { | ||
2002 | int irq = vector_to_irq(vector); | ||
2003 | |||
2004 | return startup_ioapic_irq(irq); | ||
2005 | } | ||
2006 | |||
2007 | static void ack_ioapic_vector(unsigned int vector) | ||
2008 | { | ||
2009 | int irq = vector_to_irq(vector); | ||
2010 | |||
2011 | move_native_irq(vector); | ||
2012 | ack_ioapic_irq(irq); | ||
2013 | } | ||
2014 | |||
2015 | static void ack_ioapic_quirk_vector(unsigned int vector) | ||
2016 | { | 1983 | { |
2017 | int irq = vector_to_irq(vector); | ||
2018 | |||
2019 | move_native_irq(vector); | ||
2020 | ack_ioapic_quirk_irq(irq); | ||
2021 | } | ||
2022 | |||
2023 | static void mask_IO_APIC_vector (unsigned int vector) | ||
2024 | { | ||
2025 | int irq = vector_to_irq(vector); | ||
2026 | |||
2027 | mask_IO_APIC_irq(irq); | ||
2028 | } | ||
2029 | |||
2030 | static void unmask_IO_APIC_vector (unsigned int vector) | ||
2031 | { | ||
2032 | int irq = vector_to_irq(vector); | ||
2033 | |||
2034 | unmask_IO_APIC_irq(irq); | ||
2035 | } | ||
2036 | |||
2037 | /* | ||
2038 | * Oh just glorious. If CONFIG_PCI_MSI we've done | ||
2039 | * #define set_ioapic_affinity set_ioapic_affinity_vector | ||
2040 | */ | ||
2041 | #if defined (CONFIG_SMP) && defined(CONFIG_X86_IO_APIC) && \ | ||
2042 | defined(CONFIG_PCI_MSI) | ||
2043 | static void set_ioapic_affinity_vector (unsigned int vector, | ||
2044 | cpumask_t cpu_mask) | ||
2045 | { | ||
2046 | int irq = vector_to_irq(vector); | ||
2047 | |||
2048 | set_native_irq_info(vector, cpu_mask); | ||
2049 | set_ioapic_affinity_irq(irq, cpu_mask); | ||
2050 | } | ||
2051 | #endif | ||
2052 | |||
2053 | static int ioapic_retrigger_vector(unsigned int vector) | ||
2054 | { | ||
2055 | int irq = vector_to_irq(vector); | ||
2056 | |||
2057 | send_IPI_self(IO_APIC_VECTOR(irq)); | 1984 | send_IPI_self(IO_APIC_VECTOR(irq)); |
2058 | 1985 | ||
2059 | return 1; | 1986 | return 1; |
@@ -2061,15 +1988,15 @@ static int ioapic_retrigger_vector(unsigned int vector) | |||
2061 | 1988 | ||
2062 | static struct irq_chip ioapic_chip __read_mostly = { | 1989 | static struct irq_chip ioapic_chip __read_mostly = { |
2063 | .name = "IO-APIC", | 1990 | .name = "IO-APIC", |
2064 | .startup = startup_ioapic_vector, | 1991 | .startup = startup_ioapic_irq, |
2065 | .mask = mask_IO_APIC_vector, | 1992 | .mask = mask_IO_APIC_irq, |
2066 | .unmask = unmask_IO_APIC_vector, | 1993 | .unmask = unmask_IO_APIC_irq, |
2067 | .ack = ack_ioapic_vector, | 1994 | .ack = ack_ioapic_irq, |
2068 | .eoi = ack_ioapic_quirk_vector, | 1995 | .eoi = ack_ioapic_quirk_irq, |
2069 | #ifdef CONFIG_SMP | 1996 | #ifdef CONFIG_SMP |
2070 | .set_affinity = set_ioapic_affinity, | 1997 | .set_affinity = set_ioapic_affinity_irq, |
2071 | #endif | 1998 | #endif |
2072 | .retrigger = ioapic_retrigger_vector, | 1999 | .retrigger = ioapic_retrigger_irq, |
2073 | }; | 2000 | }; |
2074 | 2001 | ||
2075 | 2002 | ||
@@ -2090,11 +2017,6 @@ static inline void init_IO_APIC_traps(void) | |||
2090 | */ | 2017 | */ |
2091 | for (irq = 0; irq < NR_IRQS ; irq++) { | 2018 | for (irq = 0; irq < NR_IRQS ; irq++) { |
2092 | int tmp = irq; | 2019 | int tmp = irq; |
2093 | if (use_pci_vector()) { | ||
2094 | if (!platform_legacy_irq(tmp)) | ||
2095 | if ((tmp = vector_to_irq(tmp)) == -1) | ||
2096 | continue; | ||
2097 | } | ||
2098 | if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { | 2020 | if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { |
2099 | /* | 2021 | /* |
2100 | * Hmm.. We don't have an entry for this, | 2022 | * Hmm.. We don't have an entry for this, |
@@ -2491,28 +2413,26 @@ device_initcall(ioapic_init_sysfs); | |||
2491 | */ | 2413 | */ |
2492 | int create_irq(void) | 2414 | int create_irq(void) |
2493 | { | 2415 | { |
2494 | /* Hack of the day: irq == vector. | 2416 | /* Allocate an unused irq */ |
2495 | * | 2417 | int irq, new, vector; |
2496 | * Ultimately this will be be more general, | ||
2497 | * and not depend on the irq to vector identity mapping. | ||
2498 | * But this version is needed until msi.c can cope with | ||
2499 | * the more general form. | ||
2500 | */ | ||
2501 | int irq, vector; | ||
2502 | unsigned long flags; | 2418 | unsigned long flags; |
2503 | vector = assign_irq_vector(AUTO_ASSIGN); | ||
2504 | irq = vector; | ||
2505 | 2419 | ||
2506 | if (vector >= 0) { | 2420 | irq = -ENOSPC; |
2507 | struct irq_desc *desc; | 2421 | spin_lock_irqsave(&vector_lock, flags); |
2508 | 2422 | for (new = (NR_IRQS - 1); new >= 0; new--) { | |
2509 | spin_lock_irqsave(&vector_lock, flags); | 2423 | if (platform_legacy_irq(new)) |
2510 | vector_irq[vector] = irq; | 2424 | continue; |
2511 | irq_vector[irq] = vector; | 2425 | if (irq_vector[new] != 0) |
2512 | spin_unlock_irqrestore(&vector_lock, flags); | 2426 | continue; |
2427 | vector = __assign_irq_vector(new); | ||
2428 | if (likely(vector > 0)) | ||
2429 | irq = new; | ||
2430 | break; | ||
2431 | } | ||
2432 | spin_unlock_irqrestore(&vector_lock, flags); | ||
2513 | 2433 | ||
2434 | if (irq >= 0) { | ||
2514 | set_intr_gate(vector, interrupt[irq]); | 2435 | set_intr_gate(vector, interrupt[irq]); |
2515 | |||
2516 | dynamic_irq_init(irq); | 2436 | dynamic_irq_init(irq); |
2517 | } | 2437 | } |
2518 | return irq; | 2438 | return irq; |
@@ -2521,13 +2441,10 @@ int create_irq(void) | |||
2521 | void destroy_irq(unsigned int irq) | 2441 | void destroy_irq(unsigned int irq) |
2522 | { | 2442 | { |
2523 | unsigned long flags; | 2443 | unsigned long flags; |
2524 | unsigned int vector; | ||
2525 | 2444 | ||
2526 | dynamic_irq_cleanup(irq); | 2445 | dynamic_irq_cleanup(irq); |
2527 | 2446 | ||
2528 | spin_lock_irqsave(&vector_lock, flags); | 2447 | spin_lock_irqsave(&vector_lock, flags); |
2529 | vector = irq_vector[irq]; | ||
2530 | vector_irq[vector] = -1; | ||
2531 | irq_vector[irq] = 0; | 2448 | irq_vector[irq] = 0; |
2532 | spin_unlock_irqrestore(&vector_lock, flags); | 2449 | spin_unlock_irqrestore(&vector_lock, flags); |
2533 | } | 2450 | } |
@@ -2754,7 +2671,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a | |||
2754 | 2671 | ||
2755 | ioapic_write_entry(ioapic, pin, entry); | 2672 | ioapic_write_entry(ioapic, pin, entry); |
2756 | spin_lock_irqsave(&ioapic_lock, flags); | 2673 | spin_lock_irqsave(&ioapic_lock, flags); |
2757 | set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); | 2674 | set_native_irq_info(irq, TARGET_CPUS); |
2758 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2675 | spin_unlock_irqrestore(&ioapic_lock, flags); |
2759 | 2676 | ||
2760 | return 0; | 2677 | return 0; |