20100903+0m5
[sgx.git] / pvr / bufferclass_example_linux.c
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 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/fs.h>
30 #include <linux/uaccess.h>
31 #include <linux/io.h>
32
33 #include <linux/dma-mapping.h>
34
35 #include "pvr_bridge_km.h"
36 #include "bufferclass_example.h"
37 #include "bufferclass_example_linux.h"
38 #include "bufferclass_example_private.h"
39 #include "pvrmodule.h"
40
41 #define DEVNAME "bc_example"
42 #define DRVNAME DEVNAME
43
44 MODULE_SUPPORTED_DEVICE(DEVNAME);
45
46 static int AssignedMajorNumber;
47
48 #define unref__ __attribute__ ((unused))
49
50
51
52 void *BCAllocKernelMem(u32 ui32Size)
53 {
54         return kmalloc(ui32Size, GFP_KERNEL);
55 }
56
57 void BCFreeKernelMem(void *pvMem)
58 {
59         kfree(pvMem);
60 }
61
62 enum PVRSRV_ERROR BCAllocContigMemory(u32 ui32Size, void **unref__ phMemHandle,
63                                  void **pLinAddr,
64                                  struct IMG_CPU_PHYADDR *pPhysAddr)
65 {
66         dma_addr_t dma;
67         void *pvLinAddr;
68
69         pvLinAddr = dma_alloc_coherent(NULL, ui32Size, &dma, GFP_KERNEL);
70
71         if (pvLinAddr == NULL)
72                 return PVRSRV_ERROR_OUT_OF_MEMORY;
73
74         pPhysAddr->uiAddr = dma;
75         *pLinAddr = pvLinAddr;
76
77         return PVRSRV_OK;
78 }
79
80 void BCFreeContigMemory(u32 ui32Size, void *unref__ hMemHandle,
81                         void *LinAddr, struct IMG_CPU_PHYADDR PhysAddr)
82 {
83         dma_free_coherent(NULL, ui32Size, LinAddr,
84                           (dma_addr_t) PhysAddr.uiAddr);
85 }
86
87 struct IMG_SYS_PHYADDR CpuPAddrToSysPAddrBC(struct IMG_CPU_PHYADDR cpu_paddr)
88 {
89         struct IMG_SYS_PHYADDR sys_paddr;
90
91         sys_paddr.uiAddr = cpu_paddr.uiAddr;
92         return sys_paddr;
93 }
94
95 struct IMG_CPU_PHYADDR SysPAddrToCpuPAddrBC(struct IMG_SYS_PHYADDR sys_paddr)
96 {
97
98         struct IMG_CPU_PHYADDR cpu_paddr;
99
100         cpu_paddr.uiAddr = sys_paddr.uiAddr;
101         return cpu_paddr;
102 }
103
104 enum PVRSRV_ERROR BCOpenPVRServices(void **phPVRServices)
105 {
106         *phPVRServices = NULL;
107         return PVRSRV_OK;
108 }
109
110 enum PVRSRV_ERROR BCClosePVRServices(void *unref__ hPVRServices)
111 {
112
113         return PVRSRV_OK;
114 }
115
116 enum PVRSRV_ERROR BCGetLibFuncAddr(void *unref__ hExtDrv, char *szFunctionName,
117           IMG_BOOL (**ppfnFuncTable)(struct PVRSRV_BC_BUFFER2SRV_KMJTABLE *))
118 {
119         if (strcmp("PVRGetBufferClassJTable", szFunctionName) != 0)
120                 return PVRSRV_ERROR_INVALID_PARAMS;
121
122         *ppfnFuncTable = PVRGetBufferClassJTable;
123
124         return PVRSRV_OK;
125 }
126
127 int BC_Example_Bridge(struct inode *inode, struct file *file, unsigned int cmd,
128                       unsigned long arg)
129 {
130         int err = -EFAULT;
131         int command = _IOC_NR(cmd);
132         struct BC_Example_ioctl_package *psBridge =
133                                         (struct BC_Example_ioctl_package *)arg;
134
135         if (!access_ok
136             (VERIFY_WRITE, psBridge, sizeof(struct BC_Example_ioctl_package)))
137                 return err;
138
139         switch (command) {
140         case _IOC_NR(BC_Example_ioctl_fill_buffer):
141                 {
142                         if (FillBuffer(psBridge->inputparam) == -1)
143                                 return err;
144                         break;
145                 }
146         case _IOC_NR(BC_Example_ioctl_get_buffer_count):
147                 {
148                         if (GetBufferCount(&psBridge->outputparam) == -1)
149                                 return err;
150
151                         break;
152                 }
153         default:
154                 return err;
155         }
156
157         return 0;
158 }
159
160 const static struct file_operations bufferclass_example_fops = {
161         .ioctl  = BC_Example_Bridge,
162 };
163
164 static int __init BC_Example_ModInit(void)
165 {
166
167
168         AssignedMajorNumber =
169             register_chrdev(0, DEVNAME, &bufferclass_example_fops);
170
171         if (AssignedMajorNumber <= 0) {
172                 printk(KERN_ERR DRVNAME
173                        ": BC_Example_ModInit: unable to get major number\n");
174
175                 goto ExitDisable;
176         }
177 #if defined(DEBUG)
178         printk(KERN_ERR DRVNAME ": BC_Example_ModInit: major device %d\n",
179                AssignedMajorNumber);
180 #endif
181
182
183         if (BC_Example_Init() != PVRSRV_OK) {
184                 printk(KERN_ERR DRVNAME
185                        ": BC_Example_ModInit: can't init device\n");
186                 goto ExitUnregister;
187         }
188
189         return 0;
190
191 ExitUnregister:
192         unregister_chrdev(AssignedMajorNumber, DEVNAME);
193 ExitDisable:
194         return -EBUSY;
195 }
196
197 static void __exit BC_Example_ModCleanup(void)
198 {
199         unregister_chrdev(AssignedMajorNumber, DEVNAME);
200
201         if (BC_Example_Deinit() != PVRSRV_OK)
202                 printk(KERN_ERR DRVNAME
203                        ": BC_Example_ModCleanup: can't deinit device\n");
204
205 }
206
207 module_init(BC_Example_ModInit);
208 module_exit(BC_Example_ModCleanup);