|
9 | 9 | */
|
10 | 10 |
|
11 | 11 | #include <linux/export.h>
|
| 12 | +#include <linux/irq.h> |
12 | 13 |
|
13 | 14 | #include "msi.h"
|
14 | 15 |
|
@@ -250,6 +251,48 @@ int pci_irq_vector(struct pci_dev *dev, unsigned int nr)
|
250 | 251 | }
|
251 | 252 | EXPORT_SYMBOL(pci_irq_vector);
|
252 | 253 |
|
| 254 | +/** |
| 255 | + * pci_irq_get_affinity() - Get a device interrupt vector affinity |
| 256 | + * @dev: the PCI device to operate on |
| 257 | + * @nr: device-relative interrupt vector index (0-based); has different |
| 258 | + * meanings, depending on interrupt mode |
| 259 | + * MSI-X the index in the MSI-X vector table |
| 260 | + * MSI the index of the enabled MSI vectors |
| 261 | + * INTx must be 0 |
| 262 | + * |
| 263 | + * Return: MSI/MSI-X vector affinity, NULL if @nr is out of range or if |
| 264 | + * the MSI(-X) vector was allocated without explicit affinity |
| 265 | + * requirements (e.g., by pci_enable_msi(), pci_enable_msix_range(), or |
| 266 | + * pci_alloc_irq_vectors() without the %PCI_IRQ_AFFINITY flag). Return a |
| 267 | + * generic set of CPU IDs representing all possible CPUs available |
| 268 | + * during system boot if the device is in legacy INTx mode. |
| 269 | + */ |
| 270 | +const struct cpumask *pci_irq_get_affinity(struct pci_dev *dev, int nr) |
| 271 | +{ |
| 272 | + int idx, irq = pci_irq_vector(dev, nr); |
| 273 | + struct msi_desc *desc; |
| 274 | + |
| 275 | + if (WARN_ON_ONCE(irq <= 0)) |
| 276 | + return NULL; |
| 277 | + |
| 278 | + desc = irq_get_msi_desc(irq); |
| 279 | + /* Non-MSI does not have the information handy */ |
| 280 | + if (!desc) |
| 281 | + return cpu_possible_mask; |
| 282 | + |
| 283 | + /* MSI[X] interrupts can be allocated without affinity descriptor */ |
| 284 | + if (!desc->affinity) |
| 285 | + return NULL; |
| 286 | + |
| 287 | + /* |
| 288 | + * MSI has a mask array in the descriptor. |
| 289 | + * MSI-X has a single mask. |
| 290 | + */ |
| 291 | + idx = dev->msi_enabled ? nr : 0; |
| 292 | + return &desc->affinity[idx].mask; |
| 293 | +} |
| 294 | +EXPORT_SYMBOL(pci_irq_get_affinity); |
| 295 | + |
253 | 296 | /**
|
254 | 297 | * pci_free_irq_vectors() - Free previously allocated IRQs for a device
|
255 | 298 | * @dev: the PCI device to operate on
|
|
0 commit comments