diff options
author | Jon Mayo <jmayo@nvidia.com> | 2012-02-28 20:55:19 -0800 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-03-23 17:50:47 -0700 |
commit | 556c92dfa53b3aae2c2504cb2b94226549c71e00 (patch) | |
tree | 80419fd8b8b932b61ab26a39894dc6ac71aa2373 | |
parent | 39ed1ef5d7ba00b2d9c7e077cebf0041a2cffb0a (diff) |
ARM: tegra: timer: add /dev/timerinfo
Add a device that allows read-only mmap() of timer registers.
Reviewed-on: http://git-master/r/87511
(cherry picked from commit 95a6a6dafd97cbc72ea305f17b600be67a03093b)
Change-Id: I8782107dc3a32ff1c5a3a3c68d2ff0e8fb123dc3
Signed-off-by: Jon Mayo <jmayo@nvidia.com>
Reviewed-on: http://git-master/r/91984
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/timerinfo.c | 74 |
2 files changed, 75 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 290ac3300f37..96d4667a51be 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_TEGRA_GRHOST) += syncpt.o obj-y += clock.o obj-y += clock-common.o obj-y += timer.o +obj-y += timerinfo.o ifeq ($(CONFIG_ARCH_TEGRA_2x_SOC),y) obj-y += tegra2_clocks.o obj-y += timer-t2.o diff --git a/arch/arm/mach-tegra/timerinfo.c b/arch/arm/mach-tegra/timerinfo.c new file mode 100644 index 000000000000..b64ea821f4a7 --- /dev/null +++ b/arch/arm/mach-tegra/timerinfo.c @@ -0,0 +1,74 @@ +/* + * arch/arch/mach-tegra/timerinfo.c + * + * Copyright (C) 2012 NVIDIA Corporation. + * + * Author: + * Jon Mayo <jmayo@nvidia.com> + * + * Copyright (C) 2012 NVIDIA Corporation. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/init.h> +#include <linux/fs.h> +#include <linux/mm.h> +#include <linux/platform_device.h> +#include <linux/miscdevice.h> +#include <mach/iomap.h> + +#include "timer.h" + +static int timerinfo_dev_mmap(struct file *file, struct vm_area_struct *vma); + +static const struct file_operations timerinfo_dev_fops = { + .owner = THIS_MODULE, + .open = nonseekable_open, + .mmap = timerinfo_dev_mmap, + .llseek = noop_llseek, +}; + +static struct miscdevice timerinfo_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "timerinfo", + .fops = &timerinfo_dev_fops, +}; + +static int timerinfo_dev_mmap(struct file *file, struct vm_area_struct *vma) +{ + /* start at first page containing TIMERUS_CNTR_1US */ + phys_addr_t addr = TEGRA_TMR1_BASE; + + if (vma->vm_end - vma->vm_start != PAGE_SIZE) + return -EINVAL; + + if (vma->vm_flags & VM_WRITE) + return -EPERM; + + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + + if (remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, PAGE_SIZE, + vma->vm_page_prot)) { + pr_err("%s:remap_pfn_range failed\n", timerinfo_dev.name); + return -EAGAIN; + } + + return 0; +} + +static int __init timerinfo_dev_init(void) +{ + return misc_register(&timerinfo_dev); +} + +module_init(timerinfo_dev_init); +MODULE_LICENSE("GPL"); |