source of highlighter
plain | download
    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