diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-13 20:05:29 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-13 20:05:29 +0300 |
commit | feb7a43de5ef625ad74097d8fd3481d5dbc06a59 (patch) | |
tree | 1aae202b28ca3a87dd00ede93783ea3c0647d4f6 /drivers/soc | |
parent | fd04899208d2057b2de808e8447cfd806fd0a607 (diff) | |
parent | 74a5257a0c175810d620b5e631c4e7554955ac25 (diff) | |
download | linux-feb7a43de5ef625ad74097d8fd3481d5dbc06a59.tar.xz |
Merge tag 'irq-msi-2022-01-13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull MSI irq updates from Thomas Gleixner:
"Rework of the MSI interrupt infrastructure.
This is a treewide cleanup and consolidation of MSI interrupt handling
in preparation for further changes in this area which are necessary
to:
- address existing shortcomings in the VFIO area
- support the upcoming Interrupt Message Store functionality which
decouples the message store from the PCI config/MMIO space"
* tag 'irq-msi-2022-01-13' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (94 commits)
genirq/msi: Populate sysfs entry only once
PCI/MSI: Unbreak pci_irq_get_affinity()
genirq/msi: Convert storage to xarray
genirq/msi: Simplify sysfs handling
genirq/msi: Add abuse prevention comment to msi header
genirq/msi: Mop up old interfaces
genirq/msi: Convert to new functions
genirq/msi: Make interrupt allocation less convoluted
platform-msi: Simplify platform device MSI code
platform-msi: Let core code handle MSI descriptors
bus: fsl-mc-msi: Simplify MSI descriptor handling
soc: ti: ti_sci_inta_msi: Remove ti_sci_inta_msi_domain_free_irqs()
soc: ti: ti_sci_inta_msi: Rework MSI descriptor allocation
NTB/msi: Convert to msi_on_each_desc()
PCI: hv: Rework MSI handling
powerpc/mpic_u3msi: Use msi_for_each-desc()
powerpc/fsl_msi: Use msi_for_each_desc()
powerpc/pasemi/msi: Convert to msi_on_each_dec()
powerpc/cell/axon_msi: Convert to msi_on_each_desc()
powerpc/4xx/hsta: Rework MSI handling
...
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/fsl/dpio/dpio-driver.c | 8 | ||||
-rw-r--r-- | drivers/soc/ti/k3-ringacc.c | 6 | ||||
-rw-r--r-- | drivers/soc/ti/ti_sci_inta_msi.c | 94 |
3 files changed, 37 insertions, 71 deletions
diff --git a/drivers/soc/fsl/dpio/dpio-driver.c b/drivers/soc/fsl/dpio/dpio-driver.c index dd948889eeab..5a2edc48dd79 100644 --- a/drivers/soc/fsl/dpio/dpio-driver.c +++ b/drivers/soc/fsl/dpio/dpio-driver.c @@ -88,7 +88,7 @@ static void unregister_dpio_irq_handlers(struct fsl_mc_device *dpio_dev) irq = dpio_dev->irqs[0]; /* clear the affinity hint */ - irq_set_affinity_hint(irq->msi_desc->irq, NULL); + irq_set_affinity_hint(irq->virq, NULL); } static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu) @@ -98,7 +98,7 @@ static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu) irq = dpio_dev->irqs[0]; error = devm_request_irq(&dpio_dev->dev, - irq->msi_desc->irq, + irq->virq, dpio_irq_handler, 0, dev_name(&dpio_dev->dev), @@ -111,10 +111,10 @@ static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu) } /* set the affinity hint */ - if (irq_set_affinity_hint(irq->msi_desc->irq, cpumask_of(cpu))) + if (irq_set_affinity_hint(irq->virq, cpumask_of(cpu))) dev_err(&dpio_dev->dev, "irq_set_affinity failed irq %d cpu %d\n", - irq->msi_desc->irq, cpu); + irq->virq, cpu); return 0; } diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c index 312ba0f98ad7..56be39161489 100644 --- a/drivers/soc/ti/k3-ringacc.c +++ b/drivers/soc/ti/k3-ringacc.c @@ -647,7 +647,7 @@ int k3_ringacc_get_ring_irq_num(struct k3_ring *ring) if (!ring) return -EINVAL; - irq_num = ti_sci_inta_msi_get_virq(ring->parent->dev, ring->ring_id); + irq_num = msi_get_virq(ring->parent->dev, ring->ring_id); if (irq_num <= 0) irq_num = -EINVAL; return irq_num; @@ -1356,9 +1356,9 @@ static int k3_ringacc_init(struct platform_device *pdev, struct resource *res; int ret, i; - dev->msi_domain = of_msi_get_domain(dev, dev->of_node, + dev->msi.domain = of_msi_get_domain(dev, dev->of_node, DOMAIN_BUS_TI_SCI_INTA_MSI); - if (!dev->msi_domain) { + if (!dev->msi.domain) { dev_err(dev, "Failed to get MSI domain\n"); return -EPROBE_DEFER; } diff --git a/drivers/soc/ti/ti_sci_inta_msi.c b/drivers/soc/ti/ti_sci_inta_msi.c index a1d9c027022a..991c78b34745 100644 --- a/drivers/soc/ti/ti_sci_inta_msi.c +++ b/drivers/soc/ti/ti_sci_inta_msi.c @@ -51,6 +51,7 @@ struct irq_domain *ti_sci_inta_msi_create_irq_domain(struct fwnode_handle *fwnod struct irq_domain *domain; ti_sci_inta_msi_update_chip_ops(info); + info->flags |= MSI_FLAG_FREE_MSI_DESCS; domain = msi_create_irq_domain(fwnode, info, parent); if (domain) @@ -60,50 +61,32 @@ struct irq_domain *ti_sci_inta_msi_create_irq_domain(struct fwnode_handle *fwnod } EXPORT_SYMBOL_GPL(ti_sci_inta_msi_create_irq_domain); -static void ti_sci_inta_msi_free_descs(struct device *dev) -{ - struct msi_desc *desc, *tmp; - - list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) { - list_del(&desc->list); - free_msi_entry(desc); - } -} - static int ti_sci_inta_msi_alloc_descs(struct device *dev, struct ti_sci_resource *res) { - struct msi_desc *msi_desc; + struct msi_desc msi_desc; int set, i, count = 0; + memset(&msi_desc, 0, sizeof(msi_desc)); + msi_desc.nvec_used = 1; + for (set = 0; set < res->sets; set++) { - for (i = 0; i < res->desc[set].num; i++) { - msi_desc = alloc_msi_entry(dev, 1, NULL); - if (!msi_desc) { - ti_sci_inta_msi_free_descs(dev); - return -ENOMEM; - } - - msi_desc->inta.dev_index = res->desc[set].start + i; - INIT_LIST_HEAD(&msi_desc->list); - list_add_tail(&msi_desc->list, dev_to_msi_list(dev)); - count++; + for (i = 0; i < res->desc[set].num; i++, count++) { + msi_desc.msi_index = res->desc[set].start + i; + if (msi_add_msi_desc(dev, &msi_desc)) + goto fail; } - for (i = 0; i < res->desc[set].num_sec; i++) { - msi_desc = alloc_msi_entry(dev, 1, NULL); - if (!msi_desc) { - ti_sci_inta_msi_free_descs(dev); - return -ENOMEM; - } - - msi_desc->inta.dev_index = res->desc[set].start_sec + i; - INIT_LIST_HEAD(&msi_desc->list); - list_add_tail(&msi_desc->list, dev_to_msi_list(dev)); - count++; + + for (i = 0; i < res->desc[set].num_sec; i++, count++) { + msi_desc.msi_index = res->desc[set].start_sec + i; + if (msi_add_msi_desc(dev, &msi_desc)) + goto fail; } } - return count; +fail: + msi_free_msi_descs(dev); + return -ENOMEM; } int ti_sci_inta_msi_domain_alloc_irqs(struct device *dev, @@ -120,39 +103,22 @@ int ti_sci_inta_msi_domain_alloc_irqs(struct device *dev, if (pdev->id < 0) return -ENODEV; - nvec = ti_sci_inta_msi_alloc_descs(dev, res); - if (nvec <= 0) - return nvec; + ret = msi_setup_device_data(dev); + if (ret) + return ret; - ret = msi_domain_alloc_irqs(msi_domain, dev, nvec); - if (ret) { - dev_err(dev, "Failed to allocate IRQs %d\n", ret); - goto cleanup; + msi_lock_descs(dev); + nvec = ti_sci_inta_msi_alloc_descs(dev, res); + if (nvec <= 0) { + ret = nvec; + goto unlock; } - return 0; - -cleanup: - ti_sci_inta_msi_free_descs(&pdev->dev); + ret = msi_domain_alloc_irqs_descs_locked(msi_domain, dev, nvec); + if (ret) + dev_err(dev, "Failed to allocate IRQs %d\n", ret); +unlock: + msi_unlock_descs(dev); return ret; } EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain_alloc_irqs); - -void ti_sci_inta_msi_domain_free_irqs(struct device *dev) -{ - msi_domain_free_irqs(dev->msi_domain, dev); - ti_sci_inta_msi_free_descs(dev); -} -EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain_free_irqs); - -unsigned int ti_sci_inta_msi_get_virq(struct device *dev, u32 dev_index) -{ - struct msi_desc *desc; - - for_each_msi_entry(desc, dev) - if (desc->inta.dev_index == dev_index) - return desc->irq; - - return -ENODEV; -} -EXPORT_SYMBOL_GPL(ti_sci_inta_msi_get_virq); |