Browse Source

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.
  ...
Linus Torvalds 18 năm trước cách đây
mục cha
commit
82798a17ad
56 tập tin đã thay đổi với 773 bổ sung514 xóa
  1. 6 0
      arch/mips/Kconfig
  2. 0 32
      arch/mips/au1000/common/irq.c
  3. 12 10
      arch/mips/au1000/common/time.c
  4. 1 0
      arch/mips/au1000/mtx-1/Makefile
  5. 86 0
      arch/mips/au1000/mtx-1/platform.c
  6. 10 11
      arch/mips/basler/excite/excite_setup.c
  7. 0 1
      arch/mips/configs/db1000_defconfig
  8. 0 1
      arch/mips/configs/db1100_defconfig
  9. 0 1
      arch/mips/configs/db1200_defconfig
  10. 0 1
      arch/mips/configs/db1500_defconfig
  11. 0 1
      arch/mips/configs/db1550_defconfig
  12. 0 1
      arch/mips/configs/pb1100_defconfig
  13. 0 1
      arch/mips/configs/pb1500_defconfig
  14. 0 1
      arch/mips/configs/pb1550_defconfig
  15. 1 1
      arch/mips/configs/sb1250-swarm_defconfig
  16. 0 6
      arch/mips/gt64120/wrppmc/time.c
  17. 7 76
      arch/mips/jmr3927/rbhma3100/setup.c
  18. 1 0
      arch/mips/kernel/Makefile
  19. 5 7
      arch/mips/kernel/cevt-gt641xx.c
  20. 31 14
      arch/mips/kernel/cevt-r4k.c
  21. 171 0
      arch/mips/kernel/cevt-txx9.c
  22. 6 2
      arch/mips/kernel/irixsig.c
  23. 9 9
      arch/mips/kernel/ptrace.c
  24. 2 2
      arch/mips/kernel/ptrace32.c
  25. 44 13
      arch/mips/kernel/smtc.c
  26. 7 2
      arch/mips/kernel/syscall.c
  27. 12 5
      arch/mips/kernel/time.c
  28. 17 15
      arch/mips/kernel/vmlinux.lds.S
  29. 2 2
      arch/mips/kernel/vpe.c
  30. 2 5
      arch/mips/lasat/setup.c
  31. 22 30
      arch/mips/mips-boards/generic/time.c
  32. 22 30
      arch/mips/mipssim/sim_time.c
  33. 32 28
      arch/mips/mm/c-r3k.c
  34. 18 3
      arch/mips/mm/c-r4k.c
  35. 1 1
      arch/mips/mm/dma-default.c
  36. 1 1
      arch/mips/pci/fixup-pmcmsp.c
  37. 1 1
      arch/mips/pci/fixup-tb0219.c
  38. 1 1
      arch/mips/pci/ops-pmcmsp.c
  39. 1 1
      arch/mips/pmc-sierra/msp71xx/msp_serial.c
  40. 7 4
      arch/mips/sgi-ip27/ip27-timer.c
  41. 77 51
      arch/mips/sgi-ip32/ip32-irq.c
  42. 0 24
      arch/mips/sibyte/bcm1480/irq.c
  43. 1 4
      arch/mips/sibyte/bcm1480/time.c
  44. 0 24
      arch/mips/sibyte/sb1250/irq.c
  45. 1 4
      arch/mips/sibyte/sb1250/time.c
  46. 64 16
      arch/mips/sni/time.c
  47. 9 8
      arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
  48. 7 12
      arch/mips/tx4938/toshiba_rbtx4938/setup.c
  49. 3 1
      include/asm-mips/ip32/ip32_ints.h
  50. 1 8
      include/asm-mips/jmr3927/jmr3927.h
  51. 1 3
      include/asm-mips/jmr3927/tx3927.h
  52. 0 37
      include/asm-mips/jmr3927/txx927.h
  53. 1 1
      include/asm-mips/time.h
  54. 3 0
      include/asm-mips/tx4927/tx4927_pci.h
  55. 0 1
      include/asm-mips/tx4938/tx4938.h
  56. 67 0
      include/asm-mips/txx9tmr.h

+ 6 - 0
arch/mips/Kconfig

@@ -583,6 +583,7 @@ config SNI_RM
 
 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_JMR3927
 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_RBTX4927
 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_GT641XX
 config CEVT_R4K
 	bool
 
+config CEVT_TXX9
+	bool
+
 config CFE
 	bool
 

+ 0 - 32
arch/mips/au1000/common/irq.c

@@ -318,38 +318,6 @@ static struct irq_chip level_irq_type = {
 	.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;

+ 12 - 10
arch/mips/au1000/common/time.c

@@ -67,7 +67,7 @@ static DEFINE_SPINLOCK(time_lock);
 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 @@ irqreturn_t counter0_irq(int irq, void *dev_id)
 	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 @@ unsigned long cal_r4koff(void)
 	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 @@ void __init plat_timer_setup(struct irqaction *irq)
 	 * 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 @@ void __init plat_timer_setup(struct irqaction *irq)
 		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.
 		*/

+ 1 - 0
arch/mips/au1000/mtx-1/Makefile

@@ -8,3 +8,4 @@
 #
 
 lib-y := init.o board_setup.o irqmap.o
+obj-y := platform.o

+ 86 - 0
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);

+ 10 - 11
arch/mips/basler/excite/excite_setup.c

@@ -68,24 +68,23 @@ DEFINE_SPINLOCK(titan_lock);
 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)

+ 0 - 1
arch/mips/configs/db1000_defconfig

@@ -738,7 +738,6 @@ CONFIG_HW_CONSOLE=y
 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

+ 0 - 1
arch/mips/configs/db1100_defconfig

@@ -714,7 +714,6 @@ CONFIG_HW_CONSOLE=y
 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

+ 0 - 1
arch/mips/configs/db1200_defconfig

@@ -775,7 +775,6 @@ CONFIG_HW_CONSOLE=y
 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

+ 0 - 1
arch/mips/configs/db1500_defconfig

@@ -811,7 +811,6 @@ CONFIG_SERIO_RAW=m
 # 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

+ 0 - 1
arch/mips/configs/db1550_defconfig

@@ -856,7 +856,6 @@ CONFIG_SERIO_RAW=m
 # 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

+ 0 - 1
arch/mips/configs/pb1100_defconfig

@@ -731,7 +731,6 @@ CONFIG_HW_CONSOLE=y
 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

+ 0 - 1
arch/mips/configs/pb1500_defconfig

@@ -849,7 +849,6 @@ CONFIG_SERIO_RAW=m
 # 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

+ 0 - 1
arch/mips/configs/pb1550_defconfig

@@ -842,7 +842,6 @@ CONFIG_SERIO_RAW=m
 # 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

+ 1 - 1
arch/mips/configs/sb1250-swarm_defconfig

@@ -468,7 +468,7 @@ CONFIG_BLK_DEV_IDEFLOPPY=y
 #
 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

+ 0 - 6
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
  *

+ 7 - 76
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 @@ static void jmr3927_machine_power_off(void)
 	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 @@ static void __init tx3927_setup(void)
 	       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;

+ 1 - 0
arch/mips/kernel/Makefile

@@ -10,6 +10,7 @@ obj-y		+= cpu-probe.o branch.o entry.o genex.o irq.o process.o \
 
 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

+ 5 - 7
arch/mips/kernel/cevt-gt641xx.c

@@ -49,10 +49,9 @@ int gt641xx_timer0_state(void)
 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 @@ static int gt641xx_timer0_set_next_event(unsigned long delta,
 	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 int gt641xx_timer0_set_next_event(unsigned long delta,
 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 @@ static void gt641xx_timer0_set_mode(enum clock_event_mode mode,
 
 	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 @@ static int __init gt641xx_timer0_clockevent_init(void)
 
 	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);
 

+ 31 - 14
arch/mips/kernel/cevt-r4k.c

@@ -28,7 +28,7 @@ static int mips_next_event(unsigned long delta,
 	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_pending(void)
 
 static int c0_compare_int_usable(void)
 {
-	const unsigned int delta = 0x300000;
+	unsigned int delta;
 	unsigned int cnt;
 
 	/*
@@ -192,11 +192,17 @@ static int c0_compare_int_usable(void)
 			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 @@ void __cpuinit mips_clockevent_init(void)
 	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 @@ void __cpuinit mips_clockevent_init(void)
 	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 @@ void __cpuinit mips_clockevent_init(void)
 
 	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
 }

+ 171 - 0
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);
+}

+ 6 - 2
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 @@ asmlinkage int irix_sigpoll_sys(unsigned long __user *set,
 
 		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)

+ 9 - 9
arch/mips/kernel/ptrace.c

@@ -65,13 +65,13 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data)
 	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 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 		}
 
 	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:

+ 2 - 2
arch/mips/kernel/ptrace32.c

@@ -346,11 +346,11 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
 		}
 
 	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:

+ 44 - 13
arch/mips/kernel/smtc.c

@@ -88,11 +88,19 @@ unsigned int smtc_status = 0;
 
 /* 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 @@ static int __init asidmask_set(char *str)
 	return 1;
 }
 
+__setup("vpe0tcs=", vpe0tcs);
 __setup("ipibufs=", ipibufs);
 __setup("nostlb", stlb_disable);
 __setup("asidmask=", asidmask_set);
@@ -340,7 +349,7 @@ static void smtc_tc_setup(int vpe, int tc, int cpu)
 
 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 @@ void mipsmt_prepare_cpus(void)
 		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 @@ void mipsmt_prepare_cpus(void)
 		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 @@ void mipsmt_prepare_cpus(void)
 			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

+ 7 - 2
arch/mips/kernel/syscall.c

@@ -73,7 +73,14 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 
 	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 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
 		return addr;
 	}
 
-	if (len > task_size)
-		return -ENOMEM;
 	do_color_align = 0;
 	if (filp || (flags & MAP_SHARED))
 		do_color_align = 1;

+ 12 - 5
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 @@ EXPORT_SYMBOL(perf_irq);
  *	    (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_time_init(void)
 {
 }
 
-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)

+ 17 - 15
arch/mips/kernel/vmlinux.lds.S

@@ -63,21 +63,23 @@ SECTIONS
 
 	/* 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)
-
-	  DATA_DATA
-	  CONSTRUCTORS
+		. = . + 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
 	}
 	_gp = . + 0x8000;
 	.lit8 : {

+ 2 - 2
arch/mips/kernel/vpe.c

@@ -942,8 +942,8 @@ static int vpe_elfload(struct vpe * v)
 			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++;
 		}
 

+ 2 - 5
arch/mips/lasat/setup.c

@@ -117,14 +117,11 @@ static struct notifier_block lasat_panic_block[] =
 	}
 };
 
-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)

+ 22 - 30
arch/mips/mips-boards/generic/time.c

@@ -127,26 +127,6 @@ unsigned long read_persistent_clock(void)
 	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_perf_setup(void)
 	}
 }
 
-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 @@ void __init plat_timer_setup(struct irqaction *irq)
 		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();

+ 22 - 30
arch/mips/mipssim/sim_time.c

@@ -75,25 +75,6 @@ static unsigned int __init estimate_cpu_frequency(void)
 	return count;
 }
 
-void __init plat_time_init(void)
-{
-	unsigned int est_freq, flags;
-
-	local_irq_save(flags);
-
-	/* Set Data mode - binary. */
-	CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
-
-	est_freq = estimate_cpu_frequency();
-
-	printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000,
-	       (est_freq % 1000000) * 100 / 1000000);
-
-	cpu_khz = est_freq / 1000;
-
-	local_irq_restore(flags);
-}
-
 static int mips_cpu_timer_irq;
 
 static void mips_timer_dispatch(void)
@@ -102,26 +83,37 @@ static void mips_timer_dispatch(void)
 }
 
 
-void __init plat_timer_setup(struct irqaction *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;
 	}
 
-	/* we are using the cpu counter for timer interrupts */
-	setup_irq(mips_cpu_timer_irq, irq);
+	return mips_cpu_timer_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
+void __init plat_time_init(void)
+{
+	unsigned int est_freq, flags;
+
+	local_irq_save(flags);
+
+	/* Set Data mode - binary. */
+	CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
+
+	est_freq = estimate_cpu_frequency();
+
+	printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000,
+	       (est_freq % 1000000) * 100 / 1000000);
+
+	cpu_khz = est_freq / 1000;
+
+	local_irq_restore(flags);
 }

+ 32 - 28
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 @@ static void r3k_flush_dcache_range(unsigned long start, unsigned long end)
 	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_mm(struct mm_struct *mm)
 }
 
 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 @@ static void r3k_flush_cache_sigtramp(unsigned long addr)
 {
 	unsigned long flags;
 
-#ifdef DEBUG_CACHE
-	printk("csigtramp[%08lx]", addr);
-#endif
+	pr_debug("csigtramp[%08lx]\n", addr);
 
 	flags = read_c0_status();
 

+ 18 - 3
arch/mips/mm/c-r4k.c

@@ -345,11 +345,26 @@ static void r4k___flush_cache_all(void)
 	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 @@ static inline void local_r4k_flush_cache_mm(void * args)
 {
 	struct mm_struct *mm = args;
 
-	if (!cpu_context(smp_processor_id(), mm))
+	if (!has_valid_asid(mm))
 		return;
 
 	/*
@@ -420,7 +435,7 @@ static inline void local_r4k_flush_cache_page(void *args)
 	 * 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;

+ 1 - 1
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>

+ 1 - 1
arch/mips/pci/fixup-pmcmsp.c

@@ -202,7 +202,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
  *  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");

+ 1 - 1
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

+ 1 - 1
arch/mips/pci/ops-pmcmsp.c

@@ -404,7 +404,7 @@ int msp_pcibios_config_access(unsigned char access_type,
 	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;

+ 1 - 1
arch/mips/pmc-sierra/msp71xx/msp_serial.c

@@ -122,7 +122,7 @@ void __init msp_serial_setup(void)
 	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;

+ 7 - 4
arch/mips/sgi-ip27/ip27-timer.c

@@ -131,12 +131,12 @@ static struct irq_chip rt_irq_type = {
 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 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
 {
 	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;

+ 77 - 51
arch/mips/sgi-ip32/ip32-irq.c

@@ -40,13 +40,6 @@ static void inline flush_mace_bus(void)
 	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 @@ struct irqaction memerr_irq = {
 	.mask = CPU_MASK_NONE,
 	.name = "CRIME memory error",
 };
+
 struct irqaction cpuerr_irq = {
 	.handler = crime_cpuerr_intr,
 	.flags = IRQF_DISABLED,
@@ -139,46 +133,70 @@ struct irqaction cpuerr_irq = {
 
 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)
+{
+	crime_disable_irq(irq);
+}
+
+static void crime_level_end_irq(unsigned int irq)
+{
+	if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
+		crime_enable_irq(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. */
-	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_int = crime->hard_int;
+	crime_int &= ~(1 << bit);
+	crime->hard_int = crime_int;
+
+	crime_disable_irq(irq);
 }
 
-static void end_crime_irq(unsigned int irq)
+static void crime_edge_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_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 @@ static void enable_maceisa_irq(unsigned int irq)
 {
 	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 @@ static void enable_maceisa_irq(unsigned int irq)
 		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 @@ static void disable_maceisa_irq(unsigned int irq)
 	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 void end_maceisa_irq(unsigned irq)
 }
 
 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 @@ static void ip32_irq0(void)
 		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 @@ void __init arch_init_irq(void)
 
 	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_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_GBE0_IRQ ... CRIME_VICE_IRQ:
-			chip = &ip32_crime_interrupt;
+		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);

+ 0 - 24
arch/mips/sibyte/bcm1480/irq.c

@@ -280,27 +280,6 @@ static struct irqaction bcm1480_dummy_action = {
 	.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 @@ void __init arch_init_irq(void)
 		__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 @@ void __init arch_init_irq(void)
 		/* 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));

+ 1 - 4
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 @@ void __cpuinit sb1480_clockevent_init(void)
 	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 @@ void __cpuinit sb1480_clockevent_init(void)
 			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;

+ 0 - 24
arch/mips/sibyte/sb1250/irq.c

@@ -250,27 +250,6 @@ static struct irqaction sb1250_dummy_action = {
 	.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 @@ void __init arch_init_irq(void)
 	__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 @@ void __init arch_init_irq(void)
 		__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) +

+ 1 - 4
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 @@ void __cpuinit sb1250_clockevent_init(void)
 	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 @@ void __cpuinit sb1250_clockevent_init(void)
 	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;

+ 64 - 16
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 @@ void __init plat_time_init(void)
 	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;
 	}
 }
 

+ 9 - 8
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 @@ extern void toshiba_rbtx4927_power_off(void);
 
 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 toshiba_rbtx4927_power_off(void)
 
 void __init toshiba_rbtx4927_setup(void)
 {
+	int i;
 	u32 cp0_config;
 	char *argptr;
 
@@ -764,6 +764,9 @@ void __init toshiba_rbtx4927_setup(void)
 	_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 @@ void __init toshiba_rbtx4927_setup(void)
 #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_setup(void)
 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)

+ 7 - 12
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 @@ void __init tx4938_board_setup(void)
 	}
 
 	/* 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 @@ void tx4938_report_pcic_status(void)
 
 #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)

+ 3 - 1
include/asm-mips/ip32/ip32_ints.h

@@ -22,10 +22,12 @@ enum ip32_irq_no {
 	 * 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,

+ 1 - 8
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:
  *

+ 1 - 3
include/asm-mips/jmr3927/tx3927.h

@@ -222,9 +222,7 @@ struct tx3927_ccfg_reg {
 #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
 
 /*

+ 0 - 37
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;
@@ -50,27 +34,6 @@ struct txx927_pio_reg {
 	volatile unsigned long maskext;
 };
 
-/*
- * 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
  */

+ 1 - 1
include/asm-mips/time.h

@@ -58,7 +58,6 @@ extern void local_timer_interrupt(int irq, void *dev_id);
  */
 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 @@ extern int (*perf_irq)(void);
  */
 #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)
 {

+ 3 - 0
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)

+ 0 - 1
include/asm-mips/tx4938/tx4938.h

@@ -641,7 +641,6 @@ struct tx4938_ccfg_reg {
 #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)

+ 67 - 0
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 */