]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
ENGR00154889-2: Add virtual iim driver
authorTerry Lv <r65388@freescale.com>
Tue, 16 Aug 2011 08:06:24 +0000 (16:06 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Wed, 20 Aug 2014 08:06:52 +0000 (10:06 +0200)
Add virtual iim driver.
This driver will be used by MM team.

Signed-off-by: Terry Lv <r65388@freescale.com>
(cherry picked from commit 6637e480585112bb310fcbd7ccd1cbf1d67cf9ff)
Signed-off-by: Robin Gong <b38343@freescale.com>
drivers/char/Kconfig
drivers/char/Makefile
drivers/char/mxs_viim.c [new file with mode: 0644]

index 5e4ccf16ec7c389bbc71b05e9fc641c0642c605d..dcac68ae02f83dc3e0f47083b098e8819e919052 100644 (file)
@@ -615,5 +615,11 @@ config TILE_SROM
          device appear much like a simple EEPROM, and knows
          how to partition a single ROM for multiple purposes.
 
+config MXS_VIIM
+       tristate "MXS Virtual IIM device driver"
+       depends on (ARCH_MX50 || ARCH_MX6)
+       help
+         Support for access to MXS Virtual IIM device, most people should say N here.
+
 endmenu
 
index 185c3a9cdca9326f70acb22f6a2ecc1ecb0bfb44..cebcf945e6f462d4aa2e162ec3d14160f952b08a 100644 (file)
@@ -57,6 +57,7 @@ obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o
 obj-$(CONFIG_TCG_TPM)          += tpm/
 
 obj-$(CONFIG_PS3_FLASH)                += ps3flash.o
+obj-$(CONFIG_MXS_VIIM)         += mxs_viim.o
 
 obj-$(CONFIG_JS_RTC)           += js-rtc.o
 js-rtc-y = rtc.o
diff --git a/drivers/char/mxs_viim.c b/drivers/char/mxs_viim.c
new file mode 100644 (file)
index 0000000..9384b84
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2009-2011, 2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+
+static unsigned long iim_reg_base0, iim_reg_end0, iim_reg_size0;
+static unsigned long iim_reg_base1, iim_reg_end1, iim_reg_size1;
+static struct device *iim_dev;
+
+/*!
+ * MXS Virtual IIM interface - memory map function
+ * This function maps one page size VIIM registers from VIIM base address0
+ * if the size of the required virtual memory space is less than or equal to
+ * one page size, otherwise this function will also map one page size VIIM
+ * registers from VIIM base address1.
+ *
+ * @param file      struct file *
+ * @param vma       structure vm_area_struct *
+ *
+ * @return          Return 0 on success or negative error code on error
+ */
+static int mxs_viim_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       size_t size = vma->vm_end - vma->vm_start;
+
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+       /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
+       if (remap_pfn_range(vma,
+                           vma->vm_start,
+                           iim_reg_base0 >> PAGE_SHIFT,
+                           iim_reg_size0,
+                           vma->vm_page_prot))
+               return -EAGAIN;
+
+       if (size > iim_reg_size0) {
+               if (remap_pfn_range(vma,
+                                   vma->vm_start + iim_reg_size0,
+                                   iim_reg_base1 >> PAGE_SHIFT,
+                                   iim_reg_size1,
+                                   vma->vm_page_prot))
+                       return -EAGAIN;
+       }
+
+       return 0;
+}
+
+/*!
+ * MXS Virtual IIM interface - open function
+ *
+ * @param inode             struct inode *
+ * @param filp      struct file *
+ *
+ * @return          Return 0 on success or negative error code on error
+ */
+static int mxs_viim_open(struct inode *inode, struct file *filp)
+{
+       return 0;
+}
+
+/*!
+ * MXS Virtual IIM interface - release function
+ *
+ * @param inode             struct inode *
+ * @param filp      struct file *
+ *
+ * @return          Return 0 on success or negative error code on error
+ */
+static int mxs_viim_release(struct inode *inode, struct file *filp)
+{
+       return 0;
+}
+
+static const struct file_operations mxs_viim_fops = {
+       .mmap = mxs_viim_mmap,
+       .open = mxs_viim_open,
+       .release = mxs_viim_release,
+};
+
+static struct miscdevice mxs_viim_miscdev = {
+       .minor = MISC_DYNAMIC_MINOR,
+       .name = "mxs_viim",
+       .fops = &mxs_viim_fops,
+};
+
+/*!
+ * This function is called by the driver framework to get virtual iim base/end
+ * address and register iim misc device.
+ *
+ * @param      dev     The device structure for Virtual IIM passed in by the
+ *                     driver framework.
+ *
+ * @return      Returns 0 on success or negative error code on error
+ */
+static int mxs_viim_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       int ret;
+
+       iim_dev = &pdev->dev;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (IS_ERR(res)) {
+               dev_err(iim_dev, "Unable to get Virtual IIM resource 0\n");
+               return -ENODEV;
+       }
+
+       iim_reg_base0 = res->start;
+       iim_reg_end0 = res->end;
+       iim_reg_size0 = iim_reg_end0 - iim_reg_base0 + 1;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (IS_ERR(res)) {
+               dev_err(iim_dev, "Unable to get Virtual IIM resource 1\n");
+               return -ENODEV;
+       }
+
+       iim_reg_base1 = res->start;
+       iim_reg_end1 = res->end;
+       iim_reg_size1 = iim_reg_end1 - iim_reg_base1 + 1;
+
+       ret = misc_register(&mxs_viim_miscdev);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int mxs_viim_remove(struct platform_device *pdev)
+{
+       misc_deregister(&mxs_viim_miscdev);
+       return 0;
+}
+
+static struct platform_driver mxs_viim_driver = {
+       .driver = {
+                  .owner = THIS_MODULE,
+                  .name = "imx_viim",
+                  },
+       .probe = mxs_viim_probe,
+       .remove = mxs_viim_remove,
+};
+
+static int __init mxs_viim_dev_init(void)
+{
+       return platform_driver_register(&mxs_viim_driver);
+}
+
+static void __exit mxs_viim_dev_cleanup(void)
+{
+       platform_driver_unregister(&mxs_viim_driver);
+}
+
+module_init(mxs_viim_dev_init);
+module_exit(mxs_viim_dev_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("IMX Virtual IIM driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(MISC_DYNAMIC_MINOR);