From 8f2d2c660964932bcdf13b2437292ce27a716a38 Mon Sep 17 00:00:00 2001 From: Terry Lv Date: Tue, 16 Aug 2011 16:06:24 +0800 Subject: imx6q: add support for virtual IIM driver Cherry picked from ENGR00154889-2: Add virtual iim driver Add virtual iim driver. This driver will be used by MM team. Signed-off-by: Terry Lv Signed-off-by: Eric Miao --- drivers/char/Kconfig | 6 ++ drivers/char/Makefile | 2 + drivers/char/mxs_viim.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 drivers/char/mxs_viim.c diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 43643033a3a..aabc52d4a23 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -608,6 +608,12 @@ config RAMOOPS This enables panic and oops messages to be logged to a circular buffer in RAM where it can be read back at some later point. +config MXS_VIIM + tristate "MXS Virtual IIM device driver" + depends on (ARCH_MX50 || SOC_IMX6Q) + help + Support for access to MXS Virtual IIM device, most people should say N here. + config MSM_SMD_PKT bool "Enable device interface for some SMD packet ports" default n diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 32762ba769c..338b91abdf9 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -61,6 +61,8 @@ obj-$(CONFIG_TCG_TPM) += tpm/ obj-$(CONFIG_PS3_FLASH) += ps3flash.o obj-$(CONFIG_RAMOOPS) += ramoops.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 index 00000000000..31195b39aa4 --- /dev/null +++ b/drivers/char/mxs_viim.c @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2009-2011 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 +#include +#include +#include +#include +#include + +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); -- cgit v1.2.3