|
@@ -76,6 +76,19 @@ int acpi_fix_pin2_polarity __initdata;
|
|
|
static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
|
|
|
#endif
|
|
|
|
|
|
+/*
|
|
|
+ * Locks related to IOAPIC hotplug
|
|
|
+ * Hotplug side:
|
|
|
+ * ->device_hotplug_lock
|
|
|
+ * ->acpi_ioapic_lock
|
|
|
+ * ->ioapic_lock
|
|
|
+ * Interrupt mapping side:
|
|
|
+ * ->acpi_ioapic_lock
|
|
|
+ * ->ioapic_mutex
|
|
|
+ * ->ioapic_lock
|
|
|
+ */
|
|
|
+static DEFINE_MUTEX(acpi_ioapic_lock);
|
|
|
+
|
|
|
/* --------------------------------------------------------------------------
|
|
|
Boot-time Configuration
|
|
|
-------------------------------------------------------------------------- */
|
|
@@ -609,8 +622,10 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp)
|
|
|
if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) {
|
|
|
*irqp = gsi;
|
|
|
} else {
|
|
|
+ mutex_lock(&acpi_ioapic_lock);
|
|
|
irq = mp_map_gsi_to_irq(gsi,
|
|
|
IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK);
|
|
|
+ mutex_unlock(&acpi_ioapic_lock);
|
|
|
if (irq < 0)
|
|
|
return -1;
|
|
|
*irqp = irq;
|
|
@@ -650,7 +665,9 @@ static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
|
|
|
int irq = gsi;
|
|
|
|
|
|
#ifdef CONFIG_X86_IO_APIC
|
|
|
+ mutex_lock(&acpi_ioapic_lock);
|
|
|
irq = mp_register_gsi(dev, gsi, trigger, polarity);
|
|
|
+ mutex_unlock(&acpi_ioapic_lock);
|
|
|
#endif
|
|
|
|
|
|
return irq;
|
|
@@ -659,7 +676,9 @@ static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
|
|
|
static void acpi_unregister_gsi_ioapic(u32 gsi)
|
|
|
{
|
|
|
#ifdef CONFIG_X86_IO_APIC
|
|
|
+ mutex_lock(&acpi_ioapic_lock);
|
|
|
mp_unregister_gsi(gsi);
|
|
|
+ mutex_unlock(&acpi_ioapic_lock);
|
|
|
#endif
|
|
|
}
|
|
|
|
|
@@ -1187,7 +1206,9 @@ static void __init acpi_process_madt(void)
|
|
|
/*
|
|
|
* Parse MADT IO-APIC entries
|
|
|
*/
|
|
|
+ mutex_lock(&acpi_ioapic_lock);
|
|
|
error = acpi_parse_madt_ioapic_entries();
|
|
|
+ mutex_unlock(&acpi_ioapic_lock);
|
|
|
if (!error) {
|
|
|
acpi_set_irq_model_ioapic();
|
|
|
|