Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/arch/mips/oprofile/Kconfig b/arch/mips/oprofile/Kconfig
new file mode 100644
index 0000000..19d3773
--- /dev/null
+++ b/arch/mips/oprofile/Kconfig
@@ -0,0 +1,23 @@
+
+menu "Profiling support"
+	depends on EXPERIMENTAL
+
+config PROFILING
+	bool "Profiling support (EXPERIMENTAL)"
+	help
+	  Say Y here to enable the extended profiling support mechanisms used
+	  by profilers such as OProfile.
+
+
+config OPROFILE
+	tristate "OProfile system profiling (EXPERIMENTAL)"
+	depends on PROFILING
+	help
+	  OProfile is a profiling system capable of profiling the
+	  whole system, include the kernel, kernel modules, libraries,
+	  and applications.
+
+	  If unsure, say N.
+
+endmenu
+
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile
new file mode 100644
index 0000000..354261d
--- /dev/null
+++ b/arch/mips/oprofile/Makefile
@@ -0,0 +1,15 @@
+EXTRA_CFLAGS := -Werror
+
+obj-$(CONFIG_OPROFILE) += oprofile.o
+
+DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
+		oprof.o cpu_buffer.o buffer_sync.o \
+		event_buffer.o oprofile_files.o \
+		oprofilefs.o oprofile_stats.o \
+		timer_int.o )
+
+oprofile-y				:= $(DRIVER_OBJS) common.o
+
+oprofile-$(CONFIG_CPU_MIPS32)		+= op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_MIPS64)		+= op_model_mipsxx.o
+oprofile-$(CONFIG_CPU_RM9000)		+= op_model_rm9000.o
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
new file mode 100644
index 0000000..ab65ce3
--- /dev/null
+++ b/arch/mips/oprofile/common.c
@@ -0,0 +1,106 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004 by Ralf Baechle
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/oprofile.h>
+#include <linux/smp.h>
+#include <asm/cpu-info.h>
+
+#include "op_impl.h"
+
+extern struct op_mips_model op_model_mipsxx __attribute__((weak));
+extern struct op_mips_model op_model_rm9000 __attribute__((weak));
+
+static struct op_mips_model *model;
+
+static struct op_counter_config ctr[20];
+
+static int op_mips_setup(void)
+{
+	/* Pre-compute the values to stuff in the hardware registers.  */
+	model->reg_setup(ctr);
+
+	/* Configure the registers on all cpus.  */
+	on_each_cpu(model->cpu_setup, 0, 0, 1);
+
+        return 0;
+}
+
+static int op_mips_create_files(struct super_block * sb, struct dentry * root)
+{
+	int i;
+
+	for (i = 0; i < model->num_counters; ++i) {
+		struct dentry *dir;
+		char buf[3];
+
+		snprintf(buf, sizeof buf, "%d", i);
+		dir = oprofilefs_mkdir(sb, root, buf);
+
+		oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
+		oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
+		oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
+		/* Dummies.  */
+		oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
+		oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
+		oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl);
+		oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
+	}
+
+	return 0;
+}
+
+static int op_mips_start(void)
+{
+	on_each_cpu(model->cpu_start, NULL, 0, 1);
+
+	return 0;
+}
+
+static void op_mips_stop(void)
+{
+	/* Disable performance monitoring for all counters.  */
+	on_each_cpu(model->cpu_stop, NULL, 0, 1);
+}
+
+void __init oprofile_arch_init(struct oprofile_operations *ops)
+{
+	struct op_mips_model *lmodel = NULL;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_24K:
+		lmodel = &op_model_mipsxx;
+		break;
+
+	case CPU_RM9000:
+		lmodel = &op_model_rm9000;
+		break;
+	};
+
+	if (!lmodel)
+		return;
+
+	if (lmodel->init())
+		return;
+
+	model = lmodel;
+
+	ops->create_files = op_mips_create_files;
+	ops->setup = op_mips_setup;
+	ops->start = op_mips_start;
+	ops->stop = op_mips_stop;
+	ops->cpu_type = lmodel->cpu_type;
+
+	printk(KERN_INFO "oprofile: using %s performance monitoring.\n",
+	       lmodel->cpu_type);
+}
+
+void oprofile_arch_exit(void)
+{
+	model->exit();
+}
diff --git a/arch/mips/oprofile/op_impl.h b/arch/mips/oprofile/op_impl.h
new file mode 100644
index 0000000..9f5cdff
--- /dev/null
+++ b/arch/mips/oprofile/op_impl.h
@@ -0,0 +1,37 @@
+/**
+ * @file arch/alpha/oprofile/op_impl.h
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author Richard Henderson <rth@twiddle.net>
+ */
+
+#ifndef OP_IMPL_H
+#define OP_IMPL_H 1
+
+/* Per-counter configuration as set via oprofilefs.  */
+struct op_counter_config {
+	unsigned long enabled;
+	unsigned long event;
+	unsigned long count;
+	/* Dummies because I am too lazy to hack the userspace tools.  */
+	unsigned long kernel;
+	unsigned long user;
+	unsigned long exl;
+	unsigned long unit_mask;
+};
+
+/* Per-architecture configury and hooks.  */
+struct op_mips_model {
+	void (*reg_setup) (struct op_counter_config *);
+	void (*cpu_setup) (void * dummy);
+	int (*init)(void);
+	void (*exit)(void);
+	void (*cpu_start)(void *args);
+	void (*cpu_stop)(void *args);
+	char *cpu_type;
+	unsigned char num_counters;
+};
+
+#endif
diff --git a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c
new file mode 100644
index 0000000..bee4779
--- /dev/null
+++ b/arch/mips/oprofile/op_model_rm9000.c
@@ -0,0 +1,137 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2004 by Ralf Baechle
+ */
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <linux/smp.h>
+
+#include "op_impl.h"
+
+#define RM9K_COUNTER1_EVENT(event)	((event) << 0)
+#define RM9K_COUNTER1_SUPERVISOR	(1ULL    <<  7)
+#define RM9K_COUNTER1_KERNEL		(1ULL    <<  8)
+#define RM9K_COUNTER1_USER		(1ULL    <<  9)
+#define RM9K_COUNTER1_ENABLE		(1ULL    << 10)
+#define RM9K_COUNTER1_OVERFLOW		(1ULL    << 15)
+
+#define RM9K_COUNTER2_EVENT(event)	((event) << 16)
+#define RM9K_COUNTER2_SUPERVISOR	(1ULL    << 23)
+#define RM9K_COUNTER2_KERNEL		(1ULL    << 24)
+#define RM9K_COUNTER2_USER		(1ULL    << 25)
+#define RM9K_COUNTER2_ENABLE		(1ULL    << 26)
+#define RM9K_COUNTER2_OVERFLOW		(1ULL    << 31)
+
+extern unsigned int rm9000_perfcount_irq;
+
+static struct rm9k_register_config {
+	unsigned int control;
+	unsigned int reset_counter1;
+	unsigned int reset_counter2;
+} reg;
+
+/* Compute all of the registers in preparation for enabling profiling.  */
+
+static void rm9000_reg_setup(struct op_counter_config *ctr)
+{
+	unsigned int control = 0;
+
+	/* Compute the performance counter control word.  */
+	/* For now count kernel and user mode */
+	if (ctr[0].enabled)
+		control |= RM9K_COUNTER1_EVENT(ctr[0].event) |
+		           RM9K_COUNTER1_KERNEL |
+		           RM9K_COUNTER1_USER |
+		           RM9K_COUNTER1_ENABLE;
+	if (ctr[1].enabled)
+		control |= RM9K_COUNTER2_EVENT(ctr[1].event) |
+		           RM9K_COUNTER2_KERNEL |
+		           RM9K_COUNTER2_USER |
+		           RM9K_COUNTER2_ENABLE;
+	reg.control = control;
+
+	reg.reset_counter1 = 0x80000000 - ctr[0].count;
+	reg.reset_counter2 = 0x80000000 - ctr[1].count;
+}
+
+/* Program all of the registers in preparation for enabling profiling.  */
+
+static void rm9000_cpu_setup (void *args)
+{
+	uint64_t perfcount;
+
+	perfcount = ((uint64_t) reg.reset_counter2 << 32) | reg.reset_counter1;
+	write_c0_perfcount(perfcount);
+}
+
+static void rm9000_cpu_start(void *args)
+{
+	/* Start all counters on current CPU */
+	write_c0_perfcontrol(reg.control);
+}
+
+static void rm9000_cpu_stop(void *args)
+{
+	/* Stop all counters on current CPU */
+	write_c0_perfcontrol(0);
+}
+
+static irqreturn_t rm9000_perfcount_handler(int irq, void * dev_id,
+	struct pt_regs *regs)
+{
+	unsigned int control = read_c0_perfcontrol();
+	uint32_t counter1, counter2;
+	uint64_t counters;
+
+	/*
+	 * RM9000 combines two 32-bit performance counters into a single
+	 * 64-bit coprocessor zero register.  To avoid a race updating the
+	 * registers we need to stop the counters while we're messing with
+	 * them ...
+	 */
+	write_c0_perfcontrol(0);
+
+	counters = read_c0_perfcount();
+	counter1 = counters;
+	counter2 = counters >> 32;
+
+	if (control & RM9K_COUNTER1_OVERFLOW) {
+		oprofile_add_sample(regs, 0);
+		counter1 = reg.reset_counter1;
+	}
+	if (control & RM9K_COUNTER2_OVERFLOW) {
+		oprofile_add_sample(regs, 1);
+		counter2 = reg.reset_counter2;
+	}
+
+	counters = ((uint64_t)counter2 << 32) | counter1;
+	write_c0_perfcount(counters);
+	write_c0_perfcontrol(reg.control);
+
+	return IRQ_HANDLED;
+}
+
+static int rm9000_init(void)
+{
+	return request_irq(rm9000_perfcount_irq, rm9000_perfcount_handler,
+	                   0, "Perfcounter", NULL);
+}
+
+static void rm9000_exit(void)
+{
+	free_irq(rm9000_perfcount_irq, NULL);
+}
+
+struct op_mips_model op_model_rm9000 = {
+	.reg_setup	= rm9000_reg_setup,
+	.cpu_setup	= rm9000_cpu_setup,
+	.init		= rm9000_init,
+	.exit		= rm9000_exit,
+	.cpu_start	= rm9000_cpu_start,
+	.cpu_stop	= rm9000_cpu_stop,
+	.cpu_type	= "mips/rm9000",
+	.num_counters	= 2
+};