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