aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2008-07-11 14:35:17 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-11 14:54:02 -0400
commitc88ac1df4885ce0d762cfeff0e7d5b83725c1e5c (patch)
tree4e26beb237403efcc9af3353a6bba58c1110be19 /arch/x86
parent1baea6e2fea6f235b21f32a322cb6cb43ffdb704 (diff)
x86: L-APIC: Always fully configure IRQ0
Unlike the 32-bit one, the 64-bit variation of the LVT0 setup code for the "8259A Virtual Wire" through the local APIC timer configuration does not fully configure the relevant irq_chip structure. Instead it relies on the preceding I/O APIC code to have set it up, which does not happen if the I/O APIC variants have not been tried. The patch includes corresponding changes to the 32-bit variation too which make them both the same, barring a small syntactic difference involving sequence of functions in the source. That should work as an aid with the upcoming merge. Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org> Cc: "Rafael J. Wysocki" <rjw@sisk.pl> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Cc: Andreas Herrmann <andreas.herrmann3@amd.com> Cc: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/io_apic_32.c15
-rw-r--r--arch/x86/kernel/io_apic_64.c29
2 files changed, 26 insertions, 18 deletions
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
index 50e1131a6ec6..74d49e04de58 100644
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -2027,7 +2027,7 @@ static inline void init_IO_APIC_traps(void)
2027 * The local APIC irq-chip implementation: 2027 * The local APIC irq-chip implementation:
2028 */ 2028 */
2029 2029
2030static void ack_apic(unsigned int irq) 2030static void ack_lapic_irq(unsigned int irq)
2031{ 2031{
2032 ack_APIC_irq(); 2032 ack_APIC_irq();
2033} 2033}
@@ -2052,9 +2052,17 @@ static struct irq_chip lapic_chip __read_mostly = {
2052 .name = "local-APIC", 2052 .name = "local-APIC",
2053 .mask = mask_lapic_irq, 2053 .mask = mask_lapic_irq,
2054 .unmask = unmask_lapic_irq, 2054 .unmask = unmask_lapic_irq,
2055 .ack = ack_apic, 2055 .ack = ack_lapic_irq,
2056}; 2056};
2057 2057
2058static void lapic_register_intr(int irq, int vector)
2059{
2060 irq_desc[irq].status &= ~IRQ_LEVEL;
2061 set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
2062 "edge");
2063 set_intr_gate(vector, interrupt[irq]);
2064}
2065
2058static void __init setup_nmi(void) 2066static void __init setup_nmi(void)
2059{ 2067{
2060 /* 2068 /*
@@ -2257,8 +2265,7 @@ static inline void __init check_timer(void)
2257 2265
2258 printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); 2266 printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
2259 2267
2260 set_irq_chip_and_handler_name(0, &lapic_chip, handle_edge_irq, 2268 lapic_register_intr(0, vector);
2261 "edge");
2262 apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ 2269 apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */
2263 enable_8259A_irq(0); 2270 enable_8259A_irq(0);
2264 2271
diff --git a/arch/x86/kernel/io_apic_64.c b/arch/x86/kernel/io_apic_64.c
index 848411753c7c..07ebcd305fb7 100644
--- a/arch/x86/kernel/io_apic_64.c
+++ b/arch/x86/kernel/io_apic_64.c
@@ -1561,7 +1561,7 @@ static inline void init_IO_APIC_traps(void)
1561 } 1561 }
1562} 1562}
1563 1563
1564static void enable_lapic_irq (unsigned int irq) 1564static void unmask_lapic_irq(unsigned int irq)
1565{ 1565{
1566 unsigned long v; 1566 unsigned long v;
1567 1567
@@ -1569,7 +1569,7 @@ static void enable_lapic_irq (unsigned int irq)
1569 apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED); 1569 apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
1570} 1570}
1571 1571
1572static void disable_lapic_irq (unsigned int irq) 1572static void mask_lapic_irq(unsigned int irq)
1573{ 1573{
1574 unsigned long v; 1574 unsigned long v;
1575 1575
@@ -1582,19 +1582,20 @@ static void ack_lapic_irq (unsigned int irq)
1582 ack_APIC_irq(); 1582 ack_APIC_irq();
1583} 1583}
1584 1584
1585static void end_lapic_irq (unsigned int i) { /* nothing */ } 1585static struct irq_chip lapic_chip __read_mostly = {
1586 1586 .name = "local-APIC",
1587static struct hw_interrupt_type lapic_irq_type __read_mostly = { 1587 .mask = mask_lapic_irq,
1588 .name = "local-APIC", 1588 .unmask = unmask_lapic_irq,
1589 .typename = "local-APIC-edge", 1589 .ack = ack_lapic_irq,
1590 .startup = NULL, /* startup_irq() not used for IRQ0 */
1591 .shutdown = NULL, /* shutdown_irq() not used for IRQ0 */
1592 .enable = enable_lapic_irq,
1593 .disable = disable_lapic_irq,
1594 .ack = ack_lapic_irq,
1595 .end = end_lapic_irq,
1596}; 1590};
1597 1591
1592static void lapic_register_intr(int irq)
1593{
1594 irq_desc[irq].status &= ~IRQ_LEVEL;
1595 set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
1596 "edge");
1597}
1598
1598static void __init setup_nmi(void) 1599static void __init setup_nmi(void)
1599{ 1600{
1600 /* 1601 /*
@@ -1784,7 +1785,7 @@ static inline void __init check_timer(void)
1784 1785
1785 apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); 1786 apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
1786 1787
1787 irq_desc[0].chip = &lapic_irq_type; 1788 lapic_register_intr(0);
1788 apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */ 1789 apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */
1789 enable_8259A_irq(0); 1790 enable_8259A_irq(0);
1790 1791