From 3bcc74c2a18c30b525a8215e22acd846c371c234 Mon Sep 17 00:00:00 2001
From: nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Date: Thu, 10 Nov 2005 01:53:27 +0000
Subject: add another batch of ar7 cleanups and an ar7 watchdog timer (thx
 enrik!). also seems to fix wag354g problems

git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@2404 3c298f89-4303-0410-b956-a3cf2f4a3e73
---
 target/linux/linux-2.4/config/ar7                  |   22 +-
 .../linux-2.4/patches/ar7/000-ar7_support.patch    | 1764 +++++++-------------
 .../linux-2.4/patches/ar7/004-atm_driver.patch     |    2 +-
 .../linux-2.4/patches/ar7/005-wdt_driver.patch     |  392 +++++
 4 files changed, 1000 insertions(+), 1180 deletions(-)
 create mode 100644 target/linux/linux-2.4/patches/ar7/005-wdt_driver.patch

diff --git a/target/linux/linux-2.4/config/ar7 b/target/linux/linux-2.4/config/ar7
index d0ef2f0e9..8fc67cb55 100644
--- a/target/linux/linux-2.4/config/ar7
+++ b/target/linux/linux-2.4/config/ar7
@@ -87,6 +87,7 @@ CONFIG_AR7_MEMORY=0x14000000
 # CONFIG_HIGHMEM is not set
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_IRQ_CPU=y
 CONFIG_NONCOHERENT_IO=y
 CONFIG_SWAP_IO_SPACE=y
 # CONFIG_MIPS_AU1000 is not set
@@ -782,25 +783,8 @@ CONFIG_AR7_ADAM2=y
 #
 CONFIG_WATCHDOG=y
 CONFIG_WATCHDOG_NOWAYOUT=y
-# CONFIG_ACQUIRE_WDT is not set
-# CONFIG_ADVANTECH_WDT is not set
-# CONFIG_ALIM1535_WDT is not set
-# CONFIG_ALIM7101_WDT is not set
-# CONFIG_SC520_WDT is not set
-# CONFIG_PCWATCHDOG is not set
-# CONFIG_EUROTECH_WDT is not set
-# CONFIG_IB700_WDT is not set
-# CONFIG_WAFER_WDT is not set
-# CONFIG_I810_TCO is not set
-# CONFIG_MIXCOMWD is not set
-# CONFIG_60XX_WDT is not set
-# CONFIG_SC1200_WDT is not set
-# CONFIG_SCx200_WDT is not set
-CONFIG_SOFT_WATCHDOG=y
-# CONFIG_W83877F_WDT is not set
-# CONFIG_WDT is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_MACHZ_WDT is not set
+CONFIG_AR7_WDT=y
+# CONFIG_SOFT_WATCHDOG is not set
 # CONFIG_SCx200 is not set
 # CONFIG_SCx200_GPIO is not set
 # CONFIG_AMD_PM768 is not set
diff --git a/target/linux/linux-2.4/patches/ar7/000-ar7_support.patch b/target/linux/linux-2.4/patches/ar7/000-ar7_support.patch
index fc7bdeb29..d5bbe4227 100644
--- a/target/linux/linux-2.4/patches/ar7/000-ar7_support.patch
+++ b/target/linux/linux-2.4/patches/ar7/000-ar7_support.patch
@@ -1,6 +1,6 @@
 diff -urN linux.old/Makefile linux.dev/Makefile
 --- linux.old/Makefile	2005-10-21 16:43:16.316951500 +0200
-+++ linux.dev/Makefile	2005-10-21 16:45:42.294074500 +0200
++++ linux.dev/Makefile	2005-11-10 01:10:45.771570000 +0100
 @@ -91,7 +91,7 @@
  
  CPPFLAGS := -D__KERNEL__ -I$(HPATH)
@@ -12,7 +12,7 @@ diff -urN linux.old/Makefile linux.dev/Makefile
  CFLAGS += -fomit-frame-pointer
 diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile
 --- linux.old/arch/mips/Makefile	2005-10-21 16:43:16.316951500 +0200
-+++ linux.dev/arch/mips/Makefile	2005-10-21 16:45:42.134064500 +0200
++++ linux.dev/arch/mips/Makefile	2005-11-10 01:10:45.775570250 +0100
 @@ -369,6 +369,16 @@
  endif
  
@@ -32,7 +32,7 @@ diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile
  ifdef CONFIG_DECSTATION
 diff -urN linux.old/arch/mips/ar7/Makefile linux.dev/arch/mips/ar7/Makefile
 --- linux.old/arch/mips/ar7/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/Makefile	2005-10-21 17:02:14.507635750 +0200
++++ linux.dev/arch/mips/ar7/Makefile	2005-11-10 01:13:51.443173750 +0100
 @@ -0,0 +1,14 @@
 +.S.s:
 +	$(CPP) $(AFLAGS) $< -o $*.s
@@ -45,13 +45,13 @@ diff -urN linux.old/arch/mips/ar7/Makefile linux.dev/arch/mips/ar7/Makefile
 +
 +obj-y := tnetd73xx_misc.o misc.o
 +export-objs := misc.o irq.o init.o
-+obj-y += setup.o irq.o mipsIRQ.o reset.o init.o psp_env.o memory.o printf.o cmdline.o time.o
++obj-y += setup.o irq.o int-handler.o reset.o init.o psp_env.o memory.o promlib.o cmdline.o
 +
 +include $(TOPDIR)/Rules.make
 diff -urN linux.old/arch/mips/ar7/cmdline.c linux.dev/arch/mips/ar7/cmdline.c
 --- linux.old/arch/mips/ar7/cmdline.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/cmdline.c	2005-10-21 16:45:42.090061750 +0200
-@@ -0,0 +1,64 @@
++++ linux.dev/arch/mips/ar7/cmdline.c	2005-11-10 01:14:16.372731750 +0100
+@@ -0,0 +1,88 @@
 +/*
 + * Carsten Langgaard, carstenl@mips.com
 + * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
@@ -86,6 +86,9 @@ diff -urN linux.old/arch/mips/ar7/cmdline.c linux.dev/arch/mips/ar7/cmdline.c
 +#define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)]))
 +
 +char arcs_cmdline[CL_SIZE];
++#ifdef CONFIG_CMDLINE_BOOL
++char __initdata cfg_cmdline[] = CONFIG_CMDLINE;
++#endif
 +
 +char * __init prom_getcmdline(void)
 +{
@@ -95,20 +98,41 @@ diff -urN linux.old/arch/mips/ar7/cmdline.c linux.dev/arch/mips/ar7/cmdline.c
 +
 +void  __init prom_init_cmdline(void)
 +{
-+	char *cp;
++	char *cp, *end;
 +	int actr;
++	char *env_cmdline = prom_getenv("kernel_args");
++	size_t len;
 +
 +	actr = 1; /* Always ignore argv[0] */
 +
-+	cp = &(arcs_cmdline[0]);
++	cp = end = &(arcs_cmdline[0]);
++	end += sizeof(arcs_cmdline);
++
++	if (env_cmdline) {
++		len = strlen(env_cmdline);
++		if (len > end - cp - 1)
++			len = end - cp - 1;
++		strncpy(cp, env_cmdline, len);
++		cp += len;
++		*cp++ = ' ';
++	}
 +#ifdef CONFIG_CMDLINE_BOOL
-+	strcpy(cp, CONFIG_CMDLINE);
-+	cp += strlen(CONFIG_CMDLINE);
-+	*cp++ = ' ';
++	else {
++		len = strlen(cfg_cmdline);
++		if (len > end - cp - 1)
++			len = end - cp - 1;
++		strncpy(cp, cfg_cmdline, len);
++		cp += len;
++		*cp++ = ' ';
++	}
 +#endif
++
 +	while(actr < prom_argc) {
-+		strcpy(cp, prom_argv(actr));
-+		cp += strlen(prom_argv(actr));
++		len = strlen(prom_argv(actr));
++		if (len > end - cp - 1)
++			break;
++		strncpy(cp, prom_argv(actr), len);
++		cp += len;
 +		*cp++ = ' ';
 +		actr++;
 +	}
@@ -118,7 +142,7 @@ diff -urN linux.old/arch/mips/ar7/cmdline.c linux.dev/arch/mips/ar7/cmdline.c
 +}
 diff -urN linux.old/arch/mips/ar7/init.c linux.dev/arch/mips/ar7/init.c
 --- linux.old/arch/mips/ar7/init.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/init.c	2005-10-21 17:02:14.507635750 +0200
++++ linux.dev/arch/mips/ar7/init.c	2005-11-10 01:10:45.795571500 +0100
 @@ -0,0 +1,199 @@
 +/*
 + * Carsten Langgaard, carstenl@mips.com
@@ -319,10 +343,77 @@ diff -urN linux.old/arch/mips/ar7/init.c linux.dev/arch/mips/ar7/init.c
 +
 +	return 0;
 +}
+diff -urN linux.old/arch/mips/ar7/int-handler.S linux.dev/arch/mips/ar7/int-handler.S
+--- linux.old/arch/mips/ar7/int-handler.S	1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/ar7/int-handler.S	2005-11-10 01:12:43.938955000 +0100
+@@ -0,0 +1,63 @@
++/*
++ * Copyright 2004 PMC-Sierra Inc.
++ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
++ * Adaption for AR7: Enrik Berkhan <enrik@akk.org>
++ *
++ * First-level interrupt dispatcher for the TI AR7
++ *
++ * 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.
++ */
++#define __ASSEMBLY__
++#include <linux/config.h>
++#include <asm/asm.h>
++#include <asm/mipsregs.h>
++#include <asm/addrspace.h>
++#include <asm/regdef.h>
++#include <asm/stackframe.h>
++
++/*
++ * First level interrupt dispatcher for TI AR7 based boards
++ */
++
++		.align	5
++		NESTED(ar7IRQ, PT_SIZE, sp)
++		SAVE_ALL
++		CLI
++		.set	at
++
++		mfc0	t0, CP0_CAUSE
++		mfc0	t2, CP0_STATUS
++
++		and	t0, t2
++
++		andi	t1, t0, STATUSF_IP2	/* hw0 hardware interrupt */
++		bnez	t1, ll_hw0_irq
++
++		andi	t1, t0, STATUSF_IP7	/* R4k CPU timer */
++		bnez	t1, ll_timer_irq
++
++		.set	reorder
++
++		/* wrong alarm or masked ... */
++		j	spurious_interrupt
++		nop
++		END(ar7IRQ)
++
++		.align	5
++
++ll_hw0_irq:
++		li	a0, 2
++		move	a1, sp
++		jal	do_IRQ
++		j	ret_from_irq
++
++ll_timer_irq:
++		li	a0, 7
++		move	a1, sp
++		jal	do_IRQ
++		j	ret_from_irq
++
++			
 diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 --- linux.old/arch/mips/ar7/irq.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/irq.c	2005-10-21 17:02:14.507635750 +0200
-@@ -0,0 +1,925 @@
++++ linux.dev/arch/mips/ar7/irq.c	2005-11-10 01:12:43.938955000 +0100
+@@ -0,0 +1,427 @@
 +/*
 + * Nitin Dhingra, iamnd@ti.com
 + * Copyright (C) 2002 Texas Instruments, Inc.  All rights reserved.
@@ -349,20 +440,13 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 + *
 + */
 +
-+#include <linux/config.h>
 +#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
 +#include <linux/interrupt.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/proc_fs.h>
-+#include <linux/module.h>
++
 +#include <asm/irq.h>
-+#include <asm/mips-boards/prom.h>
++#include <asm/mipsregs.h>
 +#include <asm/ar7/ar7.h>
 +#include <asm/ar7/avalanche_intc.h>
-+#include <asm/gdb-stub.h>
-+
 +
 +#define shutdown_avalanche_irq	disable_avalanche_irq
 +#define mask_and_ack_avalanche_irq   disable_avalanche_irq
@@ -371,9 +455,10 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 +static void end_avalanche_irq(unsigned int irq);
 +void enable_avalanche_irq(unsigned int irq_nr);
 +void disable_avalanche_irq(unsigned int irq_nr);
++void ar7_hw0_interrupt(int interrupt, void *dev, struct pt_regs *regs);
 +
 +static struct hw_interrupt_type avalanche_irq_type = {
-+	"TI AVALANCHE",
++	"AR7",
 +	startup_avalanche_irq,
 +	shutdown_avalanche_irq,
 +	enable_avalanche_irq,
@@ -383,90 +468,29 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 +	NULL
 +};
 +
-+irq_desc_t irq_desc_ti[AVALANCHE_INT_END+1] __cacheline_aligned =
-+{ [0 ... AVALANCHE_INT_END] = { 0, &avalanche_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}};
++static int ar7_irq_base;
 +
-+
-+unsigned long spurious_count = 0;
++static struct irqaction ar7_hw0_action = {
++    ar7_hw0_interrupt, 0, 0, "AR7 on hw0", NULL, NULL
++};
 +
 +struct avalanche_ictrl_regs         *avalanche_hw0_icregs;  /* Interrupt control regs (primary)   */
 +struct avalanche_exctrl_regs        *avalanche_hw0_ecregs;  /* Exception control regs (secondary) */
 +struct avalanche_ipace_regs         *avalanche_hw0_ipaceregs;
 +struct avalanche_channel_int_number *avalanche_hw0_chregs;  /* Channel control registers          */
 +
-+extern asmlinkage void mipsIRQ(void);
-+
-+#ifdef CONFIG_AR7_VLYNQ
-+#include <asm/ar7/vlynq.h>
-+extern VLYNQ_DEV vlynqDevice0, vlynqDevice1;
-+#endif
-+
-+/*
-+ *   The avalanche/MIPS interrupt line numbers are used to represent the
-+ *   interrupts within the irqaction arrays.  The index notation is
-+ *   is as follows:
-+ *
-+ *           0-7    MIPS CPU Exceptions  (HW/SW)
-+ *           8-47   Primary Interrupts   (Avalanche)
-+ *           48-79  Secondary Interrupts (Avalanche)
-+ *
-+ */
-+
-+
-+static struct irqaction *hw0_irq_action_primary[AVINTNUM(AVALANCHE_INT_END_PRIMARY)] =
-+{
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL
-+};
-+
-+static struct irqaction *hw0_irq_action_secondary[AVINTNUM(AVALANCHE_INT_END_SECONDARY)] =
-+{
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL,
-+	NULL, NULL, NULL, NULL
-+};
-+
 +/*
 +   This remaps interrupts to exist on other channels than the default
 +   channels.  essentially we can use the line # as the index for this
 +   array
 + */
 +
-+
 +static unsigned long line_to_channel[AVINTNUM(AVALANCHE_INT_END_PRIMARY)];
 +unsigned long uni_secondary_interrupt = 0;
 +
-+static struct irqaction r4ktimer_action = {
-+	NULL, 0, 0, "R4000 timer/counter", NULL, NULL,
-+};
-+
-+static struct irqaction *irq_action[8] = {
-+	NULL,              /* SW int 0 */
-+	NULL,              /* SW int 1 */
-+	NULL,              /* HW int 0 */
-+	NULL,
-+	NULL,
-+	NULL,              /* HW int 3 */
-+	NULL,              /* HW int 4 */
-+	&r4ktimer_action   /* HW int 5 */
-+};
-+
 +static void end_avalanche_irq(unsigned int irq)
 +{
-+	if (!(irq_desc_ti[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
++	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
 +		enable_avalanche_irq(irq);
 +}
 +
@@ -474,47 +498,9 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 +{
 +	unsigned long flags;
 +	unsigned long chan_nr=0;
-+	unsigned long int_bit=0;
-+
-+	if(irq_nr >= AVALANCHE_INT_END)
-+	{
-+		printk(KERN_ERR "%s: whee, invalid irq_nr %d\n",
-+		       __FUNCTION__, irq_nr);
-+		panic("IRQ, you lose...");
-+	}
 +
 +	save_and_cli(flags);
 +
-+
-+	if(irq_nr <  MIPS_EXCEPTION_OFFSET)
-+	{
-+		/* disable mips exception */
-+
-+		int_bit = read_c0_status() & ~(1 << (8+irq_nr));
-+		change_c0_status(ST0_IM,int_bit);
-+		restore_flags(flags);
-+		return;
-+	}
-+
-+#if defined (CONFIG_AR7_VLYNQ)
-+        /* Vlynq irq_nr are 72-145 in the system and are placed after
-+	 * the interrupts managed by the interrupt controller.
-+         */
-+        if(irq_nr >= AVALANCHE_INTC_END)
-+        {
-+            if(irq_nr >= AVALANCHE_INT_END_LOW_VLYNQ)
-+                /* Vlynq interrupts 32-63 */
-+                vlynq_interrupt_disable(&vlynqDevice1,VLYNQ_REMOTE_DVC,
-+					irq_nr-AVALANCHE_INT_END_LOW_VLYNQ);
-+            else
-+                /* Vlynq interupts 0-31 */
-+                vlynq_interrupt_disable(&vlynqDevice0,VLYNQ_REMOTE_DVC,
-+					irq_nr-AVALANCHE_INTC_END);
-+
-+            goto ret_from_disable_irq;
-+        }
-+#endif
-+
 +	/* irq_nr represents the line number for the interrupt.  We must
 +	 *  disable the channel number associated with that line number.
 +	 */
@@ -540,10 +526,6 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 +	else  /* secondary interrupt #'s 0-31 */
 +		avalanche_hw0_ecregs->exiecr = (1 << (chan_nr - AVINTNUM(AVALANCHE_INT_END_PRIMARY)));
 +
-+#if defined (CONFIG_AR7_VLYNQ)
-+ret_from_disable_irq:
-+#endif
-+
 +	restore_flags(flags);
 +}
 +
@@ -551,45 +533,9 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 +{
 +	unsigned long flags;
 +	unsigned long chan_nr=0;
-+	unsigned long int_bit=0;
-+
-+	if(irq_nr > AVALANCHE_INT_END) {
-+		printk(KERN_ERR "%s: whee, invalid irq_nr %d\n",
-+		       __FUNCTION__, irq_nr);
-+		panic("IRQ, you lose...");
-+	}
 +
 +	save_and_cli(flags);
 +
-+
-+	if(irq_nr <  MIPS_EXCEPTION_OFFSET)
-+	{
-+		/* Enable MIPS exceptions */
-+		int_bit = read_c0_status();
-+		change_c0_status(ST0_IM,int_bit | (1<<(8+irq_nr)));
-+		restore_flags(flags);
-+		return;
-+	}
-+
-+#if defined (CONFIG_AR7_VLYNQ)
-+        /* Vlynq irq_nr are 80-143 in the system and are placed after
-+	 * the interrupts managed by the interrupt controller.
-+         */
-+        if(irq_nr >= AVALANCHE_INTC_END)
-+        {
-+            if(irq_nr >= AVALANCHE_INT_END_LOW_VLYNQ)
-+                /* Vlynq interrupts 32-63 */
-+                vlynq_interrupt_enable(&vlynqDevice1,VLYNQ_REMOTE_DVC,
-+				       irq_nr-AVALANCHE_INT_END_LOW_VLYNQ);
-+            else
-+                /* Vlynq interupts 0-31 */
-+                vlynq_interrupt_enable(&vlynqDevice0,VLYNQ_REMOTE_DVC,
-+				       irq_nr-AVALANCHE_INTC_END);
-+
-+            goto ret_from_enable_irq;
-+        }
-+#endif
-+
 +	/* irq_nr represents the line number for the interrupt.  We must
 +	 *  disable the channel number associated with that line number.
 +	 */
@@ -613,10 +559,6 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 +	else    /* secondary interrupt #'s 0-31 */
 +		avalanche_hw0_ecregs->exiesr = (1 << (chan_nr - AVINTNUM(AVALANCHE_INT_END_PRIMARY)));
 +
-+#if defined (CONFIG_AR7_VLYNQ)
-+ret_from_enable_irq:
-+#endif
-+
 +	restore_flags(flags);
 +}
 +
@@ -626,146 +568,7 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 +	return 0; /* never anything pending */
 +}
 +
-+
-+int get_irq_list(char *buf)
-+{
-+	int i, len = 0;
-+	int num = 0;
-+	struct irqaction *action;
-+
-+	for (i = 0; i < MIPS_EXCEPTION_OFFSET; i++, num++)
-+	{
-+		action = irq_action[i];
-+		if (!action)
-+			continue;
-+		len += sprintf(buf+len, "%2d: %8d %c %s",
-+				num, kstat.irqs[0][num],
-+				(action->flags & SA_INTERRUPT) ? '+' : ' ',
-+				action->name);
-+		for (action=action->next; action; action = action->next) {
-+			len += sprintf(buf+len, ",%s %s",
-+					(action->flags & SA_INTERRUPT) ? " +" : "",
-+					action->name);
-+		}
-+		len += sprintf(buf+len, " [MIPS interrupt]\n");
-+	}
-+
-+
-+	for (i = 0; i < AVINTNUM(AVALANCHE_INT_END); i++,num++)
-+	{
-+		if(i < AVINTNUM(AVALANCHE_INT_END_PRIMARY))
-+			action = hw0_irq_action_primary[i];
-+		else
-+			action = hw0_irq_action_secondary[i-AVINTNUM(AVALANCHE_INT_END_PRIMARY)];
-+		if (!action)
-+			continue;
-+		len += sprintf(buf+len, "%2d: %8d %c %s",
-+				num, kstat.irqs[0][ LNXINTNUM(i) ],
-+				(action->flags & SA_INTERRUPT) ? '+' : ' ',
-+				action->name);
-+
-+		for (action=action->next; action; action = action->next)
-+		{
-+			len += sprintf(buf+len, ",%s %s",
-+					(action->flags & SA_INTERRUPT) ? " +" : "",
-+					action->name);
-+		}
-+
-+		if(i < AVINTNUM(AVALANCHE_INT_END_PRIMARY))
-+			len += sprintf(buf+len, " [hw0 (Avalanche Primary)]\n");
-+		else
-+			len += sprintf(buf+len, " [hw0 (Avalanche Secondary)]\n");
-+
-+	}
-+
-+	return len;
-+}
-+
-+int request_irq(unsigned int irq,
-+		void (*handler)(int, void *, struct pt_regs *),
-+		unsigned long irqflags,
-+		const char * devname,
-+		void *dev_id)
-+{
-+	struct irqaction *action;
-+
-+	if (irq >  AVALANCHE_INT_END)
-+		return -EINVAL;
-+	if (!handler)
-+		return -EINVAL;
-+
-+	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
-+	if(!action)
-+		return -ENOMEM;
-+
-+	action->handler = handler;
-+	action->flags = irqflags;
-+	action->mask = 0;
-+	action->name = devname;
-+	irq_desc_ti[irq].action = action;
-+	action->dev_id = dev_id;
-+
-+	action->next = 0;
-+
-+	if(irq <  MIPS_EXCEPTION_OFFSET)
-+	{
-+		irq_action[irq] = action;
-+		enable_avalanche_irq(irq);
-+		return 0;
-+	}
-+
-+	if(irq < AVALANCHE_INT_END_PRIMARY)
-+		hw0_irq_action_primary[line_to_channel[AVINTNUM(irq)]] = action;
-+	else
-+		hw0_irq_action_secondary[irq - AVALANCHE_INT_END_PRIMARY] = action;
-+
-+	enable_avalanche_irq(irq);
-+
-+	return 0;
-+}
-+
-+void free_irq(unsigned int irq, void *dev_id)
-+{
-+	struct irqaction *action;
-+
-+	if (irq > AVALANCHE_INT_END) {
-+		printk(KERN_ERR "Trying to free IRQ%d\n",irq);
-+		return;
-+	}
-+
-+	if(irq <  MIPS_EXCEPTION_OFFSET)
-+	{
-+		action = irq_action[irq];
-+		irq_action[irq] = NULL;
-+		irq_desc_ti[irq].action = NULL;
-+		disable_avalanche_irq(irq);
-+		kfree(action);
-+		return;
-+	}
-+
-+	if(irq < AVALANCHE_INT_END_PRIMARY) {
-+		action = hw0_irq_action_primary[line_to_channel[AVINTNUM(irq)]];
-+		hw0_irq_action_primary[line_to_channel[AVINTNUM(irq)]] = NULL;
-+		irq_desc_ti[irq].action = NULL;
-+	}
-+	else {
-+		action = hw0_irq_action_secondary[irq - AVALANCHE_INT_END_PRIMARY];
-+		hw0_irq_action_secondary[irq - AVALANCHE_INT_END_PRIMARY] = NULL;
-+		irq_desc_ti[irq].action = NULL;
-+	}
-+
-+	disable_avalanche_irq(irq);
-+	kfree(action);
-+}
-+
-+#ifdef CONFIG_KGDB
-+extern void breakpoint(void);
-+extern int remote_debug;
-+#endif
-+
-+
-+//void init_IRQ(void) __init;
-+void __init init_IRQ(void)
++void __init ar7_irq_init(int base)
 +{
 +	int i;
 +
@@ -787,63 +590,47 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 +
 +	// avalanche_hw0_ipaceregs->ipacep = (2*get_avalanche_vbus_freq()/1000000)*4;
 +	/* hack for speeding up the pacing. */
-+	printk(KERN_INFO "the pacing pre-scalar has been set as 600.\n");
++	printk("the pacing pre-scalar has been set as 600.\n");
 +	avalanche_hw0_ipaceregs->ipacep = 600;
 +	/* Channel to line mapping, Line to Channel mapping */
 +
 +	for(i = 0; i < 40; i++)
 +		avalanche_int_set(i,i);
 +
-+	/* Now safe to set the exception vector. */
-+	set_except_vector(0, mipsIRQ);
-+
-+	/* Setup the IRQ description array.  These will be mapped
-+	 *  as flat interrupts numbers.  The mapping is as follows
-+	 *
-+	 *           0-7    MIPS CPU Exceptions  (HW/SW)
-+	 *           8-46   Primary Interrupts   (Avalanche)
-+	 *           47-78  Secondary Interrupts (Avalanche)
-+	 */
-+
-+	for (i = 0; i <= AVALANCHE_INT_END; i++)
++	ar7_irq_base = base;
++	for (i = base; i <= base+40; i++)
 +	{
-+		irq_desc_ti[i].status	= IRQ_DISABLED;
-+		irq_desc_ti[i].action	= 0;
-+		irq_desc_ti[i].depth	= 1;
-+		irq_desc_ti[i].handler	= &avalanche_irq_type;
++		irq_desc[i].status	= IRQ_DISABLED;
++		irq_desc[i].action	= 0;
++		irq_desc[i].depth	= 1;
++		irq_desc[i].handler	= &avalanche_irq_type;
 +	}
 +
-+#ifdef CONFIG_KGDB
-+	if (remote_debug)
-+	{
-+		set_debug_traps();
-+		breakpoint();
-+	}
-+#endif
++	setup_irq(2, &ar7_hw0_action);
++	set_c0_status(IE_IRQ0);
++
++	return;
 +}
 +
-+void avalanche_hw0_irqdispatch(struct pt_regs *regs)
++void ar7_hw0_interrupt(int interrupt, void *dev, struct pt_regs *regs)
 +{
-+	struct irqaction *action;
-+	int irq, cpu = smp_processor_id();
-+	unsigned long int_line_number,status;
-+	int i,secondary = 0;
-+	int chan_nr=0;
++	int irq;
++	unsigned long int_line_number, status;
++	int i, chan_nr = 0;
 +
 +	int_line_number = ((avalanche_hw0_icregs->pintir >> 16) & 0x3F);
 +	chan_nr = ((avalanche_hw0_icregs->pintir) & 0x3F);
 +
-+
-+	if(chan_nr < 32)
++	if(chan_nr < 32) /* primary 0-31 */
 +	{
 +		if( chan_nr != uni_secondary_interrupt)
 +			avalanche_hw0_icregs->intcr1 = (1<<chan_nr);
 +
 +	}
 +
-+	if((chan_nr < 40) && (chan_nr > 31))
++	if((chan_nr < 40) && (chan_nr > 31)) /* primary 32-39 */
 +	{
-+		avalanche_hw0_icregs->intcr2 = (1<<(chan_nr-AVINTNUM(AVALANCHE_INT_END_SECONDARY)));
++		avalanche_hw0_icregs->intcr2 = (1<<(chan_nr-32));
 +	}
 +
 +
@@ -854,10 +641,10 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 +	if(chan_nr == 40)
 +		return;
 +
-+	if(chan_nr == uni_secondary_interrupt)
++	if(chan_nr == uni_secondary_interrupt) /* secondary 0-31 */
 +	{
 +		status = avalanche_hw0_ecregs->exsr;
-+		for(i=0; i < AVINTNUM(AVALANCHE_INT_END_SECONDARY); i++)
++		for(i=0; i < 32; i++)
 +		{
 +			if (status & 1<<i)
 +			{
@@ -866,8 +653,7 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 +				break;
 +			}
 +		}
-+		irq = i;
-+		secondary = 1;
++		irq = i+40;
 +
 +		/* clear the universal secondary interrupt */
 +		avalanche_hw0_icregs->intcr1 = 1 << uni_secondary_interrupt;
@@ -876,37 +662,7 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 +	else
 +		irq = chan_nr;
 +
-+	/* Suraj Add code to clear secondary interrupt */
-+
-+	if(secondary)
-+		action = hw0_irq_action_secondary[irq];
-+	else
-+		action = hw0_irq_action_primary[irq];
-+
-+	/* if action == NULL, then we don't have a handler for the irq */
-+
-+	if ( action == NULL ) {
-+		printk(KERN_ERR "No handler for hw0 irq: %i\n", irq);
-+		return;
-+	}
-+
-+	irq_enter(cpu,irq);
-+	if(secondary)
-+	{
-+		kstat.irqs[0][(irq + AVINTNUM(AVALANCHE_INT_END_PRIMARY)) + 8]++;
-+		action->handler((irq + AVALANCHE_INT_END_PRIMARY), action->dev_id, regs);
-+	}
-+	else
-+	{
-+		kstat.irqs[0][irq + 8]++;
-+		action->handler(LNXINTNUM(irq), action->dev_id, regs);
-+	}
-+
-+	irq_exit(cpu,irq);
-+
-+	if(softirq_pending(cpu))
-+		do_softirq();
-+
++	do_IRQ(irq + ar7_irq_base, regs);
 +	return;
 +}
 +
@@ -1035,7 +791,7 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 +			avalanche_hw0_chregs->cintnr39 = line;
 +			break;
 +		default:
-+			printk(KERN_ERR "Error: Unknown Avalanche interrupt channel\n");
++			printk("Error: Unknown Avalanche interrupt channel\n");
 +	}
 +
 +	line_to_channel[line] = channel; /* Suraj check */
@@ -1085,173 +841,10 @@ diff -urN linux.old/arch/mips/ar7/irq.c linux.dev/arch/mips/ar7/irq.c
 +
 +    return(0);
 +}
-+
-+/* Sets the trigger type: edge or level */
-+int avalanche_intr_type_set(unsigned int irq_nr, unsigned long type_val)
-+{
-+    unsigned long flags;
-+    unsigned long chan_nr=0;
-+
-+    printk(KERN_NOTICE "AVALANCHE_INT_END_PRIMARY %d\n",
-+	   AVALANCHE_INT_END_PRIMARY);
-+    printk(KERN_NOTICE "AVALANCHE_INT_END_SECONDARY %d\n",
-+	   AVALANCHE_INT_END_SECONDARY);
-+    printk(KERN_NOTICE "AVALANCHE_INT_END %d\n", AVALANCHE_INT_END);
-+    printk(KERN_NOTICE "AVALANCHE_INTC_END %d\n", AVALANCHE_INTC_END);
-+    if(irq_nr  <  MIPS_EXCEPTION_OFFSET ||
-+       irq_nr  >= AVALANCHE_INT_END)
-+    {
-+        printk(KERN_ERR "%s: whee, invalid irq_nr %d\n",
-+	       __FUNCTION__, irq_nr);
-+        panic("IRQ, you lose...");
-+        return(-1);
-+    }
-+
-+    if(type_val > 1)
-+    {
-+        printk(KERN_ERR "Not a valid polarity value.\n");
-+        return(-1);
-+    }
-+
-+#if defined (CONFIG_AR7_VLYNQ)
-+    /* Vlynq irq_nr are 80-143 in the system and are placed after the interrupts
-+     * managed by the interrupt controller.
-+     */
-+    if(irq_nr >= AVALANCHE_INTC_END)
-+    {
-+        /* Type values for VLYNQ are INTC are different. */
-+        if(irq_nr >= AVALANCHE_INT_END_LOW_VLYNQ)
-+            /* Vlynq interrupts 32-63 */
-+            vlynq_interrupt_set_type(&vlynqDevice1, VLYNQ_REMOTE_DVC,
-+                                     irq_nr - AVALANCHE_INT_END_LOW_VLYNQ, !type_val);
-+        else
-+            /* Vlynq interupts 0-31 */
-+            vlynq_interrupt_set_type(&vlynqDevice0, VLYNQ_REMOTE_DVC,
-+                                     irq_nr - AVALANCHE_INTC_END, !type_val);
-+
-+        goto ret_from_set_type;
-+    }
-+#endif
-+
-+    irq_nr = AVINTNUM(irq_nr);
-+
-+    chan_nr = line_to_channel[AVINTNUM(irq_nr)];
-+
-+    save_and_cli(flags);
-+
-+    /* primary interrupt #'s 0-31 */
-+    if(chan_nr < AVALANCHE_INT_END_PRIMARY_REG1)
-+    {
-+        if(type_val)
-+            avalanche_hw0_icregs->inttypr1 |=  (1 << chan_nr);
-+        else
-+            avalanche_hw0_icregs->inttypr1 &= ~(1 << chan_nr);
-+    }
-+    /* primary interrupt #'s 32 throuth 39 */
-+    else
-+    {
-+        if(type_val)
-+            avalanche_hw0_icregs->inttypr2 |=
-+                (1 << (chan_nr - AVALANCHE_INT_END_PRIMARY_REG1));
-+        else
-+            avalanche_hw0_icregs->inttypr2 &=
-+                ~(1 << (chan_nr - AVALANCHE_INT_END_PRIMARY_REG1));
-+    }
-+
-+    restore_flags(flags);
-+
-+#if defined (CONFIG_AR7_VLYNQ)
-+ret_from_set_type:
-+#endif
-+
-+    return(0);
-+}
-+
-+
-+int avalanche_intr_polarity_set(unsigned int irq_nr, unsigned long polarity_val)
-+{
-+    unsigned long flags;
-+    unsigned long chan_nr=0;
-+
-+    if(irq_nr  <  MIPS_EXCEPTION_OFFSET ||
-+       irq_nr  >= AVALANCHE_INT_END)
-+    {
-+        printk(KERN_ERR "%s: whee, invalid irq_nr %d\n",
-+	       __FUNCTION__, irq_nr);
-+#if defined (CONFIG_AR7_VLYNQ)
-+        printk(KERN_ERR "Not one of the primary or vlynq avalanche interrupts.\n");
-+#else
-+        printk(KERN_ERR "Not one of the primary avalanche interrupts\n");
-+#endif
-+        panic("IRQ, you lose...");
-+        return(-1);
-+    }
-+
-+    if(polarity_val > 1)
-+    {
-+        printk(KERN_ERR "Not a valid polarity value.\n");
-+        return(-1);
-+    }
-+
-+
-+#if defined (CONFIG_AR7_VLYNQ)
-+    /* Vlynq irq_nr are 80-143 in the system and are placed after the interrupts
-+     * managed by the interrupt controller.
-+     */
-+    if(irq_nr >= AVALANCHE_INTC_END)
-+    {
-+        if(irq_nr >= AVALANCHE_INT_END_LOW_VLYNQ)
-+            /* Vlynq interrupts 32-63 */
-+            vlynq_interrupt_set_polarity(&vlynqDevice1, VLYNQ_REMOTE_DVC,
-+                                         irq_nr - AVALANCHE_INT_END_LOW_VLYNQ, polarity_val);
-+        else
-+            /* Vlynq interupts 0-31 */
-+            vlynq_interrupt_set_polarity(&vlynqDevice0, VLYNQ_REMOTE_DVC,
-+                                         irq_nr - AVALANCHE_INTC_END, polarity_val);
-+        goto ret_from_set_polarity;
-+    }
-+#endif
-+
-+    irq_nr = AVINTNUM(irq_nr);
-+
-+    chan_nr = line_to_channel[irq_nr];
-+
-+    save_and_cli(flags);
-+
-+    /* primary interrupt #'s 0-31 */
-+    if(chan_nr < AVALANCHE_INT_END_PRIMARY_REG1)
-+    {
-+        if(polarity_val)
-+            avalanche_hw0_icregs->intpolr1 |=  (1 << chan_nr);
-+        else
-+            avalanche_hw0_icregs->intpolr1 &= ~(1 << chan_nr);
-+    }
-+    /* primary interrupt #'s 32 throuth 39 */
-+    else
-+    {
-+        if(polarity_val)
-+            avalanche_hw0_icregs->intpolr2 |=
-+                (1 << (chan_nr - AVALANCHE_INT_END_PRIMARY_REG1));
-+        else
-+            avalanche_hw0_icregs->intpolr2 &=
-+                ~(1 << (chan_nr - AVALANCHE_INT_END_PRIMARY_REG1));
-+    }
-+
-+    restore_flags(flags);
-+
-+#if defined (CONFIG_AR7_VLYNQ)
-+ret_from_set_polarity:
-+#endif
-+
-+    return(0);
-+}
-+
-+EXPORT_SYMBOL(avalanche_intr_polarity_set);
-+EXPORT_SYMBOL(avalanche_intr_type_set);
 diff -urN linux.old/arch/mips/ar7/memory.c linux.dev/arch/mips/ar7/memory.c
 --- linux.old/arch/mips/ar7/memory.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/memory.c	2005-10-21 16:45:42.090061750 +0200
-@@ -0,0 +1,131 @@
++++ linux.dev/arch/mips/ar7/memory.c	2005-11-10 01:14:16.372731750 +0100
+@@ -0,0 +1,103 @@
 +/*
 + * Carsten Langgaard, carstenl@mips.com
 + * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
@@ -1273,10 +866,8 @@ diff -urN linux.old/arch/mips/ar7/memory.c linux.dev/arch/mips/ar7/memory.c
 + *
 + * ########################################################################
 + *
-+ * PROM library functions for acquiring/using memory descriptors given to
-+ * us from the YAMON.
-+ *
 + */
++
 +#include <linux/config.h>
 +#include <linux/init.h>
 +#include <linux/mm.h>
@@ -1286,23 +877,16 @@ diff -urN linux.old/arch/mips/ar7/memory.c linux.dev/arch/mips/ar7/memory.c
 +#include <asm/page.h>
 +#include <asm/mips-boards/prom.h>
 +
-+enum yamon_memtypes {
-+	yamon_dontuse,
-+	yamon_prom,
-+	yamon_free,
-+};
-+struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
-+
-+/* References to section boundaries */
-+extern char _end;
-+
-+#define PFN_ALIGN(x)    (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
++extern char _ftext;
++extern int preserve_adam2;
 +
-+
-+struct prom_pmemblock * __init prom_getmdesc(void)
++void __init prom_meminit(void)
 +{
 +	char *memsize_str;
-+	unsigned int memsize;
++	unsigned long memsize, adam2size;
++
++	/* assume block before kernel is used by bootloader */
++	adam2size = __pa(&_ftext) - PHYS_OFFSET;
 +
 +	memsize_str = prom_getenv("memsize");
 +	if (!memsize_str) {
@@ -1311,206 +895,63 @@ diff -urN linux.old/arch/mips/ar7/memory.c linux.dev/arch/mips/ar7/memory.c
 +		memsize = simple_strtol(memsize_str, NULL, 0);
 +	}
 +
-+	memset(mdesc, 0, sizeof(mdesc));
-+
-+	mdesc[0].type = yamon_dontuse;
-+	mdesc[0].base = 0x00000000;
-+	mdesc[0].size = CONFIG_AR7_MEMORY;
-+
-+	mdesc[1].type = yamon_prom;
-+	mdesc[1].base = CONFIG_AR7_MEMORY;
-+	mdesc[1].size = 0x00020000;
-+
-+	mdesc[2].type = yamon_free;
-+	mdesc[2].base = CONFIG_AR7_MEMORY + 0x00020000;
-+	mdesc[2].size = (memsize + CONFIG_AR7_MEMORY) - mdesc[2].base;
-+
-+	return &mdesc[0];
-+}
-+
-+static int __init prom_memtype_classify (unsigned int type)
-+{
-+	switch (type) {
-+		case yamon_free:
-+			return BOOT_MEM_RAM;
-+		case yamon_prom:
-+			return BOOT_MEM_ROM_DATA;
-+		default:
-+			return BOOT_MEM_RESERVED;
-+	}
++#if 0
++	add_memory_region(0x00000000, PHYS_OFFSET, BOOT_MEM_RESERVED);
++#endif
++	add_memory_region(PHYS_OFFSET, adam2size, BOOT_MEM_ROM_DATA);
++	add_memory_region(PHYS_OFFSET+adam2size, memsize-adam2size,
++			  BOOT_MEM_RAM);
 +}
 +
-+void __init prom_meminit(void)
++unsigned long __init prom_free_prom_memory (void)
 +{
-+	struct prom_pmemblock *p;
-+
-+	p = prom_getmdesc();
++	int i;
++	unsigned long freed = 0;
++	unsigned long addr;
 +
-+	while (p->size) {
-+		long type;
-+		unsigned long base, size;
++	if (preserve_adam2) {
++		char *firstfree_str = prom_getenv("firstfreeaddress");
++		unsigned long firstfree = 0;
 +
-+		type = prom_memtype_classify (p->type);
-+		base = p->base;
-+		size = p->size;
++		if (firstfree_str)
++			firstfree = simple_strtol(firstfree_str, NULL, 0);
 +
-+		add_memory_region(base, size, type);
-+		p++;
++		if (firstfree && firstfree < (unsigned long)&_ftext) {
++			printk("Preserving ADAM2 memory.\n");
++		} else if (firstfree) {
++			printk("Can't preserve ADAM2 memory, "
++			       "firstfreeaddress = %08lx.\n", firstfree);
++			preserve_adam2 = 0;
++		} else {
++			printk("Can't preserve ADAM2 memory, "
++			       "firstfreeaddress unknown!\n");
++			preserve_adam2 = 0;
++		}
 +	}
-+}
 +
-+void __init prom_free_prom_memory (void)
-+{
-+#if 0
-+	int i;
-+	unsigned long freed = 0;
-+	unsigned long addr;
-+
-+	for (i = 0; i < boot_mem_map.nr_map; i++) {
-+		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
-+			continue;
++	if (!preserve_adam2) {
++		for (i = 0; i < boot_mem_map.nr_map; i++) {
++			if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
++				continue;
 +
-+		addr = boot_mem_map.map[i].addr;
-+		while (addr < boot_mem_map.map[i].addr
++			addr = boot_mem_map.map[i].addr;
++			while (addr < boot_mem_map.map[i].addr
 +				+ boot_mem_map.map[i].size) {
-+			ClearPageReserved(virt_to_page(__va(addr)));
-+			set_page_count(virt_to_page(__va(addr)), 1);
-+			free_page((unsigned long)__va(addr));
-+			addr += PAGE_SIZE;
-+			freed += PAGE_SIZE;
++				ClearPageReserved(virt_to_page(__va(addr)));
++				set_page_count(virt_to_page(__va(addr)), 1);
++				free_page((unsigned long)__va(addr));
++				addr += PAGE_SIZE;
++				freed += PAGE_SIZE;
++			}
 +		}
++		printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
 +	}
-+	printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
-+#endif
++	return freed >> PAGE_SHIFT;
 +}
-diff -urN linux.old/arch/mips/ar7/mipsIRQ.S linux.dev/arch/mips/ar7/mipsIRQ.S
---- linux.old/arch/mips/ar7/mipsIRQ.S	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/mipsIRQ.S	2005-10-21 16:45:42.118063500 +0200
-@@ -0,0 +1,120 @@
-+/*
-+ * Carsten Langgaard, carstenl@mips.com
-+ * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
-+ *
-+ * ########################################################################
-+ *
-+ *  This program is free software; you can distribute it and/or modify it
-+ *  under the terms of the GNU General Public License (Version 2) as
-+ *  published by the Free Software Foundation.
-+ *
-+ *  This program is distributed in the hope 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.,
-+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
-+ *
-+ * ########################################################################
-+ *
-+ * Interrupt exception dispatch code.
-+ *
-+ */
-+#include <linux/config.h>
-+
-+#include <asm/asm.h>
-+#include <asm/mipsregs.h>
-+#include <asm/regdef.h>
-+#include <asm/stackframe.h>
-+
-+/* A lot of complication here is taken away because:
-+ *
-+ * 1) We handle one interrupt and return, sitting in a loop and moving across
-+ *    all the pending IRQ bits in the cause register is _NOT_ the answer, the
-+ *    common case is one pending IRQ so optimize in that direction.
-+ *
-+ * 2) We need not check against bits in the status register IRQ mask, that
-+ *    would make this routine slow as hell.
-+ *
-+ * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in
-+ *    between like BSD spl() brain-damage.
-+ *
-+ * Furthermore, the IRQs on the MIPS board look basically (barring software
-+ * IRQs which we don't use at all and all external interrupt sources are
-+ * combined together on hardware interrupt 0 (MIPS IRQ 2)) like:
-+ *
-+ *	MIPS IRQ	Source
-+ *      --------        ------
-+ *             0	Software (ignored)
-+ *             1        Software (ignored)
-+ *             2        Combined hardware interrupt (hw0)
-+ *             3        Hardware (ignored)
-+ *             4        Hardware (ignored)
-+ *             5        Hardware (ignored)
-+ *             6        Hardware (ignored)
-+ *             7        R4k timer (what we use)
-+ *
-+ * Note: On the SEAD board thing are a little bit different.
-+ *       Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired
-+ *       wired to UART1.
-+ *
-+ * We handle the IRQ according to _our_ priority which is:
-+ *
-+ * Highest ----     R4k Timer
-+ * Lowest  ----     Combined hardware interrupt
-+ *
-+ * then we just return, if multiple IRQs are pending then we will just take
-+ * another exception, big deal.
-+ */
-+
-+.text
-+.set	noreorder
-+.set	noat
-+	.align	5
-+NESTED(mipsIRQ, PT_SIZE, sp)
-+	SAVE_ALL
-+	CLI
-+	.set	at
-+
-+	mfc0	s0, CP0_CAUSE		# get irq bits
-+
-+	/* First we check for r4k counter/timer IRQ. */
-+	andi	a0, s0, CAUSEF_IP7
-+	beq	a0, zero, 1f
-+	andi	a0, s0, CAUSEF_IP2	# delay slot, check hw0 interrupt
-+
-+	/* Wheee, a timer interrupt. */
-+	move	a0, sp
-+	jal	ar7_timer_interrupt
-+	nop
-+
-+	j	ret_from_irq
-+	nop
-+
-+	1:
-+	beq	a0, zero, 1f		# delay slot, check hw3 interrupt
-+	nop
-+
-+	/* Wheee, combined hardware level zero interrupt. */
-+	jal	avalanche_hw0_irqdispatch     
-+	move	a0, sp			# delay slot
-+
-+	j	ret_from_irq
-+	nop				# delay slot
-+
-+	1:
-+	/*
-+	 * Here by mistake?  This is possible, what can happen is that by the
-+	 * time we take the exception the IRQ pin goes low, so just leave if
-+	 * this is the case.
-+	 */
-+	move	a1,s0
-+	PRINT("Got interrupt: c0_cause = %08x\n")
-+	mfc0	a1, CP0_EPC
-+	PRINT("c0_epc = %08x\n")
-+
-+	j	ret_from_irq
-+	nop
-+END(mipsIRQ)
 diff -urN linux.old/arch/mips/ar7/misc.c linux.dev/arch/mips/ar7/misc.c
 --- linux.old/arch/mips/ar7/misc.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/misc.c	2005-10-21 16:45:42.122063750 +0200
-@@ -0,0 +1,319 @@
++++ linux.dev/arch/mips/ar7/misc.c	2005-11-10 01:12:43.946955500 +0100
+@@ -0,0 +1,322 @@
 +#include <asm/ar7/sangam.h>
 +#include <asm/ar7/avalanche_misc.h>
 +#include <linux/module.h>
@@ -1535,8 +976,10 @@ diff -urN linux.old/arch/mips/ar7/misc.c linux.dev/arch/mips/ar7/misc.c
 +
 +    if(module_reset_bit >= 64)
 +    {
-+        if(p_remote_vlynq_dev_reset_ctrl)
-+            return(p_remote_vlynq_dev_reset_ctrl(module_reset_bit - 64, reset_ctrl));
++        if(p_remote_vlynq_dev_reset_ctrl) {
++            p_remote_vlynq_dev_reset_ctrl(module_reset_bit - 64, reset_ctrl);
++	    return;
++	}
 +        else
 +            return;
 +    }
@@ -1545,6 +988,7 @@ diff -urN linux.old/arch/mips/ar7/misc.c linux.dev/arch/mips/ar7/misc.c
 +        *reset_reg |= 1 << module_reset_bit;
 +    else
 +        *reset_reg &= ~(1 << module_reset_bit);
++    return;
 +}
 +
 +AVALANCHE_RESET_CTRL_T avalanche_get_reset_status(unsigned int module_reset_bit)
@@ -1832,7 +1276,7 @@ diff -urN linux.old/arch/mips/ar7/misc.c linux.dev/arch/mips/ar7/misc.c
 +
 diff -urN linux.old/arch/mips/ar7/platform.h linux.dev/arch/mips/ar7/platform.h
 --- linux.old/arch/mips/ar7/platform.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/platform.h	2005-10-21 16:45:42.122063750 +0200
++++ linux.dev/arch/mips/ar7/platform.h	2005-11-10 01:10:45.799571750 +0100
 @@ -0,0 +1,65 @@
 +#ifndef _PLATFORM_H_
 +#define _PLATFORM_H_
@@ -1899,10 +1343,10 @@ diff -urN linux.old/arch/mips/ar7/platform.h linux.dev/arch/mips/ar7/platform.h
 +#endif
 +
 +#endif
-diff -urN linux.old/arch/mips/ar7/printf.c linux.dev/arch/mips/ar7/printf.c
---- linux.old/arch/mips/ar7/printf.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/printf.c	2005-10-21 16:45:42.122063750 +0200
-@@ -0,0 +1,53 @@
+diff -urN linux.old/arch/mips/ar7/promlib.c linux.dev/arch/mips/ar7/promlib.c
+--- linux.old/arch/mips/ar7/promlib.c	1970-01-01 01:00:00.000000000 +0100
++++ linux.dev/arch/mips/ar7/promlib.c	2005-11-10 01:14:16.372731750 +0100
+@@ -0,0 +1,48 @@
 +/*
 + * Carsten Langgaard, carstenl@mips.com
 + * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
@@ -1923,42 +1367,37 @@ diff -urN linux.old/arch/mips/ar7/printf.c linux.dev/arch/mips/ar7/printf.c
 + * Putting things on the screen/serial line using Adam2 facilities.
 + */
 +
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/serial_reg.h>
-+#include <linux/spinlock.h>
-+#include <asm/io.h>
-+#include <asm/serial.h>
++#include <linux/types.h>
 +#include <asm/addrspace.h>
 +
 +#define AVALANCHE_YAMON_FUNCTION_BASE (KSEG1ADDR(0x10000500))
-+#define AVALANCHE_YAMON_PROM_PRINT_COUNT_ADDR (AVALANCHE_YAMON_FUNCTION_BASE + 0x4)
-+
-+static char ppbuf[1024];
-+
-+void (*prom_print_str)(unsigned int out, char *s, int len);
++#define AVALANCHE_YAMON_PROM_PRINT_COUNT_ADDR \
++          (AVALANCHE_YAMON_FUNCTION_BASE + 1 * 0x4)
++#define AVALANCHE_YAMON_PROM_EXIT \
++          (AVALANCHE_YAMON_FUNCTION_BASE + 8 * 0x4)
 +
-+void prom_printf(char *fmt, ...) __init;
-+void prom_printf(char *fmt, ...)
++void prom_putchar(char c)
 +{
-+	va_list args;
-+	int len;
-+	prom_print_str = (void *)*(unsigned int *)AVALANCHE_YAMON_PROM_PRINT_COUNT_ADDR;
++ 	static char buf[1];
++	void (*prom_print_str)(unsigned int dummy, char *s, int len) =
++	  (void *)(*(uint32_t *)AVALANCHE_YAMON_PROM_PRINT_COUNT_ADDR);
 +
-+	va_start(args, fmt);
-+	vsprintf(ppbuf, fmt, args);
-+	len = strlen(ppbuf);
++	buf[0] = c;
++	prom_print_str(1, buf, 1);
++	return;
++}
 +
-+	prom_print_str(1, ppbuf, len);
++void adam2_exit(int retval)
++{
++	void (*yamon_exit)(int retval) =
++	  (void *)(*(uint32_t *)AVALANCHE_YAMON_PROM_EXIT);
 +
-+	va_end(args);
++	yamon_exit(retval);
 +	return;
-+
 +}
 diff -urN linux.old/arch/mips/ar7/psp_env.c linux.dev/arch/mips/ar7/psp_env.c
 --- linux.old/arch/mips/ar7/psp_env.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/psp_env.c	2005-10-21 16:45:42.122063750 +0200
++++ linux.dev/arch/mips/ar7/psp_env.c	2005-11-10 01:10:45.799571750 +0100
 @@ -0,0 +1,350 @@
 +#include <linux/config.h>
 +#include <linux/init.h>
@@ -2312,8 +1751,8 @@ diff -urN linux.old/arch/mips/ar7/psp_env.c linux.dev/arch/mips/ar7/psp_env.c
 +}
 diff -urN linux.old/arch/mips/ar7/reset.c linux.dev/arch/mips/ar7/reset.c
 --- linux.old/arch/mips/ar7/reset.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/reset.c	2005-10-21 16:45:42.122063750 +0200
-@@ -0,0 +1,56 @@
++++ linux.dev/arch/mips/ar7/reset.c	2005-11-10 01:14:16.372731750 +0100
+@@ -0,0 +1,98 @@
 +/*
 + * Carsten Langgaard, carstenl@mips.com
 + * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
@@ -2335,13 +1774,22 @@ diff -urN linux.old/arch/mips/ar7/reset.c linux.dev/arch/mips/ar7/reset.c
 + *
 + * ########################################################################
 + *
-+ * Reset the MIPS boards.
++ * Reset the AR7 boards.
 + *
 + */
-+#include <linux/config.h>
 +
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/types.h>
++
++#include <asm/mipsregs.h>
 +#include <asm/reboot.h>
-+#include <asm/mips-boards/generic.h>
++#include <asm/addrspace.h>
++
++int preserve_adam2 = 1;
++
++extern void adam2_exit(int retval);
 +
 +static void ar7_machine_restart(char *command);
 +static void ar7_machine_halt(void);
@@ -2349,7 +1797,7 @@ diff -urN linux.old/arch/mips/ar7/reset.c linux.dev/arch/mips/ar7/reset.c
 +
 +static void ar7_machine_restart(char *command)
 +{
-+	volatile unsigned int *softres_reg = (void *)(KSEG1ADDR(0x08611600 + 0x4));
++	volatile uint32_t *softres_reg = (void *)(KSEG1ADDR(0x08611600 + 0x4));
 +
 +	*softres_reg = 1;
 +}
@@ -2357,11 +1805,33 @@ diff -urN linux.old/arch/mips/ar7/reset.c linux.dev/arch/mips/ar7/reset.c
 +static void ar7_machine_halt(void)
 +{
 +
++	if (preserve_adam2) {
++		set_c0_status(ST0_BEV);
++		adam2_exit(0);
++	} else {
++		/* I'd like to have Alt-SysRq-b work in this state.
++		 * What's missing here? The timer interrupt is still running.
++		 * Why doesn't the UART work anymore? */
++		while(1) {
++		  __asm__(".set\tmips3\n\t"
++			  "wait\n\t"
++			  ".set\tmips0");
++		}
++	}
 +}
 +
 +static void ar7_machine_power_off(void)
 +{
++	volatile uint32_t *power_reg = (void *)(KSEG1ADDR(0x08610A00));
++	uint32_t power_state = *power_reg;
++
++	/* add something to turn LEDs off? */
 +
++	power_state &= ~(3 << 30);
++	power_state |=  (3 << 30); /* power down */
++	*power_reg = power_state;
++
++	printk("after power down?\n");
 +}
 +
 +void ar7_reboot_setup(void)
@@ -2370,10 +1840,21 @@ diff -urN linux.old/arch/mips/ar7/reset.c linux.dev/arch/mips/ar7/reset.c
 +	_machine_halt = ar7_machine_halt;
 +	_machine_power_off = ar7_machine_power_off;
 +}
++
++static int __init ar7_do_preserve_adam2(char *s)
++{
++	if (!strcmp(s, "no") || !strcmp(s, "0"))
++		preserve_adam2 = 0;
++	else
++	  	preserve_adam2 = 1;
++        return 1;
++}
++
++__setup("adam2=", ar7_do_preserve_adam2);
 diff -urN linux.old/arch/mips/ar7/setup.c linux.dev/arch/mips/ar7/setup.c
 --- linux.old/arch/mips/ar7/setup.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/setup.c	2005-10-21 16:45:42.122063750 +0200
-@@ -0,0 +1,120 @@
++++ linux.dev/arch/mips/ar7/setup.c	2005-11-10 01:12:43.946955500 +0100
+@@ -0,0 +1,143 @@
 +/*
 + * Carsten Langgaard, carstenl@mips.com
 + * Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
@@ -2391,33 +1872,58 @@ diff -urN linux.old/arch/mips/ar7/setup.c linux.dev/arch/mips/ar7/setup.c
 + *  with this program; if not, write to the Free Software Foundation, Inc.,
 + *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 + */
++
 +#include <linux/config.h>
 +#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/mc146818rtc.h>
-+#include <linux/ioport.h>
++#include <linux/string.h>
++#include <linux/irq.h>
 +
-+#include <asm/cpu.h>
-+#include <asm/bootinfo.h>
++#include <asm/processor.h>
 +#include <asm/irq.h>
-+#include <asm/mips-boards/generic.h>
-+#include <asm/mips-boards/prom.h>
-+
-+#include <asm/dma.h>
++#include <asm/irq_cpu.h>
 +#include <asm/time.h>
-+#include <asm/traps.h>
++#include <asm/mipsregs.h>
++#include <asm/mips-boards/prom.h>
 +
 +#ifdef CONFIG_KGDB
 +extern void rs_kgdb_hook(int);
++extern void breakpoint(void);
 +int remote_debug = 0;
 +#endif
 +
-+extern struct rtc_ops no_rtc_ops;
-+
 +extern void ar7_reboot_setup(void);
++extern void ar7_irq_init(int);
++extern asmlinkage void ar7IRQ(void);
++
++void ar7_time_init(void)
++{
++  /* XXX runtime */
++  mips_hpt_frequency = CONFIG_AR7_CPU * 500000;
++}
++
++void ar7_timer_setup(struct irqaction *irq)
++{
++  setup_irq(7, irq);
++  set_c0_status(IE_IRQ5);
++}
++
++void __init init_IRQ(void)
++{
++  init_generic_irq();
++  mips_cpu_irq_init(0);
++  ar7_irq_init(8);
++
++  /* Now safe to set the exception vector. */
++  set_except_vector(0, ar7IRQ);
 +
-+extern void ar7_time_init(void);
-+extern void ar7_timer_setup(struct irqaction *irq);
++#ifdef CONFIG_KGDB
++  if (remote_debug)
++  {
++    set_debug_traps();
++    breakpoint();
++  }
++#endif
++}
 +
 +const char *get_system_type(void)
 +{
@@ -2487,145 +1993,15 @@ diff -urN linux.old/arch/mips/ar7/setup.c linux.dev/arch/mips/ar7/setup.c
 +	if ((argptr = strstr(argptr, "nofpu")) != NULL)
 +		cpu_data[0].options &= ~MIPS_CPU_FPU;
 +
-+	rtc_ops = &no_rtc_ops;
-+
 +	ar7_reboot_setup();
 +
 +	board_time_init = ar7_time_init;
 +	board_timer_setup = ar7_timer_setup;
 +}
-diff -urN linux.old/arch/mips/ar7/time.c linux.dev/arch/mips/ar7/time.c
---- linux.old/arch/mips/ar7/time.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/time.c	2005-10-21 16:45:42.126064000 +0200
-@@ -0,0 +1,124 @@
-+/*
-+ * Carsten Langgaard, carstenl@mips.com
-+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
-+ *
-+ * ########################################################################
-+ *
-+ *  This program is free software; you can distribute it and/or modify it
-+ *  under the terms of the GNU General Public License (Version 2) as
-+ *  published by the Free Software Foundation.
-+ *
-+ *  This program is distributed in the hope 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.,
-+ *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
-+ *
-+ * ########################################################################
-+ *
-+ * Setting up the clock on the MIPS boards.
-+ *
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/sched.h>
-+#include <linux/spinlock.h>
-+
-+#include <asm/mipsregs.h>
-+#include <asm/ptrace.h>
-+#include <asm/hardirq.h>
-+#include <asm/div64.h>
-+
-+#include <linux/interrupt.h>
-+#include <linux/mc146818rtc.h>
-+#include <linux/timex.h>
-+
-+#include <asm/mips-boards/generic.h>
-+#include <asm/mips-boards/prom.h>
-+
-+extern asmlinkage void mipsIRQ(void);
-+
-+static unsigned long r4k_offset; /* Amount to increment compare reg each time */
-+static unsigned long r4k_cur;    /* What counter should be at next timer irq */
-+
-+#define MIPS_CPU_TIMER_IRQ 7
-+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
-+
-+static inline void ack_r4ktimer(unsigned long newval)
-+{
-+	write_c0_compare(newval);
-+}
-+
-+void ar7_timer_interrupt(struct pt_regs *regs)
-+{
-+	int cpu = smp_processor_id();
-+
-+	irq_enter(cpu, MIPS_CPU_TIMER_IRQ);
-+
-+	if (r4k_offset == 0)
-+		goto null;
-+
-+	do {
-+		kstat.irqs[cpu][MIPS_CPU_TIMER_IRQ]++;
-+		do_timer(regs);
-+		r4k_cur += r4k_offset;
-+		ack_r4ktimer(r4k_cur);
-+
-+	} while (((unsigned long)read_c0_count()
-+				- r4k_cur) < 0x7fffffff);
-+
-+	irq_exit(cpu, MIPS_CPU_TIMER_IRQ);
-+
-+	if (softirq_pending(cpu))
-+		do_softirq();
-+
-+	return;
-+
-+null:
-+	ack_r4ktimer(0);
-+}
-+
-+/*
-+ * Figure out the r4k offset, the amount to increment the compare
-+ * register for each time tick.
-+ */
-+static unsigned long __init cal_r4koff(void)
-+{
-+	return ((CONFIG_AR7_CPU*500000)/HZ);
-+}
-+
-+void __init ar7_time_init(void)
-+{
-+	unsigned long flags;
-+	unsigned int est_freq; 
-+
-+	set_except_vector(0, mipsIRQ);
-+	write_c0_count(0);
-+
-+	printk("calculating r4koff... ");
-+	r4k_offset = cal_r4koff();
-+	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
-+
-+	est_freq = 2*r4k_offset*HZ;
-+	est_freq += 5000;    /* round */
-+	est_freq -= est_freq%10000;
-+	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
-+			(est_freq%1000000)*100/1000000);
-+}
-+
-+void __init ar7_timer_setup(struct irqaction *irq)
-+{
-+	/* we are using the cpu counter for timer interrupts */
-+	irq->handler = no_action;     /* we use our own handler */
-+	setup_irq(MIPS_CPU_TIMER_IRQ, irq);
-+
-+	r4k_cur = (read_c0_count() + r4k_offset);
-+	write_c0_compare(r4k_cur);
-+	set_c0_status(ALLINTS);
-+}
 diff -urN linux.old/arch/mips/ar7/tnetd73xx_misc.c linux.dev/arch/mips/ar7/tnetd73xx_misc.c
 --- linux.old/arch/mips/ar7/tnetd73xx_misc.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/arch/mips/ar7/tnetd73xx_misc.c	2005-10-21 16:45:42.126064000 +0200
-@@ -0,0 +1,924 @@
++++ linux.dev/arch/mips/ar7/tnetd73xx_misc.c	2005-11-10 01:12:43.946955500 +0100
+@@ -0,0 +1,921 @@
 +/******************************************************************************
 + * FILE PURPOSE:    TNETD73xx Misc modules API Source
 + ******************************************************************************
@@ -2642,9 +2018,6 @@ diff -urN linux.old/arch/mips/ar7/tnetd73xx_misc.c linux.dev/arch/mips/ar7/tnetd
 + * (C) Copyright 2002, Texas Instruments, Inc
 + *******************************************************************************/
 +
-+#define LITTLE_ENDIAN
-+#define _LINK_KSEG0_
-+
 +#include <linux/types.h>
 +#include <asm/ar7/tnetd73xx.h>
 +#include <asm/ar7/tnetd73xx_misc.h>
@@ -3552,7 +2925,7 @@ diff -urN linux.old/arch/mips/ar7/tnetd73xx_misc.c linux.dev/arch/mips/ar7/tnetd
 +
 diff -urN linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared.in
 --- linux.old/arch/mips/config-shared.in	2005-10-21 16:43:18.917114000 +0200
-+++ linux.dev/arch/mips/config-shared.in	2005-10-21 16:45:42.126064000 +0200
++++ linux.dev/arch/mips/config-shared.in	2005-11-10 01:12:43.950955750 +0100
 @@ -20,6 +20,16 @@
  mainmenu_option next_comment
  comment 'Machine selection'
@@ -3570,18 +2943,19 @@ diff -urN linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared
  dep_bool 'Support for Alchemy Bosporus board' CONFIG_MIPS_BOSPORUS $CONFIG_MIPS32
  dep_bool 'Support for FIC Multimedia Player board' CONFIG_MIPS_FICMMP $CONFIG_MIPS32
  dep_bool 'Support for Alchemy Mirage board' CONFIG_MIPS_MIRAGE $CONFIG_MIPS32
-@@ -239,6 +249,10 @@
+@@ -239,6 +249,11 @@
     define_bool CONFIG_NONCOHERENT_IO y
     define_bool CONFIG_PC_KEYB y
  fi
 +if [ "$CONFIG_AR7" = "y" ]; then
++   define_bool CONFIG_IRQ_CPU y
 +   define_bool CONFIG_NONCOHERENT_IO y
 +   define_bool CONFIG_SWAP_IO_SPACE y
 +fi
  if [ "$CONFIG_CASIO_E55" = "y" ]; then
     define_bool CONFIG_IRQ_CPU y
     define_bool CONFIG_NONCOHERENT_IO y
-@@ -736,6 +750,7 @@
+@@ -736,6 +751,7 @@
  mainmenu_option next_comment
  comment 'General setup'
  if [ "$CONFIG_ACER_PICA_61" = "y" -o \
@@ -3589,7 +2963,7 @@ diff -urN linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared
       "$CONFIG_CASIO_E55" = "y" -o \
       "$CONFIG_DDB5074" = "y" -o \
       "$CONFIG_DDB5476" = "y" -o \
-@@ -797,6 +812,7 @@
+@@ -797,6 +813,7 @@
  bool 'Networking support' CONFIG_NET
  
  if [ "$CONFIG_ACER_PICA_61" = "y" -o \
@@ -3599,7 +2973,7 @@ diff -urN linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared
       "$CONFIG_IBM_WORKPAD" = "y" -o \
 diff -urN linux.old/arch/mips/kernel/head.S linux.dev/arch/mips/kernel/head.S
 --- linux.old/arch/mips/kernel/head.S	2005-10-21 16:43:16.396956500 +0200
-+++ linux.dev/arch/mips/kernel/head.S	2005-10-21 16:45:42.126064000 +0200
++++ linux.dev/arch/mips/kernel/head.S	2005-11-10 01:10:45.807572250 +0100
 @@ -75,11 +75,11 @@
  		 * size!
  		 */
@@ -3617,60 +2991,9 @@ diff -urN linux.old/arch/mips/kernel/head.S linux.dev/arch/mips/kernel/head.S
  		END(except_vec4)
  
  		/*
-diff -urN linux.old/arch/mips/kernel/irq.c linux.dev/arch/mips/kernel/irq.c
---- linux.old/arch/mips/kernel/irq.c	2004-02-18 14:36:30.000000000 +0100
-+++ linux.dev/arch/mips/kernel/irq.c	2005-10-21 16:45:42.130064250 +0200
-@@ -76,6 +76,7 @@
-  * Generic, controller-independent functions:
-  */
- 
-+#ifndef CONFIG_AR7
- int get_irq_list(char *buf)
- {
- 	int i, j;
-@@ -110,6 +111,7 @@
- 	p += sprintf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
- 	return p - buf;
- }
-+#endif
- 
- #ifdef CONFIG_SMP
- int global_irq_holder = NO_PROC_ID;
-@@ -525,6 +527,7 @@
-  *
-  */
- 
-+#ifndef CONFIG_AR7
- int request_irq(unsigned int irq,
- 		void (*handler)(int, void *, struct pt_regs *),
- 		unsigned long irqflags,
-@@ -569,6 +572,7 @@
- 		kfree(action);
- 	return retval;
- }
-+#endif
- 
- /**
-  *	free_irq - free an interrupt
-@@ -588,6 +592,7 @@
-  *	      the machine.
-  */
- 
-+#ifndef CONFIG_AR7
- void free_irq(unsigned int irq, void *dev_id)
- {
- 	irq_desc_t *desc;
-@@ -629,6 +634,7 @@
- 		return;
- 	}
- }
-+#endif
- 
- /*
-  * IRQ autodetection code..
 diff -urN linux.old/arch/mips/kernel/mips_ksyms.c linux.dev/arch/mips/kernel/mips_ksyms.c
 --- linux.old/arch/mips/kernel/mips_ksyms.c	2004-02-18 14:36:30.000000000 +0100
-+++ linux.dev/arch/mips/kernel/mips_ksyms.c	2005-10-21 17:02:14.507635750 +0200
++++ linux.dev/arch/mips/kernel/mips_ksyms.c	2005-11-10 01:10:45.811572500 +0100
 @@ -40,6 +40,12 @@
  extern long __strnlen_user_nocheck_asm(const char *s);
  extern long __strnlen_user_asm(const char *s);
@@ -3697,33 +3020,84 @@ diff -urN linux.old/arch/mips/kernel/mips_ksyms.c linux.dev/arch/mips/kernel/mip
 +
 diff -urN linux.old/arch/mips/kernel/setup.c linux.dev/arch/mips/kernel/setup.c
 --- linux.old/arch/mips/kernel/setup.c	2005-10-21 16:43:16.396956500 +0200
-+++ linux.dev/arch/mips/kernel/setup.c	2005-10-21 16:45:42.130064250 +0200
-@@ -235,7 +235,11 @@
- #define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
- #define PFN_PHYS(x)	((x) << PAGE_SHIFT)
++++ linux.dev/arch/mips/kernel/setup.c	2005-11-10 01:14:16.376732000 +0100
+@@ -38,6 +38,7 @@
+ #include <asm/io.h>
+ #include <asm/ptrace.h>
+ #include <asm/system.h>
++#include <asm/addrspace.h>
  
-+#ifdef CONFIG_AR7
-+#define MAXMEM		HIGHMEM_START + CONFIG_AR7_MEMORY
-+#else
- #define MAXMEM		HIGHMEM_START
-+#endif
- #define MAXMEM_PFN	PFN_DOWN(MAXMEM)
+ struct cpuinfo_mips cpu_data[NR_CPUS];
+ EXPORT_SYMBOL(cpu_data);
+@@ -88,7 +89,7 @@
+ struct boot_mem_map boot_mem_map;
+ 
+ unsigned char aux_device_present;
+-extern char _ftext, _etext, _fdata, _edata, _end;
++extern char _ftext, _etext, _fdata, _edata, _fbss, _end;
+ 
+ static char command_line[CL_SIZE];
+        char saved_command_line[CL_SIZE];
+@@ -116,6 +117,7 @@
+ 
+ static struct resource code_resource = { "Kernel code" };
+ static struct resource data_resource = { "Kernel data" };
++static struct resource  bss_resource = { "Kernel bss" };
+ 
+ asmlinkage void __init
+ init_arch(int argc, char **argv, char **envp, int *prom_vec)
+@@ -272,7 +274,7 @@
+ 	for (i = 0; i < boot_mem_map.nr_map; i++) {
+ 		unsigned long start, end;
  
- static inline void bootmem_init(void)
-@@ -320,7 +324,12 @@
+-		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
++		if (boot_mem_map.map[i].type == BOOT_MEM_RESERVED)
+ 			continue;
+ 
+ 		start = PFN_UP(boot_mem_map.map[i].addr);
+@@ -320,7 +322,8 @@
  #endif
  
  	/* Initialize the boot-time allocator with low memory only.  */
-+#ifdef CONFIG_AR7
-+	bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
-+			CONFIG_AR7_MEMORY >> PAGE_SHIFT, max_low_pfn);
-+#else
- 	bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn);
-+#endif
+-	bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn);
++	bootmap_size = init_bootmem_node(NODE_DATA(0), first_usable_pfn,
++					 PFN_UP(PHYS_OFFSET), max_low_pfn);
  
  	/*
  	 * Register fully available low RAM pages with the bootmem allocator.
-@@ -494,6 +503,7 @@
+@@ -371,11 +374,12 @@
+ 			continue;
+ 
+ 		/* Register lowmem ranges */
+-		free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
++		free_bootmem_node(NODE_DATA(0), PFN_PHYS(curr_pfn),
++				  size<<PAGE_SHIFT);
+ 	}
+ 
+ 	/* Reserve the bootmap memory.  */
+-	reserve_bootmem(PFN_PHYS(first_usable_pfn), bootmap_size);
++	reserve_bootmem_node(NODE_DATA(0), PFN_PHYS(first_usable_pfn), bootmap_size);
+ 
+ #ifdef CONFIG_BLK_DEV_INITRD
+ 	/* Board specific code should have set up initrd_start and initrd_end */
+@@ -409,6 +413,8 @@
+ 	code_resource.end = virt_to_bus(&_etext) - 1;
+ 	data_resource.start = virt_to_bus(&_fdata);
+ 	data_resource.end = virt_to_bus(&_edata) - 1;
++	bss_resource.start = virt_to_bus(&_fbss);
++	bss_resource.end = virt_to_bus(&_end) - 1;
+ 
+ 	/*
+ 	 * Request address space for all standard RAM.
+@@ -448,6 +454,7 @@
+ 		 */
+ 		request_resource(res, &code_resource);
+ 		request_resource(res, &data_resource);
++		request_resource(res, &bss_resource);
+ 	}
+ }
+ 
+@@ -494,6 +501,7 @@
  	void hp_setup(void);
  	void au1x00_setup(void);
  	void frame_info_init(void);
@@ -3731,7 +3105,7 @@ diff -urN linux.old/arch/mips/kernel/setup.c linux.dev/arch/mips/kernel/setup.c
  
  	frame_info_init();
  #if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
-@@ -691,6 +701,11 @@
+@@ -691,6 +699,11 @@
                  pmc_yosemite_setup();
                  break;
  #endif
@@ -3743,117 +3117,136 @@ diff -urN linux.old/arch/mips/kernel/setup.c linux.dev/arch/mips/kernel/setup.c
  	default:
  		panic("Unsupported architecture");
  	}
+diff -urN linux.old/arch/mips/kernel/time.c linux.dev/arch/mips/kernel/time.c
+--- linux.old/arch/mips/kernel/time.c	2005-01-19 15:09:29.000000000 +0100
++++ linux.dev/arch/mips/kernel/time.c	2005-11-10 01:12:43.950955750 +0100
+@@ -143,7 +143,6 @@
+ 	expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy;
+ 	write_c0_count(expirelo - cycles_per_jiffy);
+ 	write_c0_compare(expirelo);
+-	write_c0_count(count);
+ }
+ 
+ int (*mips_timer_state)(void);
 diff -urN linux.old/arch/mips/kernel/traps.c linux.dev/arch/mips/kernel/traps.c
 --- linux.old/arch/mips/kernel/traps.c	2005-10-21 16:43:16.400956750 +0200
-+++ linux.dev/arch/mips/kernel/traps.c	2005-10-21 16:45:42.130064250 +0200
-@@ -869,9 +869,15 @@
++++ linux.dev/arch/mips/kernel/traps.c	2005-11-10 01:13:28.301727500 +0100
+@@ -869,9 +869,24 @@
  
  	exception_handlers[n] = handler;
  	if (n == 0 && cpu_has_divec) {
-+#ifdef CONFIG_AR7
-+		*(volatile u32 *)(KSEG0+0x200+CONFIG_AR7_MEMORY) = 0x08000000 |
-+		                                 (0x03ffffff & (handler >> 2));
-+		flush_icache_range(KSEG0+0x200+CONFIG_AR7_MEMORY, KSEG0 + 0x204 + CONFIG_AR7_MEMORY);
-+#else
++	  printk(KERN_DEBUG "%s: using long jump via k0 to reach %08x\n",
++		 __FUNCTION__, handler);
++	  /* where does the 8 byte limit mentioned in head.S come from??? */
++	  if (handler > 0x0fffffff) { /* maximum for single J instruction */
++	    /* lui k0, 0x0000 */
++	    *(volatile u32 *)(KSEG0+0x200) = 0x3c1a0000 | (handler >> 16);
++	    /* ori k0, 0x0000 */
++	    *(volatile u32 *)(KSEG0+0x204) = 0x375a0000 | (handler & 0xffff);
++	    /* jr k0 */
++	    *(volatile u32 *)(KSEG0+0x208) = 0x03400008;
++	    /* nop */
++	    *(volatile u32 *)(KSEG0+0x20C) = 0x00000000;
++    	    flush_icache_range(KSEG0+0x200, KSEG0+0x210);
++	  } else {
  		*(volatile u32 *)(KSEG0+0x200) = 0x08000000 |
  		                                 (0x03ffffff & (handler >> 2));
- 		flush_icache_range(KSEG0+0x200, KSEG0 + 0x204);
-+#endif
+-		flush_icache_range(KSEG0+0x200, KSEG0 + 0x204);
++		flush_icache_range(KSEG0+0x200, KSEG0+0x204);
++	  }
  	}
  	return (void *)old_handler;
  }
-@@ -1022,6 +1028,12 @@
- 
- 	if (board_nmi_handler_setup)
- 		board_nmi_handler_setup();
-+#ifdef CONFIG_AR7
-+	memcpy((void *)(KSEG0 + CONFIG_AR7_MEMORY + 0x80), &except_vec1_generic, 0x80);
-+	memcpy((void *)(KSEG0 + CONFIG_AR7_MEMORY + 0x180), &except_vec3_generic, 0x80);
-+	memcpy((void *)(KSEG0 + CONFIG_AR7_MEMORY + 0x200), &except_vec4, 8);
-+	flush_icache_range(KSEG0 + CONFIG_AR7_MEMORY, KSEG0 + CONFIG_AR7_MEMORY + 0x208);
-+#endif
- 
- 	flush_icache_range(KSEG0, KSEG0 + 0x400);
+diff -urN linux.old/arch/mips/mm/init.c linux.dev/arch/mips/mm/init.c
+--- linux.old/arch/mips/mm/init.c	2004-02-18 14:36:30.000000000 +0100
++++ linux.dev/arch/mips/mm/init.c	2005-11-10 01:14:16.376732000 +0100
+@@ -235,10 +235,13 @@
+ #endif
+ }
  
-diff -urN linux.old/arch/mips/lib/promlib.c linux.dev/arch/mips/lib/promlib.c
---- linux.old/arch/mips/lib/promlib.c	2003-08-25 13:44:40.000000000 +0200
-+++ linux.dev/arch/mips/lib/promlib.c	2005-10-21 16:45:42.130064250 +0200
-@@ -1,6 +1,8 @@
- #include <stdarg.h>
- #include <linux/kernel.h>
-+#include <linux/config.h>
++#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT)
++#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn)
++
+ void __init paging_init(void)
+ {
+ 	unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+-	unsigned long max_dma, high, low;
++	unsigned long max_dma, high, low, start;
  
-+#ifndef CONFIG_AR7
- extern void prom_putchar(char);
+ 	pagetable_init();
  
- void prom_printf(char *fmt, ...)
-@@ -22,3 +24,4 @@
- 	}
- 	va_end(args);
- }
-+#endif
-diff -urN linux.old/arch/mips/mm/init.c linux.dev/arch/mips/mm/init.c
---- linux.old/arch/mips/mm/init.c	2004-02-18 14:36:30.000000000 +0100
-+++ linux.dev/arch/mips/mm/init.c	2005-10-21 16:45:42.134064500 +0200
-@@ -248,6 +248,9 @@
+@@ -247,7 +250,8 @@
+ #endif
  
  	max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
- 	low = max_low_pfn;
-+#ifdef CONFIG_AR7
-+	low = NODE_DATA(0)->bdata->node_low_pfn - (CONFIG_AR7_MEMORY >> PAGE_SHIFT);
-+#endif
+-	low = max_low_pfn;
++	start = START_PFN;
++	low = MAX_LOW_PFN - start;
  	high = highend_pfn;
  
  #ifdef CONFIG_ISA
-@@ -270,7 +273,11 @@
+@@ -270,7 +274,8 @@
  		zones_size[ZONE_HIGHMEM] = high - low;
  #endif
  
-+#ifdef CONFIG_AR7
-+	free_area_init_node(0, NODE_DATA(0), 0, zones_size, CONFIG_AR7_MEMORY, 0);
-+#else
- 	free_area_init(zones_size);
-+#endif
+-	free_area_init(zones_size);
++	free_area_init_node(0, NODE_DATA(0), 0, zones_size,
++			    start << PAGE_SHIFT, 0);
  }
  
  #define PFN_UP(x)	(((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
-@@ -298,6 +305,10 @@
- 	return 0;
- }
+@@ -283,7 +288,7 @@
+ 	for (i = 0; i < boot_mem_map.nr_map; i++) {
+ 		unsigned long addr, end;
  
-+#ifdef CONFIG_AR7
-+#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT)
-+#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn)
-+#endif
- void __init mem_init(void)
- {
- 	unsigned long codesize, reservedpages, datasize, initsize;
-@@ -315,9 +326,21 @@
+-		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
++		if (boot_mem_map.map[i].type == BOOT_MEM_RESERVED)
+ 			/* not usable memory */
+ 			continue;
+ 
+@@ -313,16 +318,17 @@
+ 	max_mapnr = num_physpages = highend_pfn;
+ 	num_mappedpages = max_low_pfn;
  #else
- 	max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
+-	max_mapnr = num_mappedpages = num_physpages = max_low_pfn;
++	max_mapnr = num_mappedpages = num_physpages = MAX_LOW_PFN - START_PFN;
  #endif
+-	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
+-
+-	totalram_pages += free_all_bootmem();
 +	
-+#ifdef CONFIG_AR7
-+	max_mapnr = num_mappedpages = num_physpages = MAX_LOW_PFN - START_PFN;
 +	high_memory = (void *) __va(MAX_LOW_PFN * PAGE_SIZE);
 +	
-+#if 0
-+	/* WTF? */
-+	free_bootmem_node(NODE_DATA(0), (CONFIG_AR7_MEMORY+PAGE_SIZE), (__pa(&_ftext))-(CONFIG_AR7_MEMORY+PAGE_SIZE));
-+#endif
 +	totalram_pages += free_all_bootmem_node(NODE_DATA(0));
-+#else
- 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
--
- 	totalram_pages += free_all_bootmem();
-+#endif
-+
  	totalram_pages -= setup_zero_pages();	/* Setup zeroed pages.  */
  
  	reservedpages = ram = 0;
+-	for (tmp = 0; tmp < max_low_pfn; tmp++)
+-		if (page_is_ram(tmp)) {
++	for (tmp = 0; tmp < max_mapnr; tmp++)
++		if (page_is_ram(START_PFN + tmp)) {
+ 			ram++;
+ 			if (PageReserved(mem_map+tmp))
+ 				reservedpages++;
+@@ -377,13 +383,13 @@
+ #endif
+ 
+ extern char __init_begin, __init_end;
+-extern void prom_free_prom_memory(void) __init;
++extern unsigned long prom_free_prom_memory(void) __init;
+ 
+ void free_initmem(void)
+ {
+ 	unsigned long addr;
+ 
+-	prom_free_prom_memory ();
++	totalram_pages += prom_free_prom_memory ();
+ 
+ 	addr = (unsigned long) &__init_begin;
+ 	while (addr < (unsigned long) &__init_end) {
 diff -urN linux.old/drivers/char/Config.in linux.dev/drivers/char/Config.in
 --- linux.old/drivers/char/Config.in	2005-10-21 16:43:16.440959250 +0200
-+++ linux.dev/drivers/char/Config.in	2005-10-21 17:02:20.199991500 +0200
++++ linux.dev/drivers/char/Config.in	2005-11-10 01:10:45.843574500 +0100
 @@ -188,6 +188,14 @@
     tristate 'Total Impact briQ front panel driver' CONFIG_BRIQ_PANEL
  fi
@@ -3871,7 +3264,7 @@ diff -urN linux.old/drivers/char/Config.in linux.dev/drivers/char/Config.in
  mainmenu_option next_comment
 diff -urN linux.old/drivers/char/Config.in.orig linux.dev/drivers/char/Config.in.orig
 --- linux.old/drivers/char/Config.in.orig	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/drivers/char/Config.in.orig	2005-10-21 16:45:47.854422000 +0200
++++ linux.dev/drivers/char/Config.in.orig	2005-11-10 01:10:45.863575750 +0100
 @@ -0,0 +1,414 @@
 +#
 +# Character device configuration
@@ -4289,7 +3682,7 @@ diff -urN linux.old/drivers/char/Config.in.orig linux.dev/drivers/char/Config.in
 +endmenu
 diff -urN linux.old/drivers/char/Makefile linux.dev/drivers/char/Makefile
 --- linux.old/drivers/char/Makefile	2005-10-21 16:43:16.460960500 +0200
-+++ linux.dev/drivers/char/Makefile	2005-10-21 17:02:20.199991500 +0200
++++ linux.dev/drivers/char/Makefile	2005-11-10 01:10:45.871576250 +0100
 @@ -240,6 +240,13 @@
  obj-y += joystick/js.o
  endif
@@ -4318,7 +3711,7 @@ diff -urN linux.old/drivers/char/Makefile linux.dev/drivers/char/Makefile
  fastdep:
 diff -urN linux.old/drivers/char/Makefile.orig linux.dev/drivers/char/Makefile.orig
 --- linux.old/drivers/char/Makefile.orig	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/drivers/char/Makefile.orig	2005-10-21 16:54:20.566016250 +0200
++++ linux.dev/drivers/char/Makefile.orig	2005-11-10 01:10:45.871576250 +0100
 @@ -0,0 +1,374 @@
 +#
 +# Makefile for the kernel character device drivers.
@@ -4696,7 +4089,7 @@ diff -urN linux.old/drivers/char/Makefile.orig linux.dev/drivers/char/Makefile.o
 +	set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
 diff -urN linux.old/drivers/char/avalanche_vlynq/Makefile linux.dev/drivers/char/avalanche_vlynq/Makefile
 --- linux.old/drivers/char/avalanche_vlynq/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/drivers/char/avalanche_vlynq/Makefile	2005-10-21 17:02:20.195991250 +0200
++++ linux.dev/drivers/char/avalanche_vlynq/Makefile	2005-11-10 01:10:45.871576250 +0100
 @@ -0,0 +1,16 @@
 +#
 +# Makefile for the linux kernel.
@@ -4716,7 +4109,7 @@ diff -urN linux.old/drivers/char/avalanche_vlynq/Makefile linux.dev/drivers/char
 +include $(TOPDIR)/Rules.make
 diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_board.c linux.dev/drivers/char/avalanche_vlynq/vlynq_board.c
 --- linux.old/drivers/char/avalanche_vlynq/vlynq_board.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/drivers/char/avalanche_vlynq/vlynq_board.c	2005-10-21 17:02:20.195991250 +0200
++++ linux.dev/drivers/char/avalanche_vlynq/vlynq_board.c	2005-11-10 01:10:45.871576250 +0100
 @@ -0,0 +1,184 @@
 +/*
 + * Jeff Harrell, jharrell@ti.com
@@ -4904,7 +4297,7 @@ diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_board.c linux.dev/drivers
 +
 diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_drv.c linux.dev/drivers/char/avalanche_vlynq/vlynq_drv.c
 --- linux.old/drivers/char/avalanche_vlynq/vlynq_drv.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/drivers/char/avalanche_vlynq/vlynq_drv.c	2005-10-21 17:02:20.199991500 +0200
++++ linux.dev/drivers/char/avalanche_vlynq/vlynq_drv.c	2005-11-10 01:10:45.891577500 +0100
 @@ -0,0 +1,243 @@
 +/******************************************************************************
 + * FILE PURPOSE:    Vlynq Linux Device Driver Source
@@ -5151,7 +4544,7 @@ diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_drv.c linux.dev/drivers/c
 +
 diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_hal.c linux.dev/drivers/char/avalanche_vlynq/vlynq_hal.c
 --- linux.old/drivers/char/avalanche_vlynq/vlynq_hal.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/drivers/char/avalanche_vlynq/vlynq_hal.c	2005-10-21 16:45:47.838421000 +0200
++++ linux.dev/drivers/char/avalanche_vlynq/vlynq_hal.c	2005-11-10 01:10:45.975582750 +0100
 @@ -0,0 +1,1214 @@
 +/***************************************************************************
 +**+----------------------------------------------------------------------+**
@@ -6369,7 +5762,7 @@ diff -urN linux.old/drivers/char/avalanche_vlynq/vlynq_hal.c linux.dev/drivers/c
 +
 diff -urN linux.old/drivers/char/serial.c linux.dev/drivers/char/serial.c
 --- linux.old/drivers/char/serial.c	2005-10-21 16:43:20.709226000 +0200
-+++ linux.dev/drivers/char/serial.c	2005-10-21 16:45:42.166066500 +0200
++++ linux.dev/drivers/char/serial.c	2005-11-10 01:10:46.015585250 +0100
 @@ -419,7 +419,40 @@
  	return 0;
  }
@@ -6468,7 +5861,7 @@ diff -urN linux.old/drivers/char/serial.c linux.dev/drivers/char/serial.c
  	cval >>= 8;
 diff -urN linux.old/drivers/char/serial.c.orig linux.dev/drivers/char/serial.c.orig
 --- linux.old/drivers/char/serial.c.orig	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/drivers/char/serial.c.orig	2005-10-21 16:43:20.709226000 +0200
++++ linux.dev/drivers/char/serial.c.orig	2005-11-10 01:10:46.051587500 +0100
 @@ -0,0 +1,6054 @@
 +/*
 + *  linux/drivers/char/serial.c
@@ -12526,7 +11919,7 @@ diff -urN linux.old/drivers/char/serial.c.orig linux.dev/drivers/char/serial.c.o
 +*/
 diff -urN linux.old/drivers/char/ticfg/Makefile linux.dev/drivers/char/ticfg/Makefile
 --- linux.old/drivers/char/ticfg/Makefile	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/drivers/char/ticfg/Makefile	2005-10-21 17:02:20.199991500 +0200
++++ linux.dev/drivers/char/ticfg/Makefile	2005-11-10 01:10:46.051587500 +0100
 @@ -0,0 +1,6 @@
 +
 +O_TARGET := ticfg.o
@@ -12536,7 +11929,7 @@ diff -urN linux.old/drivers/char/ticfg/Makefile linux.dev/drivers/char/ticfg/Mak
 +include $(TOPDIR)/Rules.make
 diff -urN linux.old/drivers/char/ticfg/adam2_env.c linux.dev/drivers/char/ticfg/adam2_env.c
 --- linux.old/drivers/char/ticfg/adam2_env.c	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/drivers/char/ticfg/adam2_env.c	2005-10-21 17:02:20.199991500 +0200
++++ linux.dev/drivers/char/ticfg/adam2_env.c	2005-11-10 01:10:46.051587500 +0100
 @@ -0,0 +1,85 @@
 +#include <linux/types.h>
 +#include <linux/errno.h>
@@ -12623,9 +12016,33 @@ diff -urN linux.old/drivers/char/ticfg/adam2_env.c linux.dev/drivers/char/ticfg/
 +module_exit(adam2_env_cleanup);
 +
 +MODULE_LICENSE("GPL");
+diff -urN linux.old/include/asm-mips/addrspace.h linux.dev/include/asm-mips/addrspace.h
+--- linux.old/include/asm-mips/addrspace.h	2002-11-29 00:53:15.000000000 +0100
++++ linux.dev/include/asm-mips/addrspace.h	2005-11-10 01:14:16.400733500 +0100
+@@ -11,6 +11,8 @@
+ #ifndef __ASM_MIPS_ADDRSPACE_H
+ #define __ASM_MIPS_ADDRSPACE_H
+ 
++#include <linux/config.h>
++
+ /*
+  *  Configure language
+  */
+@@ -102,4 +104,11 @@
+ #define XKPHYS_TO_PHYS(p)		((p) & TO_PHYS_MASK)
+ #define PHYS_TO_XKPHYS(cm,a)		(0x8000000000000000 | ((cm)<<59) | (a))
+ 
++#ifdef CONFIG_AR7_MEMORY
++#define PHYS_OFFSET	((unsigned long)(CONFIG_AR7_MEMORY))
++#else
++#define PHYS_OFFSET	(0)
++#endif
++#define PHYS_PFN_OFFSET	(PHYS_OFFSET >> PAGE_SHIFT)
++
+ #endif /* __ASM_MIPS_ADDRSPACE_H */
 diff -urN linux.old/include/asm-mips/ar7/adam2_env.h linux.dev/include/asm-mips/ar7/adam2_env.h
 --- linux.old/include/asm-mips/ar7/adam2_env.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/adam2_env.h	2005-10-21 17:02:25.564326750 +0200
++++ linux.dev/include/asm-mips/ar7/adam2_env.h	2005-11-10 01:10:46.067588500 +0100
 @@ -0,0 +1,13 @@
 +#ifndef _INCLUDE_ASM_AR7_ADAM2_ENV_H_
 +#define	_INCLUDE_ASM_AR7_ADAM2_ENV_H_
@@ -12642,7 +12059,7 @@ diff -urN linux.old/include/asm-mips/ar7/adam2_env.h linux.dev/include/asm-mips/
 +#endif /* _INCLUDE_ASM_AR7_ADAM2_ENV_H_ */
 diff -urN linux.old/include/asm-mips/ar7/ar7.h linux.dev/include/asm-mips/ar7/ar7.h
 --- linux.old/include/asm-mips/ar7/ar7.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/ar7.h	2005-10-21 16:45:42.178067250 +0200
++++ linux.dev/include/asm-mips/ar7/ar7.h	2005-11-10 01:10:46.067588500 +0100
 @@ -0,0 +1,33 @@
 +/*
 + * $Id$
@@ -12679,7 +12096,7 @@ diff -urN linux.old/include/asm-mips/ar7/ar7.h linux.dev/include/asm-mips/ar7/ar
 +#endif
 diff -urN linux.old/include/asm-mips/ar7/avalanche_intc.h linux.dev/include/asm-mips/ar7/avalanche_intc.h
 --- linux.old/include/asm-mips/ar7/avalanche_intc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/avalanche_intc.h	2005-10-21 17:02:25.568327000 +0200
++++ linux.dev/include/asm-mips/ar7/avalanche_intc.h	2005-11-10 01:10:46.067588500 +0100
 @@ -0,0 +1,292 @@
 + /*
 + * Nitin Dhingra, iamnd@ti.com
@@ -12975,7 +12392,7 @@ diff -urN linux.old/include/asm-mips/ar7/avalanche_intc.h linux.dev/include/asm-
 +#endif /* _AVALANCHE_INTC_H */
 diff -urN linux.old/include/asm-mips/ar7/avalanche_misc.h linux.dev/include/asm-mips/ar7/avalanche_misc.h
 --- linux.old/include/asm-mips/ar7/avalanche_misc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/avalanche_misc.h	2005-10-21 16:45:42.178067250 +0200
++++ linux.dev/include/asm-mips/ar7/avalanche_misc.h	2005-11-10 01:10:46.067588500 +0100
 @@ -0,0 +1,174 @@
 +#ifndef _AVALANCHE_MISC_H_
 +#define _AVALANCHE_MISC_H_
@@ -13153,7 +12570,7 @@ diff -urN linux.old/include/asm-mips/ar7/avalanche_misc.h linux.dev/include/asm-
 +#endif
 diff -urN linux.old/include/asm-mips/ar7/avalanche_regs.h linux.dev/include/asm-mips/ar7/avalanche_regs.h
 --- linux.old/include/asm-mips/ar7/avalanche_regs.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/avalanche_regs.h	2005-10-21 16:45:42.182067500 +0200
++++ linux.dev/include/asm-mips/ar7/avalanche_regs.h	2005-11-10 01:10:46.071588750 +0100
 @@ -0,0 +1,567 @@
 +/* 
 + *  $Id$
@@ -13724,7 +13141,7 @@ diff -urN linux.old/include/asm-mips/ar7/avalanche_regs.h linux.dev/include/asm-
 +
 diff -urN linux.old/include/asm-mips/ar7/avalanche_types.h linux.dev/include/asm-mips/ar7/avalanche_types.h
 --- linux.old/include/asm-mips/ar7/avalanche_types.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/avalanche_types.h	2005-10-21 17:02:25.568327000 +0200
++++ linux.dev/include/asm-mips/ar7/avalanche_types.h	2005-11-10 01:10:46.071588750 +0100
 @@ -0,0 +1,126 @@
 +/*------------------------------------------------------------------------------------------*\
 +\*------------------------------------------------------------------------------------------*/
@@ -13854,7 +13271,7 @@ diff -urN linux.old/include/asm-mips/ar7/avalanche_types.h linux.dev/include/asm
 +#endif /*--- #ifndef _avalanche_types_h_ ---*/
 diff -urN linux.old/include/asm-mips/ar7/if_port.h linux.dev/include/asm-mips/ar7/if_port.h
 --- linux.old/include/asm-mips/ar7/if_port.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/if_port.h	2005-10-21 16:45:42.182067500 +0200
++++ linux.dev/include/asm-mips/ar7/if_port.h	2005-11-10 01:10:46.071588750 +0100
 @@ -0,0 +1,26 @@
 +/*******************************************************************************   
 + * FILE PURPOSE:    Interface port id Header file                                      
@@ -13884,7 +13301,7 @@ diff -urN linux.old/include/asm-mips/ar7/if_port.h linux.dev/include/asm-mips/ar
 +#endif /* _IF_PORT_H_ */
 diff -urN linux.old/include/asm-mips/ar7/sangam.h linux.dev/include/asm-mips/ar7/sangam.h
 --- linux.old/include/asm-mips/ar7/sangam.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/sangam.h	2005-10-21 16:45:42.222070000 +0200
++++ linux.dev/include/asm-mips/ar7/sangam.h	2005-11-10 01:10:46.071588750 +0100
 @@ -0,0 +1,180 @@
 +#ifndef _SANGAM_H_
 +#define _SANGAM_H_
@@ -14068,7 +13485,7 @@ diff -urN linux.old/include/asm-mips/ar7/sangam.h linux.dev/include/asm-mips/ar7
 +#endif /*_SANGAM_H_ */
 diff -urN linux.old/include/asm-mips/ar7/sangam_boards.h linux.dev/include/asm-mips/ar7/sangam_boards.h
 --- linux.old/include/asm-mips/ar7/sangam_boards.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/sangam_boards.h	2005-10-21 16:45:42.182067500 +0200
++++ linux.dev/include/asm-mips/ar7/sangam_boards.h	2005-11-10 01:10:46.071588750 +0100
 @@ -0,0 +1,77 @@
 +#ifndef _SANGAM_BOARDS_H
 +#define _SANGAM_BOARDS_H
@@ -14149,7 +13566,7 @@ diff -urN linux.old/include/asm-mips/ar7/sangam_boards.h linux.dev/include/asm-m
 +#endif
 diff -urN linux.old/include/asm-mips/ar7/tnetd73xx.h linux.dev/include/asm-mips/ar7/tnetd73xx.h
 --- linux.old/include/asm-mips/ar7/tnetd73xx.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/tnetd73xx.h	2005-10-21 16:45:42.222070000 +0200
++++ linux.dev/include/asm-mips/ar7/tnetd73xx.h	2005-11-10 01:10:46.075589000 +0100
 @@ -0,0 +1,338 @@
 +/******************************************************************************
 + * FILE PURPOSE:    TNETD73xx Common Header File
@@ -14491,7 +13908,7 @@ diff -urN linux.old/include/asm-mips/ar7/tnetd73xx.h linux.dev/include/asm-mips/
 +#endif /* __TNETD73XX_H_ */
 diff -urN linux.old/include/asm-mips/ar7/tnetd73xx_err.h linux.dev/include/asm-mips/ar7/tnetd73xx_err.h
 --- linux.old/include/asm-mips/ar7/tnetd73xx_err.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/tnetd73xx_err.h	2005-10-21 16:45:42.222070000 +0200
++++ linux.dev/include/asm-mips/ar7/tnetd73xx_err.h	2005-11-10 01:10:46.075589000 +0100
 @@ -0,0 +1,42 @@
 +/******************************************************************************
 + * FILE PURPOSE:    TNETD73xx Error Definations Header File
@@ -14537,7 +13954,7 @@ diff -urN linux.old/include/asm-mips/ar7/tnetd73xx_err.h linux.dev/include/asm-m
 +#endif /* __TNETD73XX_ERR_H__ */
 diff -urN linux.old/include/asm-mips/ar7/tnetd73xx_misc.h linux.dev/include/asm-mips/ar7/tnetd73xx_misc.h
 --- linux.old/include/asm-mips/ar7/tnetd73xx_misc.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/tnetd73xx_misc.h	2005-10-21 16:45:42.222070000 +0200
++++ linux.dev/include/asm-mips/ar7/tnetd73xx_misc.h	2005-11-10 01:10:46.075589000 +0100
 @@ -0,0 +1,239 @@
 +/******************************************************************************
 + * FILE PURPOSE:    TNETD73xx Misc modules API Header
@@ -14780,7 +14197,7 @@ diff -urN linux.old/include/asm-mips/ar7/tnetd73xx_misc.h linux.dev/include/asm-
 +#endif /* __TNETD73XX_MISC_H__ */
 diff -urN linux.old/include/asm-mips/ar7/vlynq.h linux.dev/include/asm-mips/ar7/vlynq.h
 --- linux.old/include/asm-mips/ar7/vlynq.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/vlynq.h	2005-10-21 16:45:47.858422250 +0200
++++ linux.dev/include/asm-mips/ar7/vlynq.h	2005-11-10 01:10:46.095590250 +0100
 @@ -0,0 +1,610 @@
 +/***************************************************************************
 +**+----------------------------------------------------------------------+**
@@ -15394,7 +14811,7 @@ diff -urN linux.old/include/asm-mips/ar7/vlynq.h linux.dev/include/asm-mips/ar7/
 +#endif /* _VLYNQ_HAL_H_ */
 diff -urN linux.old/include/asm-mips/ar7/vlynq_hal.h linux.dev/include/asm-mips/ar7/vlynq_hal.h
 --- linux.old/include/asm-mips/ar7/vlynq_hal.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/vlynq_hal.h	2005-10-21 17:02:25.568327000 +0200
++++ linux.dev/include/asm-mips/ar7/vlynq_hal.h	2005-11-10 01:10:46.095590250 +0100
 @@ -0,0 +1,606 @@
 +/***************************************************************************
 +**+----------------------------------------------------------------------+**
@@ -16004,7 +15421,7 @@ diff -urN linux.old/include/asm-mips/ar7/vlynq_hal.h linux.dev/include/asm-mips/
 +#endif /* _VLYNQ_HAL_H_ */
 diff -urN linux.old/include/asm-mips/ar7/vlynq_hal_params.h linux.dev/include/asm-mips/ar7/vlynq_hal_params.h
 --- linux.old/include/asm-mips/ar7/vlynq_hal_params.h	1970-01-01 01:00:00.000000000 +0100
-+++ linux.dev/include/asm-mips/ar7/vlynq_hal_params.h	2005-10-21 17:02:25.568327000 +0200
++++ linux.dev/include/asm-mips/ar7/vlynq_hal_params.h	2005-11-10 01:10:46.095590250 +0100
 @@ -0,0 +1,50 @@
 +/***************************************************************************
 +**+----------------------------------------------------------------------+**
@@ -16058,75 +15475,97 @@ diff -urN linux.old/include/asm-mips/ar7/vlynq_hal_params.h linux.dev/include/as
 +#endif /* _VLYNQ_HAL_PARAMS_H */
 diff -urN linux.old/include/asm-mips/io.h linux.dev/include/asm-mips/io.h
 --- linux.old/include/asm-mips/io.h	2003-08-25 13:44:43.000000000 +0200
-+++ linux.dev/include/asm-mips/io.h	2005-10-21 16:45:42.250071750 +0200
-@@ -63,8 +63,12 @@
++++ linux.dev/include/asm-mips/io.h	2005-11-10 01:14:16.400733500 +0100
+@@ -61,9 +61,9 @@
+  * Change "struct page" to physical address.
+  */
  #ifdef CONFIG_64BIT_PHYS_ADDR
- #define page_to_phys(page)	((u64)(page - mem_map) << PAGE_SHIFT)
+-#define page_to_phys(page)	((u64)(page - mem_map) << PAGE_SHIFT)
++#define page_to_phys(page)	(((u64)(page - mem_map) << PAGE_SHIFT) + PHYS_OFFSET)
  #else
-+#ifdef CONFIG_AR7
-+#define page_to_phys(page)	(((page - mem_map) << PAGE_SHIFT) + CONFIG_AR7_MEMORY)
-+#else 
- #define page_to_phys(page)	((page - mem_map) << PAGE_SHIFT)
+-#define page_to_phys(page)	((page - mem_map) << PAGE_SHIFT)
++#define page_to_phys(page)	(((page - mem_map) << PAGE_SHIFT) + PHYS_OFFSET)
  #endif
-+#endif
  
  #define IO_SPACE_LIMIT 0xffff
- 
 diff -urN linux.old/include/asm-mips/irq.h linux.dev/include/asm-mips/irq.h
 --- linux.old/include/asm-mips/irq.h	2003-08-25 13:44:43.000000000 +0200
-+++ linux.dev/include/asm-mips/irq.h	2005-10-21 16:45:42.278073500 +0200
-@@ -14,7 +14,12 @@
++++ linux.dev/include/asm-mips/irq.h	2005-11-10 01:12:43.950955750 +0100
+@@ -14,7 +14,20 @@
  #include <linux/config.h>
  #include <linux/linkage.h>
  
 +#ifdef CONFIG_AR7
-+#include <asm/ar7/avalanche_intc.h>
-+#define NR_IRQS AVALANCHE_INT_END + 1
++/* MIPS   has 8 irqs
++ * AR7    has 40 primary and 32 secondary irqs
++ * vlynq0 has 32 irqs
++ * vlynq1 has 32 irqs
++ */
++#ifdef CONFIG_AR7_VLYNQ
++#define NR_IRQS (80 + 32 * CONFIG_AR7_VLYNQ_PORTS)
++#else
++#define NR_IRQS 80
++#endif
 +#else
  #define NR_IRQS 128		/* Largest number of ints of all machines.  */
 +#endif
  
  #ifdef CONFIG_I8259
  static inline int irq_cannonicalize(int irq)
+diff -urN linux.old/include/asm-mips/mips-boards/prom.h linux.dev/include/asm-mips/mips-boards/prom.h
+--- linux.old/include/asm-mips/mips-boards/prom.h	2001-09-09 19:43:02.000000000 +0200
++++ linux.dev/include/asm-mips/mips-boards/prom.h	2005-11-10 01:14:16.436735750 +0100
+@@ -33,7 +33,7 @@
+ extern void prom_init_cmdline(void);
+ extern void prom_meminit(void);
+ extern void prom_fixup_mem_map(unsigned long start_mem, unsigned long end_mem);
+-extern void prom_free_prom_memory (void);
++extern unsigned long prom_free_prom_memory (void);
+ extern void mips_display_message(const char *str);
+ extern void mips_display_word(unsigned int num);
+ extern int get_ethernet_addr(char *ethernet_addr);
 diff -urN linux.old/include/asm-mips/page.h linux.dev/include/asm-mips/page.h
 --- linux.old/include/asm-mips/page.h	2004-02-18 14:36:32.000000000 +0100
-+++ linux.dev/include/asm-mips/page.h	2005-10-21 16:45:42.282073750 +0200
-@@ -129,7 +129,11 @@
++++ linux.dev/include/asm-mips/page.h	2005-11-10 01:14:16.436735750 +0100
+@@ -12,6 +12,7 @@
+ 
+ #include <linux/config.h>
+ #include <asm/break.h>
++#include <asm/addrspace.h>
+ 
+ #ifdef __KERNEL__
+ 
+@@ -129,7 +130,7 @@
  
  #define __pa(x)		((unsigned long) (x) - PAGE_OFFSET)
  #define __va(x)		((void *)((unsigned long) (x) + PAGE_OFFSET))
-+#ifdef CONFIG_AR7
-+#define virt_to_page(kaddr)	phys_to_page(__pa(kaddr))
-+#else
- #define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
-+#endif
+-#define virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
++#define virt_to_page(kaddr)	(mem_map + ((__pa(kaddr)-PHYS_OFFSET) >> PAGE_SHIFT))
  #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
  
  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
 diff -urN linux.old/include/asm-mips/pgtable-32.h linux.dev/include/asm-mips/pgtable-32.h
 --- linux.old/include/asm-mips/pgtable-32.h	2004-02-18 14:36:32.000000000 +0100
-+++ linux.dev/include/asm-mips/pgtable-32.h	2005-10-21 16:45:42.286074000 +0200
-@@ -108,7 +108,18 @@
++++ linux.dev/include/asm-mips/pgtable-32.h	2005-11-10 01:14:16.436735750 +0100
+@@ -108,7 +108,7 @@
   * and a page entry and page directory to the page they refer to.
   */
  
 -#ifdef CONFIG_CPU_VR41XX
-+#if defined(CONFIG_AR7)
-+#define mk_pte(page, pgprot)						\
-+({									\
-+	pte_t   __pte;							\
-+									\
-+	pte_val(__pte) = ((phys_t)(page - mem_map) << (PAGE_SHIFT) |	\
-+		CONFIG_AR7_MEMORY) |					\
-+	pgprot_val(pgprot);						\
-+									\
-+	__pte;								\
-+})
-+#elif defined(CONFIG_CPU_VR41XX)
++#if defined(CONFIG_CPU_VR41XX)
  #define mk_pte(page, pgprot)                                            \
  ({                                                                      \
          pte_t   __pte;                                                  \
-@@ -130,6 +141,7 @@
+@@ -123,13 +123,14 @@
+ ({									\
+ 	pte_t   __pte;							\
+ 									\
+-	pte_val(__pte) = ((phys_t)(page - mem_map) << PAGE_SHIFT) | \
+-	                 pgprot_val(pgprot);				\
++	pte_val(__pte) = (((phys_t)(page - mem_map) << PAGE_SHIFT) +    \
++			  PHYS_OFFSET) | pgprot_val(pgprot);            \
+ 									\
+ 	__pte;								\
  })
  #endif
  
@@ -16134,27 +15573,32 @@ diff -urN linux.old/include/asm-mips/pgtable-32.h linux.dev/include/asm-mips/pgt
  static inline pte_t mk_pte_phys(phys_t physpage, pgprot_t pgprot)
  {
  #ifdef CONFIG_CPU_VR41XX
-@@ -175,7 +187,10 @@
+@@ -175,12 +176,12 @@
  		set_pte(ptep, __pte(0));
  }
  
 -#ifdef CONFIG_CPU_VR41XX
-+#if defined(CONFIG_AR7)
-+#define phys_to_page(phys)	(mem_map + (((phys)-CONFIG_AR7_MEMORY) >> PAGE_SHIFT))
-+#define pte_page(x)		phys_to_page(pte_val(x))
-+#elif defined(CONFIG_CPU_VR41XX)
++#if defined(CONFIG_CPU_VR41XX)
  #define pte_page(x)  (mem_map+((unsigned long)(((x).pte_low >> (PAGE_SHIFT+2)))))
  #define __mk_pte(page_nr,pgprot) __pte(((page_nr) << (PAGE_SHIFT+2)) | pgprot_val(pgprot))
  #else
+-#define pte_page(x)  (mem_map+((unsigned long)(((x).pte_low >> PAGE_SHIFT))))
+-#define __mk_pte(page_nr,pgprot) __pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
++#define pte_page(x)  (mem_map+((unsigned long)((((x).pte_low-PHYS_OFFSET) >> PAGE_SHIFT))))
++#define __mk_pte(page_nr,pgprot) __pte((((page_nr) << PAGE_SHIFT)+PHYS_OFFSET)|pgprot_val(pgprot))
+ #endif
+ 
+ #endif
 diff -urN linux.old/include/asm-mips/serial.h linux.dev/include/asm-mips/serial.h
 --- linux.old/include/asm-mips/serial.h	2005-01-19 15:10:12.000000000 +0100
-+++ linux.dev/include/asm-mips/serial.h	2005-10-21 16:45:42.294074500 +0200
-@@ -65,6 +65,15 @@
++++ linux.dev/include/asm-mips/serial.h	2005-11-10 01:14:16.436735750 +0100
+@@ -65,6 +65,16 @@
  
  #define C_P(card,port) (((card)<<6|(port)<<3) + 1)
  
 +#ifdef CONFIG_AR7
 +#include <asm/ar7/ar7.h>
++#include <asm/ar7/avalanche_intc.h>
 +#define AR7_SERIAL_PORT_DEFNS  \
 +	{ 0, AR7_BASE_BAUD, AR7_UART0_REGS_BASE, LNXINTNUM(AVALANCHE_UART0_INT), STD_COM_FLAGS }, \
 +	{ 0, AR7_BASE_BAUD, AR7_UART1_REGS_BASE, LNXINTNUM(AVALANCHE_UART1_INT), STD_COM_FLAGS }, 
@@ -16165,7 +15609,7 @@ diff -urN linux.old/include/asm-mips/serial.h linux.dev/include/asm-mips/serial.
  #ifdef CONFIG_MIPS_JAZZ
  #define _JAZZ_SERIAL_INIT(int, base)					\
  	{ .baud_base = JAZZ_BASE_BAUD, .irq = int, .flags = STD_COM_FLAGS,	\
-@@ -468,6 +477,7 @@
+@@ -468,6 +478,7 @@
  #endif
  
  #define SERIAL_PORT_DFNS			\
diff --git a/target/linux/linux-2.4/patches/ar7/004-atm_driver.patch b/target/linux/linux-2.4/patches/ar7/004-atm_driver.patch
index 475d1bcd1..f6a920853 100644
--- a/target/linux/linux-2.4/patches/ar7/004-atm_driver.patch
+++ b/target/linux/linux-2.4/patches/ar7/004-atm_driver.patch
@@ -21464,6 +21464,7 @@ diff -urN linux.old/drivers/atm/sangam_atm/tn7atm.c linux.dev/drivers/atm/sangam
 +#ifdef CONFIG_LED_MODULE
 +#include <asm/ar7/ledapp.h>
 +#endif
++#include <asm/ar7/avalanche_intc.h>
 +
 +#ifdef MODULE
 +MODULE_DESCRIPTION ("Tnetd73xx ATM Device Driver");
@@ -21473,7 +21474,6 @@ diff -urN linux.old/drivers/atm/sangam_atm/tn7atm.c linux.dev/drivers/atm/sangam
 +/* Version Information */
 +//static char atm_version[] ="1.0.0.1";
 +
-+
 +#define TRUE   1
 +#define FALSE  0
 +
diff --git a/target/linux/linux-2.4/patches/ar7/005-wdt_driver.patch b/target/linux/linux-2.4/patches/ar7/005-wdt_driver.patch
new file mode 100644
index 000000000..9b01a353d
--- /dev/null
+++ b/target/linux/linux-2.4/patches/ar7/005-wdt_driver.patch
@@ -0,0 +1,392 @@
+diff -ruN linux-2.4.30-patch006/drivers/char/ar7_wdt.c linux-2.4.30-patch007/drivers/char/ar7_wdt.c
+--- linux-2.4.30-patch006/drivers/char/ar7_wdt.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.4.30-patch007/drivers/char/ar7_wdt.c	2005-10-27 09:39:40.000000000 +0200
+@@ -0,0 +1,335 @@
++/* linux/drivers/char/ar7_wdt.c 
++
++   TI AR7 watch dog timer support
++
++   Copyright (c) 2005 Enrik Berkhan <Enrik.Berkhan@akk.org>
++
++   Som code taken from:
++   National Semiconductor SCx200 Watchdog support
++   Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
++
++   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.
++
++   The author(s) of this software shall not be held liable for damages
++   of any nature resulting due to the use of this software. This
++   software is provided AS-IS with no warranties. */
++
++#include <linux/config.h>
++#include <linux/module.h>
++#include <linux/errno.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/miscdevice.h>
++#include <linux/watchdog.h>
++#include <linux/notifier.h>
++#include <linux/reboot.h>
++#include <linux/ioport.h>
++
++#include <asm/uaccess.h>
++
++#include <asm/ar7/avalanche_misc.h>
++#include <asm/ar7/sangam.h>
++
++#define NAME "ar7_wdt"
++#define LONGNAME "TI AR7 Watchdog Timer"
++
++MODULE_AUTHOR("Enrik Berkhan <Enrik.Berkhan@akk.org>");
++MODULE_DESCRIPTION(LONGNAME);
++MODULE_LICENSE("GPL");
++
++#ifndef CONFIG_WATCHDOG_NOWAYOUT
++#define CONFIG_WATCHDOG_NOWAYOUT 0
++#endif
++
++static int margin = 60;
++MODULE_PARM(margin, "i");
++MODULE_PARM_DESC(margin, "Watchdog margin in seconds (1 - ~68)");
++
++static int nowayout = CONFIG_WATCHDOG_NOWAYOUT;
++MODULE_PARM(nowayout, "i");
++MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
++
++typedef struct {
++  uint32_t kick_lock;
++  uint32_t kick;
++  uint32_t change_lock;
++  uint32_t change ;
++  uint32_t disable_lock;
++  uint32_t disable;
++  uint32_t prescale_lock;
++  uint32_t prescale;
++} ar7_wdt_t;
++
++volatile ar7_wdt_t *ar7_wdt = (ar7_wdt_t *)AVALANCHE_WATCHDOG_TIMER_BASE;
++
++static struct semaphore open_semaphore;
++static unsigned expect_close;
++
++/* XXX correct? assumed to be sysfreq/2. get this dynamically ... */
++#define vbus_freq 62500000
++
++/* XXX currently fixed, allows max margin ~68.72 secs */
++#define prescale_value 0xFFFF
++
++static void ar7_wdt_kick(uint32_t value)
++{
++  ar7_wdt->kick_lock = 0x5555;
++  if ((ar7_wdt->kick_lock & 3) == 1) {
++    ar7_wdt->kick_lock = 0xAAAA;
++    if ((ar7_wdt->kick_lock & 3) == 3) {
++      ar7_wdt->kick = value;
++      return;
++    }
++  }
++  printk(KERN_ERR NAME "failed to unlock WDT kick reg\n");
++}
++
++static void ar7_wdt_prescale(uint32_t value)
++{
++  ar7_wdt->prescale_lock = 0x5A5A;
++  if ((ar7_wdt->prescale_lock & 3) == 1) {
++    ar7_wdt->prescale_lock = 0xA5A5;
++    if ((ar7_wdt->prescale_lock & 3) == 3) {
++      ar7_wdt->prescale = value;
++      return;
++    }
++  }
++  printk(KERN_ERR NAME "failed to unlock WDT prescale reg\n");
++}
++
++static void ar7_wdt_change(uint32_t value)
++{
++  ar7_wdt->change_lock = 0x6666;
++  if ((ar7_wdt->change_lock & 3) == 1) {
++    ar7_wdt->change_lock = 0xBBBB;
++    if ((ar7_wdt->change_lock & 3) == 3) {
++      ar7_wdt->change = value;
++      return;
++    }
++  }
++  printk(KERN_ERR NAME "failed to unlock WDT change reg\n");
++}
++
++static void ar7_wdt_disable(uint32_t value)
++{
++  ar7_wdt->disable_lock = 0x7777;
++  if ((ar7_wdt->disable_lock & 3) == 1) {
++    ar7_wdt->disable_lock = 0xCCCC;
++    if ((ar7_wdt->disable_lock & 3) == 2) {
++      ar7_wdt->disable_lock = 0xDDDD; 
++      if ((ar7_wdt->disable_lock & 3) == 3) {
++	ar7_wdt->disable = value;
++	return;
++      }
++    }
++  }
++  printk(KERN_ERR NAME "failed to unlock WDT disable reg\n");
++  return;
++}
++
++static void ar7_wdt_update_margin(int new_margin)
++{
++        uint32_t change;
++
++	change = new_margin * (vbus_freq / prescale_value);
++	if (change < 1) change = 1;
++	if (change > 0xFFFF) change = 0xFFFF;
++	ar7_wdt_change(change);
++	margin = change * prescale_value / vbus_freq;
++	printk(KERN_INFO NAME
++	       ": timer margin %d seconds (prescale %d, change %d, freq %d)\n",
++	       margin, prescale_value, change, vbus_freq);
++}
++
++static void ar7_wdt_enable_wdt(void)
++{
++	printk(KERN_DEBUG NAME ": enabling watchdog timer\n");
++	ar7_wdt_disable(1);
++	ar7_wdt_kick(1);
++}
++
++static void ar7_wdt_disable_wdt(void)
++{
++	printk(KERN_DEBUG NAME ": disabling watchdog timer\n");
++	ar7_wdt_disable(0);
++}
++
++static int ar7_wdt_open(struct inode *inode, struct file *file)
++{
++        /* only allow one at a time */
++        if (down_trylock(&open_semaphore))
++                return -EBUSY;
++	ar7_wdt_enable_wdt();
++	expect_close = 0;
++
++	return 0;
++}
++
++static int ar7_wdt_release(struct inode *inode, struct file *file)
++{
++	if (!expect_close) {
++		printk(KERN_WARNING NAME ": watchdog device closed unexpectedly, will not disable the watchdog timer\n");
++	} else if (!nowayout) {
++		ar7_wdt_disable_wdt();
++	}
++        up(&open_semaphore);
++
++	return 0;
++}
++
++static int ar7_wdt_notify_sys(struct notifier_block *this, 
++				      unsigned long code, void *unused)
++{
++        if (code == SYS_HALT || code == SYS_POWER_OFF)
++		if (!nowayout)
++			ar7_wdt_disable_wdt();
++
++        return NOTIFY_DONE;
++}
++
++static struct notifier_block ar7_wdt_notifier =
++{
++        .notifier_call = ar7_wdt_notify_sys
++};
++
++static ssize_t ar7_wdt_write(struct file *file, const char *data, 
++				     size_t len, loff_t *ppos)
++{
++	if (ppos != &file->f_pos)
++		return -ESPIPE;
++
++	/* check for a magic close character */
++	if (len) 
++	{
++		size_t i;
++
++		ar7_wdt_kick(1);
++
++		expect_close = 0;
++		for (i = 0; i < len; ++i) {
++			char c;
++			if (get_user(c, data+i))
++				return -EFAULT;
++			if (c == 'V')
++				expect_close = 1;
++		}
++
++	}
++	return len;
++}
++
++static int ar7_wdt_ioctl(struct inode *inode, struct file *file,
++	unsigned int cmd, unsigned long arg)
++{
++	static struct watchdog_info ident = {
++		.identity = LONGNAME,
++		.firmware_version = 1, 
++		.options = (WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING),
++	};
++	int new_margin;
++	
++	switch (cmd) {
++	default:
++		return -ENOTTY;
++	case WDIOC_GETSUPPORT:
++		if(copy_to_user((struct watchdog_info *)arg, &ident, 
++				sizeof(ident)))
++			return -EFAULT;
++		return 0;
++	case WDIOC_GETSTATUS:
++	case WDIOC_GETBOOTSTATUS:
++		if (put_user(0, (int *)arg))
++			return -EFAULT;
++		return 0;
++	case WDIOC_KEEPALIVE:
++		ar7_wdt_kick(1);
++		return 0;
++	case WDIOC_SETTIMEOUT:
++		if (get_user(new_margin, (int *)arg))
++			return -EFAULT;
++		if (new_margin < 1)
++			return -EINVAL;
++
++		ar7_wdt_update_margin(new_margin);
++		ar7_wdt_kick(1);
++
++	case WDIOC_GETTIMEOUT:
++		if (put_user(margin, (int *)arg))
++			return -EFAULT;
++		return 0;
++	}
++}
++
++static struct file_operations ar7_wdt_fops = {
++	.owner	 = THIS_MODULE,
++	.write   = ar7_wdt_write,
++	.ioctl   = ar7_wdt_ioctl,
++	.open    = ar7_wdt_open,
++	.release = ar7_wdt_release,
++};
++
++static struct miscdevice ar7_wdt_miscdev = {
++	.minor = WATCHDOG_MINOR,
++	.name  = "watchdog",
++	.fops  = &ar7_wdt_fops,
++};
++
++static __initdata char *last_initiator[] = {
++  [HARDWARE_RESET] = "hardware reset",
++  [SOFTWARE_RESET0] = "SW0 software reset",
++  [SOFTWARE_RESET1] = "SW1 software reset",
++  [WATCHDOG_RESET] = "watchdog"
++};
++
++static int __init ar7_wdt_init(void)
++{
++	int r;
++
++	if (!request_mem_region(AVALANCHE_WATCHDOG_TIMER_BASE,
++				sizeof(ar7_wdt_t), LONGNAME)) {
++		printk(KERN_WARNING NAME ": watchdog I/O region busy\n");
++		return -EBUSY;
++	}
++
++	printk(KERN_INFO NAME ": last system reset initiated by %s\n",
++	       last_initiator[avalanche_get_sys_last_reset_status()]);
++
++
++	ar7_wdt_disable_wdt();
++	ar7_wdt_prescale(prescale_value);
++	ar7_wdt_update_margin(margin);
++
++	sema_init(&open_semaphore, 1);
++
++	r = misc_register(&ar7_wdt_miscdev);
++	if (r) {
++                printk(KERN_ERR NAME ": unable to register misc device\n");
++		release_mem_region(AVALANCHE_WATCHDOG_TIMER_BASE,
++				   sizeof(ar7_wdt_t));
++		return r;
++	}
++
++	r = register_reboot_notifier(&ar7_wdt_notifier);
++        if (r) {
++                printk(KERN_ERR NAME ": unable to register reboot notifier\n");
++		misc_deregister(&ar7_wdt_miscdev);
++		release_mem_region(AVALANCHE_WATCHDOG_TIMER_BASE,
++				   sizeof(ar7_wdt_t));
++                return r;
++        }
++
++	return 0;
++}
++
++static void __exit ar7_wdt_cleanup(void)
++{
++        unregister_reboot_notifier(&ar7_wdt_notifier);
++	misc_deregister(&ar7_wdt_miscdev);
++	release_mem_region(AVALANCHE_WATCHDOG_TIMER_BASE, sizeof(ar7_wdt_t));
++}
++
++module_init(ar7_wdt_init);
++module_exit(ar7_wdt_cleanup);
+diff -ruN linux-2.4.30-patch006/drivers/char/Config.in linux-2.4.30-patch007/drivers/char/Config.in
+--- linux-2.4.30-patch006/drivers/char/Config.in	2005-10-27 11:25:29.000000000 +0200
++++ linux-2.4.30-patch007/drivers/char/Config.in	2005-10-27 11:17:32.000000000 +0200
+@@ -251,6 +251,9 @@
+ bool 'Watchdog Timer Support'	CONFIG_WATCHDOG
+ if [ "$CONFIG_WATCHDOG" != "n" ]; then
+    bool '  Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
++   if [ "$CONFIG_AR7" = "y" ] ; then
++     tristate '  TI AR7 Watchdog Timer' CONFIG_AR7_WDT
++   else
+    tristate '  Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT
+    tristate '  Advantech SBC Watchdog Timer' CONFIG_ADVANTECH_WDT
+    tristate '  ALi M7101 PMU on ALi 1535D+ Watchdog Timer' CONFIG_ALIM1535_WDT
+@@ -271,7 +274,6 @@
+    tristate '  SBC-60XX Watchdog Timer' CONFIG_60XX_WDT
+    dep_tristate '  SC1200 Watchdog Timer (EXPERIMENTAL)' CONFIG_SC1200_WDT $CONFIG_EXPERIMENTAL
+    tristate '  NatSemi SCx200 Watchdog' CONFIG_SCx200_WDT
+-   tristate '  Software Watchdog' CONFIG_SOFT_WATCHDOG
+    tristate '  W83877F (EMACS) Watchdog Timer' CONFIG_W83877F_WDT
+    tristate '  WDT Watchdog timer' CONFIG_WDT
+    tristate '  WDT PCI Watchdog timer' CONFIG_WDTPCI
+@@ -282,6 +284,8 @@
+       fi
+    fi
+    tristate '  ZF MachZ Watchdog' CONFIG_MACHZ_WDT
++   fi
++   tristate '  Software Watchdog' CONFIG_SOFT_WATCHDOG
+    if [ "$CONFIG_SGI_IP22" = "y" ]; then
+       dep_tristate '  Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22
+    fi
+diff -ruN linux-2.4.30-patch006/drivers/char/Makefile linux-2.4.30-patch007/drivers/char/Makefile
+--- linux-2.4.30-patch006/drivers/char/Makefile	2005-10-27 11:19:38.000000000 +0200
++++ linux-2.4.30-patch007/drivers/char/Makefile	2005-10-27 09:39:40.000000000 +0200
+@@ -342,6 +342,7 @@
+ obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
+ obj-$(CONFIG_INDYDOG) += indydog.o
+ obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
++obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
+ 
+ subdir-$(CONFIG_MWAVE) += mwave
+ ifeq ($(CONFIG_MWAVE),y)
+diff -ruN linux-2.4.30-patch006/include/asm-mips/ar7/sangam.h linux-2.4.30-patch007/include/asm-mips/ar7/sangam.h
+--- linux-2.4.30-patch006/include/asm-mips/ar7/sangam.h	2005-10-27 11:25:51.000000000 +0200
++++ linux-2.4.30-patch007/include/asm-mips/ar7/sangam.h	2005-10-27 11:13:37.000000000 +0200
+@@ -152,7 +152,7 @@
+ #define AVALANCHE_EMIF_SDRAM_CFG      (AVALANCHE_EMIF_CONTROL_BASE + 0x8)
+ #define AVALANCHE_RST_CTRL_PRCR       (KSEG1ADDR(0x08611600))
+ #define AVALANCHE_RST_CTRL_SWRCR      (KSEG1ADDR(0x08611604))
+-#define AVALANCHE_RST_CTRL_RSR        (KSEG1ADDR(0x08611600))
++#define AVALANCHE_RST_CTRL_RSR        (KSEG1ADDR(0x08611608))
+ 
+ #define AVALANCHE_POWER_CTRL_PDCR     (KSEG1ADDR(0x08610A00))
+ #define AVALANCHE_WAKEUP_CTRL_WKCR    (KSEG1ADDR(0x08610A0C))
-- 
cgit v1.2.3