aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuacai Chen <chenhc@lemote.com>2018-09-19 21:11:03 -0400
committerPaul Burton <paul.burton@mips.com>2018-09-19 21:57:30 -0400
commit8250a9b43b257f05c2aba6e8367fa636b630b0a2 (patch)
tree018a56062fee9d627328d4ed4a7d2245b9432b17
parentc824ad164760484f709daa1339df40a184f4170a (diff)
MIPS/PCI: Let Loongson-3 pci_ops access extended config space
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>
-rw-r--r--arch/mips/pci/ops-loongson3.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/arch/mips/pci/ops-loongson3.c b/arch/mips/pci/ops-loongson3.c
index 9e118431e226..2f6ad36bdea6 100644
--- a/arch/mips/pci/ops-loongson3.c
+++ b/arch/mips/pci/ops-loongson3.c
@@ -18,22 +18,36 @@ static int loongson3_pci_config_access(unsigned char access_type,
18 int where, u32 *data) 18 int where, u32 *data)
19{ 19{
20 unsigned char busnum = bus->number; 20 unsigned char busnum = bus->number;
21 u_int64_t addr, type;
22 void *addrp;
23 int device = PCI_SLOT(devfn);
24 int function = PCI_FUNC(devfn); 21 int function = PCI_FUNC(devfn);
22 int device = PCI_SLOT(devfn);
25 int reg = where & ~3; 23 int reg = where & ~3;
24 void *addrp;
25 u64 addr;
26
27 if (where < PCI_CFG_SPACE_SIZE) { /* standard config */
28 addr = (busnum << 16) | (device << 11) | (function << 8) | reg;
29 if (busnum == 0) {
30 if (device > 31)
31 return PCIBIOS_DEVICE_NOT_FOUND;
32 addrp = (void *)TO_UNCAC(HT1LO_PCICFG_BASE | addr);
33 } else {
34 addrp = (void *)TO_UNCAC(HT1LO_PCICFG_BASE_TP1 | addr);
35 }
36 } else if (where < PCI_CFG_SPACE_EXP_SIZE) { /* extended config */
37 struct pci_dev *rootdev;
38
39 rootdev = pci_get_domain_bus_and_slot(0, 0, 0);
40 if (!rootdev)
41 return PCIBIOS_DEVICE_NOT_FOUND;
26 42
27 addr = (busnum << 16) | (device << 11) | (function << 8) | reg; 43 addr = pci_resource_start(rootdev, 3);
28 if (busnum == 0) { 44 if (!addr)
29 if (device > 31)
30 return PCIBIOS_DEVICE_NOT_FOUND; 45 return PCIBIOS_DEVICE_NOT_FOUND;
31 addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE) | (addr & 0xffff));
32 type = 0;
33 46
47 addr |= busnum << 20 | device << 15 | function << 12 | reg;
48 addrp = (void *)TO_UNCAC(addr);
34 } else { 49 } else {
35 addrp = (void *)(TO_UNCAC(HT1LO_PCICFG_BASE_TP1) | (addr)); 50 return PCIBIOS_DEVICE_NOT_FOUND;
36 type = 0x10000;
37 } 51 }
38 52
39 if (access_type == PCI_ACCESS_WRITE) 53 if (access_type == PCI_ACCESS_WRITE)