aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/indirect_pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/indirect_pci.c')
-rw-r--r--arch/powerpc/sysdev/indirect_pci.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/arch/powerpc/sysdev/indirect_pci.c b/arch/powerpc/sysdev/indirect_pci.c
index c7e6e859b393..a8ac2dfdd3d4 100644
--- a/arch/powerpc/sysdev/indirect_pci.c
+++ b/arch/powerpc/sysdev/indirect_pci.c
@@ -20,12 +20,6 @@
20#include <asm/pci-bridge.h> 20#include <asm/pci-bridge.h>
21#include <asm/machdep.h> 21#include <asm/machdep.h>
22 22
23#ifdef CONFIG_PPC_INDIRECT_PCI_BE
24#define PCI_CFG_OUT out_be32
25#else
26#define PCI_CFG_OUT out_le32
27#endif
28
29static int 23static int
30indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset, 24indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
31 int len, u32 *val) 25 int len, u32 *val)
@@ -35,10 +29,17 @@ indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
35 u8 cfg_type = 0; 29 u8 cfg_type = 0;
36 u32 bus_no, reg; 30 u32 bus_no, reg;
37 31
32 if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK) {
33 if (bus->number != hose->first_busno)
34 return PCIBIOS_DEVICE_NOT_FOUND;
35 if (devfn != 0)
36 return PCIBIOS_DEVICE_NOT_FOUND;
37 }
38
38 if (ppc_md.pci_exclude_device) 39 if (ppc_md.pci_exclude_device)
39 if (ppc_md.pci_exclude_device(hose, bus->number, devfn)) 40 if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
40 return PCIBIOS_DEVICE_NOT_FOUND; 41 return PCIBIOS_DEVICE_NOT_FOUND;
41 42
42 if (hose->indirect_type & PPC_INDIRECT_TYPE_SET_CFG_TYPE) 43 if (hose->indirect_type & PPC_INDIRECT_TYPE_SET_CFG_TYPE)
43 if (bus->number != hose->first_busno) 44 if (bus->number != hose->first_busno)
44 cfg_type = 1; 45 cfg_type = 1;
@@ -51,9 +52,12 @@ indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
51 else 52 else
52 reg = offset & 0xfc; 53 reg = offset & 0xfc;
53 54
54 PCI_CFG_OUT(hose->cfg_addr, 55 if (hose->indirect_type & PPC_INDIRECT_TYPE_BIG_ENDIAN)
55 (0x80000000 | (bus_no << 16) 56 out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
56 | (devfn << 8) | reg | cfg_type)); 57 (devfn << 8) | reg | cfg_type));
58 else
59 out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
60 (devfn << 8) | reg | cfg_type));
57 61
58 /* 62 /*
59 * Note: the caller has already checked that offset is 63 * Note: the caller has already checked that offset is
@@ -83,6 +87,13 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
83 u8 cfg_type = 0; 87 u8 cfg_type = 0;
84 u32 bus_no, reg; 88 u32 bus_no, reg;
85 89
90 if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK) {
91 if (bus->number != hose->first_busno)
92 return PCIBIOS_DEVICE_NOT_FOUND;
93 if (devfn != 0)
94 return PCIBIOS_DEVICE_NOT_FOUND;
95 }
96
86 if (ppc_md.pci_exclude_device) 97 if (ppc_md.pci_exclude_device)
87 if (ppc_md.pci_exclude_device(hose, bus->number, devfn)) 98 if (ppc_md.pci_exclude_device(hose, bus->number, devfn))
88 return PCIBIOS_DEVICE_NOT_FOUND; 99 return PCIBIOS_DEVICE_NOT_FOUND;
@@ -99,9 +110,12 @@ indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
99 else 110 else
100 reg = offset & 0xfc; 111 reg = offset & 0xfc;
101 112
102 PCI_CFG_OUT(hose->cfg_addr, 113 if (hose->indirect_type & PPC_INDIRECT_TYPE_BIG_ENDIAN)
103 (0x80000000 | (bus_no << 16) 114 out_be32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
104 | (devfn << 8) | reg | cfg_type)); 115 (devfn << 8) | reg | cfg_type));
116 else
117 out_le32(hose->cfg_addr, (0x80000000 | (bus_no << 16) |
118 (devfn << 8) | reg | cfg_type));
105 119
106 /* surpress setting of PCI_PRIMARY_BUS */ 120 /* surpress setting of PCI_PRIMARY_BUS */
107 if (hose->indirect_type & PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS) 121 if (hose->indirect_type & PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS)
@@ -135,24 +149,15 @@ static struct pci_ops indirect_pci_ops =
135}; 149};
136 150
137void __init 151void __init
138setup_indirect_pci_nomap(struct pci_controller* hose, void __iomem * cfg_addr, 152setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data, u32 flags)
139 void __iomem * cfg_data)
140{
141 hose->cfg_addr = cfg_addr;
142 hose->cfg_data = cfg_data;
143 hose->ops = &indirect_pci_ops;
144}
145
146void __init
147setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data)
148{ 153{
149 unsigned long base = cfg_addr & PAGE_MASK; 154 unsigned long base = cfg_addr & PAGE_MASK;
150 void __iomem *mbase, *addr, *data; 155 void __iomem *mbase;
151 156
152 mbase = ioremap(base, PAGE_SIZE); 157 mbase = ioremap(base, PAGE_SIZE);
153 addr = mbase + (cfg_addr & ~PAGE_MASK); 158 hose->cfg_addr = mbase + (cfg_addr & ~PAGE_MASK);
154 if ((cfg_data & PAGE_MASK) != base) 159 if ((cfg_data & PAGE_MASK) != base)
155 mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE); 160 mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE);
156 data = mbase + (cfg_data & ~PAGE_MASK); 161 hose->cfg_data = mbase + (cfg_data & ~PAGE_MASK);
157 setup_indirect_pci_nomap(hose, addr, data); 162 hose->ops = &indirect_pci_ops;
158} 163}