diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2025-05-08 19:17:16 +0200 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2025-05-08 19:17:16 +0200 |
commit | a1d8a8309367565dc658ae31dcc256beb9f0423b (patch) | |
tree | 8c665be3c9187334f0b991d5729e52d224010905 | |
parent | 9357e329cdeb6f2d27b431a22d4965700bec478a (diff) | |
parent | f1680d9081e161925c3aca81231ee867c95890b0 (diff) |
Merge branch 'irq/platform-msi' into irq/msi
Pull in the platform MSI/GIC changes which are seperate for the PCI
endpoint driver updates.
-rw-r--r-- | Documentation/devicetree/bindings/pci/pci-ep.yaml | 68 | ||||
-rw-r--r-- | drivers/base/platform-msi.c | 1 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3-its-msi-parent.c | 8 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3-its.c | 2 | ||||
-rw-r--r-- | include/linux/irqdomain.h | 7 |
5 files changed, 85 insertions, 1 deletions
diff --git a/Documentation/devicetree/bindings/pci/pci-ep.yaml b/Documentation/devicetree/bindings/pci/pci-ep.yaml index f75000e3093d..214caa4ec3d5 100644 --- a/Documentation/devicetree/bindings/pci/pci-ep.yaml +++ b/Documentation/devicetree/bindings/pci/pci-ep.yaml @@ -17,6 +17,24 @@ properties: $nodename: pattern: "^pcie-ep@" + iommu-map: + $ref: /schemas/types.yaml#/definitions/uint32-matrix + items: + items: + - description: Device ID (see msi-map) base + maximum: 0x7ffff + - description: phandle to IOMMU + - description: IOMMU specifier base (currently always 1 cell) + - description: Number of Device IDs + maximum: 0x80000 + + iommu-map-mask: + description: + A mask to be applied to each Device ID prior to being mapped to an + IOMMU specifier per the iommu-map property. + $ref: /schemas/types.yaml#/definitions/uint32 + maximum: 0x7ffff + max-functions: description: Maximum number of functions that can be configured $ref: /schemas/types.yaml#/definitions/uint8 @@ -35,6 +53,56 @@ properties: $ref: /schemas/types.yaml#/definitions/uint32 enum: [ 1, 2, 3, 4 ] + msi-map: + description: | + Maps a Device ID to an MSI and associated MSI specifier data. + + A PCI Endpoint (EP) can use MSI as a doorbell function. This is achieved by + mapping the MSI controller's address into PCI BAR<n>. The PCI Root Complex + can write to this BAR<n>, triggering the EP to generate IRQ. This notifies + the EP-side driver of an event, eliminating the need for the driver to + continuously poll for status changes. + + However, the EP cannot rely on Requester ID (RID) because the RID is + determined by the PCI topology of the host system. Since the EP may be + connected to different PCI hosts, the RID can vary between systems and is + therefore not a reliable identifier. + + Each EP can support up to 8 physical functions and up to 65,536 virtual + functions. To uniquely identify each child device, a device ID is defined + as + - Bits [2:0] for the function number (func) + - Bits [18:3] for the virtual function index (vfunc) + + The resulting device ID is computed as: + + (func & 0x7) | (vfunc << 3) + + The property is an arbitrary number of tuples of + (device-id-base, msi, msi-base,length). + + Any Device ID id in the interval [id-base, id-base + length) is + associated with the listed MSI, with the MSI specifier + (id - id-base + msi-base). + $ref: /schemas/types.yaml#/definitions/uint32-matrix + items: + items: + - description: The Device ID base matched by the entry + maximum: 0x7ffff + - description: phandle to msi-controller node + - description: (optional) The msi-specifier produced for the first + Device ID matched by the entry. Currently, msi-specifier is 0 or + 1 cells. + - description: The length of consecutive Device IDs following the + Device ID base + maximum: 0x80000 + + msi-map-mask: + description: A mask to be applied to each Device ID prior to being + mapped to an msi-specifier per the msi-map property. + $ref: /schemas/types.yaml#/definitions/uint32 + maximum: 0x7ffff + num-lanes: description: maximum number of lanes $ref: /schemas/types.yaml#/definitions/uint32 diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c index 0e60dd650b5e..70db08f3ac6f 100644 --- a/drivers/base/platform-msi.c +++ b/drivers/base/platform-msi.c @@ -95,5 +95,6 @@ EXPORT_SYMBOL_GPL(platform_device_msi_init_and_alloc_irqs); void platform_device_msi_free_irqs_all(struct device *dev) { msi_domain_free_irqs_all(dev, MSI_DEFAULT_DOMAIN); + msi_remove_device_irq_domain(dev, MSI_DEFAULT_DOMAIN); } EXPORT_SYMBOL_GPL(platform_device_msi_free_irqs_all); diff --git a/drivers/irqchip/irq-gic-v3-its-msi-parent.c b/drivers/irqchip/irq-gic-v3-its-msi-parent.c index bdb04c808148..68f9ba4085ce 100644 --- a/drivers/irqchip/irq-gic-v3-its-msi-parent.c +++ b/drivers/irqchip/irq-gic-v3-its-msi-parent.c @@ -118,6 +118,14 @@ static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *dev, index++; } while (!ret); + if (ret) { + struct device_node *np = NULL; + + ret = of_map_id(dev->of_node, dev->id, "msi-map", "msi-map-mask", &np, dev_id); + if (np) + of_node_put(np); + } + return ret; } diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 0115ad6c8259..fd6e7c170d37 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -5140,7 +5140,7 @@ static int its_init_domain(struct its_node *its) irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS); inner_domain->msi_parent_ops = &gic_v3_its_msi_parent_ops; - inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT; + inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT | IRQ_DOMAIN_FLAG_MSI_IMMUTABLE; return 0; } diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h index 2f955716cf82..13cbacd1b5dc 100644 --- a/include/linux/irqdomain.h +++ b/include/linux/irqdomain.h @@ -231,6 +231,9 @@ enum { /* Irq domain must destroy generic chips when removed */ IRQ_DOMAIN_FLAG_DESTROY_GC = (1 << 10), + /* Address and data pair is mutable when irq_set_affinity() */ + IRQ_DOMAIN_FLAG_MSI_IMMUTABLE = (1 << 11), + /* * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved * for implementation specific purposes and ignored by the @@ -693,6 +696,10 @@ static inline bool irq_domain_is_msi_device(struct irq_domain *domain) return domain->flags & IRQ_DOMAIN_FLAG_MSI_DEVICE; } +static inline bool irq_domain_is_msi_immutable(struct irq_domain *domain) +{ + return domain->flags & IRQ_DOMAIN_FLAG_MSI_IMMUTABLE; +} #else /* CONFIG_IRQ_DOMAIN_HIERARCHY */ static inline int irq_domain_alloc_irqs(struct irq_domain *domain, unsigned int nr_irqs, int node, void *arg) |