Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik...
[pandora-kernel.git] / arch / powerpc / platforms / ps3 / interrupt.c
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
29 #include "platform.h"
30
31 #if defined(DEBUG)
32 #define DBG(fmt...) udbg_printf(fmt)
33 #else
34 #define DBG(fmt...) do{if(0)printk(fmt);}while(0)
35 #endif
36
37 /**
38  * struct ps3_bmp - a per cpu irq status and mask bitmap structure
39  * @status: 256 bit status bitmap indexed by plug
40  * @unused_1:
41  * @mask: 256 bit mask bitmap indexed by plug
42  * @unused_2:
43  * @lock:
44  * @ipi_debug_brk_mask:
45  *
46  * The HV mantains per SMT thread mappings of HV outlet to HV plug on
47  * behalf of the guest.  These mappings are implemented as 256 bit guest
48  * supplied bitmaps indexed by plug number.  The addresses of the bitmaps
49  * are registered with the HV through lv1_configure_irq_state_bitmap().
50  * The HV requires that the 512 bits of status + mask not cross a page
51  * boundary.  PS3_BMP_MINALIGN is used to define this minimal 64 byte
52  * alignment.
53  *
54  * The HV supports 256 plugs per thread, assigned as {0..255}, for a total
55  * of 512 plugs supported on a processor.  To simplify the logic this
56  * implementation equates HV plug value to Linux virq value, constrains each
57  * interrupt to have a system wide unique plug number, and limits the range
58  * of the plug values to map into the first dword of the bitmaps.  This
59  * gives a usable range of plug values of  {NUM_ISA_INTERRUPTS..63}.  Note
60  * that there is no constraint on how many in this set an individual thread
61  * can acquire.
62  */
63
64 #define PS3_BMP_MINALIGN 64
65
66 struct ps3_bmp {
67         struct {
68                 u64 status;
69                 u64 unused_1[3];
70                 u64 mask;
71                 u64 unused_2[3];
72         };
73         u64 ipi_debug_brk_mask;
74         spinlock_t lock;
75 };
76
77 /**
78  * struct ps3_private - a per cpu data structure
79  * @bmp: ps3_bmp structure
80  * @node: HV logical_ppe_id
81  * @cpu: HV thread_id
82  */
83
84 struct ps3_private {
85         struct ps3_bmp bmp __attribute__ ((aligned (PS3_BMP_MINALIGN)));
86         u64 node;
87         unsigned int cpu;
88 };
89
90 static DEFINE_PER_CPU(struct ps3_private, ps3_private);
91
92 int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
93         unsigned int *virq)
94 {
95         int result;
96         struct ps3_private *pd;
97
98         /* This defines the default interrupt distribution policy. */
99
100         if (cpu == PS3_BINDING_CPU_ANY)
101                 cpu = 0;
102
103         pd = &per_cpu(ps3_private, cpu);
104
105         *virq = irq_create_mapping(NULL, outlet);
106
107         if (*virq == NO_IRQ) {
108                 pr_debug("%s:%d: irq_create_mapping failed: outlet %lu\n",
109                         __func__, __LINE__, outlet);
110                 result = -ENOMEM;
111                 goto fail_create;
112         }
113
114         /* Binds outlet to cpu + virq. */
115
116         result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0);
117
118         if (result) {
119                 pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
120                 __func__, __LINE__, ps3_result(result));
121                 result = -EPERM;
122                 goto fail_connect;
123         }
124
125         pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__,
126                 outlet, cpu, *virq);
127
128         result = set_irq_chip_data(*virq, pd);
129
130         if (result) {
131                 pr_debug("%s:%d: set_irq_chip_data failed\n",
132                         __func__, __LINE__);
133                 goto fail_set;
134         }
135
136         return result;
137
138 fail_set:
139         lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, *virq);
140 fail_connect:
141         irq_dispose_mapping(*virq);
142 fail_create:
143         return result;
144 }
145 EXPORT_SYMBOL_GPL(ps3_alloc_irq);
146
147 int ps3_free_irq(unsigned int virq)
148 {
149         int result;
150         const struct ps3_private *pd = get_irq_chip_data(virq);
151
152         pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
153                 pd->node, pd->cpu, virq);
154
155         result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
156
157         if (result)
158                 pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
159                 __func__, __LINE__, ps3_result(result));
160
161         set_irq_chip_data(virq, NULL);
162         irq_dispose_mapping(virq);
163         return result;
164 }
165 EXPORT_SYMBOL_GPL(ps3_free_irq);
166
167 /**
168  * ps3_alloc_io_irq - Assign a virq to a system bus device.
169  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
170  * serviced on.
171  * @interrupt_id: The device interrupt id read from the system repository.
172  * @virq: The assigned Linux virq.
173  *
174  * An io irq represents a non-virtualized device interrupt.  interrupt_id
175  * coresponds to the interrupt number of the interrupt controller.
176  */
177
178 int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
179         unsigned int *virq)
180 {
181         int result;
182         unsigned long outlet;
183
184         result = lv1_construct_io_irq_outlet(interrupt_id, &outlet);
185
186         if (result) {
187                 pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n",
188                         __func__, __LINE__, ps3_result(result));
189                 return result;
190         }
191
192         result = ps3_alloc_irq(cpu, outlet, virq);
193         BUG_ON(result);
194
195         return result;
196 }
197
198 int ps3_free_io_irq(unsigned int virq)
199 {
200         int result;
201
202         result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
203
204         if (result)
205                 pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
206                         __func__, __LINE__, ps3_result(result));
207
208         ps3_free_irq(virq);
209
210         return result;
211 }
212
213 /**
214  * ps3_alloc_event_irq - Allocate a virq for use with a system event.
215  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
216  * serviced on.
217  * @virq: The assigned Linux virq.
218  *
219  * The virq can be used with lv1_connect_interrupt_event_receive_port() to
220  * arrange to receive events, or with ps3_send_event_locally() to signal
221  * events.
222  */
223
224 int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq)
225 {
226         int result;
227         unsigned long outlet;
228
229         result = lv1_construct_event_receive_port(&outlet);
230
231         if (result) {
232                 pr_debug("%s:%d: lv1_construct_event_receive_port failed: %s\n",
233                         __func__, __LINE__, ps3_result(result));
234                 *virq = NO_IRQ;
235                 return result;
236         }
237
238         result = ps3_alloc_irq(cpu, outlet, virq);
239         BUG_ON(result);
240
241         return result;
242 }
243
244 int ps3_free_event_irq(unsigned int virq)
245 {
246         int result;
247
248         pr_debug(" -> %s:%d\n", __func__, __LINE__);
249
250         result = lv1_destruct_event_receive_port(virq_to_hw(virq));
251
252         if (result)
253                 pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
254                         __func__, __LINE__, ps3_result(result));
255
256         ps3_free_irq(virq);
257
258         pr_debug(" <- %s:%d\n", __func__, __LINE__);
259         return result;
260 }
261
262 int ps3_send_event_locally(unsigned int virq)
263 {
264         return lv1_send_event_locally(virq_to_hw(virq));
265 }
266
267 /**
268  * ps3_connect_event_irq - Assign a virq to a system bus device.
269  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
270  * serviced on.
271  * @did: The HV device identifier read from the system repository.
272  * @interrupt_id: The device interrupt id read from the system repository.
273  * @virq: The assigned Linux virq.
274  *
275  * An event irq represents a virtual device interrupt.  The interrupt_id
276  * coresponds to the software interrupt number.
277  */
278
279 int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
280         const struct ps3_device_id *did, unsigned int interrupt_id,
281         unsigned int *virq)
282 {
283         int result;
284
285         result = ps3_alloc_event_irq(cpu, virq);
286
287         if (result)
288                 return result;
289
290         result = lv1_connect_interrupt_event_receive_port(did->bus_id,
291                 did->dev_id, virq_to_hw(*virq), interrupt_id);
292
293         if (result) {
294                 pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port"
295                         " failed: %s\n", __func__, __LINE__,
296                         ps3_result(result));
297                 ps3_free_event_irq(*virq);
298                 *virq = NO_IRQ;
299                 return result;
300         }
301
302         pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
303                 interrupt_id, *virq);
304
305         return 0;
306 }
307
308 int ps3_disconnect_event_irq(const struct ps3_device_id *did,
309         unsigned int interrupt_id, unsigned int virq)
310 {
311         int result;
312
313         pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
314                 interrupt_id, virq);
315
316         result = lv1_disconnect_interrupt_event_receive_port(did->bus_id,
317                 did->dev_id, virq_to_hw(virq), interrupt_id);
318
319         if (result)
320                 pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port"
321                         " failed: %s\n", __func__, __LINE__,
322                         ps3_result(result));
323
324         ps3_free_event_irq(virq);
325
326         pr_debug(" <- %s:%d\n", __func__, __LINE__);
327         return result;
328 }
329
330 /**
331  * ps3_alloc_vuart_irq - Configure the system virtual uart virq.
332  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
333  * serviced on.
334  * @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap.
335  * @virq: The assigned Linux virq.
336  *
337  * The system supports only a single virtual uart, so multiple calls without
338  * freeing the interrupt will return a wrong state error.
339  */
340
341 int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
342         unsigned int *virq)
343 {
344         int result;
345         unsigned long outlet;
346         u64 lpar_addr;
347
348         BUG_ON(!is_kernel_addr((u64)virt_addr_bmp));
349
350         lpar_addr = ps3_mm_phys_to_lpar(__pa(virt_addr_bmp));
351
352         result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet);
353
354         if (result) {
355                 pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n",
356                         __func__, __LINE__, ps3_result(result));
357                 return result;
358         }
359
360         result = ps3_alloc_irq(cpu, outlet, virq);
361         BUG_ON(result);
362
363         return result;
364 }
365
366 int ps3_free_vuart_irq(unsigned int virq)
367 {
368         int result;
369
370         result = lv1_deconfigure_virtual_uart_irq();
371
372         if (result) {
373                 pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n",
374                         __func__, __LINE__, ps3_result(result));
375                 return result;
376         }
377
378         ps3_free_irq(virq);
379
380         return result;
381 }
382
383 /**
384  * ps3_alloc_spe_irq - Configure an spe virq.
385  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
386  * serviced on.
387  * @spe_id: The spe_id returned from lv1_construct_logical_spe().
388  * @class: The spe interrupt class {0,1,2}.
389  * @virq: The assigned Linux virq.
390  *
391  */
392
393 int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id,
394         unsigned int class, unsigned int *virq)
395 {
396         int result;
397         unsigned long outlet;
398
399         BUG_ON(class > 2);
400
401         result = lv1_get_spe_irq_outlet(spe_id, class, &outlet);
402
403         if (result) {
404                 pr_debug("%s:%d: lv1_get_spe_irq_outlet failed: %s\n",
405                         __func__, __LINE__, ps3_result(result));
406                 return result;
407         }
408
409         result = ps3_alloc_irq(cpu, outlet, virq);
410         BUG_ON(result);
411
412         return result;
413 }
414
415 int ps3_free_spe_irq(unsigned int virq)
416 {
417         ps3_free_irq(virq);
418         return 0;
419 }
420
421
422 #define PS3_INVALID_OUTLET ((irq_hw_number_t)-1)
423 #define PS3_PLUG_MAX 63
424
425 #if defined(DEBUG)
426 static void _dump_64_bmp(const char *header, const u64 *p, unsigned cpu,
427         const char* func, int line)
428 {
429         pr_debug("%s:%d: %s %u {%04lx_%04lx_%04lx_%04lx}\n",
430                 func, line, header, cpu,
431                 *p >> 48, (*p >> 32) & 0xffff, (*p >> 16) & 0xffff,
432                 *p & 0xffff);
433 }
434
435 static void __attribute__ ((unused)) _dump_256_bmp(const char *header,
436         const u64 *p, unsigned cpu, const char* func, int line)
437 {
438         pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n",
439                 func, line, header, cpu, p[0], p[1], p[2], p[3]);
440 }
441
442 #define dump_bmp(_x) _dump_bmp(_x, __func__, __LINE__)
443 static void _dump_bmp(struct ps3_private* pd, const char* func, int line)
444 {
445         unsigned long flags;
446
447         spin_lock_irqsave(&pd->bmp.lock, flags);
448         _dump_64_bmp("stat", &pd->bmp.status, pd->cpu, func, line);
449         _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line);
450         spin_unlock_irqrestore(&pd->bmp.lock, flags);
451 }
452
453 #define dump_mask(_x) _dump_mask(_x, __func__, __LINE__)
454 static void __attribute__ ((unused)) _dump_mask(struct ps3_private* pd,
455         const char* func, int line)
456 {
457         unsigned long flags;
458
459         spin_lock_irqsave(&pd->bmp.lock, flags);
460         _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line);
461         spin_unlock_irqrestore(&pd->bmp.lock, flags);
462 }
463 #else
464 static void dump_bmp(struct ps3_private* pd) {};
465 #endif /* defined(DEBUG) */
466
467 static void ps3_chip_mask(unsigned int virq)
468 {
469         struct ps3_private *pd = get_irq_chip_data(virq);
470         u64 bit = 0x8000000000000000UL >> virq;
471         u64 *p = &pd->bmp.mask;
472         u64 old;
473         unsigned long flags;
474
475         pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
476
477         local_irq_save(flags);
478         asm volatile(
479                      "1:        ldarx %0,0,%3\n"
480                      "andc      %0,%0,%2\n"
481                      "stdcx.    %0,0,%3\n"
482                      "bne-      1b"
483                      : "=&r" (old), "+m" (*p)
484                      : "r" (bit), "r" (p)
485                      : "cc" );
486
487         lv1_did_update_interrupt_mask(pd->node, pd->cpu);
488         local_irq_restore(flags);
489 }
490
491 static void ps3_chip_unmask(unsigned int virq)
492 {
493         struct ps3_private *pd = get_irq_chip_data(virq);
494         u64 bit = 0x8000000000000000UL >> virq;
495         u64 *p = &pd->bmp.mask;
496         u64 old;
497         unsigned long flags;
498
499         pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
500
501         local_irq_save(flags);
502         asm volatile(
503                      "1:        ldarx %0,0,%3\n"
504                      "or        %0,%0,%2\n"
505                      "stdcx.    %0,0,%3\n"
506                      "bne-      1b"
507                      : "=&r" (old), "+m" (*p)
508                      : "r" (bit), "r" (p)
509                      : "cc" );
510
511         lv1_did_update_interrupt_mask(pd->node, pd->cpu);
512         local_irq_restore(flags);
513 }
514
515 static void ps3_chip_eoi(unsigned int virq)
516 {
517         const struct ps3_private *pd = get_irq_chip_data(virq);
518         lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
519 }
520
521 static struct irq_chip irq_chip = {
522         .typename = "ps3",
523         .mask = ps3_chip_mask,
524         .unmask = ps3_chip_unmask,
525         .eoi = ps3_chip_eoi,
526 };
527
528 static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
529 {
530         set_irq_chip_data(virq, NULL);
531 }
532
533 static int ps3_host_map(struct irq_host *h, unsigned int virq,
534         irq_hw_number_t hwirq)
535 {
536         pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
537                 virq);
538
539         set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq);
540
541         return 0;
542 }
543
544 static struct irq_host_ops ps3_host_ops = {
545         .map = ps3_host_map,
546         .unmap = ps3_host_unmap,
547 };
548
549 void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq)
550 {
551         struct ps3_private *pd = &per_cpu(ps3_private, cpu);
552
553         pd->bmp.ipi_debug_brk_mask = 0x8000000000000000UL >> virq;
554
555         pr_debug("%s:%d: cpu %u, virq %u, mask %lxh\n", __func__, __LINE__,
556                 cpu, virq, pd->bmp.ipi_debug_brk_mask);
557 }
558
559 unsigned int ps3_get_irq(void)
560 {
561         struct ps3_private *pd = &__get_cpu_var(ps3_private);
562         u64 x = (pd->bmp.status & pd->bmp.mask);
563         unsigned int plug;
564
565         /* check for ipi break first to stop this cpu ASAP */
566
567         if (x & pd->bmp.ipi_debug_brk_mask)
568                 x &= pd->bmp.ipi_debug_brk_mask;
569
570         asm volatile("cntlzd %0,%1" : "=r" (plug) : "r" (x));
571         plug &= 0x3f;
572
573         if (unlikely(plug) == NO_IRQ) {
574                 pr_debug("%s:%d: no plug found: cpu %u\n", __func__, __LINE__,
575                         pd->cpu);
576                 dump_bmp(&per_cpu(ps3_private, 0));
577                 dump_bmp(&per_cpu(ps3_private, 1));
578                 return NO_IRQ;
579         }
580
581 #if defined(DEBUG)
582         if (unlikely(plug < NUM_ISA_INTERRUPTS || plug > PS3_PLUG_MAX)) {
583                 dump_bmp(&per_cpu(ps3_private, 0));
584                 dump_bmp(&per_cpu(ps3_private, 1));
585                 BUG();
586         }
587 #endif
588         return plug;
589 }
590
591 void __init ps3_init_IRQ(void)
592 {
593         int result;
594         unsigned cpu;
595         struct irq_host *host;
596
597         host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops,
598                 PS3_INVALID_OUTLET);
599         irq_set_default_host(host);
600         irq_set_virq_count(PS3_PLUG_MAX + 1);
601
602         for_each_possible_cpu(cpu) {
603                 struct ps3_private *pd = &per_cpu(ps3_private, cpu);
604
605                 lv1_get_logical_ppe_id(&pd->node);
606                 pd->cpu = get_hard_smp_processor_id(cpu);
607                 spin_lock_init(&pd->bmp.lock);
608
609                 pr_debug("%s:%d: node %lu, cpu %d, bmp %lxh\n", __func__,
610                         __LINE__, pd->node, pd->cpu,
611                         ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
612
613                 result = lv1_configure_irq_state_bitmap(pd->node, pd->cpu,
614                         ps3_mm_phys_to_lpar(__pa(&pd->bmp)));
615
616                 if (result)
617                         pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:"
618                                 " %s\n", __func__, __LINE__,
619                                 ps3_result(result));
620         }
621
622         ppc_md.get_irq = ps3_get_irq;
623 }