diff options
author | Linus Torvalds | 2024-07-22 14:02:19 -0700 |
---|---|---|
committer | Linus Torvalds | 2024-07-22 14:02:19 -0700 |
commit | 66ebbdfdeb093e097399b1883390079cd4c3022b (patch) | |
tree | 5849f882aedd4f7db334eff55f2b99ff24a277d8 /kernel | |
parent | ac7473a179d65f6c5de06a4b10d3b3d36df3f172 (diff) | |
parent | c9b4f313f6b83ac80e9d51845d092c32513efdb4 (diff) |
Merge tag 'irq-msi-2024-07-22' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull MSI interrupt updates from Thomas Gleixner:
"Switch ARM/ARM64 over to the modern per device MSI domains.
This simplifies the handling of platform MSI and wire to MSI
controllers and removes about 500 lines of legacy code.
Aside of that it paves the way for ARM/ARM64 to utilize the dynamic
allocation of PCI/MSI interrupts and to support the upcoming non
standard IMS (Interrupt Message Store) mechanism on PCIe devices"
* tag 'irq-msi-2024-07-22' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (25 commits)
irqchip/gic-v3-its: Correctly fish out the DID for platform MSI
irqchip/gic-v3-its: Correctly honor the RID remapping
genirq/msi: Move msi_device_data to core
genirq/msi: Remove platform MSI leftovers
irqchip/irq-mvebu-icu: Remove platform MSI leftovers
irqchip/irq-mvebu-sei: Switch to MSI parent
irqchip/mvebu-odmi: Switch to parent MSI
irqchip/mvebu-gicp: Switch to MSI parent
irqchip/irq-mvebu-icu: Prepare for real per device MSI
irqchip/imx-mu-msi: Switch to MSI parent
irqchip/gic-v2m: Switch to device MSI
irqchip/gic_v3_mbi: Switch over to parent domain
genirq/msi: Remove platform_msi_create_device_domain()
irqchip/mbigen: Remove platform_msi_create_device_domain() fallback
irqchip/gic-v3-its: Switch platform MSI to MSI parent
irqchip/irq-msi-lib: Prepare for DOMAIN_BUS_WIRED_TO_MSI
irqchip/mbigen: Prepare for real per device MSI
irqchip/irq-msi-lib: Prepare for DEVICE MSI to replace platform MSI
irqchip/gic-v3-its: Provide MSI parent for PCI/MSI[-X]
irqchip/irq-msi-lib: Prepare for PCI MSI/MSIX
...
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/irq/irqdomain.c | 3 | ||||
-rw-r--r-- | kernel/irq/msi.c | 95 |
2 files changed, 22 insertions, 76 deletions
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index 91eaf6bfcbf0..cea8f6874b1f 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -503,7 +503,8 @@ struct irq_domain *irq_find_matching_fwspec(struct irq_fwspec *fwspec, struct fwnode_handle *fwnode = fwspec->fwnode; int rc; - /* We might want to match the legacy controller last since + /* + * We might want to match the legacy controller last since * it might potentially be set to match all interrupts in * the absence of a device node. This isn't a problem so far * yet though... diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index 2024f89baea4..5fa0547ece0c 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -8,18 +8,34 @@ * This file contains common code to support Message Signaled Interrupts for * PCI compatible and non PCI compatible devices. */ -#include <linux/types.h> #include <linux/device.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/msi.h> +#include <linux/mutex.h> +#include <linux/pci.h> #include <linux/slab.h> #include <linux/sysfs.h> -#include <linux/pci.h> +#include <linux/types.h> +#include <linux/xarray.h> #include "internals.h" /** + * struct msi_device_data - MSI per device data + * @properties: MSI properties which are interesting to drivers + * @mutex: Mutex protecting the MSI descriptor store + * @__domains: Internal data for per device MSI domains + * @__iter_idx: Index to search the next entry for iterators + */ +struct msi_device_data { + unsigned long properties; + struct mutex mutex; + struct msi_dev_domain __domains[MSI_MAX_DEVICE_IRQDOMAINS]; + unsigned long __iter_idx; +}; + +/** * struct msi_ctrl - MSI internal management control structure * @domid: ID of the domain on which management operations should be done * @first: First (hardware) slot index to operate on @@ -1088,8 +1104,8 @@ bool msi_match_device_irq_domain(struct device *dev, unsigned int domid, return ret; } -int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev, - int nvec, msi_alloc_info_t *arg) +static int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev, + int nvec, msi_alloc_info_t *arg) { struct msi_domain_info *info = domain->host_data; struct msi_domain_ops *ops = info->ops; @@ -1097,77 +1113,6 @@ int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev, return ops->msi_prepare(domain, dev, nvec, arg); } -int msi_domain_populate_irqs(struct irq_domain *domain, struct device *dev, - int virq_base, int nvec, msi_alloc_info_t *arg) -{ - struct msi_domain_info *info = domain->host_data; - struct msi_domain_ops *ops = info->ops; - struct msi_ctrl ctrl = { - .domid = MSI_DEFAULT_DOMAIN, - .first = virq_base, - .last = virq_base + nvec - 1, - }; - struct msi_desc *desc; - struct xarray *xa; - int ret, virq; - - msi_lock_descs(dev); - - if (!msi_ctrl_valid(dev, &ctrl)) { - ret = -EINVAL; - goto unlock; - } - - ret = msi_domain_add_simple_msi_descs(dev, &ctrl); - if (ret) - goto unlock; - - xa = &dev->msi.data->__domains[ctrl.domid].store; - - for (virq = virq_base; virq < virq_base + nvec; virq++) { - desc = xa_load(xa, virq); - desc->irq = virq; - - ops->set_desc(arg, desc); - ret = irq_domain_alloc_irqs_hierarchy(domain, virq, 1, arg); - if (ret) - goto fail; - - irq_set_msi_desc(virq, desc); - } - msi_unlock_descs(dev); - return 0; - -fail: - for (--virq; virq >= virq_base; virq--) { - msi_domain_depopulate_descs(dev, virq, 1); - irq_domain_free_irqs_common(domain, virq, 1); - } - msi_domain_free_descs(dev, &ctrl); -unlock: - msi_unlock_descs(dev); - return ret; -} - -void msi_domain_depopulate_descs(struct device *dev, int virq_base, int nvec) -{ - struct msi_ctrl ctrl = { - .domid = MSI_DEFAULT_DOMAIN, - .first = virq_base, - .last = virq_base + nvec - 1, - }; - struct msi_desc *desc; - struct xarray *xa; - unsigned long idx; - - if (!msi_ctrl_valid(dev, &ctrl)) - return; - - xa = &dev->msi.data->__domains[ctrl.domid].store; - xa_for_each_range(xa, idx, desc, ctrl.first, ctrl.last) - desc->irq = 0; -} - /* * Carefully check whether the device can use reservation mode. If * reservation mode is enabled then the early activation will assign a |