xref: /openbmc/linux/drivers/ps3/ps3-lpm.c (revision 8fa5723aa7e053d498336b48448b292fc2e0458b)
1 /*
2  * PS3 Logical Performance Monitor.
3  *
4  *  Copyright (C) 2007 Sony Computer Entertainment Inc.
5  *  Copyright 2007 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/interrupt.h>
24 #include <linux/uaccess.h>
25 #include <asm/time.h>
26 #include <asm/ps3.h>
27 #include <asm/lv1call.h>
28 #include <asm/cell-pmu.h>
29 
30 
31 /* BOOKMARK tag macros */
32 #define PS3_PM_BOOKMARK_START                    0x8000000000000000ULL
33 #define PS3_PM_BOOKMARK_STOP                     0x4000000000000000ULL
34 #define PS3_PM_BOOKMARK_TAG_KERNEL               0x1000000000000000ULL
35 #define PS3_PM_BOOKMARK_TAG_USER                 0x3000000000000000ULL
36 #define PS3_PM_BOOKMARK_TAG_MASK_HI              0xF000000000000000ULL
37 #define PS3_PM_BOOKMARK_TAG_MASK_LO              0x0F00000000000000ULL
38 
39 /* CBE PM CONTROL register macros */
40 #define PS3_PM_CONTROL_PPU_TH0_BOOKMARK          0x00001000
41 #define PS3_PM_CONTROL_PPU_TH1_BOOKMARK          0x00000800
42 #define PS3_PM_CONTROL_PPU_COUNT_MODE_MASK       0x000C0000
43 #define PS3_PM_CONTROL_PPU_COUNT_MODE_PROBLEM    0x00080000
44 #define PS3_WRITE_PM_MASK                        0xFFFFFFFFFFFFFFFFULL
45 
46 /* CBE PM START STOP register macros */
47 #define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START 0x02000000
48 #define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START 0x01000000
49 #define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP  0x00020000
50 #define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP  0x00010000
51 #define PS3_PM_START_STOP_START_MASK             0xFF000000
52 #define PS3_PM_START_STOP_STOP_MASK              0x00FF0000
53 
54 /* CBE PM COUNTER register macres */
55 #define PS3_PM_COUNTER_MASK_HI                   0xFFFFFFFF00000000ULL
56 #define PS3_PM_COUNTER_MASK_LO                   0x00000000FFFFFFFFULL
57 
58 /* BASE SIGNAL GROUP NUMBER macros */
59 #define PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER  0
60 #define PM_ISLAND2_SIGNAL_GROUP_NUMBER1      6
61 #define PM_ISLAND2_SIGNAL_GROUP_NUMBER2      7
62 #define PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER  7
63 #define PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER  15
64 #define PM_SPU_TRIGGER_SIGNAL_GROUP_NUMBER   17
65 #define PM_SPU_EVENT_SIGNAL_GROUP_NUMBER     18
66 #define PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER  18
67 #define PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER  24
68 #define PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER  49
69 #define PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER  52
70 #define PM_SIG_GROUP_SPU                     41
71 #define PM_SIG_GROUP_SPU_TRIGGER             42
72 #define PM_SIG_GROUP_SPU_EVENT               43
73 #define PM_SIG_GROUP_MFC_MAX                 60
74 
75 /**
76  * struct ps3_lpm_shadow_regs - Performance monitor shadow registers.
77  *
78  * @pm_control: Shadow of the processor's pm_control register.
79  * @pm_start_stop: Shadow of the processor's pm_start_stop register.
80  * @group_control: Shadow of the processor's group_control register.
81  * @debug_bus_control: Shadow of the processor's debug_bus_control register.
82  *
83  * The logical performance monitor provides a write-only interface to
84  * these processor registers.  These shadow variables cache the processor
85  * register values for reading.
86  *
87  * The initial value of the shadow registers at lpm creation is
88  * PS3_LPM_SHADOW_REG_INIT.
89  */
90 
91 struct ps3_lpm_shadow_regs {
92 	u64 pm_control;
93 	u64 pm_start_stop;
94 	u64 group_control;
95 	u64 debug_bus_control;
96 };
97 
98 #define PS3_LPM_SHADOW_REG_INIT 0xFFFFFFFF00000000ULL
99 
100 /**
101  * struct ps3_lpm_priv - Private lpm device data.
102  *
103  * @open: An atomic variable indicating the lpm driver has been opened.
104  * @rights: The lpm rigths granted by the system policy module.  A logical
105  *  OR of enum ps3_lpm_rights.
106  * @node_id: The node id of a BE prosessor whose performance monitor this
107  *  lpar has the right to use.
108  * @pu_id: The lv1 id of the logical PU.
109  * @lpm_id: The lv1 id of this lpm instance.
110  * @outlet_id: The outlet created by lv1 for this lpm instance.
111  * @tb_count: The number of bytes of data held in the lv1 trace buffer.
112  * @tb_cache: Kernel buffer to receive the data from the lv1 trace buffer.
113  *  Must be 128 byte aligned.
114  * @tb_cache_size: Size of the kernel @tb_cache buffer.  Must be 128 byte
115  *  aligned.
116  * @tb_cache_internal: An unaligned buffer allocated by this driver to be
117  *  used for the trace buffer cache when ps3_lpm_open() is called with a
118  *  NULL tb_cache argument.  Otherwise unused.
119  * @shadow: Processor register shadow of type struct ps3_lpm_shadow_regs.
120  * @sbd: The struct ps3_system_bus_device attached to this driver.
121  *
122  * The trace buffer is a buffer allocated and used internally to the lv1
123  * hypervisor to collect trace data.  The trace buffer cache is a guest
124  * buffer that accepts the trace data from the trace buffer.
125  */
126 
127 struct ps3_lpm_priv {
128 	atomic_t open;
129 	u64 rights;
130 	u64 node_id;
131 	u64 pu_id;
132 	u64 lpm_id;
133 	u64 outlet_id;
134 	u64 tb_count;
135 	void *tb_cache;
136 	u64 tb_cache_size;
137 	void *tb_cache_internal;
138 	struct ps3_lpm_shadow_regs shadow;
139 	struct ps3_system_bus_device *sbd;
140 };
141 
142 enum {
143 	PS3_LPM_DEFAULT_TB_CACHE_SIZE = 0x4000,
144 };
145 
146 /**
147  * lpm_priv - Static instance of the lpm data.
148  *
149  * Since the exported routines don't support the notion of a device
150  * instance we need to hold the instance in this static variable
151  * and then only allow at most one instance at a time to be created.
152  */
153 
154 static struct ps3_lpm_priv *lpm_priv;
155 
156 static struct device *sbd_core(void)
157 {
158 	BUG_ON(!lpm_priv || !lpm_priv->sbd);
159 	return &lpm_priv->sbd->core;
160 }
161 
162 /**
163  * use_start_stop_bookmark - Enable the PPU bookmark trace.
164  *
165  * And it enables PPU bookmark triggers ONLY if the other triggers are not set.
166  * The start/stop bookmarks are inserted at ps3_enable_pm() and ps3_disable_pm()
167  * to start/stop LPM.
168  *
169  * Used to get good quality of the performance counter.
170  */
171 
172 enum {use_start_stop_bookmark = 1,};
173 
174 void ps3_set_bookmark(u64 bookmark)
175 {
176 	/*
177 	 * As per the PPE book IV, to avoid bookmark loss there must
178 	 * not be a traced branch within 10 cycles of setting the
179 	 * SPRN_BKMK register.  The actual text is unclear if 'within'
180 	 * includes cycles before the call.
181 	 */
182 
183 	asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;nop;");
184 	mtspr(SPRN_BKMK, bookmark);
185 	asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;nop;");
186 }
187 EXPORT_SYMBOL_GPL(ps3_set_bookmark);
188 
189 void ps3_set_pm_bookmark(u64 tag, u64 incident, u64 th_id)
190 {
191 	u64 bookmark;
192 
193 	bookmark = (get_tb() & 0x00000000FFFFFFFFULL) |
194 		PS3_PM_BOOKMARK_TAG_KERNEL;
195 	bookmark = ((tag << 56) & PS3_PM_BOOKMARK_TAG_MASK_LO) |
196 		(incident << 48) | (th_id << 32) | bookmark;
197 	ps3_set_bookmark(bookmark);
198 }
199 EXPORT_SYMBOL_GPL(ps3_set_pm_bookmark);
200 
201 /**
202  * ps3_read_phys_ctr - Read physical counter registers.
203  *
204  * Each physical counter can act as one 32 bit counter or as two 16 bit
205  * counters.
206  */
207 
208 u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr)
209 {
210 	int result;
211 	u64 counter0415;
212 	u64 counter2637;
213 
214 	if (phys_ctr >= NR_PHYS_CTRS) {
215 		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
216 			__LINE__, phys_ctr);
217 		return 0;
218 	}
219 
220 	result = lv1_set_lpm_counter(lpm_priv->lpm_id, 0, 0, 0, 0, &counter0415,
221 				     &counter2637);
222 	if (result) {
223 		dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: "
224 			"phys_ctr %u, %s\n", __func__, __LINE__, phys_ctr,
225 			ps3_result(result));
226 		return 0;
227 	}
228 
229 	switch (phys_ctr) {
230 	case 0:
231 		return counter0415 >> 32;
232 	case 1:
233 		return counter0415 & PS3_PM_COUNTER_MASK_LO;
234 	case 2:
235 		return counter2637 >> 32;
236 	case 3:
237 		return counter2637 & PS3_PM_COUNTER_MASK_LO;
238 	default:
239 		BUG();
240 	}
241 	return 0;
242 }
243 EXPORT_SYMBOL_GPL(ps3_read_phys_ctr);
244 
245 /**
246  * ps3_write_phys_ctr - Write physical counter registers.
247  *
248  * Each physical counter can act as one 32 bit counter or as two 16 bit
249  * counters.
250  */
251 
252 void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val)
253 {
254 	u64 counter0415;
255 	u64 counter0415_mask;
256 	u64 counter2637;
257 	u64 counter2637_mask;
258 	int result;
259 
260 	if (phys_ctr >= NR_PHYS_CTRS) {
261 		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
262 			__LINE__, phys_ctr);
263 		return;
264 	}
265 
266 	switch (phys_ctr) {
267 	case 0:
268 		counter0415 = (u64)val << 32;
269 		counter0415_mask = PS3_PM_COUNTER_MASK_HI;
270 		counter2637 = 0x0;
271 		counter2637_mask = 0x0;
272 		break;
273 	case 1:
274 		counter0415 = (u64)val;
275 		counter0415_mask = PS3_PM_COUNTER_MASK_LO;
276 		counter2637 = 0x0;
277 		counter2637_mask = 0x0;
278 		break;
279 	case 2:
280 		counter0415 = 0x0;
281 		counter0415_mask = 0x0;
282 		counter2637 = (u64)val << 32;
283 		counter2637_mask = PS3_PM_COUNTER_MASK_HI;
284 		break;
285 	case 3:
286 		counter0415 = 0x0;
287 		counter0415_mask = 0x0;
288 		counter2637 = (u64)val;
289 		counter2637_mask = PS3_PM_COUNTER_MASK_LO;
290 		break;
291 	default:
292 		BUG();
293 	}
294 
295 	result = lv1_set_lpm_counter(lpm_priv->lpm_id,
296 				     counter0415, counter0415_mask,
297 				     counter2637, counter2637_mask,
298 				     &counter0415, &counter2637);
299 	if (result)
300 		dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: "
301 			"phys_ctr %u, val %u, %s\n", __func__, __LINE__,
302 			phys_ctr, val, ps3_result(result));
303 }
304 EXPORT_SYMBOL_GPL(ps3_write_phys_ctr);
305 
306 /**
307  * ps3_read_ctr - Read counter.
308  *
309  * Read 16 or 32 bits depending on the current size of the counter.
310  * Counters 4, 5, 6 & 7 are always 16 bit.
311  */
312 
313 u32 ps3_read_ctr(u32 cpu, u32 ctr)
314 {
315 	u32 val;
316 	u32 phys_ctr = ctr & (NR_PHYS_CTRS - 1);
317 
318 	val = ps3_read_phys_ctr(cpu, phys_ctr);
319 
320 	if (ps3_get_ctr_size(cpu, phys_ctr) == 16)
321 		val = (ctr < NR_PHYS_CTRS) ? (val >> 16) : (val & 0xffff);
322 
323 	return val;
324 }
325 EXPORT_SYMBOL_GPL(ps3_read_ctr);
326 
327 /**
328  * ps3_write_ctr - Write counter.
329  *
330  * Write 16 or 32 bits depending on the current size of the counter.
331  * Counters 4, 5, 6 & 7 are always 16 bit.
332  */
333 
334 void ps3_write_ctr(u32 cpu, u32 ctr, u32 val)
335 {
336 	u32 phys_ctr;
337 	u32 phys_val;
338 
339 	phys_ctr = ctr & (NR_PHYS_CTRS - 1);
340 
341 	if (ps3_get_ctr_size(cpu, phys_ctr) == 16) {
342 		phys_val = ps3_read_phys_ctr(cpu, phys_ctr);
343 
344 		if (ctr < NR_PHYS_CTRS)
345 			val = (val << 16) | (phys_val & 0xffff);
346 		else
347 			val = (val & 0xffff) | (phys_val & 0xffff0000);
348 	}
349 
350 	ps3_write_phys_ctr(cpu, phys_ctr, val);
351 }
352 EXPORT_SYMBOL_GPL(ps3_write_ctr);
353 
354 /**
355  * ps3_read_pm07_control - Read counter control registers.
356  *
357  * Each logical counter has a corresponding control register.
358  */
359 
360 u32 ps3_read_pm07_control(u32 cpu, u32 ctr)
361 {
362 	return 0;
363 }
364 EXPORT_SYMBOL_GPL(ps3_read_pm07_control);
365 
366 /**
367  * ps3_write_pm07_control - Write counter control registers.
368  *
369  * Each logical counter has a corresponding control register.
370  */
371 
372 void ps3_write_pm07_control(u32 cpu, u32 ctr, u32 val)
373 {
374 	int result;
375 	static const u64 mask = 0xFFFFFFFFFFFFFFFFULL;
376 	u64 old_value;
377 
378 	if (ctr >= NR_CTRS) {
379 		dev_dbg(sbd_core(), "%s:%u: ctr too big: %u\n", __func__,
380 			__LINE__, ctr);
381 		return;
382 	}
383 
384 	result = lv1_set_lpm_counter_control(lpm_priv->lpm_id, ctr, val, mask,
385 					     &old_value);
386 	if (result)
387 		dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter_control "
388 			"failed: ctr %u, %s\n", __func__, __LINE__, ctr,
389 			ps3_result(result));
390 }
391 EXPORT_SYMBOL_GPL(ps3_write_pm07_control);
392 
393 /**
394  * ps3_read_pm - Read Other LPM control registers.
395  */
396 
397 u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg)
398 {
399 	int result = 0;
400 	u64 val = 0;
401 
402 	switch (reg) {
403 	case pm_control:
404 		return lpm_priv->shadow.pm_control;
405 	case trace_address:
406 		return CBE_PM_TRACE_BUF_EMPTY;
407 	case pm_start_stop:
408 		return lpm_priv->shadow.pm_start_stop;
409 	case pm_interval:
410 		result = lv1_set_lpm_interval(lpm_priv->lpm_id, 0, 0, &val);
411 		if (result) {
412 			val = 0;
413 			dev_dbg(sbd_core(), "%s:%u: lv1 set_inteval failed: "
414 				"reg %u, %s\n", __func__, __LINE__, reg,
415 				ps3_result(result));
416 		}
417 		return (u32)val;
418 	case group_control:
419 		return lpm_priv->shadow.group_control;
420 	case debug_bus_control:
421 		return lpm_priv->shadow.debug_bus_control;
422 	case pm_status:
423 		result = lv1_get_lpm_interrupt_status(lpm_priv->lpm_id,
424 						      &val);
425 		if (result) {
426 			val = 0;
427 			dev_dbg(sbd_core(), "%s:%u: lv1 get_lpm_status failed: "
428 				"reg %u, %s\n", __func__, __LINE__, reg,
429 				ps3_result(result));
430 		}
431 		return (u32)val;
432 	case ext_tr_timer:
433 		return 0;
434 	default:
435 		dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__,
436 			__LINE__, reg);
437 		BUG();
438 		break;
439 	}
440 
441 	return 0;
442 }
443 EXPORT_SYMBOL_GPL(ps3_read_pm);
444 
445 /**
446  * ps3_write_pm - Write Other LPM control registers.
447  */
448 
449 void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val)
450 {
451 	int result = 0;
452 	u64 dummy;
453 
454 	switch (reg) {
455 	case group_control:
456 		if (val != lpm_priv->shadow.group_control)
457 			result = lv1_set_lpm_group_control(lpm_priv->lpm_id,
458 							   val,
459 							   PS3_WRITE_PM_MASK,
460 							   &dummy);
461 		lpm_priv->shadow.group_control = val;
462 		break;
463 	case debug_bus_control:
464 		if (val != lpm_priv->shadow.debug_bus_control)
465 			result = lv1_set_lpm_debug_bus_control(lpm_priv->lpm_id,
466 							      val,
467 							      PS3_WRITE_PM_MASK,
468 							      &dummy);
469 		lpm_priv->shadow.debug_bus_control = val;
470 		break;
471 	case pm_control:
472 		if (use_start_stop_bookmark)
473 			val |= (PS3_PM_CONTROL_PPU_TH0_BOOKMARK |
474 				PS3_PM_CONTROL_PPU_TH1_BOOKMARK);
475 		if (val != lpm_priv->shadow.pm_control)
476 			result = lv1_set_lpm_general_control(lpm_priv->lpm_id,
477 							     val,
478 							     PS3_WRITE_PM_MASK,
479 							     0, 0, &dummy,
480 							     &dummy);
481 		lpm_priv->shadow.pm_control = val;
482 		break;
483 	case pm_interval:
484 		result = lv1_set_lpm_interval(lpm_priv->lpm_id, val,
485 					      PS3_WRITE_PM_MASK, &dummy);
486 		break;
487 	case pm_start_stop:
488 		if (val != lpm_priv->shadow.pm_start_stop)
489 			result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id,
490 							     val,
491 							     PS3_WRITE_PM_MASK,
492 							     &dummy);
493 		lpm_priv->shadow.pm_start_stop = val;
494 		break;
495 	case trace_address:
496 	case ext_tr_timer:
497 	case pm_status:
498 		break;
499 	default:
500 		dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__,
501 			__LINE__, reg);
502 		BUG();
503 		break;
504 	}
505 
506 	if (result)
507 		dev_err(sbd_core(), "%s:%u: lv1 set_control failed: "
508 			"reg %u, %s\n", __func__, __LINE__, reg,
509 			ps3_result(result));
510 }
511 EXPORT_SYMBOL_GPL(ps3_write_pm);
512 
513 /**
514  * ps3_get_ctr_size - Get the size of a physical counter.
515  *
516  * Returns either 16 or 32.
517  */
518 
519 u32 ps3_get_ctr_size(u32 cpu, u32 phys_ctr)
520 {
521 	u32 pm_ctrl;
522 
523 	if (phys_ctr >= NR_PHYS_CTRS) {
524 		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
525 			__LINE__, phys_ctr);
526 		return 0;
527 	}
528 
529 	pm_ctrl = ps3_read_pm(cpu, pm_control);
530 	return (pm_ctrl & CBE_PM_16BIT_CTR(phys_ctr)) ? 16 : 32;
531 }
532 EXPORT_SYMBOL_GPL(ps3_get_ctr_size);
533 
534 /**
535  * ps3_set_ctr_size - Set the size of a physical counter to 16 or 32 bits.
536  */
537 
538 void ps3_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size)
539 {
540 	u32 pm_ctrl;
541 
542 	if (phys_ctr >= NR_PHYS_CTRS) {
543 		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
544 			__LINE__, phys_ctr);
545 		return;
546 	}
547 
548 	pm_ctrl = ps3_read_pm(cpu, pm_control);
549 
550 	switch (ctr_size) {
551 	case 16:
552 		pm_ctrl |= CBE_PM_16BIT_CTR(phys_ctr);
553 		ps3_write_pm(cpu, pm_control, pm_ctrl);
554 		break;
555 
556 	case 32:
557 		pm_ctrl &= ~CBE_PM_16BIT_CTR(phys_ctr);
558 		ps3_write_pm(cpu, pm_control, pm_ctrl);
559 		break;
560 	default:
561 		BUG();
562 	}
563 }
564 EXPORT_SYMBOL_GPL(ps3_set_ctr_size);
565 
566 static u64 pm_translate_signal_group_number_on_island2(u64 subgroup)
567 {
568 
569 	if (subgroup == 2)
570 		subgroup = 3;
571 
572 	if (subgroup <= 6)
573 		return PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER + subgroup;
574 	else if (subgroup == 7)
575 		return PM_ISLAND2_SIGNAL_GROUP_NUMBER1;
576 	else
577 		return PM_ISLAND2_SIGNAL_GROUP_NUMBER2;
578 }
579 
580 static u64 pm_translate_signal_group_number_on_island3(u64 subgroup)
581 {
582 
583 	switch (subgroup) {
584 	case 2:
585 	case 3:
586 	case 4:
587 		subgroup += 2;
588 		break;
589 	case 5:
590 		subgroup = 8;
591 		break;
592 	default:
593 		break;
594 	}
595 	return PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER + subgroup;
596 }
597 
598 static u64 pm_translate_signal_group_number_on_island4(u64 subgroup)
599 {
600 	return PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER + subgroup;
601 }
602 
603 static u64 pm_translate_signal_group_number_on_island5(u64 subgroup)
604 {
605 
606 	switch (subgroup) {
607 	case 3:
608 		subgroup = 4;
609 		break;
610 	case 4:
611 		subgroup = 6;
612 		break;
613 	default:
614 		break;
615 	}
616 	return PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER + subgroup;
617 }
618 
619 static u64 pm_translate_signal_group_number_on_island6(u64 subgroup,
620 						       u64 subsubgroup)
621 {
622 	switch (subgroup) {
623 	case 3:
624 	case 4:
625 	case 5:
626 		subgroup += 1;
627 		break;
628 	default:
629 		break;
630 	}
631 
632 	switch (subsubgroup) {
633 	case 4:
634 	case 5:
635 	case 6:
636 		subsubgroup += 2;
637 		break;
638 	case 7:
639 	case 8:
640 	case 9:
641 	case 10:
642 		subsubgroup += 4;
643 		break;
644 	case 11:
645 	case 12:
646 	case 13:
647 		subsubgroup += 5;
648 		break;
649 	default:
650 		break;
651 	}
652 
653 	if (subgroup <= 5)
654 		return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup);
655 	else
656 		return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup
657 			+ subsubgroup - 1);
658 }
659 
660 static u64 pm_translate_signal_group_number_on_island7(u64 subgroup)
661 {
662 	return PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER + subgroup;
663 }
664 
665 static u64 pm_translate_signal_group_number_on_island8(u64 subgroup)
666 {
667 	return PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER + subgroup;
668 }
669 
670 static u64 pm_signal_group_to_ps3_lv1_signal_group(u64 group)
671 {
672 	u64 island;
673 	u64 subgroup;
674 	u64 subsubgroup;
675 
676 	subgroup = 0;
677 	subsubgroup = 0;
678 	island = 0;
679 	if (group < 1000) {
680 		if (group < 100) {
681 			if (20 <= group && group < 30) {
682 				island = 2;
683 				subgroup = group - 20;
684 			} else if (30 <= group && group < 40) {
685 				island = 3;
686 				subgroup = group - 30;
687 			} else if (40 <= group && group < 50) {
688 				island = 4;
689 				subgroup = group - 40;
690 			} else if (50 <= group && group < 60) {
691 				island = 5;
692 				subgroup = group - 50;
693 			} else if (60 <= group && group < 70) {
694 				island = 6;
695 				subgroup = group - 60;
696 			} else if (70 <= group && group < 80) {
697 				island = 7;
698 				subgroup = group - 70;
699 			} else if (80 <= group && group < 90) {
700 				island = 8;
701 				subgroup = group - 80;
702 			}
703 		} else if (200 <= group && group < 300) {
704 			island = 2;
705 			subgroup = group - 200;
706 		} else if (600 <= group && group < 700) {
707 			island = 6;
708 			subgroup = 5;
709 			subsubgroup = group - 650;
710 		}
711 	} else if (6000 <= group && group < 7000) {
712 		island = 6;
713 		subgroup = 5;
714 		subsubgroup = group - 6500;
715 	}
716 
717 	switch (island) {
718 	case 2:
719 		return pm_translate_signal_group_number_on_island2(subgroup);
720 	case 3:
721 		return pm_translate_signal_group_number_on_island3(subgroup);
722 	case 4:
723 		return pm_translate_signal_group_number_on_island4(subgroup);
724 	case 5:
725 		return pm_translate_signal_group_number_on_island5(subgroup);
726 	case 6:
727 		return pm_translate_signal_group_number_on_island6(subgroup,
728 								   subsubgroup);
729 	case 7:
730 		return pm_translate_signal_group_number_on_island7(subgroup);
731 	case 8:
732 		return pm_translate_signal_group_number_on_island8(subgroup);
733 	default:
734 		dev_dbg(sbd_core(), "%s:%u: island not found: %lu\n", __func__,
735 			__LINE__, group);
736 		BUG();
737 		break;
738 	}
739 	return 0;
740 }
741 
742 static u64 pm_bus_word_to_ps3_lv1_bus_word(u8 word)
743 {
744 
745 	switch (word) {
746 	case 1:
747 		return 0xF000;
748 	case 2:
749 		return 0x0F00;
750 	case 4:
751 		return 0x00F0;
752 	case 8:
753 	default:
754 		return 0x000F;
755 	}
756 }
757 
758 static int __ps3_set_signal(u64 lv1_signal_group, u64 bus_select,
759 			    u64 signal_select, u64 attr1, u64 attr2, u64 attr3)
760 {
761 	int ret;
762 
763 	ret = lv1_set_lpm_signal(lpm_priv->lpm_id, lv1_signal_group, bus_select,
764 				 signal_select, attr1, attr2, attr3);
765 	if (ret)
766 		dev_err(sbd_core(),
767 			"%s:%u: error:%d 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
768 			__func__, __LINE__, ret, lv1_signal_group, bus_select,
769 			signal_select, attr1, attr2, attr3);
770 
771 	return ret;
772 }
773 
774 int ps3_set_signal(u64 signal_group, u8 signal_bit, u16 sub_unit,
775 		   u8 bus_word)
776 {
777 	int ret;
778 	u64 lv1_signal_group;
779 	u64 bus_select;
780 	u64 signal_select;
781 	u64 attr1, attr2, attr3;
782 
783 	if (signal_group == 0)
784 		return __ps3_set_signal(0, 0, 0, 0, 0, 0);
785 
786 	lv1_signal_group =
787 		pm_signal_group_to_ps3_lv1_signal_group(signal_group);
788 	bus_select = pm_bus_word_to_ps3_lv1_bus_word(bus_word);
789 
790 	switch (signal_group) {
791 	case PM_SIG_GROUP_SPU_TRIGGER:
792 		signal_select = 1;
793 		signal_select = signal_select << (63 - signal_bit);
794 		break;
795 	case PM_SIG_GROUP_SPU_EVENT:
796 		signal_select = 1;
797 		signal_select = (signal_select << (63 - signal_bit)) | 0x3;
798 		break;
799 	default:
800 		signal_select = 0;
801 		break;
802 	}
803 
804 	/*
805 	 * 0: physical object.
806 	 * 1: logical object.
807 	 * This parameter is only used for the PPE and SPE signals.
808 	 */
809 	attr1 = 1;
810 
811 	/*
812 	 * This parameter is used to specify the target physical/logical
813 	 * PPE/SPE object.
814 	 */
815 	if (PM_SIG_GROUP_SPU <= signal_group &&
816 		signal_group < PM_SIG_GROUP_MFC_MAX)
817 		attr2 = sub_unit;
818 	else
819 		attr2 = lpm_priv->pu_id;
820 
821 	/*
822 	 * This parameter is only used for setting the SPE signal.
823 	 */
824 	attr3 = 0;
825 
826 	ret = __ps3_set_signal(lv1_signal_group, bus_select, signal_select,
827 			       attr1, attr2, attr3);
828 	if (ret)
829 		dev_err(sbd_core(), "%s:%u: __ps3_set_signal failed: %d\n",
830 			__func__, __LINE__, ret);
831 
832 	return ret;
833 }
834 EXPORT_SYMBOL_GPL(ps3_set_signal);
835 
836 u32 ps3_get_hw_thread_id(int cpu)
837 {
838 	return get_hard_smp_processor_id(cpu);
839 }
840 EXPORT_SYMBOL_GPL(ps3_get_hw_thread_id);
841 
842 /**
843  * ps3_enable_pm - Enable the entire performance monitoring unit.
844  *
845  * When we enable the LPM, all pending writes to counters get committed.
846  */
847 
848 void ps3_enable_pm(u32 cpu)
849 {
850 	int result;
851 	u64 tmp;
852 	int insert_bookmark = 0;
853 
854 	lpm_priv->tb_count = 0;
855 
856 	if (use_start_stop_bookmark) {
857 		if (!(lpm_priv->shadow.pm_start_stop &
858 			(PS3_PM_START_STOP_START_MASK
859 			| PS3_PM_START_STOP_STOP_MASK))) {
860 			result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id,
861 				(PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START |
862 				PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START |
863 				PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP |
864 				PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP),
865 				0xFFFFFFFFFFFFFFFFULL, &tmp);
866 
867 			if (result)
868 				dev_err(sbd_core(), "%s:%u: "
869 					"lv1_set_lpm_trigger_control failed: "
870 					"%s\n", __func__, __LINE__,
871 					ps3_result(result));
872 
873 			insert_bookmark = !result;
874 		}
875 	}
876 
877 	result = lv1_start_lpm(lpm_priv->lpm_id);
878 
879 	if (result)
880 		dev_err(sbd_core(), "%s:%u: lv1_start_lpm failed: %s\n",
881 			__func__, __LINE__, ps3_result(result));
882 
883 	if (use_start_stop_bookmark && !result && insert_bookmark)
884 		ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_START);
885 }
886 EXPORT_SYMBOL_GPL(ps3_enable_pm);
887 
888 /**
889  * ps3_disable_pm - Disable the entire performance monitoring unit.
890  */
891 
892 void ps3_disable_pm(u32 cpu)
893 {
894 	int result;
895 	u64 tmp;
896 
897 	ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_STOP);
898 
899 	result = lv1_stop_lpm(lpm_priv->lpm_id, &tmp);
900 
901 	if (result) {
902 		if(result != LV1_WRONG_STATE)
903 			dev_err(sbd_core(), "%s:%u: lv1_stop_lpm failed: %s\n",
904 				__func__, __LINE__, ps3_result(result));
905 		return;
906 	}
907 
908 	lpm_priv->tb_count = tmp;
909 
910 	dev_dbg(sbd_core(), "%s:%u: tb_count %lu (%lxh)\n", __func__, __LINE__,
911 		lpm_priv->tb_count, lpm_priv->tb_count);
912 }
913 EXPORT_SYMBOL_GPL(ps3_disable_pm);
914 
915 /**
916  * ps3_lpm_copy_tb - Copy data from the trace buffer to a kernel buffer.
917  * @offset: Offset in bytes from the start of the trace buffer.
918  * @buf: Copy destination.
919  * @count: Maximum count of bytes to copy.
920  * @bytes_copied: Pointer to a variable that will recieve the number of
921  *  bytes copied to @buf.
922  *
923  * On error @buf will contain any successfully copied trace buffer data
924  * and bytes_copied will be set to the number of bytes successfully copied.
925  */
926 
927 int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count,
928 		    unsigned long *bytes_copied)
929 {
930 	int result;
931 
932 	*bytes_copied = 0;
933 
934 	if (!lpm_priv->tb_cache)
935 		return -EPERM;
936 
937 	if (offset >= lpm_priv->tb_count)
938 		return 0;
939 
940 	count = min(count, lpm_priv->tb_count - offset);
941 
942 	while (*bytes_copied < count) {
943 		const unsigned long request = count - *bytes_copied;
944 		u64 tmp;
945 
946 		result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset,
947 						   request, &tmp);
948 		if (result) {
949 			dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n",
950 				__func__, __LINE__, request, offset);
951 
952 			dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer "
953 				"failed: %s\n", __func__, __LINE__,
954 				ps3_result(result));
955 			return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL;
956 		}
957 
958 		memcpy(buf, lpm_priv->tb_cache, tmp);
959 		buf += tmp;
960 		*bytes_copied += tmp;
961 		offset += tmp;
962 	}
963 	dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__,
964 		*bytes_copied);
965 
966 	return 0;
967 }
968 EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb);
969 
970 /**
971  * ps3_lpm_copy_tb_to_user - Copy data from the trace buffer to a user buffer.
972  * @offset: Offset in bytes from the start of the trace buffer.
973  * @buf: A __user copy destination.
974  * @count: Maximum count of bytes to copy.
975  * @bytes_copied: Pointer to a variable that will recieve the number of
976  *  bytes copied to @buf.
977  *
978  * On error @buf will contain any successfully copied trace buffer data
979  * and bytes_copied will be set to the number of bytes successfully copied.
980  */
981 
982 int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf,
983 			    unsigned long count, unsigned long *bytes_copied)
984 {
985 	int result;
986 
987 	*bytes_copied = 0;
988 
989 	if (!lpm_priv->tb_cache)
990 		return -EPERM;
991 
992 	if (offset >= lpm_priv->tb_count)
993 		return 0;
994 
995 	count = min(count, lpm_priv->tb_count - offset);
996 
997 	while (*bytes_copied < count) {
998 		const unsigned long request = count - *bytes_copied;
999 		u64 tmp;
1000 
1001 		result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset,
1002 						   request, &tmp);
1003 		if (result) {
1004 			dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n",
1005 				__func__, __LINE__, request, offset);
1006 			dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer "
1007 				"failed: %s\n", __func__, __LINE__,
1008 				ps3_result(result));
1009 			return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL;
1010 		}
1011 
1012 		result = copy_to_user(buf, lpm_priv->tb_cache, tmp);
1013 
1014 		if (result) {
1015 			dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%p\n",
1016 				__func__, __LINE__, tmp, buf);
1017 			dev_err(sbd_core(), "%s:%u: copy_to_user failed: %d\n",
1018 				__func__, __LINE__, result);
1019 			return -EFAULT;
1020 		}
1021 
1022 		buf += tmp;
1023 		*bytes_copied += tmp;
1024 		offset += tmp;
1025 	}
1026 	dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__,
1027 		*bytes_copied);
1028 
1029 	return 0;
1030 }
1031 EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb_to_user);
1032 
1033 /**
1034  * ps3_get_and_clear_pm_interrupts -
1035  *
1036  * Clearing interrupts for the entire performance monitoring unit.
1037  * Reading pm_status clears the interrupt bits.
1038  */
1039 
1040 u32 ps3_get_and_clear_pm_interrupts(u32 cpu)
1041 {
1042 	return ps3_read_pm(cpu, pm_status);
1043 }
1044 EXPORT_SYMBOL_GPL(ps3_get_and_clear_pm_interrupts);
1045 
1046 /**
1047  * ps3_enable_pm_interrupts -
1048  *
1049  * Enabling interrupts for the entire performance monitoring unit.
1050  * Enables the interrupt bits in the pm_status register.
1051  */
1052 
1053 void ps3_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask)
1054 {
1055 	if (mask)
1056 		ps3_write_pm(cpu, pm_status, mask);
1057 }
1058 EXPORT_SYMBOL_GPL(ps3_enable_pm_interrupts);
1059 
1060 /**
1061  * ps3_enable_pm_interrupts -
1062  *
1063  * Disabling interrupts for the entire performance monitoring unit.
1064  */
1065 
1066 void ps3_disable_pm_interrupts(u32 cpu)
1067 {
1068 	ps3_get_and_clear_pm_interrupts(cpu);
1069 	ps3_write_pm(cpu, pm_status, 0);
1070 }
1071 EXPORT_SYMBOL_GPL(ps3_disable_pm_interrupts);
1072 
1073 /**
1074  * ps3_lpm_open - Open the logical performance monitor device.
1075  * @tb_type: Specifies the type of trace buffer lv1 sould use for this lpm
1076  *  instance, specified by one of enum ps3_lpm_tb_type.
1077  * @tb_cache: Optional user supplied buffer to use as the trace buffer cache.
1078  *  If NULL, the driver will allocate and manage an internal buffer.
1079  *  Unused when when @tb_type is PS3_LPM_TB_TYPE_NONE.
1080  * @tb_cache_size: The size in bytes of the user supplied @tb_cache buffer.
1081  *  Unused when @tb_cache is NULL or @tb_type is PS3_LPM_TB_TYPE_NONE.
1082  */
1083 
1084 int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
1085 	u64 tb_cache_size)
1086 {
1087 	int result;
1088 	u64 tb_size;
1089 
1090 	BUG_ON(!lpm_priv);
1091 	BUG_ON(tb_type != PS3_LPM_TB_TYPE_NONE
1092 		&& tb_type != PS3_LPM_TB_TYPE_INTERNAL);
1093 
1094 	if (tb_type == PS3_LPM_TB_TYPE_NONE && tb_cache)
1095 		dev_dbg(sbd_core(), "%s:%u: bad in vals\n", __func__, __LINE__);
1096 
1097 	if (!atomic_add_unless(&lpm_priv->open, 1, 1)) {
1098 		dev_dbg(sbd_core(), "%s:%u: busy\n", __func__, __LINE__);
1099 		return -EBUSY;
1100 	}
1101 
1102 	/* Note tb_cache needs 128 byte alignment. */
1103 
1104 	if (tb_type == PS3_LPM_TB_TYPE_NONE) {
1105 		lpm_priv->tb_cache_size = 0;
1106 		lpm_priv->tb_cache_internal = NULL;
1107 		lpm_priv->tb_cache = NULL;
1108 	} else if (tb_cache) {
1109 		if (tb_cache != (void *)_ALIGN_UP((unsigned long)tb_cache, 128)
1110 			|| tb_cache_size != _ALIGN_UP(tb_cache_size, 128)) {
1111 			dev_err(sbd_core(), "%s:%u: unaligned tb_cache\n",
1112 				__func__, __LINE__);
1113 			result = -EINVAL;
1114 			goto fail_align;
1115 		}
1116 		lpm_priv->tb_cache_size = tb_cache_size;
1117 		lpm_priv->tb_cache_internal = NULL;
1118 		lpm_priv->tb_cache = tb_cache;
1119 	} else {
1120 		lpm_priv->tb_cache_size = PS3_LPM_DEFAULT_TB_CACHE_SIZE;
1121 		lpm_priv->tb_cache_internal = kzalloc(
1122 			lpm_priv->tb_cache_size + 127, GFP_KERNEL);
1123 		if (!lpm_priv->tb_cache_internal) {
1124 			dev_err(sbd_core(), "%s:%u: alloc internal tb_cache "
1125 				"failed\n", __func__, __LINE__);
1126 			result = -ENOMEM;
1127 			goto fail_malloc;
1128 		}
1129 		lpm_priv->tb_cache = (void *)_ALIGN_UP(
1130 			(unsigned long)lpm_priv->tb_cache_internal, 128);
1131 	}
1132 
1133 	result = lv1_construct_lpm(lpm_priv->node_id, tb_type, 0, 0,
1134 				ps3_mm_phys_to_lpar(__pa(lpm_priv->tb_cache)),
1135 				lpm_priv->tb_cache_size, &lpm_priv->lpm_id,
1136 				&lpm_priv->outlet_id, &tb_size);
1137 
1138 	if (result) {
1139 		dev_err(sbd_core(), "%s:%u: lv1_construct_lpm failed: %s\n",
1140 			__func__, __LINE__, ps3_result(result));
1141 		result = -EINVAL;
1142 		goto fail_construct;
1143 	}
1144 
1145 	lpm_priv->shadow.pm_control = PS3_LPM_SHADOW_REG_INIT;
1146 	lpm_priv->shadow.pm_start_stop = PS3_LPM_SHADOW_REG_INIT;
1147 	lpm_priv->shadow.group_control = PS3_LPM_SHADOW_REG_INIT;
1148 	lpm_priv->shadow.debug_bus_control = PS3_LPM_SHADOW_REG_INIT;
1149 
1150 	dev_dbg(sbd_core(), "%s:%u: lpm_id 0x%lx, outlet_id 0x%lx, "
1151 		"tb_size 0x%lx\n", __func__, __LINE__, lpm_priv->lpm_id,
1152 		lpm_priv->outlet_id, tb_size);
1153 
1154 	return 0;
1155 
1156 fail_construct:
1157 	kfree(lpm_priv->tb_cache_internal);
1158 	lpm_priv->tb_cache_internal = NULL;
1159 fail_malloc:
1160 fail_align:
1161 	atomic_dec(&lpm_priv->open);
1162 	return result;
1163 }
1164 EXPORT_SYMBOL_GPL(ps3_lpm_open);
1165 
1166 /**
1167  * ps3_lpm_close - Close the lpm device.
1168  *
1169  */
1170 
1171 int ps3_lpm_close(void)
1172 {
1173 	dev_dbg(sbd_core(), "%s:%u\n", __func__, __LINE__);
1174 
1175 	lv1_destruct_lpm(lpm_priv->lpm_id);
1176 	lpm_priv->lpm_id = 0;
1177 
1178 	kfree(lpm_priv->tb_cache_internal);
1179 	lpm_priv->tb_cache_internal = NULL;
1180 
1181 	atomic_dec(&lpm_priv->open);
1182 	return 0;
1183 }
1184 EXPORT_SYMBOL_GPL(ps3_lpm_close);
1185 
1186 static int __devinit ps3_lpm_probe(struct ps3_system_bus_device *dev)
1187 {
1188 	dev_dbg(&dev->core, " -> %s:%u\n", __func__, __LINE__);
1189 
1190 	if (lpm_priv) {
1191 		dev_info(&dev->core, "%s:%u: called twice\n",
1192 			__func__, __LINE__);
1193 		return -EBUSY;
1194 	}
1195 
1196 	lpm_priv = kzalloc(sizeof(*lpm_priv), GFP_KERNEL);
1197 
1198 	if (!lpm_priv)
1199 		return -ENOMEM;
1200 
1201 	lpm_priv->sbd = dev;
1202 	lpm_priv->node_id = dev->lpm.node_id;
1203 	lpm_priv->pu_id = dev->lpm.pu_id;
1204 	lpm_priv->rights = dev->lpm.rights;
1205 
1206 	dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__);
1207 
1208 	return 0;
1209 }
1210 
1211 static int ps3_lpm_remove(struct ps3_system_bus_device *dev)
1212 {
1213 	dev_dbg(&dev->core, " -> %s:%u:\n", __func__, __LINE__);
1214 
1215 	ps3_lpm_close();
1216 
1217 	kfree(lpm_priv);
1218 	lpm_priv = NULL;
1219 
1220 	dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__);
1221 	return 0;
1222 }
1223 
1224 static struct ps3_system_bus_driver ps3_lpm_driver = {
1225 	.match_id = PS3_MATCH_ID_LPM,
1226 	.core.name	= "ps3-lpm",
1227 	.core.owner	= THIS_MODULE,
1228 	.probe		= ps3_lpm_probe,
1229 	.remove		= ps3_lpm_remove,
1230 	.shutdown	= ps3_lpm_remove,
1231 };
1232 
1233 static int __init ps3_lpm_init(void)
1234 {
1235 	pr_debug("%s:%d:\n", __func__, __LINE__);
1236 	return ps3_system_bus_driver_register(&ps3_lpm_driver);
1237 }
1238 
1239 static void __exit ps3_lpm_exit(void)
1240 {
1241 	pr_debug("%s:%d:\n", __func__, __LINE__);
1242 	ps3_system_bus_driver_unregister(&ps3_lpm_driver);
1243 }
1244 
1245 module_init(ps3_lpm_init);
1246 module_exit(ps3_lpm_exit);
1247 
1248 MODULE_LICENSE("GPL v2");
1249 MODULE_DESCRIPTION("PS3 Logical Performance Monitor Driver");
1250 MODULE_AUTHOR("Sony Corporation");
1251 MODULE_ALIAS(PS3_MODULE_ALIAS_LPM);
1252