When a PCIe-based FPGA card is reprogrammed, it temporarily disappears from the PCIe bus. This needs to be managed by disabling the link to avoid PCIe errors while the device is not present. Also, re-enabling the link and rescan the PCI devices must be performed after loading the new images. Export functions from pciehp driver necessary for removing and reconfiguring the PCI devices below a PCI hotplug bridge. Signed-off-by: Tianfei Zhang <tianfei.zhang@xxxxxxxxx> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@xxxxxxxxxxxxxxx> --- drivers/pci/hotplug/pciehp.h | 2 ++ drivers/pci/hotplug/pciehp_hpc.c | 5 ++++- drivers/pci/hotplug/pciehp_pci.c | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index e0a614acee05..c7f455a3b08f 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -194,6 +194,8 @@ int pciehp_get_raw_indicator_status(struct hotplug_slot *h_slot, u8 *status); int pciehp_slot_reset(struct pcie_device *dev); +int pciehp_link_enable(struct controller *ctrl); + static inline const char *slot_name(struct controller *ctrl) { return hotplug_slot_name(&ctrl->hotplug_slot); diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 10e9670eea0b..11e4bc58aec0 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -328,6 +328,7 @@ int pciehp_check_link_status(struct controller *ctrl) return 0; } +EXPORT_SYMBOL_NS_GPL(pciehp_check_link_status, PCIEHP); static int __pciehp_link_set(struct controller *ctrl, bool enable) { @@ -346,10 +347,11 @@ static int __pciehp_link_set(struct controller *ctrl, bool enable) return 0; } -static int pciehp_link_enable(struct controller *ctrl) +int pciehp_link_enable(struct controller *ctrl) { return __pciehp_link_set(ctrl, true); } +EXPORT_SYMBOL_NS_GPL(pciehp_link_enable, PCIEHP); int pciehp_get_raw_indicator_status(struct hotplug_slot *hotplug_slot, u8 *status) @@ -482,6 +484,7 @@ int pciehp_query_power_fault(struct controller *ctrl) pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status); return !!(slot_status & PCI_EXP_SLTSTA_PFD); } +EXPORT_SYMBOL_NS_GPL(pciehp_query_power_fault, PCIEHP); int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot, u8 status) diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index d17f3bf36f70..dd44e999b777 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c @@ -69,6 +69,7 @@ int pciehp_configure_device(struct controller *ctrl) pci_unlock_rescan_remove(); return ret; } +EXPORT_SYMBOL_NS_GPL(pciehp_configure_device, PCIEHP); /** * pciehp_unconfigure_device() - remove PCI devices below a hotplug bridge @@ -120,3 +121,4 @@ void pciehp_unconfigure_device(struct controller *ctrl, bool presence) pci_unlock_rescan_remove(); } +EXPORT_SYMBOL_NS_GPL(pciehp_unconfigure_device, PCIEHP); -- 2.38.1