1 From ce0180ac422bdadc3eeb317cc470b872f8348507 Mon Sep 17 00:00:00 2001 2 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> 3 Date: Thu, 11 Mar 2021 11:47:27 +0100 4 Subject: [PATCH 5/7] PCI: aardvark: Disable bus mastering and mask all 5 interrupts when unbinding driver 6 MIME-Version: 1.0 7 Content-Type: text/plain; charset=UTF-8 8 Content-Transfer-Encoding: 8bit 9 10 Ensure that after driver unbinding PCIe cards are not be able to forward 11 memory and I/O requests in the upstream direction and that no interrupt can 12 be triggered. 13 14 Fixes: 526a76991b7b ("PCI: aardvark: Implement driver 'remove' function and allow to build it as module") 15 Signed-off-by: Pali Rohár <pali@kernel.org> 16 Signed-off-by: Marek Behún <kabel@kernel.org> 17 Cc: stable@vger.kernel.org 18 --- 19 drivers/pci/controller/pci-aardvark.c | 29 +++++++++++++++++++++++++++ 20 1 file changed, 29 insertions(+) 21 22 diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c 23 index 71ce9f02d596..08b34accfe2f 100644 24 --- a/drivers/pci/controller/pci-aardvark.c 25 +++ b/drivers/pci/controller/pci-aardvark.c 26 @@ -1695,13 +1695,42 @@ static int advk_pcie_remove(struct platform_device *pdev) 27 { 28 struct advk_pcie *pcie = platform_get_drvdata(pdev); 29 struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie); 30 + u32 val; 31 int i; 32 33 + /* Remove PCI bus with all devices */ 34 pci_lock_rescan_remove(); 35 pci_stop_root_bus(bridge->bus); 36 pci_remove_root_bus(bridge->bus); 37 pci_unlock_rescan_remove(); 38 39 + /* Disable Root Bridge I/O space, memory space and bus mastering */ 40 + val = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); 41 + val &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); 42 + advk_writel(pcie, val, PCIE_CORE_CMD_STATUS_REG); 43 + 44 + /* Disable MSI */ 45 + val = advk_readl(pcie, PCIE_CORE_CTRL2_REG); 46 + val &= ~PCIE_CORE_CTRL2_MSI_ENABLE; 47 + advk_writel(pcie, val, PCIE_CORE_CTRL2_REG); 48 + 49 + /* Clear MSI address */ 50 + advk_writel(pcie, 0, PCIE_MSI_ADDR_LOW_REG); 51 + advk_writel(pcie, 0, PCIE_MSI_ADDR_HIGH_REG); 52 + 53 + /* Mask all interrupts */ 54 + advk_writel(pcie, PCIE_MSI_ALL_MASK, PCIE_MSI_MASK_REG); 55 + advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_MASK_REG); 56 + advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_MASK_REG); 57 + advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_MASK_REG); 58 + 59 + /* Clear all interrupts */ 60 + advk_writel(pcie, PCIE_MSI_ALL_MASK, PCIE_MSI_STATUS_REG); 61 + advk_writel(pcie, PCIE_ISR0_ALL_MASK, PCIE_ISR0_REG); 62 + advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG); 63 + advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG); 64 + 65 + /* Remove IRQ domains */ 66 advk_pcie_remove_msi_irq_domain(pcie); 67 advk_pcie_remove_irq_domain(pcie); 68 69 -- 70 2.32.0 71