diff options
Diffstat (limited to 'pkgs/patches-linux-5.15/0006-PCI-mvebu-Add-support-for-compiling-driver-as-module.patch')
-rw-r--r-- | pkgs/patches-linux-5.15/0006-PCI-mvebu-Add-support-for-compiling-driver-as-module.patch | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/pkgs/patches-linux-5.15/0006-PCI-mvebu-Add-support-for-compiling-driver-as-module.patch b/pkgs/patches-linux-5.15/0006-PCI-mvebu-Add-support-for-compiling-driver-as-module.patch new file mode 100644 index 0000000..2ff5eef --- /dev/null +++ b/pkgs/patches-linux-5.15/0006-PCI-mvebu-Add-support-for-compiling-driver-as-module.patch @@ -0,0 +1,175 @@ +From 2d12fdead984145ea791cac44c0b0ce25504f4c5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Sun, 31 Oct 2021 22:55:20 +0100 +Subject: [PATCH 06/90] PCI: mvebu: Add support for compiling driver as module +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Now when driver uses devm_pci_remap_iospace() function, it is possible +implement ->remove() callback for unbinding device from driver. + +Implement mvebu_pcie_remove() callback with proper cleanup phase, drop +driver's suppress_bind_attrs flag and switch type of CONFIG_PCI_MVEBU +option from bool to tristate. + +This allows to compile pci-mvebu.c driver as loadable module pci-mvebu.ko +with ability to unload it. + +Signed-off-by: Pali Rohár <pali@kernel.org> +--- + drivers/pci/controller/Kconfig | 2 +- + drivers/pci/controller/pci-mvebu.c | 91 +++++++++++++++++++++++++----- + 2 files changed, 77 insertions(+), 16 deletions(-) + +diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig +index 326f7d13024f..a4c99ebff85e 100644 +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -4,7 +4,7 @@ menu "PCI controller drivers" + depends on PCI + + config PCI_MVEBU +- bool "Marvell EBU PCIe controller" ++ tristate "Marvell EBU PCIe controller" + depends on ARCH_MVEBU || ARCH_DOVE || COMPILE_TEST + depends on MVEBU_MBUS + depends on ARM +diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c +index 9cbf10d6fc30..504eb9b94c0f 100644 +--- a/drivers/pci/controller/pci-mvebu.c ++++ b/drivers/pci/controller/pci-mvebu.c +@@ -6,6 +6,7 @@ + */ + + #include <linux/kernel.h> ++#include <linux/module.h> + #include <linux/pci.h> + #include <linux/clk.h> + #include <linux/delay.h> +@@ -154,22 +155,13 @@ static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr) + mvebu_writel(port, stat, PCIE_STAT_OFF); + } + +-/* +- * Setup PCIE BARs and Address Decode Wins: +- * BAR[0] -> internal registers (needed for MSI) +- * BAR[1] -> covers all DRAM banks +- * BAR[2] -> Disabled +- * WIN[0-3] -> DRAM bank[0-3] +- */ +-static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port) ++static void mvebu_pcie_disable_wins(struct mvebu_pcie_port *port) + { +- const struct mbus_dram_target_info *dram; +- u32 size; + int i; + +- dram = mv_mbus_dram_info(); ++ mvebu_writel(port, 0, PCIE_BAR_LO_OFF(0)); ++ mvebu_writel(port, 0, PCIE_BAR_HI_OFF(0)); + +- /* First, disable and clear BARs and windows. */ + for (i = 1; i < 3; i++) { + mvebu_writel(port, 0, PCIE_BAR_CTRL_OFF(i)); + mvebu_writel(port, 0, PCIE_BAR_LO_OFF(i)); +@@ -185,6 +177,25 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port) + mvebu_writel(port, 0, PCIE_WIN5_CTRL_OFF); + mvebu_writel(port, 0, PCIE_WIN5_BASE_OFF); + mvebu_writel(port, 0, PCIE_WIN5_REMAP_OFF); ++} ++ ++/* ++ * Setup PCIE BARs and Address Decode Wins: ++ * BAR[0] -> internal registers (needed for MSI) ++ * BAR[1] -> covers all DRAM banks ++ * BAR[2] -> Disabled ++ * WIN[0-3] -> DRAM bank[0-3] ++ */ ++static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port) ++{ ++ const struct mbus_dram_target_info *dram; ++ u32 size; ++ int i; ++ ++ dram = mv_mbus_dram_info(); ++ ++ /* First, disable and clear BARs and windows. */ ++ mvebu_pcie_disable_wins(port); + + /* Setup windows for DDR banks. Count total DDR size on the fly. */ + size = 0; +@@ -1257,6 +1268,52 @@ static int mvebu_pcie_probe(struct platform_device *pdev) + return pci_host_probe(bridge); + } + ++static int mvebu_pcie_remove(struct platform_device *pdev) ++{ ++ struct mvebu_pcie *pcie = platform_get_drvdata(pdev); ++ struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie); ++ u32 cmd; ++ int i; ++ ++ /* Remove PCI bus with all devices. */ ++ pci_lock_rescan_remove(); ++ pci_stop_root_bus(bridge->bus); ++ pci_remove_root_bus(bridge->bus); ++ pci_unlock_rescan_remove(); ++ ++ for (i = 0; i < pcie->nports; i++) { ++ struct mvebu_pcie_port *port = &pcie->ports[i]; ++ ++ if (!port->base) ++ continue; ++ ++ /* Disable Root Bridge I/O space, memory space and bus mastering. */ ++ cmd = mvebu_readl(port, PCIE_CMD_OFF); ++ cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); ++ mvebu_writel(port, cmd, PCIE_CMD_OFF); ++ ++ /* Mask all interrupt sources. */ ++ mvebu_writel(port, 0, PCIE_MASK_OFF); ++ ++ /* Free config space for emulated root bridge. */ ++ pci_bridge_emul_cleanup(&port->bridge); ++ ++ /* Disable and clear BARs and windows. */ ++ mvebu_pcie_disable_wins(port); ++ ++ /* Delete PCIe IO and MEM windows. */ ++ if (port->iowin.size) ++ mvebu_pcie_del_windows(port, port->iowin.base, port->iowin.size); ++ if (port->memwin.size) ++ mvebu_pcie_del_windows(port, port->memwin.base, port->memwin.size); ++ ++ /* Power down card and disable clocks. Must be the last step. */ ++ mvebu_pcie_powerdown(port); ++ } ++ ++ return 0; ++} ++ + static const struct of_device_id mvebu_pcie_of_match_table[] = { + { .compatible = "marvell,armada-xp-pcie", }, + { .compatible = "marvell,armada-370-pcie", }, +@@ -1273,10 +1330,14 @@ static struct platform_driver mvebu_pcie_driver = { + .driver = { + .name = "mvebu-pcie", + .of_match_table = mvebu_pcie_of_match_table, +- /* driver unloading/unbinding currently not supported */ +- .suppress_bind_attrs = true, + .pm = &mvebu_pcie_pm_ops, + }, + .probe = mvebu_pcie_probe, ++ .remove = mvebu_pcie_remove, + }; +-builtin_platform_driver(mvebu_pcie_driver); ++module_platform_driver(mvebu_pcie_driver); ++ ++MODULE_AUTHOR("Thomas Petazzoni <thomas.petazzoni@bootlin.com>"); ++MODULE_AUTHOR("Pali Rohár <pali@kernel.org>"); ++MODULE_DESCRIPTION("Marvell EBU PCIe controller"); ++MODULE_LICENSE("GPL v2"); +-- +2.34.1 + |