[PATCH] ADM5120 for 2.6.10

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

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@xxxxxxxxxxxxx
+;    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@xxxxxxxxxxxxx
+;    File    : arch/mips/am5120/irq.c
+;	 Date    : 2003.3.4
+;    Abstract: 
+;
+;Modification History:
+;
+;	Jeroen Vreeken (pe1rxq@xxxxxxxxx)
+;	Simplified and merged with 5120_int.c
+;
+;	Includes code by:
+;	Carsten Langgaard, carstenl@xxxxxxxx
+;	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@xxxxxxxxxxxxx
+;    File    : arch/mips/am5120/memory.c
+;	 Date    : 2003.3.4
+;    Abstract: 
+;
+;Modification History:
+;
+;	Jeroen Vreeken (pe1rxq@xxxxxxxxx)
+;	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@xxxxxxxx
+ * 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@xxxxxxxxxxxxx
+;    File    : arch/mips/am5120/prom.c
+;	 Date    : 2003.3.4
+;    Abstract: 
+;
+;Modification History:
+;
+;	Jeroen Vreeken (pe1rxq@xxxxxxxxx)
+;	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@xxxxxxxxxxxxx
+;    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@xxxxxxxxxxxxx
+;    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@xxxxxxxx
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
+ * Copyright (C) 2005 Jeroen Vreeken (pe1rxq@xxxxxxxxx)
+ *
+ * ########################################################################
+ *
+ *  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@xxxxxxxxx)
+;	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@xxxxxxxx
+ * 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)

[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux