[ARM] 4210/1: base for new machine type "NetSilicon NS9360"

Signed-off-by: Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 6783c2e..c843508 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -271,6 +271,14 @@
 	  If you have any questions or comments about the Linux kernel port
 	  to this board, send e-mail to <sjhill@cotw.com>.
 
+config ARCH_NS9XXX
+	bool "NetSilicon NS9xxx"
+	help
+	  Say Y here if you intend to run this kernel on a NetSilicon NS9xxx
+	  System.
+
+	  <http://www.digi.com/products/microprocessors/index.jsp>
+
 config ARCH_PNX4008
 	bool "Philips Nexperia PNX4008 Mobile"
 	help
@@ -381,6 +389,8 @@
 
 source "arch/arm/mach-netx/Kconfig"
 
+source "arch/arm/mach-ns9xxx/Kconfig"
+
 # Definitions to make life easier
 config ARCH_ACORN
 	bool
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 000f110..52d1194 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -124,10 +124,12 @@
  machine-$(CONFIG_ARCH_H720X)	   := h720x
  machine-$(CONFIG_ARCH_AAEC2000)   := aaec2000
  machine-$(CONFIG_ARCH_REALVIEW)   := realview
- machine-$(CONFIG_ARCH_AT91)       := at91rm9200
- machine-$(CONFIG_ARCH_EP93XX)     := ep93xx
- machine-$(CONFIG_ARCH_PNX4008)    := pnx4008
- machine-$(CONFIG_ARCH_NETX)       := netx
+ machine-$(CONFIG_ARCH_AT91)	   := at91rm9200
+ machine-$(CONFIG_ARCH_EP93XX)	   := ep93xx
+ machine-$(CONFIG_ARCH_PNX4008)	   := pnx4008
+ machine-$(CONFIG_ARCH_NETX)	   := netx
+ machine-$(CONFIG_ARCH_NS9XXX)	   := ns9xxx
+ textofs-$(CONFIG_ARCH_NS9XXX)	   := 0x00108000
 
 ifeq ($(CONFIG_ARCH_EBSA110),y)
 # This is what happens if you forget the IOCS16 line.
diff --git a/arch/arm/mach-ns9xxx/Kconfig b/arch/arm/mach-ns9xxx/Kconfig
new file mode 100644
index 0000000..8175ba9
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/Kconfig
@@ -0,0 +1,21 @@
+if ARCH_NS9XXX
+
+menu "NS9xxx Implementations"
+
+config MACH_CC9P9360DEV
+	bool "Connect Core 9P 9360 on an A9M9750 Devboard"
+	select PROCESSOR_NS9360
+	select BOARD_A9M9750DEV
+	help
+	  Say Y here if you are using the Digi Connect Core 9P 9360
+	  on an A9M9750 Development Board.
+
+config PROCESSOR_NS9360
+	bool
+
+config BOARD_A9M9750DEV
+	bool
+
+endmenu
+
+endif
diff --git a/arch/arm/mach-ns9xxx/Makefile b/arch/arm/mach-ns9xxx/Makefile
new file mode 100644
index 0000000..91e945f
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/Makefile
@@ -0,0 +1,5 @@
+obj-y := irq.o time.o generic.o
+
+obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o
+
+obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o
diff --git a/arch/arm/mach-ns9xxx/Makefile.boot b/arch/arm/mach-ns9xxx/Makefile.boot
new file mode 100644
index 0000000..75ed64e
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/Makefile.boot
@@ -0,0 +1,2 @@
+zreladdr-y := 0x108000
+params_phys-y := 0x100
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
new file mode 100644
index 0000000..2528988
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
@@ -0,0 +1,199 @@
+/*
+ * arch/arm/mach-ns9xxx/board-a9m9750dev.c
+ *
+ * Copyright (C) 2006,2007 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/irq.h>
+
+#include <asm/mach/map.h>
+
+#include <asm/arch-ns9xxx/board.h>
+#include <asm/arch-ns9xxx/regs-sys.h>
+#include <asm/arch-ns9xxx/regs-mem.h>
+#include <asm/arch-ns9xxx/regs-bbu.h>
+#include <asm/arch-ns9xxx/regs-board-a9m9750dev.h>
+
+#include "board-a9m9750dev.h"
+
+static struct map_desc board_a9m9750dev_io_desc[] __initdata = {
+	{ /* FPGA on CS0 */
+		.virtual = io_p2v(NS9XXX_CSxSTAT_PHYS(0)),
+		.pfn = __phys_to_pfn(NS9XXX_CSxSTAT_PHYS(0)),
+		.length = NS9XXX_CS0STAT_LENGTH,
+		.type = MT_DEVICE,
+	},
+};
+
+void __init board_a9m9750dev_map_io(void)
+{
+	iotable_init(board_a9m9750dev_io_desc,
+		     ARRAY_SIZE(board_a9m9750dev_io_desc));
+}
+
+static void a9m9750dev_fpga_ack_irq(unsigned int irq)
+{
+	/* nothing */
+}
+
+static void a9m9750dev_fpga_mask_irq(unsigned int irq)
+{
+	FPGA_IER &= ~(1 << (irq - FPGA_IRQ(0)));
+}
+
+static void a9m9750dev_fpga_maskack_irq(unsigned int irq)
+{
+	a9m9750dev_fpga_mask_irq(irq);
+	a9m9750dev_fpga_ack_irq(irq);
+}
+
+static void a9m9750dev_fpga_unmask_irq(unsigned int irq)
+{
+	FPGA_IER |= 1 << (irq - FPGA_IRQ(0));
+}
+
+static struct irq_chip a9m9750dev_fpga_chip = {
+	.ack		= a9m9750dev_fpga_ack_irq,
+	.mask		= a9m9750dev_fpga_mask_irq,
+	.mask_ack	= a9m9750dev_fpga_maskack_irq,
+	.unmask		= a9m9750dev_fpga_unmask_irq,
+};
+
+static void a9m9750dev_fpga_demux_handler(unsigned int irq,
+		struct irq_desc *desc)
+{
+	int stat = FPGA_ISR;
+
+	while (stat != 0) {
+		int irqno = fls(stat) - 1;
+
+		stat &= ~(1 << irqno);
+
+		desc = irq_desc + FPGA_IRQ(irqno);
+
+		desc_handle_irq(irqno, desc);
+	}
+}
+
+void __init board_a9m9750dev_init_irq(void)
+{
+	u32 reg;
+	int i;
+
+	/*
+	 * configure gpio for IRQ_EXT2
+	 * use GPIO 11, because GPIO 32 is used for the LCD
+	 */
+	/* XXX: proper GPIO handling */
+	BBU_GC(2) &= ~0x2000;
+
+	for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) {
+		set_irq_chip(i, &a9m9750dev_fpga_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+
+	/* IRQ_EXT2: level sensitive + active low */
+	reg = SYS_EIC(2);
+	REGSET(reg, SYS_EIC, PLTY, AL);
+	REGSET(reg, SYS_EIC, LVEDG, LEVEL);
+	SYS_EIC(2) = reg;
+
+	set_irq_chained_handler(IRQ_EXT2,
+			a9m9750dev_fpga_demux_handler);
+}
+
+static struct plat_serial8250_port board_a9m9750dev_serial8250_port[] = {
+	{
+		.iobase         = FPGA_UARTA_BASE,
+		.membase        = (unsigned char*)FPGA_UARTA_BASE,
+		.mapbase        = FPGA_UARTA_BASE,
+		.irq            = IRQ_FPGA_UARTA,
+		.iotype         = UPIO_MEM,
+		.uartclk        = 18432000,
+		.regshift       = 0,
+		.flags          = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
+	}, {
+		.iobase         = FPGA_UARTB_BASE,
+		.membase        = (unsigned char*)FPGA_UARTB_BASE,
+		.mapbase        = FPGA_UARTB_BASE,
+		.irq            = IRQ_FPGA_UARTB,
+		.iotype         = UPIO_MEM,
+		.uartclk        = 18432000,
+		.regshift       = 0,
+		.flags          = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
+	}, {
+		.iobase         = FPGA_UARTC_BASE,
+		.membase        = (unsigned char*)FPGA_UARTC_BASE,
+		.mapbase        = FPGA_UARTC_BASE,
+		.irq            = IRQ_FPGA_UARTC,
+		.iotype         = UPIO_MEM,
+		.uartclk        = 18432000,
+		.regshift       = 0,
+		.flags          = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
+	}, {
+		.iobase         = FPGA_UARTD_BASE,
+		.membase        = (unsigned char*)FPGA_UARTD_BASE,
+		.mapbase        = FPGA_UARTD_BASE,
+		.irq            = IRQ_FPGA_UARTD,
+		.iotype         = UPIO_MEM,
+		.uartclk        = 18432000,
+		.regshift       = 0,
+		.flags          = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
+	}, {
+		/* end marker */
+	},
+};
+
+static struct platform_device board_a9m9750dev_serial_device = {
+	.name = "serial8250",
+	.dev = {
+		.platform_data = board_a9m9750dev_serial8250_port,
+	},
+};
+
+static struct platform_device *board_a9m9750dev_devices[] __initdata = {
+	&board_a9m9750dev_serial_device,
+};
+
+void __init board_a9m9750dev_init_machine(void)
+{
+	u32 reg;
+
+	/* setup static CS0: memory base ... */
+	REGSETIM(SYS_SMCSSMB(0), SYS_SMCSSMB, CSxB,
+			NS9XXX_CSxSTAT_PHYS(0) >> 12);
+
+	/* ... and mask */
+	reg = SYS_SMCSSMM(0);
+	REGSETIM(reg, SYS_SMCSSMM, CSxM, 0xfffff);
+	REGSET(reg, SYS_SMCSSMM, CSEx, EN);
+	SYS_SMCSSMM(0) = reg;
+
+	/* setup static CS0: memory configuration */
+	reg = MEM_SMC(0);
+	REGSET(reg, MEM_SMC, WSMC, OFF);
+	REGSET(reg, MEM_SMC, BSMC, OFF);
+	REGSET(reg, MEM_SMC, EW, OFF);
+	REGSET(reg, MEM_SMC, PB, 1);
+	REGSET(reg, MEM_SMC, PC, AL);
+	REGSET(reg, MEM_SMC, PM, DIS);
+	REGSET(reg, MEM_SMC, MW, 8);
+	MEM_SMC(0) = reg;
+
+	/* setup static CS0: timing */
+	MEM_SMWED(0) = 0x2;
+	MEM_SMOED(0) = 0x2;
+	MEM_SMRD(0) = 0x6;
+	MEM_SMWD(0) = 0x6;
+
+	platform_add_devices(board_a9m9750dev_devices,
+			ARRAY_SIZE(board_a9m9750dev_devices));
+}
+
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.h b/arch/arm/mach-ns9xxx/board-a9m9750dev.h
new file mode 100644
index 0000000..edc75ab
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.h
@@ -0,0 +1,15 @@
+/*
+ * arch/arm/mach-ns9xxx/board-a9m9750dev.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/init.h>
+
+void __init board_a9m9750dev_map_io(void);
+void __init board_a9m9750dev_init_machine(void);
+void __init board_a9m9750dev_init_irq(void);
diff --git a/arch/arm/mach-ns9xxx/generic.c b/arch/arm/mach-ns9xxx/generic.c
new file mode 100644
index 0000000..83e2b65
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/generic.c
@@ -0,0 +1,42 @@
+/*
+ * arch/arm/mach-ns9xxx/generic.c
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/memory.h>
+#include <asm/page.h>
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+#include <asm/arch-ns9xxx/regs-sys.h>
+#include <asm/arch-ns9xxx/regs-mem.h>
+#include <asm/arch-ns9xxx/board.h>
+
+static struct map_desc standard_io_desc[] __initdata = {
+	{ /* BBus */
+		.virtual = io_p2v(0x90000000),
+		.pfn = __phys_to_pfn(0x90000000),
+		.length = 0x00700000,
+		.type = MT_DEVICE,
+	}, { /* AHB */
+		.virtual = io_p2v(0xa0100000),
+		.pfn = __phys_to_pfn(0xa0100000),
+		.length = 0x00900000,
+		.type = MT_DEVICE,
+	},
+};
+
+void __init ns9xxx_map_io(void)
+{
+	iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+}
+
+void __init ns9xxx_init_machine(void)
+{
+}
diff --git a/arch/arm/mach-ns9xxx/generic.h b/arch/arm/mach-ns9xxx/generic.h
new file mode 100644
index 0000000..687e2917
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/generic.h
@@ -0,0 +1,19 @@
+/*
+ * arch/arm/mach-ns9xxx/generic.h
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/time.h>
+#include <asm/mach/time.h>
+#include <linux/init.h>
+
+void __init ns9xxx_init_irq(void);
+void __init ns9xxx_map_io(void);
+void __init ns9xxx_init_machine(void);
+
+extern struct sys_timer ns9xxx_timer;
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
new file mode 100644
index 0000000..83d9272
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -0,0 +1,94 @@
+/*
+ * arch/arm/mach-ns9xxx/irq.c
+ *
+ * Copyright (C) 2006,2007 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/interrupt.h>
+#include <asm/mach/irq.h>
+#include <asm/mach-types.h>
+#include <asm/arch-ns9xxx/regs-sys.h>
+#include <asm/arch-ns9xxx/irqs.h>
+#include <asm/arch-ns9xxx/board.h>
+
+#include "generic.h"
+
+static void ns9xxx_ack_irq_timer(unsigned int irq)
+{
+	u32 tc = SYS_TC(irq - IRQ_TIMER0);
+
+	REGSET(tc, SYS_TCx, INTC, SET);
+	SYS_TC(irq - IRQ_TIMER0) = tc;
+
+	REGSET(tc, SYS_TCx, INTC, UNSET);
+	SYS_TC(irq - IRQ_TIMER0) = tc;
+}
+
+void (*ns9xxx_ack_irq_functions[NR_IRQS])(unsigned int) = {
+	[IRQ_TIMER0] = ns9xxx_ack_irq_timer,
+	[IRQ_TIMER1] = ns9xxx_ack_irq_timer,
+	[IRQ_TIMER2] = ns9xxx_ack_irq_timer,
+	[IRQ_TIMER3] = ns9xxx_ack_irq_timer,
+};
+
+static void ns9xxx_mask_irq(unsigned int irq)
+{
+	/* XXX: better use cpp symbols */
+	SYS_IC(irq / 4) &= ~(1 << (7 + 8 * (3 - (irq & 3))));
+}
+
+static void ns9xxx_ack_irq(unsigned int irq)
+{
+	if (!ns9xxx_ack_irq_functions[irq]) {
+		printk(KERN_ERR "no ack function for irq %u\n", irq);
+		BUG();
+	}
+
+	ns9xxx_ack_irq_functions[irq](irq);
+	SYS_ISRADDR = 0;
+}
+
+static void ns9xxx_maskack_irq(unsigned int irq)
+{
+	ns9xxx_mask_irq(irq);
+	ns9xxx_ack_irq(irq);
+}
+
+static void ns9xxx_unmask_irq(unsigned int irq)
+{
+	/* XXX: better use cpp symbols */
+	SYS_IC(irq / 4) |= 1 << (7 + 8 * (3 - (irq & 3)));
+}
+
+static struct irq_chip ns9xxx_chip = {
+	.ack		= ns9xxx_ack_irq,
+	.mask		= ns9xxx_mask_irq,
+	.mask_ack	= ns9xxx_maskack_irq,
+	.unmask		= ns9xxx_unmask_irq,
+};
+
+void __init ns9xxx_init_irq(void)
+{
+	int i;
+
+	/* disable all IRQs */
+	for (i = 0; i < 8; ++i)
+		SYS_IC(i) = (4 * i) << 24 | (4 * i + 1) << 16 |
+			(4 * i + 2) << 8 | (4 * i + 3);
+
+	/* simple interrupt prio table:
+	 * prio(x) < prio(y) <=> x < y
+	 */
+	for (i = 0; i < 32; ++i)
+		SYS_IVA(i) = i;
+
+	for (i = IRQ_WATCHDOG; i <= IRQ_EXT3; ++i) {
+		set_irq_chip(i, &ns9xxx_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+}
diff --git a/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c b/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
new file mode 100644
index 0000000..a193dd9
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
@@ -0,0 +1,41 @@
+/*
+ * arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include "board-a9m9750dev.h"
+#include "generic.h"
+
+static void __init mach_cc9p9360dev_map_io(void)
+{
+	ns9xxx_map_io();
+	board_a9m9750dev_map_io();
+}
+
+static void __init mach_cc9p9360dev_init_irq(void)
+{
+	ns9xxx_init_irq();
+	board_a9m9750dev_init_irq();
+}
+
+static void __init mach_cc9p9360dev_init_machine(void)
+{
+	ns9xxx_init_machine();
+	board_a9m9750dev_init_machine();
+}
+
+MACHINE_START(CC9P9360DEV, "Connect Core 9P 9360 on an A9M9750 Devboard")
+	.map_io = mach_cc9p9360dev_map_io,
+	.init_irq = mach_cc9p9360dev_init_irq,
+	.init_machine = mach_cc9p9360dev_init_machine,
+	.timer = &ns9xxx_timer,
+	.boot_params = 0x100,
+MACHINE_END
diff --git a/arch/arm/mach-ns9xxx/time.c b/arch/arm/mach-ns9xxx/time.c
new file mode 100644
index 0000000..eec05f1
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/time.c
@@ -0,0 +1,88 @@
+/*
+ * arch/arm/mach-ns9xxx/time.c
+ *
+ * Copyright (C) 2006 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/jiffies.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/arch-ns9xxx/regs-sys.h>
+#include <asm/arch-ns9xxx/clock.h>
+#include <asm/arch-ns9xxx/irqs.h>
+#include <asm/arch/system.h>
+#include "generic.h"
+
+#define TIMERCLOCKSELECT 64
+
+static u32 usecs_per_tick;
+
+static irqreturn_t
+ns9xxx_timer_interrupt(int irq, void *dev_id)
+{
+	write_seqlock(&xtime_lock);
+	timer_tick();
+	write_sequnlock(&xtime_lock);
+
+	return IRQ_HANDLED;
+}
+
+static unsigned long ns9xxx_timer_gettimeoffset(void)
+{
+	/* return the microseconds which have passed since the last interrupt
+	 * was _serviced_.  That is, if an interrupt is pending or the counter
+	 * reloads, return one periode more. */
+
+	u32 counter1 = SYS_TR(0);
+	int pending = SYS_ISR & (1 << IRQ_TIMER0);
+	u32 counter2 = SYS_TR(0);
+	u32 elapsed;
+
+	if (pending || counter2 > counter1)
+		elapsed = 2 * SYS_TRC(0) - counter2;
+	else
+		elapsed = SYS_TRC(0) - counter1;
+
+	return (elapsed * usecs_per_tick) >> 16;
+
+}
+
+static struct irqaction ns9xxx_timer_irq = {
+	.name = "NS9xxx Timer Tick",
+	.flags = IRQF_DISABLED | IRQF_TIMER,
+	.handler = ns9xxx_timer_interrupt,
+};
+
+static void __init ns9xxx_timer_init(void)
+{
+	int tc;
+
+	usecs_per_tick =
+		SH_DIV(1000000 * TIMERCLOCKSELECT, ns9xxx_cpuclock(), 16);
+
+	/* disable timer */
+	if ((tc = SYS_TC(0)) & SYS_TCx_TEN)
+		SYS_TC(0) = tc & ~SYS_TCx_TEN;
+
+	SYS_TRC(0) = SH_DIV(ns9xxx_cpuclock(), (TIMERCLOCKSELECT * HZ), 0);
+
+	REGSET(tc, SYS_TCx, TEN, EN);
+	REGSET(tc, SYS_TCx, TLCS, DIV64); /* This must match TIMERCLOCKSELECT */
+	REGSET(tc, SYS_TCx, INTS, EN);
+	REGSET(tc, SYS_TCx, UDS, DOWN);
+	REGSET(tc, SYS_TCx, TDBG, STOP);
+	REGSET(tc, SYS_TCx, TSZ, 32);
+	REGSET(tc, SYS_TCx, REN, EN);
+	SYS_TC(0) = tc;
+
+	setup_irq(IRQ_TIMER0, &ns9xxx_timer_irq);
+}
+
+struct sys_timer ns9xxx_timer = {
+	.init = ns9xxx_timer_init,
+	.offset = ns9xxx_timer_gettimeoffset,
+};
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index aade2f7..2762444 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -171,8 +171,8 @@
 # ARM926T
 config CPU_ARM926T
 	bool "Support ARM926T processor"
-	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261
-	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261
+	depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_NS9XXX
+	default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_NS9XXX
 	select CPU_32v5
 	select CPU_ABRT_EV5TJ
 	select CPU_CACHE_VIVT