aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-11 18:28:06 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-11 18:28:06 -0800
commit3d116a66ed9df0271b8d267093b3bfde2be19b3a (patch)
tree8415b051c87b44ea9f7ecd50bf850155b028737e /drivers/pci
parentMerge branches 'timers-core-for-linus' and 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip (diff)
parentirqchip/omap-intc: Add support for spurious irq handling (diff)
downloadlinux-dev-3d116a66ed9df0271b8d267093b3bfde2be19b3a.tar.xz
linux-dev-3d116a66ed9df0271b8d267093b3bfde2be19b3a.zip
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 department provides: - Support for MSI to wire bridges and a first user of it - More ACPI support for ARM/GIC - A new TS-4800 interrupt controller driver - RCU based free of interrupt descriptors to support the upcoming Intel VMD technology without introducing a locking nightmare - The usual pile of fixes and updates to drivers and core code" * 'irq-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (41 commits) irqchip/omap-intc: Add support for spurious irq handling irqchip/zevio: Use irq_data_get_chip_type() helper irqchip/omap-intc: Remove duplicate setup for IRQ chip type handler irqchip/ts4800: Add TS-4800 interrupt controller irqchip/ts4800: Add documentation for TS-4800 interrupt controller irq/platform-MSI: Increase the maximum MSIs the MSI framework can support irqchip/gicv2m: Miscellaneous fixes for v2m resources and SPI ranges irqchip/bcm2836: Make code more readable irqchip/bcm2836: Tolerate IRQs while no flag is set in ISR irqchip/bcm2836: Add SMP support for the 2836 irqchip/bcm2836: Fix initialization of the LOCAL_IRQ_CNT timers irqchip/gic-v2m: acpi: Introducing GICv2m ACPI support irqchip/gic-v2m: Refactor to prepare for ACPI support irqdomain: Introduce is_fwnode_irqchip helper acpi: pci: Setup MSI domain for ACPI based pci devices genirq/msi: Export functions to allow MSI domains in modules irqchip/mbigen: Implement the mbigen irq chip operation functions irqchip/mbigen: Create irq domain for each mbigen device irqchip/mgigen: Add platform device driver for mbigen device dt-bindings: Documents the mbigen bindings ...
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/msi.c4
-rw-r--r--drivers/pci/pci-acpi.c42
-rw-r--r--drivers/pci/probe.c2
3 files changed, 48 insertions, 0 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 7eaa4c87fec7..7a0df3fdbfae 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -257,6 +257,7 @@ void pci_msi_mask_irq(struct irq_data *data)
{
msi_set_mask_bit(data, 1);
}
+EXPORT_SYMBOL_GPL(pci_msi_mask_irq);
/**
* pci_msi_unmask_irq - Generic irq chip callback to unmask PCI/MSI interrupts
@@ -266,6 +267,7 @@ void pci_msi_unmask_irq(struct irq_data *data)
{
msi_set_mask_bit(data, 0);
}
+EXPORT_SYMBOL_GPL(pci_msi_unmask_irq);
void default_restore_msi_irqs(struct pci_dev *dev)
{
@@ -1126,6 +1128,7 @@ struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
{
return to_pci_dev(desc->dev);
}
+EXPORT_SYMBOL(msi_desc_to_pci_dev);
void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
{
@@ -1285,6 +1288,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode,
domain->bus_token = DOMAIN_BUS_PCI_MSI;
return domain;
}
+EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain);
/**
* pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index a32ba753e413..d3f32d6417ef 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -9,7 +9,9 @@
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/irqdomain.h>
#include <linux/pci.h>
+#include <linux/msi.h>
#include <linux/pci_hotplug.h>
#include <linux/module.h>
#include <linux/pci-aspm.h>
@@ -689,6 +691,46 @@ static struct acpi_bus_type acpi_pci_bus = {
.cleanup = pci_acpi_cleanup,
};
+
+static struct fwnode_handle *(*pci_msi_get_fwnode_cb)(struct device *dev);
+
+/**
+ * pci_msi_register_fwnode_provider - Register callback to retrieve fwnode
+ * @fn: Callback matching a device to a fwnode that identifies a PCI
+ * MSI domain.
+ *
+ * This should be called by irqchip driver, which is the parent of
+ * the MSI domain to provide callback interface to query fwnode.
+ */
+void
+pci_msi_register_fwnode_provider(struct fwnode_handle *(*fn)(struct device *))
+{
+ pci_msi_get_fwnode_cb = fn;
+}
+
+/**
+ * pci_host_bridge_acpi_msi_domain - Retrieve MSI domain of a PCI host bridge
+ * @bus: The PCI host bridge bus.
+ *
+ * This function uses the callback function registered by
+ * pci_msi_register_fwnode_provider() to retrieve the irq_domain with
+ * type DOMAIN_BUS_PCI_MSI of the specified host bridge bus.
+ * This returns NULL on error or when the domain is not found.
+ */
+struct irq_domain *pci_host_bridge_acpi_msi_domain(struct pci_bus *bus)
+{
+ struct fwnode_handle *fwnode;
+
+ if (!pci_msi_get_fwnode_cb)
+ return NULL;
+
+ fwnode = pci_msi_get_fwnode_cb(&bus->dev);
+ if (!fwnode)
+ return NULL;
+
+ return irq_find_matching_fwnode(fwnode, DOMAIN_BUS_PCI_MSI);
+}
+
static int __init acpi_pci_init(void)
{
int ret;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index edb1984201e9..553a029e37f1 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -672,6 +672,8 @@ static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
* should be called from here.
*/
d = pci_host_bridge_of_msi_domain(bus);
+ if (!d)
+ d = pci_host_bridge_acpi_msi_domain(bus);
return d;
}