[PATCH v2 06/10] PCI/portdrv: Group PCI Exp Cap services into a single mask
From: Yazen Ghannam
Date: Fri Sep 18 2026 - 12:33:13 EST
PME, hotplug, and bandwidth notification are all services of the PCI
Express Capability and share a single MSI/MSI-X interrupt vector. The
set of these services is open-coded as a bitmask in more than one place.
That is repetitive and easy to get out of sync as services are added.
Define a single PCIE_PORT_SERVICES_EXPCAP mask beside the service bits
it groups, and use it in place of the open-coded expressions. Assign the
shared vector by iterating the mask rather than naming each service
again, so adding one is a single edit.
Iterating narrows which irqs[] entries get written. The open-coded
version filled the slot of every service in the group as soon as one of
them was in the mask. Those extra entries were never read, since
pcie_init_service_irqs() presets the array to -1 and
pcie_port_device_register() only reads the slot of a service it found.
No functional change intended.
Assisted-by: LLM
Signed-off-by: Yazen Ghannam <yazen.ghannam@xxxxxxx>
---
drivers/pci/pcie/portdrv.c | 16 ++++++++--------
drivers/pci/pcie/portdrv.h | 5 +++++
2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
index a9cbfc1d2bc7..ca1b9dbb8b08 100644
--- a/drivers/pci/pcie/portdrv.c
+++ b/drivers/pci/pcie/portdrv.c
@@ -67,8 +67,7 @@ static int pcie_message_numbers(struct pci_dev *dev, int mask,
* 7.8.2, 7.10.10, 7.31.2.
*/
- if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP |
- PCIE_PORT_SERVICE_BWCTRL)) {
+ if (mask & PCIE_PORT_SERVICES_EXPCAP) {
pcie_capability_read_word(dev, PCI_EXP_FLAGS, ®16);
*pme = FIELD_GET(PCI_EXP_FLAGS_IRQ, reg16);
nvec = *pme + 1;
@@ -114,6 +113,8 @@ static int pcie_port_enable_irq_vec(struct pci_dev *dev, int *irqs, int mask)
{
int nr_entries, nvec, pcie_irq;
u32 pme = 0, aer = 0, dpc = 0;
+ unsigned long expcap;
+ unsigned int i;
/* Allocate the maximum possible number of MSI/MSI-X vectors */
nr_entries = pci_alloc_irq_vectors(dev, 1, PCIE_PORT_MAX_MSI_ENTRIES,
@@ -148,13 +149,12 @@ static int pcie_port_enable_irq_vec(struct pci_dev *dev, int *irqs, int mask)
return nr_entries;
}
- /* PME, hotplug and bandwidth notification share an MSI/MSI-X vector */
- if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP |
- PCIE_PORT_SERVICE_BWCTRL)) {
+ /* These services share the PCIe Capability Interrupt Message Number */
+ expcap = mask & PCIE_PORT_SERVICES_EXPCAP;
+ if (expcap) {
pcie_irq = pci_irq_vector(dev, pme);
- irqs[PCIE_PORT_SERVICE_PME_SHIFT] = pcie_irq;
- irqs[PCIE_PORT_SERVICE_HP_SHIFT] = pcie_irq;
- irqs[PCIE_PORT_SERVICE_BWCTRL_SHIFT] = pcie_irq;
+ for_each_set_bit(i, &expcap, PCIE_PORT_DEVICE_MAXSERVICES)
+ irqs[i] = pcie_irq;
}
if (mask & PCIE_PORT_SERVICE_AER)
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
index cc58bf2f2c84..bf18ca415990 100644
--- a/drivers/pci/pcie/portdrv.h
+++ b/drivers/pci/pcie/portdrv.h
@@ -23,6 +23,11 @@
#define PCIE_PORT_SERVICE_BWCTRL_SHIFT 4 /* Bandwidth Controller (notifications) */
#define PCIE_PORT_SERVICE_BWCTRL (1 << PCIE_PORT_SERVICE_BWCTRL_SHIFT)
+/* Services sharing the PCI Express Capability Interrupt Message Number */
+#define PCIE_PORT_SERVICES_EXPCAP (PCIE_PORT_SERVICE_PME | \
+ PCIE_PORT_SERVICE_HP | \
+ PCIE_PORT_SERVICE_BWCTRL)
+
#define PCIE_PORT_DEVICE_MAXSERVICES 5
extern bool pcie_ports_dpc_native;
--
2.43.0