summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/timerinfo.c
diff options
context:
space:
mode:
authorJon Mayo <jmayo@nvidia.com>2012-02-28 20:55:19 -0800
committerSimone Willett <swillett@nvidia.com>2012-03-23 17:50:47 -0700
commit556c92dfa53b3aae2c2504cb2b94226549c71e00 (patch)
tree80419fd8b8b932b61ab26a39894dc6ac71aa2373 /arch/arm/mach-tegra/timerinfo.c
parent39ed1ef5d7ba00b2d9c7e077cebf0041a2cffb0a (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>
Diffstat (limited to 'arch/arm/mach-tegra/timerinfo.c')
-rw-r--r--arch/arm/mach-tegra/timerinfo.c74
1 files changed, 74 insertions, 0 deletions
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");