aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/pvr/services4/srvkm/env/linux/pvr_drm.c')
-rw-r--r--drivers/gpu/pvr/services4/srvkm/env/linux/pvr_drm.c808
1 files changed, 808 insertions, 0 deletions
diff --git a/drivers/gpu/pvr/services4/srvkm/env/linux/pvr_drm.c b/drivers/gpu/pvr/services4/srvkm/env/linux/pvr_drm.c
new file mode 100644
index 000000000000..9e6b92c39954
--- /dev/null
+++ b/drivers/gpu/pvr/services4/srvkm/env/linux/pvr_drm.c
@@ -0,0 +1,808 @@
1/*************************************************************************/ /*!
2@Title PowerVR drm driver
3@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved
4@Description linux module setup
5@License Dual MIT/GPLv2
6
7The contents of this file are subject to the MIT license as set out below.
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19Alternatively, the contents of this file may be used under the terms of
20the GNU General Public License Version 2 ("GPL") in which case the provisions
21of GPL are applicable instead of those above.
22
23If you wish to allow use of your version of this file only under the terms of
24GPL, and not to allow others to use your version of this file under the terms
25of the MIT license, indicate your decision by deleting the provisions above
26and replace them with the notice and other provisions required by GPL as set
27out in the file called "GPL-COPYING" included in this distribution. If you do
28not delete the provisions above, a recipient may use your version of this file
29under the terms of either the MIT license or GPL.
30
31This License is also included in this distribution in the file called
32"MIT-COPYING".
33
34EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
35PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
36BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
37PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
38COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
39IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
40CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41*/ /**************************************************************************/
42#if defined(SUPPORT_DRI_DRM)
43
44#include <linux/version.h>
45
46#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
47#ifndef AUTOCONF_INCLUDED
48#include <linux/config.h>
49#endif
50#endif
51
52#include <linux/init.h>
53#include <linux/kernel.h>
54#include <linux/module.h>
55#include <linux/fs.h>
56#include <linux/proc_fs.h>
57#include <linux/sched.h>
58#include <asm/ioctl.h>
59#include <drm/drmP.h>
60#include <drm/drm.h>
61
62#include "img_defs.h"
63#include "services.h"
64#include "kerneldisplay.h"
65#include "kernelbuffer.h"
66#include "syscommon.h"
67#include "pvrmmap.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 "pvr_bridge.h"
77#include "pvrmodule.h"
78#include "pvrversion.h"
79#include "lock.h"
80#include "linkage.h"
81#include "pvr_drm.h"
82
83#if defined(PVR_DRI_DRM_NOT_PCI)
84#include "pvr_drm_mod.h"
85#endif
86
87#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
88#define DRM_ARRAY_SIZE(x) ARRAY_SIZE(x)
89#endif
90
91#if (defined(PVR_LDM_PLATFORM_PRE_REGISTERED) || defined(PVR_LDM_DEVICE_TREE)) && !defined(NO_HARDWARE)
92#define PVR_USE_PRE_REGISTERED_PLATFORM_DEV
93#endif
94
95#if defined(PVR_LDM_DEVICE_TREE) && !defined(NO_HARDWARE)
96#define PVR_USE_DEVICE_TREE
97#endif
98
99#if (defined(PVR_DRI_DRM_PLATFORM_DEV) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)) || defined(NO_HARDWARE)
100#define PVR_DRM_NAME SYS_SGX_DEV_NAME
101#else
102#define PVR_DRM_NAME PVRSRV_MODNAME
103#endif
104
105#define PVR_DRM_DESC "Imagination Technologies PVR DRM"
106
107#define PVR_DRM_DATE "20110701"
108
109#if defined(PVR_DRI_DRM_PLATFORM_DEV) && !defined(SUPPORT_DRI_DRM_PLUGIN)
110#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
111#define PVR_NEW_STYLE_DRM_PLATFORM_DEV
112#else
113#define PVR_OLD_STYLE_DRM_PLATFORM_DEV
114#endif
115#endif
116
117/*
118 * Prior to Linux 2.6.36, we couldn't do the release processing in post close
119 * when workqueues were being used, because drm_release held the big kernel
120 * lock (BKL) when it called post close.
121 * If the resman needs to wait for processing being done by a workqueue,
122 * that processing won't complete whilst the lock is held by another thread,
123 * as the workqueue won't get scheduled.
124 */
125#undef PVR_DRI_DRM_USE_POST_CLOSE
126#if (defined(SUPPORT_DRI_DRM_EXT) && !defined(PVR_LINUX_USING_WORKQUEUES)) || \
127 (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
128#define PVR_DRI_DRM_USE_POST_CLOSE
129#endif
130
131#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
132#define PVR_DRM_DRIVER_RENDER DRIVER_RENDER
133#define PVR_DRM_RENDER_ALLOW DRM_RENDER_ALLOW
134#else
135#define PVR_DRM_DRIVER_RENDER 0
136#define PVR_DRM_RENDER_ALLOW 0
137#endif
138
139DECLARE_WAIT_QUEUE_HEAD(sWaitForInit);
140
141#if defined(SUPPORT_DRM_MODESET)
142static struct drm_driver sPVRDrmDriver;
143#endif
144
145/* Once bInitComplete and bInitFailed are set, they stay set */
146IMG_BOOL bInitComplete;
147IMG_BOOL bInitFailed;
148
149#if !defined(PVR_DRI_DRM_NOT_PCI) && !defined(SUPPORT_DRI_DRM_PLUGIN)
150#if defined(PVR_DRI_DRM_PLATFORM_DEV)
151#if defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) && !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
152static struct platform_device *psPlatDev;
153#endif
154struct platform_device *gpsPVRLDMDev;
155#else
156struct pci_dev *gpsPVRLDMDev;
157#endif
158#endif
159
160struct drm_device *gpsPVRDRMDev;
161
162#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,24))
163#error "Linux kernel version 2.6.25 or later required for PVR DRM support"
164#endif
165
166#define PVR_DRM_FILE struct drm_file *
167
168#if !defined(SUPPORT_DRI_DRM_EXT) && !defined(SUPPORT_DRI_DRM_PLUGIN)
169#if defined(PVR_USE_DEVICE_TREE)
170static struct of_device_id asPlatIdList[] = {
171 {
172 .compatible = SYS_SGX_DEV_NAME
173 },
174 {}
175};
176MODULE_DEVICE_TABLE(of, asPlatIdList);
177#else
178#if defined(PVR_DRI_DRM_PLATFORM_DEV)
179static struct platform_device_id asPlatIdList[] = {
180 {SYS_SGX_DEV_NAME, 0},
181 {}
182};
183#else /* defined(PVR_DRI_DRM_PLATFORM_DEV) */
184static struct pci_device_id asPciIdList[] = {
185#if defined(PVR_DRI_DRM_NOT_PCI)
186 {1, 1, 1, 1, 0, 0, 0},
187#else /* defined(PVR_DRI_DRM_NOT_PCI) */
188 {SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
189#if defined(SYS_SGX_DEV1_DEVICE_ID)
190 {SYS_SGX_DEV_VENDOR_ID, SYS_SGX_DEV1_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
191#endif /* defined(SYS_SGX_DEV1_DEVICE_ID) */
192#endif /* defined(PVR_DRI_DRM_NOT_PCI) */
193 {0}
194};
195#endif /* defined(PVR_DRI_DRM_PLATFORM_DEV) */
196#endif /* defined(PVR_DEVICE_TREE) */
197#endif /* !defined(SUPPORT_DRI_DRM_EXT) */
198
199struct device *
200PVRLDMGetDevice(void)
201{
202 return gpsPVRDRMDev->dev;
203}
204
205DRI_DRM_STATIC int
206PVRSRVDrmLoad(struct drm_device *dev, unsigned long flags)
207{
208 int iRes = 0;
209
210 PVR_TRACE(("PVRSRVDrmLoad"));
211
212 gpsPVRDRMDev = dev;
213#if !defined(PVR_DRI_DRM_NOT_PCI) && !defined(SUPPORT_DRI_DRM_PLUGIN)
214#if defined(PVR_DRI_DRM_PLATFORM_DEV)
215 gpsPVRLDMDev = dev->platformdev;
216#else
217 gpsPVRLDMDev = dev->pdev;
218#endif
219#endif
220
221#if defined(PDUMP)
222 iRes = dbgdrv_init();
223 if (iRes != 0)
224 {
225 goto exit;
226 }
227#endif
228 /* Module initialisation */
229 iRes = PVRCore_Init();
230 if (iRes != 0)
231 {
232 goto exit_dbgdrv_cleanup;
233 }
234
235#if defined(DISPLAY_CONTROLLER)
236 iRes = PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Init)(dev);
237 if (iRes != 0)
238 {
239 goto exit_pvrcore_cleanup;
240 }
241#endif
242 goto exit;
243
244#if defined(DISPLAY_CONTROLLER)
245exit_pvrcore_cleanup:
246 PVRCore_Cleanup();
247#endif
248exit_dbgdrv_cleanup:
249#if defined(PDUMP)
250 dbgdrv_cleanup();
251#endif
252exit:
253 if (iRes != 0)
254 {
255 bInitFailed = IMG_TRUE;
256 }
257 bInitComplete = IMG_TRUE;
258
259 wake_up_interruptible(&sWaitForInit);
260
261 return iRes;
262}
263
264DRI_DRM_STATIC int
265PVRSRVDrmUnload(struct drm_device *dev)
266{
267 PVR_TRACE(("PVRSRVDrmUnload"));
268
269#if defined(DISPLAY_CONTROLLER)
270 PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Cleanup)(dev);
271#endif
272
273 PVRCore_Cleanup();
274
275#if defined(PDUMP)
276 dbgdrv_cleanup();
277#endif
278
279 return 0;
280}
281
282DRI_DRM_STATIC int
283PVRSRVDrmOpen(struct drm_device *dev, struct drm_file *file)
284{
285 while (!bInitComplete)
286 {
287 DEFINE_WAIT(sWait);
288
289 prepare_to_wait(&sWaitForInit, &sWait, TASK_INTERRUPTIBLE);
290
291 if (!bInitComplete)
292 {
293 PVR_TRACE(("%s: Waiting for module initialisation to complete", __FUNCTION__));
294
295 schedule();
296 }
297
298 finish_wait(&sWaitForInit, &sWait);
299
300 if (signal_pending(current))
301 {
302 return -ERESTARTSYS;
303 }
304 }
305
306 if (bInitFailed)
307 {
308 PVR_DPF((PVR_DBG_ERROR, "%s: Module initialisation failed", __FUNCTION__));
309 return -EINVAL;
310 }
311
312 return PVRSRVOpen(dev, file);
313}
314
315#if defined(PVR_DRI_DRM_USE_POST_CLOSE) || defined(SUPPORT_DRI_DRM_PLUGIN)
316#if defined(SUPPORT_DRI_DRM_PLUGIN)
317DRI_DRM_STATIC int
318PVRSRVDrmRelease(struct drm_device *dev, struct drm_file *file)
319#else
320DRI_DRM_STATIC void
321PVRSRVDrmPostClose(struct drm_device *dev, struct drm_file *file)
322#endif
323{
324 PVRSRVRelease(file->driver_priv);
325
326 file->driver_priv = NULL;
327
328#if defined(SUPPORT_DRI_DRM_PLUGIN)
329 return 0;
330#endif
331}
332#else
333DRI_DRM_STATIC int
334PVRSRVDrmRelease(struct inode *inode, struct file *filp)
335{
336 struct drm_file *file_priv = filp->private_data;
337 void *psDriverPriv = file_priv->driver_priv;
338 int ret;
339
340 ret = drm_release(inode, filp);
341
342 if (ret != 0)
343 {
344 /*
345 * An error means drm_release didn't call drm_lastclose,
346 * but it will have freed file_priv.
347 */
348 PVR_DPF((PVR_DBG_ERROR, "%s : drm_release failed: %d",
349 __FUNCTION__, ret));
350 }
351
352 PVRSRVRelease(psDriverPriv);
353
354 return 0;
355}
356#endif
357
358DRI_DRM_STATIC int
359PVRDRMIsMaster(struct drm_device *dev, void *arg, struct drm_file *pFile)
360{
361 return 0;
362}
363
364#if defined(SUPPORT_DRI_DRM_EXT)
365int
366PVRDRM_Dummy_ioctl(struct drm_device *dev, void *arg, struct drm_file *pFile)
367{
368 return 0;
369}
370#endif
371
372DRI_DRM_STATIC int
373PVRDRMUnprivCmd(struct drm_device *dev, void *arg, struct drm_file *pFile)
374{
375 int ret = 0;
376
377 LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE);
378
379 if (arg == NULL)
380 {
381 ret = -EFAULT;
382 }
383 else
384 {
385 drm_pvr_unpriv_cmd *psArgs = (drm_pvr_unpriv_cmd *)arg;
386
387 switch (psArgs->cmd)
388 {
389 case PVR_DRM_UNPRIV_INIT_SUCCESFUL:
390 psArgs->res = PVRSRVGetInitServerState(PVRSRV_INIT_SERVER_SUCCESSFUL) ? 1 : 0;
391 break;
392
393 default:
394 ret = -EFAULT;
395 }
396
397 }
398
399 LinuxUnLockMutex(&gPVRSRVLock);
400
401 return ret;
402}
403
404#if defined(DISPLAY_CONTROLLER) && defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL)
405static int
406PVRDRM_Display_ioctl(struct drm_device *dev, void *arg, struct drm_file *pFile)
407{
408 int res;
409
410 LinuxLockMutexNested(&gPVRSRVLock, PVRSRV_LOCK_CLASS_BRIDGE);
411
412 res = PVR_DRM_MAKENAME(DISPLAY_CONTROLLER, _Ioctl)(dev, arg, pFile);
413
414 LinuxUnLockMutex(&gPVRSRVLock);
415
416 return res;
417}
418#endif
419
420#if defined(SUPPORT_DRM_MODESET)
421static int
422PVRSRVPciProbe(struct pci_dev *dev, const struct pci_device_id *id)
423{
424 PVR_TRACE(("PVRSRVPciProbe"));
425
426#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36))
427 return drm_get_pci_dev(dev, id, &sPVRDrmDriver);
428#else
429 return drm_get_dev(dev, id, &sPVRDrmDriver);
430#endif
431}
432
433static void
434PVRSRVPciRemove(struct pci_dev *dev)
435{
436 struct drm_device *psDrmDev;
437
438 PVR_TRACE(("PVRSRVPciRemove"));
439
440 psDrmDev = pci_get_drvdata(dev);
441 drm_put_dev(psDrmDev);
442}
443#endif
444
445/*
446 * For Linux 2.6.33 and above, the DRM ioctl entry point is of the unlocked
447 * variety. The big kernel lock is still taken for ioctls, unless
448 * the DRM_UNLOCKED flag is set. If you revise one of the driver specific
449 * ioctls, or add a new one, consider whether the gPVRSRVLock mutex needs
450 * to be taken.
451 */
452#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
453#define PVR_DRM_FOPS_IOCTL .unlocked_ioctl
454#define PVR_DRM_UNLOCKED DRM_UNLOCKED
455#else
456#define PVR_DRM_FOPS_IOCTL .ioctl
457#define PVR_DRM_UNLOCKED 0
458#endif
459
460#if !defined(DRM_IOCTL_DEF_DRV)
461#define DRM_IOCTL_DEF_DRV(ioctl, _func, _flags) DRM_IOCTL_DEF(DRM_##ioctl, _func, _flags)
462#endif
463
464#if !defined(SUPPORT_DRI_DRM_EXT)
465struct drm_ioctl_desc sPVRDrmIoctls[] = {
466 DRM_IOCTL_DEF_DRV(PVR_SRVKM, PVRSRV_BridgeDispatchKM, PVR_DRM_RENDER_ALLOW | PVR_DRM_UNLOCKED),
467 DRM_IOCTL_DEF_DRV(PVR_IS_MASTER, PVRDRMIsMaster, PVR_DRM_RENDER_ALLOW | DRM_MASTER | PVR_DRM_UNLOCKED),
468 DRM_IOCTL_DEF_DRV(PVR_UNPRIV, PVRDRMUnprivCmd, PVR_DRM_RENDER_ALLOW | PVR_DRM_UNLOCKED),
469#if defined(PDUMP)
470 DRM_IOCTL_DEF_DRV(PVR_DBGDRV, dbgdrv_ioctl, PVR_DRM_RENDER_ALLOW | PVR_DRM_UNLOCKED),
471#endif
472#if defined(DISPLAY_CONTROLLER) && defined(PVR_DISPLAY_CONTROLLER_DRM_IOCTL)
473 DRM_IOCTL_DEF_DRV(PVR_DISP, PVRDRM_Display_ioctl, DRM_MASTER | PVR_DRM_UNLOCKED)
474#endif
475};
476
477#if !defined(SUPPORT_DRI_DRM_PLUGIN)
478static int pvr_max_ioctl = DRM_ARRAY_SIZE(sPVRDrmIoctls);
479#endif
480
481#if defined(PVR_DRI_DRM_PLATFORM_DEV) && !defined(SUPPORT_DRI_DRM_EXT) && \
482 !defined(SUPPORT_DRI_DRM_PLUGIN)
483static int PVRSRVDrmProbe(struct platform_device *pDevice);
484static int PVRSRVDrmRemove(struct platform_device *pDevice);
485#endif /* defined(PVR_DRI_DRM_PLATFORM_DEV) && !defined(SUPPORT_DRI_DRM_EXT) */
486
487#if defined(SUPPORT_DRI_DRM_PLUGIN)
488static PVRSRV_DRM_PLUGIN sPVRDrmPlugin =
489{
490 .name = PVR_DRM_NAME,
491
492 .open = PVRSRVDrmOpen,
493 .load = PVRSRVDrmLoad,
494 .unload = PVRSRVDrmUnload,
495
496 .release = PVRSRVDrmRelease,
497
498 .mmap = PVRMMap,
499
500 .ioctls = sPVRDrmIoctls,
501 .num_ioctls = DRM_ARRAY_SIZE(sPVRDrmIoctls),
502 .ioctl_start = 0
503};
504#else /* defined(SUPPORT_DRI_DRM_PLUGIN) */
505
506#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
507#if defined(CONFIG_COMPAT)
508static long pvr_compat_ioctl(struct file *file, unsigned int cmd,
509 unsigned long arg)
510{
511 unsigned int nr = DRM_IOCTL_NR(cmd);
512
513 if (nr < DRM_COMMAND_BASE)
514 {
515 return drm_compat_ioctl(file, cmd, arg);
516 }
517
518 return drm_ioctl(file, cmd, arg);
519}
520#endif /* defined(CONFIG_COMPAT) */
521
522static const struct file_operations sPVRFileOps =
523{
524 .owner = THIS_MODULE,
525 .open = drm_open,
526#if defined(PVR_DRI_DRM_USE_POST_CLOSE)
527 .release = drm_release,
528#else
529 .release = PVRSRVDrmRelease,
530#endif
531 PVR_DRM_FOPS_IOCTL = drm_ioctl,
532#if defined(CONFIG_COMPAT)
533 .compat_ioctl = pvr_compat_ioctl,
534#endif
535 .mmap = PVRMMap,
536 .poll = drm_poll,
537#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,12,0))
538 .fasync = drm_fasync,
539#endif
540};
541#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) */
542
543static struct drm_driver sPVRDrmDriver =
544{
545 .driver_features = PVR_DRM_DRIVER_RENDER
546#if defined(PVR_OLD_STYLE_DRM_PLATFORM_DEV)
547 | DRIVER_USE_PLATFORM_DEVICE
548#endif
549 ,
550 .dev_priv_size = 0,
551 .load = PVRSRVDrmLoad,
552 .unload = PVRSRVDrmUnload,
553 .open = PVRSRVDrmOpen,
554#if defined(PVR_DRI_DRM_USE_POST_CLOSE)
555 .postclose = PVRSRVDrmPostClose,
556#endif
557#if !defined(PVR_DRI_DRM_PLATFORM_DEV) && !defined(SUPPORT_DRM_MODESET)
558 .suspend = PVRSRVDriverSuspend,
559 .resume = PVRSRVDriverResume,
560#endif
561#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37))
562 .get_map_ofs = drm_core_get_map_ofs,
563 .get_reg_ofs = drm_core_get_reg_ofs,
564#endif
565 .ioctls = sPVRDrmIoctls,
566#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
567 .fops = &sPVRFileOps,
568#else
569 .fops =
570 {
571 .owner = THIS_MODULE,
572 .open = drm_open,
573#if defined(PVR_DRI_DRM_USE_POST_CLOSE)
574 .release = drm_release,
575#else
576 .release = PVRSRVDrmRelease,
577#endif
578 PVR_DRM_FOPS_IOCTL = drm_ioctl,
579 .mmap = PVRMMap,
580 .poll = drm_poll,
581 .fasync = drm_fasync,
582 },
583#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) */
584#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
585#if defined(PVR_OLD_STYLE_DRM_PLATFORM_DEV)
586 .platform_driver =
587 {
588 .id_table = asPlatIdList,
589 .driver =
590 {
591 .name = PVR_DRM_NAME,
592 },
593 .probe = PVRSRVDrmProbe,
594 .remove = PVRSRVDrmRemove,
595 .suspend = PVRSRVDriverSuspend,
596 .resume = PVRSRVDriverResume,
597 .shutdown = PVRSRVDriverShutdown,
598 },
599#else
600 .pci_driver =
601 {
602 .name = PVR_DRM_NAME,
603 .id_table = asPciIdList,
604#if defined(SUPPORT_DRM_MODESET)
605 .probe = PVRSRVPciProbe,
606 .remove = PVRSRVPciRemove,
607 .suspend = PVRSRVDriverSuspend,
608 .resume = PVRSRVDriverResume,
609#endif
610 },
611#endif
612#endif
613
614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4,5,0))
615#if defined(LDM_PLATFORM)
616 .set_busid = drm_platform_set_busid,
617#else
618#if defined(LDM_PCI)
619 .set_busid = drm_pci_set_busid,
620#else
621 #error "LDM_PLATFORM or LDM_PCI must be set"
622#endif
623#endif
624#endif
625 .name = "pvr",
626 .desc = PVR_DRM_DESC,
627 .date = PVR_DRM_DATE,
628 .major = PVRVERSION_MAJ,
629 .minor = PVRVERSION_MIN,
630 .patchlevel = PVRVERSION_BUILD,
631};
632
633#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) && !defined(PVR_DRI_DRM_PLATFORM_DEV)
634static struct pci_driver sPVRPCIDriver =
635{
636 .name = PVR_DRM_NAME,
637 .id_table = asPciIdList,
638#if defined(SUPPORT_DRM_MODESET)
639 .probe = PVRSRVPciProbe,
640 .remove = PVRSRVPciRemove,
641 .suspend = PVRSRVDriverSuspend,
642 .resume = PVRSRVDriverResume,
643#endif
644};
645#endif
646
647#if defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV)
648#if !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
649static struct platform_device_info sPVRPlatDeviceInfo = {
650 .name = PVR_DRM_NAME,
651 .id = -1,
652 .dma_mask = DMA_BIT_MASK(32)
653};
654#endif
655
656static struct platform_driver sPVRPlatDriver =
657{
658#if !defined(PVR_USE_DEVICE_TREE)
659 .id_table = asPlatIdList,
660#endif
661 .driver =
662 {
663 .name = PVR_DRM_NAME,
664#if defined(PVR_USE_DEVICE_TREE)
665 .of_match_table = asPlatIdList,
666#endif
667 },
668 .probe = PVRSRVDrmProbe,
669 .remove = PVRSRVDrmRemove,
670 .suspend = PVRSRVDriverSuspend,
671 .resume = PVRSRVDriverResume,
672 .shutdown = PVRSRVDriverShutdown,
673};
674#endif
675
676#endif /* defined(SUPPORT_DRI_DRM_PLUGIN) */
677
678#if defined(PVR_DRI_DRM_PLATFORM_DEV) && !defined(SUPPORT_DRI_DRM_EXT) && \
679 !defined(SUPPORT_DRI_DRM_PLUGIN)
680static int
681PVRSRVDrmProbe(struct platform_device *pDevice)
682{
683 PVR_TRACE(("PVRSRVDrmProbe"));
684
685#if defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV)
686 gpsPVRLDMDev = pDevice;
687
688 return drm_platform_init(&sPVRDrmDriver, gpsPVRLDMDev);
689#else
690 return drm_get_platform_dev(pDevice, &sPVRDrmDriver);
691#endif
692}
693
694static int
695PVRSRVDrmRemove(struct platform_device *pDevice)
696{
697 PVR_TRACE(("PVRSRVDrmRemove"));
698
699#if defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0))
700 drm_platform_exit(&sPVRDrmDriver, gpsPVRLDMDev);
701#else
702 drm_put_dev(gpsPVRDRMDev);
703#endif
704 return 0;
705}
706#endif
707
708static int __init PVRSRVDrmInit(void)
709{
710 int iRes;
711#if !defined(SUPPORT_DRI_DRM_PLUGIN)
712 sPVRDrmDriver.num_ioctls = pvr_max_ioctl;
713#endif
714
715#if defined(SUPPORT_DRM_MODESET)
716 sPVRDrmDriver.driver_features |= DRIVER_MODESET;
717#endif
718
719 /* Must come before attempting to print anything via Services */
720 PVRDPFInit();
721
722#if defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV)
723 iRes = platform_driver_register(&sPVRPlatDriver);
724#if !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
725 if (iRes == 0)
726 {
727 psPlatDev = platform_device_register_full(&sPVRPlatDeviceInfo);
728 if (IS_ERR(psPlatDev))
729 {
730 iRes = PTR_ERR(psPlatDev);
731 psPlatDev = NULL;
732 platform_driver_unregister(&sPVRPlatDriver);
733 }
734 }
735#endif
736#else /* defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) */
737#if defined(SUPPORT_DRI_DRM_PLUGIN)
738 iRes = SysDRMRegisterPlugin(&sPVRDrmPlugin);
739#else /* defined(SUPPORT_DRI_DRM_PLUGIN) */
740#if defined(PVR_DRI_DRM_NOT_PCI)
741 iRes = drm_pvr_dev_add();
742 if (iRes != 0)
743 {
744 return iRes;
745 }
746#endif
747
748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
749#if defined(PVR_DRI_DRM_PLATFORM_DEV)
750 iRes = drm_platform_init(&sPVRDrmDriver, gpsPVRLDMDev);
751#else
752 iRes = drm_pci_init(&sPVRDrmDriver, &sPVRPCIDriver);
753#endif
754#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) */
755 iRes = drm_init(&sPVRDrmDriver);
756#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) */
757
758#if defined(PVR_DRI_DRM_NOT_PCI)
759 if (iRes != 0)
760 {
761 drm_pvr_dev_remove();
762 }
763#endif
764#endif /* defined(SUPPORT_DRI_DRM_PLUGIN) */
765#endif /* defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) */
766 return iRes;
767}
768
769static void __exit PVRSRVDrmExit(void)
770{
771#if defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV)
772#if !defined(PVR_USE_PRE_REGISTERED_PLATFORM_DEV)
773 platform_device_unregister(psPlatDev);
774#endif
775 platform_driver_unregister(&sPVRPlatDriver);
776#else /* defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) */
777#if defined(SUPPORT_DRI_DRM_PLUGIN)
778 SysDRMUnregisterPlugin(&sPVRDrmPlugin);
779#else /* defined(SUPPORT_DRI_DRM_PLUGIN) */
780#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
781#if defined(PVR_DRI_DRM_PLATFORM_DEV)
782 drm_platform_exit(&sPVRDrmDriver, gpsPVRLDMDev);
783#else
784 drm_pci_exit(&sPVRDrmDriver, &sPVRPCIDriver);
785#endif
786#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) */
787 drm_exit(&sPVRDrmDriver);
788#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)) */
789
790#if defined(PVR_DRI_DRM_NOT_PCI)
791 drm_pvr_dev_remove();
792#endif
793#endif /* defined(SUPPORT_DRI_DRM_PLUGIN) */
794#endif /* defined(PVR_NEW_STYLE_DRM_PLATFORM_DEV) */
795}
796
797/*
798 * These macro calls define the initialisation and removal functions of the
799 * driver. Although they are prefixed `module_', they apply when compiling
800 * statically as well; in both cases they define the function the kernel will
801 * run to start/stop the driver.
802*/
803module_init(PVRSRVDrmInit);
804module_exit(PVRSRVDrmExit);
805#endif /* !defined(SUPPORT_DRI_DRM_EXT) */
806#endif /* defined(SUPPORT_DRI_DRM) */
807
808