xref: /linux/arch/powerpc/platforms/ps3/interrupt.c (revision c43990162fc7f9d2f15a12797fdc6f9c0905f704)
1 /*
2  *  PS3 interrupt routines.
3  *
4  *  Copyright (C) 2006 Sony Computer Entertainment Inc.
5  *  Copyright 2006 Sony Corp.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; version 2 of the License.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 #include <linux/kernel.h>
22 #include <linux/module.h>
23 #include <linux/irq.h>
24 
25 #include <asm/machdep.h>
26 #include <asm/udbg.h>
27 #include <asm/lv1call.h>
28 #include <asm/smp.h>
29 
30 #include "platform.h"
31 
32 #if defined(DEBUG)
33 #define DBG(fmt...) udbg_printf(fmt)
34 #else
35 #define DBG(fmt...) do{if(0)printk(fmt);}while(0)
36 #endif
37 
38 /**
39  * struct ps3_bmp - a per cpu irq status and mask bitmap structure
40  * @status: 256 bit status bitmap indexed by plug
41  * @unused_1:
42  * @mask: 256 bit mask bitmap indexed by plug
43  * @unused_2:
44  * @lock:
45  * @ipi_debug_brk_mask:
46  *
47  * The HV mantains per SMT thread mappings of HV outlet to HV plug on
48  * behalf of the guest.  These mappings are implemented as 256 bit guest
49  * supplied bitmaps indexed by plug number.  The addresses of the bitmaps
50  * are registered with the HV through lv1_configure_irq_state_bitmap().
51  * The HV requires that the 512 bits of status + mask not cross a page
52  * boundary.  PS3_BMP_MINALIGN is used to define this minimal 64 byte
53  * alignment.
54  *
55  * The HV supports 256 plugs per thread, assigned as {0..255}, for a total
56  * of 512 plugs supported on a processor.  To simplify the logic this
57  * implementation equates HV plug value to Linux virq value, constrains each
58  * interrupt to have a system wide unique plug number, and limits the range
59  * of the plug values to map into the first dword of the bitmaps.  This
60  * gives a usable range of plug values of  {NUM_ISA_INTERRUPTS..63}.  Note
61  * that there is no constraint on how many in this set an individual thread
62  * can acquire.
63  */
64 
65 #define PS3_BMP_MINALIGN 64
66 
67 struct ps3_bmp {
68 	struct {
69 		u64 status;
70 		u64 unused_1[3];
71 		u64 mask;
72 		u64 unused_2[3];
73 	};
74 	u64 ipi_debug_brk_mask;
75 	spinlock_t lock;
76 };
77 
78 /**
79  * struct ps3_private - a per cpu data structure
80  * @bmp: ps3_bmp structure
81  * @node: HV logical_ppe_id
82  * @cpu: HV thread_id
83  */
84 
85 struct ps3_private {
86 	struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN)));
87 	u64 node;
88 	unsigned int cpu;
89 };
90 
91 static DEFINE_PER_CPU(struct ps3_private, ps3_private);
92 
93 /**
94  * ps3_virq_setup - virq related setup.
95  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
96  * serviced on.
97  * @outlet: The HV outlet from the various create outlet routines.
98  * @virq: The assigned Linux virq.
99  *
100  * Calls irq_create_mapping() to get a virq and sets the chip data to
101  * ps3_private data.
102  */
103 
104 int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
105 	unsigned int *virq)
106 {
107 	int result;
108 	struct ps3_private *pd;
109 
110 	/* This defines the default interrupt distribution policy. */
111 
112 	if (cpu == PS3_BINDING_CPU_ANY)
113 		cpu = 0;
114 
115 	pd = &per_cpu(ps3_private, cpu);
116 
117 	*virq = irq_create_mapping(NULL, outlet);
118 
119 	if (*virq == NO_IRQ) {
120 		pr_debug("%s:%d: irq_create_mapping failed: outlet %lu\n",
121 			__func__, __LINE__, outlet);
122 		result = -ENOMEM;
123 		goto fail_create;
124 	}
125 
126 	pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__,
127 		outlet, cpu, *virq);
128 
129 	result = set_irq_chip_data(*virq, pd);
130 
131 	if (result) {
132 		pr_debug("%s:%d: set_irq_chip_data failed\n",
133 			__func__, __LINE__);
134 		goto fail_set;
135 	}
136 
137 	return result;
138 
139 fail_set:
140 	irq_dispose_mapping(*virq);
141 fail_create:
142 	return result;
143 }
144 
145 /**
146  * ps3_virq_destroy - virq related teardown.
147  * @virq: The assigned Linux virq.
148  *
149  * Clears chip data and calls irq_dispose_mapping() for the virq.
150  */
151 
152 int ps3_virq_destroy(unsigned int virq)
153 {
154 	const struct ps3_private *pd = get_irq_chip_data(virq);
155 
156 	pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
157 		pd->node, pd->cpu, virq);
158 
159 	set_irq_chip_data(virq, NULL);
160 	irq_dispose_mapping(virq);
161 
162 	pr_debug("%s:%d <-\n", __func__, __LINE__);
163 	return 0;
164 }
165 
166 /**
167  * ps3_irq_plug_setup - Generic outlet and virq related setup.
168  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
169  * serviced on.
170  * @outlet: The HV outlet from the various create outlet routines.
171  * @virq: The assigned Linux virq.
172  *
173  * Sets up virq and connects the irq plug.
174  */
175 
176 int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
177 	unsigned int *virq)
178 {
179 	int result;
180 	struct ps3_private *pd;
181 
182 	result = ps3_virq_setup(cpu, outlet, virq);
183 
184 	if (result) {
185 		pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__);
186 		goto fail_setup;
187 	}
188 
189 	pd = get_irq_chip_data(*virq);
190 
191 	/* Binds outlet to cpu + virq. */
192 
193 	result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0);
194 
195 	if (result) {
196 		pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
197 		__func__, __LINE__, ps3_result(result));
198 		result = -EPERM;
199 		goto fail_connect;
200 	}
201 
202 	return result;
203 
204 fail_connect:
205 	ps3_virq_destroy(*virq);
206 fail_setup:
207 	return result;
208 }
209 EXPORT_SYMBOL_GPL(ps3_irq_plug_setup);
210 
211 /**
212  * ps3_irq_plug_destroy - Generic outlet and virq related teardown.
213  * @virq: The assigned Linux virq.
214  *
215  * Disconnects the irq plug and tears down virq.
216  * Do not call for system bus event interrupts setup with
217  * ps3_sb_event_receive_port_setup().
218  */
219 
220 int ps3_irq_plug_destroy(unsigned int virq)
221 {
222 	int result;
223 	const struct ps3_private *pd = get_irq_chip_data(virq);
224 
225 	pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
226 		pd->node, pd->cpu, virq);
227 
228 	result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
229 
230 	if (result)
231 		pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
232 		__func__, __LINE__, ps3_result(result));
233 
234 	ps3_virq_destroy(virq);
235 
236 	return result;
237 }
238 EXPORT_SYMBOL_GPL(ps3_irq_plug_destroy);
239 
240 /**
241  * ps3_event_receive_port_setup - Setup an event receive port.
242  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
243  * serviced on.
244  * @virq: The assigned Linux virq.
245  *
246  * The virq can be used with lv1_connect_interrupt_event_receive_port() to
247  * arrange to receive interrupts from system-bus devices, or with
248  * ps3_send_event_locally() to signal events.
249  */
250 
251 int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq)
252 {
253 	int result;
254 	unsigned long outlet;
255 
256 	result = lv1_construct_event_receive_port(&outlet);
257 
258 	if (result) {
259 		pr_debug("%s:%d: lv1_construct_event_receive_port failed: %s\n",
260 			__func__, __LINE__, ps3_result(result));
261 		*virq = NO_IRQ;
262 		return result;
263 	}
264 
265 	result = ps3_irq_plug_setup(cpu, outlet, virq);
266 	BUG_ON(result);
267 
268 	return result;
269 }
270 EXPORT_SYMBOL_GPL(ps3_event_receive_port_setup);
271 
272 /**
273  * ps3_event_receive_port_destroy - Destroy an event receive port.
274  * @virq: The assigned Linux virq.
275  *
276  * Since ps3_event_receive_port_destroy destroys the receive port outlet,
277  * SB devices need to call disconnect_interrupt_event_receive_port() before
278  * this.
279  */
280 
281 int ps3_event_receive_port_destroy(unsigned int virq)
282 {
283 	int result;
284 
285 	pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq);
286 
287 	result = lv1_destruct_event_receive_port(virq_to_hw(virq));
288 
289 	if (result)
290 		pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
291 			__func__, __LINE__, ps3_result(result));
292 
293 	/* lv1_destruct_event_receive_port() destroys the IRQ plug,
294 	 * so don't call ps3_irq_plug_destroy() here.
295 	 */
296 
297 	result = ps3_virq_destroy(virq);
298 	BUG_ON(result);
299 
300 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
301 	return result;
302 }
303 EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
304 
305 int ps3_send_event_locally(unsigned int virq)
306 {
307 	return lv1_send_event_locally(virq_to_hw(virq));
308 }
309 
310 /**
311  * ps3_sb_event_receive_port_setup - Setup a system bus event receive port.
312  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
313  * serviced on.
314  * @did: The HV device identifier read from the system repository.
315  * @interrupt_id: The device interrupt id read from the system repository.
316  * @virq: The assigned Linux virq.
317  *
318  * An event irq represents a virtual device interrupt.  The interrupt_id
319  * coresponds to the software interrupt number.
320  */
321 
322 int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
323 	const struct ps3_device_id *did, unsigned int interrupt_id,
324 	unsigned int *virq)
325 {
326 	/* this should go in system-bus.c */
327 
328 	int result;
329 
330 	result = ps3_event_receive_port_setup(cpu, virq);
331 
332 	if (result)
333 		return result;
334 
335 	result = lv1_connect_interrupt_event_receive_port(did->bus_id,
336 		did->dev_id, virq_to_hw(*virq), interrupt_id);
337 
338 	if (result) {
339 		pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port"
340 			" failed: %s\n", __func__, __LINE__,
341 			ps3_result(result));
342 		ps3_event_receive_port_destroy(*virq);
343 		*virq = NO_IRQ;
344 		return result;
345 	}
346 
347 	pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
348 		interrupt_id, *virq);
349 
350 	return 0;
351 }
352 EXPORT_SYMBOL(ps3_sb_event_receive_port_setup);
353 
354 int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
355 	unsigned int interrupt_id, unsigned int virq)
356 {
357 	/* this should go in system-bus.c */
358 
359 	int result;
360 
361 	pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
362 		interrupt_id, virq);
363 
364 	result = lv1_disconnect_interrupt_event_receive_port(did->bus_id,
365 		did->dev_id, virq_to_hw(virq), interrupt_id);
366 
367 	if (result)
368 		pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port"
369 			" failed: %s\n", __func__, __LINE__,
370 			ps3_result(result));
371 
372 	result = ps3_event_receive_port_destroy(virq);
373 	BUG_ON(result);
374 
375 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
376 	return result;
377 }
378 EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy);
379 
380 /**
381  * ps3_io_irq_setup - Setup a system bus io irq.
382  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
383  * serviced on.
384  * @interrupt_id: The device interrupt id read from the system repository.
385  * @virq: The assigned Linux virq.
386  *
387  * An io irq represents a non-virtualized device interrupt.  interrupt_id
388  * coresponds to the interrupt number of the interrupt controller.
389  */
390 
391 int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
392 	unsigned int *virq)
393 {
394 	int result;
395 	unsigned long outlet;
396 
397 	result = lv1_construct_io_irq_outlet(interrupt_id, &outlet);
398 
399 	if (result) {
400 		pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n",
401 			__func__, __LINE__, ps3_result(result));
402 		return result;
403 	}
404 
405 	result = ps3_irq_plug_setup(cpu, outlet, virq);
406 	BUG_ON(result);
407 
408 	return result;
409 }
410 EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
411 
412 int ps3_io_irq_destroy(unsigned int virq)
413 {
414 	int result;
415 
416 	result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
417 
418 	if (result)
419 		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
420 			__func__, __LINE__, ps3_result(result));
421 
422 	result = ps3_irq_plug_destroy(virq);
423 	BUG_ON(result);
424 
425 	return result;
426 }
427 EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
428 
429 /**
430  * ps3_vuart_irq_setup - Setup the system virtual uart virq.
431  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
432  * serviced on.
433  * @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap.
434  * @virq: The assigned Linux virq.
435  *
436  * The system supports only a single virtual uart, so multiple calls without
437  * freeing the interrupt will return a wrong state error.
438  */
439 
440 int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
441 	unsigned int *virq)
442 {
443 	int result;
444 	unsigned long outlet;
445 	u64 lpar_addr;
446 
447 	BUG_ON(!is_kernel_addr((u64)virt_addr_bmp));
448 
449 	lpar_addr = ps3_mm_phys_to_lpar(__pa(virt_addr_bmp));
450 
451 	result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet);
452 
453 	if (result) {
454 		pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n",
455 			__func__, __LINE__, ps3_result(result));
456 		return result;
457 	}
458 
459 	result = ps3_irq_plug_setup(cpu, outlet, virq);
460 	BUG_ON(result);
461 
462 	return result;
463 }
464 
465 int ps3_vuart_irq_destroy(unsigned int virq)
466 {
467 	int result;
468 
469 	result = lv1_deconfigure_virtual_uart_irq();
470 
471 	if (result) {
472 		pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n",
473 			__func__, __LINE__, ps3_result(result));
474 		return result;
475 	}
476 
477 	result = ps3_irq_plug_destroy(virq);
478 	BUG_ON(result);
479 
480 	return result;
481 }
482 
483 /**
484  * ps3_spe_irq_setup - Setup an spe virq.
485  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
486  * serviced on.
487  * @spe_id: The spe_id returned from lv1_construct_logical_spe().
488  * @class: The spe interrupt class {0,1,2}.
489  * @virq: The assigned Linux virq.
490  *
491  */
492 
493 int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
494 	unsigned int class, unsigned int *virq)
495 {
496 	int result;
497 	unsigned long outlet;
498 
499 	BUG_ON(class > 2);
500 
501 	result = lv1_get_spe_irq_outlet(spe_id, class, &outlet);
502 
503 	if (result) {
504 		pr_debug("%s:%d: lv1_get_spe_irq_outlet failed: %s\n",
505 			__func__, __LINE__, ps3_result(result));
506 		return result;
507 	}
508 
509 	result = ps3_irq_plug_setup(cpu, outlet, virq);
510 	BUG_ON(result);
511 
512 	return result;
513 }
514 
515 int ps3_spe_irq_destroy(unsigned int virq)
516 {
517 	int result = ps3_irq_plug_destroy(virq);
518 	BUG_ON(result);
519 	return 0;
520 }
521 
522 
523 #define PS3_INVALID_OUTLET ((irq_hw_number_t)-1)
524 #define PS3_PLUG_MAX 63
525 
526 #if defined(DEBUG)
527 static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu,
528 	const char* func, int line)
529 {
530 	pr_debug("%s:%d: %s %u {%04lx_%04lx_%04lx_%04lx}\n",
531 		func, line, header, cpu,
532 		*p >> 48, (*p >> 32) & 0xffff, (*p >> 16) & 0xffff,
533 		*p & 0xffff);
534 }
535 
536 static void __attribute__ ((unused)) _dump_256_bmp(const char *header,
537 	const u64 *p, unsigned cpu, const char* func, int line)
538 {
539 	pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n",
540 		func, line, header, cpu, p[0], p[1], p[2], p[3]);
541 }
542 
543 #define dump_bmp(_x) _dump_bmp(_x, __func__, __LINE__)
544 static void _dump_bmp(struct ps3_private* pd, const char* func, int line)
545 {
546 	unsigned long flags;
547 
548 	spin_lock_irqsave(&pd->bmp.lock, flags);
549 	_dump_64_bmp("stat", &pd->bmp.status, pd->cpu, func, line);
550 	_dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line);
551 	spin_unlock_irqrestore(&pd->bmp.lock, flags);
552 }
553 
554 #define dump_mask(_x) _dump_mask(_x, __func__, __LINE__)
555 static void __attribute__ ((unused)) _dump_mask(struct ps3_private* pd,
556 	const char* func, int line)
557 {
558 	unsigned long flags;
559 
560 	spin_lock_irqsave(&pd->bmp.lock, flags);
561 	_dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line);
562 	spin_unlock_irqrestore(&pd->bmp.lock, flags);
563 }
564 #else
565 static void dump_bmp(struct ps3_private* pd) {};
566 #endif /* defined(DEBUG) */
567 
568 static void ps3_chip_mask(unsigned int virq)
569 {
570 	struct ps3_private *pd = get_irq_chip_data(virq);
571 	u64 bit = 0x8000000000000000UL >> virq;
572 	u64 *p = &pd->bmp.mask;
573 	u64 old;
574 	unsigned long flags;
575 
576 	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
577 
578 	local_irq_save(flags);
579 	asm volatile(
580 		     "1:	ldarx %0,0,%3\n"
581 		     "andc	%0,%0,%2\n"
582 		     "stdcx.	%0,0,%3\n"
583 		     "bne-	1b"
584 		     : "=&r" (old), "+m" (*p)
585 		     : "r" (bit), "r" (p)
586 		     : "cc" );
587 
588 	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
589 	local_irq_restore(flags);
590 }
591 
592 static void ps3_chip_unmask(unsigned int virq)
593 {
594 	struct ps3_private *pd = get_irq_chip_data(virq);
595 	u64 bit = 0x8000000000000000UL >> virq;
596 	u64 *p = &pd->bmp.mask;
597 	u64 old;
598 	unsigned long flags;
599 
600 	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
601 
602 	local_irq_save(flags);
603 	asm volatile(
604 		     "1:	ldarx %0,0,%3\n"
605 		     "or	%0,%0,%2\n"
606 		     "stdcx.	%0,0,%3\n"
607 		     "bne-	1b"
608 		     : "=&r" (old), "+m" (*p)
609 		     : "r" (bit), "r" (p)
610 		     : "cc" );
611 
612 	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
613 	local_irq_restore(flags);
614 }
615 
616 static void ps3_chip_eoi(unsigned int virq)
617 {
618 	const struct ps3_private *pd = get_irq_chip_data(virq);
619 	lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
620 }
621 
622 static struct irq_chip irq_chip = {
623 	.typename = "ps3",
624 	.mask = ps3_chip_mask,
625 	.unmask = ps3_chip_unmask,
626 	.eoi = ps3_chip_eoi,
627 };
628 
629 static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
630 {
631 	set_irq_chip_data(virq, NULL);
632 }
633 
634 static int ps3_host_map(struct irq_host *h, unsigned int virq,
635 	irq_hw_number_t hwirq)
636 {
637 	pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
638 		virq);
639 
640 	set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq);
641 
642 	return 0;
643 }
644 
645 static struct irq_host_ops ps3_host_ops = {
646 	.map = ps3_host_map,
647 	.unmap = ps3_host_unmap,
648 };
649 
650 void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq)
651 {
652 	struct ps3_private *pd = &per_cpu(ps3_private, cpu);
653 
654 	pd->bmp.ipi_debug_brk_mask = 0x8000000000000000UL >> virq;
655 
656 	pr_debug("%s:%d: cpu %u, virq %u, mask %lxh\n", __func__, __LINE__,
657 		cpu, virq, pd->bmp.ipi_debug_brk_mask);
658 }
659 
660 unsigned int ps3_get_irq(void)
661 {
662 	struct ps3_private *pd = &__get_cpu_var(ps3_private);
663 	u64 x = (pd->bmp.status & pd->bmp.mask);
664 	unsigned int plug;
665 
666 	/* check for ipi break first to stop this cpu ASAP */
667 
668 	if (x & pd->bmp.ipi_debug_brk_mask)
669 		x &= pd->bmp.ipi_debug_brk_mask;
670 
671 	asm volatile("cntlzd %0,%1" : "=r" (plug) : "r" (x));
672 	plug &= 0x3f;
673 
674 	if (unlikely(plug) == NO_IRQ) {
675 		pr_debug("%s:%d: no plug found: cpu %u\n", __func__, __LINE__,
676 			pd->cpu);
677 		dump_bmp(&per_cpu(ps3_private, 0));
678 		dump_bmp(&per_cpu(ps3_private, 1));
679 		return NO_IRQ;
680 	}
681 
682 #if defined(DEBUG)
683 	if (unlikely(plug < NUM_ISA_INTERRUPTS || plug > PS3_PLUG_MAX)) {
684 		dump_bmp(&per_cpu(ps3_private, 0));
685 		dump_bmp(&per_cpu(ps3_private, 1));
686 		BUG();
687 	}
688 #endif
689 	return plug;
690 }
691 
692 void __init ps3_init_IRQ(void)
693 {
694 	int result;
695 	unsigned cpu;
696 	struct irq_host *host;
697 
698 	host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops,
699 		PS3_INVALID_OUTLET);
700 	irq_set_default_host(host);
701 	irq_set_virq_count(PS3_PLUG_MAX + 1);
702 
703 	for_each_possible_cpu(cpu) {
704 		struct ps3_private *pd = &per_cpu(ps3_private, cpu);
705 
706 		lv1_get_logical_ppe_id(&pd->node);
707 		pd->cpu = get_hard_smp_processor_id(cpu);
708 		spin_lock_init(&pd->bmp.lock);
709 
710 		pr_debug("%s:%d: node %lu, cpu %d, bmp %lxh\n", __func__,
711 			__LINE__, pd->node, pd->cpu,
712 			ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
713 
714 		result = lv1_configure_irq_state_bitmap(pd->node, pd->cpu,
715 			ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
716 
717 		if (result)
718 			pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:"
719 				" %s\n", __func__, __LINE__,
720 				ps3_result(result));
721 	}
722 
723 	ppc_md.get_irq = ps3_get_irq;
724 }
725