* Patch by Greg Ungerer, 19 May 2005:
  add support for the KS8695P (ARM 922 based) CPU

* Patch by Steven Scholz, 19 May 2005:
  Add support for CONFIG_SERIAL_TAG on ARM boards
diff --git a/CHANGELOG b/CHANGELOG
index c704d8c..9aa5a1b 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,13 @@
 Changes for U-Boot 1.1.3:
 ======================================================================
 
+* Patches by Greg Ungerer, 19 May 2005:
+  - add support for the KS8695P (ARM 922 based) CPU
+  - add support for the OpenGear CM4008, CM4116 and CM4148 boards
+
+* Patch by Steven Scholz, 19 May 2005:
+  Add support for CONFIG_SERIAL_TAG on ARM boards
+
 * Add PCI support for Sorcery board.
   Code cleanup (especially Sorcery / Alaska / Yukon serial driver).
 
diff --git a/CREDITS b/CREDITS
index cec74a9..948043e 100644
--- a/CREDITS
+++ b/CREDITS
@@ -394,6 +394,10 @@
 E: <runet@innovsys.com>
 D: Support for Motorola MPC8266ADS board
 
+N: Greg Ungerer
+E: greg.ungerer@opengear.com
+D: Support for ks8695 CPU, and OpenGear cmXXXX boards
+
 N: David Updegraff
 E: dave@cray.com
 D: Port to Cray L1 board; DHCP vendor extensions
diff --git a/MAINTAINERS b/MAINTAINERS
index 4115127..5b560ea 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -413,6 +413,12 @@
 
 	B2				ARM7TDMI (S3C44B0X)
 
+Greg Ungerer <greg.ungerer@opengear.com>
+
+	cm4008			ks8695p
+	cm4116			ks8695p
+	cm4148			ks8695p
+
 Alex Züpke <azu@sysgo.de>
 
 	lart			SA1100
diff --git a/cpu/arm920t/ks8695/Makefile b/cpu/arm920t/ks8695/Makefile
new file mode 100644
index 0000000..ada7174
--- /dev/null
+++ b/cpu/arm920t/ks8695/Makefile
@@ -0,0 +1,43 @@
+#
+# (C) Copyright 2000-2005
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that 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
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= lib$(SOC).a
+
+OBJS	= interrupts.o serial.o
+SOBJS	= lowlevel_init.o
+
+all:	.depend $(LIB)
+
+$(LIB):	$(OBJS) $(SOBJS)
+	$(AR) crv $@ $(OBJS) $(SOBJS)
+
+#########################################################################
+
+.depend:	Makefile $(OBJS:.o=.c)
+		$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/cpu/arm920t/ks8695/interrupts.c b/cpu/arm920t/ks8695/interrupts.c
new file mode 100644
index 0000000..883d689
--- /dev/null
+++ b/cpu/arm920t/ks8695/interrupts.c
@@ -0,0 +1,112 @@
+/*
+ * (C) Copyright 2004-2005, Greg Ungerer <greg.ungerer@opengear.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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
+ */
+
+#include <common.h>
+#include <asm/arch/platform.h>
+
+/*
+ * Handy KS8695 register access functions.
+ */
+#define	ks8695_read(a)    *((volatile ulong *) (KS8695_IO_BASE + (a)))
+#define	ks8695_write(a,v) *((volatile ulong *) (KS8695_IO_BASE + (a))) = (v)
+
+int timer_inited;
+ulong timer_ticks;
+
+int interrupt_init (void)
+{
+	/* nothing happens here - we don't setup any IRQs */
+	return (0);
+}
+
+/*
+ * Initial timer set constants. Nothing complicated, just set for a 1ms
+ * tick.
+ */
+#define	TIMER_INTERVAL	(TICKS_PER_uSEC * mSEC_1)
+#define	TIMER_COUNT	(TIMER_INTERVAL / 2)
+#define	TIMER_PULSE	TIMER_COUNT
+
+void reset_timer_masked(void)
+{
+	/* Set the hadware timer for 1ms */
+	ks8695_write(KS8695_TIMER1, TIMER_COUNT);
+	ks8695_write(KS8695_TIMER1_PCOUNT, TIMER_PULSE);
+	ks8695_write(KS8695_TIMER_CTRL, 0x2);
+	timer_ticks = 0;
+	timer_inited++;
+}
+
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+ulong get_timer_masked(void)
+{
+	/* Check for timer wrap */
+	if (ks8695_read(KS8695_INT_STATUS) & KS8695_INTMASK_TIMERINT1) {
+		/* Clear interrupt condition */
+		ks8695_write(KS8695_INT_STATUS, KS8695_INTMASK_TIMERINT1);
+		timer_ticks++;
+	}
+	return timer_ticks;
+}
+
+ulong get_timer(ulong base)
+{
+       return (get_timer_masked() - base);
+}
+
+void set_timer(ulong t)
+{
+	timer_ticks = t;
+}
+
+void udelay(ulong usec)
+{
+	ulong start = get_timer_masked();
+	ulong end;
+
+	if (!timer_inited)
+		reset_timer();
+
+	/* Only 1ms resolution :-( */
+	end = usec / 1000;
+	while (get_timer(start) < end)
+		;
+}
+
+void reset_cpu (ulong ignored)
+{
+	ulong tc;
+
+	/* Set timer0 to watchdog, and let it timeout */
+	tc = ks8695_read(KS8695_TIMER_CTRL) & 0x2;
+	ks8695_write(KS8695_TIMER_CTRL, tc);
+	ks8695_write(KS8695_TIMER0, ((10 << 8) | 0xff));
+	ks8695_write(KS8695_TIMER_CTRL, (tc | 0x1));
+
+	/* Should only wait here till watchdog resets */
+	for (;;)
+		;
+}
diff --git a/cpu/arm920t/ks8695/lowlevel_init.S b/cpu/arm920t/ks8695/lowlevel_init.S
new file mode 100644
index 0000000..e9f1227
--- /dev/null
+++ b/cpu/arm920t/ks8695/lowlevel_init.S
@@ -0,0 +1,205 @@
+/*
+ *  lowlevel_init.S - basic hardware initialization for the KS8695 CPU
+ *
+ *  Copyright (c) 2004-2005, Greg Ungerer <greg.ungerer@opengear.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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
+ */
+
+#include <config.h>
+#include <version.h>
+#include <asm/arch/platform.h>
+
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+
+/*
+ *************************************************************************
+ *
+ * Handy dandy macros
+ *
+ *************************************************************************
+ */
+
+/* Delay a bit */
+.macro DELAY_FOR cycles, reg0
+	ldr     \reg0, =\cycles
+	subs    \reg0, \reg0, #1
+	subne   pc,  pc, #0xc
+.endm
+
+/*
+ *************************************************************************
+ *
+ * Some local storage.
+ *
+ *************************************************************************
+ */
+
+/* Should we boot with an interactive console or not */
+.globl serial_console
+
+/*
+ *************************************************************************
+ *
+ * Raw hardware initialization code. The important thing is to get
+ * SDRAM setup and running. We do some other basic things here too,
+ * like getting the PLL set for high speed, and init the LEDs.
+ *
+ *************************************************************************
+ */
+
+.globl lowlevel_init
+lowlevel_init:
+
+#if DEBUG
+	/*
+	 * enable UART for early debug trace
+	 */
+	ldr	r1, =(KS8695_IO_BASE+KS8695_UART_DIVISOR)
+	mov	r2, #0xd9
+	str	r2, [r1]		/* 115200 baud */
+	ldr	r1, =(KS8695_IO_BASE+KS8695_UART_LINE_CTRL)
+	mov	r2, #0x03
+	str	r2, [r1]		/* 8 data bits, no parity, 1 stop */
+	ldr	r1, =(KS8695_IO_BASE+KS8695_UART_TX_HOLDING)
+	mov	r2, #0x41
+	str	r2, [r1]		/* write 'A' */
+#endif
+#if DEBUG
+	ldr	r1, =(KS8695_IO_BASE+KS8695_UART_TX_HOLDING)
+	mov	r2, #0x42
+	str	r2, [r1]
+#endif
+
+	/*
+	 * remap the memory and flash regions. we want to end up with
+	 * ram from address 0, and flash at 32MB.
+	 */
+	ldr	r1, =(KS8695_IO_BASE+KS8695_MEM_CTRL0)
+	ldr	r2, =0xbfc00040
+	str	r2, [r1]		/* large flash map */
+	ldr	pc, =(highflash+0x02000000-0x00f00000)	/* jump to high flash address */
+highflash:
+	ldr	r2, =0x8fe00040
+	str	r2, [r1]		/* remap flash range */
+
+	/*
+	 * remap the second select region to the 4MB immediately after
+	 * the first region. This way if you have a larger flash (say 8Mb)
+	 * then you can have it all mapped nicely. Has no effect if you
+	 * only have a 4Mb or smaller flash.
+	 */
+	ldr	r1, =(KS8695_IO_BASE+KS8695_MEM_CTRL1)
+	ldr	r2, =0x9fe40040
+	str	r2, [r1]		/* remap flash2 region, contiguous */
+	ldr	r1, =(KS8695_IO_BASE+KS8695_MEM_GENERAL)
+	ldr	r2, =0x30000005
+	str	r2, [r1]		/* enable both flash selects */
+
+#ifdef CONFIG_CM41xx
+	/*
+	 * map the second flash chip, using the external IO lines.
+	 */
+	ldr	r1, =(KS8695_IO_BASE+KS8695_IO_CTRL0)
+	ldr	r2, =0xafe80b6d
+	str	r2, [r1]		/* remap io0 region, contiguous */
+	ldr	r1, =(KS8695_IO_BASE+KS8695_IO_CTRL1)
+	ldr	r2, =0xbfec0b6d
+	str	r2, [r1]		/* remap io1 region, contiguous */
+	ldr	r1, =(KS8695_IO_BASE+KS8695_MEM_GENERAL)
+	ldr	r2, =0x30050005
+	str	r2, [r1]		/* enable second flash */
+#endif
+
+	/*
+	 * before relocating, we have to setup RAM timing
+	 */
+	ldr	r1, =(KS8695_IO_BASE+KS8695_SDRAM_CTRL0)
+#if (PHYS_SDRAM_1_SIZE == 0x02000000)
+	ldr	r2, =0x7fc0000e		/* 32MB */
+#else
+	ldr	r2, =0x3fc0000e		/* 16MB */
+#endif
+	str	r2, [r1]		/* configure sdram bank0 setup */
+	ldr	r1, =(KS8695_IO_BASE+KS8695_SDRAM_CTRL1)
+	mov	r2, #0
+	str	r2, [r1]		/* configure sdram bank1 setup */
+
+	ldr	r1, =(KS8695_IO_BASE+KS8695_SDRAM_GENERAL)
+	ldr	r2, =0x0000000a
+	str	r2, [r1]		/* set RAS/CAS timing */
+
+	ldr	r1, =(KS8695_IO_BASE+KS8695_SDRAM_BUFFER)
+	ldr	r2, =0x00030000
+	str	r2, [r1]		/* send NOP command */
+	DELAY_FOR 0x100, r0
+	ldr	r2, =0x00010000
+	str	r2, [r1]		/* send PRECHARGE-ALL */
+	DELAY_FOR 0x100, r0
+
+	ldr	r1, =(KS8695_IO_BASE+KS8695_SDRAM_REFRESH)
+	ldr	r2, =0x00000020
+	str	r2, [r1]		/* set for fast refresh */
+	DELAY_FOR 0x100, r0
+	ldr	r2, =0x00000190
+	str	r2, [r1]		/* set normal refresh timing */
+
+	ldr	r1, =(KS8695_IO_BASE+KS8695_SDRAM_BUFFER)
+	ldr	r2, =0x00020033
+	str	r2, [r1]		/* send mode command */
+	DELAY_FOR 0x100, r0
+	ldr	r2, =0x01f00000
+	str	r2, [r1]		/* enable sdram fifos */
+
+	/*
+	 * set pll to top speed
+	 */
+	ldr	r1, =(KS8695_IO_BASE+KS8695_SYSTEN_BUS_CLOCK)
+	mov	r2, #0
+	str	r2, [r1]		/* set pll clock to 166MHz */
+
+	ldr	r1, =(KS8695_IO_BASE+KS8695_SWITCH_CTRL0)
+	ldr	r2, [r1]		/* Get switch ctrl0 register       */
+	and	r2, r2, #0x0fc00000	/* Mask out LED control bits       */
+	orr	r2, r2, #0x01800000	/* Set Link/activity/speed actions */
+	str	r2, [r1]
+
+#ifdef CONFIG_CM4008
+	ldr	r1, =(KS8695_IO_BASE+KS8695_GPIO_MODE)
+	ldr	r2, =0x0000fe30
+	str	r2, [r1]		/* enable LED's as outputs	    */
+	ldr	r1, =(KS8695_IO_BASE+KS8695_GPIO_DATA)
+	ldr	r2, =0x0000fe20
+	str	r2, [r1]		/* turn on power LED		    */
+#endif
+#if defined(CONFIG_CM4008) || defined(CONFIG_CM41xx)
+	ldr	r2, [r1]		/* get current GPIO input data	    */
+	tst	r2, #0x8		/* check if "erase" depressed	    */
+	beq	nobutton
+	mov	r2, #0			/* be quiet on boot, no console	    */
+	ldr	r1, =serial_console
+	str	r2, [r1]
+nobutton:
+#endif
+
+	add	lr, lr, #0x02000000	/* flash is now mapped high */
+	add	ip, ip, #0x02000000	/* this is a hack */
+	mov	pc, lr			/* all done, return */
+
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
diff --git a/cpu/arm920t/ks8695/serial.c b/cpu/arm920t/ks8695/serial.c
new file mode 100644
index 0000000..0dd91e7
--- /dev/null
+++ b/cpu/arm920t/ks8695/serial.c
@@ -0,0 +1,116 @@
+/*
+ * serial.c -- KS8695 serial driver
+ *
+ * (C) Copyright 2004, Greg Ungerer <greg.ungerer@opengear.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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
+ */
+
+#include <common.h>
+#include <asm/arch/platform.h>
+
+#ifndef CONFIG_SERIAL1
+#error "Bad: you didn't configure serial ..."
+#endif
+
+/*
+ *	Define the UART hardware register access structure.
+ */
+struct ks8695uart {
+	unsigned int	RX;		/* 0x00	- Receive data (r) */
+	unsigned int	TX;		/* 0x04	- Transmit data (w) */
+	unsigned int	FCR;		/* 0x08	- Fifo Control (r/w) */
+	unsigned int	LCR;		/* 0x0c	- Line Control (r/w) */
+	unsigned int	MCR;		/* 0x10	- Modem Control (r/w) */
+	unsigned int	LSR;		/* 0x14	- Line Status (r/w) */
+	unsigned int	MSR;		/* 0x18	- Modem Status (r/w) */
+	unsigned int	BD;		/* 0x1c	- Baud Rate (r/w) */
+	unsigned int	SR;		/* 0x20	- Status (r/w) */
+};
+
+#define	KS8695_UART_ADDR	((void *) (KS8695_IO_BASE + KS8695_UART_RX_BUFFER))
+#define	KS8695_UART_CLK		25000000
+
+
+/*
+ * Under some circumstances we want to be "quiet" and not issue any
+ * serial output - though we want u-boot to otherwise work and behave
+ * the same. By default be noisy.
+ */
+int serial_console = 1;
+
+
+void serial_setbrg(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
+
+	/* Set to global baud rate and 8 data bits, no parity, 1 stop bit*/
+	uartp->BD = KS8695_UART_CLK / gd->baudrate;
+	uartp->LCR = KS8695_UART_LINEC_WLEN8;
+}
+
+int serial_init(void)
+{
+	serial_console = 1;
+	serial_setbrg();
+	return 0;
+}
+
+void serial_raw_putc(const char c)
+{
+	volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
+	int i;
+
+	for (i = 0; (i < 0x100000); i++) {
+		if (uartp->LSR & KS8695_UART_LINES_TXFE)
+			break;
+	}
+
+	uartp->TX = c;
+}
+
+void serial_putc(const char c)
+{
+	if (serial_console) {
+		serial_raw_putc(c);
+		if (c == '\n')
+			serial_raw_putc('\r');
+	}
+}
+
+int serial_tstc(void)
+{
+	volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
+	if (serial_console)
+		return ((uartp->LSR & KS8695_UART_LINES_RXFE) ? 1 : 0);
+	return 0;
+}
+
+void serial_puts(const char *s)
+{
+	char c;
+	while ((c = *s++) != 0)
+		serial_putc(c);
+}
+
+int serial_getc(void)
+{
+	volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
+
+	while ((uartp->LSR & KS8695_UART_LINES_RXFE) == 0)
+		;
+	return (uartp->RX);
+}
diff --git a/drivers/Makefile b/drivers/Makefile
index d70988d..3461bb1 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -47,7 +47,8 @@
 	  status_led.o sym53c8xx.o \
 	  ti_pci1410a.o tigon3.o \
 	  usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \
-	  videomodes.o w83c553f.o
+	  videomodes.o w83c553f.o \
+	  ks8695eth.o
 
 all:	$(LIB)
 
diff --git a/drivers/ks8695eth.c b/drivers/ks8695eth.c
new file mode 100644
index 0000000..89c766b
--- /dev/null
+++ b/drivers/ks8695eth.c
@@ -0,0 +1,236 @@
+/*
+ * ks8695eth.c -- KS8695 ethernet driver
+ *
+ * (C) Copyright 2004-2005, Greg Ungerer <greg.ungerer@opengear.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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
+ */
+
+/****************************************************************************/
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <asm/arch/platform.h>
+
+/****************************************************************************/
+
+/*
+ * Hardware register access to the KS8695 LAN ethernet port
+ * (well, it is the 4 port switch really).
+ */
+#define	ks8695_read(a)    *((volatile unsigned long *) (KS8695_IO_BASE + (a)))
+#define	ks8695_write(a,v) *((volatile unsigned long *) (KS8695_IO_BASE + (a))) = (v)
+
+/****************************************************************************/
+
+/*
+ * Define the descriptor in-memory data structures.
+ */
+struct ks8695_txdesc {
+	uint32_t	owner;
+	uint32_t	ctrl;
+	uint32_t	addr;
+	uint32_t	next;
+};
+
+struct ks8695_rxdesc {
+	uint32_t	status;
+	uint32_t	ctrl;
+	uint32_t	addr;
+	uint32_t	next;
+};
+
+/****************************************************************************/
+
+/*
+ * Allocate local data structures to use for receiving and sending
+ * packets. Just to keep it all nice and simple.
+ */
+
+#define	TXDESCS		4
+#define	RXDESCS		4
+#define	BUFSIZE		2048
+
+volatile struct ks8695_txdesc ks8695_tx[TXDESCS] __attribute__((aligned(256)));
+volatile struct ks8695_rxdesc ks8695_rx[RXDESCS] __attribute__((aligned(256)));
+volatile uint8_t ks8695_bufs[BUFSIZE*(TXDESCS+RXDESCS)] __attribute__((aligned(2048)));;
+
+/****************************************************************************/
+
+/*
+ *	Ideally we want to use the MAC address stored in flash.
+ *	But we do some sanity checks in case they are not present
+ *	first.
+ */
+unsigned char eth_mac[] = {
+	0x00, 0x13, 0xc6, 0x00, 0x00, 0x00
+};
+
+void ks8695_getmac(void)
+{
+	unsigned char *fp;
+	int i;
+
+	/* Check if flash MAC is valid */
+	fp = (unsigned char *) 0x0201c000;
+	for (i = 0; (i < 6); i++) {
+		if ((fp[i] != 0) && (fp[i] != 0xff))
+			break;
+	}
+
+	/* If we found a valid looking MAC address then use it */
+	if (i < 6)
+		memcpy(&eth_mac[0], fp, 6);
+}
+
+/****************************************************************************/
+
+void eth_reset(bd_t *bd)
+{
+	int i;
+
+	debug ("%s(%d): eth_reset()\n", __FILE__, __LINE__);
+
+	/* Reset the ethernet engines first */
+	ks8695_write(KS8695_LAN_DMA_TX, 0x80000000);
+	ks8695_write(KS8695_LAN_DMA_RX, 0x80000000);
+
+	ks8695_getmac();
+
+	/* Set MAC address */
+	ks8695_write(KS8695_LAN_MAC_LOW, (eth_mac[5] | (eth_mac[4] << 8) |
+		(eth_mac[3] << 16) | (eth_mac[2] << 24)));
+	ks8695_write(KS8695_LAN_MAC_HIGH, (eth_mac[1] | (eth_mac[0] << 8)));
+
+	/* Turn the 4 port switch on */
+	i = ks8695_read(KS8695_SWITCH_CTRL0);
+	ks8695_write(KS8695_SWITCH_CTRL0, (i | 0x1));
+	/* ks8695_write(KS8695_WAN_CONTROL, 0x3f000066); */
+
+	/* Initialize descriptor rings */
+	for (i = 0; (i < TXDESCS); i++) {
+		ks8695_tx[i].owner = 0;
+		ks8695_tx[i].ctrl = 0;
+		ks8695_tx[i].addr = (uint32_t) &ks8695_bufs[i*BUFSIZE];
+		ks8695_tx[i].next = (uint32_t) &ks8695_tx[i+1];
+	}
+	ks8695_tx[TXDESCS-1].ctrl = 0x02000000;
+	ks8695_tx[TXDESCS-1].next = (uint32_t) &ks8695_tx[0];
+
+	for (i = 0; (i < RXDESCS); i++) {
+		ks8695_rx[i].status = 0x80000000;
+		ks8695_rx[i].ctrl = BUFSIZE - 4;
+		ks8695_rx[i].addr = (uint32_t) &ks8695_bufs[(i+TXDESCS)*BUFSIZE];
+		ks8695_rx[i].next = (uint32_t) &ks8695_rx[i+1];
+	}
+	ks8695_rx[RXDESCS-1].ctrl |= 0x00080000;
+	ks8695_rx[RXDESCS-1].next = (uint32_t) &ks8695_rx[0];
+
+	/* The KS8695 is pretty slow reseting the ethernets... */
+	udelay(2000000);
+
+	/* Enable the ethernet engine */
+	ks8695_write(KS8695_LAN_TX_LIST, (uint32_t) &ks8695_tx[0]);
+	ks8695_write(KS8695_LAN_RX_LIST, (uint32_t) &ks8695_rx[0]);
+	ks8695_write(KS8695_LAN_DMA_TX, 0x3);
+	ks8695_write(KS8695_LAN_DMA_RX, 0x71);
+	ks8695_write(KS8695_LAN_DMA_RX_START, 0x1);
+
+	printf("KS8695 ETHERNET: ");
+	for (i = 0; (i < 5); i++) {
+		bd->bi_enetaddr[i] = eth_mac[i];
+		printf("%02x:", eth_mac[i]);
+	}
+	bd->bi_enetaddr[i] = eth_mac[i];
+	printf("%02x\n", eth_mac[i]);
+}
+
+/****************************************************************************/
+
+int eth_init(bd_t *bd)
+{
+	debug ("%s(%d): eth_init()\n", __FILE__, __LINE__);
+
+	eth_reset(bd);
+	return 0;
+}
+
+/****************************************************************************/
+
+void eth_halt(void)
+{
+	debug ("%s(%d): eth_halt()\n", __FILE__, __LINE__);
+
+	/* Reset the ethernet engines */
+	ks8695_write(KS8695_LAN_DMA_TX, 0x80000000);
+	ks8695_write(KS8695_LAN_DMA_RX, 0x80000000);
+}
+
+/****************************************************************************/
+
+int eth_rx(void)
+{
+	volatile struct ks8695_rxdesc *dp;
+	int i, len = 0;
+
+	debug ("%s(%d): eth_rx()\n", __FILE__, __LINE__);
+
+	for (i = 0; (i < RXDESCS); i++) {
+		dp= &ks8695_rx[i];
+		if ((dp->status & 0x80000000) == 0) {
+			len = (dp->status & 0x7ff) - 4;
+			NetReceive((void *) dp->addr, len);
+			dp->status = 0x80000000;
+			ks8695_write(KS8695_LAN_DMA_RX_START, 0x1);
+			break;
+		}
+	}
+
+	return len;
+}
+
+/****************************************************************************/
+
+int eth_send(volatile void *packet, int len)
+{
+	volatile struct ks8695_txdesc *dp;
+	static int next = 0;
+
+	debug ("%s(%d): eth_send(packet=%x,len=%d)\n", __FILE__, __LINE__,
+		packet, len);
+
+	dp = &ks8695_tx[next];
+	memcpy((void *) dp->addr, packet, len);
+
+	if (len < 64) {
+		memset(dp->addr+len, 0, 64-len);
+		len = 64;
+	}
+
+	dp->ctrl = len | 0xe0000000;
+	dp->owner = 0x80000000;
+
+	ks8695_write(KS8695_LAN_DMA_TX, 0x3);
+	ks8695_write(KS8695_LAN_DMA_TX_START, 0x1);
+
+	if (++next >= TXDESCS)
+		next = 0;
+
+	return len;
+}
+
+/****************************************************************************/
diff --git a/include/asm-arm/arch-ks8695/platform.h b/include/asm-arm/arch-ks8695/platform.h
new file mode 100644
index 0000000..de20015
--- /dev/null
+++ b/include/asm-arm/arch-ks8695/platform.h
@@ -0,0 +1,306 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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
+ */
+#ifndef __address_h
+#define __address_h			1
+
+#define KS8695_SDRAM_START	    0x00000000
+#define KS8695_SDRAM_SIZE	    0x01000000
+#define KS8695_MEM_SIZE		    KS8695_SDRAM_SIZE
+#define KS8695_MEM_START	    KS8695_SDRAM_START
+
+#define KS8695_PCMCIA_IO_BASE	    0x03800000
+#define KS8695_PCMCIA_IO_SIZE	    0x00040000
+
+#define KS8695_IO_BASE		    0x03FF0000
+#define KS8695_IO_SIZE		    0x00010000
+
+#define KS8695_SYSTEN_CONFIG	    0x00
+#define KS8695_SYSTEN_BUS_CLOCK	    0x04
+
+#define KS8695_FLASH_START	    0x02800000
+#define KS8695_FLASH_SIZE	    0x00400000
+
+/*i/o control registers offset difinitions*/
+#define KS8695_IO_CTRL0		    0x4000
+#define KS8695_IO_CTRL1		    0x4004
+#define KS8695_IO_CTRL2		    0x4008
+#define KS8695_IO_CTRL3		    0x400C
+
+/*memory control registers offset difinitions*/
+#define KS8695_MEM_CTRL0	    0x4010
+#define KS8695_MEM_CTRL1	    0x4014
+#define KS8695_MEM_CTRL2	    0x4018
+#define KS8695_MEM_CTRL3	    0x401C
+#define KS8695_MEM_GENERAL	    0x4020
+#define KS8695_SDRAM_CTRL0	    0x4030
+#define KS8695_SDRAM_CTRL1	    0x4034
+#define KS8695_SDRAM_GENERAL	    0x4038
+#define KS8695_SDRAM_BUFFER	    0x403C
+#define KS8695_SDRAM_REFRESH	    0x4040
+
+/*WAN control registers offset difinitions*/
+#define KS8695_WAN_DMA_TX	    0x6000
+#define KS8695_WAN_DMA_RX	    0x6004
+#define KS8695_WAN_DMA_TX_START	    0x6008
+#define KS8695_WAN_DMA_RX_START	    0x600C
+#define KS8695_WAN_TX_LIST	    0x6010
+#define KS8695_WAN_RX_LIST	    0x6014
+#define KS8695_WAN_MAC_LOW	    0x6018
+#define KS8695_WAN_MAC_HIGH	    0x601C
+#define KS8695_WAN_MAC_ELOW	    0x6080
+#define KS8695_WAN_MAC_EHIGH	    0x6084
+
+/*LAN control registers offset difinitions*/
+#define KS8695_LAN_DMA_TX	    0x8000
+#define KS8695_LAN_DMA_RX	    0x8004
+#define KS8695_LAN_DMA_TX_START	    0x8008
+#define KS8695_LAN_DMA_RX_START	    0x800C
+#define KS8695_LAN_TX_LIST	    0x8010
+#define KS8695_LAN_RX_LIST	    0x8014
+#define KS8695_LAN_MAC_LOW	    0x8018
+#define KS8695_LAN_MAC_HIGH	    0x801C
+#define KS8695_LAN_MAC_ELOW	    0X8080
+#define KS8695_LAN_MAC_EHIGH	    0X8084
+
+/*HPNA control registers offset difinitions*/
+#define KS8695_HPNA_DMA_TX	    0xA000
+#define KS8695_HPNA_DMA_RX	    0xA004
+#define KS8695_HPNA_DMA_TX_START    0xA008
+#define KS8695_HPNA_DMA_RX_START    0xA00C
+#define KS8695_HPNA_TX_LIST	    0xA010
+#define KS8695_HPNA_RX_LIST	    0xA014
+#define KS8695_HPNA_MAC_LOW	    0xA018
+#define KS8695_HPNA_MAC_HIGH	    0xA01C
+#define KS8695_HPNA_MAC_ELOW	    0xA080
+#define KS8695_HPNA_MAC_EHIGH	    0xA084
+
+/*UART control registers offset difinitions*/
+#define KS8695_UART_RX_BUFFER	    0xE000
+#define KS8695_UART_TX_HOLDING	    0xE004
+
+#define KS8695_UART_FIFO_CTRL	    0xE008
+#define KS8695_UART_FIFO_TRIG01	    0x00
+#define KS8695_UART_FIFO_TRIG04	    0x80
+#define KS8695_UART_FIFO_TXRST	    0x03
+#define KS8695_UART_FIFO_RXRST	    0x02
+#define KS8695_UART_FIFO_FEN	    0x01
+
+#define KS8695_UART_LINE_CTRL	    0xE00C
+#define KS8695_UART_LINEC_BRK	    0x40
+#define KS8695_UART_LINEC_EPS	    0x10
+#define KS8695_UART_LINEC_PEN	    0x08
+#define KS8695_UART_LINEC_STP2	    0x04
+#define KS8695_UART_LINEC_WLEN8	    0x03
+#define KS8695_UART_LINEC_WLEN7	    0x02
+#define KS8695_UART_LINEC_WLEN6	    0x01
+#define KS8695_UART_LINEC_WLEN5	    0x00
+
+#define KS8695_UART_MODEM_CTRL	    0xE010
+#define KS8695_UART_MODEMC_RTS	    0x02
+#define KS8695_UART_MODEMC_DTR	    0x01
+
+#define KS8695_UART_LINE_STATUS	    0xE014
+#define KS8695_UART_LINES_TXFE	    0x20
+#define KS8695_UART_LINES_BE	    0x10
+#define KS8695_UART_LINES_FE	    0x08
+#define KS8695_UART_LINES_PE	    0x04
+#define KS8695_UART_LINES_OE	    0x02
+#define KS8695_UART_LINES_RXFE	    0x01
+#define KS8695_UART_LINES_ANY	    (KS8695_UART_LINES_OE|KS8695_UART_LINES_BE|KS8695_UART_LINES_PE|KS8695_UART_LINES_FE)
+
+#define KS8695_UART_MODEM_STATUS    0xE018
+#define KS8695_UART_MODEM_DCD	    0x80
+#define KS8695_UART_MODEM_DSR	    0x20
+#define KS8695_UART_MODEM_CTS	    0x10
+#define KS8695_UART_MODEM_DDCD	    0x08
+#define KS8695_UART_MODEM_DDSR	    0x02
+#define KS8695_UART_MODEM_DCTS	    0x01
+#define UART8695_MODEM_ANY	    0xFF
+
+#define KS8695_UART_DIVISOR	    0xE01C
+#define KS8695_UART_STATUS	    0xE020
+
+/*Interrupt controlller registers offset difinitions*/
+#define KS8695_INT_CONTL	    0xE200
+#define KS8695_INT_ENABLE	    0xE204
+#define KS8695_INT_ENABLE_MODEM	    0x0800
+#define KS8695_INT_ENABLE_ERR	    0x0400
+#define KS8695_INT_ENABLE_RX	    0x0200
+#define KS8695_INT_ENABLE_TX	    0x0100
+
+#define KS8695_INT_STATUS	    0xE208
+#define KS8695_INT_WAN_PRIORITY	    0xE20C
+#define KS8695_INT_HPNA_PRIORITY    0xE210
+#define KS8695_INT_LAN_PRIORITY	    0xE214
+#define KS8695_INT_TIMER_PRIORITY   0xE218
+#define KS8695_INT_UART_PRIORITY    0xE21C
+#define KS8695_INT_EXT_PRIORITY	    0xE220
+#define KS8695_INT_CHAN_PRIORITY    0xE224
+#define KS8695_INT_BUSERROR_PRO	    0xE228
+#define KS8695_INT_MASK_STATUS	    0xE22C
+#define KS8695_FIQ_PEND_PRIORITY    0xE230
+#define KS8695_IRQ_PEND_PRIORITY    0xE234
+
+/*timer registers offset difinitions*/
+#define KS8695_TIMER_CTRL	    0xE400
+#define KS8695_TIMER1		    0xE404
+#define KS8695_TIMER0		    0xE408
+#define KS8695_TIMER1_PCOUNT	    0xE40C
+#define KS8695_TIMER0_PCOUNT	    0xE410
+
+/*GPIO registers offset difinitions*/
+#define KS8695_GPIO_MODE	    0xE600
+#define KS8695_GPIO_CTRL	    0xE604
+#define KS8695_GPIO_DATA	    0xE608
+
+/*SWITCH registers offset difinitions*/
+#define KS8695_SWITCH_CTRL0	    0xE800
+#define KS8695_SWITCH_CTRL1	    0xE804
+#define KS8695_SWITCH_PORT1	    0xE808
+#define KS8695_SWITCH_PORT2	    0xE80C
+#define KS8695_SWITCH_PORT3	    0xE810
+#define KS8695_SWITCH_PORT4	    0xE814
+#define KS8695_SWITCH_PORT5	    0xE818
+#define KS8695_SWITCH_AUTO0	    0xE81C
+#define KS8695_SWITCH_AUTO1	    0xE820
+#define KS8695_SWITCH_LUE_CTRL	    0xE824
+#define KS8695_SWITCH_LUE_HIGH	    0xE828
+#define KS8695_SWITCH_LUE_LOW	    0xE82C
+#define KS8695_SWITCH_ADVANCED	    0xE830
+
+#define KS8695_SWITCH_LPPM12	    0xE874
+#define KS8695_SWITCH_LPPM34	    0xE878
+
+/*host communication registers difinitions*/
+#define KS8695_DSCP_HIGH	    0xE834
+#define KS8695_DSCP_LOW		    0xE838
+#define KS8695_SWITCH_MAC_HIGH	    0xE83C
+#define KS8695_SWITCH_MAC_LOW	    0xE840
+
+/*miscellaneours registers difinitions*/
+#define KS8695_MANAGE_COUNTER	    0xE844
+#define KS8695_MANAGE_DATA	    0xE848
+#define KS8695_LAN12_POWERMAGR	    0xE84C
+#define KS8695_LAN34_POWERMAGR	    0xE850
+
+#define KS8695_DEVICE_ID	    0xEA00
+#define KS8695_REVISION_ID	    0xEA04
+
+#define KS8695_MISC_CONTROL	    0xEA08
+#define KS8695_WAN_CONTROL	    0xEA0C
+#define KS8695_WAN_POWERMAGR	    0xEA10
+#define KS8695_WAN_PHY_CONTROL	    0xEA14
+#define KS8695_WAN_PHY_STATUS	    0xEA18
+
+/* bus clock definitions*/
+#define KS8695_BUS_CLOCK_125MHZ	    0x0
+#define KS8695_BUS_CLOCK_100MHZ	    0x1
+#define KS8695_BUS_CLOCK_62MHZ	    0x2
+#define KS8695_BUS_CLOCK_50MHZ	    0x3
+#define KS8695_BUS_CLOCK_41MHZ	    0x4
+#define KS8695_BUS_CLOCK_33MHZ	    0x5
+#define KS8695_BUS_CLOCK_31MHZ	    0x6
+#define KS8695_BUS_CLOCK_25MHZ	    0x7
+
+/* -------------------------------------------------------------------------------
+ *  definations for IRQ
+ * -------------------------------------------------------------------------------*/
+
+#define KS8695_INT_EXT_INT0		       2
+#define KS8695_INT_EXT_INT1		       3
+#define KS8695_INT_EXT_INT2		       4
+#define KS8695_INT_EXT_INT3		       5
+#define KS8695_INT_TIMERINT0		       6
+#define KS8695_INT_TIMERINT1		       7
+#define KS8695_INT_UART_TX		       8
+#define KS8695_INT_UART_RX		       9
+#define KS8695_INT_UART_LINE_ERR	       10
+#define KS8695_INT_UART_MODEMS		       11
+#define KS8695_INT_LAN_STOP_RX		       12
+#define KS8695_INT_LAN_STOP_TX		       13
+#define KS8695_INT_LAN_BUF_RX_STATUS	       14
+#define KS8695_INT_LAN_BUF_TX_STATUS	       15
+#define KS8695_INT_LAN_RX_STATUS	       16
+#define KS8695_INT_LAN_TX_STATUS	       17
+#define KS8695_INT_HPAN_STOP_RX		       18
+#define KS8695_INT_HPNA_STOP_TX		       19
+#define KS8695_INT_HPNA_BUF_RX_STATUS	       20
+#define KS8695_INT_HPNA_BUF_TX_STATUS	       21
+#define KS8695_INT_HPNA_RX_STATUS	       22
+#define KS8695_INT_HPNA_TX_STATUS	       23
+#define KS8695_INT_BUS_ERROR		       24
+#define KS8695_INT_WAN_STOP_RX		       25
+#define KS8695_INT_WAN_STOP_TX		       26
+#define KS8695_INT_WAN_BUF_RX_STATUS	       27
+#define KS8695_INT_WAN_BUF_TX_STATUS	       28
+#define KS8695_INT_WAN_RX_STATUS	       29
+#define KS8695_INT_WAN_TX_STATUS	       30
+
+#define KS8695_INT_UART			       KS8695_INT_UART_TX
+
+/* -------------------------------------------------------------------------------
+ *  Interrupt bit positions
+ *
+ * -------------------------------------------------------------------------------
+ */
+
+#define KS8695_INTMASK_EXT_INT0		       ( 1 << KS8695_INT_EXT_INT0 )
+#define KS8695_INTMASK_EXT_INT1		       ( 1 << KS8695_INT_EXT_INT1 )
+#define KS8695_INTMASK_EXT_INT2		       ( 1 << KS8695_INT_EXT_INT2 )
+#define KS8695_INTMASK_EXT_INT3		       ( 1 << KS8695_INT_EXT_INT3 )
+#define KS8695_INTMASK_TIMERINT0	       ( 1 << KS8695_INT_TIMERINT0 )
+#define KS8695_INTMASK_TIMERINT1	       ( 1 << KS8695_INT_TIMERINT1 )
+#define KS8695_INTMASK_UART_TX		       ( 1 << KS8695_INT_UART_TX  )
+#define KS8695_INTMASK_UART_RX		       ( 1 << KS8695_INT_UART_RX  )
+#define KS8695_INTMASK_UART_LINE_ERR	       ( 1 << KS8695_INT_UART_LINE_ERR )
+#define KS8695_INTMASK_UART_MODEMS	       ( 1 << KS8695_INT_UART_MODEMS )
+#define KS8695_INTMASK_LAN_STOP_RX	       ( 1 << KS8695_INT_LAN_STOP_RX )
+#define KS8695_INTMASK_LAN_STOP_TX	       ( 1 << KS8695_INT_LAN_STOP_TX )
+#define KS8695_INTMASK_LAN_BUF_RX_STATUS       ( 1 << KS8695_INT_LAN_BUF_RX_STATUS )
+#define KS8695_INTMASK_LAN_BUF_TX_STATUS       ( 1 << KS8695_INT_LAN_BUF_TX_STATUS )
+#define KS8695_INTMASK_LAN_RX_STATUS	       ( 1 << KS8695_INT_LAN_RX_STATUS )
+#define KS8695_INTMASK_LAN_TX_STATUS	       ( 1 << KS8695_INT_LAN_RX_STATUS )
+#define KS8695_INTMASK_HPAN_STOP_RX	       ( 1 << KS8695_INT_HPAN_STOP_RX )
+#define KS8695_INTMASK_HPNA_STOP_TX	       ( 1 << KS8695_INT_HPNA_STOP_TX )
+#define KS8695_INTMASK_HPNA_BUF_RX_STATUS      ( 1 << KS8695_INT_HPNA_BUF_RX_STATUS )
+#define KS8695_INTMAKS_HPNA_BUF_TX_STATUS      ( 1 << KS8695_INT_HPNA_BUF_TX_STATUS
+#define KS8695_INTMASK_HPNA_RX_STATUS	       ( 1 << KS8695_INT_HPNA_RX_STATUS )
+#define KS8695_INTMASK_HPNA_TX_STATUS	       ( 1 << KS8695_INT_HPNA_TX_STATUS )
+#define KS8695_INTMASK_BUS_ERROR	       ( 1 << KS8695_INT_BUS_ERROR )
+#define KS8695_INTMASK_WAN_STOP_RX	       ( 1 << KS8695_INT_WAN_STOP_RX )
+#define KS8695_INTMASK_WAN_STOP_TX	       ( 1 << KS8695_INT_WAN_STOP_TX )
+#define KS8695_INTMASK_WAN_BUF_RX_STATUS       ( 1 << KS8695_INT_WAN_BUF_RX_STATUS )
+#define KS8695_INTMASK_WAN_BUF_TX_STATUS       ( 1 << KS8695_INT_WAN_BUF_TX_STATUS )
+#define KS8695_INTMASK_WAN_RX_STATUS	       ( 1 << KS8695_INT_WAN_RX_STATUS )
+#define KS8695_INTMASK_WAN_TX_STATUS	       ( 1 << KS8695_INT_WAN_TX_STATUS )
+
+#define KS8695_SC_VALID_INT		       0xFFFFFFFF
+#define MAXIRQNUM			       31
+
+/*
+ *  Timer definitions
+ *
+ *  Use timer 1 & 2
+ *  (both run at 25MHz).
+ *
+ */
+#define TICKS_PER_uSEC			25
+#define mSEC_1				1000
+#define mSEC_10				(mSEC_1 * 10)
+
+#endif
+
+/*	END */
diff --git a/lib_arm/armlinux.c b/lib_arm/armlinux.c
index 5596569..d158605 100644
--- a/lib_arm/armlinux.c
+++ b/lib_arm/armlinux.c
@@ -377,15 +377,30 @@
 }
 #endif /* CONFIG_VFD || CONFIG_LCD */
 
+#ifdef CONFIG_SERIAL_TAG
+void setup_serial_tag (struct tag **tmp)
+{
+	struct tag *params = *tmp;
+	struct tag_serialnr serialnr;
+	void get_board_serial(struct tag_serialnr *serialnr);
+
+	get_board_serial(&serialnr);
+	params->hdr.tag = ATAG_SERIAL;
+	params->hdr.size = tag_size (tag_serialnr);
+	params->u.serialnr.low = serialnr.low;
+	params->u.serialnr.high= serialnr.high;
+	params = tag_next (params);
+	*tmp = params;
+}
+#endif
+
 #ifdef CONFIG_REVISION_TAG
 void setup_revision_tag(struct tag **in_params)
 {
 	u32 rev = 0;
-#ifdef CONFIG_OMAP2420H4
 	u32 get_board_rev(void);
 
 	rev = get_board_rev();
-#endif
 	params->hdr.tag = ATAG_REVISION;
 	params->hdr.size = tag_size (tag_revision);
 	params->u.revision.rev = rev;