diff --git a/CHANGELOG b/CHANGELOG
index 38ba03760a6edafa1f269d27c01c65ad9a75c140..fc3d4a7b23e6edd6b2ec513b5bd99f487b418e6a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,9 @@
+commit 5f6c732affea9647762d27a4617a2ae64c52dceb
+Author: Wolfgang Denk <wd@denx.de>
+Date:	Wed Apr 18 16:17:46 2007 +0200
+
+    Update CHANGELOG
+
 commit ad4eb555671d97f96dc56eab55103b1f86874b01
 Author: Wolfgang Denk <wd@denx.de>
 Date:	Wed Apr 18 14:30:39 2007 +0200
diff --git a/Makefile b/Makefile
index 8e551eb555d12cf5e910b455872f01ee330c9042..e45c9179d21d1d68f82a42a95666adbb6dc056d7 100644
--- a/Makefile
+++ b/Makefile
@@ -149,7 +149,7 @@ ifeq ($(ARCH),blackfin)
 CROSS_COMPILE = bfin-uclinux-
 endif
 ifeq ($(ARCH),avr32)
-CROSS_COMPILE = avr32-
+CROSS_COMPILE = avr32-linux-
 endif
 endif
 endif
diff --git a/avr32_config.mk b/avr32_config.mk
index 0b92053e1af9d0fe65051fe25d9b08af4157e3ed..441caa405ae3c5e2a8a1c66c0ee5c3970c4480a2 100644
--- a/avr32_config.mk
+++ b/avr32_config.mk
@@ -21,5 +21,5 @@
 # MA 02111-1307 USA
 #
 
-PLATFORM_RELFLAGS	+= -ffixed-r5 -mno-pic -mrelax
+PLATFORM_RELFLAGS	+= -ffixed-r5 -fPIC -mno-init-got -mrelax
 PLATFORM_LDFLAGS	+= --relax
diff --git a/board/atmel/atstk1000/Makefile b/board/atmel/atstk1000/Makefile
index 155d46ac979d6989d75524f67544adb35bc95f4d..8a15713cc42c8f3dee0559e2fbda0350b2083060 100644
--- a/board/atmel/atstk1000/Makefile
+++ b/board/atmel/atstk1000/Makefile
@@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk
 
 LIB	:= $(obj)lib$(BOARD).a
 
-COBJS	:= $(BOARD).o flash.o
+COBJS	:= $(BOARD).o flash.o eth.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/board/atmel/atstk1000/atstk1000.c b/board/atmel/atstk1000/atstk1000.c
index 4d737d293adc540fec06931bf9e03f027d49c141..6618963cc0e4ed6a17c07877b7ccaf0c27b20b6b 100644
--- a/board/atmel/atstk1000/atstk1000.c
+++ b/board/atmel/atstk1000/atstk1000.c
@@ -23,6 +23,8 @@
 
 #include <asm/io.h>
 #include <asm/sdram.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/hmatrix2.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -40,9 +42,27 @@ static const struct sdram_info sdram = {
 	.txsr		= 5,
 };
 
-void board_init_memories(void)
+int board_early_init_f(void)
 {
-	gd->sdram_size = sdram_init(&sdram);
+	/* Set the SDRAM_ENABLE bit in the HEBI SFR */
+	hmatrix2_writel(SFR4, 1 << 1);
+
+	gpio_enable_ebi();
+	gpio_enable_usart1();
+#if defined(CONFIG_MACB)
+	gpio_enable_macb0();
+	gpio_enable_macb1();
+#endif
+#if defined(CONFIG_MMC)
+	gpio_enable_mmci();
+#endif
+
+	return 0;
+}
+
+long int initdram(int board_type)
+{
+	return sdram_init(&sdram);
 }
 
 void board_init_info(void)
diff --git a/cpu/at32ap/at32ap7000/hebi.c b/board/atmel/atstk1000/eth.c
similarity index 66%
rename from cpu/at32ap/at32ap7000/hebi.c
rename to board/atmel/atstk1000/eth.c
index 3b32adf1ea9d8daa02c115708f69d76d44545cd8..3a7916efed294be45c6bd1ea7222f044181f84f1 100644
--- a/cpu/at32ap/at32ap7000/hebi.c
+++ b/board/atmel/atstk1000/eth.c
@@ -1,5 +1,7 @@
 /*
- * Copyright (C) 2006 Atmel Corporation
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * Ethernet initialization for the ATSTK1000 starterkit
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -21,18 +23,16 @@
  */
 #include <common.h>
 
-#include <asm/io.h>
-
-#include <asm/arch/hmatrix2.h>
 #include <asm/arch/memory-map.h>
-#include <asm/arch/platform.h>
 
-void cpu_enable_sdram(void)
-{
-	const struct device *hmatrix;
+extern int macb_eth_initialize(int id, void *regs, unsigned int phy_addr);
 
-	hmatrix = get_device(DEVICE_HMATRIX);
+#if defined(CONFIG_MACB) && (CONFIG_COMMANDS & CFG_CMD_NET)
+void atstk1000_eth_initialize(bd_t *bi)
+{
+	int id = 0;
 
-	/* Set the SDRAM_ENABLE bit in the HEBI SFR */
-	hmatrix2_writel(hmatrix, SFR4, 1 << 1);
+	macb_eth_initialize(id++, (void *)MACB0_BASE, bi->bi_phy_id[0]);
+	macb_eth_initialize(id++, (void *)MACB1_BASE, bi->bi_phy_id[1]);
 }
+#endif
diff --git a/board/atmel/atstk1000/flash.c b/board/atmel/atstk1000/flash.c
index 3aebf66ee24015a01d5f5f4c0ff68e2dc4bb86c0..958f4dc330c82fb0c245c3fafcf2deae7306632e 100644
--- a/board/atmel/atstk1000/flash.c
+++ b/board/atmel/atstk1000/flash.c
@@ -57,7 +57,7 @@ unsigned long flash_init(void)
 
 	gd->bd->bi_flashstart = CFG_FLASH_BASE;
 	gd->bd->bi_flashsize = CFG_FLASH_SIZE;
-	gd->bd->bi_flashoffset = __edata_lma - _text;
+	gd->bd->bi_flashoffset = _edata - _text;
 
 	flash_info[0].size = CFG_FLASH_SIZE;
 	flash_info[0].sector_count = 135;
diff --git a/board/atmel/atstk1000/u-boot.lds b/board/atmel/atstk1000/u-boot.lds
index ef89ea4dfa53d696cb47d5fb1ab6e06f76192632..34e347aecd5e6b7abd2ace5dd293f840838d427a 100644
--- a/board/atmel/atstk1000/u-boot.lds
+++ b/board/atmel/atstk1000/u-boot.lds
@@ -40,35 +40,38 @@ SECTIONS
 	}
 	. = ALIGN(32);
 	__flashprog_end = .;
+	_etext = .;
 
-	. = ALIGN(8);
 	.rodata : {
 		*(.rodata)
 		*(.rodata.*)
 	}
-	_etext = .;
 
-	__data_lma = ALIGN(8);
-	. = 0x24000000;
+	. = ALIGN(8);
 	_data = .;
-	.data : AT(__data_lma) {
+	.data : {
 		*(.data)
 		*(.data.*)
 	}
 
 	. = ALIGN(4);
 	__u_boot_cmd_start = .;
-	__u_boot_cmd_lma = __data_lma + (__u_boot_cmd_start - _data);
-	.u_boot_cmd : AT(__u_boot_cmd_lma) {
+	.u_boot_cmd : {
 		KEEP(*(.u_boot_cmd))
 	}
 	__u_boot_cmd_end = .;
 
+	. = ALIGN(4);
+	_got = .;
+	.got : {
+		*(.got)
+	}
+	_egot = .;
+
 	. = ALIGN(8);
 	_edata = .;
-	__edata_lma = __u_boot_cmd_lma + (_edata - __u_boot_cmd_start);
 
-	.bss : AT(__edata_lma) {
+	.bss : {
 		*(.bss)
 		*(.bss.*)
 	}
diff --git a/cpu/at32ap/Makefile b/cpu/at32ap/Makefile
index f62ec8bc9b2627d8cff712c2ffb51c01da7ec6a5..f69b1f3854665226d669a8b2a4aabcc98e73c78b 100644
--- a/cpu/at32ap/Makefile
+++ b/cpu/at32ap/Makefile
@@ -30,7 +30,7 @@ LIB	:= $(obj)lib$(CPU).a
 START	:= start.o
 SOBJS	:= entry.o
 COBJS	:= cpu.o hsdramc.o exception.o cache.o
-COBJS	+= interrupts.o device.o pm.o pio.o
+COBJS	+= interrupts.o pio.o atmel_mci.o
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
 START	:= $(addprefix $(obj),$(START))
diff --git a/cpu/at32ap/at32ap7000/Makefile b/cpu/at32ap/at32ap7000/Makefile
index 2ed74d2508cd8f508f5bd839e3d193e4b7ce7e55..d2767121184acbe3b48127452e20695299065a40 100644
--- a/cpu/at32ap/at32ap7000/Makefile
+++ b/cpu/at32ap/at32ap7000/Makefile
@@ -24,7 +24,7 @@ include $(TOPDIR)/config.mk
 
 LIB	:= $(obj)lib$(SOC).a
 
-COBJS	:= hebi.o devices.o
+COBJS	:= gpio.o
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
 
diff --git a/cpu/at32ap/at32ap7000/devices.c b/cpu/at32ap/at32ap7000/devices.c
deleted file mode 100644
index 8b216e906a2c114ac65dd660323d64c394466c26..0000000000000000000000000000000000000000
--- a/cpu/at32ap/at32ap7000/devices.c
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * Copyright (C) 2006 Atmel Corporation
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-#include <common.h>
-
-#include <asm/arch/memory-map.h>
-#include <asm/arch/platform.h>
-
-#include "../sm.h"
-
-#define ARRAY_SIZE(x)	(sizeof(x) / sizeof((x)[0]))
-
-const struct clock_domain chip_clock[] = {
-	[CLOCK_CPU] = {
-		.reg	= SM_PM_CPU_MASK,
-		.id	= CLOCK_CPU,
-		.bridge	= NO_DEVICE,
-	},
-	[CLOCK_HSB] = {
-		.reg	= SM_PM_HSB_MASK,
-		.id	= CLOCK_HSB,
-		.bridge	= NO_DEVICE,
-	},
-	[CLOCK_PBA] = {
-		.reg	= SM_PM_PBA_MASK,
-		.id	= CLOCK_PBA,
-		.bridge	= DEVICE_PBA_BRIDGE,
-	},
-	[CLOCK_PBB] = {
-		.reg	= SM_PM_PBB_MASK,
-		.id	= CLOCK_PBB,
-		.bridge	= DEVICE_PBB_BRIDGE,
-	},
-};
-
-static const struct resource hebi_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_HSB, 0 },
-		},
-	}, {
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBB, 13 },
-		},
-	}, {
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBB, 14 },
-		},
-	}, {
-		.type	= RESOURCE_GPIO,
-		.u	= {
-			.gpio	= { 27, DEVICE_PIOE, GPIO_FUNC_A, 0 },
-		},
-	},
-};
-static const struct resource pba_bridge_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_HSB, 1 },
-		}
-	}, {
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			/* HSB-HSB Bridge */
-			.clock	= { CLOCK_HSB, 4 },
-		},
-	},
-};
-static const struct resource pbb_bridge_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_HSB, 2 },
-		},
-	},
-};
-static const struct resource hramc_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_HSB, 3 },
-		},
-	},
-};
-static const struct resource pioa_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBA, 10 },
-		},
-	},
-};
-static const struct resource piob_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBA, 11 },
-		},
-	},
-};
-static const struct resource pioc_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBA, 12 },
-		},
-	},
-};
-static const struct resource piod_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBA, 13 },
-		},
-	},
-};
-static const struct resource pioe_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBA, 14 },
-		},
-	},
-};
-static const struct resource sm_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBB, 0 },
-		},
-	},
-};
-static const struct resource intc_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock = { CLOCK_PBB, 1 },
-		},
-	},
-};
-static const struct resource hmatrix_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock = { CLOCK_PBB, 2 },
-		},
-	},
-};
-#if defined(CFG_HPDC)
-static const struct resource hpdc_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBA, 16 },
-		},
-	},
-};
-#endif
-#if defined(CFG_MACB0)
-static const struct resource macb0_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_HSB, 8 },
-		},
-	}, {
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBB, 6 },
-		},
-	}, {
-		.type	= RESOURCE_GPIO,
-		.u	= {
-			.gpio	= { 19, DEVICE_PIOC, GPIO_FUNC_A, 0 },
-		},
-	},
-};
-#endif
-#if defined(CFG_MACB1)
-static const struct resource macb1_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_HSB, 9 },
-		},
-	}, {
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBB, 7 },
-		},
-	}, {
-		.type	= RESOURCE_GPIO,
-		.u	= {
-			.gpio	= { 12, DEVICE_PIOC, GPIO_FUNC_B, 19 },
-		},
-	}, {
-		.type	= RESOURCE_GPIO,
-		.u	= {
-			.gpio	= { 14, DEVICE_PIOD, GPIO_FUNC_B, 2 },
-		},
-	},
-};
-#endif
-#if defined(CFG_LCDC)
-static const struct resource lcdc_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_HSB, 7 },
-		},
-	},
-};
-#endif
-#if defined(CFG_USART0)
-static const struct resource usart0_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBA, 3 },
-		},
-	}, {
-		.type	= RESOURCE_GPIO,
-		.u	= {
-			.gpio = { 2, DEVICE_PIOA, GPIO_FUNC_B, 8 },
-		},
-	},
-};
-#endif
-#if defined(CFG_USART1)
-static const struct resource usart1_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBA, 4 },
-		},
-	}, {
-		.type	= RESOURCE_GPIO,
-		.u	= {
-			.gpio = { 2, DEVICE_PIOA, GPIO_FUNC_A, 17 },
-		},
-	},
-};
-#endif
-#if defined(CFG_USART2)
-static const struct resource usart2_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBA, 5 },
-		},
-	}, {
-		.type	= RESOURCE_GPIO,
-		.u	= {
-			.gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 26 },
-		},
-	},
-};
-#endif
-#if defined(CFG_USART3)
-static const struct resource usart3_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBA, 6 },
-		},
-	}, {
-		.type	= RESOURCE_GPIO,
-		.u	= {
-			.gpio = { 2, DEVICE_PIOB, GPIO_FUNC_B, 17 },
-		},
-	},
-};
-#endif
-#if defined(CFG_MMCI)
-static const struct resource mmci_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_PBB, 9 },
-		},
-	}, {
-		.type	= RESOURCE_GPIO,
-		.u	= {
-			.gpio = { 6, DEVICE_PIOA, GPIO_FUNC_A, 10 },
-		},
-	},
-};
-#endif
-#if defined(CFG_DMAC)
-static const struct resource dmac_resource[] = {
-	{
-		.type	= RESOURCE_CLOCK,
-		.u	= {
-			.clock	= { CLOCK_HSB, 10 },
-		},
-	},
-};
-#endif
-
-const struct device chip_device[] = {
-	[DEVICE_HEBI] = {
-		.regs		= (void *)HSMC_BASE,
-		.nr_resources	= ARRAY_SIZE(hebi_resource),
-		.resource	= hebi_resource,
-	},
-	[DEVICE_PBA_BRIDGE] = {
-		.nr_resources	= ARRAY_SIZE(pba_bridge_resource),
-		.resource	= pba_bridge_resource,
-	},
-	[DEVICE_PBB_BRIDGE] = {
-		.nr_resources	= ARRAY_SIZE(pbb_bridge_resource),
-		.resource	= pbb_bridge_resource,
-	},
-	[DEVICE_HRAMC] = {
-		.nr_resources	= ARRAY_SIZE(hramc_resource),
-		.resource	= hramc_resource,
-	},
-	[DEVICE_PIOA] = {
-		.regs		= (void *)PIOA_BASE,
-		.nr_resources	= ARRAY_SIZE(pioa_resource),
-		.resource	= pioa_resource,
-	},
-	[DEVICE_PIOB] = {
-		.regs		= (void *)PIOB_BASE,
-		.nr_resources	= ARRAY_SIZE(piob_resource),
-		.resource	= piob_resource,
-	},
-	[DEVICE_PIOC] = {
-		.regs		= (void *)PIOC_BASE,
-		.nr_resources	= ARRAY_SIZE(pioc_resource),
-		.resource	= pioc_resource,
-	},
-	[DEVICE_PIOD] = {
-		.regs		= (void *)PIOD_BASE,
-		.nr_resources	= ARRAY_SIZE(piod_resource),
-		.resource	= piod_resource,
-	},
-	[DEVICE_PIOE] = {
-		.regs		= (void *)PIOE_BASE,
-		.nr_resources	= ARRAY_SIZE(pioe_resource),
-		.resource	= pioe_resource,
-	},
-	[DEVICE_SM] = {
-		.regs		= (void *)SM_BASE,
-		.nr_resources	= ARRAY_SIZE(sm_resource),
-		.resource	= sm_resource,
-	},
-	[DEVICE_INTC] = {
-		.regs		= (void *)INTC_BASE,
-		.nr_resources	= ARRAY_SIZE(intc_resource),
-		.resource	= intc_resource,
-	},
-	[DEVICE_HMATRIX] = {
-		.regs		= (void *)HMATRIX_BASE,
-		.nr_resources	= ARRAY_SIZE(hmatrix_resource),
-		.resource	= hmatrix_resource,
-	},
-#if defined(CFG_HPDC)
-	[DEVICE_HPDC] = {
-		.nr_resources	= ARRAY_SIZE(hpdc_resource),
-		.resource	= hpdc_resource,
-	},
-#endif
-#if defined(CFG_MACB0)
-	[DEVICE_MACB0] = {
-		.regs		= (void *)MACB0_BASE,
-		.nr_resources	= ARRAY_SIZE(macb0_resource),
-		.resource	= macb0_resource,
-	},
-#endif
-#if defined(CFG_MACB1)
-	[DEVICE_MACB1] = {
-		.regs		= (void *)MACB1_BASE,
-		.nr_resources	= ARRAY_SIZE(macb1_resource),
-		.resource	= macb1_resource,
-	},
-#endif
-#if defined(CFG_LCDC)
-	[DEVICE_LCDC] = {
-		.nr_resources	= ARRAY_SIZE(lcdc_resource),
-		.resource	= lcdc_resource,
-	},
-#endif
-#if defined(CFG_USART0)
-	[DEVICE_USART0] = {
-		.regs		= (void *)USART0_BASE,
-		.nr_resources	= ARRAY_SIZE(usart0_resource),
-		.resource	= usart0_resource,
-	},
-#endif
-#if defined(CFG_USART1)
-	[DEVICE_USART1] = {
-		.regs		= (void *)USART1_BASE,
-		.nr_resources	= ARRAY_SIZE(usart1_resource),
-		.resource	= usart1_resource,
-	},
-#endif
-#if defined(CFG_USART2)
-	[DEVICE_USART2] = {
-		.regs		= (void *)USART2_BASE,
-		.nr_resources	= ARRAY_SIZE(usart2_resource),
-		.resource	= usart2_resource,
-	},
-#endif
-#if defined(CFG_USART3)
-	[DEVICE_USART3] = {
-		.regs		= (void *)USART3_BASE,
-		.nr_resources	= ARRAY_SIZE(usart3_resource),
-		.resource	= usart3_resource,
-	},
-#endif
-#if defined(CFG_MMCI)
-	[DEVICE_MMCI] = {
-		.regs		= (void *)MMCI_BASE,
-		.nr_resources	= ARRAY_SIZE(mmci_resource),
-		.resource	= mmci_resource,
-	},
-#endif
-#if defined(CFG_DMAC)
-	[DEVICE_DMAC] = {
-		.regs		= (void *)DMAC_BASE,
-		.nr_resources	= ARRAY_SIZE(dmac_resource),
-		.resource	= dmac_resource,
-	},
-#endif
-};
diff --git a/cpu/at32ap/at32ap7000/gpio.c b/cpu/at32ap/at32ap7000/gpio.c
new file mode 100644
index 0000000000000000000000000000000000000000..52f5372a607af95fad45eadc3146e71f6813da7d
--- /dev/null
+++ b/cpu/at32ap/at32ap7000/gpio.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+
+#include <asm/arch/gpio.h>
+
+/*
+ * Lots of small functions here. We depend on --gc-sections getting
+ * rid of the ones we don't need.
+ */
+void gpio_enable_ebi(void)
+{
+#ifdef CFG_HSDRAMC
+#ifndef CFG_SDRAM_16BIT
+	gpio_select_periph_A(GPIO_PIN_PE0, 0);
+	gpio_select_periph_A(GPIO_PIN_PE1, 0);
+	gpio_select_periph_A(GPIO_PIN_PE2, 0);
+	gpio_select_periph_A(GPIO_PIN_PE3, 0);
+	gpio_select_periph_A(GPIO_PIN_PE4, 0);
+	gpio_select_periph_A(GPIO_PIN_PE5, 0);
+	gpio_select_periph_A(GPIO_PIN_PE6, 0);
+	gpio_select_periph_A(GPIO_PIN_PE7, 0);
+	gpio_select_periph_A(GPIO_PIN_PE8, 0);
+	gpio_select_periph_A(GPIO_PIN_PE9, 0);
+	gpio_select_periph_A(GPIO_PIN_PE10, 0);
+	gpio_select_periph_A(GPIO_PIN_PE11, 0);
+	gpio_select_periph_A(GPIO_PIN_PE12, 0);
+	gpio_select_periph_A(GPIO_PIN_PE13, 0);
+	gpio_select_periph_A(GPIO_PIN_PE14, 0);
+	gpio_select_periph_A(GPIO_PIN_PE15, 0);
+#endif
+	gpio_select_periph_A(GPIO_PIN_PE26, 0);
+#endif
+}
+
+void gpio_enable_usart0(void)
+{
+	gpio_select_periph_B(GPIO_PIN_PA8, 0);
+	gpio_select_periph_B(GPIO_PIN_PA9, 0);
+}
+
+void gpio_enable_usart1(void)
+{
+	gpio_select_periph_A(GPIO_PIN_PA17, 0);
+	gpio_select_periph_A(GPIO_PIN_PA18, 0);
+}
+
+void gpio_enable_usart2(void)
+{
+	gpio_select_periph_B(GPIO_PIN_PB26, 0);
+	gpio_select_periph_B(GPIO_PIN_PB27, 0);
+}
+
+void gpio_enable_usart3(void)
+{
+	gpio_select_periph_B(GPIO_PIN_PB18, 0);
+	gpio_select_periph_B(GPIO_PIN_PB19, 0);
+}
+
+void gpio_enable_macb0(void)
+{
+	gpio_select_periph_A(GPIO_PIN_PC3,  0);	/* TXD0	*/
+	gpio_select_periph_A(GPIO_PIN_PC4,  0);	/* TXD1	*/
+	gpio_select_periph_A(GPIO_PIN_PC7,  0);	/* TXEN	*/
+	gpio_select_periph_A(GPIO_PIN_PC8,  0);	/* TXCK */
+	gpio_select_periph_A(GPIO_PIN_PC9,  0);	/* RXD0	*/
+	gpio_select_periph_A(GPIO_PIN_PC10, 0);	/* RXD1	*/
+	gpio_select_periph_A(GPIO_PIN_PC13, 0);	/* RXER	*/
+	gpio_select_periph_A(GPIO_PIN_PC15, 0);	/* RXDV	*/
+	gpio_select_periph_A(GPIO_PIN_PC16, 0);	/* MDC	*/
+	gpio_select_periph_A(GPIO_PIN_PC17, 0);	/* MDIO	*/
+#if !defined(CONFIG_RMII)
+	gpio_select_periph_A(GPIO_PIN_PC0,  0);	/* COL	*/
+	gpio_select_periph_A(GPIO_PIN_PC1,  0);	/* CRS	*/
+	gpio_select_periph_A(GPIO_PIN_PC2,  0);	/* TXER	*/
+	gpio_select_periph_A(GPIO_PIN_PC5,  0);	/* TXD2	*/
+	gpio_select_periph_A(GPIO_PIN_PC6,  0);	/* TXD3 */
+	gpio_select_periph_A(GPIO_PIN_PC11, 0);	/* RXD2	*/
+	gpio_select_periph_A(GPIO_PIN_PC12, 0);	/* RXD3	*/
+	gpio_select_periph_A(GPIO_PIN_PC14, 0);	/* RXCK	*/
+	gpio_select_periph_A(GPIO_PIN_PC18, 0);	/* SPD	*/
+#endif
+}
+
+void gpio_enable_macb1(void)
+{
+	gpio_select_periph_B(GPIO_PIN_PD13, 0);	/* TXD0	*/
+	gpio_select_periph_B(GPIO_PIN_PD14, 0);	/* TXD1	*/
+	gpio_select_periph_B(GPIO_PIN_PD11, 0);	/* TXEN	*/
+	gpio_select_periph_B(GPIO_PIN_PD12, 0);	/* TXCK */
+	gpio_select_periph_B(GPIO_PIN_PD10, 0);	/* RXD0	*/
+	gpio_select_periph_B(GPIO_PIN_PD6,  0);	/* RXD1	*/
+	gpio_select_periph_B(GPIO_PIN_PD5,  0);	/* RXER	*/
+	gpio_select_periph_B(GPIO_PIN_PD4,  0);	/* RXDV	*/
+	gpio_select_periph_B(GPIO_PIN_PD3,  0);	/* MDC	*/
+	gpio_select_periph_B(GPIO_PIN_PD2,  0);	/* MDIO	*/
+#if !defined(CONFIG_RMII)
+	gpio_select_periph_B(GPIO_PIN_PC19, 0);	/* COL	*/
+	gpio_select_periph_B(GPIO_PIN_PC23, 0);	/* CRS	*/
+	gpio_select_periph_B(GPIO_PIN_PC26, 0);	/* TXER	*/
+	gpio_select_periph_B(GPIO_PIN_PC27, 0);	/* TXD2	*/
+	gpio_select_periph_B(GPIO_PIN_PC28, 0);	/* TXD3 */
+	gpio_select_periph_B(GPIO_PIN_PC29, 0);	/* RXD2	*/
+	gpio_select_periph_B(GPIO_PIN_PC30, 0);	/* RXD3	*/
+	gpio_select_periph_B(GPIO_PIN_PC24, 0);	/* RXCK	*/
+	gpio_select_periph_B(GPIO_PIN_PD15, 0);	/* SPD	*/
+#endif
+}
+
+void gpio_enable_mmci(void)
+{
+	gpio_select_periph_A(GPIO_PIN_PA10, 0);	/* CLK	 */
+	gpio_select_periph_A(GPIO_PIN_PA11, 0);	/* CMD	 */
+	gpio_select_periph_A(GPIO_PIN_PA12, 0);	/* DATA0 */
+	gpio_select_periph_A(GPIO_PIN_PA13, 0);	/* DATA1 */
+	gpio_select_periph_A(GPIO_PIN_PA14, 0);	/* DATA2 */
+	gpio_select_periph_A(GPIO_PIN_PA15, 0);	/* DATA3 */
+}
diff --git a/cpu/at32ap/atmel_mci.c b/cpu/at32ap/atmel_mci.c
new file mode 100644
index 0000000000000000000000000000000000000000..9f62c0f14b8f665ca1edb9a415b01b36169a8ce6
--- /dev/null
+++ b/cpu/at32ap/atmel_mci.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * 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>
+
+#ifdef CONFIG_MMC
+
+#include <part.h>
+#include <mmc.h>
+
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/byteorder.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/memory-map.h>
+
+#include "atmel_mci.h"
+
+#ifdef DEBUG
+#define pr_debug(fmt, args...) printf(fmt, ##args)
+#else
+#define pr_debug(...) do { } while(0)
+#endif
+
+#ifndef CFG_MMC_CLK_OD
+#define CFG_MMC_CLK_OD		150000
+#endif
+
+#ifndef CFG_MMC_CLK_PP
+#define CFG_MMC_CLK_PP		5000000
+#endif
+
+#ifndef CFG_MMC_OP_COND
+#define CFG_MMC_OP_COND		0x00100000
+#endif
+
+#define MMC_DEFAULT_BLKLEN	512
+#define MMC_DEFAULT_RCA		1
+
+static unsigned int mmc_rca;
+static block_dev_desc_t mmc_blkdev;
+
+block_dev_desc_t *mmc_get_dev(int dev)
+{
+	return &mmc_blkdev;
+}
+
+static void mci_set_mode(unsigned long hz, unsigned long blklen)
+{
+	unsigned long bus_hz;
+	unsigned long clkdiv;
+
+	bus_hz = get_mci_clk_rate();
+	clkdiv = (bus_hz / hz) / 2 - 1;
+
+	pr_debug("mmc: setting clock %lu Hz, block size %lu\n",
+		 hz, blklen);
+
+	if (clkdiv & ~255UL) {
+		clkdiv = 255;
+		printf("mmc: clock %lu too low; setting CLKDIV to 255\n",
+			hz);
+	}
+
+	blklen &= 0xfffc;
+	mmci_writel(MR, (MMCI_BF(CLKDIV, clkdiv)
+			 | MMCI_BF(BLKLEN, blklen)));
+}
+
+#define RESP_NO_CRC	1
+#define R1		MMCI_BF(RSPTYP, 1)
+#define R2		MMCI_BF(RSPTYP, 2)
+#define R3		(R1 | RESP_NO_CRC)
+#define R6		R1
+#define NID		MMCI_BF(MAXLAT, 0)
+#define NCR		MMCI_BF(MAXLAT, 1)
+#define TRCMD_START	MMCI_BF(TRCMD, 1)
+#define TRDIR_READ	MMCI_BF(TRDIR, 1)
+#define TRTYP_BLOCK	MMCI_BF(TRTYP, 0)
+#define INIT_CMD	MMCI_BF(SPCMD, 1)
+#define OPEN_DRAIN	MMCI_BF(OPDCMD, 1)
+
+#define ERROR_FLAGS	(MMCI_BIT(DTOE)			\
+			 | MMCI_BIT(RDIRE)		\
+			 | MMCI_BIT(RENDE)		\
+			 | MMCI_BIT(RINDE)		\
+			 | MMCI_BIT(RTOE))
+
+static int
+mmc_cmd(unsigned long cmd, unsigned long arg,
+	void *resp, unsigned long flags)
+{
+	unsigned long *response = resp;
+	int i, response_words = 0;
+	unsigned long error_flags;
+	u32 status;
+
+	pr_debug("mmc: CMD%lu 0x%lx (flags 0x%lx)\n",
+		 cmd, arg, flags);
+
+	error_flags = ERROR_FLAGS;
+	if (!(flags & RESP_NO_CRC))
+		error_flags |= MMCI_BIT(RCRCE);
+
+	flags &= ~MMCI_BF(CMDNB, ~0UL);
+
+	if (MMCI_BFEXT(RSPTYP, flags) == MMCI_RSPTYP_48_BIT_RESP)
+		response_words = 1;
+	else if (MMCI_BFEXT(RSPTYP, flags) == MMCI_RSPTYP_136_BIT_RESP)
+		response_words = 4;
+
+	mmci_writel(ARGR, arg);
+	mmci_writel(CMDR, cmd | flags);
+	do {
+		udelay(40);
+		status = mmci_readl(SR);
+	} while (!(status & MMCI_BIT(CMDRDY)));
+
+	pr_debug("mmc: status 0x%08lx\n", status);
+
+	if (status & ERROR_FLAGS) {
+		printf("mmc: command %lu failed (status: 0x%08lx)\n",
+		       cmd, status);
+		return -EIO;
+	}
+
+	if (response_words)
+		pr_debug("mmc: response:");
+
+	for (i = 0; i < response_words; i++) {
+		response[i] = mmci_readl(RSPR);
+		pr_debug(" %08lx", response[i]);
+	}
+	pr_debug("\n");
+
+	return 0;
+}
+
+static int mmc_acmd(unsigned long cmd, unsigned long arg,
+		    void *resp, unsigned long flags)
+{
+	unsigned long aresp[4];
+	int ret;
+
+	/*
+	 * Seems like the APP_CMD part of an ACMD has 64 cycles max
+	 * latency even though the ACMD part doesn't. This isn't
+	 * entirely clear in the SD Card spec, but some cards refuse
+	 * to work if we attempt to use 5 cycles max latency here...
+	 */
+	ret = mmc_cmd(MMC_CMD_APP_CMD, 0, aresp,
+		      R1 | NCR | (flags & OPEN_DRAIN));
+	if (ret)
+		return ret;
+	if ((aresp[0] & (R1_ILLEGAL_COMMAND | R1_APP_CMD)) != R1_APP_CMD)
+		return -ENODEV;
+
+	ret = mmc_cmd(cmd, arg, resp, flags);
+	return ret;
+}
+
+static unsigned long
+mmc_bread(int dev, unsigned long start, lbaint_t blkcnt,
+	  unsigned long *buffer)
+{
+	int ret, i = 0;
+	unsigned long resp[4];
+	unsigned long card_status, data;
+	unsigned long wordcount;
+	u32 status;
+
+	if (blkcnt == 0)
+		return 0;
+
+	pr_debug("mmc_bread: dev %d, start %lx, blkcnt %lx\n",
+		 dev, start, blkcnt);
+
+	/* Put the device into Transfer state */
+	ret = mmc_cmd(MMC_CMD_SELECT_CARD, mmc_rca << 16, resp, R1 | NCR);
+	if (ret) goto fail;
+
+	/* Set block length */
+	ret = mmc_cmd(MMC_CMD_SET_BLOCKLEN, mmc_blkdev.blksz, resp, R1 | NCR);
+	if (ret) goto fail;
+
+	pr_debug("MCI_DTOR = %08lx\n", mmci_readl(DTOR));
+
+	for (i = 0; i < blkcnt; i++, start++) {
+		ret = mmc_cmd(MMC_CMD_READ_SINGLE_BLOCK,
+			      start * mmc_blkdev.blksz, resp,
+			      (R1 | NCR | TRCMD_START | TRDIR_READ
+			       | TRTYP_BLOCK));
+		if (ret) goto fail;
+
+		ret = -EIO;
+		wordcount = 0;
+		do {
+			do {
+				status = mmci_readl(SR);
+				if (status & (ERROR_FLAGS | MMCI_BIT(OVRE)))
+					goto fail;
+			} while (!(status & MMCI_BIT(RXRDY)));
+
+			if (status & MMCI_BIT(RXRDY)) {
+				data = mmci_readl(RDR);
+				/* pr_debug("%x\n", data); */
+				*buffer++ = data;
+				wordcount++;
+			}
+		} while(wordcount < (512 / 4));
+
+		pr_debug("mmc: read %u words, waiting for BLKE\n", wordcount);
+
+		do {
+			status = mmci_readl(SR);
+		} while (!(status & MMCI_BIT(BLKE)));
+
+		putc('.');
+	}
+
+out:
+	/* Put the device back into Standby state */
+	mmc_cmd(MMC_CMD_SELECT_CARD, 0, resp, NCR);
+	return i;
+
+fail:
+	mmc_cmd(MMC_CMD_SEND_STATUS, mmc_rca << 16, &card_status, R1 | NCR);
+	printf("mmc: bread failed, card status = ", card_status);
+	goto out;
+}
+
+static void mmc_parse_cid(struct mmc_cid *cid, unsigned long *resp)
+{
+	cid->mid = resp[0] >> 24;
+	cid->oid = (resp[0] >> 8) & 0xffff;
+	cid->pnm[0] = resp[0];
+	cid->pnm[1] = resp[1] >> 24;
+	cid->pnm[2] = resp[1] >> 16;
+	cid->pnm[3] = resp[1] >> 8;
+	cid->pnm[4] = resp[1];
+	cid->pnm[5] = resp[2] >> 24;
+	cid->pnm[6] = 0;
+	cid->prv = resp[2] >> 16;
+	cid->psn = (resp[2] << 16) | (resp[3] >> 16);
+	cid->mdt = resp[3] >> 8;
+}
+
+static void sd_parse_cid(struct mmc_cid *cid, unsigned long *resp)
+{
+	cid->mid = resp[0] >> 24;
+	cid->oid = (resp[0] >> 8) & 0xffff;
+	cid->pnm[0] = resp[0];
+	cid->pnm[1] = resp[1] >> 24;
+	cid->pnm[2] = resp[1] >> 16;
+	cid->pnm[3] = resp[1] >> 8;
+	cid->pnm[4] = resp[1];
+	cid->pnm[5] = 0;
+	cid->pnm[6] = 0;
+	cid->prv = resp[2] >> 24;
+	cid->psn = (resp[2] << 8) | (resp[3] >> 24);
+	cid->mdt = (resp[3] >> 8) & 0x0fff;
+}
+
+static void mmc_dump_cid(const struct mmc_cid *cid)
+{
+	printf("Manufacturer ID:       %02lX\n", cid->mid);
+	printf("OEM/Application ID:    %04lX\n", cid->oid);
+	printf("Product name:          %s\n", cid->pnm);
+	printf("Product Revision:      %lu.%lu\n",
+	       cid->prv >> 4, cid->prv & 0x0f);
+	printf("Product Serial Number: %lu\n", cid->psn);
+	printf("Manufacturing Date:    %02lu/%02lu\n",
+	       cid->mdt >> 4, cid->mdt & 0x0f);
+}
+
+static void mmc_dump_csd(const struct mmc_csd *csd)
+{
+	unsigned long *csd_raw = (unsigned long *)csd;
+	printf("CSD data: %08lx %08lx %08lx %08lx\n",
+	       csd_raw[0], csd_raw[1], csd_raw[2], csd_raw[3]);
+	printf("CSD structure version:   1.%u\n", csd->csd_structure);
+	printf("MMC System Spec version: %u\n", csd->spec_vers);
+	printf("Card command classes:    %03x\n", csd->ccc);
+	printf("Read block length:       %u\n", 1 << csd->read_bl_len);
+	if (csd->read_bl_partial)
+		puts("Supports partial reads\n");
+	else
+		puts("Does not support partial reads\n");
+	printf("Write block length:      %u\n", 1 << csd->write_bl_len);
+	if (csd->write_bl_partial)
+		puts("Supports partial writes\n");
+	else
+		puts("Does not support partial writes\n");
+	if (csd->wp_grp_enable)
+		printf("Supports group WP:      %u\n", csd->wp_grp_size + 1);
+	else
+		puts("Does not support group WP\n");
+	printf("Card capacity:		%u bytes\n",
+	       (csd->c_size + 1) * (1 << (csd->c_size_mult + 2)) *
+	       (1 << csd->read_bl_len));
+	printf("File format:            %u/%u\n",
+	       csd->file_format_grp, csd->file_format);
+	puts("Write protection:        ");
+	if (csd->perm_write_protect)
+		puts(" permanent");
+	if (csd->tmp_write_protect)
+		puts(" temporary");
+	putc('\n');
+}
+
+static int mmc_idle_cards(void)
+{
+	int ret;
+
+	/* Reset and initialize all cards */
+	ret = mmc_cmd(MMC_CMD_GO_IDLE_STATE, 0, NULL, 0);
+	if (ret)
+		return ret;
+
+	/* Keep the bus idle for 74 clock cycles */
+	return mmc_cmd(0, 0, NULL, INIT_CMD);
+}
+
+static int sd_init_card(struct mmc_cid *cid, int verbose)
+{
+	unsigned long resp[4];
+	int i, ret = 0;
+
+	mmc_idle_cards();
+	for (i = 0; i < 1000; i++) {
+		ret = mmc_acmd(MMC_ACMD_SD_SEND_OP_COND, CFG_MMC_OP_COND,
+			       resp, R3 | NID);
+		if (ret || (resp[0] & 0x80000000))
+			break;
+		ret = -ETIMEDOUT;
+	}
+
+	if (ret)
+		return ret;
+
+	ret = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, resp, R2 | NID);
+	if (ret)
+		return ret;
+	sd_parse_cid(cid, resp);
+	if (verbose)
+		mmc_dump_cid(cid);
+
+	/* Get RCA of the card that responded */
+	ret = mmc_cmd(MMC_CMD_SD_SEND_RELATIVE_ADDR, 0, resp, R6 | NCR);
+	if (ret)
+		return ret;
+
+	mmc_rca = resp[0] >> 16;
+	if (verbose)
+		printf("SD Card detected (RCA %u)\n", mmc_rca);
+	return 0;
+}
+
+static int mmc_init_card(struct mmc_cid *cid, int verbose)
+{
+	unsigned long resp[4];
+	int i, ret = 0;
+
+	mmc_idle_cards();
+	for (i = 0; i < 1000; i++) {
+		ret = mmc_cmd(MMC_CMD_SEND_OP_COND, CFG_MMC_OP_COND, resp,
+			      R3 | NID | OPEN_DRAIN);
+		if (ret || (resp[0] & 0x80000000))
+			break;
+		ret = -ETIMEDOUT;
+	}
+
+	if (ret)
+		return ret;
+
+	/* Get CID of all cards. FIXME: Support more than one card */
+	ret = mmc_cmd(MMC_CMD_ALL_SEND_CID, 0, resp, R2 | NID | OPEN_DRAIN);
+	if (ret)
+		return ret;
+	mmc_parse_cid(cid, resp);
+	if (verbose)
+		mmc_dump_cid(cid);
+
+	/* Set Relative Address of the card that responded */
+	ret = mmc_cmd(MMC_CMD_SET_RELATIVE_ADDR, mmc_rca << 16, resp,
+		      R1 | NCR | OPEN_DRAIN);
+	return ret;
+}
+
+int mmc_init(int verbose)
+{
+	struct mmc_cid cid;
+	struct mmc_csd csd;
+	int ret;
+
+	/* Initialize controller */
+	mmci_writel(CR, MMCI_BIT(SWRST));
+	mmci_writel(CR, MMCI_BIT(MCIEN));
+	mmci_writel(DTOR, 0x5f);
+	mmci_writel(IDR, ~0UL);
+	mci_set_mode(CFG_MMC_CLK_OD, MMC_DEFAULT_BLKLEN);
+
+	ret = sd_init_card(&cid, verbose);
+	if (ret) {
+		mmc_rca = MMC_DEFAULT_RCA;
+		ret = mmc_init_card(&cid, verbose);
+	}
+	if (ret)
+		return ret;
+
+	/* Get CSD from the card */
+	ret = mmc_cmd(MMC_CMD_SEND_CSD, mmc_rca << 16, &csd, R2 | NCR);
+	if (ret)
+		return ret;
+	if (verbose)
+		mmc_dump_csd(&csd);
+
+	/* Initialize the blockdev structure */
+	mmc_blkdev.if_type = IF_TYPE_MMC;
+	mmc_blkdev.part_type = PART_TYPE_DOS;
+	mmc_blkdev.block_read = mmc_bread;
+	sprintf((char *)mmc_blkdev.vendor,
+		"Man %02x%04x Snr %08x",
+		cid.mid, cid.oid, cid.psn);
+	strncpy((char *)mmc_blkdev.product, cid.pnm,
+		sizeof(mmc_blkdev.product));
+	sprintf((char *)mmc_blkdev.revision, "%x %x",
+		cid.prv >> 4, cid.prv & 0x0f);
+	mmc_blkdev.blksz = 1 << csd.read_bl_len;
+	mmc_blkdev.lba = (csd.c_size + 1) * (1 << (csd.c_size_mult + 2));
+
+	mci_set_mode(CFG_MMC_CLK_PP, mmc_blkdev.blksz);
+
+#if 0
+	if (fat_register_device(&mmc_blkdev, 1))
+		printf("Could not register MMC fat device\n");
+#else
+	init_part(&mmc_blkdev);
+#endif
+
+	return 0;
+}
+
+int mmc_read(ulong src, uchar *dst, int size)
+{
+	return -ENOSYS;
+}
+
+int mmc_write(uchar *src, ulong dst, int size)
+{
+	return -ENOSYS;
+}
+
+int mmc2info(ulong addr)
+{
+	return 0;
+}
+
+#endif /* CONFIG_MMC */
diff --git a/cpu/at32ap/atmel_mci.h b/cpu/at32ap/atmel_mci.h
new file mode 100644
index 0000000000000000000000000000000000000000..0ffbc4fd097ac8de4a0df17acf8ee0646f41c3f0
--- /dev/null
+++ b/cpu/at32ap/atmel_mci.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * 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
+ */
+#ifndef __CPU_AT32AP_ATMEL_MCI_H__
+#define __CPU_AT32AP_ATMEL_MCI_H__
+
+/* Atmel MultiMedia Card Interface (MCI) registers */
+#define MMCI_CR					0x0000
+#define MMCI_MR					0x0004
+#define MMCI_DTOR				0x0008
+#define MMCI_SDCR				0x000c
+#define MMCI_ARGR				0x0010
+#define MMCI_CMDR				0x0014
+#define MMCI_RSPR				0x0020
+#define MMCI_RSPR1				0x0024
+#define MMCI_RSPR2				0x0028
+#define MMCI_RSPR3				0x002c
+#define MMCI_RDR				0x0030
+#define MMCI_TDR				0x0034
+#define MMCI_SR					0x0040
+#define MMCI_IER				0x0044
+#define MMCI_IDR				0x0048
+#define MMCI_IMR				0x004c
+
+/* Bitfields in CR */
+#define MMCI_MCIEN_OFFSET			0
+#define MMCI_MCIEN_SIZE				1
+#define MMCI_MCIDIS_OFFSET			1
+#define MMCI_MCIDIS_SIZE			1
+#define MMCI_PWSEN_OFFSET			2
+#define MMCI_PWSEN_SIZE				1
+#define MMCI_PWSDIS_OFFSET			3
+#define MMCI_PWSDIS_SIZE			1
+#define MMCI_SWRST_OFFSET			7
+#define MMCI_SWRST_SIZE				1
+
+/* Bitfields in MR */
+#define MMCI_CLKDIV_OFFSET			0
+#define MMCI_CLKDIV_SIZE			8
+#define MMCI_PWSDIV_OFFSET			8
+#define MMCI_PWSDIV_SIZE			3
+#define MMCI_PDCPADV_OFFSET			14
+#define MMCI_PDCPADV_SIZE			1
+#define MMCI_PDCMODE_OFFSET			15
+#define MMCI_PDCMODE_SIZE			1
+#define MMCI_BLKLEN_OFFSET			16
+#define MMCI_BLKLEN_SIZE			16
+
+/* Bitfields in DTOR */
+#define MMCI_DTOCYC_OFFSET			0
+#define MMCI_DTOCYC_SIZE			4
+#define MMCI_DTOMUL_OFFSET			4
+#define MMCI_DTOMUL_SIZE			3
+
+/* Bitfields in SDCR */
+#define MMCI_SCDSEL_OFFSET			0
+#define MMCI_SCDSEL_SIZE			4
+#define MMCI_SCDBUS_OFFSET			7
+#define MMCI_SCDBUS_SIZE			1
+
+/* Bitfields in ARGR */
+#define MMCI_ARG_OFFSET				0
+#define MMCI_ARG_SIZE				32
+
+/* Bitfields in CMDR */
+#define MMCI_CMDNB_OFFSET			0
+#define MMCI_CMDNB_SIZE				6
+#define MMCI_RSPTYP_OFFSET			6
+#define MMCI_RSPTYP_SIZE			2
+#define MMCI_SPCMD_OFFSET			8
+#define MMCI_SPCMD_SIZE				3
+#define MMCI_OPDCMD_OFFSET			11
+#define MMCI_OPDCMD_SIZE			1
+#define MMCI_MAXLAT_OFFSET			12
+#define MMCI_MAXLAT_SIZE			1
+#define MMCI_TRCMD_OFFSET			16
+#define MMCI_TRCMD_SIZE				2
+#define MMCI_TRDIR_OFFSET			18
+#define MMCI_TRDIR_SIZE				1
+#define MMCI_TRTYP_OFFSET			19
+#define MMCI_TRTYP_SIZE				2
+
+/* Bitfields in RSPRx */
+#define MMCI_RSP_OFFSET				0
+#define MMCI_RSP_SIZE				32
+
+/* Bitfields in SR/IER/IDR/IMR */
+#define MMCI_CMDRDY_OFFSET			0
+#define MMCI_CMDRDY_SIZE			1
+#define MMCI_RXRDY_OFFSET			1
+#define MMCI_RXRDY_SIZE				1
+#define MMCI_TXRDY_OFFSET			2
+#define MMCI_TXRDY_SIZE				1
+#define MMCI_BLKE_OFFSET			3
+#define MMCI_BLKE_SIZE				1
+#define MMCI_DTIP_OFFSET			4
+#define MMCI_DTIP_SIZE				1
+#define MMCI_NOTBUSY_OFFSET			5
+#define MMCI_NOTBUSY_SIZE			1
+#define MMCI_ENDRX_OFFSET			6
+#define MMCI_ENDRX_SIZE				1
+#define MMCI_ENDTX_OFFSET			7
+#define MMCI_ENDTX_SIZE				1
+#define MMCI_RXBUFF_OFFSET			14
+#define MMCI_RXBUFF_SIZE			1
+#define MMCI_TXBUFE_OFFSET			15
+#define MMCI_TXBUFE_SIZE			1
+#define MMCI_RINDE_OFFSET			16
+#define MMCI_RINDE_SIZE				1
+#define MMCI_RDIRE_OFFSET			17
+#define MMCI_RDIRE_SIZE				1
+#define MMCI_RCRCE_OFFSET			18
+#define MMCI_RCRCE_SIZE				1
+#define MMCI_RENDE_OFFSET			19
+#define MMCI_RENDE_SIZE				1
+#define MMCI_RTOE_OFFSET			20
+#define MMCI_RTOE_SIZE				1
+#define MMCI_DCRCE_OFFSET			21
+#define MMCI_DCRCE_SIZE				1
+#define MMCI_DTOE_OFFSET			22
+#define MMCI_DTOE_SIZE				1
+#define MMCI_OVRE_OFFSET			30
+#define MMCI_OVRE_SIZE				1
+#define MMCI_UNRE_OFFSET			31
+#define MMCI_UNRE_SIZE				1
+
+/* Constants for DTOMUL */
+#define MMCI_DTOMUL_1_CYCLE			0
+#define MMCI_DTOMUL_16_CYCLES			1
+#define MMCI_DTOMUL_128_CYCLES			2
+#define MMCI_DTOMUL_256_CYCLES			3
+#define MMCI_DTOMUL_1024_CYCLES			4
+#define MMCI_DTOMUL_4096_CYCLES			5
+#define MMCI_DTOMUL_65536_CYCLES		6
+#define MMCI_DTOMUL_1048576_CYCLES		7
+
+/* Constants for RSPTYP */
+#define MMCI_RSPTYP_NO_RESP			0
+#define MMCI_RSPTYP_48_BIT_RESP			1
+#define MMCI_RSPTYP_136_BIT_RESP		2
+
+/* Constants for SPCMD */
+#define MMCI_SPCMD_NO_SPEC_CMD			0
+#define MMCI_SPCMD_INIT_CMD			1
+#define MMCI_SPCMD_SYNC_CMD			2
+#define MMCI_SPCMD_INT_CMD			4
+#define MMCI_SPCMD_INT_RESP			5
+
+/* Constants for TRCMD */
+#define MMCI_TRCMD_NO_TRANS			0
+#define MMCI_TRCMD_START_TRANS			1
+#define MMCI_TRCMD_STOP_TRANS			2
+
+/* Constants for TRTYP */
+#define MMCI_TRTYP_BLOCK			0
+#define MMCI_TRTYP_MULTI_BLOCK			1
+#define MMCI_TRTYP_STREAM			2
+
+/* Bit manipulation macros */
+#define MMCI_BIT(name)					\
+	(1 << MMCI_##name##_OFFSET)
+#define MMCI_BF(name,value)				\
+	(((value) & ((1 << MMCI_##name##_SIZE) - 1))	\
+	 << MMCI_##name##_OFFSET)
+#define MMCI_BFEXT(name,value)				\
+	(((value) >> MMCI_##name##_OFFSET)\
+	 & ((1 << MMCI_##name##_SIZE) - 1))
+#define MMCI_BFINS(name,value,old)			\
+	(((old) & ~(((1 << MMCI_##name##_SIZE) - 1)	\
+		    << MMCI_##name##_OFFSET))		\
+	 | MMCI_BF(name,value))
+
+/* Register access macros */
+#define mmci_readl(reg)					\
+	readl((void *)MMCI_BASE + MMCI_##reg)
+#define mmci_writel(reg,value)				\
+	writel((value), (void *)MMCI_BASE + MMCI_##reg)
+
+#endif /* __CPU_AT32AP_ATMEL_MCI_H__ */
diff --git a/cpu/at32ap/cpu.c b/cpu/at32ap/cpu.c
index 37e3ea040be6a5e898801aefc2e7db3bf95da3e5..311466b781465ac45347bc5abb22f72a5b260c6c 100644
--- a/cpu/at32ap/cpu.c
+++ b/cpu/at32ap/cpu.c
@@ -26,33 +26,79 @@
 #include <asm/sections.h>
 #include <asm/sysreg.h>
 
+#include <asm/arch/clk.h>
 #include <asm/arch/memory-map.h>
-#include <asm/arch/platform.h>
 
 #include "hsmc3.h"
+#include "sm.h"
+
+/* Sanity checks */
+#if (CFG_CLKDIV_CPU > CFG_CLKDIV_HSB)		\
+	|| (CFG_CLKDIV_HSB > CFG_CLKDIV_PBA)	\
+	|| (CFG_CLKDIV_HSB > CFG_CLKDIV_PBB)
+# error Constraint fCPU >= fHSB >= fPB{A,B} violated
+#endif
+#if defined(CONFIG_PLL) && ((CFG_PLL0_MUL < 1) || (CFG_PLL0_DIV < 1))
+# error Invalid PLL multiplier and/or divider
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
+static void pm_init(void)
+{
+	uint32_t cksel;
+
+#ifdef CONFIG_PLL
+	/* Initialize the PLL */
+	sm_writel(PM_PLL0, (SM_BF(PLLCOUNT, CFG_PLL0_SUPPRESS_CYCLES)
+			    | SM_BF(PLLMUL, CFG_PLL0_MUL - 1)
+			    | SM_BF(PLLDIV, CFG_PLL0_DIV - 1)
+			    | SM_BF(PLLOPT, CFG_PLL0_OPT)
+			    | SM_BF(PLLOSC, 0)
+			    | SM_BIT(PLLEN)));
+
+	/* Wait for lock */
+	while (!(sm_readl(PM_ISR) & SM_BIT(LOCK0))) ;
+#endif
+
+	/* Set up clocks for the CPU and all peripheral buses */
+	cksel = 0;
+	if (CFG_CLKDIV_CPU)
+		cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CFG_CLKDIV_CPU - 1);
+	if (CFG_CLKDIV_HSB)
+		cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CFG_CLKDIV_HSB - 1);
+	if (CFG_CLKDIV_PBA)
+		cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CFG_CLKDIV_PBA - 1);
+	if (CFG_CLKDIV_PBB)
+		cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CFG_CLKDIV_PBB - 1);
+	sm_writel(PM_CKSEL, cksel);
+
+	gd->cpu_hz = get_cpu_clk_rate();
+
+#ifdef CONFIG_PLL
+	/* Use PLL0 as main clock */
+	sm_writel(PM_MCCTRL, SM_BIT(PLLSEL));
+#endif
+}
+
 int cpu_init(void)
 {
-	const struct device *hebi;
 	extern void _evba(void);
 	char *p;
 
 	gd->cpu_hz = CFG_OSC0_HZ;
 
-	/* fff03400: 00010001 04030402 00050005 10011103 */
-	hebi = get_device(DEVICE_HEBI);
-	hsmc3_writel(hebi, MODE0, 0x00031103);
-	hsmc3_writel(hebi, CYCLE0, 0x000c000d);
-	hsmc3_writel(hebi, PULSE0, 0x0b0a0906);
-	hsmc3_writel(hebi, SETUP0, 0x00010002);
+	/* TODO: Move somewhere else, but needs to be run before we
+	 * increase the clock frequency. */
+	hsmc3_writel(MODE0, 0x00031103);
+	hsmc3_writel(CYCLE0, 0x000c000d);
+	hsmc3_writel(PULSE0, 0x0b0a0906);
+	hsmc3_writel(SETUP0, 0x00010002);
 
 	pm_init();
 
 	sysreg_write(EVBA, (unsigned long)&_evba);
 	asm volatile("csrf	%0" : : "i"(SYSREG_EM_OFFSET));
-	gd->console_uart = get_device(CFG_CONSOLE_UART_DEV);
 
 	/* Lock everything that mess with the flash in the icache */
 	for (p = __flashprog_start; p <= (__flashprog_end + CFG_ICACHE_LINESZ);
diff --git a/cpu/at32ap/device.c b/cpu/at32ap/device.c
deleted file mode 100644
index 89914b6b56b3ebe98126e33b1181f95f0caad6f3..0000000000000000000000000000000000000000
--- a/cpu/at32ap/device.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2006 Atmel Corporation
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-#include <common.h>
-
-#include <asm/arch/platform.h>
-
-#include "sm.h"
-
-struct device_state {
-	int refcount;
-};
-
-static struct device_state device_state[NR_DEVICES];
-
-static int claim_resource(const struct resource *res)
-{
-	int ret = 0;
-
-	switch (res->type) {
-	case RESOURCE_GPIO:
-		ret = gpio_set_func(res->u.gpio.gpio_dev,
-				    res->u.gpio.start,
-				    res->u.gpio.nr_pins,
-				    res->u.gpio.func);
-		break;
-	case RESOURCE_CLOCK:
-		ret = pm_enable_clock(res->u.clock.id, res->u.clock.index);
-		break;
-	}
-
-	return ret;
-}
-
-static void free_resource(const struct resource *res)
-{
-	switch (res->type) {
-	case RESOURCE_GPIO:
-		gpio_free(res->u.gpio.gpio_dev, res->u.gpio.start,
-			  res->u.gpio.nr_pins);
-		break;
-	case RESOURCE_CLOCK:
-		pm_disable_clock(res->u.clock.id, res->u.clock.index);
-		break;
-	}
-}
-
-static int init_dev(const struct device *dev)
-{
-	unsigned int i;
-	int ret = 0;
-
-	for (i = 0; i < dev->nr_resources; i++) {
-		ret = claim_resource(&dev->resource[i]);
-		if (ret)
-			goto cleanup;
-	}
-
-	return 0;
-
-cleanup:
-	while (i--)
-		free_resource(&dev->resource[i]);
-
-	return ret;
-}
-
-const struct device *get_device(enum device_id devid)
-{
-	struct device_state *devstate;
-	const struct device *dev;
-	unsigned long flags;
-	int initialized = 0;
-	int ret = 0;
-
-	devstate = &device_state[devid];
-	dev = &chip_device[devid];
-
-	flags = disable_interrupts();
-	if (devstate->refcount++)
-		initialized = 1;
-	if (flags)
-		enable_interrupts();
-
-	if (!initialized)
-		ret = init_dev(dev);
-
-	return ret ? NULL : dev;
-}
-
-void put_device(const struct device *dev)
-{
-	struct device_state *devstate;
-	unsigned long devid, flags;
-
-	devid = (unsigned long)(dev - chip_device) / sizeof(struct device);
-	devstate = &device_state[devid];
-
-	flags = disable_interrupts();
-	devstate--;
-	if (!devstate) {
-		unsigned int i;
-		for (i = 0; i < dev->nr_resources; i++)
-			free_resource(&dev->resource[i]);
-	}
-	if (flags)
-		enable_interrupts();
-}
diff --git a/cpu/at32ap/entry.S b/cpu/at32ap/entry.S
index b52d798be3d7eecaf35c0800ac5cb5620d538b42..a6fc68867a8c04d764e3221bc971106f1245d770 100644
--- a/cpu/at32ap/entry.S
+++ b/cpu/at32ap/entry.S
@@ -42,8 +42,7 @@ timer_interrupt_handler:
 	 * We're running at interrupt level 3, so we don't need to save
 	 * r8-r12 or lr to the stack.
 	 */
-	mov	r8, lo(timer_overflow)
-	orh	r8, hi(timer_overflow)
+	lda.w	r8, timer_overflow
 	ld.w	r9, r8[0]
 	mov	r10, -1
 	mtsr	SYSREG_COMPARE, r10
diff --git a/cpu/at32ap/exception.c b/cpu/at32ap/exception.c
index 4123c446167ad4bc93523445fb570ac3cea306ac..0672685cd024ba80e470dcd930b85b0d6f56e54f 100644
--- a/cpu/at32ap/exception.c
+++ b/cpu/at32ap/exception.c
@@ -24,6 +24,8 @@
 #include <asm/sysreg.h>
 #include <asm/ptrace.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 static const char * const cpu_modes[8] = {
 	"Application", "Supervisor", "Interrupt level 0", "Interrupt level 1",
 	"Interrupt level 2", "Interrupt level 3", "Exception", "NMI"
@@ -109,11 +111,10 @@ void do_unknown_exception(unsigned int ecr, struct pt_regs *regs)
 	printf("CPU Mode: %s\n", cpu_modes[mode]);
 
 	/* Avoid exception loops */
-	if (regs->sp >= CFG_INIT_SP_ADDR
-	    || regs->sp < (CFG_INIT_SP_ADDR - CONFIG_STACKSIZE))
+	if (regs->sp < CFG_SDRAM_BASE || regs->sp >= gd->stack_end)
 		printf("\nStack pointer seems bogus, won't do stack dump\n");
 	else
-		dump_mem("\nStack: ", regs->sp, CFG_INIT_SP_ADDR);
+		dump_mem("\nStack: ", regs->sp, gd->stack_end);
 
 	panic("Unhandled exception\n");
 }
diff --git a/cpu/at32ap/hsdramc.c b/cpu/at32ap/hsdramc.c
index f36da354528daaa6fae939341cecc3126898105b..a936e03166c1d81de52c760962b642c933ee92f5 100644
--- a/cpu/at32ap/hsdramc.c
+++ b/cpu/at32ap/hsdramc.c
@@ -25,17 +25,11 @@
 #include <asm/io.h>
 #include <asm/sdram.h>
 
-#include <asm/arch/platform.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/memory-map.h>
 
 #include "hsdramc1.h"
 
-struct hsdramc {
-	const struct device *hebi;
-	void *regs;
-};
-
-static struct hsdramc hsdramc;
-
 unsigned long sdram_init(const struct sdram_info *info)
 {
 	unsigned long *sdram = (unsigned long *)uncached(info->phys_addr);
@@ -44,16 +38,6 @@ unsigned long sdram_init(const struct sdram_info *info)
 	unsigned long bus_hz;
 	unsigned int i;
 
-	hsdramc.hebi = get_device(DEVICE_HEBI);
-	if (!hsdramc.hebi)
-		return 0;
-
-	/* FIXME: Both of these lines are complete hacks */
-	hsdramc.regs = hsdramc.hebi->regs + 0x400;
-	bus_hz = pm_get_clock_freq(hsdramc.hebi->resource[0].u.clock.id);
-
-	cpu_enable_sdram();
-
 	tmp = (HSDRAMC1_BF(NC, info->col_bits - 8)
 	       | HSDRAMC1_BF(NR, info->row_bits - 11)
 	       | HSDRAMC1_BF(NB, info->bank_bits - 1)
@@ -74,7 +58,7 @@ unsigned long sdram_init(const struct sdram_info *info)
 			   + info->bank_bits + 2);
 #endif
 
-	hsdramc1_writel(&hsdramc, CR, tmp);
+	hsdramc1_writel(CR, tmp);
 
 	/*
 	 * Initialization sequence for SDRAM, from the data sheet:
@@ -87,15 +71,15 @@ unsigned long sdram_init(const struct sdram_info *info)
 	/*
 	 * 2. A Precharge All command is issued to the SDRAM
 	 */
-	hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_BANKS_PRECHARGE);
-	hsdramc1_readl(&hsdramc, MR);
+	hsdramc1_writel(MR, HSDRAMC1_MODE_BANKS_PRECHARGE);
+	hsdramc1_readl(MR);
 	writel(0, sdram);
 
 	/*
 	 * 3. Eight auto-refresh (CBR) cycles are provided
 	 */
-	hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_AUTO_REFRESH);
-	hsdramc1_readl(&hsdramc, MR);
+	hsdramc1_writel(MR, HSDRAMC1_MODE_AUTO_REFRESH);
+	hsdramc1_readl(MR);
 	for (i = 0; i < 8; i++)
 		writel(0, sdram);
 
@@ -106,8 +90,8 @@ unsigned long sdram_init(const struct sdram_info *info)
 	 *
 	 * CAS from info struct, burst length 1, serial burst type
 	 */
-	hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_LOAD_MODE);
-	hsdramc1_readl(&hsdramc, MR);
+	hsdramc1_writel(MR, HSDRAMC1_MODE_LOAD_MODE);
+	hsdramc1_readl(MR);
 	writel(0, sdram + (info->cas << 4));
 
 	/*
@@ -117,9 +101,9 @@ unsigned long sdram_init(const struct sdram_info *info)
 	 * From the timing diagram, it looks like tMRD is 3
 	 * cycles...try a dummy read from the peripheral bus.
 	 */
-	hsdramc1_readl(&hsdramc, MR);
-	hsdramc1_writel(&hsdramc, MR, HSDRAMC1_MODE_NORMAL);
-	hsdramc1_readl(&hsdramc, MR);
+	hsdramc1_readl(MR);
+	hsdramc1_writel(MR, HSDRAMC1_MODE_NORMAL);
+	hsdramc1_readl(MR);
 	writel(0, sdram);
 
 	/*
@@ -128,7 +112,8 @@ unsigned long sdram_init(const struct sdram_info *info)
 	 *
 	 * 15.6 us is a typical value for a burst of length one
 	 */
-	hsdramc1_writel(&hsdramc, TR, (156 * (bus_hz / 1000)) / 10000);
+	bus_hz = get_sdram_clk_rate();
+	hsdramc1_writel(TR, (156 * (bus_hz / 1000)) / 10000);
 
 	printf("SDRAM: %u MB at address 0x%08lx\n",
 	       sdram_size >> 20, info->phys_addr);
diff --git a/cpu/at32ap/hsdramc1.h b/cpu/at32ap/hsdramc1.h
index ce229bca1fbb834748734058d571d8c353611980..305d2cb5d39a6b9ebd9ccb1923636a1f533cdb00 100644
--- a/cpu/at32ap/hsdramc1.h
+++ b/cpu/at32ap/hsdramc1.h
@@ -135,9 +135,9 @@
 	 | HSDRAMC1_BF(name,value))
 
 /* Register access macros */
-#define hsdramc1_readl(port,reg)				\
-	readl((port)->regs + HSDRAMC1_##reg)
-#define hsdramc1_writel(port,reg,value)				\
-	writel((value), (port)->regs + HSDRAMC1_##reg)
+#define hsdramc1_readl(reg)					\
+	readl((void *)HSDRAMC_BASE + HSDRAMC1_##reg)
+#define hsdramc1_writel(reg,value)				\
+	writel((value), (void *)HSDRAMC_BASE + HSDRAMC1_##reg)
 
 #endif /* __ASM_AVR32_HSDRAMC1_H__ */
diff --git a/cpu/at32ap/hsmc3.h b/cpu/at32ap/hsmc3.h
index ec78cee7147a571aa38935dc5eed2405a09da9a0..ca533b922edaa22e4d5bafd3a82f3dfa96d7115e 100644
--- a/cpu/at32ap/hsmc3.h
+++ b/cpu/at32ap/hsmc3.h
@@ -118,9 +118,9 @@
 	 | HSMC3_BF(name,value))
 
 /* Register access macros */
-#define hsmc3_readl(port,reg)					\
-	readl((port)->regs + HSMC3_##reg)
-#define hsmc3_writel(port,reg,value)				\
-	writel((value), (port)->regs + HSMC3_##reg)
+#define hsmc3_readl(reg)					\
+	readl((void *)HSMC_BASE + HSMC3_##reg)
+#define hsmc3_writel(reg,value)					\
+	writel((value), (void *)HSMC_BASE + HSMC3_##reg)
 
 #endif /* __CPU_AT32AP_HSMC3_H__ */
diff --git a/cpu/at32ap/interrupts.c b/cpu/at32ap/interrupts.c
index d720cfa942b32edc9622326aa7ae5fa8421de009..c9e04993c777a1344147acf2d108ca5e02d2604a 100644
--- a/cpu/at32ap/interrupts.c
+++ b/cpu/at32ap/interrupts.c
@@ -27,7 +27,7 @@
 #include <asm/processor.h>
 #include <asm/sysreg.h>
 
-#include <asm/arch/platform.h>
+#include <asm/arch/memory-map.h>
 
 #define HANDLER_MASK	0x00ffffff
 #define INTLEV_SHIFT	30
@@ -44,8 +44,6 @@ volatile unsigned long timer_overflow;
  */
 static unsigned long tb_factor;
 
-static const struct device *intc_dev;
-
 unsigned long get_tbclk(void)
 {
 	return gd->cpu_hz;
@@ -117,16 +115,19 @@ void udelay(unsigned long usec)
 static int set_interrupt_handler(unsigned int nr, void (*handler)(void),
 				 unsigned int priority)
 {
+	extern void _evba(void);
 	unsigned long intpr;
 	unsigned long handler_addr = (unsigned long)handler;
 
+	handler_addr -= (unsigned long)&_evba;
+
 	if ((handler_addr & HANDLER_MASK) != handler_addr
 	    || (priority & INTLEV_MASK) != priority)
 		return -EINVAL;
 
 	intpr = (handler_addr & HANDLER_MASK);
 	intpr |= (priority & INTLEV_MASK) << INTLEV_SHIFT;
-	writel(intpr, intc_dev->regs + 4 * nr);
+	writel(intpr, (void *)INTC_BASE + 4 * nr);
 
 	return 0;
 }
@@ -143,10 +144,7 @@ void timer_init(void)
 	do_div(tmp, gd->cpu_hz);
 	tb_factor = (u32)tmp;
 
-	intc_dev = get_device(DEVICE_INTC);
-
-	if (!intc_dev
-	    || set_interrupt_handler(0, &timer_interrupt_handler, 3))
+	if (set_interrupt_handler(0, &timer_interrupt_handler, 3))
 		return;
 
 	/* For all practical purposes, this gives us an overflow interrupt */
diff --git a/cpu/at32ap/pio.c b/cpu/at32ap/pio.c
index 8b6c3a35df505a6510d85445e1bbc74798cee318..9ba0b8ea8b26f189d1c39042908a7939dc570905 100644
--- a/cpu/at32ap/pio.c
+++ b/cpu/at32ap/pio.c
@@ -21,74 +21,40 @@
  */
 #include <common.h>
 
-#include <asm/errno.h>
 #include <asm/io.h>
-#include <asm/arch/platform.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/memory-map.h>
 
 #include "pio2.h"
 
-struct pio_state {
-	const struct device *dev;
-	u32 alloc_mask;
-};
-
-static struct pio_state pio_state[CFG_NR_PIOS];
-
-int gpio_set_func(enum device_id gpio_devid, unsigned int start,
-		  unsigned int nr_pins, enum gpio_func func)
+void gpio_select_periph_A(unsigned int pin, int use_pullup)
 {
-	const struct device *gpio;
-	struct pio_state *state;
-	u32 mask;
-
-	state = &pio_state[gpio_devid - DEVICE_PIOA];
-
-	gpio = get_device(gpio_devid);
-	if (!gpio)
-		return -EBUSY;
-
-	state->dev = gpio;
-	mask = ((1 << nr_pins) - 1) << start;
-
-	if (mask & state->alloc_mask) {
-		put_device(gpio);
-		return -EBUSY;
-	}
-	state->alloc_mask |= mask;
-
-	switch (func) {
-	case GPIO_FUNC_GPIO:
-		/* TODO */
-		return -EINVAL;
-	case GPIO_FUNC_A:
-		pio2_writel(gpio, ASR, mask);
-		pio2_writel(gpio, PDR, mask);
-		pio2_writel(gpio, PUDR, mask);
-		break;
-	case GPIO_FUNC_B:
-		pio2_writel(gpio, BSR, mask);
-		pio2_writel(gpio, PDR, mask);
-		pio2_writel(gpio, PUDR, mask);
-		break;
-	}
-
-	return 0;
+	void *base = gpio_pin_to_addr(pin);
+	uint32_t mask = 1 << (pin & 0x1f);
+
+	if (!base)
+		panic("Invalid GPIO pin %u\n", pin);
+
+	pio2_writel(base, ASR, mask);
+	pio2_writel(base, PDR, mask);
+	if (use_pullup)
+		pio2_writel(base, PUER, mask);
+	else
+		pio2_writel(base, PUDR, mask);
 }
 
-void gpio_free(enum device_id gpio_devid, unsigned int start,
-	       unsigned int nr_pins)
+void gpio_select_periph_B(unsigned int pin, int use_pullup)
 {
-	const struct device *gpio;
-	struct pio_state *state;
-	u32 mask;
-
-	state = &pio_state[gpio_devid - DEVICE_PIOA];
-	gpio = state->dev;
-	mask = ((1 << nr_pins) - 1) << start;
-
-	pio2_writel(gpio, ODR, mask);
-	pio2_writel(gpio, PER, mask);
-
-	state->alloc_mask &= ~mask;
-	put_device(gpio);
+	void *base = gpio_pin_to_addr(pin);
+	uint32_t mask = 1 << (pin & 0x1f);
+
+	if (!base)
+		panic("Invalid GPIO pin %u\n", pin);
+
+	pio2_writel(base, BSR, mask);
+	pio2_writel(base, PDR, mask);
+	if (use_pullup)
+		pio2_writel(base, PUER, mask);
+	else
+		pio2_writel(base, PUDR, mask);
 }
diff --git a/cpu/at32ap/pio2.h b/cpu/at32ap/pio2.h
index 6b79de3c72bec3fa71f8bbd6599921aff3bff694..9719ea8c433557cb16c9096d4c3fb91912b008e1 100644
--- a/cpu/at32ap/pio2.h
+++ b/cpu/at32ap/pio2.h
@@ -36,9 +36,9 @@
 #define PIO2_OWSR				0x00a8
 
 /* Register access macros */
-#define pio2_readl(port,reg)				\
-	readl((port)->regs + PIO2_##reg)
-#define pio2_writel(port,reg,value)			\
-	writel((value), (port)->regs + PIO2_##reg)
+#define pio2_readl(base,reg)				\
+	readl((void *)base + PIO2_##reg)
+#define pio2_writel(base,reg,value)			\
+	writel((value), (void *)base + PIO2_##reg)
 
 #endif /* __CPU_AT32AP_PIO2_H__ */
diff --git a/cpu/at32ap/pm.c b/cpu/at32ap/pm.c
index 01ac325ee8f60c372e87eacf24b927e7efa607e0..c78d547f85e00d06758dbdd7a5a819f141bf66b5 100644
--- a/cpu/at32ap/pm.c
+++ b/cpu/at32ap/pm.c
@@ -26,138 +26,17 @@
 #include <asm/io.h>
 
 #include <asm/arch/memory-map.h>
-#include <asm/arch/platform.h>
 
 #include "sm.h"
 
-/* Sanity checks */
-#if (CFG_CLKDIV_CPU > CFG_CLKDIV_HSB)		\
-	|| (CFG_CLKDIV_HSB > CFG_CLKDIV_PBA)	\
-	|| (CFG_CLKDIV_HSB > CFG_CLKDIV_PBB)
-# error Constraint fCPU >= fHSB >= fPB{A,B} violated
-#endif
-#if defined(CONFIG_PLL) && ((CFG_PLL0_MUL < 1) || (CFG_PLL0_DIV < 1))
-# error Invalid PLL multiplier and/or divider
-#endif
-
-DECLARE_GLOBAL_DATA_PTR;
-
-struct clock_domain_state {
-	const struct device *bridge;
-	unsigned long freq;
-	u32 mask;
-};
-static struct clock_domain_state ckd_state[NR_CLOCK_DOMAINS];
-
-int pm_enable_clock(enum clock_domain_id id, unsigned int index)
-{
-	const struct clock_domain *ckd = &chip_clock[id];
-	struct clock_domain_state *state = &ckd_state[id];
-
-	if (ckd->bridge != NO_DEVICE) {
-		state->bridge = get_device(ckd->bridge);
-		if (!state->bridge)
-			return -EBUSY;
-	}
-
-	state->mask |= 1 << index;
-	if (gd->sm)
-		writel(state->mask, gd->sm->regs + ckd->reg);
-
-	return 0;
-}
-
-void pm_disable_clock(enum clock_domain_id id, unsigned int index)
-{
-	const struct clock_domain *ckd = &chip_clock[id];
-	struct clock_domain_state *state = &ckd_state[id];
-
-	state->mask &= ~(1 << index);
-	if (gd->sm)
-		writel(state->mask, gd->sm->regs + ckd->reg);
-
-	if (ckd->bridge)
-		put_device(state->bridge);
-}
-
-unsigned long pm_get_clock_freq(enum clock_domain_id domain)
-{
-	return ckd_state[domain].freq;
-}
-
-void pm_init(void)
-{
-	uint32_t cksel = 0;
-	unsigned long main_clock;
-
-	/* Make sure we don't disable any device we're already using */
-	get_device(DEVICE_HRAMC);
-	get_device(DEVICE_HEBI);
-
-	/* Enable the PICO as well */
-	ckd_state[CLOCK_CPU].mask |= 1;
-
-	gd->sm = get_device(DEVICE_SM);
-	if (!gd->sm)
-		panic("Unable to claim system manager device!\n");
-
-	/* Disable any devices that haven't been explicitly claimed */
-	sm_writel(gd->sm, PM_PBB_MASK, ckd_state[CLOCK_PBB].mask);
-	sm_writel(gd->sm, PM_PBA_MASK, ckd_state[CLOCK_PBA].mask);
-	sm_writel(gd->sm, PM_HSB_MASK, ckd_state[CLOCK_HSB].mask);
-	sm_writel(gd->sm, PM_CPU_MASK, ckd_state[CLOCK_CPU].mask);
 
 #ifdef CONFIG_PLL
-	/* Initialize the PLL */
-	main_clock = (CFG_OSC0_HZ / CFG_PLL0_DIV) * CFG_PLL0_MUL;
-
-	sm_writel(gd->sm, PM_PLL0, (SM_BF(PLLCOUNT, CFG_PLL0_SUPPRESS_CYCLES)
-				    | SM_BF(PLLMUL, CFG_PLL0_MUL - 1)
-				    | SM_BF(PLLDIV, CFG_PLL0_DIV - 1)
-				    | SM_BF(PLLOPT, CFG_PLL0_OPT)
-				    | SM_BF(PLLOSC, 0)
-				    | SM_BIT(PLLEN)));
-
-	/* Wait for lock */
-	while (!(sm_readl(gd->sm, PM_ISR) & SM_BIT(LOCK0))) ;
+#define MAIN_CLK_RATE ((CFG_OSC0_HZ / CFG_PLL0_DIV) * CFG_PLL0_MUL)
 #else
-	main_clock = CFG_OSC0_HZ;
+#define MAIN_CLK_RATE (CFG_OSC0_HZ)
 #endif
 
-	/* Set up clocks for the CPU and all peripheral buses */
-	if (CFG_CLKDIV_CPU) {
-		cksel |= SM_BIT(CPUDIV) | SM_BF(CPUSEL, CFG_CLKDIV_CPU - 1);
-		ckd_state[CLOCK_CPU].freq = main_clock / (1 << CFG_CLKDIV_CPU);
-	} else {
-		ckd_state[CLOCK_CPU].freq = main_clock;
-	}
-	if (CFG_CLKDIV_HSB) {
-		cksel |= SM_BIT(HSBDIV) | SM_BF(HSBSEL, CFG_CLKDIV_HSB - 1);
-		ckd_state[CLOCK_HSB].freq = main_clock / (1 << CFG_CLKDIV_HSB);
-	} else {
-		ckd_state[CLOCK_HSB].freq = main_clock;
-	}
-	if (CFG_CLKDIV_PBA) {
-		cksel |= SM_BIT(PBADIV) | SM_BF(PBASEL, CFG_CLKDIV_PBA - 1);
-		ckd_state[CLOCK_PBA].freq = main_clock / (1 << CFG_CLKDIV_PBA);
-	} else {
-		ckd_state[CLOCK_PBA].freq = main_clock;
-	}
-	if (CFG_CLKDIV_PBB) {
-		cksel |= SM_BIT(PBBDIV) | SM_BF(PBBSEL, CFG_CLKDIV_PBB - 1);
-		ckd_state[CLOCK_PBB].freq = main_clock / (1 << CFG_CLKDIV_PBB);
-	} else {
-		ckd_state[CLOCK_PBB].freq = main_clock;
-	}
-	sm_writel(gd->sm, PM_CKSEL, cksel);
-
-	/* CFG_HZ currently depends on cpu_hz */
-	gd->cpu_hz = ckd_state[CLOCK_CPU].freq;
+DECLARE_GLOBAL_DATA_PTR;
 
-#ifdef CONFIG_PLL
-	/* Use PLL0 as main clock */
-	sm_writel(gd->sm, PM_MCCTRL, SM_BIT(PLLSEL));
-#endif
-}
 
 #endif /* CFG_POWER_MANAGER */
diff --git a/cpu/at32ap/sm.h b/cpu/at32ap/sm.h
index ce81ef0a4631b0bfc438852d5682f5d3439b96fc..6492c8e81d256c52443ab526fa41476bdd9c5222 100644
--- a/cpu/at32ap/sm.h
+++ b/cpu/at32ap/sm.h
@@ -196,9 +196,9 @@
 	 | SM_BF(name,value))
 
 /* Register access macros */
-#define sm_readl(port,reg)				\
-	readl((port)->regs + SM_##reg)
-#define sm_writel(port,reg,value)			\
-	writel((value), (port)->regs + SM_##reg)
+#define sm_readl(reg)					\
+	readl((void *)SM_BASE + SM_##reg)
+#define sm_writel(reg,value)				\
+	writel((value), (void *)SM_BASE + SM_##reg)
 
 #endif /* __CPU_AT32AP_SM_H__ */
diff --git a/cpu/at32ap/start.S b/cpu/at32ap/start.S
index 79ee33b1fac0d028eabd118ad831d4cbbacd9e7d..ab8c2b73d8933737f67000119ee4f3412aa5a346 100644
--- a/cpu/at32ap/start.S
+++ b/cpu/at32ap/start.S
@@ -70,32 +70,12 @@ _start:
 
 2:	lddpc	sp, sp_init
 
-	/*
-	 * Relocate the data section and initialize .bss.  Everything
-	 * is guaranteed to be at least doubleword aligned by the
-	 * linker script.
-	 */
-	lddpc	r12, .Ldata_vma
-	lddpc	r11, .Ldata_lma
-	lddpc	r10, .Ldata_end
-	sub	r10, r12
-4:	ld.d	r8, r11++
-	sub	r10, 8
-	st.d	r12++, r8
-	brne	4b
-
-	mov	r8, 0
-	mov	r9, 0
-	lddpc	r10, .Lbss_end
-	sub	r10, r12
-4:	sub	r10, 8
-	st.d	r12++, r8
-	brne	4b
-
 	/* Initialize the GOT pointer */
 	lddpc	r6, got_init
 3:	rsub	r6, pc
-	ld.w	pc, r6[start_u_boot@got]
+
+	/* Let's go */
+	rjmp	board_init_f
 
 	.align	2
 	.type	sp_init,@object
@@ -103,11 +83,82 @@ sp_init:
 	.long	CFG_INIT_SP_ADDR
 got_init:
 	.long	3b - _GLOBAL_OFFSET_TABLE_
-.Ldata_lma:
-	.long	__data_lma
-.Ldata_vma:
-	.long	_data
-.Ldata_end:
-	.long	_edata
-.Lbss_end:
-	.long	_end
+
+	/*
+	 * void	relocate_code(new_sp, new_gd, monitor_addr)
+	 *
+	 * Relocate the u-boot image into RAM and continue from there.
+	 * Does not return.
+	 */
+	.global	relocate_code
+	.type	relocate_code,@function
+relocate_code:
+	mov	sp, r12		/* use new stack */
+	mov	r12, r11	/* save new_gd */
+	mov	r11, r10	/* save destination address */
+
+	/* copy .text section and flush the cache along the way */
+	lda.w	r8, _text
+	lda.w	r9, _etext
+	sub	lr, r10, r8	/* relocation offset */
+
+1:	ldm	r8++, r0-r3
+	stm	r10, r0-r3
+	sub	r10, -16
+	ldm	r8++, r0-r3
+	stm	r10, r0-r3
+	sub	r10, -16
+	cp.w	r8, r9
+	cache	r10[-4], 0x0d	/* dcache clean/invalidate */
+	cache	r10[-4], 0x01	/* icache invalidate */
+	brlt	1b
+
+	/* flush write buffer */
+	sync	0
+
+	/* copy data sections */
+	lda.w	r9, _edata
+1:	ld.d	r0, r8++
+	st.d	r10++, r0
+	cp.w	r8, r9
+	brlt	1b
+
+	/* zero out .bss */
+	mov	r0, 0
+	mov	r1, 0
+	lda.w	r9, _end
+	sub	r9, r8
+1:	st.d	r10++, r0
+	sub	r9, 8
+	brgt	1b
+
+	/* jump to RAM */
+	sub	r0, pc, . - in_ram
+	add	pc, r0, lr
+
+	.align	2
+in_ram:
+	/* find the new GOT and relocate it */
+	lddpc	r6, got_init_reloc
+3:	rsub	r6, pc
+	mov	r8, r6
+	lda.w	r9, _egot
+	lda.w	r10, _got
+	sub	r9, r10
+1:	ld.w	r0, r8[0]
+	add	r0, lr
+	st.w	r8++, r0
+	sub	r9, 4
+	brgt	1b
+
+	/* Move the exception handlers */
+	mfsr	r2, SYSREG_EVBA
+	add	r2, lr
+	mtsr	SYSREG_EVBA, r2
+
+	/* Do the rest of the initialization sequence */
+	call	board_init_r
+
+	.align	2
+got_init_reloc:
+	.long	3b - _GLOBAL_OFFSET_TABLE_
diff --git a/disk/part.c b/disk/part.c
index 9e8bd4fb8899c50a288695a8fb9a051f8bc38743..acc1a748e44e524ea65848470188dca833f2df4d 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -179,6 +179,7 @@ void dev_print (block_dev_desc_t *dev_desc)
 #if ((CONFIG_COMMANDS & CFG_CMD_IDE)	|| \
      (CONFIG_COMMANDS & CFG_CMD_SCSI)	|| \
      (CONFIG_COMMANDS & CFG_CMD_USB)	|| \
+     defined(CONFIG_MMC)		|| \
      defined(CONFIG_SYSTEMACE)          )
 
 #if defined(CONFIG_MAC_PARTITION) || \
diff --git a/drivers/Makefile b/drivers/Makefile
index fffc22a5e1d72451739d67ffe17ba3df105c3fb1..2eac7c848558a8eb069e99e5ef9ade47f8a9bb4b 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -32,7 +32,7 @@ COBJS	= 3c589.o 5701rls.o ali512x.o atmel_usart.o \
 	  cs8900.o ct69000.o dataflash.o dc2114x.o dm9000x.o \
 	  e1000.o eepro100.o \
 	  i8042.o inca-ip_sw.o keyboard.o \
-	  lan91c96.o \
+	  lan91c96.o macb.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 pci.o pci_auto.o pci_indirect.o \
diff --git a/drivers/atmel_usart.c b/drivers/atmel_usart.c
index 41c37683d7854fb09a5fbac0d9ec4cfbf65f74fe..f35b99730f786528de863802191a1f11e2cd3846 100644
--- a/drivers/atmel_usart.c
+++ b/drivers/atmel_usart.c
@@ -19,7 +19,22 @@
 
 #ifdef CONFIG_ATMEL_USART
 #include <asm/io.h>
-#include <asm/arch/platform.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/memory-map.h>
+
+#if defined(CONFIG_USART0)
+# define USART_ID	0
+# define USART_BASE	USART0_BASE
+#elif defined(CONFIG_USART1)
+# define USART_ID	1
+# define USART_BASE	USART1_BASE
+#elif defined(CONFIG_USART2)
+# define USART_ID	2
+# define USART_BASE	USART2_BASE
+#elif defined(CONFIG_USART3)
+# define USART_ID	3
+# define USART_BASE	USART3_BASE
+#endif
 
 #include "atmel_usart.h"
 
@@ -35,26 +50,23 @@ void serial_setbrg(void)
 	 * Baud Rate = --------------
 	 *                16 * CD
 	 */
-	usart_hz = pm_get_clock_freq(gd->console_uart->resource[0].u.clock.id);
+	usart_hz = get_usart_clk_rate(USART_ID);
 	divisor = (usart_hz / 16 + gd->baudrate / 2) / gd->baudrate;
-	usart3_writel(gd->console_uart, BRGR, USART3_BF(CD, divisor));
+	usart3_writel(BRGR, USART3_BF(CD, divisor));
 }
 
 int serial_init(void)
 {
-	usart3_writel(gd->console_uart, CR,
-		      USART3_BIT(RSTRX) | USART3_BIT(RSTTX));
+	usart3_writel(CR, USART3_BIT(RSTRX) | USART3_BIT(RSTTX));
 
 	serial_setbrg();
 
-	usart3_writel(gd->console_uart, CR,
-		      USART3_BIT(RXEN) | USART3_BIT(TXEN));
-	usart3_writel(gd->console_uart, MR,
-		      USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL)
-		      | USART3_BF(USCLKS, USART3_USCLKS_MCK)
-		      | USART3_BF(CHRL, USART3_CHRL_8)
-		      | USART3_BF(PAR, USART3_PAR_NONE)
-		      | USART3_BF(NBSTOP, USART3_NBSTOP_1));
+	usart3_writel(CR, USART3_BIT(RXEN) | USART3_BIT(TXEN));
+	usart3_writel(MR, (USART3_BF(USART_MODE, USART3_USART_MODE_NORMAL)
+			   | USART3_BF(USCLKS, USART3_USCLKS_MCK)
+			   | USART3_BF(CHRL, USART3_CHRL_8)
+			   | USART3_BF(PAR, USART3_PAR_NONE)
+			   | USART3_BF(NBSTOP, USART3_NBSTOP_1)));
 
 	return 0;
 }
@@ -64,8 +76,8 @@ void serial_putc(char c)
 	if (c == '\n')
 		serial_putc('\r');
 
-	while (!(usart3_readl(gd->console_uart, CSR) & USART3_BIT(TXRDY))) ;
-	usart3_writel(gd->console_uart, THR, c);
+	while (!(usart3_readl(CSR) & USART3_BIT(TXRDY))) ;
+	usart3_writel(THR, c);
 }
 
 void serial_puts(const char *s)
@@ -76,13 +88,13 @@ void serial_puts(const char *s)
 
 int serial_getc(void)
 {
-	while (!(usart3_readl(gd->console_uart, CSR) & USART3_BIT(RXRDY))) ;
-	return usart3_readl(gd->console_uart, RHR);
+	while (!(usart3_readl(CSR) & USART3_BIT(RXRDY))) ;
+	return usart3_readl(RHR);
 }
 
 int serial_tstc(void)
 {
-	return (usart3_readl(gd->console_uart, CSR) & USART3_BIT(RXRDY)) != 0;
+	return (usart3_readl(CSR) & USART3_BIT(RXRDY)) != 0;
 }
 
 #endif /* CONFIG_ATMEL_USART */
diff --git a/drivers/atmel_usart.h b/drivers/atmel_usart.h
index fad90a8116eb69639d7bb9ebd848b8db40b618fa..af3773a99f25fada8a9467c6503ca1ef833e1ba5 100644
--- a/drivers/atmel_usart.h
+++ b/drivers/atmel_usart.h
@@ -306,9 +306,9 @@
 	 | USART3_BF(name,value))
 
 /* Register access macros */
-#define usart3_readl(port,reg)				\
-	readl((port)->regs + USART3_##reg)
-#define usart3_writel(port,reg,value)			\
-	writel((value), (port)->regs + USART3_##reg)
+#define usart3_readl(reg)				\
+	readl((void *)USART_BASE + USART3_##reg)
+#define usart3_writel(reg,value)			\
+	writel((value), (void *)USART_BASE + USART3_##reg)
 
 #endif /* __DRIVERS_ATMEL_USART_H__ */
diff --git a/drivers/macb.c b/drivers/macb.c
new file mode 100644
index 0000000000000000000000000000000000000000..186ab19d35ef2f0b42c9a2e8cb2b87f1071684db
--- /dev/null
+++ b/drivers/macb.c
@@ -0,0 +1,575 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * 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_MACB) && (CONFIG_COMMANDS & (CFG_CMD_NET | CFG_CMD_MII))
+
+/*
+ * The u-boot networking stack is a little weird.  It seems like the
+ * networking core allocates receive buffers up front without any
+ * regard to the hardware that's supposed to actually receive those
+ * packets.
+ *
+ * The MACB receives packets into 128-byte receive buffers, so the
+ * buffers allocated by the core isn't very practical to use.  We'll
+ * allocate our own, but we need one such buffer in case a packet
+ * wraps around the DMA ring so that we have to copy it.
+ *
+ * Therefore, define CFG_RX_ETH_BUFFER to 1 in the board-specific
+ * configuration header.  This way, the core allocates one RX buffer
+ * and one TX buffer, each of which can hold a ethernet packet of
+ * maximum size.
+ *
+ * For some reason, the networking core unconditionally specifies a
+ * 32-byte packet "alignment" (which really should be called
+ * "padding").  MACB shouldn't need that, but we'll refrain from any
+ * core modifications here...
+ */
+
+#include <net.h>
+#include <malloc.h>
+
+#include <linux/mii.h>
+#include <asm/io.h>
+#include <asm/dma-mapping.h>
+#include <asm/arch/clk.h>
+
+#include "macb.h"
+
+#define CFG_MACB_RX_BUFFER_SIZE		4096
+#define CFG_MACB_RX_RING_SIZE		(CFG_MACB_RX_BUFFER_SIZE / 128)
+#define CFG_MACB_TX_RING_SIZE		16
+#define CFG_MACB_TX_TIMEOUT		1000
+#define CFG_MACB_AUTONEG_TIMEOUT	5000000
+
+struct macb_dma_desc {
+	u32	addr;
+	u32	ctrl;
+};
+
+#define RXADDR_USED		0x00000001
+#define RXADDR_WRAP		0x00000002
+
+#define RXBUF_FRMLEN_MASK	0x00000fff
+#define RXBUF_FRAME_START	0x00004000
+#define RXBUF_FRAME_END		0x00008000
+#define RXBUF_TYPEID_MATCH	0x00400000
+#define RXBUF_ADDR4_MATCH	0x00800000
+#define RXBUF_ADDR3_MATCH	0x01000000
+#define RXBUF_ADDR2_MATCH	0x02000000
+#define RXBUF_ADDR1_MATCH	0x04000000
+#define RXBUF_BROADCAST		0x80000000
+
+#define TXBUF_FRMLEN_MASK	0x000007ff
+#define TXBUF_FRAME_END		0x00008000
+#define TXBUF_NOCRC		0x00010000
+#define TXBUF_EXHAUSTED		0x08000000
+#define TXBUF_UNDERRUN		0x10000000
+#define TXBUF_MAXRETRY		0x20000000
+#define TXBUF_WRAP		0x40000000
+#define TXBUF_USED		0x80000000
+
+struct macb_device {
+	void			*regs;
+
+	unsigned int		rx_tail;
+	unsigned int		tx_head;
+	unsigned int		tx_tail;
+
+	void			*rx_buffer;
+	void			*tx_buffer;
+	struct macb_dma_desc	*rx_ring;
+	struct macb_dma_desc	*tx_ring;
+
+	unsigned long		rx_buffer_dma;
+	unsigned long		rx_ring_dma;
+	unsigned long		tx_ring_dma;
+
+	const struct device	*dev;
+	struct eth_device	netdev;
+	unsigned short		phy_addr;
+};
+#define to_macb(_nd) container_of(_nd, struct macb_device, netdev)
+
+static void macb_mdio_write(struct macb_device *macb, u8 reg, u16 value)
+{
+	unsigned long netctl;
+	unsigned long netstat;
+	unsigned long frame;
+
+	netctl = macb_readl(macb, NCR);
+	netctl |= MACB_BIT(MPE);
+	macb_writel(macb, NCR, netctl);
+
+	frame = (MACB_BF(SOF, 1)
+		 | MACB_BF(RW, 1)
+		 | MACB_BF(PHYA, macb->phy_addr)
+		 | MACB_BF(REGA, reg)
+		 | MACB_BF(CODE, 2)
+		 | MACB_BF(DATA, value));
+	macb_writel(macb, MAN, frame);
+
+	do {
+		netstat = macb_readl(macb, NSR);
+	} while (!(netstat & MACB_BIT(IDLE)));
+
+	netctl = macb_readl(macb, NCR);
+	netctl &= ~MACB_BIT(MPE);
+	macb_writel(macb, NCR, netctl);
+}
+
+static u16 macb_mdio_read(struct macb_device *macb, u8 reg)
+{
+	unsigned long netctl;
+	unsigned long netstat;
+	unsigned long frame;
+
+	netctl = macb_readl(macb, NCR);
+	netctl |= MACB_BIT(MPE);
+	macb_writel(macb, NCR, netctl);
+
+	frame = (MACB_BF(SOF, 1)
+		 | MACB_BF(RW, 2)
+		 | MACB_BF(PHYA, macb->phy_addr)
+		 | MACB_BF(REGA, reg)
+		 | MACB_BF(CODE, 2));
+	macb_writel(macb, MAN, frame);
+
+	do {
+		netstat = macb_readl(macb, NSR);
+	} while (!(netstat & MACB_BIT(IDLE)));
+
+	frame = macb_readl(macb, MAN);
+
+	netctl = macb_readl(macb, NCR);
+	netctl &= ~MACB_BIT(MPE);
+	macb_writel(macb, NCR, netctl);
+
+	return MACB_BFEXT(DATA, frame);
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+static int macb_send(struct eth_device *netdev, volatile void *packet,
+		     int length)
+{
+	struct macb_device *macb = to_macb(netdev);
+	unsigned long paddr, ctrl;
+	unsigned int tx_head = macb->tx_head;
+	int i;
+
+	paddr = dma_map_single(packet, length, DMA_TO_DEVICE);
+
+	ctrl = length & TXBUF_FRMLEN_MASK;
+	ctrl |= TXBUF_FRAME_END;
+	if (tx_head == (CFG_MACB_TX_RING_SIZE - 1)) {
+		ctrl |= TXBUF_WRAP;
+		macb->tx_head = 0;
+	} else
+		macb->tx_head++;
+
+	macb->tx_ring[tx_head].ctrl = ctrl;
+	macb->tx_ring[tx_head].addr = paddr;
+	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART));
+
+	/*
+	 * I guess this is necessary because the networking core may
+	 * re-use the transmit buffer as soon as we return...
+	 */
+	i = 0;
+	while (!(macb->tx_ring[tx_head].ctrl & TXBUF_USED)) {
+		if (i > CFG_MACB_TX_TIMEOUT) {
+			printf("%s: TX timeout\n", netdev->name);
+			break;
+		}
+		udelay(1);
+		i++;
+	}
+
+	dma_unmap_single(packet, length, paddr);
+
+	if (i <= CFG_MACB_TX_TIMEOUT) {
+		ctrl = macb->tx_ring[tx_head].ctrl;
+		if (ctrl & TXBUF_UNDERRUN)
+			printf("%s: TX underrun\n", netdev->name);
+		if (ctrl & TXBUF_EXHAUSTED)
+			printf("%s: TX buffers exhausted in mid frame\n",
+			       netdev->name);
+	}
+
+	/* No one cares anyway */
+	return 0;
+}
+
+static void reclaim_rx_buffers(struct macb_device *macb,
+			       unsigned int new_tail)
+{
+	unsigned int i;
+
+	i = macb->rx_tail;
+	while (i > new_tail) {
+		macb->rx_ring[i].addr &= ~RXADDR_USED;
+		i++;
+		if (i > CFG_MACB_RX_RING_SIZE)
+			i = 0;
+	}
+
+	while (i < new_tail) {
+		macb->rx_ring[i].addr &= ~RXADDR_USED;
+		i++;
+	}
+
+	macb->rx_tail = new_tail;
+}
+
+static int macb_recv(struct eth_device *netdev)
+{
+	struct macb_device *macb = to_macb(netdev);
+	unsigned int rx_tail = macb->rx_tail;
+	void *buffer;
+	int length;
+	int wrapped = 0;
+	u32 status;
+
+	for (;;) {
+		if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED))
+			return -1;
+
+		status = macb->rx_ring[rx_tail].ctrl;
+		if (status & RXBUF_FRAME_START) {
+			if (rx_tail != macb->rx_tail)
+				reclaim_rx_buffers(macb, rx_tail);
+			wrapped = 0;
+		}
+
+		if (status & RXBUF_FRAME_END) {
+			buffer = macb->rx_buffer + 128 * macb->rx_tail;
+			length = status & RXBUF_FRMLEN_MASK;
+			if (wrapped) {
+				unsigned int headlen, taillen;
+
+				headlen = 128 * (CFG_MACB_RX_RING_SIZE
+						 - macb->rx_tail);
+				taillen = length - headlen;
+				memcpy((void *)NetRxPackets[0],
+				       buffer, headlen);
+				memcpy((void *)NetRxPackets[0] + headlen,
+				       macb->rx_buffer, taillen);
+				buffer = (void *)NetRxPackets[0];
+			}
+
+			NetReceive(buffer, length);
+			if (++rx_tail >= CFG_MACB_RX_RING_SIZE)
+				rx_tail = 0;
+			reclaim_rx_buffers(macb, rx_tail);
+		} else {
+			if (++rx_tail >= CFG_MACB_RX_RING_SIZE) {
+				wrapped = 1;
+				rx_tail = 0;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int macb_phy_init(struct macb_device *macb)
+{
+	struct eth_device *netdev = &macb->netdev;
+	u32 ncfgr;
+	u16 phy_id, status, adv, lpa;
+	int media, speed, duplex;
+	int i;
+
+	/* Check if the PHY is up to snuff... */
+	phy_id = macb_mdio_read(macb, MII_PHYSID1);
+	if (phy_id == 0xffff) {
+		printf("%s: No PHY present\n", netdev->name);
+		return 0;
+	}
+
+	adv = ADVERTISE_CSMA | ADVERTISE_ALL;
+	macb_mdio_write(macb, MII_ADVERTISE, adv);
+	printf("%s: Starting autonegotiation...\n", netdev->name);
+	macb_mdio_write(macb, MII_BMCR, (BMCR_ANENABLE
+					 | BMCR_ANRESTART));
+
+#if 0
+	for (i = 0; i < 9; i++)
+		printf("mii%d: 0x%04x\n", i, macb_mdio_read(macb, i));
+#endif
+
+	for (i = 0; i < CFG_MACB_AUTONEG_TIMEOUT / 100; i++) {
+		status = macb_mdio_read(macb, MII_BMSR);
+		if (status & BMSR_ANEGCOMPLETE)
+			break;
+		udelay(100);
+	}
+
+	if (status & BMSR_ANEGCOMPLETE)
+		printf("%s: Autonegotiation complete\n", netdev->name);
+	else
+		printf("%s: Autonegotiation timed out (status=0x%04x)\n",
+		       netdev->name, status);
+
+	if (!(status & BMSR_LSTATUS)) {
+		for (i = 0; i < CFG_MACB_AUTONEG_TIMEOUT / 100; i++) {
+			udelay(100);
+			status = macb_mdio_read(macb, MII_BMSR);
+			if (status & BMSR_LSTATUS)
+				break;
+		}
+	}
+
+	if (!(status & BMSR_LSTATUS)) {
+		printf("%s: link down (status: 0x%04x)\n",
+		       netdev->name, status);
+		return 0;
+	} else {
+		lpa = macb_mdio_read(macb, MII_LPA);
+		media = mii_nway_result(lpa & adv);
+		speed = (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)
+			 ? 1 : 0);
+		duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+		printf("%s: link up, %sMbps %s-duplex (lpa: 0x%04x)\n",
+		       netdev->name,
+		       speed ? "100" : "10",
+		       duplex ? "full" : "half",
+		       lpa);
+
+		ncfgr = macb_readl(macb, NCFGR);
+		ncfgr &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
+		if (speed)
+			ncfgr |= MACB_BIT(SPD);
+		if (duplex)
+			ncfgr |= MACB_BIT(FD);
+		macb_writel(macb, NCFGR, ncfgr);
+		return 1;
+	}
+}
+
+static int macb_init(struct eth_device *netdev, bd_t *bd)
+{
+	struct macb_device *macb = to_macb(netdev);
+	unsigned long paddr;
+	u32 hwaddr_bottom;
+	u16 hwaddr_top;
+	int i;
+
+	/*
+	 * macb_halt should have been called at some point before now,
+	 * so we'll assume the controller is idle.
+	 */
+
+	/* initialize DMA descriptors */
+	paddr = macb->rx_buffer_dma;
+	for (i = 0; i < CFG_MACB_RX_RING_SIZE; i++) {
+		if (i == (CFG_MACB_RX_RING_SIZE - 1))
+			paddr |= RXADDR_WRAP;
+		macb->rx_ring[i].addr = paddr;
+		macb->rx_ring[i].ctrl = 0;
+		paddr += 128;
+	}
+	for (i = 0; i < CFG_MACB_TX_RING_SIZE; i++) {
+		macb->tx_ring[i].addr = 0;
+		if (i == (CFG_MACB_TX_RING_SIZE - 1))
+			macb->tx_ring[i].ctrl = TXBUF_USED | TXBUF_WRAP;
+		else
+			macb->tx_ring[i].ctrl = TXBUF_USED;
+	}
+	macb->rx_tail = macb->tx_head = macb->tx_tail = 0;
+
+	macb_writel(macb, RBQP, macb->rx_ring_dma);
+	macb_writel(macb, TBQP, macb->tx_ring_dma);
+
+	/* set hardware address */
+	hwaddr_bottom = cpu_to_le32(*((u32 *)netdev->enetaddr));
+	macb_writel(macb, SA1B, hwaddr_bottom);
+	hwaddr_top = cpu_to_le16(*((u16 *)(netdev->enetaddr + 4)));
+	macb_writel(macb, SA1T, hwaddr_top);
+
+	/* choose RMII or MII mode. This depends on the board */
+#ifdef CONFIG_RMII
+	macb_writel(macb, USRIO, 0);
+#else
+	macb_writel(macb, USRIO, MACB_BIT(MII));
+#endif
+
+	if (!macb_phy_init(macb))
+		return 0;
+
+	/* Enable TX and RX */
+	macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE));
+
+	return 1;
+}
+
+static void macb_halt(struct eth_device *netdev)
+{
+	struct macb_device *macb = to_macb(netdev);
+	u32 ncr, tsr;
+
+	/* Halt the controller and wait for any ongoing transmission to end. */
+	ncr = macb_readl(macb, NCR);
+	ncr |= MACB_BIT(THALT);
+	macb_writel(macb, NCR, ncr);
+
+	do {
+		tsr = macb_readl(macb, TSR);
+	} while (tsr & MACB_BIT(TGO));
+
+	/* Disable TX and RX, and clear statistics */
+	macb_writel(macb, NCR, MACB_BIT(CLRSTAT));
+}
+
+int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
+{
+	struct macb_device *macb;
+	struct eth_device *netdev;
+	unsigned long macb_hz;
+	u32 ncfgr;
+
+	macb = malloc(sizeof(struct macb_device));
+	if (!macb) {
+		printf("Error: Failed to allocate memory for MACB%d\n", id);
+		return -1;
+	}
+	memset(macb, 0, sizeof(struct macb_device));
+
+	netdev = &macb->netdev;
+
+	macb->rx_buffer = dma_alloc_coherent(CFG_MACB_RX_BUFFER_SIZE,
+					     &macb->rx_buffer_dma);
+	macb->rx_ring = dma_alloc_coherent(CFG_MACB_RX_RING_SIZE
+					   * sizeof(struct macb_dma_desc),
+					   &macb->rx_ring_dma);
+	macb->tx_ring = dma_alloc_coherent(CFG_MACB_TX_RING_SIZE
+					   * sizeof(struct macb_dma_desc),
+					   &macb->tx_ring_dma);
+
+	macb->regs = regs;
+	macb->phy_addr = phy_addr;
+
+	sprintf(netdev->name, "macb%d", id);
+	netdev->init = macb_init;
+	netdev->halt = macb_halt;
+	netdev->send = macb_send;
+	netdev->recv = macb_recv;
+
+	/*
+	 * Do some basic initialization so that we at least can talk
+	 * to the PHY
+	 */
+	macb_hz = get_macb_pclk_rate(id);
+	if (macb_hz < 20000000)
+		ncfgr = MACB_BF(CLK, MACB_CLK_DIV8);
+	else if (macb_hz < 40000000)
+		ncfgr = MACB_BF(CLK, MACB_CLK_DIV16);
+	else if (macb_hz < 80000000)
+		ncfgr = MACB_BF(CLK, MACB_CLK_DIV32);
+	else
+		ncfgr = MACB_BF(CLK, MACB_CLK_DIV64);
+
+	macb_writel(macb, NCFGR, ncfgr);
+
+	eth_register(netdev);
+
+	return 0;
+}
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_NET) */
+
+#if (CONFIG_COMMANDS & CFG_CMD_MII)
+
+int miiphy_read(unsigned char addr, unsigned char reg, unsigned short *value)
+{
+	unsigned long netctl;
+	unsigned long netstat;
+	unsigned long frame;
+	int iflag;
+
+	iflag = disable_interrupts();
+	netctl = macb_readl(&macb, EMACB_NCR);
+	netctl |= MACB_BIT(MPE);
+	macb_writel(&macb, EMACB_NCR, netctl);
+	if (iflag)
+		enable_interrupts();
+
+	frame = (MACB_BF(SOF, 1)
+		 | MACB_BF(RW, 2)
+		 | MACB_BF(PHYA, addr)
+		 | MACB_BF(REGA, reg)
+		 | MACB_BF(CODE, 2));
+	macb_writel(&macb, EMACB_MAN, frame);
+
+	do {
+		netstat = macb_readl(&macb, EMACB_NSR);
+	} while (!(netstat & MACB_BIT(IDLE)));
+
+	frame = macb_readl(&macb, EMACB_MAN);
+	*value = MACB_BFEXT(DATA, frame);
+
+	iflag = disable_interrupts();
+	netctl = macb_readl(&macb, EMACB_NCR);
+	netctl &= ~MACB_BIT(MPE);
+	macb_writel(&macb, EMACB_NCR, netctl);
+	if (iflag)
+		enable_interrupts();
+
+	return 0;
+}
+
+int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value)
+{
+	unsigned long netctl;
+	unsigned long netstat;
+	unsigned long frame;
+	int iflag;
+
+	iflag = disable_interrupts();
+	netctl = macb_readl(&macb, EMACB_NCR);
+	netctl |= MACB_BIT(MPE);
+	macb_writel(&macb, EMACB_NCR, netctl);
+	if (iflag)
+		enable_interrupts();
+
+	frame = (MACB_BF(SOF, 1)
+		 | MACB_BF(RW, 1)
+		 | MACB_BF(PHYA, addr)
+		 | MACB_BF(REGA, reg)
+		 | MACB_BF(CODE, 2)
+		 | MACB_BF(DATA, value));
+	macb_writel(&macb, EMACB_MAN, frame);
+
+	do {
+		netstat = macb_readl(&macb, EMACB_NSR);
+	} while (!(netstat & MACB_BIT(IDLE)));
+
+	iflag = disable_interrupts();
+	netctl = macb_readl(&macb, EMACB_NCR);
+	netctl &= ~MACB_BIT(MPE);
+	macb_writel(&macb, EMACB_NCR, netctl);
+	if (iflag)
+		enable_interrupts();
+
+	return 0;
+}
+
+#endif /* (CONFIG_COMMANDS & CFG_CMD_MII) */
+
+#endif /* CONFIG_MACB */
diff --git a/drivers/macb.h b/drivers/macb.h
new file mode 100644
index 0000000000000000000000000000000000000000..c778e4ee493c94649180985546e1dbf889441e1e
--- /dev/null
+++ b/drivers/macb.h
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2005-2006 Atmel Corporation
+ *
+ * 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
+ */
+#ifndef __DRIVERS_MACB_H__
+#define __DRIVERS_MACB_H__
+
+/* MACB register offsets */
+#define MACB_NCR				0x0000
+#define MACB_NCFGR				0x0004
+#define MACB_NSR				0x0008
+#define MACB_TSR				0x0014
+#define MACB_RBQP				0x0018
+#define MACB_TBQP				0x001c
+#define MACB_RSR				0x0020
+#define MACB_ISR				0x0024
+#define MACB_IER				0x0028
+#define MACB_IDR				0x002c
+#define MACB_IMR				0x0030
+#define MACB_MAN				0x0034
+#define MACB_PTR				0x0038
+#define MACB_PFR				0x003c
+#define MACB_FTO				0x0040
+#define MACB_SCF				0x0044
+#define MACB_MCF				0x0048
+#define MACB_FRO				0x004c
+#define MACB_FCSE				0x0050
+#define MACB_ALE				0x0054
+#define MACB_DTF				0x0058
+#define MACB_LCOL				0x005c
+#define MACB_EXCOL				0x0060
+#define MACB_TUND				0x0064
+#define MACB_CSE				0x0068
+#define MACB_RRE				0x006c
+#define MACB_ROVR				0x0070
+#define MACB_RSE				0x0074
+#define MACB_ELE				0x0078
+#define MACB_RJA				0x007c
+#define MACB_USF				0x0080
+#define MACB_STE				0x0084
+#define MACB_RLE				0x0088
+#define MACB_TPF				0x008c
+#define MACB_HRB				0x0090
+#define MACB_HRT				0x0094
+#define MACB_SA1B				0x0098
+#define MACB_SA1T				0x009c
+#define MACB_SA2B				0x00a0
+#define MACB_SA2T				0x00a4
+#define MACB_SA3B				0x00a8
+#define MACB_SA3T				0x00ac
+#define MACB_SA4B				0x00b0
+#define MACB_SA4T				0x00b4
+#define MACB_TID				0x00b8
+#define MACB_TPQ				0x00bc
+#define MACB_USRIO				0x00c0
+#define MACB_WOL				0x00c4
+
+/* Bitfields in NCR */
+#define MACB_LB_OFFSET				0
+#define MACB_LB_SIZE				1
+#define MACB_LLB_OFFSET				1
+#define MACB_LLB_SIZE				1
+#define MACB_RE_OFFSET				2
+#define MACB_RE_SIZE				1
+#define MACB_TE_OFFSET				3
+#define MACB_TE_SIZE				1
+#define MACB_MPE_OFFSET				4
+#define MACB_MPE_SIZE				1
+#define MACB_CLRSTAT_OFFSET			5
+#define MACB_CLRSTAT_SIZE			1
+#define MACB_INCSTAT_OFFSET			6
+#define MACB_INCSTAT_SIZE			1
+#define MACB_WESTAT_OFFSET			7
+#define MACB_WESTAT_SIZE			1
+#define MACB_BP_OFFSET				8
+#define MACB_BP_SIZE				1
+#define MACB_TSTART_OFFSET			9
+#define MACB_TSTART_SIZE			1
+#define MACB_THALT_OFFSET			10
+#define MACB_THALT_SIZE				1
+#define MACB_NCR_TPF_OFFSET			11
+#define MACB_NCR_TPF_SIZE			1
+#define MACB_TZQ_OFFSET				12
+#define MACB_TZQ_SIZE				1
+
+/* Bitfields in NCFGR */
+#define MACB_SPD_OFFSET				0
+#define MACB_SPD_SIZE				1
+#define MACB_FD_OFFSET				1
+#define MACB_FD_SIZE				1
+#define MACB_BIT_RATE_OFFSET			2
+#define MACB_BIT_RATE_SIZE			1
+#define MACB_JFRAME_OFFSET			3
+#define MACB_JFRAME_SIZE			1
+#define MACB_CAF_OFFSET				4
+#define MACB_CAF_SIZE				1
+#define MACB_NBC_OFFSET				5
+#define MACB_NBC_SIZE				1
+#define MACB_NCFGR_MTI_OFFSET			6
+#define MACB_NCFGR_MTI_SIZE			1
+#define MACB_UNI_OFFSET				7
+#define MACB_UNI_SIZE				1
+#define MACB_BIG_OFFSET				8
+#define MACB_BIG_SIZE				1
+#define MACB_EAE_OFFSET				9
+#define MACB_EAE_SIZE				1
+#define MACB_CLK_OFFSET				10
+#define MACB_CLK_SIZE				2
+#define MACB_RTY_OFFSET				12
+#define MACB_RTY_SIZE				1
+#define MACB_PAE_OFFSET				13
+#define MACB_PAE_SIZE				1
+#define MACB_RBOF_OFFSET			14
+#define MACB_RBOF_SIZE				2
+#define MACB_RLCE_OFFSET			16
+#define MACB_RLCE_SIZE				1
+#define MACB_DRFCS_OFFSET			17
+#define MACB_DRFCS_SIZE				1
+#define MACB_EFRHD_OFFSET			18
+#define MACB_EFRHD_SIZE				1
+#define MACB_IRXFCS_OFFSET			19
+#define MACB_IRXFCS_SIZE			1
+
+/* Bitfields in NSR */
+#define MACB_NSR_LINK_OFFSET			0
+#define MACB_NSR_LINK_SIZE			1
+#define MACB_MDIO_OFFSET			1
+#define MACB_MDIO_SIZE				1
+#define MACB_IDLE_OFFSET			2
+#define MACB_IDLE_SIZE				1
+
+/* Bitfields in TSR */
+#define MACB_UBR_OFFSET				0
+#define MACB_UBR_SIZE				1
+#define MACB_COL_OFFSET				1
+#define MACB_COL_SIZE				1
+#define MACB_TSR_RLE_OFFSET			2
+#define MACB_TSR_RLE_SIZE			1
+#define MACB_TGO_OFFSET				3
+#define MACB_TGO_SIZE				1
+#define MACB_BEX_OFFSET				4
+#define MACB_BEX_SIZE				1
+#define MACB_COMP_OFFSET			5
+#define MACB_COMP_SIZE				1
+#define MACB_UND_OFFSET				6
+#define MACB_UND_SIZE				1
+
+/* Bitfields in RSR */
+#define MACB_BNA_OFFSET				0
+#define MACB_BNA_SIZE				1
+#define MACB_REC_OFFSET				1
+#define MACB_REC_SIZE				1
+#define MACB_OVR_OFFSET				2
+#define MACB_OVR_SIZE				1
+
+/* Bitfields in ISR/IER/IDR/IMR */
+#define MACB_MFD_OFFSET				0
+#define MACB_MFD_SIZE				1
+#define MACB_RCOMP_OFFSET			1
+#define MACB_RCOMP_SIZE				1
+#define MACB_RXUBR_OFFSET			2
+#define MACB_RXUBR_SIZE				1
+#define MACB_TXUBR_OFFSET			3
+#define MACB_TXUBR_SIZE				1
+#define MACB_ISR_TUND_OFFSET			4
+#define MACB_ISR_TUND_SIZE			1
+#define MACB_ISR_RLE_OFFSET			5
+#define MACB_ISR_RLE_SIZE			1
+#define MACB_TXERR_OFFSET			6
+#define MACB_TXERR_SIZE				1
+#define MACB_TCOMP_OFFSET			7
+#define MACB_TCOMP_SIZE				1
+#define MACB_ISR_LINK_OFFSET			9
+#define MACB_ISR_LINK_SIZE			1
+#define MACB_ISR_ROVR_OFFSET			10
+#define MACB_ISR_ROVR_SIZE			1
+#define MACB_HRESP_OFFSET			11
+#define MACB_HRESP_SIZE				1
+#define MACB_PFR_OFFSET				12
+#define MACB_PFR_SIZE				1
+#define MACB_PTZ_OFFSET				13
+#define MACB_PTZ_SIZE				1
+
+/* Bitfields in MAN */
+#define MACB_DATA_OFFSET			0
+#define MACB_DATA_SIZE				16
+#define MACB_CODE_OFFSET			16
+#define MACB_CODE_SIZE				2
+#define MACB_REGA_OFFSET			18
+#define MACB_REGA_SIZE				5
+#define MACB_PHYA_OFFSET			23
+#define MACB_PHYA_SIZE				5
+#define MACB_RW_OFFSET				28
+#define MACB_RW_SIZE				2
+#define MACB_SOF_OFFSET				30
+#define MACB_SOF_SIZE				2
+
+/* Bitfields in USRIO */
+#define MACB_MII_OFFSET				0
+#define MACB_MII_SIZE				1
+#define MACB_EAM_OFFSET				1
+#define MACB_EAM_SIZE				1
+#define MACB_TX_PAUSE_OFFSET			2
+#define MACB_TX_PAUSE_SIZE			1
+#define MACB_TX_PAUSE_ZERO_OFFSET		3
+#define MACB_TX_PAUSE_ZERO_SIZE			1
+
+/* Bitfields in WOL */
+#define MACB_IP_OFFSET				0
+#define MACB_IP_SIZE				16
+#define MACB_MAG_OFFSET				16
+#define MACB_MAG_SIZE				1
+#define MACB_ARP_OFFSET				17
+#define MACB_ARP_SIZE				1
+#define MACB_SA1_OFFSET				18
+#define MACB_SA1_SIZE				1
+#define MACB_WOL_MTI_OFFSET			19
+#define MACB_WOL_MTI_SIZE			1
+
+/* Constants for CLK */
+#define MACB_CLK_DIV8				0
+#define MACB_CLK_DIV16				1
+#define MACB_CLK_DIV32				2
+#define MACB_CLK_DIV64				3
+
+/* Constants for MAN register */
+#define MACB_MAN_SOF				1
+#define MACB_MAN_WRITE				1
+#define MACB_MAN_READ				2
+#define MACB_MAN_CODE				2
+
+/* Bit manipulation macros */
+#define MACB_BIT(name)					\
+	(1 << MACB_##name##_OFFSET)
+#define MACB_BF(name,value)				\
+	(((value) & ((1 << MACB_##name##_SIZE) - 1))	\
+	 << MACB_##name##_OFFSET)
+#define MACB_BFEXT(name,value)\
+	(((value) >> MACB_##name##_OFFSET)		\
+	 & ((1 << MACB_##name##_SIZE) - 1))
+#define MACB_BFINS(name,value,old)			\
+	(((old) & ~(((1 << MACB_##name##_SIZE) - 1)	\
+		    << MACB_##name##_OFFSET))		\
+	 | MACB_BF(name,value))
+
+/* Register access macros */
+#define macb_readl(port,reg)				\
+	readl((port)->regs + MACB_##reg)
+#define macb_writel(port,reg,value)			\
+	writel((value), (port)->regs + MACB_##reg)
+
+#endif /* __DRIVERS_MACB_H__ */
diff --git a/include/asm-avr32/arch-at32ap7000/clk.h b/include/asm-avr32/arch-at32ap7000/clk.h
new file mode 100644
index 0000000000000000000000000000000000000000..7e20d97b7f94132819ba737b0fa1421401d3eeb6
--- /dev/null
+++ b/include/asm-avr32/arch-at32ap7000/clk.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * 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
+ */
+#ifndef __ASM_AVR32_ARCH_CLK_H__
+#define __ASM_AVR32_ARCH_CLK_H__
+
+#ifdef CONFIG_PLL
+#define MAIN_CLK_RATE ((CFG_OSC0_HZ / CFG_PLL0_DIV) * CFG_PLL0_MUL)
+#else
+#define MAIN_CLK_RATE (CFG_OSC0_HZ)
+#endif
+
+static inline unsigned long get_cpu_clk_rate(void)
+{
+	return MAIN_CLK_RATE >> CFG_CLKDIV_CPU;
+}
+static inline unsigned long get_hsb_clk_rate(void)
+{
+	return MAIN_CLK_RATE >> CFG_CLKDIV_HSB;
+}
+static inline unsigned long get_pba_clk_rate(void)
+{
+	return MAIN_CLK_RATE >> CFG_CLKDIV_PBA;
+}
+static inline unsigned long get_pbb_clk_rate(void)
+{
+	return MAIN_CLK_RATE >> CFG_CLKDIV_PBB;
+}
+
+/* Accessors for specific devices. More will be added as needed. */
+static inline unsigned long get_sdram_clk_rate(void)
+{
+	return get_hsb_clk_rate();
+}
+static inline unsigned long get_usart_clk_rate(unsigned int dev_id)
+{
+	return get_pba_clk_rate();
+}
+static inline unsigned long get_macb_pclk_rate(unsigned int dev_id)
+{
+	return get_pbb_clk_rate();
+}
+static inline unsigned long get_macb_hclk_rate(unsigned int dev_id)
+{
+	return get_hsb_clk_rate();
+}
+static inline unsigned long get_mci_clk_rate(void)
+{
+	return get_pbb_clk_rate();
+}
+
+#endif /* __ASM_AVR32_ARCH_CLK_H__ */
diff --git a/include/asm-avr32/arch-at32ap7000/gpio.h b/include/asm-avr32/arch-at32ap7000/gpio.h
new file mode 100644
index 0000000000000000000000000000000000000000..e4812d4d08b487fd176fe09f6b531e552757f997
--- /dev/null
+++ b/include/asm-avr32/arch-at32ap7000/gpio.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2006 Atmel Corporation
+ *
+ * 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
+ */
+#ifndef __ASM_AVR32_ARCH_GPIO_H__
+#define __ASM_AVR32_ARCH_GPIO_H__
+
+#include <asm/arch/memory-map.h>
+
+#define NR_GPIO_CONTROLLERS	5
+
+/*
+ * Pin numbers identifying specific GPIO pins on the chip.
+ */
+#define GPIO_PIOA_BASE	(0)
+#define GPIO_PIN_PA0	(GPIO_PIOA_BASE +  0)
+#define GPIO_PIN_PA1	(GPIO_PIOA_BASE +  1)
+#define GPIO_PIN_PA2	(GPIO_PIOA_BASE +  2)
+#define GPIO_PIN_PA3	(GPIO_PIOA_BASE +  3)
+#define GPIO_PIN_PA4	(GPIO_PIOA_BASE +  4)
+#define GPIO_PIN_PA5	(GPIO_PIOA_BASE +  5)
+#define GPIO_PIN_PA6	(GPIO_PIOA_BASE +  6)
+#define GPIO_PIN_PA7	(GPIO_PIOA_BASE +  7)
+#define GPIO_PIN_PA8	(GPIO_PIOA_BASE +  8)
+#define GPIO_PIN_PA9	(GPIO_PIOA_BASE +  9)
+#define GPIO_PIN_PA10	(GPIO_PIOA_BASE + 10)
+#define GPIO_PIN_PA11	(GPIO_PIOA_BASE + 11)
+#define GPIO_PIN_PA12	(GPIO_PIOA_BASE + 12)
+#define GPIO_PIN_PA13	(GPIO_PIOA_BASE + 13)
+#define GPIO_PIN_PA14	(GPIO_PIOA_BASE + 14)
+#define GPIO_PIN_PA15	(GPIO_PIOA_BASE + 15)
+#define GPIO_PIN_PA16	(GPIO_PIOA_BASE + 16)
+#define GPIO_PIN_PA17	(GPIO_PIOA_BASE + 17)
+#define GPIO_PIN_PA18	(GPIO_PIOA_BASE + 18)
+#define GPIO_PIN_PA19	(GPIO_PIOA_BASE + 19)
+#define GPIO_PIN_PA20	(GPIO_PIOA_BASE + 20)
+#define GPIO_PIN_PA21	(GPIO_PIOA_BASE + 21)
+#define GPIO_PIN_PA22	(GPIO_PIOA_BASE + 22)
+#define GPIO_PIN_PA23	(GPIO_PIOA_BASE + 23)
+#define GPIO_PIN_PA24	(GPIO_PIOA_BASE + 24)
+#define GPIO_PIN_PA25	(GPIO_PIOA_BASE + 25)
+#define GPIO_PIN_PA26	(GPIO_PIOA_BASE + 26)
+#define GPIO_PIN_PA27	(GPIO_PIOA_BASE + 27)
+#define GPIO_PIN_PA28	(GPIO_PIOA_BASE + 28)
+#define GPIO_PIN_PA29	(GPIO_PIOA_BASE + 29)
+#define GPIO_PIN_PA30	(GPIO_PIOA_BASE + 30)
+#define GPIO_PIN_PA31	(GPIO_PIOA_BASE + 31)
+
+#define GPIO_PIOB_BASE	(GPIO_PIOA_BASE + 32)
+#define GPIO_PIN_PB0	(GPIO_PIOB_BASE +  0)
+#define GPIO_PIN_PB1	(GPIO_PIOB_BASE +  1)
+#define GPIO_PIN_PB2	(GPIO_PIOB_BASE +  2)
+#define GPIO_PIN_PB3	(GPIO_PIOB_BASE +  3)
+#define GPIO_PIN_PB4	(GPIO_PIOB_BASE +  4)
+#define GPIO_PIN_PB5	(GPIO_PIOB_BASE +  5)
+#define GPIO_PIN_PB6	(GPIO_PIOB_BASE +  6)
+#define GPIO_PIN_PB7	(GPIO_PIOB_BASE +  7)
+#define GPIO_PIN_PB8	(GPIO_PIOB_BASE +  8)
+#define GPIO_PIN_PB9	(GPIO_PIOB_BASE +  9)
+#define GPIO_PIN_PB10	(GPIO_PIOB_BASE + 10)
+#define GPIO_PIN_PB11	(GPIO_PIOB_BASE + 11)
+#define GPIO_PIN_PB12	(GPIO_PIOB_BASE + 12)
+#define GPIO_PIN_PB13	(GPIO_PIOB_BASE + 13)
+#define GPIO_PIN_PB14	(GPIO_PIOB_BASE + 14)
+#define GPIO_PIN_PB15	(GPIO_PIOB_BASE + 15)
+#define GPIO_PIN_PB16	(GPIO_PIOB_BASE + 16)
+#define GPIO_PIN_PB17	(GPIO_PIOB_BASE + 17)
+#define GPIO_PIN_PB18	(GPIO_PIOB_BASE + 18)
+#define GPIO_PIN_PB19	(GPIO_PIOB_BASE + 19)
+#define GPIO_PIN_PB20	(GPIO_PIOB_BASE + 20)
+#define GPIO_PIN_PB21	(GPIO_PIOB_BASE + 21)
+#define GPIO_PIN_PB22	(GPIO_PIOB_BASE + 22)
+#define GPIO_PIN_PB23	(GPIO_PIOB_BASE + 23)
+#define GPIO_PIN_PB24	(GPIO_PIOB_BASE + 24)
+#define GPIO_PIN_PB25	(GPIO_PIOB_BASE + 25)
+#define GPIO_PIN_PB26	(GPIO_PIOB_BASE + 26)
+#define GPIO_PIN_PB27	(GPIO_PIOB_BASE + 27)
+#define GPIO_PIN_PB28	(GPIO_PIOB_BASE + 28)
+#define GPIO_PIN_PB29	(GPIO_PIOB_BASE + 29)
+#define GPIO_PIN_PB30	(GPIO_PIOB_BASE + 30)
+
+#define GPIO_PIOC_BASE	(GPIO_PIOB_BASE + 32)
+#define GPIO_PIN_PC0	(GPIO_PIOC_BASE +  0)
+#define GPIO_PIN_PC1	(GPIO_PIOC_BASE +  1)
+#define GPIO_PIN_PC2	(GPIO_PIOC_BASE +  2)
+#define GPIO_PIN_PC3	(GPIO_PIOC_BASE +  3)
+#define GPIO_PIN_PC4	(GPIO_PIOC_BASE +  4)
+#define GPIO_PIN_PC5	(GPIO_PIOC_BASE +  5)
+#define GPIO_PIN_PC6	(GPIO_PIOC_BASE +  6)
+#define GPIO_PIN_PC7	(GPIO_PIOC_BASE +  7)
+#define GPIO_PIN_PC8	(GPIO_PIOC_BASE +  8)
+#define GPIO_PIN_PC9	(GPIO_PIOC_BASE +  9)
+#define GPIO_PIN_PC10	(GPIO_PIOC_BASE + 10)
+#define GPIO_PIN_PC11	(GPIO_PIOC_BASE + 11)
+#define GPIO_PIN_PC12	(GPIO_PIOC_BASE + 12)
+#define GPIO_PIN_PC13	(GPIO_PIOC_BASE + 13)
+#define GPIO_PIN_PC14	(GPIO_PIOC_BASE + 14)
+#define GPIO_PIN_PC15	(GPIO_PIOC_BASE + 15)
+#define GPIO_PIN_PC16	(GPIO_PIOC_BASE + 16)
+#define GPIO_PIN_PC17	(GPIO_PIOC_BASE + 17)
+#define GPIO_PIN_PC18	(GPIO_PIOC_BASE + 18)
+#define GPIO_PIN_PC19	(GPIO_PIOC_BASE + 19)
+#define GPIO_PIN_PC20	(GPIO_PIOC_BASE + 20)
+#define GPIO_PIN_PC21	(GPIO_PIOC_BASE + 21)
+#define GPIO_PIN_PC22	(GPIO_PIOC_BASE + 22)
+#define GPIO_PIN_PC23	(GPIO_PIOC_BASE + 23)
+#define GPIO_PIN_PC24	(GPIO_PIOC_BASE + 24)
+#define GPIO_PIN_PC25	(GPIO_PIOC_BASE + 25)
+#define GPIO_PIN_PC26	(GPIO_PIOC_BASE + 26)
+#define GPIO_PIN_PC27	(GPIO_PIOC_BASE + 27)
+#define GPIO_PIN_PC28	(GPIO_PIOC_BASE + 28)
+#define GPIO_PIN_PC29	(GPIO_PIOC_BASE + 29)
+#define GPIO_PIN_PC30	(GPIO_PIOC_BASE + 30)
+#define GPIO_PIN_PC31	(GPIO_PIOC_BASE + 31)
+
+#define GPIO_PIOD_BASE	(GPIO_PIOC_BASE + 32)
+#define GPIO_PIN_PD0	(GPIO_PIOD_BASE +  0)
+#define GPIO_PIN_PD1	(GPIO_PIOD_BASE +  1)
+#define GPIO_PIN_PD2	(GPIO_PIOD_BASE +  2)
+#define GPIO_PIN_PD3	(GPIO_PIOD_BASE +  3)
+#define GPIO_PIN_PD4	(GPIO_PIOD_BASE +  4)
+#define GPIO_PIN_PD5	(GPIO_PIOD_BASE +  5)
+#define GPIO_PIN_PD6	(GPIO_PIOD_BASE +  6)
+#define GPIO_PIN_PD7	(GPIO_PIOD_BASE +  7)
+#define GPIO_PIN_PD8	(GPIO_PIOD_BASE +  8)
+#define GPIO_PIN_PD9	(GPIO_PIOD_BASE +  9)
+#define GPIO_PIN_PD10	(GPIO_PIOD_BASE + 10)
+#define GPIO_PIN_PD11	(GPIO_PIOD_BASE + 11)
+#define GPIO_PIN_PD12	(GPIO_PIOD_BASE + 12)
+#define GPIO_PIN_PD13	(GPIO_PIOD_BASE + 13)
+#define GPIO_PIN_PD14	(GPIO_PIOD_BASE + 14)
+#define GPIO_PIN_PD15	(GPIO_PIOD_BASE + 15)
+#define GPIO_PIN_PD16	(GPIO_PIOD_BASE + 16)
+#define GPIO_PIN_PD17	(GPIO_PIOD_BASE + 17)
+
+#define GPIO_PIOE_BASE	(GPIO_PIOD_BASE + 32)
+#define GPIO_PIN_PE0	(GPIO_PIOE_BASE +  0)
+#define GPIO_PIN_PE1	(GPIO_PIOE_BASE +  1)
+#define GPIO_PIN_PE2	(GPIO_PIOE_BASE +  2)
+#define GPIO_PIN_PE3	(GPIO_PIOE_BASE +  3)
+#define GPIO_PIN_PE4	(GPIO_PIOE_BASE +  4)
+#define GPIO_PIN_PE5	(GPIO_PIOE_BASE +  5)
+#define GPIO_PIN_PE6	(GPIO_PIOE_BASE +  6)
+#define GPIO_PIN_PE7	(GPIO_PIOE_BASE +  7)
+#define GPIO_PIN_PE8	(GPIO_PIOE_BASE +  8)
+#define GPIO_PIN_PE9	(GPIO_PIOE_BASE +  9)
+#define GPIO_PIN_PE10	(GPIO_PIOE_BASE + 10)
+#define GPIO_PIN_PE11	(GPIO_PIOE_BASE + 11)
+#define GPIO_PIN_PE12	(GPIO_PIOE_BASE + 12)
+#define GPIO_PIN_PE13	(GPIO_PIOE_BASE + 13)
+#define GPIO_PIN_PE14	(GPIO_PIOE_BASE + 14)
+#define GPIO_PIN_PE15	(GPIO_PIOE_BASE + 15)
+#define GPIO_PIN_PE16	(GPIO_PIOE_BASE + 16)
+#define GPIO_PIN_PE17	(GPIO_PIOE_BASE + 17)
+#define GPIO_PIN_PE18	(GPIO_PIOE_BASE + 18)
+#define GPIO_PIN_PE19	(GPIO_PIOE_BASE + 19)
+#define GPIO_PIN_PE20	(GPIO_PIOE_BASE + 20)
+#define GPIO_PIN_PE21	(GPIO_PIOE_BASE + 21)
+#define GPIO_PIN_PE22	(GPIO_PIOE_BASE + 22)
+#define GPIO_PIN_PE23	(GPIO_PIOE_BASE + 23)
+#define GPIO_PIN_PE24	(GPIO_PIOE_BASE + 24)
+#define GPIO_PIN_PE25	(GPIO_PIOE_BASE + 25)
+#define GPIO_PIN_PE26	(GPIO_PIOE_BASE + 26)
+
+static inline void *gpio_pin_to_addr(unsigned int pin)
+{
+	switch (pin >> 5) {
+	case 0:
+		return (void *)PIOA_BASE;
+	case 1:
+		return (void *)PIOB_BASE;
+	case 2:
+		return (void *)PIOC_BASE;
+	case 3:
+		return (void *)PIOD_BASE;
+	case 4:
+		return (void *)PIOE_BASE;
+	default:
+		return NULL;
+	}
+}
+
+void gpio_select_periph_A(unsigned int pin, int use_pullup);
+void gpio_select_periph_B(unsigned int pin, int use_pullup);
+
+void gpio_enable_ebi(void);
+void gpio_enable_usart0(void);
+void gpio_enable_usart1(void);
+void gpio_enable_usart2(void);
+void gpio_enable_usart3(void);
+void gpio_enable_macb0(void);
+void gpio_enable_macb1(void);
+void gpio_enable_mmci(void);
+
+#endif /* __ASM_AVR32_ARCH_GPIO_H__ */
diff --git a/include/asm-avr32/arch-at32ap7000/hmatrix2.h b/include/asm-avr32/arch-at32ap7000/hmatrix2.h
index e6df4b7fe33a33bcb83787d64fb2235a7ededf30..b0e787a92f9888f4ec50610ae9ad567dedb0cad1 100644
--- a/include/asm-avr32/arch-at32ap7000/hmatrix2.h
+++ b/include/asm-avr32/arch-at32ap7000/hmatrix2.h
@@ -224,9 +224,9 @@
 	 | HMATRIX2_BF(name,value))
 
 /* Register access macros */
-#define hmatrix2_readl(port,reg)				\
-	readl((port)->regs + HMATRIX2_##reg)
-#define hmatrix2_writel(port,reg,value)				\
-	writel((value), (port)->regs + HMATRIX2_##reg)
+#define hmatrix2_readl(reg)					\
+	readl((void *)HMATRIX_BASE + HMATRIX2_##reg)
+#define hmatrix2_writel(reg,value)				\
+	writel((value), (void *)HMATRIX_BASE + HMATRIX2_##reg)
 
 #endif /* __ASM_AVR32_HMATRIX2_H__ */
diff --git a/include/asm-avr32/arch-at32ap7000/memory-map.h b/include/asm-avr32/arch-at32ap7000/memory-map.h
index 8ffe851c89e7181a7b42bbe917f8f5a6c89a7aff..5513e88e7b030001ca7eea9fddab14cda779c8bf 100644
--- a/include/asm-avr32/arch-at32ap7000/memory-map.h
+++ b/include/asm-avr32/arch-at32ap7000/memory-map.h
@@ -19,43 +19,48 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
  */
-#ifndef __ASM_AVR32_PART_MEMORY_MAP_H__
-#define __ASM_AVR32_PART_MEMORY_MAP_H__
+#ifndef __AT32AP7000_MEMORY_MAP_H__
+#define __AT32AP7000_MEMORY_MAP_H__
 
-#define AUDIOC_BASE                             0xFFF02800
-#define DAC_BASE                                0xFFF02000
-#define DMAC_BASE                               0xFF200000
-#define ECC_BASE                                0xFFF03C00
-#define HISI_BASE                               0xFFF02C00
-#define HMATRIX_BASE                            0xFFF00800
-#define HSDRAMC_BASE                            0xFFF03800
-#define HSMC_BASE                               0xFFF03400
-#define LCDC_BASE                               0xFF000000
-#define MACB0_BASE                              0xFFF01800
-#define MACB1_BASE                              0xFFF01C00
-#define MMCI_BASE                               0xFFF02400
-#define PIOA_BASE                               0xFFE02800
-#define PIOB_BASE                               0xFFE02C00
-#define PIOC_BASE                               0xFFE03000
-#define PIOD_BASE                               0xFFE03400
-#define PIOE_BASE                               0xFFE03800
-#define PSIF_BASE                               0xFFE03C00
-#define PWM_BASE                                0xFFF01400
-#define SM_BASE                                 0xFFF00000
-#define INTC_BASE				0XFFF00400
-#define SPI0_BASE                               0xFFE00000
-#define SPI1_BASE                               0xFFE00400
-#define SSC0_BASE                               0xFFE01C00
-#define SSC1_BASE                               0xFFE02000
-#define SSC2_BASE                               0xFFE02400
-#define TIMER0_BASE                             0xFFF00C00
-#define TIMER1_BASE                             0xFFF01000
-#define TWI_BASE                                0xFFE00800
-#define USART0_BASE                             0xFFE00C00
-#define USART1_BASE                             0xFFE01000
-#define USART2_BASE                             0xFFE01400
-#define USART3_BASE                             0xFFE01800
-#define USB_FIFO                                0xFF300000
-#define USB_BASE                                0xFFF03000
+/* Devices on the High Speed Bus (HSB) */
+#define LCDC_BASE				0xFF000000
+#define DMAC_BASE				0xFF200000
+#define USB_FIFO				0xFF300000
 
-#endif /* __ASM_AVR32_PART_MEMORY_MAP_H__ */
+/* Devices on Peripheral Bus A (PBA) */
+#define SPI0_BASE				0xFFE00000
+#define SPI1_BASE				0xFFE00400
+#define TWI_BASE				0xFFE00800
+#define USART0_BASE				0xFFE00C00
+#define USART1_BASE				0xFFE01000
+#define USART2_BASE				0xFFE01400
+#define USART3_BASE				0xFFE01800
+#define SSC0_BASE				0xFFE01C00
+#define SSC1_BASE				0xFFE02000
+#define SSC2_BASE				0xFFE02400
+#define PIOA_BASE				0xFFE02800
+#define PIOB_BASE				0xFFE02C00
+#define PIOC_BASE				0xFFE03000
+#define PIOD_BASE				0xFFE03400
+#define PIOE_BASE				0xFFE03800
+#define PSIF_BASE				0xFFE03C00
+
+/* Devices on Peripheral Bus B (PBB) */
+#define SM_BASE					0xFFF00000
+#define INTC_BASE				0xFFF00400
+#define HMATRIX_BASE				0xFFF00800
+#define TIMER0_BASE				0xFFF00C00
+#define TIMER1_BASE				0xFFF01000
+#define PWM_BASE				0xFFF01400
+#define MACB0_BASE				0xFFF01800
+#define MACB1_BASE				0xFFF01C00
+#define DAC_BASE				0xFFF02000
+#define MMCI_BASE				0xFFF02400
+#define AUDIOC_BASE				0xFFF02800
+#define HISI_BASE				0xFFF02C00
+#define USB_BASE				0xFFF03000
+#define HSMC_BASE				0xFFF03400
+#define HSDRAMC_BASE				0xFFF03800
+#define ECC_BASE				0xFFF03C00
+
+#endif /* __AT32AP7000_MEMORY_MAP_H__ */
diff --git a/include/asm-avr32/arch-at32ap7000/mmc.h b/include/asm-avr32/arch-at32ap7000/mmc.h
new file mode 100644
index 0000000000000000000000000000000000000000..fcfbbb3c6cb7fe14628bacd2b27cc7048374b17f
--- /dev/null
+++ b/include/asm-avr32/arch-at32ap7000/mmc.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * 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
+ */
+#ifndef __ASM_AVR32_MMC_H
+#define __ASM_AVR32_MMC_H
+
+struct mmc_cid {
+	unsigned long psn;
+	unsigned short oid;
+	unsigned char mid;
+	unsigned char prv;
+	unsigned char mdt;
+	char pnm[7];
+};
+
+struct mmc_csd
+{
+	u8	csd_structure:2,
+		spec_vers:4,
+		rsvd1:2;
+	u8	taac;
+	u8	nsac;
+	u8	tran_speed;
+	u16	ccc:12,
+		read_bl_len:4;
+	u64	read_bl_partial:1,
+		write_blk_misalign:1,
+		read_blk_misalign:1,
+		dsr_imp:1,
+		rsvd2:2,
+		c_size:12,
+		vdd_r_curr_min:3,
+		vdd_r_curr_max:3,
+		vdd_w_curr_min:3,
+		vdd_w_curr_max:3,
+		c_size_mult:3,
+		sector_size:5,
+		erase_grp_size:5,
+		wp_grp_size:5,
+		wp_grp_enable:1,
+		default_ecc:2,
+		r2w_factor:3,
+		write_bl_len:4,
+		write_bl_partial:1,
+		rsvd3:5;
+	u8	file_format_grp:1,
+		copy:1,
+		perm_write_protect:1,
+		tmp_write_protect:1,
+		file_format:2,
+		ecc:2;
+	u8	crc:7;
+	u8	one:1;
+};
+
+/* MMC Command numbers */
+#define MMC_CMD_GO_IDLE_STATE		0
+#define MMC_CMD_SEND_OP_COND		1
+#define MMC_CMD_ALL_SEND_CID 		2
+#define MMC_CMD_SET_RELATIVE_ADDR	3
+#define MMC_CMD_SD_SEND_RELATIVE_ADDR	3
+#define MMC_CMD_SET_DSR			4
+#define MMC_CMD_SELECT_CARD		7
+#define MMC_CMD_SEND_CSD 		9
+#define MMC_CMD_SEND_CID 		10
+#define MMC_CMD_SEND_STATUS		13
+#define MMC_CMD_SET_BLOCKLEN		16
+#define MMC_CMD_READ_SINGLE_BLOCK	17
+#define MMC_CMD_READ_MULTIPLE_BLOCK	18
+#define MMC_CMD_WRITE_BLOCK		24
+#define MMC_CMD_APP_CMD			55
+
+#define MMC_ACMD_SD_SEND_OP_COND	41
+
+#define R1_ILLEGAL_COMMAND		(1 << 22)
+#define R1_APP_CMD			(1 << 5)
+
+#endif /* __ASM_AVR32_MMC_H */
diff --git a/include/asm-avr32/arch-at32ap7000/platform.h b/include/asm-avr32/arch-at32ap7000/platform.h
deleted file mode 100644
index 759050116a93f8e787058d9dddb4e5e4c869ca81..0000000000000000000000000000000000000000
--- a/include/asm-avr32/arch-at32ap7000/platform.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2005-2006 Atmel Corporation
- *
- * 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
- */
-#ifndef _ASM_AVR32_ARCH_PM_H
-#define _ASM_AVR32_ARCH_PM_H
-
-#include <config.h>
-
-enum clock_domain_id {
-	CLOCK_CPU,
-	CLOCK_HSB,
-	CLOCK_PBA,
-	CLOCK_PBB,
-	NR_CLOCK_DOMAINS,
-};
-
-enum resource_type {
-	RESOURCE_GPIO,
-	RESOURCE_CLOCK,
-};
-
-enum gpio_func {
-	GPIO_FUNC_GPIO,
-	GPIO_FUNC_A,
-	GPIO_FUNC_B,
-};
-
-enum device_id {
-	DEVICE_HEBI,
-	DEVICE_PBA_BRIDGE,
-	DEVICE_PBB_BRIDGE,
-	DEVICE_HRAMC,
-	/* GPIO controllers must be kept together */
-	DEVICE_PIOA,
-	DEVICE_PIOB,
-	DEVICE_PIOC,
-	DEVICE_PIOD,
-	DEVICE_PIOE,
-	DEVICE_SM,
-	DEVICE_INTC,
-	DEVICE_HMATRIX,
-#if defined(CFG_HPDC)
-	DEVICE_HPDC,
-#endif
-#if defined(CFG_MACB0)
-	DEVICE_MACB0,
-#endif
-#if defined(CFG_MACB1)
-	DEVICE_MACB1,
-#endif
-#if defined(CFG_LCDC)
-	DEVICE_LCDC,
-#endif
-#if defined(CFG_USART0)
-	DEVICE_USART0,
-#endif
-#if defined(CFG_USART1)
-	DEVICE_USART1,
-#endif
-#if defined(CFG_USART2)
-	DEVICE_USART2,
-#endif
-#if defined(CFG_USART3)
-	DEVICE_USART3,
-#endif
-#if defined(CFG_MMCI)
-	DEVICE_MMCI,
-#endif
-#if defined(CFG_DMAC)
-	DEVICE_DMAC,
-#endif
-	NR_DEVICES,
-	NO_DEVICE = -1,
-};
-
-struct resource {
-	enum resource_type type;
-	union {
-		struct {
-			unsigned long base;
-		} iomem;
-		struct {
-			unsigned char nr_pins;
-			enum device_id gpio_dev;
-			enum gpio_func func;
-			unsigned short start;
-		} gpio;
-		struct {
-			enum clock_domain_id id;
-			unsigned char index;
-		} clock;
-	} u;
-};
-
-struct device {
-	void *regs;
-	unsigned int nr_resources;
-	const struct resource *resource;
-};
-
-struct clock_domain {
-	unsigned short reg;
-	enum clock_domain_id id;
-	enum device_id bridge;
-};
-
-extern const struct device chip_device[NR_DEVICES];
-extern const struct clock_domain chip_clock[NR_CLOCK_DOMAINS];
-
-/**
- * Set up PIO, clock management and I/O memory for a device.
- */
-const struct device *get_device(enum device_id devid);
-void put_device(const struct device *dev);
-
-int gpio_set_func(enum device_id gpio_devid, unsigned int start,
-		  unsigned int nr_pins, enum gpio_func func);
-void gpio_free(enum device_id gpio_devid, unsigned int start,
-	       unsigned int nr_pins);
-
-void pm_init(void);
-int pm_enable_clock(enum clock_domain_id id, unsigned int index);
-void pm_disable_clock(enum clock_domain_id id, unsigned int index);
-unsigned long pm_get_clock_freq(enum clock_domain_id domain);
-
-void cpu_enable_sdram(void);
-
-#endif /* _ASM_AVR32_ARCH_PM_H */
diff --git a/include/asm-avr32/global_data.h b/include/asm-avr32/global_data.h
index 01d836c6395a07d7922eb44a19b1f0e4dbc0428e..681c514ccf45d962abd5e5a10c44a8b282581673 100644
--- a/include/asm-avr32/global_data.h
+++ b/include/asm-avr32/global_data.h
@@ -35,10 +35,8 @@
 typedef	struct	global_data {
 	bd_t		*bd;
 	unsigned long	flags;
-	const struct device	*console_uart;
-	const struct device	*sm;
 	unsigned long	baudrate;
-	unsigned long	sdram_size;
+	unsigned long	stack_end;	/* highest stack address */
 	unsigned long	have_console;	/* serial_init() was called */
 	unsigned long	reloc_off;	/* Relocation Offset */
 	unsigned long	env_addr;	/* Address of env struct */
diff --git a/include/asm-avr32/initcalls.h b/include/asm-avr32/initcalls.h
index 7ba25cde53e2316d14b8f204441edeccce7ae96f..583e5dc1010415a29991df3925b9baaba97b47c0 100644
--- a/include/asm-avr32/initcalls.h
+++ b/include/asm-avr32/initcalls.h
@@ -26,8 +26,6 @@
 
 extern int cpu_init(void);
 extern int timer_init(void);
-extern void board_init_memories(void);
-extern void board_init_pio(void);
 extern void board_init_info(void);
 
 #endif /* __ASM_AVR32_INITCALLS_H__ */
diff --git a/include/configs/atstk1002.h b/include/configs/atstk1002.h
index 458ebabeb9a217946d39d057ed6b84a72a63126a..beaf3851dc8ece66173b667179b36ab03a820e6d 100644
--- a/include/configs/atstk1002.h
+++ b/include/configs/atstk1002.h
@@ -62,11 +62,14 @@
  */
 #define CFG_PLL0_OPT			0x04
 
-#define CFG_USART1			1
-
-#define CFG_CONSOLE_UART_DEV		DEVICE_USART1
+#undef CONFIG_USART0
+#define CONFIG_USART1			1
+#undef CONFIG_USART2
+#undef CONFIG_USART3
 
 /* User serviceable stuff */
+#define CONFIG_DOS_PARTITION		1
+
 #define CONFIG_CMDLINE_TAG		1
 #define CONFIG_SETUP_MEMORY_TAGS	1
 #define CONFIG_INITRD_TAG		1
@@ -75,16 +78,47 @@
 
 #define CONFIG_BAUDRATE			115200
 #define CONFIG_BOOTARGS							\
-	"console=ttyUS0 root=/dev/mtdblock1 fbmem=600k"
+	"console=ttyS0 root=/dev/mtdblock1 rootfstype=jffs2 fbmem=600k"
+
+#define CONFIG_BOOTCOMMAND						\
+	"fsload; bootm $(fileaddr)"
+
+/*
+ * Only interrupt autoboot if <space> is pressed. Otherwise, garbage
+ * data on the serial line may interrupt the boot sequence.
+ */
+#define CONFIG_BOOTDELAY		2
+#define CONFIG_AUTOBOOT			1
+#define CONFIG_AUTOBOOT_KEYED		1
+#define CONFIG_AUTOBOOT_PROMPT				\
+	"Press SPACE to abort autoboot in %d seconds\n"
+#define CONFIG_AUTOBOOT_DELAY_STR	"d"
+#define CONFIG_AUTOBOOT_STOP_STR	" "
+
+/*
+ * These are "locally administered ethernet addresses" generated by
+ * ./tools/gen_eth_addr
+ *
+ * After booting the board for the first time, new addresses should be
+ * generated and assigned to the environment variables "ethaddr" and
+ * "eth1addr".
+ */
+#define CONFIG_ETHADDR			"6a:87:71:14:cd:cb"
+#define CONFIG_ETH1ADDR			"ca:f8:15:e6:3e:e6"
+#define CONFIG_OVERWRITE_ETHADDR_ONCE	1
+#define CONFIG_NET_MULTI		1
+
+#define CONFIG_BOOTP_MASK		(CONFIG_BOOTP_SUBNETMASK	\
+					 | CONFIG_BOOTP_GATEWAY)
 
 #define CONFIG_COMMANDS			(CFG_CMD_BDI			\
 					 | CFG_CMD_LOADS		\
 					 | CFG_CMD_LOADB		\
-					 /* | CFG_CMD_IMI */		\
+					 | CFG_CMD_IMI			\
 					 /* | CFG_CMD_CACHE */		\
 					 | CFG_CMD_FLASH		\
 					 | CFG_CMD_MEMORY		\
-					 /* | CFG_CMD_NET */		\
+					 | CFG_CMD_NET			\
 					 | CFG_CMD_ENV			\
 					 /* | CFG_CMD_IRQ */		\
 					 | CFG_CMD_BOOTD		\
@@ -96,7 +130,7 @@
 					 /* | CFG_CMD_I2C */		\
 					 | CFG_CMD_REGINFO		\
 					 /* | CFG_CMD_DATE */		\
-					 /* | CFG_CMD_DHCP */		\
+					 | CFG_CMD_DHCP			\
 					 /* | CFG_CMD_AUTOSCRIPT */	\
 					 /* | CFG_CMD_MII */		\
 					 | CFG_CMD_MISC			\
@@ -106,19 +140,22 @@
 					 /* | CFG_CMD_SAVES */		\
 					 /* | CFG_CMD_SPI */		\
 					 /* | CFG_CMD_PING */		\
-					 /* | CFG_CMD_MMC */		\
-					 /* | CFG_CMD_FAT */		\
-					 /* | CFG_CMD_IMLS */		\
+					 | CFG_CMD_MMC			\
+					 | CFG_CMD_FAT			\
+					 | CFG_CMD_IMLS			\
 					 /* | CFG_CMD_ITEST */		\
-					 /* | CFG_CMD_EXT2 */		\
+					 | CFG_CMD_EXT2			\
+					 | CFG_CMD_JFFS2		\
 		)
 
 #include <cmd_confdefs.h>
 
 #define CONFIG_ATMEL_USART		1
+#define CONFIG_MACB			1
 #define CONFIG_PIO2			1
 #define CFG_NR_PIOS			5
 #define CFG_HSDRAMC			1
+#define CONFIG_MMC			1
 
 #define CFG_DCACHE_LINESZ		32
 #define CFG_ICACHE_LINESZ		32
@@ -150,16 +187,8 @@
 #define CFG_INIT_SP_ADDR		(CFG_INTRAM_BASE + CFG_INTRAM_SIZE)
 
 #define CFG_MALLOC_LEN			(256*1024)
-#define CFG_MALLOC_END							\
-	({								\
-		DECLARE_GLOBAL_DATA_PTR;				\
-		CFG_SDRAM_BASE + gd->sdram_size;			\
-	})
-#define CFG_MALLOC_START		(CFG_MALLOC_END - CFG_MALLOC_LEN)
-
 #define CFG_DMA_ALLOC_LEN		(16384)
-#define CFG_DMA_ALLOC_END		(CFG_MALLOC_START)
-#define CFG_DMA_ALLOC_START		(CFG_DMA_ALLOC_END - CFG_DMA_ALLOC_LEN)
+
 /* Allow 2MB for the kernel run-time image */
 #define CFG_LOAD_ADDR			(CFG_SDRAM_BASE + 0x00200000)
 #define CFG_BOOTPARAMS_LEN		(16 * 1024)
diff --git a/include/linux/mii.h b/include/linux/mii.h
new file mode 100644
index 0000000000000000000000000000000000000000..7c63095fd4331e66107b5ea1b3c835c213df1ec1
--- /dev/null
+++ b/include/linux/mii.h
@@ -0,0 +1,158 @@
+/*
+ * linux/mii.h: definitions for MII-compatible transceivers
+ * Originally drivers/net/sunhme.h.
+ *
+ * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
+ */
+
+#ifndef __LINUX_MII_H__
+#define __LINUX_MII_H__
+
+/* Generic MII registers. */
+
+#define MII_BMCR	    0x00	/* Basic mode control register */
+#define MII_BMSR	    0x01	/* Basic mode status register  */
+#define MII_PHYSID1	    0x02	/* PHYS ID 1		       */
+#define MII_PHYSID2	    0x03	/* PHYS ID 2		       */
+#define MII_ADVERTISE	    0x04	/* Advertisement control reg   */
+#define MII_LPA		    0x05	/* Link partner ability reg    */
+#define MII_EXPANSION	    0x06	/* Expansion register	       */
+#define MII_DCOUNTER	    0x12	/* Disconnect counter	       */
+#define MII_FCSCOUNTER	    0x13	/* False carrier counter       */
+#define MII_NWAYTEST	    0x14	/* N-way auto-neg test reg     */
+#define MII_RERRCOUNTER     0x15	/* Receive error counter       */
+#define MII_SREVISION	    0x16	/* Silicon revision	       */
+#define MII_RESV1	    0x17	/* Reserved...		       */
+#define MII_LBRERROR	    0x18	/* Lpback, rx, bypass error    */
+#define MII_PHYADDR	    0x19	/* PHY address		       */
+#define MII_RESV2	    0x1a	/* Reserved...		       */
+#define MII_TPISTATUS	    0x1b	/* TPI status for 10mbps       */
+#define MII_NCONFIG	    0x1c	/* Network interface config    */
+
+/* Basic mode control register. */
+#define BMCR_RESV		0x003f	/* Unused...		       */
+#define BMCR_SPEED1000		0x0040	/* MSB of Speed (1000)	       */
+#define BMCR_CTST		0x0080	/* Collision test	       */
+#define BMCR_FULLDPLX		0x0100	/* Full duplex		       */
+#define BMCR_ANRESTART		0x0200	/* Auto negotiation restart    */
+#define BMCR_ISOLATE		0x0400	/* Disconnect DP83840 from MII */
+#define BMCR_PDOWN		0x0800	/* Powerdown the DP83840       */
+#define BMCR_ANENABLE		0x1000	/* Enable auto negotiation     */
+#define BMCR_SPEED100		0x2000	/* Select 100Mbps	       */
+#define BMCR_LOOPBACK		0x4000	/* TXD loopback bits	       */
+#define BMCR_RESET		0x8000	/* Reset the DP83840	       */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP		0x0001	/* Ext-reg capability	       */
+#define BMSR_JCD		0x0002	/* Jabber detected	       */
+#define BMSR_LSTATUS		0x0004	/* Link status		       */
+#define BMSR_ANEGCAPABLE	0x0008	/* Able to do auto-negotiation */
+#define BMSR_RFAULT		0x0010	/* Remote fault detected       */
+#define BMSR_ANEGCOMPLETE	0x0020	/* Auto-negotiation complete   */
+#define BMSR_RESV		0x07c0	/* Unused...		       */
+#define BMSR_10HALF		0x0800	/* Can do 10mbps, half-duplex  */
+#define BMSR_10FULL		0x1000	/* Can do 10mbps, full-duplex  */
+#define BMSR_100HALF		0x2000	/* Can do 100mbps, half-duplex */
+#define BMSR_100FULL		0x4000	/* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4		0x8000	/* Can do 100mbps, 4k packets  */
+
+/* Advertisement control register. */
+#define ADVERTISE_SLCT		0x001f	/* Selector bits	       */
+#define ADVERTISE_CSMA		0x0001	/* Only selector supported     */
+#define ADVERTISE_10HALF	0x0020	/* Try for 10mbps half-duplex  */
+#define ADVERTISE_10FULL	0x0040	/* Try for 10mbps full-duplex  */
+#define ADVERTISE_100HALF	0x0080	/* Try for 100mbps half-duplex */
+#define ADVERTISE_100FULL	0x0100	/* Try for 100mbps full-duplex */
+#define ADVERTISE_100BASE4	0x0200	/* Try for 100mbps 4k packets  */
+#define ADVERTISE_RESV		0x1c00	/* Unused...		       */
+#define ADVERTISE_RFAULT	0x2000	/* Say we can detect faults    */
+#define ADVERTISE_LPACK		0x4000	/* Ack link partners response  */
+#define ADVERTISE_NPAGE		0x8000	/* Next page bit	       */
+
+#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
+			ADVERTISE_CSMA)
+#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+		       ADVERTISE_100HALF | ADVERTISE_100FULL)
+
+/* Link partner ability register. */
+#define LPA_SLCT		0x001f	/* Same as advertise selector  */
+#define LPA_10HALF		0x0020	/* Can do 10mbps half-duplex   */
+#define LPA_10FULL		0x0040	/* Can do 10mbps full-duplex   */
+#define LPA_100HALF		0x0080	/* Can do 100mbps half-duplex  */
+#define LPA_100FULL		0x0100	/* Can do 100mbps full-duplex  */
+#define LPA_100BASE4		0x0200	/* Can do 100mbps 4k packets   */
+#define LPA_RESV		0x1c00	/* Unused...		       */
+#define LPA_RFAULT		0x2000	/* Link partner faulted        */
+#define LPA_LPACK		0x4000	/* Link partner acked us       */
+#define LPA_NPAGE		0x8000	/* Next page bit	       */
+
+#define LPA_DUPLEX		(LPA_10FULL | LPA_100FULL)
+#define LPA_100			(LPA_100FULL | LPA_100HALF | LPA_100BASE4)
+
+/* Expansion register for auto-negotiation. */
+#define EXPANSION_NWAY		0x0001	/* Can do N-way auto-nego      */
+#define EXPANSION_LCWP		0x0002	/* Got new RX page code word   */
+#define EXPANSION_ENABLENPAGE	0x0004	/* This enables npage words    */
+#define EXPANSION_NPCAPABLE	0x0008	/* Link partner supports npage */
+#define EXPANSION_MFAULTS	0x0010	/* Multiple faults detected    */
+#define EXPANSION_RESV		0xffe0	/* Unused...		       */
+
+/* N-way test register. */
+#define NWAYTEST_RESV1		0x00ff	/* Unused...		       */
+#define NWAYTEST_LOOPBACK	0x0100	/* Enable loopback for N-way   */
+#define NWAYTEST_RESV2		0xfe00	/* Unused...		       */
+
+
+/**
+ * mii_nway_result
+ * @negotiated: value of MII ANAR and'd with ANLPAR
+ *
+ * Given a set of MII abilities, check each bit and returns the
+ * currently supported media, in the priority order defined by
+ * IEEE 802.3u.  We use LPA_xxx constants but note this is not the
+ * value of LPA solely, as described above.
+ *
+ * The one exception to IEEE 802.3u is that 100baseT4 is placed
+ * between 100T-full and 100T-half.  If your phy does not support
+ * 100T4 this is fine.	If your phy places 100T4 elsewhere in the
+ * priority order, you will need to roll your own function.
+ */
+static inline unsigned int mii_nway_result (unsigned int negotiated)
+{
+	unsigned int ret;
+
+	if (negotiated & LPA_100FULL)
+		ret = LPA_100FULL;
+	else if (negotiated & LPA_100BASE4)
+		ret = LPA_100BASE4;
+	else if (negotiated & LPA_100HALF)
+		ret = LPA_100HALF;
+	else if (negotiated & LPA_10FULL)
+		ret = LPA_10FULL;
+	else
+		ret = LPA_10HALF;
+
+	return ret;
+}
+
+/**
+ * mii_duplex
+ * @duplex_lock: Non-zero if duplex is locked at full
+ * @negotiated: value of MII ANAR and'd with ANLPAR
+ *
+ * A small helper function for a common case.  Returns one
+ * if the media is operating or locked at full duplex, and
+ * returns zero otherwise.
+ */
+static inline unsigned int mii_duplex (unsigned int duplex_lock,
+				       unsigned int negotiated)
+{
+	if (duplex_lock)
+		return 1;
+	if (mii_nway_result(negotiated) & LPA_DUPLEX)
+		return 1;
+	return 0;
+}
+
+
+#endif /* __LINUX_MII_H__ */
diff --git a/include/linux/stat.h b/include/linux/stat.h
index 4d05aa92d98f3d293d0c4275cc42f534480b673a..43fd53fc98cf8b5644c49b3c7cc5235278aa0365 100644
--- a/include/linux/stat.h
+++ b/include/linux/stat.h
@@ -7,7 +7,7 @@
 extern "C" {
 #endif
 
-#define S_IFMT  00170000	/* type of file */
+#define S_IFMT	00170000	/* type of file */
 #define S_IFSOCK 0140000	/* named socket */
 #define S_IFLNK	 0120000	/* symbolic link */
 #define S_IFREG  0100000	/* regular */
@@ -49,20 +49,20 @@ struct stat {
 	ino_t		st_ino;		/* file id */
 	mode_t		st_mode;	/* ownership/protection */
 	nlink_t		st_nlink;	/* number of links */
-	uid_t 		st_uid;		/* user id */
-	gid_t 		st_gid;		/* group id */
+	uid_t		st_uid;		/* user id */
+	gid_t		st_gid;		/* group id */
 	dev_t		st_rdev;
 	off_t		st_size;	/* file size in # of bytes */
-	unsigned long  	st_blksize;	/* block size */
-	unsigned long  	st_blocks;	/* file size in # of blocks */
-	unsigned long  	st_atime;	/* time file was last accessed */
-	unsigned long  	__unused1;
-	unsigned long  	st_mtime;	/* time file was last modified */
-	unsigned long  	__unused2;
-	unsigned long  	st_ctime;	/* time file status was last changed */
-	unsigned long  	__unused3;
-	unsigned long  	__unused4;
-	unsigned long  	__unused5;
+	unsigned long	st_blksize;	/* block size */
+	unsigned long	st_blocks;	/* file size in # of blocks */
+	unsigned long	st_atime;	/* time file was last accessed */
+	unsigned long	__unused1;
+	unsigned long	st_mtime;	/* time file was last modified */
+	unsigned long	__unused2;
+	unsigned long	st_ctime;	/* time file status was last changed */
+	unsigned long	__unused3;
+	unsigned long	__unused4;
+	unsigned long	__unused5;
 };
 
 #endif	/* __PPC__ */
@@ -97,34 +97,59 @@ struct stat {
 #if defined (__MIPS__)
 
 struct stat {
-	dev_t           st_dev;
-	long            st_pad1[3];
-	ino_t           st_ino;
-	mode_t          st_mode;
-	nlink_t         st_nlink;
-	uid_t           st_uid;
-	gid_t           st_gid;
-	dev_t           st_rdev;
-	long            st_pad2[2];
-	off_t           st_size;
-	long            st_pad3;
+	dev_t		st_dev;
+	long		st_pad1[3];
+	ino_t		st_ino;
+	mode_t		st_mode;
+	nlink_t		st_nlink;
+	uid_t		st_uid;
+	gid_t		st_gid;
+	dev_t		st_rdev;
+	long		st_pad2[2];
+	off_t		st_size;
+	long		st_pad3;
 	/*
 	 * Actually this should be timestruc_t st_atime, st_mtime and st_ctime
 	 * but we don't have it under Linux.
 	 */
-	time_t          st_atime;
-	long            reserved0;
-	time_t          st_mtime;
-	long            reserved1;
-	time_t          st_ctime;
-	long            reserved2;
-	long            st_blksize;
-	long            st_blocks;
-	long            st_pad4[14];
+	time_t		st_atime;
+	long		reserved0;
+	time_t		st_mtime;
+	long		reserved1;
+	time_t		st_ctime;
+	long		reserved2;
+	long		st_blksize;
+	long		st_blocks;
+	long		st_pad4[14];
 };
 
 #endif	/* __MIPS__ */
 
+#if defined(__AVR32__)
+
+struct stat {
+	unsigned long st_dev;
+	unsigned long st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned long  st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  st_atime_nsec;
+	unsigned long  st_mtime;
+	unsigned long  st_mtime_nsec;
+	unsigned long  st_ctime;
+	unsigned long  st_ctime_nsec;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif /* __AVR32__ */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib_avr32/avr32_linux.c b/lib_avr32/avr32_linux.c
index d128dfb53f075b01b8f73616b59a4af6f4553896..6095e2ff214aac67e4741e5a36ee531e2190d157 100644
--- a/lib_avr32/avr32_linux.c
+++ b/lib_avr32/avr32_linux.c
@@ -27,7 +27,7 @@
 #include <asm/addrspace.h>
 #include <asm/io.h>
 #include <asm/setup.h>
-#include <asm/arch/platform.h>
+#include <asm/arch/clk.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -133,7 +133,7 @@ static struct tag *setup_clock_tags(struct tag *params)
 	params->hdr.size = tag_size(tag_clock);
 	params->u.clock.clock_id = ACLOCK_HSB;
 	params->u.clock.clock_flags = 0;
-	params->u.clock.clock_hz = pm_get_clock_freq(CLOCK_HSB);
+	params->u.clock.clock_hz = get_hsb_clk_rate();
 #endif
 
 	return tag_next(params);
diff --git a/lib_avr32/board.c b/lib_avr32/board.c
index 02c106b80ede83c7a64b31a095bbe63ec49289f9..265328aa487696a11862aa12ae6e491fd60e64cb 100644
--- a/lib_avr32/board.c
+++ b/lib_avr32/board.c
@@ -47,11 +47,14 @@ static unsigned long mem_malloc_start = 0;
 static unsigned long mem_malloc_end = 0;
 static unsigned long mem_malloc_brk = 0;
 
-/* The malloc area is wherever the board wants it to be */
+/* The malloc area is right below the monitor image in RAM */
 static void mem_malloc_init(void)
 {
-	mem_malloc_start = CFG_MALLOC_START;
-	mem_malloc_end = CFG_MALLOC_END;
+	unsigned long monitor_addr;
+
+	monitor_addr = CFG_MONITOR_BASE + gd->reloc_off;
+	mem_malloc_end = monitor_addr;
+	mem_malloc_start = mem_malloc_end - CFG_MALLOC_LEN;
 	mem_malloc_brk = mem_malloc_start;
 
 	printf("malloc: Using memory from 0x%08lx to 0x%08lx\n",
@@ -73,6 +76,50 @@ void *sbrk(ptrdiff_t increment)
 	return ((void *)old);
 }
 
+#ifdef CFG_DMA_ALLOC_LEN
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+
+static unsigned long dma_alloc_start;
+static unsigned long dma_alloc_end;
+static unsigned long dma_alloc_brk;
+
+static void dma_alloc_init(void)
+{
+	unsigned long monitor_addr;
+
+	monitor_addr = CFG_MONITOR_BASE + gd->reloc_off;
+	dma_alloc_end = monitor_addr - CFG_MALLOC_LEN;
+	dma_alloc_start = dma_alloc_end - CFG_DMA_ALLOC_LEN;
+	dma_alloc_brk = dma_alloc_start;
+
+	printf("DMA: Using memory from 0x%08lx to 0x%08lx\n",
+	       dma_alloc_start, dma_alloc_end);
+
+	dcache_invalidate_range(cached(dma_alloc_start),
+				dma_alloc_end - dma_alloc_start);
+}
+
+void *dma_alloc_coherent(size_t len, unsigned long *handle)
+{
+	unsigned long paddr = dma_alloc_brk;
+
+	if (dma_alloc_brk + len > dma_alloc_end)
+		return NULL;
+
+	dma_alloc_brk = ((paddr + len + CFG_DCACHE_LINESZ - 1)
+			 & ~(CFG_DCACHE_LINESZ - 1));
+
+	*handle = paddr;
+	return uncached(paddr);
+}
+#else
+static inline void dma_alloc_init(void)
+{
+
+}
+#endif
+
 static int init_baudrate(void)
 {
 	char tmp[64];
@@ -122,40 +169,152 @@ static void display_flash_config (void)
 	printf("at address 0x%08lx\n", gd->bd->bi_flashstart);
 }
 
-void start_u_boot (void)
+void board_init_f(ulong board_type)
 {
 	gd_t gd_data;
+	gd_t *new_gd;
+	bd_t *bd;
+	unsigned long *new_sp;
+	unsigned long monitor_len;
+	unsigned long monitor_addr;
+	unsigned long addr;
+	long sdram_size;
 
 	/* Initialize the global data pointer */
 	memset(&gd_data, 0, sizeof(gd_data));
 	gd = &gd_data;
 
-	monitor_flash_len = _edata - _text;
-
 	/* Perform initialization sequence */
+	board_early_init_f();
 	cpu_init();
-	timer_init();
 	env_init();
 	init_baudrate();
 	serial_init();
 	console_init_f();
 	display_banner();
+	sdram_size = initdram(board_type);
+
+	/* If we have no SDRAM, we can't go on */
+	if (sdram_size <= 0)
+		panic("No working SDRAM available\n");
+
+	/*
+	 * Now that we have DRAM mapped and working, we can
+	 * relocate the code and continue running from DRAM.
+	 *
+	 * Reserve memory at end of RAM for (top down in that order):
+	 *  - u-boot image
+	 *  - heap for malloc()
+	 *  - board info struct
+	 *  - global data struct
+	 *  - stack
+	 */
+	addr = CFG_SDRAM_BASE + sdram_size;
+	monitor_len = _end - _text;
+
+	/*
+	 * Reserve memory for u-boot code, data and bss.
+	 * Round down to next 4 kB limit.
+	 */
+	addr -= monitor_len;
+	addr &= ~(4096UL - 1);
+	monitor_addr = addr;
+
+	/* Reserve memory for malloc() */
+	addr -= CFG_MALLOC_LEN;
+
+#ifdef CFG_DMA_ALLOC_LEN
+	/* Reserve DMA memory (must be cache aligned) */
+	addr &= ~(CFG_DCACHE_LINESZ - 1);
+	addr -= CFG_DMA_ALLOC_LEN;
+#endif
 
-	board_init_memories();
-	mem_malloc_init();
+	/* Allocate a Board Info struct on a word boundary */
+	addr -= sizeof(bd_t);
+	addr &= ~3UL;
+	gd->bd = bd = (bd_t *)addr;
+
+	/* Allocate a new global data copy on a 8-byte boundary. */
+	addr -= sizeof(gd_t);
+	addr &= ~7UL;
+	new_gd = (gd_t *)addr;
+
+	/* And finally, a new, bigger stack. */
+	new_sp = (unsigned long *)addr;
+	gd->stack_end = addr;
+	*(--new_sp) = 0;
+	*(--new_sp) = 0;
+
+	/*
+	 * Initialize the board information struct with the
+	 * information we have.
+	 */
+	bd->bi_dram[0].start = CFG_SDRAM_BASE;
+	bd->bi_dram[0].size = sdram_size;
+	bd->bi_baudrate = gd->baudrate;
+
+	memcpy(new_gd, gd, sizeof(gd_t));
+
+	relocate_code((unsigned long)new_sp, new_gd, monitor_addr);
+}
 
-	gd->bd = malloc(sizeof(bd_t));
-	memset(gd->bd, 0, sizeof(bd_t));
-	gd->bd->bi_baudrate = gd->baudrate;
-	gd->bd->bi_dram[0].start = CFG_SDRAM_BASE;
-	gd->bd->bi_dram[0].size = gd->sdram_size;
+void board_init_r(gd_t *new_gd, ulong dest_addr)
+{
+	extern void malloc_bin_reloc (void);
+#ifndef CFG_ENV_IS_NOWHERE
+	extern char * env_name_spec;
+#endif
+	cmd_tbl_t *cmdtp;
+	bd_t *bd;
+
+	gd = new_gd;
+	bd = gd->bd;
+
+	gd->flags |= GD_FLG_RELOC;
+	gd->reloc_off = dest_addr - CFG_MONITOR_BASE;
+
+	monitor_flash_len = _edata - _text;
 
+	/*
+	 * We have to relocate the command table manually
+	 */
+	for (cmdtp = &__u_boot_cmd_start;
+	     cmdtp !=  &__u_boot_cmd_end; cmdtp++) {
+		unsigned long addr;
+
+		addr = (unsigned long)cmdtp->cmd + gd->reloc_off;
+		cmdtp->cmd = (typeof(cmdtp->cmd))addr;
+
+		addr = (unsigned long)cmdtp->name + gd->reloc_off;
+		cmdtp->name = (typeof(cmdtp->name))addr;
+
+		if (cmdtp->usage) {
+			addr = (unsigned long)cmdtp->usage + gd->reloc_off;
+			cmdtp->usage = (typeof(cmdtp->usage))addr;
+		}
+#ifdef CFG_LONGHELP
+		if (cmdtp->help) {
+			addr = (unsigned long)cmdtp->help + gd->reloc_off;
+			cmdtp->help = (typeof(cmdtp->help))addr;
+		}
+#endif
+	}
+
+	/* there are some other pointer constants we must deal with */
+#ifndef CFG_ENV_IS_NOWHERE
+	env_name_spec += gd->reloc_off;
+#endif
+
+	timer_init();
+	mem_malloc_init();
+	malloc_bin_reloc();
+	dma_alloc_init();
 	board_init_info();
 	flash_init();
 
-	if (gd->bd->bi_flashsize)
+	if (bd->bi_flashsize)
 		display_flash_config();
-	if (gd->bd->bi_dram[0].size)
+	if (bd->bi_dram[0].size)
 		display_dram_config();
 
 	gd->bd->bi_boot_params = malloc(CFG_BOOTPARAMS_LEN);
@@ -169,6 +328,13 @@ void start_u_boot (void)
 	jumptable_init();
 	console_init_r();
 
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+#if defined(CONFIG_NET_MULTI)
+	puts("Net:   ");
+#endif
+	eth_initialize(gd->bd);
+#endif
+
 	for (;;) {
 		main_loop();
 	}
diff --git a/net/eth.c b/net/eth.c
index 64923d99bf13ea6cdb8d08ec5f18c84be9f6b293..b3e281fdcac47aebe36a5ef461a580e37e4c1855 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -56,6 +56,7 @@ extern int tsec_initialize(bd_t*, int, char *);
 extern int npe_initialize(bd_t *);
 extern int uec_initialize(int);
 extern int bfin_EMAC_initialize(bd_t *);
+extern int atstk1000_eth_initialize(bd_t *);
 
 static struct eth_device *eth_devices, *eth_current;
 
@@ -259,6 +260,9 @@ int eth_initialize(bd_t *bis)
 #if defined(CONFIG_BF537)
 	bfin_EMAC_initialize(bis);
 #endif
+#if defined(CONFIG_ATSTK1000)
+	atstk1000_eth_initialize(bis);
+#endif
 
 	if (!eth_devices) {
 		puts ("No ethernet found.\n");