Skip to content

Commit 9c78c1a

Browse files
committed
genirq/msi: Provide optional translation op
irq_create_fwspec_mapping() requires translation of the firmware spec to a hardware interrupt number and the trigger type information. Wired interrupts which are connected to a wire to MSI bridge, like MBIGEN are allocated that way. So far MBIGEN provides a regular irqdomain which then hooks backwards into the MSI infrastructure. That's an unholy mess and will be replaced with per device MSI domains which are regular MSI domains. Interrupts on MSI domains are not supported by irq_create_fwspec_mapping(), but for making the wire to MSI bridges sane it makes sense to provide a special allocation/free interface in the MSI infrastructure. That avoids the backdoors into the core MSI allocation code and just shares all the regular MSI infrastructure. Provide an optional translation callback in msi_domain_ops which can be utilized by these wire to MSI bridges. No other MSI domain should provide a translation callback. The default translation callback of the MSI irqdomains will warn when it is invoked on a non-prepared MSI domain. Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Anup Patel <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 1a4671f commit 9c78c1a

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

include/linux/msi.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ bool arch_restore_msi_irqs(struct pci_dev *dev);
412412
struct irq_domain;
413413
struct irq_domain_ops;
414414
struct irq_chip;
415+
struct irq_fwspec;
415416
struct device_node;
416417
struct fwnode_handle;
417418
struct msi_domain_info;
@@ -431,6 +432,8 @@ struct msi_domain_info;
431432
* function.
432433
* @msi_post_free: Optional function which is invoked after freeing
433434
* all interrupts.
435+
* @msi_translate: Optional translate callback to support the odd wire to
436+
* MSI bridges, e.g. MBIGEN
434437
*
435438
* @get_hwirq, @msi_init and @msi_free are callbacks used by the underlying
436439
* irqdomain.
@@ -468,6 +471,8 @@ struct msi_domain_ops {
468471
struct device *dev);
469472
void (*msi_post_free)(struct irq_domain *domain,
470473
struct device *dev);
474+
int (*msi_translate)(struct irq_domain *domain, struct irq_fwspec *fwspec,
475+
irq_hw_number_t *hwirq, unsigned int *type);
471476
};
472477

473478
/**

kernel/irq/msi.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,11 +726,26 @@ static void msi_domain_free(struct irq_domain *domain, unsigned int virq,
726726
irq_domain_free_irqs_top(domain, virq, nr_irqs);
727727
}
728728

729+
static int msi_domain_translate(struct irq_domain *domain, struct irq_fwspec *fwspec,
730+
irq_hw_number_t *hwirq, unsigned int *type)
731+
{
732+
struct msi_domain_info *info = domain->host_data;
733+
734+
/*
735+
* This will catch allocations through the regular irqdomain path except
736+
* for MSI domains which really support this, e.g. MBIGEN.
737+
*/
738+
if (!info->ops->msi_translate)
739+
return -ENOTSUPP;
740+
return info->ops->msi_translate(domain, fwspec, hwirq, type);
741+
}
742+
729743
static const struct irq_domain_ops msi_domain_ops = {
730744
.alloc = msi_domain_alloc,
731745
.free = msi_domain_free,
732746
.activate = msi_domain_activate,
733747
.deactivate = msi_domain_deactivate,
748+
.translate = msi_domain_translate,
734749
};
735750

736751
static irq_hw_number_t msi_domain_ops_get_hwirq(struct msi_domain_info *info,

0 commit comments

Comments
 (0)