diff options
-rw-r--r-- | drivers/char/Kconfig | 6 | ||||
-rw-r--r-- | drivers/char/Makefile | 1 | ||||
-rwxr-xr-x | drivers/char/fsl_otp.h | 4 | ||||
-rw-r--r-- | drivers/char/mxs_viim.c | 175 |
4 files changed, 184 insertions, 2 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 6165732eedc5..125645af6e80 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -638,5 +638,11 @@ config MXC_IIM help Support for access to MXC IIM device, most people should say N here. +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 diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 0103fecd7927..813845aec98e 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -63,6 +63,7 @@ obj-$(CONFIG_PS3_FLASH) += ps3flash.o obj-$(CONFIG_RAMOOPS) += ramoops.o obj-$(CONFIG_MXC_IIM) += mxc_iim.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/fsl_otp.h b/drivers/char/fsl_otp.h index fa2b21e12a88..5f779e53e41a 100755 --- a/drivers/char/fsl_otp.h +++ b/drivers/char/fsl_otp.h @@ -190,7 +190,7 @@ static int set_otp_timing(struct mxc_otp_platform_data *otp_data) /* IMX5 does not need to open the bank anymore */ static int otp_read_prepare(struct mxc_otp_platform_data *otp_data) { - return set_otp_timing(); + return set_otp_timing(otp_data); } static int otp_read_post(struct mxc_otp_platform_data *otp_data) { @@ -202,7 +202,7 @@ static int otp_write_prepare(struct mxc_otp_platform_data *otp_data) int ret = 0; /* [1] set timing */ - ret = set_otp_timing(); + ret = set_otp_timing(otp_data); if (ret) return ret; diff --git a/drivers/char/mxs_viim.c b/drivers/char/mxs_viim.c new file mode 100644 index 000000000000..31195b39aa42 --- /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 <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); |