From 556c92dfa53b3aae2c2504cb2b94226549c71e00 Mon Sep 17 00:00:00 2001 From: Jon Mayo Date: Tue, 28 Feb 2012 20:55:19 -0800 Subject: 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 Reviewed-on: http://git-master/r/91984 Reviewed-by: Simone Willett Tested-by: Simone Willett --- arch/arm/mach-tegra/Makefile | 1 + arch/arm/mach-tegra/timerinfo.c | 74 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 arch/arm/mach-tegra/timerinfo.c 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 + * + * 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 +#include +#include +#include +#include +#include + +#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"); -- cgit v1.2.3