|
|
|
[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 :)
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)
[Linux MIPS Home] [Kernel list] [Linux ARM] [Linux] [Git] [Photo] [Yosemite News] [MIPS Architecture] [Linux SCSI] [Linux Hams] [Site Home]
![]() |
![]() |