Release IOAPIC pin associated with PCI device when the PCI device is disabled. Signed-off-by: Jiang Liu <jiang.liu@xxxxxxxxxxxxxxx> --- arch/x86/kernel/acpi/boot.c | 28 ++++++++++++++++++++++++++++ drivers/acpi/pci_irq.c | 3 ++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 0592c38d9952..c8e8fe67bbc8 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -313,9 +313,11 @@ static void mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi); static int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity); +static void mp_unregister_gsi(u32 gsi); static struct irq_domain_ops acpi_irqdomain_ops = { .map = mp_irqdomain_map, + .unmap = mp_irqdomain_unmap, }; static struct irq_domain *acpi_create_irqdomain(int idx, void *arg) @@ -541,8 +543,16 @@ static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi, return irq; } +static void acpi_unregister_gsi_ioapic(u32 gsi) +{ +#ifdef CONFIG_X86_IO_APIC + mp_unregister_gsi(gsi); +#endif +} + int (*__acpi_register_gsi)(struct device *dev, u32 gsi, int trigger, int polarity) = acpi_register_gsi_pic; +void (*__acpi_unregister_gsi)(u32 gsi) = NULL; #ifdef CONFIG_ACPI_SLEEP int (*acpi_suspend_lowlevel)(void) = x86_acpi_suspend_lowlevel; @@ -562,6 +572,8 @@ EXPORT_SYMBOL_GPL(acpi_register_gsi); void acpi_unregister_gsi(u32 gsi) { + if (__acpi_unregister_gsi) + (*__acpi_unregister_gsi)(gsi); } EXPORT_SYMBOL_GPL(acpi_unregister_gsi); @@ -569,6 +581,7 @@ static void __init acpi_set_irq_model_ioapic(void) { acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; __acpi_register_gsi = acpi_register_gsi_ioapic; + __acpi_unregister_gsi = acpi_unregister_gsi_ioapic; acpi_ioapic = 1; } @@ -1050,6 +1063,21 @@ static int mp_register_gsi(struct device *dev, u32 gsi, int trigger, return irq; } +static void mp_unregister_gsi(u32 gsi) +{ + int irq; + + if (acpi_irq_model != ACPI_IRQ_MODEL_IOAPIC) + return; + + if (acpi_gbl_FADT.sci_interrupt == gsi) + return; + + irq = mp_map_gsi_to_irq(gsi, 0); + if (irq > 0) + mp_unmap_irq(irq); +} + /* * Parse IOAPIC related entries in MADT * returns 0 on success, < 0 on error diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 9c62340c2360..6ba463ceccc6 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -498,5 +498,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev) */ dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); - acpi_unregister_gsi(gsi); + if (gsi >= 0 && dev->irq > 0) + acpi_unregister_gsi(gsi); } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html