aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/apic.h2
-rw-r--r--arch/x86/kernel/acpi/boot.c7
-rw-r--r--arch/x86/kernel/apic/io_apic.c14
-rw-r--r--arch/x86/kernel/crash.c4
4 files changed, 21 insertions, 6 deletions
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index f8119b582c3c..1d2091a226bc 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -715,4 +715,6 @@ static inline void exiting_ack_irq(void)
715 ack_APIC_irq(); 715 ack_APIC_irq();
716} 716}
717 717
718extern void ioapic_zap_locks(void);
719
718#endif /* _ASM_X86_APIC_H */ 720#endif /* _ASM_X86_APIC_H */
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 2627a81253ee..81aa73b8ecf5 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -199,7 +199,7 @@ static void acpi_register_lapic(int id, u8 enabled)
199{ 199{
200 unsigned int ver = 0; 200 unsigned int ver = 0;
201 201
202 if (id >= (MAX_LOCAL_APIC-1)) { 202 if (id >= MAX_LOCAL_APIC) {
203 printk(KERN_INFO PREFIX "skipped apicid that is too big\n"); 203 printk(KERN_INFO PREFIX "skipped apicid that is too big\n");
204 return; 204 return;
205 } 205 }
@@ -1120,6 +1120,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
1120 int ioapic; 1120 int ioapic;
1121 int ioapic_pin; 1121 int ioapic_pin;
1122 struct io_apic_irq_attr irq_attr; 1122 struct io_apic_irq_attr irq_attr;
1123 int ret;
1123 1124
1124 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) 1125 if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC)
1125 return gsi; 1126 return gsi;
@@ -1149,7 +1150,9 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
1149 set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin, 1150 set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
1150 trigger == ACPI_EDGE_SENSITIVE ? 0 : 1, 1151 trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
1151 polarity == ACPI_ACTIVE_HIGH ? 0 : 1); 1152 polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
1152 io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr); 1153 ret = io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
1154 if (ret < 0)
1155 gsi = INT_MIN;
1153 1156
1154 return gsi; 1157 return gsi;
1155} 1158}
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 9ed796ccc32c..e63a5bd2a78f 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1534,6 +1534,11 @@ void intel_ir_io_apic_print_entries(unsigned int apic,
1534 } 1534 }
1535} 1535}
1536 1536
1537void ioapic_zap_locks(void)
1538{
1539 raw_spin_lock_init(&ioapic_lock);
1540}
1541
1537__apicdebuginit(void) print_IO_APIC(int ioapic_idx) 1542__apicdebuginit(void) print_IO_APIC(int ioapic_idx)
1538{ 1543{
1539 union IO_APIC_reg_00 reg_00; 1544 union IO_APIC_reg_00 reg_00;
@@ -3375,12 +3380,15 @@ int io_apic_setup_irq_pin_once(unsigned int irq, int node,
3375{ 3380{
3376 unsigned int ioapic_idx = attr->ioapic, pin = attr->ioapic_pin; 3381 unsigned int ioapic_idx = attr->ioapic, pin = attr->ioapic_pin;
3377 int ret; 3382 int ret;
3383 struct IO_APIC_route_entry orig_entry;
3378 3384
3379 /* Avoid redundant programming */ 3385 /* Avoid redundant programming */
3380 if (test_bit(pin, ioapics[ioapic_idx].pin_programmed)) { 3386 if (test_bit(pin, ioapics[ioapic_idx].pin_programmed)) {
3381 pr_debug("Pin %d-%d already programmed\n", 3387 pr_debug("Pin %d-%d already programmed\n", mpc_ioapic_id(ioapic_idx), pin);
3382 mpc_ioapic_id(ioapic_idx), pin); 3388 orig_entry = ioapic_read_entry(attr->ioapic, pin);
3383 return 0; 3389 if (attr->trigger == orig_entry.trigger && attr->polarity == orig_entry.polarity)
3390 return 0;
3391 return -EBUSY;
3384 } 3392 }
3385 ret = io_apic_setup_irq_pin(irq, node, attr); 3393 ret = io_apic_setup_irq_pin(irq, node, attr);
3386 if (!ret) 3394 if (!ret)
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 74467feb4dc5..e0e0841eef45 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -128,7 +128,9 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
128 cpu_emergency_svm_disable(); 128 cpu_emergency_svm_disable();
129 129
130 lapic_shutdown(); 130 lapic_shutdown();
131#if defined(CONFIG_X86_IO_APIC) 131#ifdef CONFIG_X86_IO_APIC
132 /* Prevent crash_kexec() from deadlocking on ioapic_lock. */
133 ioapic_zap_locks();
132 disable_IO_APIC(); 134 disable_IO_APIC();
133#endif 135#endif
134#ifdef CONFIG_HPET_TIMER 136#ifdef CONFIG_HPET_TIMER