@@ -196,6 +196,24 @@ int pciehp_get_raw_indicator_status(struct hotplug_slot *h_slot, u8 *status);
int pciehp_slot_reset(struct pcie_device *dev);
+#ifdef CONFIG_HOTPLUG_PCI_PCIE_EMUL
+bool pciehp_emul_will_manage(struct pci_dev *dev);
+int pciehp_emul_attach(struct controller *ctrl);
+void pciehp_emul_detach(struct controller *ctrl);
+#else
+static inline bool pciehp_emul_will_manage(struct pci_dev *dev)
+{
+ return false;
+};
+
+static inline int pciehp_emul_attach(struct controller *ctrl)
+{
+ return 0;
+};
+
+static inline void pciehp_emul_detach(struct controller *ctrl) {};
+#endif
+
static inline const char *slot_name(struct controller *ctrl)
{
return hotplug_slot_name(&ctrl->hotplug_slot);
@@ -370,3 +370,11 @@ void pciehp_emul_detach(struct controller *ctrl)
kfree(emul);
}
+
+static int __init pciehp_emul_init(void)
+{
+ pcie_port_slot_emulated = &pciehp_emul_will_manage;
+
+ return 0;
+}
+postcore_initcall(pciehp_emul_init);
@@ -1003,6 +1003,9 @@ struct controller *pcie_init(struct pcie_device *dev)
ctrl->pcie = dev;
ctrl->depth = pcie_hotplug_depth(dev->port);
+ if (pciehp_emul_will_manage(pdev) && pciehp_emul_attach(ctrl))
+ return NULL;
+
pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap);
if (pdev->hotplug_user_indicators)
@@ -19,6 +19,9 @@
#include "../pci.h"
#include "portdrv.h"
+/* Hook for hotplug emulation driver */
+bool (*pcie_port_slot_emulated)(struct pci_dev *dev);
+
struct portdrv_service_data {
struct pcie_port_service_driver *drv;
struct device *dev;
@@ -1656,7 +1656,11 @@ extern bool pcie_ports_native;
#define pcie_ports_native false
#endif
+#ifdef CONFIG_HOTPLUG_PCI_PCIE_EMUL
+extern bool (*pcie_port_slot_emulated)(struct pci_dev *dev);
+#else
#define pcie_port_slot_emulated(dev) false
+#endif
#define PCIE_LINK_STATE_L0S BIT(0)
#define PCIE_LINK_STATE_L1 BIT(1)
Add pcie_port_slot_emulated hook and wire it up to pciehp_emul. Add pciehp_emul_{attach,detach} calls in pciehp and move the management check into the attach caller. Signed-off-by: Jonathan Derrick <jonathan.derrick@linux.dev> --- drivers/pci/hotplug/pciehp.h | 18 ++++++++++++++++++ drivers/pci/hotplug/pciehp_emul.c | 8 ++++++++ drivers/pci/hotplug/pciehp_hpc.c | 3 +++ drivers/pci/pcie/portdrv_core.c | 3 +++ include/linux/pci.h | 4 ++++ 5 files changed, 36 insertions(+)