tizen 2.4 release
[kernel/linux-3.0.git] / drivers / gpu / arm / mali400 / mali / linux / mali_kernel_sysfs.c
1 /*
2  * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
3  *
4  * This program is free software and is provided to you under the terms of the GNU General Public License version 2
5  * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
6  *
7  * A copy of the licence is included with the program, and can also be obtained from Free Software
8  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
9  */
10
11 /**
12  * @file mali_kernel_sysfs.c
13  * Implementation of some sysfs data exports
14  */
15
16 #include <linux/kernel.h>
17 #include <linux/fs.h>
18 #include <linux/device.h>
19 #include <linux/module.h>
20 #include "mali_kernel_license.h"
21 #include "mali_kernel_common.h"
22 #include "mali_ukk.h"
23
24 #if MALI_LICENSE_IS_GPL
25
26 #include <linux/seq_file.h>
27 #include <linux/debugfs.h>
28 #include <asm/uaccess.h>
29 #include <linux/module.h>
30 #include "mali_kernel_sysfs.h"
31 #if defined(CONFIG_MALI400_INTERNAL_PROFILING)
32 #include <linux/slab.h>
33 #include "mali_osk_profiling.h"
34 #endif
35 #include "mali_pm.h"
36 #include "mali_group.h"
37 #include "mali_gp.h"
38 #include "mali_pp.h"
39 #include "mali_l2_cache.h"
40 #include "mali_hw_core.h"
41 #include "mali_kernel_core.h"
42 #include "mali_user_settings_db.h"
43 #include "mali_device_pause_resume.h"
44 #include "mali_profiling_internal.h"
45 #include "mali_gp_job.h"
46 #include "mali_pp_job.h"
47
48 #define POWER_BUFFER_SIZE 3
49
50 static struct dentry *mali_debugfs_dir = NULL;
51
52 typedef enum
53 {
54         _MALI_DEVICE_SUSPEND,
55         _MALI_DEVICE_RESUME,
56         _MALI_DEVICE_DVFS_PAUSE,
57         _MALI_DEVICE_DVFS_RESUME,
58         _MALI_MAX_EVENTS
59 } _mali_device_debug_power_events;
60
61 static const char* const mali_power_events[_MALI_MAX_EVENTS] = {
62         [_MALI_DEVICE_SUSPEND] = "suspend",
63         [_MALI_DEVICE_RESUME] = "resume",
64         [_MALI_DEVICE_DVFS_PAUSE] = "dvfs_pause",
65         [_MALI_DEVICE_DVFS_RESUME] = "dvfs_resume",
66 };
67
68 static u32 virtual_power_status_register = 0;
69 static char pwr_buf[POWER_BUFFER_SIZE];
70
71 static mali_bool power_always_on_enabled = MALI_FALSE;
72
73 static int open_copy_private_data(struct inode *inode, struct file *filp)
74 {
75         filp->private_data = inode->i_private;
76         return 0;
77 }
78
79 static ssize_t gp_gpx_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id)
80 {
81         char buf[64];
82         int r;
83         u32 val;
84
85         if (0 == src_id)
86         {
87                 val = mali_gp_job_get_gp_counter_src0();
88         }
89         else
90         {
91                 val = mali_gp_job_get_gp_counter_src1();
92         }
93
94         if (MALI_HW_CORE_NO_COUNTER == val)
95         {
96                 r = sprintf(buf, "-1\n");
97         }
98         else
99         {
100                 r = sprintf(buf, "%u\n", val);
101         }
102         return simple_read_from_buffer(ubuf, cnt, gpos, buf, r);
103 }
104
105 static ssize_t gp_gpx_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id)
106 {
107         char buf[64];
108         long val;
109         int ret;
110
111         if (cnt >= sizeof(buf))
112         {
113                 return -EINVAL;
114         }
115
116         if (copy_from_user(&buf, ubuf, cnt))
117         {
118                 return -EFAULT;
119         }
120
121         buf[cnt] = 0;
122
123         ret = strict_strtol(buf, 10, &val);
124         if (ret < 0)
125         {
126                 return ret;
127         }
128
129         if (val < 0)
130         {
131                 /* any negative input will disable counter */
132                 val = MALI_HW_CORE_NO_COUNTER;
133         }
134
135         if (0 == src_id)
136         {
137                 if (MALI_TRUE != mali_gp_job_set_gp_counter_src0((u32)val))
138                 {
139                         return 0;
140                 }
141         }
142         else
143         {
144                 if (MALI_TRUE != mali_gp_job_set_gp_counter_src1((u32)val))
145                 {
146                         return 0;
147                 }
148         }
149
150         *gpos += cnt;
151         return cnt;
152 }
153
154 static ssize_t gp_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id)
155 {
156         char buf[64];
157         long val;
158         int ret;
159         u32 num_groups;
160         int i;
161
162         if (cnt >= sizeof(buf))
163         {
164                 return -EINVAL;
165         }
166
167         if (copy_from_user(&buf, ubuf, cnt))
168         {
169                 return -EFAULT;
170         }
171
172         buf[cnt] = 0;
173
174         ret = strict_strtol(buf, 10, &val);
175         if (ret < 0)
176         {
177                 return ret;
178         }
179
180         if (val < 0)
181         {
182                 /* any negative input will disable counter */
183                 val = MALI_HW_CORE_NO_COUNTER;
184         }
185
186         num_groups = mali_group_get_glob_num_groups();
187         for (i = 0; i < num_groups; i++)
188         {
189                 struct mali_group *group = mali_group_get_glob_group(i);
190
191                 struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
192                 if (NULL != gp_core)
193                 {
194                         if (0 == src_id)
195                         {
196                                 if (MALI_TRUE != mali_gp_job_set_gp_counter_src0((u32)val))
197                                 {
198                                         return 0;
199                                 }
200                         }
201                         else
202                         {
203                                 if (MALI_TRUE != mali_gp_job_set_gp_counter_src1((u32)val))
204                                 {
205                                         return 0;
206                                 }
207                         }
208                 }
209         }
210
211         *gpos += cnt;
212         return cnt;
213 }
214
215 static ssize_t gp_gpx_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos)
216 {
217         return gp_gpx_counter_srcx_read(filp, ubuf, cnt, gpos, 0);
218 }
219
220 static ssize_t gp_gpx_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos)
221 {
222         return gp_gpx_counter_srcx_read(filp, ubuf, cnt, gpos, 1);
223 }
224
225 static ssize_t gp_gpx_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos)
226 {
227         return gp_gpx_counter_srcx_write(filp, ubuf, cnt, gpos, 0);
228 }
229
230 static ssize_t gp_gpx_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos)
231 {
232         return gp_gpx_counter_srcx_write(filp, ubuf, cnt, gpos, 1);
233 }
234
235 static ssize_t gp_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos)
236 {
237         return gp_all_counter_srcx_write(filp, ubuf, cnt, gpos, 0);
238 }
239
240 static ssize_t gp_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos)
241 {
242         return gp_all_counter_srcx_write(filp, ubuf, cnt, gpos, 1);
243 }
244
245 static const struct file_operations gp_gpx_counter_src0_fops = {
246         .owner = THIS_MODULE,
247         .open  = open_copy_private_data,
248         .read  = gp_gpx_counter_src0_read,
249         .write = gp_gpx_counter_src0_write,
250 };
251
252 static const struct file_operations gp_gpx_counter_src1_fops = {
253         .owner = THIS_MODULE,
254         .open  = open_copy_private_data,
255         .read  = gp_gpx_counter_src1_read,
256         .write = gp_gpx_counter_src1_write,
257 };
258
259 static const struct file_operations gp_all_counter_src0_fops = {
260         .owner = THIS_MODULE,
261         .write = gp_all_counter_src0_write,
262 };
263
264 static const struct file_operations gp_all_counter_src1_fops = {
265         .owner = THIS_MODULE,
266         .write = gp_all_counter_src1_write,
267 };
268
269 static ssize_t pp_ppx_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
270 {
271         char buf[64];
272         int r;
273         u32 val;
274
275         if (0 == src_id)
276         {
277                 val = mali_pp_job_get_pp_counter_src0();
278         }
279         else
280         {
281                 val = mali_pp_job_get_pp_counter_src1();
282         }
283
284         if (MALI_HW_CORE_NO_COUNTER == val)
285         {
286                 r = sprintf(buf, "-1\n");
287         }
288         else
289         {
290                 r = sprintf(buf, "%u\n", val);
291         }
292         return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
293 }
294
295 static ssize_t pp_ppx_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
296 {
297         char buf[64];
298         long val;
299         int ret;
300
301         if (cnt >= sizeof(buf))
302         {
303                 return -EINVAL;
304         }
305
306         if (copy_from_user(&buf, ubuf, cnt))
307         {
308                 return -EFAULT;
309         }
310
311         buf[cnt] = 0;
312
313         ret = strict_strtol(buf, 10, &val);
314         if (ret < 0)
315         {
316                 return ret;
317         }
318
319         if (val < 0)
320         {
321                 /* any negative input will disable counter */
322                 val = MALI_HW_CORE_NO_COUNTER;
323         }
324
325         if (0 == src_id)
326         {
327                 if (MALI_TRUE != mali_pp_job_set_pp_counter_src0((u32)val))
328                 {
329                         return 0;
330                 }
331         }
332         else
333         {
334                 if (MALI_TRUE != mali_pp_job_set_pp_counter_src1((u32)val))
335                 {
336                         return 0;
337                 }
338         }
339
340         *ppos += cnt;
341         return cnt;
342 }
343
344 static ssize_t pp_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
345 {
346         char buf[64];
347         long val;
348         int ret;
349         u32 num_groups;
350         int i;
351
352         if (cnt >= sizeof(buf))
353         {
354                 return -EINVAL;
355         }
356
357         if (copy_from_user(&buf, ubuf, cnt))
358         {
359                 return -EFAULT;
360         }
361
362         buf[cnt] = 0;
363
364         ret = strict_strtol(buf, 10, &val);
365         if (ret < 0)
366         {
367                 return ret;
368         }
369
370         if (val < 0)
371         {
372                 /* any negative input will disable counter */
373                 val = MALI_HW_CORE_NO_COUNTER;
374         }
375
376         num_groups = mali_group_get_glob_num_groups();
377         for (i = 0; i < num_groups; i++)
378         {
379                 struct mali_group *group = mali_group_get_glob_group(i);
380
381                 struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
382                 if (NULL != pp_core)
383                 {
384                         if (0 == src_id)
385                         {
386                                 if (MALI_TRUE != mali_pp_job_set_pp_counter_src0((u32)val))
387                                 {
388                                         return 0;
389                                 }
390                         }
391                         else
392                         {
393                                 if (MALI_TRUE != mali_pp_job_set_pp_counter_src1((u32)val))
394                                 {
395                                         return 0;
396                                 }
397                         }
398                 }
399         }
400
401         *ppos += cnt;
402         return cnt;
403 }
404
405 static ssize_t pp_ppx_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
406 {
407         return pp_ppx_counter_srcx_read(filp, ubuf, cnt, ppos, 0);
408 }
409
410 static ssize_t pp_ppx_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
411 {
412         return pp_ppx_counter_srcx_read(filp, ubuf, cnt, ppos, 1);
413 }
414
415 static ssize_t pp_ppx_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
416 {
417         return pp_ppx_counter_srcx_write(filp, ubuf, cnt, ppos, 0);
418 }
419
420 static ssize_t pp_ppx_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
421 {
422         return pp_ppx_counter_srcx_write(filp, ubuf, cnt, ppos, 1);
423 }
424
425 static ssize_t pp_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
426 {
427         return pp_all_counter_srcx_write(filp, ubuf, cnt, ppos, 0);
428 }
429
430 static ssize_t pp_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
431 {
432         return pp_all_counter_srcx_write(filp, ubuf, cnt, ppos, 1);
433 }
434
435 static const struct file_operations pp_ppx_counter_src0_fops = {
436         .owner = THIS_MODULE,
437         .open  = open_copy_private_data,
438         .read  = pp_ppx_counter_src0_read,
439         .write = pp_ppx_counter_src0_write,
440 };
441
442 static const struct file_operations pp_ppx_counter_src1_fops = {
443         .owner = THIS_MODULE,
444         .open  = open_copy_private_data,
445         .read  = pp_ppx_counter_src1_read,
446         .write = pp_ppx_counter_src1_write,
447 };
448
449 static const struct file_operations pp_all_counter_src0_fops = {
450         .owner = THIS_MODULE,
451         .write = pp_all_counter_src0_write,
452 };
453
454 static const struct file_operations pp_all_counter_src1_fops = {
455         .owner = THIS_MODULE,
456         .write = pp_all_counter_src1_write,
457 };
458
459 static ssize_t l2_l2x_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
460 {
461         char buf[64];
462         int r;
463         u32 val;
464         struct mali_l2_cache_core *l2_core = (struct mali_l2_cache_core *)filp->private_data;
465
466         if (0 == src_id)
467         {
468                 val = mali_l2_cache_core_get_counter_src0(l2_core);
469         }
470         else
471         {
472                 val = mali_l2_cache_core_get_counter_src1(l2_core);
473         }
474
475         if (MALI_HW_CORE_NO_COUNTER == val)
476         {
477                 r = sprintf(buf, "-1\n");
478         }
479         else
480         {
481                 r = sprintf(buf, "%u\n", val);
482         }
483         return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
484 }
485
486 static ssize_t l2_l2x_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
487 {
488         struct mali_l2_cache_core *l2_core = (struct mali_l2_cache_core *)filp->private_data;
489         char buf[64];
490         long val;
491         int ret;
492
493         if (cnt >= sizeof(buf))
494         {
495                 return -EINVAL;
496         }
497
498         if (copy_from_user(&buf, ubuf, cnt))
499         {
500                 return -EFAULT;
501         }
502
503         buf[cnt] = 0;
504
505         ret = strict_strtol(buf, 10, &val);
506         if (ret < 0)
507         {
508                 return ret;
509         }
510
511         if (val < 0)
512         {
513                 /* any negative input will disable counter */
514                 val = MALI_HW_CORE_NO_COUNTER;
515         }
516
517         if (0 == src_id)
518         {
519                 if (MALI_TRUE != mali_l2_cache_core_set_counter_src0(l2_core, (u32)val))
520                 {
521                         return 0;
522                 }
523         }
524         else
525         {
526                 if (MALI_TRUE != mali_l2_cache_core_set_counter_src1(l2_core, (u32)val))
527                 {
528                         return 0;
529                 }
530         }
531
532         *ppos += cnt;
533         return cnt;
534 }
535
536 static ssize_t l2_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
537 {
538         char buf[64];
539         long val;
540         int ret;
541         u32 l2_id;
542         struct mali_l2_cache_core *l2_cache;
543
544         if (cnt >= sizeof(buf))
545         {
546                 return -EINVAL;
547         }
548
549         if (copy_from_user(&buf, ubuf, cnt))
550         {
551                 return -EFAULT;
552         }
553
554         buf[cnt] = 0;
555
556         ret = strict_strtol(buf, 10, &val);
557         if (ret < 0)
558         {
559                 return ret;
560         }
561
562         if (val < 0)
563         {
564                 /* any negative input will disable counter */
565                 val = MALI_HW_CORE_NO_COUNTER;
566         }
567
568         l2_id = 0;
569         l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
570         while (NULL != l2_cache)
571         {
572                 if (0 == src_id)
573                 {
574                         if (MALI_TRUE != mali_l2_cache_core_set_counter_src0(l2_cache, (u32)val))
575                         {
576                                 return 0;
577                         }
578                 }
579                 else
580                 {
581                         if (MALI_TRUE != mali_l2_cache_core_set_counter_src1(l2_cache, (u32)val))
582                         {
583                                 return 0;
584                         }
585                 }
586
587                 /* try next L2 */
588                 l2_id++;
589                 l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
590         }
591
592         *ppos += cnt;
593         return cnt;
594 }
595
596 static ssize_t l2_l2x_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
597 {
598         return l2_l2x_counter_srcx_read(filp, ubuf, cnt, ppos, 0);
599 }
600
601 static ssize_t l2_l2x_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
602 {
603         return l2_l2x_counter_srcx_read(filp, ubuf, cnt, ppos, 1);
604 }
605
606 static ssize_t l2_l2x_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
607 {
608         return l2_l2x_counter_srcx_write(filp, ubuf, cnt, ppos, 0);
609 }
610
611 static ssize_t l2_l2x_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
612 {
613         return l2_l2x_counter_srcx_write(filp, ubuf, cnt, ppos, 1);
614 }
615
616 static ssize_t l2_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
617 {
618         return l2_all_counter_srcx_write(filp, ubuf, cnt, ppos, 0);
619 }
620
621 static ssize_t l2_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
622 {
623         return l2_all_counter_srcx_write(filp, ubuf, cnt, ppos, 1);
624 }
625
626 static const struct file_operations l2_l2x_counter_src0_fops = {
627         .owner = THIS_MODULE,
628         .open  = open_copy_private_data,
629         .read  = l2_l2x_counter_src0_read,
630         .write = l2_l2x_counter_src0_write,
631 };
632
633 static const struct file_operations l2_l2x_counter_src1_fops = {
634         .owner = THIS_MODULE,
635         .open  = open_copy_private_data,
636         .read  = l2_l2x_counter_src1_read,
637         .write = l2_l2x_counter_src1_write,
638 };
639
640 static const struct file_operations l2_all_counter_src0_fops = {
641         .owner = THIS_MODULE,
642         .write = l2_all_counter_src0_write,
643 };
644
645 static const struct file_operations l2_all_counter_src1_fops = {
646         .owner = THIS_MODULE,
647         .write = l2_all_counter_src1_write,
648 };
649
650 static ssize_t power_always_on_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
651 {
652         unsigned long val;
653         int ret;
654         char buf[32];
655
656         cnt = min(cnt, sizeof(buf) - 1);
657         if (copy_from_user(buf, ubuf, cnt))
658         {
659                 return -EFAULT;
660         }
661         buf[cnt] = '\0';
662
663         ret = strict_strtoul(buf, 10, &val);
664         if (0 != ret)
665         {
666                 return ret;
667         }
668
669         /* Update setting (not exactly thread safe) */
670         if (1 == val && MALI_FALSE == power_always_on_enabled)
671         {
672                 power_always_on_enabled = MALI_TRUE;
673                 _mali_osk_pm_dev_ref_add();
674         }
675         else if (0 == val && MALI_TRUE == power_always_on_enabled)
676         {
677                 power_always_on_enabled = MALI_FALSE;
678                 _mali_osk_pm_dev_ref_dec();
679         }
680
681         *ppos += cnt;
682         return cnt;
683 }
684
685 static ssize_t power_always_on_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
686 {
687         if (MALI_TRUE == power_always_on_enabled)
688         {
689                 return simple_read_from_buffer(ubuf, cnt, ppos, "1\n", 2);
690         }
691         else
692         {
693                 return simple_read_from_buffer(ubuf, cnt, ppos, "0\n", 2);
694         }
695 }
696
697 static const struct file_operations power_always_on_fops = {
698         .owner = THIS_MODULE,
699         .read  = power_always_on_read,
700         .write = power_always_on_write,
701 };
702
703 static ssize_t power_power_events_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
704 {
705
706         if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_SUSPEND],strlen(mali_power_events[_MALI_DEVICE_SUSPEND])))
707         {
708                 mali_pm_os_suspend();
709                 /* @@@@ assuming currently suspend is successful later on to tune as per previous*/
710                 virtual_power_status_register =1;
711
712         }
713         else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_RESUME],strlen(mali_power_events[_MALI_DEVICE_RESUME])))
714         {
715                 mali_pm_os_resume();
716
717                 /* @@@@ assuming currently resume is successful later on to tune as per previous */
718                 virtual_power_status_register = 1;
719         }
720         else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_PAUSE],strlen(mali_power_events[_MALI_DEVICE_DVFS_PAUSE])))
721         {
722                 mali_bool power_on;
723                 mali_dev_pause(&power_on);
724                 if (!power_on)
725                 {
726                         virtual_power_status_register = 2;
727                         mali_dev_resume();
728                 }
729                 else
730                 {
731                         /*  @@@@ assuming currently resume is successful later on to tune as per previous */
732                         virtual_power_status_register =1;
733                 }
734         }
735         else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_RESUME],strlen(mali_power_events[_MALI_DEVICE_DVFS_RESUME])))
736         {
737                 mali_dev_resume();
738                 /*  @@@@ assuming currently resume is successful later on to tune as per previous */
739                 virtual_power_status_register = 1;
740         }
741         *ppos += cnt;
742         sprintf(pwr_buf, "%d",virtual_power_status_register);
743         return cnt;
744 }
745
746 static ssize_t power_power_events_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
747 {
748         return simple_read_from_buffer(ubuf, cnt, ppos, pwr_buf, POWER_BUFFER_SIZE);
749 }
750
751 static loff_t power_power_events_seek(struct file *file, loff_t offset, int orig)
752 {
753         file->f_pos = offset;
754         return 0;
755 }
756
757 static const struct file_operations power_power_events_fops = {
758         .owner = THIS_MODULE,
759         .read  = power_power_events_read,
760         .write = power_power_events_write,
761         .llseek = power_power_events_seek,
762 };
763
764 #if MALI_STATE_TRACKING
765 static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v)
766 {
767         u32 len = 0;
768         u32 size;
769         char *buf;
770
771         size = seq_get_buf(seq_file, &buf);
772
773         if(!size)
774         {
775                         return -ENOMEM;
776         }
777
778         /* Create the internal state dump. */
779         len  = snprintf(buf+len, size-len, "Mali device driver %s\n", SVN_REV_STRING);
780         len += snprintf(buf+len, size-len, "License: %s\n\n", MALI_KERNEL_LINUX_LICENSE);
781
782         len += _mali_kernel_core_dump_state(buf + len, size - len);
783
784         seq_commit(seq_file, len);
785
786         return 0;
787 }
788
789 static int mali_seq_internal_state_open(struct inode *inode, struct file *file)
790 {
791         return single_open(file, mali_seq_internal_state_show, NULL);
792 }
793
794 static const struct file_operations mali_seq_internal_state_fops = {
795         .owner = THIS_MODULE,
796         .open = mali_seq_internal_state_open,
797         .read = seq_read,
798         .llseek = seq_lseek,
799         .release = single_release,
800 };
801 #endif /* MALI_STATE_TRACKING */
802
803 #if defined(CONFIG_MALI400_INTERNAL_PROFILING)
804 static ssize_t profiling_record_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
805 {
806         char buf[64];
807         int r;
808
809         r = sprintf(buf, "%u\n", _mali_internal_profiling_is_recording() ? 1 : 0);
810         return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
811 }
812
813 static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
814 {
815         char buf[64];
816         unsigned long val;
817         int ret;
818
819         if (cnt >= sizeof(buf))
820         {
821                 return -EINVAL;
822         }
823
824         if (copy_from_user(&buf, ubuf, cnt))
825         {
826                 return -EFAULT;
827         }
828
829         buf[cnt] = 0;
830
831         ret = strict_strtoul(buf, 10, &val);
832         if (ret < 0)
833         {
834                 return ret;
835         }
836
837         if (val != 0)
838         {
839                 u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* This can be made configurable at a later stage if we need to */
840
841                 /* check if we are already recording */
842                 if (MALI_TRUE == _mali_internal_profiling_is_recording())
843                 {
844                         MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n"));
845                         return -EFAULT;
846                 }
847
848                 /* check if we need to clear out an old recording first */
849                 if (MALI_TRUE == _mali_internal_profiling_have_recording())
850                 {
851                         if (_MALI_OSK_ERR_OK != _mali_internal_profiling_clear())
852                         {
853                                 MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n"));
854                                 return -EFAULT;
855                         }
856                 }
857
858                 /* start recording profiling data */
859                 if (_MALI_OSK_ERR_OK != _mali_internal_profiling_start(&limit))
860                 {
861                         MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n"));
862                         return -EFAULT;
863                 }
864
865                 MALI_DEBUG_PRINT(3, ("Profiling recording started (max %u events)\n", limit));
866         }
867         else
868         {
869                 /* stop recording profiling data */
870                 u32 count = 0;
871                 if (_MALI_OSK_ERR_OK != _mali_internal_profiling_stop(&count))
872                 {
873                         MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n"));
874                         return -EFAULT;
875                 }
876                 
877                 MALI_DEBUG_PRINT(2, ("Profiling recording stopped (recorded %u events)\n", count));
878         }
879
880         *ppos += cnt;
881         return cnt;
882 }
883
884 static const struct file_operations profiling_record_fops = {
885         .owner = THIS_MODULE,
886         .read  = profiling_record_read,
887         .write = profiling_record_write,
888 };
889
890 static void *profiling_events_start(struct seq_file *s, loff_t *pos)
891 {
892         loff_t *spos;
893
894         /* check if we have data avaiable */
895         if (MALI_TRUE != _mali_internal_profiling_have_recording())
896         {
897                 return NULL;
898         }
899
900         spos = kmalloc(sizeof(loff_t), GFP_KERNEL);
901         if (NULL == spos)
902         {
903                 return NULL;
904         }
905
906         *spos = *pos;
907         return spos;
908 }
909
910 static void *profiling_events_next(struct seq_file *s, void *v, loff_t *pos)
911 {
912         loff_t *spos = v;
913
914         /* check if we have data avaiable */
915         if (MALI_TRUE != _mali_internal_profiling_have_recording())
916         {
917                 return NULL;
918         }
919
920         /* check if the next entry actually is avaiable */
921         if (_mali_internal_profiling_get_count() <= (u32)(*spos + 1))
922         {
923                 return NULL;
924         }
925
926         *pos = ++*spos;
927         return spos;
928 }
929
930 static void profiling_events_stop(struct seq_file *s, void *v)
931 {
932         kfree(v);
933 }
934
935 static int profiling_events_show(struct seq_file *seq_file, void *v)
936 {
937         loff_t *spos = v;
938         u32 index;
939         u64 timestamp;
940         u32 event_id;
941         u32 data[5];
942
943         index = (u32)*spos;
944
945         /* Retrieve all events */
946         if (_MALI_OSK_ERR_OK == _mali_internal_profiling_get_event(index, &timestamp, &event_id, data))
947         {
948                 seq_printf(seq_file, "%llu %u %u %u %u %u %u\n", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]);
949                 return 0;
950         }
951
952         return 0;
953 }
954
955 static int profiling_events_show_human_readable(struct seq_file *seq_file, void *v)
956 {
957         #define MALI_EVENT_ID_IS_HW(event_id) (((event_id & 0x00FF0000) >= MALI_PROFILING_EVENT_CHANNEL_GP0) && ((event_id & 0x00FF0000) <= MALI_PROFILING_EVENT_CHANNEL_PP7))
958
959         static u64 start_time = 0;
960         loff_t *spos = v;
961         u32 index;
962         u64 timestamp;
963         u32 event_id;
964         u32 data[5];
965
966         index = (u32)*spos;
967
968         /* Retrieve all events */
969         if (_MALI_OSK_ERR_OK == _mali_internal_profiling_get_event(index, &timestamp, &event_id, data))
970         {
971                 seq_printf(seq_file, "%llu %u %u %u %u %u %u # ", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]);
972
973                 if (0 == index)
974                 {
975                         start_time = timestamp;
976                 }
977
978                 seq_printf(seq_file, "[%06u] ", index);
979
980                 switch(event_id & 0x0F000000)
981                 {
982                 case MALI_PROFILING_EVENT_TYPE_SINGLE:
983                         seq_printf(seq_file, "SINGLE | ");
984                         break;
985                 case MALI_PROFILING_EVENT_TYPE_START:
986                         seq_printf(seq_file, "START | ");
987                         break;
988                 case MALI_PROFILING_EVENT_TYPE_STOP:
989                         seq_printf(seq_file, "STOP | ");
990                         break;
991                 case MALI_PROFILING_EVENT_TYPE_SUSPEND:
992                         seq_printf(seq_file, "SUSPEND | ");
993                         break;
994                 case MALI_PROFILING_EVENT_TYPE_RESUME:
995                         seq_printf(seq_file, "RESUME | ");
996                         break;
997                 default:
998                         seq_printf(seq_file, "0x%01X | ", (event_id & 0x0F000000) >> 24);
999                         break;
1000                 }
1001
1002                 switch(event_id & 0x00FF0000)
1003                 {
1004                 case MALI_PROFILING_EVENT_CHANNEL_SOFTWARE:
1005                         seq_printf(seq_file, "SW | ");
1006                         break;
1007                 case MALI_PROFILING_EVENT_CHANNEL_GP0:
1008                         seq_printf(seq_file, "GP0 | ");
1009                         break;
1010                 case MALI_PROFILING_EVENT_CHANNEL_PP0:
1011                         seq_printf(seq_file, "PP0 | ");
1012                         break;
1013                 case MALI_PROFILING_EVENT_CHANNEL_PP1:
1014                         seq_printf(seq_file, "PP1 | ");
1015                         break;
1016                 case MALI_PROFILING_EVENT_CHANNEL_PP2:
1017                         seq_printf(seq_file, "PP2 | ");
1018                         break;
1019                 case MALI_PROFILING_EVENT_CHANNEL_PP3:
1020                         seq_printf(seq_file, "PP3 | ");
1021                         break;
1022                 case MALI_PROFILING_EVENT_CHANNEL_PP4:
1023                         seq_printf(seq_file, "PP4 | ");
1024                         break;
1025                 case MALI_PROFILING_EVENT_CHANNEL_PP5:
1026                         seq_printf(seq_file, "PP5 | ");
1027                         break;
1028                 case MALI_PROFILING_EVENT_CHANNEL_PP6:
1029                         seq_printf(seq_file, "PP6 | ");
1030                         break;
1031                 case MALI_PROFILING_EVENT_CHANNEL_PP7:
1032                         seq_printf(seq_file, "PP7 | ");
1033                         break;
1034                 case MALI_PROFILING_EVENT_CHANNEL_GPU:
1035                         seq_printf(seq_file, "GPU | ");
1036                         break;
1037                 default:
1038                         seq_printf(seq_file, "0x%02X | ", (event_id & 0x00FF0000) >> 16);
1039                         break;
1040                 }
1041
1042                 if (MALI_EVENT_ID_IS_HW(event_id))
1043                 {
1044                         if (((event_id & 0x0F000000) == MALI_PROFILING_EVENT_TYPE_START) || ((event_id & 0x0F000000) == MALI_PROFILING_EVENT_TYPE_STOP))
1045                         {
1046                                 switch(event_id & 0x0000FFFF)
1047                                 {
1048                                 case MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL:
1049                                         seq_printf(seq_file, "PHYSICAL | ");
1050                                         break;
1051                                 case MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL:
1052                                         seq_printf(seq_file, "VIRTUAL | ");
1053                                         break;
1054                                 default:
1055                                         seq_printf(seq_file, "0x%04X | ", event_id & 0x0000FFFF);
1056                                         break;
1057                                 }
1058                         }
1059                         else
1060                         {
1061                                 seq_printf(seq_file, "0x%04X | ", event_id & 0x0000FFFF);
1062                         }
1063                 }
1064                 else
1065                 {
1066                         seq_printf(seq_file, "0x%04X | ", event_id & 0x0000FFFF);
1067                 }
1068
1069                 seq_printf(seq_file, "T0 + 0x%016llX\n", timestamp - start_time);
1070
1071                 return 0;
1072         }
1073
1074         return 0;
1075 }
1076
1077 static const struct seq_operations profiling_events_seq_ops = {
1078         .start = profiling_events_start,
1079         .next  = profiling_events_next,
1080         .stop  = profiling_events_stop,
1081         .show  = profiling_events_show
1082 };
1083
1084 static int profiling_events_open(struct inode *inode, struct file *file)
1085 {
1086         return seq_open(file, &profiling_events_seq_ops);
1087 }
1088
1089 static const struct file_operations profiling_events_fops = {
1090         .owner = THIS_MODULE,
1091         .open = profiling_events_open,
1092         .read = seq_read,
1093         .llseek = seq_lseek,
1094         .release = seq_release,
1095 };
1096
1097 static const struct seq_operations profiling_events_human_readable_seq_ops = {
1098         .start = profiling_events_start,
1099         .next  = profiling_events_next,
1100         .stop  = profiling_events_stop,
1101         .show  = profiling_events_show_human_readable
1102 };
1103
1104 static int profiling_events_human_readable_open(struct inode *inode, struct file *file)
1105 {
1106         return seq_open(file, &profiling_events_human_readable_seq_ops);
1107 }
1108
1109 static const struct file_operations profiling_events_human_readable_fops = {
1110         .owner = THIS_MODULE,
1111         .open = profiling_events_human_readable_open,
1112         .read = seq_read,
1113         .llseek = seq_lseek,
1114         .release = seq_release,
1115 };
1116
1117 #endif
1118
1119 static ssize_t memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
1120 {
1121         char buf[64];
1122         size_t r;
1123         u32 mem = _mali_ukk_report_memory_usage();
1124
1125         r = snprintf(buf, 64, "%u\n", mem);
1126         return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
1127 }
1128
1129 static const struct file_operations memory_usage_fops = {
1130         .owner = THIS_MODULE,
1131         .read = memory_used_read,
1132 };
1133
1134 static ssize_t utilization_gp_pp_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
1135 {
1136         char buf[64];
1137         size_t r;
1138         u32 uval= _mali_ukk_utilization_gp_pp();
1139
1140         r = snprintf(buf, 64, "%u\n", uval);
1141         return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
1142 }
1143
1144 static ssize_t utilization_gp_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
1145 {
1146         char buf[64];
1147         size_t r;
1148         u32 uval= _mali_ukk_utilization_gp();
1149
1150         r = snprintf(buf, 64, "%u\n", uval);
1151         return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
1152 }
1153
1154 static ssize_t utilization_pp_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
1155 {
1156         char buf[64];
1157         size_t r;
1158         u32 uval= _mali_ukk_utilization_pp();
1159
1160         r = snprintf(buf, 64, "%u\n", uval);
1161         return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
1162 }
1163
1164
1165 static const struct file_operations utilization_gp_pp_fops = {
1166         .owner = THIS_MODULE,
1167         .read = utilization_gp_pp_read,
1168 };
1169
1170 static const struct file_operations utilization_gp_fops = {
1171         .owner = THIS_MODULE,
1172         .read = utilization_gp_read,
1173 };
1174
1175 static const struct file_operations utilization_pp_fops = {
1176         .owner = THIS_MODULE,
1177         .read = utilization_pp_read,
1178 };
1179
1180 static ssize_t user_settings_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
1181 {
1182         unsigned long val;
1183         int ret;
1184         _mali_uk_user_setting_t setting;
1185         char buf[32];
1186
1187         cnt = min(cnt, sizeof(buf) - 1);
1188         if (copy_from_user(buf, ubuf, cnt))
1189         {
1190                 return -EFAULT;
1191         }
1192         buf[cnt] = '\0';
1193
1194         ret = strict_strtoul(buf, 10, &val);
1195         if (0 != ret)
1196         {
1197                 return ret;
1198         }
1199
1200         /* Update setting */
1201         setting = (_mali_uk_user_setting_t)(filp->private_data);
1202         mali_set_user_setting(setting, val);
1203
1204         *ppos += cnt;
1205         return cnt;
1206 }
1207
1208 static ssize_t user_settings_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
1209 {
1210         char buf[64];
1211         size_t r;
1212         u32 value;
1213         _mali_uk_user_setting_t setting;
1214
1215         setting = (_mali_uk_user_setting_t)(filp->private_data);
1216         value = mali_get_user_setting(setting);
1217
1218         r = snprintf(buf, 64, "%u\n", value);
1219         return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
1220 }
1221
1222 static const struct file_operations user_settings_fops = {
1223         .owner = THIS_MODULE,
1224         .open = open_copy_private_data,
1225         .read = user_settings_read,
1226         .write = user_settings_write,
1227 };
1228
1229 static int mali_sysfs_user_settings_register(void)
1230 {
1231         struct dentry *mali_user_settings_dir = debugfs_create_dir("userspace_settings", mali_debugfs_dir);
1232
1233         if (mali_user_settings_dir != NULL)
1234         {
1235                 int i;
1236                 for (i = 0; i < _MALI_UK_USER_SETTING_MAX; i++)
1237                 {
1238                         debugfs_create_file(_mali_uk_user_setting_descriptions[i], 0600, mali_user_settings_dir, (void*)i, &user_settings_fops);
1239                 }
1240         }
1241
1242         return 0;
1243 }
1244
1245 int mali_sysfs_register(const char *mali_dev_name)
1246 {
1247         mali_debugfs_dir = debugfs_create_dir(mali_dev_name, NULL);
1248         if(ERR_PTR(-ENODEV) == mali_debugfs_dir)
1249         {
1250                 /* Debugfs not supported. */
1251                 mali_debugfs_dir = NULL;
1252         }
1253         else
1254         {
1255                 if(NULL != mali_debugfs_dir)
1256                 {
1257                         /* Debugfs directory created successfully; create files now */
1258                         struct dentry *mali_power_dir;
1259                         struct dentry *mali_gp_dir;
1260                         struct dentry *mali_pp_dir;
1261                         struct dentry *mali_l2_dir;
1262 #if defined(CONFIG_MALI400_INTERNAL_PROFILING)
1263                         struct dentry *mali_profiling_dir;
1264 #endif
1265
1266                         mali_power_dir = debugfs_create_dir("power", mali_debugfs_dir);
1267                         if (mali_power_dir != NULL)
1268                         {
1269                                 debugfs_create_file("always_on", 0400, mali_power_dir, NULL, &power_always_on_fops);
1270                                 debugfs_create_file("power_events", 0400, mali_power_dir, NULL, &power_power_events_fops);
1271                         }
1272
1273                         mali_gp_dir = debugfs_create_dir("gp", mali_debugfs_dir);
1274                         if (mali_gp_dir != NULL)
1275                         {
1276                                 struct dentry *mali_gp_all_dir;
1277                                 u32 num_groups;
1278                                 int i;
1279
1280                                 mali_gp_all_dir = debugfs_create_dir("all", mali_gp_dir);
1281                                 if (mali_gp_all_dir != NULL)
1282                                 {
1283                                         debugfs_create_file("counter_src0", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src0_fops);
1284                                         debugfs_create_file("counter_src1", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src1_fops);
1285                                 }
1286
1287                                 num_groups = mali_group_get_glob_num_groups();
1288                                 for (i = 0; i < num_groups; i++)
1289                                 {
1290                                         struct mali_group *group = mali_group_get_glob_group(i);
1291
1292                                         struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
1293                                         if (NULL != gp_core)
1294                                         {
1295                                                 struct dentry *mali_gp_gpx_dir;
1296                                                 mali_gp_gpx_dir = debugfs_create_dir("gp0", mali_gp_dir);
1297                                                 if (NULL != mali_gp_gpx_dir)
1298                                                 {
1299                                                         debugfs_create_file("counter_src0", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src0_fops);
1300                                                         debugfs_create_file("counter_src1", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src1_fops);
1301                                                 }
1302                                                 break; /* no need to look for any other GP cores */
1303                                         }
1304
1305                                 }
1306                         }
1307
1308                         mali_pp_dir = debugfs_create_dir("pp", mali_debugfs_dir);
1309                         if (mali_pp_dir != NULL)
1310                         {
1311                                 struct dentry *mali_pp_all_dir;
1312                                 u32 num_groups;
1313                                 int i;
1314
1315                                 mali_pp_all_dir = debugfs_create_dir("all", mali_pp_dir);
1316                                 if (mali_pp_all_dir != NULL)
1317                                 {
1318                                         debugfs_create_file("counter_src0", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src0_fops);
1319                                         debugfs_create_file("counter_src1", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src1_fops);
1320                                 }
1321
1322                                 num_groups = mali_group_get_glob_num_groups();
1323                                 for (i = 0; i < num_groups; i++)
1324                                 {
1325                                         struct mali_group *group = mali_group_get_glob_group(i);
1326
1327                                         struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
1328                                         if (NULL != pp_core)
1329                                         {
1330                                                 char buf[16];
1331                                                 struct dentry *mali_pp_ppx_dir;
1332                                                 _mali_osk_snprintf(buf, sizeof(buf), "pp%u", mali_pp_core_get_id(pp_core));
1333                                                 mali_pp_ppx_dir = debugfs_create_dir(buf, mali_pp_dir);
1334                                                 if (NULL != mali_pp_ppx_dir)
1335                                                 {
1336                                                         debugfs_create_file("counter_src0", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src0_fops);
1337                                                         debugfs_create_file("counter_src1", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src1_fops);
1338                                                 }
1339                                         }
1340                                 }
1341                         }
1342
1343                         mali_l2_dir = debugfs_create_dir("l2", mali_debugfs_dir);
1344                         if (mali_l2_dir != NULL)
1345                         {
1346                                 struct dentry *mali_l2_all_dir;
1347                                 u32 l2_id;
1348                                 struct mali_l2_cache_core *l2_cache;
1349
1350                                 mali_l2_all_dir = debugfs_create_dir("all", mali_l2_dir);
1351                                 if (mali_l2_all_dir != NULL)
1352                                 {
1353                                         debugfs_create_file("counter_src0", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src0_fops);
1354                                         debugfs_create_file("counter_src1", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src1_fops);
1355                                 }
1356
1357                                 l2_id = 0;
1358                                 l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
1359                                 while (NULL != l2_cache)
1360                                 {
1361                                         char buf[16];
1362                                         struct dentry *mali_l2_l2x_dir;
1363                                         _mali_osk_snprintf(buf, sizeof(buf), "l2%u", l2_id);
1364                                         mali_l2_l2x_dir = debugfs_create_dir(buf, mali_l2_dir);
1365                                         if (NULL != mali_l2_l2x_dir)
1366                                         {
1367                                                 debugfs_create_file("counter_src0", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src0_fops);
1368                                                 debugfs_create_file("counter_src1", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src1_fops);
1369                                         }
1370
1371                                         /* try next L2 */
1372                                         l2_id++;
1373                                         l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
1374                                 }
1375                         }
1376
1377                         debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops);
1378
1379                         debugfs_create_file("utilization_gp_pp", 0400, mali_debugfs_dir, NULL, &utilization_gp_pp_fops);
1380                         debugfs_create_file("utilization_gp", 0400, mali_debugfs_dir, NULL, &utilization_gp_fops);
1381                         debugfs_create_file("utilization_pp", 0400, mali_debugfs_dir, NULL, &utilization_pp_fops);
1382
1383 #if defined(CONFIG_MALI400_INTERNAL_PROFILING)
1384                         mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir);
1385                         if (mali_profiling_dir != NULL)
1386                         {
1387                                 struct dentry *mali_profiling_proc_dir = debugfs_create_dir("proc", mali_profiling_dir);
1388                                 if (mali_profiling_proc_dir != NULL)
1389                                 {
1390                                         struct dentry *mali_profiling_proc_default_dir = debugfs_create_dir("default", mali_profiling_proc_dir);
1391                                         if (mali_profiling_proc_default_dir != NULL)
1392                                         {
1393                                                 debugfs_create_file("enable", 0600, mali_profiling_proc_default_dir, (void*)_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, &user_settings_fops);
1394                                         }
1395                                 }
1396                                 debugfs_create_file("record", 0600, mali_profiling_dir, NULL, &profiling_record_fops);
1397                                 debugfs_create_file("events", 0400, mali_profiling_dir, NULL, &profiling_events_fops);
1398                                 debugfs_create_file("events_human_readable", 0400, mali_profiling_dir, NULL, &profiling_events_human_readable_fops);
1399                         }
1400 #endif
1401
1402 #if MALI_STATE_TRACKING
1403                         debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops);
1404 #endif
1405
1406                         if (mali_sysfs_user_settings_register())
1407                         {
1408                                 /* Failed to create the debugfs entries for the user settings DB. */
1409                                 MALI_DEBUG_PRINT(2, ("Failed to create user setting debugfs files. Ignoring...\n"));
1410                         }
1411                 }
1412         }
1413
1414         /* Success! */
1415         return 0;
1416 }
1417
1418 int mali_sysfs_unregister(void)
1419 {
1420         if(NULL != mali_debugfs_dir)
1421         {
1422                 debugfs_remove_recursive(mali_debugfs_dir);
1423         }
1424         return 0;
1425 }
1426
1427 #else
1428
1429 /* Dummy implementations for non-GPL */
1430
1431 int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name)
1432 {
1433         return 0;
1434 }
1435
1436 int mali_sysfs_unregister(void)
1437 {
1438         return 0;
1439 }
1440
1441
1442 #endif