Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'irq/platform-msi' into irq/msi

Pull in the platform MSI/GIC changes which are seperate for the PCI
endpoint driver updates.

+85 -1
+68
Documentation/devicetree/bindings/pci/pci-ep.yaml
··· 17 17 $nodename: 18 18 pattern: "^pcie-ep@" 19 19 20 + iommu-map: 21 + $ref: /schemas/types.yaml#/definitions/uint32-matrix 22 + items: 23 + items: 24 + - description: Device ID (see msi-map) base 25 + maximum: 0x7ffff 26 + - description: phandle to IOMMU 27 + - description: IOMMU specifier base (currently always 1 cell) 28 + - description: Number of Device IDs 29 + maximum: 0x80000 30 + 31 + iommu-map-mask: 32 + description: 33 + A mask to be applied to each Device ID prior to being mapped to an 34 + IOMMU specifier per the iommu-map property. 35 + $ref: /schemas/types.yaml#/definitions/uint32 36 + maximum: 0x7ffff 37 + 20 38 max-functions: 21 39 description: Maximum number of functions that can be configured 22 40 $ref: /schemas/types.yaml#/definitions/uint8 ··· 52 34 max-link-speed: 53 35 $ref: /schemas/types.yaml#/definitions/uint32 54 36 enum: [ 1, 2, 3, 4 ] 37 + 38 + msi-map: 39 + description: | 40 + Maps a Device ID to an MSI and associated MSI specifier data. 41 + 42 + A PCI Endpoint (EP) can use MSI as a doorbell function. This is achieved by 43 + mapping the MSI controller's address into PCI BAR<n>. The PCI Root Complex 44 + can write to this BAR<n>, triggering the EP to generate IRQ. This notifies 45 + the EP-side driver of an event, eliminating the need for the driver to 46 + continuously poll for status changes. 47 + 48 + However, the EP cannot rely on Requester ID (RID) because the RID is 49 + determined by the PCI topology of the host system. Since the EP may be 50 + connected to different PCI hosts, the RID can vary between systems and is 51 + therefore not a reliable identifier. 52 + 53 + Each EP can support up to 8 physical functions and up to 65,536 virtual 54 + functions. To uniquely identify each child device, a device ID is defined 55 + as 56 + - Bits [2:0] for the function number (func) 57 + - Bits [18:3] for the virtual function index (vfunc) 58 + 59 + The resulting device ID is computed as: 60 + 61 + (func & 0x7) | (vfunc << 3) 62 + 63 + The property is an arbitrary number of tuples of 64 + (device-id-base, msi, msi-base,length). 65 + 66 + Any Device ID id in the interval [id-base, id-base + length) is 67 + associated with the listed MSI, with the MSI specifier 68 + (id - id-base + msi-base). 69 + $ref: /schemas/types.yaml#/definitions/uint32-matrix 70 + items: 71 + items: 72 + - description: The Device ID base matched by the entry 73 + maximum: 0x7ffff 74 + - description: phandle to msi-controller node 75 + - description: (optional) The msi-specifier produced for the first 76 + Device ID matched by the entry. Currently, msi-specifier is 0 or 77 + 1 cells. 78 + - description: The length of consecutive Device IDs following the 79 + Device ID base 80 + maximum: 0x80000 81 + 82 + msi-map-mask: 83 + description: A mask to be applied to each Device ID prior to being 84 + mapped to an msi-specifier per the msi-map property. 85 + $ref: /schemas/types.yaml#/definitions/uint32 86 + maximum: 0x7ffff 55 87 56 88 num-lanes: 57 89 description: maximum number of lanes
+1
drivers/base/platform-msi.c
··· 95 95 void platform_device_msi_free_irqs_all(struct device *dev) 96 96 { 97 97 msi_domain_free_irqs_all(dev, MSI_DEFAULT_DOMAIN); 98 + msi_remove_device_irq_domain(dev, MSI_DEFAULT_DOMAIN); 98 99 } 99 100 EXPORT_SYMBOL_GPL(platform_device_msi_free_irqs_all);
+8
drivers/irqchip/irq-gic-v3-its-msi-parent.c
··· 118 118 index++; 119 119 } while (!ret); 120 120 121 + if (ret) { 122 + struct device_node *np = NULL; 123 + 124 + ret = of_map_id(dev->of_node, dev->id, "msi-map", "msi-map-mask", &np, dev_id); 125 + if (np) 126 + of_node_put(np); 127 + } 128 + 121 129 return ret; 122 130 } 123 131
+1 -1
drivers/irqchip/irq-gic-v3-its.c
··· 5140 5140 irq_domain_update_bus_token(inner_domain, DOMAIN_BUS_NEXUS); 5141 5141 5142 5142 inner_domain->msi_parent_ops = &gic_v3_its_msi_parent_ops; 5143 - inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT; 5143 + inner_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT | IRQ_DOMAIN_FLAG_MSI_IMMUTABLE; 5144 5144 5145 5145 return 0; 5146 5146 }
+7
include/linux/irqdomain.h
··· 231 231 /* Irq domain must destroy generic chips when removed */ 232 232 IRQ_DOMAIN_FLAG_DESTROY_GC = (1 << 10), 233 233 234 + /* Address and data pair is mutable when irq_set_affinity() */ 235 + IRQ_DOMAIN_FLAG_MSI_IMMUTABLE = (1 << 11), 236 + 234 237 /* 235 238 * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved 236 239 * for implementation specific purposes and ignored by the ··· 696 693 return domain->flags & IRQ_DOMAIN_FLAG_MSI_DEVICE; 697 694 } 698 695 696 + static inline bool irq_domain_is_msi_immutable(struct irq_domain *domain) 697 + { 698 + return domain->flags & IRQ_DOMAIN_FLAG_MSI_IMMUTABLE; 699 + } 699 700 #else /* CONFIG_IRQ_DOMAIN_HIERARCHY */ 700 701 static inline int irq_domain_alloc_irqs(struct irq_domain *domain, 701 702 unsigned int nr_irqs, int node, void *arg)