aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/mem.c
diff options
context:
space:
mode:
authorcodeworkx <daniel.hillenbrand@codeworkx.de>2012-06-02 13:09:29 +0200
committercodeworkx <daniel.hillenbrand@codeworkx.de>2012-06-02 13:09:29 +0200
commitc6da2cfeb05178a11c6d062a06f8078150ee492f (patch)
treef3b4021d252c52d6463a9b3c1bb7245e399b009c /drivers/char/mem.c
parentc6d7c4dbff353eac7919342ae6b3299a378160a6 (diff)
downloadkernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.zip
kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.gz
kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.bz2
samsung update 1
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r--drivers/char/mem.c117
1 files changed, 116 insertions, 1 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 8fc04b4..3f4e40f 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -34,6 +34,16 @@
# include <linux/efi.h>
#endif
+#ifdef CONFIG_S3C_MEM
+# include "s3c_mem.h"
+#ifdef CONFIG_S3C_MEM_CMA_ALLOC
+#include <linux/cma.h>
+#include <linux/platform_device.h>
+#define S3CMEM_NAME "s3c-mem"
+
+#endif
+#endif
+
static inline unsigned long size_inside_page(unsigned long start,
unsigned long size)
{
@@ -56,6 +66,7 @@ static inline int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
}
#endif
+#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM)
#ifdef CONFIG_STRICT_DEVMEM
static inline int range_is_allowed(unsigned long pfn, unsigned long size)
{
@@ -81,7 +92,9 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
return 1;
}
#endif
+#endif
+#ifdef CONFIG_DEVMEM
void __weak unxlate_dev_mem_ptr(unsigned long phys, void *addr)
{
}
@@ -208,6 +221,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
*ppos += written;
return written;
}
+#endif /* CONFIG_DEVMEM */
+
+#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM)
int __weak phys_mem_access_prot_allowed(struct file *file,
unsigned long pfn, unsigned long size, pgprot_t *vma_prot)
@@ -329,6 +345,7 @@ static int mmap_mem(struct file *file, struct vm_area_struct *vma)
}
return 0;
}
+#endif /* CONFIG_DEVMEM */
#ifdef CONFIG_DEVKMEM
static int mmap_kmem(struct file *file, struct vm_area_struct *vma)
@@ -693,6 +710,8 @@ static loff_t null_lseek(struct file *file, loff_t offset, int orig)
return file->f_pos = 0;
}
+#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) || defined(CONFIG_DEVPORT)
+
/*
* The memory devices use the full 32/64 bits of the offset, and so we cannot
* check against negative addresses: they are ok. The return value is weird,
@@ -726,10 +745,14 @@ static loff_t memory_lseek(struct file *file, loff_t offset, int orig)
return ret;
}
+#endif
+
+#if defined(CONFIG_DEVMEM) || defined(CONFIG_DEVKMEM) || defined(CONFIG_DEVPORT)
static int open_port(struct inode * inode, struct file * filp)
{
return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
}
+#endif
#define zero_lseek null_lseek
#define full_lseek null_lseek
@@ -739,6 +762,7 @@ static int open_port(struct inode * inode, struct file * filp)
#define open_kmem open_mem
#define open_oldmem open_mem
+#ifdef CONFIG_DEVMEM
static const struct file_operations mem_fops = {
.llseek = memory_lseek,
.read = read_mem,
@@ -747,6 +771,7 @@ static const struct file_operations mem_fops = {
.open = open_mem,
.get_unmapped_area = get_unmapped_area_mem,
};
+#endif
#ifdef CONFIG_DEVKMEM
static const struct file_operations kmem_fops = {
@@ -806,6 +831,34 @@ static const struct file_operations oldmem_fops = {
};
#endif
+#ifdef CONFIG_S3C_MEM
+extern int s3c_mem_mmap(struct file* filp, struct vm_area_struct *vma);
+extern long s3c_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+
+static const struct file_operations s3c_mem_fops = {
+#ifdef CONFIG_S3C_MEM_CMA_ALLOC
+ .open = s3c_mem_open,
+ .release = s3c_mem_release,
+#endif
+ .unlocked_ioctl = s3c_mem_ioctl,
+ .mmap = s3c_mem_mmap,
+};
+#endif
+
+#ifdef CONFIG_EXYNOS_MEM
+extern int exynos_mem_open(struct inode * inode, struct file *filp);
+extern int exynos_mem_release(struct inode * inode, struct file *filp);
+extern long exynos_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+extern int exynos_mem_mmap(struct file* filp, struct vm_area_struct *vma);
+
+static const struct file_operations exynos_mem_fops = {
+ .open = exynos_mem_open,
+ .release = exynos_mem_release,
+ .unlocked_ioctl = exynos_mem_ioctl,
+ .mmap = exynos_mem_mmap,
+};
+#endif
+
static ssize_t kmsg_writev(struct kiocb *iocb, const struct iovec *iv,
unsigned long count, loff_t pos)
{
@@ -850,7 +903,9 @@ static const struct memdev {
const struct file_operations *fops;
struct backing_dev_info *dev_info;
} devlist[] = {
+#ifdef CONFIG_DEVMEM
[1] = { "mem", 0, &mem_fops, &directly_mappable_cdev_bdi },
+#endif
#ifdef CONFIG_DEVKMEM
[2] = { "kmem", 0, &kmem_fops, &directly_mappable_cdev_bdi },
#endif
@@ -866,6 +921,14 @@ static const struct memdev {
#ifdef CONFIG_CRASH_DUMP
[12] = { "oldmem", 0, &oldmem_fops, NULL },
#endif
+#ifdef CONFIG_S3C_MEM
+ [13] = {"s3c-mem", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
+ | S_IWOTH, &s3c_mem_fops},
+#endif
+#ifdef CONFIG_EXYNOS_MEM
+ [14] = {"exynos-mem", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
+ | S_IWOTH, &exynos_mem_fops},
+#endif
};
static int memory_open(struct inode *inode, struct file *filp)
@@ -913,7 +976,9 @@ static int __init chr_dev_init(void)
{
int minor;
int err;
-
+#ifdef CONFIG_S3C_MEM_CMA_ALLOC
+ struct device *dev;
+#endif
err = bdi_init(&zero_bdi);
if (err)
return err;
@@ -929,11 +994,61 @@ static int __init chr_dev_init(void)
for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
if (!devlist[minor].name)
continue;
+#ifndef CONFIG_S3C_MEM_CMA_ALLOC
device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
NULL, devlist[minor].name);
+#else
+ dev = device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
+ NULL, devlist[minor].name);
+ if (strncmp(devlist[minor].name, S3CMEM_NAME, 7) == 0) {
+#ifdef CONFIG_VIDEO_SAMSUNG_USE_DMA_MEM
+
+ s3c_mem_cma_dev =
+ kzalloc(sizeof(struct device), GFP_KERNEL);
+ memcpy(s3c_mem_cma_dev, dev, sizeof(struct device));
+#else
+ struct cma_info s_cma_mem_info;
+ dma_addr_t base_addr = 0;
+ int err, i = 0;
+ err = cma_info(&s_cma_mem_info, dev, 0);
+ if (err) {
+ printk(KERN_INFO "%s: get cma info failed\n",
+ __func__);
+ } else {
+ base_addr =
+ (dma_addr_t) cma_alloc(dev, S3CMEM_NAME,
+ (size_t)
+ s_cma_mem_info.
+ total_size, 0);
+ }
+
+ printk(KERN_INFO "base_addr = 0x%x\n", base_addr);
+ s3c_cma_block_size = SLOT_SIZE * SZ_1K;
+ s3c_cma_max_block_num =
+ (s_cma_mem_info.total_size / s3c_cma_block_size);
+ s3c_slot_info =
+ kzalloc(sizeof(struct s3c_slot_info) *
+ s3c_cma_max_block_num, GFP_KERNEL);
+ for (i = 0; i < s3c_cma_max_block_num; i++) {
+ s3c_slot_info[i].s_start_addr =
+ base_addr + (i * s3c_cma_block_size);
+ s3c_slot_info[i].s_end_addr =
+ s3c_slot_info[i].s_start_addr +
+ s3c_cma_block_size;
+ s3c_slot_info[i].s_size = s3c_cma_block_size;
+ s3c_slot_info[i].s_mapped = false;
+ }
+#endif
+ }
+#endif
+
}
return tty_init();
}
+#ifdef CONFIG_S3C_MEM_CMA_ALLOC
+late_initcall(chr_dev_init);
+#else
fs_initcall(chr_dev_init);
+#endif