diff options
author | Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> | 2007-11-07 01:38:30 -0500 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2007-11-09 16:01:09 -0500 |
commit | c9d059def234d7cd60809a6a122102ff96d2d0ca (patch) | |
tree | 858f20940d522481ee694a7bf81d5b87bbe46a1d | |
parent | 4c013f5c7ea39cd62e02c80408560751b4e8c0de (diff) |
[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: | |||
748 | #endif | 748 | #endif |
749 | } | 749 | } |
750 | 750 | ||
751 | static inline unsigned char choose_dmode(void) | ||
752 | { | ||
753 | #ifdef CONFIG_SMP | ||
754 | if (smp_int_redirect & SMP_IRQ_REDIRECTION) | ||
755 | return IOSAPIC_LOWEST_PRIORITY; | ||
756 | #endif | ||
757 | return IOSAPIC_FIXED; | ||
758 | } | ||
759 | |||
751 | /* | 760 | /* |
752 | * ACPI can describe IOSAPIC interrupts via static tables and namespace | 761 | * ACPI can describe IOSAPIC interrupts via static tables and namespace |
753 | * methods. This provides an interface to register those interrupts and | 762 | * methods. This provides an interface to register those interrupts and |
@@ -762,6 +771,7 @@ iosapic_register_intr (unsigned int gsi, | |||
762 | unsigned long flags; | 771 | unsigned long flags; |
763 | struct iosapic_rte_info *rte; | 772 | struct iosapic_rte_info *rte; |
764 | u32 low32; | 773 | u32 low32; |
774 | unsigned char dmode; | ||
765 | 775 | ||
766 | /* | 776 | /* |
767 | * If this GSI has already been registered (i.e., it's a | 777 | * If this GSI has already been registered (i.e., it's a |
@@ -791,8 +801,8 @@ iosapic_register_intr (unsigned int gsi, | |||
791 | 801 | ||
792 | spin_lock(&irq_desc[irq].lock); | 802 | spin_lock(&irq_desc[irq].lock); |
793 | dest = get_target_cpu(gsi, irq); | 803 | dest = get_target_cpu(gsi, irq); |
794 | err = register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, | 804 | dmode = choose_dmode(); |
795 | polarity, trigger); | 805 | err = register_intr(gsi, irq, dmode, polarity, trigger); |
796 | if (err < 0) { | 806 | if (err < 0) { |
797 | spin_unlock(&irq_desc[irq].lock); | 807 | spin_unlock(&irq_desc[irq].lock); |
798 | irq = err; | 808 | irq = err; |
@@ -961,10 +971,12 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, | |||
961 | { | 971 | { |
962 | int vector, irq; | 972 | int vector, irq; |
963 | unsigned int dest = cpu_physical_id(smp_processor_id()); | 973 | unsigned int dest = cpu_physical_id(smp_processor_id()); |
974 | unsigned char dmode; | ||
964 | 975 | ||
965 | irq = vector = isa_irq_to_vector(isa_irq); | 976 | irq = vector = isa_irq_to_vector(isa_irq); |
966 | BUG_ON(bind_irq_vector(irq, vector, CPU_MASK_ALL)); | 977 | BUG_ON(bind_irq_vector(irq, vector, CPU_MASK_ALL)); |
967 | register_intr(gsi, irq, IOSAPIC_LOWEST_PRIORITY, polarity, trigger); | 978 | dmode = choose_dmode(); |
979 | register_intr(gsi, irq, dmode, polarity, trigger); | ||
968 | 980 | ||
969 | DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n", | 981 | DBG("ISA: IRQ %u -> GSI %u (%s,%s) -> CPU %d (0x%04x) vector %d\n", |
970 | isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level", | 982 | isa_irq, gsi, trigger == IOSAPIC_EDGE ? "edge" : "level", |