linux-mips
[Top] [All Lists]

[PATCH] MIPS: pci-ar724x: avoid data bus error due to a missing PCIe mod

To: Ralf Baechle <ralf@linux-mips.org>
Subject: [PATCH] MIPS: pci-ar724x: avoid data bus error due to a missing PCIe module
From: Gabor Juhos <juhosg@openwrt.org>
Date: Thu, 23 Aug 2012 15:35:26 +0200
Cc: linux-mips@linux-mips.org, Gabor Juhos <juhosg@openwrt.org>, <stable@vger.kernel.org>, #@arrakis.dune.hu, v3.5+@arrakis.dune.hu
List-archive: <http://www.linux-mips.org/archives/linux-mips/>
List-help: <mailto:ecartis@linux-mips.org?Subject=help>
List-id: linux-mips <linux-mips.eddie.linux-mips.org>
List-owner: <mailto:ralf@linux-mips.org>
List-post: <mailto:linux-mips@linux-mips.org>
List-software: Ecartis version 1.0.0
List-subscribe: <mailto:ecartis@linux-mips.org?subject=subscribe%20linux-mips>
List-unsubscribe: <mailto:ecartis@linux-mips.org?subject=unsubscribe%20linux-mips>
Sender: linux-mips-bounce@linux-mips.org
If the controller has no PCIe module attached,
accessing of the device configuration space
causes a data bus error. Avoid this by checking
the status of the PCIe link in advance, and
indicate an error if the link is down.

Cc: <stable@vger.kernel.org> # v3.5+
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
 arch/mips/pci/pci-ar724x.c |   22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
index 414a745..86d77a6 100644
--- a/arch/mips/pci/pci-ar724x.c
+++ b/arch/mips/pci/pci-ar724x.c
@@ -23,9 +23,12 @@
 #define AR724X_PCI_MEM_BASE    0x10000000
 #define AR724X_PCI_MEM_SIZE    0x08000000
 
+#define AR724X_PCI_REG_RESET           0x18
 #define AR724X_PCI_REG_INT_STATUS      0x4c
 #define AR724X_PCI_REG_INT_MASK                0x50
 
+#define AR724X_PCI_RESET_LINK_UP       BIT(0)
+
 #define AR724X_PCI_INT_DEV0            BIT(14)
 
 #define AR724X_PCI_IRQ_COUNT           1
@@ -38,6 +41,15 @@ static void __iomem *ar724x_pci_ctrl_base;
 
 static u32 ar724x_pci_bar0_value;
 static bool ar724x_pci_bar0_is_cached;
+static bool ar724x_pci_link_up;
+
+static inline bool ar724x_pci_check_link(void)
+{
+       u32 reset;
+
+       reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET);
+       return reset & AR724X_PCI_RESET_LINK_UP;
+}
 
 static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
                            int size, uint32_t *value)
@@ -46,6 +58,9 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int 
devfn, int where,
        void __iomem *base;
        u32 data;
 
+       if (!ar724x_pci_link_up)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
        if (devfn)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
@@ -96,6 +111,9 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned 
int devfn, int where,
        u32 data;
        int s;
 
+       if (!ar724x_pci_link_up)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+
        if (devfn)
                return PCIBIOS_DEVICE_NOT_FOUND;
 
@@ -280,6 +298,10 @@ int __init ar724x_pcibios_init(int irq)
        if (ar724x_pci_ctrl_base == NULL)
                goto err_unmap_devcfg;
 
+       ar724x_pci_link_up = ar724x_pci_check_link();
+       if (!ar724x_pci_link_up)
+               pr_warn("ar724x: PCIe link is down\n");
+
        ar724x_pci_irq_init(irq);
        register_pci_controller(&ar724x_pci_controller);
 
-- 
1.7.10


<Prev in Thread] Current Thread [Next in Thread>