]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
MIPS/PCI: Let Loongson-3 pci_ops access extended config space
authorHuacai Chen <chenhc@lemote.com>
Thu, 20 Sep 2018 01:11:03 +0000 (09:11 +0800)
committerPaul Burton <paul.burton@mips.com>
Thu, 20 Sep 2018 01:57:30 +0000 (18:57 -0700)
Original Loongson-3 pci_ops can only access standard pci config space,
this patch let it be able to access extended pci config space.

Signed-off-by: Huacai Chen <chenhc@lemote.com>
[paul.burton@mips.com: Tweaks to fix checkpatch warnings, reverse xmas tree]
Signed-off-by: Paul Burton <paul.burton@mips.com>
Patchwork: https://patchwork.linux-mips.org/patch/20707/
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: James Hogan <jhogan@kernel.org>
Cc: linux-mips@linux-mips.org
Cc: Fuxin Zhang <zhangfx@lemote.com>
Cc: Zhangjin Wu <wuzhangjin@gmail.com>
Cc: Huacai Chen <chenhuacai@gmail.com>
arch/mips/pci/ops-loongson3.c

index 9e118431e22681170e9ea494a2f2b88e45e5b15d..2f6ad36bdea69b888955c550cc3a75b4927b7291 100644 (file)
@@ -18,22 +18,36 @@ static int loongson3_pci_config_access(unsigned char access_type,
                int where, u32 *data)
 {
        unsigned char busnum = bus->number;
-       u_int64_t addr, type;
-       void *addrp;
-       int device = PCI_SLOT(devfn);
        int function = PCI_FUNC(devfn);
+       int device = PCI_SLOT(devfn);
        int reg = where & ~3;
+       void *addrp;
+       u64 addr;
+
+       if (where < PCI_CFG_SPACE_SIZE) { /* 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);
+               } else {
+                       addrp = (void *)TO_UNCAC(HT1LO_PCICFG_BASE_TP1 | addr);
+               }
+       } else if (where < PCI_CFG_SPACE_EXP_SIZE) {  /* extended config */
+               struct pci_dev *rootdev;
+
+               rootdev = pci_get_domain_bus_and_slot(0, 0, 0);
+               if (!rootdev)
+                       return PCIBIOS_DEVICE_NOT_FOUND;
 
-       addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
-       if (busnum == 0) {
-               if (device > 31)
+               addr = pci_resource_start(rootdev, 3);
+               if (!addr)
                        return PCIBIOS_DEVICE_NOT_FOUND;
-               addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE) | (addr & 0xffff));
-               type = 0;
 
+               addr |= busnum << 20 | device << 15 | function << 12 | reg;
+               addrp = (void *)TO_UNCAC(addr);
        } else {
-               addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE_TP1) | (addr));
-               type = 0x10000;
+               return PCIBIOS_DEVICE_NOT_FOUND;
        }
 
        if (access_type == PCI_ACCESS_WRITE)