Loading Documentation/devicetree/bindings/pci/pci-ep.yaml +68 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading drivers/base/platform-msi.c +1 −0 Original line number Diff line number Diff line Loading @@ -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); drivers/irqchip/irq-gic-v3-its-msi-parent.c +8 −0 Original line number Diff line number Diff line Loading @@ -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; } Loading drivers/irqchip/irq-gic-v3-its.c +1 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading include/linux/irqdomain.h +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) Loading Loading
Documentation/devicetree/bindings/pci/pci-ep.yaml +68 −0 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading
drivers/base/platform-msi.c +1 −0 Original line number Diff line number Diff line Loading @@ -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);
drivers/irqchip/irq-gic-v3-its-msi-parent.c +8 −0 Original line number Diff line number Diff line Loading @@ -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; } Loading
drivers/irqchip/irq-gic-v3-its.c +1 −1 Original line number Diff line number Diff line Loading @@ -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; } Loading
include/linux/irqdomain.h +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) Loading