0fd336b8c5492674084507aad2ecbcd3a8a5f934
[profile/ivi/intel-emgd-kmod.git] / pvr / services4 / srvkm / env / linux / module.c
1 /**********************************************************************
2  Copyright (c) Imagination Technologies Ltd.
3
4  Permission is hereby granted, free of charge, to any person obtaining a copy
5  of this software and associated documentation files (the "Software"), to deal
6  in the Software without restriction, including without limitation the rights
7  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  copies of the Software, and to permit persons to whom the Software is
9  furnished to do so, subject to the following conditions:
10
11  The above copyright notice and this permission notice shall be included in
12  all copies or substantial portions of the Software.
13
14  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  THE SOFTWARE.
21  ******************************************************************************/
22
23 #if !defined(SUPPORT_DRI_DRM)
24
25         #if defined(LDM_PLATFORM)
26                 #define PVR_LDM_PLATFORM_MODULE
27                 #define PVR_LDM_MODULE
28         #else
29                 #if defined(LDM_PCI)
30                         #define PVR_LDM_PCI_MODULE
31                         #define PVR_LDM_MODULE
32                 #endif
33         #endif
34 #endif
35
36 #include <linux/init.h>
37 #include <linux/kernel.h>
38 #include <linux/module.h>
39 #include <linux/version.h>
40 #include <linux/fs.h>
41 #include <linux/proc_fs.h>
42
43 #if defined(SUPPORT_DRI_DRM)
44 #include <drm/drmP.h>
45 #endif
46
47 #if defined(PVR_LDM_PLATFORM_MODULE)
48 #include <linux/platform_device.h>
49 #endif
50
51 #if defined(PVR_LDM_PCI_MODULE)
52 #include <linux/pci.h>
53 #endif
54
55 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
56 #include <asm/uaccess.h>
57 #endif
58
59 #include "img_defs.h"
60 #include "services.h"
61 #include "kerneldisplay.h"
62 #include "kernelbuffer.h"
63 #include "sysconfig.h"
64 #include "sysplb.h"
65 #include "systnc.h"
66 #include "pvrmmap.h"
67 #include "mutils.h"
68 #include "mm.h"
69 #include "mmap.h"
70 #include "mutex.h"
71 #include "pvr_debug.h"
72 #include "srvkm.h"
73 #include "perproc.h"
74 #include "handle.h"
75 #include "pvr_bridge_km.h"
76 #include "proc.h"
77 #include "pvrmodule.h"
78 #include "private_data.h"
79 #include "lock.h"
80 #include "linkage.h"
81
82 #if defined(SUPPORT_DRI_DRM)
83 #include "pvr_drm.h"
84 #endif
85 #define DRVNAME         "pvrsrvkm"
86 #define DEVNAME         "pvrsrvkm"
87
88 #if defined(SUPPORT_DRI_DRM)
89 #define PRIVATE_DATA(pFile) ((pFile)->driver_priv)
90 #else
91 #define PRIVATE_DATA(pFile) ((pFile)->private_data)
92 #endif
93
94 MODULE_SUPPORTED_DEVICE(DEVNAME);
95 #ifdef DEBUG
96 static IMG_INT debug = DBGPRIV_WARNING;
97 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
98 #include <linux/moduleparam.h>
99 module_param(debug, int, 0);
100 #else
101 MODULE_PARM(debug, "i");
102 MODULE_PARM_DESC(debug, "Sets the level of debug output (default=0x4)");
103 #endif
104 #endif
105
106
107 extern IMG_BOOL PVRGetDisplayClassJTable(PVRSRV_DC_DISP2SRV_KMJTABLE *psJTable);
108 extern IMG_BOOL PVRGetBufferClassJTable(PVRSRV_BC_BUFFER2SRV_KMJTABLE *psJTable);
109
110 EXPORT_SYMBOL(PVRGetDisplayClassJTable);
111 EXPORT_SYMBOL(PVRGetBufferClassJTable);
112
113
114 #if defined(PVR_LDM_MODULE)
115 static struct class *psPvrClass;
116 #endif
117
118 #if !defined(SUPPORT_DRI_DRM)
119 static IMG_INT AssignedMajorNumber;
120
121 static IMG_INT PVRSRVOpen(struct inode* pInode, struct file* pFile);
122 static IMG_INT PVRSRVRelease(struct inode* pInode, struct file* pFile);
123
124 static struct file_operations pvrsrv_fops = {
125         .owner=THIS_MODULE,
126         .unlocked_ioctl=PVRSRV_BridgeDispatchKM,
127         .open=PVRSRVOpen,
128         .release=PVRSRVRelease,
129         .mmap=PVRMMap,
130 };
131 #endif
132
133 struct mutex gPVRSRVLock;
134
135 IMG_UINT32 gui32ReleasePID;
136
137 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
138 static IMG_UINT32 gPVRPowerLevel;
139 #endif
140
141 #if defined(PVR_LDM_MODULE)
142
143 #if defined(PVR_LDM_PLATFORM_MODULE)
144 #define LDM_DEV struct platform_device
145 #define LDM_DRV struct platform_driver
146 #endif
147
148 #if defined(PVR_LDM_PCI_MODULE)
149 #define LDM_DEV struct pci_dev
150 #define LDM_DRV struct pci_driver
151 #endif
152
153 #if defined(PVR_LDM_PLATFORM_MODULE)
154 static IMG_INT PVRSRVDriverRemove(LDM_DEV *device);
155 static IMG_INT PVRSRVDriverProbe(LDM_DEV *device);
156 #endif
157 #if defined(PVR_LDM_PCI_MODULE)
158 static IMG_VOID PVRSRVDriverRemove(LDM_DEV *device);
159 static IMG_INT PVRSRVDriverProbe(LDM_DEV *device, const struct pci_device_id *id);
160 #endif
161 static IMG_INT PVRSRVDriverSuspend(LDM_DEV *device, pm_message_t state);
162 static IMG_VOID PVRSRVDriverShutdown(LDM_DEV *device);
163 static IMG_INT PVRSRVDriverResume(LDM_DEV *device);
164
165 #if defined(PVR_LDM_PCI_MODULE)
166 /* all supported platform ids */
167 struct pci_device_id powervr_id_table[] __devinitdata = {
168         { PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID_PLB) },
169         { PCI_DEVICE(SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID_TNC) },
170         { 0 }
171 };
172
173 MODULE_DEVICE_TABLE(pci, powervr_id_table);
174 #endif
175
176 static LDM_DRV powervr_driver = {
177 #if defined(PVR_LDM_PLATFORM_MODULE)
178         .driver = {
179                 .name           = DRVNAME,
180         },
181 #endif
182 #if defined(PVR_LDM_PCI_MODULE)
183         .name           = DRVNAME,
184         .id_table = powervr_id_table,
185 #endif
186         .probe          = PVRSRVDriverProbe,
187 #if defined(PVR_LDM_PLATFORM_MODULE)
188         .remove         = PVRSRVDriverRemove,
189 #endif
190 #if defined(PVR_LDM_PCI_MODULE)
191         .remove         = __devexit_p(PVRSRVDriverRemove),
192 #endif
193         .suspend        = PVRSRVDriverSuspend,
194         .resume         = PVRSRVDriverResume,
195         .shutdown       = PVRSRVDriverShutdown,
196 };
197
198 LDM_DEV *gpsPVRLDMDev;
199
200 #if defined(MODULE) && defined(PVR_LDM_PLATFORM_MODULE)
201
202 static IMG_VOID PVRSRVDeviceRelease(struct device *pDevice)
203 {
204         PVR_UNREFERENCED_PARAMETER(pDevice);
205 }
206
207 static struct platform_device powervr_device = {
208         .name                   = DEVNAME,
209         .id                             = -1,
210         .dev                    = {
211                 .release        = PVRSRVDeviceRelease
212         }
213 };
214
215 #endif
216
217 #if defined(PVR_LDM_PLATFORM_MODULE)
218 static IMG_INT PVRSRVDriverProbe(LDM_DEV *pDevice)
219 #endif
220 #if defined(PVR_LDM_PCI_MODULE)
221 static IMG_INT __devinit PVRSRVDriverProbe(LDM_DEV *pDevice, const struct pci_device_id *id)
222 #endif
223 {
224         SYS_DATA *psSysData;
225
226         PVR_TRACE(("PVRSRVDriverProbe(pDevice=%p)", pDevice));
227
228 #if 0
229
230         if (PerDeviceSysInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
231         {
232                 return -EINVAL;
233         }
234 #endif
235
236         if (SysAcquireData(&psSysData) != PVRSRV_OK)
237         {
238                 gpsPVRLDMDev = pDevice;
239
240                 if (SysInitialise() != PVRSRV_OK)
241                 {
242                         return -ENODEV;
243                 }
244         }
245
246         return 0;
247 }
248
249
250 #if defined (PVR_LDM_PLATFORM_MODULE)
251 static IMG_INT PVRSRVDriverRemove(LDM_DEV *pDevice)
252 #endif
253 #if defined(PVR_LDM_PCI_MODULE)
254 static IMG_VOID __devexit PVRSRVDriverRemove(LDM_DEV *pDevice)
255 #endif
256 {
257         SYS_DATA *psSysData;
258
259         PVR_TRACE(("PVRSRVDriverRemove(pDevice=%p)", pDevice));
260
261         if (SysAcquireData(&psSysData) == PVRSRV_OK)
262         {
263 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
264                 if (gPVRPowerLevel != 0)
265                 {
266                         if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
267                         {
268                                 gPVRPowerLevel = 0;
269                         }
270                 }
271 #endif
272                 SysDeinitialise(psSysData);
273
274                 gpsPVRLDMDev = IMG_NULL;
275         }
276
277 #if 0
278         if (PerDeviceSysDeInitialise((IMG_PVOID)pDevice) != PVRSRV_OK)
279         {
280                 return -EINVAL;
281         }
282 #endif
283
284 #if defined (PVR_LDM_PLATFORM_MODULE)
285         return 0;
286 #endif
287 #if defined (PVR_LDM_PCI_MODULE)
288         return;
289 #endif
290 }
291
292
293 static IMG_VOID PVRSRVDriverShutdown(LDM_DEV *pDevice)
294 {
295         PVR_TRACE(("PVRSRVDriverShutdown(pDevice=%p)", pDevice));
296
297         (IMG_VOID) PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3);
298 }
299
300 #endif
301
302
303 #if defined(PVR_LDM_MODULE) || defined(SUPPORT_DRI_DRM)
304 #if defined(SUPPORT_DRI_DRM)
305 IMG_INT PVRSRVDriverSuspend(struct drm_device *pDevice, pm_message_t state)
306 #else
307 static IMG_INT PVRSRVDriverSuspend(LDM_DEV *pDevice, pm_message_t state)
308 #endif
309 {
310 #if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
311         PVR_TRACE(( "PVRSRVDriverSuspend(pDevice=%p)", pDevice));
312
313         if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK)
314         {
315                 return -EINVAL;
316         }
317 #endif
318         return 0;
319 }
320
321
322 #if defined(SUPPORT_DRI_DRM)
323 IMG_INT PVRSRVDriverResume(struct drm_device *pDevice)
324 #else
325 static IMG_INT PVRSRVDriverResume(LDM_DEV *pDevice)
326 #endif
327 {
328 #if !(defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM))
329         PVR_TRACE(("PVRSRVDriverResume(pDevice=%p)", pDevice));
330
331         if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
332         {
333                 return -EINVAL;
334         }
335 #endif
336         return 0;
337 }
338 #endif
339
340
341 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL) && !defined(SUPPORT_DRI_DRM)
342 IMG_INT PVRProcSetPowerLevel(struct file *file, const IMG_CHAR *buffer, IMG_UINT32 count, IMG_VOID *data)
343 {
344         IMG_CHAR data_buffer[2];
345         IMG_UINT32 PVRPowerLevel;
346
347         if (count != sizeof(data_buffer))
348         {
349                 return -EINVAL;
350         }
351         else
352         {
353                 if (copy_from_user(data_buffer, buffer, count))
354                         return -EINVAL;
355                 if (data_buffer[count - 1] != '\n')
356                         return -EINVAL;
357                 PVRPowerLevel = data_buffer[0] - '0';
358                 if (PVRPowerLevel != gPVRPowerLevel)
359                 {
360                         if (PVRPowerLevel != 0)
361                         {
362                                 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D3) != PVRSRV_OK)
363                                 {
364                                         return -EINVAL;
365                                 }
366                         }
367                         else
368                         {
369                                 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) != PVRSRV_OK)
370                                 {
371                                         return -EINVAL;
372                                 }
373                         }
374
375                         gPVRPowerLevel = PVRPowerLevel;
376                 }
377         }
378         return (count);
379 }
380
381 #ifdef PVR_PROC_USE_SEQ_FILE
382 void ProcSeqShowPowerLevel(struct seq_file *sfile,void* el)
383 {
384         seq_printf(sfile, "%lu\n", gPVRPowerLevel);
385 }
386
387 #else
388 IMG_INT PVRProcGetPowerLevel(IMG_CHAR *page, IMG_CHAR **start, off_t off, IMG_INT count, IMG_INT *eof, IMG_VOID *data)
389 {
390         if (off == 0) {
391                 *start = (IMG_CHAR *)1;
392                 return printAppend(page, count, 0, "%lu\n", gPVRPowerLevel);
393         }
394         *eof = 1;
395         return 0;
396 }
397 #endif
398
399 #endif
400
401 #if defined(SUPPORT_DRI_DRM)
402 IMG_INT PVRSRVOpen(struct drm_device unref__ *dev, struct drm_file *pFile)
403 #else
404 static IMG_INT PVRSRVOpen(struct inode unref__ * pInode, struct file *pFile)
405 #endif
406 {
407         PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
408         IMG_HANDLE hBlockAlloc;
409         IMG_INT iRet = -ENOMEM;
410         PVRSRV_ERROR eError;
411         IMG_UINT32 ui32PID;
412 #if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
413         PVRSRV_ENV_PER_PROCESS_DATA *psEnvPerProc;
414 #endif
415
416 #if defined(SUPPORT_DRI_DRM)
417         PVR_UNREFERENCED_PARAMETER(dev);
418 #else
419         PVR_UNREFERENCED_PARAMETER(pInode);
420 #endif
421
422         mutex_lock(&gPVRSRVLock);
423
424         ui32PID = OSGetCurrentProcessIDKM();
425
426         if (PVRSRVProcessConnect(ui32PID) != PVRSRV_OK)
427                 goto err_unlock;
428
429 #if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
430         psEnvPerProc = PVRSRVPerProcessPrivateData(ui32PID);
431         if (psEnvPerProc == IMG_NULL)
432         {
433                 PVR_DPF((PVR_DBG_ERROR, "%s: No per-process private data", __FUNCTION__));
434                 goto err_unlock;
435         }
436 #endif
437
438         eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
439                                                 sizeof(PVRSRV_FILE_PRIVATE_DATA),
440                                                 (IMG_PVOID *)&psPrivateData,
441                                                 &hBlockAlloc,
442                                                 "File Private Data");
443
444         if(eError != PVRSRV_OK)
445                 goto err_unlock;
446
447 #if defined(PVR_SECURE_FD_EXPORT)
448         psPrivateData->hKernelMemInfo = NULL;
449 #endif
450 #if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
451         psPrivateData->psDRMFile = pFile;
452
453         list_add_tail(&psPrivateData->sDRMAuthListItem, &psEnvPerProc->sDRMAuthListHead);
454 #endif
455         psPrivateData->ui32OpenPID = ui32PID;
456         psPrivateData->hBlockAlloc = hBlockAlloc;
457         PRIVATE_DATA(pFile) = psPrivateData;
458         iRet = 0;
459 err_unlock:
460         mutex_unlock(&gPVRSRVLock);
461         return iRet;
462 }
463
464
465 #if defined(SUPPORT_DRI_DRM)
466 IMG_INT PVRSRVRelease(struct drm_device unref__ *dev, struct drm_file *pFile)
467 #else
468 static IMG_INT PVRSRVRelease(struct inode unref__ * pInode, struct file *pFile)
469 #endif
470 {
471         PVRSRV_FILE_PRIVATE_DATA *psPrivateData;
472
473 #if defined(SUPPORT_DRI_DRM)
474         PVR_UNREFERENCED_PARAMETER(dev);
475 #else
476         PVR_UNREFERENCED_PARAMETER(pInode);
477 #endif
478
479         mutex_lock(&gPVRSRVLock);
480
481         psPrivateData = PRIVATE_DATA(pFile);
482
483 #if defined(SUPPORT_DRI_DRM) && defined(PVR_SECURE_DRM_AUTH_EXPORT)
484         list_del(&psPrivateData->sDRMAuthListItem);
485 #endif
486
487
488         gui32ReleasePID = psPrivateData->ui32OpenPID;
489         PVRSRVProcessDisconnect(psPrivateData->ui32OpenPID);
490         gui32ReleasePID = 0;
491
492         OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
493                           sizeof(PVRSRV_FILE_PRIVATE_DATA),
494                           psPrivateData, psPrivateData->hBlockAlloc);
495
496         PRIVATE_DATA(pFile) = NULL;
497
498         mutex_unlock(&gPVRSRVLock);
499         return 0;
500 }
501
502
503 #if defined(SUPPORT_DRI_DRM)
504 IMG_INT PVRCore_Init(IMG_VOID)
505 #else
506 static IMG_INT __init PVRCore_Init(IMG_VOID)
507 #endif
508 {
509         IMG_INT error;
510 #if !defined(PVR_LDM_MODULE)
511         PVRSRV_ERROR eError;
512 #else
513         struct device *psDev;
514 #endif
515
516         PVRDPFInit();
517         PVR_TRACE(("PVRCore_Init"));
518
519         mutex_init(&gPVRSRVLock);
520
521 #ifdef DEBUG
522         PVRDebugSetLevel(debug);
523 #endif
524
525         if (CreateProcEntries ())
526         {
527                 error = -ENOMEM;
528                 return error;
529         }
530
531         if (PVROSFuncInit() != PVRSRV_OK)
532         {
533                 error = -ENOMEM;
534                 goto init_failed;
535         }
536
537         PVRLinuxMUtilsInit();
538
539         if(LinuxMMInit() != PVRSRV_OK)
540         {
541                 error = -ENOMEM;
542                 goto init_failed;
543         }
544
545         LinuxBridgeInit();
546
547         PVRMMapInit();
548
549 #if defined(PVR_LDM_MODULE)
550
551 #if defined(PVR_LDM_PLATFORM_MODULE)
552         if ((error = platform_driver_register(&powervr_driver)) != 0)
553         {
554                 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform driver (%d)", error));
555
556                 goto init_failed;
557         }
558
559 #if defined(MODULE)
560         if ((error = platform_device_register(&powervr_device)) != 0)
561         {
562                 platform_driver_unregister(&powervr_driver);
563
564                 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register platform device (%d)", error));
565
566                 goto init_failed;
567         }
568 #endif
569 #endif
570
571 #if defined(PVR_LDM_PCI_MODULE)
572         if ((error = pci_register_driver(&powervr_driver)) != 0)
573         {
574                 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to register PCI driver (%d)", error));
575
576                 goto init_failed;
577         }
578 #endif
579
580 #else
581
582         if ((eError = SysInitialise()) != PVRSRV_OK)
583         {
584                 error = -ENODEV;
585 #if defined(TCF_REV) && (TCF_REV == 110)
586                 if(eError == PVRSRV_ERROR_NOT_SUPPORTED)
587                 {
588                         printk("\nAtlas wrapper (FPGA image) version mismatch");
589                         error = -ENODEV;
590                 }
591 #endif
592                 goto init_failed;
593         }
594 #endif
595
596 #if !defined(SUPPORT_DRI_DRM)
597         AssignedMajorNumber = register_chrdev(0, DEVNAME, &pvrsrv_fops);
598
599         if (AssignedMajorNumber <= 0)
600         {
601                 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to get major number"));
602
603                 error = -EBUSY;
604                 goto sys_deinit;
605         }
606
607         PVR_TRACE(("PVRCore_Init: major device %d", AssignedMajorNumber));
608 #endif
609
610 #if defined(PVR_LDM_MODULE)
611
612         psPvrClass = class_create(THIS_MODULE, "pvr");
613
614         if (IS_ERR(psPvrClass))
615         {
616                 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create class (%ld)", PTR_ERR(psPvrClass)));
617                 error = -EBUSY;
618                 goto unregister_device;
619         }
620
621         psDev = device_create(psPvrClass, NULL, MKDEV(AssignedMajorNumber, 0),
622 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26))
623                                   NULL,
624 #endif
625                                   DEVNAME);
626         if (IS_ERR(psDev))
627         {
628                 PVR_DPF((PVR_DBG_ERROR, "PVRCore_Init: unable to create device (%ld)", PTR_ERR(psDev)));
629                 error = -EBUSY;
630                 goto destroy_class;
631         }
632 #endif
633
634         return 0;
635
636 #if defined(PVR_LDM_MODULE)
637 destroy_class:
638         class_destroy(psPvrClass);
639 unregister_device:
640         unregister_chrdev((IMG_UINT)AssignedMajorNumber, DRVNAME);
641 #endif
642 #if !defined(SUPPORT_DRI_DRM)
643 sys_deinit:
644 #endif
645 #if defined(PVR_LDM_MODULE)
646 #if defined(PVR_LDM_PCI_MODULE)
647         pci_unregister_driver(&powervr_driver);
648 #endif
649
650 #if defined (PVR_LDM_PLATFORM_MODULE)
651 #if defined (MODULE)
652         platform_device_unregister(&powervr_device);
653 #endif
654         platform_driver_unregister(&powervr_driver);
655 #endif
656
657 #else
658
659         {
660                 SYS_DATA *psSysData;
661
662                 SysAcquireData(&psSysData);
663                 if (psSysData != IMG_NULL)
664                 {
665                         SysDeinitialise(psSysData);
666                 }
667         }
668 #endif
669 init_failed:
670         PVRMMapCleanup();
671         LinuxMMCleanup();
672         LinuxBridgeDeInit();
673         PVROSFuncDeInit();
674         RemoveProcEntries();
675
676         return error;
677
678 }
679
680
681 #if defined(SUPPORT_DRI_DRM)
682 IMG_VOID PVRCore_Cleanup(IMG_VOID)
683 #else
684 static IMG_VOID __exit PVRCore_Cleanup(IMG_VOID)
685 #endif
686 {
687         SYS_DATA *psSysData;
688
689         PVR_TRACE(("PVRCore_Cleanup"));
690
691         SysAcquireData(&psSysData);
692
693 #if defined(PVR_LDM_MODULE)
694         device_destroy(psPvrClass, MKDEV(AssignedMajorNumber, 0));
695         class_destroy(psPvrClass);
696 #endif
697
698 #if !defined(SUPPORT_DRI_DRM)
699 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
700         if (
701 #endif
702                 unregister_chrdev((IMG_UINT)AssignedMajorNumber, DRVNAME)
703 #if !(LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22))
704                                                                 ;
705 #else
706                                                                 )
707         {
708                 PVR_DPF((PVR_DBG_ERROR," can't unregister device major %d", AssignedMajorNumber));
709         }
710 #endif
711 #endif
712
713 #if defined(PVR_LDM_MODULE)
714
715 #if defined(PVR_LDM_PCI_MODULE)
716         pci_unregister_driver(&powervr_driver);
717 #endif
718
719 #if defined (PVR_LDM_PLATFORM_MODULE)
720 #if defined (MODULE)
721         platform_device_unregister(&powervr_device);
722 #endif
723         platform_driver_unregister(&powervr_driver);
724 #endif
725
726 #else
727 #if defined(DEBUG) && defined(PVR_MANUAL_POWER_CONTROL)
728         if (gPVRPowerLevel != 0)
729         {
730                 if (PVRSRVSetPowerStateKM(PVRSRV_SYS_POWER_STATE_D0) == PVRSRV_OK)
731                 {
732                         gPVRPowerLevel = 0;
733                 }
734         }
735 #endif
736
737         SysDeinitialise(psSysData);
738 #endif
739
740         PVRMMapCleanup();
741
742         LinuxMMCleanup();
743
744         LinuxBridgeDeInit();
745
746         PVROSFuncDeInit();
747
748         RemoveProcEntries();
749
750         PVR_TRACE(("PVRCore_Cleanup: unloading"));
751 }
752
753 #if !defined(SUPPORT_DRI_DRM)
754 module_init(PVRCore_Init);
755 module_exit(PVRCore_Cleanup);
756 #endif