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>
This commit is contained in:
Родитель
1baea6e2fe
Коммит
c88ac1df48
|
@ -2027,7 +2027,7 @@ static inline void init_IO_APIC_traps(void)
|
||||||
* The local APIC irq-chip implementation:
|
* The local APIC irq-chip implementation:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void ack_apic(unsigned int irq)
|
static void ack_lapic_irq(unsigned int irq)
|
||||||
{
|
{
|
||||||
ack_APIC_irq();
|
ack_APIC_irq();
|
||||||
}
|
}
|
||||||
|
@ -2052,9 +2052,17 @@ static struct irq_chip lapic_chip __read_mostly = {
|
||||||
.name = "local-APIC",
|
.name = "local-APIC",
|
||||||
.mask = mask_lapic_irq,
|
.mask = mask_lapic_irq,
|
||||||
.unmask = unmask_lapic_irq,
|
.unmask = unmask_lapic_irq,
|
||||||
.ack = ack_apic,
|
.ack = ack_lapic_irq,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void lapic_register_intr(int irq, int vector)
|
||||||
|
{
|
||||||
|
irq_desc[irq].status &= ~IRQ_LEVEL;
|
||||||
|
set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
|
||||||
|
"edge");
|
||||||
|
set_intr_gate(vector, interrupt[irq]);
|
||||||
|
}
|
||||||
|
|
||||||
static void __init setup_nmi(void)
|
static void __init setup_nmi(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -2257,8 +2265,7 @@ static inline void __init check_timer(void)
|
||||||
|
|
||||||
printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
|
printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
|
||||||
|
|
||||||
set_irq_chip_and_handler_name(0, &lapic_chip, handle_edge_irq,
|
lapic_register_intr(0, vector);
|
||||||
"edge");
|
|
||||||
apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */
|
apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */
|
||||||
enable_8259A_irq(0);
|
enable_8259A_irq(0);
|
||||||
|
|
||||||
|
|
|
@ -1561,7 +1561,7 @@ static inline void init_IO_APIC_traps(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enable_lapic_irq (unsigned int irq)
|
static void unmask_lapic_irq(unsigned int irq)
|
||||||
{
|
{
|
||||||
unsigned long v;
|
unsigned long v;
|
||||||
|
|
||||||
|
@ -1569,7 +1569,7 @@ static void enable_lapic_irq (unsigned int irq)
|
||||||
apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
|
apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disable_lapic_irq (unsigned int irq)
|
static void mask_lapic_irq(unsigned int irq)
|
||||||
{
|
{
|
||||||
unsigned long v;
|
unsigned long v;
|
||||||
|
|
||||||
|
@ -1582,19 +1582,20 @@ static void ack_lapic_irq (unsigned int irq)
|
||||||
ack_APIC_irq();
|
ack_APIC_irq();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_lapic_irq (unsigned int i) { /* nothing */ }
|
static struct irq_chip lapic_chip __read_mostly = {
|
||||||
|
.name = "local-APIC",
|
||||||
static struct hw_interrupt_type lapic_irq_type __read_mostly = {
|
.mask = mask_lapic_irq,
|
||||||
.name = "local-APIC",
|
.unmask = unmask_lapic_irq,
|
||||||
.typename = "local-APIC-edge",
|
.ack = ack_lapic_irq,
|
||||||
.startup = NULL, /* startup_irq() not used for IRQ0 */
|
|
||||||
.shutdown = NULL, /* shutdown_irq() not used for IRQ0 */
|
|
||||||
.enable = enable_lapic_irq,
|
|
||||||
.disable = disable_lapic_irq,
|
|
||||||
.ack = ack_lapic_irq,
|
|
||||||
.end = end_lapic_irq,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void lapic_register_intr(int irq)
|
||||||
|
{
|
||||||
|
irq_desc[irq].status &= ~IRQ_LEVEL;
|
||||||
|
set_irq_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
|
||||||
|
"edge");
|
||||||
|
}
|
||||||
|
|
||||||
static void __init setup_nmi(void)
|
static void __init setup_nmi(void)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -1784,7 +1785,7 @@ static inline void __init check_timer(void)
|
||||||
|
|
||||||
apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
|
apic_printk(APIC_VERBOSE, KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
|
||||||
|
|
||||||
irq_desc[0].chip = &lapic_irq_type;
|
lapic_register_intr(0);
|
||||||
apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */
|
apic_write(APIC_LVT0, APIC_DM_FIXED | cfg->vector); /* Fixed mode */
|
||||||
enable_8259A_irq(0);
|
enable_8259A_irq(0);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче