Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus

* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (34 commits)
  [MIPS] tb0219: Update copyright message.
  [MIPS] MT: Fix bug in multithreaded kernels.
  [MIPS] Alchemy: Remove CONFIG_TS_AU1X00_ADS7846 from defconfigs.
  Author: Ralf Baechle <ralf@linux-mips.org>
  [MIPS] sb1250: Enable GenBus IDE in defconfig.
  [MIPS] vmlinux.ld.S: correctly indent .data section
  [MIPS] c-r3k: Implement flush_cache_range()
  [MIPS] Store sign-extend register values for PTRACE_GETREGS
  [MIPS] Alchemy: Register platform devices
  [MIPS] Add len and addr validation for MAP_FIXED mappings.
  [MIPS] IRIX: Fix off-by-one error in signal compat code.
  [MIPS] time: Replace plat_timer_setup with modern APIs.
  [MIPS] time: Fix cut'n'paste bug in Sibyte clockevent driver.
  [MIPS] time: Make c0_compare_int_usable faster
  [MIPS] time: Fix cevt-r4k.c for 64-bit kernel
  [MIPS] Sibyte: Delete {sb1250,bcm1480}_steal_irq().
  [MIPS] txx9tmr clockevent/clocksource driver
  [MIPS] Add mips_hpt_frequency check to mips_clockevent_init().
  [MIPS] IP32: Fixes after interrupt renumbering.
  [MIPS] IP27: Fix slice logic to work for arbitrary number of slices.
  ...
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 61262c5..97da953 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -583,6 +583,7 @@
 
 config TOSHIBA_JMR3927
 	bool "Toshiba JMR-TX3927 board"
+	select CEVT_TXX9
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
 	select MIPS_TX3927
@@ -597,6 +598,7 @@
 config TOSHIBA_RBTX4927
 	bool "Toshiba RBTX49[23]7 board"
 	select CEVT_R4K
+	select CEVT_TXX9
 	select DMA_NONCOHERENT
 	select HAS_TXX9_SERIAL
 	select HW_HAS_PCI
@@ -618,6 +620,7 @@
 config TOSHIBA_RBTX4938
 	bool "Toshiba RBTX4938 board"
 	select CEVT_R4K
+	select CEVT_TXX9
 	select DMA_NONCOHERENT
 	select HAS_TXX9_SERIAL
 	select HW_HAS_PCI
@@ -736,6 +739,9 @@
 config CEVT_R4K
 	bool
 
+config CEVT_TXX9
+	bool
+
 config CFE
 	bool
 
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c
index 59e932a9..ddfb7f0 100644
--- a/arch/mips/au1000/common/irq.c
+++ b/arch/mips/au1000/common/irq.c
@@ -318,38 +318,6 @@
 	.end		= end_irq,
 };
 
-#ifdef CONFIG_PM
-void startup_match20_interrupt(irq_handler_t handler)
-{
-	struct irq_desc *desc = &irq_desc[AU1000_TOY_MATCH2_INT];
-
-	static struct irqaction action;
-	memset(&action, 0, sizeof(struct irqaction));
-
-	/*
-	 * This is a big problem.... since we didn't use request_irq
-	 * when kernel/irq.c calls probe_irq_xxx this interrupt will
-	 * be probed for usage. This will end up disabling the device :(
-	 * Give it a bogus "action" pointer -- this will keep it from
-	 * getting auto-probed!
-	 *
-	 * By setting the status to match that of request_irq() we
-	 * can avoid it.  --cgray
-	*/
-	action.dev_id = handler;
-	action.flags = IRQF_DISABLED;
-	cpus_clear(action.mask);
-	action.name = "Au1xxx TOY";
-	action.handler = handler;
-	action.next = NULL;
-
-	desc->action = &action;
-	desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
-
-	local_enable_irq(AU1000_TOY_MATCH2_INT);
-}
-#endif
-
 static void __init setup_local_irq(unsigned int irq_nr, int type, int int_req)
 {
 	unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
diff --git a/arch/mips/au1000/common/time.c b/arch/mips/au1000/common/time.c
index 2556399..f113b51 100644
--- a/arch/mips/au1000/common/time.c
+++ b/arch/mips/au1000/common/time.c
@@ -67,7 +67,7 @@
 unsigned long wtimer;
 
 #ifdef CONFIG_PM
-irqreturn_t counter0_irq(int irq, void *dev_id)
+static irqreturn_t counter0_irq(int irq, void *dev_id)
 {
 	unsigned long pc0;
 	int time_elapsed;
@@ -117,6 +117,13 @@
 	return IRQ_HANDLED;
 }
 
+struct irqaction counter0_action = {
+	.handler	= counter0_irq,
+	.flags		= IRQF_DISABLED,
+	.name		= "alchemy-toy",
+	.dev_id		= NULL,
+};
+
 /* When we wakeup from sleep, we have to "catch up" on all of the
  * timer ticks we have missed.
  */
@@ -221,7 +228,7 @@
 	return (cpu_speed / HZ);
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
+void __init plat_time_init(void)
 {
 	unsigned int est_freq;
 
@@ -255,15 +262,10 @@
 	 * we do this.
 	 */
 	if (no_au1xxx_32khz) {
-		unsigned int c0_status;
-
 		printk("WARNING: no 32KHz clock found.\n");
 
-		/* Ensure we get CPO_COUNTER interrupts.
-		*/
-		c0_status = read_c0_status();
-		c0_status |= IE_IRQ5;
-		write_c0_status(c0_status);
+		/* Ensure we get CPO_COUNTER interrupts.  */
+		set_c0_status(IE_IRQ5);
 	}
 	else {
 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
@@ -280,7 +282,7 @@
 		au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
 		au_sync();
 		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
-		startup_match20_interrupt(counter0_irq);
+		setup_irq(AU1000_TOY_MATCH2_INT, &counter0_action);
 
 		/* We can use the real 'wait' instruction.
 		*/
diff --git a/arch/mips/au1000/mtx-1/Makefile b/arch/mips/au1000/mtx-1/Makefile
index 764bf9f..afa7007d 100644
--- a/arch/mips/au1000/mtx-1/Makefile
+++ b/arch/mips/au1000/mtx-1/Makefile
@@ -8,3 +8,4 @@
 #
 
 lib-y := init.o board_setup.o irqmap.o
+obj-y := platform.o
diff --git a/arch/mips/au1000/mtx-1/platform.c b/arch/mips/au1000/mtx-1/platform.c
new file mode 100644
index 0000000..01ebff6
--- /dev/null
+++ b/arch/mips/au1000/mtx-1/platform.c
@@ -0,0 +1,86 @@
+/*
+ * MTX-1 platform devices registration
+ *
+ * Copyright (C) 2007, Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+
+#include <asm/gpio.h>
+
+static struct resource mtx1_wdt_res[] = {
+	[0] = {
+		.start	= 15,
+		.end	= 15,
+		.name	= "mtx1-wdt-gpio",
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct resource mtx1_sys_btn[] = {
+	[0] = {
+		.start	= 7,
+		.end	= 7,
+		.name	= "mtx1-sys-btn-gpio",
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static struct platform_device mtx1_wdt = {
+	.name = "mtx1-wdt",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mtx1_wdt_res),
+	.resource = mtx1_wdt_res,
+};
+
+static struct gpio_led default_leds[] = {
+	{
+		.name	= "mtx1:green",
+		.gpio = 211,
+	}, {
+		.name = "mtx1:red",
+		.gpio = 212,
+	},
+};
+
+static struct gpio_led_platform_data mtx1_led_data = {
+	.num_leds = ARRAY_SIZE(default_leds),
+	.leds = default_leds,
+};
+
+static struct platform_device mtx1_gpio_leds = {
+	.name = "leds-gpio",
+	.id = -1,
+	.dev = {
+		.platform_data = &mtx1_led_data,
+	}
+};
+
+static struct __initdata platform_device * mtx1_devs[] = {
+	&mtx1_gpio_leds,
+	&mtx1_wdt
+};
+
+static int __init mtx1_register_devices(void)
+{
+	return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs));
+}
+
+arch_initcall(mtx1_register_devices);
diff --git a/arch/mips/basler/excite/excite_setup.c b/arch/mips/basler/excite/excite_setup.c
index 404ca92..24378b9 100644
--- a/arch/mips/basler/excite/excite_setup.c
+++ b/arch/mips/basler/excite/excite_setup.c
@@ -68,24 +68,23 @@
 int titan_irqflags;
 
 
+/*
+ * The eXcite platform uses the alternate timer interrupt
+ *
+ * Fixme: At the time of this writing cevt-r4k.c doesn't yet know about how
+ * to handle the alternate timer interrupt of the RM9000.
+ */
 void __init plat_time_init(void)
 {
 	const u32 modebit5 = ocd_readl(0x00e4);
-	unsigned int
-		mult = ((modebit5 >> 11) & 0x1f) + 2,
-		div = ((modebit5 >> 16) & 0x1f) + 2;
+	unsigned int mult = ((modebit5 >> 11) & 0x1f) + 2,
+	unsigned int div = ((modebit5 >> 16) & 0x1f) + 2;
 
-	if (div == 33) div = 1;
+	if (div == 33)
+		div = 1;
 	mips_hpt_frequency = EXCITE_CPU_EXT_CLOCK * mult / div / 2;
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	/* The eXcite platform uses the alternate timer interrupt */
-	set_c0_intcontrol(0x80);
-	setup_irq(TIMER_IRQ, irq);
-}
-
 static int __init excite_init_console(void)
 {
 #if defined(CONFIG_SERIAL_8250)
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 885b633..5a8b7ac 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -738,7 +738,6 @@
 CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 # CONFIG_AU1X00_GPIO is not set
-# CONFIG_TS_AU1X00_ADS7846 is not set
 
 #
 # Serial drivers
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
index e3c3a07..d4ed90b 100644
--- a/arch/mips/configs/db1100_defconfig
+++ b/arch/mips/configs/db1100_defconfig
@@ -714,7 +714,6 @@
 CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 # CONFIG_AU1X00_GPIO is not set
-# CONFIG_TS_AU1X00_ADS7846 is not set
 
 #
 # Serial drivers
diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig
index 9aa7c3e..a055657 100644
--- a/arch/mips/configs/db1200_defconfig
+++ b/arch/mips/configs/db1200_defconfig
@@ -775,7 +775,6 @@
 CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 # CONFIG_AU1X00_GPIO is not set
-# CONFIG_TS_AU1X00_ADS7846 is not set
 
 #
 # Serial drivers
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
index 99240668..0ad08cf 100644
--- a/arch/mips/configs/db1500_defconfig
+++ b/arch/mips/configs/db1500_defconfig
@@ -811,7 +811,6 @@
 # CONFIG_VT is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 # CONFIG_AU1X00_GPIO is not set
-# CONFIG_TS_AU1X00_ADS7846 is not set
 
 #
 # Serial drivers
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index 19992f7..057c7d4 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -856,7 +856,6 @@
 # CONFIG_VT is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 # CONFIG_AU1X00_GPIO is not set
-# CONFIG_TS_AU1X00_ADS7846 is not set
 
 #
 # Serial drivers
diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig
index d53fa8f..703d28d 100644
--- a/arch/mips/configs/pb1100_defconfig
+++ b/arch/mips/configs/pb1100_defconfig
@@ -731,7 +731,6 @@
 CONFIG_VT_HW_CONSOLE_BINDING=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 # CONFIG_AU1X00_GPIO is not set
-# CONFIG_TS_AU1X00_ADS7846 is not set
 
 #
 # Serial drivers
diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig
index dc4aa0c..82f0c5c 100644
--- a/arch/mips/configs/pb1500_defconfig
+++ b/arch/mips/configs/pb1500_defconfig
@@ -849,7 +849,6 @@
 # CONFIG_VT is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 # CONFIG_AU1X00_GPIO is not set
-# CONFIG_TS_AU1X00_ADS7846 is not set
 
 #
 # Serial drivers
diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig
index 24428e1..147a4fc 100644
--- a/arch/mips/configs/pb1550_defconfig
+++ b/arch/mips/configs/pb1550_defconfig
@@ -842,7 +842,6 @@
 # CONFIG_VT is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 # CONFIG_AU1X00_GPIO is not set
-# CONFIG_TS_AU1X00_ADS7846 is not set
 
 #
 # Serial drivers
diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig
index 49dfcef..c279822 100644
--- a/arch/mips/configs/sb1250-swarm_defconfig
+++ b/arch/mips/configs/sb1250-swarm_defconfig
@@ -468,7 +468,7 @@
 #
 CONFIG_IDE_GENERIC=y
 # CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_BLK_DEV_IDE_SWARM is not set
+CONFIG_BLK_DEV_IDE_SWARM=y
 # CONFIG_IDE_ARM is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
 # CONFIG_IDEDMA_AUTO is not set
diff --git a/arch/mips/gt64120/wrppmc/time.c b/arch/mips/gt64120/wrppmc/time.c
index b207e7f..668dbd5 100644
--- a/arch/mips/gt64120/wrppmc/time.c
+++ b/arch/mips/gt64120/wrppmc/time.c
@@ -19,12 +19,6 @@
 
 #define WRPPMC_CPU_CLK_FREQ 40000000 /* 40MHZ */
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	/* Install ISR for timer interrupt */
-	setup_irq(WRPPMC_MIPS_TIMER_IRQ, irq);
-}
-
 /*
  * Estimate CPU frequency.  Sets mips_hpt_frequency as a side-effect
  *
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
index edb9e59..06e01c8 100644
--- a/arch/mips/jmr3927/rbhma3100/setup.c
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -27,17 +27,13 @@
  * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org)
  */
 
-#include <linux/clockchips.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kdev_t.h>
 #include <linux/types.h>
-#include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/ide.h>
-#include <linux/irq.h>
 #include <linux/ioport.h>
-#include <linux/param.h>	/* for HZ */
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/platform_device.h>
@@ -48,17 +44,13 @@
 #endif
 
 #include <asm/addrspace.h>
-#include <asm/time.h>
+#include <asm/txx9tmr.h>
 #include <asm/reboot.h>
 #include <asm/jmr3927/jmr3927.h>
 #include <asm/mipsregs.h>
 
 extern void puts(const char *cp);
 
-/* Tick Timer divider */
-#define JMR3927_TIMER_CCD	0	/* 1/2 */
-#define JMR3927_TIMER_CLK	(JMR3927_IMCLK / (2 << JMR3927_TIMER_CCD))
-
 /* don't enable - see errata */
 static int jmr3927_ccfg_toeon;
 
@@ -93,66 +85,12 @@
 	while (1);
 }
 
-static cycle_t jmr3927_hpt_read(void)
-{
-	/* We assume this function is called xtime_lock held. */
-	return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr;
-}
-
-static void jmr3927_set_mode(enum clock_event_mode mode,
-	struct clock_event_device *evt)
-{
-	/* Nothing to do here */
-}
-
-struct clock_event_device jmr3927_clock_event_device = {
-	.name		= "MIPS",
-	.features	= CLOCK_EVT_FEAT_PERIODIC,
-	.shift		= 32,
-	.rating		= 300,
-	.cpumask	= CPU_MASK_CPU0,
-	.irq		= JMR3927_IRQ_TICK,
-	.set_mode	= jmr3927_set_mode,
-};
-
-static irqreturn_t jmr3927_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *cd = &jmr3927_clock_event_device;
-
-	jmr3927_tmrptr->tisr = 0;       /* ack interrupt */
-
-	cd->event_handler(cd);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction jmr3927_timer_irqaction = {
-	.handler	= jmr3927_timer_interrupt,
-	.flags		= IRQF_DISABLED | IRQF_PERCPU,
-	.name		= "jmr3927-timer",
-};
-
 void __init plat_time_init(void)
 {
-	struct clock_event_device *cd;
-
-	clocksource_mips.read = jmr3927_hpt_read;
-	mips_hpt_frequency = JMR3927_TIMER_CLK;
-
-	jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ;
-	jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE;
-	jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD;
-	jmr3927_tmrptr->tcr =
-		TXx927_TMTCR_TCE | TXx927_TMTCR_CCDE | TXx927_TMTCR_TMODE_ITVL;
-
-	cd = &jmr3927_clock_event_device;
-	/* Calculate the min / max delta */
-	cd->mult = div_sc((unsigned long) JMR3927_IMCLK, NSEC_PER_SEC, 32);
-	cd->max_delta_ns	= clockevent_delta2ns(0x7fffffff, cd);
-	cd->min_delta_ns	= clockevent_delta2ns(0x300, cd);
-	clockevents_register_device(cd);
-
-	setup_irq(JMR3927_IRQ_TICK, &jmr3927_timer_irqaction);
+	txx9_clockevent_init(TX3927_TMR_REG(0),
+			     TXX9_IRQ_BASE + JMR3927_IRQ_IRC_TMR(0),
+			     JMR3927_IMCLK);
+	txx9_clocksource_init(TX3927_TMR_REG(1), JMR3927_IMCLK);
 }
 
 #define DO_WRITE_THROUGH
@@ -317,15 +255,8 @@
 	       tx3927_ccfgptr->ccfg, tx3927_ccfgptr->pcfg);
 
 	/* TMR */
-	/* disable all timers */
-	for (i = 0; i < TX3927_NR_TMR; i++) {
-		tx3927_tmrptr(i)->tcr = TXx927_TMTCR_CRE;
-		tx3927_tmrptr(i)->tisr = 0;
-		tx3927_tmrptr(i)->cpra = 0xffffffff;
-		tx3927_tmrptr(i)->itmr = 0;
-		tx3927_tmrptr(i)->ccdr = 0;
-		tx3927_tmrptr(i)->pgmr = 0;
-	}
+	for (i = 0; i < TX3927_NR_TMR; i++)
+		txx9_tmr_init(TX3927_TMR_REG(i));
 
 	/* DMA */
 	tx3927_dmaptr->mcr = 0;
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index d7745c8..3196509 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -10,6 +10,7 @@
 
 obj-$(CONFIG_CEVT_R4K)		+= cevt-r4k.o
 obj-$(CONFIG_CEVT_GT641XX)	+= cevt-gt641xx.o
+obj-$(CONFIG_CEVT_TXX9)		+= cevt-txx9.o
 
 binfmt_irix-objs	:= irixelf.o irixinv.o irixioctl.o irixsig.o	\
 			   irix5sys.o sysirix.o
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c
index 4c651b2..c367726 100644
--- a/arch/mips/kernel/cevt-gt641xx.c
+++ b/arch/mips/kernel/cevt-gt641xx.c
@@ -49,10 +49,9 @@
 static int gt641xx_timer0_set_next_event(unsigned long delta,
 					 struct clock_event_device *evt)
 {
-	unsigned long flags;
 	u32 ctrl;
 
-	spin_lock_irqsave(&gt641xx_timer_lock, flags);
+	spin_lock(&gt641xx_timer_lock);
 
 	ctrl = GT_READ(GT_TC_CONTROL_OFS);
 	ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
@@ -61,7 +60,7 @@
 	GT_WRITE(GT_TC0_OFS, delta);
 	GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
 
-	spin_unlock_irqrestore(&gt641xx_timer_lock, flags);
+	spin_unlock(&gt641xx_timer_lock);
 
 	return 0;
 }
@@ -69,10 +68,9 @@
 static void gt641xx_timer0_set_mode(enum clock_event_mode mode,
 				    struct clock_event_device *evt)
 {
-	unsigned long flags;
 	u32 ctrl;
 
-	spin_lock_irqsave(&gt641xx_timer_lock, flags);
+	spin_lock(&gt641xx_timer_lock);
 
 	ctrl = GT_READ(GT_TC_CONTROL_OFS);
 	ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
@@ -90,7 +88,7 @@
 
 	GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
 
-	spin_unlock_irqrestore(&gt641xx_timer_lock, flags);
+	spin_unlock(&gt641xx_timer_lock);
 }
 
 static void gt641xx_timer0_event_handler(struct clock_event_device *dev)
@@ -133,9 +131,9 @@
 
 	cd = &gt641xx_timer0_clockevent;
 	cd->rating = 200 + gt641xx_base_clock / 10000000;
+	clockevent_set_clock(cd, gt641xx_base_clock);
 	cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
 	cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
-	clockevent_set_clock(cd, gt641xx_base_clock);
 
 	clockevents_register_device(&gt641xx_timer0_clockevent);
 
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index ae2984f..bab935a 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -28,7 +28,7 @@
 	cnt = read_c0_count();
 	cnt += delta;
 	write_c0_compare(cnt);
-	res = ((long)(read_c0_count() - cnt ) > 0) ? -ETIME : 0;
+	res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
 #ifdef CONFIG_MIPS_MT_SMTC
 	evpe(vpflags);
 	local_irq_restore(flags);
@@ -179,7 +179,7 @@
 
 static int c0_compare_int_usable(void)
 {
-	const unsigned int delta = 0x300000;
+	unsigned int delta;
 	unsigned int cnt;
 
 	/*
@@ -192,11 +192,17 @@
 			return 0;
 	}
 
-	cnt = read_c0_count();
-	cnt += delta;
-	write_c0_compare(cnt);
+	for (delta = 0x10; delta <= 0x400000; delta <<= 1) {
+		cnt = read_c0_count();
+		cnt += delta;
+		write_c0_compare(cnt);
+		irq_disable_hazard();
+		if ((int)(read_c0_count() - cnt) < 0)
+		    break;
+		/* increase delta if the timer was already expired */
+	}
 
-	while ((long)(read_c0_count() - cnt) <= 0)
+	while ((int)(read_c0_count() - cnt) <= 0)
 		;	/* Wait for expiry  */
 
 	if (!c0_compare_int_pending())
@@ -218,9 +224,9 @@
 	uint64_t mips_freq = mips_hpt_frequency;
 	unsigned int cpu = smp_processor_id();
 	struct clock_event_device *cd;
-	unsigned int irq = MIPS_CPU_IRQ_BASE + 7;
+	unsigned int irq;
 
-	if (!cpu_has_counter)
+	if (!cpu_has_counter || !mips_hpt_frequency)
 		return;
 
 #ifdef CONFIG_MIPS_MT_SMTC
@@ -237,6 +243,15 @@
 	if (!c0_compare_int_usable())
 		return;
 
+	/*
+	 * With vectored interrupts things are getting platform specific.
+	 * get_c0_compare_int is a hook to allow a platform to return the
+	 * interrupt number of it's liking.
+	 */
+	irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
+	if (get_c0_compare_int)
+		irq = get_c0_compare_int();
+
 	cd = &per_cpu(mips_clockevent_device, cpu);
 
 	cd->name		= "MIPS";
@@ -261,13 +276,15 @@
 
 	clockevents_register_device(cd);
 
-	if (!cp0_timer_irq_installed) {
+	if (!cp0_timer_irq_installed)
+		return;
+
+	cp0_timer_irq_installed = 1;
+
 #ifdef CONFIG_MIPS_MT_SMTC
 #define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq)
-		setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT);
+	setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT);
 #else
-		setup_irq(irq, &c0_compare_irqaction);
-#endif /* CONFIG_MIPS_MT_SMTC */
-		cp0_timer_irq_installed = 1;
-	}
+	setup_irq(irq, &c0_compare_irqaction);
+#endif
 }
diff --git a/arch/mips/kernel/cevt-txx9.c b/arch/mips/kernel/cevt-txx9.c
new file mode 100644
index 0000000..795cb8f
--- /dev/null
+++ b/arch/mips/kernel/cevt-txx9.c
@@ -0,0 +1,171 @@
+/*
+ * 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.
+ *
+ * Based on linux/arch/mips/kernel/cevt-r4k.c,
+ *          linux/arch/mips/jmr3927/rbhma3100/setup.c
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Copyright (C) 2000-2001 Toshiba Corporation
+ * Copyright (C) 2007 MIPS Technologies, Inc.
+ * Copyright (C) 2007 Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <asm/time.h>
+#include <asm/txx9tmr.h>
+
+#define TCR_BASE (TXx9_TMTCR_CCDE | TXx9_TMTCR_CRE | TXx9_TMTCR_TMODE_ITVL)
+#define TIMER_CCD	0	/* 1/2 */
+#define TIMER_CLK(imclk)	((imclk) / (2 << TIMER_CCD))
+
+static struct txx9_tmr_reg __iomem *txx9_cs_tmrptr;
+
+static cycle_t txx9_cs_read(void)
+{
+	return __raw_readl(&txx9_cs_tmrptr->trr);
+}
+
+/* Use 1 bit smaller width to use full bits in that width */
+#define TXX9_CLOCKSOURCE_BITS (TXX9_TIMER_BITS - 1)
+
+static struct clocksource txx9_clocksource = {
+	.name		= "TXx9",
+	.rating		= 200,
+	.read		= txx9_cs_read,
+	.mask		= CLOCKSOURCE_MASK(TXX9_CLOCKSOURCE_BITS),
+	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init txx9_clocksource_init(unsigned long baseaddr,
+				  unsigned int imbusclk)
+{
+	struct txx9_tmr_reg __iomem *tmrptr;
+
+	clocksource_set_clock(&txx9_clocksource, TIMER_CLK(imbusclk));
+	clocksource_register(&txx9_clocksource);
+
+	tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
+	__raw_writel(TCR_BASE, &tmrptr->tcr);
+	__raw_writel(0, &tmrptr->tisr);
+	__raw_writel(TIMER_CCD, &tmrptr->ccdr);
+	__raw_writel(TXx9_TMITMR_TZCE, &tmrptr->itmr);
+	__raw_writel(1 << TXX9_CLOCKSOURCE_BITS, &tmrptr->cpra);
+	__raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
+	txx9_cs_tmrptr = tmrptr;
+}
+
+static struct txx9_tmr_reg __iomem *txx9_tmrptr;
+
+static void txx9tmr_stop_and_clear(struct txx9_tmr_reg __iomem *tmrptr)
+{
+	/* stop and reset counter */
+	__raw_writel(TCR_BASE, &tmrptr->tcr);
+	/* clear pending interrupt */
+	__raw_writel(0, &tmrptr->tisr);
+}
+
+static void txx9tmr_set_mode(enum clock_event_mode mode,
+			     struct clock_event_device *evt)
+{
+	struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
+
+	txx9tmr_stop_and_clear(tmrptr);
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		__raw_writel(TXx9_TMITMR_TIIE | TXx9_TMITMR_TZCE,
+			     &tmrptr->itmr);
+		/* start timer */
+		__raw_writel(((u64)(NSEC_PER_SEC / HZ) * evt->mult) >>
+			     evt->shift,
+			     &tmrptr->cpra);
+		__raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
+		break;
+	case CLOCK_EVT_MODE_SHUTDOWN:
+	case CLOCK_EVT_MODE_UNUSED:
+		__raw_writel(0, &tmrptr->itmr);
+		break;
+	case CLOCK_EVT_MODE_ONESHOT:
+		__raw_writel(TXx9_TMITMR_TIIE, &tmrptr->itmr);
+		break;
+	case CLOCK_EVT_MODE_RESUME:
+		__raw_writel(TIMER_CCD, &tmrptr->ccdr);
+		__raw_writel(0, &tmrptr->itmr);
+		break;
+	}
+}
+
+static int txx9tmr_set_next_event(unsigned long delta,
+				  struct clock_event_device *evt)
+{
+	struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
+
+	txx9tmr_stop_and_clear(tmrptr);
+	/* start timer */
+	__raw_writel(delta, &tmrptr->cpra);
+	__raw_writel(TCR_BASE | TXx9_TMTCR_TCE, &tmrptr->tcr);
+	return 0;
+}
+
+static struct clock_event_device txx9tmr_clock_event_device = {
+	.name		= "TXx9",
+	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
+	.rating		= 200,
+	.cpumask	= CPU_MASK_CPU0,
+	.set_mode	= txx9tmr_set_mode,
+	.set_next_event	= txx9tmr_set_next_event,
+};
+
+static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *cd = &txx9tmr_clock_event_device;
+	struct txx9_tmr_reg __iomem *tmrptr = txx9_tmrptr;
+
+	__raw_writel(0, &tmrptr->tisr);	/* ack interrupt */
+	cd->event_handler(cd);
+	return IRQ_HANDLED;
+}
+
+static struct irqaction txx9tmr_irq = {
+	.handler	= txx9tmr_interrupt,
+	.flags		= IRQF_DISABLED | IRQF_PERCPU,
+	.name		= "txx9tmr",
+};
+
+void __init txx9_clockevent_init(unsigned long baseaddr, int irq,
+				 unsigned int imbusclk)
+{
+	struct clock_event_device *cd = &txx9tmr_clock_event_device;
+	struct txx9_tmr_reg __iomem *tmrptr;
+
+	tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
+	txx9tmr_stop_and_clear(tmrptr);
+	__raw_writel(TIMER_CCD, &tmrptr->ccdr);
+	__raw_writel(0, &tmrptr->itmr);
+	txx9_tmrptr = tmrptr;
+
+	clockevent_set_clock(cd, TIMER_CLK(imbusclk));
+	cd->max_delta_ns =
+		clockevent_delta2ns(0xffffffff >> (32 - TXX9_TIMER_BITS), cd);
+	cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
+	cd->irq = irq;
+	clockevents_register_device(cd);
+	setup_irq(irq, &txx9tmr_irq);
+	printk(KERN_INFO "TXx9: clockevent device at 0x%lx, irq %d\n",
+	       baseaddr, irq);
+}
+
+void __init txx9_tmr_init(unsigned long baseaddr)
+{
+	struct txx9_tmr_reg __iomem *tmrptr;
+
+	tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
+	__raw_writel(TXx9_TMTCR_CRE, &tmrptr->tcr);
+	__raw_writel(0, &tmrptr->tisr);
+	__raw_writel(0xffffffff, &tmrptr->cpra);
+	__raw_writel(0, &tmrptr->itmr);
+	__raw_writel(0, &tmrptr->ccdr);
+	__raw_writel(0, &tmrptr->pgmr);
+	iounmap(tmrptr);
+}
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index a0a9105..33506ff 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -24,8 +24,12 @@
 
 #define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
 
+#define _IRIX_NSIG		128
+#define _IRIX_NSIG_BPW		BITS_PER_LONG
+#define _IRIX_NSIG_WORDS	(_IRIX_NSIG / _IRIX_NSIG_BPW)
+
 typedef struct {
-	unsigned long sig[4];
+	unsigned long sig[_IRIX_NSIG_WORDS];
 } irix_sigset_t;
 
 struct sigctx_irix5 {
@@ -527,7 +531,7 @@
 
 		expire = schedule_timeout_interruptible(expire);
 
-		for (i=0; i<=4; i++)
+		for (i=0; i < _IRIX_NSIG_WORDS; i++)
 			tmp |= (current->pending.signal.sig[i] & kset.sig[i]);
 
 		if (tmp)
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 999f785..35234b9 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -65,13 +65,13 @@
 	regs = task_pt_regs(child);
 
 	for (i = 0; i < 32; i++)
-		__put_user(regs->regs[i], data + i);
-	__put_user(regs->lo, data + EF_LO - EF_R0);
-	__put_user(regs->hi, data + EF_HI - EF_R0);
-	__put_user(regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
-	__put_user(regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
-	__put_user(regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
-	__put_user(regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
+		__put_user((long)regs->regs[i], data + i);
+	__put_user((long)regs->lo, data + EF_LO - EF_R0);
+	__put_user((long)regs->hi, data + EF_HI - EF_R0);
+	__put_user((long)regs->cp0_epc, data + EF_CP0_EPC - EF_R0);
+	__put_user((long)regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0);
+	__put_user((long)regs->cp0_status, data + EF_CP0_STATUS - EF_R0);
+	__put_user((long)regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0);
 
 	return 0;
 }
@@ -390,11 +390,11 @@
 		}
 
 	case PTRACE_GETREGS:
-		ret = ptrace_getregs(child, (__u64 __user *) data);
+		ret = ptrace_getregs(child, (__s64 __user *) data);
 		break;
 
 	case PTRACE_SETREGS:
-		ret = ptrace_setregs(child, (__u64 __user *) data);
+		ret = ptrace_setregs(child, (__s64 __user *) data);
 		break;
 
 	case PTRACE_GETFPREGS:
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index f2bffed..76818be 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -346,11 +346,11 @@
 		}
 
 	case PTRACE_GETREGS:
-		ret = ptrace_getregs(child, (__u64 __user *) (__u64) data);
+		ret = ptrace_getregs(child, (__s64 __user *) (__u64) data);
 		break;
 
 	case PTRACE_SETREGS:
-		ret = ptrace_setregs(child, (__u64 __user *) (__u64) data);
+		ret = ptrace_setregs(child, (__s64 __user *) (__u64) data);
 		break;
 
 	case PTRACE_GETFPREGS:
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index a8c1a69..9c92d42 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -88,11 +88,19 @@
 
 /* Boot command line configuration overrides */
 
+static int vpe0limit;
 static int ipibuffers = 0;
 static int nostlb = 0;
 static int asidmask = 0;
 unsigned long smtc_asid_mask = 0xff;
 
+static int __init vpe0tcs(char *str)
+{
+	get_option(&str, &vpe0limit);
+
+	return 1;
+}
+
 static int __init ipibufs(char *str)
 {
 	get_option(&str, &ipibuffers);
@@ -125,6 +133,7 @@
 	return 1;
 }
 
+__setup("vpe0tcs=", vpe0tcs);
 __setup("ipibufs=", ipibufs);
 __setup("nostlb", stlb_disable);
 __setup("asidmask=", asidmask_set);
@@ -340,7 +349,7 @@
 
 void mipsmt_prepare_cpus(void)
 {
-	int i, vpe, tc, ntc, nvpe, tcpervpe, slop, cpu;
+	int i, vpe, tc, ntc, nvpe, tcpervpe[NR_CPUS], slop, cpu;
 	unsigned long flags;
 	unsigned long val;
 	int nipi;
@@ -401,8 +410,39 @@
 		ntc = NR_CPUS;
 	if (tclimit > 0 && ntc > tclimit)
 		ntc = tclimit;
-	tcpervpe = ntc / nvpe;
-	slop = ntc % nvpe;	/* Residual TCs, < NVPE */
+	slop = ntc % nvpe;
+	for (i = 0; i < nvpe; i++) {
+		tcpervpe[i] = ntc / nvpe;
+		if (slop) {
+			if((slop - i) > 0) tcpervpe[i]++;
+		}
+	}
+	/* Handle command line override for VPE0 */
+	if (vpe0limit > ntc) vpe0limit = ntc;
+	if (vpe0limit > 0) {
+		int slopslop;
+		if (vpe0limit < tcpervpe[0]) {
+		    /* Reducing TC count - distribute to others */
+		    slop = tcpervpe[0] - vpe0limit;
+		    slopslop = slop % (nvpe - 1);
+		    tcpervpe[0] = vpe0limit;
+		    for (i = 1; i < nvpe; i++) {
+			tcpervpe[i] += slop / (nvpe - 1);
+			if(slopslop && ((slopslop - (i - 1) > 0)))
+				tcpervpe[i]++;
+		    }
+		} else if (vpe0limit > tcpervpe[0]) {
+		    /* Increasing TC count - steal from others */
+		    slop = vpe0limit - tcpervpe[0];
+		    slopslop = slop % (nvpe - 1);
+		    tcpervpe[0] = vpe0limit;
+		    for (i = 1; i < nvpe; i++) {
+			tcpervpe[i] -= slop / (nvpe - 1);
+			if(slopslop && ((slopslop - (i - 1) > 0)))
+				tcpervpe[i]--;
+		    }
+		}
+	}
 
 	/* Set up shared TLB */
 	smtc_configure_tlb();
@@ -416,7 +456,7 @@
 		if (vpe != 0)
 			printk(", ");
 		printk("VPE %d: TC", vpe);
-		for (i = 0; i < tcpervpe; i++) {
+		for (i = 0; i < tcpervpe[vpe]; i++) {
 			/*
 			 * TC 0 is bound to VPE 0 at reset,
 			 * and is presumably executing this
@@ -429,15 +469,6 @@
 			printk(" %d", tc);
 			tc++;
 		}
-		if (slop) {
-			if (tc != 0) {
-				smtc_tc_setup(vpe, tc, cpu);
-				cpu++;
-			}
-			printk(" %d", tc);
-			tc++;
-			slop--;
-		}
 		if (vpe != 0) {
 			/*
 			 * Clear any stale software interrupts from VPE's Cause
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index b95fe93..af1bdc8 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -73,7 +73,14 @@
 
 	task_size = STACK_TOP;
 
+	if (len > task_size)
+		return -ENOMEM;
+
 	if (flags & MAP_FIXED) {
+		/* Even MAP_FIXED mappings must reside within task_size.  */
+		if (task_size - len < addr)
+			return -EINVAL;
+
 		/*
 		 * We do not accept a shared mapping if it would violate
 		 * cache aliasing constraints.
@@ -83,8 +90,6 @@
 		return addr;
 	}
 
-	if (len > task_size)
-		return -ENOMEM;
 	do_color_align = 0;
 	if (filp || (flags & MAP_SHARED))
 		do_color_align = 1;
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 6c6849a..27228f5 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -11,6 +11,7 @@
  * Free Software Foundation;  either version 2 of the  License, or (at your
  * option) any later version.
  */
+#include <linux/bug.h>
 #include <linux/clockchips.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
@@ -115,10 +116,6 @@
  *	    (only needed if you intended to use cpu counter as timer interrupt
  *	     source)
  * 2) calculate a couple of cached variables for later usage
- * 3) plat_timer_setup() -
- *	a) (optional) over-write any choices made above by time_init().
- *	b) machine specific code should setup the timer irqaction.
- *	c) enable the timer interrupt
  */
 
 unsigned int mips_hpt_frequency;
@@ -221,8 +218,18 @@
 {
 }
 
-void __init __weak plat_timer_setup(struct irqaction *irq)
+/*
+ * This function exists in order to cause an error due to a duplicate
+ * definition if platform code should have its own implementation.  The hook
+ * to use instead is plat_time_init.  plat_time_init does not receive the
+ * irqaction pointer argument anymore.  This is because any function which
+ * initializes an interrupt timer now takes care of its own request_irq rsp.
+ * setup_irq calls and each clock_event_device should use its own
+ * struct irqrequest.
+ */
+void __init plat_timer_setup(struct irqaction *irq)
 {
+	BUG();
 }
 
 void __init time_init(void)
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S
index 2781cff..5fc2398 100644
--- a/arch/mips/kernel/vmlinux.lds.S
+++ b/arch/mips/kernel/vmlinux.lds.S
@@ -63,21 +63,23 @@
 
 	/* writeable */
 	.data : {	/* Data */
-	  . = . + DATAOFFSET;		/* for CONFIG_MAPPED_KERNEL */
-	  /*
-	   * This ALIGN is needed as a workaround for a bug a gcc bug upto 4.1 which
-	   * limits the maximum alignment to at most 32kB and results in the following
-	   * warning:
-	   *
-	   *  CC      arch/mips/kernel/init_task.o
-	   * arch/mips/kernel/init_task.c:30: warning: alignment of ‘init_thread_union’
-	   * is greater than maximum object file alignment.  Using 32768
-	   */
-	  . = ALIGN(_PAGE_SIZE);
-	  *(.data.init_task)
+		. = . + DATAOFFSET;		/* for CONFIG_MAPPED_KERNEL */
+		/*
+		 * This ALIGN is needed as a workaround for a bug a
+		 * gcc bug upto 4.1 which limits the maximum alignment
+		 * to at most 32kB and results in the following
+		 * warning:
+		 *
+		 *  CC      arch/mips/kernel/init_task.o
+		 * arch/mips/kernel/init_task.c:30: warning: alignment
+		 * of ‘init_thread_union’ is greater than maximum
+		 * object file alignment.  Using 32768
+		 */
+		. = ALIGN(_PAGE_SIZE);
+		*(.data.init_task)
 
-	  DATA_DATA
-	  CONSTRUCTORS
+		DATA_DATA
+		CONSTRUCTORS
 	}
 	_gp = . + 0x8000;
 	.lit8 : {
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c
index df8cbe4..436a64f 100644
--- a/arch/mips/kernel/vpe.c
+++ b/arch/mips/kernel/vpe.c
@@ -942,8 +942,8 @@
 			if (phdr->p_type != PT_LOAD)
 				continue;
 
-			memcpy((void *)phdr->p_vaddr, (char *)hdr + phdr->p_offset, phdr->p_filesz);
-			memset((void *)phdr->p_vaddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
+			memcpy((void *)phdr->p_paddr, (char *)hdr + phdr->p_offset, phdr->p_filesz);
+			memset((void *)phdr->p_paddr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz);
 			phdr++;
 		}
 
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c
index 54827d0..e072da4 100644
--- a/arch/mips/lasat/setup.c
+++ b/arch/mips/lasat/setup.c
@@ -117,14 +117,11 @@
 	}
 };
 
-void plat_time_init(void)
+void __init plat_time_init(void)
 {
 	mips_hpt_frequency = lasat_board_info.li_cpu_hz / 2;
-}
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	change_c0_status(ST0_IM, IE_IRQ0 | IE_IRQ5);
+	change_c0_status(ST0_IM, IE_IRQ0);
 }
 
 void __init plat_mem_setup(void)
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c
index 9d6243a..f02ce63 100644
--- a/arch/mips/mips-boards/generic/time.c
+++ b/arch/mips/mips-boards/generic/time.c
@@ -127,26 +127,6 @@
 	return mc146818_get_cmos_time();
 }
 
-void __init plat_time_init(void)
-{
-	unsigned int est_freq;
-
-        /* Set Data mode - binary. */
-        CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
-
-	est_freq = estimate_cpu_frequency();
-
-	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
-	       (est_freq%1000000)*100/1000000);
-
-        cpu_khz = est_freq / 1000;
-
-	mips_scroll_message();
-#ifdef CONFIG_I8253		/* Only Malta has a PIT */
-	setup_pit_timer();
-#endif
-}
-
 void __init plat_perf_setup(void)
 {
 	cp0_perfcount_irq = -1;
@@ -166,14 +146,13 @@
 	}
 }
 
-void __init plat_timer_setup(struct irqaction *irq)
+unsigned int __init get_c0_compare_int(void)
 {
 #ifdef MSC01E_INT_BASE
 	if (cpu_has_veic) {
 		set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
 		mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
-	}
-	else
+	} else
 #endif
 	{
 		if (cpu_has_vint)
@@ -181,13 +160,26 @@
 		mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
 	}
 
-#ifdef CONFIG_MIPS_MT_SMTC
-	setup_irq_smtc(mips_cpu_timer_irq, irq, 0x100 << cp0_compare_irq);
-#else
-	setup_irq(mips_cpu_timer_irq, irq);
-#endif /* CONFIG_MIPS_MT_SMTC */
-#ifdef CONFIG_SMP
-	set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq);
+	return mips_cpu_timer_irq;
+}
+
+void __init plat_time_init(void)
+{
+	unsigned int est_freq;
+
+        /* Set Data mode - binary. */
+        CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
+
+	est_freq = estimate_cpu_frequency();
+
+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
+	       (est_freq%1000000)*100/1000000);
+
+        cpu_khz = est_freq / 1000;
+
+	mips_scroll_message();
+#ifdef CONFIG_I8253		/* Only Malta has a PIT */
+	setup_pit_timer();
 #endif
 
 	plat_perf_setup();
diff --git a/arch/mips/mipssim/sim_time.c b/arch/mips/mipssim/sim_time.c
index e7fa0d1..bfaafa3 100644
--- a/arch/mips/mipssim/sim_time.c
+++ b/arch/mips/mipssim/sim_time.c
@@ -75,6 +75,30 @@
 	return count;
 }
 
+static int mips_cpu_timer_irq;
+
+static void mips_timer_dispatch(void)
+{
+	do_IRQ(mips_cpu_timer_irq);
+}
+
+
+unsigned __init get_c0_compare_int(void)
+{
+#ifdef MSC01E_INT_BASE
+	if (cpu_has_veic) {
+		set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
+		mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
+	} else {
+#endif
+		if (cpu_has_vint)
+			set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
+		mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
+	}
+
+	return mips_cpu_timer_irq;
+}
+
 void __init plat_time_init(void)
 {
 	unsigned int est_freq, flags;
@@ -93,35 +117,3 @@
 
 	local_irq_restore(flags);
 }
-
-static int mips_cpu_timer_irq;
-
-static void mips_timer_dispatch(void)
-{
-	do_IRQ(mips_cpu_timer_irq);
-}
-
-
-void __init plat_timer_setup(struct irqaction *irq)
-{
-	if (cpu_has_veic) {
-		set_vi_handler(MSC01E_INT_CPUCTR, mips_timer_dispatch);
-		mips_cpu_timer_irq = MSC01E_INT_BASE + MSC01E_INT_CPUCTR;
-	} else {
-		if (cpu_has_vint)
-			set_vi_handler(cp0_compare_irq, mips_timer_dispatch);
-		mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
-	}
-
-	/* we are using the cpu counter for timer interrupts */
-	setup_irq(mips_cpu_timer_irq, irq);
-
-#ifdef CONFIG_SMP
-	/* irq_desc(riptor) is a global resource, when the interrupt overlaps
-	   on seperate cpu's the first one tries to handle the second interrupt.
-	   The effect is that the int remains disabled on the second cpu.
-	   Mark the interrupt with IRQ_PER_CPU to avoid any confusion */
-	irq_desc[mips_cpu_timer_irq].flags |= IRQ_PER_CPU;
-	set_irq_handler(mips_cpu_timer_irq, handle_percpu_irq);
-#endif
-}
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
index c55312f..562abb7 100644
--- a/arch/mips/mm/c-r3k.c
+++ b/arch/mips/mm/c-r3k.c
@@ -7,7 +7,7 @@
  * Tx39XX R4k style caches added. HK
  * Copyright (C) 1998, 1999, 2000 Harald Koerfgen
  * Copyright (C) 1998 Gleb Raiko & Vladimir Roganov
- * Copyright (C) 2001, 2004  Maciej W. Rozycki
+ * Copyright (C) 2001, 2004, 2007  Maciej W. Rozycki
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -26,8 +26,6 @@
 static unsigned long icache_size, dcache_size;		/* Size in bytes */
 static unsigned long icache_lsize, dcache_lsize;	/* Size in bytes */
 
-#undef DEBUG_CACHE
-
 unsigned long __init r3k_cache_size(unsigned long ca_flags)
 {
 	unsigned long flags, status, dummy, size;
@@ -217,26 +215,6 @@
 	write_c0_status(flags);
 }
 
-static inline unsigned long get_phys_page(unsigned long addr,
-					  struct mm_struct *mm)
-{
-	pgd_t *pgd;
-	pud_t *pud;
-	pmd_t *pmd;
-	pte_t *pte;
-	unsigned long physpage;
-
-	pgd = pgd_offset(mm, addr);
-	pud = pud_offset(pgd, addr);
-	pmd = pmd_offset(pud, addr);
-	pte = pte_offset(pmd, addr);
-
-	if ((physpage = pte_val(*pte)) & _PAGE_VALID)
-		return KSEG0ADDR(physpage & PAGE_MASK);
-
-	return 0;
-}
-
 static inline void r3k_flush_cache_all(void)
 {
 }
@@ -252,12 +230,40 @@
 }
 
 static void r3k_flush_cache_range(struct vm_area_struct *vma,
-	unsigned long start, unsigned long end)
+				  unsigned long start, unsigned long end)
 {
 }
 
-static void r3k_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
+static void r3k_flush_cache_page(struct vm_area_struct *vma,
+				 unsigned long addr, unsigned long pfn)
 {
+	unsigned long kaddr = KSEG0ADDR(pfn << PAGE_SHIFT);
+	int exec = vma->vm_flags & VM_EXEC;
+	struct mm_struct *mm = vma->vm_mm;
+	pgd_t *pgdp;
+	pud_t *pudp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+
+	pr_debug("cpage[%08lx,%08lx]\n",
+		 cpu_context(smp_processor_id(), mm), addr);
+
+	/* No ASID => no such page in the cache.  */
+	if (cpu_context(smp_processor_id(), mm) == 0)
+		return;
+
+	pgdp = pgd_offset(mm, addr);
+	pudp = pud_offset(pgdp, addr);
+	pmdp = pmd_offset(pudp, addr);
+	ptep = pte_offset(pmdp, addr);
+
+	/* Invalid => no such page in the cache.  */
+	if (!(pte_val(*ptep) & _PAGE_PRESENT))
+		return;
+
+	r3k_flush_dcache_range(kaddr, kaddr + PAGE_SIZE);
+	if (exec)
+		r3k_flush_icache_range(kaddr, kaddr + PAGE_SIZE);
 }
 
 static void local_r3k_flush_data_cache_page(void *addr)
@@ -272,9 +278,7 @@
 {
 	unsigned long flags;
 
-#ifdef DEBUG_CACHE
-	printk("csigtramp[%08lx]", addr);
-#endif
+	pr_debug("csigtramp[%08lx]\n", addr);
 
 	flags = read_c0_status();
 
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index d708833..6806d58 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -345,11 +345,26 @@
 	r4k_on_each_cpu(local_r4k___flush_cache_all, NULL, 1, 1);
 }
 
+static inline int has_valid_asid(const struct mm_struct *mm)
+{
+#if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC)
+	int i;
+
+	for_each_online_cpu(i)
+		if (cpu_context(i, mm))
+			return 1;
+
+	return 0;
+#else
+	return cpu_context(smp_processor_id(), mm);
+#endif
+}
+
 static inline void local_r4k_flush_cache_range(void * args)
 {
 	struct vm_area_struct *vma = args;
 
-	if (!(cpu_context(smp_processor_id(), vma->vm_mm)))
+	if (!(has_valid_asid(vma->vm_mm)))
 		return;
 
 	r4k_blast_dcache();
@@ -368,7 +383,7 @@
 {
 	struct mm_struct *mm = args;
 
-	if (!cpu_context(smp_processor_id(), mm))
+	if (!has_valid_asid(mm))
 		return;
 
 	/*
@@ -420,7 +435,7 @@
 	 * If ownes no valid ASID yet, cannot possibly have gotten
 	 * this page into the cache.
 	 */
-	if (cpu_context(smp_processor_id(), mm) == 0)
+	if (!has_valid_asid(mm))
 		return;
 
 	addr &= PAGE_MASK;
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index b1b4052..33519ce 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -12,8 +12,8 @@
 #include <linux/dma-mapping.h>
 #include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/string.h>
 #include <linux/scatterlist.h>
+#include <linux/string.h>
 
 #include <asm/cache.h>
 #include <asm/io.h>
diff --git a/arch/mips/pci/fixup-pmcmsp.c b/arch/mips/pci/fixup-pmcmsp.c
index 0026121..65735b1 100644
--- a/arch/mips/pci/fixup-pmcmsp.c
+++ b/arch/mips/pci/fixup-pmcmsp.c
@@ -202,7 +202,7 @@
  *  RETURNS:     IRQ number
  *
  ****************************************************************************/
-int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
 #if !defined(CONFIG_PMC_MSP7120_GW) && !defined(CONFIG_PMC_MSP7120_EVAL)
 	printk(KERN_WARNING "PCI: unknown board, no PCI IRQs assigned.\n");
diff --git a/arch/mips/pci/fixup-tb0219.c b/arch/mips/pci/fixup-tb0219.c
index 720a2b7..ed87733 100644
--- a/arch/mips/pci/fixup-tb0219.c
+++ b/arch/mips/pci/fixup-tb0219.c
@@ -2,7 +2,7 @@
  *  fixup-tb0219.c, The TANBAC TB0219 specific PCI fixups.
  *
  *  Copyright (C) 2003  Megasolution Inc. <matsu@megasolution.jp>
- *  Copyright (C) 2004  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
+ *  Copyright (C) 2004-2005  Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c
index 059eade..109c95c 100644
--- a/arch/mips/pci/ops-pmcmsp.c
+++ b/arch/mips/pci/ops-pmcmsp.c
@@ -404,7 +404,7 @@
 	if (pciirqflag == 0) {
 		request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */
 				bpci_interrupt,
-				SA_SHIRQ | SA_INTERRUPT,
+				IRQF_SHARED | IRQF_DISABLED,
 				"PMC MSP PCI Host",
 				preg);
 		pciirqflag = ~0;
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_serial.c b/arch/mips/pmc-sierra/msp71xx/msp_serial.c
index 15e7b80..9de3430 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_serial.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_serial.c
@@ -122,7 +122,7 @@
 	up.uartclk      = uartclk;
 	up.regshift     = 2;
 	up.iotype       = UPIO_DWAPB; /* UPIO_MEM like */
-	up.flags        = STD_COM_FLAGS;
+	up.flags        = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
 	up.type         = PORT_16550A;
 	up.line         = 0;
 	up.private_data		= (void*)UART0_STATUS_REG;
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index f5dccf0..dc59c3b70 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -131,12 +131,12 @@
 static int rt_next_event(unsigned long delta, struct clock_event_device *evt)
 {
 	unsigned int cpu = smp_processor_id();
-	int slice = cputoslice(cpu) == 0;
+	int slice putoslice(cpu);
 	unsigned long cnt;
 
 	cnt = LOCAL_HUB_L(PI_RT_COUNT);
 	cnt += delta;
-	LOCAL_HUB_S(slice ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, cnt);
+	LOCAL_HUB_S(PI_RT_COMPARE_A + PI_COUNT_OFFSET * slice, cnt);
 
 	return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0;
 }
@@ -164,9 +164,12 @@
 {
 	struct clock_event_device *cd = dev_id;
 	unsigned int cpu = smp_processor_id();
-	int slice = cputoslice(cpu) == 0;
+	int slice = cputoslice(cpu);
 
-	LOCAL_HUB_S(slice ? PI_RT_PEND_A : PI_RT_PEND_B, 0);	/* Ack  */
+	/*
+	 * Ack
+	 */
+	LOCAL_HUB_S(PI_RT_PEND_A + PI_COUNT_OFFSET * slice, cnt);
 	cd->event_handler(cd);
 
 	return IRQ_HANDLED;
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index 7e8094f..aab17dd 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -40,13 +40,6 @@
 	mace->perif.ctrl.misc;
 }
 
-#undef DEBUG_IRQ
-#ifdef DEBUG_IRQ
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
 /*
  * O2 irq map
  *
@@ -125,6 +118,7 @@
 	.mask = CPU_MASK_NONE,
 	.name = "CRIME memory error",
 };
+
 struct irqaction cpuerr_irq = {
 	.handler = crime_cpuerr_intr,
 	.flags = IRQF_DISABLED,
@@ -139,46 +133,70 @@
 
 static uint64_t crime_mask;
 
-static void enable_crime_irq(unsigned int irq)
+static inline void crime_enable_irq(unsigned int irq)
 {
-	crime_mask |= 1 << (irq - 1);
+	unsigned int bit = irq - CRIME_IRQ_BASE;
+
+	crime_mask |= 1 << bit;
 	crime->imask = crime_mask;
 }
 
-static void disable_crime_irq(unsigned int irq)
+static inline void crime_disable_irq(unsigned int irq)
 {
-	crime_mask &= ~(1 << (irq - 1));
+	unsigned int bit = irq - CRIME_IRQ_BASE;
+
+	crime_mask &= ~(1 << bit);
 	crime->imask = crime_mask;
 	flush_crime_bus();
 }
 
-static void mask_and_ack_crime_irq(unsigned int irq)
+static void crime_level_mask_and_ack_irq(unsigned int irq)
 {
-	/* Edge triggered interrupts must be cleared. */
-	if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ)
-	    || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ)
-	    || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) {
-	        uint64_t crime_int;
-		crime_int = crime->hard_int;
-		crime_int &= ~(1 << (irq - 1));
-		crime->hard_int = crime_int;
-	}
-	disable_crime_irq(irq);
+	crime_disable_irq(irq);
 }
 
-static void end_crime_irq(unsigned int irq)
+static void crime_level_end_irq(unsigned int irq)
 {
 	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
-		enable_crime_irq(irq);
+		crime_enable_irq(irq);
 }
 
-static struct irq_chip ip32_crime_interrupt = {
-	.name = "IP32 CRIME",
-	.ack = mask_and_ack_crime_irq,
-	.mask = disable_crime_irq,
-	.mask_ack = mask_and_ack_crime_irq,
-	.unmask = enable_crime_irq,
-	.end = end_crime_irq,
+static struct irq_chip crime_level_interrupt = {
+	.name		= "IP32 CRIME",
+	.ack		= crime_level_mask_and_ack_irq,
+	.mask		= crime_disable_irq,
+	.mask_ack	= crime_level_mask_and_ack_irq,
+	.unmask		= crime_enable_irq,
+	.end		= crime_level_end_irq,
+};
+
+static void crime_edge_mask_and_ack_irq(unsigned int irq)
+{
+	unsigned int bit = irq - CRIME_IRQ_BASE;
+	uint64_t crime_int;
+
+	/* Edge triggered interrupts must be cleared. */
+
+	crime_int = crime->hard_int;
+	crime_int &= ~(1 << bit);
+	crime->hard_int = crime_int;
+
+	crime_disable_irq(irq);
+}
+
+static void crime_edge_end_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		crime_enable_irq(irq);
+}
+
+static struct irq_chip crime_edge_interrupt = {
+	.name		= "IP32 CRIME",
+	.ack		= crime_edge_mask_and_ack_irq,
+	.mask		= crime_disable_irq,
+	.mask_ack	= crime_edge_mask_and_ack_irq,
+	.unmask		= crime_enable_irq,
+	.end		= crime_edge_end_irq,
 };
 
 /*
@@ -265,7 +283,7 @@
 {
 	unsigned int crime_int = 0;
 
-	DBG("maceisa enable: %u\n", irq);
+	pr_debug("maceisa enable: %u\n", irq);
 
 	switch (irq) {
 	case MACEISA_AUDIO_SW_IRQ ... MACEISA_AUDIO3_MERR_IRQ:
@@ -278,7 +296,7 @@
 		crime_int = MACE_SUPERIO_INT;
 		break;
 	}
-	DBG("crime_int %08x enabled\n", crime_int);
+	pr_debug("crime_int %08x enabled\n", crime_int);
 	crime_mask |= crime_int;
 	crime->imask = crime_mask;
 	maceisa_mask |= 1 << (irq - 33);
@@ -290,11 +308,11 @@
 	unsigned int crime_int = 0;
 
 	maceisa_mask &= ~(1 << (irq - 33));
-        if(!(maceisa_mask & MACEISA_AUDIO_INT))
+        if (!(maceisa_mask & MACEISA_AUDIO_INT))
 		crime_int |= MACE_AUDIO_INT;
-        if(!(maceisa_mask & MACEISA_MISC_INT))
+        if (!(maceisa_mask & MACEISA_MISC_INT))
 		crime_int |= MACE_MISC_INT;
-        if(!(maceisa_mask & MACEISA_SUPERIO_INT))
+        if (!(maceisa_mask & MACEISA_SUPERIO_INT))
 		crime_int |= MACE_SUPERIO_INT;
 	crime_mask &= ~crime_int;
 	crime->imask = crime_mask;
@@ -327,12 +345,12 @@
 }
 
 static struct irq_chip ip32_maceisa_interrupt = {
-	.name = "IP32 MACE ISA",
-	.ack = mask_and_ack_maceisa_irq,
-	.mask = disable_maceisa_irq,
-	.mask_ack = mask_and_ack_maceisa_irq,
-	.unmask = enable_maceisa_irq,
-	.end = end_maceisa_irq,
+	.name		= "IP32 MACE ISA",
+	.ack		= mask_and_ack_maceisa_irq,
+	.mask		= disable_maceisa_irq,
+	.mask_ack	= mask_and_ack_maceisa_irq,
+	.unmask		= enable_maceisa_irq,
+	.end		= end_maceisa_irq,
 };
 
 /* This is used for regular non-ISA, non-PCI MACE interrupts.  That means
@@ -411,7 +429,7 @@
 		irq = __ffs(mace_int & maceisa_mask) + MACEISA_AUDIO_SW_IRQ;
 	}
 
-	DBG("*irq %u*\n", irq);
+	pr_debug("*irq %u*\n", irq);
 	do_IRQ(irq);
 }
 
@@ -472,23 +490,31 @@
 
 	mips_cpu_irq_init();
 	for (irq = MIPS_CPU_IRQ_BASE + 8; irq <= IP32_IRQ_MAX; irq++) {
-		struct irq_chip *chip;
-
 		switch (irq) {
 		case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
-			chip = &ip32_mace_interrupt;
+			set_irq_chip(irq, &ip32_mace_interrupt);
 			break;
 		case MACEPCI_SCSI0_IRQ ...  MACEPCI_SHARED2_IRQ:
-			chip = &ip32_macepci_interrupt;
+			set_irq_chip(irq, &ip32_macepci_interrupt);
 			break;
-		case CRIME_GBE0_IRQ ... CRIME_VICE_IRQ:
-			chip = &ip32_crime_interrupt;
+		case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ:
+			set_irq_chip(irq, &crime_edge_interrupt);
+			break;
+		case CRIME_CPUERR_IRQ:
+		case CRIME_MEMERR_IRQ:
+			set_irq_chip(irq, &crime_level_interrupt);
+			break;
+		case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ:
+		case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ:
+			set_irq_chip(irq, &crime_edge_interrupt);
+			break;
+		case CRIME_VICE_IRQ:
+			set_irq_chip(irq, &crime_edge_interrupt);
 			break;
 		default:
-			chip = &ip32_maceisa_interrupt;
+			set_irq_chip(irq, &ip32_maceisa_interrupt);
+			break;
 		}
-
-		set_irq_chip(irq, chip);
 	}
 	setup_irq(CRIME_MEMERR_IRQ, &memerr_irq);
 	setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq);
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 10299ba..61790c4 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -280,27 +280,6 @@
 	.dev_id  = 0
 };
 
-int bcm1480_steal_irq(int irq)
-{
-	struct irq_desc *desc = irq_desc + irq;
-	unsigned long flags;
-	int retval = 0;
-
-	if (irq >= BCM1480_NR_IRQS)
-		return -EINVAL;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	/* Don't allow sharing at all for these */
-	if (desc->action != NULL)
-		retval = -EBUSY;
-	else {
-		desc->action = &bcm1480_dummy_action;
-		desc->depth = 0;
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
-	return 0;
-}
-
 /*
  *  init_IRQ is called early in the boot sequence from init/main.c.  It
  *  is responsible for setting up the interrupt mapper and installing the
@@ -386,8 +365,6 @@
 		__raw_writeq(tmp, IOADDR(A_BCM1480_IMR_REGISTER(cpu, R_BCM1480_IMR_INTERRUPT_MASK_L)));
 	}
 
-	bcm1480_steal_irq(K_BCM1480_INT_MBOX_0_0);
-
 	/*
 	 * Note that the timer interrupts are also mapped, but this is
 	 * done in bcm1480_time_init().  Also, the profiling driver
@@ -411,7 +388,6 @@
 		/* QQQ FIXME */
 		__raw_writeq(M_DUART_IMR_BRK, IO_SPACE_BASE + A_DUART_IMRREG(kgdb_port));
 
-		bcm1480_steal_irq(kgdb_irq);
 		__raw_writeq(IMR_IP6_VAL,
 			     IO_SPACE_BASE + A_BCM1480_IMR_REGISTER(0, R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) +
 			     (kgdb_irq<<3));
diff --git a/arch/mips/sibyte/bcm1480/time.c b/arch/mips/sibyte/bcm1480/time.c
index 610f025..bbf19bf 100644
--- a/arch/mips/sibyte/bcm1480/time.c
+++ b/arch/mips/sibyte/bcm1480/time.c
@@ -37,8 +37,6 @@
 #define IMR_IP3_VAL	K_BCM1480_INT_MAP_I1
 #define IMR_IP4_VAL	K_BCM1480_INT_MAP_I2
 
-extern int bcm1480_steal_irq(int irq);
-
 /*
  * The general purpose timer ticks at 1MHz independent if
  * the rest of the system
@@ -121,7 +119,7 @@
 	sprintf(name, "bcm1480-counter %d", cpu);
 	cd->name		= name;
 	cd->features		= CLOCK_EVT_FEAT_PERIODIC |
-				  CLOCK_EVT_MODE_ONESHOT;
+				  CLOCK_EVT_FEAT_ONESHOT;
 	clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
 	cd->max_delta_ns	= clockevent_delta2ns(0x7fffff, cd);
 	cd->min_delta_ns	= clockevent_delta2ns(1, cd);
@@ -142,7 +140,6 @@
 			R_BCM1480_IMR_INTERRUPT_MAP_BASE_H) + (irq << 3)));
 
 	bcm1480_unmask_irq(cpu, irq);
-	bcm1480_steal_irq(irq);
 
 	action->handler	= sibyte_counter_handler;
 	action->flags	= IRQF_DISABLED | IRQF_PERCPU;
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index 53780a1..52d18fc 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -250,27 +250,6 @@
 	.dev_id  = 0
 };
 
-int sb1250_steal_irq(int irq)
-{
-	struct irq_desc *desc = irq_desc + irq;
-	unsigned long flags;
-	int retval = 0;
-
-	if (irq >= SB1250_NR_IRQS)
-		return -EINVAL;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	/* Don't allow sharing at all for these */
-	if (desc->action != NULL)
-		retval = -EBUSY;
-	else {
-		desc->action = &sb1250_dummy_action;
-		desc->depth = 0;
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
-	return 0;
-}
-
 /*
  *  arch_init_irq is called early in the boot sequence from init/main.c via
  *  init_IRQ.  It is responsible for setting up the interrupt mapper and
@@ -342,8 +321,6 @@
 	__raw_writeq(tmp, IOADDR(A_IMR_REGISTER(0, R_IMR_INTERRUPT_MASK)));
 	__raw_writeq(tmp, IOADDR(A_IMR_REGISTER(1, R_IMR_INTERRUPT_MASK)));
 
-	sb1250_steal_irq(K_INT_MBOX_0);
-
 	/*
 	 * Note that the timer interrupts are also mapped, but this is
 	 * done in sb1250_time_init().  Also, the profiling driver
@@ -367,7 +344,6 @@
 		__raw_writeq(M_DUART_IMR_BRK,
 			     IOADDR(A_DUART_IMRREG(kgdb_port)));
 
-		sb1250_steal_irq(kgdb_irq);
 		__raw_writeq(IMR_IP6_VAL,
 			     IOADDR(A_IMR_REGISTER(0,
 						   R_IMR_INTERRUPT_MAP_BASE) +
diff --git a/arch/mips/sibyte/sb1250/time.c b/arch/mips/sibyte/sb1250/time.c
index a41e908..95ad34e 100644
--- a/arch/mips/sibyte/sb1250/time.c
+++ b/arch/mips/sibyte/sb1250/time.c
@@ -50,8 +50,6 @@
 #define SB1250_HPT_VALUE	M_SCD_TIMER_CNT /* max value */
 
 
-extern int sb1250_steal_irq(int irq);
-
 /*
  * The general purpose timer ticks at 1 Mhz independent if
  * the rest of the system
@@ -139,7 +137,7 @@
 	sprintf(name, "bcm1480-counter %d", cpu);
 	cd->name		= name;
 	cd->features		= CLOCK_EVT_FEAT_PERIODIC |
-				  CLOCK_EVT_MODE_ONESHOT;
+				  CLOCK_EVT_FEAT_ONESHOT;
 	clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
 	cd->max_delta_ns	= clockevent_delta2ns(0x7fffff, cd);
 	cd->min_delta_ns	= clockevent_delta2ns(1, cd);
@@ -159,7 +157,6 @@
 	cd->cpumask = cpumask_of_cpu(0);
 
 	sb1250_unmask_irq(cpu, irq);
-	sb1250_steal_irq(irq);
 
 	action->handler	= sibyte_counter_handler;
 	action->flags	= IRQF_DISABLED | IRQF_PERCPU;
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
index 0910b35..60bc62e 100644
--- a/arch/mips/sni/time.c
+++ b/arch/mips/sni/time.c
@@ -11,27 +11,78 @@
 #define SNI_COUNTER2_DIV        64
 #define SNI_COUNTER0_DIV        ((SNI_CLOCK_TICK_RATE / SNI_COUNTER2_DIV) / HZ)
 
-static void sni_a20r_timer_ack(void)
+static void a20r_set_mode(enum clock_event_mode mode,
+                          struct clock_event_device *evt)
 {
-        *(volatile u8 *)A20R_PT_TIM0_ACK = 0x0; wmb();
+	switch (mode) {
+	case CLOCK_EVT_MODE_PERIODIC:
+		*(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34;
+		wmb();
+		*(volatile u8 *)(A20R_PT_CLOCK_BASE +  0) = SNI_COUNTER0_DIV;
+		wmb();
+		*(volatile u8 *)(A20R_PT_CLOCK_BASE +  0) = SNI_COUNTER0_DIV >> 8;
+		wmb();
+
+		*(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4;
+		wmb();
+		*(volatile u8 *)(A20R_PT_CLOCK_BASE +  8) = SNI_COUNTER2_DIV;
+		wmb();
+		*(volatile u8 *)(A20R_PT_CLOCK_BASE +  8) = SNI_COUNTER2_DIV >> 8;
+		wmb();
+
+                break;
+        case CLOCK_EVT_MODE_ONESHOT:
+        case CLOCK_EVT_MODE_UNUSED:
+        case CLOCK_EVT_MODE_SHUTDOWN:
+                break;
+        case CLOCK_EVT_MODE_RESUME:
+                break;
+        }
 }
 
+static struct clock_event_device a20r_clockevent_device = {
+	.name		= "a20r-timer",
+	.features	= CLOCK_EVT_FEAT_PERIODIC,
+
+	/* .mult, .shift, .max_delta_ns and .min_delta_ns left uninitialized */
+
+	.rating		= 300,
+	.irq		= SNI_A20R_IRQ_TIMER,
+	.set_mode	= a20r_set_mode,
+};
+
+static irqreturn_t a20r_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *cd = dev_id;
+
+	*(volatile u8 *)A20R_PT_TIM0_ACK = 0;
+	wmb();
+
+	cd->event_handler(cd);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction a20r_irqaction = {
+	.handler	= a20r_interrupt,
+	.flags		= IRQF_DISABLED | IRQF_PERCPU,
+	.name		= "a20r-timer",
+};
+
 /*
  * a20r platform uses 2 counters to divide the input frequency.
  * Counter 2 output is connected to Counter 0 & 1 input.
  */
-static void __init sni_a20r_timer_setup(struct irqaction *irq)
+static void __init sni_a20r_timer_setup(void)
 {
-        *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34; wmb();
-        *(volatile u8 *)(A20R_PT_CLOCK_BASE +  0) = (SNI_COUNTER0_DIV) & 0xff; wmb();
-        *(volatile u8 *)(A20R_PT_CLOCK_BASE +  0) = (SNI_COUNTER0_DIV >> 8) & 0xff; wmb();
+	struct clock_event_device *cd = &a20r_clockevent_device;
+	struct irqaction *action = &a20r_irqaction;
+	unsigned int cpu = smp_processor_id();
 
-        *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4; wmb();
-        *(volatile u8 *)(A20R_PT_CLOCK_BASE +  8) = (SNI_COUNTER2_DIV) & 0xff; wmb();
-        *(volatile u8 *)(A20R_PT_CLOCK_BASE +  8) = (SNI_COUNTER2_DIV >> 8) & 0xff; wmb();
+	cd->cpumask             = cpumask_of_cpu(cpu);
 
-        setup_irq(SNI_A20R_IRQ_TIMER, irq);
-        mips_timer_ack = sni_a20r_timer_ack;
+	action->dev_id = cd;
+	setup_irq(SNI_A20R_IRQ_TIMER, &a20r_irqaction);
 }
 
 #define SNI_8254_TICK_RATE        1193182UL
@@ -119,17 +170,14 @@
 	mips_hpt_frequency = r4k_tick * HZ;
 
 	setup_pit_timer();
-}
 
-void __init plat_timer_setup(struct irqaction *irq)
-{
 	switch (sni_brd_type) {
 	case SNI_BRD_10:
 	case SNI_BRD_10NEW:
 	case SNI_BRD_TOWER_OASIC:
 	case SNI_BRD_MINITOWER:
-	        sni_a20r_timer_setup(irq);
-	        break;
+		sni_a20r_timer_setup();
+		break;
 	}
 }
 
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index c7470fb..0299595 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -63,6 +63,7 @@
 #include <asm/processor.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
+#include <asm/txx9tmr.h>
 #include <linux/bootmem.h>
 #include <linux/blkdev.h>
 #ifdef CONFIG_TOSHIBA_FPCIB0
@@ -93,7 +94,6 @@
 
 #define TOSHIBA_RBTX4927_SETUP_EFWFU       ( 1 <<  3 )
 #define TOSHIBA_RBTX4927_SETUP_SETUP       ( 1 <<  4 )
-#define TOSHIBA_RBTX4927_SETUP_TIME_INIT   ( 1 <<  5 )
 #define TOSHIBA_RBTX4927_SETUP_PCIBIOS     ( 1 <<  7 )
 #define TOSHIBA_RBTX4927_SETUP_PCI1        ( 1 <<  8 )
 #define TOSHIBA_RBTX4927_SETUP_PCI2        ( 1 <<  9 )
@@ -130,7 +130,6 @@
 
 int tx4927_using_backplane = 0;
 
-extern void gt64120_time_init(void);
 extern void toshiba_rbtx4927_irq_setup(void);
 
 char *prom_getcmdline(void);
@@ -721,6 +720,7 @@
 
 void __init toshiba_rbtx4927_setup(void)
 {
+	int i;
 	u32 cp0_config;
 	char *argptr;
 
@@ -764,6 +764,9 @@
 	_machine_halt = toshiba_rbtx4927_halt;
 	pm_power_off = toshiba_rbtx4927_power_off;
 
+	for (i = 0; i < TX4927_NR_TMR; i++)
+		txx9_tmr_init(TX4927_TMR_REG(0) & 0xfffffffffULL);
+
 #ifdef CONFIG_PCI
 
 	/* PCIC */
@@ -892,7 +895,6 @@
 #ifdef CONFIG_SERIAL_TXX9
 	{
 		extern int early_serial_txx9_setup(struct uart_port *port);
-		int i;
 		struct uart_port req;
 		for(i = 0; i < 2; i++) {
 			memset(&req, 0, sizeof(req));
@@ -937,12 +939,11 @@
 void __init
 toshiba_rbtx4927_time_init(void)
 {
-	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "-\n");
-
 	mips_hpt_frequency = tx4927_cpu_clock / 2;
-
-	TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIME_INIT, "+\n");
-
+	if (tx4927_ccfgptr->ccfg & TX4927_CCFG_TINTDIS)
+		txx9_clockevent_init(TX4927_TMR_REG(0) & 0xfffffffffULL,
+				     TXX9_IRQ_BASE + 17,
+				     50000000);
 }
 
 static int __init toshiba_rbtx4927_rtc_init(void)
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index ceecaf4..4a81523 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -26,6 +26,7 @@
 #include <asm/reboot.h>
 #include <asm/irq.h>
 #include <asm/time.h>
+#include <asm/txx9tmr.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/bootinfo.h>
@@ -773,15 +774,8 @@
 	}
 
 	/* TMR */
-	/* disable all timers */
-	for (i = 0; i < TX4938_NR_TMR; i++) {
-		tx4938_tmrptr(i)->tcr  = 0x00000020;
-		tx4938_tmrptr(i)->tisr = 0;
-		tx4938_tmrptr(i)->cpra = 0xffffffff;
-		tx4938_tmrptr(i)->itmr = 0;
-		tx4938_tmrptr(i)->ccdr = 0;
-		tx4938_tmrptr(i)->pgmr = 0;
-	}
+	for (i = 0; i < TX4938_NR_TMR; i++)
+		txx9_tmr_init(TX4938_TMR_REG(i) & 0xfffffffffULL);
 
 	/* enable DMA */
 	TX4938_WR64(0xff1fb150, TX4938_DMA_MCR_MSTEN);
@@ -852,12 +846,13 @@
 
 #endif /* CONFIG_PCI */
 
-/* We use onchip r4k counter or TMR timer as our system wide timer
- * interrupt running at 100HZ. */
-
 void __init plat_time_init(void)
 {
 	mips_hpt_frequency = txx9_cpu_clock / 2;
+	if (tx4938_ccfgptr->ccfg & TX4938_CCFG_TINTDIS)
+		txx9_clockevent_init(TX4938_TMR_REG(0) & 0xfffffffffULL,
+				     TXX9_IRQ_BASE + TX4938_IR_TMR(0),
+				     txx9_gbus_clock / 2);
 }
 
 void __init toshiba_rbtx4938_setup(void)
diff --git a/include/asm-mips/ip32/ip32_ints.h b/include/asm-mips/ip32/ip32_ints.h
index 042f8218..ab5612f 100644
--- a/include/asm-mips/ip32/ip32_ints.h
+++ b/include/asm-mips/ip32/ip32_ints.h
@@ -22,10 +22,12 @@
 	 * CPU interrupts are 0 ... 7
 	 */
 
+	CRIME_IRQ_BASE			= MIPS_CPU_IRQ_BASE,
+
 	/*
 	 * MACE
 	 */
-	MACE_VID_IN1_IRQ		= MIPS_CPU_IRQ_BASE + 8,
+	MACE_VID_IN1_IRQ		= CRIME_IRQ_BASE,
 	MACE_VID_IN2_IRQ,
 	MACE_VID_OUT_IRQ,
 	MACE_ETHERNET_IRQ,
diff --git a/include/asm-mips/jmr3927/jmr3927.h b/include/asm-mips/jmr3927/jmr3927.h
index b2dc35f..81602c8 100644
--- a/include/asm-mips/jmr3927/jmr3927.h
+++ b/include/asm-mips/jmr3927/jmr3927.h
@@ -132,9 +132,7 @@
 #define JMR3927_IRQ_IRC_DMA	(JMR3927_IRQ_IRC + TX3927_IR_DMA)
 #define JMR3927_IRQ_IRC_PIO	(JMR3927_IRQ_IRC + TX3927_IR_PIO)
 #define JMR3927_IRQ_IRC_PCI	(JMR3927_IRQ_IRC + TX3927_IR_PCI)
-#define JMR3927_IRQ_IRC_TMR0	(JMR3927_IRQ_IRC + TX3927_IR_TMR0)
-#define JMR3927_IRQ_IRC_TMR1	(JMR3927_IRQ_IRC + TX3927_IR_TMR1)
-#define JMR3927_IRQ_IRC_TMR2	(JMR3927_IRQ_IRC + TX3927_IR_TMR2)
+#define JMR3927_IRQ_IRC_TMR(ch)	(JMR3927_IRQ_IRC + TX3927_IR_TMR(ch))
 #define JMR3927_IRQ_IOC_PCIA	(JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIA)
 #define JMR3927_IRQ_IOC_PCIB	(JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIB)
 #define JMR3927_IRQ_IOC_PCIC	(JMR3927_IRQ_IOC + JMR3927_IOC_INTB_PCIC)
@@ -148,17 +146,12 @@
 #define JMR3927_IRQ_IOCINT	JMR3927_IRQ_IRC_INT1
 /* TC35815 100M Ether (JMR-TX3912:JPW4:2-3 Short) */
 #define JMR3927_IRQ_ETHER0	JMR3927_IRQ_IRC_INT3
-/* Clock Tick (10ms) */
-#define JMR3927_IRQ_TICK	JMR3927_IRQ_IRC_TMR0
 
 /* Clocks */
 #define JMR3927_CORECLK	132710400	/* 132.7MHz */
 #define JMR3927_GBUSCLK	(JMR3927_CORECLK / 2)	/* 66.35MHz */
 #define JMR3927_IMCLK	(JMR3927_CORECLK / 4)	/* 33.17MHz */
 
-#define jmr3927_tmrptr		tx3927_tmrptr(0)	/* TMR0 */
-
-
 /*
  * TX3927 Pin Configuration:
  *
diff --git a/include/asm-mips/jmr3927/tx3927.h b/include/asm-mips/jmr3927/tx3927.h
index 211bcf4..338f998 100644
--- a/include/asm-mips/jmr3927/tx3927.h
+++ b/include/asm-mips/jmr3927/tx3927.h
@@ -222,9 +222,7 @@
 #define TX3927_IR_DMA	8
 #define TX3927_IR_PIO	9
 #define TX3927_IR_PCI	10
-#define TX3927_IR_TMR0	13
-#define TX3927_IR_TMR1	14
-#define TX3927_IR_TMR2	15
+#define TX3927_IR_TMR(ch)	(13 + (ch))
 #define TX3927_NUM_IR	16
 
 /*
diff --git a/include/asm-mips/jmr3927/txx927.h b/include/asm-mips/jmr3927/txx927.h
index 58a8ff6..0474fe8 100644
--- a/include/asm-mips/jmr3927/txx927.h
+++ b/include/asm-mips/jmr3927/txx927.h
@@ -10,22 +10,6 @@
 #ifndef __ASM_TXX927_H
 #define __ASM_TXX927_H
 
-struct txx927_tmr_reg {
-	volatile unsigned long tcr;
-	volatile unsigned long tisr;
-	volatile unsigned long cpra;
-	volatile unsigned long cprb;
-	volatile unsigned long itmr;
-	volatile unsigned long unused0[3];
-	volatile unsigned long ccdr;
-	volatile unsigned long unused1[3];
-	volatile unsigned long pgmr;
-	volatile unsigned long unused2[3];
-	volatile unsigned long wtmr;
-	volatile unsigned long unused3[43];
-	volatile unsigned long trr;
-};
-
 struct txx927_sio_reg {
 	volatile unsigned long lcr;
 	volatile unsigned long dicr;
@@ -51,27 +35,6 @@
 };
 
 /*
- * TMR
- */
-/* TMTCR : Timer Control */
-#define TXx927_TMTCR_TCE	0x00000080
-#define TXx927_TMTCR_CCDE	0x00000040
-#define TXx927_TMTCR_CRE	0x00000020
-#define TXx927_TMTCR_ECES	0x00000008
-#define TXx927_TMTCR_CCS	0x00000004
-#define TXx927_TMTCR_TMODE_MASK	0x00000003
-#define TXx927_TMTCR_TMODE_ITVL	0x00000000
-
-/* TMTISR : Timer Int. Status */
-#define TXx927_TMTISR_TPIBS	0x00000004
-#define TXx927_TMTISR_TPIAS	0x00000002
-#define TXx927_TMTISR_TIIS	0x00000001
-
-/* TMTITMR : Interval Timer Mode */
-#define TXx927_TMTITMR_TIIE	0x00008000
-#define TXx927_TMTITMR_TZCE	0x00000001
-
-/*
  * SIO
  */
 /* SILCR : Line Control */
diff --git a/include/asm-mips/time.h b/include/asm-mips/time.h
index bc47af3..0a6bc7d 100644
--- a/include/asm-mips/time.h
+++ b/include/asm-mips/time.h
@@ -58,7 +58,6 @@
  */
 struct irqaction;
 extern void plat_time_init(void);
-extern void plat_timer_setup(struct irqaction *irq);
 
 /*
  * mips_hpt_frequency - must be set if you intend to use an R4k-compatible
@@ -78,6 +77,7 @@
  */
 #ifdef CONFIG_CEVT_R4K
 extern void mips_clockevent_init(void);
+extern unsigned int __weak get_c0_compare_int(void);
 #else
 static inline void mips_clockevent_init(void)
 {
diff --git a/include/asm-mips/tx4927/tx4927_pci.h b/include/asm-mips/tx4927/tx4927_pci.h
index f98b2bb..3f1e470 100644
--- a/include/asm-mips/tx4927/tx4927_pci.h
+++ b/include/asm-mips/tx4927/tx4927_pci.h
@@ -9,6 +9,7 @@
 #define __ASM_TX4927_TX4927_PCI_H
 
 #define TX4927_CCFG_TOE 0x00004000
+#define TX4927_CCFG_TINTDIS	0x01000000
 
 #define TX4927_PCIMEM      0x08000000
 #define TX4927_PCIMEM_SIZE 0x08000000
@@ -20,6 +21,8 @@
 #define TX4927_PCIC_REG         0xff1fd000
 #define TX4927_CCFG_REG         0xff1fe000
 #define TX4927_IRC_REG          0xff1ff600
+#define TX4927_NR_TMR	3
+#define TX4927_TMR_REG(ch)	(0xff1ff000 + (ch) * 0x100)
 #define TX4927_CE3      0x17f00000      /* 1M */
 #define TX4927_PCIRESET_ADDR    0xbc00f006
 #define TX4927_PCI_CLK_ADDR     (KSEG1 + TX4927_CE3 + 0x00040020)
diff --git a/include/asm-mips/tx4938/tx4938.h b/include/asm-mips/tx4938/tx4938.h
index 650b010..f7c448b 100644
--- a/include/asm-mips/tx4938/tx4938.h
+++ b/include/asm-mips/tx4938/tx4938.h
@@ -641,7 +641,6 @@
 #define tx4938_pcicptr		((struct tx4938_pcic_reg *)TX4938_PCIC_REG)
 #define tx4938_pcic1ptr		((struct tx4938_pcic_reg *)TX4938_PCIC1_REG)
 #define tx4938_ccfgptr		((struct tx4938_ccfg_reg *)TX4938_CCFG_REG)
-#define tx4938_tmrptr(ch)	((struct tx4938_tmr_reg *)TX4938_TMR_REG(ch))
 #define tx4938_sioptr(ch)	((struct tx4938_sio_reg *)TX4938_SIO_REG(ch))
 #define tx4938_pioptr		((struct tx4938_pio_reg *)TX4938_PIO_REG)
 #define tx4938_aclcptr		((struct tx4938_aclc_reg *)TX4938_ACLC_REG)
diff --git a/include/asm-mips/txx9tmr.h b/include/asm-mips/txx9tmr.h
new file mode 100644
index 0000000..67f70a8
--- /dev/null
+++ b/include/asm-mips/txx9tmr.h
@@ -0,0 +1,67 @@
+/*
+ * include/asm-mips/txx9tmr.h
+ * TX39/TX49 timer controller definitions.
+ *
+ * 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.
+ */
+#ifndef __ASM_TXX9TMR_H
+#define __ASM_TXX9TMR_H
+
+#include <linux/types.h>
+
+struct txx9_tmr_reg {
+	u32 tcr;
+	u32 tisr;
+	u32 cpra;
+	u32 cprb;
+	u32 itmr;
+	u32 unused0[3];
+	u32 ccdr;
+	u32 unused1[3];
+	u32 pgmr;
+	u32 unused2[3];
+	u32 wtmr;
+	u32 unused3[43];
+	u32 trr;
+};
+
+/* TMTCR : Timer Control */
+#define TXx9_TMTCR_TCE		0x00000080
+#define TXx9_TMTCR_CCDE		0x00000040
+#define TXx9_TMTCR_CRE		0x00000020
+#define TXx9_TMTCR_ECES		0x00000008
+#define TXx9_TMTCR_CCS		0x00000004
+#define TXx9_TMTCR_TMODE_MASK	0x00000003
+#define TXx9_TMTCR_TMODE_ITVL	0x00000000
+#define TXx9_TMTCR_TMODE_PGEN	0x00000001
+#define TXx9_TMTCR_TMODE_WDOG	0x00000002
+
+/* TMTISR : Timer Int. Status */
+#define TXx9_TMTISR_TPIBS	0x00000004
+#define TXx9_TMTISR_TPIAS	0x00000002
+#define TXx9_TMTISR_TIIS	0x00000001
+
+/* TMITMR : Interval Timer Mode */
+#define TXx9_TMITMR_TIIE	0x00008000
+#define TXx9_TMITMR_TZCE	0x00000001
+
+/* TMWTMR : Watchdog Timer Mode */
+#define TXx9_TMWTMR_TWIE	0x00008000
+#define TXx9_TMWTMR_WDIS	0x00000080
+#define TXx9_TMWTMR_TWC		0x00000001
+
+void txx9_clocksource_init(unsigned long baseaddr,
+			   unsigned int imbusclk);
+void txx9_clockevent_init(unsigned long baseaddr, int irq,
+			  unsigned int imbusclk);
+void txx9_tmr_init(unsigned long baseaddr);
+
+#ifdef CONFIG_CPU_TX39XX
+#define TXX9_TIMER_BITS	24
+#else
+#define TXX9_TIMER_BITS	32
+#endif
+
+#endif /* __ASM_TXX9TMR_H */