diff options
| -rw-r--r-- | arch/i386/kernel/apic.c | 22 | ||||
| -rw-r--r-- | arch/i386/kernel/io_apic.c | 5 | ||||
| -rw-r--r-- | include/asm-i386/mach-default/mach_apic.h | 38 | ||||
| -rw-r--r-- | include/asm-i386/mach-numaq/mach_apic.h | 25 |
4 files changed, 52 insertions, 38 deletions
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 1e64226ec2db..98936e86c9b8 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -311,11 +311,9 @@ void __init setup_local_APIC (void) __error_in_apic_c(); /* - * Double-check wether this APIC is really registered. - * This is meaningless in clustered apic mode, so we skip it. + * Double-check whether this APIC is really registered. */ - if (!clustered_apic_mode && - !test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map)) + if (!apic_id_registered()) BUG(); /* @@ -323,21 +321,7 @@ void __init setup_local_APIC (void) * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel * document number 292116). So here it goes... */ - - if (!clustered_apic_mode) { - /* - * In clustered apic mode, the firmware does this for us - * Put the APIC into flat delivery mode. - * Must be "all ones" explicitly for 82489DX. - */ - apic_write_around(APIC_DFR, APIC_DFR_VALUE); - - /* - * Set up the logical destination ID. - */ - value = apic_read(APIC_LDR); - apic_write_around(APIC_LDR, calculate_ldr(value)); - } + init_apic_ldr(); /* * Set Task Priority to 'accept all'. We never change this diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index d9d97abb7c1d..25a412c5557e 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -262,7 +262,7 @@ static inline void balance_irq(int irq) irq_balance_t *entry = irq_balance + irq; unsigned long now = jiffies; - if (clustered_apic_mode) + if (no_balance_irq) return; if (unlikely(time_after(now, entry->timestamp + IRQ_BALANCE_INTERVAL))) { @@ -740,7 +740,6 @@ void __init setup_IO_APIC_irqs(void) if (irq_trigger(idx)) { entry.trigger = 1; entry.mask = 1; - entry.dest.logical.logical_dest = TARGET_CPUS; } irq = pin_2_irq(idx, apic, pin); @@ -748,7 +747,7 @@ void __init setup_IO_APIC_irqs(void) * skip adding the timer int on secondary nodes, which causes * a small but painful rift in the time-space continuum */ - if (clustered_apic_mode && (apic != 0) && (irq == 0)) + if (multi_timer_check(apic, irq)) continue; else add_pin_to_irq(irq, apic, pin); diff --git a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h index 9b1e59a7df5e..b527dcdc68f7 100644 --- a/include/asm-i386/mach-default/mach_apic.h +++ b/include/asm-i386/mach-default/mach_apic.h @@ -1,14 +1,6 @@ #ifndef __ASM_MACH_APIC_H #define __ASM_MACH_APIC_H -static inline unsigned long calculate_ldr(unsigned long old) -{ - unsigned long id; - - id = 1UL << smp_processor_id(); - return ((old & ~APIC_LDR_MASK) | SET_APIC_LOGICAL_ID(id)); -} - #define APIC_DFR_VALUE (APIC_DFR_FLAT) #ifdef CONFIG_SMP @@ -17,6 +9,8 @@ static inline unsigned long calculate_ldr(unsigned long old) #define TARGET_CPUS 0x01 #endif +#define no_balance_irq (0) + #define APIC_BROADCAST_ID 0x0F #define check_apicid_used(bitmap, apicid) (bitmap & (1 << apicid)) @@ -24,12 +18,40 @@ static inline void summit_check(char *oem, char *productid) { } +static inline int apic_id_registered(void) +{ + return (test_bit(GET_APIC_ID(apic_read(APIC_ID)), + &phys_cpu_present_map)); +} + +/* + * Set up the logical destination ID. + * + * Intel recommends to set DFR, LDR and TPR before enabling + * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel + * document number 292116). So here it goes... + */ +static inline void init_apic_ldr(void) +{ + unsigned long val; + + apic_write_around(APIC_DFR, APIC_DFR_VALUE); + val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; + val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); + apic_write_around(APIC_LDR, val); +} + static inline void clustered_apic_check(void) { printk("Enabling APIC mode: %s. Using %d I/O APICs\n", "Flat", nr_ioapics); } +static inline int multi_timer_check(int apic, int irq) +{ + return 0; +} + static inline int cpu_present_to_apicid(int mps_cpu) { return mps_cpu; diff --git a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h index 77c7317d26fd..82a4a7fae61d 100644 --- a/include/asm-i386/mach-numaq/mach_apic.h +++ b/include/asm-i386/mach-numaq/mach_apic.h @@ -1,18 +1,12 @@ #ifndef __ASM_MACH_APIC_H #define __ASM_MACH_APIC_H -static inline unsigned long calculate_ldr(unsigned long old) -{ - unsigned long id; - - id = 1UL << smp_processor_id(); - return ((old & ~APIC_LDR_MASK) | SET_APIC_LOGICAL_ID(id)); -} - #define APIC_DFR_VALUE (APIC_DFR_FLAT) #define TARGET_CPUS (0xf) +#define no_balance_irq (1) + #define APIC_BROADCAST_ID 0x0F #define check_apicid_used(bitmap, apicid) (bitmap & (1 << apicid)) @@ -20,12 +14,27 @@ static inline void summit_check(char *oem, char *productid) { } +static inline int apic_id_registered(void) +{ + return (1); +} + +static inline void init_apic_ldr(void) +{ + /* Already done in NUMA-Q firmware */ +} + static inline void clustered_apic_check(void) { printk("Enabling APIC mode: %s. Using %d I/O APICs\n", "NUMA-Q", nr_ioapics); } +static inline int multi_timer_check(int apic, int irq) +{ + return (apic != 0 && irq == 0); +} + static inline int cpu_present_to_apicid(int mps_cpu) { return ( ((mps_cpu/4)*16) + (1<<(mps_cpu%4)) ); |
