diff options
author | Ingo Molnar <mingo@elte.hu> | 2006-10-04 05:16:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-04 10:55:25 -0400 |
commit | f5b9ed7acdcfea4bf73a70dececa7483787503ed (patch) | |
tree | d2d1510d8a4dd8a5a00310dd07ab791c2ab0612f /arch | |
parent | f29bd1ba68c8c6a0f50bd678bbd5a26674018f7c (diff) |
[PATCH] genirq: convert the i386 architecture to irq-chips
This patch converts all the i386 PIC controllers (except VisWS and Voyager,
which I could not test - but which should still work as old-style IRQ layers)
to the new and simpler irq-chip interrupt handling layer.
[akpm@osdl.org: build fix]
[mingo@elte.hu: enable fasteoi handler for i386 level-triggered IO-APIC irqs]
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Roland Dreier <rolandd@cisco.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/i386/kernel/i8259.c | 45 | ||||
-rw-r--r-- | arch/i386/kernel/io_apic.c | 160 | ||||
-rw-r--r-- | arch/i386/kernel/irq.c | 19 |
3 files changed, 80 insertions, 144 deletions
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..b3b01894ca69 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c | |||
@@ -1219,8 +1219,7 @@ next: | |||
1219 | return vector; | 1219 | return vector; |
1220 | } | 1220 | } |
1221 | 1221 | ||
1222 | static struct hw_interrupt_type ioapic_level_type; | 1222 | static struct irq_chip ioapic_chip; |
1223 | static struct hw_interrupt_type ioapic_edge_type; | ||
1224 | 1223 | ||
1225 | #define IOAPIC_AUTO -1 | 1224 | #define IOAPIC_AUTO -1 |
1226 | #define IOAPIC_EDGE 0 | 1225 | #define IOAPIC_EDGE 0 |
@@ -1234,9 +1233,11 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger) | |||
1234 | 1233 | ||
1235 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || | 1234 | if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || |
1236 | trigger == IOAPIC_LEVEL) | 1235 | trigger == IOAPIC_LEVEL) |
1237 | irq_desc[idx].chip = &ioapic_level_type; | 1236 | set_irq_chip_and_handler(idx, &ioapic_chip, |
1237 | handle_fasteoi_irq); | ||
1238 | else | 1238 | else |
1239 | irq_desc[idx].chip = &ioapic_edge_type; | 1239 | set_irq_chip_and_handler(idx, &ioapic_chip, |
1240 | handle_edge_irq); | ||
1240 | set_intr_gate(vector, interrupt[idx]); | 1241 | set_intr_gate(vector, interrupt[idx]); |
1241 | } | 1242 | } |
1242 | 1243 | ||
@@ -1346,7 +1347,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 | 1347 | * The timer IRQ doesn't have to know that behind the |
1347 | * scene we have a 8259A-master in AEOI mode ... | 1348 | * scene we have a 8259A-master in AEOI mode ... |
1348 | */ | 1349 | */ |
1349 | irq_desc[0].chip = &ioapic_edge_type; | 1350 | irq_desc[0].chip = &ioapic_chip; |
1351 | set_irq_handler(0, handle_edge_irq); | ||
1350 | 1352 | ||
1351 | /* | 1353 | /* |
1352 | * Add it to the IO-APIC irq-routing table: | 1354 | * Add it to the IO-APIC irq-routing table: |
@@ -1918,6 +1920,8 @@ static int __init timer_irq_works(void) | |||
1918 | */ | 1920 | */ |
1919 | 1921 | ||
1920 | /* | 1922 | /* |
1923 | * Startup quirk: | ||
1924 | * | ||
1921 | * Starting up a edge-triggered IO-APIC interrupt is | 1925 | * Starting up a edge-triggered IO-APIC interrupt is |
1922 | * nasty - we need to make sure that we get the edge. | 1926 | * nasty - we need to make sure that we get the edge. |
1923 | * If it is already asserted for some reason, we need | 1927 | * If it is already asserted for some reason, we need |
@@ -1925,8 +1929,10 @@ static int __init timer_irq_works(void) | |||
1925 | * | 1929 | * |
1926 | * This is not complete - we should be able to fake | 1930 | * This is not complete - we should be able to fake |
1927 | * an edge even if it isn't on the 8259A... | 1931 | * an edge even if it isn't on the 8259A... |
1932 | * | ||
1933 | * (We do this for level-triggered IRQs too - it cannot hurt.) | ||
1928 | */ | 1934 | */ |
1929 | static unsigned int startup_edge_ioapic_irq(unsigned int irq) | 1935 | static unsigned int startup_ioapic_irq(unsigned int irq) |
1930 | { | 1936 | { |
1931 | int was_pending = 0; | 1937 | int was_pending = 0; |
1932 | unsigned long flags; | 1938 | unsigned long flags; |
@@ -1943,42 +1949,13 @@ static unsigned int startup_edge_ioapic_irq(unsigned int irq) | |||
1943 | return was_pending; | 1949 | return was_pending; |
1944 | } | 1950 | } |
1945 | 1951 | ||
1946 | /* | 1952 | 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 | { | 1953 | { |
1953 | move_irq(irq); | 1954 | move_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(); | 1955 | ack_APIC_irq(); |
1958 | } | 1956 | } |
1959 | 1957 | ||
1960 | /* | 1958 | 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 | { | 1959 | { |
1983 | unsigned long v; | 1960 | unsigned long v; |
1984 | int i; | 1961 | int i; |
@@ -2018,35 +1995,27 @@ static void end_level_ioapic_irq (unsigned int irq) | |||
2018 | } | 1995 | } |
2019 | } | 1996 | } |
2020 | 1997 | ||
2021 | #ifdef CONFIG_PCI_MSI | 1998 | static unsigned int startup_ioapic_vector(unsigned int vector) |
2022 | static unsigned int startup_edge_ioapic_vector(unsigned int vector) | ||
2023 | { | 1999 | { |
2024 | int irq = vector_to_irq(vector); | 2000 | int irq = vector_to_irq(vector); |
2025 | 2001 | ||
2026 | return startup_edge_ioapic_irq(irq); | 2002 | return startup_ioapic_irq(irq); |
2027 | } | 2003 | } |
2028 | 2004 | ||
2029 | static void ack_edge_ioapic_vector(unsigned int vector) | 2005 | static void ack_ioapic_vector(unsigned int vector) |
2030 | { | 2006 | { |
2031 | int irq = vector_to_irq(vector); | 2007 | int irq = vector_to_irq(vector); |
2032 | 2008 | ||
2033 | move_native_irq(vector); | 2009 | move_native_irq(vector); |
2034 | ack_edge_ioapic_irq(irq); | 2010 | ack_ioapic_irq(irq); |
2035 | } | 2011 | } |
2036 | 2012 | ||
2037 | static unsigned int startup_level_ioapic_vector (unsigned int vector) | 2013 | static void ack_ioapic_quirk_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 | { | 2014 | { |
2046 | int irq = vector_to_irq(vector); | 2015 | int irq = vector_to_irq(vector); |
2047 | 2016 | ||
2048 | move_native_irq(vector); | 2017 | move_native_irq(vector); |
2049 | end_level_ioapic_irq(irq); | 2018 | ack_ioapic_quirk_irq(irq); |
2050 | } | 2019 | } |
2051 | 2020 | ||
2052 | static void mask_IO_APIC_vector (unsigned int vector) | 2021 | static void mask_IO_APIC_vector (unsigned int vector) |
@@ -2063,7 +2032,12 @@ static void unmask_IO_APIC_vector (unsigned int vector) | |||
2063 | unmask_IO_APIC_irq(irq); | 2032 | unmask_IO_APIC_irq(irq); |
2064 | } | 2033 | } |
2065 | 2034 | ||
2066 | #ifdef CONFIG_SMP | 2035 | /* |
2036 | * Oh just glorious. If CONFIG_PCI_MSI we've done | ||
2037 | * #define set_ioapic_affinity set_ioapic_affinity_vector | ||
2038 | */ | ||
2039 | #if defined (CONFIG_SMP) && defined(CONFIG_X86_IO_APIC) && \ | ||
2040 | defined(CONFIG_PCI_MSI) | ||
2067 | static void set_ioapic_affinity_vector (unsigned int vector, | 2041 | static void set_ioapic_affinity_vector (unsigned int vector, |
2068 | cpumask_t cpu_mask) | 2042 | cpumask_t cpu_mask) |
2069 | { | 2043 | { |
@@ -2073,50 +2047,29 @@ static void set_ioapic_affinity_vector (unsigned int vector, | |||
2073 | set_ioapic_affinity_irq(irq, cpu_mask); | 2047 | set_ioapic_affinity_irq(irq, cpu_mask); |
2074 | } | 2048 | } |
2075 | #endif | 2049 | #endif |
2076 | #endif | ||
2077 | 2050 | ||
2078 | static int ioapic_retrigger(unsigned int irq) | 2051 | static int ioapic_retrigger_vector(unsigned int vector) |
2079 | { | 2052 | { |
2053 | int irq = vector_to_irq(vector); | ||
2054 | |||
2080 | send_IPI_self(IO_APIC_VECTOR(irq)); | 2055 | send_IPI_self(IO_APIC_VECTOR(irq)); |
2081 | 2056 | ||
2082 | return 1; | 2057 | return 1; |
2083 | } | 2058 | } |
2084 | 2059 | ||
2085 | /* | 2060 | static struct irq_chip ioapic_chip __read_mostly = { |
2086 | * Level and edge triggered IO-APIC interrupts need different handling, | 2061 | .name = "IO-APIC", |
2087 | * so we use two separate IRQ descriptors. Edge triggered IRQs can be | 2062 | .startup = startup_ioapic_vector, |
2088 | * handled with the level-triggered descriptor, but that one has slightly | 2063 | .mask = mask_IO_APIC_vector, |
2089 | * more overhead. Level-triggered interrupts cannot be handled with the | 2064 | .unmask = unmask_IO_APIC_vector, |
2090 | * edge-triggered handler, without risking IRQ storms and other ugly | 2065 | .ack = ack_ioapic_vector, |
2091 | * races. | 2066 | .eoi = ack_ioapic_quirk_vector, |
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 | 2067 | #ifdef CONFIG_SMP |
2102 | .set_affinity = set_ioapic_affinity, | 2068 | .set_affinity = set_ioapic_affinity, |
2103 | #endif | 2069 | #endif |
2104 | .retrigger = ioapic_retrigger, | 2070 | .retrigger = ioapic_retrigger_vector, |
2105 | }; | 2071 | }; |
2106 | 2072 | ||
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 | 2073 | ||
2121 | static inline void init_IO_APIC_traps(void) | 2074 | static inline void init_IO_APIC_traps(void) |
2122 | { | 2075 | { |
@@ -2150,20 +2103,21 @@ static inline void init_IO_APIC_traps(void) | |||
2150 | make_8259A_irq(irq); | 2103 | make_8259A_irq(irq); |
2151 | else | 2104 | else |
2152 | /* Strange. Oh, well.. */ | 2105 | /* Strange. Oh, well.. */ |
2153 | irq_desc[irq].chip = &no_irq_type; | 2106 | irq_desc[irq].chip = &no_irq_chip; |
2154 | } | 2107 | } |
2155 | } | 2108 | } |
2156 | } | 2109 | } |
2157 | 2110 | ||
2158 | static void enable_lapic_irq (unsigned int irq) | 2111 | /* |
2159 | { | 2112 | * The local APIC irq-chip implementation: |
2160 | unsigned long v; | 2113 | */ |
2161 | 2114 | ||
2162 | v = apic_read(APIC_LVT0); | 2115 | static void ack_apic(unsigned int irq) |
2163 | apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED); | 2116 | { |
2117 | ack_APIC_irq(); | ||
2164 | } | 2118 | } |
2165 | 2119 | ||
2166 | static void disable_lapic_irq (unsigned int irq) | 2120 | static void mask_lapic_irq (unsigned int irq) |
2167 | { | 2121 | { |
2168 | unsigned long v; | 2122 | unsigned long v; |
2169 | 2123 | ||
@@ -2171,21 +2125,19 @@ static void disable_lapic_irq (unsigned int irq) | |||
2171 | apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); | 2125 | apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED); |
2172 | } | 2126 | } |
2173 | 2127 | ||
2174 | static void ack_lapic_irq (unsigned int irq) | 2128 | static void unmask_lapic_irq (unsigned int irq) |
2175 | { | 2129 | { |
2176 | ack_APIC_irq(); | 2130 | unsigned long v; |
2177 | } | ||
2178 | 2131 | ||
2179 | static void end_lapic_irq (unsigned int i) { /* nothing */ } | 2132 | v = apic_read(APIC_LVT0); |
2133 | apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED); | ||
2134 | } | ||
2180 | 2135 | ||
2181 | static struct hw_interrupt_type lapic_irq_type __read_mostly = { | 2136 | static struct irq_chip lapic_chip __read_mostly = { |
2182 | .typename = "local-APIC-edge", | 2137 | .name = "local-APIC-edge", |
2183 | .startup = NULL, /* startup_irq() not used for IRQ0 */ | 2138 | .mask = mask_lapic_irq, |
2184 | .shutdown = NULL, /* shutdown_irq() not used for IRQ0 */ | 2139 | .unmask = unmask_lapic_irq, |
2185 | .enable = enable_lapic_irq, | 2140 | .eoi = ack_apic, |
2186 | .disable = disable_lapic_irq, | ||
2187 | .ack = ack_lapic_irq, | ||
2188 | .end = end_lapic_irq | ||
2189 | }; | 2141 | }; |
2190 | 2142 | ||
2191 | static void setup_nmi (void) | 2143 | static void setup_nmi (void) |
@@ -2356,7 +2308,7 @@ static inline void check_timer(void) | |||
2356 | printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); | 2308 | printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); |
2357 | 2309 | ||
2358 | disable_8259A_irq(0); | 2310 | disable_8259A_irq(0); |
2359 | irq_desc[0].chip = &lapic_irq_type; | 2311 | set_irq_chip_and_handler(0, &lapic_chip, handle_fasteoi_irq); |
2360 | apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ | 2312 | apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ |
2361 | enable_8259A_irq(0); | 2313 | enable_8259A_irq(0); |
2362 | 2314 | ||
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) |