diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index bc2f5719dace25faf19aae25754d1b115825517b..188eced6813eddb9c313fdb59016b972835e7674 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -222,6 +222,7 @@ struct irq_domain *irq_domain_add_legacy(struct device_node *of_node, void *host_data); extern struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec, enum irq_domain_bus_token bus_token); +extern bool irq_domain_check_msi_remap(void); extern void irq_set_default_host(struct irq_domain *host); extern int irq_domain_alloc_descs(int virq, unsigned int nr_irqs, irq_hw_number_t hwirq, int node, diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 876e13172dc83f89f02d0b47edbd6d97fdca97fe..80c4f931218710eab830f2e83711007b06bf147c 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -277,6 +277,31 @@ struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec, } EXPORT_SYMBOL_GPL(irq_find_matching_fwspec); +/** + * irq_domain_check_msi_remap - Check whether all MSI irq domains implement + * IRQ remapping + * + * Return: false if any MSI irq domain does not support IRQ remapping, + * true otherwise (including if there is no MSI irq domain) + */ +bool irq_domain_check_msi_remap(void) +{ + struct irq_domain *h; + bool ret = true; + + mutex_lock(&irq_domain_mutex); + list_for_each_entry(h, &irq_domain_list, link) { + if (irq_domain_is_msi(h) && + !irq_domain_hierarchical_is_msi_remap(h)) { + ret = false; + break; + } + } + mutex_unlock(&irq_domain_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(irq_domain_check_msi_remap); + /** * irq_set_default_host() - Set a "default" irq domain * @domain: default domain pointer