gator: Version 5.18

Signed-off-by: Jon Medhurst <tixy@linaro.org>
diff --git a/drivers/gator/Kconfig b/drivers/gator/Kconfig
new file mode 100644
index 0000000..e46ccb9
--- /dev/null
+++ b/drivers/gator/Kconfig
@@ -0,0 +1,39 @@
+config GATOR
+	tristate "Gator module for ARM's Streamline Performance Analyzer"
+	default m if (ARM || ARM64)
+	depends on PROFILING
+	depends on HIGH_RES_TIMERS
+	depends on LOCAL_TIMERS || !(ARM && SMP)
+	depends on PERF_EVENTS
+	depends on HW_PERF_EVENTS || !(ARM || ARM64)
+	select TRACING
+	help
+	  Gator module for ARM's Streamline Performance Analyzer
+
+config GATOR_WITH_MALI_SUPPORT
+	bool
+
+choice
+	prompt "Enable Mali GPU support in Gator"
+	depends on GATOR
+	optional
+	help
+	  Enable Mali GPU support in Gator
+
+config GATOR_MALI_4XXMP
+	bool "Mali-400MP or Mali-450MP"
+	select GATOR_WITH_MALI_SUPPORT
+
+config GATOR_MALI_T6XX
+	bool "Mali-T604 or Mali-T658"
+	select GATOR_WITH_MALI_SUPPORT
+
+endchoice
+
+config GATOR_MALI_PATH
+	string "Path to Mali driver"
+	depends on GATOR_WITH_MALI_SUPPORT
+	default "drivers/gpu/arm/mali400mp"
+	help
+	  The gator code adds this to its include path so it can get the Mali
+	  trace headers with: #include "linux/mali_linux_trace.h"
diff --git a/drivers/gator/gator.h b/drivers/gator/gator.h
index d8981ed..586cd9e 100644
--- a/drivers/gator/gator.h
+++ b/drivers/gator/gator.h
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
@@ -31,6 +31,7 @@
 #define CORTEX_A9   0xc09
 #define CORTEX_A12  0xc0d
 #define CORTEX_A15  0xc0f
+#define CORTEX_A17  0xc0e
 #define SCORPION    0x00f
 #define SCORPIONMP  0x02d
 #define KRAITSIM    0x049
@@ -47,9 +48,7 @@
 	const int cpuid;
 	// Human readable name
 	const char core_name[MAXSIZE_CORE_NAME];
-	// Perf PMU name
-	const char * const pmu_name;
-	// gatorfs event name
+	// gatorfs event and Perf PMU name
 	const char * const pmnc_name;
 	// compatible from Documentation/devicetree/bindings/arm/cpus.txt
 	const char * const dt_name;
@@ -62,10 +61,6 @@
 /******************************************************************************
  * Filesystem
  ******************************************************************************/
-int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root,
-			     char const *name,
-			     const struct file_operations *fops, int perm);
-
 struct dentry *gatorfs_mkdir(struct super_block *sb, struct dentry *root,
 			     char const *name);
 
@@ -75,8 +70,6 @@
 int gatorfs_create_ro_ulong(struct super_block *sb, struct dentry *root,
 			    char const *name, unsigned long *val);
 
-void gator_op_create_files(struct super_block *sb, struct dentry *root);
-
 /******************************************************************************
  * Tracepoints
  ******************************************************************************/
diff --git a/drivers/gator/gator_annotate.c b/drivers/gator/gator_annotate.c
index 5b9399b..7e2c6e5 100644
--- a/drivers/gator/gator_annotate.c
+++ b/drivers/gator/gator_annotate.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_annotate_kernel.c b/drivers/gator/gator_annotate_kernel.c
index a406e48..0108068 100644
--- a/drivers/gator/gator_annotate_kernel.c
+++ b/drivers/gator/gator_annotate_kernel.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2012-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2012-2014. All rights reserved.
  *
  * 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
@@ -29,12 +29,14 @@
 	}
 }
 
-static void marshal_u16(char *buf, u16 val) {
+static void marshal_u16(char *buf, u16 val)
+{
 	buf[0] = val & 0xff;
 	buf[1] = (val >> 8) & 0xff;
 }
 
-static void marshal_u32(char *buf, u32 val) {
+static void marshal_u32(char *buf, u32 val)
+{
 	buf[0] = val & 0xff;
 	buf[1] = (val >> 8) & 0xff;
 	buf[2] = (val >> 16) & 0xff;
diff --git a/drivers/gator/gator_backtrace.c b/drivers/gator/gator_backtrace.c
index ffacb49..9f305cf 100644
--- a/drivers/gator/gator_backtrace.c
+++ b/drivers/gator/gator_backtrace.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
@@ -30,6 +30,18 @@
 	};
 };
 
+static void gator_add_trace(int cpu, unsigned long address)
+{
+	off_t offset = 0;
+	unsigned long cookie = get_address_cookie(cpu, current, address & ~1, &offset);
+
+	if (cookie == NO_COOKIE || cookie == UNRESOLVED_COOKIE) {
+		offset = address;
+	}
+
+	marshal_backtrace(offset & ~1, cookie, 0);
+}
+
 static void arm_backtrace_eabi(int cpu, struct pt_regs *const regs, unsigned int depth)
 {
 #if defined(__arm__) || defined(__aarch64__)
@@ -122,7 +134,7 @@
 			addr = addr - (unsigned long)mod->module_core;
 		}
 #endif
-		marshal_backtrace(addr & ~1, cookie);
+		marshal_backtrace(addr & ~1, cookie, 1);
 		(*depth)--;
 	}
 
@@ -136,7 +148,7 @@
 #if (defined(__arm__) || defined(__aarch64__)) && !defined(GATOR_KERNEL_STACK_UNWINDING)
 // Disabled by default
 MODULE_PARM_DESC(kernel_stack_unwinding, "Allow kernel stack unwinding.");
-bool kernel_stack_unwinding = 0;
+static bool kernel_stack_unwinding = 0;
 module_param(kernel_stack_unwinding, bool, 0644);
 #endif
 
@@ -163,6 +175,34 @@
 #endif
 	walk_stackframe(&frame, report_trace, &depth);
 #else
-	marshal_backtrace(PC_REG & ~1, NO_COOKIE);
+	marshal_backtrace(PC_REG & ~1, NO_COOKIE, 1);
 #endif
 }
+ 
+static void gator_add_sample(int cpu, struct pt_regs *const regs, u64 time)
+{
+	bool in_kernel;
+	unsigned long exec_cookie;
+
+	if (!regs)
+		return;
+
+	in_kernel = !user_mode(regs);
+	exec_cookie = get_exec_cookie(cpu, current);
+
+	if (!marshal_backtrace_header(exec_cookie, current->tgid, current->pid, time))
+		return;
+
+	if (in_kernel) {
+		kernel_backtrace(cpu, regs);
+	} else {
+		// Cookie+PC
+		gator_add_trace(cpu, PC_REG);
+
+		// Backtrace
+		if (gator_backtrace_depth)
+			arm_backtrace_eabi(cpu, regs, gator_backtrace_depth);
+	}
+
+	marshal_backtrace_footer(time);
+}
diff --git a/drivers/gator/gator_buffer.c b/drivers/gator/gator_buffer.c
new file mode 100644
index 0000000..eba22df
--- /dev/null
+++ b/drivers/gator/gator_buffer.c
@@ -0,0 +1,168 @@
+/**
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
+ *
+ * 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.
+ *
+ */
+
+static void marshal_frame(int cpu, int buftype)
+{
+	int frame;
+
+	if (!per_cpu(gator_buffer, cpu)[buftype]) {
+		return;
+	}
+
+	switch (buftype) {
+	case SUMMARY_BUF:
+		frame = FRAME_SUMMARY;
+		break;
+	case BACKTRACE_BUF:
+		frame = FRAME_BACKTRACE;
+		break;
+	case NAME_BUF:
+		frame = FRAME_NAME;
+		break;
+	case COUNTER_BUF:
+		frame = FRAME_COUNTER;
+		break;
+	case BLOCK_COUNTER_BUF:
+		frame = FRAME_BLOCK_COUNTER;
+		break;
+	case ANNOTATE_BUF:
+		frame = FRAME_ANNOTATE;
+		break;
+	case SCHED_TRACE_BUF:
+		frame = FRAME_SCHED_TRACE;
+		break;
+	case GPU_TRACE_BUF:
+		frame = FRAME_GPU_TRACE;
+		break;
+	case IDLE_BUF:
+		frame = FRAME_IDLE;
+		break;
+	default:
+		frame = -1;
+		break;
+	}
+
+	// add response type
+	if (gator_response_type > 0) {
+		gator_buffer_write_packed_int(cpu, buftype, gator_response_type);
+	}
+
+	// leave space for 4-byte unpacked length
+	per_cpu(gator_buffer_write, cpu)[buftype] = (per_cpu(gator_buffer_write, cpu)[buftype] + sizeof(s32)) & gator_buffer_mask[buftype];
+
+	// add frame type and core number
+	gator_buffer_write_packed_int(cpu, buftype, frame);
+	gator_buffer_write_packed_int(cpu, buftype, cpu);
+}
+
+static int buffer_bytes_available(int cpu, int buftype)
+{
+	int remaining, filled;
+
+	filled = per_cpu(gator_buffer_write, cpu)[buftype] - per_cpu(gator_buffer_read, cpu)[buftype];
+	if (filled < 0) {
+		filled += gator_buffer_size[buftype];
+	}
+
+	remaining = gator_buffer_size[buftype] - filled;
+
+	if (per_cpu(buffer_space_available, cpu)[buftype]) {
+		// Give some extra room; also allows space to insert the overflow error packet
+		remaining -= 200;
+	} else {
+		// Hysteresis, prevents multiple overflow messages
+		remaining -= 2000;
+	}
+
+	return remaining;
+}
+
+static bool buffer_check_space(int cpu, int buftype, int bytes)
+{
+	int remaining = buffer_bytes_available(cpu, buftype);
+
+	if (remaining < bytes) {
+		per_cpu(buffer_space_available, cpu)[buftype] = false;
+	} else {
+		per_cpu(buffer_space_available, cpu)[buftype] = true;
+	}
+
+	return per_cpu(buffer_space_available, cpu)[buftype];
+}
+
+static int contiguous_space_available(int cpu, int buftype)
+{
+	int remaining = buffer_bytes_available(cpu, buftype);
+	int contiguous = gator_buffer_size[buftype] - per_cpu(gator_buffer_write, cpu)[buftype];
+	if (remaining < contiguous)
+		return remaining;
+	else
+		return contiguous;
+}
+
+static void gator_commit_buffer(int cpu, int buftype, u64 time)
+{
+	int type_length, commit, length, byte;
+	unsigned long flags;
+
+	if (!per_cpu(gator_buffer, cpu)[buftype])
+		return;
+
+	// post-populate the length, which does not include the response type length nor the length itself, i.e. only the length of the payload
+	local_irq_save(flags);
+	type_length = gator_response_type ? 1 : 0;
+	commit = per_cpu(gator_buffer_commit, cpu)[buftype];
+	length = per_cpu(gator_buffer_write, cpu)[buftype] - commit;
+	if (length < 0) {
+		length += gator_buffer_size[buftype];
+	}
+	length = length - type_length - sizeof(s32);
+
+	if (length <= FRAME_HEADER_SIZE) {
+		// Nothing to write, only the frame header is present
+		local_irq_restore(flags);
+		return;
+	}
+
+	for (byte = 0; byte < sizeof(s32); byte++) {
+		per_cpu(gator_buffer, cpu)[buftype][(commit + type_length + byte) & gator_buffer_mask[buftype]] = (length >> byte * 8) & 0xFF;
+	}
+
+	per_cpu(gator_buffer_commit, cpu)[buftype] = per_cpu(gator_buffer_write, cpu)[buftype];
+
+	if (gator_live_rate > 0) {
+		while (time > per_cpu(gator_buffer_commit_time, cpu)) {
+			per_cpu(gator_buffer_commit_time, cpu) += gator_live_rate;
+		}
+	}
+
+	marshal_frame(cpu, buftype);
+	local_irq_restore(flags);
+
+	// had to delay scheduling work as attempting to schedule work during the context switch is illegal in kernel versions 3.5 and greater
+	if (per_cpu(in_scheduler_context, cpu)) {
+#ifndef CONFIG_PREEMPT_RT_FULL
+		// mod_timer can not be used in interrupt context in RT-Preempt full
+		mod_timer(&gator_buffer_wake_up_timer, jiffies + 1);
+#endif
+	} else {
+		up(&gator_buffer_wake_sem);
+	}
+}
+
+static void buffer_check(int cpu, int buftype, u64 time)
+{
+	int filled = per_cpu(gator_buffer_write, cpu)[buftype] - per_cpu(gator_buffer_commit, cpu)[buftype];
+	if (filled < 0) {
+		filled += gator_buffer_size[buftype];
+	}
+	if (filled >= ((gator_buffer_size[buftype] * 3) / 4)) {
+		gator_commit_buffer(cpu, buftype, time);
+	}
+}
diff --git a/drivers/gator/gator_pack.c b/drivers/gator/gator_buffer_write.c
similarity index 68%
rename from drivers/gator/gator_pack.c
rename to drivers/gator/gator_buffer_write.c
index 2c082f2..b621ba9 100644
--- a/drivers/gator/gator_pack.c
+++ b/drivers/gator/gator_buffer_write.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
@@ -56,3 +56,25 @@
 
 	per_cpu(gator_buffer_write, cpu)[buftype] = (write + packedBytes) & mask;
 }
+
+static void gator_buffer_write_bytes(int cpu, int buftype, const char *x, int len)
+{
+	int i;
+	u32 write = per_cpu(gator_buffer_write, cpu)[buftype];
+	u32 mask = gator_buffer_mask[buftype];
+	char *buffer = per_cpu(gator_buffer, cpu)[buftype];
+
+	for (i = 0; i < len; i++) {
+		buffer[write] = x[i];
+		write = (write + 1) & mask;
+	}
+
+	per_cpu(gator_buffer_write, cpu)[buftype] = write;
+}
+
+static void gator_buffer_write_string(int cpu, int buftype, const char *x)
+{
+	int len = strlen(x);
+	gator_buffer_write_packed_int(cpu, buftype, len);
+	gator_buffer_write_bytes(cpu, buftype, x, len);
+}
diff --git a/drivers/gator/gator_cookies.c b/drivers/gator/gator_cookies.c
index 91adfdd..5c7d842 100644
--- a/drivers/gator/gator_cookies.c
+++ b/drivers/gator/gator_cookies.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
@@ -15,17 +15,22 @@
 static uint32_t *gator_crc32_table;
 static unsigned int translate_buffer_mask;
 
+struct cookie_args {
+	struct task_struct *task;
+	const char *text;
+};
+
 static DEFINE_PER_CPU(char *, translate_text);
 static DEFINE_PER_CPU(uint32_t, cookie_next_key);
 static DEFINE_PER_CPU(uint64_t *, cookie_keys);
 static DEFINE_PER_CPU(uint32_t *, cookie_values);
 static DEFINE_PER_CPU(int, translate_buffer_read);
 static DEFINE_PER_CPU(int, translate_buffer_write);
-static DEFINE_PER_CPU(void **, translate_buffer);
+static DEFINE_PER_CPU(struct cookie_args *, translate_buffer);
 
 static uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq);
 static void wq_cookie_handler(struct work_struct *unused);
-DECLARE_WORK(cookie_work, wq_cookie_handler);
+static DECLARE_WORK(cookie_work, wq_cookie_handler);
 static struct timer_list app_process_wake_up_timer;
 static void app_process_wake_up_handler(unsigned long unused_data);
 
@@ -109,36 +114,62 @@
 }
 
 #ifndef CONFIG_PREEMPT_RT_FULL
-static void translate_buffer_write_ptr(int cpu, void *x)
+static void translate_buffer_write_args(int cpu, struct task_struct *task, const char *text)
 {
-	per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x;
-	per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask;
+	unsigned long flags;
+	int write;
+	int next_write;
+	struct cookie_args *args;
+
+	local_irq_save(flags);
+
+	write = per_cpu(translate_buffer_write, cpu);
+	next_write = (write + 1) & translate_buffer_mask;
+
+	// At least one entry must always remain available as when read == write, the queue is empty not full
+	if (next_write != per_cpu(translate_buffer_read, cpu)) {
+		args = &per_cpu(translate_buffer, cpu)[write];
+		args->task = task;
+		args->text = text;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
+		get_task_struct(task);
+#endif
+		per_cpu(translate_buffer_write, cpu) = next_write;
+	}
+
+	local_irq_restore(flags);
 }
 #endif
 
-static void *translate_buffer_read_ptr(int cpu)
+static void translate_buffer_read_args(int cpu, struct cookie_args *args)
 {
-	void *value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++];
-	per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask;
-	return value;
+	unsigned long flags;
+	int read;
+
+	local_irq_save(flags);
+
+	read = per_cpu(translate_buffer_read, cpu);
+	*args = per_cpu(translate_buffer, cpu)[read];
+	per_cpu(translate_buffer_read, cpu) = (read + 1) & translate_buffer_mask;
+
+	local_irq_restore(flags);
 }
 
 static void wq_cookie_handler(struct work_struct *unused)
 {
-	struct task_struct *task;
-	char *text;
+	struct cookie_args args;
 	int cpu = get_physical_cpu(), cookie;
-	unsigned int commit;
 
 	mutex_lock(&start_mutex);
 
 	if (gator_started != 0) {
-		commit = per_cpu(translate_buffer_write, cpu);
-		while (per_cpu(translate_buffer_read, cpu) != commit) {
-			task = (struct task_struct *)translate_buffer_read_ptr(cpu);
-			text = (char *)translate_buffer_read_ptr(cpu);
-			cookie = get_cookie(cpu, task, text, true);
-			marshal_link(cookie, task->tgid, task->pid);
+		while (per_cpu(translate_buffer_read, cpu) != per_cpu(translate_buffer_write, cpu)) {
+			translate_buffer_read_args(cpu, &args);
+			cookie = get_cookie(cpu, args.task, args.text, true);
+			marshal_link(cookie, args.task->tgid, args.task->pid);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
+			put_task_struct(args.task);
+#endif
 		}
 	}
 
@@ -169,15 +200,14 @@
 	//   inconsistent during a context switch between android/linux versions
 	if (!from_wq) {
 		// Check if already in buffer
-		int ptr = per_cpu(translate_buffer_read, cpu);
-		while (ptr != per_cpu(translate_buffer_write, cpu)) {
-			if (per_cpu(translate_buffer, cpu)[ptr] == (void *)task)
+		int pos = per_cpu(translate_buffer_read, cpu);
+		while (pos != per_cpu(translate_buffer_write, cpu)) {
+			if (per_cpu(translate_buffer, cpu)[pos].task == task)
 				goto out;
-			ptr = (ptr + 2) & translate_buffer_mask;
+			pos = (pos + 1) & translate_buffer_mask;
 		}
 
-		translate_buffer_write_ptr(cpu, (void *)task);
-		translate_buffer_write_ptr(cpu, (void *)*text);
+		translate_buffer_write_args(cpu, task, *text);
 
 		// Not safe to call in RT-Preempt full in schedule switch context
 		mod_timer(&app_process_wake_up_timer, jiffies + 1);
@@ -340,7 +370,7 @@
 		}
 		memset(per_cpu(cookie_values, cpu), 0, size);
 
-		per_cpu(translate_buffer, cpu) = (void **)kmalloc(TRANSLATE_BUFFER_SIZE, GFP_KERNEL);
+		per_cpu(translate_buffer, cpu) = (struct cookie_args *)kmalloc(TRANSLATE_BUFFER_SIZE, GFP_KERNEL);
 		if (!per_cpu(translate_buffer, cpu)) {
 			err = -ENOMEM;
 			goto cookie_setup_error;
diff --git a/drivers/gator/gator_events_armv6.c b/drivers/gator/gator_events_armv6.c
index dd79740..3536456 100644
--- a/drivers/gator/gator_events_armv6.c
+++ b/drivers/gator/gator_events_armv6.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_armv7.c b/drivers/gator/gator_events_armv7.c
index 30881c8..153119b 100644
--- a/drivers/gator/gator_events_armv7.c
+++ b/drivers/gator/gator_events_armv7.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
@@ -141,9 +141,9 @@
 	for (i = 0; i < pmnc_counters; i++) {
 		char buf[40];
 		if (i == 0) {
-			snprintf(buf, sizeof buf, "ARM_%s_ccnt", pmnc_name);
+			snprintf(buf, sizeof buf, "%s_ccnt", pmnc_name);
 		} else {
-			snprintf(buf, sizeof buf, "ARM_%s_cnt%d", pmnc_name, i - 1);
+			snprintf(buf, sizeof buf, "%s_cnt%d", pmnc_name, i - 1);
 		}
 		dir = gatorfs_mkdir(sb, root, buf);
 		if (!dir) {
@@ -275,25 +275,27 @@
 
 	switch (gator_cpuid()) {
 	case CORTEX_A5:
-		pmnc_name = "Cortex-A5";
+		pmnc_name = "ARMv7_Cortex_A5";
 		pmnc_counters = 2;
 		break;
 	case CORTEX_A7:
-		pmnc_name = "Cortex-A7";
+		pmnc_name = "ARMv7_Cortex_A7";
 		pmnc_counters = 4;
 		break;
 	case CORTEX_A8:
-		pmnc_name = "Cortex-A8";
+		pmnc_name = "ARMv7_Cortex_A8";
 		pmnc_counters = 4;
 		break;
 	case CORTEX_A9:
-		pmnc_name = "Cortex-A9";
+		pmnc_name = "ARMv7_Cortex_A9";
 		pmnc_counters = 6;
 		break;
+	// ARM Cortex A12 is not supported by version of Linux before 3.0
 	case CORTEX_A15:
-		pmnc_name = "Cortex-A15";
+		pmnc_name = "ARMv7_Cortex_A15";
 		pmnc_counters = 6;
 		break;
+	// ARM Cortex A17 is not supported by version of Linux before 3.0
 	default:
 		return -1;
 	}
diff --git a/drivers/gator/gator_events_block.c b/drivers/gator/gator_events_block.c
index 691ef25..b2bc414 100644
--- a/drivers/gator/gator_events_block.c
+++ b/drivers/gator/gator_events_block.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_ccn-504.c b/drivers/gator/gator_events_ccn-504.c
index b892319..024ffc2 100644
--- a/drivers/gator/gator_events_ccn-504.c
+++ b/drivers/gator/gator_events_ccn-504.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2013. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_irq.c b/drivers/gator/gator_events_irq.c
index b11879a..facbdd6 100644
--- a/drivers/gator/gator_events_irq.c
+++ b/drivers/gator/gator_events_irq.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_l2c-310.c b/drivers/gator/gator_events_l2c-310.c
index ee521af..553f970 100644
--- a/drivers/gator/gator_events_l2c-310.c
+++ b/drivers/gator/gator_events_l2c-310.c
@@ -1,7 +1,7 @@
 /**
  * l2c310 (L2 Cache Controller) event counters for gator
  *
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_mali_4xx.c b/drivers/gator/gator_events_mali_4xx.c
index 6719c1e..85d4764 100644
--- a/drivers/gator/gator_events_mali_4xx.c
+++ b/drivers/gator/gator_events_mali_4xx.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_mali_4xx.h b/drivers/gator/gator_events_mali_4xx.h
index 413ad0f..976ca8c 100644
--- a/drivers/gator/gator_events_mali_4xx.h
+++ b/drivers/gator/gator_events_mali_4xx.h
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2011-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2011-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_mali_common.c b/drivers/gator/gator_events_mali_common.c
index 466ca16..dc58dcf 100644
--- a/drivers/gator/gator_events_mali_common.c
+++ b/drivers/gator/gator_events_mali_common.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2012-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2012-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_mali_common.h b/drivers/gator/gator_events_mali_common.h
index 509f9b6..41c2a3c 100644
--- a/drivers/gator/gator_events_mali_common.h
+++ b/drivers/gator/gator_events_mali_common.h
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2012-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2012-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_mali_t6xx.c b/drivers/gator/gator_events_mali_t6xx.c
index 7bf7d6a..76f14ee 100644
--- a/drivers/gator/gator_events_mali_t6xx.c
+++ b/drivers/gator/gator_events_mali_t6xx.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2011-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2011-2014. All rights reserved.
  *
  * 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
@@ -15,7 +15,13 @@
 #include <linux/slab.h>
 #include <asm/io.h>
 
+#ifdef MALI_DIR_MIDGARD
+/* New DDK Directory structure with kernel/drivers/gpu/arm/midgard*/
+#include "mali_linux_trace.h"
+#else
+/* Old DDK Directory structure with kernel/drivers/gpu/arm/t6xx*/
 #include "linux/mali_linux_trace.h"
+#endif
 
 #include "gator_events_mali_common.h"
 
diff --git a/drivers/gator/gator_events_mali_t6xx_hw.c b/drivers/gator/gator_events_mali_t6xx_hw.c
index e406991..dfbc91f 100644
--- a/drivers/gator/gator_events_mali_t6xx_hw.c
+++ b/drivers/gator/gator_events_mali_t6xx_hw.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2012-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2012-2014. All rights reserved.
  *
  * 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
@@ -16,9 +16,17 @@
 #include <asm/io.h>
 
 /* Mali T6xx DDK includes */
+#ifdef MALI_DIR_MIDGARD
+/* New DDK Directory structure with kernel/drivers/gpu/arm/midgard*/
+#include "mali_linux_trace.h"
+#include "mali_kbase.h"
+#include "mali_kbase_mem_linux.h"
+#else
+/* Old DDK Directory structure with kernel/drivers/gpu/arm/t6xx*/
 #include "linux/mali_linux_trace.h"
 #include "kbase/src/common/mali_kbase.h"
 #include "kbase/src/linux/mali_kbase_mem_linux.h"
+#endif
 
 #include "gator_events_mali_common.h"
 
diff --git a/drivers/gator/gator_events_mali_t6xx_hw_test.c b/drivers/gator/gator_events_mali_t6xx_hw_test.c
index efb32dd..ba6553f 100644
--- a/drivers/gator/gator_events_mali_t6xx_hw_test.c
+++ b/drivers/gator/gator_events_mali_t6xx_hw_test.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2012-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2012-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_meminfo.c b/drivers/gator/gator_events_meminfo.c
index 451290d..c633dfd 100644
--- a/drivers/gator/gator_events_meminfo.c
+++ b/drivers/gator/gator_events_meminfo.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
@@ -274,6 +274,28 @@
 	return meminfo_length;
 }
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)
+
+static inline unsigned long gator_get_mm_counter(struct mm_struct *mm, int member)
+{
+#ifdef SPLIT_RSS_COUNTING
+	long val = atomic_long_read(&mm->rss_stat.count[member]);
+	if (val < 0)
+		val = 0;
+	return (unsigned long)val;
+#else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0)
+	return mm->rss_stat.count[member];
+#else
+	return atomic_long_read(&mm->rss_stat.count[member]);
+#endif
+#endif
+}
+
+#define get_mm_counter(mm, member) gator_get_mm_counter(mm, member)
+
+#endif
+
 static int gator_events_meminfo_read_proc(long long **buffer, struct task_struct *task)
 {
 	struct mm_struct *mm;
@@ -302,7 +324,7 @@
 	// Derived from task_statm in fs/proc/task_mmu.c
 	if (meminfo_enabled[MEMINFO_MEMUSED] || proc_enabled[PROC_SHARE]) {
 		share = get_mm_counter(mm,
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 32)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
 							   file_rss
 #else
 							   MM_FILEPAGES
@@ -338,7 +360,7 @@
 
 	if (meminfo_enabled[MEMINFO_MEMUSED]) {
 		value = share + get_mm_counter(mm,
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 32)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
 									   anon_rss
 #else
 									   MM_ANONPAGES
diff --git a/drivers/gator/gator_events_mmapped.c b/drivers/gator/gator_events_mmapped.c
index f055e48..3b248ec 100644
--- a/drivers/gator/gator_events_mmapped.c
+++ b/drivers/gator/gator_events_mmapped.c
@@ -1,7 +1,7 @@
 /*
  * Example events provider
  *
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_net.c b/drivers/gator/gator_events_net.c
index 9c8d3a4..11c10e3 100644
--- a/drivers/gator/gator_events_net.c
+++ b/drivers/gator/gator_events_net.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_perf_pmu.c b/drivers/gator/gator_events_perf_pmu.c
index d472df9..8b2d67a 100644
--- a/drivers/gator/gator_events_perf_pmu.c
+++ b/drivers/gator/gator_events_perf_pmu.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_sched.c b/drivers/gator/gator_events_sched.c
index 29f4e39..9e39158 100644
--- a/drivers/gator/gator_events_sched.c
+++ b/drivers/gator/gator_events_sched.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_events_scorpion.c b/drivers/gator/gator_events_scorpion.c
index c91db12..8ca251a 100644
--- a/drivers/gator/gator_events_scorpion.c
+++ b/drivers/gator/gator_events_scorpion.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2011-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2011-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_fs.c b/drivers/gator/gator_fs.c
index fe6f83d..166cfe7 100644
--- a/drivers/gator/gator_fs.c
+++ b/drivers/gator/gator_fs.c
@@ -39,12 +39,7 @@
 	.drop_inode = generic_delete_inode,
 };
 
-ssize_t gatorfs_str_to_user(char const *str, char __user *buf, size_t count, loff_t *offset)
-{
-	return simple_read_from_buffer(buf, count, offset, str, strlen(str));
-}
-
-ssize_t gatorfs_ulong_to_user(unsigned long val, char __user *buf, size_t count, loff_t *offset)
+static ssize_t gatorfs_ulong_to_user(unsigned long val, char __user *buf, size_t count, loff_t *offset)
 {
 	char tmpbuf[TMPBUFSIZE];
 	size_t maxlen = snprintf(tmpbuf, TMPBUFSIZE, "%lu\n", val);
@@ -53,7 +48,7 @@
 	return simple_read_from_buffer(buf, count, offset, tmpbuf, maxlen);
 }
 
-ssize_t gatorfs_u64_to_user(u64 val, char __user *buf, size_t count, loff_t *offset)
+static ssize_t gatorfs_u64_to_user(u64 val, char __user *buf, size_t count, loff_t *offset)
 {
 	char tmpbuf[TMPBUFSIZE];
 	size_t maxlen = snprintf(tmpbuf, TMPBUFSIZE, "%llu\n", val);
@@ -62,7 +57,7 @@
 	return simple_read_from_buffer(buf, count, offset, tmpbuf, maxlen);
 }
 
-int gatorfs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count)
+static int gatorfs_ulong_from_user(unsigned long *val, char const __user *buf, size_t count)
 {
 	char tmpbuf[TMPBUFSIZE];
 	unsigned long flags;
@@ -84,7 +79,7 @@
 	return 0;
 }
 
-int gatorfs_u64_from_user(u64 *val, char const __user *buf, size_t count)
+static int gatorfs_u64_from_user(u64 *val, char const __user *buf, size_t count)
 {
 	char tmpbuf[TMPBUFSIZE];
 	unsigned long flags;
@@ -211,8 +206,8 @@
 	return 0;
 }
 
-int gatorfs_create_u64(struct super_block *sb, struct dentry *root,
-			 char const *name, u64 *val)
+static int gatorfs_create_u64(struct super_block *sb, struct dentry *root,
+			      char const *name, u64 *val)
 {
 	struct dentry *d = __gatorfs_create_file(sb, root, name,
 						 &u64_fops, 0644);
@@ -235,8 +230,8 @@
 	return 0;
 }
 
-int gatorfs_create_ro_u64(struct super_block *sb, struct dentry *root,
-			  char const *name, u64 * val)
+static int gatorfs_create_ro_u64(struct super_block *sb, struct dentry *root,
+				 char const *name, u64 * val)
 {
 	struct dentry *d =
 	    __gatorfs_create_file(sb, root, name, &u64_ro_fops, 0444);
@@ -258,29 +253,17 @@
 	.open = default_open,
 };
 
-int gatorfs_create_ro_atomic(struct super_block *sb, struct dentry *root,
-			     char const *name, atomic_t *val)
-{
-	struct dentry *d = __gatorfs_create_file(sb, root, name,
-						 &atomic_ro_fops, 0444);
-	if (!d)
-		return -EFAULT;
-
-	d->d_inode->i_private = val;
-	return 0;
-}
-
-int gatorfs_create_file(struct super_block *sb, struct dentry *root,
-			char const *name, const struct file_operations *fops)
+static int gatorfs_create_file(struct super_block *sb, struct dentry *root,
+			       char const *name, const struct file_operations *fops)
 {
 	if (!__gatorfs_create_file(sb, root, name, fops, 0644))
 		return -EFAULT;
 	return 0;
 }
 
-int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root,
-			     char const *name,
-			     const struct file_operations *fops, int perm)
+static int gatorfs_create_file_perm(struct super_block *sb, struct dentry *root,
+				    char const *name,
+				    const struct file_operations *fops, int perm)
 {
 	if (!__gatorfs_create_file(sb, root, name, fops, perm))
 		return -EFAULT;
@@ -371,12 +354,12 @@
 	.kill_sb = kill_litter_super,
 };
 
-int __init gatorfs_register(void)
+static int __init gatorfs_register(void)
 {
 	return register_filesystem(&gatorfs_type);
 }
 
-void gatorfs_unregister(void)
+static void gatorfs_unregister(void)
 {
 	unregister_filesystem(&gatorfs_type);
 }
diff --git a/drivers/gator/gator_hrtimer_gator.c b/drivers/gator/gator_hrtimer_gator.c
index b0c947a..7658455 100644
--- a/drivers/gator/gator_hrtimer_gator.c
+++ b/drivers/gator/gator_hrtimer_gator.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2011-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2011-2014. All rights reserved.
  *
  * 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
@@ -7,10 +7,6 @@
  *
  */
 
-// gator_hrtimer_perf.c is used if perf is supported
-//   update, gator_hrtimer_gator.c always used until issues resolved with perf hrtimers
-#if 1
-
 void (*callback)(void);
 DEFINE_PER_CPU(struct hrtimer, percpu_hrtimer);
 DEFINE_PER_CPU(ktime_t, hrtimer_expire);
@@ -82,5 +78,3 @@
 {
 	/* empty */
 }
-
-#endif
diff --git a/drivers/gator/gator_hrtimer_perf.c b/drivers/gator/gator_hrtimer_perf.c
deleted file mode 100644
index 7b95399..0000000
--- a/drivers/gator/gator_hrtimer_perf.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * Copyright (C) ARM Limited 2011-2013. All rights reserved.
- *
- * 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.
- *
- */
-
-// gator_hrtimer_gator.c is used if perf is not supported
-//   update, gator_hrtimer_gator.c always used until issues resolved with perf hrtimers
-#if 0
-
-// Note: perf Cortex support added in 2.6.35 and PERF_COUNT_SW_CPU_CLOCK/hrtimer broken on 2.6.35 and 2.6.36
-//       not relevant as this code is not active until 3.0.0, but wanted to document the issue
-
-void (*callback)(void);
-static int profiling_interval;
-static DEFINE_PER_CPU(struct perf_event *, perf_hrtimer);
-static DEFINE_PER_CPU(struct perf_event_attr *, perf_hrtimer_attr);
-
-static void gator_hrtimer_shutdown(void);
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
-static void hrtimer_overflow_handler(struct perf_event *event, int unused, struct perf_sample_data *data, struct pt_regs *regs)
-#else
-static void hrtimer_overflow_handler(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs)
-#endif
-{
-	(*callback)();
-}
-
-static int gator_online_single_hrtimer(int cpu)
-{
-	if (per_cpu(perf_hrtimer, cpu) != 0 || per_cpu(perf_hrtimer_attr, cpu) == 0)
-		return 0;
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 1, 0)
-	per_cpu(perf_hrtimer, cpu) = perf_event_create_kernel_counter(per_cpu(perf_hrtimer_attr, cpu), cpu, 0, hrtimer_overflow_handler);
-#else
-	per_cpu(perf_hrtimer, cpu) = perf_event_create_kernel_counter(per_cpu(perf_hrtimer_attr, cpu), cpu, 0, hrtimer_overflow_handler, 0);
-#endif
-	if (IS_ERR(per_cpu(perf_hrtimer, cpu))) {
-		per_cpu(perf_hrtimer, cpu) = NULL;
-		return -1;
-	}
-
-	if (per_cpu(perf_hrtimer, cpu)->state != PERF_EVENT_STATE_ACTIVE) {
-		perf_event_release_kernel(per_cpu(perf_hrtimer, cpu));
-		per_cpu(perf_hrtimer, cpu) = NULL;
-		return -1;
-	}
-
-	return 0;
-}
-
-static void gator_hrtimer_online(int cpu)
-{
-	if (gator_online_single_hrtimer(cpu) < 0) {
-		pr_debug("gator: unable to online the hrtimer on cpu%d\n", cpu);
-	}
-}
-
-static void gator_hrtimer_offline(int cpu)
-{
-	if (per_cpu(perf_hrtimer, cpu)) {
-		perf_event_release_kernel(per_cpu(perf_hrtimer, cpu));
-		per_cpu(perf_hrtimer, cpu) = NULL;
-	}
-}
-
-static int gator_hrtimer_init(int interval, void (*func)(void))
-{
-	u32 size = sizeof(struct perf_event_attr);
-	int cpu;
-
-	callback = func;
-
-	// calculate profiling interval
-	profiling_interval = 1000000000 / interval;
-
-	for_each_present_cpu(cpu) {
-		per_cpu(perf_hrtimer, cpu) = 0;
-		per_cpu(perf_hrtimer_attr, cpu) = kmalloc(size, GFP_KERNEL);
-		if (per_cpu(perf_hrtimer_attr, cpu) == 0) {
-			gator_hrtimer_shutdown();
-			return -1;
-		}
-
-		memset(per_cpu(perf_hrtimer_attr, cpu), 0, size);
-		per_cpu(perf_hrtimer_attr, cpu)->type = PERF_TYPE_SOFTWARE;
-		per_cpu(perf_hrtimer_attr, cpu)->size = size;
-		per_cpu(perf_hrtimer_attr, cpu)->config = PERF_COUNT_SW_CPU_CLOCK;
-		per_cpu(perf_hrtimer_attr, cpu)->sample_period = profiling_interval;
-		per_cpu(perf_hrtimer_attr, cpu)->pinned = 1;
-	}
-
-	return 0;
-}
-
-static void gator_hrtimer_shutdown(void)
-{
-	int cpu;
-
-	for_each_present_cpu(cpu) {
-		if (per_cpu(perf_hrtimer_attr, cpu)) {
-			kfree(per_cpu(perf_hrtimer_attr, cpu));
-			per_cpu(perf_hrtimer_attr, cpu) = NULL;
-		}
-	}
-}
-
-#endif
diff --git a/drivers/gator/gator_iks.c b/drivers/gator/gator_iks.c
index 24233d7..e90dfcc 100644
--- a/drivers/gator/gator_iks.c
+++ b/drivers/gator/gator_iks.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2013. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2014. All rights reserved.
  *
  * 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
@@ -147,11 +147,13 @@
 {
 	int cpu;
 	// Send the cpu names
+	preempt_disable();
 	for (cpu = 0; cpu < nr_cpu_ids; ++cpu) {
 		if (mpidr_cpus[cpu] != NULL) {
 			gator_send_core_name(cpu, mpidr_cpus[cpu]->cpuid, mpidr_cpus[cpu]);
 		}
 	}
+	preempt_enable();
 }
 
 static int gator_migrate_start(void)
diff --git a/drivers/gator/gator_main.c b/drivers/gator/gator_main.c
index 9773ae2..e67f7c5 100644
--- a/drivers/gator/gator_main.c
+++ b/drivers/gator/gator_main.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
@@ -8,7 +8,7 @@
  */
 
 // This version must match the gator daemon version
-#define PROTOCOL_VERSION 17
+#define PROTOCOL_VERSION 18
 static unsigned long gator_protocol_version = PROTOCOL_VERSION;
 
 #include <linux/slab.h>
@@ -89,20 +89,27 @@
 
 #define MESSAGE_END_BACKTRACE 1
 
+// Name Frame Messages
 #define MESSAGE_COOKIE      1
 #define MESSAGE_THREAD_NAME 2
-#define HRTIMER_CORE_NAME   3
 #define MESSAGE_LINK        4
 
+// GPU Trace Frame Messages
 #define MESSAGE_GPU_START 1
 #define MESSAGE_GPU_STOP  2
 
+// Scheduler Trace Frame Messages
 #define MESSAGE_SCHED_SWITCH 1
 #define MESSAGE_SCHED_EXIT   2
 #define MESSAGE_SCHED_START  3
 
+// Idle Frame Messages
 #define MESSAGE_IDLE_ENTER 1
-#define MESSAGE_IDLE_EXIT 2
+#define MESSAGE_IDLE_EXIT  2
+
+// Summary Frame Messages
+#define MESSAGE_SUMMARY   1
+#define MESSAGE_CORE_NAME 3
 
 #define MAXSIZE_PACK32     5
 #define MAXSIZE_PACK64    10
@@ -154,7 +161,13 @@
 static DECLARE_WAIT_QUEUE_HEAD(gator_buffer_wait);
 static DECLARE_WAIT_QUEUE_HEAD(gator_annotate_wait);
 static struct timer_list gator_buffer_wake_up_timer;
-static bool gator_buffer_wake_stop;
+static bool gator_buffer_wake_run;
+// Initialize semaphore unlocked to initialize memory values
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36)
+static DECLARE_MUTEX(gator_buffer_wake_sem);
+#else
+static DEFINE_SEMAPHORE(gator_buffer_wake_sem);
+#endif
 static struct task_struct *gator_buffer_wake_thread;
 static LIST_HEAD(gator_events);
 
@@ -164,21 +177,19 @@
 
 static bool sent_core_name[NR_CPUS];
 
+static DEFINE_PER_CPU(bool, in_scheduler_context);
+
 /******************************************************************************
  * Prototypes
  ******************************************************************************/
-static void buffer_check(int cpu, int buftype, u64 time);
-static void gator_commit_buffer(int cpu, int buftype, u64 time);
-static int buffer_bytes_available(int cpu, int buftype);
-static bool buffer_check_space(int cpu, int buftype, int bytes);
-static int contiguous_space_available(int cpu, int bufytpe);
-static void gator_buffer_write_packed_int(int cpu, int buftype, int x);
-static void gator_buffer_write_packed_int64(int cpu, int buftype, long long x);
-static void gator_buffer_write_bytes(int cpu, int buftype, const char *x, int len);
-static void gator_buffer_write_string(int cpu, int buftype, const char *x);
-static void gator_add_trace(int cpu, unsigned long address);
-static void gator_add_sample(int cpu, struct pt_regs *const regs, u64 time);
 static u64 gator_get_time(void);
+static void gator_op_create_files(struct super_block *sb, struct dentry *root);
+
+// gator_buffer is protected by being per_cpu and by having IRQs disabled when writing to it.
+// Most marshal_* calls take care of this except for marshal_cookie*, marshal_backtrace* and marshal_frame where the caller is responsible for doing so.
+// No synchronization is needed with the backtrace buffer as it is per cpu and is only used from the hrtimer.
+// The annotate_lock must be held when using the annotation buffer as it is not per cpu.
+// collect_counters which is the sole writer to the block counter frame is additionally protected by the per cpu collecting flag
 
 // Size of the buffer, must be a power of 2. Effectively constant, set in gator_op_setup.
 static uint32_t gator_buffer_size[NUM_GATOR_BUFS];
@@ -229,8 +240,10 @@
 /******************************************************************************
  * Application Includes
  ******************************************************************************/
+#include "gator_fs.c"
+#include "gator_buffer_write.c"
+#include "gator_buffer.c"
 #include "gator_marshaling.c"
-#include "gator_hrtimer_perf.c"
 #include "gator_hrtimer_gator.c"
 #include "gator_cookies.c"
 #include "gator_annotate.c"
@@ -238,14 +251,12 @@
 #include "gator_trace_power.c"
 #include "gator_trace_gpu.c"
 #include "gator_backtrace.c"
-#include "gator_fs.c"
-#include "gator_pack.c"
 
 /******************************************************************************
  * Misc
  ******************************************************************************/
 
-const struct gator_cpu gator_cpus[] = {
+static const struct gator_cpu gator_cpus[] = {
 	{
 		.cpuid = ARM1136,
 		.core_name = "ARM1136",
@@ -277,52 +288,53 @@
 	{
 		.cpuid = CORTEX_A5,
 		.core_name = "Cortex-A5",
-		.pmu_name = "ARMv7_Cortex_A5",
-		.pmnc_name = "ARM_Cortex-A5",
+		.pmnc_name = "ARMv7_Cortex_A5",
 		.dt_name = "arm,cortex-a5",
 		.pmnc_counters = 2,
 	},
 	{
 		.cpuid = CORTEX_A7,
 		.core_name = "Cortex-A7",
-		.pmu_name = "ARMv7_Cortex_A7",
-		.pmnc_name = "ARM_Cortex-A7",
+		.pmnc_name = "ARMv7_Cortex_A7",
 		.dt_name = "arm,cortex-a7",
 		.pmnc_counters = 4,
 	},
 	{
 		.cpuid = CORTEX_A8,
 		.core_name = "Cortex-A8",
-		.pmu_name = "ARMv7_Cortex_A8",
-		.pmnc_name = "ARM_Cortex-A8",
+		.pmnc_name = "ARMv7_Cortex_A8",
 		.dt_name = "arm,cortex-a8",
 		.pmnc_counters = 4,
 	},
 	{
 		.cpuid = CORTEX_A9,
 		.core_name = "Cortex-A9",
-		.pmu_name = "ARMv7_Cortex_A9",
-		.pmnc_name = "ARM_Cortex-A9",
+		.pmnc_name = "ARMv7_Cortex_A9",
 		.dt_name = "arm,cortex-a9",
 		.pmnc_counters = 6,
 	},
 	{
 		.cpuid = CORTEX_A12,
 		.core_name = "Cortex-A12",
-		.pmu_name = "ARMv7_Cortex_A12",
-		.pmnc_name = "ARM_Cortex-A12",
+		.pmnc_name = "ARMv7_Cortex_A12",
 		.dt_name = "arm,cortex-a12",
 		.pmnc_counters = 6,
 	},
 	{
 		.cpuid = CORTEX_A15,
 		.core_name = "Cortex-A15",
-		.pmu_name = "ARMv7_Cortex_A15",
-		.pmnc_name = "ARM_Cortex-A15",
+		.pmnc_name = "ARMv7_Cortex_A15",
 		.dt_name = "arm,cortex-a15",
 		.pmnc_counters = 6,
 	},
 	{
+		.cpuid = CORTEX_A17,
+		.core_name = "Cortex-A17",
+		.pmnc_name = "ARMv7_Cortex_A17",
+		.dt_name = "arm,cortex-a17",
+		.pmnc_counters = 6,
+	},
+	{
 		.cpuid = SCORPION,
 		.core_name = "Scorpion",
 		.pmnc_name = "Scorpion",
@@ -401,7 +413,7 @@
 
 	for (i = 0; gator_cpus[i].cpuid != 0; ++i) {
 		const struct gator_cpu *const gator_cpu = &gator_cpus[i];
-		if (gator_cpu->pmu_name != NULL && strcmp(gator_cpu->pmu_name, name) == 0) {
+		if (gator_cpu->pmnc_name != NULL && strcmp(gator_cpu->pmnc_name, name) == 0) {
 			return gator_cpu;
 		}
 	}
@@ -431,10 +443,15 @@
 
 static int gator_buffer_wake_func(void *data)
 {
-	while (!gator_buffer_wake_stop) {
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule();
-		if (gator_buffer_wake_stop) {
+	for (;;) {
+		if (down_killable(&gator_buffer_wake_sem)) {
+			break;
+		}
+
+		// Eat up any pending events
+		while (!down_trylock(&gator_buffer_wake_sem));
+
+		if (!gator_buffer_wake_run) {
 			break;
 		}
 
@@ -464,173 +481,6 @@
 }
 
 /******************************************************************************
- * Buffer management
- ******************************************************************************/
-static int buffer_bytes_available(int cpu, int buftype)
-{
-	int remaining, filled;
-
-	filled = per_cpu(gator_buffer_write, cpu)[buftype] - per_cpu(gator_buffer_read, cpu)[buftype];
-	if (filled < 0) {
-		filled += gator_buffer_size[buftype];
-	}
-
-	remaining = gator_buffer_size[buftype] - filled;
-
-	if (per_cpu(buffer_space_available, cpu)[buftype]) {
-		// Give some extra room; also allows space to insert the overflow error packet
-		remaining -= 200;
-	} else {
-		// Hysteresis, prevents multiple overflow messages
-		remaining -= 2000;
-	}
-
-	return remaining;
-}
-
-static int contiguous_space_available(int cpu, int buftype)
-{
-	int remaining = buffer_bytes_available(cpu, buftype);
-	int contiguous = gator_buffer_size[buftype] - per_cpu(gator_buffer_write, cpu)[buftype];
-	if (remaining < contiguous)
-		return remaining;
-	else
-		return contiguous;
-}
-
-static bool buffer_check_space(int cpu, int buftype, int bytes)
-{
-	int remaining = buffer_bytes_available(cpu, buftype);
-
-	if (remaining < bytes) {
-		per_cpu(buffer_space_available, cpu)[buftype] = false;
-	} else {
-		per_cpu(buffer_space_available, cpu)[buftype] = true;
-	}
-
-	return per_cpu(buffer_space_available, cpu)[buftype];
-}
-
-static void gator_buffer_write_bytes(int cpu, int buftype, const char *x, int len)
-{
-	int i;
-	u32 write = per_cpu(gator_buffer_write, cpu)[buftype];
-	u32 mask = gator_buffer_mask[buftype];
-	char *buffer = per_cpu(gator_buffer, cpu)[buftype];
-
-	for (i = 0; i < len; i++) {
-		buffer[write] = x[i];
-		write = (write + 1) & mask;
-	}
-
-	per_cpu(gator_buffer_write, cpu)[buftype] = write;
-}
-
-static void gator_buffer_write_string(int cpu, int buftype, const char *x)
-{
-	int len = strlen(x);
-	gator_buffer_write_packed_int(cpu, buftype, len);
-	gator_buffer_write_bytes(cpu, buftype, x, len);
-}
-
-static void gator_commit_buffer(int cpu, int buftype, u64 time)
-{
-	int type_length, commit, length, byte;
-
-	if (!per_cpu(gator_buffer, cpu)[buftype])
-		return;
-
-	// post-populate the length, which does not include the response type length nor the length itself, i.e. only the length of the payload
-	type_length = gator_response_type ? 1 : 0;
-	commit = per_cpu(gator_buffer_commit, cpu)[buftype];
-	length = per_cpu(gator_buffer_write, cpu)[buftype] - commit;
-	if (length < 0) {
-		length += gator_buffer_size[buftype];
-	}
-	length = length - type_length - sizeof(s32);
-
-	if (length <= FRAME_HEADER_SIZE) {
-		// Nothing to write, only the frame header is present
-		return;
-	}
-
-	for (byte = 0; byte < sizeof(s32); byte++) {
-		per_cpu(gator_buffer, cpu)[buftype][(commit + type_length + byte) & gator_buffer_mask[buftype]] = (length >> byte * 8) & 0xFF;
-	}
-
-	per_cpu(gator_buffer_commit, cpu)[buftype] = per_cpu(gator_buffer_write, cpu)[buftype];
-
-	if (gator_live_rate > 0) {
-		while (time > per_cpu(gator_buffer_commit_time, cpu)) {
-			per_cpu(gator_buffer_commit_time, cpu) += gator_live_rate;
-		}
-	}
-
-	marshal_frame(cpu, buftype);
-
-	// had to delay scheduling work as attempting to schedule work during the context switch is illegal in kernel versions 3.5 and greater
-	if (per_cpu(in_scheduler_context, cpu)) {
-#ifndef CONFIG_PREEMPT_RT_FULL
-		// mod_timer can not be used in interrupt context in RT-Preempt full
-		mod_timer(&gator_buffer_wake_up_timer, jiffies + 1);
-#endif
-	} else {
-		wake_up_process(gator_buffer_wake_thread);
-	}
-}
-
-static void buffer_check(int cpu, int buftype, u64 time)
-{
-	int filled = per_cpu(gator_buffer_write, cpu)[buftype] - per_cpu(gator_buffer_commit, cpu)[buftype];
-	if (filled < 0) {
-		filled += gator_buffer_size[buftype];
-	}
-	if (filled >= ((gator_buffer_size[buftype] * 3) / 4)) {
-		gator_commit_buffer(cpu, buftype, time);
-	}
-}
-
-static void gator_add_trace(int cpu, unsigned long address)
-{
-	off_t offset = 0;
-	unsigned long cookie = get_address_cookie(cpu, current, address & ~1, &offset);
-
-	if (cookie == NO_COOKIE || cookie == UNRESOLVED_COOKIE) {
-		offset = address;
-	}
-
-	marshal_backtrace(offset & ~1, cookie);
-}
-
-static void gator_add_sample(int cpu, struct pt_regs *const regs, u64 time)
-{
-	bool inKernel;
-	unsigned long exec_cookie;
-
-	if (!regs)
-		return;
-
-	inKernel = !user_mode(regs);
-	exec_cookie = get_exec_cookie(cpu, current);
-
-	if (!marshal_backtrace_header(exec_cookie, current->tgid, current->pid, inKernel, time))
-		return;
-
-	if (inKernel) {
-		kernel_backtrace(cpu, regs);
-	} else {
-		// Cookie+PC
-		gator_add_trace(cpu, PC_REG);
-
-		// Backtrace
-		if (gator_backtrace_depth)
-			arm_backtrace_eabi(cpu, regs, gator_backtrace_depth);
-	}
-
-	marshal_backtrace_footer(time);
-}
-
-/******************************************************************************
  * hrtimer interrupt processing
  ******************************************************************************/
 static void gator_timer_interrupt(void)
@@ -721,7 +571,8 @@
 }
 
 #if defined(__arm__) || defined(__aarch64__)
-static void gator_send_core_name(int cpu, const u32 cpuid, const struct gator_cpu *const gator_cpu) {
+static void gator_send_core_name(int cpu, const u32 cpuid, const struct gator_cpu *const gator_cpu)
+{
 	const char *core_name = NULL;
 	char core_name_buf[32];
 
@@ -788,7 +639,7 @@
 
 #include "gator_iks.c"
 
-int gator_timer_start(unsigned long sample_rate)
+static int gator_timer_start(unsigned long sample_rate)
 {
 	int cpu;
 
@@ -944,7 +795,6 @@
 	struct timespec ts;
 	char uname_buf[512];
 	void (*m2b)(struct timespec *ts);
-	unsigned long flags;
 
 	snprintf(uname_buf, sizeof(uname_buf), "%s %s %s %s %s GNU/Linux", utsname()->sysname, utsname()->nodename, utsname()->release, utsname()->version, utsname()->machine);
 
@@ -959,14 +809,14 @@
 	}
 	uptime = timespec_to_ns(&ts);
 
-	// Disable interrupts as gator_get_time calls smp_processor_id to verify time is monotonic
-	local_irq_save(flags);
+	// Disable preemption as gator_get_time calls smp_processor_id to verify time is monotonic
+	preempt_disable();
 	// Set monotonic_started to zero as gator_get_time is uptime minus monotonic_started
 	gator_monotonic_started = 0;
 	gator_monotonic_started = gator_get_time();
-	local_irq_restore(flags);
 
 	marshal_summary(timestamp, uptime, gator_monotonic_started, uname_buf);
+	preempt_enable();
 }
 
 int gator_events_install(struct gator_interface *interface)
@@ -1019,7 +869,7 @@
 	unsigned long cpu, i;
 	struct gator_interface *gi;
 
-	gator_buffer_wake_stop = false;
+	gator_buffer_wake_run = true;
 	if (IS_ERR(gator_buffer_wake_thread = kthread_run(gator_buffer_wake_func, NULL, "gator_bwake"))) {
 		goto bwake_failure;
 	}
@@ -1094,8 +944,9 @@
 events_failure:
 	gator_migrate_stop();
 migrate_failure:
-	gator_buffer_wake_stop = true;
-	wake_up_process(gator_buffer_wake_thread);
+	gator_buffer_wake_run = false;
+	up(&gator_buffer_wake_sem);
+	gator_buffer_wake_thread = NULL;
 bwake_failure:
 
 	return -1;
@@ -1121,8 +972,9 @@
 
 	gator_migrate_stop();
 
-	gator_buffer_wake_stop = true;
-	wake_up_process(gator_buffer_wake_thread);
+	gator_buffer_wake_run = false;
+	up(&gator_buffer_wake_sem);
+	gator_buffer_wake_thread = NULL;
 }
 
 /******************************************************************************
@@ -1417,7 +1269,7 @@
 	return written > 0 ? written : -EFAULT;
 }
 
-const struct file_operations gator_event_buffer_fops = {
+static const struct file_operations gator_event_buffer_fops = {
 	.open = userspace_buffer_open,
 	.release = userspace_buffer_release,
 	.read = userspace_buffer_read,
@@ -1452,7 +1304,7 @@
 	.write = depth_write
 };
 
-void gator_op_create_files(struct super_block *sb, struct dentry *root)
+static void gator_op_create_files(struct super_block *sb, struct dentry *root)
 {
 	struct dentry *dir;
 	struct gator_interface *gi;
diff --git a/drivers/gator/gator_marshaling.c b/drivers/gator/gator_marshaling.c
index af80ff6..fd413ad 100644
--- a/drivers/gator/gator_marshaling.c
+++ b/drivers/gator/gator_marshaling.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2012-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2012-2014. All rights reserved.
  *
  * 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
@@ -29,6 +29,7 @@
 	int cpu = 0;
 
 	local_irq_save(flags);
+	gator_buffer_write_packed_int(cpu, SUMMARY_BUF, MESSAGE_SUMMARY);
 	gator_buffer_write_string(cpu, SUMMARY_BUF, NEWLINE_CANARY);
 	gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, timestamp);
 	gator_buffer_write_packed_int64(cpu, SUMMARY_BUF, uptime);
@@ -52,8 +53,8 @@
 #endif
 	gator_buffer_write_string(cpu, SUMMARY_BUF, "");
 	// Commit the buffer now so it can be one of the first frames read by Streamline
-	gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
 	local_irq_restore(flags);
+	gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
 }
 
 static bool marshal_cookie_header(const char *text)
@@ -85,8 +86,8 @@
 		gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
 		gator_buffer_write_string(cpu, NAME_BUF, name);
 	}
-	buffer_check(cpu, NAME_BUF, time);
 	local_irq_restore(flags);
+	buffer_check(cpu, NAME_BUF, time);
 }
 
 static void marshal_link(int cookie, int tgid, int pid)
@@ -103,12 +104,12 @@
 		gator_buffer_write_packed_int(cpu, NAME_BUF, tgid);
 		gator_buffer_write_packed_int(cpu, NAME_BUF, pid);
 	}
+	local_irq_restore(flags);
 	// Check and commit; commit is set to occur once buffer is 3/4 full
 	buffer_check(cpu, NAME_BUF, time);
-	local_irq_restore(flags);
 }
 
-static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, int inKernel, u64 time)
+static bool marshal_backtrace_header(int exec_cookie, int tgid, int pid, u64 time)
 {
 	int cpu = get_physical_cpu();
 	if (!buffer_check_space(cpu, BACKTRACE_BUF, MAXSIZE_PACK64 + 5 * MAXSIZE_PACK32 + gator_backtrace_depth * 2 * MAXSIZE_PACK32)) {
@@ -122,14 +123,16 @@
 	gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, exec_cookie);
 	gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, tgid);
 	gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, pid);
-	gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, inKernel);
 
 	return true;
 }
 
-static void marshal_backtrace(unsigned long address, int cookie)
+static void marshal_backtrace(unsigned long address, int cookie, int in_kernel)
 {
 	int cpu = get_physical_cpu();
+	if (cookie == 0 && !in_kernel) {
+		cookie = UNRESOLVED_COOKIE;
+	}
 	gator_buffer_write_packed_int(cpu, BACKTRACE_BUF, cookie);
 	gator_buffer_write_packed_int64(cpu, BACKTRACE_BUF, address);
 }
@@ -224,9 +227,9 @@
 		gator_buffer_write_packed_int(cpu, COUNTER_BUF, key);
 		gator_buffer_write_packed_int(cpu, COUNTER_BUF, value);
 	}
+	local_irq_restore(flags);
 	// Check and commit; commit is set to occur once buffer is 3/4 full
 	buffer_check(cpu, COUNTER_BUF, time);
-	local_irq_restore(flags);
 }
 #endif
 
@@ -248,9 +251,9 @@
 		gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, tgid);
 		gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, pid);
 	}
+	local_irq_restore(flags);
 	// Check and commit; commit is set to occur once buffer is 3/4 full
 	buffer_check(cpu, GPU_TRACE_BUF, time);
-	local_irq_restore(flags);
 }
 
 static void marshal_sched_gpu_stop(int unit, int core)
@@ -269,9 +272,9 @@
 		gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, unit);
 		gator_buffer_write_packed_int(cpu, GPU_TRACE_BUF, core);
 	}
+	local_irq_restore(flags);
 	// Check and commit; commit is set to occur once buffer is 3/4 full
 	buffer_check(cpu, GPU_TRACE_BUF, time);
-	local_irq_restore(flags);
 }
 
 static void marshal_sched_trace_start(int tgid, int pid, int cookie)
@@ -291,9 +294,9 @@
 		gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
 		gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
 	}
+	local_irq_restore(flags);
 	// Check and commit; commit is set to occur once buffer is 3/4 full
 	buffer_check(cpu, SCHED_TRACE_BUF, time);
-	local_irq_restore(flags);
 }
 
 static void marshal_sched_trace_switch(int tgid, int pid, int cookie, int state)
@@ -314,9 +317,9 @@
 		gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, cookie);
 		gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, state);
 	}
+	local_irq_restore(flags);
 	// Check and commit; commit is set to occur once buffer is 3/4 full
 	buffer_check(cpu, SCHED_TRACE_BUF, time);
-	local_irq_restore(flags);
 }
 
 static void marshal_sched_trace_exit(int tgid, int pid)
@@ -334,9 +337,9 @@
 		gator_buffer_write_packed_int64(cpu, SCHED_TRACE_BUF, time);
 		gator_buffer_write_packed_int(cpu, SCHED_TRACE_BUF, pid);
 	}
+	local_irq_restore(flags);
 	// Check and commit; commit is set to occur once buffer is 3/4 full
 	buffer_check(cpu, SCHED_TRACE_BUF, time);
-	local_irq_restore(flags);
 }
 
 #if GATOR_CPU_FREQ_SUPPORT
@@ -353,80 +356,26 @@
 		gator_buffer_write_packed_int64(cpu, IDLE_BUF, time);
 		gator_buffer_write_packed_int(cpu, IDLE_BUF, core);
 	}
+	local_irq_restore(flags);
 	// Check and commit; commit is set to occur once buffer is 3/4 full
 	buffer_check(cpu, IDLE_BUF, time);
-	local_irq_restore(flags);
 }
 #endif
 
-static void marshal_frame(int cpu, int buftype)
-{
-	int frame;
-
-	if (!per_cpu(gator_buffer, cpu)[buftype]) {
-		return;
-	}
-
-	switch (buftype) {
-	case SUMMARY_BUF:
-		frame = FRAME_SUMMARY;
-		break;
-	case BACKTRACE_BUF:
-		frame = FRAME_BACKTRACE;
-		break;
-	case NAME_BUF:
-		frame = FRAME_NAME;
-		break;
-	case COUNTER_BUF:
-		frame = FRAME_COUNTER;
-		break;
-	case BLOCK_COUNTER_BUF:
-		frame = FRAME_BLOCK_COUNTER;
-		break;
-	case ANNOTATE_BUF:
-		frame = FRAME_ANNOTATE;
-		break;
-	case SCHED_TRACE_BUF:
-		frame = FRAME_SCHED_TRACE;
-		break;
-	case GPU_TRACE_BUF:
-		frame = FRAME_GPU_TRACE;
-		break;
-	case IDLE_BUF:
-		frame = FRAME_IDLE;
-		break;
-	default:
-		frame = -1;
-		break;
-	}
-
-	// add response type
-	if (gator_response_type > 0) {
-		gator_buffer_write_packed_int(cpu, buftype, gator_response_type);
-	}
-
-	// leave space for 4-byte unpacked length
-	per_cpu(gator_buffer_write, cpu)[buftype] = (per_cpu(gator_buffer_write, cpu)[buftype] + sizeof(s32)) & gator_buffer_mask[buftype];
-
-	// add frame type and core number
-	gator_buffer_write_packed_int(cpu, buftype, frame);
-	gator_buffer_write_packed_int(cpu, buftype, cpu);
-}
-
 #if defined(__arm__) || defined(__aarch64__)
 static void marshal_core_name(const int core, const int cpuid, const char *name)
 {
 	int cpu = get_physical_cpu();
 	unsigned long flags;
 	local_irq_save(flags);
-	if (buffer_check_space(cpu, NAME_BUF, MAXSIZE_PACK32 + MAXSIZE_CORE_NAME)) {
-		gator_buffer_write_packed_int(cpu, NAME_BUF, HRTIMER_CORE_NAME);
-		gator_buffer_write_packed_int(cpu, NAME_BUF, core);
-		gator_buffer_write_packed_int(cpu, NAME_BUF, cpuid);
-		gator_buffer_write_string(cpu, NAME_BUF, name);
+	if (buffer_check_space(cpu, SUMMARY_BUF, MAXSIZE_PACK32 + MAXSIZE_CORE_NAME)) {
+		gator_buffer_write_packed_int(cpu, SUMMARY_BUF, MESSAGE_CORE_NAME);
+		gator_buffer_write_packed_int(cpu, SUMMARY_BUF, core);
+		gator_buffer_write_packed_int(cpu, SUMMARY_BUF, cpuid);
+		gator_buffer_write_string(cpu, SUMMARY_BUF, name);
 	}
 	// Commit core names now so that they can show up in live
-	gator_commit_buffer(cpu, NAME_BUF, gator_get_time());
 	local_irq_restore(flags);
+	gator_commit_buffer(cpu, SUMMARY_BUF, gator_get_time());
 }
 #endif
diff --git a/drivers/gator/gator_trace_gpu.c b/drivers/gator/gator_trace_gpu.c
index be135b4..6332098 100644
--- a/drivers/gator/gator_trace_gpu.c
+++ b/drivers/gator/gator_trace_gpu.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
@@ -14,8 +14,15 @@
 #include <linux/math64.h>
 
 #ifdef MALI_SUPPORT
+#ifdef MALI_DIR_MIDGARD
+/* New DDK Directory structure with kernel/drivers/gpu/arm/midgard*/
+#include "mali_linux_trace.h"
+#else
+/* Old DDK Directory structure with kernel/drivers/gpu/arm/t6xx*/
 #include "linux/mali_linux_trace.h"
 #endif
+#endif
+
 #include "gator_trace_gpu.h"
 
 /*
@@ -235,7 +242,7 @@
 	mali_gpu_stop(gpu_unit, gpu_core);
 }
 
-int gator_trace_gpu_start(void)
+static int gator_trace_gpu_start(void)
 {
 	/*
 	 * Returns nonzero for installation failed
@@ -271,7 +278,7 @@
 	return 0;
 }
 
-void gator_trace_gpu_stop(void)
+static void gator_trace_gpu_stop(void)
 {
 #if defined(MALI_SUPPORT) && (MALI_SUPPORT != MALI_T6xx)
 	if (mali_timeline_trace_registered) {
diff --git a/drivers/gator/gator_trace_gpu.h b/drivers/gator/gator_trace_gpu.h
index bb0f42d..5113d45 100644
--- a/drivers/gator/gator_trace_gpu.h
+++ b/drivers/gator/gator_trace_gpu.h
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/gator_trace_power.c b/drivers/gator/gator_trace_power.c
index 272e056..1895bb9 100644
--- a/drivers/gator/gator_trace_power.c
+++ b/drivers/gator/gator_trace_power.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2011-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2011-2014. All rights reserved.
  *
  * 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
@@ -166,7 +166,7 @@
 	}
 }
 
-void gator_trace_power_init(void)
+static void gator_trace_power_init(void)
 {
 	int i;
 	for (i = 0; i < POWER_TOTAL; i++) {
@@ -197,7 +197,7 @@
 {
 }
 
-void gator_trace_power_init(void)
+static void gator_trace_power_init(void)
 {
 }
 #endif
diff --git a/drivers/gator/gator_trace_sched.c b/drivers/gator/gator_trace_sched.c
index 332b3f6..52990e9 100644
--- a/drivers/gator/gator_trace_sched.c
+++ b/drivers/gator/gator_trace_sched.c
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
  *
  * 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
@@ -22,7 +22,6 @@
 
 static DEFINE_PER_CPU(uint64_t *, taskname_keys);
 static DEFINE_PER_CPU(int, collecting);
-static DEFINE_PER_CPU(bool, in_scheduler_context);
 
 // this array is never read as the cpu wait charts are derived counters
 // the files are needed, nonetheless, to show that these counters are available
@@ -52,7 +51,7 @@
 	return 0;
 }
 
-void emit_pid_name(struct task_struct *task)
+static void emit_pid_name(struct task_struct *task)
 {
 	bool found = false;
 	char taskcomm[TASK_COMM_LEN + 3];
@@ -116,20 +115,21 @@
 		// Commit buffers on timeout
 		if (gator_live_rate > 0 && time >= per_cpu(gator_buffer_commit_time, cpu)) {
 			static const int buftypes[] = { NAME_BUF, COUNTER_BUF, BLOCK_COUNTER_BUF, SCHED_TRACE_BUF };
-			unsigned long flags;
 			int i;
 
-			local_irq_save(flags);
 			for (i = 0; i < ARRAY_SIZE(buftypes); ++i) {
 				gator_commit_buffer(cpu, buftypes[i], time);
 			}
-			local_irq_restore(flags);
 
+			// spinlocks are noops on uniprocessor machines and mutexes do not work in sched_switch context in
+			// RT-Preempt full, so disable proactive flushing of the annotate frame on uniprocessor machines.
+#ifdef CONFIG_SMP
 			// Try to preemptively flush the annotate buffer to reduce the chance of the buffer being full
 			if (on_primary_core() && spin_trylock(&annotate_lock)) {
 				gator_commit_buffer(0, ANNOTATE_BUF, time);
 				spin_unlock(&annotate_lock);
 			}
+#endif
 		}
 	}
 }
@@ -222,7 +222,7 @@
 	return -1;
 }
 
-int gator_trace_sched_start(void)
+static int gator_trace_sched_start(void)
 {
 	int cpu, size;
 
@@ -237,7 +237,7 @@
 	return register_scheduler_tracepoints();
 }
 
-void gator_trace_sched_offline(void)
+static void gator_trace_sched_offline(void)
 {
 	trace_sched_insert_idle();
 }
@@ -250,7 +250,7 @@
 	pr_debug("gator: unregistered tracepoints\n");
 }
 
-void gator_trace_sched_stop(void)
+static void gator_trace_sched_stop(void)
 {
 	int cpu;
 	unregister_scheduler_tracepoints();
@@ -260,7 +260,7 @@
 	}
 }
 
-void gator_trace_sched_init(void)
+static void gator_trace_sched_init(void)
 {
 	int i;
 	for (i = 0; i < CPU_WAIT_TOTAL; i++) {
diff --git a/drivers/gator/mali/mali_mjollnir_profiling_gator_api.h b/drivers/gator/mali/mali_mjollnir_profiling_gator_api.h
index 347a4fe..ff00d90 100644
--- a/drivers/gator/mali/mali_mjollnir_profiling_gator_api.h
+++ b/drivers/gator/mali/mali_mjollnir_profiling_gator_api.h
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2013. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/mali/mali_utgard_profiling_gator_api.h b/drivers/gator/mali/mali_utgard_profiling_gator_api.h
index 559647a..43c5760 100644
--- a/drivers/gator/mali/mali_utgard_profiling_gator_api.h
+++ b/drivers/gator/mali/mali_utgard_profiling_gator_api.h
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) ARM Limited 2013. All rights reserved.
+ * Copyright (C) ARM Limited 2013-2014. All rights reserved.
  *
  * 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
diff --git a/drivers/gator/mali_t6xx.mk b/drivers/gator/mali_t6xx.mk
index 1a98c1c..059d47a 100644
--- a/drivers/gator/mali_t6xx.mk
+++ b/drivers/gator/mali_t6xx.mk
@@ -10,8 +10,17 @@
                 -DMALI_NO_MALI=0
 
 DDK_DIR ?= .
+ifneq ($(wildcard $(DDK_DIR)/drivers/gpu/arm/t6xx),)
 KBASE_DIR = $(DDK_DIR)/drivers/gpu/arm/t6xx/kbase
 OSK_DIR = $(DDK_DIR)/drivers/gpu/arm/t6xx/kbase/osk
+endif
+
+ifneq ($(wildcard $(DDK_DIR)/drivers/gpu/arm/midgard),)
+KBASE_DIR = $(DDK_DIR)/drivers/gpu/arm/midgard
+OSK_DIR = $(DDK_DIR)/drivers/gpu/arm/midgard/osk
+EXTRA_CFLAGS += -DMALI_DIR_MIDGARD=1
+endif
+
 UMP_DIR = $(DDK_DIR)/include/linux
 
 # Include directories in the DDK