X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/dc4e55fa64197a3ff073227ee49027a4c9a7db4e..abc719ecfdda0ac7a916c66e55ccbe1d9569cad4:/target/linux/ar71xx/files/arch/mips/pci/pci-ar71xx.c?ds=sidebyside diff --git a/target/linux/ar71xx/files/arch/mips/pci/pci-ar71xx.c b/target/linux/ar71xx/files/arch/mips/pci/pci-ar71xx.c index 88eb917a5..5f10d6a65 100644 --- a/target/linux/ar71xx/files/arch/mips/pci/pci-ar71xx.c +++ b/target/linux/ar71xx/files/arch/mips/pci/pci-ar71xx.c @@ -107,7 +107,7 @@ int ar71xx_pci_be_handler(int is_fixup) __raw_writel(ahb_err, base + PCI_REG_AHB_ERR); } - return ((ahb_err | pci_err) ? 1 : 0); + return (ahb_err | pci_err) ? 1 : 0; } static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus, @@ -136,6 +136,7 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, static u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0}; unsigned long flags; u32 data; + int retry = 0; int ret; ret = PCIBIOS_SUCCESSFUL; @@ -143,6 +144,7 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, DBG("PCI: read config: %02x:%02x.%01x/%02x:%01d\n", bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size); +retry: spin_lock_irqsave(&ar71xx_pci_lock, flags); if (bus->number == 0 && devfn == 0) { @@ -176,6 +178,14 @@ static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, *value = (data >> (8 * (where & 3))) & mask[size & 7]; + /* + * PCI controller bug: sometimes reads to the PCI_COMMAND register + * return 0xffff, even though the PCI trace shows the correct value. + * Work around this by retrying reads to this register + */ + if (where == PCI_COMMAND && (*value & 0xffff) == 0xffff && retry++ < 2) + goto retry; + return ret; } @@ -384,6 +394,8 @@ int __init ar71xx_pcibios_init(void) ar71xx_pcicfg_base = ioremap_nocache(AR71XX_PCI_CFG_BASE, AR71XX_PCI_CFG_SIZE); + if (ar71xx_pcicfg_base == NULL) + return -ENOMEM; __raw_writel(PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0); __raw_writel(PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1);