diff options
-rw-r--r-- | arch/powerpc/platforms/powermac/pci.c | 209 |
1 files changed, 39 insertions, 170 deletions
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 04702db35d45..f4071a67ad00 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c | |||
@@ -133,17 +133,23 @@ static void __init fixup_bus_range(struct device_node *bridge) | |||
133 | |(((unsigned int)(off)) & 0xFCUL) \ | 133 | |(((unsigned int)(off)) & 0xFCUL) \ |
134 | |1UL) | 134 | |1UL) |
135 | 135 | ||
136 | static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose, | 136 | static void __iomem *macrisc_cfg_map_bus(struct pci_bus *bus, |
137 | u8 bus, u8 dev_fn, u8 offset) | 137 | unsigned int dev_fn, |
138 | int offset) | ||
138 | { | 139 | { |
139 | unsigned int caddr; | 140 | unsigned int caddr; |
141 | struct pci_controller *hose; | ||
140 | 142 | ||
141 | if (bus == hose->first_busno) { | 143 | hose = pci_bus_to_host(bus); |
144 | if (hose == NULL) | ||
145 | return NULL; | ||
146 | |||
147 | if (bus->number == hose->first_busno) { | ||
142 | if (dev_fn < (11 << 3)) | 148 | if (dev_fn < (11 << 3)) |
143 | return NULL; | 149 | return NULL; |
144 | caddr = MACRISC_CFA0(dev_fn, offset); | 150 | caddr = MACRISC_CFA0(dev_fn, offset); |
145 | } else | 151 | } else |
146 | caddr = MACRISC_CFA1(bus, dev_fn, offset); | 152 | caddr = MACRISC_CFA1(bus->number, dev_fn, offset); |
147 | 153 | ||
148 | /* Uninorth will return garbage if we don't read back the value ! */ | 154 | /* Uninorth will return garbage if we don't read back the value ! */ |
149 | do { | 155 | do { |
@@ -154,129 +160,46 @@ static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose, | |||
154 | return hose->cfg_data + offset; | 160 | return hose->cfg_data + offset; |
155 | } | 161 | } |
156 | 162 | ||
157 | static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, | ||
158 | int offset, int len, u32 *val) | ||
159 | { | ||
160 | struct pci_controller *hose; | ||
161 | volatile void __iomem *addr; | ||
162 | |||
163 | hose = pci_bus_to_host(bus); | ||
164 | if (hose == NULL) | ||
165 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
166 | if (offset >= 0x100) | ||
167 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
168 | addr = macrisc_cfg_access(hose, bus->number, devfn, offset); | ||
169 | if (!addr) | ||
170 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
171 | /* | ||
172 | * Note: the caller has already checked that offset is | ||
173 | * suitably aligned and that len is 1, 2 or 4. | ||
174 | */ | ||
175 | switch (len) { | ||
176 | case 1: | ||
177 | *val = in_8(addr); | ||
178 | break; | ||
179 | case 2: | ||
180 | *val = in_le16(addr); | ||
181 | break; | ||
182 | default: | ||
183 | *val = in_le32(addr); | ||
184 | break; | ||
185 | } | ||
186 | return PCIBIOS_SUCCESSFUL; | ||
187 | } | ||
188 | |||
189 | static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, | ||
190 | int offset, int len, u32 val) | ||
191 | { | ||
192 | struct pci_controller *hose; | ||
193 | volatile void __iomem *addr; | ||
194 | |||
195 | hose = pci_bus_to_host(bus); | ||
196 | if (hose == NULL) | ||
197 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
198 | if (offset >= 0x100) | ||
199 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
200 | addr = macrisc_cfg_access(hose, bus->number, devfn, offset); | ||
201 | if (!addr) | ||
202 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
203 | /* | ||
204 | * Note: the caller has already checked that offset is | ||
205 | * suitably aligned and that len is 1, 2 or 4. | ||
206 | */ | ||
207 | switch (len) { | ||
208 | case 1: | ||
209 | out_8(addr, val); | ||
210 | break; | ||
211 | case 2: | ||
212 | out_le16(addr, val); | ||
213 | break; | ||
214 | default: | ||
215 | out_le32(addr, val); | ||
216 | break; | ||
217 | } | ||
218 | return PCIBIOS_SUCCESSFUL; | ||
219 | } | ||
220 | |||
221 | static struct pci_ops macrisc_pci_ops = | 163 | static struct pci_ops macrisc_pci_ops = |
222 | { | 164 | { |
223 | .read = macrisc_read_config, | 165 | .map_bus = macrisc_cfg_map_bus, |
224 | .write = macrisc_write_config, | 166 | .read = pci_generic_config_read, |
167 | .write = pci_generic_config_write, | ||
225 | }; | 168 | }; |
226 | 169 | ||
227 | #ifdef CONFIG_PPC32 | 170 | #ifdef CONFIG_PPC32 |
228 | /* | 171 | /* |
229 | * Verify that a specific (bus, dev_fn) exists on chaos | 172 | * Verify that a specific (bus, dev_fn) exists on chaos |
230 | */ | 173 | */ |
231 | static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset) | 174 | static void __iomem *chaos_map_bus(struct pci_bus *bus, unsigned int devfn, |
175 | int offset) | ||
232 | { | 176 | { |
233 | struct device_node *np; | 177 | struct device_node *np; |
234 | const u32 *vendor, *device; | 178 | const u32 *vendor, *device; |
235 | 179 | ||
236 | if (offset >= 0x100) | 180 | if (offset >= 0x100) |
237 | return PCIBIOS_BAD_REGISTER_NUMBER; | 181 | return NULL; |
238 | np = of_pci_find_child_device(bus->dev.of_node, devfn); | 182 | np = of_pci_find_child_device(bus->dev.of_node, devfn); |
239 | if (np == NULL) | 183 | if (np == NULL) |
240 | return PCIBIOS_DEVICE_NOT_FOUND; | 184 | return NULL; |
241 | 185 | ||
242 | vendor = of_get_property(np, "vendor-id", NULL); | 186 | vendor = of_get_property(np, "vendor-id", NULL); |
243 | device = of_get_property(np, "device-id", NULL); | 187 | device = of_get_property(np, "device-id", NULL); |
244 | if (vendor == NULL || device == NULL) | 188 | if (vendor == NULL || device == NULL) |
245 | return PCIBIOS_DEVICE_NOT_FOUND; | 189 | return NULL; |
246 | 190 | ||
247 | if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10) | 191 | if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10) |
248 | && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24)) | 192 | && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24)) |
249 | return PCIBIOS_BAD_REGISTER_NUMBER; | 193 | return NULL; |
250 | |||
251 | return PCIBIOS_SUCCESSFUL; | ||
252 | } | ||
253 | 194 | ||
254 | static int | 195 | return macrisc_cfg_map_bus(bus, devfn, offset); |
255 | chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
256 | int len, u32 *val) | ||
257 | { | ||
258 | int result = chaos_validate_dev(bus, devfn, offset); | ||
259 | if (result == PCIBIOS_BAD_REGISTER_NUMBER) | ||
260 | *val = ~0U; | ||
261 | if (result != PCIBIOS_SUCCESSFUL) | ||
262 | return result; | ||
263 | return macrisc_read_config(bus, devfn, offset, len, val); | ||
264 | } | ||
265 | |||
266 | static int | ||
267 | chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset, | ||
268 | int len, u32 val) | ||
269 | { | ||
270 | int result = chaos_validate_dev(bus, devfn, offset); | ||
271 | if (result != PCIBIOS_SUCCESSFUL) | ||
272 | return result; | ||
273 | return macrisc_write_config(bus, devfn, offset, len, val); | ||
274 | } | 196 | } |
275 | 197 | ||
276 | static struct pci_ops chaos_pci_ops = | 198 | static struct pci_ops chaos_pci_ops = |
277 | { | 199 | { |
278 | .read = chaos_read_config, | 200 | .map_bus = chaos_map_bus, |
279 | .write = chaos_write_config, | 201 | .read = pci_generic_config_read, |
202 | .write = pci_generic_config_write, | ||
280 | }; | 203 | }; |
281 | 204 | ||
282 | static void __init setup_chaos(struct pci_controller *hose, | 205 | static void __init setup_chaos(struct pci_controller *hose, |
@@ -471,15 +394,24 @@ static struct pci_ops u3_ht_pci_ops = | |||
471 | |(((unsigned int)(off)) & 0xfcU) \ | 394 | |(((unsigned int)(off)) & 0xfcU) \ |
472 | |1UL) | 395 | |1UL) |
473 | 396 | ||
474 | static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose, | 397 | static void __iomem *u4_pcie_cfg_map_bus(struct pci_bus *bus, |
475 | u8 bus, u8 dev_fn, int offset) | 398 | unsigned int dev_fn, |
399 | int offset) | ||
476 | { | 400 | { |
401 | struct pci_controller *hose; | ||
477 | unsigned int caddr; | 402 | unsigned int caddr; |
478 | 403 | ||
479 | if (bus == hose->first_busno) { | 404 | if (offset >= 0x1000) |
405 | return NULL; | ||
406 | |||
407 | hose = pci_bus_to_host(bus); | ||
408 | if (!hose) | ||
409 | return NULL; | ||
410 | |||
411 | if (bus->number == hose->first_busno) { | ||
480 | caddr = U4_PCIE_CFA0(dev_fn, offset); | 412 | caddr = U4_PCIE_CFA0(dev_fn, offset); |
481 | } else | 413 | } else |
482 | caddr = U4_PCIE_CFA1(bus, dev_fn, offset); | 414 | caddr = U4_PCIE_CFA1(bus->number, dev_fn, offset); |
483 | 415 | ||
484 | /* Uninorth will return garbage if we don't read back the value ! */ | 416 | /* Uninorth will return garbage if we don't read back the value ! */ |
485 | do { | 417 | do { |
@@ -490,74 +422,11 @@ static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose, | |||
490 | return hose->cfg_data + offset; | 422 | return hose->cfg_data + offset; |
491 | } | 423 | } |
492 | 424 | ||
493 | static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | ||
494 | int offset, int len, u32 *val) | ||
495 | { | ||
496 | struct pci_controller *hose; | ||
497 | volatile void __iomem *addr; | ||
498 | |||
499 | hose = pci_bus_to_host(bus); | ||
500 | if (hose == NULL) | ||
501 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
502 | if (offset >= 0x1000) | ||
503 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
504 | addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset); | ||
505 | if (!addr) | ||
506 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
507 | /* | ||
508 | * Note: the caller has already checked that offset is | ||
509 | * suitably aligned and that len is 1, 2 or 4. | ||
510 | */ | ||
511 | switch (len) { | ||
512 | case 1: | ||
513 | *val = in_8(addr); | ||
514 | break; | ||
515 | case 2: | ||
516 | *val = in_le16(addr); | ||
517 | break; | ||
518 | default: | ||
519 | *val = in_le32(addr); | ||
520 | break; | ||
521 | } | ||
522 | return PCIBIOS_SUCCESSFUL; | ||
523 | } | ||
524 | |||
525 | static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | ||
526 | int offset, int len, u32 val) | ||
527 | { | ||
528 | struct pci_controller *hose; | ||
529 | volatile void __iomem *addr; | ||
530 | |||
531 | hose = pci_bus_to_host(bus); | ||
532 | if (hose == NULL) | ||
533 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
534 | if (offset >= 0x1000) | ||
535 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
536 | addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset); | ||
537 | if (!addr) | ||
538 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
539 | /* | ||
540 | * Note: the caller has already checked that offset is | ||
541 | * suitably aligned and that len is 1, 2 or 4. | ||
542 | */ | ||
543 | switch (len) { | ||
544 | case 1: | ||
545 | out_8(addr, val); | ||
546 | break; | ||
547 | case 2: | ||
548 | out_le16(addr, val); | ||
549 | break; | ||
550 | default: | ||
551 | out_le32(addr, val); | ||
552 | break; | ||
553 | } | ||
554 | return PCIBIOS_SUCCESSFUL; | ||
555 | } | ||
556 | |||
557 | static struct pci_ops u4_pcie_pci_ops = | 425 | static struct pci_ops u4_pcie_pci_ops = |
558 | { | 426 | { |
559 | .read = u4_pcie_read_config, | 427 | .map_bus = u4_pcie_cfg_map_bus, |
560 | .write = u4_pcie_write_config, | 428 | .read = pci_generic_config_read, |
429 | .write = pci_generic_config_write, | ||
561 | }; | 430 | }; |
562 | 431 | ||
563 | static void pmac_pci_fixup_u4_of_node(struct pci_dev *dev) | 432 | static void pmac_pci_fixup_u4_of_node(struct pci_dev *dev) |