All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeroen Vreeken <pe1rxq@amsat.org>
To: linux-mips@linux-mips.org
Subject: [PATCH] ADM5120 for 2.6.10
Date: Thu, 27 Jan 2005 21:34:06 +0100	[thread overview]
Message-ID: <41F9503E.5030004@amsat.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 1245 bytes --]

Hi,

I finally succeeded in getting 2.6.10 working on my adm5120 router.
Attached is a patch against 2.6.10 with the needed changes.

First a list of what it does NOT do:
-ethernet
-usb
-pci (my board doesn't have pci)
-anything usefull :)

What it does do:
-Boot
-Serial support (with improved timing compared to the official 2.4.18 
kernels)
-Simplified init code (the 2.4.18 code was way to complex)

I also found the most probable reason people had problems porting the 
released sources to other kernels: the bootloader jumps to a fixed 
address that just happens to be the kernel_entry in 2.4.18
I 'solved' it by adding a jump on this address to the real kernel_entry 
(which is at the other end of the kernel in 2.6)
I also had some great fun figuring out how the hell initramfs is 
supposed to work.... To finally find out after two days I had one slash 
to little in the configured path..... I also found that standard 2.6.10 
doesn't support symlinks and my initramfs ended up being 14Mb.

Next I plan to port the ethernet driver and usb. I don't think I will 
port the led driver as is, its much easier to just offer a character 
device with access to the GPIO port than the 'LED BLINK' stuff used in 
the ADMtek led driver.

Jeroen


[-- Attachment #2: linux-2.6.10-adm.1.diff --]
[-- Type: text/x-patch, Size: 132010 bytes --]

diff -ruN linux-2.6.10/Makefile linux-2.6.10-adm.1/Makefile
--- linux-2.6.10/Makefile	2004-12-24 22:35:01.000000000 +0100
+++ linux-2.6.10-adm.1/Makefile	2005-01-27 21:07:04.000000000 +0100
@@ -4,6 +4,8 @@
 EXTRAVERSION =
 NAME=Woozy Numbat
 
+ARCH=mips
+
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
 # More info can be located in ./README
@@ -722,6 +724,10 @@
 vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
 	$(call if_changed_rule,vmlinux__)
 
+vmlinuz: vmlinux
+	$(OBJCOPY) -O binary vmlinux vmlinux.bin
+	gzip vmlinux.bin -c >vmlinuz
+
 # The actual objects are generated when descending, 
 # make sure no implicit rule kicks in
 $(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ;
diff -ruN linux-2.6.10/arch/mips/Kconfig linux-2.6.10-adm.1/arch/mips/Kconfig
--- linux-2.6.10/arch/mips/Kconfig	2004-12-24 22:34:45.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/Kconfig	2005-01-27 21:06:17.000000000 +0100
@@ -46,6 +46,10 @@
 	  the MIPS architecture, check out the Linux/MIPS FAQ on the WWW at
 	  <http://www.linux-mips.org/>.
 
+config MIPS_AM5120
+	bool "Support for ADM5120 board"
+	select DMA_NONCOHERENT
+
 config MIPS_MAGNUM_4000
 	bool "Support for MIPS Magnum 4000"
 	depends on MACH_JAZZ
diff -ruN linux-2.6.10/arch/mips/Makefile linux-2.6.10-adm.1/arch/mips/Makefile
--- linux-2.6.10/arch/mips/Makefile	2004-12-24 22:33:49.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/Makefile	2005-01-27 21:06:16.000000000 +0100
@@ -49,7 +49,7 @@
 endif
 
 ifdef CONFIG_CROSSCOMPILE
-CROSS_COMPILE		:= $(tool-prefix)
+CROSS_COMPILE		:= /export/tools/bin/$(tool-prefix)
 endif
 
 ifdef CONFIG_BUILD_ELF64
@@ -232,6 +232,13 @@
 load-$(CONFIG_MACH_JAZZ)	+= 0xffffffff80080000
 
 #
+# ADMtek 5120
+#
+
+core-$(CONFIG_MIPS_AM5120)	+= arch/mips/am5120/
+load-$(CONFIG_MIPS_AM5120)	+= 0xffffffff80002000
+
+#
 # Common Alchemy Au1x00 stuff
 #
 core-$(CONFIG_SOC_AU1X00)	+= arch/mips/au1000/common/
diff -ruN linux-2.6.10/arch/mips/am5120/5120_rtc.c linux-2.6.10-adm.1/arch/mips/am5120/5120_rtc.c
--- linux-2.6.10/arch/mips/am5120/5120_rtc.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/am5120/5120_rtc.c	2005-01-27 21:06:17.000000000 +0100
@@ -0,0 +1,73 @@
+/*****************************************************************************
+;
+;   (C) Unpublished Work of ADMtek Incorporated.  All Rights Reserved.
+;
+;       THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
+;       PROPRIETARY AND TRADESECRET INFORMATION OF ADMTEK INCORPORATED.
+;       ACCESS TO THIS WORK IS RESTRICTED TO (I) ADMTEK EMPLOYEES WHO HAVE A
+;       NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR ASSIGNMENTS
+;       AND (II) ENTITIES OTHER THAN ADMTEK WHO HAVE ENTERED INTO APPROPRIATE
+;       LICENSE AGREEMENTS.  NO PART OF THIS WORK MAY BE USED, PRACTICED,
+;       PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,
+;       ABBRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
+;       TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF ADMTEK.
+;       ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD
+;       SUBJECT THE PERPERTRATOR TO CRIMINAL AND CIVIL LIABILITY.
+;
+;------------------------------------------------------------------------------
+;
+;    Project : ADM5120
+;    Creator : daniell@admtek.com.tw
+;    File    : arch/mips/am5120/5120_rtc.c
+;	 Date    : 2003.3.4
+;    Abstract: 
+;
+;Modification History:
+;
+;*****************************************************************************/
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/serial.h>
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/reboot.h>
+#include <asm/io.h>
+#include <asm/time.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+
+#include <linux/mc146818rtc.h>
+#include <asm/am5120/adm5120.h>
+#include <asm-arm/rtc.h>
+
+struct rtc_ops *rtc_ops=NULL;
+/*
+static unsigned char am5120_rtc_read_data(unsigned long addr)
+{
+	//outb(addr, MALTA_RTC_ADR_REG);
+	//return inb(MALTA_RTC_DAT_REG);
+	return 0;
+}
+
+static void am5120_rtc_write_data(unsigned char data, unsigned long addr)
+{
+	//outb(addr, MALTA_RTC_ADR_REG);
+	//outb(data, MALTA_RTC_DAT_REG);
+}
+
+static int am5120_rtc_bcd_mode(void)
+{
+	return 0;
+}
+
+struct rtc_ops am5120_rtc_ops = {
+	&am5120_rtc_read_data,
+	&am5120_rtc_write_data,
+	&am5120_rtc_bcd_mode
+};
+*/
diff -ruN linux-2.6.10/arch/mips/am5120/Makefile linux-2.6.10-adm.1/arch/mips/am5120/Makefile
--- linux-2.6.10/arch/mips/am5120/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/am5120/Makefile	2005-01-27 21:06:17.000000000 +0100
@@ -0,0 +1,3 @@
+
+obj-y	:= setup.o prom.o irq.o serial.o memory.o mipsIRQ.o time.o pci.o
+# 5120_rtc.o led.o
diff -ruN linux-2.6.10/arch/mips/am5120/irq.c linux-2.6.10-adm.1/arch/mips/am5120/irq.c
--- linux-2.6.10/arch/mips/am5120/irq.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/am5120/irq.c	2005-01-27 21:06:17.000000000 +0100
@@ -0,0 +1,181 @@
+/*****************************************************************************
+;
+;   (C) Unpublished Work of ADMtek Incorporated.  All Rights Reserved.
+;
+;       THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
+;       PROPRIETARY AND TRADESECRET INFORMATION OF ADMTEK INCORPORATED.
+;       ACCESS TO THIS WORK IS RESTRICTED TO (I) ADMTEK EMPLOYEES WHO HAVE A
+;       NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR ASSIGNMENTS
+;       AND (II) ENTITIES OTHER THAN ADMTEK WHO HAVE ENTERED INTO APPROPRIATE
+;       LICENSE AGREEMENTS.  NO PART OF THIS WORK MAY BE USED, PRACTICED,
+;       PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,
+;       ABBRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
+;       TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF ADMTEK.
+;       ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD
+;       SUBJECT THE PERPERTRATOR TO CRIMINAL AND CIVIL LIABILITY.
+;
+;------------------------------------------------------------------------------
+;
+;    Project : ADM5120
+;    Creator : daniell@admtek.com.tw
+;    File    : arch/mips/am5120/irq.c
+;	 Date    : 2003.3.4
+;    Abstract: 
+;
+;Modification History:
+;
+;	Jeroen Vreeken (pe1rxq@amsat.org)
+;	Simplified and merged with 5120_int.c
+;
+;	Includes code by:
+;	Carsten Langgaard, carstenl@mips.com
+;	Copyright (C) 2000, 2001 MIPS Technologies, Inc.
+;	Copyright (C) 2001 Ralf Baechle
+;
+;*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/pm.h>
+
+#include <asm/irq.h>
+#include <asm/mipsregs.h>
+#include <asm/gdb-stub.h>
+
+#include <asm/am5120/adm5120.h>
+
+extern void breakpoint(void);
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+extern irq_desc_t irq_desc[];
+extern asmlinkage void mipsIRQ(void);
+
+int mips_int_lock(void);
+void mips_int_unlock(int);
+
+static spinlock_t mips_irq_lock = SPIN_LOCK_UNLOCKED;
+
+void am5120_hw0_irqdispatch(struct pt_regs *regs)
+{
+	unsigned long flags;
+	unsigned long intsrc;
+	int i;
+
+	/* We don't have multiple cpus, is this locking really needed???
+		- Jeroen
+	 */
+	spin_lock_irqsave(&mips_irq_lock, flags);
+
+	intsrc = ADM5120_INTC_REG(IRQ_STATUS_REG) & IRQ_MASK;
+
+	for (i = 0; intsrc; intsrc >>= 1, i++)
+		if (intsrc & 0x1)
+			do_IRQ(i, regs);
+
+	spin_unlock_irqrestore(&mips_irq_lock, flags);
+}
+
+
+void enable_am5120_irq(unsigned int irq)
+{
+	int s;
+
+	/* Disable all interrupts (FIQ/IRQ) */
+	s = mips_int_lock();
+
+	if ((irq < 0) || (irq > INT_LVL_MAX)) 
+		goto err_exit;
+
+	ADM5120_INTC_REG(IRQ_ENABLE_REG) = (1<<irq);
+
+err_exit:
+
+	/* Restore the interrupts states */
+	mips_int_unlock(s);
+}
+
+
+void disable_am5120_irq(unsigned int irq)
+{
+	int s;
+
+	/* Disable all interrupts (FIQ/IRQ) */
+	s = mips_int_lock();
+
+	if ((irq < 0) || (irq > INT_LVL_MAX)) 
+		goto err_exit;
+
+	ADM5120_INTC_REG(IRQ_DISABLE_REG) = (1<<irq);
+
+err_exit:
+	/* Restore the interrupts states */
+	mips_int_unlock(s);
+}
+
+unsigned int startup_am5120_irq(unsigned int irq)
+{
+	enable_am5120_irq(irq);
+	return 0;
+}
+
+void shutdown_am5120_irq(unsigned int irq)
+{
+	disable_am5120_irq(irq);
+}
+
+static inline void ack_am5120_irq(unsigned int irq_nr)
+{
+	ADM5120_INTC_REG(IRQ_DISABLE_REG) = (1 << irq_nr);
+}
+
+
+static void end_am5120_irq(unsigned int irq_nr)
+{
+	ADM5120_INTC_REG(IRQ_ENABLE_REG) = (1 << irq_nr);
+}
+
+
+void set_affinity_am5120_irq(unsigned int irq, cpumask_t mask)
+{
+	return;
+}
+
+	
+static hw_irq_controller am5120_irq_type = {
+	"ADM5120 INTC",
+	startup_am5120_irq,
+	shutdown_am5120_irq,
+	enable_am5120_irq,
+	disable_am5120_irq,
+	ack_am5120_irq,
+	end_am5120_irq,
+	set_affinity_am5120_irq
+};
+
+
+void __init arch_init_irq(void)
+{
+	int i;
+	set_except_vector(0, mipsIRQ);
+	
+	for (i=0; i<=INT_LVL_MAX; i++) {
+		irq_desc[i].status=IRQ_DISABLED;
+		irq_desc[i].action=0;
+		irq_desc[i].depth=1;
+		irq_desc[i].handler=&am5120_irq_type;
+	}
+
+#ifdef CONFIG_REMOTE_DEBUG
+ 	printk("Setting debug traps - please connect the remote debugger.\n");
+
+	set_debug_traps();
+
+	breakpoint();
+#endif
+}
+
diff -ruN linux-2.6.10/arch/mips/am5120/led.c linux-2.6.10-adm.1/arch/mips/am5120/led.c
--- linux-2.6.10/arch/mips/am5120/led.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/am5120/led.c	2005-01-27 21:06:17.000000000 +0100
@@ -0,0 +1,493 @@
+/*
+ * LED interface for WP3200
+ *
+ * Copyright (C) 2002, by Allen Hung
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/fcntl.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include "led.h"
+
+#define BUF_LEN		30
+
+struct LED_DATA  {
+    char sts_buf[BUF_LEN+1];
+    unsigned long sts;
+};
+
+struct LED_DATA led_data[LED_DEV_NUM];
+// sam 01-30-2004 for watchdog
+static struct timer_list watchdog;
+// end sam
+
+static struct timer_list blink_timer[LED_DEV_NUM];
+static char cmd_buf[BUF_LEN+1];
+
+//------------------------------------------------------------
+static long atoh(char *p) 
+{
+    long v = 0, c;
+    while ( (c = *p++) )  {
+        if      ( c >= '0' && c <= '9' )  v = (v << 4) + c - '0';
+        else if ( c >= 'a' && c <= 'f' )  v = (v << 4) + c - 'a' + 0xA;
+        else if ( c >= 'A' && c <= 'F' )  v = (v << 4) + c - 'A' + 0xA;
+        else  break;
+    }
+    return v;
+}
+
+
+#define GPIO_VAL		(*(unsigned long *)0xb20000b8)
+#define GPIO_SEL		(*(unsigned long *)0xb20000bc)
+#define GPIO_SEL_I_O 	(*(unsigned long *)0xb20000b8)
+#define GPIO_O_EN		(*(unsigned long *)0xb20000b8)
+#define INIT_WATCHDOG_REGISTER 0x20
+
+// sam 1-30-2004 LED status 
+// bit map as following
+// BIT 4:0  Link status   -->PHY Link ->1 = up, 0 = down
+#define LINK_STATUS     (*(unsigned long *)0xb2000014)
+#define WATCHDOG_VAL    (*(unsigned long *)0xb20000c0)
+#define WATCHDOG_PERIOD 2000 // unit ms
+#define EXPIRE_TIME     300 // unit 10 ms
+#define CLEAR_TIMEER    0xffffa000l  // bit 14:0 -> count up timer, write 0 to clear
+#define ENABLE_WATCHDOG 0x80000000l  // bit 31 -> 1 enable , 0 disable watchdog
+#define WATCHDOG_SET_TMR_SHIFT 16    // bit 16:30 -> watchdog timer set
+// end sam
+//------------------------------------------------------------
+static void turn_led(int id, int on)
+{
+    unsigned long led_bit = 1 << (id);
+	unsigned long led_bit_val;
+
+	led_bit_val = led_bit << 24;
+	
+    switch ( on ) {
+      case 0:  GPIO_VAL |=  led_bit_val;	break; // LED OFF
+      case 1:  GPIO_VAL &= ~led_bit_val;	break; // LED ON
+      case 2:  GPIO_VAL ^=  led_bit_val;	break; // LED inverse
+    }
+}
+
+static void blink_wrapper(u_long id)
+{
+    u_long sts = led_data[id].sts;
+    if ( (sts & LED_BLINK_CMD) == LED_BLINK_CMD )  {
+	int period = sts & LED_BLINK_PERIOD;
+	blink_timer[id].expires = jiffies + (period * HZ / 1000);
+	turn_led(id, 2);
+	add_timer(&blink_timer[id]);
+    }
+    else if ( sts == LED_ON || sts == LED_OFF )
+	turn_led(id, sts==LED_ON ? 1 : 0);
+}
+//------------------------------------------------------------
+static void get_token_str(char *str, char token[][21], int token_num)
+{
+    int t, i;
+    for ( t = 0 ; t < token_num ; t++ )  {
+    	memset(token[t], 0, 21);
+    	while ( *str == ' ' )  str++;
+    	for ( i = 0 ; str[i] ; i++ )  {
+    	    if ( str[i] == '\t' || str[i] == ' ' || str[i] == '\n' )  break;
+    	    if ( i < 20 )  token[t][i] = str[i];
+    	}
+    	str += i;
+    }
+}
+
+//------------------------------------------------------------
+static void set_led_status_by_str(int id)
+{
+    char token[3][21], *p;
+
+    get_token_str(led_data[id].sts_buf, token, 3);
+    if ( strcmp(token[0], "LED") )   
+        goto set_led_off;
+    if ( !strcmp(token[1], "ON") )  {
+    	turn_led(id, 1);
+    	led_data[id].sts = LED_ON;
+    }
+    else if ( !strcmp(token[1], "OFF") )  {
+	    goto set_led_off;
+    }
+    else if ( !strcmp(token[1], "BLINK") ) {
+    	int period = 0;
+    	p = token[2];
+    	if ( !strcmp(p, "FAST") )
+    	    period = LED_BLINK_FAST & LED_BLINK_PERIOD;
+    	else if ( !strcmp(p, "SLOW") )
+    	    period = LED_BLINK_SLOW & LED_BLINK_PERIOD;
+    	else if ( !strcmp(p, "EXTRA_SLOW") )
+    	    period = LED_BLINK_EXTRA_SLOW & LED_BLINK_PERIOD;
+    	else if ( !strcmp(p, "OFF") )
+	    goto set_led_off;
+	else if ( *p >= '0' && *p <= '9' )  {
+    	while ( *p >= '0' && *p <= '9' )
+    	    period = period * 10 + (*p++) - '0';
+    	if ( period > 10000 )  period = 10000;
+	}
+	else
+    	period = LED_BLINK & LED_BLINK_PERIOD;
+    	if ( period == 0 )
+    	    goto set_led_off;
+	    sprintf(led_data[id].sts_buf, "LED BLINK %d\n", period);
+    	led_data[id].sts = LED_BLINK_CMD + period;
+    	turn_led(id, 2);
+     // Set timer for next blink
+	    del_timer(&blink_timer[id]);
+        blink_timer[id].function = blink_wrapper;
+        blink_timer[id].data = id;
+        init_timer(&blink_timer[id]);
+        blink_timer[id].expires = jiffies + (period * HZ / 1000);
+        add_timer(&blink_timer[id]);
+    }
+    else
+        goto set_led_off;
+    return;
+  set_led_off:
+    strcpy(led_data[id].sts_buf, "LED OFF\n");
+    led_data[id].sts = LED_OFF;
+    turn_led(id, 0);
+}
+
+//----------------------------------------------------------------------
+static int led_read_proc(char *buf, char **start, off_t fpos, int length, int *eof, void *data)
+{
+    int len, dev;
+    for ( len = dev = 0 ; dev < LED_DEV_NUM ; dev++ )  {
+    	len += sprintf(buf+len, "%d: %s", dev, led_data[dev].sts_buf);
+    }
+    len = strlen(buf) - fpos;
+    if ( len <= 0 ) {
+	*start = buf;
+	*eof = 1;
+	return 0;
+    }
+    *start = buf + fpos;
+    if ( len <= length )   *eof = 1;
+    return len < length ? len : length;
+}
+
+//----------------------------------------------------------------------
+static int led_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+    int id = (int)file->private_data;
+
+    switch ( cmd )  {
+      case LED_ON:
+    	strcpy(led_data[id].sts_buf, "LED ON\n");
+	set_led_status_by_str(id);
+	break;
+      case LED_OFF:
+    	strcpy(led_data[id].sts_buf, "LED OFF\n");
+	set_led_status_by_str(id);
+	break;
+      default:
+        if ( (cmd & LED_BLINK_CMD) != LED_BLINK_CMD )
+	    break;
+      case LED_BLINK:
+      case LED_BLINK_FAST:
+      case LED_BLINK_SLOW:
+      case LED_BLINK_EXTRA_SLOW:
+        sprintf(led_data[id].sts_buf, "LED BLINK %d\n", (int)(cmd & LED_BLINK_PERIOD));
+	set_led_status_by_str(id);
+	break;
+    }
+    return 0;
+}
+
+static int led_open(struct inode *inode, struct file *file)
+{
+    int led_id = MINOR(inode->i_rdev);
+    unsigned long led_bit = 1 << (led_id);
+    if ( led_id >= LED_DEV_NUM )
+        return -ENODEV;
+
+    GPIO_SEL_I_O &= ~led_bit;   // 0 to GPIO
+    GPIO_O_EN |= (led_bit << 16);   // 0 to Output
+	
+    file->private_data = (void*)led_id;
+    return 0;
+}
+
+static long led_read(struct file *file, char *buf, size_t count, loff_t *fpos)
+{
+    int  rem, len;
+    int  id = (int)file->private_data;
+    char *p = led_data[id].sts_buf;
+    len = strlen(p);
+    rem = len - *fpos;
+    if ( rem <= 0 )  {
+    	*fpos = len;
+    	return 0;
+    }
+    if ( rem > count )   rem = count;
+    memcpy(buf, p+(*fpos), rem);
+    *fpos += rem;
+    return rem;
+}
+
+static long led_write(struct file *file, char *buf, size_t count, loff_t *fpos)
+{
+    int  len;
+    int  id = (int)file->private_data;
+    char *p = id == REG_MINOR ? cmd_buf : led_data[id].sts_buf;
+    memset(p, 0, BUF_LEN);
+    p += *fpos;
+    len = 0;
+    while ( count > 0 )  {
+    	if ( *fpos < BUF_LEN )  {
+    	    int c = *buf++;
+            p[len] = c>='a' && c<='z' ? c-'a'+'A' : c;
+        }
+    	(*fpos)++;
+	    len++;
+    	count--;
+    }
+    return len;
+}
+
+static int led_flush(struct file *file)
+{
+    int  id = (int)file->private_data;
+    if ( file->f_mode & FMODE_WRITE )
+    	set_led_status_by_str(id);
+    return 0;
+}
+
+static struct file_operations led_fops = {
+    read:	led_read,
+    write:	led_write,
+    flush:	led_flush,
+    ioctl:	led_ioctl,
+    open:	led_open,
+};
+
+//----------------------------------------------
+static unsigned long *reg_addr;
+static int  dump_len;
+
+static int dump_content(char *buf)
+{
+    int  i, j, len;
+    unsigned long *p = reg_addr;
+    j = dump_len/4 + ((dump_len&3) ? 1 : 0);
+    len = sprintf(buf, "Reg Addr = %08lX,  Value = \n", (unsigned long)p);
+    for ( i = 0 ; i < j ; i++, p++ )
+        len += sprintf(buf+len,"%08lX%c", *p, (i&7)==7||i==j-1?'\n':' ');
+    return len;
+}
+
+static long gpio_read(struct file *file, char *buf, size_t count, loff_t *fpos)
+{
+    int  rem, len;
+    int  id = (int)file->private_data;
+    char temp[80*10];
+    if ( id < GPIO_DEV_NUM )  {
+        int  gpio_bit = 1 << id;
+        len = sprintf(temp, "%d\n", ((GPIO_VAL >> 8)&gpio_bit) ? 1 : 0);
+    }
+    else   // REG device
+        len = dump_content(temp);
+    rem = len - *fpos;
+    if ( rem <= 0 )  {
+    	*fpos = len;
+    	return 0;
+    }
+    if ( rem > count )   rem = count;
+    memcpy(buf, temp+(*fpos), rem);
+    *fpos += rem;
+    return rem;
+}
+
+static int gpio_flush(struct file *file)
+{
+    long v, addr;
+    int  id = (int)file->private_data;
+
+    if ( id == REG_MINOR && (file->f_mode & FMODE_WRITE) )  {
+        char token[3][21], *p;
+        get_token_str(cmd_buf, token, 3);
+        // get reg address
+        p = token[0];
+        if ( *p == 0 )   return 0;
+        addr = atoh(p);
+        //---------------------
+        p = token[1];
+        if ( *p == 'W' )  {
+            int width = 0;
+            if ( !strcmp(p, "W") || !strcmp(p, "WW") )
+                width = 4;
+            else if ( !strcmp(p, "WH") )
+                width = 2;
+            else if ( !strcmp(p, "WB") )
+                width = 1;
+            else
+                return 0;
+            p = token[2];
+            if ( *p == 0 )   return 0;
+            v = atoh(p);
+            switch ( width )  {
+              case 1:  *((char *)addr) = (v & 0xFF);    break;
+              case 2:  *((short*)addr) = (v & 0xFFFF);  break;
+              case 4:  *((long *)addr) =  v;            break;
+            }
+        }
+        else  { // get dump len
+            char temp[80*10];
+            reg_addr = (unsigned long *)(addr & ~3);
+            dump_len = 4;
+            if ( *p )   {
+                dump_len = atoh(p);
+                dump_len = dump_len < 4 ? 4 : dump_len > 32*10 ? 32*10 : dump_len;
+            }
+            dump_content(temp);
+            printk( KERN_INFO "%s", temp);
+        }
+        cmd_buf[0] = 0;
+    }
+    return 0;
+}
+
+static int gpio_open(struct inode *inode, struct file *file)
+{
+    int id = MINOR(inode->i_rdev);
+    if ( id >= GPIO_DEV_NUM && id != REG_MINOR )
+        return -ENODEV;
+    if ( id < GPIO_DEV_NUM )  {
+        int gpio_bit = 1 << id;
+		
+		GPIO_SEL = 0;
+      	GPIO_SEL |= gpio_bit;   // bit=0 for GPIO
+    }
+    file->private_data = (void*)id;
+    return 0;
+}
+
+static struct file_operations gpio_fops = {
+    read:	gpio_read,
+    open:	gpio_open,
+    flush:	gpio_flush,
+    write:	led_write,
+};
+
+//----------------------------------------------
+static void watchdog_wrapper(unsigned int period)
+{
+	// clear timer count
+	WATCHDOG_VAL &= CLEAR_TIMEER;
+	watchdog.expires = jiffies + (period * HZ / 1000);
+	add_timer(&watchdog);
+}
+//----------------------------------------------
+static int init_status;
+
+#define INIT_REGION	        0x01
+#define INIT_LED_REGISTER	0x02
+#define INIT_LED_PROC_READ	0x04
+#define INIT_GPIO_REGISTER	0x08
+
+static void led_exit(void)
+{
+    int id;
+    for ( id = 0 ; id < LED_DEV_NUM ; id++ )  {
+        del_timer(&blink_timer[id]);
+        turn_led(id, 0);
+    }
+    if ( init_status & INIT_LED_PROC_READ )
+    	remove_proc_entry("driver/led", NULL);
+    	
+    if ( init_status & INIT_LED_REGISTER )
+    	unregister_chrdev(LED_MAJOR, "led");
+
+    if ( init_status & INIT_GPIO_REGISTER )
+    	unregister_chrdev(GPIO_MAJOR, "gpio");
+
+    if ( init_status & INIT_REGION )
+    	release_region(GPIO_IO_BASE, GPIO_IO_EXTENT);
+}
+
+static int __init led_init(void)
+{
+    int result, id;
+    init_status = 0;
+	
+  //---- request region --------------------------
+  /*
+    if ( check_region(GPIO_IO_BASE, GPIO_IO_EXTENT) )  {
+	    printk(KERN_ERR "gpio: I/O port %lX is not free.\n", GPIO_IO_BASE);
+	    return -EIO;
+    }
+    request_region(GPIO_IO_BASE, GPIO_IO_EXTENT, "gpio");
+    init_status |= INIT_REGION;
+  */
+  //----- register device (LED)-------------------------
+    result = register_chrdev(LED_MAJOR, "led", &led_fops);
+    if ( result < 0 )   {
+    	printk(KERN_ERR "led: can't register char device\n" );
+    	led_exit();
+    	return result;
+    }
+    init_status |= INIT_LED_REGISTER;
+  //----- register device (GPIO)-------------------------
+    result = register_chrdev(GPIO_MAJOR, "gpio", &gpio_fops);
+    if ( result < 0 )   {
+    	printk(KERN_ERR "gpio: can't register char device\n" );
+    	led_exit();
+    	return result;
+    }
+    init_status |= INIT_GPIO_REGISTER;
+  // sam 1-30-2004 LAN Status
+  // ----- register device (LAN_STATUS)-------------------
+/*    result = register_chrdev(LAN_STATUS_MAJOR, "lanSt", &lanSt_fops);
+    if ( result < 0 )   {
+    	printk(KERN_ERR "lanSt: can't register char device\n" );
+    	led_exit();
+    	return result;
+    }
+    init_status |= INIT_LAN_STATUS_REGISTER;
+	*/
+ // -----------init watchdog timer-------------------------
+	 //del_timer(&blink_timer[id]);
+	 WATCHDOG_VAL = ENABLE_WATCHDOG | ( EXPIRE_TIME  << WATCHDOG_SET_TMR_SHIFT);
+    watchdog.function = watchdog_wrapper;
+    watchdog.data = WATCHDOG_PERIOD;
+    init_timer(&watchdog);
+    watchdog.expires = jiffies + (WATCHDOG_PERIOD * HZ / 1000);
+    add_timer(&watchdog);
+    init_status |= INIT_WATCHDOG_REGISTER;
+  
+ // end sam   
+  //------ read proc -------------------
+    if ( !create_proc_read_entry("driver/led", 0, 0, led_read_proc, NULL) )  {
+	printk(KERN_ERR "led: can't create /proc/driver/led\n");
+    	led_exit();
+    	return -ENOMEM;
+    }
+    init_status |= INIT_LED_PROC_READ;
+  //------------------------------
+    reg_addr = (unsigned long *)0xB4000000;
+    dump_len = 4;
+    for ( id = 0 ; id < LED_DEV_NUM ; id++ )  {
+    	strcpy(led_data[id].sts_buf, "LED OFF\n" );
+    	set_led_status_by_str(id);
+    }
+    printk(KERN_INFO "LED & GPIO Driver " LED_VERSION "\n");
+    return 0;
+}
+
+module_init(led_init);
+module_exit(led_exit);
+EXPORT_NO_SYMBOLS;
diff -ruN linux-2.6.10/arch/mips/am5120/led.h linux-2.6.10-adm.1/arch/mips/am5120/led.h
--- linux-2.6.10/arch/mips/am5120/led.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/am5120/led.h	2005-01-27 21:06:17.000000000 +0100
@@ -0,0 +1,26 @@
+#ifndef _LED_H_INCLUDED
+#define _LED_H_INCLUDED
+
+#include <linux/config.h>
+
+#define LED_VERSION 		"v1.0"
+#define LED_MAJOR       	166
+#define LED_DEV_NUM		    8 
+#define LED_GPIO_START      1
+#define GPIO_MAJOR       	167
+#define GPIO_DEV_NUM		16
+#define REG_MINOR           128
+//#define GPIO_IO_BASE        0xB4002480
+#define GPIO_IO_BASE        ((unsigned long)0xb20000b8)
+#define GPIO_IO_EXTENT		0x40
+
+#define LED_ON              0x010000
+#define LED_OFF             0x020000
+#define LED_BLINK_CMD       0x030000
+#define LED_BLINK_PERIOD    0x00FFFF
+#define LED_BLINK           (LED_BLINK_CMD|1000)
+#define LED_BLINK_FAST      (LED_BLINK_CMD|250)
+#define LED_BLINK_SLOW      (LED_BLINK_CMD|500)
+#define LED_BLINK_EXTRA_SLOW    (LED_BLINK_CMD|2000)
+
+#endif
diff -ruN linux-2.6.10/arch/mips/am5120/memory.c linux-2.6.10-adm.1/arch/mips/am5120/memory.c
--- linux-2.6.10/arch/mips/am5120/memory.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/am5120/memory.c	2005-01-27 21:06:17.000000000 +0100
@@ -0,0 +1,84 @@
+/*****************************************************************************
+;
+;   (C) Unpublished Work of ADMtek Incorporated.  All Rights Reserved.
+;
+;       THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
+;       PROPRIETARY AND TRADESECRET INFORMATION OF ADMTEK INCORPORATED.
+;       ACCESS TO THIS WORK IS RESTRICTED TO (I) ADMTEK EMPLOYEES WHO HAVE A
+;       NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR ASSIGNMENTS
+;       AND (II) ENTITIES OTHER THAN ADMTEK WHO HAVE ENTERED INTO APPROPRIATE
+;       LICENSE AGREEMENTS.  NO PART OF THIS WORK MAY BE USED, PRACTICED,
+;       PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,
+;       ABBRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
+;       TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF ADMTEK.
+;       ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD
+;       SUBJECT THE PERPERTRATOR TO CRIMINAL AND CIVIL LIABILITY.
+;
+;------------------------------------------------------------------------------
+;
+;    Project : ADM5120
+;    Creator : daniell@admtek.com.tw
+;    File    : arch/mips/am5120/memory.c
+;	 Date    : 2003.3.4
+;    Abstract: 
+;
+;Modification History:
+;
+;	Jeroen Vreeken (pe1rxq@amsat.org)
+;	Simplified by ripping out fake env stuff.
+;
+;*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/am5120/prom.h>
+#include <asm/am5120/adm5120.h>
+
+
+/* References to section boundaries */
+extern char _end;
+
+#define PFN_ALIGN(x)    (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK)
+#define ADM5120_MEMSIZE	0x1000000 /* 16 Mb */
+
+void __init prom_meminit(void)
+{
+	unsigned long base=CPHYSADDR(PFN_ALIGN(&_end));
+	unsigned long size=ADM5120_MEMSIZE;
+
+	add_memory_region(base, size-base, BOOT_MEM_RAM);
+}
+
+
+void __init prom_free_prom_memory (void)
+{
+	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;
+
+		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;
+		}
+	}
+
+	printk("Freeing prom memory: %ldkb freed\n", freed >> 10);
+}
+
+
diff -ruN linux-2.6.10/arch/mips/am5120/mipsIRQ.S linux-2.6.10-adm.1/arch/mips/am5120/mipsIRQ.S
--- linux-2.6.10/arch/mips/am5120/mipsIRQ.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/am5120/mipsIRQ.S	2005-01-27 21:06:17.000000000 +0100
@@ -0,0 +1,135 @@
+/*
+ * 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>
+
+#define STATUS_IE	0x00000001
+
+/* 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		
+	mfc0	s1, CP0_STATUS
+	and     s0, s0, s1
+	
+	/* First we check for r4k counter/timer IRQ. */
+	andi	a0, s0, CAUSEF_IP7
+	beq		a0, zero, 1f
+	nop
+
+	move	a0, sp
+	jal		mips_timer_interrupt
+	nop
+
+	j		ret_from_irq
+	nop				
+
+1:
+	andi	a0, s0, CAUSEF_IP2
+	beq		a0, zero, 1f	
+	nop
+	
+	move	a0, sp			
+	jal		am5120_hw0_irqdispatch	 
+	nop
+1:
+	j		ret_from_irq
+	nop							
+
+END(mipsIRQ)
+
+
+LEAF(mips_int_lock)
+	.set noreorder
+	mfc0	v0, CP0_STATUS
+	li		v1, ~STATUS_IE
+	and		v1, v1, v0
+	mtc0	v1, CP0_STATUS
+	j		ra
+	and		v0, v0, STATUS_IE
+	.set reorder
+END(mips_int_lock)
+
+
+LEAF(mips_int_unlock)
+	mfc0	v0, CP0_STATUS
+	and		a0, a0, STATUS_IE
+	or		v0, v0, a0
+	mtc0	v0, CP0_STATUS
+	j		ra
+	nop
+END(mips_int_unlock)
+
diff -ruN linux-2.6.10/arch/mips/am5120/pci.c linux-2.6.10-adm.1/arch/mips/am5120/pci.c
--- linux-2.6.10/arch/mips/am5120/pci.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/am5120/pci.c	2005-01-27 21:06:17.000000000 +0100
@@ -0,0 +1,214 @@
+/*****************************************************************************
+;
+;   (C) Unpublished Work of ADMtek Incorporated.  All Rights Reserved.
+;
+;       THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
+;       PROPRIETARY AND TRADESECRET INFORMATION OF ADMTEK INCORPORATED.
+;       ACCESS TO THIS WORK IS RESTRICTED TO (I) ADMTEK EMPLOYEES WHO HAVE A
+;       NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR ASSIGNMENTS
+;       AND (II) ENTITIES OTHER THAN ADMTEK WHO HAVE ENTERED INTO APPROPRIATE
+;       LICENSE AGREEMENTS.  NO PART OF THIS WORK MAY BE USED, PRACTICED,
+;       PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,
+;       ABBRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
+;       TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF ADMTEK.
+;       ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD
+;       SUBJECT THE PERPERTRATOR TO CRIMINAL AND CIVIL LIABILITY.
+;
+;------------------------------------------------------------------------------
+;
+;    Project : ADM5120
+;    Creator : 
+;    File    : 
+;    Abstract: 
+;
+;Modification History:
+; 
+;
+;*****************************************************************************/
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+#ifdef CONFIG_PCI
+
+#include <asm/pci_channel.h>
+#include <asm/am5120/adm5120.h>
+
+
+volatile u32* pci_config_address_reg = (volatile u32*)KSEG1ADDR(0x115ffff0);
+volatile u32* pci_config_data_reg = (volatile u32*)KSEG1ADDR(0x115ffff8);
+
+#define PCI_ENABLE 0x80000000
+#define PCI_CMM_IOACC_EN		0x1
+#define PCI_CMM_MEMACC_EN		0x2
+#define PCI_CMM_MASTER_EN		0x4
+#define PCI_CMM_DEF				(PCI_CMM_IOACC_EN | PCI_CMM_MEMACC_EN | PCI_CMM_MASTER_EN)
+
+#define PCI_DEF_CACHE_LINE_SZ	4
+#define PCI_DEF_LATENCY_TIMER	0x20
+#define PCI_DEF_CACHE_LATENCY	((PCI_DEF_LATENCY_TIMER << 8) | PCI_DEF_CACHE_LINE_SZ)
+
+
+                             
+#define cfgaddr(dev, where) (((dev->bus->number & 0xff) << 0x10) |  \
+                             ((dev->devfn & 0xff) << 0x08) |        \
+                             (where & 0xfc)) | PCI_ENABLE
+
+
+/*
+ * We can't address 8 and 16 bit words directly.  Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int am5120_read_config_byte (struct pci_dev *dev,
+                                   int where, unsigned char *val)
+{
+    *pci_config_address_reg = cfgaddr(dev, where);
+    *val = ((*pci_config_data_reg) >> ((where&3)<<3)) & 0xff;
+//	printk("pci_read_byte 0x%x == 0x%x\n", where, *val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int am5120_read_config_word (struct pci_dev *dev,
+                                   int where, unsigned short *val)
+{
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	*pci_config_address_reg = cfgaddr(dev, where);
+	*val = ((*pci_config_data_reg) >> ((where&3)<<3)) & 0xffff;
+//	printk("pci_read_word 0x%x == 0x%x\n", where, *val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int am5120_read_config_dword (struct pci_dev *dev,
+                                    int where, unsigned int *val)
+{
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	*pci_config_address_reg = cfgaddr(dev, where);
+	*val = (*pci_config_data_reg);
+//	printk("pci_read_dword 0x%x == 0x%x\n", where, *val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int am5120_write_config_byte (struct pci_dev *dev,
+                                    int where, unsigned char val)
+{
+	*pci_config_address_reg = cfgaddr(dev, where);
+	*(volatile u8 *)(((int)pci_config_data_reg) + (where & 3)) = val;
+//	printk("pci_write_byte 0x%x = 0x%x\n", where, val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int am5120_write_config_word (struct pci_dev *dev,
+                                    int where, unsigned short val)
+{
+	if (where & 1)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	*pci_config_address_reg = cfgaddr(dev, where);
+	*(volatile u16 *)(((int)pci_config_data_reg) + (where & 2)) = (val);
+//	printk("pci_write_word 0x%x = 0x%x\n", where, val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int am5120_write_config_dword (struct pci_dev *dev,
+                                     int where, unsigned int val)
+{
+	if (where & 3)
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	*pci_config_address_reg = cfgaddr(dev, where);
+	*pci_config_data_reg = (val);
+//	printk("pci_write_dword 0x%x = 0x%x\n", where, val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+
+struct pci_ops am5120_pci_ops = {
+	am5120_read_config_byte,
+	am5120_read_config_word,
+	am5120_read_config_dword,
+	am5120_write_config_byte,
+	am5120_write_config_word,
+	am5120_write_config_dword
+};
+struct resource pciioport_resource = {
+	"pci IO space", 
+	0x11500000,  
+	0x115ffff0-1,
+	IORESOURCE_IO
+};
+
+struct resource pciiomem_resource = {
+	"pci memory space", 
+	0x11400000,
+	0x11500000-1,
+	IORESOURCE_MEM
+};
+
+static void am5120_pcibios_fixup(struct pci_dev *dev)
+{
+	printk("am5120 fix up\n");
+	pci_write_config_word(dev, PCI_COMMAND, PCI_CMM_DEF);
+	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, PCI_DEF_CACHE_LATENCY);
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0);
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0);
+
+}
+
+struct pci_channel mips_pci_channels[] = {
+	{ &am5120_pci_ops, &pciioport_resource, &pciiomem_resource,0,0xff},
+	{ NULL, NULL, NULL , NULL , NULL}
+};
+
+
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+        return 1;
+}
+
+void __init pcibios_fixup(void)
+{
+	printk("pcibios_fixup\n");
+}
+
+void __init pcibios_fixup_irqs(void)
+{
+   struct pci_dev *dev;
+   int slot_num;
+
+   printk("fixup IRQ\n");	
+   pci_for_each_dev(dev) {
+      slot_num = PCI_SLOT(dev->devfn);
+      switch(slot_num) {
+         case 2: 
+		 dev->irq = 6;  
+		 pci_write_config_word(dev, PCI_INTERRUPT_LINE, 6);
+		 break;
+         case 3: 
+		 dev->irq = 7;  
+		 pci_write_config_word(dev, PCI_INTERRUPT_LINE, 7);
+		 break;
+         case 4: 
+		 dev->irq = 8;  
+		 pci_write_config_word(dev, PCI_INTERRUPT_LINE, 8);
+		 break;
+         default: break;
+      }
+   }
+}
+
+void __init pcibios_fixup_resources(struct pci_dev *dev)
+{
+	printk("fixup resource\n");
+	if (dev->devfn == 0)
+	{
+		printk("fixup host controller\n");
+		am5120_pcibios_fixup(dev);
+	}
+}
+
+#endif /* CONFIG_PCI */
diff -ruN linux-2.6.10/arch/mips/am5120/prom.c linux-2.6.10-adm.1/arch/mips/am5120/prom.c
--- linux-2.6.10/arch/mips/am5120/prom.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/am5120/prom.c	2005-01-27 21:06:17.000000000 +0100
@@ -0,0 +1,70 @@
+/*****************************************************************************
+;
+;   (C) Unpublished Work of ADMtek Incorporated.  All Rights Reserved.
+;
+;       THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
+;       PROPRIETARY AND TRADESECRET INFORMATION OF ADMTEK INCORPORATED.
+;       ACCESS TO THIS WORK IS RESTRICTED TO (I) ADMTEK EMPLOYEES WHO HAVE A
+;       NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR ASSIGNMENTS
+;       AND (II) ENTITIES OTHER THAN ADMTEK WHO HAVE ENTERED INTO APPROPRIATE
+;       LICENSE AGREEMENTS.  NO PART OF THIS WORK MAY BE USED, PRACTICED,
+;       PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,
+;       ABBRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
+;       TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF ADMTEK.
+;       ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD
+;       SUBJECT THE PERPERTRATOR TO CRIMINAL AND CIVIL LIABILITY.
+;
+;------------------------------------------------------------------------------
+;
+;    Project : ADM5120
+;    Creator : daniell@admtek.com.tw
+;    File    : arch/mips/am5120/prom.c
+;	 Date    : 2003.3.4
+;    Abstract: 
+;
+;Modification History:
+;
+;	Jeroen Vreeken (pe1rxq@amsat.org)
+;	Ripped out cmdline and env stuff left over from YAMON cut-and-paste.
+;
+;*****************************************************************************/
+
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+
+extern void am5120_serial_console_init(void);
+void setup_prom_printf(int);
+void prom_printf(char *, ...);
+void prom_meminit(void);
+
+/*
+ * initialize the prom module.
+ */
+void __init prom_init(void)
+{
+	/* you should these macros defined in include/asm/bootinfo.h */
+	mips_machgroup = MACH_GROUP_ADM_GW;
+	mips_machtype = MACH_ADM_GW_5120;
+
+	/* set IO port base to zero */ 
+
+	/* init print from uart0 */
+	setup_prom_printf(0);
+
+	prom_printf("\nLINUX started...\n");
+	
+	/* init command line */
+	strcpy(&(arcs_cmdline[0]), ""/*"root=/dev/ram0 console=ttyS0"*/);
+
+	/* init memory map */
+	prom_meminit();
+}
+
+
diff -ruN linux-2.6.10/arch/mips/am5120/serial.c linux-2.6.10-adm.1/arch/mips/am5120/serial.c
--- linux-2.6.10/arch/mips/am5120/serial.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/am5120/serial.c	2005-01-27 21:06:17.000000000 +0100
@@ -0,0 +1,1711 @@
+/*****************************************************************************
+;
+;   (C) Unpublished Work of ADMtek Incorporated.  All Rights Reserved.
+;
+;       THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
+;       PROPRIETARY AND TRADESECRET INFORMATION OF ADMTEK INCORPORATED.
+;       ACCESS TO THIS WORK IS RESTRICTED TO (I) ADMTEK EMPLOYEES WHO HAVE A
+;       NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR ASSIGNMENTS
+;       AND (II) ENTITIES OTHER THAN ADMTEK WHO HAVE ENTERED INTO APPROPRIATE
+;       LICENSE AGREEMENTS.  NO PART OF THIS WORK MAY BE USED, PRACTICED,
+;       PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,
+;       ABBRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
+;       TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF ADMTEK.
+;       ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD
+;       SUBJECT THE PERPERTRATOR TO CRIMINAL AND CIVIL LIABILITY.
+;
+;------------------------------------------------------------------------------
+;
+;    Project : ADM5120
+;    Creator : daniell@admtek.com.tw
+;    File    : arch/mips/am5120/printf.c
+;	 Date    : 2003.3.4
+;    Abstract: 
+;
+;Modification History:
+;
+;*****************************************************************************/
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+#include <linux/serial_reg.h>
+#include <linux/console.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/devpts_fs.h>
+
+#include <linux/major.h>
+#include <linux/string.h>
+#include <linux/fcntl.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/serial.h>
+#include <asm/am5120/adm5120.h>
+
+
+//#define SERIAL_DEBUG_OPEN	1
+//#define SERIAL_DEBUG_INTR	1
+
+static struct tty_driver dev_tty_driver;
+
+/*
+ * IN_W
+ */
+static inline unsigned long IN_W(unsigned long _addr)
+{
+	return (*(volatile unsigned long *)(_addr));
+}
+
+
+/*
+ * OUT_W
+ */
+static inline void OUT_W(unsigned long _addr, unsigned long _value)
+{
+	(*((volatile unsigned long *)(_addr))) = _value;
+}
+
+
+/*
+ * serial_in
+ */
+static unsigned int serial_in(struct async_struct *info, int offset)
+{
+	return IN_W(info->port + offset);
+}
+
+
+/*
+ * serial_out
+ */
+static void serial_out(struct async_struct *info, int offset,
+				int value)
+{
+	OUT_W(info->port + offset, value);
+}
+
+
+/*
+ * serial state 
+ */
+static struct serial_state rs_table[] = 
+{
+	{baud_base:UART_115200bps_DIVISOR, port:KSEG1ADDR(UART0_BASE), irq:1, flags:STD_COM_FLAGS, type:SERIAL_IO_MEM}
+};
+
+
+/*-------------------------------------------------------
+ * prom_printf 
+ * 
+ *-----------------------------------------------------*/
+/*
+ * Hooks to fake "prom" console I/O before devices 
+ * are fully initialized. 
+ */
+static struct async_struct prom_port_info = {0};
+
+void __init setup_prom_printf(int tty_no) 
+{
+	struct serial_state *ser = &rs_table[tty_no];
+
+	prom_port_info.state = ser;
+	prom_port_info.magic = SERIAL_MAGIC;
+	prom_port_info.port = ser->port;
+	prom_port_info.flags = ser->flags;
+
+	/* set baudrate to 115200 */
+	serial_out(&prom_port_info, UART_LCR_L_REG, prom_port_info.state->baud_base); 
+	serial_out(&prom_port_info, UART_LCR_M_REG, prom_port_info.state->baud_base >> 8);
+	
+	/* Set default line mode */
+	serial_out(&prom_port_info, UART_LCR_H_REG, UART_WLEN_8BITS | UART_ENABLE_FIFO);
+
+	/* Enable uart port */
+	serial_out(&prom_port_info, UART_CR_REG, UART_PORT_EN);
+}
+
+
+/* 
+ * putPromChar
+ */
+int putPromChar(char c)
+{
+	if (!prom_port_info.state) { 	/* need to init device first */
+		return 0;
+	}
+
+	while ((serial_in(&prom_port_info, UART_FR_REG) &
+	    UART_TX_FIFO_FULL) != 0);
+
+	serial_out(&prom_port_info, UART_DR_REG, c);
+
+	return 1;
+}
+
+
+/* 
+ * getPromChar
+ */
+char getPromChar(void)
+{
+	if (!prom_port_info.state) 	/* need to init device first */
+		return 0;
+
+	if ((serial_in(&prom_port_info, UART_FR_REG) & UART_RX_FIFO_EMPTY))
+		return 0;
+
+	return(serial_in(&prom_port_info, UART_DR_REG));
+}
+
+
+static char buf[1024];
+
+/*
+ * prom_printf
+ */
+void __init prom_printf(char *fmt, ...)
+{
+	va_list args;
+	int l;
+	char *p, *buf_end;
+	long flags;
+
+	int putPromChar(char);
+
+	/* Low level, brute force, not SMP safe... */
+	save_and_cli(flags);
+	va_start(args, fmt);
+	l = vsprintf(buf, fmt, args); /* hopefully i < sizeof(buf) */
+	va_end(args);
+
+	buf_end = buf + l;
+
+	for (p = buf; p < buf_end; p++) {
+		/* Crude cr/nl handling is better than none */
+		if(*p == '\n')putPromChar('\r');
+		putPromChar(*p);
+	}
+	restore_flags(flags);
+}
+
+
+/*-------------------------------------------------------
+ * console driver
+ * 
+ *-----------------------------------------------------*/
+/*
+ *	Print a string to the serial port trying not to disturb
+ *	any possible real use of the port...
+ *
+ *	The console_lock must be held when we get here.
+ */
+static void serial_console_write(struct console *co, const char *s,
+				unsigned count)
+{
+	int i;
+
+	for (i = 0; i < count; i++, s++)
+	{
+		if (*s == '\n')
+			putPromChar('\r');
+		putPromChar(*s);
+	}
+}
+
+
+/*
+ *	Receive character from the serial port
+ */
+static int serial_console_wait_key(struct console *co)
+{
+	return 0;
+}
+
+
+/*
+ * Get serial console device
+ */
+static struct tty_driver *serial_console_device(struct console *c, int *index)
+{
+	*index=c->index;
+	return &dev_tty_driver;
+}
+
+
+/*
+ *	Setup initial baud/bits/parity. We do two things here:
+ *	- construct a cflag setting for the first rs_open()
+ *	- initialize the serial port
+ *	Return non-zero if we didn't find a serial port.
+ */
+static int __init serial_console_setup(struct console *co, char *options)
+{
+	return 0;
+}
+
+
+/* 
+ * Console data structure
+ */
+static struct console sercons = {
+	name:		"ttyS",
+	write:		serial_console_write,
+	device:		serial_console_device,
+//	wait_key:	serial_console_wait_key,
+	setup:		serial_console_setup,
+	flags:		CON_PRINTBUFFER,
+	index:		-1,
+};
+
+/*
+ *	Register console.
+ */
+static int __init am5120_serial_console_init(void)
+{
+	register_console(&sercons);
+	return 0;
+}
+console_initcall(am5120_serial_console_init);
+
+/*------------------------------------------------------
+ * Register tty driver
+ *
+ *----------------------------------------------------*/
+
+static char *serial_version = "0.01";
+static char *serial_revdate = "2003-04-17";
+
+#define LOCAL_VERSTRING ""
+
+#define NR_PORTS	(sizeof(rs_table)/sizeof(struct serial_state))
+#define WAKEUP_CHARS 256
+#define RS_ISR_PASS_LIMIT 256
+
+static unsigned char *tmp_buf;
+#ifdef DECLARE_MUTEX
+static DECLARE_MUTEX(tmp_buf_sem);
+#else
+static struct semaphore tmp_buf_sem = MUTEX;
+#endif
+
+static int serial_refcount;
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+static unsigned char *tmp_buf = 0;
+static struct async_struct *IRQ_ports[NR_IRQS] = {0};
+
+
+
+
+static void do_softint(void *private_)
+{
+	struct async_struct	*info = (struct async_struct *) private_;
+	struct tty_struct	*tty;
+	
+	tty = info->tty;
+	if (!tty)
+		return;
+
+	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &info->event)) {
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+		wake_up_interruptible(&tty->poll_wait);
+#endif
+	}
+}
+
+
+static int get_async_struct(int line, struct async_struct **ret_info)
+{
+	struct async_struct *info;
+	struct serial_state *sstate;
+
+	sstate = rs_table + line;
+	sstate->count++;
+	if (sstate->info) {
+		*ret_info = sstate->info;
+		return 0;
+	}
+
+	info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
+	if (!info) {
+		sstate->count--;
+		return -ENOMEM;
+	}
+
+	memset(info, 0, sizeof(struct async_struct));
+	init_waitqueue_head(&info->open_wait);
+	init_waitqueue_head(&info->close_wait);
+	init_waitqueue_head(&info->delta_msr_wait);
+	info->magic = SERIAL_MAGIC;
+	info->port = sstate->port;
+	info->flags = sstate->flags;
+	info->io_type = sstate->io_type;
+	info->iomem_base = sstate->iomem_base;
+	info->iomem_reg_shift = sstate->iomem_reg_shift;
+	info->xmit_fifo_size = sstate->xmit_fifo_size;
+	info->line = line;
+	INIT_WORK(&info->work, do_softint, info);
+//	info->tqueue.routine = do_softint;
+//	info->tqueue.data = info;
+	info->state = sstate;
+	if (sstate->info) {
+		kfree(info);
+		*ret_info = sstate->info;
+		return 0;
+	}
+	*ret_info = sstate->info = info;
+	return 0;
+}
+
+
+static void transmit_chars(struct async_struct *info, int *intr_done)
+{
+	if (info->x_char) {
+		serial_out(info, UART_DR_REG, info->x_char);
+		info->state->icount.tx++;
+		info->x_char = 0;
+		if (intr_done)
+			*intr_done = 0;
+		return;
+	}
+
+	if (info->xmit.head == info->xmit.tail
+	    || info->tty->stopped
+	    || info->tty->hw_stopped) {
+		info->IER &= ~UART_TX_INT_EN;
+		serial_out(info, UART_CR_REG, info->IER);
+		return;
+	}
+	
+	do {
+		while ((serial_in(info, UART_FR_REG) & UART_TX_FIFO_FULL) != 0)
+			;
+
+		serial_out(info, UART_DR_REG, info->xmit.buf[info->xmit.tail]);
+		info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
+		info->state->icount.tx++;
+		if (info->xmit.head == info->xmit.tail)
+			break;
+	} while (1);
+	
+	//if (CIRC_CNT(info->xmit.head,
+	//	     info->xmit.tail,
+	//	     SERIAL_XMIT_SIZE) < WAKEUP_CHARS)
+		//rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
+
+#ifdef SERIAL_DEBUG_INTR
+	printk("THRE...");
+#endif
+
+	if (intr_done)
+		*intr_done = 0;
+
+	if (info->xmit.head == info->xmit.tail) {
+		info->IER &= ~UART_TX_INT_EN;
+		serial_out(info, UART_CR_REG, info->IER);
+	}
+}
+
+
+
+static void receive_chars(struct async_struct *info,
+				 struct pt_regs * regs)
+{
+	struct tty_struct *tty = info->tty;
+	unsigned char ch;
+	//int ignored = 0;
+	struct	async_icount *icount;
+	unsigned int status;
+	unsigned int rsr_flag;
+
+	icount = &info->state->icount;
+
+	do {
+		ch = serial_in(info, UART_DR_REG);
+
+		rsr_flag = serial_in(info, UART_RSR_REG);
+		serial_out(info, UART_RSR_REG, rsr_flag);
+
+		if (rsr_flag & UART_RX_ERROR)
+			goto ignore_char;
+			
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+			goto ignore_char;
+
+		*tty->flip.char_buf_ptr = ch;
+		icount->rx++;
+		
+#ifdef SERIAL_DEBUG_INTR
+		printk("DR%02x...", ch);
+#endif
+		*tty->flip.flag_buf_ptr = 0;
+
+		tty->flip.flag_buf_ptr++;
+		tty->flip.char_buf_ptr++;
+		tty->flip.count++;
+
+		status = serial_in(info, UART_FR_REG);
+
+	} while (!(status & UART_RX_FIFO_EMPTY));
+
+ignore_char:
+
+	tty_flip_buffer_push(tty);
+}
+
+
+/*
+ * This is the serial driver's interrupt routine for a single port
+ */
+irqreturn_t rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	int status;
+	int pass_counter = 0;
+	struct async_struct * info;
+	int handled=IRQ_NONE;
+	
+#ifdef SERIAL_DEBUG_INTR
+	printk("rs_interrupt(%d)...", irq);
+#endif
+
+	info = IRQ_ports[irq];
+	if (!info || !info->tty)
+		return handled;
+
+	do {
+		status = serial_in(info, UART_IIR_REG);
+
+		if (status & (UART_RX_INT | UART_RX_TIMEOUT_INT))
+		{
+			//if ((serial_in(info, UART_FR_REG) & UART_RX_FIFO_EMPTY))
+			//	break;
+			handled=IRQ_HANDLED;
+			receive_chars(info, regs);
+		}
+
+		if (status & UART_TX_INT)
+		{
+			handled=IRQ_HANDLED;
+			transmit_chars(info, 0);
+		}
+		
+		if (pass_counter++ > RS_ISR_PASS_LIMIT) {
+			break;
+		}
+
+	} while (serial_in(info, UART_IIR_REG) & (UART_RX_INT | UART_RX_TIMEOUT_INT | UART_TX_INT));
+
+	info->last_active = jiffies;
+	return handled;
+}
+
+
+static int startup(struct async_struct * info)
+{
+	unsigned long flags;
+	int	retval=0;
+	irqreturn_t (*handler)(int, void *, struct pt_regs *);
+	struct serial_state *state= info->state;
+	unsigned long page;
+
+	if (info->flags & ASYNC_INITIALIZED) 
+		return retval;
+
+	page = get_zeroed_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	save_flags(flags); 
+	
+	cli();
+
+	if (!CONFIGURED_SERIAL_PORT(state) || !state->type) 
+	{
+		if (info->tty)
+			set_bit(TTY_IO_ERROR, &info->tty->flags);
+		free_page(page);
+		goto errout;
+	}
+	
+	if (info->xmit.buf)
+		free_page(page);
+	else
+		info->xmit.buf = (unsigned char *) page;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("starting up ttyS%d (irq %d)...", info->line, state->irq);
+#endif
+
+	/*
+	 * Allocate the IRQ if necessary
+	 */
+	if ((!IRQ_ports[state->irq] || !IRQ_ports[state->irq]->next_port)) 
+	{
+		if (IRQ_ports[state->irq]) 
+		{
+			retval = -EBUSY;
+			goto errout;
+		} 
+		else 
+			handler = rs_interrupt;
+
+		retval = request_irq(state->irq, handler, SA_SHIRQ,
+							"serial", &IRQ_ports[state->irq]);
+		if (retval) 
+		{
+			if (capable(CAP_SYS_ADMIN)) 
+			{
+				if (info->tty)
+					set_bit(TTY_IO_ERROR, &info->tty->flags);
+			}
+			goto errout;
+		}
+	}
+
+	/*
+	 * Insert serial port into IRQ chain.
+	 */
+	info->prev_port = 0;
+	info->next_port = IRQ_ports[state->irq];
+	
+	if (info->next_port)
+		info->next_port->prev_port = info;
+	
+	IRQ_ports[state->irq] = info;
+
+	/*
+	 * Now, initialize the UART 
+	 */
+	serial_out(info, UART_LCR_L_REG, info->state->baud_base); 
+	serial_out(info, UART_LCR_M_REG, info->state->baud_base >> 8);
+	serial_out(info, UART_LCR_H_REG, (UART_WLEN_8BITS | UART_ENABLE_FIFO));
+
+	/*
+	 * Finally, enable interrupts
+	 */
+	info->IER = UART_RX_INT_EN | UART_RX_TIMEOUT_INT_EN | UART_PORT_EN;
+	serial_out(info, UART_CR_REG, info->IER);
+
+	if (info->tty)
+		clear_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->xmit.head = info->xmit.tail = 0;
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+
+	return 0;
+	
+errout:
+	restore_flags(flags);
+	return retval;
+}
+
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+static int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct	*info;
+	int 			retval, line;
+	unsigned long		page;
+
+//	line = MINOR(tty->device) - tty->driver.minor_start;
+	line=0;
+	if ((line < 0) || (line >= NR_PORTS)) 
+	{
+		return -ENODEV;
+	}
+
+	retval = get_async_struct(line, &info);
+	if (retval) 
+	{
+		return retval;
+	}
+
+	tty->driver_data = info;
+	info->tty = tty;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+	       info->state->count);
+#endif
+	
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+
+	if (!tmp_buf) 
+	{
+		page = get_zeroed_page(GFP_KERNEL);
+		if (!page) 
+		{
+			return -ENOMEM;
+		}
+
+		if (tmp_buf)
+			free_page(page);
+		else
+			tmp_buf = (unsigned char *) page;
+	}
+
+	/*
+	 * If the port is the middle of closing, bail out now
+	 */
+	if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) 
+	{
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+
+		return -EAGAIN;
+	}
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval) 
+	{
+		return retval;
+	}
+
+#if 0
+	retval = block_til_ready(tty, filp, info);
+	if (retval) {
+#ifdef SERIAL_DEBUG_OPEN
+		printk("rs_open returning after block_til_ready with %d\n",
+		       retval);
+#endif
+		return retval;
+	}
+#endif
+
+	if ((info->state->count == 1) &&
+	    (info->flags & ASYNC_SPLIT_TERMIOS)) 
+	{
+//		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+//			*tty->termios = info->state->normal_termios;
+//		else 
+//			*tty->termios = info->state->callout_termios;
+	}
+
+//	info->session = current->session;
+//	info->pgrp = current->pgrp;
+
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_open ttys%d successful...", info->line);
+#endif
+
+	return 0;
+}
+
+
+/*
+ * rs_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state;
+	unsigned long flags;
+
+	state = info->state;
+	
+	save_flags(flags); 
+	cli();
+	
+	//if (tty_hung_up_p(filp)) {
+	//	DBG_CNT("before DEC-hung");
+	//	restore_flags(flags);
+	//	return;
+	//}
+	
+#ifdef SERIAL_DEBUG_OPEN
+	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
+#endif
+
+	if ((tty->count == 1) && (state->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  state->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		//printk("rs_close: bad serial port count; tty->count is 1, "
+		 //      "state->count is %d\n", state->count);
+		state->count = 1;
+	}
+
+	if (--state->count < 0) {
+		//printk("rs_close: bad serial port count for ttys%d: %d\n",
+		   //    info->line, state->count);
+		state->count = 0;
+	}
+
+	restore_flags(flags);
+	return;
+
+#if 0
+	info->flags |= ASYNC_CLOSING;
+	restore_flags(flags);
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (info->flags & ASYNC_NORMAL_ACTIVE)
+		info->state->normal_termios = *tty->termios;
+	if (info->flags & ASYNC_CALLOUT_ACTIVE)
+		info->state->callout_termios = *tty->termios;
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+
+	if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE)
+		tty_wait_until_sent(tty, info->closing_wait);
+
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and tell the
+	 * interrupt driver to stop checking the data ready bit in the
+	 * line status register.
+	 */
+	//info->IER &= ~UART_IER_RLSI;
+	//info->read_status_mask &= ~UART_LSR_DR;
+	//if (info->flags & ASYNC_INITIALIZED) {
+	//	serial_out(info, UART_IER, info->IER);
+		/*
+		 * Before we drop DTR, make sure the UART transmitter
+		 * has completely drained; this is especially
+		 * important if there is a transmit FIFO!
+		 */
+	//	rs_wait_until_sent(tty, info->timeout);
+	//}
+	//shutdown(info);
+
+	if (tty->driver.flush_buffer)
+		tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer)
+		tty->ldisc.flush_buffer(tty);
+	tty->closing = 0;
+	info->event = 0;
+	info->tty = 0;
+	//if (info->blocked_open) {
+	//	if (info->close_delay) {
+	//		set_current_state(TASK_INTERRUPTIBLE);
+	//		schedule_timeout(info->close_delay);
+	//	}
+	//	wake_up_interruptible(&info->open_wait);
+	//}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
+			 ASYNC_CLOSING);
+	
+	wake_up_interruptible(&info->close_wait);
+#endif
+}
+
+
+static int rs_write(struct tty_struct * tty, const unsigned char *buf,
+	int count)
+{
+	int	c, ret = 0;
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (!tty || !info->xmit.buf || !tmp_buf)
+		return 0;
+
+	save_flags(flags);
+	if (0/*from_user*/) {
+		down(&tmp_buf_sem);
+		while (1) {
+			int c1;
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+			cli();
+			c1 = CIRC_SPACE_TO_END(info->xmit.head,
+					       info->xmit.tail,
+					       SERIAL_XMIT_SIZE);
+			if (c1 < c)
+				c = c1;
+			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		cli();
+		while (1) {
+			c = CIRC_SPACE_TO_END(info->xmit.head,
+					      info->xmit.tail,
+					      SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0) {
+				break;
+			}
+			memcpy(info->xmit.buf + info->xmit.head, buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		restore_flags(flags);
+	}
+	if (info->xmit.head != info->xmit.tail
+	    && !tty->stopped
+	    && !tty->hw_stopped
+	    && !(info->IER & UART_TX_INT)) {
+		info->IER |= UART_TX_INT_EN;
+		serial_out(info, UART_CR_REG, info->IER);
+	}
+	return ret;
+}
+
+
+static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (!tty || !info->xmit.buf)
+		return;
+
+	save_flags(flags); 
+	cli();
+	
+	if (CIRC_SPACE(info->xmit.head,
+		       info->xmit.tail,
+		       SERIAL_XMIT_SIZE) == 0) {
+		restore_flags(flags);
+		return;
+	}
+
+	info->xmit.buf[info->xmit.head] = ch;
+	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
+	restore_flags(flags);
+}
+
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+				
+	if (info->xmit.head == info->xmit.tail
+	    || tty->stopped
+	    || tty->hw_stopped
+	    || !info->xmit.buf)
+		return;
+
+	save_flags(flags); 
+	cli();
+	
+	info->IER |= UART_TX_INT_EN;
+	serial_out(info, UART_CR_REG, info->IER);
+	restore_flags(flags);
+}
+
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+				
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	save_flags(flags); 
+	cli();
+
+	info->xmit.head = info->xmit.tail = 0;
+	restore_flags(flags);
+	wake_up_interruptible(&tty->write_wait);
+#ifdef SERIAL_HAVE_POLL_WAIT
+	wake_up_interruptible(&tty->poll_wait);
+#endif
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+
+static int get_serial_info(struct async_struct * info,
+			   struct serial_struct * retinfo)
+{
+	struct serial_struct tmp;
+	struct serial_state *state = info->state;
+   
+	if (!retinfo)
+		return -EFAULT;
+
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = state->type;
+	tmp.line = state->line;
+	tmp.port = state->port;
+	//if (HIGH_BITS_OFFSET)
+	//	tmp.port_high = state->port >> HIGH_BITS_OFFSET;
+	//else
+		tmp.port_high = 0;
+	tmp.irq = state->irq;
+	tmp.flags = state->flags;
+	tmp.xmit_fifo_size = state->xmit_fifo_size;
+	tmp.baud_base = state->baud_base;
+	tmp.close_delay = state->close_delay;
+	tmp.closing_wait = state->closing_wait;
+	tmp.custom_divisor = state->custom_divisor;
+	tmp.hub6 = state->hub6;
+	tmp.io_type = state->io_type;
+	if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
+		return -EFAULT;
+	return 0;
+}
+
+
+#if 0
+static int set_serial_info(struct async_struct * info,
+			   struct serial_struct * new_info)
+{
+	struct serial_struct new_serial;
+ 	struct serial_state old_state, *state;
+	unsigned int		i,change_irq,change_port;
+	int 			retval = 0;
+	unsigned long		new_port;
+
+	if (copy_from_user(&new_serial,new_info,sizeof(new_serial)))
+		return -EFAULT;
+	state = info->state;
+	old_state = *state;
+
+	new_port = new_serial.port;
+	if (HIGH_BITS_OFFSET)
+		new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
+
+	change_irq = new_serial.irq != state->irq;
+	change_port = (new_port != ((int) state->port)) ||
+		(new_serial.hub6 != state->hub6);
+  
+	if (!capable(CAP_SYS_ADMIN)) {
+		if (change_irq || change_port ||
+		    (new_serial.baud_base != state->baud_base) ||
+		    (new_serial.type != state->type) ||
+		    (new_serial.close_delay != state->close_delay) ||
+		    (new_serial.xmit_fifo_size != state->xmit_fifo_size) ||
+		    ((new_serial.flags & ~ASYNC_USR_MASK) !=
+		     (state->flags & ~ASYNC_USR_MASK)))
+			return -EPERM;
+		state->flags = ((state->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		info->flags = ((info->flags & ~ASYNC_USR_MASK) |
+			       (new_serial.flags & ASYNC_USR_MASK));
+		state->custom_divisor = new_serial.custom_divisor;
+		goto check_and_exit;
+	}
+
+	new_serial.irq = irq_cannonicalize(new_serial.irq);
+
+	if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) || 
+	    (new_serial.baud_base < 9600)|| (new_serial.type < PORT_UNKNOWN) ||
+	    (new_serial.type > PORT_MAX) || (new_serial.type == PORT_CIRRUS) ||
+	    (new_serial.type == PORT_STARTECH)) {
+		return -EINVAL;
+	}
+
+	if ((new_serial.type != state->type) ||
+	    (new_serial.xmit_fifo_size <= 0))
+		new_serial.xmit_fifo_size =
+			uart_config[new_serial.type].dfl_xmit_fifo_size;
+
+	/* Make sure address is not already in use */
+	if (new_serial.type) {
+		for (i = 0 ; i < NR_PORTS; i++)
+			if ((state != &rs_table[i]) &&
+			    (rs_table[i].port == new_port) &&
+			    rs_table[i].type)
+				return -EADDRINUSE;
+	}
+
+	if ((change_port || change_irq) && (state->count > 1))
+		return -EBUSY;
+
+	/*
+	 * OK, past this point, all the error checking has been done.
+	 * At this point, we start making changes.....
+	 */
+
+	state->baud_base = new_serial.baud_base;
+	state->flags = ((state->flags & ~ASYNC_FLAGS) |
+			(new_serial.flags & ASYNC_FLAGS));
+	info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
+		       (info->flags & ASYNC_INTERNAL_FLAGS));
+	state->custom_divisor = new_serial.custom_divisor;
+	state->close_delay = new_serial.close_delay * HZ/100;
+	state->closing_wait = new_serial.closing_wait * HZ/100;
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+	info->xmit_fifo_size = state->xmit_fifo_size =
+		new_serial.xmit_fifo_size;
+
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+		release_region(state->port,8);
+	}
+	state->type = new_serial.type;
+	if (change_port || change_irq) {
+		/*
+		 * We need to shutdown the serial port at the old
+		 * port/irq combination.
+		 */
+		shutdown(info);
+		state->irq = new_serial.irq;
+		info->port = state->port = new_port;
+		info->hub6 = state->hub6 = new_serial.hub6;
+		if (info->hub6)
+			info->io_type = state->io_type = SERIAL_IO_HUB6;
+		else if (info->io_type == SERIAL_IO_HUB6)
+			info->io_type = state->io_type = SERIAL_IO_PORT;
+	}
+	if ((state->type != PORT_UNKNOWN) && state->port) {
+			request_region(state->port,8,"serial(set)");
+	}
+
+	
+check_and_exit:
+	if (!state->port || !state->type)
+		return 0;
+	if (info->flags & ASYNC_INITIALIZED) {
+		if (((old_state.flags & ASYNC_SPD_MASK) !=
+		     (state->flags & ASYNC_SPD_MASK)) ||
+		    (old_state.custom_divisor != state->custom_divisor)) {
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+				info->tty->alt_speed = 57600;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+				info->tty->alt_speed = 115200;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+				info->tty->alt_speed = 230400;
+			if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+				info->tty->alt_speed = 460800;
+			change_speed(info, 0);
+		}
+	} else {
+		retval = startup(info);
+	}
+	return retval;
+}
+#endif
+
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct async_icount cprev, cnow;	/* kernel counter temps */
+	struct serial_icounter_struct icount;
+	unsigned long flags;
+	
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+	
+	switch (cmd) {
+		//case TIOCMGET:
+		//	return get_modem_info(info, (unsigned int *) arg);
+		case TIOCMBIS:
+		case TIOCMBIC:
+		//case TIOCMSET:
+		//	return set_modem_info(info, cmd, (unsigned int *) arg);
+		case TIOCGSERIAL:
+			return get_serial_info(info,
+					       (struct serial_struct *) arg);
+		//case TIOCSSERIAL:
+		//	return set_serial_info(info,
+					       //(struct serial_struct *) arg);
+		//case TIOCSERCONFIG:
+		//	return do_autoconfig(info);
+
+		//case TIOCSERGETLSR: /* Get line status register */
+		//	return get_lsr_info(info, (unsigned int *) arg);
+
+		case TIOCSERGSTRUCT:
+			if (copy_to_user((struct async_struct *) arg,
+					 info, sizeof(struct async_struct)))
+				return -EFAULT;
+			return 0;
+				
+			
+		/*
+		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		 * - mask passed in arg for lines of interest
+ 		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		 * Caller should use TIOCGICOUNT to see which one it was
+		 */
+		case TIOCMIWAIT:
+#if 0
+			save_flags(flags); 
+			cli();
+			/* note the counters on entry */
+			cprev = info->state->icount;
+			restore_flags(flags);
+			/* Force modem status interrupts on */
+			info->IER |= UART_IER_MSI;
+			serial_out(info, UART_IER, info->IER);
+			while (1) {
+				interruptible_sleep_on(&info->delta_msr_wait);
+				/* see if a signal did it */
+				if (signal_pending(current))
+					return -ERESTARTSYS;
+				save_flags(flags); cli();
+				cnow = info->state->icount; /* atomic copy */
+				restore_flags(flags);
+				if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && 
+				    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+					return -EIO; /* no change => error */
+				if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+				     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+				     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+				     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+					return 0;
+				}
+				cprev = cnow;
+			}
+			/* NOTREACHED */
+#endif
+
+		/* 
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+		case TIOCGICOUNT:
+			save_flags(flags); 
+			cli();
+			cnow = info->state->icount;
+			restore_flags(flags);
+			icount.cts = cnow.cts;
+			icount.dsr = cnow.dsr;
+			icount.rng = cnow.rng;
+			icount.dcd = cnow.dcd;
+			icount.rx = cnow.rx;
+			icount.tx = cnow.tx;
+			icount.frame = cnow.frame;
+			icount.overrun = cnow.overrun;
+			icount.parity = cnow.parity;
+			icount.brk = cnow.brk;
+			icount.buf_overrun = cnow.buf_overrun;
+			
+			if (copy_to_user((void *)arg, &icount, sizeof(icount)))
+				return -EFAULT;
+			return 0;
+		case TIOCSERGWILD:
+		case TIOCSERSWILD:
+			/* "setserial -W" is called in Debian boot */
+			printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+	}
+
+	return 0;
+}
+
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+#if 0
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("throttle %s: %d....\n", tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (I_IXOFF(tty))
+		rs_send_xchar(tty, STOP_CHAR(tty));
+
+	if (tty->termios->c_cflag & CRTSCTS)
+		info->MCR &= ~UART_MCR_RTS;
+
+	save_flags(flags); cli();
+	serial_out(info, UART_MCR, info->MCR);
+	restore_flags(flags);
+#endif
+}
+
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+#if 0
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+#ifdef SERIAL_DEBUG_THROTTLE
+	char	buf[64];
+	
+	printk("unthrottle %s: %d....\n", tty_name(tty, buf),
+	       tty->ldisc.chars_in_buffer(tty));
+#endif
+
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			rs_send_xchar(tty, START_CHAR(tty));
+	}
+	//if (tty->termios->c_cflag & CRTSCTS)
+	//	info->MCR |= UART_MCR_RTS;
+	save_flags(flags); 
+	cli();
+	//serial_out(info, UART_MCR, info->MCR);
+	restore_flags(flags);
+#endif
+}
+
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+#if 0
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	unsigned int cflag = tty->termios->c_cflag;
+	
+	if ((cflag == old_termios->c_cflag)
+	    && (RELEVANT_IFLAG(tty->termios->c_iflag) 
+		== RELEVANT_IFLAG(old_termios->c_iflag)))
+	  return;
+
+	/* Handle transition to B0 status */
+	if ((old_termios->c_cflag & CBAUD) &&
+	    !(cflag & CBAUD)) {
+		info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
+		save_flags(flags); cli();
+		serial_out(info, UART_MCR, info->MCR);
+		restore_flags(flags);
+	}
+	
+	/* Handle transition away from B0 status */
+	if (!(old_termios->c_cflag & CBAUD) &&
+	    (cflag & CBAUD)) {
+		info->MCR |= UART_MCR_DTR;
+		if (!(tty->termios->c_cflag & CRTSCTS) || 
+		    !test_bit(TTY_THROTTLED, &tty->flags)) {
+			info->MCR |= UART_MCR_RTS;
+		}
+		save_flags(flags); cli();
+		serial_out(info, UART_MCR, info->MCR);
+		restore_flags(flags);
+	}
+	
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+#endif
+}
+
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	save_flags(flags); 
+	cli();
+	
+	if (info->IER & UART_TX_INT_EN) {
+		info->IER &= ~UART_TX_INT_EN;
+		serial_out(info, UART_CR_REG, info->IER);
+	}
+	restore_flags(flags);
+}
+
+
+
+static void rs_start(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	save_flags(flags); 
+	cli();
+	
+	if (info->xmit.head != info->xmit.tail
+	    && info->xmit.buf
+	    && !(info->IER & UART_TX_INT_EN)) {
+		info->IER |= UART_TX_INT_EN;
+		serial_out(info, UART_CR_REG, info->IER);
+	}
+	restore_flags(flags);
+}
+
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state = info->state;
+	
+	state = info->state;
+	
+	rs_flush_buffer(tty);
+	
+	if (info->flags & ASYNC_CLOSING)
+		return;
+
+	info->event = 0;
+	state->count = 0;
+//	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+
+/*
+ * rs_break() --- routine which turns the break handling on or off
+ */
+static void rs_break(struct tty_struct *tty, int break_state)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+	
+	if (!CONFIGURED_SERIAL_PORT(info))
+		return;
+	
+	save_flags(flags); 
+	cli();
+	if (break_state == -1)
+		info->LCR |= UART_SEND_BREAK;
+	else
+		info->LCR &= ~UART_SEND_BREAK;
+	
+	serial_out(info, UART_LCR_H_REG, info->LCR);
+	restore_flags(flags);
+}
+
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	info->x_char = ch;
+	if (ch) {
+		/* Make sure transmit interrupts are on */
+		info->IER |= UART_TX_INT_EN;
+		serial_out(info, UART_CR_REG, info->IER);
+	}
+}
+
+
+/*
+ * rs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+#if 0
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	unsigned long orig_jiffies, char_time;
+	int lsr;
+	
+	if (info->state->type == PORT_UNKNOWN)
+		return;
+
+	if (info->xmit_fifo_size == 0)
+		return; /* Just in case.... */
+
+	orig_jiffies = jiffies;
+	/*
+	 * Set the check interval to be 1/5 of the estimated time to
+	 * send a single character, and make it at least 1.  The check
+	 * interval should also be less than the timeout.
+	 * 
+	 * Note: we have to use pretty tight timings here to satisfy
+	 * the NIST-PCTS.
+	 */
+	char_time = (info->timeout - HZ/50) / info->xmit_fifo_size;
+	char_time = char_time / 5;
+	if (char_time == 0)
+		char_time = 1;
+	if (timeout && timeout < char_time)
+		char_time = timeout;
+	/*
+	 * If the transmitter hasn't cleared in twice the approximate
+	 * amount of time to send the entire FIFO, it probably won't
+	 * ever clear.  This assumes the UART isn't doing flow
+	 * control, which is currently the case.  Hence, if it ever
+	 * takes longer than info->timeout, this is probably due to a
+	 * UART bug of some kind.  So, we clamp the timeout parameter at
+	 * 2*info->timeout.
+	 */
+	if (!timeout || timeout > 2*info->timeout)
+		timeout = 2*info->timeout;
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
+	printk("jiff=%lu...", jiffies);
+#endif
+	while (!((lsr = serial_inp(info, UART_LSR)) & UART_LSR_TEMT)) {
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
+#endif
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+			break;
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+			break;
+	}
+	set_current_state(TASK_RUNNING);
+#ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
+	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
+#endif
+#endif
+}
+
+/*
+ * /proc fs routines....
+ */
+
+static inline int line_info(char *buf, struct serial_state *state)
+{
+#if 0
+	struct async_struct *info = state->info, scr_info;
+	char	stat_buf[30], control, status;
+	int	ret;
+	unsigned long flags;
+
+	ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d",
+		      state->line, uart_config[state->type].name, 
+		      state->port, state->irq);
+
+	if (!state->port || (state->type == PORT_UNKNOWN)) {
+		ret += sprintf(buf+ret, "\n");
+		return ret;
+	}
+
+	/*
+	 * Figure out the current RS-232 lines
+	 */
+	if (!info) {
+		info = &scr_info;	/* This is just for serial_{in,out} */
+
+		info->magic = SERIAL_MAGIC;
+		info->port = state->port;
+		info->flags = state->flags;
+		info->quot = 0;
+		info->tty = 0;
+	}
+	save_flags(flags); cli();
+	status = serial_in(info, UART_MSR);
+	control = info != &scr_info ? info->MCR : serial_in(info, UART_MCR);
+	restore_flags(flags); 
+
+	stat_buf[0] = 0;
+	stat_buf[1] = 0;
+	if (control & UART_MCR_RTS)
+		strcat(stat_buf, "|RTS");
+	if (status & UART_MSR_CTS)
+		strcat(stat_buf, "|CTS");
+	if (control & UART_MCR_DTR)
+		strcat(stat_buf, "|DTR");
+	if (status & UART_MSR_DSR)
+		strcat(stat_buf, "|DSR");
+	if (status & UART_MSR_DCD)
+		strcat(stat_buf, "|CD");
+	if (status & UART_MSR_RI)
+		strcat(stat_buf, "|RI");
+
+	if (info->quot) {
+		ret += sprintf(buf+ret, " baud:%d",
+			       state->baud_base / info->quot);
+	}
+
+	ret += sprintf(buf+ret, " tx:%d rx:%d",
+		      state->icount.tx, state->icount.rx);
+
+	if (state->icount.frame)
+		ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+	
+	if (state->icount.parity)
+		ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+	
+	if (state->icount.brk)
+		ret += sprintf(buf+ret, " brk:%d", state->icount.brk);	
+
+	if (state->icount.overrun)
+		ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+
+	/*
+	 * Last thing is the RS-232 status lines
+	 */
+	ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+	return ret;
+#endif
+	return 0;
+}
+
+
+int rs_read_proc(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	int i, len = 0, l;
+	off_t	begin = 0;
+
+	len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n",
+		       serial_version, LOCAL_VERSTRING, serial_revdate);
+	for (i = 0; i < NR_PORTS && len < 4000; i++) {
+		l = line_info(page + len, &rs_table[i]);
+		len += l;
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (off-begin);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+
+/* 
+ * This routine must be called by kernel at boot time 
+ */
+int __init serial5120_init(void) 
+{
+	memset(&dev_tty_driver, 0, sizeof(struct tty_driver));
+
+	dev_tty_driver.magic = TTY_DRIVER_MAGIC;
+	dev_tty_driver.driver_name = "/dev/ttyS0";
+	dev_tty_driver.name = "ttyS0";
+	dev_tty_driver.major = TTY_MAJOR;
+	dev_tty_driver.minor_start = 64;
+	dev_tty_driver.num = 1;
+	dev_tty_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	dev_tty_driver.subtype = SERIAL_TYPE_NORMAL;
+	dev_tty_driver.init_termios = tty_std_termios;
+	dev_tty_driver.init_termios.c_cflag =
+		B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+	dev_tty_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
+//	dev_tty_driver.refcount = &serial_refcount;
+//	dev_tty_driver.table = serial_table;
+	dev_tty_driver.termios = serial_termios;
+	dev_tty_driver.termios_locked = serial_termios_locked;
+
+	dev_tty_driver.open = rs_open;
+	dev_tty_driver.close = rs_close;
+	dev_tty_driver.write = rs_write;
+	dev_tty_driver.put_char = rs_put_char;
+	dev_tty_driver.flush_chars = rs_flush_chars;
+	dev_tty_driver.write_room = rs_write_room;
+	dev_tty_driver.chars_in_buffer = rs_chars_in_buffer;
+	dev_tty_driver.flush_buffer = rs_flush_buffer;
+	dev_tty_driver.ioctl = rs_ioctl;
+	dev_tty_driver.throttle = rs_throttle;
+	dev_tty_driver.unthrottle = rs_unthrottle;
+	dev_tty_driver.set_termios = rs_set_termios;
+	dev_tty_driver.stop = rs_stop;
+	dev_tty_driver.start = rs_start;
+	dev_tty_driver.hangup = rs_hangup;
+	dev_tty_driver.break_ctl = rs_break;
+	dev_tty_driver.send_xchar = rs_send_xchar;
+	dev_tty_driver.wait_until_sent = rs_wait_until_sent;
+	dev_tty_driver.read_proc = rs_read_proc;
+
+	if (tty_register_driver(&dev_tty_driver))
+		panic("Couldn't register /dev/ttyS0 driver\n");
+
+	return 0;
+}
+
+__initcall(serial5120_init);
diff -ruN linux-2.6.10/arch/mips/am5120/setup.c linux-2.6.10-adm.1/arch/mips/am5120/setup.c
--- linux-2.6.10/arch/mips/am5120/setup.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/am5120/setup.c	2005-01-27 21:06:17.000000000 +0100
@@ -0,0 +1,119 @@
+/*****************************************************************************
+;
+;   (C) Unpublished Work of ADMtek Incorporated.  All Rights Reserved.
+;
+;       THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
+;       PROPRIETARY AND TRADESECRET INFORMATION OF ADMTEK INCORPORATED.
+;       ACCESS TO THIS WORK IS RESTRICTED TO (I) ADMTEK EMPLOYEES WHO HAVE A
+;       NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR ASSIGNMENTS
+;       AND (II) ENTITIES OTHER THAN ADMTEK WHO HAVE ENTERED INTO APPROPRIATE
+;       LICENSE AGREEMENTS.  NO PART OF THIS WORK MAY BE USED, PRACTICED,
+;       PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,
+;       ABBRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
+;       TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF ADMTEK.
+;       ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD
+;       SUBJECT THE PERPERTRATOR TO CRIMINAL AND CIVIL LIABILITY.
+;
+;------------------------------------------------------------------------------
+;
+;    Project : ADM5120
+;    Creator : daniell@admtek.com.tw
+;    File    : arch/mips/am5120/setup.c
+;	 Date    : 2003.3.4
+;    Abstract: 
+;
+;Modification History:
+;
+;*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/serial.h>
+#include <linux/types.h>
+#include <linux/string.h>	/* for memset */
+
+#include <asm/reboot.h>
+#include <asm/io.h>
+#include <asm/time.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/am5120/adm5120.h>
+
+
+//extern struct rtc_ops am5120_rtc_ops;
+//extern struct rtc_ops *rtc_ops;
+
+void  mips_timer_setup(struct irqaction *irq);
+void  mips_time_init(void);
+
+int am5120_pci_module;
+
+
+void am5120_restart(char *command)
+{
+	int i;
+
+	/* Disable All ports*/
+	ADM5120_SW_REG(Port_conf0_REG) |= SW_DISABLE_PORT_MASK;
+
+	/* Disable CPU port */
+	ADM5120_SW_REG(CPUp_conf_REG) |= SW_CPU_PORT_DISABLE;
+
+	// Wait until switch DMA idle. At least 1ms is required!!!!
+	for (i=0; i <1000000; i++);
+
+	ADM5120_SW_REG(SftRest_REG) = SOFTWARE_RESET;
+}
+
+
+void am5120_halt(void)
+{
+        printk(KERN_NOTICE "\n** You can safely turn off the power\n");
+        while (1);
+}
+
+
+void am5120_power_off(void)
+{
+        am5120_halt();
+}
+
+static int __init am5120_setup(void)
+{
+	printk("ADM5120 board setup\n");
+
+	board_time_init = mips_time_init;
+	board_timer_setup = mips_timer_setup;
+
+	_machine_restart = am5120_restart;
+	_machine_halt = am5120_halt;
+	_machine_power_off = am5120_power_off;
+
+//	rtc_ops = &am5120_rtc_ops;
+
+	set_io_port_base(KSEG1);
+
+	/* check pci in existence or not */
+	if (ADM5120_SW_REG(CODE_REG) & CPU_PQFP_MODE)
+	{
+		printk("System no PCI BIOS\n");
+		am5120_pci_module = 0;
+	}
+	else
+	{
+		printk("System has PCI BIOS\n");
+		am5120_pci_module = 1;
+	}
+	return 0;
+}
+
+early_initcall(am5120_setup);
+
+const char *get_system_type(void)
+{
+	return "ADM5120 Board";
+}
diff -ruN linux-2.6.10/arch/mips/am5120/time.c linux-2.6.10-adm.1/arch/mips/am5120/time.c
--- linux-2.6.10/arch/mips/am5120/time.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/am5120/time.c	2005-01-27 21:06:17.000000000 +0100
@@ -0,0 +1,98 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2005 Jeroen Vreeken (pe1rxq@amsat.org)
+ *
+ * ########################################################################
+ *
+ *  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 <asm/cpu.h>
+#include <asm/am5120/adm5120.h>
+
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <asm/time.h>
+#include <asm/mipsregs.h>
+
+
+unsigned int mips_counter_frequency;
+
+#define ALLINTS (IE_IRQ0 | IE_IRQ5 | STATUS_IE)
+
+#define MIPS_CPU_TIMER_IRQ 7
+
+
+void mips_timer_interrupt(struct pt_regs *regs)
+{
+	write_c0_compare(read_c0_count()+ mips_counter_frequency/HZ);
+	ll_timer_interrupt(MIPS_CPU_TIMER_IRQ, regs);
+}
+
+
+void __init mips_time_init(void)
+{
+	unsigned long clock;
+
+	clock = (ADM5120_SW_REG(CODE_REG) & CODE_CLK_MASK) >> CODE_CLK_SHIFT;
+
+	switch (clock)
+	{
+	case CPU_CLK_175MHZ:
+		mips_counter_frequency = CPU_SPEED_175M;
+		printk("CPU clock: 175MHz\n");
+		break;
+
+	case CPU_CLK_200MHZ:
+		mips_counter_frequency = CPU_SPEED_200M;
+		printk("CPU clock: 200MHz\n");
+		break;
+
+	case CPU_CLK_225MHZ:
+		mips_counter_frequency = CPU_SPEED_225M;
+		printk("CPU clock: 225MHz\n");
+		break;
+
+	case CPU_CLK_250MHZ:
+		mips_counter_frequency = CPU_SPEED_250M;
+		printk("CPU clock: 250MHz\n");
+		break;
+	}
+}
+
+
+void __init mips_timer_setup(struct irqaction *irq)
+{
+	/* to generate the first timer interrupt */
+	write_c0_compare(read_c0_count()+ mips_counter_frequency/HZ);
+	clear_c0_status(ST0_BEV);
+	set_c0_status(ALLINTS);
+}
diff -ruN linux-2.6.10/arch/mips/kernel/head.S linux-2.6.10-adm.1/arch/mips/kernel/head.S
--- linux-2.6.10/arch/mips/kernel/head.S	2004-12-24 22:35:01.000000000 +0100
+++ linux-2.6.10-adm.1/arch/mips/kernel/head.S	2005-01-27 21:06:16.000000000 +0100
@@ -127,12 +127,16 @@
 	 * Necessary for machines which link their kernels at KSEG0.
 	 */
 	.fill	0x400
+#ifdef CONFIG_MIPS_AM5120
+	/* AM5120 bootloader jumps to 0x6d8 */
+	.fill   0x2d8
+	j kernel_entry
+#endif
 
 EXPORT(stext)					# used for profiling
 EXPORT(_stext)
 
 	__INIT
-
 NESTED(kernel_entry, 16, sp)			# kernel entry point
 	setup_c0_status_pri
 
diff -ruN linux-2.6.10/include/asm-mips/am5120/adm5120.h linux-2.6.10-adm.1/include/asm-mips/am5120/adm5120.h
--- linux-2.6.10/include/asm-mips/am5120/adm5120.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/include/asm-mips/am5120/adm5120.h	2005-01-27 21:06:27.000000000 +0100
@@ -0,0 +1,1084 @@
+/*****************************************************************************
+;
+;   (C) Unpublished Work of ADMtek Incorporated.  All Rights Reserved.
+;
+;       THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
+;       PROPRIETARY AND TRADESECRET INFORMATION OF ADMTEK INCORPORATED.
+;       ACCESS TO THIS WORK IS RESTRICTED TO (I) ADMTEK EMPLOYEES WHO HAVE A
+;       NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR ASSIGNMENTS
+;       AND (II) ENTITIES OTHER THAN ADMTEK WHO HAVE ENTERED INTO APPROPRIATE
+;       LICENSE AGREEMENTS.  NO PART OF THIS WORK MAY BE USED, PRACTICED,
+;       PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,
+;       ABBRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
+;       TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF ADMTEK.
+;       ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD
+;       SUBJECT THE PERPERTRATOR TO CRIMINAL AND CIVIL LIABILITY.
+;
+;------------------------------------------------------------------------------
+;
+;    Project : ADM5120
+;    Creator : 
+;    File    : include/asm/am5120/adm5120.h
+;	 Date    : 2003.3.10
+;    Abstract: 
+;
+;Modification History:
+; 
+;	Jeroen Vreeken (pe1rxq@amsat.org)
+;	Changed UART_BAUDDIV() to minimize for rounding errors.
+;	Reformatted (somebody likes 4 character tabs....)
+;
+;*****************************************************************************/
+
+
+#ifndef  __ADM5120_H__
+#define  __ADM5120_H__
+
+
+#include <asm/addrspace.h>
+
+
+/*=========================  Physical Memory Map  ============================*/
+#define SDRAM_BASE			0x00000000
+#define SMEM1_BASE			0x10000000
+
+#define EXTIO0_BASE			0x10C00000
+#define EXTIO1_BASE			0x10E00000
+#define MPMC_BASE			0x11000000
+#define USBHOST_BASE			0x11200000
+#define PCIMEM_BASE			0x11400000
+#define PCIIO_BASE			0x11500000
+#define PCICFG_BASE			0x115FFFF0
+#define MIPS_BASE			0x11A00000
+#define SWCTRL_BASE			0x12000000
+
+#define INTC_BASE			0x12200000
+#define SYSC_BASE			0x12400000
+
+#define UART0_BASE			0x12600000
+#define UART1_BASE			0x12800000
+
+#define SMEM0_BASE			0x1FC00000
+
+
+/*=======================  MIPS interrupt  ===================*/
+#define MIPSINT_SOFT0			0
+#define MIPSINT_SOFT1			1
+#define MIPSINT_IRQ			2
+#define MIPSINT_FIQ			3
+#define MIPSINT_REV0			4
+#define MIPSINT_REV1			5
+#define MIPSINT_REV2			6
+#define MIPSINT_TIMER			7
+
+#define STATUS_IE			0x00000001
+
+/*====================  MultiPort Memory Controller (MPMC) ==================*/
+/* registers offset */
+#define MPMC_CONTROL_REG		0x0000
+#define MPMC_STATUS_REG			0x0004
+#define MPMC_CONFIG_REG			0x0008
+
+#define MPMC_DM_CONTROL_REG		0x0020
+#define MPMC_DM_REFRESH_REG		0x0024
+
+#define MPMC_DM_TRP_REG			0x0030
+#define MPMC_DM_TRAS_REG		0x0034
+#define MPMC_DM_TSREX_REG		0x0038
+#define MPMC_DM_TAPR_REG		0x003C
+#define MPMC_DM_TDAL_REG		0x0040
+#define MPMC_DM_TWR_REG			0x0044
+#define MPMC_DM_TRC_REG			0x0048
+#define MPMC_DM_TRFC_REG		0x004C
+#define MPMC_DM_TXSR_REG		0x0050
+#define MPMC_DM_TRRD_REG		0x0054
+#define MPMC_DM_TMRD_REG		0x0058
+
+#define MPMC_SM_EXTWAIT_REG		0x0080
+
+#define MPMC_DM_CONFIG0_REG		0x0100
+#define MPMC_DM_RASCAS0_REG		0x0104
+
+#define MPMC_DM_CONFIG1_REG		0x0120
+#define MPMC_DM_RASCAS1_REG		0x0124
+
+#define MPMC_SM_CONFIG0_REG		0x0200
+#define MPMC_SM_WAITWEN0_REG		0x0204
+#define MPMC_SM_WAITOEN0_REG		0x0208
+#define MPMC_SM_WAITRD0_REG		0x020C
+#define MPMC_SM_WAITPAGE0_REG		0x0210
+#define MPMC_SM_WAITWR0_REG		0x0214
+#define MPMC_SM_WAITTURN0_REG		0x0218
+
+#define MPMC_SM_CONFIG1_REG		0x0220
+#define MPMC_SM_WAITWEN1_REG		0x0224
+#define MPMC_SM_WAITOEN1_REG		0x0228
+#define MPMC_SM_WAITRD1_REG		0x022C
+#define MPMC_SM_WAITPAGE1_REG		0x0230
+#define MPMC_SM_WAITWR1_REG		0x0234
+#define MPMC_SM_WAITTURN1_REG		0x0238
+
+#define MPMC_SM_CONFIG2_REG		0x0240
+#define MPMC_SM_WAITWEN2_REG		0x0244
+#define MPMC_SM_WAITOEN2_REG		0x0248
+#define MPMC_SM_WAITRD2_REG		0x024C
+#define MPMC_SM_WAITPAGE2_REG		0x0250
+#define MPMC_SM_WAITWR2_REG		0x0254
+#define MPMC_SM_WAITTURN2_REG		0x0258
+
+#define MPMC_SM_CONFIG3_REG		0x0260
+#define MPMC_SM_WAITWEN3_REG		0x0264
+#define MPMC_SM_WAITOEN3_REG		0x0268
+#define MPMC_SM_WAITRD3_REG		0x026C
+#define MPMC_SM_WAITPAGE3_REG		0x0270
+#define MPMC_SM_WAITWR3_REG		0x0274
+#define MPMC_SM_WAITTURN3_REG		0x0278
+
+/* Macro for access MPMC register */
+#define MPMC_REG(_offset) \
+	(*((volatile unsigned long *)(KSEG1ADDR(MPMC_BASE + (_offset)))))
+
+
+/* MPMC_CONTROL_REG (offset: 0x0000) */
+#define MPMC_DRAIN_W_BUF		0x00000008
+#define MPMC_LOW_POWER_MODE		0x00000004
+#define MPMC_ADDR_MIRROR		0x00000002
+#define MPMC_ENABLE			0x00000001
+#define MPMC_CONTROL_MASK		0x0000000f
+
+/* MPMC_STATUS_REG (offset: 0x0004) */
+#define MPMC_SREFACK			0x00000004
+#define MPMC_WBUF_DIRTY			0x00000002
+#define MPMC_BUSY			0x00000001
+#define MPMC_STATUS_MASK		0x00000007
+
+/* MPMC_CONFIG_REG (offset: 0x0008) */
+#define MPMC_CLK_RATIO_1_1		0x00000000
+#define MPMC_CLK_RATIO_1_2		0x00000100
+#define MPMC_LITTLE_ENDIAN		0x00000000
+#define MPMC_BIG_ENDIAN			0x00000001
+#define MPMC_CONFIG_MASK		0x00000101
+
+/* MPMC_DM_CONTROL_REG (offset: 0x0020) */
+#define DM_PVHHOUT_HI_VOLTAGE		0x00008000
+#define DM_RPOUT_HI_VOLTAGE		0x00004000
+#define DM_DEEP_SLEEP_MODE		0x00002000
+
+#define DM_SDRAM_NOP			0x00000180
+#define DM_SDRAM_PRECHARGE_ALL		0x00000100
+#define DM_SDRAM_MODE_SETTING		0x00000080
+#define DM_SDRAM_NORMAL_OP		0x00000000
+#define DM_SDRAM_OPMODE_MASK		0x00000180
+
+#define DM_SELF_REFRESH_MODE		0x00000004
+#define DM_CLKOUT_ALWAYS		0x00000002
+#define DM_CLKEN_ALWAYS			0x00000001
+
+#define MPMC_DM_CONTROL_MASK		0x0000e187
+
+
+/* MPMC_DM_REFRESH_REG (offset:0x0024) */
+#define MPMC_DM_REFRESH_MASK		0x00000300
+
+/* MPMC_DM_TRP_REG (offset: 0x0030) */
+#define MPMC_DM_TRP_MASK		0x0000000f
+
+/* MPMC_DM_TRAS_REG (offset: 0x0034) */
+#define MPMC_DM_TRAS_MASK		0x0000000f
+
+/* MPMC_DM_TSREX_REG (offset: 0x0038) */
+#define MPMC_DM_TSREX_MASK		0x0000000f
+
+/* MPMC_DM_TAPR_REG	(offset: 0x003C) */
+#define MPMC_DM_TAPR_MASK		0x0000000f
+
+/* MPMC_DM_TDAL_REG	(offset: 0x0040) */
+#define MPMC_DM_TDAL_MASK		0x0000000f
+
+/* MPMC_DM_TWR_REG (offset: 0x0044) */
+#define MPMC_DM_TWR_MASK		0x0000000f
+
+/* MPMC_DM_TRC_REG (offset: 0x0048) */
+#define MPMC_DM_TRC_MASK 		0x0000001f
+
+/* MPMC_DM_TRFC_REG (offset: 0x004C) */
+#define MPMC_DM_TRFC_MASK		0x0000001f
+
+/* MPMC_DM_TXSR_REG	(offset: 0x0050) */
+#define MPMC_DM_TXSR_MASK		0x0000001f
+
+/* MPMC_DM_TRRD_REG	(offset: 0x0054) */
+#define MPMC_DM_TRRD_MASK		0x0000000f
+
+/* MPMC_DM_TMRD_REG	(offset: 0x0058) */
+#define MPMC_DM_TMRD_MASK		0x0000000f
+
+/* MPMC_SM_EXTWAIT_REG (offset:	0x0080) */
+#define MPMC_SM_EXTWAIT_MASK		0x0000003f
+
+
+/* MPMC_DM_CONFIG0_REG (offset: 0x0100) */
+/* MPMC_DM_CONFIG1_REG (offset: 0x0120) */
+#define DM_CFG_ROW_WIDTH_13BIT		0x20000000
+#define DM_CFG_ROW_WIDTH_12BIT		0x10000000
+#define DM_CFG_ROW_WIDTH_11BIT		0x00000000
+#define DM_CFG_ROW_WIDTH_MASK		0x30000000
+#define DM_CFG_ROW_WIDTH_SHIFT		28
+
+#define DM_CFG_2BANK_DEV		0x00000000
+#define DM_CFG_4BANK_DEV		0x04000000
+#define DM_CFG_BANK_SHIFT		26
+
+#define DM_CFG_COL_WIDTH_11BIT		0x01400000
+#define DM_CFG_COL_WIDTH_10BIT		0x01000000
+#define DM_CFG_COL_WIDTH_9BIT		0x00c00000
+#define DM_CFG_COL_WIDTH_8BIT		0x00800000
+#define DM_CFG_COL_WIDTH_7BIT		0x00400000
+#define DM_CFG_COL_WIDTH_6BIT		0x00000000
+#define DM_CFG_COL_WIDTH_MASK		0x01c00000
+#define DM_CFG_COL_WIDTH_SHIFT		22
+
+#define DM_CFG_WRITE_PROTECT		0x00100000
+#define DM_CFG_BUFFER_EN		0x00080000
+
+#define DM_CFG_ADDR_MAPPING_MASK	0x00005F80
+
+#define DM_CFG_DEV_SYNC_FLASH		0x00000010
+#define DM_CFG_DEV_LOWPOWER_SDRAM	0x00000008
+#define DM_CFG_DEV_SDRAM		0x00000000
+#define DM_CFG_DEV_MASK			0x00000018
+
+
+/* MPMC_DM_RASCAS0_REG (offset: 0x0104) */
+/* MPMC_DM_RASCAS1_REG (offset: 0x0124) */
+
+#define DM_CAS_LATENCY_3		0x00000300
+#define DM_CAS_LATENCY_2		0x00000200
+#define DM_CAS_LATENCY_1		0x00000100
+
+#define DM_RAS_LATENCY_3		0x00000003
+#define DM_RAS_LATENCY_2		0x00000002
+#define DM_RAS_LATENCY_1		0x00000001
+
+
+/* MPMC_SM_CONFIG0_REG (offset: 0x0200) */
+/* MPMC_SM_CONFIG1_REG (offset: 0x0220) */
+/* MPMC_SM_CONFIG2_REG (offset: 0x0240) */
+/* MPMC_SM_CONFIG3_REG (offset: 0x0260) */
+
+#define SM_WRITE_PROTECT		0x00100000
+#define SM_WRITEBUF_ENABLE		0x00080000
+#define SM_EXTENDED_WAIT		0x00000100
+#define SM_PB				0x00000080
+#define SM_CS_HIGH			0x00000040
+#define SM_PAGE_MODE			0x00000008
+
+#define SM_MEM_WIDTH_32BIT		0x00000002
+#define SM_MEM_WIDTH_16BIT		0x00000001
+#define SM_MEM_WIDTH_8BIT		0x00000000
+	
+#define MPMC_SM_CONFIG_MASK		0x001801cb
+
+
+/* MPMC_SM_WAITWEN0_REG	(offset: 0x0204) */
+/* MPMC_SM_WAITWEN1_REG	(offset: 0x0224) */
+/* MPMC_SM_WAITWEN2_REG	(offset: 0x0244) */
+/* MPMC_SM_WAITWEN3_REG	(offset: 0x0264) */
+#define MPMC_SM_WAITWEN_MASK		0x0000000f
+
+
+/* MPMC_SM_WAITOEN0_REG (offset: 0x0208) */
+/* MPMC_SM_WAITOEN1_REG (offset: 0x0228) */
+/* MPMC_SM_WAITOEN2_REG (offset: 0x0248) */
+/* MPMC_SM_WAITOEN3_REG (offset: 0x0268) */
+#define MPMC_SM_WAITOEN_MASK		0x0000000f
+
+/* MPMC_SM_WAITRD0_REG (offset: 0x020C) */
+/* MPMC_SM_WAITRD1_REG (offset: 0x022C) */
+/* MPMC_SM_WAITRD2_REG (offset: 0x024C) */
+/* MPMC_SM_WAITRD3_REG (offset: 0x026C) */
+#define MPMC_SM_WAITRD_MASK		0x0000001f
+
+/* MPMC_SM_WAITPAGE0_REG (offset: 0x0210) */
+/* MPMC_SM_WAITPAGE1_REG (offset: 0x0230) */
+/* MPMC_SM_WAITPAGE2_REG (offset: 0x0250) */
+/* MPMC_SM_WAITPAGE3_REG (offset: 0x0270) */
+#define MPMC_SM_WAITPAGE_MASK		0x0000001f
+
+
+/* MPMC_SM_WAITWR0_REG (offset: 0x0214) */
+/* MPMC_SM_WAITWR1_REG (offset: 0x0234) */
+/* MPMC_SM_WAITWR2_REG (offset: 0x0254) */
+/* MPMC_SM_WAITWR3_REG (offset: 0x0274) */
+#define MPMC_SM_WAITWR_MASK		0x0000001f
+
+
+/* MPMC_SM_WAITTURN0_REG (offset: 0x0218) */
+/* MPMC_SM_WAITTURN1_REG (offset: 0x0238) */
+/* MPMC_SM_WAITTURN2_REG (offset: 0x0258) */
+/* MPMC_SM_WAITTURN3_REG (offset: 0x0278) */
+#define MPMC_SM_WAITTURN_MASK		0x0000000f
+
+
+/* SDRAM mode register */
+/* ref: SDRAM data sheet. Ex: Micron MT48LC4M16A2 data sheet. */
+#define SDRAM_BTLEN_1			0x0000
+#define SDRAM_BTLEN_2			0x0001
+#define SDRAM_BTLEN_4			0x0002
+#define SDRAM_BTLEN_8			0x0003
+#define SDRAM_BTLEN_FULLPAGE		0x0007
+#define SDRAM_BTLEN_MASK		0x0007
+
+#define SDRAM_BT_SEQUENCIAL		0x0000
+#define SDRAM_BT_INTERLEVED		0x0008
+
+#define SDRAM_CAS_LATENCY_2		0x0020
+#define SDRAM_CAS_LATENCY_3		0x0030
+#define SDRAM_CAS_LATENCY_MASK		0x0030
+
+#define SDRAM_OPMODE_STANDARD		0x0000
+#define SDRAM_OPMODE_MASK		0x0180
+
+#define SDRAM_WBTMODE_ENABLE		0x0000
+#define SDRAM_WBTMODE_DISABLE		0x0200
+
+#define SDRAM_MODEREG_MASK		0x03FF
+
+
+
+/*==========================  Interrupt Controller  ==========================*/
+/* registers offset */
+#define IRQ_STATUS_REG			0x00	/* Read */
+#define IRQ_RAW_STATUS_REG		0x04	/* Read */
+#define IRQ_ENABLE_REG			0x08	/* Read/Write */
+#define IRQ_DISABLE_REG			0x0C	/* Write */
+#define IRQ_SOFT_REG			0x10	/* Write */
+
+#define IRQ_MODE_REG			0x14	/* Read/Write */
+#define FIQ_STATUS_REG			0x18	/* Read */
+
+/* test registers */
+#define IRQ_TESTSRC_REG			0x1c	/* Read/Write */
+#define IRQ_SRCSEL_REG			0x20	/* Read/Write */
+#define IRQ_LEVEL_REG			0x24	/* Read/Write */
+
+/*  Macro for accessing Interrupt controller register  */
+#define ADM5120_INTC_REG(_reg) \
+	(*((volatile unsigned long *)(KSEG1ADDR(INTC_BASE + (_reg)))))
+
+/* interrupt levels */
+#define INT_LVL_TIMER			0	/* Timer */
+#define INT_LVL_UART0			1	/* Uart 0 */
+#define INT_LVL_UART1			2	/* Uart 1 */
+#define INT_LVL_USBHOST			3	/* USB Host */
+#define INT_LVL_EXTIO_0			4	/* External I/O 0 */
+#define INT_LVL_EXTIO_1			5	/* External I/O 1 */
+#define INT_LVL_PCI_0			6	/* PCI 0 */
+#define INT_LVL_PCI_1			7	/* PCI 1 */
+#define INT_LVL_PCI_2			8	/* PCI 2 */
+#define INT_LVL_SWITCH			9	/* Switch */
+#define INT_LVL_MAX			INT_LVL_SWITCH	
+
+/* interrupts */
+#define IRQ_TIMER			(0x1 << INT_LVL_TIMER)
+#define IRQ_UART0			(0x1 << INT_LVL_UART0)
+#define IRQ_UART1			(0x1 << INT_LVL_UART1)
+#define IRQ_USBHOST			(0x1 << INT_LVL_USBHOST)
+#define IRQ_EXTIO_0			(0x1 << INT_LVL_EXTIO_0)
+#define IRQ_EXTIO_1			(0x1 << INT_LVL_EXTIO_1)
+#define IRQ_PCI_INT0			(0x1 << INT_LVL_PCI_0)
+#define IRQ_PCI_INT1			(0x1 << INT_LVL_PCI_1)
+#define IRQ_PCI_INT2			(0x1 << INT_LVL_PCI_2)
+#define IRQ_SWITCH			(0x1 << INT_LVL_SWITCH)
+
+#define IRQ_MASK			0x3ff
+
+
+/* IRQ LEVEL reg */
+#define IRQ_EXTIO0_ACT_LOW		IRQ_EXTIO_0
+#define IRQ_EXTIO1_ACT_LOW		IRQ_EXTIO_1
+#define IRQ_PCIINT0_ACT_LOW		IRQ_PCI_INT0
+#define IRQ_PCIINT1_ACT_LOW		IRQ_PCI_INT1
+#define IRQ_PCIINT2_ACT_LOW		IRQ_PCI_INT2
+
+#define IRQ_LEVEL_MASK			0x01F0
+
+/*=========================  Switch Control Register  ========================*/
+/* Control Register */
+#define CODE_REG								0x0000
+#define SftRest_REG			0x0004
+#define Boot_done_REG			0x0008
+#define SWReset_REG			0x000C
+#define Global_St_REG			0x0010
+#define PHY_st_REG			0x0014
+#define Port_st_REG			0x0018
+#define Mem_control_REG			0x001C	
+#define SW_conf_REG			0x0020
+#define CPUp_conf_REG			0x0024
+#define Port_conf0_REG			0x0028
+#define Port_conf1_REG			0x002C
+#define Port_conf2_REG			0x0030
+
+#define VLAN_G1_REG			0x0040
+#define VLAN_G2_REG			0x0044
+#define Send_trig_REG			0x0048
+#define Srch_cmd_REG			0x004C
+#define ADDR_st0_REG			0x0050
+#define ADDR_st1_REG			0x0054
+#define MAC_wt0_REG			0x0058
+#define MAC_wt1_REG			0x005C
+#define BW_cntl0_REG			0x0060
+#define BW_cntl1_REG			0x0064
+#define PHY_cntl0_REG			0x0068
+#define PHY_cntl1_REG			0x006C
+#define FC_th_REG			0x0070
+#define Adj_port_th_REG			0x0074
+#define Port_th_REG			0x0078
+#define PHY_cntl2_REG			0x007C
+#define PHY_cntl3_REG			0x0080
+#define Pri_cntl_REG			0x0084
+#define VLAN_pri_REG			0x0088
+#define TOS_en_REG			0x008C
+#define TOS_map0_REG			0x0090
+#define TOS_map1_REG			0x0094
+#define Custom_pri1_REG			0x0098
+#define Custom_pri2_REG			0x009C
+
+#define Empty_cnt_REG			0x00A4
+#define Port_cnt_sel_REG		0x00A8
+#define Port_cnt_REG			0x00AC
+#define SW_Int_st_REG			0x00B0
+#define SW_Int_mask_REG			0x00B4
+
+// GPIO config
+#define GPIO_conf0_REG			0x00B8
+#define GPIO_conf2_REG			0x00BC
+
+// Watch dog
+#define Watchdog0_REG			0x00C0
+#define Watchdog1_REG			0x00C4
+
+#define Swap_in_REG			0x00C8
+#define Swap_out_REG			0x00CC
+
+// Tx/Rx Descriptors
+#define Send_HBaddr_REG			0x00D0
+#define Send_LBaddr_REG			0x00D4
+#define Recv_HBaddr_REG			0x00D8
+#define Recv_LBaddr_REG			0x00DC
+#define Send_HWaddr_REG			0x00E0
+#define Send_LWaddr_REG			0x00E4
+#define Recv_HWaddr_REG			0x00E8
+#define Recv_LWaddr_REG			0x00EC
+
+// Timer Control 
+#define Timer_int_REG			0x00F0
+#define Timer_REG			0x00F4
+
+// LED control
+#define Port0_LED_REG			0x0100
+#define Port1_LED_REG			0x0104
+#define Port2_LED_REG			0x0108
+#define Port3_LED_REG			0x010c
+#define Port4_LED_REG			0x0110
+
+
+/* Macros for accessing Switch control register */
+#define ADM5120_SW_REG(_reg) \
+	(*((volatile unsigned long *)(KSEG1ADDR(SWCTRL_BASE + (_reg)))))
+
+
+
+/* CODE_REG */
+#define CODE_ID_MASK			0x00FFFF
+#define CODE_ADM5120_ID			0x5120
+
+#define CODE_REV_MASK			0x0F0000
+#define CODE_REV_SHIFT			16
+#define CODE_REV_ADM5120_0		0x8
+
+#define CODE_CLK_MASK			0x300000
+#define CODE_CLK_SHIFT			20
+
+#define CPU_CLK_175MHZ			0x0
+#define CPU_CLK_200MHZ			0x1
+#define CPU_CLK_225MHZ			0x2
+#define CPU_CLK_250MHZ			0x3
+
+#define CPU_SPEED_175M			(175000000/2)
+#define CPU_SPEED_200M			(200000000/2)
+#define CPU_SPEED_225M			(225000000/2)
+#define CPU_SPEED_250M			(250000000/2)
+
+#define CPU_NAND_BOOT			0x01000000
+#define CPU_DCACHE_2K_WAY		(0x1 << 25)
+#define CPU_DCACHE_2WAY			(0x1 << 26)
+#define CPU_ICACHE_2K_WAY		(0x1 << 27)
+#define CPU_ICACHE_2WAY			(0x1 << 28)
+
+#define CPU_GMII_SUPPORT		0x20000000
+
+#define CPU_PQFP_MODE			(0x1 << 29)
+
+#define CPU_CACHE_LINE_SIZE		16
+
+/* SftRest_REG	*/
+#define SOFTWARE_RESET			0x1
+
+/* Boot_done_REG */
+#define BOOT_DONE			0x1
+
+/* SWReset_REG */
+#define SWITCH_RESET			0x1
+
+/* Global_St_REG */
+#define DATA_BUF_BIST_FAILED		(0x1 << 0)
+#define LINK_TAB_BIST_FAILED		(0x1 << 1)
+#define MC_TAB_BIST_FAILED		(0x1 << 2)
+#define ADDR_TAB_BIST_FAILED		(0x1 << 3)
+#define DCACHE_D_FAILED			(0x3 << 4)
+#define DCACHE_T_FAILED			(0x1 << 6)
+#define ICACHE_D_FAILED			(0x3 << 7)
+#define ICACHE_T_FAILED			(0x1 << 9)
+#define BIST_FAILED_MASK		0x03FF
+
+#define ALLMEM_TEST_DONE		(0x1 << 10)
+
+#define SKIP_BLK_CNT_MASK		0x1FF000
+#define SKIP_BLK_CNT_SHIFT		12
+
+
+/* PHY_st_REG */
+#define PORT_LINK_MASK			0x0000001F
+#define PORT_MII_LINKFAIL		0x00000020
+#define PORT_SPEED_MASK			0x00001F00
+
+#define PORT_GMII_SPD_MASK		0x00006000
+#define PORT_GMII_SPD_10M		0x00000000
+#define PORT_GMII_SPD_100M		0x00002000
+#define PORT_GMII_SPD_1000M		0x00004000
+
+#define PORT_DUPLEX_MASK		0x003F0000
+#define PORT_FLOWCTRL_MASK		0x1F000000
+
+#define PORT_GMII_FLOWCTRL_MASK		0x60000000
+#define PORT_GMII_FC_ON			0x20000000
+#define PORT_GMII_RXFC_ON		0x20000000
+#define PORT_GMII_TXFC_ON		0x40000000
+
+/* Port_st_REG */
+#define PORT_SECURE_ST_MASK		0x001F
+#define MII_PORT_TXC_ERR		0x0080
+
+/* Mem_control_REG */
+#define SDRAM_SIZE_4MBYTES		0x0001
+#define SDRAM_SIZE_8MBYTES		0x0002
+#define SDRAM_SIZE_16MBYTES		0x0003
+#define SDRAM_SIZE_64MBYTES		0x0004
+#define SDRAM_SIZE_128MBYTES		0x0005
+#define SDRAM_SIZE_MASK			0x0007
+
+#define MEMCNTL_SDRAM1_EN		(0x1 << 5)
+
+#define ROM_SIZE_DISABLE		0x0000
+#define ROM_SIZE_512KBYTES		0x0001
+#define ROM_SIZE_1MBYTES		0x0002
+#define	ROM_SIZE_2MBYTES		0x0003
+#define ROM_SIZE_4MBYTES		0x0004
+#define ROM_SIZE_8MBYTES		0x0005
+#define ROM_SIZE_MASK			0x0007
+
+#define ROM0_SIZE_SHIFT			8
+#define ROM1_SIZE_SHIFT			16
+
+
+/* SW_conf_REG */
+#define SW_AGE_TIMER_MASK		0x000000F0
+#define SW_AGE_TIMER_DISABLE		0x00000000
+#define SW_AGE_TIMER_FAST		0x00000080
+#define SW_AGE_TIMER_300SEC		0x00000010
+#define SW_AGE_TIMER_600SEC		0x00000020
+#define SW_AGE_TIMER_1200SEC		0x00000030
+#define SW_AGE_TIMER_2400SEC		0x00000040
+#define SW_AGE_TIMER_4800SEC		0x00000050
+#define SW_AGE_TIMER_9600SEC		0x00000060
+#define SW_AGE_TIMER_19200SEC		0x00000070
+//#define SW_AGE_TIMER_38400SEC		0x00000070
+
+#define SW_BC_PREV_MASK			0x00000300
+#define SW_BC_PREV_DISABLE		0x00000000
+#define SW_BC_PREV_64BC			0x00000100
+#define SW_BC_PREV_48BC			0x00000200
+#define SW_BC_PREV_32BC			0x00000300
+
+#define SW_MAX_LEN_MASK			0x00000C00
+#define SW_MAX_LEN_1536			0x00000000
+#define SW_MAX_LEN_1522			0x00000800
+#define SW_MAX_LEN_1518			0x00000400
+
+#define SW_DIS_COLABT			0x00001000
+
+#define SW_HASH_ALG_MASK		0x00006000
+#define SW_HASH_ALG_DIRECT		0x00000000
+#define SW_HASH_ALG_XOR48		0x00002000
+#define SW_HASH_ALG_XOR32		0x00004000
+
+#define SW_DISABLE_BACKOFF_TIMER	0x00008000
+
+#define SW_BP_NUM_MASK			0x000F0000
+#define SW_BP_NUM_SHIFT			16
+#define SW_BP_MODE_MASK			0x00300000
+#define SW_BP_MODE_DISABLE		0x00000000
+#define SW_BP_MODE_JAM			0x00100000
+#define SW_BP_MODE_JAMALL		0x00200000
+#define SW_BP_MODE_CARRIER		0x00300000
+#define SW_RESRV_MC_FILTER		0x00400000
+#define SW_BISR_DISABLE			0x00800000
+
+#define SW_DIS_MII_WAS_TX		0x01000000
+#define SW_BISS_EN			0x02000000
+#define SW_BISS_TH_MASK			0x0C000000
+#define SW_BISS_TH_SHIFT		26
+#define SW_REQ_LATENCY_MASK		0xF0000000
+#define SW_REQ_LATENCY_SHIFT		28
+
+
+/* CPUp_conf_REG */
+#define SW_CPU_PORT_DISABLE		0x00000001
+#define SW_PADING_CRC			0x00000002
+#define SW_BRIDGE_MODE			0x00000004
+
+#define SW_DIS_UN_SHIFT			9
+#define SW_DIS_UN_MASK			(0x3F << SW_DIS_UN_SHIFT)
+#define SW_DIS_MC_SHIFT			16
+#define SW_DIS_MC_MASK			(0x3F << SW_DIS_MC_SHIFT)
+#define SW_DIS_BC_SHIFT			24
+#define SW_DIS_BC_MASK			(0x3F << SW_DIS_BC_SHIFT)
+
+
+/* Port_conf0_REG */
+#define SW_DISABLE_PORT_MASK		0x0000003F
+#define SW_EN_MC_MASK			0x00003F00
+#define SW_EN_MC_SHIFT			8
+#define SW_EN_BP_MASK			0x003F0000
+#define SW_EN_BP_SHIFT			16
+#define SW_EN_FC_MASK			0x3F000000
+#define SW_EN_FC_SHIFT			24
+
+
+/* Port_conf1_REG */
+#define SW_DIS_SA_LEARN_MASK		0x0000003F
+#define SW_PORT_BLOCKING_MASK		0x00000FC0
+#define SW_PORT_BLOCKING_SHIFT		6
+#define SW_PORT_BLOCKING_ON		0x1
+
+#define SW_PORT_BLOCKING_MODE_MASK	0x0003F000
+#define SW_PORT_BLOCKING_MODE_SHIFT	12
+#define SW_PORT_BLOCKING_CTRLONLY	0x1
+
+#define SW_EN_PORT_AGE_MASK		0x03F00000
+#define SW_EN_PORT_AGE_SHIFT		20
+#define SW_EN_SA_SECURED_MASK		0xFC000000
+#define SW_EN_SA_SECURED_SHIFT		26
+
+
+/* Port_conf2_REG */
+#define SW_GMII_AN_EN			0x00000001
+#define SW_GMII_FORCE_SPD_MASK		0x00000006
+#define SW_GMII_FORCE_SPD_10M		0
+#define SW_GMII_FORCE_SPD_100M		0x2
+#define SW_GMII_FORCE_SPD_1000M		0x4
+
+#define SW_GMII_FORCE_FULL_DUPLEX	0x00000008
+
+#define SW_GMII_FORCE_RXFC		0x00000010
+#define SW_GMII_FORCE_TXFC		0x00000020
+
+#define SW_GMII_EN			0x00000040
+#define SW_GMII_REVERSE			0x00000080
+
+#define SW_GMII_TXC_CHECK_EN		0x00000100
+
+#define SW_LED_FLASH_TIME_MASK		0x00030000
+#define SW_LED_FLASH_TIME_30MS		0x00000000
+#define SW_LED_FLASH_TIME_60MS		0x00010000
+#define SW_LED_FLASH_TIME_240MS		0x00020000
+#define SW_LED_FLASH_TIME_480MS		0x00030000
+
+
+/* Send_trig_REG */
+#define SEND_TRIG_LOW			0x0001
+#define SEND_TRIG_HIGH			0x0002
+
+
+/* Srch_cmd_REG */
+#define SW_MAC_SEARCH_START		0x000001
+#define SW_MAX_SEARCH_AGAIN		0x000002
+
+
+/* MAC_wt0_REG */
+#define SW_MAC_WRITE			0x00000001
+#define SW_MAC_WRITE_DONE		0x00000002
+#define SW_MAC_FILTER_EN		0x00000004
+#define SW_MAC_VLANID_SHIFT		3
+#define SW_MAC_VLANID_MASK		0x00000038
+#define SW_MAC_VLANID_EN		0x00000040
+#define SW_MAC_PORTMAP_MASK		0x00001F80
+#define SW_MAC_PORTMAP_SHIFT		7
+#define SW_MAC_AGE_MASK			(0x7 << 13)
+#define SW_MAC_AGE_STATIC		(0x7 << 13)
+#define SW_MAC_AGE_VALID		(0x1 << 13)
+#define SW_MAC_AGE_EMPTY		0
+
+/* BW_cntl0_REG */
+#define SW_PORT_TX_NOLIMIT		0
+#define SW_PORT_TX_64K			1
+#define SW_PORT_TX_128K			2
+#define SW_PORT_TX_256K			3
+#define SW_PORT_TX_512K			4
+#define SW_PORT_TX_1M			5
+#define SW_PORT_TX_4M			6
+#define SW_PORT_TX_10MK			7
+
+/* BW_cntl1_REG */
+#define SW_TRAFFIC_SHAPE_IPG		(0x1 << 31)
+
+/* PHY_cntl0_REG */
+#define SW_PHY_ADDR_MASK		0x0000001F
+#define PHY_ADDR_MAX			0x1f
+#define SW_PHY_REG_ADDR_MASK		0x00001F00
+#define SW_PHY_REG_ADDR_SHIFT		8
+#define PHY_REG_ADDR_MAX		0x1f
+#define SW_PHY_WRITE			0x00002000
+#define SW_PHY_READ			0x00004000
+#define SW_PHY_WDATA_MASK		0xFFFF0000
+#define SW_PHY_WDATA_SHIFT		16
+
+
+/* PHY_cntl1_REG */
+#define SW_PHY_WRITE_DONE		0x00000001
+#define SW_PHY_READ_DONE		0x00000002
+#define SW_PHY_RDATA_MASK		0xFFFF0000
+#define SW_PHY_RDATA_SHIFT		16
+
+/* FC_th_REG */
+/* Adj_port_th_REG */
+/* Port_th_REG */
+
+/* PHY_cntl2_REG */
+#define SW_PHY_AN_MASK			0x0000001F
+#define SW_PHY_SPD_MASK			0x000003E0
+#define SW_PHY_SPD_SHIFT		5
+#define SW_PHY_DPX_MASK			0x00007C00
+#define SW_PHY_DPX_SHIFT		10
+#define SW_FORCE_FC_MASK		0x000F8000
+#define SW_FORCE_FC_SHIFT		15
+#define SW_PHY_NORMAL_MASK		0x01F00000
+#define SW_PHY_NORMAL_SHIFT		20
+#define SW_PHY_AUTOMDIX_MASK		0x3E000000
+#define SW_PHY_AUTOMDIX_SHIFT		25
+#define SW_PHY_REC_MCCAVERAGE		0x40000000
+
+
+/* PHY_cntl3_REG */
+/* Pri_cntl_REG */
+/* VLAN_pri_REG */
+/* TOS_en_REG */
+/* TOS_map0_REG */
+/* TOS_map1_REG */
+/* Custom_pri1_REG */
+/* Custom_pri2_REG */
+/* Empty_cnt_REG */
+/* Port_cnt_sel_REG */
+/* Port_cnt_REG */
+
+
+/* SW_Int_st_REG & SW_Int_mask_REG */
+#define SEND_H_DONE_INT			0x0000001
+#define SEND_L_DONE_INT			0x0000002
+#define RX_H_DONE_INT			0x0000004
+#define RX_L_DONE_INT			0x0000008
+#define RX_H_DESC_FULL_INT		0x0000010
+#define RX_L_DESC_FULL_INT		0x0000020
+#define PORT0_QUE_FULL_INT		0x0000040
+#define PORT1_QUE_FULL_INT		0x0000080
+#define PORT2_QUE_FULL_INT		0x0000100
+#define PORT3_QUE_FULL_INT		0x0000200
+#define PORT4_QUE_FULL_INT		0x0000400
+#define PORT5_QUE_FULL_INT		0x0000800
+
+#define CPU_QUE_FULL_INT		0x0002000
+#define GLOBAL_QUE_FULL_INT		0x0004000
+#define MUST_DROP_INT			0x0008000
+#define BC_STORM_INT			0x0010000
+
+#define PORT_STATUS_CHANGE_INT		0x0040000
+#define INTRUDER_INT			0x0080000
+#define	WATCHDOG0_EXPR_INT		0x0100000
+#define WATCHDOG1_EXPR_INT		0x0200000
+#define RX_DESC_ERR_INT			0x0400000
+#define SEND_DESC_ERR_INT		0x0800000
+#define CPU_HOLD_INT			0x1000000
+#define SWITCH_INT_MASK			0x1FDEFFF
+
+
+/* GPIO_conf0_REG */
+#define GPIO0_INPUT_MODE		0x00000001
+#define GPIO1_INPUT_MODE		0x00000002
+#define GPIO2_INPUT_MODE		0x00000004
+#define GPIO3_INPUT_MODE		0x00000008
+#define GPIO4_INPUT_MODE		0x00000010
+#define GPIO5_INPUT_MODE		0x00000020
+#define GPIO6_INPUT_MODE		0x00000040
+#define GPIO7_INPUT_MODE		0x00000080
+
+#define GPIO0_OUTPUT_MODE		0
+#define GPIO1_OUTPUT_MODE		0
+#define GPIO2_OUTPUT_MODE		0
+#define GPIO3_OUTPUT_MODE		0
+#define GPIO4_OUTPUT_MODE		0
+#define GPIO5_OUTPUT_MODE		0
+#define GPIO6_OUTPUT_MODE		0
+#define GPIO7_OUTPUT_MODE		0
+
+#define GPIO0_INPUT_MASK		0x00000100
+#define GPIO1_INPUT_MASK		0x00000200
+#define GPIO2_INPUT_MASK		0x00000400
+#define GPIO3_INPUT_MASK		0x00000800
+#define GPIO4_INPUT_MASK		0x00001000
+#define GPIO5_INPUT_MASK		0x00002000
+#define GPIO6_INPUT_MASK		0x00004000
+#define GPIO7_INPUT_MASK		0x00008000
+
+#define GPIO0_OUTPUT_EN			0x00010000
+#define GPIO1_OUTPUT_EN			0x00020000
+#define GPIO2_OUTPUT_EN			0x00040000
+#define GPIO3_OUTPUT_EN			0x00080000
+#define GPIO4_OUTPUT_EN			0x00100000
+#define GPIO5_OUTPUT_EN			0x00200000
+#define GPIO6_OUTPUT_EN			0x00400000
+#define GPIO7_OUTPUT_EN			0x00800000
+
+#define GPIO_CONF0_OUTEN_MASK		0x00ff0000
+
+#define GPIO0_OUTPUT_HI			0x01000000
+#define GPIO1_OUTPUT_HI			0x02000000
+#define GPIO2_OUTPUT_HI			0x04000000
+#define GPIO3_OUTPUT_HI			0x08000000
+#define GPIO4_OUTPUT_HI			0x10000000
+#define GPIO5_OUTPUT_HI			0x20000000
+#define GPIO6_OUTPUT_HI			0x40000000
+#define GPIO7_OUTPUT_HI			0x80000000
+
+#define GPIO0_OUTPUT_LOW		0
+#define GPIO1_OUTPUT_LOW		0
+#define GPIO2_OUTPUT_LOW		0
+#define GPIO3_OUTPUT_LOW		0
+#define GPIO4_OUTPUT_LOW		0
+#define GPIO5_OUTPUT_LOW		0
+#define GPIO6_OUTPUT_LOW		0
+#define GPIO7_OUTPUT_LOW		0
+
+
+/* GPIO_conf2_REG */
+#define EXTIO_WAIT_EN			(0x1 << 6)
+#define EXTIO_CS1_INT1_EN		(0x1 << 5)
+#define EXTIO_CS0_INT0_EN		(0x1 << 4)
+
+/* Watchdog0_REG, Watchdog1_REG */
+#define WATCHDOG0_RESET_EN		0x80000000
+#define WATCHDOG1_DROP_EN		0x80000000
+
+#define WATCHDOG_TIMER_SET_MASK		0x7FFF0000
+#define WATCHDOG_TIMER_SET_SHIFT	16
+#define WATCHDOG_TIMER_MASK		0x00007FFF
+
+
+/* Timer_int_REG */
+#define SW_TIMER_INT_DISABLE		0x10000
+#define SW_TIMER_INT			0x1
+
+/* Timer_REG */
+#define SW_TIMER_EN			0x10000
+#define SW_TIMER_MASK			0xffff
+#define SW_TIMER_10MS_TICKS		0x3D09
+#define SW_TIMER_1MS_TICKS		0x61A
+#define SW_TIMER_100US_TICKS		0x9D
+
+
+/* Port0_LED_REG, Port1_LED_REG, Port2_LED_REG, Port3_LED_REG, Port4_LED_REG*/
+#define GPIOL_INPUT_MODE		0x00
+#define GPIOL_OUTPUT_FLASH		0x01
+#define GPIOL_OUTPUT_LOW		0x02
+#define GPIOL_OUTPUT_HIGH		0x03
+#define GPIOL_LINK_LED			0x04
+#define GPIOL_SPEED_LED			0x05
+#define GPIOL_DUPLEX_LED		0x06
+#define GPIOL_ACT_LED			0x07
+#define GPIOL_COL_LED			0x08
+#define GPIOL_LINK_ACT_LED		0x09
+#define GPIOL_DUPLEX_COL_LED		0x0A
+#define GPIOL_10MLINK_ACT_LED		0x0B
+#define GPIOL_100MLINK_ACT_LED		0x0C
+#define GPIOL_CTRL_MASK			0x0F
+
+#define GPIOL_INPUT_MASK		0x7000
+#define GPIOL_INPUT_0_MASK		0x1000
+#define GPIOL_INPUT_1_MASK		0x2000
+#define GPIOL_INPUT_2_MASK		0x4000
+
+#define PORT_LED0_SHIFT			0
+#define PORT_LED1_SHIFT			4
+#define PORT_LED2_SHIFT			8
+
+
+/*===========================  UART Control Register  ========================*/
+#define UART_DR_REG			0x00
+#define UART_RSR_REG			0x04
+#define UART_ECR_REG			0x04
+#define UART_LCR_H_REG			0x08
+#define UART_LCR_M_REG			0x0c
+#define UART_LCR_L_REG			0x10
+#define UART_CR_REG			0x14
+#define UART_FR_REG			0x18
+#define UART_IIR_REG			0x1c
+#define UART_ICR_REG			0x1C
+#define UART_ILPR_REG			0x20
+
+/*  rsr/ecr reg  */
+#define UART_OVERRUN_ERR		0x08
+#define UART_BREAK_ERR			0x04
+#define UART_PARITY_ERR			0x02
+#define UART_FRAMING_ERR		0x01
+#define UART_RX_STATUS_MASK		0x0f
+#define UART_RX_ERROR	( UART_BREAK_ERR | UART_PARITY_ERR | UART_FRAMING_ERR)
+
+/*  lcr_h reg  */
+#define UART_SEND_BREAK			0x01
+#define UART_PARITY_EN			0x02
+#define UART_EVEN_PARITY		0x04
+#define UART_TWO_STOP_BITS		0x08
+#define UART_ENABLE_FIFO		0x10
+
+#define UART_WLEN_5BITS			0x00
+#define UART_WLEN_6BITS			0x20
+#define UART_WLEN_7BITS			0x40
+#define UART_WLEN_8BITS			0x60
+#define UART_WLEN_MASK			0x60
+
+/*  cr reg  */
+#define UART_PORT_EN			0x01
+#define UART_SIREN			0x02
+#define UART_SIRLP			0x04
+#define UART_MODEM_STATUS_INT_EN	0x08
+#define UART_RX_INT_EN			0x10
+#define UART_TX_INT_EN			0x20
+#define UART_RX_TIMEOUT_INT_EN		0x40
+#define UART_LOOPBACK_EN		0x80
+
+/*  fr reg  */
+#define UART_CTS			0x01
+#define UART_DSR			0x02
+#define UART_DCD			0x04
+#define UART_BUSY			0x08
+#define UART_RX_FIFO_EMPTY		0x10
+#define UART_TX_FIFO_FULL		0x20
+#define UART_RX_FIFO_FULL		0x40
+#define UART_TX_FIFO_EMPTY		0x80
+
+/*  iir/icr reg  */
+#define UART_MODEM_STATUS_INT		0x01
+#define UART_RX_INT			0x02
+#define UART_TX_INT			0x04
+#define UART_RX_TIMEOUT_INT		0x08
+
+#define UART_INT_MASK			0x0f
+
+#define ADM5120_UARTCLK_FREQ		62500000
+
+/* This is slightly different from the ADM5120 manual, this method has better
+   rounding for higher baudrates
+	- Jeroen
+ */
+#define UART_BAUDDIV(_rate) \
+	((unsigned long)(((ADM5120_UARTCLK_FREQ)/(8*(_rate))+1)/2 - 1))
+
+/*  uart_baudrate  */
+#define UART_230400bps_DIVISOR		UART_BAUDDIV(230400)
+#define UART_115200bps_DIVISOR		UART_BAUDDIV(115200)
+#define UART_76800bps_DIVISOR		UART_BAUDDIV(76800)
+#define UART_57600bps_DIVISOR		UART_BAUDDIV(57600)
+#define UART_38400bps_DIVISOR		UART_BAUDDIV(38400)
+#define UART_19200bps_DIVISOR		UART_BAUDDIV(19200)
+#define UART_14400bps_DIVISOR		UART_BAUDDIV(14400)
+#define UART_9600bps_DIVISOR		UART_BAUDDIV(9600)
+#define UART_2400bps_DIVISOR		UART_BAUDDIV(2400)
+#define UART_1200bps_DIVISOR		UART_BAUDDIV(1200)
+
+
+/* Cache Controller */
+//#define ADM5120_CACHE_CTRL_BASE	0x70000000
+#define ADM5120_CACHE_LINE_SIZE		16
+//#define ADM5120_CACHE_CTRL_REGSIZE	4
+
+
+/********** GPIO macro *************/
+#define GPIO_MEASURE	0x000f00f0 //enable output status of pin 0, 1, 2, 3 
+
+#define GPIO_MEASURE_INIT() \
+do { \
+	ADM5120_SW_REG(GPIO_conf0_REG) = GPIO_MEASURE; \
+} while (0)
+
+
+#define GPIO_SET_HI(num) \
+do { \
+	ADM5120_SW_REG(GPIO_conf0_REG) |= 1 << (24 + num); \
+} while (0)
+
+
+#define GPIO_SET_LOW(num) \
+do { \
+	ADM5120_SW_REG(GPIO_conf0_REG) &= ~(1 << (24 + num)); \
+} while (0)
+
+
+#define GPIO_TOGGLE(num) \
+do { \
+	ADM5120_SW_REG(GPIO_conf0_REG) ^= (1 << (24 + num)); \
+} while (0)
+
+
+#define BOOT_LINE_SIZE	256
+#define BSP_STR_LEN		64
+
+/*
+ * System configuration
+ */
+typedef struct BOARD_CFG_S
+{
+	unsigned long blmagic;
+	unsigned char bootline[BOOT_LINE_SIZE+1];
+	
+	unsigned long macmagic;
+    unsigned char mac[4][8];
+
+	unsigned long idmagic;    
+    unsigned char serial[BSP_STR_LEN+1];
+
+    unsigned long vermagic;
+    unsigned char ver[BSP_STR_LEN+1];
+	
+} BOARD_CFG_T, *PBOARD_CFG_T;
+
+
+#define BL_MAGIC			0x6c62676d
+#define MAC_MAGIC			0x636d676d
+#define VER_MAGIC			0x7276676d
+#define ID_MAGIC			0x6469676d
+
+
+
+
+
+#endif /* __ADM5120_H__ */
diff -ruN linux-2.6.10/include/asm-mips/am5120/mx.h linux-2.6.10-adm.1/include/asm-mips/am5120/mx.h
--- linux-2.6.10/include/asm-mips/am5120/mx.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/include/asm-mips/am5120/mx.h	2005-01-27 21:06:27.000000000 +0100
@@ -0,0 +1,69 @@
+/*****************************************************************************
+;
+;   (C) Unpublished Work of ADMtek Technology,  Corp.  All Rights Reserved.
+;
+;       THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
+;       PROPRIETARY AND TRADESECRET INFORMATION OF ADMTEK TECHNOLOGY CORP.
+;       ACCESS TO THIS WORK IS RESTRICTED TO (I) ADMTEK EMPLOYEES WHO HAVE A
+;       NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR ASSIGNMENTS
+;       AND (II) ENTITIES OTHER THAN ADMTEK WHO HAVE ENTERED INTO APPROPRIATE
+;       LICENSE AGREEMENTS.  NO PART OF THIS WORK MAY BE USED, PRACTICED,
+;       PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,
+;       ABBRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
+;       TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF ADMTEK.
+;       ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD
+;       SUBJECT THE PERPERTRATOR TO CRIMINAL AND CIVIL LIABILITY.
+;------------------------------------------------------------------------------
+;
+;    Project : Common plateform
+;    Creator : Simon
+;    File    : nv_drv.h
+;
+;Modification History:
+;   Location    Resonder   Modification Description
+; ------------ ---------- ----------------------------------------------
+;
+;*****************************************************************************/
+#if __cplusplus
+extern "C" {
+#endif
+
+#ifndef _FLASH_H_
+#define _FLASH_H_
+
+enum    FLASH_E
+{
+    FLASH_NOT_FIT_IN = -2,
+    FLASH_ERROR = -1,
+    FLASH_OK = 0,
+    FLASH_PARTIAL_DONE
+};
+
+typedef struct FLASH_DESC_S
+{
+    struct FLASH_DESC_S *next;
+    int flash_size;
+    int addr_inc;
+    int byte_width;
+    char *start;
+    unsigned long *blocks;
+    int num;
+    int (*erase)(struct FLASH_DESC_S *cp, char *flash, int cells);
+    int (*read) (struct FLASH_DESC_S *cp, char *flash, char *dst, int cells);
+    int (*write)(struct FLASH_DESC_S *cp, char *flash, char *src, int cells);
+}
+FLASH_DESC;
+
+
+int flash_init();
+int flash_add(FLASH_DESC *cp);
+int flash_erase(char *flash, int size);
+int flash_read (char *flash, char *dst, int size);
+int flash_write(char *flash, char *src, int size);
+
+
+#endif  /* _FLASH_H_   */
+
+#if __cplusplus
+}
+#endif
diff -ruN linux-2.6.10/include/asm-mips/am5120/mx29lv320b.h linux-2.6.10-adm.1/include/asm-mips/am5120/mx29lv320b.h
--- linux-2.6.10/include/asm-mips/am5120/mx29lv320b.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/include/asm-mips/am5120/mx29lv320b.h	2005-01-27 21:06:27.000000000 +0100
@@ -0,0 +1,61 @@
+/*****************************************************************************
+;
+;   (C) Unpublished Work of ADMtek Incorporated.  All Rights Reserved.
+;
+;       THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,
+;       PROPRIETARY AND TRADESECRET INFORMATION OF ADMTEK INCORPORATED.
+;       ACCESS TO THIS WORK IS RESTRICTED TO (I) ADMTEK EMPLOYEES WHO HAVE A
+;       NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR ASSIGNMENTS
+;       AND (II) ENTITIES OTHER THAN ADMTEK WHO HAVE ENTERED INTO APPROPRIATE
+;       LICENSE AGREEMENTS.  NO PART OF THIS WORK MAY BE USED, PRACTICED,
+;       PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,
+;       ABBRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
+;       TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF ADMTEK.
+;       ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD
+;       SUBJECT THE PERPERTRATOR TO CRIMINAL AND CIVIL LIABILITY.
+;
+;------------------------------------------------------------------------------
+;
+;    Project : ADM5120
+;    Creator : 
+;    File    : include/asm/am5120/mx29lv320b.h
+;    Date    : 2003.07.30
+;    Abstract: 
+;
+;Modification History:
+; 
+;
+;*****************************************************************************/
+
+
+#ifndef  __MX29LV320B_H__
+#define  __MX29LV320B_H__
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#define FLASH_PHYS_ADDR 0x1FC00000
+#define FLASH_SIZE 		0x200000  
+
+#define FLASH_PARTITION1_ADDR 0x00000000
+#define FLASH_PARTITION1_SIZE 0x00200000
+
+struct map_info mx29lv320b_map = {
+		.name =		"MX29LV320B flash device",
+		.size =		FLASH_SIZE,
+		.buswidth =	2,
+};
+
+struct mtd_partition mx29lv320b_parts[] = {
+	{
+		.name =		"Flash Disk 1",
+		.offset =	FLASH_PARTITION1_ADDR,
+		.size =		FLASH_PARTITION1_SIZE
+	}
+};
+
+#define PARTITION_COUNT (sizeof(mx29lv320b_parts)/sizeof(struct mtd_partition))
+
+#endif /* __MX29LV320B_H__ */
+
diff -ruN linux-2.6.10/include/asm-mips/am5120/prom.h linux-2.6.10-adm.1/include/asm-mips/am5120/prom.h
--- linux-2.6.10/include/asm-mips/am5120/prom.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.10-adm.1/include/asm-mips/am5120/prom.h	2005-01-27 21:06:27.000000000 +0100
@@ -0,0 +1,49 @@
+/*
+ * Carsten Langgaard, carstenl@mips.com
+ * Copyright (C) 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.
+ *
+ * ########################################################################
+ *
+ * MIPS boards bootprom interface for the Linux kernel.
+ *
+ */
+
+#ifndef _MIPS_PROM_H
+#define _MIPS_PROM_H
+
+extern char *prom_getcmdline(void);
+extern char *prom_getenv(char *name);
+extern void setup_prom_printf(int tty_no);
+extern void prom_printf(char *fmt, ...);
+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 void mips_display_message(const char *str);
+extern void mips_display_word(unsigned int num);
+extern int get_ethernet_addr(char *ethernet_addr);
+
+/* Memory descriptor management. */
+#define PROM_MAX_PMEMBLOCKS    32
+struct prom_pmemblock {
+        unsigned long base; /* Within KSEG0. */
+        unsigned int size;  /* In bytes. */
+        unsigned int type;  /* free or prom memory */
+};
+
+#endif /* !(_MIPS_PROM_H) */
diff -ruN linux-2.6.10/include/asm-mips/bootinfo.h linux-2.6.10-adm.1/include/asm-mips/bootinfo.h
--- linux-2.6.10/include/asm-mips/bootinfo.h	2004-12-24 22:34:26.000000000 +0100
+++ linux-2.6.10-adm.1/include/asm-mips/bootinfo.h	2005-01-27 21:06:26.000000000 +0100
@@ -212,6 +212,12 @@
 #define MACH_GROUP_TITAN       22	/* PMC-Sierra Titan		*/
 #define  MACH_TITAN_YOSEMITE	1	/* PMC-Sierra Yosemite		*/
 
+/*
+ * Valid machtype for group ADMtek
+ */
+#define MACH_GROUP_ADM_GW      23
+#define MACH_ADM_GW_5120	0
+
 #define CL_SIZE			COMMAND_LINE_SIZE
 
 const char *get_system_type(void);
diff -ruN linux-2.6.10/include/linux/init.h linux-2.6.10-adm.1/include/linux/init.h
--- linux-2.6.10/include/linux/init.h	2004-12-24 22:33:50.000000000 +0100
+++ linux-2.6.10-adm.1/include/linux/init.h	2005-01-27 21:06:29.000000000 +0100
@@ -86,6 +86,8 @@
 	static initcall_t __initcall_##fn __attribute_used__ \
 	__attribute__((__section__(".initcall" level ".init"))) = fn
 
+#define early_initcall(fn)		__define_initcall(".early1",fn)
+
 #define core_initcall(fn)		__define_initcall("1",fn)
 #define postcore_initcall(fn)		__define_initcall("2",fn)
 #define arch_initcall(fn)		__define_initcall("3",fn)

             reply	other threads:[~2005-01-27 20:34 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-27 20:34 Jeroen Vreeken [this message]
2005-01-27 21:01 ` [PATCH] ADM5120 for 2.6.10 sjhill
2005-01-27 21:17   ` Jeroen Vreeken
2005-01-27 21:32     ` sjhill
2005-01-27 22:00       ` Jeroen Vreeken
2005-01-27 22:00         ` Jeroen Vreeken
2005-01-28 16:56         ` Tsang-Ren Chang
2005-01-28 17:03           ` sjhill

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=41F9503E.5030004@amsat.org \
    --to=pe1rxq@amsat.org \
    --cc=linux-mips@linux-mips.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.