aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries')
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c90
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c4
-rw-r--r--arch/powerpc/platforms/pseries/pci.c35
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c6
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c3
-rw-r--r--arch/powerpc/platforms/pseries/setup.c5
-rw-r--r--arch/powerpc/platforms/pseries/xics.c68
7 files changed, 105 insertions, 106 deletions
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 556c279a789d..3c95392f4f41 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -309,7 +309,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb,
309 tbl->it_size = size >> IOMMU_PAGE_SHIFT; 309 tbl->it_size = size >> IOMMU_PAGE_SHIFT;
310} 310}
311 311
312static void iommu_bus_setup_pSeries(struct pci_bus *bus) 312static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
313{ 313{
314 struct device_node *dn; 314 struct device_node *dn;
315 struct iommu_table *tbl; 315 struct iommu_table *tbl;
@@ -318,10 +318,9 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
318 struct pci_dn *pci; 318 struct pci_dn *pci;
319 int children; 319 int children;
320 320
321 DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
322
323 dn = pci_bus_to_OF_node(bus); 321 dn = pci_bus_to_OF_node(bus);
324 pci = PCI_DN(dn); 322
323 DBG("pci_dma_bus_setup_pSeries: setting up bus %s\n", dn->full_name);
325 324
326 if (bus->self) { 325 if (bus->self) {
327 /* This is not a root bus, any setup will be done for the 326 /* This is not a root bus, any setup will be done for the
@@ -329,6 +328,7 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
329 */ 328 */
330 return; 329 return;
331 } 330 }
331 pci = PCI_DN(dn);
332 332
333 /* Check if the ISA bus on the system is under 333 /* Check if the ISA bus on the system is under
334 * this PHB. 334 * this PHB.
@@ -390,17 +390,17 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
390} 390}
391 391
392 392
393static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) 393static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
394{ 394{
395 struct iommu_table *tbl; 395 struct iommu_table *tbl;
396 struct device_node *dn, *pdn; 396 struct device_node *dn, *pdn;
397 struct pci_dn *ppci; 397 struct pci_dn *ppci;
398 const void *dma_window = NULL; 398 const void *dma_window = NULL;
399 399
400 DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
401
402 dn = pci_bus_to_OF_node(bus); 400 dn = pci_bus_to_OF_node(bus);
403 401
402 DBG("pci_dma_bus_setup_pSeriesLP: setting up bus %s\n", dn->full_name);
403
404 /* Find nearest ibm,dma-window, walking up the device tree */ 404 /* Find nearest ibm,dma-window, walking up the device tree */
405 for (pdn = dn; pdn != NULL; pdn = pdn->parent) { 405 for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
406 dma_window = get_property(pdn, "ibm,dma-window", NULL); 406 dma_window = get_property(pdn, "ibm,dma-window", NULL);
@@ -409,11 +409,15 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
409 } 409 }
410 410
411 if (dma_window == NULL) { 411 if (dma_window == NULL) {
412 DBG("iommu_bus_setup_pSeriesLP: bus %s seems to have no ibm,dma-window property\n", dn->full_name); 412 DBG(" no ibm,dma-window property !\n");
413 return; 413 return;
414 } 414 }
415 415
416 ppci = PCI_DN(pdn); 416 ppci = PCI_DN(pdn);
417
418 DBG(" parent is %s, iommu_table: 0x%p\n",
419 pdn->full_name, ppci->iommu_table);
420
417 if (!ppci->iommu_table) { 421 if (!ppci->iommu_table) {
418 /* Bussubno hasn't been copied yet. 422 /* Bussubno hasn't been copied yet.
419 * Do it now because iommu_table_setparms_lpar needs it. 423 * Do it now because iommu_table_setparms_lpar needs it.
@@ -427,6 +431,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
427 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); 431 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
428 432
429 ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node); 433 ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
434 DBG(" created table: %p\n", ppci->iommu_table);
430 } 435 }
431 436
432 if (pdn != dn) 437 if (pdn != dn)
@@ -434,27 +439,27 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
434} 439}
435 440
436 441
437static void iommu_dev_setup_pSeries(struct pci_dev *dev) 442static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
438{ 443{
439 struct device_node *dn, *mydn; 444 struct device_node *dn;
440 struct iommu_table *tbl; 445 struct iommu_table *tbl;
441 446
442 DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev)); 447 DBG("pci_dma_dev_setup_pSeries: %s\n", pci_name(dev));
443 448
444 mydn = dn = pci_device_to_OF_node(dev); 449 dn = dev->dev.archdata.of_node;
445 450
446 /* If we're the direct child of a root bus, then we need to allocate 451 /* If we're the direct child of a root bus, then we need to allocate
447 * an iommu table ourselves. The bus setup code should have setup 452 * an iommu table ourselves. The bus setup code should have setup
448 * the window sizes already. 453 * the window sizes already.
449 */ 454 */
450 if (!dev->bus->self) { 455 if (!dev->bus->self) {
456 struct pci_controller *phb = PCI_DN(dn)->phb;
457
451 DBG(" --> first child, no bridge. Allocating iommu table.\n"); 458 DBG(" --> first child, no bridge. Allocating iommu table.\n");
452 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, 459 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
453 PCI_DN(dn)->phb->node); 460 phb->node);
454 iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl); 461 iommu_table_setparms(phb, dn, tbl);
455 PCI_DN(dn)->iommu_table = iommu_init_table(tbl, 462 dev->dev.archdata.dma_data = iommu_init_table(tbl, phb->node);
456 PCI_DN(dn)->phb->node);
457
458 return; 463 return;
459 } 464 }
460 465
@@ -465,11 +470,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev)
465 while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL) 470 while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL)
466 dn = dn->parent; 471 dn = dn->parent;
467 472
468 if (dn && PCI_DN(dn)) { 473 if (dn && PCI_DN(dn))
469 PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table; 474 dev->dev.archdata.dma_data = PCI_DN(dn)->iommu_table;
470 } else { 475 else
471 DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev)); 476 printk(KERN_WARNING "iommu: Device %s has no iommu table\n",
472 } 477 pci_name(dev));
473} 478}
474 479
475static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) 480static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
@@ -495,13 +500,15 @@ static struct notifier_block iommu_reconfig_nb = {
495 .notifier_call = iommu_reconfig_notifier, 500 .notifier_call = iommu_reconfig_notifier,
496}; 501};
497 502
498static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) 503static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
499{ 504{
500 struct device_node *pdn, *dn; 505 struct device_node *pdn, *dn;
501 struct iommu_table *tbl; 506 struct iommu_table *tbl;
502 const void *dma_window = NULL; 507 const void *dma_window = NULL;
503 struct pci_dn *pci; 508 struct pci_dn *pci;
504 509
510 DBG("pci_dma_dev_setup_pSeriesLP: %s\n", pci_name(dev));
511
505 /* dev setup for LPAR is a little tricky, since the device tree might 512 /* dev setup for LPAR is a little tricky, since the device tree might
506 * contain the dma-window properties per-device and not neccesarily 513 * contain the dma-window properties per-device and not neccesarily
507 * for the bus. So we need to search upwards in the tree until we 514 * for the bus. So we need to search upwards in the tree until we
@@ -509,9 +516,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
509 * already allocated. 516 * already allocated.
510 */ 517 */
511 dn = pci_device_to_OF_node(dev); 518 dn = pci_device_to_OF_node(dev);
512 519 DBG(" node is %s\n", dn->full_name);
513 DBG("iommu_dev_setup_pSeriesLP, dev %p (%s) %s\n",
514 dev, pci_name(dev), dn->full_name);
515 520
516 for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; 521 for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
517 pdn = pdn->parent) { 522 pdn = pdn->parent) {
@@ -520,16 +525,17 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
520 break; 525 break;
521 } 526 }
522 527
528 DBG(" parent is %s\n", pdn->full_name);
529
523 /* Check for parent == NULL so we don't try to setup the empty EADS 530 /* Check for parent == NULL so we don't try to setup the empty EADS
524 * slots on POWER4 machines. 531 * slots on POWER4 machines.
525 */ 532 */
526 if (dma_window == NULL || pdn->parent == NULL) { 533 if (dma_window == NULL || pdn->parent == NULL) {
527 DBG("No dma window for device, linking to parent\n"); 534 DBG(" no dma window for device, linking to parent\n");
528 PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table; 535 dev->dev.archdata.dma_data = PCI_DN(pdn)->iommu_table;
529 return; 536 return;
530 } else {
531 DBG("Found DMA window, allocating table\n");
532 } 537 }
538 DBG(" found DMA window, table: %p\n", pci->iommu_table);
533 539
534 pci = PCI_DN(pdn); 540 pci = PCI_DN(pdn);
535 if (!pci->iommu_table) { 541 if (!pci->iommu_table) {
@@ -542,24 +548,20 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
542 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); 548 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
543 549
544 pci->iommu_table = iommu_init_table(tbl, pci->phb->node); 550 pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
551 DBG(" created table: %p\n", pci->iommu_table);
545 } 552 }
546 553
547 if (pdn != dn) 554 dev->dev.archdata.dma_data = pci->iommu_table;
548 PCI_DN(dn)->iommu_table = pci->iommu_table;
549} 555}
550 556
551static void iommu_bus_setup_null(struct pci_bus *b) { }
552static void iommu_dev_setup_null(struct pci_dev *d) { }
553
554/* These are called very early. */ 557/* These are called very early. */
555void iommu_init_early_pSeries(void) 558void iommu_init_early_pSeries(void)
556{ 559{
557 if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) { 560 if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) {
558 /* Direct I/O, IOMMU off */ 561 /* Direct I/O, IOMMU off */
559 ppc_md.iommu_dev_setup = iommu_dev_setup_null; 562 ppc_md.pci_dma_dev_setup = NULL;
560 ppc_md.iommu_bus_setup = iommu_bus_setup_null; 563 ppc_md.pci_dma_bus_setup = NULL;
561 pci_direct_iommu_init(); 564 pci_dma_ops = &dma_direct_ops;
562
563 return; 565 return;
564 } 566 }
565 567
@@ -572,19 +574,19 @@ void iommu_init_early_pSeries(void)
572 ppc_md.tce_free = tce_free_pSeriesLP; 574 ppc_md.tce_free = tce_free_pSeriesLP;
573 } 575 }
574 ppc_md.tce_get = tce_get_pSeriesLP; 576 ppc_md.tce_get = tce_get_pSeriesLP;
575 ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP; 577 ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP;
576 ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP; 578 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP;
577 } else { 579 } else {
578 ppc_md.tce_build = tce_build_pSeries; 580 ppc_md.tce_build = tce_build_pSeries;
579 ppc_md.tce_free = tce_free_pSeries; 581 ppc_md.tce_free = tce_free_pSeries;
580 ppc_md.tce_get = tce_get_pseries; 582 ppc_md.tce_get = tce_get_pseries;
581 ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries; 583 ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeries;
582 ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; 584 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeries;
583 } 585 }
584 586
585 587
586 pSeries_reconfig_notifier_register(&iommu_reconfig_nb); 588 pSeries_reconfig_notifier_register(&iommu_reconfig_nb);
587 589
588 pci_iommu_init(); 590 pci_dma_ops = &dma_iommu_ops;
589} 591}
590 592
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 1820a0b0a8c6..721436db3ef0 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -282,7 +282,7 @@ void vpa_init(int cpu)
282 } 282 }
283} 283}
284 284
285long pSeries_lpar_hpte_insert(unsigned long hpte_group, 285static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
286 unsigned long va, unsigned long pa, 286 unsigned long va, unsigned long pa,
287 unsigned long rflags, unsigned long vflags, 287 unsigned long rflags, unsigned long vflags,
288 int psize) 288 int psize)
@@ -506,7 +506,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
506 * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie 506 * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie
507 * lock. 507 * lock.
508 */ 508 */
509void pSeries_lpar_flush_hash_range(unsigned long number, int local) 509static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
510{ 510{
511 int i; 511 int i;
512 unsigned long flags = 0; 512 unsigned long flags = 0;
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index 410a6bcc4ca0..715db5c89908 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -29,8 +29,6 @@
29#include <asm/prom.h> 29#include <asm/prom.h>
30#include <asm/ppc-pci.h> 30#include <asm/ppc-pci.h>
31 31
32static int __devinitdata s7a_workaround = -1;
33
34#if 0 32#if 0
35void pcibios_name_device(struct pci_dev *dev) 33void pcibios_name_device(struct pci_dev *dev)
36{ 34{
@@ -57,39 +55,6 @@ void pcibios_name_device(struct pci_dev *dev)
57DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device); 55DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
58#endif 56#endif
59 57
60static void __devinit check_s7a(void)
61{
62 struct device_node *root;
63 const char *model;
64
65 s7a_workaround = 0;
66 root = of_find_node_by_path("/");
67 if (root) {
68 model = get_property(root, "model", NULL);
69 if (model && !strcmp(model, "IBM,7013-S7A"))
70 s7a_workaround = 1;
71 of_node_put(root);
72 }
73}
74
75void __devinit pSeries_irq_bus_setup(struct pci_bus *bus)
76{
77 struct pci_dev *dev;
78
79 if (s7a_workaround < 0)
80 check_s7a();
81 list_for_each_entry(dev, &bus->devices, bus_list) {
82 pci_read_irq_line(dev);
83 if (s7a_workaround) {
84 if (dev->irq > 16) {
85 dev->irq -= 3;
86 pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
87 dev->irq);
88 }
89 }
90 }
91}
92
93static void __init pSeries_request_regions(void) 58static void __init pSeries_request_regions(void)
94{ 59{
95 if (!isa_io_base) 60 if (!isa_io_base)
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 6bfacc217085..ac56b868913a 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -93,8 +93,8 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
93 if (list_empty(&dev->global_list)) { 93 if (list_empty(&dev->global_list)) {
94 int i; 94 int i;
95 95
96 /* Need to setup IOMMU tables */ 96 /* Fill device archdata and setup iommu table */
97 ppc_md.iommu_dev_setup(dev); 97 pcibios_setup_new_device(dev);
98 98
99 if(fix_bus) 99 if(fix_bus)
100 pcibios_fixup_device_resources(dev, bus); 100 pcibios_fixup_device_resources(dev, bus);
@@ -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);
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 1773103354be..4ad33e41b008 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -268,11 +268,10 @@ static char * parse_next_property(char *buf, char *end, char **name, int *length
268static struct property *new_property(const char *name, const int length, 268static struct property *new_property(const char *name, const int length,
269 const unsigned char *value, struct property *last) 269 const unsigned char *value, struct property *last)
270{ 270{
271 struct property *new = kmalloc(sizeof(*new), GFP_KERNEL); 271 struct property *new = kzalloc(sizeof(*new), GFP_KERNEL);
272 272
273 if (!new) 273 if (!new)
274 return NULL; 274 return NULL;
275 memset(new, 0, sizeof(*new));
276 275
277 if (!(new->name = kmalloc(strlen(name) + 1, GFP_KERNEL))) 276 if (!(new->name = kmalloc(strlen(name) + 1, GFP_KERNEL)))
278 goto cleanup; 277 goto cleanup;
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 89a8119f988d..0dc2548ca9bc 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -347,6 +347,7 @@ static int __init pSeries_init_panel(void)
347} 347}
348arch_initcall(pSeries_init_panel); 348arch_initcall(pSeries_init_panel);
349 349
350#ifdef CONFIG_HOTPLUG_CPU
350static void pSeries_mach_cpu_die(void) 351static void pSeries_mach_cpu_die(void)
351{ 352{
352 local_irq_disable(); 353 local_irq_disable();
@@ -357,6 +358,9 @@ static void pSeries_mach_cpu_die(void)
357 BUG(); 358 BUG();
358 for(;;); 359 for(;;);
359} 360}
361#else
362#define pSeries_mach_cpu_die NULL
363#endif
360 364
361static int pseries_set_dabr(unsigned long dabr) 365static int pseries_set_dabr(unsigned long dabr)
362{ 366{
@@ -553,7 +557,6 @@ define_machine(pseries) {
553 .log_error = pSeries_log_error, 557 .log_error = pSeries_log_error,
554 .pcibios_fixup = pSeries_final_fixup, 558 .pcibios_fixup = pSeries_final_fixup,
555 .pci_probe_mode = pSeries_pci_probe_mode, 559 .pci_probe_mode = pSeries_pci_probe_mode,
556 .irq_bus_setup = pSeries_irq_bus_setup,
557 .restart = rtas_restart, 560 .restart = rtas_restart,
558 .power_off = rtas_power_off, 561 .power_off = rtas_power_off,
559 .halt = rtas_halt, 562 .halt = rtas_halt,
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index d071abe78ab1..b5b2b1103de8 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -656,13 +656,38 @@ static void __init xics_setup_8259_cascade(void)
656 set_irq_chained_handler(cascade, pseries_8259_cascade); 656 set_irq_chained_handler(cascade, pseries_8259_cascade);
657} 657}
658 658
659static struct device_node *cpuid_to_of_node(int cpu)
660{
661 struct device_node *np;
662 u32 hcpuid = get_hard_smp_processor_id(cpu);
663
664 for_each_node_by_type(np, "cpu") {
665 int i, len;
666 const u32 *intserv;
667
668 intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len);
669
670 if (!intserv)
671 intserv = get_property(np, "reg", &len);
672
673 i = len / sizeof(u32);
674
675 while (i--)
676 if (intserv[i] == hcpuid)
677 return np;
678 }
679
680 return NULL;
681}
682
659void __init xics_init_IRQ(void) 683void __init xics_init_IRQ(void)
660{ 684{
661 int i; 685 int i, j;
662 struct device_node *np; 686 struct device_node *np;
663 u32 ilen, indx = 0; 687 u32 ilen, indx = 0;
664 const u32 *ireg; 688 const u32 *ireg, *isize;
665 int found = 0; 689 int found = 0;
690 u32 hcpuid;
666 691
667 ppc64_boot_msg(0x20, "XICS Init"); 692 ppc64_boot_msg(0x20, "XICS Init");
668 693
@@ -683,26 +708,31 @@ void __init xics_init_IRQ(void)
683 xics_init_host(); 708 xics_init_host();
684 709
685 /* Find the server numbers for the boot cpu. */ 710 /* Find the server numbers for the boot cpu. */
686 for (np = of_find_node_by_type(NULL, "cpu"); 711 np = cpuid_to_of_node(boot_cpuid);
687 np; 712 BUG_ON(!np);
688 np = of_find_node_by_type(np, "cpu")) { 713 ireg = get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
689 ireg = get_property(np, "reg", &ilen); 714 if (!ireg)
690 if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) { 715 goto skip_gserver_check;
691 ireg = get_property(np, 716 i = ilen / sizeof(int);
692 "ibm,ppc-interrupt-gserver#s", &ilen); 717 hcpuid = get_hard_smp_processor_id(boot_cpuid);
693 i = ilen / sizeof(int); 718
694 if (ireg && i > 0) { 719 /* Global interrupt distribution server is specified in the last
695 default_server = ireg[0]; 720 * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
696 /* take last element */ 721 * entry fom this property for current boot cpu id and use it as
697 default_distrib_server = ireg[i-1]; 722 * default distribution server
698 } 723 */
699 ireg = get_property(np, 724 for (j = 0; j < i; j += 2) {
725 if (ireg[j] == hcpuid) {
726 default_server = hcpuid;
727 default_distrib_server = ireg[j+1];
728
729 isize = get_property(np,
700 "ibm,interrupt-server#-size", NULL); 730 "ibm,interrupt-server#-size", NULL);
701 if (ireg) 731 if (isize)
702 interrupt_server_size = *ireg; 732 interrupt_server_size = *isize;
703 break;
704 } 733 }
705 } 734 }
735skip_gserver_check:
706 of_node_put(np); 736 of_node_put(np);
707 737
708 if (firmware_has_feature(FW_FEATURE_LPAR)) 738 if (firmware_has_feature(FW_FEATURE_LPAR))