diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-19 14:02:02 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-19 14:02:02 -0800 |
commit | e589c9e13aeb0c5539bf1314b3a78442ea8fc0c2 (patch) | |
tree | 87aaebb0ef7c4cc7ee6cffc152a9264b24659b7e /drivers | |
parent | 4bb9374e0bd40d8fe97860ea0d61a0330b7c3925 (diff) | |
parent | 719b530cdc70b45f22fed2185db8b34568b4c3f8 (diff) | |
download | lwn-e589c9e13aeb0c5539bf1314b3a78442ea8fc0c2.tar.gz lwn-e589c9e13aeb0c5539bf1314b3a78442ea8fc0c2.zip |
Merge branch 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 apic updates from Thomas Gleixner:
"After stopping the full x86/apic branch, I took some time to go
through the first block of patches again, which are mostly cleanups
and preparatory work for the irqdomain conversion and ioapic hotplug
support.
Unfortunaly one of the real problematic commits was right at the
beginning, so I rebased this portion of the pending patches without
the offenders.
It would be great to get this into 3.19. That makes reworking the
problematic parts simpler. The usual tip testing did not unearth any
issues and it is fully bisectible now.
I'm pretty confident that this wont affect the calmness of the xmas
season.
Changes:
- Split the convoluted io_apic.c code into domain specific parts
(vector, ioapic, msi, htirq)
- Introduce proper helper functions to retrieve irq specific data
instead of open coded dereferencing of pointers
- Preparatory work for ioapic hotplug and irqdomain conversion
- Removal of the non functional pci-ioapic driver
- Removal of unused irq entry stubs
- Make native_smp_prepare_cpus() preemtible to avoid GFP_ATOMIC
allocations for everything which is called from there.
- Small cleanups and fixes"
* 'x86-apic-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (36 commits)
iommu/amd: Use helpers to access irq_cfg data structure associated with IRQ
iommu/vt-d: Use helpers to access irq_cfg data structure associated with IRQ
x86: irq_remapping: Use helpers to access irq_cfg data structure associated with IRQ
x86, irq: Use helpers to access irq_cfg data structure associated with IRQ
x86, irq: Make MSI and HT_IRQ indepenent of X86_IO_APIC
x86, irq: Move IRQ initialization routines from io_apic.c into vector.c
x86, irq: Move IOAPIC related declarations from hw_irq.h into io_apic.h
x86, irq: Move HT IRQ related code from io_apic.c into htirq.c
x86, irq: Move PCI MSI related code from io_apic.c into msi.c
x86, irq: Replace printk(KERN_LVL) with pr_lvl() utilities
x86, irq: Make UP version of irq_complete_move() an inline stub
x86, irq: Move local APIC related code from io_apic.c into vector.c
x86, irq: Introduce helpers to access struct irq_cfg
x86, irq: Protect __clear_irq_vector() with vector_lock
x86, irq: Rename local APIC related functions in io_apic.c as apic_xxx()
x86, irq: Refine hw_irq.h to prepare for irqdomain support
x86, irq: Convert irq_2_pin list to generic list
x86, irq: Kill useless parameter 'irq_attr' of IO_APIC_get_PCI_irq_vector()
x86, irq, acpi: Get rid of special handling of GSI for ACPI SCI
x86, irq: Introduce helper to check whether an IOAPIC has been registered
...
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/pci_irq.c | 11 | ||||
-rw-r--r-- | drivers/acpi/processor_core.c | 9 | ||||
-rw-r--r-- | drivers/acpi/resource.c | 2 | ||||
-rw-r--r-- | drivers/iommu/amd_iommu.c | 14 | ||||
-rw-r--r-- | drivers/iommu/intel_irq_remapping.c | 10 | ||||
-rw-r--r-- | drivers/iommu/irq_remapping.c | 6 | ||||
-rw-r--r-- | drivers/pci/Kconfig | 9 | ||||
-rw-r--r-- | drivers/pci/Makefile | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/ibmphp_core.c | 6 | ||||
-rw-r--r-- | drivers/pci/ioapic.c | 121 |
10 files changed, 32 insertions, 158 deletions
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 7cc4e33179f9..5277a0ee5704 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -413,6 +413,9 @@ int acpi_pci_irq_enable(struct pci_dev *dev) return 0; } + if (dev->irq_managed && dev->irq > 0) + return 0; + entry = acpi_pci_irq_lookup(dev, pin); if (!entry) { /* @@ -456,6 +459,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) return rc; } dev->irq = rc; + dev->irq_managed = 1; if (link) snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link); @@ -478,7 +482,7 @@ void acpi_pci_irq_disable(struct pci_dev *dev) u8 pin; pin = dev->pin; - if (!pin) + if (!pin || !dev->irq_managed || dev->irq <= 0) return; /* Keep IOAPIC pin configuration when suspending */ @@ -506,6 +510,9 @@ void acpi_pci_irq_disable(struct pci_dev *dev) */ dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); - if (gsi >= 0 && dev->irq > 0) + if (gsi >= 0) { acpi_unregister_gsi(gsi); + dev->irq = 0; + dev->irq_managed = 0; + } } diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index ef58f46c8442..342942f90a10 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -125,13 +125,12 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) } header = (struct acpi_subtable_header *)obj->buffer.pointer; - if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) { + if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) map_lapic_id(header, acpi_id, &apic_id); - } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { + else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) map_lsapic_id(header, type, acpi_id, &apic_id); - } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) { + else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) map_x2apic_id(header, type, acpi_id, &apic_id); - } exit: kfree(buffer.pointer); @@ -164,7 +163,7 @@ int acpi_map_cpuid(int apic_id, u32 acpi_id) * For example, * * Scope (_PR) - * { + * { * Processor (CPU0, 0x00, 0x00000410, 0x06) {} * Processor (CPU1, 0x01, 0x00000410, 0x06) {} * Processor (CPU2, 0x02, 0x00000410, 0x06) {} diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 2ba8f02ced36..782a0d15c25f 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -200,7 +200,7 @@ bool acpi_dev_resource_address_space(struct acpi_resource *ares, status = acpi_resource_to_address64(ares, &addr); if (ACPI_FAILURE(status)) - return true; + return false; res->start = addr.minimum; res->end = addr.maximum; diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index b205f76d7129..98024856df07 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -4071,7 +4071,7 @@ static int setup_ioapic_entry(int irq, struct IO_APIC_route_entry *entry, int devid; int ret; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); if (!cfg) return -EINVAL; @@ -4134,7 +4134,7 @@ static int set_affinity(struct irq_data *data, const struct cpumask *mask, if (!config_enabled(CONFIG_SMP)) return -1; - cfg = data->chip_data; + cfg = irqd_cfg(data); irq = data->irq; irte_info = &cfg->irq_2_irte; @@ -4172,7 +4172,7 @@ static int free_irq(int irq) struct irq_2_irte *irte_info; struct irq_cfg *cfg; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); if (!cfg) return -EINVAL; @@ -4191,7 +4191,7 @@ static void compose_msi_msg(struct pci_dev *pdev, struct irq_cfg *cfg; union irte irte; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); if (!cfg) return; @@ -4220,7 +4220,7 @@ static int msi_alloc_irq(struct pci_dev *pdev, int irq, int nvec) if (!pdev) return -EINVAL; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); if (!cfg) return -EINVAL; @@ -4240,7 +4240,7 @@ static int msi_setup_irq(struct pci_dev *pdev, unsigned int irq, if (!pdev) return -EINVAL; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); if (!cfg) return -EINVAL; @@ -4263,7 +4263,7 @@ static int alloc_hpet_msi(unsigned int irq, unsigned int id) struct irq_cfg *cfg; int index, devid; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); if (!cfg) return -EINVAL; diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 27541d440849..a55b207b9425 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -54,7 +54,7 @@ static int __init parse_ioapics_under_ir(void); static struct irq_2_iommu *irq_2_iommu(unsigned int irq) { - struct irq_cfg *cfg = irq_get_chip_data(irq); + struct irq_cfg *cfg = irq_cfg(irq); return cfg ? &cfg->irq_2_iommu : NULL; } @@ -85,7 +85,7 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count) { struct ir_table *table = iommu->ir_table; struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); - struct irq_cfg *cfg = irq_get_chip_data(irq); + struct irq_cfg *cfg = irq_cfg(irq); unsigned int mask = 0; unsigned long flags; int index; @@ -153,7 +153,7 @@ static int map_irq_to_irte_handle(int irq, u16 *sub_handle) static int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle) { struct irq_2_iommu *irq_iommu = irq_2_iommu(irq); - struct irq_cfg *cfg = irq_get_chip_data(irq); + struct irq_cfg *cfg = irq_cfg(irq); unsigned long flags; if (!irq_iommu) @@ -1050,7 +1050,7 @@ static int intel_ioapic_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force) { - struct irq_cfg *cfg = data->chip_data; + struct irq_cfg *cfg = irqd_cfg(data); unsigned int dest, irq = data->irq; struct irte irte; int err; @@ -1105,7 +1105,7 @@ static void intel_compose_msi_msg(struct pci_dev *pdev, u16 sub_handle = 0; int ir_index; - cfg = irq_get_chip_data(irq); + cfg = irq_cfg(irq); ir_index = map_irq_to_irte_handle(irq, &sub_handle); BUG_ON(ir_index == -1); diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c index 2c3f5ad01098..89c4846683be 100644 --- a/drivers/iommu/irq_remapping.c +++ b/drivers/iommu/irq_remapping.c @@ -298,7 +298,7 @@ static int set_remapped_irq_affinity(struct irq_data *data, void free_remapped_irq(int irq) { - struct irq_cfg *cfg = irq_get_chip_data(irq); + struct irq_cfg *cfg = irq_cfg(irq); if (!remap_ops || !remap_ops->free_irq) return; @@ -311,7 +311,7 @@ void compose_remapped_msi_msg(struct pci_dev *pdev, unsigned int irq, unsigned int dest, struct msi_msg *msg, u8 hpet_id) { - struct irq_cfg *cfg = irq_get_chip_data(irq); + struct irq_cfg *cfg = irq_cfg(irq); if (!irq_remapped(cfg)) native_compose_msi_msg(pdev, irq, dest, msg, hpet_id); @@ -364,7 +364,7 @@ static void ir_ack_apic_edge(struct irq_data *data) static void ir_ack_apic_level(struct irq_data *data) { ack_APIC_irq(); - eoi_ioapic_irq(data->irq, data->chip_data); + eoi_ioapic_irq(data->irq, irqd_cfg(data)); } static void ir_print_prefix(struct irq_data *data, struct seq_file *p) diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index cced84233ac0..7a8f1c5e65af 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -67,7 +67,7 @@ config XEN_PCIDEV_FRONTEND config HT_IRQ bool "Interrupts on hypertransport devices" default y - depends on PCI && X86_LOCAL_APIC && X86_IO_APIC + depends on PCI && X86_LOCAL_APIC help This allows native hypertransport devices to use interrupts. @@ -110,13 +110,6 @@ config PCI_PASID If unsure, say N. -config PCI_IOAPIC - bool "PCI IO-APIC hotplug support" if X86 - depends on PCI - depends on ACPI - depends on X86_IO_APIC - default !X86 - config PCI_LABEL def_bool y if (DMI || ACPI) select NLS diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index e04fe2d9df3b..73e4af400a5a 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -13,8 +13,6 @@ obj-$(CONFIG_PCI_QUIRKS) += quirks.o # Build PCI Express stuff if needed obj-$(CONFIG_PCIEPORTBUS) += pcie/ -obj-$(CONFIG_PCI_IOAPIC) += ioapic.o - # Build the PCI Hotplug drivers if we were asked to obj-$(CONFIG_HOTPLUG_PCI) += hotplug/ ifdef CONFIG_HOTPLUG_PCI diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 3efaf4c38528..96c5c729cdbc 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -36,6 +36,7 @@ #include <linux/wait.h> #include "../pci.h" #include <asm/pci_x86.h> /* for struct irq_routing_table */ +#include <asm/io_apic.h> #include "ibmphp.h" #define attn_on(sl) ibmphp_hpc_writeslot (sl, HPC_SLOT_ATTNON) @@ -155,13 +156,10 @@ int ibmphp_init_devno(struct slot **cur_slot) for (loop = 0; loop < len; loop++) { if ((*cur_slot)->number == rtable->slots[loop].slot && (*cur_slot)->bus == rtable->slots[loop].bus) { - struct io_apic_irq_attr irq_attr; - (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn); for (i = 0; i < 4; i++) (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus, - (int) (*cur_slot)->device, i, - &irq_attr); + (int) (*cur_slot)->device, i); debug("(*cur_slot)->irq[0] = %x\n", (*cur_slot)->irq[0]); diff --git a/drivers/pci/ioapic.c b/drivers/pci/ioapic.c deleted file mode 100644 index f6219d36227f..000000000000 --- a/drivers/pci/ioapic.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * IOAPIC/IOxAPIC/IOSAPIC driver - * - * Copyright (C) 2009 Fujitsu Limited. - * (c) Copyright 2009 Hewlett-Packard Development Company, L.P. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* - * This driver manages PCI I/O APICs added by hotplug after boot. We try to - * claim all I/O APIC PCI devices, but those present at boot were registered - * when we parsed the ACPI MADT, so we'll fail when we try to re-register - * them. - */ - -#include <linux/pci.h> -#include <linux/module.h> -#include <linux/acpi.h> -#include <linux/slab.h> - -struct ioapic { - acpi_handle handle; - u32 gsi_base; -}; - -static int ioapic_probe(struct pci_dev *dev, const struct pci_device_id *ent) -{ - acpi_handle handle; - acpi_status status; - unsigned long long gsb; - struct ioapic *ioapic; - int ret; - char *type; - struct resource *res; - - handle = ACPI_HANDLE(&dev->dev); - if (!handle) - return -EINVAL; - - status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb); - if (ACPI_FAILURE(status)) - return -EINVAL; - - /* - * The previous code in acpiphp evaluated _MAT if _GSB failed, but - * ACPI spec 4.0 sec 6.2.2 requires _GSB for hot-pluggable I/O APICs. - */ - - ioapic = kzalloc(sizeof(*ioapic), GFP_KERNEL); - if (!ioapic) - return -ENOMEM; - - ioapic->handle = handle; - ioapic->gsi_base = (u32) gsb; - - if (dev->class == PCI_CLASS_SYSTEM_PIC_IOAPIC) - type = "IOAPIC"; - else - type = "IOxAPIC"; - - ret = pci_enable_device(dev); - if (ret < 0) - goto exit_free; - - pci_set_master(dev); - - if (pci_request_region(dev, 0, type)) - goto exit_disable; - - res = &dev->resource[0]; - if (acpi_register_ioapic(ioapic->handle, res->start, ioapic->gsi_base)) - goto exit_release; - - pci_set_drvdata(dev, ioapic); - dev_info(&dev->dev, "%s at %pR, GSI %u\n", type, res, ioapic->gsi_base); - return 0; - -exit_release: - pci_release_region(dev, 0); -exit_disable: - pci_disable_device(dev); -exit_free: - kfree(ioapic); - return -ENODEV; -} - -static void ioapic_remove(struct pci_dev *dev) -{ - struct ioapic *ioapic = pci_get_drvdata(dev); - - acpi_unregister_ioapic(ioapic->handle, ioapic->gsi_base); - pci_release_region(dev, 0); - pci_disable_device(dev); - kfree(ioapic); -} - - -static const struct pci_device_id ioapic_devices[] = { - { PCI_DEVICE_CLASS(PCI_CLASS_SYSTEM_PIC_IOAPIC, ~0) }, - { PCI_DEVICE_CLASS(PCI_CLASS_SYSTEM_PIC_IOXAPIC, ~0) }, - { } -}; -MODULE_DEVICE_TABLE(pci, ioapic_devices); - -static struct pci_driver ioapic_driver = { - .name = "ioapic", - .id_table = ioapic_devices, - .probe = ioapic_probe, - .remove = ioapic_remove, -}; - -static int __init ioapic_init(void) -{ - return pci_register_driver(&ioapic_driver); -} -module_init(ioapic_init); - -MODULE_LICENSE("GPL"); |