Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0 2 : /* 3 : * PCI Message Signaled Interrupt (MSI) - irqdomain support 4 : */ 5 : #include <linux/acpi_iort.h> 6 : #include <linux/irqdomain.h> 7 : #include <linux/of_irq.h> 8 : 9 : #include "msi.h" 10 : 11 0 : int pci_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 12 : { 13 : struct irq_domain *domain; 14 : 15 0 : domain = dev_get_msi_domain(&dev->dev); 16 0 : if (domain && irq_domain_is_hierarchy(domain)) 17 0 : return msi_domain_alloc_irqs_descs_locked(domain, &dev->dev, nvec); 18 : 19 0 : return pci_msi_legacy_setup_msi_irqs(dev, nvec, type); 20 : } 21 : 22 0 : void pci_msi_teardown_msi_irqs(struct pci_dev *dev) 23 : { 24 : struct irq_domain *domain; 25 : 26 0 : domain = dev_get_msi_domain(&dev->dev); 27 0 : if (domain && irq_domain_is_hierarchy(domain)) 28 0 : msi_domain_free_irqs_descs_locked(domain, &dev->dev); 29 : else 30 0 : pci_msi_legacy_teardown_msi_irqs(dev); 31 0 : msi_free_msi_descs(&dev->dev); 32 0 : } 33 : 34 : /** 35 : * pci_msi_domain_write_msg - Helper to write MSI message to PCI config space 36 : * @irq_data: Pointer to interrupt data of the MSI interrupt 37 : * @msg: Pointer to the message 38 : */ 39 0 : static void pci_msi_domain_write_msg(struct irq_data *irq_data, struct msi_msg *msg) 40 : { 41 0 : struct msi_desc *desc = irq_data_get_msi_desc(irq_data); 42 : 43 : /* 44 : * For MSI-X desc->irq is always equal to irq_data->irq. For 45 : * MSI only the first interrupt of MULTI MSI passes the test. 46 : */ 47 0 : if (desc->irq == irq_data->irq) 48 0 : __pci_write_msi_msg(desc, msg); 49 0 : } 50 : 51 : /** 52 : * pci_msi_domain_calc_hwirq - Generate a unique ID for an MSI source 53 : * @desc: Pointer to the MSI descriptor 54 : * 55 : * The ID number is only used within the irqdomain. 56 : */ 57 0 : static irq_hw_number_t pci_msi_domain_calc_hwirq(struct msi_desc *desc) 58 : { 59 0 : struct pci_dev *dev = msi_desc_to_pci_dev(desc); 60 : 61 0 : return (irq_hw_number_t)desc->msi_index | 62 0 : pci_dev_id(dev) << 11 | 63 0 : (pci_domain_nr(dev->bus) & 0xFFFFFFFF) << 27; 64 : } 65 : 66 : static inline bool pci_msi_desc_is_multi_msi(struct msi_desc *desc) 67 : { 68 0 : return !desc->pci.msi_attrib.is_msix && desc->nvec_used > 1; 69 : } 70 : 71 : /** 72 : * pci_msi_domain_check_cap - Verify that @domain supports the capabilities 73 : * for @dev 74 : * @domain: The interrupt domain to check 75 : * @info: The domain info for verification 76 : * @dev: The device to check 77 : * 78 : * Returns: 79 : * 0 if the functionality is supported 80 : * 1 if Multi MSI is requested, but the domain does not support it 81 : * -ENOTSUPP otherwise 82 : */ 83 0 : static int pci_msi_domain_check_cap(struct irq_domain *domain, 84 : struct msi_domain_info *info, 85 : struct device *dev) 86 : { 87 0 : struct msi_desc *desc = msi_first_desc(dev, MSI_DESC_ALL); 88 : 89 : /* Special handling to support __pci_enable_msi_range() */ 90 0 : if (pci_msi_desc_is_multi_msi(desc) && 91 0 : !(info->flags & MSI_FLAG_MULTI_PCI_MSI)) 92 : return 1; 93 : 94 0 : if (desc->pci.msi_attrib.is_msix) { 95 0 : if (!(info->flags & MSI_FLAG_PCI_MSIX)) 96 : return -ENOTSUPP; 97 : 98 0 : if (info->flags & MSI_FLAG_MSIX_CONTIGUOUS) { 99 0 : unsigned int idx = 0; 100 : 101 : /* Check for gaps in the entry indices */ 102 0 : msi_for_each_desc(desc, dev, MSI_DESC_ALL) { 103 0 : if (desc->msi_index != idx++) 104 : return -ENOTSUPP; 105 : } 106 : } 107 : } 108 : return 0; 109 : } 110 : 111 0 : static void pci_msi_domain_set_desc(msi_alloc_info_t *arg, 112 : struct msi_desc *desc) 113 : { 114 0 : arg->desc = desc; 115 0 : arg->hwirq = pci_msi_domain_calc_hwirq(desc); 116 0 : } 117 : 118 : static struct msi_domain_ops pci_msi_domain_ops_default = { 119 : .set_desc = pci_msi_domain_set_desc, 120 : .msi_check = pci_msi_domain_check_cap, 121 : }; 122 : 123 : static void pci_msi_domain_update_dom_ops(struct msi_domain_info *info) 124 : { 125 0 : struct msi_domain_ops *ops = info->ops; 126 : 127 0 : if (ops == NULL) { 128 0 : info->ops = &pci_msi_domain_ops_default; 129 : } else { 130 0 : if (ops->set_desc == NULL) 131 0 : ops->set_desc = pci_msi_domain_set_desc; 132 0 : if (ops->msi_check == NULL) 133 0 : ops->msi_check = pci_msi_domain_check_cap; 134 : } 135 : } 136 : 137 0 : static void pci_msi_domain_update_chip_ops(struct msi_domain_info *info) 138 : { 139 0 : struct irq_chip *chip = info->chip; 140 : 141 0 : BUG_ON(!chip); 142 0 : if (!chip->irq_write_msi_msg) 143 0 : chip->irq_write_msi_msg = pci_msi_domain_write_msg; 144 0 : if (!chip->irq_mask) 145 0 : chip->irq_mask = pci_msi_mask_irq; 146 0 : if (!chip->irq_unmask) 147 0 : chip->irq_unmask = pci_msi_unmask_irq; 148 0 : } 149 : 150 : /** 151 : * pci_msi_create_irq_domain - Create a MSI interrupt domain 152 : * @fwnode: Optional fwnode of the interrupt controller 153 : * @info: MSI domain info 154 : * @parent: Parent irq domain 155 : * 156 : * Updates the domain and chip ops and creates a MSI interrupt domain. 157 : * 158 : * Returns: 159 : * A domain pointer or NULL in case of failure. 160 : */ 161 0 : struct irq_domain *pci_msi_create_irq_domain(struct fwnode_handle *fwnode, 162 : struct msi_domain_info *info, 163 : struct irq_domain *parent) 164 : { 165 : struct irq_domain *domain; 166 : 167 0 : if (WARN_ON(info->flags & MSI_FLAG_LEVEL_CAPABLE)) 168 0 : info->flags &= ~MSI_FLAG_LEVEL_CAPABLE; 169 : 170 0 : if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS) 171 0 : pci_msi_domain_update_dom_ops(info); 172 0 : if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS) 173 0 : pci_msi_domain_update_chip_ops(info); 174 : 175 0 : info->flags |= MSI_FLAG_ACTIVATE_EARLY | MSI_FLAG_DEV_SYSFS; 176 : if (IS_ENABLED(CONFIG_GENERIC_IRQ_RESERVATION_MODE)) 177 : info->flags |= MSI_FLAG_MUST_REACTIVATE; 178 : 179 : /* PCI-MSI is oneshot-safe */ 180 0 : info->chip->flags |= IRQCHIP_ONESHOT_SAFE; 181 : 182 0 : domain = msi_create_irq_domain(fwnode, info, parent); 183 0 : if (!domain) 184 : return NULL; 185 : 186 0 : irq_domain_update_bus_token(domain, DOMAIN_BUS_PCI_MSI); 187 0 : return domain; 188 : } 189 : EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain); 190 : 191 : /* 192 : * Users of the generic MSI infrastructure expect a device to have a single ID, 193 : * so with DMA aliases we have to pick the least-worst compromise. Devices with 194 : * DMA phantom functions tend to still emit MSIs from the real function number, 195 : * so we ignore those and only consider topological aliases where either the 196 : * alias device or RID appears on a different bus number. We also make the 197 : * reasonable assumption that bridges are walked in an upstream direction (so 198 : * the last one seen wins), and the much braver assumption that the most likely 199 : * case is that of PCI->PCIe so we should always use the alias RID. This echoes 200 : * the logic from intel_irq_remapping's set_msi_sid(), which presumably works 201 : * well enough in practice; in the face of the horrible PCIe<->PCI-X conditions 202 : * for taking ownership all we can really do is close our eyes and hope... 203 : */ 204 0 : static int get_msi_id_cb(struct pci_dev *pdev, u16 alias, void *data) 205 : { 206 0 : u32 *pa = data; 207 0 : u8 bus = PCI_BUS_NUM(*pa); 208 : 209 0 : if (pdev->bus->number != bus || PCI_BUS_NUM(alias) != bus) 210 0 : *pa = alias; 211 : 212 0 : return 0; 213 : } 214 : 215 : /** 216 : * pci_msi_domain_get_msi_rid - Get the MSI requester id (RID) 217 : * @domain: The interrupt domain 218 : * @pdev: The PCI device. 219 : * 220 : * The RID for a device is formed from the alias, with a firmware 221 : * supplied mapping applied 222 : * 223 : * Returns: The RID. 224 : */ 225 0 : u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev) 226 : { 227 : struct device_node *of_node; 228 0 : u32 rid = pci_dev_id(pdev); 229 : 230 0 : pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); 231 : 232 0 : of_node = irq_domain_get_of_node(domain); 233 0 : rid = of_node ? of_msi_map_id(&pdev->dev, of_node, rid) : 234 0 : iort_msi_map_id(&pdev->dev, rid); 235 : 236 0 : return rid; 237 : } 238 : 239 : /** 240 : * pci_msi_get_device_domain - Get the MSI domain for a given PCI device 241 : * @pdev: The PCI device 242 : * 243 : * Use the firmware data to find a device-specific MSI domain 244 : * (i.e. not one that is set as a default). 245 : * 246 : * Returns: The corresponding MSI domain or NULL if none has been found. 247 : */ 248 0 : struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev) 249 : { 250 : struct irq_domain *dom; 251 0 : u32 rid = pci_dev_id(pdev); 252 : 253 0 : pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); 254 0 : dom = of_msi_map_get_device_domain(&pdev->dev, rid, DOMAIN_BUS_PCI_MSI); 255 : if (!dom) 256 0 : dom = iort_get_device_domain(&pdev->dev, rid, 257 : DOMAIN_BUS_PCI_MSI); 258 0 : return dom; 259 : } 260 : 261 : /** 262 : * pci_dev_has_special_msi_domain - Check whether the device is handled by 263 : * a non-standard PCI-MSI domain 264 : * @pdev: The PCI device to check. 265 : * 266 : * Returns: True if the device irqdomain or the bus irqdomain is 267 : * non-standard PCI/MSI. 268 : */ 269 0 : bool pci_dev_has_special_msi_domain(struct pci_dev *pdev) 270 : { 271 0 : struct irq_domain *dom = dev_get_msi_domain(&pdev->dev); 272 : 273 0 : if (!dom) 274 0 : dom = dev_get_msi_domain(&pdev->bus->dev); 275 : 276 0 : if (!dom) 277 : return true; 278 : 279 0 : return dom->bus_token != DOMAIN_BUS_PCI_MSI; 280 : }