diff options
Diffstat (limited to 'target/linux/coldfire/patches/010-Add-SRAM-char-device-driver-support-for-MCF5445x.patch')
-rw-r--r-- | target/linux/coldfire/patches/010-Add-SRAM-char-device-driver-support-for-MCF5445x.patch | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/target/linux/coldfire/patches/010-Add-SRAM-char-device-driver-support-for-MCF5445x.patch b/target/linux/coldfire/patches/010-Add-SRAM-char-device-driver-support-for-MCF5445x.patch new file mode 100644 index 000000000..ed0516fcd --- /dev/null +++ b/target/linux/coldfire/patches/010-Add-SRAM-char-device-driver-support-for-MCF5445x.patch @@ -0,0 +1,198 @@ +From f54ba59d355f59e4c01b5b9c7dbc2d27b47302d2 Mon Sep 17 00:00:00 2001 +From: Alison Wang <b18965@freescale.com> +Date: Thu, 4 Aug 2011 09:59:41 +0800 +Subject: [PATCH 10/52] Add SRAM char device driver support for MCF5445x + +Created "/dev/sram" device file and implemented the sram mmap() operation to +provide interface for userspace access. + +Signed-off-by: Alison Wang <b18965@freescale.com> +--- + drivers/char/Kconfig | 11 ++++ + drivers/char/Makefile | 2 + + drivers/char/sram.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 164 insertions(+), 0 deletions(-) + create mode 100644 drivers/char/sram.c + +--- a/drivers/char/Kconfig ++++ b/drivers/char/Kconfig +@@ -97,6 +97,17 @@ config DEVKMEM + kind of kernel debugging operations. + When in doubt, say "N". + ++config DEVSRAM ++ tristate "/dev/sram virtual device support" ++ depends on M5445X ++ default m ++ help ++ Say Y here if you want to suppot the SRAM char device. When in ++ doubt, say "N". ++ ++ It implements mmap system call to provide interface for ++ user space access. ++ + config BFIN_JTAG_COMM + tristate "Blackfin JTAG Communication" + depends on BLACKFIN +--- a/drivers/char/Makefile ++++ b/drivers/char/Makefile +@@ -87,3 +87,5 @@ obj-$(CONFIG_RAMOOPS) += ramoops.o + + obj-$(CONFIG_JS_RTC) += js-rtc.o + js-rtc-y = rtc.o ++ ++obj-$(CONFIG_DEVSRAM) += sram.o +--- /dev/null ++++ b/drivers/char/sram.c +@@ -0,0 +1,151 @@ ++/* ++ * linux/drivers/char/sram.c ++ * ++ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved. ++ * Author: Lanttor.Guo@freescale.com ++ * ++ * SRAM char device driver, implements mmap() system call to provide ++ * interface for user space access. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include <linux/module.h> ++#include <linux/moduleparam.h> ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/slab.h> ++#include <linux/fs.h> ++#include <linux/errno.h> ++#include <linux/types.h> ++#include <linux/mm.h> ++#include <linux/kdev_t.h> ++#include <asm/page.h> ++#include <linux/cdev.h> ++#include <linux/device.h> ++ ++MODULE_LICENSE("GPL"); ++ ++static struct class *sram_class; ++static int sram_major; ++static int sram_minor; ++static struct cdev sram_cdev; ++ ++/* ++ * Set up the cdev structure for sram. ++ */ ++static void sram_setup_cdev(struct cdev *dev, int minor, ++ const struct file_operations *fops) ++{ ++ int err, devno = MKDEV(sram_major, minor); ++ ++ cdev_init(dev, fops); ++ dev->owner = THIS_MODULE; ++ dev->ops = fops; ++ err = cdev_add(dev, devno, 1); ++ /* Fail gracefully if need be */ ++ if (err) ++ printk(KERN_NOTICE "Error %d adding sram%d", err, minor); ++} ++ ++static int sram_open(struct inode *inode, struct file *filp) ++{ ++ filp->f_mapping->backing_dev_info = &directly_mappable_cdev_bdi; ++ return 0; ++} ++ ++static int sram_release(struct inode *inode, struct file *filp) ++{ ++ return 0; ++} ++ ++void sram_vma_open(struct vm_area_struct *vma) ++{ ++ printk(KERN_DEBUG "Sram VMA open, virt %lx, phys %lx\n", ++ vma->vm_start, ++ CONFIG_SRAM_BASE + (vma->vm_pgoff << PAGE_SHIFT)); ++} ++ ++void sram_vma_close(struct vm_area_struct *vma) ++{ ++ printk(KERN_DEBUG "Sram VMA close.\n"); ++} ++ ++ ++static struct vm_operations_struct sram_remap_vm_ops = { ++ .open = sram_vma_open, ++ .close = sram_vma_close, ++}; ++ ++static int sram_remap_mmap(struct file *filp, struct vm_area_struct *vma) ++{ ++ size_t size = vma->vm_end - vma->vm_start; ++ ++ if (PAGE_ALIGN(size) > CONFIG_SRAM_SIZE) { ++ printk(KERN_ERR "required length exceed the size " ++ "of physical sram (%x)\n", CONFIG_SRAM_SIZE); ++ return -EAGAIN; ++ } ++ ++ if ((CONFIG_SRAM_BASE + (vma->vm_pgoff << PAGE_SHIFT) + size) ++ > (CONFIG_SRAM_BASE + CONFIG_SRAM_SIZE)) { ++ printk(KERN_ERR "required sram range exceed the size " ++ "of phisical sram\n"); ++ return -EAGAIN; ++ } ++ ++ if (remap_pfn_range(vma, vma->vm_start, ++ (CONFIG_SRAM_BASE >> PAGE_SHIFT) + vma->vm_pgoff, ++ size, ++ vma->vm_page_prot)) { ++ printk(KERN_ERR "remap_pfn_range faile at %s()\n", __func__); ++ return -EAGAIN; ++ } ++ ++ vma->vm_ops = &sram_remap_vm_ops; ++ return 0; ++} ++ ++static const struct file_operations sram_ops = { ++ .owner = THIS_MODULE, ++ .open = sram_open, ++ .release = sram_release, ++ .mmap = sram_remap_mmap, ++}; ++ ++static int __init sram_chrdev_init(void) ++{ ++ int minor_devs = 1; ++ int result; ++ dev_t dev = 0; ++ sram_minor = 0; ++ ++ result = alloc_chrdev_region(&dev, sram_minor, minor_devs, "sram"); ++ sram_major = MAJOR(dev); ++ if (result < 0) { ++ printk(KERN_WARNING "sram: can't get major %d\n", sram_major); ++ return result; ++ } ++ ++ sram_setup_cdev(&sram_cdev, 0, &sram_ops); ++ ++ sram_class = class_create(THIS_MODULE, "sram"); ++ device_create(sram_class, NULL, MKDEV(sram_major, sram_minor), ++ NULL, "sram"); ++ ++ return 0; ++} ++ ++static void sram_chrdev_cleanup(void) ++{ ++ cdev_del(&sram_cdev); ++ device_destroy(sram_class, MKDEV(sram_major, sram_minor)); ++ class_destroy(sram_class); ++ unregister_chrdev_region(MKDEV(sram_major, 0), 1); ++} ++ ++module_init(sram_chrdev_init); ++module_exit(sram_chrdev_cleanup); |