diff options
author | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
---|---|---|
committer | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
commit | c6da2cfeb05178a11c6d062a06f8078150ee492f (patch) | |
tree | f3b4021d252c52d6463a9b3c1bb7245e399b009c /drivers/char/mem.c | |
parent | c6d7c4dbff353eac7919342ae6b3299a378160a6 (diff) | |
download | kernel_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.c | 117 |
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 |