aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/xics.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/platforms/pseries/xics.c')
-rw-r--r--arch/powerpc/platforms/pseries/xics.c485
1 files changed, 297 insertions, 188 deletions
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index c7f04420066d..716972aa9777 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -8,6 +8,9 @@
8 * as published by the Free Software Foundation; either version 8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version. 9 * 2 of the License, or (at your option) any later version.
10 */ 10 */
11
12#undef DEBUG
13
11#include <linux/types.h> 14#include <linux/types.h>
12#include <linux/threads.h> 15#include <linux/threads.h>
13#include <linux/kernel.h> 16#include <linux/kernel.h>
@@ -19,6 +22,7 @@
19#include <linux/gfp.h> 22#include <linux/gfp.h>
20#include <linux/radix-tree.h> 23#include <linux/radix-tree.h>
21#include <linux/cpu.h> 24#include <linux/cpu.h>
25
22#include <asm/firmware.h> 26#include <asm/firmware.h>
23#include <asm/prom.h> 27#include <asm/prom.h>
24#include <asm/io.h> 28#include <asm/io.h>
@@ -31,9 +35,6 @@
31 35
32#include "xics.h" 36#include "xics.h"
33 37
34/* This is used to map real irq numbers to virtual */
35static struct radix_tree_root irq_map = RADIX_TREE_INIT(GFP_ATOMIC);
36
37#define XICS_IPI 2 38#define XICS_IPI 2
38#define XICS_IRQ_SPURIOUS 0 39#define XICS_IRQ_SPURIOUS 0
39 40
@@ -64,12 +65,12 @@ struct xics_ipl {
64 65
65static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS]; 66static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS];
66 67
67static int xics_irq_8259_cascade = 0;
68static int xics_irq_8259_cascade_real = 0;
69static unsigned int default_server = 0xFF; 68static unsigned int default_server = 0xFF;
70static unsigned int default_distrib_server = 0; 69static unsigned int default_distrib_server = 0;
71static unsigned int interrupt_server_size = 8; 70static unsigned int interrupt_server_size = 8;
72 71
72static struct irq_host *xics_host;
73
73/* 74/*
74 * XICS only has a single IPI, so encode the messages per CPU 75 * XICS only has a single IPI, so encode the messages per CPU
75 */ 76 */
@@ -85,7 +86,7 @@ static int ibm_int_off;
85/* Direct HW low level accessors */ 86/* Direct HW low level accessors */
86 87
87 88
88static inline int direct_xirr_info_get(int n_cpu) 89static inline unsigned int direct_xirr_info_get(int n_cpu)
89{ 90{
90 return in_be32(&xics_per_cpu[n_cpu]->xirr.word); 91 return in_be32(&xics_per_cpu[n_cpu]->xirr.word);
91} 92}
@@ -130,7 +131,7 @@ static inline long plpar_xirr(unsigned long *xirr_ret)
130 return plpar_hcall(H_XIRR, 0, 0, 0, 0, xirr_ret, &dummy, &dummy); 131 return plpar_hcall(H_XIRR, 0, 0, 0, 0, xirr_ret, &dummy, &dummy);
131} 132}
132 133
133static inline int lpar_xirr_info_get(int n_cpu) 134static inline unsigned int lpar_xirr_info_get(int n_cpu)
134{ 135{
135 unsigned long lpar_rc; 136 unsigned long lpar_rc;
136 unsigned long return_value; 137 unsigned long return_value;
@@ -138,7 +139,7 @@ static inline int lpar_xirr_info_get(int n_cpu)
138 lpar_rc = plpar_xirr(&return_value); 139 lpar_rc = plpar_xirr(&return_value);
139 if (lpar_rc != H_SUCCESS) 140 if (lpar_rc != H_SUCCESS)
140 panic(" bad return code xirr - rc = %lx \n", lpar_rc); 141 panic(" bad return code xirr - rc = %lx \n", lpar_rc);
141 return (int)return_value; 142 return (unsigned int)return_value;
142} 143}
143 144
144static inline void lpar_xirr_info_set(int n_cpu, int value) 145static inline void lpar_xirr_info_set(int n_cpu, int value)
@@ -175,11 +176,11 @@ static inline void lpar_qirr_info(int n_cpu , u8 value)
175 176
176 177
177#ifdef CONFIG_SMP 178#ifdef CONFIG_SMP
178static int get_irq_server(unsigned int irq) 179static int get_irq_server(unsigned int virq)
179{ 180{
180 unsigned int server; 181 unsigned int server;
181 /* For the moment only implement delivery to all cpus or one cpu */ 182 /* For the moment only implement delivery to all cpus or one cpu */
182 cpumask_t cpumask = irq_desc[irq].affinity; 183 cpumask_t cpumask = irq_desc[virq].affinity;
183 cpumask_t tmp = CPU_MASK_NONE; 184 cpumask_t tmp = CPU_MASK_NONE;
184 185
185 if (!distribute_irqs) 186 if (!distribute_irqs)
@@ -200,7 +201,7 @@ static int get_irq_server(unsigned int irq)
200 201
201} 202}
202#else 203#else
203static int get_irq_server(unsigned int irq) 204static int get_irq_server(unsigned int virq)
204{ 205{
205 return default_server; 206 return default_server;
206} 207}
@@ -213,9 +214,11 @@ static void xics_unmask_irq(unsigned int virq)
213 int call_status; 214 int call_status;
214 unsigned int server; 215 unsigned int server;
215 216
216 irq = virt_irq_to_real(irq_offset_down(virq)); 217 pr_debug("xics: unmask virq %d\n", virq);
217 WARN_ON(irq == NO_IRQ); 218
218 if (irq == XICS_IPI || irq == NO_IRQ) 219 irq = (unsigned int)irq_map[virq].hwirq;
220 pr_debug(" -> map to hwirq 0x%x\n", irq);
221 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
219 return; 222 return;
220 223
221 server = get_irq_server(virq); 224 server = get_irq_server(virq);
@@ -267,75 +270,57 @@ static void xics_mask_irq(unsigned int virq)
267{ 270{
268 unsigned int irq; 271 unsigned int irq;
269 272
270 irq = virt_irq_to_real(irq_offset_down(virq)); 273 pr_debug("xics: mask virq %d\n", virq);
271 WARN_ON(irq == NO_IRQ); 274
272 if (irq != NO_IRQ) 275 irq = (unsigned int)irq_map[virq].hwirq;
273 xics_mask_real_irq(irq); 276 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
277 return;
278 xics_mask_real_irq(irq);
274} 279}
275 280
276static void xics_set_irq_revmap(unsigned int virq) 281static unsigned int xics_startup(unsigned int virq)
277{ 282{
278 unsigned int irq; 283 unsigned int irq;
279 284
280 irq = irq_offset_down(virq); 285 /* force a reverse mapping of the interrupt so it gets in the cache */
281 if (radix_tree_insert(&irq_map, virt_irq_to_real(irq), 286 irq = (unsigned int)irq_map[virq].hwirq;
282 &virt_irq_to_real_map[irq]) == -ENOMEM) 287 irq_radix_revmap(xics_host, irq);
283 printk(KERN_CRIT "Out of memory creating real -> virtual"
284 " IRQ mapping for irq %u (real 0x%x)\n",
285 virq, virt_irq_to_real(irq));
286}
287 288
288static unsigned int xics_startup(unsigned int virq) 289 /* unmask it */
289{
290 xics_set_irq_revmap(virq);
291 xics_unmask_irq(virq); 290 xics_unmask_irq(virq);
292 return 0; 291 return 0;
293} 292}
294 293
295static unsigned int real_irq_to_virt(unsigned int real_irq) 294static void xics_eoi_direct(unsigned int virq)
296{
297 unsigned int *ptr;
298
299 ptr = radix_tree_lookup(&irq_map, real_irq);
300 if (ptr == NULL)
301 return NO_IRQ;
302 return ptr - virt_irq_to_real_map;
303}
304
305static void xics_eoi_direct(unsigned int irq)
306{ 295{
307 int cpu = smp_processor_id(); 296 int cpu = smp_processor_id();
297 unsigned int irq = (unsigned int)irq_map[virq].hwirq;
308 298
309 iosync(); 299 iosync();
310 direct_xirr_info_set(cpu, ((0xff << 24) | 300 direct_xirr_info_set(cpu, (0xff << 24) | irq);
311 (virt_irq_to_real(irq_offset_down(irq)))));
312} 301}
313 302
314 303
315static void xics_eoi_lpar(unsigned int irq) 304static void xics_eoi_lpar(unsigned int virq)
316{ 305{
317 int cpu = smp_processor_id(); 306 int cpu = smp_processor_id();
307 unsigned int irq = (unsigned int)irq_map[virq].hwirq;
318 308
319 iosync(); 309 iosync();
320 lpar_xirr_info_set(cpu, ((0xff << 24) | 310 lpar_xirr_info_set(cpu, (0xff << 24) | irq);
321 (virt_irq_to_real(irq_offset_down(irq)))));
322
323} 311}
324 312
325static inline int xics_remap_irq(int vec) 313static inline unsigned int xics_remap_irq(unsigned int vec)
326{ 314{
327 int irq; 315 unsigned int irq;
328 316
329 vec &= 0x00ffffff; 317 vec &= 0x00ffffff;
330 318
331 if (vec == XICS_IRQ_SPURIOUS) 319 if (vec == XICS_IRQ_SPURIOUS)
332 return NO_IRQ; 320 return NO_IRQ;
333 321 irq = irq_radix_revmap(xics_host, vec);
334 irq = real_irq_to_virt(vec);
335 if (irq == NO_IRQ)
336 irq = real_irq_to_virt_slowpath(vec);
337 if (likely(irq != NO_IRQ)) 322 if (likely(irq != NO_IRQ))
338 return irq_offset_up(irq); 323 return irq;
339 324
340 printk(KERN_ERR "Interrupt %u (real) is invalid," 325 printk(KERN_ERR "Interrupt %u (real) is invalid,"
341 " disabling it.\n", vec); 326 " disabling it.\n", vec);
@@ -343,14 +328,14 @@ static inline int xics_remap_irq(int vec)
343 return NO_IRQ; 328 return NO_IRQ;
344} 329}
345 330
346static int xics_get_irq_direct(struct pt_regs *regs) 331static unsigned int xics_get_irq_direct(struct pt_regs *regs)
347{ 332{
348 unsigned int cpu = smp_processor_id(); 333 unsigned int cpu = smp_processor_id();
349 334
350 return xics_remap_irq(direct_xirr_info_get(cpu)); 335 return xics_remap_irq(direct_xirr_info_get(cpu));
351} 336}
352 337
353static int xics_get_irq_lpar(struct pt_regs *regs) 338static unsigned int xics_get_irq_lpar(struct pt_regs *regs)
354{ 339{
355 unsigned int cpu = smp_processor_id(); 340 unsigned int cpu = smp_processor_id();
356 341
@@ -437,8 +422,8 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
437 unsigned long newmask; 422 unsigned long newmask;
438 cpumask_t tmp = CPU_MASK_NONE; 423 cpumask_t tmp = CPU_MASK_NONE;
439 424
440 irq = virt_irq_to_real(irq_offset_down(virq)); 425 irq = (unsigned int)irq_map[virq].hwirq;
441 if (irq == XICS_IPI || irq == NO_IRQ) 426 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
442 return; 427 return;
443 428
444 status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq); 429 status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
@@ -469,6 +454,24 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
469 } 454 }
470} 455}
471 456
457void xics_setup_cpu(void)
458{
459 int cpu = smp_processor_id();
460
461 xics_set_cpu_priority(cpu, 0xff);
462
463 /*
464 * Put the calling processor into the GIQ. This is really only
465 * necessary from a secondary thread as the OF start-cpu interface
466 * performs this function for us on primary threads.
467 *
468 * XXX: undo of teardown on kexec needs this too, as may hotplug
469 */
470 rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
471 (1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
472}
473
474
472static struct irq_chip xics_pic_direct = { 475static struct irq_chip xics_pic_direct = {
473 .typename = " XICS ", 476 .typename = " XICS ",
474 .startup = xics_startup, 477 .startup = xics_startup,
@@ -489,90 +492,245 @@ static struct irq_chip xics_pic_lpar = {
489}; 492};
490 493
491 494
492void xics_setup_cpu(void) 495static int xics_host_match(struct irq_host *h, struct device_node *node)
493{ 496{
494 int cpu = smp_processor_id(); 497 /* IBM machines have interrupt parents of various funky types for things
498 * like vdevices, events, etc... The trick we use here is to match
499 * everything here except the legacy 8259 which is compatible "chrp,iic"
500 */
501 return !device_is_compatible(node, "chrp,iic");
502}
495 503
496 xics_set_cpu_priority(cpu, 0xff); 504static int xics_host_map_direct(struct irq_host *h, unsigned int virq,
505 irq_hw_number_t hw, unsigned int flags)
506{
507 unsigned int sense = flags & IRQ_TYPE_SENSE_MASK;
497 508
498 /* 509 pr_debug("xics: map_direct virq %d, hwirq 0x%lx, flags: 0x%x\n",
499 * Put the calling processor into the GIQ. This is really only 510 virq, hw, flags);
500 * necessary from a secondary thread as the OF start-cpu interface 511
501 * performs this function for us on primary threads. 512 if (sense && sense != IRQ_TYPE_LEVEL_LOW)
502 * 513 printk(KERN_WARNING "xics: using unsupported sense 0x%x"
503 * XXX: undo of teardown on kexec needs this too, as may hotplug 514 " for irq %d (h: 0x%lx)\n", flags, virq, hw);
515
516 get_irq_desc(virq)->status |= IRQ_LEVEL;
517 set_irq_chip_and_handler(virq, &xics_pic_direct, handle_fasteoi_irq);
518 return 0;
519}
520
521static int xics_host_map_lpar(struct irq_host *h, unsigned int virq,
522 irq_hw_number_t hw, unsigned int flags)
523{
524 unsigned int sense = flags & IRQ_TYPE_SENSE_MASK;
525
526 pr_debug("xics: map_lpar virq %d, hwirq 0x%lx, flags: 0x%x\n",
527 virq, hw, flags);
528
529 if (sense && sense != IRQ_TYPE_LEVEL_LOW)
530 printk(KERN_WARNING "xics: using unsupported sense 0x%x"
531 " for irq %d (h: 0x%lx)\n", flags, virq, hw);
532
533 get_irq_desc(virq)->status |= IRQ_LEVEL;
534 set_irq_chip_and_handler(virq, &xics_pic_lpar, handle_fasteoi_irq);
535 return 0;
536}
537
538static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
539 u32 *intspec, unsigned int intsize,
540 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
541
542{
543 /* Current xics implementation translates everything
544 * to level. It is not technically right for MSIs but this
545 * is irrelevant at this point. We might get smarter in the future
504 */ 546 */
505 rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, 547 *out_hwirq = intspec[0];
506 (1UL << interrupt_server_size) - 1 - default_distrib_server, 1); 548 *out_flags = IRQ_TYPE_LEVEL_LOW;
549
550 return 0;
551}
552
553static struct irq_host_ops xics_host_direct_ops = {
554 .match = xics_host_match,
555 .map = xics_host_map_direct,
556 .xlate = xics_host_xlate,
557};
558
559static struct irq_host_ops xics_host_lpar_ops = {
560 .match = xics_host_match,
561 .map = xics_host_map_lpar,
562 .xlate = xics_host_xlate,
563};
564
565static void __init xics_init_host(void)
566{
567 struct irq_host_ops *ops;
568
569 if (firmware_has_feature(FW_FEATURE_LPAR))
570 ops = &xics_host_lpar_ops;
571 else
572 ops = &xics_host_direct_ops;
573 xics_host = irq_alloc_host(IRQ_HOST_MAP_TREE, 0, ops,
574 XICS_IRQ_SPURIOUS);
575 BUG_ON(xics_host == NULL);
576 irq_set_default_host(xics_host);
507} 577}
508 578
509void xics_init_IRQ(void) 579static void __init xics_map_one_cpu(int hw_id, unsigned long addr,
580 unsigned long size)
510{ 581{
582#ifdef CONFIG_SMP
511 int i; 583 int i;
512 unsigned long intr_size = 0;
513 struct device_node *np;
514 uint *ireg, ilen, indx = 0;
515 unsigned long intr_base = 0;
516 struct xics_interrupt_node {
517 unsigned long addr;
518 unsigned long size;
519 } intnodes[NR_CPUS];
520 struct irq_chip *chip;
521 584
522 ppc64_boot_msg(0x20, "XICS Init"); 585 /* This may look gross but it's good enough for now, we don't quite
586 * have a hard -> linux processor id matching.
587 */
588 for_each_possible_cpu(i) {
589 if (!cpu_present(i))
590 continue;
591 if (hw_id == get_hard_smp_processor_id(i)) {
592 xics_per_cpu[i] = ioremap(addr, size);
593 return;
594 }
595 }
596#else
597 if (hw_id != 0)
598 return;
599 xics_per_cpu[0] = ioremap(addr, size);
600#endif /* CONFIG_SMP */
601}
523 602
524 ibm_get_xive = rtas_token("ibm,get-xive"); 603static void __init xics_init_one_node(struct device_node *np,
525 ibm_set_xive = rtas_token("ibm,set-xive"); 604 unsigned int *indx)
526 ibm_int_on = rtas_token("ibm,int-on"); 605{
527 ibm_int_off = rtas_token("ibm,int-off"); 606 unsigned int ilen;
607 u32 *ireg;
528 608
529 np = of_find_node_by_type(NULL, "PowerPC-External-Interrupt-Presentation"); 609 /* This code does the theorically broken assumption that the interrupt
530 if (!np) 610 * server numbers are the same as the hard CPU numbers.
531 panic("xics_init_IRQ: can't find interrupt presentation"); 611 * This happens to be the case so far but we are playing with fire...
612 * should be fixed one of these days. -BenH.
613 */
614 ireg = (u32 *)get_property(np, "ibm,interrupt-server-ranges", NULL);
532 615
533nextnode: 616 /* Do that ever happen ? we'll know soon enough... but even good'old
534 ireg = (uint *)get_property(np, "ibm,interrupt-server-ranges", NULL); 617 * f80 does have that property ..
618 */
619 WARN_ON(ireg == NULL);
535 if (ireg) { 620 if (ireg) {
536 /* 621 /*
537 * set node starting index for this node 622 * set node starting index for this node
538 */ 623 */
539 indx = *ireg; 624 *indx = *ireg;
540 } 625 }
541 626 ireg = (u32 *)get_property(np, "reg", &ilen);
542 ireg = (uint *)get_property(np, "reg", &ilen);
543 if (!ireg) 627 if (!ireg)
544 panic("xics_init_IRQ: can't find interrupt reg property"); 628 panic("xics_init_IRQ: can't find interrupt reg property");
545 629
546 while (ilen) { 630 while (ilen >= (4 * sizeof(u32))) {
547 intnodes[indx].addr = (unsigned long)*ireg++ << 32; 631 unsigned long addr, size;
548 ilen -= sizeof(uint); 632
549 intnodes[indx].addr |= *ireg++; 633 /* XXX Use proper OF parsing code here !!! */
550 ilen -= sizeof(uint); 634 addr = (unsigned long)*ireg++ << 32;
551 intnodes[indx].size = (unsigned long)*ireg++ << 32; 635 ilen -= sizeof(u32);
552 ilen -= sizeof(uint); 636 addr |= *ireg++;
553 intnodes[indx].size |= *ireg++; 637 ilen -= sizeof(u32);
554 ilen -= sizeof(uint); 638 size = (unsigned long)*ireg++ << 32;
555 indx++; 639 ilen -= sizeof(u32);
556 if (indx >= NR_CPUS) break; 640 size |= *ireg++;
641 ilen -= sizeof(u32);
642 xics_map_one_cpu(*indx, addr, size);
643 (*indx)++;
644 }
645}
646
647
648static void __init xics_setup_8259_cascade(void)
649{
650 struct device_node *np, *old, *found = NULL;
651 int cascade, naddr;
652 u32 *addrp;
653 unsigned long intack = 0;
654
655 for_each_node_by_type(np, "interrupt-controller")
656 if (device_is_compatible(np, "chrp,iic")) {
657 found = np;
658 break;
659 }
660 if (found == NULL) {
661 printk(KERN_DEBUG "xics: no ISA interrupt controller\n");
662 return;
557 } 663 }
664 cascade = irq_of_parse_and_map(found, 0);
665 if (cascade == NO_IRQ) {
666 printk(KERN_ERR "xics: failed to map cascade interrupt");
667 return;
668 }
669 pr_debug("xics: cascade mapped to irq %d\n", cascade);
670
671 for (old = of_node_get(found); old != NULL ; old = np) {
672 np = of_get_parent(old);
673 of_node_put(old);
674 if (np == NULL)
675 break;
676 if (strcmp(np->name, "pci") != 0)
677 continue;
678 addrp = (u32 *)get_property(np, "8259-interrupt-acknowledge", NULL);
679 if (addrp == NULL)
680 continue;
681 naddr = prom_n_addr_cells(np);
682 intack = addrp[naddr-1];
683 if (naddr > 1)
684 intack |= ((unsigned long)addrp[naddr-2]) << 32;
685 }
686 if (intack)
687 printk(KERN_DEBUG "xics: PCI 8259 intack at 0x%016lx\n", intack);
688 i8259_init(found, intack);
689 of_node_put(found);
690 set_irq_chained_handler(cascade, pseries_8259_cascade);
691}
558 692
559 np = of_find_node_by_type(np, "PowerPC-External-Interrupt-Presentation"); 693void __init xics_init_IRQ(void)
560 if ((indx < NR_CPUS) && np) goto nextnode; 694{
695 int i;
696 struct device_node *np;
697 u32 *ireg, ilen, indx = 0;
698 int found = 0;
699
700 ppc64_boot_msg(0x20, "XICS Init");
701
702 ibm_get_xive = rtas_token("ibm,get-xive");
703 ibm_set_xive = rtas_token("ibm,set-xive");
704 ibm_int_on = rtas_token("ibm,int-on");
705 ibm_int_off = rtas_token("ibm,int-off");
706
707 for_each_node_by_type(np, "PowerPC-External-Interrupt-Presentation") {
708 found = 1;
709 if (firmware_has_feature(FW_FEATURE_LPAR))
710 break;
711 xics_init_one_node(np, &indx);
712 }
713 if (found == 0)
714 return;
715
716 xics_init_host();
561 717
562 /* Find the server numbers for the boot cpu. */ 718 /* Find the server numbers for the boot cpu. */
563 for (np = of_find_node_by_type(NULL, "cpu"); 719 for (np = of_find_node_by_type(NULL, "cpu");
564 np; 720 np;
565 np = of_find_node_by_type(np, "cpu")) { 721 np = of_find_node_by_type(np, "cpu")) {
566 ireg = (uint *)get_property(np, "reg", &ilen); 722 ireg = (u32 *)get_property(np, "reg", &ilen);
567 if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) { 723 if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) {
568 ireg = (uint *)get_property(np, "ibm,ppc-interrupt-gserver#s", 724 ireg = (u32 *)get_property(np,
569 &ilen); 725 "ibm,ppc-interrupt-gserver#s",
726 &ilen);
570 i = ilen / sizeof(int); 727 i = ilen / sizeof(int);
571 if (ireg && i > 0) { 728 if (ireg && i > 0) {
572 default_server = ireg[0]; 729 default_server = ireg[0];
573 default_distrib_server = ireg[i-1]; /* take last element */ 730 /* take last element */
731 default_distrib_server = ireg[i-1];
574 } 732 }
575 ireg = (uint *)get_property(np, 733 ireg = (u32 *)get_property(np,
576 "ibm,interrupt-server#-size", NULL); 734 "ibm,interrupt-server#-size", NULL);
577 if (ireg) 735 if (ireg)
578 interrupt_server_size = *ireg; 736 interrupt_server_size = *ireg;
@@ -581,102 +739,48 @@ nextnode:
581 } 739 }
582 of_node_put(np); 740 of_node_put(np);
583 741
584 intr_base = intnodes[0].addr; 742 if (firmware_has_feature(FW_FEATURE_LPAR))
585 intr_size = intnodes[0].size; 743 ppc_md.get_irq = xics_get_irq_lpar;
586 744 else
587 if (firmware_has_feature(FW_FEATURE_LPAR)) {
588 ppc_md.get_irq = xics_get_irq_lpar;
589 chip = &xics_pic_lpar;
590 } else {
591#ifdef CONFIG_SMP
592 for_each_possible_cpu(i) {
593 int hard_id;
594
595 /* FIXME: Do this dynamically! --RR */
596 if (!cpu_present(i))
597 continue;
598
599 hard_id = get_hard_smp_processor_id(i);
600 xics_per_cpu[i] = ioremap(intnodes[hard_id].addr,
601 intnodes[hard_id].size);
602 }
603#else
604 xics_per_cpu[0] = ioremap(intr_base, intr_size);
605#endif /* CONFIG_SMP */
606 ppc_md.get_irq = xics_get_irq_direct; 745 ppc_md.get_irq = xics_get_irq_direct;
607 chip = &xics_pic_direct;
608
609 }
610
611 for (i = irq_offset_value(); i < NR_IRQS; ++i) {
612 /* All IRQs on XICS are level for now. MSI code may want to modify
613 * that for reporting purposes
614 */
615 get_irq_desc(i)->status |= IRQ_LEVEL;
616 set_irq_chip_and_handler(i, chip, handle_fasteoi_irq);
617 }
618 746
619 xics_setup_cpu(); 747 xics_setup_cpu();
620 748
621 ppc64_boot_msg(0x21, "XICS Done"); 749 xics_setup_8259_cascade();
622}
623 750
624static int xics_setup_8259_cascade(void) 751 ppc64_boot_msg(0x21, "XICS Done");
625{
626 struct device_node *np;
627 uint *ireg;
628
629 np = of_find_node_by_type(NULL, "interrupt-controller");
630 if (np == NULL) {
631 printk(KERN_WARNING "xics: no ISA interrupt controller\n");
632 xics_irq_8259_cascade_real = -1;
633 xics_irq_8259_cascade = -1;
634 return 0;
635 }
636
637 ireg = (uint *) get_property(np, "interrupts", NULL);
638 if (!ireg)
639 panic("xics_init_IRQ: can't find ISA interrupts property");
640
641 xics_irq_8259_cascade_real = *ireg;
642 xics_irq_8259_cascade = irq_offset_up
643 (virt_irq_create_mapping(xics_irq_8259_cascade_real));
644 i8259_init(0, 0);
645 of_node_put(np);
646
647 xics_set_irq_revmap(xics_irq_8259_cascade);
648 set_irq_chained_handler(xics_irq_8259_cascade, pSeries_8259_cascade);
649
650 return 0;
651} 752}
652arch_initcall(xics_setup_8259_cascade);
653 753
654 754
655#ifdef CONFIG_SMP 755#ifdef CONFIG_SMP
656void xics_request_IPIs(void) 756void xics_request_IPIs(void)
657{ 757{
658 virt_irq_to_real_map[XICS_IPI] = XICS_IPI; 758 unsigned int ipi;
759
760 ipi = irq_create_mapping(xics_host, XICS_IPI, 0);
761 BUG_ON(ipi == NO_IRQ);
659 762
660 /* 763 /*
661 * IPIs are marked IRQF_DISABLED as they must run with irqs 764 * IPIs are marked IRQF_DISABLED as they must run with irqs
662 * disabled 765 * disabled
663 */ 766 */
664 set_irq_handler(irq_offset_up(XICS_IPI), handle_percpu_irq); 767 set_irq_handler(ipi, handle_percpu_irq);
665 if (firmware_has_feature(FW_FEATURE_LPAR)) 768 if (firmware_has_feature(FW_FEATURE_LPAR))
666 request_irq(irq_offset_up(XICS_IPI), xics_ipi_action_lpar, 769 request_irq(ipi, xics_ipi_action_lpar, IRQF_DISABLED,
667 SA_INTERRUPT, "IPI", NULL); 770 "IPI", NULL);
668 else 771 else
669 request_irq(irq_offset_up(XICS_IPI), xics_ipi_action_direct, 772 request_irq(ipi, xics_ipi_action_direct, IRQF_DISABLED,
670 SA_INTERRUPT, "IPI", NULL); 773 "IPI", NULL);
671} 774}
672#endif /* CONFIG_SMP */ 775#endif /* CONFIG_SMP */
673 776
674void xics_teardown_cpu(int secondary) 777void xics_teardown_cpu(int secondary)
675{ 778{
676 struct irq_desc *desc = get_irq_desc(irq_offset_up(XICS_IPI));
677 int cpu = smp_processor_id(); 779 int cpu = smp_processor_id();
780 unsigned int ipi;
781 struct irq_desc *desc;
678 782
679 xics_set_cpu_priority(cpu, 0); 783 xics_set_cpu_priority(cpu, 0);
680 784
681 /* 785 /*
682 * we need to EOI the IPI if we got here from kexec down IPI 786 * we need to EOI the IPI if we got here from kexec down IPI
@@ -685,6 +789,11 @@ void xics_teardown_cpu(int secondary)
685 * should we be flagging idle loop instead? 789 * should we be flagging idle loop instead?
686 * or creating some task to be scheduled? 790 * or creating some task to be scheduled?
687 */ 791 */
792
793 ipi = irq_find_mapping(xics_host, XICS_IPI);
794 if (ipi == XICS_IRQ_SPURIOUS)
795 return;
796 desc = get_irq_desc(ipi);
688 if (desc->chip && desc->chip->eoi) 797 if (desc->chip && desc->chip->eoi)
689 desc->chip->eoi(XICS_IPI); 798 desc->chip->eoi(XICS_IPI);
690 799
@@ -694,8 +803,8 @@ void xics_teardown_cpu(int secondary)
694 */ 803 */
695 if (secondary) 804 if (secondary)
696 rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, 805 rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
697 (1UL << interrupt_server_size) - 1 - 806 (1UL << interrupt_server_size) - 1 -
698 default_distrib_server, 0); 807 default_distrib_server, 0);
699} 808}
700 809
701#ifdef CONFIG_HOTPLUG_CPU 810#ifdef CONFIG_HOTPLUG_CPU
@@ -723,15 +832,15 @@ void xics_migrate_irqs_away(void)
723 unsigned long flags; 832 unsigned long flags;
724 833
725 /* We cant set affinity on ISA interrupts */ 834 /* We cant set affinity on ISA interrupts */
726 if (virq < irq_offset_value()) 835 if (virq < NUM_ISA_INTERRUPTS)
727 continue; 836 continue;
728 837 if (irq_map[virq].host != xics_host)
729 desc = get_irq_desc(virq); 838 continue;
730 irq = virt_irq_to_real(irq_offset_down(virq)); 839 irq = (unsigned int)irq_map[virq].hwirq;
731
732 /* We need to get IPIs still. */ 840 /* We need to get IPIs still. */
733 if (irq == XICS_IPI || irq == NO_IRQ) 841 if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
734 continue; 842 continue;
843 desc = get_irq_desc(virq);
735 844
736 /* We only need to migrate enabled IRQS */ 845 /* We only need to migrate enabled IRQS */
737 if (desc == NULL || desc->chip == NULL 846 if (desc == NULL || desc->chip == NULL