aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/Kconfig6
-rw-r--r--arch/powerpc/kernel/of_platform.c103
-rw-r--r--arch/powerpc/kernel/pci_64.c9
-rw-r--r--arch/powerpc/kernel/rtas_pci.c7
-rw-r--r--arch/powerpc/platforms/cell/setup.c1
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c2
6 files changed, 124 insertions, 4 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 65588a6bd2fe..3d26ba7ad76d 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -223,6 +223,11 @@ config PPC_DCR
223 depends on PPC_DCR_NATIVE || PPC_DCR_MMIO 223 depends on PPC_DCR_NATIVE || PPC_DCR_MMIO
224 default y 224 default y
225 225
226config PPC_OF_PLATFORM_PCI
227 bool
228 depends on PPC64 # not supported on 32 bits yet
229 default n
230
226config BOOKE 231config BOOKE
227 bool 232 bool
228 depends on E200 || E500 233 depends on E200 || E500
@@ -469,6 +474,7 @@ config PPC_CELL_NATIVE
469 bool 474 bool
470 select PPC_CELL 475 select PPC_CELL
471 select PPC_DCR_MMIO 476 select PPC_DCR_MMIO
477 select PPC_OF_PLATFORM_PCI
472 select MPIC 478 select MPIC
473 default n 479 default n
474 480
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index 7a0e77af7c9f..6029543c1b5e 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. 2 * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
3 * <benh@kernel.crashing.org> 3 * <benh@kernel.crashing.org>
4 * and Arnd Bergmann, IBM Corp.
4 * 5 *
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
@@ -17,12 +18,15 @@
17#include <linux/module.h> 18#include <linux/module.h>
18#include <linux/mod_devicetable.h> 19#include <linux/mod_devicetable.h>
19#include <linux/slab.h> 20#include <linux/slab.h>
21#include <linux/pci.h>
20 22
21#include <asm/errno.h> 23#include <asm/errno.h>
22#include <asm/dcr.h> 24#include <asm/dcr.h>
23#include <asm/of_device.h> 25#include <asm/of_device.h>
24#include <asm/of_platform.h> 26#include <asm/of_platform.h>
25#include <asm/topology.h> 27#include <asm/topology.h>
28#include <asm/pci-bridge.h>
29#include <asm/ppc-pci.h>
26 30
27/* 31/*
28 * The list of OF IDs below is used for matching bus types in the 32 * The list of OF IDs below is used for matching bus types in the
@@ -377,3 +381,102 @@ struct of_device *of_find_device_by_phandle(phandle ph)
377 return NULL; 381 return NULL;
378} 382}
379EXPORT_SYMBOL(of_find_device_by_phandle); 383EXPORT_SYMBOL(of_find_device_by_phandle);
384
385
386#ifdef CONFIG_PPC_OF_PLATFORM_PCI
387
388/* The probing of PCI controllers from of_platform is currently
389 * 64 bits only, mostly due to gratuitous differences between
390 * the 32 and 64 bits PCI code on PowerPC and the 32 bits one
391 * lacking some bits needed here.
392 */
393
394static int __devinit of_pci_phb_probe(struct of_device *dev,
395 const struct of_device_id *match)
396{
397 struct pci_controller *phb;
398
399 /* Check if we can do that ... */
400 if (ppc_md.pci_setup_phb == NULL)
401 return -ENODEV;
402
403 printk(KERN_INFO "Setting up PCI bus %s\n", dev->node->full_name);
404
405 /* Alloc and setup PHB data structure */
406 phb = pcibios_alloc_controller(dev->node);
407 if (!phb)
408 return -ENODEV;
409
410 /* Setup parent in sysfs */
411 phb->parent = &dev->dev;
412
413 /* Setup the PHB using arch provided callback */
414 if (ppc_md.pci_setup_phb(phb)) {
415 pcibios_free_controller(phb);
416 return -ENODEV;
417 }
418
419 /* Process "ranges" property */
420 pci_process_bridge_OF_ranges(phb, dev->node, 0);
421
422 /* Setup IO space.
423 * This will not work properly for ISA IOs, something needs to be done
424 * about it if we ever generalize that way of probing PCI brigdes
425 */
426 pci_setup_phb_io_dynamic(phb, 0);
427
428 /* Init pci_dn data structures */
429 pci_devs_phb_init_dynamic(phb);
430
431 /* Register devices with EEH */
432#ifdef CONFIG_EEH
433 if (dev->node->child)
434 eeh_add_device_tree_early(dev->node);
435#endif /* CONFIG_EEH */
436
437 /* Scan the bus */
438 scan_phb(phb);
439
440 /* Claim resources. This might need some rework as well depending
441 * wether we are doing probe-only or not, like assigning unassigned
442 * resources etc...
443 */
444 pcibios_claim_one_bus(phb->bus);
445
446 /* Finish EEH setup */
447#ifdef CONFIG_EEH
448 eeh_add_device_tree_late(phb->bus);
449#endif
450
451 /* Add probed PCI devices to the device model */
452 pci_bus_add_devices(phb->bus);
453
454 return 0;
455}
456
457static struct of_device_id of_pci_phb_ids[] = {
458 { .type = "pci", },
459 { .type = "pcix", },
460 { .type = "pcie", },
461 { .type = "pciex", },
462 { .type = "ht", },
463 {}
464};
465
466static struct of_platform_driver of_pci_phb_driver = {
467 .name = "of-pci",
468 .match_table = of_pci_phb_ids,
469 .probe = of_pci_phb_probe,
470 .driver = {
471 .multithread_probe = 1,
472 },
473};
474
475static __init int of_pci_phb_init(void)
476{
477 return of_register_platform_driver(&of_pci_phb_driver);
478}
479
480device_initcall(of_pci_phb_init);
481
482#endif /* CONFIG_PPC_OF_PLATFORM_PCI */
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 74e580d25c1b..d800e19ea564 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -210,6 +210,10 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
210 210
211void pcibios_free_controller(struct pci_controller *phb) 211void pcibios_free_controller(struct pci_controller *phb)
212{ 212{
213 spin_lock(&hose_spinlock);
214 list_del(&phb->list_node);
215 spin_unlock(&hose_spinlock);
216
213 if (phb->is_dynamic) 217 if (phb->is_dynamic)
214 kfree(phb); 218 kfree(phb);
215} 219}
@@ -1242,6 +1246,11 @@ static void __devinit do_bus_setup(struct pci_bus *bus)
1242void __devinit pcibios_fixup_bus(struct pci_bus *bus) 1246void __devinit pcibios_fixup_bus(struct pci_bus *bus)
1243{ 1247{
1244 struct pci_dev *dev = bus->self; 1248 struct pci_dev *dev = bus->self;
1249 struct device_node *np;
1250
1251 np = pci_bus_to_OF_node(bus);
1252
1253 DBG("pcibios_fixup_bus(%s)\n", np ? np->full_name : "<???>");
1245 1254
1246 if (dev && pci_probe_only && 1255 if (dev && pci_probe_only &&
1247 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { 1256 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 2576e12d7255..03cacc25a0ae 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -257,8 +257,10 @@ static int phb_set_bus_ranges(struct device_node *dev,
257 return 0; 257 return 0;
258} 258}
259 259
260int __devinit setup_phb(struct device_node *dev, struct pci_controller *phb) 260int __devinit rtas_setup_phb(struct pci_controller *phb)
261{ 261{
262 struct device_node *dev = phb->arch_data;
263
262 if (is_python(dev)) 264 if (is_python(dev))
263 python_countermeasures(dev); 265 python_countermeasures(dev);
264 266
@@ -290,7 +292,7 @@ unsigned long __init find_and_init_phbs(void)
290 phb = pcibios_alloc_controller(node); 292 phb = pcibios_alloc_controller(node);
291 if (!phb) 293 if (!phb)
292 continue; 294 continue;
293 setup_phb(node, phb); 295 rtas_setup_phb(phb);
294 pci_process_bridge_OF_ranges(phb, node, 0); 296 pci_process_bridge_OF_ranges(phb, node, 0);
295 pci_setup_phb_io(phb, index == 0); 297 pci_setup_phb_io(phb, index == 0);
296 index++; 298 index++;
@@ -362,7 +364,6 @@ int pcibios_remove_root_bus(struct pci_controller *phb)
362 } 364 }
363 } 365 }
364 366
365 list_del(&phb->list_node);
366 pcibios_free_controller(phb); 367 pcibios_free_controller(phb);
367 368
368 return 0; 369 return 0;
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index b39753f16d48..7e18420166c4 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -256,6 +256,7 @@ define_machine(cell) {
256 .check_legacy_ioport = cell_check_legacy_ioport, 256 .check_legacy_ioport = cell_check_legacy_ioport,
257 .progress = cell_progress, 257 .progress = cell_progress,
258 .init_IRQ = cell_init_irq, 258 .init_IRQ = cell_init_irq,
259 .pci_setup_phb = rtas_setup_phb,
259#ifdef CONFIG_KEXEC 260#ifdef CONFIG_KEXEC
260 .machine_kexec = default_machine_kexec, 261 .machine_kexec = default_machine_kexec,
261 .machine_kexec_prepare = default_machine_kexec_prepare, 262 .machine_kexec_prepare = default_machine_kexec_prepare,
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index bb0cb5c5b565..ac56b868913a 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -195,7 +195,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
195 phb = pcibios_alloc_controller(dn); 195 phb = pcibios_alloc_controller(dn);
196 if (!phb) 196 if (!phb)
197 return NULL; 197 return NULL;
198 setup_phb(dn, phb); 198 rtas_setup_phb(phb);
199 pci_process_bridge_OF_ranges(phb, dn, 0); 199 pci_process_bridge_OF_ranges(phb, dn, 0);
200 200
201 pci_setup_phb_io_dynamic(phb, primary); 201 pci_setup_phb_io_dynamic(phb, primary);