diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/kernel/acpi/boot.c | 9 | ||||
-rw-r--r-- | arch/i386/kernel/i8259.c | 45 | ||||
-rw-r--r-- | arch/i386/kernel/io_apic.c | 495 | ||||
-rw-r--r-- | arch/i386/kernel/irq.c | 19 | ||||
-rw-r--r-- | arch/i386/pci/irq.c | 34 |
5 files changed, 328 insertions, 274 deletions
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 1aaea6ab8c46..92f79cdd9a48 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -62,8 +62,6 @@ static inline int acpi_madt_oem_check(char *oem_id, char *oem_table_id) { return | |||
62 | #include <mach_mpparse.h> | 62 | #include <mach_mpparse.h> |
63 | #endif /* CONFIG_X86_LOCAL_APIC */ | 63 | #endif /* CONFIG_X86_LOCAL_APIC */ |
64 | 64 | ||
65 | static inline int gsi_irq_sharing(int gsi) { return gsi; } | ||
66 | |||
67 | #endif /* X86 */ | 65 | #endif /* X86 */ |
68 | 66 | ||
69 | #define BAD_MADT_ENTRY(entry, end) ( \ | 67 | #define BAD_MADT_ENTRY(entry, end) ( \ |
@@ -468,12 +466,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) | |||
468 | 466 | ||
469 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) | 467 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irq) |
470 | { | 468 | { |
471 | #ifdef CONFIG_X86_IO_APIC | 469 | *irq = gsi; |
472 | if (use_pci_vector() && !platform_legacy_irq(gsi)) | ||
473 | *irq = IO_APIC_VECTOR(gsi); | ||
474 | else | ||
475 | #endif | ||
476 | *irq = gsi_irq_sharing(gsi); | ||
477 | return 0; | 470 | return 0; |
478 | } | 471 | } |
479 | 472 | ||
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c index ea5f4e7958d8..d07ed31f11e3 100644 --- a/arch/i386/kernel/i8259.c +++ b/arch/i386/kernel/i8259.c | |||
@@ -34,35 +34,15 @@ | |||
34 | * moves to arch independent land | 34 | * moves to arch independent land |
35 | */ | 35 | */ |
36 | 36 | ||
37 | DEFINE_SPINLOCK(i8259A_lock); | ||
38 | |||
39 | static void end_8259A_irq (unsigned int irq) | ||
40 | { | ||
41 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)) && | ||
42 | irq_desc[irq].action) | ||
43 | enable_8259A_irq(irq); | ||
44 | } | ||
45 | |||
46 | #define shutdown_8259A_irq disable_8259A_irq | ||
47 | |||
48 | static int i8259A_auto_eoi; | 37 | static int i8259A_auto_eoi; |
49 | 38 | DEFINE_SPINLOCK(i8259A_lock); | |
50 | static void mask_and_ack_8259A(unsigned int); | 39 | static void mask_and_ack_8259A(unsigned int); |
51 | 40 | ||
52 | unsigned int startup_8259A_irq(unsigned int irq) | 41 | static struct irq_chip i8259A_chip = { |
53 | { | 42 | .name = "XT-PIC", |
54 | enable_8259A_irq(irq); | 43 | .mask = disable_8259A_irq, |
55 | return 0; /* never anything pending */ | 44 | .unmask = enable_8259A_irq, |
56 | } | 45 | .mask_ack = mask_and_ack_8259A, |
57 | |||
58 | static struct hw_interrupt_type i8259A_irq_type = { | ||
59 | .typename = "XT-PIC", | ||
60 | .startup = startup_8259A_irq, | ||
61 | .shutdown = shutdown_8259A_irq, | ||
62 | .enable = enable_8259A_irq, | ||
63 | .disable = disable_8259A_irq, | ||
64 | .ack = mask_and_ack_8259A, | ||
65 | .end = end_8259A_irq, | ||
66 | }; | 46 | }; |
67 | 47 | ||
68 | /* | 48 | /* |
@@ -133,7 +113,7 @@ void make_8259A_irq(unsigned int irq) | |||
133 | { | 113 | { |
134 | disable_irq_nosync(irq); | 114 | disable_irq_nosync(irq); |
135 | io_apic_irqs &= ~(1<<irq); | 115 | io_apic_irqs &= ~(1<<irq); |
136 | irq_desc[irq].chip = &i8259A_irq_type; | 116 | set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq); |
137 | enable_irq(irq); | 117 | enable_irq(irq); |
138 | } | 118 | } |
139 | 119 | ||
@@ -327,12 +307,12 @@ void init_8259A(int auto_eoi) | |||
327 | outb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */ | 307 | outb_p(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* (slave's support for AEOI in flat mode is to be investigated) */ |
328 | if (auto_eoi) | 308 | if (auto_eoi) |
329 | /* | 309 | /* |
330 | * in AEOI mode we just have to mask the interrupt | 310 | * In AEOI mode we just have to mask the interrupt |
331 | * when acking. | 311 | * when acking. |
332 | */ | 312 | */ |
333 | i8259A_irq_type.ack = disable_8259A_irq; | 313 | i8259A_chip.mask_ack = disable_8259A_irq; |
334 | else | 314 | else |
335 | i8259A_irq_type.ack = mask_and_ack_8259A; | 315 | i8259A_chip.mask_ack = mask_and_ack_8259A; |
336 | 316 | ||
337 | udelay(100); /* wait for 8259A to initialize */ | 317 | udelay(100); /* wait for 8259A to initialize */ |
338 | 318 | ||
@@ -389,12 +369,13 @@ void __init init_ISA_irqs (void) | |||
389 | /* | 369 | /* |
390 | * 16 old-style INTA-cycle interrupts: | 370 | * 16 old-style INTA-cycle interrupts: |
391 | */ | 371 | */ |
392 | irq_desc[i].chip = &i8259A_irq_type; | 372 | set_irq_chip_and_handler(i, &i8259A_chip, |
373 | handle_level_irq); | ||
393 | } else { | 374 | } else { |
394 | /* | 375 | /* |
395 | * 'high' PCI IRQs filled in on demand | 376 | * 'high' PCI IRQs filled in on demand |
396 | */ | 377 | */ |
397 | irq_desc[i].chip = &no_irq_type; | 378 | irq_desc[i].chip = &no_irq_chip; |
398 | } | 379 | } |
399 | } | 380 | } |
400 | } | 381 | } |
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index fd0df75cfbda..b7287fb499f3 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -31,6 +31,9 @@ | |||
31 | #include <linux/acpi.h> | 31 | #include <linux/acpi.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/sysdev.h> | 33 | #include <linux/sysdev.h> |
34 | #include <linux/pci.h> | ||
35 | #include <linux/msi.h> | ||
36 | #include <linux/htirq.h> | ||
34 | 37 | ||
35 | #include <asm/io.h> | 38 | #include <asm/io.h> |
36 | #include <asm/smp.h> | 39 | #include <asm/smp.h> |
@@ -38,6 +41,8 @@ | |||
38 | #include <asm/timer.h> | 41 | #include <asm/timer.h> |
39 | #include <asm/i8259.h> | 42 | #include <asm/i8259.h> |
40 | #include <asm/nmi.h> | 43 | #include <asm/nmi.h> |
44 | #include <asm/msidef.h> | ||
45 | #include <asm/hypertransport.h> | ||
41 | 46 | ||
42 | #include <mach_apic.h> | 47 | #include <mach_apic.h> |
43 | #include <mach_apicdef.h> | 48 | #include <mach_apicdef.h> |
@@ -86,15 +91,6 @@ static struct irq_pin_list { | |||
86 | int apic, pin, next; | 91 | int apic, pin, next; |
87 | } irq_2_pin[PIN_MAP_SIZE]; | 92 | } irq_2_pin[PIN_MAP_SIZE]; |
88 | 93 | ||
89 | int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1}; | ||
90 | #ifdef CONFIG_PCI_MSI | ||
91 | #define vector_to_irq(vector) \ | ||
92 | (platform_legacy_irq(vector) ? vector : vector_irq[vector]) | ||
93 | #else | ||
94 | #define vector_to_irq(vector) (vector) | ||
95 | #endif | ||
96 | |||
97 | |||
98 | union entry_union { | 94 | union entry_union { |
99 | struct { u32 w1, w2; }; | 95 | struct { u32 w1, w2; }; |
100 | struct IO_APIC_route_entry entry; | 96 | struct IO_APIC_route_entry entry; |
@@ -280,7 +276,7 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) | |||
280 | break; | 276 | break; |
281 | entry = irq_2_pin + entry->next; | 277 | entry = irq_2_pin + entry->next; |
282 | } | 278 | } |
283 | set_irq_info(irq, cpumask); | 279 | set_native_irq_info(irq, cpumask); |
284 | spin_unlock_irqrestore(&ioapic_lock, flags); | 280 | spin_unlock_irqrestore(&ioapic_lock, flags); |
285 | } | 281 | } |
286 | 282 | ||
@@ -1181,46 +1177,45 @@ static inline int IO_APIC_irq_trigger(int irq) | |||
1181 | /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ | 1177 | /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ |
1182 | u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; | 1178 | u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; |
1183 | 1179 | ||
1184 | int assign_irq_vector(int irq) | 1180 | static int __assign_irq_vector(int irq) |
1185 | { | 1181 | { |
1186 | static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; | 1182 | static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; |
1187 | unsigned long flags; | ||
1188 | int vector; | 1183 | int vector; |
1189 | 1184 | ||
1190 | BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS); | 1185 | BUG_ON((unsigned)irq >= NR_IRQ_VECTORS); |
1191 | 1186 | ||
1192 | spin_lock_irqsave(&vector_lock, flags); | 1187 | if (IO_APIC_VECTOR(irq) > 0) |
1193 | |||
1194 | if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) { | ||
1195 | spin_unlock_irqrestore(&vector_lock, flags); | ||
1196 | return IO_APIC_VECTOR(irq); | 1188 | return IO_APIC_VECTOR(irq); |
1197 | } | 1189 | |
1198 | next: | ||
1199 | current_vector += 8; | 1190 | current_vector += 8; |
1200 | if (current_vector == SYSCALL_VECTOR) | 1191 | if (current_vector == SYSCALL_VECTOR) |
1201 | goto next; | 1192 | current_vector += 8; |
1202 | 1193 | ||
1203 | if (current_vector >= FIRST_SYSTEM_VECTOR) { | 1194 | if (current_vector >= FIRST_SYSTEM_VECTOR) { |
1204 | offset++; | 1195 | offset++; |
1205 | if (!(offset%8)) { | 1196 | if (!(offset % 8)) |
1206 | spin_unlock_irqrestore(&vector_lock, flags); | ||
1207 | return -ENOSPC; | 1197 | return -ENOSPC; |
1208 | } | ||
1209 | current_vector = FIRST_DEVICE_VECTOR + offset; | 1198 | current_vector = FIRST_DEVICE_VECTOR + offset; |
1210 | } | 1199 | } |
1211 | 1200 | ||
1212 | vector = current_vector; | 1201 | vector = current_vector; |
1213 | vector_irq[vector] = irq; | 1202 | IO_APIC_VECTOR(irq) = vector; |
1214 | if (irq != AUTO_ASSIGN) | 1203 | |
1215 | IO_APIC_VECTOR(irq) = vector; | 1204 | return vector; |
1205 | } | ||
1206 | |||
1207 | static int assign_irq_vector(int irq) | ||
1208 | { | ||
1209 | unsigned long flags; | ||
1210 | int vector; | ||
1216 | 1211 | ||
1212 | spin_lock_irqsave(&vector_lock, flags); | ||
1213 | vector = __assign_irq_vector(irq); | ||
1217 | spin_unlock_irqrestore(&vector_lock, flags); | 1214 | spin_unlock_irqrestore(&vector_lock, flags); |
1218 | 1215 | ||
1219 | return vector; | 1216 | return vector; |
1220 | } | 1217 | } |
1221 | 1218 | static struct irq_chip ioapic_chip; | |
1222 | static struct hw_interrupt_type ioapic_level_type; | ||
1223 | static struct hw_interrupt_type ioapic_edge_type; | ||
1224 | 1219 | ||
1225 | #define IOAPIC_AUTO -1 | 1220 | #define IOAPIC_AUTO -1 |
1226 | #define IOAPIC_EDGE 0 | 1221 | #define IOAPIC_EDGE 0 |
@@ -1228,16 +1223,14 @@ static struct hw_interrupt_type ioapic_edge_type; | |||
1228 | 1223 | ||
1229 | static void ioapic_register_intr(int irq, int vector, unsigned long trigger) | 1224 | static void ioapic_register_intr(int irq, int vector, unsigned long trigger) |
1230 | { | 1225 | { |
1231 | unsigned idx; | ||
1232 | |||
1233 | idx = use_pci_vector() && !platform_legacy_irq(irq) ? vector : irq; | ||
1234 | |||
1235 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || | 1226 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || |
1236 | trigger == IOAPIC_LEVEL) | 1227 | trigger == IOAPIC_LEVEL) |
1237 | irq_desc[idx].chip = &ioapic_level_type; | 1228 | set_irq_chip_and_handler(irq, &ioapic_chip, |
1229 | handle_fasteoi_irq); | ||
1238 | else | 1230 | else |
1239 | irq_desc[idx].chip = &ioapic_edge_type; | 1231 | set_irq_chip_and_handler(irq, &ioapic_chip, |
1240 | set_intr_gate(vector, interrupt[idx]); | 1232 | handle_edge_irq); |
1233 | set_intr_gate(vector, interrupt[irq]); | ||
1241 | } | 1234 | } |
1242 | 1235 | ||
1243 | static void __init setup_IO_APIC_irqs(void) | 1236 | static void __init setup_IO_APIC_irqs(void) |
@@ -1346,7 +1339,8 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in | |||
1346 | * The timer IRQ doesn't have to know that behind the | 1339 | * The timer IRQ doesn't have to know that behind the |
1347 | * scene we have a 8259A-master in AEOI mode ... | 1340 | * scene we have a 8259A-master in AEOI mode ... |
1348 | */ | 1341 | */ |
1349 | irq_desc[0].chip = &ioapic_edge_type; | 1342 | irq_desc[0].chip = &ioapic_chip; |
1343 | set_irq_handler(0, handle_edge_irq); | ||
1350 | 1344 | ||
1351 | /* | 1345 | /* |
1352 | * Add it to the IO-APIC irq-routing table: | 1346 | * Add it to the IO-APIC irq-routing table: |
@@ -1481,17 +1475,12 @@ void __init print_IO_APIC(void) | |||
1481 | ); | 1475 | ); |
1482 | } | 1476 | } |
1483 | } | 1477 | } |
1484 | if (use_pci_vector()) | ||
1485 | printk(KERN_INFO "Using vector-based indexing\n"); | ||
1486 | printk(KERN_DEBUG "IRQ to pin mappings:\n"); | 1478 | printk(KERN_DEBUG "IRQ to pin mappings:\n"); |
1487 | for (i = 0; i < NR_IRQS; i++) { | 1479 | for (i = 0; i < NR_IRQS; i++) { |
1488 | struct irq_pin_list *entry = irq_2_pin + i; | 1480 | struct irq_pin_list *entry = irq_2_pin + i; |
1489 | if (entry->pin < 0) | 1481 | if (entry->pin < 0) |
1490 | continue; | 1482 | continue; |
1491 | if (use_pci_vector() && !platform_legacy_irq(i)) | 1483 | printk(KERN_DEBUG "IRQ%d ", i); |
1492 | printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i)); | ||
1493 | else | ||
1494 | printk(KERN_DEBUG "IRQ%d ", i); | ||
1495 | for (;;) { | 1484 | for (;;) { |
1496 | printk("-> %d:%d", entry->apic, entry->pin); | 1485 | printk("-> %d:%d", entry->apic, entry->pin); |
1497 | if (!entry->next) | 1486 | if (!entry->next) |
@@ -1918,6 +1907,8 @@ static int __init timer_irq_works(void) | |||
1918 | */ | 1907 | */ |
1919 | 1908 | ||
1920 | /* | 1909 | /* |
1910 | * Startup quirk: | ||
1911 | * | ||
1921 | * Starting up a edge-triggered IO-APIC interrupt is | 1912 | * Starting up a edge-triggered IO-APIC interrupt is |
1922 | * nasty - we need to make sure that we get the edge. | 1913 | * nasty - we need to make sure that we get the edge. |
1923 | * If it is already asserted for some reason, we need | 1914 | * If it is already asserted for some reason, we need |
@@ -1925,8 +1916,10 @@ static int __init timer_irq_works(void) | |||
1925 | * | 1916 | * |
1926 | * This is not complete - we should be able to fake | 1917 | * This is not complete - we should be able to fake |
1927 | * an edge even if it isn't on the 8259A... | 1918 | * an edge even if it isn't on the 8259A... |
1919 | * | ||
1920 | * (We do this for level-triggered IRQs too - it cannot hurt.) | ||
1928 | */ | 1921 | */ |
1929 | static unsigned int startup_edge_ioapic_irq(unsigned int irq) | 1922 | static unsigned int startup_ioapic_irq(unsigned int irq) |
1930 | { | 1923 | { |
1931 | int was_pending = 0; | 1924 | int was_pending = 0; |
1932 | unsigned long flags; | 1925 | unsigned long flags; |
@@ -1943,47 +1936,18 @@ static unsigned int startup_edge_ioapic_irq(unsigned int irq) | |||
1943 | return was_pending; | 1936 | return was_pending; |
1944 | } | 1937 | } |
1945 | 1938 | ||
1946 | /* | 1939 | static void ack_ioapic_irq(unsigned int irq) |
1947 | * Once we have recorded IRQ_PENDING already, we can mask the | ||
1948 | * interrupt for real. This prevents IRQ storms from unhandled | ||
1949 | * devices. | ||
1950 | */ | ||
1951 | static void ack_edge_ioapic_irq(unsigned int irq) | ||
1952 | { | 1940 | { |
1953 | move_irq(irq); | 1941 | move_native_irq(irq); |
1954 | if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED)) | ||
1955 | == (IRQ_PENDING | IRQ_DISABLED)) | ||
1956 | mask_IO_APIC_irq(irq); | ||
1957 | ack_APIC_irq(); | 1942 | ack_APIC_irq(); |
1958 | } | 1943 | } |
1959 | 1944 | ||
1960 | /* | 1945 | static void ack_ioapic_quirk_irq(unsigned int irq) |
1961 | * Level triggered interrupts can just be masked, | ||
1962 | * and shutting down and starting up the interrupt | ||
1963 | * is the same as enabling and disabling them -- except | ||
1964 | * with a startup need to return a "was pending" value. | ||
1965 | * | ||
1966 | * Level triggered interrupts are special because we | ||
1967 | * do not touch any IO-APIC register while handling | ||
1968 | * them. We ack the APIC in the end-IRQ handler, not | ||
1969 | * in the start-IRQ-handler. Protection against reentrance | ||
1970 | * from the same interrupt is still provided, both by the | ||
1971 | * generic IRQ layer and by the fact that an unacked local | ||
1972 | * APIC does not accept IRQs. | ||
1973 | */ | ||
1974 | static unsigned int startup_level_ioapic_irq (unsigned int irq) | ||
1975 | { | ||
1976 | unmask_IO_APIC_irq(irq); | ||
1977 | |||
1978 | return 0; /* don't check for pending */ | ||
1979 | } | ||
1980 | |||
1981 | static void end_level_ioapic_irq (unsigned int irq) | ||
1982 | { | 1946 | { |
1983 | unsigned long v; | 1947 | unsigned long v; |
1984 | int i; | 1948 | int i; |
1985 | 1949 | ||
1986 | move_irq(irq); | 1950 | move_native_irq(irq); |
1987 | /* | 1951 | /* |
1988 | * It appears there is an erratum which affects at least version 0x11 | 1952 | * It appears there is an erratum which affects at least version 0x11 |
1989 | * of I/O APIC (that's the 82093AA and cores integrated into various | 1953 | * of I/O APIC (that's the 82093AA and cores integrated into various |
@@ -2018,105 +1982,26 @@ static void end_level_ioapic_irq (unsigned int irq) | |||
2018 | } | 1982 | } |
2019 | } | 1983 | } |
2020 | 1984 | ||
2021 | #ifdef CONFIG_PCI_MSI | 1985 | static int ioapic_retrigger_irq(unsigned int irq) |
2022 | static unsigned int startup_edge_ioapic_vector(unsigned int vector) | ||
2023 | { | ||
2024 | int irq = vector_to_irq(vector); | ||
2025 | |||
2026 | return startup_edge_ioapic_irq(irq); | ||
2027 | } | ||
2028 | |||
2029 | static void ack_edge_ioapic_vector(unsigned int vector) | ||
2030 | { | ||
2031 | int irq = vector_to_irq(vector); | ||
2032 | |||
2033 | move_native_irq(vector); | ||
2034 | ack_edge_ioapic_irq(irq); | ||
2035 | } | ||
2036 | |||
2037 | static unsigned int startup_level_ioapic_vector (unsigned int vector) | ||
2038 | { | ||
2039 | int irq = vector_to_irq(vector); | ||
2040 | |||
2041 | return startup_level_ioapic_irq (irq); | ||
2042 | } | ||
2043 | |||
2044 | static void end_level_ioapic_vector (unsigned int vector) | ||
2045 | { | ||
2046 | int irq = vector_to_irq(vector); | ||
2047 | |||
2048 | move_native_irq(vector); | ||
2049 | end_level_ioapic_irq(irq); | ||
2050 | } | ||
2051 | |||
2052 | static void mask_IO_APIC_vector (unsigned int vector) | ||
2053 | { | ||
2054 | int irq = vector_to_irq(vector); | ||
2055 | |||
2056 | mask_IO_APIC_irq(irq); | ||
2057 | } | ||
2058 | |||
2059 | static void unmask_IO_APIC_vector (unsigned int vector) | ||
2060 | { | ||
2061 | int irq = vector_to_irq(vector); | ||
2062 | |||
2063 | unmask_IO_APIC_irq(irq); | ||
2064 | } | ||
2065 | |||
2066 | #ifdef CONFIG_SMP | ||
2067 | static void set_ioapic_affinity_vector (unsigned int vector, | ||
2068 | cpumask_t cpu_mask) | ||
2069 | { | ||
2070 | int irq = vector_to_irq(vector); | ||
2071 | |||
2072 | set_native_irq_info(vector, cpu_mask); | ||
2073 | set_ioapic_affinity_irq(irq, cpu_mask); | ||
2074 | } | ||
2075 | #endif | ||
2076 | #endif | ||
2077 | |||
2078 | static int ioapic_retrigger(unsigned int irq) | ||
2079 | { | 1986 | { |
2080 | send_IPI_self(IO_APIC_VECTOR(irq)); | 1987 | send_IPI_self(IO_APIC_VECTOR(irq)); |
2081 | 1988 | ||
2082 | return 1; | 1989 | return 1; |
2083 | } | 1990 | } |
2084 | 1991 | ||
2085 | /* | 1992 | static struct irq_chip ioapic_chip __read_mostly = { |
2086 | * Level and edge triggered IO-APIC interrupts need different handling, | 1993 | .name = "IO-APIC", |
2087 | * so we use two separate IRQ descriptors. Edge triggered IRQs can be | 1994 | .startup = startup_ioapic_irq, |
2088 | * handled with the level-triggered descriptor, but that one has slightly | 1995 | .mask = mask_IO_APIC_irq, |
2089 | * more overhead. Level-triggered interrupts cannot be handled with the | 1996 | .unmask = unmask_IO_APIC_irq, |
2090 | * edge-triggered handler, without risking IRQ storms and other ugly | 1997 | .ack = ack_ioapic_irq, |
2091 | * races. | 1998 | .eoi = ack_ioapic_quirk_irq, |
2092 | */ | ||
2093 | static struct hw_interrupt_type ioapic_edge_type __read_mostly = { | ||
2094 | .typename = "IO-APIC-edge", | ||
2095 | .startup = startup_edge_ioapic, | ||
2096 | .shutdown = shutdown_edge_ioapic, | ||
2097 | .enable = enable_edge_ioapic, | ||
2098 | .disable = disable_edge_ioapic, | ||
2099 | .ack = ack_edge_ioapic, | ||
2100 | .end = end_edge_ioapic, | ||
2101 | #ifdef CONFIG_SMP | 1999 | #ifdef CONFIG_SMP |
2102 | .set_affinity = set_ioapic_affinity, | 2000 | .set_affinity = set_ioapic_affinity_irq, |
2103 | #endif | 2001 | #endif |
2104 | .retrigger = ioapic_retrigger, | 2002 | .retrigger = ioapic_retrigger_irq, |
2105 | }; | 2003 | }; |
2106 | 2004 | ||
2107 | static struct hw_interrupt_type ioapic_level_type __read_mostly = { | ||
2108 | .typename = "IO-APIC-level", | ||
2109 | .startup = startup_level_ioapic, | ||
2110 | .shutdown = shutdown_level_ioapic, | ||
2111 | .enable = enable_level_ioapic, | ||
2112 | .disable = disable_level_ioapic, | ||
2113 | .ack = mask_and_ack_level_ioapic, | ||
2114 | .end = end_level_ioapic, | ||
2115 | #ifdef CONFIG_SMP | ||
2116 | .set_affinity = set_ioapic_affinity, | ||
2117 | #endif | ||
2118 | .retrigger = ioapic_retrigger, | ||
2119 | }; | ||
2120 | 2005 | ||
2121 | static inline void init_IO_APIC_traps(void) | 2006 | static inline void init_IO_APIC_traps(void) |
2122 | { | 2007 | { |
@@ -2135,11 +2020,6 @@ static inline void init_IO_APIC_traps(void) | |||
2135 | */ | 2020 | */ |
2136 | for (irq = 0; irq < NR_IRQS ; irq++) { | 2021 | for (irq = 0; irq < NR_IRQS ; irq++) { |
2137 | int tmp = irq; | 2022 | int tmp = irq; |
2138 | if (use_pci_vector()) { | ||
2139 | if (!platform_legacy_irq(tmp)) | ||
2140 | if ((tmp = vector_to_irq(tmp)) == -1) | ||
2141 | continue; | ||
2142 | } | ||
2143 | if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { | 2023 | if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { |
2144 | /* | 2024 | /* |
2145 | * Hmm.. We don't have an entry for this, | 2025 | * Hmm.. We don't have an entry for this, |
@@ -2150,20 +2030,21 @@ static inline void init_IO_APIC_traps(void) | |||
2150 | make_8259A_irq(irq); | 2030 | make_8259A_irq(irq); |
2151 | else | 2031 | else |
2152 | /* Strange. Oh, well.. */ | 2032 | /* Strange. Oh, well.. */ |
2153 | irq_desc[irq].chip = &no_irq_type; | 2033 | irq_desc[irq].chip = &no_irq_chip; |
2154 | } | 2034 | } |
2155 | } | 2035 | } |
2156 | } | 2036 | } |
2157 | 2037 | ||
2158 | static void enable_lapic_irq (unsigned int irq) | 2038 | /* |
2159 | { | 2039 | * The local APIC irq-chip implementation: |
2160 | unsigned long v; | 2040 | */ |
2161 | 2041 | ||
2162 | v = apic_read(APIC_LVT0); | 2042 | static void ack_apic(unsigned int irq) |
2163 | apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED); | 2043 | { |
2044 | ack_APIC_irq(); | ||
2164 | } | 2045 | } |
2165 | 2046 | ||
2166 | static void disable_lapic_irq (unsigned int irq) | 2047 | static void mask_lapic_irq (unsigned int irq) |
2167 | { | 2048 | { |
2168 | unsigned long v; | 2049 | unsigned long v; |
2169 | 2050 | ||
@@ -2171,21 +2052,19 @@ static void disable_lapic_irq (unsigned int irq) | |||
2171 | apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); | 2052 | apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); |
2172 | } | 2053 | } |
2173 | 2054 | ||
2174 | static void ack_lapic_irq (unsigned int irq) | 2055 | static void unmask_lapic_irq (unsigned int irq) |
2175 | { | 2056 | { |
2176 | ack_APIC_irq(); | 2057 | unsigned long v; |
2177 | } | ||
2178 | 2058 | ||
2179 | static void end_lapic_irq (unsigned int i) { /* nothing */ } | 2059 | v = apic_read(APIC_LVT0); |
2060 | apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED); | ||
2061 | } | ||
2180 | 2062 | ||
2181 | static struct hw_interrupt_type lapic_irq_type __read_mostly = { | 2063 | static struct irq_chip lapic_chip __read_mostly = { |
2182 | .typename = "local-APIC-edge", | 2064 | .name = "local-APIC-edge", |
2183 | .startup = NULL, /* startup_irq() not used for IRQ0 */ | 2065 | .mask = mask_lapic_irq, |
2184 | .shutdown = NULL, /* shutdown_irq() not used for IRQ0 */ | 2066 | .unmask = unmask_lapic_irq, |
2185 | .enable = enable_lapic_irq, | 2067 | .eoi = ack_apic, |
2186 | .disable = disable_lapic_irq, | ||
2187 | .ack = ack_lapic_irq, | ||
2188 | .end = end_lapic_irq | ||
2189 | }; | 2068 | }; |
2190 | 2069 | ||
2191 | static void setup_nmi (void) | 2070 | static void setup_nmi (void) |
@@ -2356,7 +2235,7 @@ static inline void check_timer(void) | |||
2356 | printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); | 2235 | printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); |
2357 | 2236 | ||
2358 | disable_8259A_irq(0); | 2237 | disable_8259A_irq(0); |
2359 | irq_desc[0].chip = &lapic_irq_type; | 2238 | set_irq_chip_and_handler(0, &lapic_chip, handle_fasteoi_irq); |
2360 | apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ | 2239 | apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ |
2361 | enable_8259A_irq(0); | 2240 | enable_8259A_irq(0); |
2362 | 2241 | ||
@@ -2531,6 +2410,238 @@ static int __init ioapic_init_sysfs(void) | |||
2531 | 2410 | ||
2532 | device_initcall(ioapic_init_sysfs); | 2411 | device_initcall(ioapic_init_sysfs); |
2533 | 2412 | ||
2413 | /* | ||
2414 | * Dynamic irq allocate and deallocation | ||
2415 | */ | ||
2416 | int create_irq(void) | ||
2417 | { | ||
2418 | /* Allocate an unused irq */ | ||
2419 | int irq, new, vector; | ||
2420 | unsigned long flags; | ||
2421 | |||
2422 | irq = -ENOSPC; | ||
2423 | spin_lock_irqsave(&vector_lock, flags); | ||
2424 | for (new = (NR_IRQS - 1); new >= 0; new--) { | ||
2425 | if (platform_legacy_irq(new)) | ||
2426 | continue; | ||
2427 | if (irq_vector[new] != 0) | ||
2428 | continue; | ||
2429 | vector = __assign_irq_vector(new); | ||
2430 | if (likely(vector > 0)) | ||
2431 | irq = new; | ||
2432 | break; | ||
2433 | } | ||
2434 | spin_unlock_irqrestore(&vector_lock, flags); | ||
2435 | |||
2436 | if (irq >= 0) { | ||
2437 | set_intr_gate(vector, interrupt[irq]); | ||
2438 | dynamic_irq_init(irq); | ||
2439 | } | ||
2440 | return irq; | ||
2441 | } | ||
2442 | |||
2443 | void destroy_irq(unsigned int irq) | ||
2444 | { | ||
2445 | unsigned long flags; | ||
2446 | |||
2447 | dynamic_irq_cleanup(irq); | ||
2448 | |||
2449 | spin_lock_irqsave(&vector_lock, flags); | ||
2450 | irq_vector[irq] = 0; | ||
2451 | spin_unlock_irqrestore(&vector_lock, flags); | ||
2452 | } | ||
2453 | |||
2454 | /* | ||
2455 | * MSI mesage composition | ||
2456 | */ | ||
2457 | #ifdef CONFIG_PCI_MSI | ||
2458 | static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_msg *msg) | ||
2459 | { | ||
2460 | int vector; | ||
2461 | unsigned dest; | ||
2462 | |||
2463 | vector = assign_irq_vector(irq); | ||
2464 | if (vector >= 0) { | ||
2465 | dest = cpu_mask_to_apicid(TARGET_CPUS); | ||
2466 | |||
2467 | msg->address_hi = MSI_ADDR_BASE_HI; | ||
2468 | msg->address_lo = | ||
2469 | MSI_ADDR_BASE_LO | | ||
2470 | ((INT_DEST_MODE == 0) ? | ||
2471 | MSI_ADDR_DEST_MODE_PHYSICAL: | ||
2472 | MSI_ADDR_DEST_MODE_LOGICAL) | | ||
2473 | ((INT_DELIVERY_MODE != dest_LowestPrio) ? | ||
2474 | MSI_ADDR_REDIRECTION_CPU: | ||
2475 | MSI_ADDR_REDIRECTION_LOWPRI) | | ||
2476 | MSI_ADDR_DEST_ID(dest); | ||
2477 | |||
2478 | msg->data = | ||
2479 | MSI_DATA_TRIGGER_EDGE | | ||
2480 | MSI_DATA_LEVEL_ASSERT | | ||
2481 | ((INT_DELIVERY_MODE != dest_LowestPrio) ? | ||
2482 | MSI_DATA_DELIVERY_FIXED: | ||
2483 | MSI_DATA_DELIVERY_LOWPRI) | | ||
2484 | MSI_DATA_VECTOR(vector); | ||
2485 | } | ||
2486 | return vector; | ||
2487 | } | ||
2488 | |||
2489 | #ifdef CONFIG_SMP | ||
2490 | static void set_msi_irq_affinity(unsigned int irq, cpumask_t mask) | ||
2491 | { | ||
2492 | struct msi_msg msg; | ||
2493 | unsigned int dest; | ||
2494 | cpumask_t tmp; | ||
2495 | int vector; | ||
2496 | |||
2497 | cpus_and(tmp, mask, cpu_online_map); | ||
2498 | if (cpus_empty(tmp)) | ||
2499 | tmp = TARGET_CPUS; | ||
2500 | |||
2501 | vector = assign_irq_vector(irq); | ||
2502 | if (vector < 0) | ||
2503 | return; | ||
2504 | |||
2505 | dest = cpu_mask_to_apicid(mask); | ||
2506 | |||
2507 | read_msi_msg(irq, &msg); | ||
2508 | |||
2509 | msg.data &= ~MSI_DATA_VECTOR_MASK; | ||
2510 | msg.data |= MSI_DATA_VECTOR(vector); | ||
2511 | msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; | ||
2512 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); | ||
2513 | |||
2514 | write_msi_msg(irq, &msg); | ||
2515 | set_native_irq_info(irq, mask); | ||
2516 | } | ||
2517 | #endif /* CONFIG_SMP */ | ||
2518 | |||
2519 | /* | ||
2520 | * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices, | ||
2521 | * which implement the MSI or MSI-X Capability Structure. | ||
2522 | */ | ||
2523 | static struct irq_chip msi_chip = { | ||
2524 | .name = "PCI-MSI", | ||
2525 | .unmask = unmask_msi_irq, | ||
2526 | .mask = mask_msi_irq, | ||
2527 | .ack = ack_ioapic_irq, | ||
2528 | #ifdef CONFIG_SMP | ||
2529 | .set_affinity = set_msi_irq_affinity, | ||
2530 | #endif | ||
2531 | .retrigger = ioapic_retrigger_irq, | ||
2532 | }; | ||
2533 | |||
2534 | int arch_setup_msi_irq(unsigned int irq, struct pci_dev *dev) | ||
2535 | { | ||
2536 | struct msi_msg msg; | ||
2537 | int ret; | ||
2538 | ret = msi_compose_msg(dev, irq, &msg); | ||
2539 | if (ret < 0) | ||
2540 | return ret; | ||
2541 | |||
2542 | write_msi_msg(irq, &msg); | ||
2543 | |||
2544 | set_irq_chip_and_handler(irq, &msi_chip, handle_edge_irq); | ||
2545 | |||
2546 | return 0; | ||
2547 | } | ||
2548 | |||
2549 | void arch_teardown_msi_irq(unsigned int irq) | ||
2550 | { | ||
2551 | return; | ||
2552 | } | ||
2553 | |||
2554 | #endif /* CONFIG_PCI_MSI */ | ||
2555 | |||
2556 | /* | ||
2557 | * Hypertransport interrupt support | ||
2558 | */ | ||
2559 | #ifdef CONFIG_HT_IRQ | ||
2560 | |||
2561 | #ifdef CONFIG_SMP | ||
2562 | |||
2563 | static void target_ht_irq(unsigned int irq, unsigned int dest) | ||
2564 | { | ||
2565 | u32 low, high; | ||
2566 | low = read_ht_irq_low(irq); | ||
2567 | high = read_ht_irq_high(irq); | ||
2568 | |||
2569 | low &= ~(HT_IRQ_LOW_DEST_ID_MASK); | ||
2570 | high &= ~(HT_IRQ_HIGH_DEST_ID_MASK); | ||
2571 | |||
2572 | low |= HT_IRQ_LOW_DEST_ID(dest); | ||
2573 | high |= HT_IRQ_HIGH_DEST_ID(dest); | ||
2574 | |||
2575 | write_ht_irq_low(irq, low); | ||
2576 | write_ht_irq_high(irq, high); | ||
2577 | } | ||
2578 | |||
2579 | static void set_ht_irq_affinity(unsigned int irq, cpumask_t mask) | ||
2580 | { | ||
2581 | unsigned int dest; | ||
2582 | cpumask_t tmp; | ||
2583 | |||
2584 | cpus_and(tmp, mask, cpu_online_map); | ||
2585 | if (cpus_empty(tmp)) | ||
2586 | tmp = TARGET_CPUS; | ||
2587 | |||
2588 | cpus_and(mask, tmp, CPU_MASK_ALL); | ||
2589 | |||
2590 | dest = cpu_mask_to_apicid(mask); | ||
2591 | |||
2592 | target_ht_irq(irq, dest); | ||
2593 | set_native_irq_info(irq, mask); | ||
2594 | } | ||
2595 | #endif | ||
2596 | |||
2597 | static struct hw_interrupt_type ht_irq_chip = { | ||
2598 | .name = "PCI-HT", | ||
2599 | .mask = mask_ht_irq, | ||
2600 | .unmask = unmask_ht_irq, | ||
2601 | .ack = ack_ioapic_irq, | ||
2602 | #ifdef CONFIG_SMP | ||
2603 | .set_affinity = set_ht_irq_affinity, | ||
2604 | #endif | ||
2605 | .retrigger = ioapic_retrigger_irq, | ||
2606 | }; | ||
2607 | |||
2608 | int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) | ||
2609 | { | ||
2610 | int vector; | ||
2611 | |||
2612 | vector = assign_irq_vector(irq); | ||
2613 | if (vector >= 0) { | ||
2614 | u32 low, high; | ||
2615 | unsigned dest; | ||
2616 | cpumask_t tmp; | ||
2617 | |||
2618 | cpus_clear(tmp); | ||
2619 | cpu_set(vector >> 8, tmp); | ||
2620 | dest = cpu_mask_to_apicid(tmp); | ||
2621 | |||
2622 | high = HT_IRQ_HIGH_DEST_ID(dest); | ||
2623 | |||
2624 | low = HT_IRQ_LOW_BASE | | ||
2625 | HT_IRQ_LOW_DEST_ID(dest) | | ||
2626 | HT_IRQ_LOW_VECTOR(vector) | | ||
2627 | ((INT_DEST_MODE == 0) ? | ||
2628 | HT_IRQ_LOW_DM_PHYSICAL : | ||
2629 | HT_IRQ_LOW_DM_LOGICAL) | | ||
2630 | HT_IRQ_LOW_RQEOI_EDGE | | ||
2631 | ((INT_DELIVERY_MODE != dest_LowestPrio) ? | ||
2632 | HT_IRQ_LOW_MT_FIXED : | ||
2633 | HT_IRQ_LOW_MT_ARBITRATED) | | ||
2634 | HT_IRQ_LOW_IRQ_MASKED; | ||
2635 | |||
2636 | write_ht_irq_low(irq, low); | ||
2637 | write_ht_irq_high(irq, high); | ||
2638 | |||
2639 | set_irq_chip_and_handler(irq, &ht_irq_chip, handle_edge_irq); | ||
2640 | } | ||
2641 | return vector; | ||
2642 | } | ||
2643 | #endif /* CONFIG_HT_IRQ */ | ||
2644 | |||
2534 | /* -------------------------------------------------------------------------- | 2645 | /* -------------------------------------------------------------------------- |
2535 | ACPI-based IOAPIC Configuration | 2646 | ACPI-based IOAPIC Configuration |
2536 | -------------------------------------------------------------------------- */ | 2647 | -------------------------------------------------------------------------- */ |
@@ -2684,7 +2795,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a | |||
2684 | 2795 | ||
2685 | ioapic_write_entry(ioapic, pin, entry); | 2796 | ioapic_write_entry(ioapic, pin, entry); |
2686 | spin_lock_irqsave(&ioapic_lock, flags); | 2797 | spin_lock_irqsave(&ioapic_lock, flags); |
2687 | set_native_irq_info(use_pci_vector() ? entry.vector : irq, TARGET_CPUS); | 2798 | set_native_irq_info(irq, TARGET_CPUS); |
2688 | spin_unlock_irqrestore(&ioapic_lock, flags); | 2799 | spin_unlock_irqrestore(&ioapic_lock, flags); |
2689 | 2800 | ||
2690 | return 0; | 2801 | return 0; |
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 5fe547cd8f9f..3dd2e180151b 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c | |||
@@ -55,6 +55,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) | |||
55 | { | 55 | { |
56 | /* high bit used in ret_from_ code */ | 56 | /* high bit used in ret_from_ code */ |
57 | int irq = ~regs->orig_eax; | 57 | int irq = ~regs->orig_eax; |
58 | struct irq_desc *desc = irq_desc + irq; | ||
58 | #ifdef CONFIG_4KSTACKS | 59 | #ifdef CONFIG_4KSTACKS |
59 | union irq_ctx *curctx, *irqctx; | 60 | union irq_ctx *curctx, *irqctx; |
60 | u32 *isp; | 61 | u32 *isp; |
@@ -94,7 +95,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) | |||
94 | * current stack (which is the irq stack already after all) | 95 | * current stack (which is the irq stack already after all) |
95 | */ | 96 | */ |
96 | if (curctx != irqctx) { | 97 | if (curctx != irqctx) { |
97 | int arg1, arg2, ebx; | 98 | int arg1, arg2, arg3, ebx; |
98 | 99 | ||
99 | /* build the stack frame on the IRQ stack */ | 100 | /* build the stack frame on the IRQ stack */ |
100 | isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); | 101 | isp = (u32*) ((char*)irqctx + sizeof(*irqctx)); |
@@ -110,16 +111,17 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) | |||
110 | (curctx->tinfo.preempt_count & SOFTIRQ_MASK); | 111 | (curctx->tinfo.preempt_count & SOFTIRQ_MASK); |
111 | 112 | ||
112 | asm volatile( | 113 | asm volatile( |
113 | " xchgl %%ebx,%%esp \n" | 114 | " xchgl %%ebx,%%esp \n" |
114 | " call __do_IRQ \n" | 115 | " call *%%edi \n" |
115 | " movl %%ebx,%%esp \n" | 116 | " movl %%ebx,%%esp \n" |
116 | : "=a" (arg1), "=d" (arg2), "=b" (ebx) | 117 | : "=a" (arg1), "=d" (arg2), "=c" (arg3), "=b" (ebx) |
117 | : "0" (irq), "1" (regs), "2" (isp) | 118 | : "0" (irq), "1" (desc), "2" (regs), "3" (isp), |
118 | : "memory", "cc", "ecx" | 119 | "D" (desc->handle_irq) |
120 | : "memory", "cc" | ||
119 | ); | 121 | ); |
120 | } else | 122 | } else |
121 | #endif | 123 | #endif |
122 | __do_IRQ(irq, regs); | 124 | desc->handle_irq(irq, desc, regs); |
123 | 125 | ||
124 | irq_exit(); | 126 | irq_exit(); |
125 | 127 | ||
@@ -253,7 +255,8 @@ int show_interrupts(struct seq_file *p, void *v) | |||
253 | for_each_online_cpu(j) | 255 | for_each_online_cpu(j) |
254 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); | 256 | seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); |
255 | #endif | 257 | #endif |
256 | seq_printf(p, " %14s", irq_desc[i].chip->typename); | 258 | seq_printf(p, " %8s", irq_desc[i].chip->name); |
259 | seq_printf(p, "-%s", handle_irq_name(irq_desc[i].handle_irq)); | ||
257 | seq_printf(p, " %s", action->name); | 260 | seq_printf(p, " %s", action->name); |
258 | 261 | ||
259 | for (action=action->next; action; action = action->next) | 262 | for (action=action->next; action; action = action->next) |
diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 4a8995c9c762..47f02af74be3 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c | |||
@@ -981,10 +981,6 @@ static void __init pcibios_fixup_irqs(void) | |||
981 | pci_name(bridge), 'A' + pin, irq); | 981 | pci_name(bridge), 'A' + pin, irq); |
982 | } | 982 | } |
983 | if (irq >= 0) { | 983 | if (irq >= 0) { |
984 | if (use_pci_vector() && | ||
985 | !platform_legacy_irq(irq)) | ||
986 | irq = IO_APIC_VECTOR(irq); | ||
987 | |||
988 | printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n", | 984 | printk(KERN_INFO "PCI->APIC IRQ transform: %s[%c] -> IRQ %d\n", |
989 | pci_name(dev), 'A' + pin, irq); | 985 | pci_name(dev), 'A' + pin, irq); |
990 | dev->irq = irq; | 986 | dev->irq = irq; |
@@ -1169,33 +1165,3 @@ static int pirq_enable_irq(struct pci_dev *dev) | |||
1169 | } | 1165 | } |
1170 | return 0; | 1166 | return 0; |
1171 | } | 1167 | } |
1172 | |||
1173 | int pci_vector_resources(int last, int nr_released) | ||
1174 | { | ||
1175 | int count = nr_released; | ||
1176 | |||
1177 | int next = last; | ||
1178 | int offset = (last % 8); | ||
1179 | |||
1180 | while (next < FIRST_SYSTEM_VECTOR) { | ||
1181 | next += 8; | ||
1182 | #ifdef CONFIG_X86_64 | ||
1183 | if (next == IA32_SYSCALL_VECTOR) | ||
1184 | continue; | ||
1185 | #else | ||
1186 | if (next == SYSCALL_VECTOR) | ||
1187 | continue; | ||
1188 | #endif | ||
1189 | count++; | ||
1190 | if (next >= FIRST_SYSTEM_VECTOR) { | ||
1191 | if (offset%8) { | ||
1192 | next = FIRST_DEVICE_VECTOR + offset; | ||
1193 | offset++; | ||
1194 | continue; | ||
1195 | } | ||
1196 | count--; | ||
1197 | } | ||
1198 | } | ||
1199 | |||
1200 | return count; | ||
1201 | } | ||