aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/kernel/io_apic.c147
-rw-r--r--include/asm-x86_64/hw_irq.h1
-rw-r--r--include/asm-x86_64/io_apic.h40
-rw-r--r--include/asm-x86_64/irq.h5
4 files changed, 47 insertions, 146 deletions
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 437b6f96cc80..bb16f3790f09 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -44,6 +44,8 @@
44#include <asm/nmi.h> 44#include <asm/nmi.h>
45#include <asm/msidef.h> 45#include <asm/msidef.h>
46 46
47static int assign_irq_vector(int irq);
48
47#define __apicdebuginit __init 49#define __apicdebuginit __init
48 50
49int sis_apic_bug; /* not actually supported, dummy for compile */ 51int sis_apic_bug; /* not actually supported, dummy for compile */
@@ -83,14 +85,6 @@ static struct irq_pin_list {
83 short apic, pin, next; 85 short apic, pin, next;
84} irq_2_pin[PIN_MAP_SIZE]; 86} irq_2_pin[PIN_MAP_SIZE];
85 87
86int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1};
87#ifdef CONFIG_PCI_MSI
88#define vector_to_irq(vector) \
89 (platform_legacy_irq(vector) ? vector : vector_irq[vector])
90#else
91#define vector_to_irq(vector) (vector)
92#endif
93
94#define __DO_ACTION(R, ACTION, FINAL) \ 88#define __DO_ACTION(R, ACTION, FINAL) \
95 \ 89 \
96{ \ 90{ \
@@ -162,7 +156,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t mask)
162 156
163 spin_lock_irqsave(&ioapic_lock, flags); 157 spin_lock_irqsave(&ioapic_lock, flags);
164 __DO_ACTION(1, = dest, ) 158 __DO_ACTION(1, = dest, )
165 set_irq_info(irq, mask); 159 set_native_irq_info(irq, mask);
166 spin_unlock_irqrestore(&ioapic_lock, flags); 160 spin_unlock_irqrestore(&ioapic_lock, flags);
167} 161}
168#endif 162#endif
@@ -599,18 +593,14 @@ static inline int IO_APIC_irq_trigger(int irq)
599/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ 593/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
600u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; 594u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
601 595
602int assign_irq_vector(int irq) 596static int __assign_irq_vector(int irq)
603{ 597{
604 static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; 598 static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
605 unsigned long flags;
606 int vector; 599 int vector;
607 600
608 BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS); 601 BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
609
610 spin_lock_irqsave(&vector_lock, flags);
611 602
612 if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) { 603 if (IO_APIC_VECTOR(irq) > 0) {
613 spin_unlock_irqrestore(&vector_lock, flags);
614 return IO_APIC_VECTOR(irq); 604 return IO_APIC_VECTOR(irq);
615 } 605 }
616next: 606next:
@@ -625,10 +615,18 @@ next:
625 } 615 }
626 616
627 vector = current_vector; 617 vector = current_vector;
628 vector_irq[vector] = irq; 618 IO_APIC_VECTOR(irq) = vector;
629 if (irq != AUTO_ASSIGN) 619
630 IO_APIC_VECTOR(irq) = vector; 620 return vector;
621}
622
623static int assign_irq_vector(int irq)
624{
625 int vector;
626 unsigned long flags;
631 627
628 spin_lock_irqsave(&vector_lock, flags);
629 vector = __assign_irq_vector(irq);
632 spin_unlock_irqrestore(&vector_lock, flags); 630 spin_unlock_irqrestore(&vector_lock, flags);
633 631
634 return vector; 632 return vector;
@@ -644,18 +642,14 @@ static struct irq_chip ioapic_chip;
644 642
645static void ioapic_register_intr(int irq, int vector, unsigned long trigger) 643static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
646{ 644{
647 unsigned idx;
648
649 idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq;
650
651 if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || 645 if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
652 trigger == IOAPIC_LEVEL) 646 trigger == IOAPIC_LEVEL)
653 set_irq_chip_and_handler(idx, &ioapic_chip, 647 set_irq_chip_and_handler(irq, &ioapic_chip,
654 handle_fasteoi_irq); 648 handle_fasteoi_irq);
655 else 649 else
656 set_irq_chip_and_handler(idx, &ioapic_chip, 650 set_irq_chip_and_handler(irq, &ioapic_chip,
657 handle_edge_irq); 651 handle_edge_irq);
658 set_intr_gate(vector, interrupt[idx]); 652 set_intr_gate(vector, interrupt[irq]);
659} 653}
660 654
661static void __init setup_IO_APIC_irqs(void) 655static void __init setup_IO_APIC_irqs(void)
@@ -872,17 +866,12 @@ void __apicdebuginit print_IO_APIC(void)
872 ); 866 );
873 } 867 }
874 } 868 }
875 if (use_pci_vector())
876 printk(KERN_INFO "Using vector-based indexing\n");
877 printk(KERN_DEBUG "IRQ to pin mappings:\n"); 869 printk(KERN_DEBUG "IRQ to pin mappings:\n");
878 for (i = 0; i < NR_IRQS; i++) { 870 for (i = 0; i < NR_IRQS; i++) {
879 struct irq_pin_list *entry = irq_2_pin + i; 871 struct irq_pin_list *entry = irq_2_pin + i;
880 if (entry->pin < 0) 872 if (entry->pin < 0)
881 continue; 873 continue;
882 if (use_pci_vector() && !platform_legacy_irq(i)) 874 printk(KERN_DEBUG "IRQ%d ", i);
883 printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i));
884 else
885 printk(KERN_DEBUG "IRQ%d ", i);
886 for (;;) { 875 for (;;) {
887 printk("-> %d:%d", entry->apic, entry->pin); 876 printk("-> %d:%d", entry->apic, entry->pin);
888 if (!entry->next) 877 if (!entry->next)
@@ -1206,42 +1195,8 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
1206 return was_pending; 1195 return was_pending;
1207} 1196}
1208 1197
1209static unsigned int startup_ioapic_vector(unsigned int vector) 1198static int ioapic_retrigger_irq(unsigned int irq)
1210{
1211 int irq = vector_to_irq(vector);
1212
1213 return startup_ioapic_irq(irq);
1214}
1215
1216static void mask_ioapic_vector (unsigned int vector)
1217{
1218 int irq = vector_to_irq(vector);
1219
1220 mask_IO_APIC_irq(irq);
1221}
1222
1223static void unmask_ioapic_vector (unsigned int vector)
1224{
1225 int irq = vector_to_irq(vector);
1226
1227 unmask_IO_APIC_irq(irq);
1228}
1229
1230#ifdef CONFIG_SMP
1231static void set_ioapic_affinity_vector (unsigned int vector,
1232 cpumask_t cpu_mask)
1233{
1234 int irq = vector_to_irq(vector);
1235
1236 set_native_irq_info(vector, cpu_mask);
1237 set_ioapic_affinity_irq(irq, cpu_mask);
1238}
1239#endif // CONFIG_SMP
1240
1241static int ioapic_retrigger_vector(unsigned int vector)
1242{ 1199{
1243 int irq = vector_to_irq(vector);
1244
1245 send_IPI_self(IO_APIC_VECTOR(irq)); 1200 send_IPI_self(IO_APIC_VECTOR(irq));
1246 1201
1247 return 1; 1202 return 1;
@@ -1288,15 +1243,15 @@ static void ack_apic_level(unsigned int irq)
1288 1243
1289static struct irq_chip ioapic_chip __read_mostly = { 1244static struct irq_chip ioapic_chip __read_mostly = {
1290 .name = "IO-APIC", 1245 .name = "IO-APIC",
1291 .startup = startup_ioapic_vector, 1246 .startup = startup_ioapic_irq,
1292 .mask = mask_ioapic_vector, 1247 .mask = mask_IO_APIC_irq,
1293 .unmask = unmask_ioapic_vector, 1248 .unmask = unmask_IO_APIC_irq,
1294 .ack = ack_apic_edge, 1249 .ack = ack_apic_edge,
1295 .eoi = ack_apic_level, 1250 .eoi = ack_apic_level,
1296#ifdef CONFIG_SMP 1251#ifdef CONFIG_SMP
1297 .set_affinity = set_ioapic_affinity_vector, 1252 .set_affinity = set_ioapic_affinity_irq,
1298#endif 1253#endif
1299 .retrigger = ioapic_retrigger_vector, 1254 .retrigger = ioapic_retrigger_irq,
1300}; 1255};
1301 1256
1302static inline void init_IO_APIC_traps(void) 1257static inline void init_IO_APIC_traps(void)
@@ -1316,11 +1271,6 @@ static inline void init_IO_APIC_traps(void)
1316 */ 1271 */
1317 for (irq = 0; irq < NR_IRQS ; irq++) { 1272 for (irq = 0; irq < NR_IRQS ; irq++) {
1318 int tmp = irq; 1273 int tmp = irq;
1319 if (use_pci_vector()) {
1320 if (!platform_legacy_irq(tmp))
1321 if ((tmp = vector_to_irq(tmp)) == -1)
1322 continue;
1323 }
1324 if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { 1274 if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) {
1325 /* 1275 /*
1326 * Hmm.. We don't have an entry for this, 1276 * Hmm.. We don't have an entry for this,
@@ -1695,32 +1645,33 @@ static int __init ioapic_init_sysfs(void)
1695 1645
1696device_initcall(ioapic_init_sysfs); 1646device_initcall(ioapic_init_sysfs);
1697 1647
1698#ifdef CONFIG_PCI_MSI
1699/* 1648/*
1700 * Dynamic irq allocate and deallocation for MSI 1649 * Dynamic irq allocate and deallocation
1701 */ 1650 */
1702int create_irq(void) 1651int create_irq(void)
1703{ 1652{
1704 /* Hack of the day: irq == vector. 1653 /* Allocate an unused irq */
1705 * 1654 int irq;
1706 * Ultimately this will be be more general, 1655 int new;
1707 * and not depend on the irq to vector identity mapping. 1656 int vector = 0;
1708 * But this version is needed until msi.c can cope with
1709 * the more general form.
1710 */
1711 int irq, vector;
1712 unsigned long flags; 1657 unsigned long flags;
1713 vector = assign_irq_vector(AUTO_ASSIGN);
1714 irq = vector;
1715 1658
1716 if (vector >= 0) { 1659 irq = -ENOSPC;
1717 spin_lock_irqsave(&vector_lock, flags); 1660 spin_lock_irqsave(&vector_lock, flags);
1718 vector_irq[vector] = irq; 1661 for (new = (NR_IRQS - 1); new >= 0; new--) {
1719 irq_vector[irq] = vector; 1662 if (platform_legacy_irq(new))
1720 spin_unlock_irqrestore(&vector_lock, flags); 1663 continue;
1664 if (irq_vector[new] != 0)
1665 continue;
1666 vector = __assign_irq_vector(new);
1667 if (likely(vector > 0))
1668 irq = new;
1669 break;
1670 }
1671 spin_unlock_irqrestore(&vector_lock, flags);
1721 1672
1673 if (irq >= 0) {
1722 set_intr_gate(vector, interrupt[irq]); 1674 set_intr_gate(vector, interrupt[irq]);
1723
1724 dynamic_irq_init(irq); 1675 dynamic_irq_init(irq);
1725 } 1676 }
1726 return irq; 1677 return irq;
@@ -1729,17 +1680,13 @@ int create_irq(void)
1729void destroy_irq(unsigned int irq) 1680void destroy_irq(unsigned int irq)
1730{ 1681{
1731 unsigned long flags; 1682 unsigned long flags;
1732 unsigned int vector;
1733 1683
1734 dynamic_irq_cleanup(irq); 1684 dynamic_irq_cleanup(irq);
1735 1685
1736 spin_lock_irqsave(&vector_lock, flags); 1686 spin_lock_irqsave(&vector_lock, flags);
1737 vector = irq_vector[irq];
1738 vector_irq[vector] = -1;
1739 irq_vector[irq] = 0; 1687 irq_vector[irq] = 0;
1740 spin_unlock_irqrestore(&vector_lock, flags); 1688 spin_unlock_irqrestore(&vector_lock, flags);
1741} 1689}
1742#endif
1743 1690
1744/* 1691/*
1745 * MSI mesage composition 1692 * MSI mesage composition
@@ -1882,7 +1829,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int triggering, int p
1882 ioapic_write_entry(ioapic, pin, entry); 1829 ioapic_write_entry(ioapic, pin, entry);
1883 1830
1884 spin_lock_irqsave(&ioapic_lock, flags); 1831 spin_lock_irqsave(&ioapic_lock, flags);
1885 set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); 1832 set_native_irq_info(irq, TARGET_CPUS);
1886 spin_unlock_irqrestore(&ioapic_lock, flags); 1833 spin_unlock_irqrestore(&ioapic_lock, flags);
1887 1834
1888 return 0; 1835 return 0;
diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h
index f5da94af9c41..1a8dc185a79f 100644
--- a/include/asm-x86_64/hw_irq.h
+++ b/include/asm-x86_64/hw_irq.h
@@ -75,7 +75,6 @@
75#ifndef __ASSEMBLY__ 75#ifndef __ASSEMBLY__
76extern u8 irq_vector[NR_IRQ_VECTORS]; 76extern u8 irq_vector[NR_IRQ_VECTORS];
77#define IO_APIC_VECTOR(irq) (irq_vector[irq]) 77#define IO_APIC_VECTOR(irq) (irq_vector[irq])
78#define AUTO_ASSIGN -1
79 78
80/* 79/*
81 * Various low-level irq details needed by irq.c, process.c, 80 * Various low-level irq details needed by irq.c, process.c,
diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h
index 5d1b5c68e36e..df579ac29a1e 100644
--- a/include/asm-x86_64/io_apic.h
+++ b/include/asm-x86_64/io_apic.h
@@ -10,45 +10,7 @@
10 * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar 10 * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar
11 */ 11 */
12 12
13#ifdef CONFIG_PCI_MSI
14static inline int use_pci_vector(void) {return 1;}
15static inline void disable_edge_ioapic_vector(unsigned int vector) { }
16static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { }
17static inline void end_edge_ioapic_vector (unsigned int vector) { }
18#define startup_level_ioapic startup_level_ioapic_vector
19#define shutdown_level_ioapic mask_IO_APIC_vector
20#define enable_level_ioapic unmask_IO_APIC_vector
21#define disable_level_ioapic mask_IO_APIC_vector
22#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_vector
23#define end_level_ioapic end_level_ioapic_vector
24#define set_ioapic_affinity set_ioapic_affinity_vector
25
26#define startup_edge_ioapic startup_edge_ioapic_vector
27#define shutdown_edge_ioapic disable_edge_ioapic_vector
28#define enable_edge_ioapic unmask_IO_APIC_vector
29#define disable_edge_ioapic disable_edge_ioapic_vector
30#define ack_edge_ioapic ack_edge_ioapic_vector
31#define end_edge_ioapic end_edge_ioapic_vector
32#else
33static inline int use_pci_vector(void) {return 0;} 13static inline int use_pci_vector(void) {return 0;}
34static inline void disable_edge_ioapic_irq(unsigned int irq) { }
35static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { }
36static inline void end_edge_ioapic_irq (unsigned int irq) { }
37#define startup_level_ioapic startup_level_ioapic_irq
38#define shutdown_level_ioapic mask_IO_APIC_irq
39#define enable_level_ioapic unmask_IO_APIC_irq
40#define disable_level_ioapic mask_IO_APIC_irq
41#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq
42#define end_level_ioapic end_level_ioapic_irq
43#define set_ioapic_affinity set_ioapic_affinity_irq
44
45#define startup_edge_ioapic startup_edge_ioapic_irq
46#define shutdown_edge_ioapic disable_edge_ioapic_irq
47#define enable_edge_ioapic unmask_IO_APIC_irq
48#define disable_edge_ioapic disable_edge_ioapic_irq
49#define ack_edge_ioapic ack_edge_ioapic_irq
50#define end_edge_ioapic end_edge_ioapic_irq
51#endif
52 14
53#define APIC_MISMATCH_DEBUG 15#define APIC_MISMATCH_DEBUG
54 16
@@ -207,8 +169,6 @@ extern int timer_uses_ioapic_pin_0;
207 169
208extern int sis_apic_bug; /* dummy */ 170extern int sis_apic_bug; /* dummy */
209 171
210extern int assign_irq_vector(int irq);
211
212void enable_NMI_through_LVT0 (void * dummy); 172void enable_NMI_through_LVT0 (void * dummy);
213 173
214extern spinlock_t i8259A_lock; 174extern spinlock_t i8259A_lock;
diff --git a/include/asm-x86_64/irq.h b/include/asm-x86_64/irq.h
index 43469d8ab71a..b8f87287847f 100644
--- a/include/asm-x86_64/irq.h
+++ b/include/asm-x86_64/irq.h
@@ -31,13 +31,8 @@
31 31
32#define FIRST_SYSTEM_VECTOR 0xef /* duplicated in hw_irq.h */ 32#define FIRST_SYSTEM_VECTOR 0xef /* duplicated in hw_irq.h */
33 33
34#ifdef CONFIG_PCI_MSI
35#define NR_IRQS FIRST_SYSTEM_VECTOR
36#define NR_IRQ_VECTORS NR_IRQS
37#else
38#define NR_IRQS 224 34#define NR_IRQS 224
39#define NR_IRQ_VECTORS (32 * NR_CPUS) 35#define NR_IRQ_VECTORS (32 * NR_CPUS)
40#endif
41 36
42static __inline__ int irq_canonicalize(int irq) 37static __inline__ int irq_canonicalize(int irq)
43{ 38{