From c706c239af5bc297b5fbf1adc715632e1c222f7a Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Tue, 28 Jul 2015 14:46:15 +0100 Subject: [PATCH] of/platform: Assign MSI domain to platform device As for PCI, we're able to populate the msi_domain field at probe time, provided that the device tree has an "msi-parent" property. Signed-off-by: Marc Zyngier Cc: Cc: Yijing Wang Cc: Ma Jun Cc: Lorenzo Pieralisi Cc: Duc Dang Cc: Hanjun Guo Cc: Bjorn Helgaas Cc: Jiang Liu Cc: Jason Cooper Link: http://lkml.kernel.org/r/1438091186-10244-9-git-send-email-marc.zyngier@arm.com Signed-off-by: Thomas Gleixner --- drivers/of/irq.c | 21 +++++++++++++++++++++ drivers/of/platform.c | 1 + include/linux/irqdomain.h | 1 + include/linux/of_irq.h | 1 + 4 files changed, 24 insertions(+) diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 3cf7a01f557f..2956d725649f 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -18,6 +18,7 @@ * driver. */ +#include #include #include #include @@ -576,3 +577,23 @@ err: kfree(desc); } } + +/** + * of_msi_configure - Set the msi_domain field of a device + * @dev: device structure to associate with an MSI irq domain + * @np: device node for that device + */ +void of_msi_configure(struct device *dev, struct device_node *np) +{ + struct device_node *msi_np; + struct irq_domain *d; + + msi_np = of_parse_phandle(np, "msi-parent", 0); + if (!msi_np) + return; + + d = irq_find_matching_host(msi_np, DOMAIN_BUS_PLATFORM_MSI); + if (!d) + d = irq_find_host(msi_np); + dev_set_msi_domain(dev, d); +} diff --git a/drivers/of/platform.c b/drivers/of/platform.c index ddf8e42c9367..8a002d6151f2 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -184,6 +184,7 @@ static struct platform_device *of_platform_device_create_pdata( dev->dev.bus = &platform_bus_type; dev->dev.platform_data = platform_data; of_dma_configure(&dev->dev, dev->dev.of_node); + of_msi_configure(&dev->dev, dev->dev.of_node); if (of_device_add(dev) != 0) { of_dma_deconfigure(&dev->dev); diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 25e9e6696a65..b4a74f73a0c3 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -55,6 +55,7 @@ struct irq_data; enum irq_domain_bus_token { DOMAIN_BUS_ANY = 0, DOMAIN_BUS_PCI_MSI, + DOMAIN_BUS_PLATFORM_MSI, }; /** diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index d884929a7747..4bcbd586a672 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h @@ -74,6 +74,7 @@ static inline int of_irq_to_resource_table(struct device_node *dev, */ extern unsigned int irq_of_parse_and_map(struct device_node *node, int index); extern struct device_node *of_irq_find_parent(struct device_node *child); +extern void of_msi_configure(struct device *dev, struct device_node *np); #else /* !CONFIG_OF */ static inline unsigned int irq_of_parse_and_map(struct device_node *dev, -- 2.20.1