diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-04 01:40:01 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-04 01:40:01 +0300 |
commit | 6aa2fdb87cf01d7746955c600cbac352dc04d451 (patch) | |
tree | 75ba04b2579fafb103dfa049289e7e6b7b3d5bb9 /drivers/pci/probe.c | |
parent | 7b2a4306f9e7d64bb408a6df3bb419500578068a (diff) | |
parent | d9e4ad5badf4ccbfddee208c898fb8fd0c8836b1 (diff) | |
download | linux-6aa2fdb87cf01d7746955c600cbac352dc04d451.tar.xz |
Merge branch 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq updates from Thomas Gleixner:
"The irq departement delivers:
- Rework the irqdomain core infrastructure to accomodate ACPI based
systems. This is required to support ARM64 without creating
artificial device tree nodes.
- Sanitize the ACPI based ARM GIC initialization by making use of the
new firmware independent irqdomain core
- Further improvements to the generic MSI management
- Generalize the irq migration on CPU hotplug
- Improvements to the threaded interrupt infrastructure
- Allow the migration of "chained" low level interrupt handlers
- Allow optional force masking of interrupts in disable_irq[_nosysnc]
- Support for two new interrupt chips - Sigh!
- A larger set of errata fixes for ARM gicv3
- The usual pile of fixes, updates, improvements and cleanups all
over the place"
* 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (71 commits)
Document that IRQ_NONE should be returned when IRQ not actually handled
PCI/MSI: Allow the MSI domain to be device-specific
PCI: Add per-device MSI domain hook
of/irq: Use the msi-map property to provide device-specific MSI domain
of/irq: Split of_msi_map_rid to reuse msi-map lookup
irqchip/gic-v3-its: Parse new version of msi-parent property
PCI/MSI: Use of_msi_get_domain instead of open-coded "msi-parent" parsing
of/irq: Use of_msi_get_domain instead of open-coded "msi-parent" parsing
of/irq: Add support code for multi-parent version of "msi-parent"
irqchip/gic-v3-its: Add handling of PCI requester id.
PCI/MSI: Add helper function pci_msi_domain_get_msi_rid().
of/irq: Add new function of_msi_map_rid()
Docs: dt: Add PCI MSI map bindings
irqchip/gic-v2m: Add support for multiple MSI frames
irqchip/gic-v3: Fix translation of LPIs after conversion to irq_fwspec
irqchip/mxs: Add Alphascale ASM9260 support
irqchip/mxs: Prepare driver for hardware with different offsets
irqchip/mxs: Panic if ioremap or domain creation fails
irqdomain: Documentation updates
irqdomain/msi: Use fwnode instead of of_node
...
Diffstat (limited to 'drivers/pci/probe.c')
-rw-r--r-- | drivers/pci/probe.c | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 8361d27e5eca..f14a970b61fa 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1622,15 +1622,48 @@ static void pci_init_capabilities(struct pci_dev *dev) pci_enable_acs(dev); } +/* + * This is the equivalent of pci_host_bridge_msi_domain that acts on + * devices. Firmware interfaces that can select the MSI domain on a + * per-device basis should be called from here. + */ +static struct irq_domain *pci_dev_msi_domain(struct pci_dev *dev) +{ + struct irq_domain *d; + + /* + * If a domain has been set through the pcibios_add_device + * callback, then this is the one (platform code knows best). + */ + d = dev_get_msi_domain(&dev->dev); + if (d) + return d; + + /* + * Let's see if we have a firmware interface able to provide + * the domain. + */ + d = pci_msi_get_device_domain(dev); + if (d) + return d; + + return NULL; +} + static void pci_set_msi_domain(struct pci_dev *dev) { + struct irq_domain *d; + /* - * If no domain has been set through the pcibios_add_device - * callback, inherit the default from the bus device. + * If the platform or firmware interfaces cannot supply a + * device-specific MSI domain, then inherit the default domain + * from the host bridge itself. */ - if (!dev_get_msi_domain(&dev->dev)) - dev_set_msi_domain(&dev->dev, - dev_get_msi_domain(&dev->bus->dev)); + d = pci_dev_msi_domain(dev); + if (!d) + d = dev_get_msi_domain(&dev->bus->dev); + + dev_set_msi_domain(&dev->dev, d); } void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) |