From 3095cc0d5b2c246ddfcb18f54ed5557640224b6a Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sat, 27 Jan 2024 21:47:36 +0530 Subject: [PATCH] genirq/msi: Split msi_domain_alloc_irq_at() In preparation for providing a special allocation function for wired interrupts which are connected to a wire to MSI bridge, split the inner workings of msi_domain_alloc_irq_at() out into a helper function so the code can be shared. No functional change. Signed-off-by: Thomas Gleixner Signed-off-by: Anup Patel Signed-off-by: Thomas Gleixner Link: https://lore.kernel.org/r/20240127161753.114685-9-apatel@ventanamicro.com --- kernel/irq/msi.c | 84 +++++++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index c0e73788e878..8d463901c864 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -1446,6 +1446,51 @@ int msi_domain_alloc_irqs_all_locked(struct device *dev, unsigned int domid, int return msi_domain_alloc_locked(dev, &ctrl); } +static struct msi_map __msi_domain_alloc_irq_at(struct device *dev, unsigned int domid, + unsigned int index, + const struct irq_affinity_desc *affdesc, + union msi_instance_cookie *icookie) +{ + struct msi_ctrl ctrl = { .domid = domid, .nirqs = 1, }; + struct irq_domain *domain; + struct msi_map map = { }; + struct msi_desc *desc; + int ret; + + domain = msi_get_device_domain(dev, domid); + if (!domain) { + map.index = -ENODEV; + return map; + } + + desc = msi_alloc_desc(dev, 1, affdesc); + if (!desc) { + map.index = -ENOMEM; + return map; + } + + if (icookie) + desc->data.icookie = *icookie; + + ret = msi_insert_desc(dev, desc, domid, index); + if (ret) { + map.index = ret; + return map; + } + + ctrl.first = ctrl.last = desc->msi_index; + + ret = __msi_domain_alloc_irqs(dev, domain, &ctrl); + if (ret) { + map.index = ret; + msi_domain_free_locked(dev, &ctrl); + } else { + map.index = desc->msi_index; + map.virq = desc->irq; + } + return map; +} + /** * msi_domain_alloc_irq_at - Allocate an interrupt from a MSI interrupt domain at * a given index - or at the next free index @@ -1475,45 +1520,10 @@ struct msi_map msi_domain_alloc_irq_at(struct device *dev, unsigned int domid, u const struct irq_affinity_desc *affdesc, union msi_instance_cookie *icookie) { - struct msi_ctrl ctrl = { .domid = domid, .nirqs = 1, }; - struct irq_domain *domain; - struct msi_map map = { }; - struct msi_desc *desc; - int ret; + struct msi_map map; msi_lock_descs(dev); - domain = msi_get_device_domain(dev, domid); - if (!domain) { - map.index = -ENODEV; - goto unlock; - } - - desc = msi_alloc_desc(dev, 1, affdesc); - if (!desc) { - map.index = -ENOMEM; - goto unlock; - } - - if (icookie) - desc->data.icookie = *icookie; - - ret = msi_insert_desc(dev, desc, domid, index); - if (ret) { - map.index = ret; - goto unlock; - } - - ctrl.first = ctrl.last = desc->msi_index; - - ret = __msi_domain_alloc_irqs(dev, domain, &ctrl); - if (ret) { - map.index = ret; - msi_domain_free_locked(dev, &ctrl); - } else { - map.index = desc->msi_index; - map.virq = desc->irq; - } -unlock: + map = __msi_domain_alloc_irq_at(dev, domid, index, affdesc, icookie); msi_unlock_descs(dev); return map; }