aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/io_apic.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2006-10-04 05:16:47 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-04 10:55:28 -0400
commitace80ab796ae30d2c9ee8a84ab6f608a61f8b87b (patch)
tree05eb2c68e534af4982ad82c459b1a65e3e712faf /arch/i386/kernel/io_apic.c
parent04b9267b15206fc902a18de1f78de6c82ca47716 (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.c181
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
91int 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
100union entry_union { 91union 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. */
1184u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; 1175u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
1185 1176
1186int assign_irq_vector(int irq) 1177static 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
1200next:
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
1204static 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
1224static struct irq_chip ioapic_chip; 1215static 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
1230static void ioapic_register_intr(int irq, int vector, unsigned long trigger) 1221static 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
1246static void __init setup_IO_APIC_irqs(void) 1233static 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
1954static void ack_ioapic_irq(unsigned int irq) 1936static 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
2000static unsigned int startup_ioapic_vector(unsigned int vector) 1982static int ioapic_retrigger_irq(unsigned int irq)
2001{
2002 int irq = vector_to_irq(vector);
2003
2004 return startup_ioapic_irq(irq);
2005}
2006
2007static 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
2015static 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
2023static 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
2030static 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)
2043static 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
2053static 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
2062static struct irq_chip ioapic_chip __read_mostly = { 1989static 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 */
2492int create_irq(void) 2414int 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)
2521void destroy_irq(unsigned int irq) 2441void 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;