[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250807070917.2245463-2-hongxing.zhu@nxp.com>
Date: Thu, 7 Aug 2025 15:09:16 +0800
From: Richard Zhu <hongxing.zhu@....com>
To: frank.li@....com,
Zhiqiang.Hou@....com,
bhelgaas@...gle.com,
ilpo.jarvinen@...ux.intel.com,
Jonthan.Cameron@...wei.com,
lukas@...ner.de,
feng.tang@...ux.alibaba.com,
jingoohan1@...il.com,
mani@...nel.org,
lpieralisi@...nel.org,
kwilczynski@...nel.org,
robh@...nel.org
Cc: linux-pci@...r.kernel.org,
linux-kernel@...r.kernel.org,
imx@...ts.linux.dev,
Richard Zhu <hongxing.zhu@....com>
Subject: [PATCH v1 1/2] PCI/portdrv: Use get_service_irqs() callback to get PME/AER irqs
Some PCI host bridges have limitation that AER/PME can't work over MSI.
Vendors route the AER/PME via the dedicated SPI interrupt which is only
handled by the controller driver.
Add the generic get_service_irqs() callback for bridge, to let portdrv
can fetch the vendor specific AER/PME interrupter by it.
Signed-off-by: Richard Zhu <hongxing.zhu@....com>
---
drivers/pci/pcie/portdrv.c | 7 +++++++
include/linux/pci.h | 1 +
2 files changed, 8 insertions(+)
diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c
index e8318fd5f6ed5..035e6425ce034 100644
--- a/drivers/pci/pcie/portdrv.c
+++ b/drivers/pci/pcie/portdrv.c
@@ -176,11 +176,18 @@ static int pcie_port_enable_irq_vec(struct pci_dev *dev, int *irqs, int mask)
*/
static int pcie_init_service_irqs(struct pci_dev *dev, int *irqs, int mask)
{
+ struct pci_host_bridge *host_bridge = pci_find_host_bridge(dev->bus);
int ret, i;
for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
irqs[i] = -1;
+ if (host_bridge->get_service_irqs) {
+ ret = host_bridge->get_service_irqs(host_bridge, irqs, mask);
+ if (ret > 0)
+ return 0;
+ }
+
/*
* If we support PME but can't use MSI/MSI-X for it, we have to
* fall back to INTx or other interrupts, e.g., a system shared
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 05e68f35f3923..e681f2e6adc17 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -597,6 +597,7 @@ struct pci_host_bridge {
u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */
int (*map_irq)(const struct pci_dev *, u8, u8);
void (*release_fn)(struct pci_host_bridge *);
+ int (*get_service_irqs)(struct pci_host_bridge *bridge, int *irqs, int mask);
int (*enable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
void (*disable_device)(struct pci_host_bridge *bridge, struct pci_dev *dev);
void *release_data;
--
2.37.1
Powered by blists - more mailing lists