Initial commit
[kernel/linux-3.0.git] / drivers / gpu / vithar_rev0 / kbase / src / linux / mali_kbase_core_linux.c
1 /*
2  *
3  * (C) COPYRIGHT 2010-2012 ARM Limited. All rights reserved.
4  *
5  * This program is free software and is provided to you under the terms of the GNU General Public License version 2
6  * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
7  * 
8  * A copy of the licence is included with the program, and can also be obtained from Free Software
9  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
10  * 
11  */
12
13
14
15 /**
16  * @file mali_kbase_core_linux.c
17  * Base kernel driver init.
18  */
19
20 #include <osk/mali_osk.h>
21 #include <kbase/src/common/mali_kbase.h>
22 #include <kbase/src/common/mali_kbase_uku.h>
23 #include <kbase/src/common/mali_midg_regmap.h>
24 #include <kbase/src/linux/mali_kbase_mem_linux.h>
25 #include <kbase/src/linux/mali_kbase_config_linux.h>
26 #include <uk/mali_ukk.h>
27 #if MALI_NO_MALI
28 #include "mali_kbase_model_linux.h"
29 #endif
30
31 #include <linux/module.h>
32 #include <linux/init.h>
33 #include <linux/poll.h>
34 #include <linux/kernel.h>
35 #include <linux/errno.h>
36 #if MALI_LICENSE_IS_GPL
37 #include <linux/platform_device.h>
38 #include <linux/pci.h>
39 #include <linux/miscdevice.h>
40 #endif
41 #include <linux/list.h>
42 #include <linux/semaphore.h>
43 #include <linux/fs.h>
44 #include <linux/uaccess.h>
45 #include <linux/interrupt.h>
46 #include <linux/io.h>
47 #if BASE_HW_ISSUE_8401
48 #include <kbase/src/common/mali_kbase_8401_workaround.h>
49 #endif
50 #ifdef CONFIG_VITHAR
51 #include <mach/map.h>
52 #include <kbase/src/platform/mali_kbase_platform.h>
53 #include <kbase/src/platform/mali_kbase_runtime_pm.h>
54 #include <kbase/src/platform/mali_kbase_dvfs.h>
55 #endif
56
57 #define JOB_IRQ_TAG     0
58 #define MMU_IRQ_TAG     1
59 #define GPU_IRQ_TAG     2
60
61 struct kbase_irq_table
62 {
63         u32             tag;
64         irq_handler_t   handler;
65 };
66 #if MALI_DEBUG
67 kbase_exported_test_data shared_kernel_test_data;
68 EXPORT_SYMBOL(shared_kernel_test_data);
69 #endif /* MALI_DEBUG */
70
71 static const char kbase_drv_name[] = KBASE_DRV_NAME;
72
73 static int kbase_dev_nr;
74
75 #if MALI_LICENSE_IS_GPL
76 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
77 static DEFINE_SEMAPHORE(kbase_dev_list_lock);
78 #else
79 static DECLARE_MUTEX(kbase_dev_list_lock);
80 #endif
81 static LIST_HEAD(kbase_dev_list);
82
83 KBASE_EXPORT_TEST_API(kbase_dev_list_lock)
84 KBASE_EXPORT_TEST_API(kbase_dev_list)
85 #endif
86
87 #if MALI_LICENSE_IS_GPL == 0
88 #include <linux/cdev.h>              /* character device definitions */
89
90 /* By default the module uses any available major, but it's possible to set it at load time to a specific number */
91 int mali_major = 0;
92 module_param(mali_major, int, S_IRUGO); /* r--r--r-- */
93 MODULE_PARM_DESC(mali_major, "Device major number");
94
95 struct mali_linux_device
96 {
97     struct cdev cdev;
98 };
99
100 /* The global variable containing the global device data */
101 static struct mali_linux_device mali_linux_device;
102
103 static char mali_dev_name[] = KBASE_DRV_NAME; /* should be const, but the functions we call requires non-cost */
104
105 #undef dev_err
106 #undef dev_info
107 #undef dev_dbg
108 #define dev_err(dev,msg,...)  do { printk(KERN_ERR   KBASE_DRV_NAME " error: "); printk(msg, ## __VA_ARGS__); } while(0)
109 #define dev_info(dev,msg,...) do { printk(KERN_INFO  KBASE_DRV_NAME " info: ");  printk(msg, ## __VA_ARGS__); } while(0)
110 #define dev_dbg(dev,msg,...)  do { printk(KERN_DEBUG KBASE_DRV_NAME " debug: "); printk(msg, ## __VA_ARGS__); } while(0)
111 #define dev_name(dev) "MALI"
112
113 /* STATIC */ struct kbase_device     *g_kbdev;
114 KBASE_EXPORT_TEST_API(g_kbdev);
115
116 #endif
117
118
119 #if MALI_LICENSE_IS_GPL
120 #define KERNEL_SIDE_DDK_VERSION_STRING "K:" MALI_RELEASE_NAME "(GPL)"
121 #else
122 #define KERNEL_SIDE_DDK_VERSION_STRING "K:" MALI_RELEASE_NAME
123 #endif /* MALI_LICENSE_IS_GPL */
124
125 static INLINE void __compile_time_asserts( void )
126 {
127         CSTD_COMPILE_TIME_ASSERT( sizeof(KERNEL_SIDE_DDK_VERSION_STRING) <= KBASE_GET_VERSION_BUFFER_SIZE);
128 }
129
130 static mali_error kbase_dispatch(ukk_call_context * const ukk_ctx, void * const args, u32 args_size)
131 {
132         struct kbase_context *kctx;
133         struct kbase_device *kbdev;
134         uk_header *ukh = args;
135         u32 id;
136
137         OSKP_ASSERT( ukh != NULL );
138
139         kctx = CONTAINER_OF(ukk_session_get(ukk_ctx), kbase_context, ukk_session);
140         kbdev = kctx->kbdev;
141         id = ukh->id;
142         ukh->ret = MALI_ERROR_NONE; /* Be optimistic */
143
144         switch(id)
145         {
146                 case KBASE_FUNC_TMEM_ALLOC:
147                 {
148                         kbase_uk_tmem_alloc *tmem = args;
149                         struct kbase_va_region *reg;
150
151                         if (sizeof(*tmem) != args_size)
152                         {
153                                 goto bad_size;
154                         }
155
156                         reg = kbase_tmem_alloc(kctx, tmem->vsize, tmem->psize,
157                                                tmem->extent, tmem->flags, tmem->is_growable);
158                         if (reg)
159                         {
160                                 tmem->gpu_addr  = reg->start_pfn << 12;
161                         }
162                         else
163                         {
164                                 ukh->ret = MALI_ERROR_FUNCTION_FAILED;
165                         }
166                         break;
167                 }
168
169                 case KBASE_FUNC_TMEM_FROM_UMP:
170 #if MALI_USE_UMP
171                 {
172                         kbase_uk_tmem_from_ump * tmem_ump = args;
173                         struct kbase_va_region *reg;
174
175                         if (sizeof(*tmem_ump) != args_size)
176                         {
177                                 goto bad_size;
178                         }
179
180                         reg = kbase_tmem_from_ump(kctx, tmem_ump->id, &tmem_ump->pages);
181                         if (reg)
182                         {
183                                 tmem_ump->gpu_addr = reg->start_pfn << 12;
184                         }
185                         else
186                         {
187                                 ukh->ret = MALI_ERROR_FUNCTION_FAILED;
188                         }
189                         break;
190                 }
191 #else
192                 {
193                         ukh->ret = MALI_ERROR_FUNCTION_FAILED;
194                         break;
195                 }
196 #endif
197
198                 case KBASE_FUNC_PMEM_ALLOC:
199                 {
200                         kbase_uk_pmem_alloc *pmem = args;
201                         struct kbase_va_region *reg;
202
203                         if (sizeof(*pmem) != args_size)
204                         {
205                                 goto bad_size;
206                         }
207
208                         reg = kbase_pmem_alloc(kctx, pmem->vsize, pmem->flags,
209                                                &pmem->cookie);
210                         if (!reg)
211                         {
212                                 ukh->ret = MALI_ERROR_FUNCTION_FAILED;
213                         }
214                         break;
215                 }
216
217                 case KBASE_FUNC_MEM_FREE:
218                 {
219                         kbase_uk_mem_free *mem = args;
220
221                         if (sizeof(*mem) != args_size)
222                         {
223                                 goto bad_size;
224                         }
225
226                         if (kbase_mem_free(kctx, mem->gpu_addr))
227                         {
228                                 ukh->ret = MALI_ERROR_FUNCTION_FAILED;
229                         }
230                         break;
231                 }
232
233                 case KBASE_FUNC_JOB_SUBMIT:
234                 {
235                         kbase_uk_job_submit * job = args;
236                         
237                         if (sizeof(*job) != args_size)
238                         {
239                                 goto bad_size;
240                         }
241
242                         if (MALI_ERROR_NONE != kbase_jd_submit(kctx, job))
243                         {
244                                 ukh->ret = MALI_ERROR_FUNCTION_FAILED;
245                         }
246                         break;
247                 }
248
249                 case KBASE_FUNC_SYNC:
250                 {
251                         kbase_uk_sync_now *sn = args;
252
253                         if (sizeof(*sn) != args_size)
254                         {
255                                 goto bad_size;
256                         }
257
258                         if (MALI_ERROR_NONE != kbase_sync_now(kctx, &sn->sset))
259                         {
260                                 ukh->ret = MALI_ERROR_FUNCTION_FAILED;
261                         }
262                         break;
263                 }
264
265                 case KBASE_FUNC_POST_TERM:
266                 {
267                         kbase_event_close(kctx);
268                         break;
269                 }
270
271                 case KBASE_FUNC_HWCNT_SETUP:
272                 {
273                         kbase_uk_hwcnt_setup * setup = args;
274
275                         if (sizeof(*setup) != args_size)
276                         {
277                                 goto bad_size;
278                         }
279
280                         if (MALI_ERROR_NONE != kbase_instr_hwcnt_setup(kctx, setup))
281                         {
282                                 ukh->ret = MALI_ERROR_FUNCTION_FAILED;
283                         }
284                         break;
285                 }
286
287                 case KBASE_FUNC_HWCNT_DUMP:
288                 {
289                         /* args ignored */
290                         if (MALI_ERROR_NONE != kbase_instr_hwcnt_dump(kctx))
291                         {
292                                 ukh->ret = MALI_ERROR_FUNCTION_FAILED;
293                         }
294                         break;
295                 }
296
297                 case KBASE_FUNC_HWCNT_CLEAR:
298                 {
299                         /* args ignored */
300                         if (MALI_ERROR_NONE != kbase_instr_hwcnt_clear(kctx))
301                         {
302                                 ukh->ret = MALI_ERROR_FUNCTION_FAILED;
303                         }
304                         break;
305                 }
306
307                 case KBASE_FUNC_GPU_PROPS_REG_DUMP:
308                 {
309                         kbase_uk_gpuprops * setup = args;
310
311                         if (sizeof(*setup) != args_size)
312                         {
313                                 goto bad_size;
314                         }
315
316                         if (MALI_ERROR_NONE != kbase_gpuprops_uk_get_props(kctx, setup))
317                         {
318                                 ukh->ret = MALI_ERROR_FUNCTION_FAILED;
319                         }
320                         break;
321                 }
322
323                 case KBASE_FUNC_TMEM_RESIZE:
324                 {
325                         kbase_uk_tmem_resize *resize = args;
326                         if (sizeof(*resize) != args_size)
327                         {
328                                 goto bad_size;
329                         }
330
331                         ukh->ret = kbase_tmem_resize(kctx, resize->gpu_addr, resize->delta, &resize->size, &resize->result_subcode);
332                         break;
333                 }
334
335                 case KBASE_FUNC_FIND_CPU_MAPPING:
336                 {
337                         kbase_uk_find_cpu_mapping *find = args;
338                         struct kbase_cpu_mapping *map;
339
340                         if (sizeof(*find) != args_size)
341                         {
342                                 goto bad_size;
343                         }
344
345                         OSKP_ASSERT( find != NULL );
346                         if ( find->size > SIZE_MAX || find->cpu_addr > UINTPTR_MAX )
347                         {
348                                 map = NULL;
349                         }
350                         else
351                         {
352                                 map = kbasep_find_enclosing_cpu_mapping( kctx,
353                                                                          find->gpu_addr,
354                                                                          (osk_virt_addr)(uintptr_t)find->cpu_addr,
355                                                                          (size_t)find->size );
356                         }
357
358                         if ( NULL != map )
359                         {
360                                 find->uaddr = PTR_TO_U64( map->uaddr );
361                                 find->nr_pages = map->nr_pages;
362                                 find->page_off = map->page_off;
363                         }
364                         else
365                         {
366                                 ukh->ret = MALI_ERROR_FUNCTION_FAILED;
367                         }
368                         break;
369                 }
370                 case KBASE_FUNC_GET_VERSION:
371                 {
372                         kbase_uk_get_ddk_version *get_version = (kbase_uk_get_ddk_version *)args;
373
374                         if (sizeof(*get_version) != args_size)
375                         {
376                                 goto bad_size;
377                         }
378
379                         /* version buffer size check is made in compile time assert */
380                         OSK_MEMCPY(get_version->version_buffer, KERNEL_SIDE_DDK_VERSION_STRING,
381                                 sizeof(KERNEL_SIDE_DDK_VERSION_STRING));
382                         get_version->version_string_size = sizeof(KERNEL_SIDE_DDK_VERSION_STRING);
383                         break;
384                 }
385
386 #if MALI_DEBUG
387                 case KBASE_FUNC_SET_TEST_DATA:
388                 {
389                         kbase_uk_set_test_data *set_data = args;
390
391                         shared_kernel_test_data = set_data->test_data;
392                         shared_kernel_test_data.kctx = kctx;
393                         shared_kernel_test_data.mm = (void*)current->mm;
394                         ukh->ret = MALI_ERROR_NONE;
395                         break;
396                 }
397 #endif /* MALI_DEBUG */
398 #if MALI_ERROR_INJECT_ON
399                 case KBASE_FUNC_INJECT_ERROR:
400                 {
401                         kbase_error_params params = ((kbase_uk_error_params*)args)->params;
402                         /*mutex lock*/
403                         osk_spinlock_lock(&kbdev->osdev.reg_op_lock);
404                         ukh->ret = job_atom_inject_error(&params);
405                         osk_spinlock_unlock(&kbdev->osdev.reg_op_lock);
406                         /*mutex unlock*/
407
408                         break;
409                 }
410 #endif /*MALI_ERROR_INJECT_ON*/
411 #if MALI_NO_MALI
412                 case KBASE_FUNC_MODEL_CONTROL:
413                 {
414                         kbase_model_control_params params = ((kbase_uk_model_control_params*)args)->params;
415                         /*mutex lock*/
416                         osk_spinlock_lock(&kbdev->osdev.reg_op_lock);
417                         ukh->ret = midg_model_control(kbdev->osdev.model, &params);
418                         osk_spinlock_unlock(&kbdev->osdev.reg_op_lock);
419                         /*mutex unlock*/
420                         break;
421                 }
422 #endif /* MALI_NO_MALI */
423                 default:
424                         dev_err(kbdev->osdev.dev, "unknown syscall %08x", ukh->id);
425                         goto out_bad;
426         }
427
428         return MALI_ERROR_NONE;
429
430 bad_size:
431         dev_err(kbdev->osdev.dev, "Wrong syscall size (%d) for %08x\n", args_size, ukh->id);
432 out_bad:
433         return MALI_ERROR_FUNCTION_FAILED;
434 }
435
436 #if MALI_LICENSE_IS_GPL
437 static struct kbase_device *to_kbase_device(struct device *dev)
438 {
439         return dev_get_drvdata(dev);
440 }
441 #endif /* MALI_LICENSE_IS_GPL */
442
443 /* Find a particular kbase device (as specified by minor number), or find the "first" device if -1 is specified */
444 struct kbase_device *kbase_find_device(int minor)
445 {
446         struct kbase_device *kbdev = NULL;
447 #if MALI_LICENSE_IS_GPL
448         struct list_head *entry;
449
450         down(&kbase_dev_list_lock);
451         list_for_each(entry, &kbase_dev_list)
452         {
453                 struct kbase_device *tmp;
454
455                 tmp = list_entry(entry, struct kbase_device, osdev.entry);
456                 if (tmp->osdev.mdev.minor == minor || minor == -1)
457                 {
458                         kbdev = tmp;
459                         get_device(kbdev->osdev.dev);
460                         break;
461                 }
462         }
463         up(&kbase_dev_list_lock);
464 #else
465         kbdev = g_kbdev;
466 #endif
467
468         return kbdev;
469 }
470
471 EXPORT_SYMBOL(kbase_find_device);
472
473 void kbase_release_device(struct kbase_device *kbdev)
474 {
475 #if MALI_LICENSE_IS_GPL
476         put_device(kbdev->osdev.dev);
477 #endif
478 }
479
480 EXPORT_SYMBOL(kbase_release_device);
481
482 static int kbase_open(struct inode *inode, struct file *filp)
483 {
484         struct kbase_device *kbdev = NULL;
485         struct kbase_context *kctx;
486         int ret = 0;
487
488         /* Enforce that the driver is opened with O_CLOEXEC so that execve() automatically
489          * closes the file descriptor in a child process. 
490          */
491         if (0 == (filp->f_flags & O_CLOEXEC))
492         {
493                 printk(KERN_ERR   KBASE_DRV_NAME " error: O_CLOEXEC flag not set\n");
494                 return -EINVAL;
495         }
496
497         kbdev = kbase_find_device(iminor(inode));
498
499         if (!kbdev)
500                 return -ENODEV;
501
502         kctx = kbase_create_context(kbdev);
503         if (!kctx)
504         {
505                 ret = -ENOMEM;
506                 goto out;
507         }
508     
509         if (MALI_ERROR_NONE != ukk_session_init(&kctx->ukk_session, kbase_dispatch, BASE_UK_VERSION_MAJOR, BASE_UK_VERSION_MINOR))
510         {
511                 kbase_destroy_context(kctx);
512                 ret = -EFAULT;
513                 goto out;
514         }
515
516         init_waitqueue_head(&kctx->osctx.event_queue);
517         filp->private_data = kctx;
518
519         dev_dbg(kbdev->osdev.dev, "created base context\n");
520         return 0;
521
522 out:
523         kbase_release_device(kbdev);
524         return ret;
525 }
526
527 static int kbase_release(struct inode *inode, struct file *filp)
528 {
529         struct kbase_context *kctx = filp->private_data;
530         struct kbase_device *kbdev = kctx->kbdev;
531
532         ukk_session_term(&kctx->ukk_session);
533         filp->private_data = NULL;
534         kbase_destroy_context(kctx);
535
536         dev_dbg(kbdev->osdev.dev, "deleted base context\n");
537         kbase_release_device(kbdev);
538         return 0;
539 }
540
541 static long kbase_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
542 {
543         u64 msg[(UKK_CALL_MAX_SIZE+7)>>3]; /* alignment fixup */
544         u32 size = _IOC_SIZE(cmd);
545         ukk_call_context ukk_ctx;
546         struct kbase_context *kctx = filp->private_data;
547
548         if (size > UKK_CALL_MAX_SIZE) return -ENOTTY;
549
550         if (0 != copy_from_user(&msg, (void *)arg, size))
551         {
552                 return -EFAULT;
553         }
554
555         ukk_call_prepare(&ukk_ctx, &kctx->ukk_session, NULL);
556
557         if (MALI_ERROR_NONE != ukk_dispatch(&ukk_ctx, &msg, size))
558         {
559                 return -EFAULT;
560         }
561
562         if (0 != copy_to_user((void *)arg, &msg, size))
563         {
564                 pr_err("failed to copy results of UK call back to user space\n");
565                 return -EFAULT;
566         }
567         return 0;
568 }
569
570 static ssize_t kbase_read(struct file *filp, char __user *buf,
571                           size_t count, loff_t *f_pos)
572 {
573         struct kbase_context *kctx = filp->private_data;
574         base_jd_event uevent;
575
576         if (count < sizeof(uevent))
577         {
578                 return -ENOBUFS;
579         }
580
581         while (kbase_event_dequeue(kctx, &uevent))
582         {
583                 if (filp->f_flags & O_NONBLOCK)
584                 {
585                         return -EAGAIN;
586                 }
587
588                 if (wait_event_interruptible(kctx->osctx.event_queue,
589                                              kbase_event_pending(kctx)))
590                 {
591                         return -ERESTARTSYS;
592                 }
593         }
594
595         if (copy_to_user(buf, &uevent, sizeof(uevent)))
596         {
597                 return -EFAULT;
598         }
599
600         return sizeof(uevent);
601 }
602
603 static unsigned int kbase_poll(struct file *filp, poll_table *wait)
604 {
605         struct kbase_context *kctx = filp->private_data;
606
607         poll_wait(filp, &kctx->osctx.event_queue, wait);
608         if (kbase_event_pending(kctx))
609         {
610                 return POLLIN | POLLRDNORM;
611         }
612
613         return 0;
614 }
615
616 void kbase_event_wakeup(kbase_context *kctx)
617 {
618         OSK_ASSERT(kctx);
619
620         wake_up_interruptible(&kctx->osctx.event_queue);
621 }
622 KBASE_EXPORT_TEST_API(kbase_event_wakeup)
623
624 int kbase_check_flags(int flags)
625 {
626         /* Enforce that the driver keeps the O_CLOEXEC flag so that execve() always
627          * closes the file descriptor in a child process. 
628          */
629         if (0 == (flags & O_CLOEXEC))
630         {
631                 return -EINVAL; 
632         }
633
634         return 0;
635 }
636
637 static const struct file_operations kbase_fops =
638 {
639         .owner          = THIS_MODULE,
640         .open           = kbase_open,
641         .release        = kbase_release,
642         .read           = kbase_read,
643         .poll           = kbase_poll,
644         .unlocked_ioctl = kbase_ioctl,
645         .mmap           = kbase_mmap,
646         .check_flags    = kbase_check_flags,
647 };
648
649 #if !MALI_NO_MALI
650 void kbase_os_reg_write(kbase_device *kbdev, u16 offset, u32 value)
651 {
652         writel(value, kbdev->osdev.reg + offset);
653 }
654
655 u32 kbase_os_reg_read(kbase_device *kbdev, u16 offset)
656 {
657         return readl(kbdev->osdev.reg + offset);
658 }
659
660 static void *kbase_tag(void *ptr, u32 tag)
661 {
662         return (void *)(((uintptr_t) ptr) | tag);
663 }
664
665 static void *kbase_untag(void *ptr)
666 {
667         return (void *)(((uintptr_t) ptr) & ~3);
668 }
669
670 static irqreturn_t kbase_job_irq_handler(int irq, void *data)
671 {
672         struct kbase_device *kbdev      = kbase_untag(data);
673         u32 val;
674
675         val = kbase_reg_read(kbdev, JOB_CONTROL_REG(JOB_IRQ_RAWSTAT), NULL);
676         if (!val)
677         {
678                 return IRQ_NONE;
679         }
680
681         dev_dbg(kbdev->osdev.dev, "%s: irq %d rawstat 0x%x\n", __func__, irq, val);
682
683         kbase_job_done(kbdev, val);
684
685         return IRQ_HANDLED;
686 }
687
688 static irqreturn_t kbase_mmu_irq_handler(int irq, void *data)
689 {
690         struct kbase_device *kbdev      = kbase_untag(data);
691         u32 val;
692
693         val = kbase_reg_read(kbdev, MMU_REG(MMU_IRQ_STATUS), NULL);
694         if (!val)
695         {
696                 return IRQ_NONE;
697         }
698
699         dev_dbg(kbdev->osdev.dev, "%s: irq %d irqstatus 0x%x\n", __func__, irq, val);
700
701         kbase_mmu_interrupt(kbdev, val);
702
703         return IRQ_HANDLED;
704 }
705
706 static irqreturn_t kbase_gpu_irq_handler(int irq, void *data)
707 {
708         struct kbase_device *kbdev      = kbase_untag(data);
709         u32 val;
710
711         val = kbase_reg_read(kbdev, GPU_CONTROL_REG(GPU_IRQ_STATUS), NULL);
712
713         if (!val)
714         {
715                 return IRQ_NONE;
716         }
717
718         dev_dbg(kbdev->osdev.dev, "%s: irq %d rawstat 0x%x\n", __func__, irq, val);
719
720         kbase_gpu_interrupt(kbdev, val);
721
722         return IRQ_HANDLED;
723 }
724
725 static irq_handler_t kbase_handler_table[] = {
726         [JOB_IRQ_TAG] = kbase_job_irq_handler,
727         [MMU_IRQ_TAG] = kbase_mmu_irq_handler,
728         [GPU_IRQ_TAG] = kbase_gpu_irq_handler,
729 };
730
731 static int kbase_install_interrupts(kbase_device *kbdev)
732 {
733         struct kbase_os_device *osdev = &kbdev->osdev;
734         int nr = ARRAY_SIZE(kbase_handler_table);
735         int err;
736         u32 i;
737
738         BUG_ON(nr >= 4);        /* Only 3 interrupts! */
739
740         for (i = 0; i < nr; i++)
741         {
742                 err = request_irq(osdev->irqs[i].irq,
743                                   kbase_handler_table[i],
744                                   osdev->irqs[i].flags | IRQF_SHARED,
745                                   dev_name(osdev->dev), 
746                                   kbase_tag(kbdev, i));
747                 if (err)
748                 {
749                         dev_err(osdev->dev, "Can't request interrupt %d (index %d)\n", osdev->irqs[i].irq, i);
750                         goto release;
751                 }
752         }
753
754         return 0;
755
756 release:
757         while (i-- > 0)
758         {
759                 free_irq(osdev->irqs[i].irq, kbase_tag(kbdev, i));
760         }
761
762         return err;
763 }
764
765 static void kbase_release_interrupts(kbase_device *kbdev)
766 {
767         struct kbase_os_device *osdev = &kbdev->osdev;
768         int nr = ARRAY_SIZE(kbase_handler_table);
769         u32 i;
770
771         for (i = 0; i < nr; i++)
772         {
773                 if (osdev->irqs[i].irq)
774                 {
775                         free_irq(osdev->irqs[i].irq, kbase_tag(kbdev, i));
776                 }
777         }
778 }
779 #endif
780
781 #if MALI_LICENSE_IS_GPL
782
783 /** Show callback for the @c power_policy sysfs file.
784  *
785  * This function is called to get the contents of the @c power_policy sysfs
786  * file. This is a list of the available policies with the currently active one
787  * surrounded by square brackets.
788  *
789  * @param dev   The device this sysfs file is for
790  * @param attr  The attributes of the sysfs file
791  * @param buf   The output buffer for the sysfs file contents
792  *
793  * @return The number of bytes output to @c buf.
794  */
795 static ssize_t show_policy(struct device *dev, struct device_attribute *attr, char *buf)
796 {
797         struct kbase_device *kbdev;
798         const struct kbase_pm_policy *current_policy;
799         const struct kbase_pm_policy * const *policy_list;
800         int policy_count;
801         int i;
802         ssize_t ret = 0;
803
804         kbdev = to_kbase_device(dev);
805
806         if (!kbdev)
807         {
808                 return -ENODEV;
809         }
810
811         current_policy = kbase_pm_get_policy(kbdev);
812
813         policy_count = kbase_pm_list_policies(&policy_list);
814
815         for(i=0; i<policy_count && ret<PAGE_SIZE; i++)
816         {
817                 if (policy_list[i] == current_policy)
818                 {
819                         ret += scnprintf(buf+ret, PAGE_SIZE - ret, "[%s] ", policy_list[i]->name);
820                 }
821                 else
822                 {
823                         ret += scnprintf(buf+ret, PAGE_SIZE - ret, "%s ", policy_list[i]->name);
824                 }
825         }
826
827         if (ret < PAGE_SIZE - 1)
828         {
829                 ret += scnprintf(buf+ret, PAGE_SIZE-ret, "\n");
830         }
831         else
832         {
833                 buf[PAGE_SIZE-2] = '\n';
834                 buf[PAGE_SIZE-1] = '\0';
835                 ret = PAGE_SIZE-1;
836         }
837
838         return ret;
839 }
840
841 /** Store callback for the @c power_policy sysfs file.
842  *
843  * This function is called when the @c power_policy sysfs file is written to.
844  * It matches the requested policy against the available policies and if a
845  * matching policy is found calls @ref kbase_pm_set_policy to change the
846  * policy.
847  *
848  * @param dev   The device with sysfs file is for
849  * @param attr  The attributes of the sysfs file
850  * @param buf   The value written to the sysfs file
851  * @param count The number of bytes written to the sysfs file
852  *
853  * @return @c count if the function succeeded. An error code on failure.
854  */
855 static ssize_t set_policy(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
856 {
857         struct kbase_device *kbdev;
858         const struct kbase_pm_policy *new_policy = NULL;
859         const struct kbase_pm_policy * const *policy_list;
860         int policy_count;
861         int i;
862
863         kbdev = to_kbase_device(dev);
864
865         if (!kbdev)
866         {
867                 return -ENODEV;
868         }
869
870         policy_count = kbase_pm_list_policies(&policy_list);
871
872         for(i=0; i<policy_count; i++)
873         {
874                 if (sysfs_streq(policy_list[i]->name, buf))
875                 {
876                         new_policy = policy_list[i];
877                         break;
878                 }
879         }
880
881         if (!new_policy)
882         {
883                 dev_err(dev, "power_policy: policy not found\n");
884                 return -EINVAL;
885         }
886
887         kbase_pm_set_policy(kbdev, new_policy);
888         return count;
889 }
890
891 /** The sysfs file @c power_policy.
892  *
893  * This is used for obtaining information about the available policies,
894  * determining which policy is currently active, and changing the active
895  * policy.
896  */
897 DEVICE_ATTR(power_policy, S_IRUGO|S_IWUSR, show_policy, set_policy);
898
899 #if  MALI_LICENSE_IS_GPL && (MALI_CUSTOMER_RELEASE == 0)
900 /** Store callback for the @c js_timeouts sysfs file.
901  *
902  * This function is called to get the contents of the @c js_timeouts sysfs
903  * file. This file contains five values separated by whitespace. The values
904  * are basically the same as KBASE_CONFIG_ATTR_JS_SOFT_STOP_TICKS,
905  * KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_SS, KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_NSS,
906  * KBASE_CONFIG_ATTR_JS_RESET_TICKS_SS, BASE_CONFIG_ATTR_JS_RESET_TICKS_NSS
907  * configuration values (in that order), with the difference that the js_timeout
908  * valus are expressed in MILLISECONDS.
909  *
910  * The js_timeouts sysfile file allows the current values in
911  * use by the job scheduler to get override. Note that a value needs to
912  * be other than 0 for it to override the current job scheduler value.
913  *
914  * @param dev   The device with sysfs file is for
915  * @param attr  The attributes of the sysfs file
916  * @param buf   The value written to the sysfs file
917  * @param count The number of bytes written to the sysfs file
918  *
919  * @return @c count if the function succeeded. An error code on failure.
920  */
921 static ssize_t set_js_timeouts(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
922 {
923         struct kbase_device *kbdev;
924         int items;
925         unsigned long js_soft_stop_ms;
926         unsigned long js_hard_stop_ms_ss;
927         unsigned long js_hard_stop_ms_nss;
928         unsigned long js_reset_ms_ss;
929         unsigned long js_reset_ms_nss;
930
931         kbdev = to_kbase_device(dev);
932         if (!kbdev)
933         {
934                 return -ENODEV;
935         }
936
937         items = sscanf(buf, "%lu %lu %lu %lu %lu", &js_soft_stop_ms, &js_hard_stop_ms_ss, &js_hard_stop_ms_nss, &js_reset_ms_ss, &js_reset_ms_nss);
938         if (items == 5)
939         {
940                 u64 ticks;
941
942                 ticks = js_soft_stop_ms * 1000000ULL;
943                 osk_divmod6432(&ticks, kbdev->js_data.scheduling_tick_ns);
944                 kbdev->js_soft_stop_ticks = ticks;
945
946                 ticks = js_hard_stop_ms_ss * 1000000ULL;
947                 osk_divmod6432(&ticks, kbdev->js_data.scheduling_tick_ns);
948                 kbdev->js_hard_stop_ticks_ss = ticks;
949
950                 ticks = js_hard_stop_ms_nss * 1000000ULL;
951                 osk_divmod6432(&ticks, kbdev->js_data.scheduling_tick_ns);
952                 kbdev->js_hard_stop_ticks_nss = ticks;
953
954                 ticks = js_reset_ms_ss * 1000000ULL;
955                 osk_divmod6432(&ticks, kbdev->js_data.scheduling_tick_ns);
956                 kbdev->js_reset_ticks_ss = ticks;
957
958                 ticks = js_reset_ms_nss * 1000000ULL;
959                 osk_divmod6432(&ticks, kbdev->js_data.scheduling_tick_ns);
960                 kbdev->js_reset_ticks_nss = ticks;
961
962                 dev_info(kbdev->osdev.dev, "Overriding KBASE_CONFIG_ATTR_JS_SOFT_STOP_TICKS with %lu ticks (%lu ms)\n", (unsigned long)kbdev->js_soft_stop_ticks, js_soft_stop_ms);
963                 dev_info(kbdev->osdev.dev, "Overriding KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_SS with %lu ticks (%lu ms)\n", (unsigned long)kbdev->js_hard_stop_ticks_ss, js_hard_stop_ms_ss);
964                 dev_info(kbdev->osdev.dev, "Overriding KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_NSS with %lu ticks (%lu ms)\n", (unsigned long)kbdev->js_hard_stop_ticks_nss, js_hard_stop_ms_nss);
965                 dev_info(kbdev->osdev.dev, "Overriding KBASE_CONFIG_ATTR_JS_RESET_TICKS_SS with %lu ticks (%lu ms)\n", (unsigned long)kbdev->js_reset_ticks_ss, js_reset_ms_ss);
966                 dev_info(kbdev->osdev.dev, "Overriding KBASE_CONFIG_ATTR_JS_RESET_TICKS_NSS with %lu ticks (%lu ms)\n", (unsigned long)kbdev->js_reset_ticks_nss, js_reset_ms_nss);
967
968                 return count;
969         }
970         else
971         {
972                 dev_err(kbdev->osdev.dev, "Couldn't process js_timeouts write operation.\nUse format "
973                                           "<soft_stop_ms> <hard_stop_ms_ss> <hard_stop_ms_nss> <reset_ms_ss> <reset_ms_nss>\n");
974                 return -EINVAL;
975         }
976 }
977
978 /** Show callback for the @c js_timeouts sysfs file.
979  *
980  * This function is called to get the contents of the @c js_timeouts sysfs
981  * file. It returns the last set values written to the js_timeouts sysfs file.
982  * If the file didn't get written yet, the values will be 0.
983  *
984  * @param dev   The device this sysfs file is for
985  * @param attr  The attributes of the sysfs file
986  * @param buf   The output buffer for the sysfs file contents
987  *
988  * @return The number of bytes output to @c buf.
989  */
990 static ssize_t show_js_timeouts(struct device *dev, struct device_attribute *attr, char *buf)
991 {
992         struct kbase_device *kbdev;
993         ssize_t ret;
994         u64 ms;
995         unsigned long js_soft_stop_ms;
996         unsigned long js_hard_stop_ms_ss;
997         unsigned long js_hard_stop_ms_nss;
998         unsigned long js_reset_ms_ss;
999         unsigned long js_reset_ms_nss;
1000
1001         kbdev = to_kbase_device(dev);
1002         if (!kbdev)
1003         {
1004                 return -ENODEV;
1005         }
1006
1007         ms = (u64)kbdev->js_soft_stop_ticks * kbdev->js_data.scheduling_tick_ns;
1008         osk_divmod6432(&ms, 1000000UL);
1009         js_soft_stop_ms = (unsigned long)ms;
1010
1011         ms = (u64)kbdev->js_hard_stop_ticks_ss * kbdev->js_data.scheduling_tick_ns;
1012         osk_divmod6432(&ms, 1000000UL);
1013         js_hard_stop_ms_ss = (unsigned long)ms;
1014
1015         ms = (u64)kbdev->js_hard_stop_ticks_nss * kbdev->js_data.scheduling_tick_ns;
1016         osk_divmod6432(&ms, 1000000UL);
1017         js_hard_stop_ms_nss = (unsigned long)ms;
1018
1019         ms = (u64)kbdev->js_reset_ticks_ss * kbdev->js_data.scheduling_tick_ns;
1020         osk_divmod6432(&ms, 1000000UL);
1021         js_reset_ms_ss = (unsigned long)ms;
1022
1023         ms = (u64)kbdev->js_reset_ticks_nss * kbdev->js_data.scheduling_tick_ns;
1024         osk_divmod6432(&ms, 1000000UL);
1025         js_reset_ms_nss = (unsigned long)ms;
1026
1027         ret = scnprintf(buf, PAGE_SIZE, "%lu %lu %lu %lu %lu\n", js_soft_stop_ms, js_hard_stop_ms_ss, js_hard_stop_ms_nss, js_reset_ms_ss, js_reset_ms_nss);
1028
1029         if (ret >= PAGE_SIZE )
1030         {
1031                 buf[PAGE_SIZE-2] = '\n';
1032                 buf[PAGE_SIZE-1] = '\0';
1033                 ret = PAGE_SIZE-1;
1034         }
1035
1036         return ret;
1037 }
1038 /** The sysfs file @c js_timeouts.
1039  *
1040  * This is used to override the current job scheduler values for
1041  * KBASE_CONFIG_ATTR_JS_STOP_STOP_TICKS_SS
1042  * KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_SS
1043  * KBASE_CONFIG_ATTR_JS_HARD_STOP_TICKS_NSS
1044  * KBASE_CONFIG_ATTR_JS_RESET_TICKS_SS
1045  * KBASE_CONFIG_ATTR_JS_RESET_TICKS_NSS.
1046  */
1047 DEVICE_ATTR(js_timeouts, S_IRUGO|S_IWUSR, show_js_timeouts, set_js_timeouts);
1048 #endif  /* MALI_LICENSE_IS_GPL && (MALI_CUSTOMER_RELEASE == 0) */
1049
1050 #if MALI_DEBUG
1051 typedef void (kbasep_debug_command_func)( kbase_device * );
1052
1053 typedef enum
1054 {
1055         KBASEP_DEBUG_COMMAND_DUMPTRACE,
1056
1057         /* This must be the last enum */
1058         KBASEP_DEBUG_COMMAND_COUNT
1059 } kbasep_debug_command_code;
1060
1061 typedef struct kbasep_debug_command
1062 {
1063         char *str;
1064         kbasep_debug_command_func *func;
1065 } kbasep_debug_command;
1066
1067 /** Debug commands supported by the driver */
1068 static const kbasep_debug_command debug_commands[] =
1069 {
1070         {
1071                 .str = "dumptrace",
1072                 .func = &kbasep_trace_dump,
1073         }
1074 };
1075
1076 /** Show callback for the @c debug_command sysfs file.
1077  *
1078  * This function is called to get the contents of the @c debug_command sysfs
1079  * file. This is a list of the available debug commands, separated by newlines.
1080  *
1081  * @param dev   The device this sysfs file is for
1082  * @param attr  The attributes of the sysfs file
1083  * @param buf   The output buffer for the sysfs file contents
1084  *
1085  * @return The number of bytes output to @c buf.
1086  */
1087 static ssize_t show_debug(struct device *dev, struct device_attribute *attr, char *buf)
1088 {
1089         struct kbase_device *kbdev;
1090         int i;
1091         ssize_t ret = 0;
1092
1093         kbdev = to_kbase_device(dev);
1094
1095         if (!kbdev)
1096         {
1097                 return -ENODEV;
1098         }
1099
1100         for(i=0; i<KBASEP_DEBUG_COMMAND_COUNT && ret<PAGE_SIZE; i++)
1101         {
1102                 ret += scnprintf(buf+ret, PAGE_SIZE - ret, "%s\n", debug_commands[i].str);
1103         }
1104
1105         if (ret >= PAGE_SIZE )
1106         {
1107                 buf[PAGE_SIZE-2] = '\n';
1108                 buf[PAGE_SIZE-1] = '\0';
1109                 ret = PAGE_SIZE-1;
1110         }
1111
1112         return ret;
1113 }
1114
1115 /** Store callback for the @c debug_command sysfs file.
1116  *
1117  * This function is called when the @c debug_command sysfs file is written to.
1118  * It matches the requested command against the available commands, and if
1119  * a matching command is found calls the associated function from
1120  * @ref debug_commands to issue the command.
1121  *
1122  * @param dev   The device with sysfs file is for
1123  * @param attr  The attributes of the sysfs file
1124  * @param buf   The value written to the sysfs file
1125  * @param count The number of bytes written to the sysfs file
1126  *
1127  * @return @c count if the function succeeded. An error code on failure.
1128  */
1129 static ssize_t issue_debug(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
1130 {
1131         struct kbase_device *kbdev;
1132         int i;
1133
1134         kbdev = to_kbase_device(dev);
1135
1136         if (!kbdev)
1137         {
1138                 return -ENODEV;
1139         }
1140
1141         for(i=0; i<KBASEP_DEBUG_COMMAND_COUNT; i++)
1142         {
1143                 if (sysfs_streq(debug_commands[i].str, buf))
1144                 {
1145                         debug_commands[i].func( kbdev );
1146                         return count;
1147                 }
1148         }
1149
1150         /* Debug Command not found */
1151         dev_err(dev, "debug_command: command not known\n");
1152         return -EINVAL;
1153 }
1154
1155 /** The sysfs file @c debug_command.
1156  *
1157  * This is used to issue general debug commands to the device driver.
1158  * Reading it will produce a list of debug commands, separated by newlines.
1159  * Writing to it with one of those commands will issue said command.
1160  */
1161 DEVICE_ATTR(debug_command, S_IRUGO|S_IWUSR, show_debug, issue_debug);
1162 #endif /*MALI_DEBUG*/
1163 #endif /*MALI_LICENSE_IS_GPL*/
1164
1165 static int kbase_common_device_init(kbase_device *kbdev)
1166 {
1167         struct kbase_os_device  *osdev = &kbdev->osdev;
1168         int err = -ENOMEM;
1169         mali_error mali_err;
1170         enum
1171         {
1172                  inited_mem         = (1u << 0),
1173                  inited_job_slot    = (1u << 1),
1174                  inited_pm          = (1u << 2),
1175                  inited_js          = (1u << 3),
1176                  inited_irqs        = (1u << 4)
1177 #if MALI_LICENSE_IS_GPL
1178                 ,inited_debug       = (1u << 5)
1179 #endif
1180 #if MALI_CUSTOMER_RELEASE == 0
1181                 ,inited_js_timeouts = (1u << 6)
1182 #endif
1183 #if BASE_HW_ISSUE_8401
1184                 ,inited_workaround  = (1u << 7)
1185 #endif
1186         };
1187
1188         int inited = 0;
1189         
1190         osdev->reg_res = request_mem_region(osdev->reg_start,
1191                                             osdev->reg_size,
1192 #if MALI_LICENSE_IS_GPL
1193                                             dev_name(osdev->dev)
1194 #else
1195                                             mali_dev_name
1196 #endif
1197                                         );
1198         if (!osdev->reg_res)
1199         {
1200                 dev_err(osdev->dev, "Register window unavailable\n");
1201                 err = -EIO;
1202                 goto out_region;
1203         }
1204
1205         osdev->reg = ioremap(osdev->reg_start, osdev->reg_size);
1206         if (!osdev->reg)
1207         {
1208                 dev_err(osdev->dev, "Can't remap register window\n");
1209                 err = -EINVAL;
1210                 goto out_ioremap;
1211         }
1212 #if MALI_LICENSE_IS_GPL
1213         dev_set_drvdata(osdev->dev, kbdev);
1214         osdev->mdev.minor       = MISC_DYNAMIC_MINOR;
1215         osdev->mdev.name        = osdev->devname;
1216         osdev->mdev.fops        = &kbase_fops;
1217         osdev->mdev.parent      = get_device(osdev->dev);
1218 #endif
1219
1220         scnprintf(osdev->devname, DEVNAME_SIZE, "%s%d", kbase_drv_name, kbase_dev_nr++);
1221
1222 #if MALI_LICENSE_IS_GPL
1223         if (misc_register(&osdev->mdev))
1224         {
1225                 dev_err(osdev->dev, "Couldn't register misc dev %s\n", osdev->devname);
1226                 err = -EINVAL;
1227                 goto out_misc;
1228         }
1229
1230         if (device_create_file(osdev->dev, &dev_attr_power_policy))
1231         {
1232                 dev_err(osdev->dev, "Couldn't create power_policy sysfs file\n");
1233                 goto out_file;
1234         }
1235
1236 #ifdef CONFIG_VITHAR
1237         if(kbase_platform_init(osdev->dev))
1238         {
1239                 dev_err(osdev->dev, "kbase_platform_init failed\n");
1240                 goto out_file;
1241         }
1242 #endif
1243         down(&kbase_dev_list_lock);
1244         list_add(&osdev->entry, &kbase_dev_list);
1245         up(&kbase_dev_list_lock);
1246         dev_info(osdev->dev, "Probed as %s\n", dev_name(osdev->mdev.this_device));
1247 #endif
1248
1249 #if MALI_NO_MALI
1250         mali_err = midg_device_create(kbdev);
1251         if (MALI_ERROR_NONE != mali_err)
1252         {
1253                 goto out_kbdev;
1254         }
1255 #endif
1256
1257         mali_err = kbase_pm_init(kbdev);
1258         if (MALI_ERROR_NONE != mali_err)
1259         {
1260                 goto out_partial;
1261         }
1262         inited |= inited_pm;
1263
1264         mali_err = kbase_mem_init(kbdev);
1265         if (MALI_ERROR_NONE != mali_err)
1266         {
1267                 goto out_partial;
1268         }
1269         inited |= inited_mem;
1270
1271         mali_err = kbase_job_slot_init(kbdev);
1272         if (MALI_ERROR_NONE != mali_err)
1273         {
1274                 goto out_partial;
1275         }
1276         inited |= inited_job_slot;
1277
1278         mali_err = kbasep_js_devdata_init(kbdev);
1279         if (MALI_ERROR_NONE != mali_err)
1280         {
1281                 goto out_partial;
1282         }
1283         inited |= inited_js;
1284
1285         err = kbase_install_interrupts(kbdev);
1286         if (err)
1287         {
1288                 goto out_partial;
1289         }
1290         inited |= inited_irqs;
1291
1292 #if MALI_LICENSE_IS_GPL
1293 #if MALI_DEBUG
1294         if (device_create_file(osdev->dev, &dev_attr_debug_command))
1295         {
1296                 dev_err(osdev->dev, "Couldn't create debug_command sysfs file\n");
1297                 goto out_partial;
1298         }
1299         inited |= inited_debug;
1300
1301 #endif
1302 #if MALI_CUSTOMER_RELEASE == 0
1303         if (device_create_file(osdev->dev, &dev_attr_js_timeouts))
1304         {
1305                 dev_err(osdev->dev, "Couldn't create js_timeouts sysfs file\n");
1306                 goto out_partial;
1307         }
1308         inited |= inited_js_timeouts;
1309 #endif
1310 #endif /*MALI_LICENSE_IS_GPL*/
1311
1312 #if BASE_HW_ISSUE_8401
1313         if (MALI_ERROR_NONE != kbasep_8401_workaround_init(kbdev))
1314         {
1315                 goto out_partial;
1316         }
1317         inited |= inited_workaround;
1318 #endif
1319
1320         mali_err = kbase_pm_powerup(kbdev);
1321         if (MALI_ERROR_NONE == mali_err)
1322         {
1323                 kbase_gpuprops_set(kbdev);
1324                 return 0;
1325         }
1326
1327 out_partial:
1328 #if BASE_HW_ISSUE_8401
1329         if (inited & inited_workaround)
1330         {
1331                 kbasep_8401_workaround_term(kbdev);
1332         }
1333 #endif
1334
1335 #if MALI_LICENSE_IS_GPL
1336 #if MALI_CUSTOMER_RELEASE == 0
1337         if (inited & inited_js_timeouts)
1338         {
1339                 device_remove_file(kbdev->osdev.dev, &dev_attr_js_timeouts);
1340         }
1341 #endif
1342 #if MALI_DEBUG
1343         if (inited & inited_debug)
1344         {
1345                 device_remove_file(kbdev->osdev.dev, &dev_attr_debug_command);
1346         }
1347 #endif
1348 #endif /*MALI_LICENSE_IS_GPL*/
1349
1350         if (inited & inited_js)
1351         {
1352                 kbasep_js_devdata_halt(kbdev);
1353         }
1354         if (inited & inited_job_slot)
1355         {
1356                 kbase_job_slot_halt(kbdev);
1357         }
1358         if (inited & inited_mem)
1359         {
1360                 kbase_mem_halt(kbdev);
1361         }
1362         if (inited & inited_pm)
1363         {
1364                 kbase_pm_halt(kbdev);
1365         }
1366
1367         if (inited & inited_irqs)
1368         {
1369                 kbase_release_interrupts(kbdev);
1370         }
1371
1372         if (inited & inited_js)
1373         {
1374                 kbasep_js_devdata_term(kbdev);
1375         }
1376         if (inited & inited_job_slot)
1377         {
1378                 kbase_job_slot_term(kbdev);
1379         }
1380         if (inited & inited_mem)
1381         {
1382                 kbase_mem_term(kbdev);
1383         }
1384         if (inited & inited_pm)
1385         {
1386                 kbase_pm_term(kbdev);
1387         }
1388
1389 #if MALI_NO_MALI
1390         midg_device_destroy(kbdev);
1391 out_kbdev:
1392 #endif
1393
1394 #if MALI_LICENSE_IS_GPL
1395         down(&kbase_dev_list_lock);
1396         list_del(&osdev->entry);
1397         up(&kbase_dev_list_lock);
1398
1399         device_remove_file(kbdev->osdev.dev, &dev_attr_power_policy);
1400 #ifdef CONFIG_VITHAR
1401         kbase_platform_remove_sysfs_file(kbdev->osdev.dev);
1402 #endif
1403 out_file:
1404         misc_deregister(&kbdev->osdev.mdev);
1405 out_misc:
1406         put_device(osdev->dev);
1407 #endif
1408         iounmap(osdev->reg);
1409 out_ioremap:
1410         release_resource(osdev->reg_res);
1411         kfree(osdev->reg_res);
1412 out_region:
1413         return err;
1414 }
1415
1416 #if MALI_LICENSE_IS_GPL
1417
1418 static kbase_attribute pci_attributes[] =
1419 {
1420         {
1421                 KBASE_CONFIG_ATTR_MEMORY_PER_PROCESS_LIMIT,
1422                 512 * 1024 * 1024UL /* 512MB */
1423         },
1424         {
1425                 KBASE_CONFIG_ATTR_UMP_DEVICE,
1426                 UMP_DEVICE_Z_SHIFT
1427         },
1428         {
1429                 KBASE_CONFIG_ATTR_MEMORY_OS_SHARED_MAX,
1430                 768 * 1024 * 1024UL /* 768MB */
1431         },
1432         {
1433                 KBASE_CONFIG_ATTR_END,
1434                 0
1435         }
1436 };
1437
1438 static int kbase_pci_device_probe(struct pci_dev *pdev,
1439                                   const struct pci_device_id *pci_id)
1440 {
1441         const kbase_device_info *dev_info;
1442         kbase_device            *kbdev;
1443         kbase_os_device         *osdev;
1444         kbase_attribute     *platform_data;
1445         int err;
1446
1447         dev_info = &kbase_dev_info[pci_id->driver_data];
1448         kbdev = kbase_device_create(dev_info);
1449         if (!kbdev)
1450         {
1451                 dev_err(&pdev->dev, "Can't allocate device\n");
1452                 err = -ENOMEM;
1453                 goto out;
1454         }
1455
1456         osdev = &kbdev->osdev;
1457         osdev->dev = &pdev->dev;
1458         platform_data = (kbase_attribute *)osdev->dev->platform_data;
1459
1460         err = pci_enable_device(pdev);
1461         if (err)
1462         {
1463                 goto out_free_dev;
1464         }
1465
1466         osdev->reg_start = pci_resource_start(pdev, 0);
1467         osdev->reg_size = pci_resource_len(pdev, 0);
1468         if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM))
1469         {
1470                 err = -EINVAL;
1471                 goto out_disable;
1472         }
1473
1474         osdev->irqs[0].irq = pdev->irq;
1475         osdev->irqs[1].irq = pdev->irq;
1476         osdev->irqs[2].irq = pdev->irq;
1477
1478         pci_set_master(pdev);
1479
1480         if (MALI_TRUE != kbasep_validate_configuration_attributes(pci_attributes))
1481         {
1482                 err = -EINVAL;
1483                 goto out_disable;
1484         }
1485         /* Use the master passed in instead of the pci attributes */
1486         kbdev->config_attributes = platform_data;
1487
1488         kbdev->memdev.ump_device_id = kbasep_get_config_value(pci_attributes,
1489                         KBASE_CONFIG_ATTR_UMP_DEVICE);
1490         kbdev->memdev.per_process_memory_limit = kbasep_get_config_value(pci_attributes,
1491                         KBASE_CONFIG_ATTR_MEMORY_PER_PROCESS_LIMIT);
1492
1493         err = kbase_register_memory_regions(kbdev, pci_attributes);
1494         if (err)
1495         {
1496                 goto out_disable;
1497         }
1498
1499         /* obtain min/max configured gpu frequencies */
1500         {
1501                 struct mali_base_gpu_core_props *core_props = &(kbdev->gpu_props.props.core_props);
1502                 core_props->gpu_freq_khz_min = kbasep_get_config_value(platform_data,
1503                                                                                                                            KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MIN);
1504                 core_props->gpu_freq_khz_max = kbasep_get_config_value(platform_data,
1505                                                                                                                            KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MAX);
1506         }
1507
1508         err = kbase_common_device_init(kbdev);
1509         if (err)
1510         {
1511                 goto out_disable;
1512         }
1513
1514         return 0;
1515
1516 out_disable:
1517         pci_disable_device(pdev);
1518 out_free_dev:
1519         kbase_device_destroy(kbdev);
1520 out:
1521         return err;
1522 }
1523
1524 static int kbase_platform_device_probe(struct platform_device *pdev)
1525 {
1526         struct kbase_device     *kbdev;
1527         kbase_device_info       *dev_info;
1528         struct kbase_os_device  *osdev;
1529         struct resource         *reg_res;
1530         kbase_attribute     *platform_data;
1531         int                     err;
1532         int                     i;
1533
1534         dev_info = (kbase_device_info *)pdev->id_entry->driver_data;
1535         kbdev = kbase_device_create(dev_info);
1536
1537         if (!kbdev)
1538         {
1539                 dev_err(&pdev->dev, "Can't allocate device\n");
1540                 err = -ENOMEM;
1541                 goto out;
1542         }
1543
1544         osdev = &kbdev->osdev;
1545         osdev->dev = &pdev->dev;
1546         platform_data = (kbase_attribute *)osdev->dev->platform_data;
1547
1548         if (NULL == platform_data)
1549         {
1550                 dev_err(osdev->dev, "Platform data not specified\n");
1551                 err = -ENOENT;
1552                 goto out_free_dev;
1553         }
1554
1555         if (MALI_TRUE != kbasep_validate_configuration_attributes(platform_data))
1556         {
1557                 dev_err(osdev->dev, "Configuration attributes failed to validate\n");
1558                 err = -EINVAL;
1559                 goto out_free_dev;
1560         }
1561         kbdev->config_attributes = platform_data;
1562
1563         kbdev->memdev.ump_device_id = kbasep_get_config_value(platform_data,
1564                         KBASE_CONFIG_ATTR_UMP_DEVICE);
1565         kbdev->memdev.per_process_memory_limit = kbasep_get_config_value(platform_data,
1566                         KBASE_CONFIG_ATTR_MEMORY_PER_PROCESS_LIMIT);
1567
1568         /* obtain min/max configured gpu frequencies */
1569         {
1570                 struct mali_base_gpu_core_props *core_props = &(kbdev->gpu_props.props.core_props);
1571                 core_props->gpu_freq_khz_min = kbasep_get_config_value(platform_data,
1572                                                                                                                            KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MIN);
1573                 core_props->gpu_freq_khz_max = kbasep_get_config_value(platform_data,
1574                                                                                                                            KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MAX);
1575         }
1576
1577         /* 3 IRQ resources */
1578         for (i = 0; i < 3; i++)
1579         {
1580                 struct resource *irq_res;
1581
1582                 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
1583                 if (!irq_res)
1584                 {
1585                         dev_err(osdev->dev, "No IRQ resource at index %d\n", i);
1586                         err = -ENOENT;
1587                         goto out_free_dev;
1588                 }
1589
1590                 osdev->irqs[i].irq = irq_res->start;
1591                 osdev->irqs[i].flags = (irq_res->flags & IRQF_TRIGGER_MASK);
1592         }
1593
1594         /* the first memory resource is the physical address of the GPU registers */
1595         reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1596         if (!reg_res)
1597         {
1598                 dev_err(&pdev->dev, "Invalid register resource\n");
1599                 err = -ENOENT;
1600                 goto out_free_dev;
1601         }
1602
1603         osdev->reg_start = reg_res->start;
1604         osdev->reg_size = resource_size(reg_res);
1605
1606         err = kbase_register_memory_regions(kbdev, (kbase_attribute *)osdev->dev->platform_data);
1607         if (err)
1608         {
1609                 dev_err(osdev->dev, "Failed to register memory regions\n");
1610                 goto out_free_dev;
1611         }
1612
1613         err = kbase_common_device_init(kbdev);
1614         if (err)
1615         {
1616                 dev_err(osdev->dev, "Failed kbase_common_device_init\n");
1617                 goto out_free_dev;
1618         }
1619         return 0;
1620
1621 out_free_dev:
1622         kbase_device_destroy(kbdev);
1623 out:
1624         return err;
1625 }
1626 #endif /* MALI_LICENSE_IS_GPL */
1627
1628 static int kbase_common_device_remove(struct kbase_device *kbdev)
1629 {
1630 #if BASE_HW_ISSUE_8401
1631         kbasep_8401_workaround_term(kbdev);
1632 #endif
1633 #if MALI_LICENSE_IS_GPL
1634         /* Remove the sys power policy file */
1635         device_remove_file(kbdev->osdev.dev, &dev_attr_power_policy);
1636 #if MALI_DEBUG
1637         device_remove_file(kbdev->osdev.dev, &dev_attr_debug_command);
1638 #endif
1639 #endif
1640 #ifdef CONFIG_VITHAR
1641         kbase_platform_remove_sysfs_file(kbdev->osdev.dev);
1642         kbase_platform_term(kbdev->osdev.dev);
1643 #endif
1644         kbasep_js_devdata_halt(kbdev);
1645         kbase_job_slot_halt(kbdev);
1646         kbase_mem_halt(kbdev);
1647         kbase_pm_halt(kbdev);
1648
1649         kbase_release_interrupts(kbdev);
1650
1651         kbasep_js_devdata_term(kbdev);
1652         kbase_job_slot_term(kbdev);
1653         kbase_mem_term(kbdev);
1654         kbase_pm_term(kbdev);
1655
1656 #if MALI_NO_MALI
1657         midg_device_destroy(kbdev);
1658 #endif
1659
1660 #if MALI_LICENSE_IS_GPL
1661         down(&kbase_dev_list_lock);
1662         list_del(&kbdev->osdev.entry);
1663         up(&kbase_dev_list_lock);
1664         misc_deregister(&kbdev->osdev.mdev);
1665         put_device(kbdev->osdev.dev);
1666 #endif
1667         iounmap(kbdev->osdev.reg);
1668         release_resource(kbdev->osdev.reg_res);
1669         kfree(kbdev->osdev.reg_res);
1670
1671         kbase_device_destroy(kbdev);
1672
1673         return 0;
1674 }
1675
1676
1677 #if MALI_LICENSE_IS_GPL
1678 static void kbase_pci_device_remove(struct pci_dev *pdev)
1679 {
1680         struct kbase_device *kbdev = to_kbase_device(&pdev->dev);
1681
1682         if (!kbdev)
1683         {
1684                 return;
1685         }
1686
1687         kbase_common_device_remove(kbdev);
1688         pci_disable_device(pdev);
1689 }
1690
1691 static int kbase_platform_device_remove(struct platform_device *pdev)
1692 {
1693         struct kbase_device *kbdev = to_kbase_device(&pdev->dev);
1694
1695         if (!kbdev)
1696         {
1697                 return -ENODEV;
1698         }
1699
1700         return kbase_common_device_remove(kbdev);
1701 }
1702
1703 /** Suspend callback from the OS.
1704  *
1705  * This is called by Linux when the device should suspend.
1706  *
1707  * @param dev   The device to suspend
1708  *
1709  * @return A standard Linux error code
1710  */
1711 static int kbase_device_suspend(struct device *dev)
1712 {
1713         struct kbase_device *kbdev = to_kbase_device(dev);
1714
1715         if (!kbdev)
1716         {
1717                 return -ENODEV;
1718         }
1719
1720         /* Send the event to the power policy */
1721         kbase_pm_send_event(kbdev, KBASE_PM_EVENT_SYSTEM_SUSPEND);
1722
1723         /* Wait for the policy to suspend the device */
1724         kbase_pm_wait_for_power_down(kbdev);
1725
1726 #ifdef CONFIG_VITHAR
1727         kbase_platform_cmu_pmu_control(dev, 0);
1728 #endif
1729
1730         return 0;
1731 }
1732
1733 /** Resume callback from the OS.
1734  *
1735  * This is called by Linux when the device should resume from suspension.
1736  *
1737  * @param dev   The device to resume
1738  *
1739  * @return A standard Linux error code
1740  */
1741 static int kbase_device_resume(struct device *dev)
1742 {
1743         struct kbase_device *kbdev = to_kbase_device(dev);
1744
1745         if (!kbdev)
1746         {
1747                 return -ENODEV;
1748         }
1749 #ifdef CONFIG_VITHAR
1750         kbase_platform_cmu_pmu_control(dev, 1);
1751 #endif
1752
1753         /* Send the event to the power policy */
1754         kbase_pm_send_event(kbdev, KBASE_PM_EVENT_SYSTEM_RESUME);
1755
1756         /* Wait for the policy to resume the device */
1757         kbase_pm_wait_for_power_up(kbdev);
1758
1759         return 0;
1760 }
1761
1762 #define kbdev_info(x) ((kernel_ulong_t)&kbase_dev_info[(x)])
1763
1764 static struct platform_device_id kbase_platform_id_table[] =
1765 {
1766         {
1767                 .name           = "mali-t6xm",
1768                 .driver_data    = kbdev_info(KBASE_MALI_T6XM),
1769         },
1770         {
1771                 .name           = "mali-t6f1",
1772                 .driver_data    = kbdev_info(KBASE_MALI_T6F1),
1773         },
1774         {
1775                 .name           = "mali-t601",
1776                 .driver_data    = kbdev_info(KBASE_MALI_T601),
1777         },
1778         {
1779                 .name           = "mali-t604",
1780                 .driver_data    = kbdev_info(KBASE_MALI_T604),
1781         },
1782         {
1783                 .name           = "mali-t608",
1784                 .driver_data    = kbdev_info(KBASE_MALI_T608),
1785         },
1786         {},
1787 };
1788
1789 MODULE_DEVICE_TABLE(platform, kbase_platform_id_table);
1790
1791 static DEFINE_PCI_DEVICE_TABLE(kbase_pci_id_table) =
1792 {
1793         { PCI_DEVICE(0x13b5, 0x6956), 0, 0, KBASE_MALI_T6XM },
1794         {},
1795 };
1796 MODULE_DEVICE_TABLE(pci, kbase_pci_id_table);
1797
1798 /** The power management operations for the platform driver.
1799  */
1800 static struct dev_pm_ops kbase_pm_ops =
1801 {
1802         .suspend        = kbase_device_suspend,
1803         .resume         = kbase_device_resume,
1804 #ifdef CONFIG_VITHAR_RT_PM
1805         .runtime_suspend        = kbase_device_runtime_suspend,
1806         .runtime_resume         = kbase_device_runtime_resume,
1807 #endif
1808 };
1809
1810 static struct platform_driver kbase_platform_driver =
1811 {
1812         .probe          = kbase_platform_device_probe,
1813         .remove         = kbase_platform_device_remove,
1814         .driver         =
1815         {
1816                 .name           = kbase_drv_name,
1817                 .owner          = THIS_MODULE,
1818                 .pm             = &kbase_pm_ops,
1819         },
1820         .id_table       = kbase_platform_id_table,
1821 };
1822
1823 static struct pci_driver kbase_pci_driver =
1824 {
1825         .name           = KBASE_DRV_NAME,
1826         .probe          = kbase_pci_device_probe,
1827         .remove         = kbase_pci_device_remove,
1828         .id_table       = kbase_pci_id_table,
1829 };
1830 #endif /* MALI_LICENSE_IS_GPL */
1831
1832 #if MALI_LICENSE_IS_GPL && MALI_FAKE_PLATFORM_DEVICE
1833 static struct platform_device *mali_device;
1834 #endif /* MALI_LICENSE_IS_GPL && MALI_FAKE_PLATFORM_DEVICE */
1835
1836 #if MALI_LICENSE_IS_GPL
1837 static int __init kbase_driver_init(void)
1838 {
1839         int err;
1840 #if MALI_FAKE_PLATFORM_DEVICE
1841         kbase_platform_config *config;
1842         int attribute_count;
1843         struct resource resources[PLATFORM_CONFIG_RESOURCE_COUNT];
1844
1845         config = kbasep_get_platform_config();
1846         attribute_count = kbasep_get_config_attribute_count(config->attributes);
1847         mali_device = platform_device_alloc( kbasep_midgard_type_to_string(config->midgard_type), 0);
1848         if (mali_device == NULL)
1849         {
1850                 return -ENOMEM;
1851         }
1852
1853         kbasep_config_parse_io_resources(config->io_resources, resources);
1854         err = platform_device_add_resources(mali_device, resources, PLATFORM_CONFIG_RESOURCE_COUNT);
1855         if (err)
1856         {
1857                 platform_device_put(mali_device);
1858                 mali_device = NULL;
1859                 return err;
1860         }
1861
1862         err = platform_device_add_data(mali_device, config->attributes, attribute_count * sizeof(config->attributes[0]));
1863         if (err)
1864         {
1865                 platform_device_unregister(mali_device);
1866                 mali_device = NULL;
1867                 return err;
1868         }
1869
1870         err = platform_device_add(mali_device);
1871         if (err)
1872         {
1873                 platform_device_unregister(mali_device);
1874                 mali_device = NULL;
1875                 return err;
1876         }
1877
1878 #endif /* MALI_FAKE_PLATFORM_DEVICE */
1879         err = platform_driver_register(&kbase_platform_driver);
1880         if (err)
1881         {
1882                 return err;
1883         }
1884
1885         err = pci_register_driver(&kbase_pci_driver);
1886         if (err)
1887         {
1888                 platform_driver_unregister(&kbase_platform_driver);
1889                 return err;
1890         }
1891
1892         return 0;
1893 }
1894 #else
1895 static int __init kbase_driver_init(void)
1896 {
1897         kbase_platform_config   *config;
1898         struct kbase_device     *kbdev;
1899         const kbase_device_info *dev_info;
1900         kbase_os_device         *osdev;
1901         int                     err;
1902         dev_t                   dev = 0;
1903
1904         if (0 == mali_major)
1905         {
1906                 /* auto select a major */
1907                 err = alloc_chrdev_region(&dev, 0, 1, mali_dev_name);
1908                 mali_major = MAJOR(dev);
1909         }
1910         else
1911         {
1912                 /* use load time defined major number */
1913                 dev = MKDEV(mali_major, 0);
1914                 err = register_chrdev_region(dev, 1, mali_dev_name);
1915         }
1916
1917         if (0 != err)
1918         {
1919                 goto out_region;
1920         }
1921
1922         memset(&mali_linux_device, 0, sizeof(mali_linux_device));
1923
1924         /* initialize our char dev data */
1925         cdev_init(&mali_linux_device.cdev, &kbase_fops);
1926         mali_linux_device.cdev.owner = THIS_MODULE;
1927         mali_linux_device.cdev.ops = &kbase_fops;
1928
1929         /* register char dev with the kernel */
1930         err = cdev_add(&mali_linux_device.cdev, dev, 1/*count*/);
1931         if (0 != err)
1932         {
1933                 goto out_cdev_add;
1934         }
1935         config = kbasep_get_platform_config();
1936         if (MALI_TRUE != kbasep_validate_configuration_attributes(config->attributes))
1937         {
1938                 err = -EINVAL;
1939                 goto out_validate_attributes;
1940         }
1941
1942         dev_info = &kbase_dev_info[config->midgard_type];
1943         kbdev = kbase_device_create(dev_info);
1944         if (!kbdev)
1945         {
1946                 dev_err(&pdev->dev, "Can't allocate device\n");
1947                 err = -ENOMEM;
1948                 goto out_device_create;
1949         }
1950         kbdev->config_attributes = config->attributes;
1951
1952
1953         osdev = &kbdev->osdev;
1954         osdev->dev = &mali_linux_device.cdev;
1955         osdev->reg_start   = config->io_resources->io_memory_region.start;
1956         osdev->reg_size    = config->io_resources->io_memory_region.end - config->io_resources->io_memory_region.start + 1;
1957         osdev->irqs[0].irq = config->io_resources->job_irq_number;
1958         osdev->irqs[1].irq = config->io_resources->mmu_irq_number;
1959         osdev->irqs[2].irq = config->io_resources->gpu_irq_number;
1960
1961         kbdev->memdev.per_process_memory_limit = kbasep_get_config_value(config->attributes,
1962                         KBASE_CONFIG_ATTR_MEMORY_PER_PROCESS_LIMIT);
1963         kbdev->memdev.ump_device_id = kbasep_get_config_value(config->attributes, KBASE_CONFIG_ATTR_UMP_DEVICE);
1964
1965         /* obtain min/max configured gpu frequencies */
1966         {
1967                 struct mali_base_gpu_core_props *core_props = &(kbdev->gpu_props.props.core_props);
1968                 core_props->gpu_freq_khz_min = kbasep_get_config_value(config->attributes,
1969                                                                                                                           KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MIN);
1970                 core_props->gpu_freq_khz_max = kbasep_get_config_value(config->attributes,
1971                                                                                                                           KBASE_CONFIG_ATTR_GPU_FREQ_KHZ_MAX);
1972         }
1973
1974         err = kbase_register_memory_regions(kbdev, config->attributes);
1975         if (err)
1976         {
1977                 goto out_device_init;
1978         }
1979
1980         err = kbase_common_device_init(kbdev);
1981         if (0 != err)
1982         {
1983                 goto out_device_init;
1984         }
1985
1986         g_kbdev = kbdev;
1987
1988         return 0;
1989
1990 out_device_init:
1991         kbase_device_destroy(kbdev);
1992         g_kbdev = NULL;
1993 out_validate_attributes:
1994 out_device_create:
1995         cdev_del(&mali_linux_device.cdev);
1996 out_cdev_add:
1997         unregister_chrdev_region(dev, 1);
1998 out_region:
1999         return err;
2000 }
2001
2002 #endif /* MALI_LICENSE_IS_GPL */
2003
2004 static void __exit kbase_driver_exit(void)
2005 {
2006 #if MALI_LICENSE_IS_GPL
2007         pci_unregister_driver(&kbase_pci_driver);
2008         platform_driver_unregister(&kbase_platform_driver);
2009 #if MALI_FAKE_PLATFORM_DEVICE
2010         if (mali_device)
2011         {
2012                 platform_device_unregister(mali_device);
2013         }
2014 #endif
2015 #else
2016         dev_t dev = MKDEV(mali_major, 0);
2017         struct kbase_device *kbdev = g_kbdev;
2018
2019         if (!kbdev)
2020         {
2021                 return;
2022         }
2023
2024         kbase_common_device_remove(kbdev);
2025
2026         /* unregister char device */
2027         cdev_del(&mali_linux_device.cdev);
2028
2029         /* free major */
2030         unregister_chrdev_region(dev, 1);
2031 #endif
2032 }
2033
2034 module_init(kbase_driver_init);
2035 module_exit(kbase_driver_exit);
2036
2037 #if MALI_LICENSE_IS_GPL
2038 MODULE_LICENSE("GPL");
2039 #else
2040 MODULE_LICENSE("Proprietary");
2041 #endif
2042
2043 #if MALI_GATOR_SUPPORT
2044 /* Create the trace points (otherwise we just get code to call a tracepoint) */
2045 #define CREATE_TRACE_POINTS
2046 #include "mali_linux_trace.h"
2047
2048 void kbase_trace_mali_timeline_event(u32 event)
2049 {
2050         trace_mali_timeline_event(event);
2051 }
2052 #endif
2053