Signed-off-by: Huacai Chen <chenhc@xxxxxxxxxx> --- arch/mips/pci/ops-loongson3.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/arch/mips/pci/ops-loongson3.c b/arch/mips/pci/ops-loongson3.c index 9e11843..3100117 100644 --- a/arch/mips/pci/ops-loongson3.c +++ b/arch/mips/pci/ops-loongson3.c @@ -24,16 +24,29 @@ static int loongson3_pci_config_access(unsigned char access_type, int function = PCI_FUNC(devfn); int reg = where & ~3; - addr = (busnum << 16) | (device << 11) | (function << 8) | reg; - if (busnum == 0) { - if (device > 31) + if (where < 256) { /* standard config */ + addr = (busnum << 16) | (device << 11) | (function << 8) | reg; + if (busnum == 0) { + if (device > 31) + return PCIBIOS_DEVICE_NOT_FOUND; + addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE) | (addr & 0xffff)); + type = 0; + } else { + addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE_TP1) | (addr)); + type = 0x10000; + } + } else { /* extended config */ + struct pci_dev *rootdev; + + rootdev = pci_get_domain_bus_and_slot(0, 0, 0); + if (!rootdev) + return PCIBIOS_DEVICE_NOT_FOUND; + + addr = pci_resource_start(rootdev, 3); + if (!addr) return PCIBIOS_DEVICE_NOT_FOUND; - addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE) | (addr & 0xffff)); - type = 0; - } else { - addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE_TP1) | (addr)); - type = 0x10000; + addrp = (void *)TO_UNCAC(addr | busnum << 20 | device << 15 | function << 12 | reg); } if (access_type == PCI_ACCESS_WRITE) -- 2.7.0