diff options
author | Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> | 2007-11-07 07:38:30 +0100 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2007-11-09 22:01:09 +0100 |
commit | c9d059def234d7cd60809a6a122102ff96d2d0ca (patch) | |
tree | 858f20940d522481ee694a7bf81d5b87bbe46a1d | |
parent | [IA64] XPC heartbeat timer function must run on CPU 0 (diff) | |
download | linux-c9d059def234d7cd60809a6a122102ff96d2d0ca.tar.xz linux-c9d059def234d7cd60809a6a122102ff96d2d0ca.zip |
[IA64] Fix IOSAPIC delivery mode setting
Fix the problem that redirect hit bit in I/O SAPIC RTE is set even
when it must be disabled (e.g. nointroute boot option is set, CPU
hotplug is enabled or percpu vector is enabled).
Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r-- | arch/ia64/kernel/iosapic.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index cfe4654838f4..274a59383043 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -748,6 +748,15 @@ skip_numa_setup: #endif } +static inline unsigned char choose_dmode(void) +{ +#ifdef CONFIG_SMP + if (smp_int_redirect & SMP_IRQ_REDIRECTION) + return IOSAPIC_LOWEST_PRIORITY; +#endif + return IOSAPIC_FIXED; +} + /* * ACPI can describe IOSAPIC interrupts via static tables and namespace * methods. This provides an interface to register those interrupts and @@ -762,6 +771,7 @@ iosapic_register_intr (unsigned int gsi, unsigned long flags; struct iosapic_rte_info *rte; u32 low32; + unsigned char dmode; /* * If this GSI has already been registered (i.e., it's a @@ -791,8 +801,8 @@ iosapic_register_intr (unsigned int gsi, spin_lock(&irq_desc[irq].lock); dest = get_target_cpu(gsi, irq); - err = register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, - polarity, trigger); + dmode = choose_dmode(); + err = register_intr(gsi, irq, dmode, polarity, trigger); if (err < 0) { spin_unlock(&irq_desc[irq].lock); irq = err; @@ -961,10 +971,12 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, { int vector, irq; unsigned int dest = cpu_physical_id(smp_processor_id()); + unsigned char dmode; irq = vector = isa_irq_to_vector(isa_irq); BUG_ON(bind_irq_vector(irq, vector, CPU_MASK_ALL)); - register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, polarity, trigger); + dmode = choose_dmode(); + register_intr(gsi, irq, dmode, polarity, trigger); DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n", isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level", |