Merge commit 'u-boot/master' into for-1.3.1

Conflicts:

	drivers/rtc/Makefile
diff --git a/drivers/Makefile b/drivers/Makefile
deleted file mode 100755
index 00978d8..0000000
--- a/drivers/Makefile
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# (C) Copyright 2000-2007
-# 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
-
-# CFLAGS += -DET_DEBUG -DDEBUG
-
-LIB	= $(obj)libdrivers.a
-
-COBJS	= 3c589.o 5701rls.o ali512x.o at45.o ata_piix.o \
-	  ati_radeon_fb.o atmel_usart.o \
-	  bcm570x.o bcm570x_autoneg.o cfb_console.o cfi_flash.o \
-	  cs8900.o ct69000.o dataflash.o dc2114x.o dm9000x.o \
-	  ds1722.o e1000.o eepro100.o enc28j60.o \
-	  fsl_i2c.o fsl_pci_init.o \
-	  i8042.o inca-ip_sw.o isp116x-hcd.o \
-	  keyboard.o ks8695eth.o \
-	  lan91c96.o macb.o mpc8xx_pcmcia.o mw_eeprom.o \
-	  natsemi.o ne2000.o netarm_eth.o netconsole.o \
-	  ns16550.o ns8382x.o ns87308.o ns7520_eth.o omap1510_i2c.o \
-	  omap24xx_i2c.o pc_keyb.o \
-	  pci.o pci_auto.o pci_indirect.o \
-	  pcnet.o plb2800_eth.o ps2ser.o ps2mult.o pxa_pcmcia.o \
-	  rpx_pcmcia.o rtl8019.o rtl8139.o rtl8169.o \
-	  s3c4510b_eth.o s3c4510b_uart.o \
-	  sed13806.o sed156x.o \
-	  serial.o serial_max3100.o \
-	  serial_pl010.o serial_pl011.o serial_xuartlite.o \
-	  sil680.o sl811_usb.o sm501.o smc91111.o smiLynxEM.o \
-	  status_led.o sym53c8xx.o systemace.o ahci.o \
-	  ti_pci1410a.o tigon3.o tqm8xx_pcmcia.o tsec.o \
-	  tsi108_eth.o tsi108_i2c.o tsi108_pci.o \
-	  usb_ohci.o \
-	  usbdcore.o usbdcore_ep0.o usbdcore_mpc8xx.o usbdcore_omap1510.o \
-	  usbtty.o \
-	  videomodes.o w83c553f.o
-
-SRCS	:= $(COBJS:.o=.c)
-OBJS	:= $(addprefix $(obj),$(COBJS))
-
-all:	$(LIB)
-
-$(LIB): $(obj).depend $(OBJS)
-	$(AR) $(ARFLAGS) $@ $(OBJS)
-
-#########################################################################
-
-# defines $(obj).depend target
-include $(SRCTREE)/rules.mk
-
-sinclude $(obj).depend
-
-#########################################################################
diff --git a/drivers/bios_emulator/besys.c b/drivers/bios_emulator/besys.c
index 8f1d8b2..cb1b0c1 100644
--- a/drivers/bios_emulator/besys.c
+++ b/drivers/bios_emulator/besys.c
@@ -96,7 +96,7 @@
 	else if (addr >= 0xFFFF5 && addr < 0xFFFFE) {
 		/* Return a faked BIOS date string for non-x86 machines */
 		DB(printf("BE_memaddr - Returning BIOS date\n");)
-		return BE_biosDate + addr - 0xFFFF5;
+		return (u8 *)(BE_biosDate + addr - 0xFFFF5);
 	} else if (addr == 0xFFFFE) {
 		/* Return system model identifier for non-x86 machines */
 		DB(printf("BE_memaddr - Returning model\n");)
diff --git a/drivers/bios_emulator/biosemu.c b/drivers/bios_emulator/biosemu.c
index ccfc872..75ceb45 100644
--- a/drivers/bios_emulator/biosemu.c
+++ b/drivers/bios_emulator/biosemu.c
@@ -96,7 +96,7 @@
 		return 0;
 	}
 
-	M.mem_base = (unsigned long)malloc(memSize);
+	M.mem_base = malloc(memSize);
 
 	if (M.mem_base == NULL){
 		printf("Biosemu:Out of memory!");
@@ -106,7 +106,7 @@
 
 	_BE_env.emulateVGA = 0;
 	_BE_env.busmem_base = (unsigned long)malloc(128 * 1024);
-	if (_BE_env.busmem_base == NULL){
+	if ((void *)_BE_env.busmem_base == NULL){
 		printf("Biosemu:Out of memory!");
 		return 0;
 	}
@@ -230,7 +230,7 @@
 void X86API BE_exit(void)
 {
 	free(M.mem_base);
-	free(_BE_env.busmem_base);
+	free((void *)_BE_env.busmem_base);
 }
 
 /****************************************************************************
diff --git a/drivers/nand/Makefile b/drivers/block/Makefile
similarity index 87%
copy from drivers/nand/Makefile
copy to drivers/block/Makefile
index fb0185b..e069969 100644
--- a/drivers/nand/Makefile
+++ b/drivers/block/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2006
+# (C) Copyright 2000-2007
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,10 +23,15 @@
 
 include $(TOPDIR)/config.mk
 
-LIB 	:= $(obj)libnand.a
+LIB 	:= $(obj)libblock.a
 
-COBJS 	:= nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
+COBJS-y += ahci.o
+COBJS-y += ata_piix.o
+COBJS-y += sil680.o
+COBJS-y += sym53c8xx.o
+COBJS-y += systemace.o
 
+COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
 OBJS 	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/ahci.c b/drivers/block/ahci.c
similarity index 100%
rename from drivers/ahci.c
rename to drivers/block/ahci.c
diff --git a/drivers/ata_piix.c b/drivers/block/ata_piix.c
similarity index 100%
rename from drivers/ata_piix.c
rename to drivers/block/ata_piix.c
diff --git a/drivers/sil680.c b/drivers/block/sil680.c
similarity index 100%
rename from drivers/sil680.c
rename to drivers/block/sil680.c
diff --git a/drivers/sym53c8xx.c b/drivers/block/sym53c8xx.c
similarity index 100%
rename from drivers/sym53c8xx.c
rename to drivers/block/sym53c8xx.c
diff --git a/drivers/systemace.c b/drivers/block/systemace.c
similarity index 100%
rename from drivers/systemace.c
rename to drivers/block/systemace.c
diff --git a/drivers/nand/Makefile b/drivers/hwmon/Makefile
similarity index 74%
copy from drivers/nand/Makefile
copy to drivers/hwmon/Makefile
index fb0185b..cebb2ba 100644
--- a/drivers/nand/Makefile
+++ b/drivers/hwmon/Makefile
@@ -2,6 +2,9 @@
 # (C) Copyright 2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
+# (C) Copyright 2001
+# Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
+#
 # See file CREDITS for list of people who contributed to this
 # project.
 #
@@ -12,7 +15,7 @@
 #
 # 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
+# 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
@@ -23,12 +26,20 @@
 
 include $(TOPDIR)/config.mk
 
-LIB 	:= $(obj)libnand.a
+#CFLAGS += -DDEBUG
 
-COBJS 	:= nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
+LIB	= $(obj)libhwmon.a
+
+COBJS-y += adm1021.o
+COBJS-y += ds1621.o
+COBJS-y += ds1722.o
+COBJS-y += ds1775.o
+COBJS-y += lm75.o
+COBJS-y += lm81.o
 
-SRCS 	:= $(COBJS:.o=.c)
-OBJS 	:= $(addprefix $(obj),$(COBJS))
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
 
 all:	$(LIB)
 
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
new file mode 100644
index 0000000..9f65cfb27
--- /dev/null
+++ b/drivers/hwmon/adm1021.c
@@ -0,0 +1,174 @@
+/*
+ * (C) Copyright 2003
+ * Murray Jensen, CSIRO-MIT, Murray.Jensen@csiro.au
+ *
+ * based on dtt/lm75.c which is ...
+ *
+ * (C) Copyright 2001
+ * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
+ *
+ * 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
+ */
+
+/*
+ * Analog Devices's ADM1021
+ * "Low Cost Microprocessor System Temperature Monitor"
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_ADM1021
+
+#include <i2c.h>
+#include <dtt.h>
+
+typedef
+	struct {
+		uint i2c_addr:7;	/* 7bit i2c chip address */
+		uint conv_rate:3;	/* conversion rate */
+		uint enable_alert:1;	/* enable alert output pin */
+		uint enable_local:1;	/* enable internal temp sensor */
+		uint max_local:8;	/* internal temp maximum */
+		uint min_local:8;	/* internal temp minimum */
+		uint enable_remote:1;	/* enable remote temp sensor */
+		uint max_remote:8;	/* remote temp maximum */
+		uint min_remote:8;	/* remote temp minimum */
+	}
+dtt_cfg_t;
+
+dtt_cfg_t dttcfg[] = CFG_DTT_ADM1021;
+
+int
+dtt_read (int sensor, int reg)
+{
+	dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
+	uchar data;
+
+	if (i2c_read(dcp->i2c_addr, reg, 1, &data, 1) != 0)
+		return -1;
+
+	return (int)data;
+} /* dtt_read() */
+
+int
+dtt_write (int sensor, int reg, int val)
+{
+	dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
+	uchar data;
+
+	data = (uchar)(val & 0xff);
+
+	if (i2c_write(dcp->i2c_addr, reg, 1, &data, 1) != 0)
+		return 1;
+
+	return 0;
+} /* dtt_write() */
+
+static int
+_dtt_init (int sensor)
+{
+	dtt_cfg_t *dcp = &dttcfg[sensor >> 1];
+	int reg, val;
+
+	if (((sensor & 1) == 0 ? dcp->enable_local : dcp->enable_remote) == 0)
+		return 1;	/* sensor is disabled (or rather ignored) */
+
+	/*
+	 * Setup High Limit register
+	 */
+	if ((sensor & 1) == 0) {
+		reg = DTT_WRITE_LOC_HIGHLIM;
+		val = dcp->max_local;
+	}
+	else {
+		reg = DTT_WRITE_REM_HIGHLIM;
+		val = dcp->max_remote;
+	}
+	if (dtt_write (sensor, reg, val) != 0)
+		return 1;
+
+	/*
+	 * Setup Low Limit register
+	 */
+	if ((sensor & 1) == 0) {
+		reg = DTT_WRITE_LOC_LOWLIM;
+		val = dcp->min_local;
+	}
+	else {
+		reg = DTT_WRITE_REM_LOWLIM;
+		val = dcp->min_remote;
+	}
+	if (dtt_write (sensor, reg, val) != 0)
+		return 1;
+
+	/* shouldn't hurt if the rest gets done twice */
+
+	/*
+	 * Setup Conversion Rate register
+	 */
+	if (dtt_write (sensor, DTT_WRITE_CONVRATE, dcp->conv_rate) != 0)
+		return 1;
+
+	/*
+	 * Setup configuraton register
+	 */
+	val = 0;				/* running */
+	if (dcp->enable_alert == 0)
+		val |= DTT_CONFIG_ALERT_MASKED;	/* mask ALERT pin */
+	if (dtt_write (sensor, DTT_WRITE_CONFIG, val) != 0)
+		return 1;
+
+	return 0;
+} /* _dtt_init() */
+
+int
+dtt_init (void)
+{
+	int i;
+	unsigned char sensors[] = CONFIG_DTT_SENSORS;
+	const char *const header = "DTT:   ";
+
+	/* switch to correct I2C bus */
+	I2C_SET_BUS(CFG_DTT_BUS_NUM);
+
+	for (i = 0; i < sizeof(sensors); i++) {
+		if (_dtt_init(sensors[i]) != 0)
+			printf ("%s%d FAILED INIT\n", header, i+1);
+		else
+			printf ("%s%d is %i C\n", header, i+1,
+				dtt_get_temp(sensors[i]));
+	}
+
+	return (0);
+} /* dtt_init() */
+
+int
+dtt_get_temp (int sensor)
+{
+	signed char val;
+
+	if ((sensor & 1) == 0)
+		val = dtt_read(sensor, DTT_READ_LOC_VALUE);
+	else
+		val = dtt_read(sensor, DTT_READ_REM_VALUE);
+
+	return (int) val;
+} /* dtt_get_temp() */
+
+#endif /* CONFIG_DTT_ADM1021 */
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
new file mode 100644
index 0000000..4948181
--- /dev/null
+++ b/drivers/hwmon/ds1621.c
@@ -0,0 +1,190 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.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
+ */
+
+/*
+ * Dallas Semiconductor's DS1621 Digital Thermometer and Thermostat.
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_DS1621
+#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
+	(CFG_EEPROM_PAGE_WRITE_BITS < 1)
+# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than 1 to use CONFIG_DTT_DS1621"
+#endif
+#include <i2c.h>
+#include <dtt.h>
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x48			/* Dallas Semi's DS1621 */
+
+int dtt_read(int sensor, int reg)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Calculate sensor address and command.
+     *
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1621*/
+
+    /*
+     * Prepare to handle 2 byte result.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+	(reg == DTT_TEMP_HIGH) || (reg == DTT_TEMP_LOW))
+	dlen = 2;
+    else
+	dlen = 1;
+
+    /*
+     * Now try to read the register.
+     */
+    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+	return 1;
+
+    /*
+     * Handle 2 byte result.
+     */
+    if (dlen == 2)
+	return ((int)((short)data[1] + (((short)data[0]) << 8)));
+
+    return (int)data[0];
+} /* dtt_read() */
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Calculate sensor address and register.
+     *
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07);
+
+    /*
+     * Handle various data sizes.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+	(reg == DTT_TEMP_HIGH) || (reg == DTT_TEMP_LOW)) {
+	dlen = 2;
+	data[0] = (char)((val >> 8) & 0xff);	/* MSB first */
+	data[1] = (char)(val & 0xff);
+    }
+    else if ((reg == DTT_WRITE_START_CONV) || (reg == DTT_WRITE_STOP_CONV)) {
+	dlen = 0;
+	data[0] = (char)0;
+	data[1] = (char)0;
+    }
+    else {
+	dlen = 1;
+	data[0] = (char)(val & 0xff);
+    }
+
+    /*
+     * Write value to device.
+     */
+    if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+	return 1;
+
+    return 0;
+} /* dtt_write() */
+
+
+static int _dtt_init(int sensor)
+{
+    int val;
+
+    /*
+     * Setup High Temp.
+     */
+    val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80;
+    if (dtt_write(sensor, DTT_TEMP_HIGH, val) != 0)
+	return 1;
+    udelay(50000);				/* Max 50ms */
+
+    /*
+     * Setup Low Temp - hysteresis.
+     */
+    val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+    if (dtt_write(sensor, DTT_TEMP_LOW, val) != 0)
+	return 1;
+    udelay(50000);				/* Max 50ms */
+
+    /*
+     * Setup configuraton register
+     *
+     * Clear THF & TLF, Reserved = 1, Polarity = Active Low, One Shot = YES
+     *
+     * We run in polled mode, since there isn't any way to know if this
+     * lousy device is ready to provide temperature readings on power up.
+     */
+    val = 0x9;
+    if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+	return 1;
+    udelay(50000);				/* Max 50ms */
+
+    return 0;
+} /* _dtt_init() */
+
+
+int dtt_init (void)
+{
+    int i;
+    unsigned char sensors[] = CONFIG_DTT_SENSORS;
+
+    for (i = 0; i < sizeof(sensors); i++) {
+	if (_dtt_init(sensors[i]) != 0)
+	    printf("DTT%d:  FAILED\n", i+1);
+	else
+	    printf("DTT%d:  %i C\n", i+1, dtt_get_temp(sensors[i]));
+    }
+
+    return (0);
+} /* dtt_init() */
+
+
+int dtt_get_temp(int sensor)
+{
+    int i;
+
+    /*
+     * Start a conversion, may take up to 1 second.
+     */
+    dtt_write(sensor, DTT_WRITE_START_CONV, 0);
+    for (i = 0; i <= 10; i++) {
+	udelay(100000);
+	if (dtt_read(sensor, DTT_CONFIG) & 0x80)
+	    break;
+    }
+
+    return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+} /* dtt_get_temp() */
+
+
+#endif /* CONFIG_DTT_DS1621 */
diff --git a/drivers/ds1722.c b/drivers/hwmon/ds1722.c
similarity index 100%
rename from drivers/ds1722.c
rename to drivers/hwmon/ds1722.c
diff --git a/drivers/hwmon/ds1775.c b/drivers/hwmon/ds1775.c
new file mode 100644
index 0000000..0fbb0b4
--- /dev/null
+++ b/drivers/hwmon/ds1775.c
@@ -0,0 +1,156 @@
+/*
+ * 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
+ */
+
+/*
+ * Dallas Semiconductor's DS1775 Digital Thermometer and Thermostat
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_DS1775
+#include <i2c.h>
+#include <dtt.h>
+
+#define DTT_I2C_DEV_CODE	CFG_I2C_DTT_ADDR /* Dallas Semi's DS1775 device code */
+
+int dtt_read(int sensor, int reg)
+{
+	int dlen;
+	uchar data[2];
+
+	/*
+	 * Calculate sensor address and command
+	 */
+	sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1775 */
+
+	/*
+	 * Prepare to handle 2 byte result
+	 */
+	if ((reg == DTT_READ_TEMP) ||
+	    (reg == DTT_TEMP_OS) || (reg == DTT_TEMP_HYST))
+		dlen = 2;
+	else
+		dlen = 1;
+
+	/*
+	 * Now try to read the register
+	 */
+	if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+		return 1;
+
+	/*
+	 * Handle 2 byte result
+	 */
+	if (dlen == 2)
+		return ((int)((short)data[1] + (((short)data[0]) << 8)));
+
+	return (int) data[0];
+}
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+	int dlen;
+	uchar data[2];
+
+	/*
+	 * Calculate sensor address and register
+	 */
+	sensor = DTT_I2C_DEV_CODE + (sensor & 0x07);
+
+	/*
+	 * Handle various data sizes
+	 */
+	if ((reg == DTT_READ_TEMP) ||
+	    (reg == DTT_TEMP_OS) || (reg == DTT_TEMP_HYST)) {
+		dlen = 2;
+		data[0] = (char)((val >> 8) & 0xff); /* MSB first */
+		data[1] = (char)(val & 0xff);
+	} else {
+		dlen = 1;
+		data[0] = (char)(val & 0xff);
+	}
+
+	/*
+	 * Write value to device
+	 */
+	if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+		return 1;
+
+	return 0;
+}
+
+
+static int _dtt_init(int sensor)
+{
+	int val;
+
+	/*
+	 * Setup High Temp
+	 */
+	val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80;
+	if (dtt_write(sensor, DTT_TEMP_OS, val) != 0)
+		return 1;
+	udelay(50000);			/* Max 50ms */
+
+	/*
+	 * Setup Low Temp - hysteresis
+	 */
+	val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+	if (dtt_write(sensor, DTT_TEMP_HYST, val) != 0)
+		return 1;
+	udelay(50000);			/* Max 50ms */
+
+	/*
+	 * Setup configuraton register
+	 *
+	 * Fault Tolerance limits 4, Thermometer resolution bits is 9,
+	 * Polarity = Active Low,continuous conversion mode, Thermostat
+	 * mode is interrupt mode
+	 */
+	val = 0xa;
+	if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+		return 1;
+	udelay(50000);			/* Max 50ms */
+
+	return 0;
+}
+
+
+int dtt_init (void)
+{
+	int i;
+	unsigned char sensors[] = CONFIG_DTT_SENSORS;
+
+	for (i = 0; i < sizeof(sensors); i++) {
+		if (_dtt_init(sensors[i]) != 0)
+			printf("DTT%d:  FAILED\n", i+1);
+		else
+			printf("DTT%d:  %i C\n", i+1, dtt_get_temp(sensors[i]));
+	}
+
+	return (0);
+}
+
+
+int dtt_get_temp(int sensor)
+{
+	return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+}
+
+
+#endif /* CONFIG_DTT_DS1775 */
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
new file mode 100644
index 0000000..63f3b75
--- /dev/null
+++ b/drivers/hwmon/lm75.c
@@ -0,0 +1,185 @@
+/*
+ * (C) Copyright 2001
+ * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
+ *
+ * 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
+ */
+
+/*
+ * On Semiconductor's LM75 Temperature Sensor
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_LM75
+#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
+	(CFG_EEPROM_PAGE_WRITE_BITS < 1)
+# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than  1 to use CONFIG_DTT_LM75"
+#endif
+
+#include <i2c.h>
+#include <dtt.h>
+
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x48			/* ON Semi's LM75 device */
+
+int dtt_read(int sensor, int reg)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Validate 'reg' param
+     */
+    if((reg < 0) || (reg > 3))
+	return -1;
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* calculate address of lm75 */
+
+    /*
+     * Prepare to handle 2 byte result.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+	(reg == DTT_TEMP_HYST) ||
+	(reg == DTT_TEMP_SET))
+	dlen = 2;
+    else
+	dlen = 1;
+
+    /*
+     * Now try to read the register.
+     */
+    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+	return -1;
+
+    /*
+     * Handle 2 byte result.
+     */
+    if (dlen == 2)
+	return ((int)((short)data[1] + (((short)data[0]) << 8)));
+
+
+    return (int)data[0];
+} /* dtt_read() */
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+    int dlen;
+    uchar data[2];
+
+    /*
+     * Validate 'reg' param
+     */
+    if ((reg < 0) || (reg > 3))
+	return 1;
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* calculate address of lm75 */
+
+    /*
+     * Handle 2 byte values.
+     */
+    if ((reg == DTT_READ_TEMP) ||
+	(reg == DTT_TEMP_HYST) ||
+	(reg == DTT_TEMP_SET)) {
+	dlen = 2;
+	data[0] = (char)((val >> 8) & 0xff);	/* MSB first */
+	data[1] = (char)(val & 0xff);
+    } else {
+	dlen = 1;
+	data[0] = (char)(val & 0xff);
+    }
+
+    /*
+     * Write value to register.
+     */
+    if (i2c_write(sensor, reg, 1, data, dlen) != 0)
+	return 1;
+
+    return 0;
+} /* dtt_write() */
+
+
+static int _dtt_init(int sensor)
+{
+    int val;
+
+    /*
+     * Setup TSET ( trip point ) register
+     */
+    val = ((CFG_DTT_MAX_TEMP * 2) << 7) & 0xff80; /* trip */
+    if (dtt_write(sensor, DTT_TEMP_SET, val) != 0)
+	return 1;
+
+    /*
+     * Setup THYST ( untrip point ) register - Hysteresis
+     */
+    val = (((CFG_DTT_MAX_TEMP - CFG_DTT_HYSTERESIS) * 2) << 7) & 0xff80;
+    if (dtt_write(sensor, DTT_TEMP_HYST, val) != 0)
+	return 1;
+
+    /*
+     * Setup configuraton register
+     */
+#ifdef CONFIG_DTT_AD7414
+    /* config = alert active low and disabled */
+    val = 0x60;
+#else
+    /* config = 6 sample integration, int mode, active low, and enable */
+    val = 0x18;
+#endif
+    if (dtt_write(sensor, DTT_CONFIG, val) != 0)
+	return 1;
+
+    return 0;
+} /* _dtt_init() */
+
+
+int dtt_init (void)
+{
+    int i;
+    unsigned char sensors[] = CONFIG_DTT_SENSORS;
+    const char *const header = "DTT:   ";
+
+    for (i = 0; i < sizeof(sensors); i++) {
+	if (_dtt_init(sensors[i]) != 0)
+	    printf("%s%d FAILED INIT\n", header, i+1);
+	else
+	    printf("%s%d is %i C\n", header, i+1,
+		   dtt_get_temp(sensors[i]));
+    }
+
+    return (0);
+} /* dtt_init() */
+
+int dtt_get_temp(int sensor)
+{
+    return (dtt_read(sensor, DTT_READ_TEMP) / 256);
+} /* dtt_get_temp() */
+
+#endif /* CONFIG_DTT_LM75 */
diff --git a/drivers/hwmon/lm81.c b/drivers/hwmon/lm81.c
new file mode 100644
index 0000000..03bc53d
--- /dev/null
+++ b/drivers/hwmon/lm81.c
@@ -0,0 +1,148 @@
+/*
+ * (C) Copyright 2006
+ * Heiko Schocher, DENX Software Enginnering <hs@denx.de>
+ *
+ * based on dtt/lm75.c which is ...
+ *
+ * (C) Copyright 2001
+ * Bill Hunter,  Wave 7 Optics, williamhunter@mediaone.net
+ *
+ * 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
+ */
+
+/*
+ * On Semiconductor's LM81 Temperature Sensor
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_DTT_LM81
+#if !defined(CFG_EEPROM_PAGE_WRITE_ENABLE) || \
+	(CFG_EEPROM_PAGE_WRITE_BITS < 1)
+# error "CFG_EEPROM_PAGE_WRITE_ENABLE must be defined and CFG_EEPROM_PAGE_WRITE_BITS must be greater than  1 to use CONFIG_DTT_LM81"
+#endif
+
+#include <i2c.h>
+#include <dtt.h>
+
+/*
+ * Device code
+ */
+#define DTT_I2C_DEV_CODE 0x2c			/* ON Semi's LM81 device */
+
+int dtt_read(int sensor, int reg)
+{
+    int dlen = 1;
+    uchar data[2];
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x03); /* calculate address of lm81 */
+
+    /*
+     * Now try to read the register.
+     */
+    if (i2c_read(sensor, reg, 1, data, dlen) != 0)
+	return -1;
+
+    return (int)data[0];
+} /* dtt_read() */
+
+
+int dtt_write(int sensor, int reg, int val)
+{
+    uchar data;
+
+    /*
+     * Calculate sensor address and register.
+     */
+    sensor = DTT_I2C_DEV_CODE + (sensor & 0x03); /* calculate address of lm81 */
+
+    data = (char)(val & 0xff);
+
+    /*
+     * Write value to register.
+     */
+    if (i2c_write(sensor, reg, 1, &data, 1) != 0)
+	return 1;
+
+    return 0;
+} /* dtt_write() */
+
+#define DTT_MANU	0x3e
+#define DTT_REV		0x3f
+#define DTT_CONFIG	0x40
+#define DTT_ADR		0x48
+
+static int _dtt_init(int sensor)
+{
+	int	man;
+	int	adr;
+	int	rev;
+
+	if (dtt_write (sensor, DTT_CONFIG, 0x01) < 0)
+		return 1;
+	/* The LM81 needs 400ms to get the correct values ... */
+	udelay (400000);
+	man = dtt_read (sensor, DTT_MANU);
+	if (man != 0x01)
+		return 1;
+	adr = dtt_read (sensor, DTT_ADR);
+	if (adr < 0)
+		return 1;
+	rev = dtt_read (sensor, DTT_REV);
+	if (adr < 0)
+		return 1;
+
+	printf ("DTT:   Found LM81@%x Rev: %d\n", adr, rev);
+	return 0;
+} /* _dtt_init() */
+
+
+int dtt_init (void)
+{
+    int i;
+    unsigned char sensors[] = CONFIG_DTT_SENSORS;
+    const char *const header = "DTT:   ";
+
+    for (i = 0; i < sizeof(sensors); i++) {
+	if (_dtt_init(sensors[i]) != 0)
+	    printf("%s%d FAILED INIT\n", header, i+1);
+	else
+	    printf("%s%d is %i C\n", header, i+1,
+		   dtt_get_temp(sensors[i]));
+    }
+
+    return (0);
+} /* dtt_init() */
+
+#define TEMP_FROM_REG(temp) \
+   ((temp)<256?((((temp)&0x1fe) >> 1) * 10)	 + ((temp) & 1) * 5:  \
+	       ((((temp)&0x1fe) >> 1) -255) * 10 - ((temp) & 1) * 5)  \
+
+int dtt_get_temp(int sensor)
+{
+	int val = dtt_read (sensor, DTT_READ_TEMP);
+	int tmpcnf = dtt_read (sensor, DTT_CONFIG_TEMP);
+
+	return (TEMP_FROM_REG((val << 1) + ((tmpcnf & 0x80) >> 7))) / 10;
+} /* dtt_get_temp() */
+
+#endif /* CONFIG_DTT_LM81 */
diff --git a/drivers/nand/Makefile b/drivers/i2c/Makefile
similarity index 87%
copy from drivers/nand/Makefile
copy to drivers/i2c/Makefile
index fb0185b..29d6c03 100644
--- a/drivers/nand/Makefile
+++ b/drivers/i2c/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2006
+# (C) Copyright 2000-2007
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,10 +23,14 @@
 
 include $(TOPDIR)/config.mk
 
-LIB 	:= $(obj)libnand.a
+LIB 	:= $(obj)libi2c.a
 
-COBJS 	:= nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
+COBJS-y += fsl_i2c.o
+COBJS-y += omap1510_i2c.o
+COBJS-y += omap24xx_i2c.o
+COBJS-y += tsi108_i2c.o
 
+COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
 OBJS 	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/fsl_i2c.c b/drivers/i2c/fsl_i2c.c
similarity index 100%
rename from drivers/fsl_i2c.c
rename to drivers/i2c/fsl_i2c.c
diff --git a/drivers/omap1510_i2c.c b/drivers/i2c/omap1510_i2c.c
similarity index 100%
rename from drivers/omap1510_i2c.c
rename to drivers/i2c/omap1510_i2c.c
diff --git a/drivers/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
similarity index 100%
rename from drivers/omap24xx_i2c.c
rename to drivers/i2c/omap24xx_i2c.c
diff --git a/drivers/tsi108_i2c.c b/drivers/i2c/tsi108_i2c.c
similarity index 99%
rename from drivers/tsi108_i2c.c
rename to drivers/i2c/tsi108_i2c.c
index 3a3b75c..d6736b0 100644
--- a/drivers/tsi108_i2c.c
+++ b/drivers/i2c/tsi108_i2c.c
@@ -276,7 +276,7 @@
 	 * The Tsi108 HW doesn't support sending just the chip address
 	 * and checkong for an <ACK> back.
 	 */
-	return i2c_read (chip, 0, 1, (char *)&tmp, 1);
+	return i2c_read (chip, 0, 1, (uchar *)&tmp, 1);
 }
 
 #endif
diff --git a/drivers/nand/Makefile b/drivers/input/Makefile
similarity index 88%
copy from drivers/nand/Makefile
copy to drivers/input/Makefile
index fb0185b..df22cf9 100644
--- a/drivers/nand/Makefile
+++ b/drivers/input/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2006
+# (C) Copyright 2000-2007
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,10 +23,13 @@
 
 include $(TOPDIR)/config.mk
 
-LIB 	:= $(obj)libnand.a
+LIB 	:= $(obj)libinput.a
 
-COBJS 	:= nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
+COBJS-y += i8042.o
+COBJS-y += keyboard.o
+COBJS-y += pc_keyb.o ps2ser.o ps2mult.o
 
+COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
 OBJS 	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/i8042.c b/drivers/input/i8042.c
similarity index 100%
rename from drivers/i8042.c
rename to drivers/input/i8042.c
diff --git a/drivers/keyboard.c b/drivers/input/keyboard.c
similarity index 100%
rename from drivers/keyboard.c
rename to drivers/input/keyboard.c
diff --git a/drivers/pc_keyb.c b/drivers/input/pc_keyb.c
similarity index 100%
rename from drivers/pc_keyb.c
rename to drivers/input/pc_keyb.c
diff --git a/drivers/ps2mult.c b/drivers/input/ps2mult.c
similarity index 100%
rename from drivers/ps2mult.c
rename to drivers/input/ps2mult.c
diff --git a/drivers/ps2ser.c b/drivers/input/ps2ser.c
similarity index 100%
rename from drivers/ps2ser.c
rename to drivers/input/ps2ser.c
diff --git a/drivers/nand/Makefile b/drivers/misc/Makefile
similarity index 89%
rename from drivers/nand/Makefile
rename to drivers/misc/Makefile
index fb0185b..78cec21 100644
--- a/drivers/nand/Makefile
+++ b/drivers/misc/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2006
+# (C) Copyright 2000-2007
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,10 +23,13 @@
 
 include $(TOPDIR)/config.mk
 
-LIB 	:= $(obj)libnand.a
+LIB 	:= $(obj)libmisc.a
 
-COBJS 	:= nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
+COBJS-y += ali512x.o
+COBJS-y += ns87308.o
+COBJS-y += status_led.o
 
+COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
 OBJS 	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/ali512x.c b/drivers/misc/ali512x.c
similarity index 100%
rename from drivers/ali512x.c
rename to drivers/misc/ali512x.c
diff --git a/drivers/ns87308.c b/drivers/misc/ns87308.c
similarity index 100%
rename from drivers/ns87308.c
rename to drivers/misc/ns87308.c
diff --git a/drivers/status_led.c b/drivers/misc/status_led.c
similarity index 100%
rename from drivers/status_led.c
rename to drivers/misc/status_led.c
diff --git a/drivers/nand/Makefile b/drivers/mtd/Makefile
similarity index 88%
copy from drivers/nand/Makefile
copy to drivers/mtd/Makefile
index fb0185b..95c5e02 100644
--- a/drivers/nand/Makefile
+++ b/drivers/mtd/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2006
+# (C) Copyright 2000-2007
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,10 +23,14 @@
 
 include $(TOPDIR)/config.mk
 
-LIB 	:= $(obj)libnand.a
+LIB 	:= $(obj)libmtd.a
 
-COBJS 	:= nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
+COBJS-y += at45.o
+COBJS-y += cfi_flash.o
+COBJS-y += dataflash.o
+COBJS-y += mw_eeprom.o
 
+COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
 OBJS 	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/at45.c b/drivers/mtd/at45.c
similarity index 100%
rename from drivers/at45.c
rename to drivers/mtd/at45.c
diff --git a/drivers/cfi_flash.c b/drivers/mtd/cfi_flash.c
similarity index 100%
rename from drivers/cfi_flash.c
rename to drivers/mtd/cfi_flash.c
diff --git a/drivers/dataflash.c b/drivers/mtd/dataflash.c
similarity index 100%
rename from drivers/dataflash.c
rename to drivers/mtd/dataflash.c
diff --git a/drivers/mw_eeprom.c b/drivers/mtd/mw_eeprom.c
similarity index 100%
rename from drivers/mw_eeprom.c
rename to drivers/mtd/mw_eeprom.c
diff --git a/drivers/nand/Makefile b/drivers/mtd/nand/Makefile
similarity index 89%
copy from drivers/nand/Makefile
copy to drivers/mtd/nand/Makefile
index fb0185b..42864f9 100644
--- a/drivers/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -25,8 +25,14 @@
 
 LIB 	:= $(obj)libnand.a
 
-COBJS 	:= nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
+COBJS-y += nand.o
+COBJS-y += nand_base.o
+COBJS-y += nand_ids.o
+COBJS-y += nand_ecc.o
+COBJS-y += nand_bbt.o
+COBJS-y += nand_util.o
 
+COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
 OBJS 	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
similarity index 100%
rename from drivers/nand/diskonchip.c
rename to drivers/mtd/nand/diskonchip.c
diff --git a/drivers/nand/nand.c b/drivers/mtd/nand/nand.c
similarity index 100%
rename from drivers/nand/nand.c
rename to drivers/mtd/nand/nand.c
diff --git a/drivers/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
similarity index 100%
rename from drivers/nand/nand_base.c
rename to drivers/mtd/nand/nand_base.c
diff --git a/drivers/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
similarity index 100%
rename from drivers/nand/nand_bbt.c
rename to drivers/mtd/nand/nand_bbt.c
diff --git a/drivers/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
similarity index 100%
rename from drivers/nand/nand_ecc.c
rename to drivers/mtd/nand/nand_ecc.c
diff --git a/drivers/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c
similarity index 100%
rename from drivers/nand/nand_ids.c
rename to drivers/mtd/nand/nand_ids.c
diff --git a/drivers/nand/nand_util.c b/drivers/mtd/nand/nand_util.c
similarity index 100%
rename from drivers/nand/nand_util.c
rename to drivers/mtd/nand/nand_util.c
diff --git a/drivers/nand_legacy/Makefile b/drivers/mtd/nand_legacy/Makefile
similarity index 100%
rename from drivers/nand_legacy/Makefile
rename to drivers/mtd/nand_legacy/Makefile
diff --git a/drivers/nand_legacy/nand_legacy.c b/drivers/mtd/nand_legacy/nand_legacy.c
similarity index 100%
rename from drivers/nand_legacy/nand_legacy.c
rename to drivers/mtd/nand_legacy/nand_legacy.c
diff --git a/drivers/onenand/Makefile b/drivers/mtd/onenand/Makefile
similarity index 100%
rename from drivers/onenand/Makefile
rename to drivers/mtd/onenand/Makefile
diff --git a/drivers/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
similarity index 100%
rename from drivers/onenand/onenand_base.c
rename to drivers/mtd/onenand/onenand_base.c
diff --git a/drivers/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
similarity index 100%
rename from drivers/onenand/onenand_bbt.c
rename to drivers/mtd/onenand/onenand_bbt.c
diff --git a/drivers/3c589.c b/drivers/net/3c589.c
similarity index 100%
rename from drivers/3c589.c
rename to drivers/net/3c589.c
diff --git a/drivers/3c589.h b/drivers/net/3c589.h
similarity index 100%
rename from drivers/3c589.h
rename to drivers/net/3c589.h
diff --git a/drivers/5701rls.c b/drivers/net/5701rls.c
similarity index 100%
rename from drivers/5701rls.c
rename to drivers/net/5701rls.c
diff --git a/drivers/5701rls.h b/drivers/net/5701rls.h
similarity index 100%
rename from drivers/5701rls.h
rename to drivers/net/5701rls.h
diff --git a/drivers/8390.h b/drivers/net/8390.h
similarity index 100%
rename from drivers/8390.h
rename to drivers/net/8390.h
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 37d69b9..41e1bde 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -25,8 +25,39 @@
 
 LIB 	:= $(obj)libnet.a
 
-COBJS 	:= mcffec.o
+COBJS-y += 3c589.o
+COBJS-y += bcm570x.o bcm570x_autoneg.o 5701rls.o
+COBJS-y += cs8900.o
+COBJS-y += dc2114x.o
+COBJS-y += dm9000x.o
+COBJS-y += e1000.o
+COBJS-y += eepro100.o
+COBJS-y += enc28j60.o
+COBJS-y += inca-ip_sw.o
+COBJS-y += ks8695eth.o
+COBJS-y += lan91c96.o
+COBJS-y += macb.o
+COBJS-y += mcffec.o
+COBJS-y += natsemi.o
+COBJS-y += ne2000.o
+COBJS-y += netarm_eth.o
+COBJS-y += netconsole.o
+COBJS-y += ns7520_eth.o
+COBJS-y += ns8382x.o
+COBJS-y += ns9750_eth.o
+COBJS-y += pcnet.o
+COBJS-y += plb2800_eth.o
+COBJS-y += rtl8019.o
+COBJS-y += rtl8139.o
+COBJS-y += rtl8169.o
+COBJS-y += s3c4510b_eth.o
+COBJS-y += smc91111.o
+COBJS-y += tigon3.o
+COBJS-y += tsec.o
+COBJS-y += tsi108_eth.o
+COBJS-y += uli526x.o
 
+COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
 OBJS 	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/bcm570x.c b/drivers/net/bcm570x.c
similarity index 100%
rename from drivers/bcm570x.c
rename to drivers/net/bcm570x.c
diff --git a/drivers/bcm570x_autoneg.c b/drivers/net/bcm570x_autoneg.c
similarity index 100%
rename from drivers/bcm570x_autoneg.c
rename to drivers/net/bcm570x_autoneg.c
diff --git a/drivers/bcm570x_autoneg.h b/drivers/net/bcm570x_autoneg.h
similarity index 100%
rename from drivers/bcm570x_autoneg.h
rename to drivers/net/bcm570x_autoneg.h
diff --git a/drivers/bcm570x_bits.h b/drivers/net/bcm570x_bits.h
similarity index 100%
rename from drivers/bcm570x_bits.h
rename to drivers/net/bcm570x_bits.h
diff --git a/drivers/bcm570x_debug.h b/drivers/net/bcm570x_debug.h
similarity index 100%
rename from drivers/bcm570x_debug.h
rename to drivers/net/bcm570x_debug.h
diff --git a/drivers/bcm570x_lm.h b/drivers/net/bcm570x_lm.h
similarity index 100%
rename from drivers/bcm570x_lm.h
rename to drivers/net/bcm570x_lm.h
diff --git a/drivers/bcm570x_mm.h b/drivers/net/bcm570x_mm.h
similarity index 100%
rename from drivers/bcm570x_mm.h
rename to drivers/net/bcm570x_mm.h
diff --git a/drivers/bcm570x_queue.h b/drivers/net/bcm570x_queue.h
similarity index 100%
rename from drivers/bcm570x_queue.h
rename to drivers/net/bcm570x_queue.h
diff --git a/drivers/cs8900.c b/drivers/net/cs8900.c
similarity index 100%
rename from drivers/cs8900.c
rename to drivers/net/cs8900.c
diff --git a/drivers/cs8900.h b/drivers/net/cs8900.h
similarity index 100%
rename from drivers/cs8900.h
rename to drivers/net/cs8900.h
diff --git a/drivers/dc2114x.c b/drivers/net/dc2114x.c
similarity index 100%
rename from drivers/dc2114x.c
rename to drivers/net/dc2114x.c
diff --git a/drivers/dm9000x.c b/drivers/net/dm9000x.c
similarity index 100%
rename from drivers/dm9000x.c
rename to drivers/net/dm9000x.c
diff --git a/drivers/dm9000x.h b/drivers/net/dm9000x.h
similarity index 100%
rename from drivers/dm9000x.h
rename to drivers/net/dm9000x.h
diff --git a/drivers/e1000.c b/drivers/net/e1000.c
similarity index 100%
rename from drivers/e1000.c
rename to drivers/net/e1000.c
diff --git a/drivers/e1000.h b/drivers/net/e1000.h
similarity index 100%
rename from drivers/e1000.h
rename to drivers/net/e1000.h
diff --git a/drivers/eepro100.c b/drivers/net/eepro100.c
similarity index 100%
rename from drivers/eepro100.c
rename to drivers/net/eepro100.c
diff --git a/drivers/enc28j60.c b/drivers/net/enc28j60.c
similarity index 100%
rename from drivers/enc28j60.c
rename to drivers/net/enc28j60.c
diff --git a/drivers/inca-ip_sw.c b/drivers/net/inca-ip_sw.c
similarity index 100%
rename from drivers/inca-ip_sw.c
rename to drivers/net/inca-ip_sw.c
diff --git a/drivers/ks8695eth.c b/drivers/net/ks8695eth.c
similarity index 100%
rename from drivers/ks8695eth.c
rename to drivers/net/ks8695eth.c
diff --git a/drivers/lan91c96.c b/drivers/net/lan91c96.c
similarity index 100%
rename from drivers/lan91c96.c
rename to drivers/net/lan91c96.c
diff --git a/drivers/lan91c96.h b/drivers/net/lan91c96.h
similarity index 100%
rename from drivers/lan91c96.h
rename to drivers/net/lan91c96.h
diff --git a/drivers/macb.c b/drivers/net/macb.c
similarity index 100%
rename from drivers/macb.c
rename to drivers/net/macb.c
diff --git a/drivers/macb.h b/drivers/net/macb.h
similarity index 100%
rename from drivers/macb.h
rename to drivers/net/macb.h
diff --git a/drivers/natsemi.c b/drivers/net/natsemi.c
similarity index 100%
rename from drivers/natsemi.c
rename to drivers/net/natsemi.c
diff --git a/drivers/ne2000.c b/drivers/net/ne2000.c
similarity index 98%
rename from drivers/ne2000.c
rename to drivers/net/ne2000.c
index 695a1dc..c978d62 100644
--- a/drivers/ne2000.c
+++ b/drivers/net/ne2000.c
@@ -723,7 +723,8 @@
 	{ /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 },
 	{ /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 },
 	{ /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 },
-	{ /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 }
+	{ /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 },
+	{ /* Qemu */ 0x0, 0x52, 0x54, 0x00, 0 }
 };
 
 #define NR_INFO		(sizeof(hw_info)/sizeof(hw_info_t))
@@ -824,30 +825,22 @@
 
 /* U-boot specific routines */
 
-#define NB 5
 
 static unsigned char *pbuf = NULL;
-static int plen[NB];
-static int nrx = 0;
 
 static int pkey = -1;
 static int initialized=0;
 
 void uboot_push_packet_len(int len) {
-	PRINTK("pushed len = %d, nrx = %d\n", len, nrx);
+	PRINTK("pushed len = %d\n", len);
 	if (len>=2000) {
 		printf("NE2000: packet too big\n");
 		return;
 	}
-	if (nrx >= NB) {
-		printf("losing packets in rx\n");
-		return;
-	}
-	plen[nrx] = len;
-	dp83902a_recv(&pbuf[nrx*2000], len);
+	dp83902a_recv(&pbuf[0], len);
 
 	/*Just pass it to the upper layer*/
-	NetReceive(&pbuf[nrx*2000], plen[nrx]);
+	NetReceive(&pbuf[0], len);
 }
 
 void uboot_push_tx_done(int key, int val) {
@@ -862,9 +855,9 @@
 	PRINTK("### eth_init\n");
 
 	if (!pbuf) {
-		pbuf = malloc(NB*2000);
+		pbuf = malloc(2000);
 		if (!pbuf) {
-			printf("Cannot allocate rx buffers\n");
+			printf("Cannot allocate rx buffer\n");
 			return -1;
 		}
 	}
diff --git a/drivers/ne2000.h b/drivers/net/ne2000.h
similarity index 100%
rename from drivers/ne2000.h
rename to drivers/net/ne2000.h
diff --git a/drivers/netarm_eth.c b/drivers/net/netarm_eth.c
similarity index 100%
rename from drivers/netarm_eth.c
rename to drivers/net/netarm_eth.c
diff --git a/drivers/netarm_eth.h b/drivers/net/netarm_eth.h
similarity index 100%
rename from drivers/netarm_eth.h
rename to drivers/net/netarm_eth.h
diff --git a/drivers/netconsole.c b/drivers/net/netconsole.c
similarity index 100%
rename from drivers/netconsole.c
rename to drivers/net/netconsole.c
diff --git a/drivers/nicext.h b/drivers/net/nicext.h
similarity index 100%
rename from drivers/nicext.h
rename to drivers/net/nicext.h
diff --git a/drivers/ns7520_eth.c b/drivers/net/ns7520_eth.c
similarity index 100%
rename from drivers/ns7520_eth.c
rename to drivers/net/ns7520_eth.c
diff --git a/drivers/ns8382x.c b/drivers/net/ns8382x.c
similarity index 100%
rename from drivers/ns8382x.c
rename to drivers/net/ns8382x.c
diff --git a/drivers/ns9750_eth.c b/drivers/net/ns9750_eth.c
similarity index 100%
rename from drivers/ns9750_eth.c
rename to drivers/net/ns9750_eth.c
diff --git a/drivers/pcnet.c b/drivers/net/pcnet.c
similarity index 100%
rename from drivers/pcnet.c
rename to drivers/net/pcnet.c
diff --git a/drivers/plb2800_eth.c b/drivers/net/plb2800_eth.c
similarity index 100%
rename from drivers/plb2800_eth.c
rename to drivers/net/plb2800_eth.c
diff --git a/drivers/rtl8019.c b/drivers/net/rtl8019.c
similarity index 100%
rename from drivers/rtl8019.c
rename to drivers/net/rtl8019.c
diff --git a/drivers/rtl8019.h b/drivers/net/rtl8019.h
similarity index 100%
rename from drivers/rtl8019.h
rename to drivers/net/rtl8019.h
diff --git a/drivers/rtl8139.c b/drivers/net/rtl8139.c
similarity index 100%
rename from drivers/rtl8139.c
rename to drivers/net/rtl8139.c
diff --git a/drivers/rtl8169.c b/drivers/net/rtl8169.c
similarity index 100%
rename from drivers/rtl8169.c
rename to drivers/net/rtl8169.c
diff --git a/drivers/s3c4510b_eth.c b/drivers/net/s3c4510b_eth.c
similarity index 98%
rename from drivers/s3c4510b_eth.c
rename to drivers/net/s3c4510b_eth.c
index 48901aa..3d9066a 100644
--- a/drivers/s3c4510b_eth.c
+++ b/drivers/net/s3c4510b_eth.c
@@ -175,7 +175,7 @@
 	}
 
 	/* copy user data into frame data pointer */
-	memcpy((void *)(eth->m_curTX_FD->m_frameDataPtr.bf.dataPtr),
+	memcpy((void *)((u32)(eth->m_curTX_FD->m_frameDataPtr.bf.dataPtr)),
 	       (void *)packet,
 	       length);
 
diff --git a/drivers/s3c4510b_eth.h b/drivers/net/s3c4510b_eth.h
similarity index 100%
rename from drivers/s3c4510b_eth.h
rename to drivers/net/s3c4510b_eth.h
diff --git a/drivers/sk98lin/Makefile b/drivers/net/sk98lin/Makefile
similarity index 90%
rename from drivers/sk98lin/Makefile
rename to drivers/net/sk98lin/Makefile
index 7e50b1d..a7d4a3b 100644
--- a/drivers/sk98lin/Makefile
+++ b/drivers/net/sk98lin/Makefile
@@ -29,12 +29,26 @@
 
 LIB	:= $(obj)libsk98lin.a
 
-COBJS	:= skge.o skaddr.o skgehwt.o skgeinit.o skgepnmi.o skgesirq.o \
-		ski2c.o sklm80.o skqueue.o skrlmt.o sktimer.o skvpd.o \
-		skxmac2.o skcsum.o #skproc.o
+COBJS-y += skge.o
+COBJS-y += skaddr.o
+COBJS-y += skgehwt.o
+COBJS-y += skgeinit.o
+COBJS-y += skgepnmi.o
+COBJS-y += skgesirq.o
+COBJS-y += ski2c.o
+COBJS-y += sklm80.o
+COBJS-y += skqueue.o
+COBJS-y += skrlmt.o
+COBJS-y += sktimer.o
+COBJS-y += skvpd.o
+COBJS-y += skxmac2.o
+COBJS-y += skcsum.o
+#COBJS-y += skproc.o
 
-COBJS	+= uboot_skb.o uboot_drv.o
+COBJS-y += uboot_skb.o
+COBJS-y += uboot_drv.o
 
+COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/sk98lin/h/lm80.h b/drivers/net/sk98lin/h/lm80.h
similarity index 100%
rename from drivers/sk98lin/h/lm80.h
rename to drivers/net/sk98lin/h/lm80.h
diff --git a/drivers/sk98lin/h/skaddr.h b/drivers/net/sk98lin/h/skaddr.h
similarity index 100%
rename from drivers/sk98lin/h/skaddr.h
rename to drivers/net/sk98lin/h/skaddr.h
diff --git a/drivers/sk98lin/h/skcsum.h b/drivers/net/sk98lin/h/skcsum.h
similarity index 100%
rename from drivers/sk98lin/h/skcsum.h
rename to drivers/net/sk98lin/h/skcsum.h
diff --git a/drivers/sk98lin/h/skdebug.h b/drivers/net/sk98lin/h/skdebug.h
similarity index 100%
rename from drivers/sk98lin/h/skdebug.h
rename to drivers/net/sk98lin/h/skdebug.h
diff --git a/drivers/sk98lin/h/skdrv1st.h b/drivers/net/sk98lin/h/skdrv1st.h
similarity index 100%
rename from drivers/sk98lin/h/skdrv1st.h
rename to drivers/net/sk98lin/h/skdrv1st.h
diff --git a/drivers/sk98lin/h/skdrv2nd.h b/drivers/net/sk98lin/h/skdrv2nd.h
similarity index 100%
rename from drivers/sk98lin/h/skdrv2nd.h
rename to drivers/net/sk98lin/h/skdrv2nd.h
diff --git a/drivers/sk98lin/h/skerror.h b/drivers/net/sk98lin/h/skerror.h
similarity index 100%
rename from drivers/sk98lin/h/skerror.h
rename to drivers/net/sk98lin/h/skerror.h
diff --git a/drivers/sk98lin/h/skgedrv.h b/drivers/net/sk98lin/h/skgedrv.h
similarity index 100%
rename from drivers/sk98lin/h/skgedrv.h
rename to drivers/net/sk98lin/h/skgedrv.h
diff --git a/drivers/sk98lin/h/skgehw.h b/drivers/net/sk98lin/h/skgehw.h
similarity index 100%
rename from drivers/sk98lin/h/skgehw.h
rename to drivers/net/sk98lin/h/skgehw.h
diff --git a/drivers/sk98lin/h/skgehwt.h b/drivers/net/sk98lin/h/skgehwt.h
similarity index 100%
rename from drivers/sk98lin/h/skgehwt.h
rename to drivers/net/sk98lin/h/skgehwt.h
diff --git a/drivers/sk98lin/h/skgei2c.h b/drivers/net/sk98lin/h/skgei2c.h
similarity index 100%
rename from drivers/sk98lin/h/skgei2c.h
rename to drivers/net/sk98lin/h/skgei2c.h
diff --git a/drivers/sk98lin/h/skgeinit.h b/drivers/net/sk98lin/h/skgeinit.h
similarity index 100%
rename from drivers/sk98lin/h/skgeinit.h
rename to drivers/net/sk98lin/h/skgeinit.h
diff --git a/drivers/sk98lin/h/skgepnm2.h b/drivers/net/sk98lin/h/skgepnm2.h
similarity index 100%
rename from drivers/sk98lin/h/skgepnm2.h
rename to drivers/net/sk98lin/h/skgepnm2.h
diff --git a/drivers/sk98lin/h/skgepnmi.h b/drivers/net/sk98lin/h/skgepnmi.h
similarity index 100%
rename from drivers/sk98lin/h/skgepnmi.h
rename to drivers/net/sk98lin/h/skgepnmi.h
diff --git a/drivers/sk98lin/h/skgesirq.h b/drivers/net/sk98lin/h/skgesirq.h
similarity index 100%
rename from drivers/sk98lin/h/skgesirq.h
rename to drivers/net/sk98lin/h/skgesirq.h
diff --git a/drivers/sk98lin/h/ski2c.h b/drivers/net/sk98lin/h/ski2c.h
similarity index 100%
rename from drivers/sk98lin/h/ski2c.h
rename to drivers/net/sk98lin/h/ski2c.h
diff --git a/drivers/sk98lin/h/skqueue.h b/drivers/net/sk98lin/h/skqueue.h
similarity index 100%
rename from drivers/sk98lin/h/skqueue.h
rename to drivers/net/sk98lin/h/skqueue.h
diff --git a/drivers/sk98lin/h/skrlmt.h b/drivers/net/sk98lin/h/skrlmt.h
similarity index 100%
rename from drivers/sk98lin/h/skrlmt.h
rename to drivers/net/sk98lin/h/skrlmt.h
diff --git a/drivers/sk98lin/h/sktimer.h b/drivers/net/sk98lin/h/sktimer.h
similarity index 100%
rename from drivers/sk98lin/h/sktimer.h
rename to drivers/net/sk98lin/h/sktimer.h
diff --git a/drivers/sk98lin/h/sktypes.h b/drivers/net/sk98lin/h/sktypes.h
similarity index 100%
rename from drivers/sk98lin/h/sktypes.h
rename to drivers/net/sk98lin/h/sktypes.h
diff --git a/drivers/sk98lin/h/skversion.h b/drivers/net/sk98lin/h/skversion.h
similarity index 100%
rename from drivers/sk98lin/h/skversion.h
rename to drivers/net/sk98lin/h/skversion.h
diff --git a/drivers/sk98lin/h/skvpd.h b/drivers/net/sk98lin/h/skvpd.h
similarity index 100%
rename from drivers/sk98lin/h/skvpd.h
rename to drivers/net/sk98lin/h/skvpd.h
diff --git a/drivers/sk98lin/h/xmac_ii.h b/drivers/net/sk98lin/h/xmac_ii.h
similarity index 100%
rename from drivers/sk98lin/h/xmac_ii.h
rename to drivers/net/sk98lin/h/xmac_ii.h
diff --git a/drivers/sk98lin/skaddr.c b/drivers/net/sk98lin/skaddr.c
similarity index 100%
rename from drivers/sk98lin/skaddr.c
rename to drivers/net/sk98lin/skaddr.c
diff --git a/drivers/sk98lin/skcsum.c b/drivers/net/sk98lin/skcsum.c
similarity index 100%
rename from drivers/sk98lin/skcsum.c
rename to drivers/net/sk98lin/skcsum.c
diff --git a/drivers/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
similarity index 100%
rename from drivers/sk98lin/skge.c
rename to drivers/net/sk98lin/skge.c
diff --git a/drivers/sk98lin/skgehwt.c b/drivers/net/sk98lin/skgehwt.c
similarity index 100%
rename from drivers/sk98lin/skgehwt.c
rename to drivers/net/sk98lin/skgehwt.c
diff --git a/drivers/sk98lin/skgeinit.c b/drivers/net/sk98lin/skgeinit.c
similarity index 100%
rename from drivers/sk98lin/skgeinit.c
rename to drivers/net/sk98lin/skgeinit.c
diff --git a/drivers/sk98lin/skgemib.c b/drivers/net/sk98lin/skgemib.c
similarity index 100%
rename from drivers/sk98lin/skgemib.c
rename to drivers/net/sk98lin/skgemib.c
diff --git a/drivers/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c
similarity index 100%
rename from drivers/sk98lin/skgepnmi.c
rename to drivers/net/sk98lin/skgepnmi.c
diff --git a/drivers/sk98lin/skgesirq.c b/drivers/net/sk98lin/skgesirq.c
similarity index 100%
rename from drivers/sk98lin/skgesirq.c
rename to drivers/net/sk98lin/skgesirq.c
diff --git a/drivers/sk98lin/ski2c.c b/drivers/net/sk98lin/ski2c.c
similarity index 100%
rename from drivers/sk98lin/ski2c.c
rename to drivers/net/sk98lin/ski2c.c
diff --git a/drivers/sk98lin/sklm80.c b/drivers/net/sk98lin/sklm80.c
similarity index 100%
rename from drivers/sk98lin/sklm80.c
rename to drivers/net/sk98lin/sklm80.c
diff --git a/drivers/sk98lin/skproc.c b/drivers/net/sk98lin/skproc.c
similarity index 100%
rename from drivers/sk98lin/skproc.c
rename to drivers/net/sk98lin/skproc.c
diff --git a/drivers/sk98lin/skqueue.c b/drivers/net/sk98lin/skqueue.c
similarity index 100%
rename from drivers/sk98lin/skqueue.c
rename to drivers/net/sk98lin/skqueue.c
diff --git a/drivers/sk98lin/skrlmt.c b/drivers/net/sk98lin/skrlmt.c
similarity index 100%
rename from drivers/sk98lin/skrlmt.c
rename to drivers/net/sk98lin/skrlmt.c
diff --git a/drivers/sk98lin/sktimer.c b/drivers/net/sk98lin/sktimer.c
similarity index 100%
rename from drivers/sk98lin/sktimer.c
rename to drivers/net/sk98lin/sktimer.c
diff --git a/drivers/sk98lin/skvpd.c b/drivers/net/sk98lin/skvpd.c
similarity index 100%
rename from drivers/sk98lin/skvpd.c
rename to drivers/net/sk98lin/skvpd.c
diff --git a/drivers/sk98lin/skxmac2.c b/drivers/net/sk98lin/skxmac2.c
similarity index 100%
rename from drivers/sk98lin/skxmac2.c
rename to drivers/net/sk98lin/skxmac2.c
diff --git a/drivers/sk98lin/u-boot_compat.h b/drivers/net/sk98lin/u-boot_compat.h
similarity index 100%
rename from drivers/sk98lin/u-boot_compat.h
rename to drivers/net/sk98lin/u-boot_compat.h
diff --git a/drivers/sk98lin/uboot_drv.c b/drivers/net/sk98lin/uboot_drv.c
similarity index 100%
rename from drivers/sk98lin/uboot_drv.c
rename to drivers/net/sk98lin/uboot_drv.c
diff --git a/drivers/sk98lin/uboot_skb.c b/drivers/net/sk98lin/uboot_skb.c
similarity index 100%
rename from drivers/sk98lin/uboot_skb.c
rename to drivers/net/sk98lin/uboot_skb.c
diff --git a/drivers/smc91111.c b/drivers/net/smc91111.c
similarity index 100%
rename from drivers/smc91111.c
rename to drivers/net/smc91111.c
diff --git a/drivers/smc91111.h b/drivers/net/smc91111.h
similarity index 100%
rename from drivers/smc91111.h
rename to drivers/net/smc91111.h
diff --git a/drivers/tigon3.c b/drivers/net/tigon3.c
similarity index 100%
rename from drivers/tigon3.c
rename to drivers/net/tigon3.c
diff --git a/drivers/tigon3.h b/drivers/net/tigon3.h
similarity index 100%
rename from drivers/tigon3.h
rename to drivers/net/tigon3.h
diff --git a/drivers/tsec.c b/drivers/net/tsec.c
similarity index 99%
rename from drivers/tsec.c
rename to drivers/net/tsec.c
index 4ff3339..ca6284b 100644
--- a/drivers/tsec.c
+++ b/drivers/net/tsec.c
@@ -117,10 +117,13 @@
 void phy_run_commands(struct tsec_private *priv, struct phy_cmd *cmd);
 static void adjust_link(struct eth_device *dev);
 static void relocate_cmds(void);
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
+	&& !defined(BITBANGMII)
 static int tsec_miiphy_write(char *devname, unsigned char addr,
 			     unsigned char reg, unsigned short value);
 static int tsec_miiphy_read(char *devname, unsigned char addr,
 			    unsigned char reg, unsigned short *value);
+#endif
 #ifdef CONFIG_MCAST_TFTP
 static int tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set);
 #endif
@@ -803,6 +806,7 @@
 	/* Tell the DMA it is clear to go */
 	regs->dmactrl |= DMACTRL_INIT_SETTINGS;
 	regs->tstat = TSTAT_CLEAR_THALT;
+	regs->rstat = RSTAT_CLEAR_RHALT;
 	regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
 }
 
diff --git a/drivers/tsec.h b/drivers/net/tsec.h
similarity index 100%
rename from drivers/tsec.h
rename to drivers/net/tsec.h
diff --git a/drivers/tsi108_eth.c b/drivers/net/tsi108_eth.c
similarity index 100%
rename from drivers/tsi108_eth.c
rename to drivers/net/tsi108_eth.c
diff --git a/drivers/net/uli526x.c b/drivers/net/uli526x.c
new file mode 100644
index 0000000..1267c57
--- /dev/null
+++ b/drivers/net/uli526x.c
@@ -0,0 +1,996 @@
+/*
+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Author: Roy Zang <tie-fei.zang@freescale.com>, Sep, 2007
+ *
+ * Description:
+ * ULI 526x Ethernet port driver.
+ * Based on the Linux driver: drivers/net/tulip/uli526x.c
+ *
+ * This 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.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/io.h>
+#include <pci.h>
+#include <miiphy.h>
+
+/* some kernel function compatible define */
+
+#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
+	defined(CONFIG_ULI526X)
+
+#undef DEBUG
+
+/* Board/System/Debug information/definition */
+#define ULI_VENDOR_ID		0x10B9
+#define ULI5261_DEVICE_ID	0x5261
+#define ULI5263_DEVICE_ID	0x5263
+/* ULi M5261 ID*/
+#define PCI_ULI5261_ID		ULI5261_DEVICE_ID << 16 | ULI_VENDOR_ID
+/* ULi M5263 ID*/
+#define PCI_ULI5263_ID		ULI5263_DEVICE_ID << 16 | ULI_VENDOR_ID
+
+#define ULI526X_IO_SIZE	0x100
+#define TX_DESC_CNT	0x10		/* Allocated Tx descriptors */
+#define RX_DESC_CNT	PKTBUFSRX	/* Allocated Rx descriptors */
+#define TX_FREE_DESC_CNT	(TX_DESC_CNT - 2) /* Max TX packet count */
+#define TX_WAKE_DESC_CNT	(TX_DESC_CNT - 3) /* TX wakeup count */
+#define DESC_ALL_CNT		(TX_DESC_CNT + RX_DESC_CNT)
+#define TX_BUF_ALLOC		0x300
+#define RX_ALLOC_SIZE		PKTSIZE
+#define ULI526X_RESET		1
+#define CR0_DEFAULT		0
+#define CR6_DEFAULT		0x22200000
+#define CR7_DEFAULT		0x180c1
+#define CR15_DEFAULT		0x06		/* TxJabber RxWatchdog */
+#define TDES0_ERR_MASK		0x4302		/* TXJT, LC, EC, FUE */
+#define MAX_PACKET_SIZE		1514
+#define ULI5261_MAX_MULTICAST	14
+#define RX_COPY_SIZE		100
+#define MAX_CHECK_PACKET	0x8000
+
+#define ULI526X_10MHF		0
+#define ULI526X_100MHF		1
+#define ULI526X_10MFD		4
+#define ULI526X_100MFD		5
+#define ULI526X_AUTO		8
+
+#define ULI526X_TXTH_72		0x400000	/* TX TH 72 byte */
+#define ULI526X_TXTH_96		0x404000	/* TX TH 96 byte */
+#define ULI526X_TXTH_128	0x0000		/* TX TH 128 byte */
+#define ULI526X_TXTH_256	0x4000		/* TX TH 256 byte */
+#define ULI526X_TXTH_512	0x8000		/* TX TH 512 byte */
+#define ULI526X_TXTH_1K		0xC000		/* TX TH 1K  byte */
+
+/* CR9 definition: SROM/MII */
+#define CR9_SROM_READ		0x4800
+#define CR9_SRCS		0x1
+#define CR9_SRCLK		0x2
+#define CR9_CRDOUT		0x8
+#define SROM_DATA_0		0x0
+#define SROM_DATA_1		0x4
+#define PHY_DATA_1		0x20000
+#define PHY_DATA_0		0x00000
+#define MDCLKH			0x10000
+
+#define PHY_POWER_DOWN	0x800
+
+#define SROM_V41_CODE		0x14
+
+#define SROM_CLK_WRITE(data, ioaddr) do {			\
+	outl(data|CR9_SROM_READ|CR9_SRCS, ioaddr);		\
+	udelay(5);						\
+	outl(data|CR9_SROM_READ|CR9_SRCS|CR9_SRCLK, ioaddr);	\
+	udelay(5);						\
+	outl(data|CR9_SROM_READ|CR9_SRCS, ioaddr);		\
+	udelay(5);						\
+	} while (0)
+
+/* Structure/enum declaration */
+
+struct tx_desc {
+	u32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */
+	char *tx_buf_ptr;		/* Data for us */
+	struct tx_desc *next_tx_desc;
+};
+
+struct rx_desc {
+	u32 rdes0, rdes1, rdes2, rdes3;	/* Data for the card */
+	char *rx_buf_ptr;		/* Data for us */
+	struct rx_desc *next_rx_desc;
+};
+
+struct uli526x_board_info {
+	u32 chip_id;	/* Chip vendor/Device ID */
+	pci_dev_t pdev;
+
+	long ioaddr;			/* I/O base address */
+	u32 cr0_data;
+	u32 cr5_data;
+	u32 cr6_data;
+	u32 cr7_data;
+	u32 cr15_data;
+
+	/* pointer for memory physical address */
+	dma_addr_t buf_pool_dma_ptr;	/* Tx buffer pool memory */
+	dma_addr_t buf_pool_dma_start;	/* Tx buffer pool align dword */
+	dma_addr_t desc_pool_dma_ptr;	/* descriptor pool memory */
+	dma_addr_t first_tx_desc_dma;
+	dma_addr_t first_rx_desc_dma;
+
+	/* descriptor pointer */
+	unsigned char *buf_pool_ptr;	/* Tx buffer pool memory */
+	unsigned char *buf_pool_start;	/* Tx buffer pool align dword */
+	unsigned char *desc_pool_ptr;	/* descriptor pool memory */
+	struct tx_desc *first_tx_desc;
+	struct tx_desc *tx_insert_ptr;
+	struct tx_desc *tx_remove_ptr;
+	struct rx_desc *first_rx_desc;
+	struct rx_desc *rx_ready_ptr;	/* packet come pointer */
+	unsigned long tx_packet_cnt;	/* transmitted packet count */
+
+	u16 PHY_reg4;			/* Saved Phyxcer register 4 value */
+
+	u8 media_mode;			/* user specify media mode */
+	u8 op_mode;			/* real work dedia mode */
+	u8 phy_addr;
+
+	/* NIC SROM data */
+	unsigned char srom[128];
+};
+
+enum uli526x_offsets {
+	DCR0 = 0x00, DCR1 = 0x08, DCR2 = 0x10, DCR3 = 0x18, DCR4 = 0x20,
+	DCR5 = 0x28, DCR6 = 0x30, DCR7 = 0x38, DCR8 = 0x40, DCR9 = 0x48,
+	DCR10 = 0x50, DCR11 = 0x58, DCR12 = 0x60, DCR13 = 0x68, DCR14 = 0x70,
+	DCR15 = 0x78
+};
+
+enum uli526x_CR6_bits {
+	CR6_RXSC = 0x2, CR6_PBF = 0x8, CR6_PM = 0x40, CR6_PAM = 0x80,
+	CR6_FDM = 0x200, CR6_TXSC = 0x2000, CR6_STI = 0x100000,
+	CR6_SFT = 0x200000, CR6_RXA = 0x40000000, CR6_NO_PURGE = 0x20000000
+};
+
+/* Global variable declaration -- */
+
+static unsigned char uli526x_media_mode = ULI526X_AUTO;
+
+static struct tx_desc desc_pool_array[DESC_ALL_CNT + 0x20]
+	__attribute__ ((aligned(32)));
+static char buf_pool[TX_BUF_ALLOC * TX_DESC_CNT + 4];
+
+/* For module input parameter */
+static int mode = 8;
+
+/* function declaration -- */
+static int uli526x_start_xmit(struct eth_device *dev,
+				volatile void *packet, int length);
+static const struct ethtool_ops netdev_ethtool_ops;
+static u16 read_srom_word(long, int);
+static void uli526x_descriptor_init(struct uli526x_board_info *, unsigned long);
+static void allocate_rx_buffer(struct uli526x_board_info *);
+static void update_cr6(u32, unsigned long);
+static u16 phy_read(unsigned long, u8, u8, u32);
+static u16 phy_readby_cr10(unsigned long, u8, u8);
+static void phy_write(unsigned long, u8, u8, u16, u32);
+static void phy_writeby_cr10(unsigned long, u8, u8, u16);
+static void phy_write_1bit(unsigned long, u32, u32);
+static u16 phy_read_1bit(unsigned long, u32);
+static int uli526x_rx_packet(struct eth_device *);
+static void uli526x_free_tx_pkt(struct eth_device *,
+		struct uli526x_board_info *);
+static void uli526x_reuse_buf(struct rx_desc *);
+static void uli526x_init(struct eth_device *);
+static void uli526x_set_phyxcer(struct uli526x_board_info *);
+
+
+static int uli526x_init_one(struct eth_device *, bd_t *);
+static void uli526x_disable(struct eth_device *);
+static void set_mac_addr(struct eth_device *);
+
+static struct pci_device_id uli526x_pci_tbl[] = {
+	{ ULI_VENDOR_ID, ULI5261_DEVICE_ID}, /* 5261 device */
+	{ ULI_VENDOR_ID, ULI5263_DEVICE_ID}, /* 5263 device */
+	{}
+};
+
+/* ULI526X network board routine */
+
+/*
+ *	Search ULI526X board, register it
+ */
+
+int uli526x_initialize(bd_t *bis)
+{
+	pci_dev_t devno;
+	int card_number = 0;
+	struct eth_device *dev;
+	struct uli526x_board_info *db;	/* board information structure */
+
+	u32 iobase;
+	int idx = 0;
+
+	while (1) {
+		/* Find PCI device */
+		devno = pci_find_devices(uli526x_pci_tbl, idx++);
+		if (devno < 0)
+			break;
+
+		pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase);
+		iobase &= ~0xf;
+
+		dev = (struct eth_device *)malloc(sizeof *dev);
+		sprintf(dev->name, "uli526x#%d\n", card_number);
+		db = (struct uli526x_board_info *)
+			malloc(sizeof(struct uli526x_board_info));
+
+		dev->priv = db;
+		db->pdev = devno;
+		dev->iobase = iobase;
+
+		dev->init = uli526x_init_one;
+		dev->halt = uli526x_disable;
+		dev->send = uli526x_start_xmit;
+		dev->recv = uli526x_rx_packet;
+
+		/* init db */
+		db->ioaddr = dev->iobase;
+		/* get chip id */
+
+		pci_read_config_dword(devno, PCI_VENDOR_ID, &db->chip_id);
+#ifdef DEBUG
+		printf("uli526x: uli526x @0x%x\n", iobase);
+		printf("uli526x: chip_id%x\n", db->chip_id);
+#endif
+		eth_register(dev);
+		card_number++;
+		pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20);
+		udelay(10 * 1000);
+	}
+	return card_number;
+}
+
+static int uli526x_init_one(struct eth_device *dev, bd_t *bis)
+{
+
+	struct uli526x_board_info *db = dev->priv;
+	int i;
+
+	switch (mode) {
+	case ULI526X_10MHF:
+	case ULI526X_100MHF:
+	case ULI526X_10MFD:
+	case ULI526X_100MFD:
+		uli526x_media_mode = mode;
+		break;
+	default:
+		uli526x_media_mode = ULI526X_AUTO;
+		break;
+	}
+
+	/* Allocate Tx/Rx descriptor memory */
+	db->desc_pool_ptr = (uchar *)&desc_pool_array[0];
+	db->desc_pool_dma_ptr = (dma_addr_t)&desc_pool_array[0];
+	if (db->desc_pool_ptr == NULL)
+		return 0;
+
+	db->buf_pool_ptr = &buf_pool[0];
+	db->buf_pool_dma_ptr = (dma_addr_t)&buf_pool[0];
+	if (db->buf_pool_ptr == NULL)
+		return 0;
+
+	db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr;
+	db->first_tx_desc_dma = db->desc_pool_dma_ptr;
+
+	db->buf_pool_start = db->buf_pool_ptr;
+	db->buf_pool_dma_start = db->buf_pool_dma_ptr;
+
+#ifdef DEBUG
+	printf("%s(): db->ioaddr= 0x%x\n",
+		__FUNCTION__, db->ioaddr);
+	printf("%s(): media_mode= 0x%x\n",
+		__FUNCTION__, uli526x_media_mode);
+	printf("%s(): db->desc_pool_ptr= 0x%x\n",
+		__FUNCTION__, db->desc_pool_ptr);
+	printf("%s(): db->desc_pool_dma_ptr= 0x%x\n",
+		__FUNCTION__, db->desc_pool_dma_ptr);
+	printf("%s(): db->buf_pool_ptr= 0x%x\n",
+		__FUNCTION__, db->buf_pool_ptr);
+	printf("%s(): db->buf_pool_dma_ptr= 0x%x\n",
+		__FUNCTION__, db->buf_pool_dma_ptr);
+#endif
+
+	/* read 64 word srom data */
+	for (i = 0; i < 64; i++)
+		((u16 *) db->srom)[i] = cpu_to_le16(read_srom_word(db->ioaddr,
+			i));
+
+	/* Set Node address */
+	if (((u16 *) db->srom)[0] == 0xffff || ((u16 *) db->srom)[0] == 0)
+	/* SROM absent, so write MAC address to ID Table */
+		set_mac_addr(dev);
+	else {		/*Exist SROM*/
+		for (i = 0; i < 6; i++)
+			dev->enetaddr[i] = db->srom[20 + i];
+	}
+#ifdef DEBUG
+	for (i = 0; i < 6; i++)
+		printf("%c%02x", i ? ':' : ' ', dev->enetaddr[i]);
+#endif
+	db->PHY_reg4 = 0x1e0;
+
+	/* system variable init */
+	db->cr6_data = CR6_DEFAULT ;
+	db->cr6_data |= ULI526X_TXTH_256;
+	db->cr0_data = CR0_DEFAULT;
+	uli526x_init(dev);
+	return 1;
+}
+
+static void uli526x_disable(struct eth_device *dev)
+{
+#ifdef DEBUG
+	printf("uli526x_disable\n");
+#endif
+	struct uli526x_board_info *db = dev->priv;
+
+	if (!((inl(db->ioaddr + DCR12)) & 0x8)) {
+		/* Reset & stop ULI526X board */
+		outl(ULI526X_RESET, db->ioaddr + DCR0);
+		udelay(5);
+		phy_write(db->ioaddr, db->phy_addr, 0, 0x8000, db->chip_id);
+
+		/* reset the board */
+		db->cr6_data &= ~(CR6_RXSC | CR6_TXSC);	/* Disable Tx/Rx */
+		update_cr6(db->cr6_data, dev->iobase);
+		outl(0, dev->iobase + DCR7);		/* Disable Interrupt */
+		outl(inl(dev->iobase + DCR5), dev->iobase + DCR5);
+	}
+}
+
+/*	Initialize ULI526X board
+ *	Reset ULI526X board
+ *	Initialize TX/Rx descriptor chain structure
+ *	Send the set-up frame
+ *	Enable Tx/Rx machine
+ */
+
+static void uli526x_init(struct eth_device *dev)
+{
+
+	struct uli526x_board_info *db = dev->priv;
+	u8	phy_tmp;
+	u16	phy_value;
+	u16 phy_reg_reset;
+
+	/* Reset M526x MAC controller */
+	outl(ULI526X_RESET, db->ioaddr + DCR0);	/* RESET MAC */
+	udelay(100);
+	outl(db->cr0_data, db->ioaddr + DCR0);
+	udelay(5);
+
+	/* Phy addr : In some boards,M5261/M5263 phy address != 1 */
+	db->phy_addr = 1;
+	db->tx_packet_cnt = 0;
+	for (phy_tmp = 0; phy_tmp < 32; phy_tmp++) {
+		/* peer add */
+		phy_value = phy_read(db->ioaddr, phy_tmp, 3, db->chip_id);
+		if (phy_value != 0xffff && phy_value != 0) {
+			db->phy_addr = phy_tmp;
+			break;
+		}
+	}
+
+#ifdef DEBUG
+	printf("%s(): db->ioaddr= 0x%x\n", __FUNCTION__, db->ioaddr);
+	printf("%s(): db->phy_addr= 0x%x\n", __FUNCTION__, db->phy_addr);
+#endif
+	if (phy_tmp == 32)
+		printf("Can not find the phy address!!!");
+
+	/* Parser SROM and media mode */
+	db->media_mode = uli526x_media_mode;
+
+	if (!(inl(db->ioaddr + DCR12) & 0x8)) {
+		/* Phyxcer capability setting */
+		phy_reg_reset = phy_read(db->ioaddr,
+			db->phy_addr, 0, db->chip_id);
+		phy_reg_reset = (phy_reg_reset | 0x8000);
+		phy_write(db->ioaddr, db->phy_addr, 0,
+			phy_reg_reset, db->chip_id);
+		udelay(500);
+
+		/* Process Phyxcer Media Mode */
+		uli526x_set_phyxcer(db);
+	}
+	/* Media Mode Process */
+	if (!(db->media_mode & ULI526X_AUTO))
+		db->op_mode = db->media_mode; 	/* Force Mode */
+
+	/* Initialize Transmit/Receive decriptor and CR3/4 */
+	uli526x_descriptor_init(db, db->ioaddr);
+
+	/* Init CR6 to program M526X operation */
+	update_cr6(db->cr6_data, db->ioaddr);
+
+	/* Init CR7, interrupt active bit */
+	db->cr7_data = CR7_DEFAULT;
+	outl(db->cr7_data, db->ioaddr + DCR7);
+
+	/* Init CR15, Tx jabber and Rx watchdog timer */
+	outl(db->cr15_data, db->ioaddr + DCR15);
+
+	/* Enable ULI526X Tx/Rx function */
+	db->cr6_data |= CR6_RXSC | CR6_TXSC;
+	update_cr6(db->cr6_data, db->ioaddr);
+	while (!(inl(db->ioaddr + DCR12) & 0x8))
+		udelay(10);
+}
+
+/*
+ *	Hardware start transmission.
+ *	Send a packet to media from the upper layer.
+ */
+
+static int uli526x_start_xmit(struct eth_device *dev,
+				volatile void *packet, int length)
+{
+	struct uli526x_board_info *db = dev->priv;
+	struct tx_desc *txptr;
+	unsigned int len = length;
+	/* Too large packet check */
+	if (len > MAX_PACKET_SIZE) {
+		printf(": big packet = %d\n", len);
+		return 0;
+	}
+
+	/* No Tx resource check, it never happen nromally */
+	if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) {
+		printf("No Tx resource %ld\n", db->tx_packet_cnt);
+		return 0;
+	}
+
+	/* Disable NIC interrupt */
+	outl(0, dev->iobase + DCR7);
+
+	/* transmit this packet */
+	txptr = db->tx_insert_ptr;
+	memcpy((char *)txptr->tx_buf_ptr, (char *)packet, (int)length);
+	txptr->tdes1 = cpu_to_le32(0xe1000000 | length);
+
+	/* Point to next transmit free descriptor */
+	db->tx_insert_ptr = txptr->next_tx_desc;
+
+	/* Transmit Packet Process */
+	if ((db->tx_packet_cnt < TX_DESC_CNT)) {
+		txptr->tdes0 = cpu_to_le32(0x80000000);	/* Set owner bit */
+		db->tx_packet_cnt++;			/* Ready to send */
+		outl(0x1, dev->iobase + DCR1);	/* Issue Tx polling */
+	}
+
+	/* Got ULI526X status */
+	db->cr5_data = inl(db->ioaddr + DCR5);
+	outl(db->cr5_data, db->ioaddr + DCR5);
+
+#ifdef TX_DEBUG
+	printf("%s(): length = 0x%x\n", __FUNCTION__, length);
+	printf("%s(): cr5_data=%x\n", __FUNCTION__, db->cr5_data);
+#endif
+
+	outl(db->cr7_data, dev->iobase + DCR7);
+	uli526x_free_tx_pkt(dev, db);
+
+	return length;
+}
+
+/*
+ *	Free TX resource after TX complete
+ */
+
+static void uli526x_free_tx_pkt(struct eth_device *dev,
+	struct uli526x_board_info *db)
+{
+	struct tx_desc *txptr;
+	u32 tdes0;
+
+	txptr = db->tx_remove_ptr;
+	while (db->tx_packet_cnt) {
+		tdes0 = le32_to_cpu(txptr->tdes0);
+		/* printf(DRV_NAME ": tdes0=%x\n", tdes0); */
+		if (tdes0 & 0x80000000)
+			break;
+
+		/* A packet sent completed */
+		db->tx_packet_cnt--;
+
+		if (tdes0 != 0x7fffffff) {
+#ifdef TX_DEBUG
+			printf("%s()tdes0=%x\n", __FUNCTION__, tdes0);
+#endif
+			if (tdes0 & TDES0_ERR_MASK) {
+				if (tdes0 & 0x0002) {	/* UnderRun */
+					if (!(db->cr6_data & CR6_SFT)) {
+						db->cr6_data = db->cr6_data |
+							CR6_SFT;
+						update_cr6(db->cr6_data,
+							db->ioaddr);
+					}
+				}
+			}
+		}
+
+		txptr = txptr->next_tx_desc;
+	}/* End of while */
+
+	/* Update TX remove pointer to next */
+	db->tx_remove_ptr = txptr;
+}
+
+
+/*
+ *	Receive the come packet and pass to upper layer
+ */
+
+static int uli526x_rx_packet(struct eth_device *dev)
+{
+	struct uli526x_board_info *db = dev->priv;
+	struct rx_desc *rxptr;
+	int rxlen = 0;
+	u32 rdes0;
+
+	rxptr = db->rx_ready_ptr;
+
+	rdes0 = le32_to_cpu(rxptr->rdes0);
+#ifdef RX_DEBUG
+	printf("%s(): rxptr->rdes0=%x:%x\n", __FUNCTION__, rxptr->rdes0);
+#endif
+	if (!(rdes0 & 0x80000000)) {	/* packet owner check */
+		if ((rdes0 & 0x300) != 0x300) {
+			/* A packet without First/Last flag */
+			/* reuse this buf */
+			printf("A packet without First/Last flag");
+			uli526x_reuse_buf(rxptr);
+		} else {
+			/* A packet with First/Last flag */
+			rxlen = ((rdes0 >> 16) & 0x3fff) - 4;
+#ifdef RX_DEBUG
+			printf("%s(): rxlen =%x\n", __FUNCTION__, rxlen);
+#endif
+			/* error summary bit check */
+			if (rdes0 & 0x8000) {
+				/* This is a error packet */
+				printf("Eroor: rdes0: %lx\n", rdes0);
+			}
+
+			if (!(rdes0 & 0x8000) ||
+				((db->cr6_data & CR6_PM) && (rxlen > 6))) {
+
+#ifdef RX_DEBUG
+				printf("%s(): rx_skb_ptr =%x\n",
+					__FUNCTION__, rxptr->rx_buf_ptr);
+				printf("%s(): rxlen =%x\n",
+					__FUNCTION__, rxlen);
+
+				printf("%s(): buf addr =%x\n",
+					__FUNCTION__, rxptr->rx_buf_ptr);
+				printf("%s(): rxlen =%x\n",
+					__FUNCTION__, rxlen);
+				int i;
+				for (i = 0; i < 0x20; i++)
+					printf("%s(): data[%x] =%x\n",
+					__FUNCTION__, i, rxptr->rx_buf_ptr[i]);
+#endif
+
+				NetReceive(rxptr->rx_buf_ptr, rxlen);
+				uli526x_reuse_buf(rxptr);
+
+			} else {
+				/* Reuse SKB buffer when the packet is error */
+				printf("Reuse buffer, rdes0");
+				uli526x_reuse_buf(rxptr);
+			}
+		}
+
+		rxptr = rxptr->next_rx_desc;
+	}
+
+	db->rx_ready_ptr = rxptr;
+	return rxlen;
+}
+
+/*
+ *	Reuse the RX buffer
+ */
+
+static void uli526x_reuse_buf(struct rx_desc *rxptr)
+{
+
+	if (!(rxptr->rdes0 & cpu_to_le32(0x80000000)))
+		rxptr->rdes0 = cpu_to_le32(0x80000000);
+	else
+		printf("Buffer reuse method error");
+}
+/*
+ *	Initialize transmit/Receive descriptor
+ *	Using Chain structure, and allocate Tx/Rx buffer
+ */
+
+static void uli526x_descriptor_init(struct uli526x_board_info *db,
+	unsigned long ioaddr)
+{
+	struct tx_desc *tmp_tx;
+	struct rx_desc *tmp_rx;
+	unsigned char *tmp_buf;
+	dma_addr_t tmp_tx_dma, tmp_rx_dma;
+	dma_addr_t tmp_buf_dma;
+	int i;
+	/* tx descriptor start pointer */
+	db->tx_insert_ptr = db->first_tx_desc;
+	db->tx_remove_ptr = db->first_tx_desc;
+
+	outl(db->first_tx_desc_dma, ioaddr + DCR4);     /* TX DESC address */
+
+	/* rx descriptor start pointer */
+	db->first_rx_desc = (void *)db->first_tx_desc +
+		sizeof(struct tx_desc) * TX_DESC_CNT;
+	db->first_rx_desc_dma =  db->first_tx_desc_dma +
+		sizeof(struct tx_desc) * TX_DESC_CNT;
+	db->rx_ready_ptr = db->first_rx_desc;
+	outl(db->first_rx_desc_dma, ioaddr + DCR3);	/* RX DESC address */
+#ifdef DEBUG
+	printf("%s(): db->first_tx_desc= 0x%x\n",
+		__FUNCTION__, db->first_tx_desc);
+	printf("%s(): db->first_rx_desc_dma= 0x%x\n",
+		__FUNCTION__, db->first_rx_desc_dma);
+#endif
+	/* Init Transmit chain */
+	tmp_buf = db->buf_pool_start;
+	tmp_buf_dma = db->buf_pool_dma_start;
+	tmp_tx_dma = db->first_tx_desc_dma;
+	for (tmp_tx = db->first_tx_desc, i = 0;
+			i < TX_DESC_CNT; i++, tmp_tx++) {
+		tmp_tx->tx_buf_ptr = tmp_buf;
+		tmp_tx->tdes0 = cpu_to_le32(0);
+		tmp_tx->tdes1 = cpu_to_le32(0x81000000);	/* IC, chain */
+		tmp_tx->tdes2 = cpu_to_le32(tmp_buf_dma);
+		tmp_tx_dma += sizeof(struct tx_desc);
+		tmp_tx->tdes3 = cpu_to_le32(tmp_tx_dma);
+		tmp_tx->next_tx_desc = tmp_tx + 1;
+		tmp_buf = tmp_buf + TX_BUF_ALLOC;
+		tmp_buf_dma = tmp_buf_dma + TX_BUF_ALLOC;
+	}
+	(--tmp_tx)->tdes3 = cpu_to_le32(db->first_tx_desc_dma);
+	tmp_tx->next_tx_desc = db->first_tx_desc;
+
+	 /* Init Receive descriptor chain */
+	tmp_rx_dma = db->first_rx_desc_dma;
+	for (tmp_rx = db->first_rx_desc, i = 0; i < RX_DESC_CNT;
+			i++, tmp_rx++) {
+		tmp_rx->rdes0 = cpu_to_le32(0);
+		tmp_rx->rdes1 = cpu_to_le32(0x01000600);
+		tmp_rx_dma += sizeof(struct rx_desc);
+		tmp_rx->rdes3 = cpu_to_le32(tmp_rx_dma);
+		tmp_rx->next_rx_desc = tmp_rx + 1;
+	}
+	(--tmp_rx)->rdes3 = cpu_to_le32(db->first_rx_desc_dma);
+	tmp_rx->next_rx_desc = db->first_rx_desc;
+
+	/* pre-allocate Rx buffer */
+	allocate_rx_buffer(db);
+}
+
+/*
+ *	Update CR6 value
+ *	Firstly stop ULI526X, then written value and start
+ */
+
+static void update_cr6(u32 cr6_data, unsigned long ioaddr)
+{
+
+	outl(cr6_data, ioaddr + DCR6);
+	udelay(5);
+}
+
+/*
+ *	Allocate rx buffer,
+ */
+
+static void allocate_rx_buffer(struct uli526x_board_info *db)
+{
+	int index;
+	struct rx_desc *rxptr;
+	rxptr = db->first_rx_desc;
+	u32 addr;
+
+	for (index = 0; index < RX_DESC_CNT; index++) {
+		addr = (u32)NetRxPackets[index];
+		addr += (16 - (addr & 15));
+		rxptr->rx_buf_ptr = (char *) addr;
+		rxptr->rdes2 = cpu_to_le32(addr);
+		rxptr->rdes0 = cpu_to_le32(0x80000000);
+#ifdef DEBUG
+		printf("%s(): Number 0x%x:\n", __FUNCTION__, index);
+		printf("%s(): addr 0x%x:\n", __FUNCTION__, addr);
+		printf("%s(): rxptr address = 0x%x\n", __FUNCTION__, rxptr);
+		printf("%s(): rxptr buf address = 0x%x\n", \
+			__FUNCTION__, rxptr->rx_buf_ptr);
+		printf("%s(): rdes2  = 0x%x\n", __FUNCTION__, rxptr->rdes2);
+#endif
+		rxptr = rxptr->next_rx_desc;
+	}
+}
+
+/*
+ *	Read one word data from the serial ROM
+ */
+
+static u16 read_srom_word(long ioaddr, int offset)
+{
+	int i;
+	u16 srom_data = 0;
+	long cr9_ioaddr = ioaddr + DCR9;
+
+	outl(CR9_SROM_READ, cr9_ioaddr);
+	outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+
+	/* Send the Read Command 110b */
+	SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
+	SROM_CLK_WRITE(SROM_DATA_1, cr9_ioaddr);
+	SROM_CLK_WRITE(SROM_DATA_0, cr9_ioaddr);
+
+	/* Send the offset */
+	for (i = 5; i >= 0; i--) {
+		srom_data = (offset & (1 << i)) ? SROM_DATA_1 : SROM_DATA_0;
+		SROM_CLK_WRITE(srom_data, cr9_ioaddr);
+	}
+
+	outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+
+	for (i = 16; i > 0; i--) {
+		outl(CR9_SROM_READ | CR9_SRCS | CR9_SRCLK, cr9_ioaddr);
+		udelay(5);
+		srom_data = (srom_data << 1) | ((inl(cr9_ioaddr) & CR9_CRDOUT)
+			? 1 : 0);
+		outl(CR9_SROM_READ | CR9_SRCS, cr9_ioaddr);
+		udelay(5);
+	}
+
+	outl(CR9_SROM_READ, cr9_ioaddr);
+	return srom_data;
+}
+
+/*
+ *	Set 10/100 phyxcer capability
+ *	AUTO mode : phyxcer register4 is NIC capability
+ *	Force mode: phyxcer register4 is the force media
+ */
+
+static void uli526x_set_phyxcer(struct uli526x_board_info *db)
+{
+	u16 phy_reg;
+
+	/* Phyxcer capability setting */
+	phy_reg = phy_read(db->ioaddr, db->phy_addr, 4, db->chip_id) & ~0x01e0;
+
+	if (db->media_mode & ULI526X_AUTO) {
+		/* AUTO Mode */
+		phy_reg |= db->PHY_reg4;
+	} else {
+		/* Force Mode */
+		switch (db->media_mode) {
+		case ULI526X_10MHF: phy_reg |= 0x20; break;
+		case ULI526X_10MFD: phy_reg |= 0x40; break;
+		case ULI526X_100MHF: phy_reg |= 0x80; break;
+		case ULI526X_100MFD: phy_reg |= 0x100; break;
+		}
+
+	}
+
+	/* Write new capability to Phyxcer Reg4 */
+	if (!(phy_reg & 0x01e0)) {
+		phy_reg |= db->PHY_reg4;
+		db->media_mode |= ULI526X_AUTO;
+	}
+	phy_write(db->ioaddr, db->phy_addr, 4, phy_reg, db->chip_id);
+
+	/* Restart Auto-Negotiation */
+	phy_write(db->ioaddr, db->phy_addr, 0, 0x1200, db->chip_id);
+	udelay(50);
+}
+
+/*
+ *	Write a word to Phy register
+ */
+
+static void phy_write(unsigned long iobase, u8 phy_addr, u8 offset,
+	u16 phy_data, u32 chip_id)
+{
+	u16 i;
+	unsigned long ioaddr;
+
+	if (chip_id == PCI_ULI5263_ID) {
+		phy_writeby_cr10(iobase, phy_addr, offset, phy_data);
+		return;
+	}
+	/* M5261/M5263 Chip */
+	ioaddr = iobase + DCR9;
+
+	/* Send 33 synchronization clock to Phy controller */
+	for (i = 0; i < 35; i++)
+		phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+	/* Send start command(01) to Phy */
+	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+	/* Send write command(01) to Phy */
+	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+	/* Send Phy address */
+	for (i = 0x10; i > 0; i = i >> 1)
+		phy_write_1bit(ioaddr, phy_addr & i ?
+			PHY_DATA_1 : PHY_DATA_0, chip_id);
+
+	/* Send register address */
+	for (i = 0x10; i > 0; i = i >> 1)
+		phy_write_1bit(ioaddr, offset & i ?
+			PHY_DATA_1 : PHY_DATA_0, chip_id);
+
+	/* written trasnition */
+	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+
+	/* Write a word data to PHY controller */
+	for (i = 0x8000; i > 0; i >>= 1)
+		phy_write_1bit(ioaddr, phy_data & i ?
+			PHY_DATA_1 : PHY_DATA_0, chip_id);
+}
+
+/*
+ *	Read a word data from phy register
+ */
+
+static u16 phy_read(unsigned long iobase, u8 phy_addr, u8 offset, u32 chip_id)
+{
+	int i;
+	u16 phy_data;
+	unsigned long ioaddr;
+
+	if (chip_id == PCI_ULI5263_ID)
+		return phy_readby_cr10(iobase, phy_addr, offset);
+	/* M5261/M5263 Chip */
+	ioaddr = iobase + DCR9;
+
+	/* Send 33 synchronization clock to Phy controller */
+	for (i = 0; i < 35; i++)
+		phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+	/* Send start command(01) to Phy */
+	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+
+	/* Send read command(10) to Phy */
+	phy_write_1bit(ioaddr, PHY_DATA_1, chip_id);
+	phy_write_1bit(ioaddr, PHY_DATA_0, chip_id);
+
+	/* Send Phy address */
+	for (i = 0x10; i > 0; i = i >> 1)
+		phy_write_1bit(ioaddr, phy_addr & i ?
+			PHY_DATA_1 : PHY_DATA_0, chip_id);
+
+	/* Send register address */
+	for (i = 0x10; i > 0; i = i >> 1)
+		phy_write_1bit(ioaddr, offset & i ?
+			PHY_DATA_1 : PHY_DATA_0, chip_id);
+
+	/* Skip transition state */
+	phy_read_1bit(ioaddr, chip_id);
+
+	/* read 16bit data */
+	for (phy_data = 0, i = 0; i < 16; i++) {
+		phy_data <<= 1;
+		phy_data |= phy_read_1bit(ioaddr, chip_id);
+	}
+
+	return phy_data;
+}
+
+static u16 phy_readby_cr10(unsigned long iobase, u8 phy_addr, u8 offset)
+{
+	unsigned long ioaddr, cr10_value;
+
+	ioaddr = iobase + DCR10;
+	cr10_value = phy_addr;
+	cr10_value = (cr10_value<<5) + offset;
+	cr10_value = (cr10_value<<16) + 0x08000000;
+	outl(cr10_value, ioaddr);
+	udelay(1);
+	while (1) {
+		cr10_value = inl(ioaddr);
+		if (cr10_value & 0x10000000)
+			break;
+	}
+	return (cr10_value&0x0ffff);
+}
+
+static void phy_writeby_cr10(unsigned long iobase, u8 phy_addr,
+	u8 offset, u16 phy_data)
+{
+	unsigned long ioaddr, cr10_value;
+
+	ioaddr = iobase + DCR10;
+	cr10_value = phy_addr;
+	cr10_value = (cr10_value<<5) + offset;
+	cr10_value = (cr10_value<<16) + 0x04000000 + phy_data;
+	outl(cr10_value, ioaddr);
+	udelay(1);
+}
+/*
+ *	Write one bit data to Phy Controller
+ */
+
+static void phy_write_1bit(unsigned long ioaddr, u32 phy_data, u32 chip_id)
+{
+	outl(phy_data , ioaddr);			/* MII Clock Low */
+	udelay(1);
+	outl(phy_data  | MDCLKH, ioaddr);	/* MII Clock High */
+	udelay(1);
+	outl(phy_data , ioaddr);			/* MII Clock Low */
+	udelay(1);
+}
+
+/*
+ *	Read one bit phy data from PHY controller
+ */
+
+static u16 phy_read_1bit(unsigned long ioaddr, u32 chip_id)
+{
+	u16 phy_data;
+
+	outl(0x50000 , ioaddr);
+	udelay(1);
+	phy_data = (inl(ioaddr) >> 19) & 0x1;
+	outl(0x40000 , ioaddr);
+	udelay(1);
+
+	return phy_data;
+}
+
+/*
+ * Set MAC address to ID Table
+ */
+
+static void set_mac_addr(struct eth_device *dev)
+{
+	int i;
+	u16 addr;
+	struct uli526x_board_info *db = dev->priv;
+	outl(0x10000, db->ioaddr + DCR0);	/* Diagnosis mode */
+	/* Reset dianostic pointer port */
+	outl(0x1c0, db->ioaddr + DCR13);
+	outl(0, db->ioaddr + DCR14);	/* Clear reset port */
+	outl(0x10, db->ioaddr + DCR14);	/* Reset ID Table pointer */
+	outl(0, db->ioaddr + DCR14);	/* Clear reset port */
+	outl(0, db->ioaddr + DCR13);	/* Clear CR13 */
+	/* Select ID Table access port */
+	outl(0x1b0, db->ioaddr + DCR13);
+	/* Read MAC address from CR14 */
+	for (i = 0; i < 3; i++) {
+		addr = dev->enetaddr[2 * i] | (dev->enetaddr[2 * i + 1] << 8);
+		outl(addr, db->ioaddr + DCR14);
+	}
+	/* write end */
+	outl(0, db->ioaddr + DCR13);	/* Clear CR13 */
+	outl(0, db->ioaddr + DCR0);	/* Clear CR0 */
+	udelay(10);
+	return;
+}
+#endif
diff --git a/drivers/nand/Makefile b/drivers/pci/Makefile
similarity index 85%
copy from drivers/nand/Makefile
copy to drivers/pci/Makefile
index fb0185b..fe45839 100644
--- a/drivers/nand/Makefile
+++ b/drivers/pci/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2006
+# (C) Copyright 2000-2007
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,10 +23,16 @@
 
 include $(TOPDIR)/config.mk
 
-LIB 	:= $(obj)libnand.a
+LIB 	:= $(obj)libpci.a
 
-COBJS 	:= nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
+COBJS-y += fsl_pci_init.o
+COBJS-y += pci.o
+COBJS-y += pci_auto.o
+COBJS-y += pci_indirect.o
+COBJS-y += tsi108_pci.o
+COBJS-y += w83c553f.o
 
+COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
 OBJS 	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c
similarity index 100%
rename from drivers/fsl_pci_init.c
rename to drivers/pci/fsl_pci_init.c
diff --git a/drivers/pci.c b/drivers/pci/pci.c
similarity index 100%
rename from drivers/pci.c
rename to drivers/pci/pci.c
diff --git a/drivers/pci_auto.c b/drivers/pci/pci_auto.c
similarity index 100%
rename from drivers/pci_auto.c
rename to drivers/pci/pci_auto.c
diff --git a/drivers/pci_indirect.c b/drivers/pci/pci_indirect.c
similarity index 100%
rename from drivers/pci_indirect.c
rename to drivers/pci/pci_indirect.c
diff --git a/drivers/tsi108_pci.c b/drivers/pci/tsi108_pci.c
similarity index 98%
rename from drivers/tsi108_pci.c
rename to drivers/pci/tsi108_pci.c
index 9f606df..d5f11e4 100644
--- a/drivers/tsi108_pci.c
+++ b/drivers/pci/tsi108_pci.c
@@ -33,6 +33,9 @@
 #include <pci.h>
 #include <asm/io.h>
 #include <tsi108.h>
+#ifdef CONFIG_OF_FLAT_TREE
+#include <ft_build.h>
+#endif
 
 struct pci_controller local_hose;
 
diff --git a/drivers/w83c553f.c b/drivers/pci/w83c553f.c
similarity index 100%
rename from drivers/w83c553f.c
rename to drivers/pci/w83c553f.c
diff --git a/drivers/nand/Makefile b/drivers/pcmcia/Makefile
similarity index 85%
copy from drivers/nand/Makefile
copy to drivers/pcmcia/Makefile
index fb0185b..55528c8 100644
--- a/drivers/nand/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2006
+# (C) Copyright 2000-2007
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,10 +23,15 @@
 
 include $(TOPDIR)/config.mk
 
-LIB 	:= $(obj)libnand.a
+LIB 	:= $(obj)libpcmcia.a
 
-COBJS 	:= nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
+COBJS-y += mpc8xx_pcmcia.o
+COBJS-y += pxa_pcmcia.o
+COBJS-y += rpx_pcmcia.o
+COBJS-y += ti_pci1410a.o
+COBJS-y += tqm8xx_pcmcia.o
 
+COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
 OBJS 	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/i82365.c b/drivers/pcmcia/i82365.c
similarity index 100%
rename from drivers/i82365.c
rename to drivers/pcmcia/i82365.c
diff --git a/drivers/mpc8xx_pcmcia.c b/drivers/pcmcia/mpc8xx_pcmcia.c
similarity index 100%
rename from drivers/mpc8xx_pcmcia.c
rename to drivers/pcmcia/mpc8xx_pcmcia.c
diff --git a/drivers/pxa_pcmcia.c b/drivers/pcmcia/pxa_pcmcia.c
similarity index 100%
rename from drivers/pxa_pcmcia.c
rename to drivers/pcmcia/pxa_pcmcia.c
diff --git a/drivers/rpx_pcmcia.c b/drivers/pcmcia/rpx_pcmcia.c
similarity index 100%
rename from drivers/rpx_pcmcia.c
rename to drivers/pcmcia/rpx_pcmcia.c
diff --git a/drivers/ti_pci1410a.c b/drivers/pcmcia/ti_pci1410a.c
similarity index 100%
rename from drivers/ti_pci1410a.c
rename to drivers/pcmcia/ti_pci1410a.c
diff --git a/drivers/tqm8xx_pcmcia.c b/drivers/pcmcia/tqm8xx_pcmcia.c
similarity index 100%
rename from drivers/tqm8xx_pcmcia.c
rename to drivers/pcmcia/tqm8xx_pcmcia.c
diff --git a/drivers/nand/Makefile b/drivers/rtc/Makefile
similarity index 61%
copy from drivers/nand/Makefile
copy to drivers/rtc/Makefile
index fb0185b..1d6016e 100644
--- a/drivers/nand/Makefile
+++ b/drivers/rtc/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2006
+# (C) Copyright 2001-2006
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -12,7 +12,7 @@
 #
 # 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
+# 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
@@ -23,12 +23,38 @@
 
 include $(TOPDIR)/config.mk
 
-LIB 	:= $(obj)libnand.a
+#CFLAGS += -DDEBUG
 
-COBJS 	:= nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
+LIB	= $(obj)librtc.a
+
+COBJS-y += date.o
+COBJS-y += bf5xx_rtc.o
+COBJS-y += ds12887.o
+COBJS-y += ds1302.o
+COBJS-y += ds1306.o
+COBJS-y += ds1307.o
+COBJS-y += ds1337.o
+COBJS-y += ds1374.o
+COBJS-y += ds1556.o
+COBJS-y += ds164x.o
+COBJS-y += ds174x.o
+COBJS-y += ds3231.o
+COBJS-y += m41t11.o
+COBJS-y += max6900.o
+COBJS-y += m48t35ax.o
+COBJS-y += mc146818.o
+COBJS-y += mk48t59.o
+COBJS-y += mpc5xxx.o
+COBJS-y += mpc8xx.o
+COBJS-y += pcf8563.o
+COBJS-y += s3c24x0_rtc.o
+COBJS-y += rs5c372.o
+COBJS-y += mcfrtc.o
+COBJS-y += x1205.o
 
-SRCS 	:= $(COBJS:.o=.c)
-OBJS 	:= $(addprefix $(obj),$(COBJS))
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
 
 all:	$(LIB)
 
diff --git a/drivers/rtc/bf5xx_rtc.c b/drivers/rtc/bf5xx_rtc.c
new file mode 100644
index 0000000..8856bb9
--- /dev/null
+++ b/drivers/rtc/bf5xx_rtc.c
@@ -0,0 +1,143 @@
+/*
+ * (C) Copyright 2001
+ * 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
+ * Real Time Clock interface of ADI21535 (Blackfin) for uCLinux
+ *
+ * Copyright (C) 2003 Motorola Corporation.  All rights reserved.
+ * 				Richard Xiao (A2590C@email.mot.com)
+ *
+ * Copyright (C) 1996 Paul Gortmaker
+ *
+ *
+ *	Based on other minimal char device drivers, like Alan's
+ *	watchdog, Ted's random, etc. etc.
+ *
+ *	1.07	Paul Gortmaker.
+ *	1.08	Miquel van Smoorenburg: disallow certain things on the
+ *		DEC Alpha as the CMOS clock is also used for other things.
+ *	1.09	Nikita Schmidt: epoch support and some Alpha cleanup.
+ *	1.09a	Pete Zaitcev: Sun SPARC
+ *	1.09b	Jeff Garzik: Modularize, init cleanup
+ *	1.09c	Jeff Garzik: SMP cleanup
+ *	1.10    Paul Barton-Davis: add support for async I/O
+ *	1.10a	Andrea Arcangeli: Alpha updates
+ *	1.10b	Andrew Morton: SMP lock fix
+ *	1.10c	Cesar Barros: SMP locking fixes and cleanup
+ *	1.10d	Paul Gortmaker: delete paranoia check in rtc_exit
+ *	1.10e   LG Soft India: Register access is different in BF533.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_BFIN) && defined(CONFIG_CMD_DATE)
+
+#include <asm/blackfin.h>
+#include <asm/arch/bf5xx_rtc.h>
+
+void rtc_reset(void)
+{
+	return;			/* nothing to do */
+}
+
+/* Wait for pending writes to complete */
+void wait_for_complete(void)
+{
+	while (!(*(volatile unsigned short *)RTC_ISTAT & 0x8000)) {
+		printf("");
+	}
+	*(volatile unsigned short *)RTC_ISTAT = 0x8000;
+}
+
+/* Enable the RTC prescaler enable register */
+void rtc_init()
+{
+	*(volatile unsigned short *)RTC_PREN = 0x1;
+	wait_for_complete();
+}
+
+/* Set the time. Get the time_in_secs which is the number of seconds since Jan 1970 and set the RTC registers
+ * based on this value.
+ */
+void rtc_set(struct rtc_time *tmp)
+{
+	unsigned long n_days_1970 = 0;
+	unsigned long n_secs_rem = 0;
+	unsigned long n_hrs = 0;
+	unsigned long n_mins = 0;
+	unsigned long n_secs = 0;
+	unsigned long time_in_secs;
+
+	if (tmp == NULL) {
+		printf("Error setting the date/time \n");
+		return;
+	}
+
+	time_in_secs =
+	    mktime(tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_hour,
+		   tmp->tm_min, tmp->tm_sec);
+
+	/* Compute no. of days since 1970 */
+	n_days_1970 = (unsigned long)(time_in_secs / (NUM_SECS_IN_DAY));
+
+	/* From the remining secs, compute the hrs(0-23), mins(0-59) and secs(0-59) */
+	n_secs_rem = (unsigned long)(time_in_secs % (NUM_SECS_IN_DAY));
+	n_hrs = n_secs_rem / (NUM_SECS_IN_HOUR);
+	n_secs_rem = n_secs_rem % (NUM_SECS_IN_HOUR);
+	n_mins = n_secs_rem / (NUM_SECS_IN_MIN);
+	n_secs = n_secs_rem % (NUM_SECS_IN_MIN);
+
+	/* Store the new time in the RTC_STAT register */
+	*(volatile unsigned long *)RTC_STAT =
+	    ((n_days_1970 << DAY_BITS_OFF) | (n_hrs << HOUR_BITS_OFF) |
+	     (n_mins << MIN_BITS_OFF) | (n_secs << SEC_BITS_OFF));
+
+	wait_for_complete();
+}
+
+/* Read the time from the RTC_STAT. time_in_seconds is seconds since Jan 1970 */
+void rtc_get(struct rtc_time *tmp)
+{
+	unsigned long cur_rtc_stat = 0;
+	unsigned long time_in_sec;
+	unsigned long tm_sec = 0, tm_min = 0, tm_hour = 0, tm_day = 0;
+
+	if (tmp == NULL) {
+		printf("Error getting the date/time \n");
+		return;
+	}
+
+	/* Read the RTC_STAT register */
+	cur_rtc_stat = *(volatile unsigned long *)RTC_STAT;
+
+	/* Get the secs (0-59), mins (0-59), hrs (0-23) and the days since Jan 1970 */
+	tm_sec = (cur_rtc_stat >> SEC_BITS_OFF) & 0x3f;
+	tm_min = (cur_rtc_stat >> MIN_BITS_OFF) & 0x3f;
+	tm_hour = (cur_rtc_stat >> HOUR_BITS_OFF) & 0x1f;
+	tm_day = (cur_rtc_stat >> DAY_BITS_OFF) & 0x7fff;
+
+	/* Calculate the total number of seconds since Jan 1970 */
+	time_in_sec = (tm_sec) +
+	    MIN_TO_SECS(tm_min) + HRS_TO_SECS(tm_hour) + DAYS_TO_SECS(tm_day);
+	to_tm(time_in_sec, tmp);
+}
+#endif
diff --git a/drivers/rtc/date.c b/drivers/rtc/date.c
new file mode 100644
index 0000000..a83a723
--- /dev/null
+++ b/drivers/rtc/date.c
@@ -0,0 +1,156 @@
+/*
+ * (C) Copyright 2001
+ * 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
+ */
+
+/*
+ * Date & Time support for Philips PCF8563 RTC
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_CMD_DATE) || defined(CONFIG_TIMESTAMP)
+
+#define FEBRUARY		2
+#define	STARTOFTIME		1970
+#define SECDAY			86400L
+#define SECYR			(SECDAY * 365)
+#define	leapyear(year)		((year) % 4 == 0)
+#define	days_in_year(a) 	(leapyear(a) ? 366 : 365)
+#define	days_in_month(a) 	(month_days[(a) - 1])
+
+static int month_days[12] = {
+	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+
+/*
+ * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
+ */
+void GregorianDay(struct rtc_time * tm)
+{
+	int leapsToDate;
+	int lastYear;
+	int day;
+	int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
+
+	lastYear=tm->tm_year-1;
+
+	/*
+	 * Number of leap corrections to apply up to end of last year
+	 */
+	leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
+
+	/*
+	 * This year is a leap year if it is divisible by 4 except when it is
+	 * divisible by 100 unless it is divisible by 400
+	 *
+	 * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
+	 */
+	if((tm->tm_year%4==0) &&
+	   ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
+	   (tm->tm_mon>2)) {
+		/*
+		 * We are past Feb. 29 in a leap year
+		 */
+		day=1;
+	} else {
+		day=0;
+	}
+
+	day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday;
+
+	tm->tm_wday=day%7;
+}
+
+void to_tm(int tim, struct rtc_time * tm)
+{
+	register int    i;
+	register long   hms, day;
+
+	day = tim / SECDAY;
+	hms = tim % SECDAY;
+
+	/* Hours, minutes, seconds are easy */
+	tm->tm_hour = hms / 3600;
+	tm->tm_min = (hms % 3600) / 60;
+	tm->tm_sec = (hms % 3600) % 60;
+
+	/* Number of years in days */
+	for (i = STARTOFTIME; day >= days_in_year(i); i++) {
+		day -= days_in_year(i);
+	}
+	tm->tm_year = i;
+
+	/* Number of months in days left */
+	if (leapyear(tm->tm_year)) {
+		days_in_month(FEBRUARY) = 29;
+	}
+	for (i = 1; day >= days_in_month(i); i++) {
+		day -= days_in_month(i);
+	}
+	days_in_month(FEBRUARY) = 28;
+	tm->tm_mon = i;
+
+	/* Days are what is left over (+1) from all that. */
+	tm->tm_mday = day + 1;
+
+	/*
+	 * Determine the day of week
+	 */
+	GregorianDay(tm);
+}
+
+/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+ *
+ * [For the Julian calendar (which was used in Russia before 1917,
+ * Britain & colonies before 1752, anywhere else before 1582,
+ * and is still in use by some communities) leave out the
+ * -year/100+year/400 terms, and add 10.]
+ *
+ * This algorithm was first published by Gauss (I think).
+ *
+ * WARNING: this function will overflow on 2106-02-07 06:28:16 on
+ * machines were long is 32-bit! (However, as time_t is signed, we
+ * will already get problems at other places on 2038-01-19 03:14:08)
+ */
+unsigned long
+mktime (unsigned int year, unsigned int mon,
+	unsigned int day, unsigned int hour,
+	unsigned int min, unsigned int sec)
+{
+	if (0 >= (int) (mon -= 2)) {	/* 1..12 -> 11,12,1..10 */
+		mon += 12;		/* Puts Feb last since it has leap day */
+		year -= 1;
+	}
+
+	return (((
+		(unsigned long) (year/4 - year/100 + year/400 + 367*mon/12 + day) +
+			year*365 - 719499
+	    )*24 + hour /* now have hours */
+	  )*60 + min /* now have minutes */
+	)*60 + sec; /* finally seconds */
+}
+
+#endif
diff --git a/drivers/rtc/ds12887.c b/drivers/rtc/ds12887.c
new file mode 100644
index 0000000..84fecf0
--- /dev/null
+++ b/drivers/rtc/ds12887.c
@@ -0,0 +1,238 @@
+/*
+ * (C) Copyright 2003
+ *
+ * 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
+ */
+
+/*
+ * Date & Time support for the DS12887 RTC
+ */
+
+#undef	RTC_DEBUG
+
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_DS12887) && defined(CONFIG_CMD_DATE)
+
+#define RTC_SECONDS			0x00
+#define RTC_SECONDS_ALARM		0x01
+#define RTC_MINUTES			0x02
+#define RTC_MINUTES_ALARM		0x03
+#define RTC_HOURS			0x04
+#define RTC_HOURS_ALARM 		0x05
+#define RTC_DAY_OF_WEEK 		0x06
+#define RTC_DATE_OF_MONTH		0x07
+#define RTC_MONTH			0x08
+#define RTC_YEAR			0x09
+#define RTC_CONTROL_A 			0x0A
+#define RTC_CONTROL_B 			0x0B
+#define RTC_CONTROL_C 			0x0C
+#define RTC_CONTROL_D			0x0D
+
+#define RTC_CA_UIP			0x80
+#define RTC_CB_DM			0x04
+#define RTC_CB_24_12			0x02
+#define RTC_CB_SET			0x80
+
+#if defined(CONFIG_ATC)
+
+static uchar rtc_read (uchar reg)
+{
+	uchar val;
+
+	*(volatile unsigned char*)(RTC_PORT_ADDR) = reg;
+	__asm__ __volatile__ ("sync");
+
+	val = *(volatile unsigned char*)(RTC_PORT_DATA);
+	return (val);
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+	*(volatile unsigned char*)(RTC_PORT_ADDR) = reg;
+	__asm__ __volatile__ ("sync");
+
+	*(volatile unsigned char*)(RTC_PORT_DATA) = val;
+	__asm__ __volatile__ ("sync");
+}
+
+#else
+# error Board specific rtc access functions should be supplied
+#endif
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+	uchar sec, min, hour, mday, wday, mon, year;
+
+	/* check if rtc is available for access */
+	while( rtc_read(RTC_CONTROL_A) & RTC_CA_UIP)
+		;
+
+	sec  = rtc_read(RTC_SECONDS);
+	min  = rtc_read(RTC_MINUTES);
+	hour = rtc_read(RTC_HOURS);
+	mday = rtc_read(RTC_DATE_OF_MONTH);
+	wday = rtc_read(RTC_DAY_OF_WEEK);
+	mon  = rtc_read(RTC_MONTH);
+	year = rtc_read(RTC_YEAR);
+
+#ifdef RTC_DEBUG
+	printf( "Get RTC year: %d; mon: %d; mday: %d; wday: %d; "
+		"hr: %d; min: %d; sec: %d\n",
+		year, mon, mday, wday, hour, min, sec );
+
+	printf ( "Alarms: hour: %02x min: %02x sec: %02x\n",
+		 rtc_read (RTC_HOURS_ALARM),
+		 rtc_read (RTC_MINUTES_ALARM),
+		 rtc_read (RTC_SECONDS_ALARM) );
+#endif
+
+	if( !(rtc_read(RTC_CONTROL_B) & RTC_CB_DM))
+	{	    /* Information is in BCD format */
+printf(" Get: Convert BSD to BIN\n");
+		tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+		tmp->tm_min  = bcd2bin (min  & 0x7F);
+		tmp->tm_hour = bcd2bin (hour & 0x3F);
+		tmp->tm_mday = bcd2bin (mday & 0x3F);
+		tmp->tm_mon  = bcd2bin (mon & 0x1F);
+		tmp->tm_year = bcd2bin (year);
+		tmp->tm_wday = bcd2bin (wday & 0x07);
+	}
+else
+	{
+		tmp->tm_sec  = sec  & 0x7F;
+		tmp->tm_min  = min  & 0x7F;
+		tmp->tm_hour = hour & 0x3F;
+		tmp->tm_mday = mday & 0x3F;
+		tmp->tm_mon  = mon & 0x1F;
+		tmp->tm_year = year;
+		tmp->tm_wday = wday & 0x07;
+	}
+
+
+	if(tmp->tm_year<70)
+		tmp->tm_year+=2000;
+	else
+		tmp->tm_year+=1900;
+
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+	printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+	uchar save_ctrl_b;
+	uchar sec, min, hour, mday, wday, mon, year;
+
+#ifdef RTC_DEBUG
+	printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+
+	if( !(rtc_read(RTC_CONTROL_B) & RTC_CB_DM))
+	{	    /* Information is in BCD format */
+		year = bin2bcd(tmp->tm_year % 100);
+		mon  = bin2bcd(tmp->tm_mon);
+		wday = bin2bcd(tmp->tm_wday);
+		mday = bin2bcd(tmp->tm_mday);
+		hour = bin2bcd(tmp->tm_hour);
+		min  = bin2bcd(tmp->tm_min);
+		sec  = bin2bcd(tmp->tm_sec);
+	}
+	else
+	{
+		year = tmp->tm_year % 100;
+		mon  = tmp->tm_mon;
+		wday = tmp->tm_wday;
+		mday = tmp->tm_mday;
+		hour = tmp->tm_hour;
+		min  = tmp->tm_min;
+		sec  = tmp->tm_sec;
+	}
+
+	/* disables the RTC to update the regs */
+	save_ctrl_b = rtc_read(RTC_CONTROL_B);
+	save_ctrl_b |= RTC_CB_SET;
+	rtc_write(RTC_CONTROL_B, save_ctrl_b);
+
+	rtc_write (RTC_YEAR, year);
+	rtc_write (RTC_MONTH, mon);
+	rtc_write (RTC_DAY_OF_WEEK, wday);
+	rtc_write (RTC_DATE_OF_MONTH, mday);
+	rtc_write (RTC_HOURS, hour);
+	rtc_write (RTC_MINUTES, min);
+	rtc_write (RTC_SECONDS, sec);
+
+	/* enables the RTC to update the regs */
+	save_ctrl_b &= ~RTC_CB_SET;
+	rtc_write(RTC_CONTROL_B, save_ctrl_b);
+}
+
+void rtc_reset (void)
+{
+	struct rtc_time tmp;
+	uchar ctrl_rg;
+
+	ctrl_rg = RTC_CB_SET;
+	rtc_write(RTC_CONTROL_B,ctrl_rg);
+
+	tmp.tm_year = 1970 % 100;
+	tmp.tm_mon = 1;
+	tmp.tm_mday= 1;
+	tmp.tm_hour = 0;
+	tmp.tm_min = 0;
+	tmp.tm_sec = 0;
+
+#ifdef RTC_DEBUG
+	printf ( "RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
+		    tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+		    tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+#endif
+
+	ctrl_rg = RTC_CB_SET | RTC_CB_24_12 | RTC_CB_DM;
+	rtc_write(RTC_CONTROL_B,ctrl_rg);
+	rtc_set(&tmp);
+
+	rtc_write(RTC_HOURS_ALARM, 0),
+	rtc_write(RTC_MINUTES_ALARM, 0),
+	rtc_write(RTC_SECONDS_ALARM, 0);
+
+	ctrl_rg = RTC_CB_24_12 | RTC_CB_DM;
+	rtc_write(RTC_CONTROL_B,ctrl_rg);
+}
+
+#endif
diff --git a/drivers/rtc/ds1302.c b/drivers/rtc/ds1302.c
new file mode 100644
index 0000000..55af130
--- /dev/null
+++ b/drivers/rtc/ds1302.c
@@ -0,0 +1,327 @@
+/*
+ * ds1302.c - Support for the Dallas Semiconductor DS1302 Timekeeping Chip
+ *
+ * Rex G. Feany <rfeany@zumanetworks.com>
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_DS1302) && defined(CONFIG_CMD_DATE)
+
+/* GPP Pins */
+#define DATA		0x200
+#define SCLK		0x400
+#define RST		0x800
+
+/* Happy Fun Defines(tm) */
+#define RESET		rtc_go_low(RST), rtc_go_low(SCLK)
+#define N_RESET		rtc_go_high(RST), rtc_go_low(SCLK)
+
+#define CLOCK_HIGH	rtc_go_high(SCLK)
+#define CLOCK_LOW	rtc_go_low(SCLK)
+
+#define DATA_HIGH	rtc_go_high(DATA)
+#define DATA_LOW	rtc_go_low(DATA)
+#define DATA_READ	(GTREGREAD(GPP_VALUE) & DATA)
+
+#undef RTC_DEBUG
+
+#ifdef RTC_DEBUG
+#  define DPRINTF(x,args...)	printf("ds1302: " x , ##args)
+static inline void DUMP(const char *ptr, int num)
+{
+	while (num--) printf("%x ", *ptr++);
+	printf("]\n");
+}
+#else
+#  define DPRINTF(x,args...)
+#  define DUMP(ptr, num)
+#endif
+
+/* time data format for DS1302 */
+struct ds1302_st
+{
+	unsigned char CH:1;		/* clock halt 1=stop 0=start */
+	unsigned char sec10:3;
+	unsigned char sec:4;
+
+	unsigned char zero0:1;
+	unsigned char min10:3;
+	unsigned char min:4;
+
+	unsigned char fmt:1;		/* 1=12 hour 0=24 hour */
+	unsigned char zero1:1;
+	unsigned char hr10:2;	/* 10 (0-2) or am/pm (am/pm, 0-1) */
+	unsigned char hr:4;
+
+	unsigned char zero2:2;
+	unsigned char date10:2;
+	unsigned char date:4;
+
+	unsigned char zero3:3;
+	unsigned char month10:1;
+	unsigned char month:4;
+
+	unsigned char zero4:5;
+	unsigned char day:3; 		/* day of week */
+
+	unsigned char year10:4;
+	unsigned char year:4;
+
+	unsigned char WP:1;		/* write protect 1=protect 0=unprot */
+	unsigned char zero5:7;
+};
+
+static int ds1302_initted=0;
+
+/* Pin control */
+static inline void
+rtc_go_high(unsigned int mask)
+{
+	unsigned int f = GTREGREAD(GPP_VALUE) | mask;
+
+	GT_REG_WRITE(GPP_VALUE, f);
+}
+
+static inline void
+rtc_go_low(unsigned int mask)
+{
+	unsigned int f = GTREGREAD(GPP_VALUE) & ~mask;
+
+	GT_REG_WRITE(GPP_VALUE, f);
+}
+
+static inline void
+rtc_go_input(unsigned int mask)
+{
+	unsigned int f = GTREGREAD(GPP_IO_CONTROL) & ~mask;
+
+	GT_REG_WRITE(GPP_IO_CONTROL, f);
+}
+
+static inline void
+rtc_go_output(unsigned int mask)
+{
+	unsigned int f = GTREGREAD(GPP_IO_CONTROL) | mask;
+
+	GT_REG_WRITE(GPP_IO_CONTROL, f);
+}
+
+/* Access data in RTC */
+
+static void
+write_byte(unsigned char b)
+{
+	int i;
+	unsigned char mask=1;
+
+	for(i=0;i<8;i++) {
+		CLOCK_LOW;			/* Lower clock */
+		(b&mask)?DATA_HIGH:DATA_LOW;	/* set data */
+		udelay(1);
+		CLOCK_HIGH;		/* latch data with rising clock */
+		udelay(1);
+		mask=mask<<1;
+	}
+}
+
+static unsigned char
+read_byte(void)
+{
+	int i;
+	unsigned char mask=1;
+	unsigned char b=0;
+
+	for(i=0;i<8;i++) {
+		CLOCK_LOW;
+		udelay(1);
+		if (DATA_READ) b|=mask;	/* if this bit is high, set in b */
+		CLOCK_HIGH;		/* clock out next bit */
+		udelay(1);
+		mask=mask<<1;
+	}
+	return b;
+}
+
+static void
+read_ser_drv(unsigned char addr, unsigned char *buf, int count)
+{
+	int i;
+#ifdef RTC_DEBUG
+	char *foo = buf;
+#endif
+
+	DPRINTF("READ 0x%x bytes @ 0x%x [ ", count, addr);
+
+	addr|=1;	/* READ */
+	N_RESET;
+	udelay(4);
+	write_byte(addr);
+	rtc_go_input(DATA); /* Put gpp pin into input mode */
+	udelay(1);
+	for(i=0;i<count;i++) *(buf++)=read_byte();
+	RESET;
+	rtc_go_output(DATA);/* Reset gpp for output */
+	udelay(4);
+
+	DUMP(foo, count);
+}
+
+static void
+write_ser_drv(unsigned char addr, unsigned char *buf, int count)
+{
+	int i;
+
+	DPRINTF("WRITE 0x%x bytes @ 0x%x [ ", count, addr);
+	DUMP(buf, count);
+
+	addr&=~1;	/* WRITE */
+	N_RESET;
+	udelay(4);
+	write_byte(addr);
+	for(i=0;i<count;i++) write_byte(*(buf++));
+	RESET;
+	udelay(4);
+
+}
+
+void
+rtc_init(void)
+{
+    	struct ds1302_st bbclk;
+	unsigned char b;
+	int mod;
+
+	DPRINTF("init\n");
+
+	rtc_go_output(DATA|SCLK|RST);
+
+	/* disable write protect */
+	b = 0;
+	write_ser_drv(0x8e,&b,1);
+
+	/* enable trickle */
+	b = 0xa5;	/* 1010.0101 */
+	write_ser_drv(0x90,&b,1);
+
+	/* read burst */
+	read_ser_drv(0xbe, (unsigned char *)&bbclk, 8);
+
+	/* Sanity checks */
+	mod = 0;
+	if (bbclk.CH) {
+		printf("ds1302: Clock was halted, starting clock\n");
+		bbclk.CH=0;
+		mod=1;
+	}
+
+	if (bbclk.fmt) {
+		printf("ds1302: Clock was in 12 hour mode, fixing\n");
+		bbclk.fmt=0;
+		mod=1;
+	}
+
+	if (bbclk.year>9) {
+		printf("ds1302: Year was corrupted, fixing\n");
+		bbclk.year10=100/10;	/* 2000 - why not? ;) */
+		bbclk.year=0;
+		mod=1;
+	}
+
+	/* Write out the changes if needed */
+	if (mod) {
+		/* enable write protect */
+		bbclk.WP = 1;
+		write_ser_drv(0xbe,(unsigned char *)&bbclk,8);
+	} else {
+		/* Else just turn write protect on */
+		b = 0x80;
+		write_ser_drv(0x8e,&b,1);
+	}
+	DPRINTF("init done\n");
+
+	ds1302_initted=1;
+}
+
+void
+rtc_reset(void)
+{
+	if(!ds1302_initted) rtc_init();
+	/* TODO */
+}
+
+void
+rtc_get(struct rtc_time *tmp)
+{
+	struct ds1302_st bbclk;
+
+	if(!ds1302_initted) rtc_init();
+
+	read_ser_drv(0xbe,(unsigned char *)&bbclk, 8);      /* read burst */
+
+	if (bbclk.CH) {
+		printf("ds1302: rtc_get: Clock was halted, clock probably "
+			"corrupt\n");
+	}
+
+	tmp->tm_sec=10*bbclk.sec10+bbclk.sec;
+	tmp->tm_min=10*bbclk.min10+bbclk.min;
+	tmp->tm_hour=10*bbclk.hr10+bbclk.hr;
+	tmp->tm_wday=bbclk.day;
+	tmp->tm_mday=10*bbclk.date10+bbclk.date;
+	tmp->tm_mon=10*bbclk.month10+bbclk.month;
+	tmp->tm_year=10*bbclk.year10+bbclk.year + 1900;
+
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	DPRINTF("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+}
+
+void
+rtc_set(struct rtc_time *tmp)
+{
+	struct ds1302_st bbclk;
+	unsigned char b=0;
+
+	if(!ds1302_initted) rtc_init();
+
+	DPRINTF("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	memset(&bbclk,0,sizeof(bbclk));
+	bbclk.CH=0; /* dont halt */
+	bbclk.WP=1; /* write protect when we're done */
+
+	bbclk.sec10=tmp->tm_sec/10;
+	bbclk.sec=tmp->tm_sec%10;
+
+	bbclk.min10=tmp->tm_min/10;
+	bbclk.min=tmp->tm_min%10;
+
+	bbclk.hr10=tmp->tm_hour/10;
+	bbclk.hr=tmp->tm_hour%10;
+
+	bbclk.day=tmp->tm_wday;
+
+	bbclk.date10=tmp->tm_mday/10;
+	bbclk.date=tmp->tm_mday%10;
+
+	bbclk.month10=tmp->tm_mon/10;
+	bbclk.month=tmp->tm_mon%10;
+
+	tmp->tm_year -= 1900;
+	bbclk.year10=tmp->tm_year/10;
+	bbclk.year=tmp->tm_year%10;
+
+	write_ser_drv(0x8e,&b,1);           /* disable write protect */
+	write_ser_drv(0xbe,(unsigned char *)&bbclk, 8);     /* write burst */
+}
+
+#endif
diff --git a/drivers/rtc/ds1306.c b/drivers/rtc/ds1306.c
new file mode 100644
index 0000000..89e433d
--- /dev/null
+++ b/drivers/rtc/ds1306.c
@@ -0,0 +1,438 @@
+/*
+ * (C) Copyright 2002 SIXNET, dge@sixnetio.com.
+ *
+ * (C) Copyright 2004, Li-Pro.Net <www.li-pro.net>
+ * Stephan Linz <linz@li-pro.net>
+ *
+ * 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
+ */
+
+/*
+ * Date & Time support for DS1306 RTC using SPI:
+ *
+ *    - SXNI855T:    it uses its own soft SPI here in this file
+ *    - all other:   use the external spi_xfer() function
+ *                   (see include/spi.h)
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <spi.h>
+
+#if defined(CONFIG_RTC_DS1306) && defined(CONFIG_CMD_DATE)
+
+#define	RTC_SECONDS		0x00
+#define	RTC_MINUTES		0x01
+#define	RTC_HOURS		0x02
+#define	RTC_DAY_OF_WEEK		0x03
+#define	RTC_DATE_OF_MONTH	0x04
+#define	RTC_MONTH		0x05
+#define	RTC_YEAR		0x06
+
+#define	RTC_SECONDS_ALARM0	0x07
+#define	RTC_MINUTES_ALARM0	0x08
+#define	RTC_HOURS_ALARM0	0x09
+#define	RTC_DAY_OF_WEEK_ALARM0	0x0a
+
+#define	RTC_SECONDS_ALARM1	0x0b
+#define	RTC_MINUTES_ALARM1	0x0c
+#define	RTC_HOURS_ALARM1	0x0d
+#define	RTC_DAY_OF_WEEK_ALARM1	0x0e
+
+#define	RTC_CONTROL		0x0f
+#define	RTC_STATUS		0x10
+#define	RTC_TRICKLE_CHARGER	0x11
+
+#define	RTC_USER_RAM_BASE	0x20
+
+/*
+ * External table of chip select functions (see the appropriate board
+ * support for the actual definition of the table).
+ */
+extern spi_chipsel_type spi_chipsel[];
+extern int spi_chipsel_cnt;
+
+static unsigned int bin2bcd (unsigned int n);
+static unsigned char bcd2bin (unsigned char c);
+
+/* ************************************************************************* */
+#ifdef CONFIG_SXNI855T		/* !!! SHOULD BE CHANGED TO NEW CODE !!! */
+
+static void soft_spi_send (unsigned char n);
+static unsigned char soft_spi_read (void);
+static void init_spi (void);
+
+/*-----------------------------------------------------------------------
+ * Definitions
+ */
+
+#define	PB_SPISCK	0x00000002	/* PB 30 */
+#define PB_SPIMOSI	0x00000004	/* PB 29 */
+#define PB_SPIMISO	0x00000008	/* PB 28 */
+#define PB_SPI_CE	0x00010000	/* PB 15 */
+
+/* ------------------------------------------------------------------------- */
+
+/* read clock time from DS1306 and return it in *tmp */
+void rtc_get (struct rtc_time *tmp)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	unsigned char spi_byte;	/* Data Byte */
+
+	init_spi ();		/* set port B for software SPI */
+
+	/* Now we can enable the DS1306 RTC */
+	immap->im_cpm.cp_pbdat |= PB_SPI_CE;
+	udelay (10);
+
+	/* Shift out the address (0) of the time in the Clock Chip */
+	soft_spi_send (0);
+
+	/* Put the clock readings into the rtc_time structure */
+	tmp->tm_sec = bcd2bin (soft_spi_read ());	/* Read seconds */
+	tmp->tm_min = bcd2bin (soft_spi_read ());	/* Read minutes */
+
+	/* Hours are trickier */
+	spi_byte = soft_spi_read ();	/* Read Hours into temporary value */
+	if (spi_byte & 0x40) {
+		/* 12 hour mode bit is set (time is in 1-12 format) */
+		if (spi_byte & 0x20) {
+			/* since PM we add 11 to get 0-23 for hours */
+			tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) + 11;
+		} else {
+			/* since AM we subtract 1 to get 0-23 for hours */
+			tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) - 1;
+		}
+	} else {
+		/* Otherwise, 0-23 hour format */
+		tmp->tm_hour = (bcd2bin (spi_byte & 0x3F));
+	}
+
+	soft_spi_read ();	/* Read and discard Day of week */
+	tmp->tm_mday = bcd2bin (soft_spi_read ());	/* Read Day of the Month */
+	tmp->tm_mon = bcd2bin (soft_spi_read ());	/* Read Month */
+
+	/* Read Year and convert to this century */
+	tmp->tm_year = bcd2bin (soft_spi_read ()) + 2000;
+
+	/* Now we can disable the DS1306 RTC */
+	immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;	/* Disable DS1306 Chip */
+	udelay (10);
+
+	GregorianDay (tmp);	/* Determine the day of week */
+
+	debug ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* set clock time in DS1306 RTC and in MPC8xx RTC */
+void rtc_set (struct rtc_time *tmp)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+	init_spi ();		/* set port B for software SPI */
+
+	/* Now we can enable the DS1306 RTC */
+	immap->im_cpm.cp_pbdat |= PB_SPI_CE;	/* Enable DS1306 Chip */
+	udelay (10);
+
+	/* First disable write protect in the clock chip control register */
+	soft_spi_send (0x8F);	/* send address of the control register */
+	soft_spi_send (0x00);	/* send control register contents */
+
+	/* Now disable the DS1306 to terminate the write */
+	immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;
+	udelay (10);
+
+	/* Now enable the DS1306 to initiate a new write */
+	immap->im_cpm.cp_pbdat |= PB_SPI_CE;
+	udelay (10);
+
+	/* Next, send the address of the clock time write registers */
+	soft_spi_send (0x80);	/* send address of the first time register */
+
+	/* Use Burst Mode to send all of the time data to the clock */
+	bin2bcd (tmp->tm_sec);
+	soft_spi_send (bin2bcd (tmp->tm_sec));	/* Send Seconds */
+	soft_spi_send (bin2bcd (tmp->tm_min));	/* Send Minutes */
+	soft_spi_send (bin2bcd (tmp->tm_hour));	/* Send Hour */
+	soft_spi_send (bin2bcd (tmp->tm_wday));	/* Send Day of the Week */
+	soft_spi_send (bin2bcd (tmp->tm_mday));	/* Send Day of Month */
+	soft_spi_send (bin2bcd (tmp->tm_mon));	/* Send Month */
+	soft_spi_send (bin2bcd (tmp->tm_year - 2000));	/* Send Year */
+
+	/* Now we can disable the Clock chip to terminate the burst write */
+	immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;	/* Disable DS1306 Chip */
+	udelay (10);
+
+	/* Now we can enable the Clock chip to initiate a new write */
+	immap->im_cpm.cp_pbdat |= PB_SPI_CE;	/* Enable DS1306 Chip */
+	udelay (10);
+
+	/* First we Enable write protect in the clock chip control register */
+	soft_spi_send (0x8F);	/* send address of the control register */
+	soft_spi_send (0x40);	/* send out Control Register contents */
+
+	/* Now disable the DS1306 */
+	immap->im_cpm.cp_pbdat &= ~PB_SPI_CE;	/*  Disable DS1306 Chip */
+	udelay (10);
+
+	/* Set standard MPC8xx clock to the same time so Linux will
+	 * see the time even if it doesn't have a DS1306 clock driver.
+	 * This helps with experimenting with standard kernels.
+	 */
+	{
+		ulong tim;
+
+		tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
+			      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+		immap->im_sitk.sitk_rtck = KAPWR_KEY;
+		immap->im_sit.sit_rtc = tim;
+	}
+
+	debug ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* Initialize Port B for software SPI */
+static void init_spi (void)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+	/* Force output pins to begin at logic 0 */
+	immap->im_cpm.cp_pbdat &= ~(PB_SPI_CE | PB_SPIMOSI | PB_SPISCK);
+
+	/* Set these 3 signals as outputs */
+	immap->im_cpm.cp_pbdir |= (PB_SPIMOSI | PB_SPI_CE | PB_SPISCK);
+
+	immap->im_cpm.cp_pbdir &= ~PB_SPIMISO;	/* Make MISO pin an input */
+	udelay (10);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* NOTE: soft_spi_send() assumes that the I/O lines are configured already */
+static void soft_spi_send (unsigned char n)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+	unsigned char bitpos;	/* bit position to receive */
+	unsigned char i;	/* Loop Control */
+
+	/* bit position to send, start with most significant bit */
+	bitpos = 0x80;
+
+	/* Send 8 bits to software SPI */
+	for (i = 0; i < 8; i++) {	/* Loop for 8 bits */
+		immap->im_cpm.cp_pbdat |= PB_SPISCK;	/* Raise SCK */
+
+		if (n & bitpos)
+			immap->im_cpm.cp_pbdat |= PB_SPIMOSI;	/* Set MOSI to 1 */
+		else
+			immap->im_cpm.cp_pbdat &= ~PB_SPIMOSI;	/* Set MOSI to 0 */
+		udelay (10);
+
+		immap->im_cpm.cp_pbdat &= ~PB_SPISCK;	/* Lower SCK */
+		udelay (10);
+
+		bitpos >>= 1;	/* Shift for next bit position */
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* NOTE: soft_spi_read() assumes that the I/O lines are configured already */
+static unsigned char soft_spi_read (void)
+{
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+	unsigned char spi_byte = 0;	/* Return value, assume success */
+	unsigned char bitpos;	/* bit position to receive */
+	unsigned char i;	/* Loop Control */
+
+	/* bit position to receive, start with most significant bit */
+	bitpos = 0x80;
+
+	/* Read 8 bits here */
+	for (i = 0; i < 8; i++) {	/* Do 8 bits in loop */
+		immap->im_cpm.cp_pbdat |= PB_SPISCK;	/* Raise SCK */
+		udelay (10);
+		if (immap->im_cpm.cp_pbdat & PB_SPIMISO)	/* Get a bit of data */
+			spi_byte |= bitpos;	/* Set data accordingly */
+		immap->im_cpm.cp_pbdat &= ~PB_SPISCK;	/* Lower SCK */
+		udelay (10);
+		bitpos >>= 1;	/* Shift for next bit position */
+	}
+
+	return spi_byte;	/* Return the byte read */
+}
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_reset (void)
+{
+	return;			/* nothing to do */
+}
+
+#else  /* not CONFIG_SXNI855T */
+/* ************************************************************************* */
+
+static unsigned char rtc_read (unsigned char reg);
+static void rtc_write (unsigned char reg, unsigned char val);
+
+/* read clock time from DS1306 and return it in *tmp */
+void rtc_get (struct rtc_time *tmp)
+{
+	unsigned char sec, min, hour, mday, wday, mon, year;
+
+	sec = rtc_read (RTC_SECONDS);
+	min = rtc_read (RTC_MINUTES);
+	hour = rtc_read (RTC_HOURS);
+	mday = rtc_read (RTC_DATE_OF_MONTH);
+	wday = rtc_read (RTC_DAY_OF_WEEK);
+	mon = rtc_read (RTC_MONTH);
+	year = rtc_read (RTC_YEAR);
+
+	debug ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
+	       "hr: %02x min: %02x sec: %02x\n",
+	       year, mon, mday, wday, hour, min, sec);
+	debug ("Alarms[0]: wday: %02x hour: %02x min: %02x sec: %02x\n",
+	       rtc_read (RTC_DAY_OF_WEEK_ALARM0),
+	       rtc_read (RTC_HOURS_ALARM0),
+	       rtc_read (RTC_MINUTES_ALARM0), rtc_read (RTC_SECONDS_ALARM0));
+	debug ("Alarms[1]: wday: %02x hour: %02x min: %02x sec: %02x\n",
+	       rtc_read (RTC_DAY_OF_WEEK_ALARM1),
+	       rtc_read (RTC_HOURS_ALARM1),
+	       rtc_read (RTC_MINUTES_ALARM1), rtc_read (RTC_SECONDS_ALARM1));
+
+	tmp->tm_sec = bcd2bin (sec & 0x7F);	/* convert Seconds */
+	tmp->tm_min = bcd2bin (min & 0x7F);	/* convert Minutes */
+
+	/* convert Hours */
+	tmp->tm_hour = (hour & 0x40)
+		? ((hour & 0x20)	/* 12 hour mode */
+		   ? bcd2bin (hour & 0x1F) + 11	/* PM */
+		   : bcd2bin (hour & 0x1F) - 1	/* AM */
+		)
+		: bcd2bin (hour & 0x3F);	/* 24 hour mode */
+
+	tmp->tm_mday = bcd2bin (mday & 0x3F);	/* convert Day of the Month */
+	tmp->tm_mon = bcd2bin (mon & 0x1F);	/* convert Month */
+	tmp->tm_year = bcd2bin (year) + 2000;	/* convert Year */
+	tmp->tm_wday = bcd2bin (wday & 0x07) - 1;	/* convert Day of the Week */
+	tmp->tm_yday = 0;
+	tmp->tm_isdst = 0;
+
+	debug ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* set clock time from *tmp in DS1306 RTC */
+void rtc_set (struct rtc_time *tmp)
+{
+	debug ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	rtc_write (RTC_SECONDS, bin2bcd (tmp->tm_sec));
+	rtc_write (RTC_MINUTES, bin2bcd (tmp->tm_min));
+	rtc_write (RTC_HOURS, bin2bcd (tmp->tm_hour));
+	rtc_write (RTC_DAY_OF_WEEK, bin2bcd (tmp->tm_wday + 1));
+	rtc_write (RTC_DATE_OF_MONTH, bin2bcd (tmp->tm_mday));
+	rtc_write (RTC_MONTH, bin2bcd (tmp->tm_mon));
+	rtc_write (RTC_YEAR, bin2bcd (tmp->tm_year - 2000));
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* reset the DS1306 */
+void rtc_reset (void)
+{
+	/* clear the control register */
+	rtc_write (RTC_CONTROL, 0x00);	/* 1st step: reset WP */
+	rtc_write (RTC_CONTROL, 0x00);	/* 2nd step: reset 1Hz, AIE1, AIE0 */
+
+	/* reset all alarms */
+	rtc_write (RTC_SECONDS_ALARM0, 0x00);
+	rtc_write (RTC_SECONDS_ALARM1, 0x00);
+	rtc_write (RTC_MINUTES_ALARM0, 0x00);
+	rtc_write (RTC_MINUTES_ALARM1, 0x00);
+	rtc_write (RTC_HOURS_ALARM0, 0x00);
+	rtc_write (RTC_HOURS_ALARM1, 0x00);
+	rtc_write (RTC_DAY_OF_WEEK_ALARM0, 0x00);
+	rtc_write (RTC_DAY_OF_WEEK_ALARM1, 0x00);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static unsigned char rtc_read (unsigned char reg)
+{
+	unsigned char dout[2];	/* SPI Output Data Bytes */
+	unsigned char din[2];	/* SPI Input Data Bytes */
+
+	dout[0] = reg;
+
+	if (spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din) != 0) {
+		return 0;
+	} else {
+		return din[1];
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void rtc_write (unsigned char reg, unsigned char val)
+{
+	unsigned char dout[2];	/* SPI Output Data Bytes */
+	unsigned char din[2];	/* SPI Input Data Bytes */
+
+	dout[0] = 0x80 | reg;
+	dout[1] = val;
+
+	spi_xfer (spi_chipsel[CFG_SPI_RTC_DEVID], 16, dout, din);
+}
+
+#endif /* end of code exclusion (see #ifdef CONFIG_SXNI855T above) */
+
+/* ------------------------------------------------------------------------- */
+
+static unsigned char bcd2bin (unsigned char n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+/* ------------------------------------------------------------------------- */
+
+static unsigned int bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+/* ------------------------------------------------------------------------- */
+
+#endif
diff --git a/drivers/rtc/ds1307.c b/drivers/rtc/ds1307.c
new file mode 100644
index 0000000..c882d79
--- /dev/null
+++ b/drivers/rtc/ds1307.c
@@ -0,0 +1,204 @@
+/*
+ * (C) Copyright 2001, 2002, 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com`
+ * Steven Scholz, steven.scholz@imc-berlin.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
+ */
+
+/*
+ * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
+ * DS1307 and DS1338 Real Time Clock (RTC).
+ *
+ * based on ds1337.c
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if (defined(CONFIG_RTC_DS1307) || defined(CONFIG_RTC_DS1338) ) && \
+    defined(CONFIG_CMD_DATE)
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_RTC
+
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGR(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+#ifndef CFG_I2C_RTC_ADDR
+# define CFG_I2C_RTC_ADDR	0x68
+#endif
+
+#if defined(CONFIG_RTC_DS1307) && (CFG_I2C_SPEED > 100000)
+# error The DS1307 is specified only up to 100kHz!
+#endif
+
+/*
+ * RTC register addresses
+ */
+#define RTC_SEC_REG_ADDR	0x00
+#define RTC_MIN_REG_ADDR	0x01
+#define RTC_HR_REG_ADDR		0x02
+#define RTC_DAY_REG_ADDR	0x03
+#define RTC_DATE_REG_ADDR	0x04
+#define RTC_MON_REG_ADDR	0x05
+#define RTC_YR_REG_ADDR		0x06
+#define RTC_CTL_REG_ADDR	0x07
+
+#define RTC_SEC_BIT_CH		0x80	/* Clock Halt (in Register 0)   */
+
+#define RTC_CTL_BIT_RS0		0x01	/* Rate select 0                */
+#define RTC_CTL_BIT_RS1		0x02	/* Rate select 1                */
+#define RTC_CTL_BIT_SQWE	0x10	/* Square Wave Enable           */
+#define RTC_CTL_BIT_OUT		0x80	/* Output Control               */
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val);
+static uchar bin2bcd (unsigned int n);
+static unsigned bcd2bin (uchar c);
+
+/*
+ * Get the current time from the RTC
+ */
+void rtc_get (struct rtc_time *tmp)
+{
+	uchar sec, min, hour, mday, wday, mon, year;
+
+	sec = rtc_read (RTC_SEC_REG_ADDR);
+	min = rtc_read (RTC_MIN_REG_ADDR);
+	hour = rtc_read (RTC_HR_REG_ADDR);
+	wday = rtc_read (RTC_DAY_REG_ADDR);
+	mday = rtc_read (RTC_DATE_REG_ADDR);
+	mon = rtc_read (RTC_MON_REG_ADDR);
+	year = rtc_read (RTC_YR_REG_ADDR);
+
+	DEBUGR ("Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon, mday, wday, hour, min, sec);
+
+	if (sec & RTC_SEC_BIT_CH) {
+		printf ("### Warning: RTC oscillator has stopped\n");
+		/* clear the CH flag */
+		rtc_write (RTC_SEC_REG_ADDR,
+			   rtc_read (RTC_SEC_REG_ADDR) & ~RTC_SEC_BIT_CH);
+	}
+
+	tmp->tm_sec  = bcd2bin (sec & 0x7F);
+	tmp->tm_min  = bcd2bin (min & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon & 0x1F);
+	tmp->tm_year = bcd2bin (year) + ( bcd2bin (year) >= 70 ? 1900 : 2000);
+	tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+
+/*
+ * Set the RTC
+ */
+void rtc_set (struct rtc_time *tmp)
+{
+	DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
+		printf("WARNING: year should be between 1970 and 2069!\n");
+
+	rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
+	rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon));
+	rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
+	rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
+	rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
+	rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
+	rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
+}
+
+
+/*
+ * Reset the RTC. We setting the date back to 1970-01-01.
+ * We also enable the oscillator output on the SQW/OUT pin and program
+ * it for 32,768 Hz output. Note that according to the datasheet, turning
+ * on the square wave output increases the current drain on the backup
+ * battery to something between 480nA and 800nA.
+ */
+void rtc_reset (void)
+{
+	struct rtc_time tmp;
+
+	rtc_write (RTC_SEC_REG_ADDR, 0x00);	/* clearing Clock Halt	*/
+	rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_SQWE | RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS0);
+
+	tmp.tm_year = 1970;
+	tmp.tm_mon = 1;
+	tmp.tm_mday= 1;
+	tmp.tm_hour = 0;
+	tmp.tm_min = 0;
+	tmp.tm_sec = 0;
+
+	rtc_set(&tmp);
+
+	printf ( "RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
+		tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+		tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+
+	return;
+}
+
+
+/*
+ * Helper functions
+ */
+
+static
+uchar rtc_read (uchar reg)
+{
+	return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+
+static void rtc_write (uchar reg, uchar val)
+{
+	i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+}
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/ds1337.c b/drivers/rtc/ds1337.c
new file mode 100644
index 0000000..c636ac5
--- /dev/null
+++ b/drivers/rtc/ds1337.c
@@ -0,0 +1,191 @@
+/*
+ * (C) Copyright 2001, 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.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
+ */
+
+/*
+ * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
+ * DS1337 Real Time Clock (RTC).
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_RTC_DS1337) && defined(CONFIG_CMD_DATE)
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_RTC
+
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGR(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+/*
+ * RTC register addresses
+ */
+#define RTC_SEC_REG_ADDR	0x0
+#define RTC_MIN_REG_ADDR	0x1
+#define RTC_HR_REG_ADDR		0x2
+#define RTC_DAY_REG_ADDR	0x3
+#define RTC_DATE_REG_ADDR	0x4
+#define RTC_MON_REG_ADDR	0x5
+#define RTC_YR_REG_ADDR		0x6
+#define RTC_CTL_REG_ADDR	0x0e
+#define RTC_STAT_REG_ADDR	0x0f
+
+/*
+ * RTC control register bits
+ */
+#define RTC_CTL_BIT_A1IE	0x1	/* Alarm 1 interrupt enable     */
+#define RTC_CTL_BIT_A2IE	0x2	/* Alarm 2 interrupt enable     */
+#define RTC_CTL_BIT_INTCN	0x4	/* Interrupt control            */
+#define RTC_CTL_BIT_RS1		0x8	/* Rate select 1                */
+#define RTC_CTL_BIT_RS2		0x10	/* Rate select 2                */
+#define RTC_CTL_BIT_DOSC	0x80	/* Disable Oscillator           */
+
+/*
+ * RTC status register bits
+ */
+#define RTC_STAT_BIT_A1F	0x1	/* Alarm 1 flag                 */
+#define RTC_STAT_BIT_A2F	0x2	/* Alarm 2 flag                 */
+#define RTC_STAT_BIT_OSF	0x80	/* Oscillator stop flag         */
+
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val);
+static uchar bin2bcd (unsigned int n);
+static unsigned bcd2bin (uchar c);
+
+
+/*
+ * Get the current time from the RTC
+ */
+void rtc_get (struct rtc_time *tmp)
+{
+	uchar sec, min, hour, mday, wday, mon_cent, year, control, status;
+
+	control = rtc_read (RTC_CTL_REG_ADDR);
+	status = rtc_read (RTC_STAT_REG_ADDR);
+	sec = rtc_read (RTC_SEC_REG_ADDR);
+	min = rtc_read (RTC_MIN_REG_ADDR);
+	hour = rtc_read (RTC_HR_REG_ADDR);
+	wday = rtc_read (RTC_DAY_REG_ADDR);
+	mday = rtc_read (RTC_DATE_REG_ADDR);
+	mon_cent = rtc_read (RTC_MON_REG_ADDR);
+	year = rtc_read (RTC_YR_REG_ADDR);
+
+	DEBUGR ("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x control: %02x status: %02x\n",
+		year, mon_cent, mday, wday, hour, min, sec, control, status);
+
+	if (status & RTC_STAT_BIT_OSF) {
+		printf ("### Warning: RTC oscillator has stopped\n");
+		/* clear the OSF flag */
+		rtc_write (RTC_STAT_REG_ADDR,
+			   rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF);
+	}
+
+	tmp->tm_sec  = bcd2bin (sec & 0x7F);
+	tmp->tm_min  = bcd2bin (min & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
+	tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
+	tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+
+/*
+ * Set the RTC
+ */
+void rtc_set (struct rtc_time *tmp)
+{
+	uchar century;
+
+	DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
+
+	century = (tmp->tm_year >= 2000) ? 0x80 : 0;
+	rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century);
+
+	rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
+	rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
+	rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
+	rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
+	rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
+}
+
+
+/*
+ * Reset the RTC.  We also enable the oscillator output on the
+ * SQW/INTB* pin and program it for 32,768 Hz output. Note that
+ * according to the datasheet, turning on the square wave output
+ * increases the current drain on the backup battery from about
+ * 600 nA to 2uA.
+ */
+void rtc_reset (void)
+{
+	rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2);
+}
+
+
+/*
+ * Helper functions
+ */
+
+static
+uchar rtc_read (uchar reg)
+{
+	return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+
+static void rtc_write (uchar reg, uchar val)
+{
+	i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+}
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/ds1374.c b/drivers/rtc/ds1374.c
new file mode 100644
index 0000000..e773dd9
--- /dev/null
+++ b/drivers/rtc/ds1374.c
@@ -0,0 +1,253 @@
+/*
+ * (C) Copyright 2001, 2002, 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com`
+ * Steven Scholz, steven.scholz@imc-berlin.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
+ */
+
+/*
+ * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
+ * DS1374 Real Time Clock (RTC).
+ *
+ * based on ds1337.c
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if (defined(CONFIG_RTC_DS1374)) && defined(CONFIG_CMD_DATE)
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_RTC
+#define DEBUG_RTC
+
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGR(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+#ifndef CFG_I2C_RTC_ADDR
+# define CFG_I2C_RTC_ADDR	0x68
+#endif
+
+#if defined(CONFIG_RTC_DS1374) && (CFG_I2C_SPEED > 400000)
+# error The DS1374 is specified up to 400kHz in fast mode!
+#endif
+
+/*
+ * RTC register addresses
+ */
+#define RTC_TOD_CNT_BYTE0_ADDR		0x00 /* TimeOfDay */
+#define RTC_TOD_CNT_BYTE1_ADDR		0x01
+#define RTC_TOD_CNT_BYTE2_ADDR		0x02
+#define RTC_TOD_CNT_BYTE3_ADDR		0x03
+
+#define RTC_WD_ALM_CNT_BYTE0_ADDR	0x04
+#define RTC_WD_ALM_CNT_BYTE1_ADDR	0x05
+#define RTC_WD_ALM_CNT_BYTE2_ADDR	0x06
+
+#define RTC_CTL_ADDR			0x07 /* RTC-CoNTrol-register */
+#define RTC_SR_ADDR			0x08 /* RTC-StatusRegister */
+#define RTC_TCS_DS_ADDR			0x09 /* RTC-TrickleChargeSelect DiodeSelect-register */
+
+#define RTC_CTL_BIT_AIE			(1<<0) /* Bit 0 - Alarm Interrupt enable */
+#define RTC_CTL_BIT_RS1			(1<<1) /* Bit 1/2 - Rate Select square wave output */
+#define RTC_CTL_BIT_RS2			(1<<2) /* Bit 2/2 - Rate Select square wave output */
+#define RTC_CTL_BIT_WDSTR		(1<<3) /* Bit 3 - Watchdog Reset Steering */
+#define RTC_CTL_BIT_BBSQW		(1<<4) /* Bit 4 - Battery-Backed Square-Wave */
+#define RTC_CTL_BIT_WD_ALM		(1<<5) /* Bit 5 - Watchdoc/Alarm Counter Select */
+#define RTC_CTL_BIT_WACE		(1<<6) /* Bit 6 - Watchdog/Alarm Counter Enable WACE*/
+#define RTC_CTL_BIT_EN_OSC		(1<<7) /* Bit 7 - Enable Oscilator */
+
+#define RTC_SR_BIT_AF			0x01 /* Bit 0 = Alarm Flag */
+#define RTC_SR_BIT_OSF			0x80 /* Bit 7 - Osc Stop Flag */
+
+typedef unsigned char boolean_t;
+
+#ifndef TRUE
+#define TRUE ((boolean_t)(0==0))
+#endif
+#ifndef FALSE
+#define FALSE (!TRUE)
+#endif
+
+const char RtcTodAddr[] = {
+	RTC_TOD_CNT_BYTE0_ADDR,
+	RTC_TOD_CNT_BYTE1_ADDR,
+	RTC_TOD_CNT_BYTE2_ADDR,
+	RTC_TOD_CNT_BYTE3_ADDR
+};
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val, boolean_t set);
+static void rtc_write_raw (uchar reg, uchar val);
+
+/*
+ * Get the current time from the RTC
+ */
+void rtc_get (struct rtc_time *tm){
+
+	unsigned long time1, time2;
+	unsigned int limit;
+	unsigned char tmp;
+	unsigned int i;
+
+	/*
+	 * Since the reads are being performed one byte at a time,
+	 * there is a chance that a carry will occur during the read.
+	 * To detect this, 2 reads are performed and compared.
+	 */
+	limit = 10;
+	do {
+		i = 4;
+		time1 = 0;
+		while (i--) {
+			tmp = rtc_read(RtcTodAddr[i]);
+			time1 = (time1 << 8) | (tmp & 0xff);
+		}
+
+		i = 4;
+		time2 = 0;
+		while (i--) {
+			tmp = rtc_read(RtcTodAddr[i]);
+			time2 = (time2 << 8) | (tmp & 0xff);
+		}
+	} while ((time1 != time2) && limit--);
+
+	if (time1 != time2) {
+		printf("can't get consistent time from rtc chip\n");
+	}
+
+	DEBUGR ("Get RTC s since 1.1.1970: %d\n", time1);
+
+	to_tm(time1, tm); /* To Gregorian Date */
+
+	if (rtc_read(RTC_SR_ADDR) & RTC_SR_BIT_OSF)
+		printf ("### Warning: RTC oscillator has stopped\n");
+
+	DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday,
+		tm->tm_hour, tm->tm_min, tm->tm_sec);
+}
+
+/*
+ * Set the RTC
+ */
+void rtc_set (struct rtc_time *tmp){
+
+	unsigned long time;
+	unsigned i;
+
+	DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
+		printf("WARNING: year should be between 1970 and 2069!\n");
+
+	time = mktime(tmp->tm_year, tmp->tm_mon,
+			tmp->tm_mday, tmp->tm_hour,
+			tmp->tm_min, tmp->tm_sec);
+
+	DEBUGR ("Set RTC s since 1.1.1970: %d (0x%02x)\n", time, time);
+
+	/* write to RTC_TOD_CNT_BYTEn_ADDR */
+	for (i = 0; i <= 3; i++) {
+		rtc_write_raw(RtcTodAddr[i], (unsigned char)(time & 0xff));
+		time = time >> 8;
+	}
+
+	/* Start clock */
+	rtc_write(RTC_CTL_ADDR, RTC_CTL_BIT_EN_OSC, FALSE);
+}
+
+/*
+ * Reset the RTC. We setting the date back to 1970-01-01.
+ * We also enable the oscillator output on the SQW/OUT pin and program
+ * it for 32,768 Hz output. Note that according to the datasheet, turning
+ * on the square wave output increases the current drain on the backup
+ * battery to something between 480nA and 800nA.
+ */
+void rtc_reset (void){
+
+	struct rtc_time tmp;
+
+	/* clear status flags */
+	rtc_write (RTC_SR_ADDR, (RTC_SR_BIT_AF|RTC_SR_BIT_OSF), FALSE); /* clearing OSF and AF */
+
+	/* Initialise DS1374 oriented to MPC8349E-ADS */
+	rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_EN_OSC
+				 |RTC_CTL_BIT_WACE
+				 |RTC_CTL_BIT_AIE), FALSE);/* start osc, disable WACE, clear AIE
+							      - set to 0 */
+	rtc_write (RTC_CTL_ADDR, (RTC_CTL_BIT_WD_ALM
+				|RTC_CTL_BIT_WDSTR
+				|RTC_CTL_BIT_RS1
+				|RTC_CTL_BIT_RS2
+				|RTC_CTL_BIT_BBSQW), TRUE);/* disable WD/ALM, WDSTR set to INT-pin,
+							      set BBSQW and SQW to 32k
+							      - set to 1 */
+	tmp.tm_year = 1970;
+	tmp.tm_mon = 1;
+	tmp.tm_mday= 1;
+	tmp.tm_hour = 0;
+	tmp.tm_min = 0;
+	tmp.tm_sec = 0;
+
+	rtc_set(&tmp);
+
+	printf("RTC:   %4d-%02d-%02d %2d:%02d:%02d UTC\n",
+		tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+		tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+
+	rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR,0xAC, TRUE);
+	rtc_write(RTC_WD_ALM_CNT_BYTE1_ADDR,0xDE, TRUE);
+	rtc_write(RTC_WD_ALM_CNT_BYTE2_ADDR,0xAD, TRUE);
+}
+
+/*
+ * Helper functions
+ */
+static uchar rtc_read (uchar reg)
+{
+	return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+static void rtc_write (uchar reg, uchar val, boolean_t set)
+{
+	if (set == TRUE) {
+		val |= i2c_reg_read (CFG_I2C_RTC_ADDR, reg);
+		i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+	} else {
+		val = i2c_reg_read (CFG_I2C_RTC_ADDR, reg) & ~val;
+		i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+	}
+}
+
+static void rtc_write_raw (uchar reg, uchar val)
+{
+		i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+}
+#endif
diff --git a/drivers/rtc/ds1556.c b/drivers/rtc/ds1556.c
new file mode 100644
index 0000000..4365cfb
--- /dev/null
+++ b/drivers/rtc/ds1556.c
@@ -0,0 +1,206 @@
+/*
+ * (C) Copyright 2002
+ * ARIO Data Networks, Inc. dchiu@ariodata.com
+ *
+ * modified for DS1556:
+ * Frank Panno <fpanno@delphintech.com>, Delphin Technology AG
+ *
+ * Based on MontaVista DS1743 code and U-Boot mc146818 code
+ *
+ * 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
+ */
+
+/*
+ * Date & Time support for the DS1556 RTC
+ */
+
+/*#define	RTC_DEBUG */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+
+#if defined(CONFIG_RTC_DS1556) && defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read( unsigned int addr );
+static void  rtc_write( unsigned int addr, uchar val);
+static uchar bin2bcd   (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+#define RTC_BASE		( CFG_NVRAM_SIZE + CFG_NVRAM_BASE_ADDR )
+
+#define RTC_YEAR		( RTC_BASE + 0xf )
+#define RTC_MONTH		( RTC_BASE + 0xe )
+#define RTC_DAY_OF_MONTH	( RTC_BASE + 0xd )
+#define RTC_DAY_OF_WEEK		( RTC_BASE + 0xc )
+#define RTC_HOURS		( RTC_BASE + 0xb )
+#define RTC_MINUTES		( RTC_BASE + 0xa )
+#define RTC_SECONDS		( RTC_BASE + 0x9 )
+#define RTC_CENTURY		( RTC_BASE + 0x8 )
+
+#define RTC_CONTROLA		RTC_CENTURY
+#define RTC_CONTROLB		RTC_SECONDS
+#define RTC_CONTROLC		RTC_BASE
+
+#define RTC_CA_WRITE		0x80
+#define RTC_CA_READ		0x40
+
+#define RTC_CB_OSC_DISABLE	0x80
+
+#define RTC_CC_BATTERY_FLAG	0x10
+#define RTC_CC_FREQ_TEST	0x40
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get( struct rtc_time *tmp )
+{
+	uchar sec, min, hour;
+	uchar mday, wday, mon, year;
+
+	int century;
+
+	uchar reg_a;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	/* lock clock registers for read */
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
+
+	sec     = rtc_read( RTC_SECONDS );
+	min     = rtc_read( RTC_MINUTES );
+	hour    = rtc_read( RTC_HOURS );
+	mday    = rtc_read( RTC_DAY_OF_MONTH );
+	wday    = rtc_read( RTC_DAY_OF_WEEK );
+	mon     = rtc_read( RTC_MONTH );
+	year    = rtc_read( RTC_YEAR );
+	century = rtc_read( RTC_CENTURY );
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
+
+#ifdef RTC_DEBUG
+	printf( "Get RTC year: %02x mon/cent: %02x mon: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, century, mon, mday, wday,
+		hour, min, sec );
+#endif
+	tmp->tm_sec  = bcd2bin( sec  & 0x7F );
+	tmp->tm_min  = bcd2bin( min  & 0x7F );
+	tmp->tm_hour = bcd2bin( hour & 0x3F );
+	tmp->tm_mday = bcd2bin( mday & 0x3F );
+	tmp->tm_mon  = bcd2bin( mon & 0x1F );
+	tmp->tm_wday = bcd2bin( wday & 0x07 );
+
+	/* glue year from century and year in century */
+	tmp->tm_year = bcd2bin( year ) +
+		( bcd2bin( century & 0x3F ) * 100 );
+
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+	printf( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+#endif
+}
+
+void rtc_set( struct rtc_time *tmp )
+{
+	uchar reg_a;
+#ifdef RTC_DEBUG
+	printf( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+	/* lock clock registers for write */
+	reg_a = rtc_read( RTC_CONTROLA );
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
+
+	rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
+
+	rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
+	rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
+	rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
+	rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
+	rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
+
+	/* break year up into century and year in century */
+	rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
+	rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
+}
+
+void rtc_reset (void)
+{
+	uchar reg_a, reg_b, reg_c;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	reg_b = rtc_read( RTC_CONTROLB );
+
+	if ( reg_b & RTC_CB_OSC_DISABLE )
+	{
+		printf( "real-time-clock was stopped. Now starting...\n" );
+		reg_a |= RTC_CA_WRITE;
+		reg_b &= ~RTC_CB_OSC_DISABLE;
+
+		rtc_write( RTC_CONTROLA, reg_a );
+		rtc_write( RTC_CONTROLB, reg_b );
+	}
+
+	/* make sure read/write clock register bits are cleared */
+	reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
+	rtc_write( RTC_CONTROLA, reg_a );
+
+	reg_c = rtc_read( RTC_CONTROLC );
+	if (( reg_c & RTC_CC_BATTERY_FLAG ) == 0 )
+		printf( "RTC battery low. Clock setting may not be reliable.\n" );
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read( unsigned int addr )
+{
+	uchar val = *(volatile unsigned char*)(addr);
+#ifdef RTC_DEBUG
+	printf( "rtc_read: %x:%x\n", addr, val );
+#endif
+	return( val );
+}
+
+static void rtc_write( unsigned int addr, uchar val )
+{
+#ifdef RTC_DEBUG
+	printf( "rtc_write: %x:%x\n", addr, val );
+#endif
+	*(volatile unsigned char*)(addr) = val;
+}
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/ds164x.c b/drivers/rtc/ds164x.c
new file mode 100644
index 0000000..bff22b9a
--- /dev/null
+++ b/drivers/rtc/ds164x.c
@@ -0,0 +1,200 @@
+/*
+ * (C) Copyright 2002
+ * ARIO Data Networks, Inc. dchiu@ariodata.com
+ *
+ * modified for DS164x:
+ * The LEOX team <team@leox.org>, http://www.leox.org
+ *
+ * Based on MontaVista DS1743 code and U-Boot mc146818 code
+ *
+ * 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
+ */
+
+/*
+ * Date & Time support for the DS164x RTC
+ */
+
+/* #define	RTC_DEBUG */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+
+#if defined(CONFIG_RTC_DS164x) && defined(CONFIG_CMD_DATE)
+
+static uchar    rtc_read(unsigned int addr );
+static void     rtc_write(unsigned int addr, uchar val);
+static uchar    bin2bcd(unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+#define RTC_EPOCH                 2000	/* century */
+
+/*
+ * DS164x registers layout
+ */
+#define RTC_BASE		( CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE )
+
+#define RTC_YEAR		( RTC_BASE + 0x07 )
+#define RTC_MONTH		( RTC_BASE + 0x06 )
+#define RTC_DAY_OF_MONTH	( RTC_BASE + 0x05 )
+#define RTC_DAY_OF_WEEK		( RTC_BASE + 0x04 )
+#define RTC_HOURS		( RTC_BASE + 0x03 )
+#define RTC_MINUTES		( RTC_BASE + 0x02 )
+#define RTC_SECONDS		( RTC_BASE + 0x01 )
+#define RTC_CONTROL		( RTC_BASE + 0x00 )
+
+#define RTC_CONTROLA		RTC_CONTROL	/* W=bit6, R=bit5 */
+#define   RTC_CA_WRITE		  0x80
+#define   RTC_CA_READ		  0x40
+#define RTC_CONTROLB		RTC_SECONDS	/* OSC=bit7       */
+#define   RTC_CB_OSC_DISABLE	  0x80
+#define RTC_CONTROLC		RTC_DAY_OF_WEEK	/* FT=bit6        */
+#define   RTC_CC_FREQ_TEST	  0x40
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get( struct rtc_time *tmp )
+{
+	uchar sec, min, hour;
+	uchar mday, wday, mon, year;
+
+	uchar reg_a;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	/* lock clock registers for read */
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
+
+	sec     = rtc_read( RTC_SECONDS );
+	min     = rtc_read( RTC_MINUTES );
+	hour    = rtc_read( RTC_HOURS );
+	mday    = rtc_read( RTC_DAY_OF_MONTH );
+	wday    = rtc_read( RTC_DAY_OF_WEEK );
+	mon     = rtc_read( RTC_MONTH );
+	year    = rtc_read( RTC_YEAR );
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
+
+#ifdef RTC_DEBUG
+	printf( "Get RTC year: %02x mon: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon, mday, wday,
+		hour, min, sec );
+#endif
+	tmp->tm_sec  = bcd2bin( sec  & 0x7F );
+	tmp->tm_min  = bcd2bin( min  & 0x7F );
+	tmp->tm_hour = bcd2bin( hour & 0x3F );
+	tmp->tm_mday = bcd2bin( mday & 0x3F );
+	tmp->tm_mon  = bcd2bin( mon  & 0x1F );
+	tmp->tm_wday = bcd2bin( wday & 0x07 );
+
+	/* glue year in century (2000) */
+	tmp->tm_year = bcd2bin( year ) + RTC_EPOCH;
+
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+	printf( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+#endif
+}
+
+void rtc_set( struct rtc_time *tmp )
+{
+	uchar reg_a;
+
+#ifdef RTC_DEBUG
+	printf( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+	/* lock clock registers for write */
+	reg_a = rtc_read( RTC_CONTROLA );
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
+
+	rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
+
+	rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
+	rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
+	rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
+	rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
+	rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
+
+	/* break year in century */
+	rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
+}
+
+void rtc_reset (void)
+{
+	uchar reg_a, reg_b;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	reg_b = rtc_read( RTC_CONTROLB );
+
+	if ( reg_b & RTC_CB_OSC_DISABLE )
+	{
+		printf( "real-time-clock was stopped. Now starting...\n" );
+		reg_a |= RTC_CA_WRITE;
+		reg_b &= ~RTC_CB_OSC_DISABLE;
+
+		rtc_write( RTC_CONTROLA, reg_a );
+		rtc_write( RTC_CONTROLB, reg_b );
+	}
+
+	/* make sure read/write clock register bits are cleared */
+	reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
+	rtc_write( RTC_CONTROLA, reg_a );
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read( unsigned int addr )
+{
+	uchar val = *(volatile unsigned char*)(addr);
+
+#ifdef RTC_DEBUG
+	printf( "rtc_read: %x:%x\n", addr, val );
+#endif
+	return( val );
+}
+
+static void rtc_write( unsigned int addr, uchar val )
+{
+#ifdef RTC_DEBUG
+	printf( "rtc_write: %x:%x\n", addr, val );
+#endif
+	*(volatile unsigned char*)(addr) = val;
+}
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/ds174x.c b/drivers/rtc/ds174x.c
new file mode 100644
index 0000000..5f85a68
--- /dev/null
+++ b/drivers/rtc/ds174x.c
@@ -0,0 +1,202 @@
+/*
+ * (C) Copyright 2001
+ * ARIO Data Networks, Inc. dchiu@ariodata.com
+ *
+ * Based on MontaVista DS1743 code and U-Boot mc146818 code
+ *
+ * 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
+ */
+
+/*
+ * Date & Time support for the DS174x RTC
+ */
+
+/*#define	DEBUG*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_DS174x) && defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read( unsigned int addr );
+static void  rtc_write( unsigned int addr, uchar val);
+static uchar bin2bcd   (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+#define RTC_BASE		( CFG_NVRAM_SIZE + CFG_NVRAM_BASE_ADDR )
+
+#define RTC_YEAR		( RTC_BASE + 7 )
+#define RTC_MONTH		( RTC_BASE + 6 )
+#define RTC_DAY_OF_MONTH	( RTC_BASE + 5 )
+#define RTC_DAY_OF_WEEK		( RTC_BASE + 4 )
+#define RTC_HOURS		( RTC_BASE + 3 )
+#define RTC_MINUTES		( RTC_BASE + 2 )
+#define RTC_SECONDS		( RTC_BASE + 1 )
+#define RTC_CENTURY		( RTC_BASE + 0 )
+
+#define RTC_CONTROLA		RTC_CENTURY
+#define RTC_CONTROLB		RTC_SECONDS
+#define RTC_CONTROLC		RTC_DAY_OF_WEEK
+
+#define RTC_CA_WRITE		0x80
+#define RTC_CA_READ		0x40
+
+#define RTC_CB_OSC_DISABLE	0x80
+
+#define RTC_CC_BATTERY_FLAG	0x80
+#define RTC_CC_FREQ_TEST	0x40
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get( struct rtc_time *tmp )
+{
+	uchar sec, min, hour;
+	uchar mday, wday, mon, year;
+
+	int century;
+
+	uchar reg_a;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	/* lock clock registers for read */
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_READ ));
+
+	sec     = rtc_read( RTC_SECONDS );
+	min     = rtc_read( RTC_MINUTES );
+	hour    = rtc_read( RTC_HOURS );
+	mday    = rtc_read( RTC_DAY_OF_MONTH );
+	wday    = rtc_read( RTC_DAY_OF_WEEK );
+	mon     = rtc_read( RTC_MONTH );
+	year    = rtc_read( RTC_YEAR );
+	century = rtc_read( RTC_CENTURY );
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a & ~RTC_CA_READ ));
+
+#ifdef RTC_DEBUG
+	printf( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon_cent, mday, wday,
+		hour, min, sec );
+#endif
+	tmp->tm_sec  = bcd2bin( sec  & 0x7F );
+	tmp->tm_min  = bcd2bin( min  & 0x7F );
+	tmp->tm_hour = bcd2bin( hour & 0x3F );
+	tmp->tm_mday = bcd2bin( mday & 0x3F );
+	tmp->tm_mon  = bcd2bin( mon & 0x1F );
+	tmp->tm_wday = bcd2bin( wday & 0x07 );
+
+	/* glue year from century and year in century */
+	tmp->tm_year = bcd2bin( year ) +
+		( bcd2bin( century & 0x3F ) * 100 );
+
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+	printf( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
+#endif
+}
+
+void rtc_set( struct rtc_time *tmp )
+{
+	uchar reg_a;
+#ifdef RTC_DEBUG
+	printf( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+	/* lock clock registers for write */
+	reg_a = rtc_read( RTC_CONTROLA );
+	rtc_write( RTC_CONTROLA, ( reg_a | RTC_CA_WRITE ));
+
+	rtc_write( RTC_MONTH, bin2bcd( tmp->tm_mon ));
+
+	rtc_write( RTC_DAY_OF_WEEK, bin2bcd( tmp->tm_wday ));
+	rtc_write( RTC_DAY_OF_MONTH, bin2bcd( tmp->tm_mday ));
+	rtc_write( RTC_HOURS, bin2bcd( tmp->tm_hour ));
+	rtc_write( RTC_MINUTES, bin2bcd( tmp->tm_min ));
+	rtc_write( RTC_SECONDS, bin2bcd( tmp->tm_sec ));
+
+	/* break year up into century and year in century */
+	rtc_write( RTC_YEAR, bin2bcd( tmp->tm_year % 100 ));
+	rtc_write( RTC_CENTURY, bin2bcd( tmp->tm_year / 100 ));
+
+	/* unlock clock registers after read */
+	rtc_write( RTC_CONTROLA, ( reg_a  & ~RTC_CA_WRITE ));
+}
+
+void rtc_reset (void)
+{
+	uchar reg_a, reg_b, reg_c;
+
+	reg_a = rtc_read( RTC_CONTROLA );
+	reg_b = rtc_read( RTC_CONTROLB );
+
+	if ( reg_b & RTC_CB_OSC_DISABLE )
+	{
+		printf( "real-time-clock was stopped. Now starting...\n" );
+		reg_a |= RTC_CA_WRITE;
+		reg_b &= ~RTC_CB_OSC_DISABLE;
+
+		rtc_write( RTC_CONTROLA, reg_a );
+		rtc_write( RTC_CONTROLB, reg_b );
+	}
+
+	/* make sure read/write clock register bits are cleared */
+	reg_a &= ~( RTC_CA_WRITE | RTC_CA_READ );
+	rtc_write( RTC_CONTROLA, reg_a );
+
+	reg_c = rtc_read( RTC_CONTROLC );
+	if (( reg_c & RTC_CC_BATTERY_FLAG ) == 0 )
+		printf( "RTC battery low. Clock setting may not be reliable.\n" );
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read( unsigned int addr )
+{
+	uchar val = in8( addr );
+#ifdef RTC_DEBUG
+	printf( "rtc_read: %x:%x\n", addr, val );
+#endif
+	return( val );
+}
+
+static void rtc_write( unsigned int addr, uchar val )
+{
+#ifdef RTC_DEBUG
+	printf( "rtc_write: %x:%x\n", addr, val );
+#endif
+	out8( addr, val );
+}
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/ds3231.c b/drivers/rtc/ds3231.c
new file mode 100644
index 0000000..fe11b86
--- /dev/null
+++ b/drivers/rtc/ds3231.c
@@ -0,0 +1,193 @@
+/*
+ * (C) Copyright 2006
+ * Markus Klotzbuecher, mk@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
+ */
+
+/*
+ * Date & Time support (no alarms) for Dallas Semiconductor (now Maxim)
+ * Extremly Accurate DS3231 Real Time Clock (RTC).
+ *
+ * copied from ds1337.c
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_RTC_DS3231) && defined(CONFIG_CMD_DATE)
+
+/*---------------------------------------------------------------------*/
+#undef DEBUG_RTC
+
+#ifdef DEBUG_RTC
+#define DEBUGR(fmt,args...) printf(fmt ,##args)
+#else
+#define DEBUGR(fmt,args...)
+#endif
+/*---------------------------------------------------------------------*/
+
+/*
+ * RTC register addresses
+ */
+#define RTC_SEC_REG_ADDR	0x0
+#define RTC_MIN_REG_ADDR	0x1
+#define RTC_HR_REG_ADDR		0x2
+#define RTC_DAY_REG_ADDR	0x3
+#define RTC_DATE_REG_ADDR	0x4
+#define RTC_MON_REG_ADDR	0x5
+#define RTC_YR_REG_ADDR		0x6
+#define RTC_CTL_REG_ADDR	0x0e
+#define RTC_STAT_REG_ADDR	0x0f
+
+
+/*
+ * RTC control register bits
+ */
+#define RTC_CTL_BIT_A1IE	0x1	/* Alarm 1 interrupt enable     */
+#define RTC_CTL_BIT_A2IE	0x2	/* Alarm 2 interrupt enable     */
+#define RTC_CTL_BIT_INTCN	0x4	/* Interrupt control            */
+#define RTC_CTL_BIT_RS1		0x8	/* Rate select 1                */
+#define RTC_CTL_BIT_RS2		0x10	/* Rate select 2                */
+#define RTC_CTL_BIT_DOSC	0x80	/* Disable Oscillator           */
+
+/*
+ * RTC status register bits
+ */
+#define RTC_STAT_BIT_A1F	0x1	/* Alarm 1 flag                 */
+#define RTC_STAT_BIT_A2F	0x2	/* Alarm 2 flag                 */
+#define RTC_STAT_BIT_OSF	0x80	/* Oscillator stop flag         */
+
+
+static uchar rtc_read (uchar reg);
+static void rtc_write (uchar reg, uchar val);
+static uchar bin2bcd (unsigned int n);
+static unsigned bcd2bin (uchar c);
+
+
+/*
+ * Get the current time from the RTC
+ */
+void rtc_get (struct rtc_time *tmp)
+{
+	uchar sec, min, hour, mday, wday, mon_cent, year, control, status;
+
+	control = rtc_read (RTC_CTL_REG_ADDR);
+	status = rtc_read (RTC_STAT_REG_ADDR);
+	sec = rtc_read (RTC_SEC_REG_ADDR);
+	min = rtc_read (RTC_MIN_REG_ADDR);
+	hour = rtc_read (RTC_HR_REG_ADDR);
+	wday = rtc_read (RTC_DAY_REG_ADDR);
+	mday = rtc_read (RTC_DATE_REG_ADDR);
+	mon_cent = rtc_read (RTC_MON_REG_ADDR);
+	year = rtc_read (RTC_YR_REG_ADDR);
+
+	DEBUGR ("Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x control: %02x status: %02x\n",
+		year, mon_cent, mday, wday, hour, min, sec, control, status);
+
+	if (status & RTC_STAT_BIT_OSF) {
+		printf ("### Warning: RTC oscillator has stopped\n");
+		/* clear the OSF flag */
+		rtc_write (RTC_STAT_REG_ADDR,
+			   rtc_read (RTC_STAT_REG_ADDR) & ~RTC_STAT_BIT_OSF);
+	}
+
+	tmp->tm_sec  = bcd2bin (sec & 0x7F);
+	tmp->tm_min  = bcd2bin (min & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
+	tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
+	tmp->tm_wday = bcd2bin ((wday - 1) & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	DEBUGR ("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+
+/*
+ * Set the RTC
+ */
+void rtc_set (struct rtc_time *tmp)
+{
+	uchar century;
+
+	DEBUGR ("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	rtc_write (RTC_YR_REG_ADDR, bin2bcd (tmp->tm_year % 100));
+
+	century = (tmp->tm_year >= 2000) ? 0x80 : 0;
+	rtc_write (RTC_MON_REG_ADDR, bin2bcd (tmp->tm_mon) | century);
+
+	rtc_write (RTC_DAY_REG_ADDR, bin2bcd (tmp->tm_wday + 1));
+	rtc_write (RTC_DATE_REG_ADDR, bin2bcd (tmp->tm_mday));
+	rtc_write (RTC_HR_REG_ADDR, bin2bcd (tmp->tm_hour));
+	rtc_write (RTC_MIN_REG_ADDR, bin2bcd (tmp->tm_min));
+	rtc_write (RTC_SEC_REG_ADDR, bin2bcd (tmp->tm_sec));
+}
+
+
+/*
+ * Reset the RTC.  We also enable the oscillator output on the
+ * SQW/INTB* pin and program it for 32,768 Hz output. Note that
+ * according to the datasheet, turning on the square wave output
+ * increases the current drain on the backup battery from about
+ * 600 nA to 2uA.
+ */
+void rtc_reset (void)
+{
+	rtc_write (RTC_CTL_REG_ADDR, RTC_CTL_BIT_RS1 | RTC_CTL_BIT_RS2);
+}
+
+
+/*
+ * Helper functions
+ */
+
+static
+uchar rtc_read (uchar reg)
+{
+	return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+
+static void rtc_write (uchar reg, uchar val)
+{
+	i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+}
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/m41t11.c b/drivers/rtc/m41t11.c
new file mode 100644
index 0000000..81da33a
--- /dev/null
+++ b/drivers/rtc/m41t11.c
@@ -0,0 +1,202 @@
+/*
+ * (C) Copyright 2002
+ * Andrew May, Viasat Inc, amay@viasat.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
+ */
+
+/*
+ * M41T11 Serial Access Timekeeper(R) SRAM
+ * can you believe a trademark on that?
+ */
+
+/* #define DEBUG 1 */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+/*
+	I Don't have an example config file but this
+	is what should be done.
+
+#define CONFIG_RTC_M41T11 1
+#define CFG_I2C_RTC_ADDR 0x68
+#if 0
+#define CFG_M41T11_EXT_CENTURY_DATA
+#else
+#define CFG_M41T11_BASE_YEAR 2000
+#endif
+*/
+
+#if defined(CONFIG_RTC_M41T11) && defined(CFG_I2C_RTC_ADDR) && defined(CONFIG_CMD_DATE)
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+
+/* ------------------------------------------------------------------------- */
+/*
+  these are simple defines for the chip local to here so they aren't too
+  verbose
+  DAY/DATE aren't nice but that is how they are on the data sheet
+*/
+#define RTC_SEC_ADDR       0x0
+#define RTC_MIN_ADDR       0x1
+#define RTC_HOUR_ADDR      0x2
+#define RTC_DAY_ADDR       0x3
+#define RTC_DATE_ADDR      0x4
+#define RTC_MONTH_ADDR     0x5
+#define RTC_YEARS_ADDR     0x6
+
+#define RTC_REG_CNT        7
+
+#define RTC_CONTROL_ADDR   0x7
+
+
+#ifndef CFG_M41T11_EXT_CENTURY_DATA
+
+#define REG_CNT            (RTC_REG_CNT+1)
+
+/*
+  you only get 00-99 for the year we will asume you
+  want from the year 2000 if you don't set the config
+*/
+#ifndef CFG_M41T11_BASE_YEAR
+#define CFG_M41T11_BASE_YEAR 2000
+#endif
+
+#else
+/* we will store extra year info in byte 9*/
+#define M41T11_YEAR_DATA   0x8
+#define M41T11_YEAR_SIZE   1
+#define REG_CNT            (RTC_REG_CNT+1+M41T11_YEAR_SIZE)
+#endif
+
+#define M41T11_STORAGE_SZ  (64-REG_CNT)
+
+void rtc_get (struct rtc_time *tmp)
+{
+	uchar data[RTC_REG_CNT];
+
+	i2c_read(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, data, RTC_REG_CNT);
+
+	if( data[RTC_SEC_ADDR] & 0x80 ){
+		printf( "m41t11 RTC Clock stopped!!!\n" );
+	}
+	tmp->tm_sec  = bcd2bin (data[RTC_SEC_ADDR]  & 0x7F);
+	tmp->tm_min  = bcd2bin (data[RTC_MIN_ADDR]  & 0x7F);
+	tmp->tm_hour = bcd2bin (data[RTC_HOUR_ADDR] & 0x3F);
+	tmp->tm_mday = bcd2bin (data[RTC_DATE_ADDR] & 0x3F);
+	tmp->tm_mon  = bcd2bin (data[RTC_MONTH_ADDR]& 0x1F);
+#ifndef CFG_M41T11_EXT_CENTURY_DATA
+	tmp->tm_year = CFG_M41T11_BASE_YEAR
+		+ bcd2bin(data[RTC_YEARS_ADDR])
+		+ ((data[RTC_HOUR_ADDR]&0x40) ? 100 : 0);
+#else
+	{
+		unsigned char cent;
+		i2c_read(CFG_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
+		if( !(data[RTC_HOUR_ADDR] & 0x80) ){
+			printf( "m41t11 RTC: cann't keep track of years without CEB set\n" );
+		}
+		if( (cent & 0x1) != ((data[RTC_HOUR_ADDR]&0x40)>>7) ){
+			/*century flip store off new year*/
+			cent += 1;
+			i2c_write(CFG_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
+		}
+		tmp->tm_year =((int)cent*100)+bcd2bin(data[RTC_YEARS_ADDR]);
+	}
+#endif
+	tmp->tm_wday = bcd2bin (data[RTC_DAY_ADDR]  & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+	uchar data[RTC_REG_CNT];
+
+	debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	data[RTC_SEC_ADDR]    = bin2bcd(tmp->tm_sec) &  0x7F;/*just in case*/
+	data[RTC_MIN_ADDR]    = bin2bcd(tmp->tm_min);
+	data[RTC_HOUR_ADDR]   = bin2bcd(tmp->tm_hour) & 0x3F;/*handle cent stuff later*/
+	data[RTC_DATE_ADDR]   = bin2bcd(tmp->tm_mday) & 0x3F;
+	data[RTC_MONTH_ADDR]  = bin2bcd(tmp->tm_mon);
+	data[RTC_DAY_ADDR]    = bin2bcd(tmp->tm_wday) & 0x07;
+
+	data[RTC_HOUR_ADDR]   |= 0x80;/*we will always use CEB*/
+
+	data[RTC_YEARS_ADDR]  = bin2bcd(tmp->tm_year%100);/*same thing either way*/
+#ifndef CFG_M41T11_EXT_CENTURY_DATA
+	if( ((tmp->tm_year - CFG_M41T11_BASE_YEAR) > 200) ||
+	    (tmp->tm_year < CFG_M41T11_BASE_YEAR) ){
+		printf( "m41t11 RTC setting year out of range!!need recompile\n" );
+	}
+	data[RTC_HOUR_ADDR] |= (tmp->tm_year - CFG_M41T11_BASE_YEAR) > 100 ? 0x40 : 0;
+#else
+	{
+		unsigned char cent;
+		cent = tmp->tm_year ? tmp->tm_year / 100 : 0;
+		data[RTC_HOUR_ADDR] |= (cent & 0x1) ? 0x40 : 0;
+		i2c_write(CFG_I2C_RTC_ADDR, M41T11_YEAR_DATA, 1, &cent, M41T11_YEAR_SIZE);
+	}
+#endif
+	i2c_write(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, data, RTC_REG_CNT);
+}
+
+void rtc_reset (void)
+{
+	unsigned char val;
+	/* clear all control & status registers */
+	i2c_read(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, &val, 1);
+	val = val & 0x7F;/*make sure we are running*/
+	i2c_write(CFG_I2C_RTC_ADDR, RTC_SEC_ADDR, 1, &val, RTC_REG_CNT);
+
+	i2c_read(CFG_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
+	val = val & 0x3F;/*turn off freq test keep calibration*/
+	i2c_write(CFG_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
+}
+
+int rtc_store(int addr, unsigned char* data, int size)
+{
+	/*don't let things wrap onto the time on a write*/
+	if( (addr+size) >= M41T11_STORAGE_SZ )
+		return 1;
+	return i2c_write( CFG_I2C_RTC_ADDR, REG_CNT+addr, 1, data, size );
+}
+
+int rtc_recall(int addr, unsigned char* data, int size)
+{
+	return i2c_read( CFG_I2C_RTC_ADDR, REG_CNT+addr, 1, data, size );
+}
+
+#endif
diff --git a/drivers/rtc/m48t35ax.c b/drivers/rtc/m48t35ax.c
new file mode 100644
index 0000000..0a0ffa8
--- /dev/null
+++ b/drivers/rtc/m48t35ax.c
@@ -0,0 +1,166 @@
+/*
+ * (C) Copyright 2001
+ * Erik Theisen,  Wave 7 Optics, etheisen@mindspring.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
+ */
+
+/*
+ * Date & Time support for ST Electronics M48T35Ax RTC
+ */
+
+/*#define       DEBUG */
+
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <config.h>
+
+#if defined(CONFIG_RTC_M48T35A) && defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read  (uchar reg);
+static void  rtc_write (uchar reg, uchar val);
+static uchar bin2bcd   (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+	uchar sec, min, hour, cent_day, date, month, year;
+	uchar ccr;			/* Clock control register */
+
+	/* Lock RTC for read using clock control register */
+	ccr = rtc_read(0);
+	ccr = ccr | 0x40;
+	rtc_write(0, ccr);
+
+	sec	= rtc_read (0x1);
+	min	= rtc_read (0x2);
+	hour	= rtc_read (0x3);
+	cent_day= rtc_read (0x4);
+	date	= rtc_read (0x5);
+	month   = rtc_read (0x6);
+	year	= rtc_read (0x7);
+
+	/* UNLock RTC */
+	ccr = rtc_read(0);
+	ccr = ccr & 0xBF;
+	rtc_write(0, ccr);
+
+	debug ( "Get RTC year: %02x month: %02x date: %02x cent_day: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, month, date, cent_day,
+		hour, min, sec );
+
+	tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+	tmp->tm_min  = bcd2bin (min  & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (date & 0x3F);
+	tmp->tm_mon  = bcd2bin (month & 0x1F);
+	tmp->tm_year = bcd2bin (year) + ((cent_day & 0x10) ? 2000 : 1900);
+	tmp->tm_wday = bcd2bin (cent_day & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+	uchar ccr;			/* Clock control register */
+	uchar century;
+
+	debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	/* Lock RTC for write using clock control register */
+	ccr = rtc_read(0);
+	ccr = ccr | 0x80;
+	rtc_write(0, ccr);
+
+	rtc_write (0x07, bin2bcd(tmp->tm_year % 100));
+	rtc_write (0x06, bin2bcd(tmp->tm_mon));
+	rtc_write (0x05, bin2bcd(tmp->tm_mday));
+
+	century = ((tmp->tm_year >= 2000) ? 0x10 : 0) | 0x20;
+	rtc_write (0x04, bin2bcd(tmp->tm_wday) | century);
+
+	rtc_write (0x03, bin2bcd(tmp->tm_hour));
+	rtc_write (0x02, bin2bcd(tmp->tm_min ));
+	rtc_write (0x01, bin2bcd(tmp->tm_sec ));
+
+	/* UNLock RTC */
+	ccr = rtc_read(0);
+	ccr = ccr & 0x7F;
+	rtc_write(0, ccr);
+}
+
+void rtc_reset (void)
+{
+	uchar val;
+
+	/* Clear all clock control registers */
+	rtc_write (0x0, 0x80);		/* No Read Lock or calibration */
+
+	/* Clear stop bit */
+	val = rtc_read (0x1);
+	val &= 0x7f;
+	rtc_write(0x1, val);
+
+	/* Enable century / disable frequency test */
+	val = rtc_read (0x4);
+	val = (val & 0xBF) | 0x20;
+	rtc_write(0x4, val);
+
+	/* Clear write lock */
+	rtc_write(0x0, 0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read (uchar reg)
+{
+	uchar val;
+	val = *(unsigned char *)
+		((CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE - 8) + reg);
+	return val;
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+	*(unsigned char *)
+		((CFG_NVRAM_BASE_ADDR + CFG_NVRAM_SIZE - 8) + reg) = val;
+}
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/max6900.c b/drivers/rtc/max6900.c
new file mode 100644
index 0000000..c75a8e0
--- /dev/null
+++ b/drivers/rtc/max6900.c
@@ -0,0 +1,131 @@
+/*
+ * (C) Copyright 2004
+ * 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
+ */
+
+/*
+ * Date & Time support for MAXIM MAX6900 RTC
+ */
+
+/* #define	DEBUG	*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_RTC_MAX6900) && defined(CONFIG_CMD_DATE)
+
+#ifndef	CFG_I2C_RTC_ADDR
+#define	CFG_I2C_RTC_ADDR	0x50
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read (uchar reg)
+{
+	return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+	i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+	udelay(2500);
+}
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+	uchar sec, min, hour, mday, wday, mon, cent, year;
+	int retry = 1;
+
+	do {
+		sec	= rtc_read (0x80);
+		min	= rtc_read (0x82);
+		hour	= rtc_read (0x84);
+		mday	= rtc_read (0x86);
+		mon	= rtc_read (0x88);
+		wday	= rtc_read (0x8a);
+		year	= rtc_read (0x8c);
+		cent	= rtc_read (0x92);
+		/*
+		 * Check for seconds rollover
+		 */
+		if ((sec != 59) || (rtc_read(0x80) == sec)){
+			retry = 0;
+		}
+	} while (retry);
+
+	debug ( "Get RTC year: %02x mon: %02x cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon, cent, mday, wday,
+		hour, min, sec );
+
+	tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+	tmp->tm_min  = bcd2bin (min  & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon & 0x1F);
+	tmp->tm_year = bcd2bin (year) + bcd2bin(cent) * 100;
+	tmp->tm_wday = bcd2bin (wday & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+
+	debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	rtc_write (0x9E, 0x00);
+	rtc_write (0x80, 0);	/* Clear seconds to ensure no rollover */
+	rtc_write (0x92, bin2bcd(tmp->tm_year / 100));
+	rtc_write (0x8c, bin2bcd(tmp->tm_year % 100));
+	rtc_write (0x8a, bin2bcd(tmp->tm_wday));
+	rtc_write (0x88, bin2bcd(tmp->tm_mon));
+	rtc_write (0x86, bin2bcd(tmp->tm_mday));
+	rtc_write (0x84, bin2bcd(tmp->tm_hour));
+	rtc_write (0x82, bin2bcd(tmp->tm_min ));
+	rtc_write (0x80, bin2bcd(tmp->tm_sec ));
+}
+
+void rtc_reset (void)
+{
+}
+
+#endif
diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c
new file mode 100644
index 0000000..ab377ed
--- /dev/null
+++ b/drivers/rtc/mc146818.c
@@ -0,0 +1,178 @@
+/*
+ * (C) Copyright 2001
+ * Denis Peter MPL AG Switzerland. d.peter@mpl.ch
+ *
+ * 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
+ */
+
+/*
+ * Date & Time support for the MC146818 (PIXX4) RTC
+ */
+
+/*#define	DEBUG*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_MC146818) && defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read  (uchar reg);
+static void  rtc_write (uchar reg, uchar val);
+static uchar bin2bcd   (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+#define RTC_PORT_MC146818		CFG_ISA_IO_BASE_ADDRESS +  0x70
+#define RTC_SECONDS       	0x00
+#define RTC_SECONDS_ALARM 	0x01
+#define RTC_MINUTES 				0x02
+#define RTC_MINUTES_ALARM 	0x03
+#define RTC_HOURS 					0x04
+#define RTC_HOURS_ALARM 		0x05
+#define RTC_DAY_OF_WEEK 		0x06
+#define RTC_DATE_OF_MONTH 	0x07
+#define RTC_MONTH 					0x08
+#define RTC_YEAR 						0x09
+#define RTC_CONFIG_A 				0x0A
+#define RTC_CONFIG_B 				0x0B
+#define RTC_CONFIG_C 				0x0C
+#define RTC_CONFIG_D 				0x0D
+
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+	uchar sec, min, hour, mday, wday, mon, year;
+  /* here check if rtc can be accessed */
+	while((rtc_read(RTC_CONFIG_A)&0x80)==0x80);
+	sec		= rtc_read (RTC_SECONDS);
+	min		= rtc_read (RTC_MINUTES);
+	hour	= rtc_read (RTC_HOURS);
+	mday	= rtc_read (RTC_DATE_OF_MONTH);
+	wday	= rtc_read (RTC_DAY_OF_WEEK);
+	mon		= rtc_read (RTC_MONTH);
+	year	= rtc_read (RTC_YEAR);
+#ifdef CONFIG_AMIGAONEG3SE
+	wday -= 1; /* VIA 686 stores Sunday = 1, Monday = 2, ... */
+#endif
+#ifdef RTC_DEBUG
+	printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon, mday, wday,
+		hour, min, sec );
+	printf ( "Alarms: month: %02x hour: %02x min: %02x sec: %02x\n",
+		rtc_read (RTC_CONFIG_D) & 0x3F,
+		rtc_read (RTC_HOURS_ALARM),
+		rtc_read (RTC_MINUTES_ALARM),
+		rtc_read (RTC_SECONDS_ALARM) );
+#endif
+	tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+	tmp->tm_min  = bcd2bin (min  & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon & 0x1F);
+	tmp->tm_year = bcd2bin (year);
+	tmp->tm_wday = bcd2bin (wday & 0x07);
+	if(tmp->tm_year<70)
+		tmp->tm_year+=2000;
+	else
+		tmp->tm_year+=1900;
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+	printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+#ifdef RTC_DEBUG
+	printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+	rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */
+
+	rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
+	rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
+#ifdef CONFIG_AMIGAONEG3SE
+	rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday)+1);
+#else
+	rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
+#endif
+	rtc_write (RTC_DATE_OF_MONTH, bin2bcd(tmp->tm_mday));
+	rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
+	rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
+	rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
+	rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
+
+}
+
+void rtc_reset (void)
+{
+	rtc_write(RTC_CONFIG_B,0x82); /* disables the RTC to update the regs */
+	rtc_write(RTC_CONFIG_A,0x20); /* Normal OP */
+	rtc_write(RTC_CONFIG_B,0x00);
+	rtc_write(RTC_CONFIG_B,0x00);
+	rtc_write(RTC_CONFIG_B,0x02); /* enables the RTC to update the regs */
+}
+
+/* ------------------------------------------------------------------------- */
+
+#ifdef CFG_RTC_REG_BASE_ADDR
+/*
+ * use direct memory access
+ */
+static uchar rtc_read (uchar reg)
+{
+	return(in8(CFG_RTC_REG_BASE_ADDR+reg));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+	out8(CFG_RTC_REG_BASE_ADDR+reg, val);
+}
+#else
+static uchar rtc_read (uchar reg)
+{
+	out8(RTC_PORT_MC146818,reg);
+	return(in8(RTC_PORT_MC146818+1));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+	out8(RTC_PORT_MC146818,reg);
+	out8(RTC_PORT_MC146818+1,val);
+}
+#endif
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/mcfrtc.c b/drivers/rtc/mcfrtc.c
new file mode 100644
index 0000000..27386e5
--- /dev/null
+++ b/drivers/rtc/mcfrtc.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
+ * TsiChung Liew (Tsi-Chung.Liew@freescale.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>
+
+#if defined(CONFIG_MCFRTC) && defined(CONFIG_CMD_DATE)
+
+#include <command.h>
+#include <rtc.h>
+#include <asm/immap.h>
+#include <asm/rtc.h>
+
+#undef RTC_DEBUG
+
+#ifndef CFG_MCFRTC_BASE
+#error RTC_BASE is not defined!
+#endif
+
+#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+#define	STARTOFTIME		1970
+
+void rtc_get(struct rtc_time *tmp)
+{
+	volatile rtc_t *rtc = (rtc_t *) (CFG_MCFRTC_BASE);
+
+	int rtc_days, rtc_hrs, rtc_mins;
+	int tim;
+
+	rtc_days = rtc->days;
+	rtc_hrs = rtc->hourmin >> 8;
+	rtc_mins = RTC_HOURMIN_MINUTES(rtc->hourmin);
+
+	tim = (rtc_days * 24) + rtc_hrs;
+	tim = (tim * 60) + rtc_mins;
+	tim = (tim * 60) + rtc->seconds;
+
+	to_tm(tim, tmp);
+
+	tmp->tm_yday = 0;
+	tmp->tm_isdst = 0;
+
+#ifdef RTC_DEBUG
+	printf("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+}
+
+void rtc_set(struct rtc_time *tmp)
+{
+	volatile rtc_t *rtc = (rtc_t *) (CFG_MCFRTC_BASE);
+
+	static int month_days[12] = {
+		31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+	};
+	int days, i, months;
+
+	if (tmp->tm_year > 2037) {
+		printf("Unable to handle. Exceeding integer limitation!\n");
+		tmp->tm_year = 2027;
+	}
+#ifdef RTC_DEBUG
+	printf("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+	       tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+	       tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+
+	/* calculate days by years */
+	for (i = STARTOFTIME, days = 0; i < tmp->tm_year; i++) {
+		days += 365 + isleap(i);
+	}
+
+	/* calculate days by months */
+	months = tmp->tm_mon - 1;
+	for (i = 0; i < months; i++) {
+		days += month_days[i];
+
+		if (i == 1)
+			days += isleap(i);
+	}
+
+	days += tmp->tm_mday - 1;
+
+	rtc->days = days;
+	rtc->hourmin = (tmp->tm_hour << 8) | tmp->tm_min;
+	rtc->seconds = tmp->tm_sec;
+}
+
+void rtc_reset(void)
+{
+	volatile rtc_t *rtc = (rtc_t *) (CFG_MCFRTC_BASE);
+
+	if ((rtc->cr & RTC_CR_EN) == 0) {
+		printf("real-time-clock was stopped. Now starting...\n");
+		rtc->cr |= RTC_CR_EN;
+	}
+
+	rtc->cr |= RTC_CR_SWR;
+}
+
+#endif				/* CONFIG_MCFRTC && CONFIG_CMD_DATE */
diff --git a/drivers/rtc/mk48t59.c b/drivers/rtc/mk48t59.c
new file mode 100644
index 0000000..bacdb5b
--- /dev/null
+++ b/drivers/rtc/mk48t59.c
@@ -0,0 +1,237 @@
+/*
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.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
+ */
+
+/*
+ * Date & Time support for the MK48T59 RTC
+ */
+
+#undef	RTC_DEBUG
+
+#include <common.h>
+#include <command.h>
+#include <config.h>
+#include <rtc.h>
+#include <mk48t59.h>
+
+#if defined(CONFIG_RTC_MK48T59)
+
+#if defined(CONFIG_BAB7xx)
+
+static uchar rtc_read (short reg)
+{
+	out8(RTC_PORT_ADDR0, reg & 0xFF);
+	out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
+	return in8(RTC_PORT_DATA);
+}
+
+static void rtc_write (short reg, uchar val)
+{
+	out8(RTC_PORT_ADDR0, reg & 0xFF);
+	out8(RTC_PORT_ADDR1, (reg>>8) & 0xFF);
+	out8(RTC_PORT_DATA, val);
+}
+
+#elif defined(CONFIG_PCIPPC2)
+
+#include "../board/pcippc2/pcippc2.h"
+
+static uchar rtc_read (short reg)
+{
+	return in8(RTC(reg));
+}
+
+static void rtc_write (short reg, uchar val)
+{
+	out8(RTC(reg),val);
+}
+
+#elif defined(CONFIG_AMIGAONEG3SE)
+
+#include "../board/MAI/AmigaOneG3SE/via686.h"
+#include "../board/MAI/AmigaOneG3SE/memio.h"
+
+
+static uchar rtc_read (short reg)
+{
+    out_byte(CMOS_ADDR, (uint8)reg);
+    return in_byte(CMOS_DATA);
+}
+
+static void rtc_write (short reg, uchar val)
+{
+    out_byte(CMOS_ADDR, (uint8)reg);
+    out_byte(CMOS_DATA, (uint8)val);
+}
+
+#elif defined(CONFIG_EVAL5200)
+
+static uchar rtc_read (short reg)
+{
+	return in8(RTC(reg));
+}
+
+static void rtc_write (short reg, uchar val)
+{
+	out8(RTC(reg),val);
+}
+
+#else
+# error Board specific rtc access functions should be supplied
+#endif
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+/* ------------------------------------------------------------------------- */
+
+void *nvram_read(void *dest, const short src, size_t count)
+{
+	uchar *d = (uchar *) dest;
+	short s = src;
+
+	while (count--)
+		*d++ = rtc_read(s++);
+
+	return dest;
+}
+
+void nvram_write(short dest, const void *src, size_t count)
+{
+	short d = dest;
+	uchar *s = (uchar *) src;
+
+	while (count--)
+		rtc_write(d++, *s++);
+}
+
+#if defined(CONFIG_CMD_DATE)
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+	uchar save_ctrl_a;
+	uchar sec, min, hour, mday, wday, mon, year;
+
+	/* Simple: freeze the clock, read it and allow updates again */
+	save_ctrl_a = rtc_read(RTC_CONTROLA);
+
+	/* Set the register to read the value. */
+	save_ctrl_a |= RTC_CA_READ;
+	rtc_write(RTC_CONTROLA, save_ctrl_a);
+
+	sec		= rtc_read (RTC_SECONDS);
+	min		= rtc_read (RTC_MINUTES);
+	hour	= rtc_read (RTC_HOURS);
+	mday	= rtc_read (RTC_DAY_OF_MONTH);
+	wday	= rtc_read (RTC_DAY_OF_WEEK);
+	mon		= rtc_read (RTC_MONTH);
+	year	= rtc_read (RTC_YEAR);
+
+	/* re-enable update */
+	save_ctrl_a &= ~RTC_CA_READ;
+	rtc_write(RTC_CONTROLA, save_ctrl_a);
+
+#ifdef RTC_DEBUG
+	printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon, mday, wday,
+		hour, min, sec );
+#endif
+	tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+	tmp->tm_min  = bcd2bin (min  & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon & 0x1F);
+	tmp->tm_year = bcd2bin (year);
+	tmp->tm_wday = bcd2bin (wday & 0x07);
+	if(tmp->tm_year<70)
+		tmp->tm_year+=2000;
+	else
+		tmp->tm_year+=1900;
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+	printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+	uchar save_ctrl_a;
+
+#ifdef RTC_DEBUG
+	printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+	save_ctrl_a = rtc_read(RTC_CONTROLA);
+
+	save_ctrl_a |= RTC_CA_WRITE;
+	rtc_write(RTC_CONTROLA, save_ctrl_a); /* disables the RTC to update the regs */
+
+	rtc_write (RTC_YEAR, bin2bcd(tmp->tm_year % 100));
+	rtc_write (RTC_MONTH, bin2bcd(tmp->tm_mon));
+
+	rtc_write (RTC_DAY_OF_WEEK, bin2bcd(tmp->tm_wday));
+	rtc_write (RTC_DAY_OF_MONTH, bin2bcd(tmp->tm_mday));
+	rtc_write (RTC_HOURS, bin2bcd(tmp->tm_hour));
+	rtc_write (RTC_MINUTES, bin2bcd(tmp->tm_min ));
+	rtc_write (RTC_SECONDS, bin2bcd(tmp->tm_sec ));
+
+	save_ctrl_a &= ~RTC_CA_WRITE;
+	rtc_write(RTC_CONTROLA, save_ctrl_a); /* enables the RTC to update the regs */
+}
+
+void rtc_reset (void)
+{
+	uchar control_b;
+
+	/*
+	 * Start oscillator here.
+	 */
+	control_b = rtc_read(RTC_CONTROLB);
+
+	control_b &= ~RTC_CB_STOP;
+	rtc_write(RTC_CONTROLB, control_b);
+}
+
+void rtc_set_watchdog(short multi, short res)
+{
+	uchar wd_value;
+
+	wd_value = RTC_WDS | ((multi & 0x1F) << 2) | (res & 0x3);
+	rtc_write(RTC_WATCHDOG, wd_value);
+}
+
+#endif
+#endif	/* CONFIG_RTC_MK48T59 */
diff --git a/drivers/rtc/mpc5xxx.c b/drivers/rtc/mpc5xxx.c
new file mode 100644
index 0000000..216386a
--- /dev/null
+++ b/drivers/rtc/mpc5xxx.c
@@ -0,0 +1,140 @@
+/*
+ * (C) Copyright 2004
+ * Reinhard Meyer, EMK Elektronik GmbH
+ * r.meyer@emk-elektronik.de
+ * www.emk-elektronik.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
+ */
+
+/*****************************************************************************
+ * Date & Time support for internal RTC of MPC52xx
+ *****************************************************************************/
+/*#define	DEBUG*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_MPC5200) && defined(CONFIG_CMD_DATE)
+
+/*****************************************************************************
+ * this structure should be defined in mpc5200.h ...
+ *****************************************************************************/
+typedef struct rtc5200 {
+	volatile ulong	tsr;	/* MBAR+0x800: time set register */
+	volatile ulong	dsr;	/* MBAR+0x804: data set register */
+	volatile ulong	nysr;	/* MBAR+0x808: new year and stopwatch register */
+	volatile ulong	aier;	/* MBAR+0x80C: alarm and interrupt enable register */
+	volatile ulong	ctr;	/* MBAR+0x810: current time register */
+	volatile ulong	cdr;	/* MBAR+0x814: current data register */
+	volatile ulong	asir;	/* MBAR+0x818: alarm and stopwatch interupt register */
+	volatile ulong	piber;	/* MBAR+0x81C: periodic interrupt and bus error register */
+	volatile ulong	trdr;	/* MBAR+0x820: test register/divides register */
+} RTC5200;
+
+#define	RTC_SET		0x02000000
+#define	RTC_PAUSE	0x01000000
+
+/*****************************************************************************
+ * get time
+ *****************************************************************************/
+void rtc_get (struct rtc_time *tmp)
+{
+	RTC5200	*rtc = (RTC5200 *) (CFG_MBAR+0x800);
+	ulong time, date, time2;
+
+	/* read twice to avoid getting a funny time when the second is just changing */
+	do {
+		time = rtc->ctr;
+		date = rtc->cdr;
+		time2 = rtc->ctr;
+	} while (time != time2);
+
+	tmp->tm_year	= date & 0xfff;
+	tmp->tm_mon		= (date >> 24) & 0xf;
+	tmp->tm_mday	= (date >> 16) & 0x1f;
+	tmp->tm_wday	= (date >> 21) & 7;
+	/* sunday is 7 in 5200 but 0 in rtc_time */
+	if (tmp->tm_wday == 7)
+		tmp->tm_wday = 0;
+	tmp->tm_hour	= (time >> 16) & 0x1f;
+	tmp->tm_min		= (time >> 8) & 0x3f;
+	tmp->tm_sec		= time & 0x3f;
+
+	debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+/*****************************************************************************
+ * set time
+ *****************************************************************************/
+void rtc_set (struct rtc_time *tmp)
+{
+	RTC5200	*rtc = (RTC5200 *) (CFG_MBAR+0x800);
+	ulong time, date, year;
+
+	debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	time = (tmp->tm_hour << 16) | (tmp->tm_min << 8) | tmp->tm_sec;
+	date = (tmp->tm_mon << 16) | tmp->tm_mday;
+	if (tmp->tm_wday == 0)
+		date |= (7 << 8);
+	else
+		date |= (tmp->tm_wday << 8);
+	year = tmp->tm_year;
+
+	/* mask unwanted bits that might show up when rtc_time is corrupt */
+	time &= 0x001f3f3f;
+	date &= 0x001f071f;
+	year &= 0x00000fff;
+
+	/* pause and set the RTC */
+	rtc->nysr = year;
+	rtc->dsr = date | RTC_PAUSE;
+	udelay (1000);
+	rtc->dsr = date | RTC_PAUSE | RTC_SET;
+	udelay (1000);
+	rtc->dsr = date | RTC_PAUSE;
+	udelay (1000);
+	rtc->dsr = date;
+	udelay (1000);
+
+	rtc->tsr = time | RTC_PAUSE;
+	udelay (1000);
+	rtc->tsr = time | RTC_PAUSE | RTC_SET;
+	udelay (1000);
+	rtc->tsr = time | RTC_PAUSE;
+	udelay (1000);
+	rtc->tsr = time;
+	udelay (1000);
+}
+
+/*****************************************************************************
+ * reset rtc circuit
+ *****************************************************************************/
+void rtc_reset (void)
+{
+	return;	/* nothing to do */
+}
+
+#endif
diff --git a/drivers/rtc/mpc8xx.c b/drivers/rtc/mpc8xx.c
new file mode 100644
index 0000000..8d10c0e
--- /dev/null
+++ b/drivers/rtc/mpc8xx.c
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2001
+ * 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
+ */
+
+/*
+ * Date & Time support for internal RTC of MPC8xx
+ */
+
+/*#define	DEBUG*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+
+#if defined(CONFIG_RTC_MPC8xx) && defined(CONFIG_CMD_DATE)
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+	ulong tim;
+
+	tim = immr->im_sit.sit_rtc;
+
+	to_tm (tim, tmp);
+
+	debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+	volatile immap_t *immr = (immap_t *)CFG_IMMR;
+	ulong tim;
+
+	debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
+		      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	immr->im_sitk.sitk_rtck = KAPWR_KEY;
+	immr->im_sit.sit_rtc = tim;
+}
+
+void rtc_reset (void)
+{
+	return;	/* nothing to do */
+}
+
+#endif
diff --git a/drivers/rtc/pcf8563.c b/drivers/rtc/pcf8563.c
new file mode 100644
index 0000000..2d73d5d
--- /dev/null
+++ b/drivers/rtc/pcf8563.c
@@ -0,0 +1,144 @@
+/*
+ * (C) Copyright 2001
+ * 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
+ */
+
+/*
+ * Date & Time support for Philips PCF8563 RTC
+ */
+
+/* #define	DEBUG	*/
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_RTC_PCF8563) && defined(CONFIG_CMD_DATE)
+
+static uchar rtc_read  (uchar reg);
+static void  rtc_write (uchar reg, uchar val);
+static uchar bin2bcd   (unsigned int n);
+static unsigned bcd2bin(uchar c);
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+	uchar sec, min, hour, mday, wday, mon_cent, year;
+
+	sec	= rtc_read (0x02);
+	min	= rtc_read (0x03);
+	hour	= rtc_read (0x04);
+	mday	= rtc_read (0x05);
+	wday	= rtc_read (0x06);
+	mon_cent= rtc_read (0x07);
+	year	= rtc_read (0x08);
+
+	debug ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon_cent, mday, wday,
+		hour, min, sec );
+	debug ( "Alarms: wday: %02x day: %02x hour: %02x min: %02x\n",
+		rtc_read (0x0C),
+		rtc_read (0x0B),
+		rtc_read (0x0A),
+		rtc_read (0x09) );
+
+	if (sec & 0x80) {
+		puts ("### Warning: RTC Low Voltage - date/time not reliable\n");
+	}
+
+	tmp->tm_sec  = bcd2bin (sec  & 0x7F);
+	tmp->tm_min  = bcd2bin (min  & 0x7F);
+	tmp->tm_hour = bcd2bin (hour & 0x3F);
+	tmp->tm_mday = bcd2bin (mday & 0x3F);
+	tmp->tm_mon  = bcd2bin (mon_cent & 0x1F);
+	tmp->tm_year = bcd2bin (year) + ((mon_cent & 0x80) ? 2000 : 1900);
+	tmp->tm_wday = bcd2bin (wday & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+
+	debug ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+	uchar century;
+
+	debug ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	rtc_write (0x08, bin2bcd(tmp->tm_year % 100));
+
+	century = (tmp->tm_year >= 2000) ? 0x80 : 0;
+	rtc_write (0x07, bin2bcd(tmp->tm_mon) | century);
+
+	rtc_write (0x06, bin2bcd(tmp->tm_wday));
+	rtc_write (0x05, bin2bcd(tmp->tm_mday));
+	rtc_write (0x04, bin2bcd(tmp->tm_hour));
+	rtc_write (0x03, bin2bcd(tmp->tm_min ));
+	rtc_write (0x02, bin2bcd(tmp->tm_sec ));
+}
+
+void rtc_reset (void)
+{
+	/* clear all control & status registers */
+	rtc_write (0x00, 0x00);
+	rtc_write (0x01, 0x00);
+	rtc_write (0x0D, 0x00);
+
+	/* clear Voltage Low bit */
+	rtc_write (0x02, rtc_read (0x02) & 0x7F);
+
+	/* reset all alarms */
+	rtc_write (0x09, 0x00);
+	rtc_write (0x0A, 0x00);
+	rtc_write (0x0B, 0x00);
+	rtc_write (0x0C, 0x00);
+}
+
+/* ------------------------------------------------------------------------- */
+
+static uchar rtc_read (uchar reg)
+{
+	return (i2c_reg_read (CFG_I2C_RTC_ADDR, reg));
+}
+
+static void rtc_write (uchar reg, uchar val)
+{
+	i2c_reg_write (CFG_I2C_RTC_ADDR, reg, val);
+}
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+#endif
diff --git a/drivers/rtc/rs5c372.c b/drivers/rtc/rs5c372.c
new file mode 100644
index 0000000..3d1346e
--- /dev/null
+++ b/drivers/rtc/rs5c372.c
@@ -0,0 +1,302 @@
+/*
+ * rs5c372.c
+ *
+ * Device driver for Ricoh's Real Time Controller RS5C372A.
+ *
+ * Copyright (C) 2004 Gary Jennejohn garyj@denx.de
+ *
+ * Based in part in ds1307.c -
+ * (C) Copyright 2001, 2002, 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Keith Outwater, keith_outwater@mvis.com`
+ * Steven Scholz, steven.scholz@imc-berlin.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 version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 <command.h>
+#include <rtc.h>
+#include <i2c.h>
+
+#if defined(CONFIG_RTC_RS5C372A) && defined(CONFIG_CMD_DATE)
+/*
+ * Reads are always done starting with register 15, which requires some
+ * jumping-through-hoops to access the data correctly.
+ *
+ * Writes are always done starting with register 0.
+ */
+
+#define DEBUG 0
+
+#if DEBUG
+static unsigned int rtc_debug = DEBUG;
+#else
+#define rtc_debug 0	/* gcc will remove all the debug code for us */
+#endif
+
+#ifndef CFG_I2C_RTC_ADDR
+#define CFG_I2C_RTC_ADDR 0x32
+#endif
+
+#define RS5C372_RAM_SIZE 0x10
+#define RATE_32000HZ	0x80	/* Rate Select 32.000KHz */
+#define RATE_32768HZ	0x00	/* Rate Select 32.768KHz */
+
+#define STATUS_XPT  0x10    /* data invalid because voltage was 0 */
+
+#define USE_24HOUR_MODE 0x20
+#define TWELVE_HOUR_MODE(n) ((((n) >> 5) & 1) == 0)
+#define HOURS_AP(n)	(((n) >> 5) & 1)
+#define HOURS_12(n)	bcd2bin((n) & 0x1F)
+#define HOURS_24(n)	bcd2bin((n) & 0x3F)
+
+
+static uchar bin2bcd (unsigned int n);
+static unsigned bcd2bin (uchar c);
+
+static int setup_done = 0;
+
+static int
+rs5c372_readram(unsigned char *buf, int len)
+{
+	int ret;
+
+	ret = i2c_read(CFG_I2C_RTC_ADDR, 0, 0, buf, len);
+	if (ret != 0) {
+		printf("%s: failed to read\n", __FUNCTION__);
+		return ret;
+	}
+
+	if (buf[0] & STATUS_XPT)
+		printf("### Warning: RTC lost power\n");
+
+	return ret;
+}
+
+static void
+rs5c372_enable(void)
+{
+	unsigned char buf[RS5C372_RAM_SIZE + 1];
+	int ret;
+
+	/* note that this returns reg. 15 in buf[1] */
+	ret = rs5c372_readram(&buf[1], RS5C372_RAM_SIZE);
+	if (ret != 0) {
+		printf("%s: failed\n", __FUNCTION__);
+		return;
+	}
+
+	buf[0] = 0;
+	/* we want to start writing at register 0 so we have to copy the */
+	/* register contents up one slot */
+	for (ret = 2; ret < 9; ret++)
+		buf[ret - 1] = buf[ret];
+	/* registers 0 to 6 (time values) are not touched */
+	buf[8] = RATE_32768HZ; /* reg. 7 */
+	buf[9] = 0; /* reg. 8 */
+	buf[10] = 0; /* reg. 9 */
+	buf[11] = 0; /* reg. 10 */
+	buf[12] = 0; /* reg. 11 */
+	buf[13] = 0; /* reg. 12 */
+	buf[14] = 0; /* reg. 13 */
+	buf[15] = 0; /* reg. 14 */
+	buf[16] = USE_24HOUR_MODE; /* reg. 15 */
+	ret = i2c_write(CFG_I2C_RTC_ADDR, 0, 0, buf, RS5C372_RAM_SIZE+1);
+	if (ret != 0) {
+		printf("%s: failed\n", __FUNCTION__);
+		return;
+	}
+	setup_done = 1;
+
+	return;
+}
+
+static void
+rs5c372_convert_to_time(struct rtc_time *dt, unsigned char *buf)
+{
+	/* buf[0] is register 15 */
+	dt->tm_sec = bcd2bin(buf[1]);
+	dt->tm_min = bcd2bin(buf[2]);
+
+	if (TWELVE_HOUR_MODE(buf[0])) {
+		dt->tm_hour = HOURS_12(buf[3]);
+		if (HOURS_AP(buf[3])) /* PM */
+			dt->tm_hour += 12;
+	} else /* 24-hour-mode */
+		dt->tm_hour = HOURS_24(buf[3]);
+
+	dt->tm_mday = bcd2bin(buf[5]);
+	dt->tm_mon = bcd2bin(buf[6]);
+	dt->tm_year = bcd2bin(buf[7]);
+	if (dt->tm_year >= 70)
+		dt->tm_year += 1900;
+	else
+		dt->tm_year += 2000;
+	/* 0 is Sunday */
+	dt->tm_wday = bcd2bin(buf[4] & 0x07);
+	dt->tm_yday = 0;
+	dt->tm_isdst= 0;
+
+	if(rtc_debug > 2) {
+		printf("rs5c372_convert_to_time: year = %d\n", dt->tm_year);
+		printf("rs5c372_convert_to_time: mon  = %d\n", dt->tm_mon);
+		printf("rs5c372_convert_to_time: mday = %d\n", dt->tm_mday);
+		printf("rs5c372_convert_to_time: hour = %d\n", dt->tm_hour);
+		printf("rs5c372_convert_to_time: min  = %d\n", dt->tm_min);
+		printf("rs5c372_convert_to_time: sec  = %d\n", dt->tm_sec);
+	}
+}
+
+/*
+ * Get the current time from the RTC
+ */
+void
+rtc_get (struct rtc_time *tmp)
+{
+	unsigned char buf[RS5C372_RAM_SIZE];
+	int ret;
+
+	if (!setup_done)
+		rs5c372_enable();
+
+	if (!setup_done)
+		return;
+
+	memset(buf, 0, sizeof(buf));
+
+	/* note that this returns reg. 15 in buf[0] */
+	ret = rs5c372_readram(buf, RS5C372_RAM_SIZE);
+	if (ret != 0) {
+		printf("%s: failed\n", __FUNCTION__);
+		return;
+	}
+
+	rs5c372_convert_to_time(tmp, buf);
+
+	return;
+}
+
+/*
+ * Set the RTC
+ */
+void
+rtc_set (struct rtc_time *tmp)
+{
+	unsigned char buf[8], reg15;
+	int ret;
+
+	if (!setup_done)
+		rs5c372_enable();
+
+	if (!setup_done)
+		return;
+
+	if(rtc_debug > 2) {
+		printf("rtc_set: tm_year = %d\n", tmp->tm_year);
+		printf("rtc_set: tm_mon	 = %d\n", tmp->tm_mon);
+		printf("rtc_set: tm_mday = %d\n", tmp->tm_mday);
+		printf("rtc_set: tm_hour = %d\n", tmp->tm_hour);
+		printf("rtc_set: tm_min	 = %d\n", tmp->tm_min);
+		printf("rtc_set: tm_sec	 = %d\n", tmp->tm_sec);
+	}
+
+	memset(buf, 0, sizeof(buf));
+
+	/* only read register 15 */
+	ret = i2c_read(CFG_I2C_RTC_ADDR, 0, 0, buf, 1);
+
+	if (ret == 0) {
+		/* need to save register 15 */
+		reg15 = buf[0];
+		buf[0] = 0;	/* register address on RS5C372 */
+		buf[1] = bin2bcd(tmp->tm_sec);
+		buf[2] = bin2bcd(tmp->tm_min);
+		/* need to handle 12 hour mode */
+		if (TWELVE_HOUR_MODE(reg15)) {
+			if (tmp->tm_hour >= 12) { /* PM */
+				/* 12 PM is a special case */
+				if (tmp->tm_hour == 12)
+					buf[3] = bin2bcd(tmp->tm_hour);
+				else
+					buf[3] = bin2bcd(tmp->tm_hour - 12);
+				buf[3] |= 0x20;
+			}
+		} else {
+			buf[3] = bin2bcd(tmp->tm_hour);
+		}
+
+		buf[4] = bin2bcd(tmp->tm_wday);
+		buf[5] = bin2bcd(tmp->tm_mday);
+		buf[6] = bin2bcd(tmp->tm_mon);
+		if (tmp->tm_year < 1970 || tmp->tm_year > 2069)
+			printf("WARNING: year should be between 1970 and 2069!\n");
+		buf[7] = bin2bcd(tmp->tm_year % 100);
+
+		ret = i2c_write(CFG_I2C_RTC_ADDR, 0, 0, buf, 8);
+		if (ret != 0)
+			printf("rs5c372_set_datetime(), i2c_master_send() returned %d\n",ret);
+	}
+
+	return;
+}
+
+/*
+ * Reset the RTC. We set the date back to 1970-01-01.
+ */
+void
+rtc_reset (void)
+{
+	struct rtc_time tmp;
+
+	if (!setup_done)
+		rs5c372_enable();
+
+	if (!setup_done)
+		return;
+
+	tmp.tm_year = 1970;
+	tmp.tm_mon = 1;
+	/* Jan. 1, 1970 was a Thursday */
+	tmp.tm_wday= 4;
+	tmp.tm_mday= 1;
+	tmp.tm_hour = 0;
+	tmp.tm_min = 0;
+	tmp.tm_sec = 0;
+
+	rtc_set(&tmp);
+
+	printf ("RTC:	%4d-%02d-%02d %2d:%02d:%02d UTC\n",
+		tmp.tm_year, tmp.tm_mon, tmp.tm_mday,
+		tmp.tm_hour, tmp.tm_min, tmp.tm_sec);
+
+	return;
+}
+
+static unsigned int
+bcd2bin (unsigned char n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char
+bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+#endif
diff --git a/drivers/rtc/s3c24x0_rtc.c b/drivers/rtc/s3c24x0_rtc.c
new file mode 100644
index 0000000..7f8b4fa
--- /dev/null
+++ b/drivers/rtc/s3c24x0_rtc.c
@@ -0,0 +1,178 @@
+/*
+ * (C) Copyright 2003
+ * David Müller ELSOFT AG Switzerland. d.mueller@elsoft.ch
+ *
+ * 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
+ */
+
+/*
+ * Date & Time support for the built-in Samsung S3C24X0 RTC
+ */
+
+#include <common.h>
+#include <command.h>
+
+#if defined(CONFIG_RTC_S3C24X0) && (defined(CONFIG_CMD_DATE))
+
+#if defined(CONFIG_S3C2400)
+#include <s3c2400.h>
+#elif defined(CONFIG_S3C2410)
+#include <s3c2410.h>
+#endif
+
+#include <rtc.h>
+
+/*#define	DEBUG*/
+
+typedef enum {
+	RTC_ENABLE,
+	RTC_DISABLE
+} RTC_ACCESS;
+
+
+static inline void SetRTC_Access(RTC_ACCESS a)
+{
+	S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
+	switch (a) {
+		case RTC_ENABLE:
+			rtc->RTCCON |= 0x01; break;
+
+		case RTC_DISABLE:
+			rtc->RTCCON &= ~0x01; break;
+	}
+}
+
+static unsigned bcd2bin (uchar n)
+{
+	return ((((n >> 4) & 0x0F) * 10) + (n & 0x0F));
+}
+
+static unsigned char bin2bcd (unsigned int n)
+{
+	return (((n / 10) << 4) | (n % 10));
+}
+
+/* ------------------------------------------------------------------------- */
+
+void rtc_get (struct rtc_time *tmp)
+{
+	S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
+	uchar sec, min, hour, mday, wday, mon, year;
+	uchar a_sec,a_min, a_hour, a_date, a_mon, a_year, a_armed;
+
+	/* enable access to RTC registers */
+	SetRTC_Access(RTC_ENABLE);
+
+	/* read RTC registers */
+	do {
+		sec	= rtc->BCDSEC;
+		min	= rtc->BCDMIN;
+		hour	= rtc->BCDHOUR;
+		mday	= rtc->BCDDATE;
+		wday	= rtc->BCDDAY;
+		mon	= rtc->BCDMON;
+		year	= rtc->BCDYEAR;
+	} while (sec != rtc->BCDSEC);
+
+	/* read ALARM registers */
+	a_sec	= rtc->ALMSEC;
+	a_min	= rtc->ALMMIN;
+	a_hour	= rtc->ALMHOUR;
+	a_date	= rtc->ALMDATE;
+	a_mon	= rtc->ALMMON;
+	a_year	= rtc->ALMYEAR;
+	a_armed	= rtc->RTCALM;
+
+	/* disable access to RTC registers */
+	SetRTC_Access(RTC_DISABLE);
+
+#ifdef RTC_DEBUG
+	printf ( "Get RTC year: %02x mon/cent: %02x mday: %02x wday: %02x "
+		"hr: %02x min: %02x sec: %02x\n",
+		year, mon, mday, wday,
+		hour, min, sec);
+	printf ( "Alarms: %02x: year: %02x month: %02x date: %02x hour: %02x min: %02x sec: %02x\n",
+		a_armed,
+		a_year, a_mon, a_date,
+		a_hour, a_min, a_sec);
+#endif
+
+	tmp->tm_sec  = bcd2bin(sec  & 0x7F);
+	tmp->tm_min  = bcd2bin(min  & 0x7F);
+	tmp->tm_hour = bcd2bin(hour & 0x3F);
+	tmp->tm_mday = bcd2bin(mday & 0x3F);
+	tmp->tm_mon  = bcd2bin(mon & 0x1F);
+	tmp->tm_year = bcd2bin(year);
+	tmp->tm_wday = bcd2bin(wday & 0x07);
+	if(tmp->tm_year<70)
+		tmp->tm_year+=2000;
+	else
+		tmp->tm_year+=1900;
+	tmp->tm_yday = 0;
+	tmp->tm_isdst= 0;
+#ifdef RTC_DEBUG
+	printf ( "Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+}
+
+void rtc_set (struct rtc_time *tmp)
+{
+	S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
+	uchar sec, min, hour, mday, wday, mon, year;
+
+#ifdef RTC_DEBUG
+	printf ( "Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+#endif
+	year	= bin2bcd(tmp->tm_year % 100);
+	mon	= bin2bcd(tmp->tm_mon);
+	wday	= bin2bcd(tmp->tm_wday);
+	mday	= bin2bcd(tmp->tm_mday);
+	hour	= bin2bcd(tmp->tm_hour);
+	min	= bin2bcd(tmp->tm_min);
+	sec	= bin2bcd(tmp->tm_sec);
+
+	/* enable access to RTC registers */
+	SetRTC_Access(RTC_ENABLE);
+
+	/* write RTC registers */
+	rtc->BCDSEC	= sec;
+	rtc->BCDMIN	= min;
+	rtc->BCDHOUR	= hour;
+	rtc->BCDDATE	= mday;
+	rtc->BCDDAY	= wday;
+	rtc->BCDMON	= mon;
+	rtc->BCDYEAR	= year;
+
+	/* disable access to RTC registers */
+	SetRTC_Access(RTC_DISABLE);
+}
+
+void rtc_reset (void)
+{
+	S3C24X0_RTC * const rtc = S3C24X0_GetBase_RTC();
+
+	rtc->RTCCON = (rtc->RTCCON & ~0x06) | 0x08;
+	rtc->RTCCON &= ~(0x08|0x01);
+}
+
+#endif
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 93c68dd..735c630 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -25,8 +25,19 @@
 
 LIB 	:= $(obj)libserial.a
 
-COBJS 	:= mcfuart.o
+COBJS-y += atmel_usart.o
+COBJS-y += mcfuart.o
+COBJS-y += ns9750_serial.o
+COBJS-y += ns16550.o
+COBJS-y += s3c4510b_uart.o
+COBJS-y += serial.o
+COBJS-y += serial_max3100.o
+COBJS-y += serial_pl010.o
+COBJS-y += serial_pl011.o
+COBJS-y += serial_xuartlite.o
+COBJS-y += usbtty.o
 
+COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
 OBJS 	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/atmel_usart.c b/drivers/serial/atmel_usart.c
similarity index 100%
rename from drivers/atmel_usart.c
rename to drivers/serial/atmel_usart.c
diff --git a/drivers/atmel_usart.h b/drivers/serial/atmel_usart.h
similarity index 100%
rename from drivers/atmel_usart.h
rename to drivers/serial/atmel_usart.h
diff --git a/drivers/ns16550.c b/drivers/serial/ns16550.c
similarity index 100%
rename from drivers/ns16550.c
rename to drivers/serial/ns16550.c
diff --git a/drivers/ns9750_serial.c b/drivers/serial/ns9750_serial.c
similarity index 100%
rename from drivers/ns9750_serial.c
rename to drivers/serial/ns9750_serial.c
diff --git a/drivers/s3c4510b_uart.c b/drivers/serial/s3c4510b_uart.c
similarity index 100%
rename from drivers/s3c4510b_uart.c
rename to drivers/serial/s3c4510b_uart.c
diff --git a/drivers/s3c4510b_uart.h b/drivers/serial/s3c4510b_uart.h
similarity index 100%
rename from drivers/s3c4510b_uart.h
rename to drivers/serial/s3c4510b_uart.h
diff --git a/drivers/serial.c b/drivers/serial/serial.c
similarity index 100%
rename from drivers/serial.c
rename to drivers/serial/serial.c
diff --git a/drivers/serial_max3100.c b/drivers/serial/serial_max3100.c
similarity index 100%
rename from drivers/serial_max3100.c
rename to drivers/serial/serial_max3100.c
diff --git a/drivers/serial_pl010.c b/drivers/serial/serial_pl010.c
similarity index 100%
rename from drivers/serial_pl010.c
rename to drivers/serial/serial_pl010.c
diff --git a/drivers/serial_pl011.c b/drivers/serial/serial_pl011.c
similarity index 100%
rename from drivers/serial_pl011.c
rename to drivers/serial/serial_pl011.c
diff --git a/drivers/serial_pl011.h b/drivers/serial/serial_pl011.h
similarity index 100%
rename from drivers/serial_pl011.h
rename to drivers/serial/serial_pl011.h
diff --git a/drivers/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c
similarity index 100%
rename from drivers/serial_xuartlite.c
rename to drivers/serial/serial_xuartlite.c
diff --git a/drivers/usbtty.c b/drivers/serial/usbtty.c
similarity index 100%
rename from drivers/usbtty.c
rename to drivers/serial/usbtty.c
diff --git a/drivers/usbtty.h b/drivers/serial/usbtty.h
similarity index 100%
rename from drivers/usbtty.h
rename to drivers/serial/usbtty.h
diff --git a/drivers/nand/Makefile b/drivers/usb/Makefile
similarity index 83%
copy from drivers/nand/Makefile
copy to drivers/usb/Makefile
index fb0185b..f8ea167 100644
--- a/drivers/nand/Makefile
+++ b/drivers/usb/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2006
+# (C) Copyright 2000-2007
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,10 +23,17 @@
 
 include $(TOPDIR)/config.mk
 
-LIB 	:= $(obj)libnand.a
+LIB 	:= $(obj)libusb.a
 
-COBJS 	:= nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
+COBJS-y += isp116x-hcd.o
+COBJS-y += sl811_usb.o
+COBJS-y += usb_ohci.o
+COBJS-y += usbdcore.o
+COBJS-y += usbdcore_ep0.o
+COBJS-y += usbdcore_mpc8xx.o
+COBJS-y += usbdcore_omap1510.o
 
+COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
 OBJS 	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/isp116x-hcd.c b/drivers/usb/isp116x-hcd.c
similarity index 100%
rename from drivers/isp116x-hcd.c
rename to drivers/usb/isp116x-hcd.c
diff --git a/drivers/isp116x.h b/drivers/usb/isp116x.h
similarity index 100%
rename from drivers/isp116x.h
rename to drivers/usb/isp116x.h
diff --git a/drivers/sl811.h b/drivers/usb/sl811.h
similarity index 100%
rename from drivers/sl811.h
rename to drivers/usb/sl811.h
diff --git a/drivers/sl811_usb.c b/drivers/usb/sl811_usb.c
similarity index 99%
rename from drivers/sl811_usb.c
rename to drivers/usb/sl811_usb.c
index b0cdf0b..c1f8427 100644
--- a/drivers/sl811_usb.c
+++ b/drivers/usb/sl811_usb.c
@@ -41,7 +41,7 @@
 #include <usb.h>
 #include "sl811.h"
 
-#include "../board/kup/common/kup.h"
+#include "../../board/kup/common/kup.h"
 
 #ifdef __PPC__
 # define EIEIO		__asm__ volatile ("eieio")
diff --git a/drivers/usb_ohci.c b/drivers/usb/usb_ohci.c
similarity index 99%
rename from drivers/usb_ohci.c
rename to drivers/usb/usb_ohci.c
index 7ddcab6..cfa384e 100644
--- a/drivers/usb_ohci.c
+++ b/drivers/usb/usb_ohci.c
@@ -59,6 +59,10 @@
 #include <usb.h>
 #include "usb_ohci.h"
 
+#ifdef CONFIG_AT91RM9200
+#include <asm/arch/hardware.h>	/* needed for AT91_USB_HOST_BASE */
+#endif
+
 #if defined(CONFIG_ARM920T) || \
     defined(CONFIG_S3C2400) || \
     defined(CONFIG_S3C2410) || \
diff --git a/drivers/usb_ohci.h b/drivers/usb/usb_ohci.h
similarity index 100%
rename from drivers/usb_ohci.h
rename to drivers/usb/usb_ohci.h
diff --git a/drivers/usbdcore.c b/drivers/usb/usbdcore.c
similarity index 100%
rename from drivers/usbdcore.c
rename to drivers/usb/usbdcore.c
diff --git a/drivers/usbdcore_ep0.c b/drivers/usb/usbdcore_ep0.c
similarity index 100%
rename from drivers/usbdcore_ep0.c
rename to drivers/usb/usbdcore_ep0.c
diff --git a/drivers/usbdcore_mpc8xx.c b/drivers/usb/usbdcore_mpc8xx.c
similarity index 100%
rename from drivers/usbdcore_mpc8xx.c
rename to drivers/usb/usbdcore_mpc8xx.c
diff --git a/drivers/usbdcore_omap1510.c b/drivers/usb/usbdcore_omap1510.c
similarity index 100%
rename from drivers/usbdcore_omap1510.c
rename to drivers/usb/usbdcore_omap1510.c
diff --git a/drivers/nand/Makefile b/drivers/video/Makefile
similarity index 82%
copy from drivers/nand/Makefile
copy to drivers/video/Makefile
index fb0185b..36611ec 100644
--- a/drivers/nand/Makefile
+++ b/drivers/video/Makefile
@@ -1,5 +1,5 @@
 #
-# (C) Copyright 2006
+# (C) Copyright 2000-2007
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 #
 # See file CREDITS for list of people who contributed to this
@@ -23,10 +23,18 @@
 
 include $(TOPDIR)/config.mk
 
-LIB 	:= $(obj)libnand.a
+LIB 	:= $(obj)libvideo.a
 
-COBJS 	:= nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o nand_util.o
+COBJS-y += ati_radeon_fb.o
+COBJS-y += cfb_console.o
+COBJS-y += ct69000.o
+COBJS-y += sed13806.o
+COBJS-y += sed156x.o
+COBJS-y += sm501.o
+COBJS-y += smiLynxEM.o
+COBJS-y += videomodes.o
 
+COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
 OBJS 	:= $(addprefix $(obj),$(COBJS))
 
diff --git a/drivers/ati_ids.h b/drivers/video/ati_ids.h
similarity index 100%
rename from drivers/ati_ids.h
rename to drivers/video/ati_ids.h
diff --git a/drivers/ati_radeon_fb.c b/drivers/video/ati_radeon_fb.c
similarity index 98%
rename from drivers/ati_radeon_fb.c
rename to drivers/video/ati_radeon_fb.c
index c174f37..0bdaa1c 100644
--- a/drivers/ati_radeon_fb.c
+++ b/drivers/video/ati_radeon_fb.c
@@ -300,7 +300,7 @@
 	u32 val;
 } reg_val;
 
-
+#if 0	/* unused ? -> scheduled for removal */
 /* these common regs are cleared before mode setting so they do not
  * interfere with anything
  */
@@ -316,11 +316,10 @@
 	{ CAP0_TRIG_CNTL, 0 },
 	{ CAP1_TRIG_CNTL, 0 },
 };
-
+#endif /* 0 */
 
 void radeon_setmode(void)
 {
-	int i;
 	struct radeon_regs *mode = malloc(sizeof(struct radeon_regs));
 
 	mode->crtc_gen_cntl = 0x03000200;
@@ -351,6 +350,9 @@
 	radeon_write_pll_regs(rinfo, mode);
 }
 
+#include "../bios_emulator/include/biosemu.h"
+extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp);
+
 int radeon_probe(struct radeonfb_info *rinfo)
 {
 	pci_dev_t pdev;
diff --git a/drivers/ati_radeon_fb.h b/drivers/video/ati_radeon_fb.h
similarity index 100%
rename from drivers/ati_radeon_fb.h
rename to drivers/video/ati_radeon_fb.h
diff --git a/drivers/cfb_console.c b/drivers/video/cfb_console.c
similarity index 100%
rename from drivers/cfb_console.c
rename to drivers/video/cfb_console.c
diff --git a/drivers/ct69000.c b/drivers/video/ct69000.c
similarity index 100%
rename from drivers/ct69000.c
rename to drivers/video/ct69000.c
diff --git a/drivers/sed13806.c b/drivers/video/sed13806.c
similarity index 100%
rename from drivers/sed13806.c
rename to drivers/video/sed13806.c
diff --git a/drivers/sed156x.c b/drivers/video/sed156x.c
similarity index 100%
rename from drivers/sed156x.c
rename to drivers/video/sed156x.c
diff --git a/drivers/sm501.c b/drivers/video/sm501.c
similarity index 100%
rename from drivers/sm501.c
rename to drivers/video/sm501.c
diff --git a/drivers/smiLynxEM.c b/drivers/video/smiLynxEM.c
similarity index 100%
rename from drivers/smiLynxEM.c
rename to drivers/video/smiLynxEM.c
diff --git a/drivers/videomodes.c b/drivers/video/videomodes.c
similarity index 100%
rename from drivers/videomodes.c
rename to drivers/video/videomodes.c
diff --git a/drivers/videomodes.h b/drivers/video/videomodes.h
similarity index 100%
rename from drivers/videomodes.h
rename to drivers/video/videomodes.h