| 1 | From 9cfa64ddaba49975b420ce5e5020efc3301061ac Mon Sep 17 00:00:00 2001 |
| 2 | From: Gabor Juhos <juhosg@openwrt.org> |
| 3 | Date: Tue, 26 Jun 2012 10:19:46 +0200 |
| 4 | Subject: [PATCH 01/34] MIPS: pci-ar724x: avoid data bus error due to a missing PCIe module |
| 5 | |
| 6 | If the controller has no PCIe module attached, |
| 7 | accessing of the device configuration space |
| 8 | causes a data bus error. Avoid this by checking |
| 9 | the status of the PCIe link in advance, and |
| 10 | indicate an error if the link is down. |
| 11 | |
| 12 | Signed-off-by: Gabor Juhos <juhosg@openwrt.org> |
| 13 | --- |
| 14 | arch/mips/pci/pci-ar724x.c | 22 ++++++++++++++++++++++ |
| 15 | 1 files changed, 22 insertions(+), 0 deletions(-) |
| 16 | |
| 17 | --- a/arch/mips/pci/pci-ar724x.c |
| 18 | +++ b/arch/mips/pci/pci-ar724x.c |
| 19 | @@ -23,9 +23,12 @@ |
| 20 | #define AR724X_PCI_MEM_BASE 0x10000000 |
| 21 | #define AR724X_PCI_MEM_SIZE 0x08000000 |
| 22 | |
| 23 | +#define AR724X_PCI_REG_RESET 0x18 |
| 24 | #define AR724X_PCI_REG_INT_STATUS 0x4c |
| 25 | #define AR724X_PCI_REG_INT_MASK 0x50 |
| 26 | |
| 27 | +#define AR724X_PCI_RESET_LINK_UP BIT(0) |
| 28 | + |
| 29 | #define AR724X_PCI_INT_DEV0 BIT(14) |
| 30 | |
| 31 | #define AR724X_PCI_IRQ_COUNT 1 |
| 32 | @@ -38,6 +41,15 @@ static void __iomem *ar724x_pci_ctrl_bas |
| 33 | |
| 34 | static u32 ar724x_pci_bar0_value; |
| 35 | static bool ar724x_pci_bar0_is_cached; |
| 36 | +static bool ar724x_pci_link_up; |
| 37 | + |
| 38 | +static inline bool ar724x_pci_check_link(void) |
| 39 | +{ |
| 40 | + u32 reset; |
| 41 | + |
| 42 | + reset = __raw_readl(ar724x_pci_ctrl_base + AR724X_PCI_REG_RESET); |
| 43 | + return reset & AR724X_PCI_RESET_LINK_UP; |
| 44 | +} |
| 45 | |
| 46 | static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, |
| 47 | int size, uint32_t *value) |
| 48 | @@ -46,6 +58,9 @@ static int ar724x_pci_read(struct pci_bu |
| 49 | void __iomem *base; |
| 50 | u32 data; |
| 51 | |
| 52 | + if (!ar724x_pci_link_up) |
| 53 | + return PCIBIOS_DEVICE_NOT_FOUND; |
| 54 | + |
| 55 | if (devfn) |
| 56 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 57 | |
| 58 | @@ -96,6 +111,9 @@ static int ar724x_pci_write(struct pci_b |
| 59 | u32 data; |
| 60 | int s; |
| 61 | |
| 62 | + if (!ar724x_pci_link_up) |
| 63 | + return PCIBIOS_DEVICE_NOT_FOUND; |
| 64 | + |
| 65 | if (devfn) |
| 66 | return PCIBIOS_DEVICE_NOT_FOUND; |
| 67 | |
| 68 | @@ -280,6 +298,10 @@ int __init ar724x_pcibios_init(int irq) |
| 69 | if (ar724x_pci_ctrl_base == NULL) |
| 70 | goto err_unmap_devcfg; |
| 71 | |
| 72 | + ar724x_pci_link_up = ar724x_pci_check_link(); |
| 73 | + if (!ar724x_pci_link_up) |
| 74 | + pr_warn("ar724x: PCIe link is down\n"); |
| 75 | + |
| 76 | ar724x_pci_irq_init(irq); |
| 77 | register_pci_controller(&ar724x_pci_controller); |
| 78 | |
| 79 | |