This patch introduces x86_of_new_msi_irq() and x86_of_del_msi_irq(), which shall be invoked by native_setup_msi_irqs() and native_teardown_msi_irq() respectively to add/delete irq numbers to/from the "dummy" msi irqdomain. Signed-off-by: Davide Ciminaghi <ciminaghi@xxxxxxxxx> Acked-by: Giancarlo Asnaghi <giancarlo.asnaghi@xxxxxx> --- arch/x86/include/asm/prom.h | 9 +++++++ arch/x86/kernel/devicetree.c | 48 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 0 deletions(-) diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h index bade6ac..902b361 100644 --- a/arch/x86/include/asm/prom.h +++ b/arch/x86/include/asm/prom.h @@ -27,11 +27,20 @@ extern int of_ioapic; extern u64 initial_dtb; extern void add_dtb(u64 data); extern void x86_add_irq_domains(void); +extern int x86_of_new_msi_irq(struct pci_dev *pdev, unsigned int irq); +extern void x86_of_del_msi_irq(unsigned int irq); void x86_of_pci_init(void); void x86_dtb_init(void); #else static inline void add_dtb(u64 data) { } static inline void x86_add_irq_domains(void) { } + +static inline int x86_of_new_msi_irq(struct pci_dev *pdev, unsigned int irq) +{ + return 0; +} + +static inline void x86_of_del_msi_irq(unsigned int irq) { } static inline void x86_of_pci_init(void) { } static inline void x86_dtb_init(void) { } #define of_ioapic 0 diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index d1dcfd0..805931b 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -401,6 +401,54 @@ static void __init ioapic_add_ofnode(struct device_node *np) printk(KERN_ERR "IOxAPIC at %s is not registered.\n", np->full_name); } +int x86_of_new_msi_irq(struct pci_dev *pdev, unsigned int irq) +{ + struct device_node *n = of_node_get(pci_device_to_OF_node(pdev)); + struct device_node *iparent; + struct irq_domain *d; + int ret = 0; + /* Dummy interrupt specifier */ + __be32 intspec = 0; + const __be32 *addr; + struct of_irq oirq; + + /* Walk up the tree looking for the device's interrupt controller */ + if (!n) + return ret; + iparent = of_irq_find_parent(n); + of_node_put(n); + if (!iparent) + return ret; + + addr = of_get_property(n, "reg", NULL); + if (!addr) + return ret; + + ret = of_irq_map_raw(iparent, &intspec, 1, addr, &oirq); + if (ret < 0) + return ret; + + /* Controller found, now look for the relevant irq domain */ + d = irq_find_host(oirq.controller); + if (!d) { + WARN_ON(1); + return -ENODEV; + } + /* And finally simply associate this irq number with itself */ + ret = irq_domain_associate(d, irq, irq); + return ret; +} + +void x86_of_del_msi_irq(unsigned int irq) +{ + struct irq_data *irq_data = irq_get_irq_data(irq); + if (!irq_data->domain) { + WARN_ON(1); + return; + } + irq_domain_disassociate(irq_data->domain, irq); +} + static const struct irq_domain_ops msi_irq_domain_ops = { .xlate = irq_domain_xlate_onecell, }; -- 1.7.7.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html