diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2006-10-04 05:16:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 10:55:28 -0400 |
commit | 04b9267b15206fc902a18de1f78de6c82ca47716 (patch) | |
tree | 02cd5fdc44f3ec188af41ec7188d8239badf24c3 /arch/x86_64 | |
parent | 4b2fabb9ec9b3b1cf5cf848a678058fb20c4d552 (diff) |
[PATCH] genirq: x86_64 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
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/x86_64')
-rw-r--r-- | arch/x86_64/kernel/io_apic.c | 147 |
1 files changed, 47 insertions, 100 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 | ||
47 | static int assign_irq_vector(int irq); | ||
48 | |||
47 | #define __apicdebuginit __init | 49 | #define __apicdebuginit __init |
48 | 50 | ||
49 | int sis_apic_bug; /* not actually supported, dummy for compile */ | 51 | int 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 | ||
86 | int 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. */ |
600 | u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; | 594 | u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; |
601 | 595 | ||
602 | int assign_irq_vector(int irq) | 596 | static 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 | } |
616 | next: | 606 | next: |
@@ -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 | |||
623 | static 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 | ||
645 | static void ioapic_register_intr(int irq, int vector, unsigned long trigger) | 643 | static 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 | ||
661 | static void __init setup_IO_APIC_irqs(void) | 655 | static 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 | ||
1209 | static unsigned int startup_ioapic_vector(unsigned int vector) | 1198 | static int ioapic_retrigger_irq(unsigned int irq) |
1210 | { | ||
1211 | int irq = vector_to_irq(vector); | ||
1212 | |||
1213 | return startup_ioapic_irq(irq); | ||
1214 | } | ||
1215 | |||
1216 | static void mask_ioapic_vector (unsigned int vector) | ||
1217 | { | ||
1218 | int irq = vector_to_irq(vector); | ||
1219 | |||
1220 | mask_IO_APIC_irq(irq); | ||
1221 | } | ||
1222 | |||
1223 | static 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 | ||
1231 | static 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 | |||
1241 | static 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 | ||
1289 | static struct irq_chip ioapic_chip __read_mostly = { | 1244 | static 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 | ||
1302 | static inline void init_IO_APIC_traps(void) | 1257 | static 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 | ||
1696 | device_initcall(ioapic_init_sysfs); | 1646 | device_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 | */ |
1702 | int create_irq(void) | 1651 | int 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) | |||
1729 | void destroy_irq(unsigned int irq) | 1680 | void 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; |