aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/rtas_pci.c
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-11-15 00:05:33 -0500
committerPaul Mackerras <paulus@samba.org>2005-11-15 21:29:46 -0500
commitb5166cc252190be80465f3b4f050e4a0310f71af (patch)
tree565d11c2ea25d1553489d6c8a9b4d2c00e110288 /arch/powerpc/kernel/rtas_pci.c
parentf9e4ec57c66586d0c165ed9373efaf9e329d5766 (diff)
[PATCH] powerpc: pci_64 fixes & cleanups
I discovered that in some cases (PowerMac for example) we wouldn't properly map the PCI IO space on recent kernels. In addition, the code for initializing PCI host bridges was scattered all over the place with some duplication between platforms. This patch fixes the problem and does a small cleanup by creating a pcibios_alloc_controller() in pci_64.c that is similar to the one in pci_32.c (just takes an additional device node argument) that takes care of all the grunt allocation and initialisation work. It should work for both boot time and dynamically allocated PHBs. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/rtas_pci.c')
-rw-r--r--arch/powerpc/kernel/rtas_pci.c68
1 files changed, 5 insertions, 63 deletions
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 0e5a8e116653..60dec2401c26 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -304,75 +304,18 @@ static int __devinit setup_phb(struct device_node *dev,
304 struct pci_controller *phb, 304 struct pci_controller *phb,
305 unsigned int addr_size_words) 305 unsigned int addr_size_words)
306{ 306{
307 pci_setup_pci_controller(phb);
308
309 if (is_python(dev)) 307 if (is_python(dev))
310 python_countermeasures(dev, addr_size_words); 308 python_countermeasures(dev, addr_size_words);
311 309
312 if (phb_set_bus_ranges(dev, phb)) 310 if (phb_set_bus_ranges(dev, phb))
313 return 1; 311 return 1;
314 312
315 phb->arch_data = dev;
316 phb->ops = &rtas_pci_ops; 313 phb->ops = &rtas_pci_ops;
317 phb->buid = get_phb_buid(dev); 314 phb->buid = get_phb_buid(dev);
318 315
319 return 0; 316 return 0;
320} 317}
321 318
322static void __devinit add_linux_pci_domain(struct device_node *dev,
323 struct pci_controller *phb,
324 struct property *of_prop)
325{
326 memset(of_prop, 0, sizeof(struct property));
327 of_prop->name = "linux,pci-domain";
328 of_prop->length = sizeof(phb->global_number);
329 of_prop->value = (unsigned char *)&of_prop[1];
330 memcpy(of_prop->value, &phb->global_number, sizeof(phb->global_number));
331 prom_add_property(dev, of_prop);
332}
333
334static struct pci_controller * __init alloc_phb(struct device_node *dev,
335 unsigned int addr_size_words)
336{
337 struct pci_controller *phb;
338 struct property *of_prop;
339
340 phb = alloc_bootmem(sizeof(struct pci_controller));
341 if (phb == NULL)
342 return NULL;
343
344 of_prop = alloc_bootmem(sizeof(struct property) +
345 sizeof(phb->global_number));
346 if (!of_prop)
347 return NULL;
348
349 if (setup_phb(dev, phb, addr_size_words))
350 return NULL;
351
352 add_linux_pci_domain(dev, phb, of_prop);
353
354 return phb;
355}
356
357static struct pci_controller * __devinit alloc_phb_dynamic(struct device_node *dev, unsigned int addr_size_words)
358{
359 struct pci_controller *phb;
360
361 phb = (struct pci_controller *)kmalloc(sizeof(struct pci_controller),
362 GFP_KERNEL);
363 if (phb == NULL)
364 return NULL;
365
366 if (setup_phb(dev, phb, addr_size_words))
367 return NULL;
368
369 phb->is_dynamic = 1;
370
371 /* TODO: linux,pci-domain? */
372
373 return phb;
374}
375
376unsigned long __init find_and_init_phbs(void) 319unsigned long __init find_and_init_phbs(void)
377{ 320{
378 struct device_node *node; 321 struct device_node *node;
@@ -397,10 +340,10 @@ unsigned long __init find_and_init_phbs(void)
397 if (node->type == NULL || strcmp(node->type, "pci") != 0) 340 if (node->type == NULL || strcmp(node->type, "pci") != 0)
398 continue; 341 continue;
399 342
400 phb = alloc_phb(node, root_size_cells); 343 phb = pcibios_alloc_controller(node);
401 if (!phb) 344 if (!phb)
402 continue; 345 continue;
403 346 setup_phb(node, phb, root_size_cells);
404 pci_process_bridge_OF_ranges(phb, node, 0); 347 pci_process_bridge_OF_ranges(phb, node, 0);
405 pci_setup_phb_io(phb, index == 0); 348 pci_setup_phb_io(phb, index == 0);
406#ifdef CONFIG_PPC_PSERIES 349#ifdef CONFIG_PPC_PSERIES
@@ -446,10 +389,10 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
446 root_size_cells = prom_n_size_cells(root); 389 root_size_cells = prom_n_size_cells(root);
447 390
448 primary = list_empty(&hose_list); 391 primary = list_empty(&hose_list);
449 phb = alloc_phb_dynamic(dn, root_size_cells); 392 phb = pcibios_alloc_controller(dn);
450 if (!phb) 393 if (!phb)
451 return NULL; 394 return NULL;
452 395 setup_phb(dn, phb, root_size_cells);
453 pci_process_bridge_OF_ranges(phb, dn, primary); 396 pci_process_bridge_OF_ranges(phb, dn, primary);
454 397
455 pci_setup_phb_io_dynamic(phb, primary); 398 pci_setup_phb_io_dynamic(phb, primary);
@@ -505,8 +448,7 @@ int pcibios_remove_root_bus(struct pci_controller *phb)
505 } 448 }
506 449
507 list_del(&phb->list_node); 450 list_del(&phb->list_node);
508 if (phb->is_dynamic) 451 pcibios_free_controller(phb);
509 kfree(phb);
510 452
511 return 0; 453 return 0;
512} 454}