[PATCH 1/1] OMAP gptimer based event monitor driver for oprofile

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Siarhei Siamashka <siarhei.siamashka@xxxxxxxxx>
---
 arch/arm/Kconfig                          |    6 ++
 arch/arm/oprofile/Makefile                |    1 +
 arch/arm/oprofile/common.c                |    5 ++
 arch/arm/oprofile/op_arm_model.h          |    2 +
 arch/arm/oprofile/op_model_omap_gptimer.c |   76 +++++++++++++++++++++++++++++
 5 files changed, 90 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/oprofile/op_model_omap_gptimer.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 72b45cd..5f0acee 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -161,6 +161,12 @@ config GENERIC_HARDIRQS_NO__DO_IRQ
 
 if OPROFILE
 
+config OPROFILE_OMAP_GPTIMER
+	def_bool y
+	depends on ARCH_OMAP
+	select CONFIG_OMAP_32K_TIMER
+	select CONFIG_OMAP_DM_TIMER
+
 config OPROFILE_ARMV6
 	def_bool y
 	depends on CPU_V6 && !SMP
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
index 88e31f5..7e9f76e 100644
--- a/arch/arm/oprofile/Makefile
+++ b/arch/arm/oprofile/Makefile
@@ -10,5 +10,6 @@ oprofile-y				:= $(DRIVER_OBJS) common.o backtrace.o
 oprofile-$(CONFIG_CPU_XSCALE)		+= op_model_xscale.o
 oprofile-$(CONFIG_OPROFILE_ARM11_CORE)	+= op_model_arm11_core.o
 oprofile-$(CONFIG_OPROFILE_ARMV6)	+= op_model_v6.o
+oprofile-$(CONFIG_OPROFILE_OMAP_GPTIMER)	+= op_model_omap_gptimer.o
 oprofile-$(CONFIG_OPROFILE_MPCORE)	+= op_model_mpcore.o
 oprofile-$(CONFIG_OPROFILE_ARMV7)	+= op_model_v7.o
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index 3fcd752..add3cb4 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -133,6 +133,11 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
 
 	ops->backtrace = arm_backtrace;
 
+/* comes first, so that it can be overrided by a better implementation */
+#ifdef CONFIG_OPROFILE_OMAP_GPTIMER
+	spec = &op_omap_gptimer_spec;
+#endif
+
 #ifdef CONFIG_CPU_XSCALE
 	spec = &op_xscale_spec;
 #endif
diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h
index 8c4e4f6..db936da 100644
--- a/arch/arm/oprofile/op_arm_model.h
+++ b/arch/arm/oprofile/op_arm_model.h
@@ -24,6 +24,8 @@ struct op_arm_model_spec {
 extern struct op_arm_model_spec op_xscale_spec;
 #endif
 
+extern struct op_arm_model_spec op_omap_gptimer_spec;
+
 extern struct op_arm_model_spec op_armv6_spec;
 extern struct op_arm_model_spec op_mpcore_spec;
 extern struct op_arm_model_spec op_armv7_spec;
diff --git a/arch/arm/oprofile/op_model_omap_gptimer.c b/arch/arm/oprofile/op_model_omap_gptimer.c
new file mode 100644
index 0000000..d67a291
--- /dev/null
+++ b/arch/arm/oprofile/op_model_omap_gptimer.c
@@ -0,0 +1,76 @@
+/**
+ * OMAP gptimer based event monitor driver for oprofile
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ * Author: Siarhei Siamashka <siarhei.siamashka@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <mach/dmtimer.h>
+
+#include "op_counter.h"
+#include "op_arm_model.h"
+
+static struct omap_dm_timer *gptimer;
+
+static int gptimer_init(void)
+{
+	return 0;
+}
+
+static int gptimer_setup(void)
+{
+	return 0;
+}
+
+static irqreturn_t gptimer_interrupt(int irq, void *arg)
+{
+	omap_dm_timer_write_status(gptimer, OMAP_TIMER_INT_OVERFLOW);
+	oprofile_add_sample(get_irq_regs(), 0);
+	return IRQ_HANDLED;
+}
+
+static int gptimer_start(void)
+{
+	u32 count = counter_config[0].count;
+	gptimer = omap_dm_timer_request();
+	BUG_ON(gptimer == NULL);
+	omap_dm_timer_set_source(gptimer, OMAP_TIMER_SRC_32_KHZ);
+	if (request_irq(omap_dm_timer_get_irq(gptimer), gptimer_interrupt,
+			IRQF_DISABLED, "oprofile gptimer", NULL) != 0) {
+		printk(KERN_ERR "oprofile: unable to request gptimer IRQ\n");
+		return -1;
+	}
+
+	if (count < 1)
+		count = 1;
+
+	omap_dm_timer_set_load_start(gptimer, 1, 0xffffffff - count);
+	omap_dm_timer_set_int_enable(gptimer, OMAP_TIMER_INT_OVERFLOW);
+	return 0;
+}
+
+static void gptimer_stop(void)
+{
+	omap_dm_timer_set_int_enable(gptimer, 0);
+	free_irq(omap_dm_timer_get_irq(gptimer), NULL);
+	omap_dm_timer_free(gptimer);
+}
+
+struct op_arm_model_spec op_omap_gptimer_spec = {
+	.init		= gptimer_init,
+	.num_counters	= 1,
+	.setup_ctrs	= gptimer_setup,
+	.start		= gptimer_start,
+	.stop		= gptimer_stop,
+	.name		= "hrtimer",
+};
-- 
1.5.6.5

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux