]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/powerpc/platforms/cell/spu_base.c
b9ae675640d08fff52d460ed192261eb11c3bb03
[linux-2.6-omap-h63xx.git] / arch / powerpc / platforms / cell / spu_base.c
1 /*
2  * Low-level SPU handling
3  *
4  * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5  *
6  * Author: Arnd Bergmann <arndb@de.ibm.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #undef DEBUG
24
25 #include <linux/interrupt.h>
26 #include <linux/list.h>
27 #include <linux/module.h>
28 #include <linux/ptrace.h>
29 #include <linux/slab.h>
30 #include <linux/wait.h>
31 #include <linux/mm.h>
32 #include <linux/io.h>
33 #include <linux/mutex.h>
34 #include <linux/linux_logo.h>
35 #include <asm/spu.h>
36 #include <asm/spu_priv1.h>
37 #include <asm/spu_csa.h>
38 #include <asm/xmon.h>
39 #include <asm/prom.h>
40
41 const struct spu_management_ops *spu_management_ops;
42 EXPORT_SYMBOL_GPL(spu_management_ops);
43
44 const struct spu_priv1_ops *spu_priv1_ops;
45 EXPORT_SYMBOL_GPL(spu_priv1_ops);
46
47 struct cbe_spu_info cbe_spu_info[MAX_NUMNODES];
48 EXPORT_SYMBOL_GPL(cbe_spu_info);
49
50 /*
51  * The spufs fault-handling code needs to call force_sig_info to raise signals
52  * on DMA errors. Export it here to avoid general kernel-wide access to this
53  * function
54  */
55 EXPORT_SYMBOL_GPL(force_sig_info);
56
57 /*
58  * Protects cbe_spu_info and spu->number.
59  */
60 static DEFINE_SPINLOCK(spu_lock);
61
62 /*
63  * List of all spus in the system.
64  *
65  * This list is iterated by callers from irq context and callers that
66  * want to sleep.  Thus modifications need to be done with both
67  * spu_full_list_lock and spu_full_list_mutex held, while iterating
68  * through it requires either of these locks.
69  *
70  * In addition spu_full_list_lock protects all assignmens to
71  * spu->mm.
72  */
73 static LIST_HEAD(spu_full_list);
74 static DEFINE_SPINLOCK(spu_full_list_lock);
75 static DEFINE_MUTEX(spu_full_list_mutex);
76
77 struct spu_slb {
78         u64 esid, vsid;
79 };
80
81 void spu_invalidate_slbs(struct spu *spu)
82 {
83         struct spu_priv2 __iomem *priv2 = spu->priv2;
84         unsigned long flags;
85
86         spin_lock_irqsave(&spu->register_lock, flags);
87         if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK)
88                 out_be64(&priv2->slb_invalidate_all_W, 0UL);
89         spin_unlock_irqrestore(&spu->register_lock, flags);
90 }
91 EXPORT_SYMBOL_GPL(spu_invalidate_slbs);
92
93 /* This is called by the MM core when a segment size is changed, to
94  * request a flush of all the SPEs using a given mm
95  */
96 void spu_flush_all_slbs(struct mm_struct *mm)
97 {
98         struct spu *spu;
99         unsigned long flags;
100
101         spin_lock_irqsave(&spu_full_list_lock, flags);
102         list_for_each_entry(spu, &spu_full_list, full_list) {
103                 if (spu->mm == mm)
104                         spu_invalidate_slbs(spu);
105         }
106         spin_unlock_irqrestore(&spu_full_list_lock, flags);
107 }
108
109 /* The hack below stinks... try to do something better one of
110  * these days... Does it even work properly with NR_CPUS == 1 ?
111  */
112 static inline void mm_needs_global_tlbie(struct mm_struct *mm)
113 {
114         int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1;
115
116         /* Global TLBIE broadcast required with SPEs. */
117         __cpus_setall(&mm->cpu_vm_mask, nr);
118 }
119
120 void spu_associate_mm(struct spu *spu, struct mm_struct *mm)
121 {
122         unsigned long flags;
123
124         spin_lock_irqsave(&spu_full_list_lock, flags);
125         spu->mm = mm;
126         spin_unlock_irqrestore(&spu_full_list_lock, flags);
127         if (mm)
128                 mm_needs_global_tlbie(mm);
129 }
130 EXPORT_SYMBOL_GPL(spu_associate_mm);
131
132 int spu_64k_pages_available(void)
133 {
134         return mmu_psize_defs[MMU_PAGE_64K].shift != 0;
135 }
136 EXPORT_SYMBOL_GPL(spu_64k_pages_available);
137
138 static void spu_restart_dma(struct spu *spu)
139 {
140         struct spu_priv2 __iomem *priv2 = spu->priv2;
141
142         if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags))
143                 out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
144 }
145
146 static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb)
147 {
148         struct spu_priv2 __iomem *priv2 = spu->priv2;
149
150         pr_debug("%s: adding SLB[%d] 0x%016lx 0x%016lx\n",
151                         __func__, slbe, slb->vsid, slb->esid);
152
153         out_be64(&priv2->slb_index_W, slbe);
154         /* set invalid before writing vsid */
155         out_be64(&priv2->slb_esid_RW, 0);
156         /* now it's safe to write the vsid */
157         out_be64(&priv2->slb_vsid_RW, slb->vsid);
158         /* setting the new esid makes the entry valid again */
159         out_be64(&priv2->slb_esid_RW, slb->esid);
160 }
161
162 static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
163 {
164         struct mm_struct *mm = spu->mm;
165         struct spu_slb slb;
166         int psize;
167
168         pr_debug("%s\n", __func__);
169
170         slb.esid = (ea & ESID_MASK) | SLB_ESID_V;
171
172         switch(REGION_ID(ea)) {
173         case USER_REGION_ID:
174 #ifdef CONFIG_PPC_MM_SLICES
175                 psize = get_slice_psize(mm, ea);
176 #else
177                 psize = mm->context.user_psize;
178 #endif
179                 slb.vsid = (get_vsid(mm->context.id, ea, MMU_SEGSIZE_256M)
180                                 << SLB_VSID_SHIFT) | SLB_VSID_USER;
181                 break;
182         case VMALLOC_REGION_ID:
183                 if (ea < VMALLOC_END)
184                         psize = mmu_vmalloc_psize;
185                 else
186                         psize = mmu_io_psize;
187                 slb.vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M)
188                                 << SLB_VSID_SHIFT) | SLB_VSID_KERNEL;
189                 break;
190         case KERNEL_REGION_ID:
191                 psize = mmu_linear_psize;
192                 slb.vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M)
193                                 << SLB_VSID_SHIFT) | SLB_VSID_KERNEL;
194                 break;
195         default:
196                 /* Future: support kernel segments so that drivers
197                  * can use SPUs.
198                  */
199                 pr_debug("invalid region access at %016lx\n", ea);
200                 return 1;
201         }
202         slb.vsid |= mmu_psize_defs[psize].sllp;
203
204         spu_load_slb(spu, spu->slb_replace, &slb);
205
206         spu->slb_replace++;
207         if (spu->slb_replace >= 8)
208                 spu->slb_replace = 0;
209
210         spu_restart_dma(spu);
211         spu->stats.slb_flt++;
212         return 0;
213 }
214
215 extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap); //XXX
216 static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
217 {
218         pr_debug("%s, %lx, %lx\n", __func__, dsisr, ea);
219
220         /* Handle kernel space hash faults immediately.
221            User hash faults need to be deferred to process context. */
222         if ((dsisr & MFC_DSISR_PTE_NOT_FOUND)
223             && REGION_ID(ea) != USER_REGION_ID
224             && hash_page(ea, _PAGE_PRESENT, 0x300) == 0) {
225                 spu_restart_dma(spu);
226                 return 0;
227         }
228
229         spu->class_1_dar = ea;
230         spu->class_1_dsisr = dsisr;
231
232         spu->stop_callback(spu, 1);
233
234         spu->class_1_dar = 0;
235         spu->class_1_dsisr = 0;
236
237         return 0;
238 }
239
240 static void __spu_kernel_slb(void *addr, struct spu_slb *slb)
241 {
242         unsigned long ea = (unsigned long)addr;
243         u64 llp;
244
245         if (REGION_ID(ea) == KERNEL_REGION_ID)
246                 llp = mmu_psize_defs[mmu_linear_psize].sllp;
247         else
248                 llp = mmu_psize_defs[mmu_virtual_psize].sllp;
249
250         slb->vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) |
251                 SLB_VSID_KERNEL | llp;
252         slb->esid = (ea & ESID_MASK) | SLB_ESID_V;
253 }
254
255 /**
256  * Given an array of @nr_slbs SLB entries, @slbs, return non-zero if the
257  * address @new_addr is present.
258  */
259 static inline int __slb_present(struct spu_slb *slbs, int nr_slbs,
260                 void *new_addr)
261 {
262         unsigned long ea = (unsigned long)new_addr;
263         int i;
264
265         for (i = 0; i < nr_slbs; i++)
266                 if (!((slbs[i].esid ^ ea) & ESID_MASK))
267                         return 1;
268
269         return 0;
270 }
271
272 /**
273  * Setup the SPU kernel SLBs, in preparation for a context save/restore. We
274  * need to map both the context save area, and the save/restore code.
275  *
276  * Because the lscsa and code may cross segment boundaires, we check to see
277  * if mappings are required for the start and end of each range. We currently
278  * assume that the mappings are smaller that one segment - if not, something
279  * is seriously wrong.
280  */
281 void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa,
282                 void *code, int code_size)
283 {
284         struct spu_slb slbs[4];
285         int i, nr_slbs = 0;
286         /* start and end addresses of both mappings */
287         void *addrs[] = {
288                 lscsa, (void *)lscsa + sizeof(*lscsa) - 1,
289                 code, code + code_size - 1
290         };
291
292         /* check the set of addresses, and create a new entry in the slbs array
293          * if there isn't already a SLB for that address */
294         for (i = 0; i < ARRAY_SIZE(addrs); i++) {
295                 if (__slb_present(slbs, nr_slbs, addrs[i]))
296                         continue;
297
298                 __spu_kernel_slb(addrs[i], &slbs[nr_slbs]);
299                 nr_slbs++;
300         }
301
302         spin_lock_irq(&spu->register_lock);
303         /* Add the set of SLBs */
304         for (i = 0; i < nr_slbs; i++)
305                 spu_load_slb(spu, i, &slbs[i]);
306         spin_unlock_irq(&spu->register_lock);
307 }
308 EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs);
309
310 static irqreturn_t
311 spu_irq_class_0(int irq, void *data)
312 {
313         struct spu *spu;
314         unsigned long stat, mask;
315
316         spu = data;
317
318         spin_lock(&spu->register_lock);
319         mask = spu_int_mask_get(spu, 0);
320         stat = spu_int_stat_get(spu, 0) & mask;
321
322         spu->class_0_pending |= stat;
323         spu->class_0_dsisr = spu_mfc_dsisr_get(spu);
324         spu->class_0_dar = spu_mfc_dar_get(spu);
325         spin_unlock(&spu->register_lock);
326
327         spu->stop_callback(spu, 0);
328
329         spu->class_0_pending = 0;
330         spu->class_0_dsisr = 0;
331         spu->class_0_dar = 0;
332
333         spu_int_stat_clear(spu, 0, stat);
334
335         return IRQ_HANDLED;
336 }
337
338 static irqreturn_t
339 spu_irq_class_1(int irq, void *data)
340 {
341         struct spu *spu;
342         unsigned long stat, mask, dar, dsisr;
343
344         spu = data;
345
346         /* atomically read & clear class1 status. */
347         spin_lock(&spu->register_lock);
348         mask  = spu_int_mask_get(spu, 1);
349         stat  = spu_int_stat_get(spu, 1) & mask;
350         dar   = spu_mfc_dar_get(spu);
351         dsisr = spu_mfc_dsisr_get(spu);
352         if (stat & CLASS1_STORAGE_FAULT_INTR)
353                 spu_mfc_dsisr_set(spu, 0ul);
354         spu_int_stat_clear(spu, 1, stat);
355
356         if (stat & CLASS1_SEGMENT_FAULT_INTR)
357                 __spu_trap_data_seg(spu, dar);
358
359         spin_unlock(&spu->register_lock);
360         pr_debug("%s: %lx %lx %lx %lx\n", __func__, mask, stat,
361                         dar, dsisr);
362
363         if (stat & CLASS1_STORAGE_FAULT_INTR)
364                 __spu_trap_data_map(spu, dar, dsisr);
365
366         if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_GET_INTR)
367                 ;
368
369         if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR)
370                 ;
371
372         spu->class_1_dsisr = 0;
373         spu->class_1_dar = 0;
374
375         return stat ? IRQ_HANDLED : IRQ_NONE;
376 }
377
378 static irqreturn_t
379 spu_irq_class_2(int irq, void *data)
380 {
381         struct spu *spu;
382         unsigned long stat;
383         unsigned long mask;
384         const int mailbox_intrs =
385                 CLASS2_MAILBOX_THRESHOLD_INTR | CLASS2_MAILBOX_INTR;
386
387         spu = data;
388         spin_lock(&spu->register_lock);
389         stat = spu_int_stat_get(spu, 2);
390         mask = spu_int_mask_get(spu, 2);
391         /* ignore interrupts we're not waiting for */
392         stat &= mask;
393
394         /* mailbox interrupts are level triggered. mask them now before
395          * acknowledging */
396         if (stat & mailbox_intrs)
397                 spu_int_mask_and(spu, 2, ~(stat & mailbox_intrs));
398         /* acknowledge all interrupts before the callbacks */
399         spu_int_stat_clear(spu, 2, stat);
400         spin_unlock(&spu->register_lock);
401
402         pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask);
403
404         if (stat & CLASS2_MAILBOX_INTR)
405                 spu->ibox_callback(spu);
406
407         if (stat & CLASS2_SPU_STOP_INTR)
408                 spu->stop_callback(spu, 2);
409
410         if (stat & CLASS2_SPU_HALT_INTR)
411                 spu->stop_callback(spu, 2);
412
413         if (stat & CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR)
414                 spu->mfc_callback(spu);
415
416         if (stat & CLASS2_MAILBOX_THRESHOLD_INTR)
417                 spu->wbox_callback(spu);
418
419         spu->stats.class2_intr++;
420         return stat ? IRQ_HANDLED : IRQ_NONE;
421 }
422
423 static int spu_request_irqs(struct spu *spu)
424 {
425         int ret = 0;
426
427         if (spu->irqs[0] != NO_IRQ) {
428                 snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0",
429                          spu->number);
430                 ret = request_irq(spu->irqs[0], spu_irq_class_0,
431                                   IRQF_DISABLED,
432                                   spu->irq_c0, spu);
433                 if (ret)
434                         goto bail0;
435         }
436         if (spu->irqs[1] != NO_IRQ) {
437                 snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1",
438                          spu->number);
439                 ret = request_irq(spu->irqs[1], spu_irq_class_1,
440                                   IRQF_DISABLED,
441                                   spu->irq_c1, spu);
442                 if (ret)
443                         goto bail1;
444         }
445         if (spu->irqs[2] != NO_IRQ) {
446                 snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2",
447                          spu->number);
448                 ret = request_irq(spu->irqs[2], spu_irq_class_2,
449                                   IRQF_DISABLED,
450                                   spu->irq_c2, spu);
451                 if (ret)
452                         goto bail2;
453         }
454         return 0;
455
456 bail2:
457         if (spu->irqs[1] != NO_IRQ)
458                 free_irq(spu->irqs[1], spu);
459 bail1:
460         if (spu->irqs[0] != NO_IRQ)
461                 free_irq(spu->irqs[0], spu);
462 bail0:
463         return ret;
464 }
465
466 static void spu_free_irqs(struct spu *spu)
467 {
468         if (spu->irqs[0] != NO_IRQ)
469                 free_irq(spu->irqs[0], spu);
470         if (spu->irqs[1] != NO_IRQ)
471                 free_irq(spu->irqs[1], spu);
472         if (spu->irqs[2] != NO_IRQ)
473                 free_irq(spu->irqs[2], spu);
474 }
475
476 void spu_init_channels(struct spu *spu)
477 {
478         static const struct {
479                  unsigned channel;
480                  unsigned count;
481         } zero_list[] = {
482                 { 0x00, 1, }, { 0x01, 1, }, { 0x03, 1, }, { 0x04, 1, },
483                 { 0x18, 1, }, { 0x19, 1, }, { 0x1b, 1, }, { 0x1d, 1, },
484         }, count_list[] = {
485                 { 0x00, 0, }, { 0x03, 0, }, { 0x04, 0, }, { 0x15, 16, },
486                 { 0x17, 1, }, { 0x18, 0, }, { 0x19, 0, }, { 0x1b, 0, },
487                 { 0x1c, 1, }, { 0x1d, 0, }, { 0x1e, 1, },
488         };
489         struct spu_priv2 __iomem *priv2;
490         int i;
491
492         priv2 = spu->priv2;
493
494         /* initialize all channel data to zero */
495         for (i = 0; i < ARRAY_SIZE(zero_list); i++) {
496                 int count;
497
498                 out_be64(&priv2->spu_chnlcntptr_RW, zero_list[i].channel);
499                 for (count = 0; count < zero_list[i].count; count++)
500                         out_be64(&priv2->spu_chnldata_RW, 0);
501         }
502
503         /* initialize channel counts to meaningful values */
504         for (i = 0; i < ARRAY_SIZE(count_list); i++) {
505                 out_be64(&priv2->spu_chnlcntptr_RW, count_list[i].channel);
506                 out_be64(&priv2->spu_chnlcnt_RW, count_list[i].count);
507         }
508 }
509 EXPORT_SYMBOL_GPL(spu_init_channels);
510
511 static int spu_shutdown(struct sys_device *sysdev)
512 {
513         struct spu *spu = container_of(sysdev, struct spu, sysdev);
514
515         spu_free_irqs(spu);
516         spu_destroy_spu(spu);
517         return 0;
518 }
519
520 static struct sysdev_class spu_sysdev_class = {
521         .name = "spu",
522         .shutdown = spu_shutdown,
523 };
524
525 int spu_add_sysdev_attr(struct sysdev_attribute *attr)
526 {
527         struct spu *spu;
528
529         mutex_lock(&spu_full_list_mutex);
530         list_for_each_entry(spu, &spu_full_list, full_list)
531                 sysdev_create_file(&spu->sysdev, attr);
532         mutex_unlock(&spu_full_list_mutex);
533
534         return 0;
535 }
536 EXPORT_SYMBOL_GPL(spu_add_sysdev_attr);
537
538 int spu_add_sysdev_attr_group(struct attribute_group *attrs)
539 {
540         struct spu *spu;
541         int rc = 0;
542
543         mutex_lock(&spu_full_list_mutex);
544         list_for_each_entry(spu, &spu_full_list, full_list) {
545                 rc = sysfs_create_group(&spu->sysdev.kobj, attrs);
546
547                 /* we're in trouble here, but try unwinding anyway */
548                 if (rc) {
549                         printk(KERN_ERR "%s: can't create sysfs group '%s'\n",
550                                         __func__, attrs->name);
551
552                         list_for_each_entry_continue_reverse(spu,
553                                         &spu_full_list, full_list)
554                                 sysfs_remove_group(&spu->sysdev.kobj, attrs);
555                         break;
556                 }
557         }
558
559         mutex_unlock(&spu_full_list_mutex);
560
561         return rc;
562 }
563 EXPORT_SYMBOL_GPL(spu_add_sysdev_attr_group);
564
565
566 void spu_remove_sysdev_attr(struct sysdev_attribute *attr)
567 {
568         struct spu *spu;
569
570         mutex_lock(&spu_full_list_mutex);
571         list_for_each_entry(spu, &spu_full_list, full_list)
572                 sysdev_remove_file(&spu->sysdev, attr);
573         mutex_unlock(&spu_full_list_mutex);
574 }
575 EXPORT_SYMBOL_GPL(spu_remove_sysdev_attr);
576
577 void spu_remove_sysdev_attr_group(struct attribute_group *attrs)
578 {
579         struct spu *spu;
580
581         mutex_lock(&spu_full_list_mutex);
582         list_for_each_entry(spu, &spu_full_list, full_list)
583                 sysfs_remove_group(&spu->sysdev.kobj, attrs);
584         mutex_unlock(&spu_full_list_mutex);
585 }
586 EXPORT_SYMBOL_GPL(spu_remove_sysdev_attr_group);
587
588 static int spu_create_sysdev(struct spu *spu)
589 {
590         int ret;
591
592         spu->sysdev.id = spu->number;
593         spu->sysdev.cls = &spu_sysdev_class;
594         ret = sysdev_register(&spu->sysdev);
595         if (ret) {
596                 printk(KERN_ERR "Can't register SPU %d with sysfs\n",
597                                 spu->number);
598                 return ret;
599         }
600
601         sysfs_add_device_to_node(&spu->sysdev, spu->node);
602
603         return 0;
604 }
605
606 static int __init create_spu(void *data)
607 {
608         struct spu *spu;
609         int ret;
610         static int number;
611         unsigned long flags;
612         struct timespec ts;
613
614         ret = -ENOMEM;
615         spu = kzalloc(sizeof (*spu), GFP_KERNEL);
616         if (!spu)
617                 goto out;
618
619         spu->alloc_state = SPU_FREE;
620
621         spin_lock_init(&spu->register_lock);
622         spin_lock(&spu_lock);
623         spu->number = number++;
624         spin_unlock(&spu_lock);
625
626         ret = spu_create_spu(spu, data);
627
628         if (ret)
629                 goto out_free;
630
631         spu_mfc_sdr_setup(spu);
632         spu_mfc_sr1_set(spu, 0x33);
633         ret = spu_request_irqs(spu);
634         if (ret)
635                 goto out_destroy;
636
637         ret = spu_create_sysdev(spu);
638         if (ret)
639                 goto out_free_irqs;
640
641         mutex_lock(&cbe_spu_info[spu->node].list_mutex);
642         list_add(&spu->cbe_list, &cbe_spu_info[spu->node].spus);
643         cbe_spu_info[spu->node].n_spus++;
644         mutex_unlock(&cbe_spu_info[spu->node].list_mutex);
645
646         mutex_lock(&spu_full_list_mutex);
647         spin_lock_irqsave(&spu_full_list_lock, flags);
648         list_add(&spu->full_list, &spu_full_list);
649         spin_unlock_irqrestore(&spu_full_list_lock, flags);
650         mutex_unlock(&spu_full_list_mutex);
651
652         spu->stats.util_state = SPU_UTIL_IDLE_LOADED;
653         ktime_get_ts(&ts);
654         spu->stats.tstamp = timespec_to_ns(&ts);
655
656         INIT_LIST_HEAD(&spu->aff_list);
657
658         goto out;
659
660 out_free_irqs:
661         spu_free_irqs(spu);
662 out_destroy:
663         spu_destroy_spu(spu);
664 out_free:
665         kfree(spu);
666 out:
667         return ret;
668 }
669
670 static const char *spu_state_names[] = {
671         "user", "system", "iowait", "idle"
672 };
673
674 static unsigned long long spu_acct_time(struct spu *spu,
675                 enum spu_utilization_state state)
676 {
677         struct timespec ts;
678         unsigned long long time = spu->stats.times[state];
679
680         /*
681          * If the spu is idle or the context is stopped, utilization
682          * statistics are not updated.  Apply the time delta from the
683          * last recorded state of the spu.
684          */
685         if (spu->stats.util_state == state) {
686                 ktime_get_ts(&ts);
687                 time += timespec_to_ns(&ts) - spu->stats.tstamp;
688         }
689
690         return time / NSEC_PER_MSEC;
691 }
692
693
694 static ssize_t spu_stat_show(struct sys_device *sysdev, char *buf)
695 {
696         struct spu *spu = container_of(sysdev, struct spu, sysdev);
697
698         return sprintf(buf, "%s %llu %llu %llu %llu "
699                       "%llu %llu %llu %llu %llu %llu %llu %llu\n",
700                 spu_state_names[spu->stats.util_state],
701                 spu_acct_time(spu, SPU_UTIL_USER),
702                 spu_acct_time(spu, SPU_UTIL_SYSTEM),
703                 spu_acct_time(spu, SPU_UTIL_IOWAIT),
704                 spu_acct_time(spu, SPU_UTIL_IDLE_LOADED),
705                 spu->stats.vol_ctx_switch,
706                 spu->stats.invol_ctx_switch,
707                 spu->stats.slb_flt,
708                 spu->stats.hash_flt,
709                 spu->stats.min_flt,
710                 spu->stats.maj_flt,
711                 spu->stats.class2_intr,
712                 spu->stats.libassist);
713 }
714
715 static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL);
716
717 static int __init init_spu_base(void)
718 {
719         int i, ret = 0;
720
721         for (i = 0; i < MAX_NUMNODES; i++) {
722                 mutex_init(&cbe_spu_info[i].list_mutex);
723                 INIT_LIST_HEAD(&cbe_spu_info[i].spus);
724         }
725
726         if (!spu_management_ops)
727                 goto out;
728
729         /* create sysdev class for spus */
730         ret = sysdev_class_register(&spu_sysdev_class);
731         if (ret)
732                 goto out;
733
734         ret = spu_enumerate_spus(create_spu);
735
736         if (ret < 0) {
737                 printk(KERN_WARNING "%s: Error initializing spus\n",
738                         __func__);
739                 goto out_unregister_sysdev_class;
740         }
741
742         if (ret > 0) {
743                 /*
744                  * We cannot put the forward declaration in
745                  * <linux/linux_logo.h> because of conflicting session type
746                  * conflicts for const and __initdata with different compiler
747                  * versions
748                  */
749                 extern const struct linux_logo logo_spe_clut224;
750
751                 fb_append_extra_logo(&logo_spe_clut224, ret);
752         }
753
754         mutex_lock(&spu_full_list_mutex);
755         xmon_register_spus(&spu_full_list);
756         crash_register_spus(&spu_full_list);
757         mutex_unlock(&spu_full_list_mutex);
758         spu_add_sysdev_attr(&attr_stat);
759
760         spu_init_affinity();
761
762         return 0;
763
764  out_unregister_sysdev_class:
765         sysdev_class_unregister(&spu_sysdev_class);
766  out:
767         return ret;
768 }
769 module_init(init_spu_base);
770
771 MODULE_LICENSE("GPL");
772 MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");