aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/celleb/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/celleb/pci.c')
-rw-r--r--arch/powerpc/platforms/celleb/pci.c98
1 files changed, 56 insertions, 42 deletions
diff --git a/arch/powerpc/platforms/celleb/pci.c b/arch/powerpc/platforms/celleb/pci.c
index e9ac19c4bba4..6bc32fda7a6b 100644
--- a/arch/powerpc/platforms/celleb/pci.c
+++ b/arch/powerpc/platforms/celleb/pci.c
@@ -31,6 +31,7 @@
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/bootmem.h> 32#include <linux/bootmem.h>
33#include <linux/pci_regs.h> 33#include <linux/pci_regs.h>
34#include <linux/of_device.h>
34 35
35#include <asm/io.h> 36#include <asm/io.h>
36#include <asm/irq.h> 37#include <asm/irq.h>
@@ -242,8 +243,8 @@ static int celleb_fake_pci_write_config(struct pci_bus *bus,
242} 243}
243 244
244static struct pci_ops celleb_fake_pci_ops = { 245static struct pci_ops celleb_fake_pci_ops = {
245 celleb_fake_pci_read_config, 246 .read = celleb_fake_pci_read_config,
246 celleb_fake_pci_write_config 247 .write = celleb_fake_pci_write_config,
247}; 248};
248 249
249static inline void celleb_setup_pci_base_addrs(struct pci_controller *hose, 250static inline void celleb_setup_pci_base_addrs(struct pci_controller *hose,
@@ -288,8 +289,8 @@ static inline void celleb_setup_pci_base_addrs(struct pci_controller *hose,
288 celleb_config_write_fake(config, PCI_COMMAND, 2, val); 289 celleb_config_write_fake(config, PCI_COMMAND, 2, val);
289} 290}
290 291
291static int __devinit celleb_setup_fake_pci_device(struct device_node *node, 292static int __init celleb_setup_fake_pci_device(struct device_node *node,
292 struct pci_controller *hose) 293 struct pci_controller *hose)
293{ 294{
294 unsigned int rlen; 295 unsigned int rlen;
295 int num_base_addr = 0; 296 int num_base_addr = 0;
@@ -327,10 +328,7 @@ static int __devinit celleb_setup_fake_pci_device(struct device_node *node,
327 328
328 size = 256; 329 size = 256;
329 config = &private->fake_config[devno][fn]; 330 config = &private->fake_config[devno][fn];
330 if (mem_init_done) 331 *config = alloc_maybe_bootmem(size, GFP_KERNEL);
331 *config = kzalloc(size, GFP_KERNEL);
332 else
333 *config = alloc_bootmem(size);
334 if (*config == NULL) { 332 if (*config == NULL) {
335 printk(KERN_ERR "PCI: " 333 printk(KERN_ERR "PCI: "
336 "not enough memory for fake configuration space\n"); 334 "not enough memory for fake configuration space\n");
@@ -341,10 +339,7 @@ static int __devinit celleb_setup_fake_pci_device(struct device_node *node,
341 339
342 size = sizeof(struct celleb_pci_resource); 340 size = sizeof(struct celleb_pci_resource);
343 res = &private->res[devno][fn]; 341 res = &private->res[devno][fn];
344 if (mem_init_done) 342 *res = alloc_maybe_bootmem(size, GFP_KERNEL);
345 *res = kzalloc(size, GFP_KERNEL);
346 else
347 *res = alloc_bootmem(size);
348 if (*res == NULL) { 343 if (*res == NULL) {
349 printk(KERN_ERR 344 printk(KERN_ERR
350 "PCI: not enough memory for resource data space\n"); 345 "PCI: not enough memory for resource data space\n");
@@ -418,8 +413,8 @@ error:
418 return 1; 413 return 1;
419} 414}
420 415
421static int __devinit phb_set_bus_ranges(struct device_node *dev, 416static int __init phb_set_bus_ranges(struct device_node *dev,
422 struct pci_controller *phb) 417 struct pci_controller *phb)
423{ 418{
424 const int *bus_range; 419 const int *bus_range;
425 unsigned int len; 420 unsigned int len;
@@ -434,46 +429,65 @@ static int __devinit phb_set_bus_ranges(struct device_node *dev,
434 return 0; 429 return 0;
435} 430}
436 431
437static void __devinit celleb_alloc_private_mem(struct pci_controller *hose) 432static void __init celleb_alloc_private_mem(struct pci_controller *hose)
438{ 433{
439 if (mem_init_done) 434 hose->private_data =
440 hose->private_data = 435 alloc_maybe_bootmem(sizeof(struct celleb_pci_private),
441 kzalloc(sizeof(struct celleb_pci_private), GFP_KERNEL); 436 GFP_KERNEL);
442 else
443 hose->private_data =
444 alloc_bootmem(sizeof(struct celleb_pci_private));
445} 437}
446 438
447int __devinit celleb_setup_phb(struct pci_controller *phb) 439static int __init celleb_setup_fake_pci(struct device_node *dev,
440 struct pci_controller *phb)
448{ 441{
449 const char *name;
450 struct device_node *dev = phb->arch_data;
451 struct device_node *node; 442 struct device_node *node;
452 unsigned int rlen;
453 443
454 name = of_get_property(dev, "name", &rlen); 444 phb->ops = &celleb_fake_pci_ops;
455 if (!name) 445 celleb_alloc_private_mem(phb);
456 return 1;
457 446
458 pr_debug("PCI: celleb_setup_phb() %s\n", name); 447 for (node = of_get_next_child(dev, NULL);
459 phb_set_bus_ranges(dev, phb); 448 node != NULL; node = of_get_next_child(dev, node))
460 phb->buid = 1; 449 celleb_setup_fake_pci_device(node, phb);
450
451 return 0;
452}
461 453
462 if (strcmp(name, "epci") == 0) { 454void __init fake_pci_workaround_init(struct pci_controller *phb)
463 phb->ops = &celleb_epci_ops; 455{
464 return celleb_setup_epci(dev, phb); 456 /**
457 * We will add fake pci bus to scc_pci_bus for the purpose to improve
458 * I/O Macro performance. But device-tree and device drivers
459 * are not ready to use address with a token.
460 */
461
462 /* celleb_pci_add_one(phb, NULL); */
463}
465 464
466 } else if (strcmp(name, "pci-pseudo") == 0) { 465static struct of_device_id celleb_phb_match[] __initdata = {
467 phb->ops = &celleb_fake_pci_ops; 466 {
468 celleb_alloc_private_mem(phb); 467 .name = "pci-pseudo",
469 for (node = of_get_next_child(dev, NULL); 468 .data = celleb_setup_fake_pci,
470 node != NULL; node = of_get_next_child(dev, node)) 469 }, {
471 celleb_setup_fake_pci_device(node, phb); 470 .name = "epci",
471 .data = celleb_setup_epci,
472 }, {
473 },
474};
472 475
473 } else 476int __init celleb_setup_phb(struct pci_controller *phb)
477{
478 struct device_node *dev = phb->arch_data;
479 const struct of_device_id *match;
480 int (*setup_func)(struct device_node *, struct pci_controller *);
481
482 match = of_match_node(celleb_phb_match, dev);
483 if (!match)
474 return 1; 484 return 1;
475 485
476 return 0; 486 phb_set_bus_ranges(dev, phb);
487 phb->buid = 1;
488
489 setup_func = match->data;
490 return (*setup_func)(dev, phb);
477} 491}
478 492
479int celleb_pci_probe_mode(struct pci_bus *bus) 493int celleb_pci_probe_mode(struct pci_bus *bus)