1 /**********************************************************************
3 * Copyright(c) 2008 Imagination Technologies Ltd. All rights reserved.
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.
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.
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.
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
21 * Contact Information:
22 * Imagination Technologies Ltd. <gpl-support@imgtec.com>
23 * Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
25 ******************************************************************************/
27 #include <linux/init.h>
28 #include <linux/kernel.h>
29 #include <linux/module.h>
30 #include <linux/version.h>
32 #include <linux/proc_fs.h>
33 #include <linux/miscdevice.h>
35 #include <linux/platform_device.h>
39 #include "kerneldisplay.h"
40 #include "kernelbuffer.h"
41 #include "syscommon.h"
46 #include "pvr_debug.h"
50 #include "pvr_bridge_km.h"
51 #include "sgx_bridge_km.h"
53 #include "pvrmodule.h"
54 #include "private_data.h"
55 #include "pvr_events.h"
57 #ifdef CONFIG_DEBUG_FS
58 #include "pvr_debugfs.h"
61 #define DRVNAME "pvrsrvkm"
63 #ifdef CONFIG_PVR_DEBUG_EXTRA
64 static int debug = DBGPRIV_WARNING;
65 #include <linux/moduleparam.h>
66 module_param(debug, int, 0);
69 static int pvr_open(struct inode unref__ * inode, struct file *filp)
71 struct PVRSRV_FILE_PRIVATE_DATA *priv;
74 enum PVRSRV_ERROR err;
79 if (pvr_is_disabled()) {
84 pid = OSGetCurrentProcessIDKM();
86 if (PVRSRVProcessConnect(pid) != PVRSRV_OK)
89 err = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
91 (void **)&priv, &block_alloc);
96 priv->ui32OpenPID = pid;
97 priv->hBlockAlloc = block_alloc;
98 priv->proc = PVRSRVPerProcessData(pid);
99 filp->private_data = priv;
101 INIT_LIST_HEAD(&priv->event_list);
102 init_waitqueue_head(&priv->event_wait);
103 priv->event_space = 4096; /* set aside 4k for event buffer */
112 static int pvr_release(struct inode unref__ * inode, struct file *filp)
114 struct PVRSRV_FILE_PRIVATE_DATA *priv;
118 priv = filp->private_data;
120 pvr_release_events(priv);
122 PVRSRVProcessDisconnect(priv->ui32OpenPID);
124 OSFreeMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
126 priv, priv->hBlockAlloc);
133 static const struct file_operations pvr_fops = {
134 .owner = THIS_MODULE,
135 .unlocked_ioctl = PVRSRV_BridgeDispatchKM,
137 .release = pvr_release,
143 static void pvr_shutdown(struct platform_device *pdev)
145 PVR_TRACE("pvr_shutdown(pdev=%p)", pdev);
147 (void)PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D3);
150 static int pvr_suspend(struct platform_device *pdev, pm_message_t state)
152 PVR_TRACE("pvr_suspend(pdev=%p)", pdev);
154 if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D3) != PVRSRV_OK)
159 static int pvr_resume(struct platform_device *pdev)
161 PVR_TRACE("pvr_resume(pdev=%p)", pdev);
163 if (PVRSRVSetPowerStateKM(PVRSRV_POWER_STATE_D0) != PVRSRV_OK)
168 static struct miscdevice pvr_miscdevice = {
169 .minor = MISC_DYNAMIC_MINOR,
174 static int __devinit pvr_probe(struct platform_device *pdev)
176 struct SYS_DATA *sysdata;
179 PVR_TRACE("pvr_probe(pdev=%p)", pdev);
181 if (SysAcquireData(&sysdata) != PVRSRV_OK &&
182 SysInitialise(pdev) != PVRSRV_OK) {
187 ret = misc_register(&pvr_miscdevice);
194 dev_err(&pdev->dev, "probe failed (%d)\n", ret);
199 static int __devexit pvr_remove(struct platform_device *pdev)
201 struct SYS_DATA *sysdata;
204 PVR_TRACE("pvr_remove(pdev=%p)", pdev);
206 ret = misc_deregister(&pvr_miscdevice);
208 dev_err(&pdev->dev, "remove failed (%d)\n", ret);
212 if (SysAcquireData(&sysdata) == PVRSRV_OK)
213 SysDeinitialise(sysdata);
219 static struct platform_driver pvr_driver = {
224 .remove = __devexit_p(pvr_remove),
225 .suspend = pvr_suspend,
226 .resume = pvr_resume,
227 .shutdown = pvr_shutdown,
230 static void pvr_dummy_release(struct device *dev)
234 static struct sgx_platform_data pvr_pdata;
236 static struct platform_device pvr_device = {
240 .platform_data = &pvr_pdata,
241 .release = pvr_dummy_release,
245 static int __init pvr_init(void)
251 PVR_TRACE("pvr_init");
253 #ifdef CONFIG_PVR_DEBUG_EXTRA
254 PVRDebugSetLevel(debug);
257 #ifdef CONFIG_DEBUG_FS
261 error = CreateProcEntries();
266 if (LinuxMMInit() != PVRSRV_OK)
269 if (LinuxBridgeInit() != PVRSRV_OK)
274 error = platform_driver_register(&pvr_driver);
278 pvr_pdata.fclock_max = 200000000;
279 error = platform_device_register(&pvr_device);
288 platform_driver_unregister(&pvr_driver);
297 pr_err("%s: failed (%d)\n", __func__, error);
302 static void __exit pvr_cleanup(void)
304 PVR_TRACE("pvr_cleanup");
308 platform_driver_unregister(&pvr_driver);
309 platform_device_unregister(&pvr_device);
316 PVR_TRACE("pvr_cleanup: unloading");
318 #ifdef CONFIG_DEBUG_FS
319 pvr_debugfs_cleanup();
324 module_init(pvr_init);
325 module_exit(pvr_cleanup);
327 MODULE_SUPPORTED_DEVICE(DRVNAME);
328 MODULE_ALIAS("platform:" DRVNAME);