diff options
author | Huacai Chen <chenhc@lemote.com> | 2018-09-19 21:11:03 -0400 |
---|---|---|
committer | Paul Burton <paul.burton@mips.com> | 2018-09-19 21:57:30 -0400 |
commit | 8250a9b43b257f05c2aba6e8367fa636b630b0a2 (patch) | |
tree | 018a56062fee9d627328d4ed4a7d2245b9432b17 | |
parent | c824ad164760484f709daa1339df40a184f4170a (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.c | 34 |
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) |