upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / char / s3c_mem.c
1 /* drivers/char/s3c_mem.c
2  *
3  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4  *              http://www.samsung.com/
5  *
6  * S3C MEM driver for /dev/mem
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11 */
12
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/types.h>
17 #include <linux/timer.h>
18 #include <linux/kernel.h>
19 #include <linux/fs.h>
20 #include <linux/interrupt.h>
21 #include <linux/clk.h>
22 #include <linux/delay.h>
23 #include <linux/uaccess.h>
24 #include <linux/errno.h>        /* error codes */
25 #include <asm/div64.h>
26 #include <linux/mm.h>
27 #include <linux/tty.h>
28 #include <linux/io.h>
29 #include <linux/sched.h>
30 #include <asm/irq.h>
31 #include <asm/cacheflush.h>
32 #include <linux/slab.h>
33 #include <linux/mman.h>
34 #include <linux/dma-mapping.h>
35
36 #include <linux/unistd.h>
37 #include <linux/version.h>
38 #include <mach/map.h>
39 #include <mach/hardware.h>
40
41 #include "s3c_mem.h"
42 #ifdef CONFIG_S3C_DMA_MEM
43 #include "s3c_dma_mem.h"
44 #endif
45
46 #ifdef CONFIG_S3C_MEM_CMA_ALLOC
47 #include <linux/cma.h>
48 #include <linux/platform_device.h>
49 #endif
50
51 static int flag;
52
53 static unsigned int physical_address;
54
55 #ifdef USE_DMA_ALLOC
56 static unsigned int virtual_address;
57 #endif
58
59 #ifdef CONFIG_S3C_MEM_CMA_ALLOC
60
61 struct s3c_slot_info *s3c_slot_info;
62 int s3c_cma_max_block_num;
63 int s3c_cma_block_size;
64
65
66 static void s3c_mem_log(struct s3c_dev_info *prv_data, bool mem_info)
67 {
68         int i = 0;
69         for (i = 0; i < prv_data->dev_max_slot_num; i++)
70                 printk(KERN_INFO
71                        "s_slot_info[%d].s_start_addr=0x%x s_mapped=%d \n", i,
72                        prv_data->s_slot_info[i].s_start_addr,
73                        prv_data->s_slot_info[i].s_mapped);
74         if (mem_info)
75                 printk(KERN_INFO
76                        "s_cur_mem_info->paddr=0x%x s_mem_info->vaddr=0x%x s_mem_info->size=%d \n",
77                        prv_data->s_cur_mem_info.paddr,
78                        prv_data->s_cur_mem_info.vaddr,
79                        prv_data->s_cur_mem_info.mapped_size);
80 }
81
82 static unsigned long s3c_mapping_slot(struct s3c_dev_info *prv_data)
83 {
84         int i, j, k, v_start_slot = 0;
85         unsigned long lv_ret = 0;
86
87         for (i = 0; i < prv_data->dev_max_slot_num; i++) {
88                 if (prv_data->s_slot_info[i].s_mapped == false) {
89                         if (i + prv_data->s_cur_mem_info.req_memblock >
90                             prv_data->dev_max_slot_num) {
91                                 printk(KERN_ERR "ERROR : not enough memory \n");
92                                 return lv_ret;
93                         }
94                         v_start_slot = i;
95                         for (j = i;
96                              j < i + prv_data->s_cur_mem_info.req_memblock;
97                              j++) {
98                                 if (prv_data->s_slot_info[j].s_mapped == true)
99                                         break;
100                                 }
101                         if (j == i + prv_data->s_cur_mem_info.req_memblock) {
102                                 lv_ret =
103                                     __phys_to_pfn(prv_data->s_slot_info
104                                                   [v_start_slot].s_start_addr);
105                                 physical_address = (unsigned int)
106                                     prv_data->s_slot_info[v_start_slot].
107                                     s_start_addr;
108                                 for (k = v_start_slot; k < j; k++) {
109                                         prv_data->s_slot_info[k].s_mapped =
110                                             true;
111                                         printk(KERN_INFO
112                                                "prv_data->s_slot_info[%d].s_mapped=1 \n",
113                                                k);
114                                 }
115                                 break;
116                         }
117                 } else
118                         continue;
119         }
120         if (i == prv_data->dev_max_slot_num)
121                 printk(KERN_ERR "ERROR :can not find the suitable slot \n");
122
123         return lv_ret;
124 }
125
126 static int s3c_unmapping_slot(struct s3c_dev_info *prv_data)
127 {
128         int i, j, lv_ret = 0;
129         for (i = 0; i < prv_data->dev_max_slot_num; i++) {
130                 if (prv_data->s_slot_info[i].s_start_addr ==
131                     prv_data->s_cur_mem_info.paddr) {
132                         for (j = i;
133                              j < i + prv_data->s_cur_mem_info.req_memblock;
134                              j++) {
135                                 prv_data->s_slot_info[j].s_mapped = false;
136                                 printk(KERN_INFO
137                                        "s_slot_info[%d].s_mapped = 0 \n", j);
138                         }
139                 }
140         }
141         return lv_ret;
142 }
143
144 int s3c_mem_open(struct inode *inode, struct file *filp)
145 {
146         struct s3c_dev_info *prv_data;
147         mutex_lock(&mem_open_lock);
148
149         prv_data = kzalloc(sizeof(struct s3c_dev_info), GFP_KERNEL);
150         if (!prv_data) {
151                 pr_err("%s: not enough memory\n", __func__);
152                 return -ENOMEM;
153         }
154         prv_data->s_slot_info = s3c_slot_info;
155         prv_data->dev_slot_size = s3c_cma_block_size;
156         prv_data->dev_max_slot_num = s3c_cma_max_block_num;
157         prv_data->s_cur_mem_info.paddr = 0;
158         prv_data->s_cur_mem_info.vaddr = 0;
159         prv_data->s_cur_mem_info.mapped_size = 0;
160         prv_data->s_cur_mem_info.req_memblock = 0;
161         filp->private_data = prv_data;
162
163         mutex_unlock(&mem_open_lock);
164
165         return 0;
166 }
167
168 int s3c_mem_release(struct inode *inode, struct file *filp)
169 {
170         struct mm_struct *mm = current->mm;
171         struct s3c_dev_info *prv_data =
172             (struct s3c_dev_info *)filp->private_data;
173
174         mutex_lock(&mem_release_lock);
175
176         printk(KERN_INFO
177                "prv_data->s_cur_mem_info->paddr=0x%x vaddr=0x%x size=%d \n",
178                prv_data->s_cur_mem_info.paddr, prv_data->s_cur_mem_info.vaddr,
179                prv_data->s_cur_mem_info.mapped_size);
180
181         if (prv_data->s_cur_mem_info.vaddr) {
182                 s3c_unmapping_slot(prv_data);
183                 if (do_munmap
184                     (mm, prv_data->s_cur_mem_info.vaddr,
185                      prv_data->s_cur_mem_info.mapped_size) < 0) {
186                         printk(KERN_ERR "do_munmap() failed !!\n");
187                         mutex_unlock(&mem_release_lock);
188                         return -EINVAL;
189                 }
190         }
191         kfree(filp->private_data);
192         filp->private_data = NULL;
193         mutex_unlock(&mem_release_lock);
194
195         return 0;
196 }
197 #endif
198
199 long s3c_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
200 {
201 #ifdef USE_DMA_ALLOC
202         unsigned long virt_addr;
203 #else
204         unsigned long *virt_addr;
205 #endif
206
207         struct mm_struct *mm = current->mm;
208         struct s3c_mem_alloc param;
209         struct vm_area_struct *vma;
210         unsigned long start, this_pfn;
211 #ifdef CONFIG_S3C_DMA_MEM
212         struct s3c_mem_dma_param dma_param;
213 #endif
214
215         switch (cmd) {
216         case S3C_MEM_ALLOC:
217                 mutex_lock(&mem_alloc_lock);
218                 if (copy_from_user(&param, (struct s3c_mem_alloc *)arg,
219                                    sizeof(struct s3c_mem_alloc))) {
220                         mutex_unlock(&mem_alloc_lock);
221                         return -EFAULT;
222                 }
223                 flag = MEM_ALLOC;
224                 param.vir_addr = do_mmap(file, 0, param.size,
225                                 (PROT_READ|PROT_WRITE), MAP_SHARED, 0);
226                 DEBUG("param.vir_addr = %08x, %d\n",
227                                                 param.vir_addr, __LINE__);
228                 if (param.vir_addr == -EINVAL) {
229                         printk(KERN_INFO "S3C_MEM_ALLOC FAILED\n");
230                         flag = 0;
231                         mutex_unlock(&mem_alloc_lock);
232                         return -EFAULT;
233                 }
234                 param.phy_addr = physical_address;
235 #ifdef USE_DMA_ALLOC
236                 param.kvir_addr = virtual_address;
237 #endif
238
239                 DEBUG("KERNEL MALLOC : param.phy_addr = 0x%X \t "
240                       "size = %d \t param.vir_addr = 0x%X, %d\n",
241                                 param.phy_addr, param.size, param.vir_addr,
242                                 __LINE__);
243
244                 if (copy_to_user((struct s3c_mem_alloc *)arg, &param,
245                                  sizeof(struct s3c_mem_alloc))) {
246                         flag = 0;
247                         mutex_unlock(&mem_alloc_lock);
248                         return -EFAULT;
249                 }
250                 flag = 0;
251                 mutex_unlock(&mem_alloc_lock);
252
253                 break;
254 #ifdef CONFIG_S3C_MEM_CMA_ALLOC
255         case S3C_MEM_CMA_ALLOC:
256                 {
257                         struct s3c_dev_info *prv_data =
258                             (struct s3c_dev_info *)file->private_data;
259
260                         mutex_lock(&mem_alloc_lock);
261                         if (copy_from_user(&param, (struct s3c_mem_alloc *)arg,
262                                            sizeof(struct s3c_mem_alloc))) {
263                                 mutex_unlock(&mem_alloc_lock);
264                                 return -EFAULT;
265                         }
266                         flag = MEM_CMA_ALLOC;
267
268                         param.vir_addr =
269                             do_mmap(file, 0, param.size,
270                                     (PROT_READ | PROT_WRITE), MAP_SHARED, 0);
271                         DEBUG("param.vir_addr = %08x, %d\n", param.vir_addr,
272                               __LINE__);
273
274                         if (param.vir_addr == -EINVAL) {
275                                 printk(KERN_ERR "S3C_MEM_ALLOC FAILED\n");
276                                 flag = 0;
277                                 mutex_unlock(&mem_alloc_lock);
278                                 return -EFAULT;
279                         }
280
281                         param.phy_addr = physical_address;
282                         printk(KERN_INFO "physical_address=0x%x \n",
283                                physical_address);
284
285                         if (copy_to_user((struct s3c_mem_alloc *)arg, &param,
286                                          sizeof(struct s3c_mem_alloc))) {
287                                 flag = 0;
288                                 mutex_unlock(&mem_alloc_lock);
289                                 return -EFAULT;
290                         }
291                         flag = 0;
292
293                         prv_data->s_cur_mem_info.paddr = param.phy_addr;
294                         prv_data->s_cur_mem_info.vaddr = param.vir_addr;
295                         prv_data->s_cur_mem_info.mapped_size =
296                             PAGE_ALIGN(param.size);
297
298                         mutex_unlock(&mem_alloc_lock);
299                 }
300                 break;
301
302 #endif
303         case S3C_MEM_CACHEABLE_ALLOC:
304                 mutex_lock(&mem_cacheable_alloc_lock);
305                 if (copy_from_user(&param, (struct s3c_mem_alloc *)arg,
306                                    sizeof(struct s3c_mem_alloc))) {
307                         mutex_unlock(&mem_cacheable_alloc_lock);
308                         return -EFAULT;
309                 }
310                 flag = MEM_ALLOC_CACHEABLE;
311                 param.vir_addr = do_mmap(file, 0, param.size,
312                                 (PROT_READ|PROT_WRITE), MAP_SHARED, 0);
313                 DEBUG("param.vir_addr = %08x, %d\n",
314                                 param.vir_addr, __LINE__);
315                 if (param.vir_addr == -EINVAL) {
316                         printk(KERN_INFO "S3C_MEM_ALLOC FAILED\n");
317                         flag = 0;
318                         mutex_unlock(&mem_cacheable_alloc_lock);
319                         return -EFAULT;
320                 }
321                 param.phy_addr = physical_address;
322                 DEBUG("KERNEL MALLOC : param.phy_addr = 0x%X"
323                       " \t size = %d \t param.vir_addr = 0x%X, %d\n",
324                                 param.phy_addr, param.size, param.vir_addr,
325                                 __LINE__);
326
327                 if (copy_to_user((struct s3c_mem_alloc *)arg, &param,
328                                  sizeof(struct s3c_mem_alloc))) {
329                         flag = 0;
330                         mutex_unlock(&mem_cacheable_alloc_lock);
331                         return -EFAULT;
332                 }
333                 flag = 0;
334                 mutex_unlock(&mem_cacheable_alloc_lock);
335
336                 break;
337
338         case S3C_MEM_SHARE_ALLOC:
339                 mutex_lock(&mem_share_alloc_lock);
340                 if (copy_from_user(&param, (struct s3c_mem_alloc *)arg,
341                                    sizeof(struct s3c_mem_alloc))) {
342                         mutex_unlock(&mem_share_alloc_lock);
343                         return -EFAULT;
344                 }
345                 flag = MEM_ALLOC_SHARE;
346                 physical_address = param.phy_addr;
347                 DEBUG("param.phy_addr = %08x, %d\n",
348                       physical_address, __LINE__);
349                 param.vir_addr = do_mmap(file, 0, param.size,
350                                 (PROT_READ|PROT_WRITE), MAP_SHARED, 0);
351                 DEBUG("param.vir_addr = %08x, %d\n",
352                                 param.vir_addr, __LINE__);
353                 if (param.vir_addr == -EINVAL) {
354                         printk(KERN_INFO "S3C_MEM_SHARE_ALLOC FAILED\n");
355                         flag = 0;
356                         mutex_unlock(&mem_share_alloc_lock);
357                         return -EFAULT;
358                 }
359                 DEBUG("MALLOC_SHARE : param.phy_addr = 0x%X \t "
360                       "size = %d \t param.vir_addr = 0x%X, %d\n",
361                                 param.phy_addr, param.size, param.vir_addr,
362                                 __LINE__);
363
364                 if (copy_to_user((struct s3c_mem_alloc *)arg, &param,
365                                  sizeof(struct s3c_mem_alloc))) {
366                         flag = 0;
367                         mutex_unlock(&mem_share_alloc_lock);
368                         return -EFAULT;
369                 }
370                 flag = 0;
371                 mutex_unlock(&mem_share_alloc_lock);
372
373                 break;
374
375         case S3C_MEM_CACHEABLE_SHARE_ALLOC:
376                 mutex_lock(&mem_cacheable_share_alloc_lock);
377                 if (copy_from_user(&param, (struct s3c_mem_alloc *)arg,
378                                    sizeof(struct s3c_mem_alloc))) {
379                         mutex_unlock(&mem_cacheable_share_alloc_lock);
380                         return -EFAULT;
381                 }
382                 flag = MEM_ALLOC_CACHEABLE_SHARE;
383                 physical_address = param.phy_addr;
384                 DEBUG("param.phy_addr = %08x, %d\n",
385                       physical_address, __LINE__);
386                 param.vir_addr = do_mmap(file, 0, param.size,
387                                 (PROT_READ|PROT_WRITE), MAP_SHARED, 0);
388                 DEBUG("param.vir_addr = %08x, %d\n",
389                                 param.vir_addr, __LINE__);
390                 if (param.vir_addr == -EINVAL) {
391                         printk(KERN_INFO "S3C_MEM_SHARE_ALLOC FAILED\n");
392                         flag = 0;
393                         mutex_unlock(&mem_cacheable_share_alloc_lock);
394                         return -EFAULT;
395                 }
396                 DEBUG("MALLOC_SHARE : param.phy_addr = 0x%X \t "
397                       "size = %d \t param.vir_addr = 0x%X, %d\n",
398                                 param.phy_addr, param.size, param.vir_addr,
399                                 __LINE__);
400
401                 if (copy_to_user((struct s3c_mem_alloc *)arg, &param,
402                                  sizeof(struct s3c_mem_alloc))) {
403                         flag = 0;
404                         mutex_unlock(&mem_cacheable_share_alloc_lock);
405                         return -EFAULT;
406                 }
407                 flag = 0;
408                 mutex_unlock(&mem_cacheable_share_alloc_lock);
409
410                 break;
411
412         case S3C_MEM_FREE:
413                 mutex_lock(&mem_free_lock);
414                 if (copy_from_user(&param, (struct s3c_mem_alloc *)arg,
415                                    sizeof(struct s3c_mem_alloc))) {
416                         mutex_unlock(&mem_free_lock);
417                         return -EFAULT;
418                 }
419
420                 DEBUG("KERNEL FREE : param.phy_addr = 0x%X \t "
421                       "size = %d \t param.vir_addr = 0x%X, %d\n",
422                                 param.phy_addr, param.size, param.vir_addr,
423                                 __LINE__);
424
425                 if (do_munmap(mm, param.vir_addr, param.size) < 0) {
426                         printk(KERN_INFO "do_munmap() failed !!\n");
427                         mutex_unlock(&mem_free_lock);
428                         return -EINVAL;
429                 }
430
431 #ifdef USE_DMA_ALLOC
432                 virt_addr = param.kvir_addr;
433                 dma_free_writecombine(NULL, param.size,
434                                 (unsigned int *) virt_addr, param.phy_addr);
435 #else
436                 virt_addr = (unsigned long *)phys_to_virt(param.phy_addr);
437                 kfree(virt_addr);
438 #endif
439                 param.size = 0;
440                 DEBUG("do_munmap() succeed !!\n");
441
442                 if (copy_to_user((struct s3c_mem_alloc *)arg, &param,
443                                  sizeof(struct s3c_mem_alloc))) {
444                         mutex_unlock(&mem_free_lock);
445                         return -EFAULT;
446                 }
447
448                 mutex_unlock(&mem_free_lock);
449
450                 break;
451 #ifdef CONFIG_S3C_MEM_CMA_ALLOC
452         case S3C_MEM_CMA_FREE:
453                 {
454                         struct s3c_dev_info *prv_data =
455                             (struct s3c_dev_info *)file->private_data;
456
457                         mutex_lock(&mem_free_lock);
458                         if (copy_from_user(&param, (struct s3c_mem_alloc *)arg,
459                                            sizeof(struct s3c_mem_alloc))) {
460                                 mutex_unlock(&mem_free_lock);
461                                 return -EFAULT;
462                         }
463
464                         DEBUG("KERNEL FREE : param.phy_addr = 0x%X \t "
465                               "size = %d \t param.vir_addr = 0x%X, %d\n",
466                               param.phy_addr, param.size, param.vir_addr,
467                               __LINE__);
468
469                         printk
470                             ("FREE : pa = 0x%x size = %d va = 0x%x\n",
471                              param.phy_addr, param.size, param.vir_addr);
472                         if (param.vir_addr) {
473                                 s3c_unmapping_slot(prv_data);
474
475                                 if (do_munmap(mm, param.vir_addr, param.size) <
476                                     0) {
477                                         printk(KERN_ERR
478                                                "do_munmap() failed !!\n");
479                                         mutex_unlock(&mem_free_lock);
480                                         return -EINVAL;
481                                 }
482                                 param.size = 0;
483                                 prv_data->s_cur_mem_info.paddr = 0;
484                                 prv_data->s_cur_mem_info.vaddr = 0;
485                                 prv_data->s_cur_mem_info.mapped_size = 0;
486                                 prv_data->s_cur_mem_info.req_memblock = 0;
487                                 DEBUG("do_munmap() succeed !!\n");
488                         }
489
490                         if (copy_to_user((struct s3c_mem_alloc *)arg, &param,
491                                          sizeof(struct s3c_mem_alloc))) {
492                                 mutex_unlock(&mem_free_lock);
493                                 return -EFAULT;
494                         }
495
496                         mutex_unlock(&mem_free_lock);
497                 }
498                 break;
499 #endif
500         case S3C_MEM_SHARE_FREE:
501                 mutex_lock(&mem_share_free_lock);
502                 if (copy_from_user(&param, (struct s3c_mem_alloc *)arg,
503                                    sizeof(struct s3c_mem_alloc))) {
504                         mutex_unlock(&mem_share_free_lock);
505                         return -EFAULT; }
506
507                 DEBUG("MEM_SHARE_FREE : param.phy_addr = 0x%X \t "
508                       "size = %d \t param.vir_addr = 0x%X, %d\n",
509                                 param.phy_addr, param.size, param.vir_addr,
510                                 __LINE__);
511
512                 if (do_munmap(mm, param.vir_addr, param.size) < 0) {
513                         printk(KERN_INFO "do_munmap() failed - MEM_SHARE_FREE!!\n");
514                         mutex_unlock(&mem_share_free_lock);
515                         return -EINVAL;
516                 }
517
518                 param.vir_addr = 0;
519                 DEBUG("do_munmap() succeed !! - MEM_SHARE_FREE\n");
520
521                 if (copy_to_user((struct s3c_mem_alloc *)arg, &param,
522                                  sizeof(struct s3c_mem_alloc))) {
523                         mutex_unlock(&mem_share_free_lock);
524                         return -EFAULT;
525                 }
526
527                 mutex_unlock(&mem_share_free_lock);
528
529                 break;
530
531 #ifdef CONFIG_S3C_DMA_MEM
532         case S3C_MEM_DMA_COPY:
533                 if (copy_from_user(&dma_param, (struct s3c_mem_dma_param *)arg,
534                                    sizeof(struct s3c_mem_dma_param))) {
535                         return -EFAULT;
536                 }
537                 if (s3c_dma_mem_start(current->mm, &dma_param,
538                                 S3C_DMA_MEM2MEM)) {
539                         return -EINVAL;
540                 }
541                 if (copy_to_user((struct s3c_mem_dma_param *)arg, &dma_param,
542                                  sizeof(struct s3c_mem_dma_param))) {
543                         return -EFAULT;
544                 }
545                 break;
546 #endif
547
548         case S3C_MEM_GET_PADDR:
549                 if (copy_from_user(&param, (struct s3c_mem_alloc *)arg,
550                                    sizeof(struct s3c_mem_alloc))) {
551                         return -EFAULT;
552                 }
553                 start = param.vir_addr;
554                 down_read(&mm->mmap_sem);
555                 vma = find_vma(mm, start);
556
557                 if (vma == NULL) {
558                         up_read(&mm->mmap_sem);
559                         return -EINVAL;
560                 }
561
562                 if (follow_pfn(vma, start, &this_pfn)) {
563                         up_read(&mm->mmap_sem);
564                         return -EINVAL;
565                 }
566
567                 param.phy_addr = this_pfn << PAGE_SHIFT;
568                 up_read(&mm->mmap_sem);
569
570                 if (copy_to_user((struct s3c_mem_alloc *)arg, &param,
571                                  sizeof(struct s3c_mem_alloc))) {
572                         return -EFAULT;
573                 }
574                 break;
575
576         default:
577                 DEBUG("s3c_mem_ioctl() : default !!\n");
578                 return -EINVAL;
579         }
580
581         return 0;
582 }
583 EXPORT_SYMBOL(s3c_mem_ioctl);
584
585 int s3c_mem_mmap(struct file *filp, struct vm_area_struct *vma)
586 {
587         unsigned long pageFrameNo = 0, size, phys_addr;
588
589 #ifdef USE_DMA_ALLOC
590         unsigned long virt_addr;
591 #else
592         unsigned long *virt_addr;
593 #endif
594
595         size = vma->vm_end - vma->vm_start;
596
597         switch (flag) {
598         case MEM_ALLOC:
599         case MEM_ALLOC_CACHEABLE:
600
601 #ifdef USE_DMA_ALLOC
602                 virt_addr = (unsigned long)dma_alloc_writecombine(NULL, size,
603                                 (unsigned int *) &phys_addr,
604                                                                   GFP_KERNEL);
605 #else
606                 virt_addr = kmalloc(size, GFP_DMA | GFP_ATOMIC);
607 #endif
608                 if (!virt_addr) {
609                         printk(KERN_INFO "kmalloc() failed !\n");
610                         return -EINVAL;
611                 }
612                 DEBUG("MMAP_KMALLOC : virt addr = 0x%08x, size = %d, %d\n",
613                       virt_addr, size, __LINE__);
614
615 #ifndef USE_DMA_ALLOC
616                 dmac_map_area(virt_addr, size / sizeof(unsigned long), 2);
617                 phys_addr = virt_to_phys((unsigned long *)virt_addr);
618 #endif
619                 physical_address = (unsigned int)phys_addr;
620
621 #ifdef USE_DMA_ALLOC
622                 virtual_address = virt_addr;
623 #endif
624                 pageFrameNo = __phys_to_pfn(phys_addr);
625                 break;
626 #ifdef CONFIG_S3C_MEM_CMA_ALLOC
627         case MEM_CMA_ALLOC:
628                 {
629                         struct s3c_dev_info *prv_data =
630                             (struct s3c_dev_info *)filp->private_data;
631                         prv_data->s_cur_mem_info.req_memblock =
632                             PAGE_ALIGN(size) / prv_data->dev_slot_size;
633
634                         if (PAGE_ALIGN(size) % prv_data->dev_slot_size)
635                                 prv_data->s_cur_mem_info.req_memblock++;
636
637                         printk(KERN_INFO "required slot=%d size=%lu \n",
638                                prv_data->s_cur_mem_info.req_memblock, size);
639
640                         vma->vm_page_prot =
641                             pgprot_writecombine(vma->vm_page_prot);
642
643                         pageFrameNo = s3c_mapping_slot(prv_data);
644                         if (!pageFrameNo) {
645                                 printk(KERN_ERR "mapping failed !\n");
646                                 return -EINVAL;
647                         }
648
649                 }
650                 break;
651 #endif
652         case MEM_ALLOC_SHARE:
653         case MEM_ALLOC_CACHEABLE_SHARE:
654                 DEBUG("MMAP_KMALLOC_SHARE : phys addr = 0x%08x, %d\n",
655                       physical_address, __LINE__);
656
657 /* page frame number of the address for the physical_address to be shared. */
658                 pageFrameNo = __phys_to_pfn(physical_address);
659                 DEBUG("MMAP_KMALLOC_SHARE : vma->end = 0x%08x, "
660                       "vma->start = 0x%08x, size = %d, %d\n",
661                       vma->vm_end, vma->vm_start, size, __LINE__);
662                 break;
663
664         default:
665                 break;
666         }
667
668         if ((flag == MEM_ALLOC) || (flag == MEM_ALLOC_SHARE))
669                 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
670
671         vma->vm_flags |= VM_RESERVED;
672
673         if (remap_pfn_range(vma, vma->vm_start, pageFrameNo,
674                             size, vma->vm_page_prot)) {
675                 printk(KERN_INFO "s3c_mem_mmap() : remap_pfn_range() failed !\n");
676                 return -EINVAL;
677         }
678
679         return 0;
680 }
681 EXPORT_SYMBOL(s3c_mem_mmap);