diff options
author | Jiang Liu <jiang.liu@linux.intel.com> | 2014-06-10 08:16:27 +0200 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2014-06-21 23:05:44 +0200 |
commit | 6a38fa0e3c94dfd1394a71a2d47c9c4d47367374 (patch) | |
tree | 467a9e2bab59c23c4c0659d3d950720ce4b7c729 /arch/x86/kernel/acpi | |
parent | x86, irq: Introduce helper functions to release IOAPIC pin (diff) | |
download | linux-6a38fa0e3c94dfd1394a71a2d47c9c4d47367374.tar.xz linux-6a38fa0e3c94dfd1394a71a2d47c9c4d47367374.zip |
x86, irq, ACPI: Release IOAPIC pin when PCI device is disabled
Release IOAPIC pin associated with PCI device when the PCI device
is disabled.
Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Len Brown <len.brown@intel.com>
Cc: Pavel Machek <pavel@ucw.cz>
Link: http://lkml.kernel.org/r/1402380987-32577-1-git-send-email-jiang.liu@linux.intel.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/acpi')
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index fd4b6d2e436c..8c28023924bf 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -421,8 +421,24 @@ 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); +} + static struct irq_domain_ops acpi_irqdomain_ops = { .map = mp_irqdomain_map, + .unmap = mp_irqdomain_unmap, }; static int __init @@ -640,8 +656,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; @@ -661,6 +685,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); @@ -668,6 +694,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; } |