diff options
author | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2005-11-10 01:53:27 +0000 |
---|---|---|
committer | nbd <nbd@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2005-11-10 01:53:27 +0000 |
commit | 3bcc74c2a18c30b525a8215e22acd846c371c234 (patch) | |
tree | d4e7525fd3d95148cd0cfcf018c70230d20a3f0c /target/linux | |
parent | ef91617e28fc66f8fc21e568a90c1f54f28d51b1 (diff) |
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
Diffstat (limited to 'target/linux')
-rw-r--r-- | target/linux/linux-2.4/config/ar7 | 22 | ||||
-rw-r--r-- | target/linux/linux-2.4/patches/ar7/000-ar7_support.patch | 1764 | ||||
-rw-r--r-- | target/linux/linux-2.4/patches/ar7/004-atm_driver.patch | 2 | ||||
-rw-r--r-- | target/linux/linux-2.4/patches/ar7/005-wdt_driver.patch | 392 |
4 files changed, 1000 insertions, 1180 deletions
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]; ++#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_print_str)(unsigned int out, char *s, int len); -+ -+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); + -+extern void ar7_time_init(void); -+extern void ar7_timer_setup(struct irqaction *irq); ++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); ++ ++#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 inline void bootmem_init(void) -@@ -320,7 +324,12 @@ + 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; + +- 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)) |