[PATCH] x86/apic: RFC decouple legacy irq handling in ioapic

From: Jacob Pan
Date: Wed Jul 15 2009 - 14:29:42 EST


This patch uses platform feature flags to separate i8259/PIC from ioapic.
A cleaner solution might be adding abstraction for device interrupt
controller and moving apic initialization earlier so that
platforms with legacy replace devices can boot without the constriant of
PIC, PIT, etc. Such change obviously introduces risk.

The intention of this patch is also to show what kind of changes are needed
for non-pc x86 platform such as Moorestown MID. perhpas we can take a phased
approach.

Signed-off-by: Jacob Pan <jacob.jun.pan@xxxxxxxxx>
---
arch/x86/kernel/apic/apic.c | 3 +++
arch/x86/kernel/apic/io_apic.c | 29 +++++++++++++++++++++++------
2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 8c7c042..c2b67d4 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -49,6 +49,7 @@
#include <asm/mtrr.h>
#include <asm/smp.h>
#include <asm/mce.h>
+#include <asm/platform_feature.h>

unsigned int num_processors;

@@ -1115,6 +1116,8 @@ void __init init_bsp_APIC(void)
value |= SPURIOUS_APIC_VECTOR;
apic_write(APIC_SPIV, value);

+ if (!platform_has(X86_PLATFORM_FEATURE_8259))
+ return;
/*
* Set up the virtual wire mode.
*/
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index bff8990..645c8eb 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -62,7 +62,7 @@
#include <asm/hw_irq.h>
#include <asm/uv/uv_hub.h>
#include <asm/uv/uv_irq.h>
-
+#include <asm/platform_feature.h>
#include <asm/apic.h>

#define __apicdebuginit(type) static type __init
@@ -1447,6 +1447,12 @@ int setup_ioapic_entry(int apic_id, int irq,
return 0;
}

+static inline int is_i8259_legacy_irq(int irq)
+{
+ return ((irq < NR_IRQS_LEGACY)
+ && platform_has(X86_PLATFORM_FEATURE_8259));
+}
+
static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq_desc *desc,
int trigger, int polarity)
{
@@ -1480,7 +1486,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
}

ioapic_register_intr(irq, desc, trigger);
- if (irq < NR_IRQS_LEGACY)
+ if (is_i8259_legacy_irq(irq))
disable_8259A_irq(irq);

ioapic_write_entry(apic_id, pin, entry);
@@ -1857,6 +1863,9 @@ __apicdebuginit(void) print_PIC(void)
unsigned int v;
unsigned long flags;

+ if (!platform_has(X86_PLATFORM_FEATURE_8259))
+ return;
+
if (apic_verbosity == APIC_QUIET)
return;

@@ -1920,6 +1929,8 @@ void __init enable_IO_APIC(void)
spin_unlock_irqrestore(&ioapic_lock, flags);
nr_ioapic_registers[apic] = reg_01.bits.entries+1;
}
+ if (!platform_has(X86_PLATFORM_FEATURE_8259))
+ return;
for(apic = 0; apic < nr_ioapics; apic++) {
int pin;
/* See if any of the pins is in ExtINT mode */
@@ -1974,6 +1985,8 @@ void disable_IO_APIC(void)
*/
clear_IO_APIC();

+ if (!platform_has(X86_PLATFORM_FEATURE_8259))
+ return;
/*
* If the i8259 is routed through an IOAPIC
* Put that IOAPIC in virtual wire mode
@@ -2205,7 +2218,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
struct irq_cfg *cfg;

spin_lock_irqsave(&ioapic_lock, flags);
- if (irq < NR_IRQS_LEGACY) {
+ if (is_i8259_legacy_irq(irq)) {
disable_8259A_irq(irq);
if (i8259A_irq_pending(irq))
was_pending = 1;
@@ -2716,7 +2729,7 @@ static inline void init_IO_APIC_traps(void)
* so default to an old-fashioned 8259
* interrupt if we can..
*/
- if (irq < NR_IRQS_LEGACY)
+ if (is_i8259_legacy_irq(irq))
make_8259A_irq(irq);
else
/* Strange. Oh, well.. */
@@ -3059,9 +3072,13 @@ void __init setup_IO_APIC(void)

/*
* calling enable_IO_APIC() is moved to setup_local_APIC for BP
+ * For platforms that do not have legacy IRQs, IOAPIC IRQ can be any
+ * number.
*/
-
- io_apic_irqs = ~PIC_IRQS;
+ if (!platform_has(X86_PLATFORM_FEATURE_8259))
+ io_apic_irqs = ~0;
+ else
+ io_apic_irqs = ~PIC_IRQS;

apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
/*
--
1.5.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/