diff -urN linux-2.6.28.2-0rig//arch/arm/mach-at91/include/mach/cpu.h linux-2.6.28.2/arch/arm/mach-at91/include/mach/cpu.h
--- linux-2.6.28.2-0rig//arch/arm/mach-at91/include/mach/cpu.h	2009-01-29 08:39:33.000000000 +0100
+++ linux-2.6.28.2/arch/arm/mach-at91/include/mach/cpu.h	2009-01-29 08:52:44.000000000 +0100
@@ -99,5 +99,6 @@
  * definitions may reduce clutter in common drivers.
  */
 #define cpu_is_at32ap7000()	(0)
+#define cpu_is_at32ap7200()	(0)
 
 #endif
diff -urN linux-2.6.28.2-0rig//arch/avr32/boards/atstk1000/atstk1005.c linux-2.6.28.2/arch/avr32/boards/atstk1000/atstk1005.c
--- linux-2.6.28.2-0rig//arch/avr32/boards/atstk1000/atstk1005.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/boards/atstk1000/atstk1005.c	2009-01-29 08:52:48.000000000 +0100
@@ -0,0 +1,225 @@
+/*
+ * ATSTK1005 daughterboard-specific init code
+ *
+ * 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/string.h>
+#include <linux/mtd/partitions.h>
+#include <linux/spi/spi.h>
+
+#include <asm/atmel-mci.h>
+#include <asm/setup.h>
+
+#include <mach/at32ap720x.h>
+#include <mach/board.h>
+#include <mach/init.h>
+#include <mach/portmux.h>
+#include <mach/smc.h>
+
+#include "atstk1000.h"
+
+/* Oscillator frequencies. These are board specific */
+unsigned long at32_board_osc_rates[4] = {
+	[0] = 20000000,	/* 20 MHz on osc0 */
+	[1] = 0,	/* Nothing on osc1 */
+	[2] = 12000000,	/* 12 MHz on osc2 */
+	[3] = 32768,	/* 32.768 kHz on RTC osc */
+};
+
+struct eth_addr {
+	u8 addr[6];
+};
+
+static struct eth_addr __initdata hw_addr;
+static struct eth_platform_data __initdata eth_data;
+
+static struct mci_platform_data mci_data __initdata = {
+	.slot[0]	= {
+		.detect_pin		= GPIO_PIN_NONE,
+		.wp_pin			= GPIO_PIN_NONE,
+		.bus_width		= 4,
+	},
+	.slot[1]	= {
+		.detect_pin		= GPIO_PIN_PA(30),
+		.wp_pin			= GPIO_PIN_PA(31),
+		.bus_width		= 8,
+	},
+};
+
+static struct spi_board_info spi0_board_info[] __initdata = {
+	{
+		/* AT45DB642D: 8MB DataFlash */
+		.modalias	= "mtd_dataflash",
+		.max_speed_hz	= 8000000,
+		.chip_select	= 0,
+		.mode		= SPI_MODE_0,
+	}, {
+		/* QVGA display */
+		.modalias	= "ltv350qv",
+		.max_speed_hz	= 8000000,
+		.chip_select	= 2,
+		.mode		= SPI_MODE_3,
+	},
+};
+
+static struct smc_timing nand_timing __initdata = {
+	.ncs_read_setup		= 0,
+	.nrd_setup		= 10,
+	.ncs_write_setup	= 0,
+	.nwe_setup		= 10,
+
+	.ncs_read_pulse		= 30,
+	.nrd_pulse		= 15,
+	.ncs_write_pulse	= 30,
+	.nwe_pulse		= 15,
+
+	.read_cycle		= 30,
+	.write_cycle		= 30,
+
+	.ncs_read_recover	= 0,
+	.nrd_recover		= 15,
+	.ncs_write_recover	= 0,
+	.nwe_recover		= 50,
+};
+
+static struct smc_config nand_config __initdata = {
+	.bus_width		= 1,
+	.nrd_controlled		= 1,
+	.nwe_controlled		= 1,
+	.nwait_mode		= 0,
+	.byte_write		= 0,
+	.tdf_cycles		= 3,
+	.tdf_mode		= 0,
+};
+
+static struct mtd_partition nand_partitions[] = {
+	{
+		.name	= "u-boot",
+		.offset	= 0,
+		.size	= 131072,
+	}, {
+		.name	= "kernel",
+		.offset	= 262144,
+		.size	= 2097152,
+	}, {
+		.name	= "user",
+		.offset	= 2359296,
+		.size	= MTDPART_SIZ_FULL,
+	},
+};
+
+/* Isn't this rather more complicated than necessary? */
+static struct mtd_partition *nand_part_info(int size, int *num_partitions)
+{
+	*num_partitions = ARRAY_SIZE(nand_partitions);
+	return nand_partitions;
+}
+
+static struct atmel_nand_data nand_data __initdata = {
+	.cle		= 21,
+	.ale		= 22,
+	.rdy_pin	= GPIO_PIN_PE(31),
+	.enable_pin	= GPIO_PIN_PF(2),
+	.det_pin	= GPIO_PIN_NONE,
+	.partition_info	= nand_part_info,
+};
+
+
+/*
+ * Grab ethernet address and PHY address provided by the boot loader.
+ */
+static int __init parse_tag_ethernet(struct tag *tag)
+{
+	struct tag_ethernet *etag = &tag->u.ethernet;
+
+	if (etag->mac_index == 0) {
+		eth_data.phy_mask = ~(1U << etag->mii_phy_addr);
+		memcpy(&hw_addr.addr, etag->hw_address, sizeof(hw_addr.addr));
+	}
+
+	return 0;
+}
+__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
+
+/*
+ * We need to get rid of this crap and pass the mac address to the
+ * driver explicitly.
+ */
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+static void __init set_hw_addr(struct platform_device *pdev)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	const u8 *addr;
+	void __iomem *regs;
+	struct clk *pclk;
+
+	if (!res)
+		return;
+	if (pdev->id != 0)
+		return;
+
+	addr = hw_addr.addr;
+	if (!is_valid_ether_addr(addr))
+		return;
+
+	/*
+	 * Since this is board-specific code, we'll cheat and use the
+	 * physical address directly as we happen to know that it's
+	 * the same as the virtual address.
+	 */
+	regs = (void __iomem __force *)res->start;
+	pclk = clk_get(&pdev->dev, "pclk");
+	if (!pclk)
+		return;
+
+	clk_enable(pclk);
+	__raw_writel((addr[3] << 24) | (addr[2] << 16)
+		     | (addr[1] << 8) | addr[0], regs + 0x98);
+	__raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
+	clk_disable(pclk);
+	clk_put(pclk);
+}
+
+void __init setup_board(void)
+{
+	at32_map_usart(4, 0);	/* USART4: /dev/ttyS0, DB9 */
+	at32_setup_serial_console(0);
+}
+
+static int __init atstk1005_init(void)
+{
+	struct platform_device	*lcdc_pdev;
+
+	at32_add_device_usart(0);
+
+	set_hw_addr(at32_add_device_eth(0, &eth_data));
+	lcdc_pdev = at32_add_device_lcdc(0, &atstk1000_lcdc_data,
+			fbmem_start, fbmem_size, 0);
+	at32_add_device_mpop(0, lcdc_pdev, fbmem_start, fbmem_size);
+	at32_add_device_mci(0, &mci_data);
+	at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info));
+
+	/* NAND Flash */
+	smc_set_timing(&nand_config, &nand_timing);
+	smc_set_configuration(3, &nand_config);
+	at32_add_device_nand(0, &nand_data);
+
+	/* USB OHCI/EHCI host */
+	at32_add_device_ohci(0);
+	at32_add_device_ehci(0);
+
+	return 0;
+}
+postcore_initcall(atstk1005_init);
diff -urN linux-2.6.28.2-0rig//arch/avr32/boards/atstk1000/Kconfig linux-2.6.28.2/arch/avr32/boards/atstk1000/Kconfig
--- linux-2.6.28.2-0rig//arch/avr32/boards/atstk1000/Kconfig	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/boards/atstk1000/Kconfig	2009-01-29 08:52:48.000000000 +0100
@@ -18,6 +18,10 @@
 	bool "ATSTK1004"
 	select CPU_AT32AP7002
 
+config BOARD_ATSTK1005
+	bool "ATSTK1005"
+	select CPU_AT32AP7200
+
 config BOARD_ATSTK1006
 	bool "ATSTK1006"
 	select CPU_AT32AP7000
diff -urN linux-2.6.28.2-0rig//arch/avr32/boards/atstk1000/Makefile linux-2.6.28.2/arch/avr32/boards/atstk1000/Makefile
--- linux-2.6.28.2-0rig//arch/avr32/boards/atstk1000/Makefile	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/boards/atstk1000/Makefile	2009-01-29 08:52:48.000000000 +0100
@@ -2,4 +2,5 @@
 obj-$(CONFIG_BOARD_ATSTK1002)	+= atstk1002.o
 obj-$(CONFIG_BOARD_ATSTK1003)	+= atstk1003.o
 obj-$(CONFIG_BOARD_ATSTK1004)	+= atstk1004.o
+obj-$(CONFIG_BOARD_ATSTK1005)	+= atstk1005.o
 obj-$(CONFIG_BOARD_ATSTK1006)	+= atstk1002.o
diff -urN linux-2.6.28.2-0rig//arch/avr32/configs/atngw100_defconfig linux-2.6.28.2/arch/avr32/configs/atngw100_defconfig
--- linux-2.6.28.2-0rig//arch/avr32/configs/atngw100_defconfig	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/configs/atngw100_defconfig	2009-01-29 08:52:48.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc1
-# Tue Aug  5 16:00:47 2008
+# Linux kernel version: 2.6.27.4
+# Thu Nov 13 14:33:33 2008
 #
 CONFIG_AVR32=y
 CONFIG_GENERIC_GPIO=y
@@ -130,11 +130,15 @@
 CONFIG_SUBARCH_AVR32B=y
 CONFIG_MMU=y
 CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PORTMUX_PIO=y
 CONFIG_PLATFORM_AT32AP=y
 CONFIG_CPU_AT32AP700X=y
 CONFIG_CPU_AT32AP7000=y
 # CONFIG_BOARD_ATSTK1000 is not set
 CONFIG_BOARD_ATNGW100=y
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MIMC200 is not set
+# CONFIG_BOARD_ATNGW100_EVKLCD10X is not set
 CONFIG_LOADER_U_BOOT=y
 
 #
@@ -177,7 +181,7 @@
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 CONFIG_CMDLINE=""
 
 #
@@ -615,6 +619,7 @@
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_ALGOBIT=m
 
 #
@@ -664,6 +669,7 @@
 #
 # SPI Master Controller Drivers
 #
+CONFIG_SPI_ATMEL_HAVE_PDC=y
 CONFIG_SPI_ATMEL=y
 # CONFIG_SPI_BITBANG is not set
 
@@ -706,7 +712,7 @@
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT32AP700X_WDT=y
+CONFIG_AT32_WDT=y
 
 #
 # Sonics Silicon Backplane
@@ -720,6 +726,7 @@
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -751,11 +758,14 @@
 # CONFIG_DISPLAY_SUPPORT is not set
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -806,6 +816,7 @@
 #
 # CONFIG_MMC_SDHCI is not set
 CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_ATMELMCI_DMA is not set
 CONFIG_MMC_SPI=m
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -880,11 +891,13 @@
 # on-CPU RTC drivers
 #
 CONFIG_RTC_DRV_AT32AP700X=y
+# CONFIG_RTC_DRV_AVR32_AST is not set
 CONFIG_DMADEVICES=y
 
 #
 # DMA Devices
 #
+# CONFIG_ATMEL_PDCA is not set
 CONFIG_DW_DMAC=y
 CONFIG_DMA_ENGINE=y
 
@@ -898,13 +911,13 @@
 #
 # File systems
 #
-CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
 # CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=m
+CONFIG_JBD=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
@@ -944,7 +957,7 @@
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_CONFIGFS_FS=m
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
diff -urN linux-2.6.28.2-0rig//arch/avr32/configs/atstk1002_defconfig linux-2.6.28.2/arch/avr32/configs/atstk1002_defconfig
--- linux-2.6.28.2-0rig//arch/avr32/configs/atstk1002_defconfig	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/configs/atstk1002_defconfig	2009-01-29 08:52:49.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc1
-# Mon Aug  4 16:02:27 2008
+# Linux kernel version: 2.6.27.4
+# Wed Nov 12 10:28:45 2008
 #
 CONFIG_AVR32=y
 CONFIG_GENERIC_GPIO=y
@@ -129,20 +129,24 @@
 CONFIG_SUBARCH_AVR32B=y
 CONFIG_MMU=y
 CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PORTMUX_PIO=y
 CONFIG_PLATFORM_AT32AP=y
 CONFIG_CPU_AT32AP700X=y
 CONFIG_CPU_AT32AP7000=y
 CONFIG_BOARD_ATSTK1000=y
 # CONFIG_BOARD_ATNGW100 is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MIMC200 is not set
 CONFIG_BOARD_ATSTK1002=y
 # CONFIG_BOARD_ATSTK1003 is not set
 # CONFIG_BOARD_ATSTK1004 is not set
+# CONFIG_BOARD_ATSTK1005 is not set
 # CONFIG_BOARD_ATSTK1006 is not set
 # CONFIG_BOARD_ATSTK100X_CUSTOM is not set
 # CONFIG_BOARD_ATSTK100X_SPI1 is not set
-# CONFIG_BOARD_ATSTK1000_J2_LED is not set
+CONFIG_BOARD_ATSTK1000_J2_LED=y
 # CONFIG_BOARD_ATSTK1000_J2_LED8 is not set
-# CONFIG_BOARD_ATSTK1000_J2_RGB is not set
+CONFIG_BOARD_ATSTK1000_J2_RGB=y
 CONFIG_BOARD_ATSTK1000_EXTDAC=y
 CONFIG_LOADER_U_BOOT=y
 
@@ -186,7 +190,7 @@
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 CONFIG_CMDLINE=""
 
 #
@@ -360,7 +364,8 @@
 #
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
@@ -421,12 +426,23 @@
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
 # CONFIG_MTD_NAND is not set
+# CONFIG_MTD_NAND_ATMEL_ECC_HW is not set
+# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set
+# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
 # UBI - Unsorted block images
 #
-# CONFIG_MTD_UBI is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
@@ -502,7 +518,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
+# CONFIG_TUN is not set
 # CONFIG_VETH is not set
 CONFIG_PHYLIB=y
 
@@ -561,7 +577,7 @@
 #
 # Input device support
 #
-CONFIG_INPUT=m
+CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 CONFIG_INPUT_POLLDEV=m
 
@@ -590,6 +606,8 @@
 CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 CONFIG_MOUSE_GPIO=m
 # CONFIG_INPUT_JOYSTICK is not set
@@ -606,8 +624,12 @@
 #
 # Character devices
 #
-# CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -634,6 +656,7 @@
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_ALGOBIT=m
 
 #
@@ -663,7 +686,7 @@
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-CONFIG_AT24=m
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
@@ -683,6 +706,7 @@
 #
 # SPI Master Controller Drivers
 #
+CONFIG_SPI_ATMEL_HAVE_PDC=y
 CONFIG_SPI_ATMEL=y
 # CONFIG_SPI_BITBANG is not set
 
@@ -725,7 +749,7 @@
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT32AP700X_WDT=y
+CONFIG_AT32_WDT=y
 
 #
 # Sonics Silicon Backplane
@@ -739,6 +763,7 @@
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -784,6 +809,7 @@
 #
 # CONFIG_FB_S1D13XXX is not set
 CONFIG_FB_ATMEL=y
+# CONFIG_FB_ATMEL_MPOP is not set
 # CONFIG_FB_VIRTUAL is not set
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
@@ -797,6 +823,12 @@
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
 # CONFIG_LOGO is not set
 CONFIG_SOUND=m
 CONFIG_SND=m
@@ -820,11 +852,14 @@
 # CONFIG_SOUND_PRIME is not set
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB_SUPPORT=y
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -876,6 +911,7 @@
 #
 # CONFIG_MMC_SDHCI is not set
 CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_ATMELMCI_DMA is not set
 CONFIG_MMC_SPI=m
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
@@ -952,11 +988,13 @@
 # on-CPU RTC drivers
 #
 CONFIG_RTC_DRV_AT32AP700X=y
+# CONFIG_RTC_DRV_AVR32_AST is not set
 CONFIG_DMADEVICES=y
 
 #
 # DMA Devices
 #
+# CONFIG_ATMEL_PDCA is not set
 CONFIG_DW_DMAC=y
 CONFIG_DMA_ENGINE=y
 
@@ -1017,7 +1055,7 @@
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
@@ -1031,7 +1069,8 @@
 # CONFIG_EFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_WRITEBUFFER is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
 # CONFIG_JFFS2_SUMMARY is not set
 # CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
@@ -1039,6 +1078,12 @@
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_XATTR=y
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=m
@@ -1173,7 +1218,7 @@
 #
 # Crypto core or helper
 #
-CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI=y
 CONFIG_CRYPTO_AEAD=m
 CONFIG_CRYPTO_BLKCIPHER=m
 CONFIG_CRYPTO_HASH=m
@@ -1247,8 +1292,8 @@
 #
 # Compression
 #
-CONFIG_CRYPTO_DEFLATE=m
-# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
 # CONFIG_CRYPTO_HW is not set
 
 #
@@ -1258,7 +1303,7 @@
 # CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
 CONFIG_CRC_T10DIF=m
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
@@ -1266,6 +1311,8 @@
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_GENERIC_ALLOCATOR=y
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
diff -urN linux-2.6.28.2-0rig//arch/avr32/configs/atstk1003_defconfig linux-2.6.28.2/arch/avr32/configs/atstk1003_defconfig
--- linux-2.6.28.2-0rig//arch/avr32/configs/atstk1003_defconfig	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/configs/atstk1003_defconfig	2009-01-29 08:52:49.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc1
-# Tue Aug  5 15:34:44 2008
+# Linux kernel version: 2.6.27.4
+# Wed Nov 12 10:33:33 2008
 #
 CONFIG_AVR32=y
 CONFIG_GENERIC_GPIO=y
@@ -34,12 +34,9 @@
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_TASKSTATS=y
-CONFIG_TASK_DELAY_ACCT=y
-# CONFIG_TASK_XACCT is not set
-CONFIG_AUDIT=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
@@ -71,7 +68,7 @@
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_VM_EVENT_COUNTERS=y
-# CONFIG_SLUB_DEBUG is not set
+CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
@@ -90,6 +87,7 @@
 CONFIG_HAVE_CLK=y
 CONFIG_PROC_PAGE_MONITOR=y
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=1
@@ -131,20 +129,24 @@
 CONFIG_SUBARCH_AVR32B=y
 CONFIG_MMU=y
 CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PORTMUX_PIO=y
 CONFIG_PLATFORM_AT32AP=y
 CONFIG_CPU_AT32AP700X=y
 CONFIG_CPU_AT32AP7001=y
 CONFIG_BOARD_ATSTK1000=y
 # CONFIG_BOARD_ATNGW100 is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MIMC200 is not set
 # CONFIG_BOARD_ATSTK1002 is not set
 CONFIG_BOARD_ATSTK1003=y
 # CONFIG_BOARD_ATSTK1004 is not set
+# CONFIG_BOARD_ATSTK1005 is not set
 # CONFIG_BOARD_ATSTK1006 is not set
 # CONFIG_BOARD_ATSTK100X_CUSTOM is not set
 # CONFIG_BOARD_ATSTK100X_SPI1 is not set
-# CONFIG_BOARD_ATSTK1000_J2_LED is not set
+CONFIG_BOARD_ATSTK1000_J2_LED=y
 # CONFIG_BOARD_ATSTK1000_J2_LED8 is not set
-# CONFIG_BOARD_ATSTK1000_J2_RGB is not set
+CONFIG_BOARD_ATSTK1000_J2_RGB=y
 CONFIG_BOARD_ATSTK1000_EXTDAC=y
 CONFIG_LOADER_U_BOOT=y
 
@@ -188,7 +190,7 @@
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 CONFIG_CMDLINE=""
 
 #
@@ -239,40 +241,71 @@
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
 # CONFIG_ARPD is not set
 # CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 # CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
-# CONFIG_IPV6 is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
+CONFIG_STP=m
+CONFIG_BRIDGE=m
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
+CONFIG_LLC=m
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
@@ -331,7 +364,8 @@
 #
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
@@ -397,7 +431,15 @@
 #
 # UBI - Unsorted block images
 #
-# CONFIG_MTD_UBI is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_COW_COMMON is not set
@@ -458,9 +500,7 @@
 # CONFIG_SCSI_ISCSI_ATTRS is not set
 # CONFIG_SCSI_SAS_LIBSAS is not set
 # CONFIG_SCSI_SRP_ATTRS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_LOWLEVEL is not set
 # CONFIG_SCSI_DH is not set
 CONFIG_ATA=m
 # CONFIG_ATA_NONSTANDARD is not set
@@ -477,7 +517,32 @@
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_NET_ETHERNET is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 
@@ -509,7 +574,7 @@
 #
 # Input device support
 #
-CONFIG_INPUT=m
+CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 CONFIG_INPUT_POLLDEV=m
 
@@ -521,7 +586,7 @@
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+CONFIG_INPUT_EVDEV=m
 # CONFIG_INPUT_EVBUG is not set
 
 #
@@ -538,6 +603,8 @@
 CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 CONFIG_MOUSE_GPIO=m
 # CONFIG_INPUT_JOYSTICK is not set
@@ -555,7 +622,7 @@
 # Character devices
 #
 # CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -582,6 +649,7 @@
 CONFIG_I2C=m
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
 CONFIG_I2C_ALGOBIT=m
 
 #
@@ -611,7 +679,7 @@
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
-CONFIG_AT24=m
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
@@ -631,6 +699,7 @@
 #
 # SPI Master Controller Drivers
 #
+CONFIG_SPI_ATMEL_HAVE_PDC=y
 CONFIG_SPI_ATMEL=y
 # CONFIG_SPI_BITBANG is not set
 
@@ -673,7 +742,7 @@
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT32AP700X_WDT=y
+CONFIG_AT32_WDT=y
 
 #
 # Sonics Silicon Backplane
@@ -687,6 +756,7 @@
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -726,8 +796,8 @@
 CONFIG_SND_PCM_OSS=m
 CONFIG_SND_PCM_OSS_PLUGINS=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 # CONFIG_SND_DRIVERS is not set
@@ -738,11 +808,14 @@
 # CONFIG_SOUND_PRIME is not set
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB_SUPPORT=y
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -750,7 +823,7 @@
 CONFIG_USB_GADGET=y
 # CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
-CONFIG_USB_GADGET_DEBUG_FS=y
+# CONFIG_USB_GADGET_DEBUG_FS is not set
 CONFIG_USB_GADGET_SELECTED=y
 # CONFIG_USB_GADGET_AMD5536UDC is not set
 CONFIG_USB_GADGET_ATMEL_USBA=y
@@ -787,33 +860,34 @@
 CONFIG_MMC_BLOCK=y
 CONFIG_MMC_BLOCK_BOUNCE=y
 # CONFIG_SDIO_UART is not set
-CONFIG_MMC_TEST=m
+# CONFIG_MMC_TEST is not set
 
 #
 # MMC/SD Host Controller Drivers
 #
 # CONFIG_MMC_SDHCI is not set
 CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_ATMELMCI_DMA is not set
 CONFIG_MMC_SPI=m
 # CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_CLASS=m
 
 #
 # LED drivers
 #
 CONFIG_LEDS_ATMEL_PWM=m
 # CONFIG_LEDS_PCA9532 is not set
-CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_GPIO=m
 # CONFIG_LEDS_PCA955X is not set
 
 #
 # LED Triggers
 #
 CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
 # CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
@@ -870,11 +944,13 @@
 # on-CPU RTC drivers
 #
 CONFIG_RTC_DRV_AT32AP700X=y
+# CONFIG_RTC_DRV_AVR32_AST is not set
 CONFIG_DMADEVICES=y
 
 #
 # DMA Devices
 #
+# CONFIG_ATMEL_PDCA is not set
 CONFIG_DW_DMAC=y
 CONFIG_DMA_ENGINE=y
 
@@ -888,13 +964,13 @@
 #
 # File systems
 #
-CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
 # CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=m
+CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
@@ -935,7 +1011,7 @@
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-CONFIG_CONFIGFS_FS=m
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
@@ -958,16 +1034,39 @@
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_XATTR=y
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
-# CONFIG_MINIX_FS is not set
+CONFIG_MINIX_FS=m
 # CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
 
 #
 # Partition Types
@@ -1036,6 +1135,8 @@
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1068,7 +1169,88 @@
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+# CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
@@ -1077,15 +1259,16 @@
 # CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
-# CONFIG_CRC16 is not set
+CONFIG_CRC16=y
 CONFIG_CRC_T10DIF=m
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 CONFIG_CRC7=m
 # CONFIG_LIBCRC32C is not set
-CONFIG_AUDIT_GENERIC=y
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_GENERIC_ALLOCATOR=y
 CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
diff -urN linux-2.6.28.2-0rig//arch/avr32/configs/atstk1004_defconfig linux-2.6.28.2/arch/avr32/configs/atstk1004_defconfig
--- linux-2.6.28.2-0rig//arch/avr32/configs/atstk1004_defconfig	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/configs/atstk1004_defconfig	2009-01-29 08:52:49.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc1
-# Tue Aug  5 15:38:56 2008
+# Linux kernel version: 2.6.27.4
+# Wed Nov 12 10:35:14 2008
 #
 CONFIG_AVR32=y
 CONFIG_GENERIC_GPIO=y
@@ -30,8 +30,10 @@
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SYSVIPC is not set
-# CONFIG_POSIX_MQUEUE is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
@@ -41,14 +43,16 @@
 # CONFIG_GROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_SYSFS_DEPRECATED_V2=y
-# CONFIG_RELAY is not set
+CONFIG_RELAY=y
 # CONFIG_NAMESPACES is not set
-# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL=y
 CONFIG_EMBEDDED=y
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
@@ -56,19 +60,23 @@
 CONFIG_ELF_CORE=y
 # CONFIG_COMPAT_BRK is not set
 # CONFIG_BASE_FULL is not set
-# CONFIG_FUTEX is not set
-# CONFIG_EPOLL is not set
-# CONFIG_SIGNALFD is not set
-# CONFIG_TIMERFD is not set
-# CONFIG_EVENTFD is not set
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
-# CONFIG_SLUB is not set
-CONFIG_SLOB=y
-# CONFIG_PROFILING is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
 # CONFIG_MARKERS is not set
+CONFIG_OPROFILE=m
 CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
 # CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
 # CONFIG_HAVE_IOREMAP_PROT is not set
 CONFIG_HAVE_KPROBES=y
@@ -77,36 +85,68 @@
 # CONFIG_HAVE_DMA_ATTRS is not set
 # CONFIG_USE_GENERIC_SMP_HELPERS is not set
 CONFIG_HAVE_CLK=y
-# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_PROC_PAGE_MONITOR=y
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=1
-# CONFIG_MODULES is not set
-# CONFIG_BLOCK is not set
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
 CONFIG_CLASSIC_RCU=y
 
 #
 # System Type and features
 #
-# CONFIG_TICK_ONESHOT is not set
-# CONFIG_NO_HZ is not set
-# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 CONFIG_SUBARCH_AVR32B=y
 CONFIG_MMU=y
 CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PORTMUX_PIO=y
 CONFIG_PLATFORM_AT32AP=y
 CONFIG_CPU_AT32AP700X=y
 CONFIG_CPU_AT32AP7002=y
 CONFIG_BOARD_ATSTK1000=y
 # CONFIG_BOARD_ATNGW100 is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MIMC200 is not set
 # CONFIG_BOARD_ATSTK1002 is not set
 # CONFIG_BOARD_ATSTK1003 is not set
 CONFIG_BOARD_ATSTK1004=y
+# CONFIG_BOARD_ATSTK1005 is not set
 # CONFIG_BOARD_ATSTK1006 is not set
 # CONFIG_BOARD_ATSTK100X_CUSTOM is not set
 # CONFIG_BOARD_ATSTK100X_SPI1 is not set
-# CONFIG_BOARD_ATSTK1000_J2_LED is not set
+CONFIG_BOARD_ATSTK1000_J2_LED=y
+# CONFIG_BOARD_ATSTK1000_J2_LED8 is not set
+CONFIG_BOARD_ATSTK1000_J2_RGB=y
 CONFIG_BOARD_ATSTK1000_EXTDAC=y
 CONFIG_LOADER_U_BOOT=y
 
@@ -144,25 +184,43 @@
 CONFIG_NR_QUICK=2
 CONFIG_VIRT_TO_BUS=y
 # CONFIG_OWNERSHIP_TRACE is not set
-# CONFIG_NMI_DEBUGGING is not set
+CONFIG_NMI_DEBUGGING=y
 # CONFIG_HZ_100 is not set
 CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 CONFIG_CMDLINE=""
 
 #
 # Power management options
 #
-# CONFIG_PM is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 
 #
 # CPU Frequency scaling
 #
-# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+# CONFIG_CPU_FREQ_STAT is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_AT32AP=y
 
 #
 # Bus options
@@ -183,40 +241,71 @@
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
 # CONFIG_IP_MULTICAST is not set
 # CONFIG_IP_ADVANCED_ROUTER is not set
 CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
 # CONFIG_ARPD is not set
 # CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
 # CONFIG_INET_IPCOMP is not set
 # CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
 # CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
-# CONFIG_IPV6 is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
 # CONFIG_IP_SCTP is not set
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
+CONFIG_STP=m
+CONFIG_BRIDGE=m
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
+CONFIG_LLC=m
 # CONFIG_LLC2 is not set
 # CONFIG_IPX is not set
 # CONFIG_ATALK is not set
@@ -230,6 +319,7 @@
 # Network testing
 #
 # CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
 # CONFIG_HAMRADIO is not set
 # CONFIG_CAN is not set
 # CONFIG_IRDA is not set
@@ -257,6 +347,8 @@
 CONFIG_STANDALONE=y
 # CONFIG_PREVENT_FIRMWARE_BUILD is not set
 # CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 CONFIG_MTD=y
@@ -271,6 +363,14 @@
 # User Modules And Translation Layers
 #
 CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
 # CONFIG_MTD_OOPS is not set
 
 #
@@ -311,11 +411,13 @@
 #
 # Self-contained MTD device drivers
 #
-# CONFIG_MTD_DATAFLASH is not set
-# CONFIG_MTD_M25P80 is not set
+CONFIG_MTD_DATAFLASH=m
+CONFIG_MTD_M25P80=m
+CONFIG_M25PXX_USE_FAST_READ=y
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
 
 #
 # Disk-On-Chip Device Drivers
@@ -329,24 +431,186 @@
 #
 # UBI - Unsorted block images
 #
-# CONFIG_MTD_UBI is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
 # CONFIG_PARPORT is not set
-# CONFIG_MISC_DEVICES is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_PWM=m
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_TCB_CLKSRC=y
+CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_ATMEL_SSC=m
+# CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HAVE_IDE is not set
 
 #
 # SCSI device support
 #
-# CONFIG_SCSI_DMA is not set
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
 # CONFIG_SCSI_NETLINK is not set
-# CONFIG_NETDEVICES is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_PMP is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+CONFIG_PATA_AT32=m
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_MII is not set
+CONFIG_MACB=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
 # CONFIG_ISDN is not set
 # CONFIG_PHONE is not set
 
 #
 # Input device support
 #
-# CONFIG_INPUT is not set
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_POLLDEV=m
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+CONFIG_MOUSE_GPIO=m
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
 
 #
 # Hardware I/O ports
@@ -357,8 +621,12 @@
 #
 # Character devices
 #
-# CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -371,7 +639,7 @@
 #
 CONFIG_SERIAL_ATMEL=y
 CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_SERIAL_ATMEL_PDC is not set
+CONFIG_SERIAL_ATMEL_PDC=y
 # CONFIG_SERIAL_ATMEL_TTYAT is not set
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
@@ -380,14 +648,62 @@
 # CONFIG_IPMI_HANDLER is not set
 # CONFIG_HW_RANDOM is not set
 # CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_GPIO=m
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
 CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
 CONFIG_SPI_MASTER=y
 
 #
 # SPI Master Controller Drivers
 #
+CONFIG_SPI_ATMEL_HAVE_PDC=y
 CONFIG_SPI_ATMEL=y
 # CONFIG_SPI_BITBANG is not set
 
@@ -395,15 +711,19 @@
 # SPI Protocol Masters
 #
 # CONFIG_SPI_AT25 is not set
-# CONFIG_SPI_SPIDEV is not set
+CONFIG_SPI_SPIDEV=m
 # CONFIG_SPI_TLE62X0 is not set
 CONFIG_ARCH_REQUIRE_GPIOLIB=y
 CONFIG_GPIOLIB=y
-# CONFIG_GPIO_SYSFS is not set
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
 
 #
 # I2C GPIO expanders:
 #
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
 
 #
 # PCI GPIO expanders:
@@ -426,7 +746,7 @@
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
-CONFIG_AT32AP700X_WDT=y
+CONFIG_AT32_WDT=y
 
 #
 # Sonics Silicon Backplane
@@ -440,6 +760,7 @@
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -485,6 +806,7 @@
 #
 # CONFIG_FB_S1D13XXX is not set
 CONFIG_FB_ATMEL=y
+# CONFIG_FB_ATMEL_MPOP is not set
 # CONFIG_FB_VIRTUAL is not set
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
 CONFIG_LCD_CLASS_DEVICE=y
@@ -498,20 +820,51 @@
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
 # CONFIG_LOGO is not set
-# CONFIG_SOUND is not set
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_DRIVERS is not set
+CONFIG_SND_SPI=y
+CONFIG_SND_AT73C213=m
+CONFIG_SND_AT73C213_TARGET_BITRATE=48000
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+# CONFIG_HID_SUPPORT is not set
 CONFIG_USB_SUPPORT=y
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
 # CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
 CONFIG_USB_GADGET_SELECTED=y
 # CONFIG_USB_GADGET_AMD5536UDC is not set
 CONFIG_USB_GADGET_ATMEL_USBA=y
@@ -528,18 +881,54 @@
 # CONFIG_USB_GADGET_AT91 is not set
 # CONFIG_USB_GADGET_DUMMY_HCD is not set
 CONFIG_USB_GADGET_DUALSPEED=y
-# CONFIG_USB_ZERO is not set
-CONFIG_USB_ETH=y
-# CONFIG_USB_ETH_RNDIS is not set
-# CONFIG_USB_GADGETFS is not set
-# CONFIG_USB_FILE_STORAGE is not set
-# CONFIG_USB_G_SERIAL is not set
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
-# CONFIG_USB_CDC_COMPOSITE is not set
-# CONFIG_MMC is not set
+CONFIG_USB_CDC_COMPOSITE=m
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_ATMELMCI_DMA is not set
+CONFIG_MMC_SPI=m
 # CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+CONFIG_LEDS_ATMEL_PWM=m
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=m
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
 # CONFIG_ACCESSIBILITY is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
@@ -551,12 +940,28 @@
 # RTC interfaces
 #
 CONFIG_RTC_INTF_SYSFS=y
-# CONFIG_RTC_INTF_PROC is not set
+CONFIG_RTC_INTF_PROC=y
 CONFIG_RTC_INTF_DEV=y
 # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
 # CONFIG_RTC_DRV_TEST is not set
 
 #
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
 # SPI RTC drivers
 #
 # CONFIG_RTC_DRV_M41T94 is not set
@@ -580,18 +985,62 @@
 # on-CPU RTC drivers
 #
 CONFIG_RTC_DRV_AT32AP700X=y
-# CONFIG_DMADEVICES is not set
+# CONFIG_RTC_DRV_AVR32_AST is not set
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+# CONFIG_ATMEL_PDCA is not set
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+CONFIG_DMATEST=m
 # CONFIG_UIO is not set
 
 #
 # File systems
 #
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
 # CONFIG_DNOTIFY is not set
-# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
 
 #
 # Pseudo filesystems
@@ -603,14 +1052,22 @@
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
 #
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
 CONFIG_JFFS2_FS=y
 CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_WRITEBUFFER is not set
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
 # CONFIG_JFFS2_SUMMARY is not set
 # CONFIG_JFFS2_FS_XATTR is not set
 # CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
@@ -618,8 +1075,85 @@
 # CONFIG_JFFS2_LZO is not set
 CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
-# CONFIG_NETWORK_FILESYSTEMS is not set
-# CONFIG_NLS is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_XATTR=y
+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=m
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
 # CONFIG_DLM is not set
 
 #
@@ -631,11 +1165,43 @@
 CONFIG_FRAME_WARN=1024
 CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
+CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
 # CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
 # CONFIG_SAMPLES is not set
 
 #
@@ -644,7 +1210,88 @@
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+# CONFIG_CRYPTO_HW is not set
 
 #
 # Library routines
@@ -652,16 +1299,19 @@
 CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_T10DIF is not set
-# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=m
+CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
+CONFIG_CRC7=m
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
 CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
diff -urN linux-2.6.28.2-0rig//arch/avr32/configs/atstk1005_defconfig linux-2.6.28.2/arch/avr32/configs/atstk1005_defconfig
--- linux-2.6.28.2-0rig//arch/avr32/configs/atstk1005_defconfig	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/configs/atstk1005_defconfig	2009-01-29 08:52:49.000000000 +0100
@@ -0,0 +1,1505 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.27.4
+# Fri Nov  7 10:22:27 2008
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=m
+CONFIG_HAVE_OPROFILE=y
+CONFIG_KPROBES=y
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
+CONFIG_HAVE_KPROBES=y
+# CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
+# CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+CONFIG_HAVE_CLK=y
+CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=1
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type and features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PORTMUX_GPIO_V2=y
+CONFIG_TIMER_AST=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP720X=y
+CONFIG_CPU_AT32AP7200=y
+CONFIG_BOARD_ATSTK1000=y
+# CONFIG_BOARD_ATNGW100 is not set
+# CONFIG_BOARD_FAVR_32 is not set
+# CONFIG_BOARD_MIMC200 is not set
+# CONFIG_BOARD_ATSTK1002 is not set
+# CONFIG_BOARD_ATSTK1003 is not set
+# CONFIG_BOARD_ATSTK1004 is not set
+CONFIG_BOARD_ATSTK1005=y
+# CONFIG_BOARD_ATSTK1006 is not set
+# CONFIG_BOARD_ATSTK100X_CUSTOM is not set
+# CONFIG_BOARD_ATSTK100X_SPI1 is not set
+CONFIG_BOARD_ATSTK1000_J2_LED=y
+# CONFIG_BOARD_ATSTK1000_J2_LED8 is not set
+CONFIG_BOARD_ATSTK1000_J2_RGB=y
+CONFIG_BOARD_ATSTK1000_EXTDAC=y
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+CONFIG_LOAD_ADDRESS=0x10000000
+CONFIG_ENTRY_ADDRESS=0x90000000
+CONFIG_PHYS_OFFSET=0x10000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_QUICKLIST=y
+# CONFIG_HAVE_ARCH_BOOTMEM_NODE is not set
+# CONFIG_ARCH_HAVE_MEMORY_PRESENT is not set
+# CONFIG_NEED_NODE_MEMMAP_SIZE is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+# CONFIG_ARCH_SPARSEMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=2
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_OWNERSHIP_TRACE is not set
+CONFIG_NMI_DEBUGGING=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_CMDLINE=""
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# CPU Frequency scaling
+#
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_TABLE=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+# CONFIG_CPU_FREQ_STAT is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_AT32AP=y
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=m
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
+CONFIG_NET_KEY=m
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE=m
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+# CONFIG_IPV6_MIP6 is not set
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+CONFIG_STP=m
+CONFIG_BRIDGE=m
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_TCPPROBE is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=m
+CONFIG_MTD_M25P80=m
+CONFIG_M25PXX_USE_FAST_READ=y
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_ATMEL_ECC_HW=y
+# CONFIG_MTD_NAND_ATMEL_ECC_SOFT is not set
+# CONFIG_MTD_NAND_ATMEL_ECC_NONE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
+CONFIG_MTD_UBI_BEB_RESERVE=1
+# CONFIG_MTD_UBI_GLUEBI is not set
+
+#
+# UBI debugging options
+#
+# CONFIG_MTD_UBI_DEBUG is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=m
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_PWM=m
+# CONFIG_ATMEL_TCLIB is not set
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_ATMEL_SSC=m
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HAVE_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_PMP is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+CONFIG_PATA_AT32=m
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+CONFIG_MACB=y
+# CONFIG_ENC28J60 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+CONFIG_USB_CATC=m
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_AX8817X is not set
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_GL620A is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+CONFIG_USB_NET_CDC_SUBSET=m
+# CONFIG_USB_ALI_M5632 is not set
+# CONFIG_USB_AN2720 is not set
+CONFIG_USB_BELKIN=y
+CONFIG_USB_ARMLINUX=y
+# CONFIG_USB_EPSON2888 is not set
+# CONFIG_USB_KC2190 is not set
+# CONFIG_USB_NET_ZAURUS is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_POLLDEV=m
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=m
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+CONFIG_MOUSE_GPIO=m
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_SERIAL_ATMEL_PDC=y
+# CONFIG_SERIAL_ATMEL_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=m
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_GPIO=m
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+CONFIG_I2C_TINY_USB=m
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_ATMEL=y
+# CONFIG_SPI_BITBANG is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+CONFIG_SPI_SPIDEV=m
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_AT32_WDT=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_ATMEL=y
+# CONFIG_FB_ATMEL_MPOP is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_LTV350QV=y
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+# CONFIG_LOGO is not set
+CONFIG_SOUND=m
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_HWDEP=m
+CONFIG_SND_RAWMIDI=m
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_DRIVERS is not set
+CONFIG_SND_SPI=y
+CONFIG_SND_AT73C213=m
+CONFIG_SND_AT73C213_TARGET_BITRATE=48000
+CONFIG_SND_USB=y
+CONFIG_SND_USB_AUDIO=m
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_SOC is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
+CONFIG_USB_EHCI_BIG_ENDIAN_DESC=y
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+# CONFIG_USB_OHCI_LITTLE_ENDIAN is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+# CONFIG_USB_GADGET_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_WDM=m
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+CONFIG_USB_SERIAL=m
+# CONFIG_USB_EZUSB is not set
+CONFIG_USB_SERIAL_GENERIC=y
+# CONFIG_USB_SERIAL_AIRCABLE is not set
+# CONFIG_USB_SERIAL_ARK3116 is not set
+# CONFIG_USB_SERIAL_BELKIN is not set
+# CONFIG_USB_SERIAL_CH341 is not set
+# CONFIG_USB_SERIAL_WHITEHEAT is not set
+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
+# CONFIG_USB_SERIAL_CP2101 is not set
+# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
+# CONFIG_USB_SERIAL_EMPEG is not set
+# CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
+# CONFIG_USB_SERIAL_VISOR is not set
+# CONFIG_USB_SERIAL_IPAQ is not set
+# CONFIG_USB_SERIAL_IR is not set
+# CONFIG_USB_SERIAL_EDGEPORT is not set
+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
+# CONFIG_USB_SERIAL_GARMIN is not set
+# CONFIG_USB_SERIAL_IPW is not set
+# CONFIG_USB_SERIAL_IUU is not set
+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
+# CONFIG_USB_SERIAL_KEYSPAN is not set
+# CONFIG_USB_SERIAL_KLSI is not set
+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
+# CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_MOS7720 is not set
+# CONFIG_USB_SERIAL_MOS7840 is not set
+# CONFIG_USB_SERIAL_MOTOROLA is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
+CONFIG_USB_SERIAL_PL2303=m
+# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_SPCP8X5 is not set
+# CONFIG_USB_SERIAL_HP4X is not set
+# CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
+# CONFIG_USB_SERIAL_TI is not set
+# CONFIG_USB_SERIAL_CYBERJACK is not set
+# CONFIG_USB_SERIAL_XIRCOM is not set
+# CONFIG_USB_SERIAL_OPTION is not set
+# CONFIG_USB_SERIAL_OMNINET is not set
+# CONFIG_USB_SERIAL_DEBUG is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=m
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+CONFIG_USB_GADGET_ATMEL_USBA=y
+CONFIG_USB_ATMEL_USBA=y
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+# CONFIG_USB_CDC_COMPOSITE is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+CONFIG_MMC_TEST=m
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_ATMELMCI_DMA is not set
+CONFIG_MMC_SPI=m
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+CONFIG_LEDS_ATMEL_PWM=m
+# CONFIG_LEDS_PCA9532 is not set
+CONFIG_LEDS_GPIO=m
+# CONFIG_LEDS_PCA955X is not set
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_AT32AP700X is not set
+CONFIG_RTC_DRV_AVR32_AST=y
+CONFIG_DMADEVICES=y
+
+#
+# DMA Devices
+#
+CONFIG_ATMEL_PDCA=y
+CONFIG_DW_DMAC=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+CONFIG_DMATEST=m
+# CONFIG_UIO is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4DEV_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=m
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_XATTR=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_ZLIB=y
+# CONFIG_UBIFS_FS_DEBUG is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=m
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_KPROBES_SANITY_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SAMPLES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_MANAGER=m
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=m
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=m
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=m
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=m
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=m
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_LZO=y
+# CONFIG_CRYPTO_HW is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+CONFIG_CRC7=m
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff -urN linux-2.6.28.2-0rig//arch/avr32/configs/atstk1006_defconfig linux-2.6.28.2/arch/avr32/configs/atstk1006_defconfig
--- linux-2.6.28.2-0rig//arch/avr32/configs/atstk1006_defconfig	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/configs/atstk1006_defconfig	2009-01-29 09:11:15.000000000 +0100
@@ -124,6 +124,7 @@
 CONFIG_SUBARCH_AVR32B=y
 CONFIG_MMU=y
 CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PORTMUX_PIO=y
 CONFIG_PLATFORM_AT32AP=y
 CONFIG_CPU_AT32AP700X=y
 CONFIG_CPU_AT32AP7000=y
@@ -137,9 +138,9 @@
 CONFIG_BOARD_ATSTK1006=y
 # CONFIG_BOARD_ATSTK100X_CUSTOM is not set
 # CONFIG_BOARD_ATSTK100X_SPI1 is not set
-# CONFIG_BOARD_ATSTK1000_J2_LED is not set
+CONFIG_BOARD_ATSTK1000_J2_LED=y
 # CONFIG_BOARD_ATSTK1000_J2_LED8 is not set
-# CONFIG_BOARD_ATSTK1000_J2_RGB is not set
+CONFIG_BOARD_ATSTK1000_J2_RGB=y
 CONFIG_BOARD_ATSTK1000_EXTDAC=y
 CONFIG_LOADER_U_BOOT=y
 
@@ -355,7 +356,8 @@
 CONFIG_MTD_CHAR=y
 CONFIG_HAVE_MTD_OTP=y
 CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_MTD_BLOCK_RO is not set
 # CONFIG_FTL is not set
 # CONFIG_NFTL is not set
 # CONFIG_INFTL is not set
@@ -419,7 +421,7 @@
 # CONFIG_MTD_DOC2001PLUS is not set
 CONFIG_MTD_NAND=y
 # CONFIG_MTD_NAND_VERIFY_WRITE is not set
-# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND_ECC_SMC=y
 # CONFIG_MTD_NAND_MUSEUM_IDS is not set
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
@@ -519,7 +521,7 @@
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
+# CONFIG_TUN is not set
 # CONFIG_VETH is not set
 CONFIG_PHYLIB=y
 
@@ -581,7 +583,7 @@
 #
 # Input device support
 #
-CONFIG_INPUT=m
+CONFIG_INPUT=y
 # CONFIG_INPUT_FF_MEMLESS is not set
 CONFIG_INPUT_POLLDEV=m
 
@@ -610,6 +612,8 @@
 CONFIG_INPUT_MOUSE=y
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 CONFIG_MOUSE_GPIO=m
 # CONFIG_INPUT_JOYSTICK is not set
@@ -626,8 +630,12 @@
 #
 # Character devices
 #
-# CONFIG_VT is not set
-# CONFIG_DEVKMEM is not set
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -704,6 +712,7 @@
 #
 # SPI Master Controller Drivers
 #
+CONFIG_SPI_ATMEL_HAVE_PDC=y
 CONFIG_SPI_ATMEL=y
 # CONFIG_SPI_BITBANG is not set
 
@@ -752,6 +761,7 @@
 # CONFIG_SOFT_WATCHDOG is not set
 CONFIG_AT32AP700X_WDT=y
 CONFIG_SSB_POSSIBLE=y
+CONFIG_AT32_WDT=y
 
 #
 # Sonics Silicon Backplane
@@ -814,6 +824,7 @@
 #
 # CONFIG_FB_S1D13XXX is not set
 CONFIG_FB_ATMEL=y
+# CONFIG_FB_ATMEL_MPOP is not set
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FB_METRONOME is not set
 # CONFIG_FB_MB862XX is not set
@@ -830,6 +841,12 @@
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
 # CONFIG_LOGO is not set
 CONFIG_SOUND=m
 CONFIG_SOUND_OSS_CORE=y
@@ -846,11 +863,7 @@
 # CONFIG_SND_VERBOSE_PROCFS is not set
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
+# CONFIG_SND_DRIVERS is not set
 CONFIG_SND_SPI=y
 CONFIG_SND_AT73C213=m
 CONFIG_SND_AT73C213_TARGET_BITRATE=48000
@@ -858,9 +871,9 @@
 # CONFIG_SOUND_PRIME is not set
 # CONFIG_HID_SUPPORT is not set
 CONFIG_USB_SUPPORT=y
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 # CONFIG_USB_MUSB_HDRC is not set
@@ -900,7 +913,7 @@
 CONFIG_USB_G_SERIAL=m
 # CONFIG_USB_MIDI_GADGET is not set
 # CONFIG_USB_G_PRINTER is not set
-# CONFIG_USB_CDC_COMPOSITE is not set
+CONFIG_USB_CDC_COMPOSITE=m
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
@@ -1002,11 +1015,13 @@
 # on-CPU RTC drivers
 #
 CONFIG_RTC_DRV_AT32AP700X=y
+# CONFIG_RTC_DRV_AVR32_AST is not set
 CONFIG_DMADEVICES=y
 
 #
 # DMA Devices
 #
+# CONFIG_ATMEL_PDCA is not set
 CONFIG_DW_DMAC=y
 CONFIG_DMA_ENGINE=y
 
@@ -1022,17 +1037,17 @@
 #
 # File systems
 #
-CONFIG_EXT2_FS=m
+CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=m
+CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
-CONFIG_EXT4_FS=m
-CONFIG_EXT4DEV_COMPAT=y
+# CONFIG_EXT4_FS is not set
+# CONFIG_EXT4DEV_COMPAT=y
 # CONFIG_EXT4_FS_XATTR is not set
-CONFIG_JBD=m
+CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
-CONFIG_JBD2=m
+# CONFIG_JBD2 is not set
 # CONFIG_JBD2_DEBUG is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
@@ -1075,7 +1090,7 @@
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
 # CONFIG_HUGETLB_PAGE is not set
-# CONFIG_CONFIGFS_FS is not set
+CONFIG_CONFIGFS_FS=y
 
 #
 # Miscellaneous filesystems
diff -urN linux-2.6.28.2-0rig//arch/avr32/include/asm/ast_regs.h linux-2.6.28.2/arch/avr32/include/asm/ast_regs.h
--- linux-2.6.28.2-0rig//arch/avr32/include/asm/ast_regs.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/include/asm/ast_regs.h	2009-01-29 08:52:49.000000000 +0100
@@ -0,0 +1,88 @@
+/*
+ * Register definitions for the Asynchronous Timer (AST)
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __AST_REGS_H__
+#define __AST_REGS_H__
+
+/* Control Register */
+#define AST_CR				0x0000
+# define AST_CR_EN_BIT			0	/* Enable */
+# define AST_CR_PCLR_BIT		1	/* Prescaler Clear */
+# define AST_CR_CA0_BIT			8	/* Clear on Alarm */
+# define AST_CR_CA1_BIT			9
+# define AST_CR_PSEL_START		16	/* Prescale Select */
+# define AST_CR_PSEL_SIZE		4
+
+/* Counter Value */
+#define AST_CV				0x0004
+
+/* Status, Status Clear, Interrupt Enable/Disable/Mask, Wake Enable */
+#define AST_SR				0x0008
+#define AST_SCR				0x000c
+#define AST_IER				0x0010
+#define AST_IDR				0x0014
+#define AST_IMR				0x0018
+#define AST_WER				0x001c
+# define AST_OVF_BIT			0	/* Overflow */
+# define AST_ALARM0_BIT			8	/* Alarm event */
+# define AST_ALARM1_BIT			9
+# define AST_PER0_BIT			16	/* Periodic event */
+# define AST_PER1_BIT			17
+# define AST_BUSY_BIT			24	/* AST busy */
+# define AST_READY_BIT			25	/* BUSY 1 -> 0 event */
+# define AST_CLK_BUSY_BIT		28	/* CLOCK busy */
+# define AST_CLK_READY_BIT		29	/* CKL_BUSY 1 -> 0 event */
+
+/* Alarm registers */
+#define AST_AR0				0x0020
+#define AST_AR1				0x0024
+
+/* Periodic Interval registers */
+#define AST_PIR0			0x0030
+#define AST_PIR1			0x0034
+# define AST_PIRx_INSEL_START		0	/* Interval select */
+# define AST_PIRx_INSEL_SIZE		4
+
+/* Clock Select register */
+#define AST_CLOCK			0x0040
+# define AST_CLOCK_CEN_BIT		0	/* Clock Enable */
+# define AST_CLOCK_CSSEL_START		8	/* Clock Source */
+# define AST_CLOCK_CSSEL_SIZE		2
+#  define AST_CLOCK_SLOW		0	/* RC oscillator */
+#  define AST_CLOCK_OSC32		1	/* 32 kHz oscillator */
+#  define AST_CLOCK_PB			2	/* Peripheral Bus clock */
+#  define AST_CLOCK_GC			3	/* Generic clock */
+
+/* Version register */
+#define AST_VERSION			0x00fc
+
+/* Bit manipulation macros */
+#define AST_BIT(name)						\
+	(1 << AST_##name##_BIT)
+#define AST_BF(name,value)					\
+	(((value) & ((1 << AST_##name##_SIZE) - 1))		\
+	 << AST_##name##_START)
+#define AST_BFEXT(name,value)					\
+	(((value) >> AST_##name##_START)			\
+	 & ((1 << AST_##name##_SIZE) - 1))
+#define AST_BFINS(name,value,old)				\
+	(((old) & ~(((1 << AST_##name##_SIZE) - 1)		\
+		    << AST_##name##_START))			\
+	 | AST_BF(name,value))
+
+/* Register access macros */
+#define ast_readl(base, reg)					\
+	__raw_readl(base + AST_##reg)
+#define ast_writel(base, reg, value)				\
+	__raw_writel(value, base + AST_##reg)
+
+struct platform_device;
+void ast_time_init(struct platform_device *pdev, unsigned int clksel);
+
+#endif /* __AST_REGS_H__ */
diff -urN linux-2.6.28.2-0rig//arch/avr32/Kconfig linux-2.6.28.2/arch/avr32/Kconfig
--- linux-2.6.28.2-0rig//arch/avr32/Kconfig	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/Kconfig	2009-01-29 08:52:44.000000000 +0100
@@ -85,6 +85,18 @@
 config PERFORMANCE_COUNTERS
 	bool
 
+# The old "PIO" portmux/GPIO module used on AT32AP700x
+config PORTMUX_PIO
+	bool
+
+# The new "GPIO" portmux/GPIO module, version 2
+config PORTMUX_GPIO_V2
+	bool
+
+# Asynchronous Timer clocksource/clockevent driver
+config TIMER_AST
+	bool
+
 config PLATFORM_AT32AP
 	bool
 	select SUBARCH_AVR32B
@@ -101,6 +113,7 @@
 config CPU_AT32AP700X
 	bool
 	select PLATFORM_AT32AP
+	select PORTMUX_PIO
 config CPU_AT32AP7000
 	bool
 	select CPU_AT32AP700X
@@ -111,6 +124,16 @@
 	bool
 	select CPU_AT32AP700X
 
+# AP7200 derivatives
+config CPU_AT32AP720X
+	bool
+	select PLATFORM_AT32AP
+	select TIMER_AST
+	select PORTMUX_GPIO_V2
+config CPU_AT32AP7200
+	bool
+	select CPU_AT32AP720X
+
 choice
 	prompt "AVR32 board type"
 	default BOARD_ATSTK1000
@@ -148,14 +171,17 @@
 config LOAD_ADDRESS
 	hex
 	default 0x10000000 if LOADER_U_BOOT=y && CPU_AT32AP700X=y
+	default 0x10000000 if LOADER_U_BOOT=y && CPU_AT32AP720X=y
 
 config ENTRY_ADDRESS
 	hex
 	default 0x90000000 if LOADER_U_BOOT=y && CPU_AT32AP700X=y
+	default 0x90000000 if LOADER_U_BOOT=y && CPU_AT32AP720X=y
 
 config PHYS_OFFSET
 	hex
 	default 0x10000000 if CPU_AT32AP700X=y
+	default 0x10000000 if CPU_AT32AP720X=y
 
 source "kernel/Kconfig.preempt"
 
diff -urN linux-2.6.28.2-0rig//arch/avr32/kernel/cpu.c linux-2.6.28.2/arch/avr32/kernel/cpu.c
--- linux-2.6.28.2-0rig//arch/avr32/kernel/cpu.c	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/kernel/cpu.c	2009-01-29 08:52:49.000000000 +0100
@@ -208,6 +208,7 @@
 
 static const struct chip_id_map chip_names[] = {
 	{ .mid = 0x1f, .pn = 0x1e82, .name = "AT32AP700x" },
+	{ .mid = 0x1f, .pn = 0x1e83, .name = "AT32AP720x" },
 };
 #define NR_CHIP_NAMES ARRAY_SIZE(chip_names)
 
diff -urN linux-2.6.28.2-0rig//arch/avr32/kernel/entry-avr32b.S linux-2.6.28.2/arch/avr32/kernel/entry-avr32b.S
--- linux-2.6.28.2-0rig//arch/avr32/kernel/entry-avr32b.S	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/kernel/entry-avr32b.S	2009-01-29 08:52:49.000000000 +0100
@@ -112,7 +112,9 @@
 
 	/* Second level lookup */
 	ld.w	r2, r3[r1 << 2]
+#ifdef CONFIG_CPU_AT32AP700X
 	mfsr	r0, SYSREG_TLBARLO
+#endif
 	bld	r2, _PAGE_BIT_PRESENT
 	brcc	page_not_present
 
@@ -124,6 +126,8 @@
 	andl	r2, _PAGE_FLAGS_HARDWARE_MASK & 0xffff
 	mtsr	SYSREG_TLBELO, r2
 
+	/* Later CPUs do this algorithm in hardware */
+#ifdef CONFIG_CPU_AT32AP700X
 	/* Figure out which entry we want to replace */
 	mfsr	r1, SYSREG_MMUCR
 	clz	r2, r0
@@ -134,6 +138,7 @@
 
 1:	bfins	r1, r2, SYSREG_DRP_OFFSET, SYSREG_DRP_SIZE
 	mtsr	SYSREG_MMUCR, r1
+#endif /* CONFIG_CPU_AT32AP700X */
 	tlbw
 
 	tlbmiss_restore
@@ -751,8 +756,10 @@
 
 	lddsp	r4, sp[REG_SR]
 	bfextu	r4, r4, SYSREG_M0_OFFSET, 3
+#ifdef CONFIG_CPU_AT32AP700X
 	cp.w	r4, MODE_SUPERVISOR >> SYSREG_M0_OFFSET
 	breq	2f
+#endif
 	cp.w	r4, MODE_USER >> SYSREG_M0_OFFSET
 #ifdef CONFIG_PREEMPT
 	brne	3f
@@ -786,6 +793,7 @@
 	rete
 #endif
 
+#ifdef CONFIG_CPU_AT32AP700X
 2:	get_thread_info	r0
 	ld.w	r1, r0[TI_flags]
 	bld	r1, TIF_CPU_GOING_TO_SLEEP
@@ -796,6 +804,7 @@
 #endif
 	sub	r1, pc, . - cpu_idle_skip_sleep
 	stdsp	sp[REG_PC], r1
+#endif
 #ifdef CONFIG_PREEMPT
 3:	get_thread_info r0
 	ld.w	r2, r0[TI_preempt_count]
diff -urN linux-2.6.28.2-0rig//arch/avr32/kernel/time.c linux-2.6.28.2/arch/avr32/kernel/time.c
--- linux-2.6.28.2-0rig//arch/avr32/kernel/time.c	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/kernel/time.c	2009-01-29 08:52:49.000000000 +0100
@@ -15,6 +15,8 @@
 
 #include <asm/sysreg.h>
 
+#include <mach/cpu.h>
+#include <mach/init.h>
 #include <mach/pm.h>
 
 
@@ -116,6 +118,9 @@
 	unsigned long counter_hz;
 	int ret;
 
+	/* Make sure we don't get any interrupts until we ask for it. */
+	sysreg_write(COMPARE, 0);
+
 	xtime.tv_sec = mktime(2007, 1, 1, 0, 0, 0);
 	xtime.tv_nsec = 0;
 
@@ -130,12 +135,16 @@
 	if (ret)
 		pr_debug("timer: could not register clocksource: %d\n", ret);
 
+	if (!cpu_has_working_compare()) {
+		platform_time_init();
+		return;
+	}
+
 	/* setup COMPARE clockevent */
 	comparator.mult = div_sc(counter_hz, NSEC_PER_SEC, comparator.shift);
 	comparator.max_delta_ns = clockevent_delta2ns((u32)~0, &comparator);
 	comparator.min_delta_ns = clockevent_delta2ns(50, &comparator) + 1;
 
-	sysreg_write(COMPARE, 0);
 	timer_irqaction.dev_id = &comparator;
 
 	ret = setup_irq(0, &timer_irqaction);
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/at32ap700x.c linux-2.6.28.2/arch/avr32/mach-at32ap/at32ap700x.c
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/at32ap700x.c	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/at32ap700x.c	2009-01-29 08:52:49.000000000 +0100
@@ -23,6 +23,7 @@
 #include <mach/at32ap700x.h>
 #include <mach/board.h>
 #include <mach/hmatrix.h>
+#include <mach/pm.h>
 #include <mach/portmux.h>
 #include <mach/sram.h>
 
@@ -30,7 +31,7 @@
 
 #include "clock.h"
 #include "pio.h"
-#include "pm.h"
+#include "pm-v1.h"
 
 
 #define PBMEM(base)					\
@@ -996,6 +997,7 @@
 void __init at32_map_usart(unsigned int hw_id, unsigned int line)
 {
 	struct platform_device *pdev;
+	u32 pin_mask;
 
 	switch (hw_id) {
 	case 0:
@@ -1155,6 +1157,7 @@
 static struct resource atmel_spi0_resource[] = {
 	PBMEM(0xffe00000),
 	IRQ(3),
+	{ 0 },	/* SRAM buffer, if available */
 };
 DEFINE_DEV(atmel_spi, 0);
 DEV_CLK(spi_clk, atmel_spi0, pba, 0);
@@ -1162,6 +1165,7 @@
 static struct resource atmel_spi1_resource[] = {
 	PBMEM(0xffe00400),
 	IRQ(4),
+	{ 0 },	/* SRAM buffer, if available */
 };
 DEFINE_DEV(atmel_spi, 1);
 DEV_CLK(spi_clk, atmel_spi1, pba, 1);
@@ -1191,6 +1195,8 @@
 struct platform_device *__init
 at32_add_device_spi(unsigned int id, struct spi_board_info *b, unsigned int n)
 {
+	unsigned long sram_buf;
+
 	/*
 	 * Manage the chipselects as GPIOs, normally using the same pins
 	 * the SPI controller expects; but boards can use other pins.
@@ -1231,6 +1237,13 @@
 		return NULL;
 	}
 
+	sram_buf = sram_alloc(4096);
+	if (sram_buf) {
+		pdev->resource[2].start = sram_buf;
+		pdev->resource[2].end = sram_buf + 4096 - 1;
+		pdev->resource[2].flags = IORESOURCE_MEM;
+	}
+
 	spi_register_board_info(b, n);
 	platform_device_register(pdev);
 	return pdev;
@@ -1738,6 +1751,7 @@
 		struct usba_ep_data ep[7];
 	} usba_data;
 	struct platform_device *pdev;
+	u32 pin_mask;
 
 	if (id != 0)
 		return NULL;
@@ -1940,6 +1954,7 @@
 at32_add_device_nand(unsigned int id, struct atmel_nand_data *data)
 {
 	struct platform_device *pdev;
+	u32 pin_mask;
 
 	if (id != 0 || !data)
 		return NULL;
@@ -2272,6 +2287,11 @@
 	at32_init_pio(&pio4_device);
 }
 
+unsigned long at32_get_reset_cause(void)
+{
+	return pm_readl(RCAUSE);
+}
+
 struct gen_pool *sram_pool;
 
 static int __init sram_init(void)
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/at32ap720x.c linux-2.6.28.2/arch/avr32/mach-at32ap/at32ap720x.c
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/at32ap720x.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/at32ap720x.c	2009-01-29 08:52:49.000000000 +0100
@@ -0,0 +1,2303 @@
+/*
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/atmel_pdca.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/dw_dmac.h>
+#include <linux/errno.h>
+#include <linux/fb.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/spinlock.h>
+#include <linux/spi/atmel_spi.h>
+#include <linux/spi/spi.h>
+#include <video/atmel_lcdc.h>
+#include <video/atmel_mpop.h>
+
+#include <asm/ast_regs.h>
+#include <asm/atmel-mci.h>
+
+#include <mach/at32ap720x.h>
+#include <mach/board.h>
+#include <mach/hmatrix.h>
+#include <mach/init.h>
+#include <mach/pm.h>
+#include <mach/portmux.h>
+#include <mach/sram.h>
+
+#include "clock.h"
+#include "gpio-v2.h"
+#include "pm-v3.h"
+#include "sdc.h"
+
+#define PBMEM(base)					\
+	{						\
+		.start		= base,			\
+		.end		= base + 0x3ff,		\
+		.flags		= IORESOURCE_MEM,	\
+	}
+#define IRQ(num)					\
+	{						\
+		.start		= num,			\
+		.end		= num,			\
+		.flags		= IORESOURCE_IRQ,	\
+	}
+
+#define select_peripheral(port, pin_mask, periph, flags)	\
+	at32_select_periph(GPIO_##port##_BASE, pin_mask,	\
+			   GPIO_##periph, flags)
+
+#define DEV_CLK(_name, devname, bus, _index)			\
+static struct clk devname##_##_name = {				\
+	.name		= #_name,				\
+	.dev		= &devname##_device.dev,		\
+	.parent		= &bus##_clk,				\
+	.mode		= bus##_clk_mode,			\
+	.get_rate	= bus##_clk_get_rate,			\
+	.index		= _index,				\
+}
+
+static DEFINE_SPINLOCK(pm_lock);
+
+static unsigned long rcosc_get_rate(struct clk *clk)
+{
+	return 32768;
+}
+
+static unsigned long osc_get_rate(struct clk *clk)
+{
+	return at32_board_osc_rates[clk->index];
+}
+
+static void osc32_mode(struct clk *clk, int enabled)
+{
+	/* We never disable the 32 kHz oscillator */
+	if (!enabled)
+		return;
+
+	/* If it's already running, we're done. */
+	if (pm_readl(POSCSR) & PM_BIT(POSCSR_OSC32RDY))
+		return;
+
+	/* Enable it, unless someone did it for us already */
+	if (!(sdc_readl(OSCCTRL32) & SDC_BIT(OSCCTRL32_OSC32EN))) {
+		u32 value;
+
+		value = SDC_BF(OSCCTRL32_STARTUP, 5)
+			| SDC_BF(OSCCTRL32_MODE, 0xd)
+			| SDC_BIT(OSCCTRL32_OSC32EN);
+
+		sdc_writel(OSCCTRL32, value | SDC_BF(OSCCTRL32_KEY, 0x55));
+		sdc_writel(OSCCTRL32, value | SDC_BF(OSCCTRL32_KEY, 0xaa));
+	}
+
+	pr_info("Waiting for 32 kHz crystal oscillator to start...\n");
+
+	while (!(pm_readl(POSCSR) & PM_BIT(POSCSR_OSC32RDY)))
+		cpu_relax();
+}
+
+static void oscn_mode(struct clk *clk, int enabled)
+{
+	unsigned int	i = clk->index;
+	u32		mcctrl;
+
+	BUG_ON(i > 2);
+
+	/* Let's keep oscillators running for now... */
+	if (!enabled)
+		goto out;
+
+	/* If it's already running, we're done */
+	if (pm_readl(POSCSR) & (PM_BIT(POSCSR_OSC0RDY) << i))
+		goto out;
+
+	/* Enable it, unless someone did it for us already */
+	mcctrl = pm_readl(MCCTRL);
+	if (!(mcctrl & (PM_BIT(MCCTRL_OSC0EN) << i))) {
+		/* TODO: Make OSC startup parameters configurable */
+		pm_writel(OSCCTRL[i], PM_BF(OSCCTRLx_STARTUP, 5)
+				| PM_BF(OSCCTRLx_MODE, 0xa));
+		pm_writel(MCCTRL, mcctrl | (PM_BIT(MCCTRL_OSC0EN) << i));
+	}
+
+	pr_debug("clk %s: waiting for clock to become ready...\n", clk->name);
+	pr_debug("clk %s: MCCTRL=%08x OSCCTRL%u=%08x\n", clk->name,
+			pm_readl(MCCTRL), i, pm_readl(OSCCTRL[i]));
+
+	while (!(pm_readl(POSCSR) & (PM_BIT(POSCSR_OSC0RDY) << i)))
+		cpu_relax();
+
+out:
+	pr_debug("clk %s: running\n", clk->name);
+}
+
+static struct clk rcosc = {
+	.name		= "rcosc",
+	.get_rate	= rcosc_get_rate,
+	.users		= 1,
+};
+static struct clk osc0 = {
+	.name		= "osc0",
+	.get_rate	= osc_get_rate,
+	.mode		= oscn_mode,
+	.users		= 1,
+	.index		= 0,
+};
+static struct clk osc1 = {
+	.name		= "osc1",
+	.get_rate	= osc_get_rate,
+	.mode		= oscn_mode,
+	.index		= 1,
+};
+static struct clk osc2 = {
+	.name		= "osc2",
+	.get_rate	= osc_get_rate,
+	.mode		= oscn_mode,
+	.index		= 2,
+};
+static struct clk osc32 = {
+	.name		= "osc32k",
+	.get_rate	= osc_get_rate,
+	.mode		= osc32_mode,
+	.index		= 3,
+};
+
+static void pll_mode(struct clk *clk, int enabled)
+{
+	unsigned long timeout;
+	unsigned int index = clk->index;
+	u32 status;
+	u32 ctrl;
+
+	ctrl = pm_readl(PLL[index]);
+
+	if (enabled) {
+		if (PM_BFEXT(PLLx_PLLMUL, ctrl) <= 1) {
+			pr_debug("clk %s: failed to enable, rate not set\n",
+					clk->name);
+			return;
+		}
+
+		ctrl |= PM_BIT(PLLx_PLLEN);
+		pm_writel(PLL[index], ctrl);
+
+		pr_debug("clk %s: waiting for lock...\n", clk->name);
+		for (timeout = 10000; timeout; timeout--) {
+			status = pm_readl(POSCSR);
+			if (status & (PM_BIT(POSCSR_LOCK0) << index))
+				break;
+			udelay(10);
+		}
+
+		if (!(status & (PM_BIT(POSCSR_LOCK0) << index)))
+			pr_err("clk %s: timeout waiting for lock\n",
+					clk->name);
+		else
+			pr_debug("clk %s: running\n", clk->name);
+	} else {
+		ctrl &= ~PM_BIT(PLLx_PLLEN);
+		pm_writel(PLL[index], ctrl);
+		pr_debug("clk %s: stopped\n", clk->name);
+	}
+}
+
+
+static unsigned long pll_get_rate(struct clk *clk)
+{
+	unsigned long rate;
+	unsigned int div;
+	unsigned int mul;
+	u32 ctrl;
+
+	ctrl = pm_readl(PLL[clk->index]);
+
+	div = PM_BFEXT(PLLx_PLLDIV, ctrl);
+	mul = PM_BFEXT(PLLx_PLLMUL, ctrl);
+
+	rate = clk->parent->get_rate(clk->parent);
+	if (div != 0)
+		rate = (rate + div / 2) / div;
+	else
+		rate = rate * 2;
+	rate *= mul;
+
+	if (ctrl & PM_BF(PLLx_PLLOPT, 4))
+		rate = (rate + 1) / 2;
+
+	return rate;
+}
+
+static long pll_set_rate(struct clk *clk, unsigned long rate, int apply)
+{
+	unsigned long mul_best_fit = 0;
+	unsigned long div;
+	unsigned long div_min;
+	unsigned long div_max;
+	unsigned long div_best_fit = 0;
+	unsigned long base;
+	unsigned long fvco;
+	unsigned long actual = 0;
+	unsigned long rate_error_prev = ~0UL;
+	u32 ctrl;
+
+	/* Rate must be between 25 MHz and 400 Mhz. */
+	if (rate < 25000000UL || rate > 400000000UL)
+		return -EINVAL;
+
+	base = clk->parent->get_rate(clk->parent);
+
+	/* PLL input frequency must be between 10 MHz and 200 MHz. */
+	div_min = DIV_ROUND_UP(base, 200000000UL);
+	div_max = base / 10000000UL;
+
+	if (div_max < div_min)
+		return -EINVAL;
+
+	for (div = div_min; div <= div_max; div++) {
+		unsigned long mul;
+		unsigned long pll_in;
+		unsigned long rate_error;
+
+		pll_in = (base + div / 2) / div;
+		mul = (rate + pll_in / 2) / pll_in;
+
+		if (mul < 1)
+			continue;
+
+		actual = pll_in * mul;
+		rate_error = abs(actual - rate);
+
+		if (rate_error < rate_error_prev) {
+			mul_best_fit = mul;
+			div_best_fit = div;
+			rate_error_prev = rate_error;
+		}
+
+		if (rate_error == 0)
+			break;
+	}
+
+	if (div_best_fit == 0)
+		return -EINVAL;
+
+	ctrl = 0;
+	fvco = actual;
+
+	/*
+	 * MUL=1 is not allowed. So we must double it and set the
+	 * divide-by-two bit.
+	 */
+	if (mul_best_fit == 1) {
+		ctrl |= PM_BF(PLLx_PLLOPT, 4);
+		mul_best_fit *= 2;
+		fvco = actual * 2;
+	}
+
+	if (fvco > 200000000)
+		ctrl |= PM_BF(PLLx_PLLOPT, 3);
+	else if (fvco > 100000000)
+		ctrl |= PM_BF(PLLx_PLLOPT, 2);
+	else if (fvco > 50000000)
+		ctrl |= PM_BF(PLLx_PLLOPT, 1);
+
+	ctrl |= PM_BF(PLLx_PLLCOUNT, 31);
+	ctrl |= PM_BF(PLLx_PLLMUL, mul_best_fit);
+	ctrl |= PM_BF(PLLx_PLLDIV, div_best_fit);
+	ctrl |= PM_BF(PLLx_PLLOSC, clk->parent->index);
+
+	if (apply) {
+		if (actual != rate)
+			return -EINVAL;
+		if (clk->users > 0)
+			return -EBUSY;
+		pr_debug(KERN_INFO "clk %s: new rate %lu (actual rate %lu)\n",
+				clk->name, rate, actual);
+		pm_writel(PLL[clk->index], ctrl);
+	}
+
+	return actual;
+}
+
+static int pll_set_parent(struct clk *clk, struct clk *parent)
+{
+	unsigned int index = clk->index;
+	u32 ctrl;
+
+	if (clk->users > 0)
+		return -EBUSY;
+
+	ctrl = pm_readl(PLL[index]);
+	BUG_ON(ctrl & PM_BIT(PLLx_PLLEN));
+
+	ctrl = PM_BFINS(PLLx_PLLOSC, parent->index, ctrl);
+	pm_writel(PLL[index], ctrl);
+
+	clk->parent = parent;
+
+	return 0;
+}
+
+static struct clk pll0 = {
+	.name		= "pll0",
+	.mode		= pll_mode,
+	.get_rate	= pll_get_rate,
+	.set_rate	= pll_set_rate,
+	.set_parent	= pll_set_parent,
+	.users		= 1,
+	.index		= 0,
+};
+static struct clk pll1 = {
+	.name		= "pll1",
+	.mode		= pll_mode,
+	.get_rate	= pll_get_rate,
+	.set_rate	= pll_set_rate,
+	.set_parent	= pll_set_parent,
+	.users		= 0,
+	.index		= 1,
+};
+static struct clk pll2 = {
+	.name		= "pll2",
+	.mode		= pll_mode,
+	.get_rate	= pll_get_rate,
+	.set_rate	= pll_set_rate,
+	.set_parent	= pll_set_parent,
+	.users		= 0,
+	.index		= 2,
+};
+
+/*
+ * The main clock can be either rcosc, osc0 or pll0.  The boot loader
+ * may have chosen one for us, so we don't really know which one until
+ * we have a look at the PM registers.
+ */
+static struct clk *main_clock;
+
+/*
+ * Synchronous clocks are generated from the main clock. The clocks
+ * must satisfy the constraint
+ *   fCPU >= fHSB >= fPB
+ * i.e. each clock must not be faster than its parent.
+ */
+static unsigned long bus_clk_get_rate(struct clk *clk, unsigned int shift)
+{
+	return main_clock->get_rate(main_clock) >> shift;
+};
+
+static void cpu_clk_mode(struct clk *clk, int enabled)
+{
+	unsigned long flags;
+	u32 mask;
+
+	spin_lock_irqsave(&pm_lock, flags);
+
+	while (!(pm_readl(POSCSR) & PM_BIT(POSCSR_MSKRDY)))
+		cpu_relax();
+
+	mask = pm_readl(CPUMASK);
+	if (enabled)
+		mask |= 1 << clk->index;
+	else
+		mask &= ~(1 << clk->index);
+	pm_writel(CPUMASK, mask);
+	spin_unlock_irqrestore(&pm_lock, flags);
+}
+
+static unsigned long cpu_clk_get_rate(struct clk *clk)
+{
+	unsigned long cksel, shift = 0;
+
+	cksel = pm_readl(CKSEL);
+	if (cksel & PM_BIT(CKSEL_CPUDIV))
+		shift = PM_BFEXT(CKSEL_CPUSEL, cksel) + 1;
+
+	return bus_clk_get_rate(clk, shift);
+}
+
+static long cpu_clk_set_rate(struct clk *clk, unsigned long rate, int apply)
+{
+	u32 control;
+	unsigned long parent_rate, child_div, actual_rate, div;
+
+	parent_rate = clk->parent->get_rate(clk->parent);
+	control = pm_readl(CKSEL);
+
+	if (control & PM_BIT(CKSEL_HSBDIV))
+		child_div = 1 << (PM_BFEXT(CKSEL_HSBSEL, control) + 1);
+	else
+		child_div = 1;
+
+	if (rate > 3 * (parent_rate / 4) || child_div == 1) {
+		actual_rate = parent_rate;
+		control &= ~PM_BIT(CKSEL_CPUDIV);
+	} else {
+		unsigned int cpusel;
+		div = (parent_rate + rate / 2) / rate;
+		if (div > child_div)
+			div = child_div;
+		cpusel = (div > 1) ? (fls(div) - 2) : 0;
+		control = PM_BIT(CKSEL_CPUDIV)
+			| PM_BFINS(CKSEL_CPUSEL, cpusel, control);
+		actual_rate = parent_rate / (1 << (cpusel + 1));
+	}
+
+	pr_debug("clk %s: new rate %lu (actual rate %lu)\n",
+			clk->name, rate, actual_rate);
+
+	if (apply) {
+		while (!(pm_readl(POSCSR) & PM_BIT(POSCSR_CKRDY)))
+			cpu_relax();
+
+		pm_writel(CKSEL, control);
+	}
+
+	return actual_rate;
+}
+
+static void hsb_clk_mode(struct clk *clk, int enabled)
+{
+	unsigned long flags;
+	u32 mask;
+
+	spin_lock_irqsave(&pm_lock, flags);
+
+	while (!(pm_readl(POSCSR) & PM_BIT(POSCSR_MSKRDY)))
+		cpu_relax();
+
+	mask = pm_readl(HSBMASK);
+	if (enabled)
+		mask |= 1 << clk->index;
+	else
+		mask &= ~(1 << clk->index);
+	pm_writel(HSBMASK, mask);
+	spin_unlock_irqrestore(&pm_lock, flags);
+}
+
+static unsigned long hsb_clk_get_rate(struct clk *clk)
+{
+	unsigned long cksel, shift = 0;
+
+	cksel = pm_readl(CKSEL);
+	if (cksel & PM_BIT(CKSEL_HSBDIV))
+		shift = PM_BFEXT(CKSEL_HSBSEL, cksel) + 1;
+
+	return bus_clk_get_rate(clk, shift);
+}
+
+static void pba_clk_mode(struct clk *clk, int enabled)
+{
+	unsigned long flags;
+	u32 mask;
+
+	spin_lock_irqsave(&pm_lock, flags);
+
+	while (!(pm_readl(POSCSR) & PM_BIT(POSCSR_MSKRDY)))
+		cpu_relax();
+
+	mask = pm_readl(PBAMASK);
+	if (enabled)
+		mask |= 1 << clk->index;
+	else
+		mask &= ~(1 << clk->index);
+	pm_writel(PBAMASK, mask);
+	spin_unlock_irqrestore(&pm_lock, flags);
+}
+
+static unsigned long pba_clk_get_rate(struct clk *clk)
+{
+	unsigned long cksel, shift = 0;
+
+	cksel = pm_readl(CKSEL);
+	if (cksel & PM_BIT(CKSEL_PBADIV))
+		shift = PM_BFEXT(CKSEL_PBASEL, cksel) + 1;
+
+	return bus_clk_get_rate(clk, shift);
+}
+
+static void pbb_clk_mode(struct clk *clk, int enabled)
+{
+	unsigned long flags;
+	u32 mask;
+
+	spin_lock_irqsave(&pm_lock, flags);
+
+	while (!(pm_readl(POSCSR) & PM_BIT(POSCSR_MSKRDY)))
+		cpu_relax();
+
+	mask = pm_readl(PBBMASK);
+	if (enabled)
+		mask |= 1 << clk->index;
+	else
+		mask &= ~(1 << clk->index);
+	pm_writel(PBBMASK, mask);
+	spin_unlock_irqrestore(&pm_lock, flags);
+}
+
+static unsigned long pbb_clk_get_rate(struct clk *clk)
+{
+	unsigned long cksel, shift = 0;
+
+	cksel = pm_readl(CKSEL);
+	if (cksel & PM_BIT(CKSEL_PBBDIV))
+		shift = PM_BFEXT(CKSEL_PBBSEL, cksel) + 1;
+
+	return bus_clk_get_rate(clk, shift);
+}
+
+static struct clk cpu_clk = {
+	.name		= "cpu",
+	.get_rate	= cpu_clk_get_rate,
+	.set_rate	= cpu_clk_set_rate,
+	.users		= 1,
+};
+static struct clk hsb_clk = {
+	.name		= "hsb",
+	.parent		= &cpu_clk,
+	.get_rate	= hsb_clk_get_rate,
+};
+static struct clk pba_clk = {
+	.name		= "pba",
+	.parent		= &hsb_clk,
+	.mode		= hsb_clk_mode,
+	.get_rate	= pba_clk_get_rate,
+	.users		= 1,
+	.index		= 1,
+};
+static struct clk pbb_clk = {
+	.name		= "pbb",
+	.parent		= &hsb_clk,
+	.mode		= hsb_clk_mode,
+	.get_rate	= pbb_clk_get_rate,
+	.users		= 1,
+	.index		= 2,
+};
+static struct clk pbc_clk = {
+	.name		= "pbc",
+	.parent		= &hsb_clk,
+	.mode		= hsb_clk_mode,
+	.get_rate	= pbb_clk_get_rate,
+	.index		= 3,
+};
+
+/* --------------------------------------------------------------------
+ *  Generic Clocks
+ * -------------------------------------------------------------------- */
+
+/* Mapping from GCCTRL:OSCSEL values to parent clocks */
+static struct clk *const genclk_parent[] = {
+	&rcosc,
+	&osc32,
+	&osc0,
+	&osc1,
+	&osc2,
+	&pll0,
+	&pll1,
+	&pll2,
+	&cpu_clk,
+	&hsb_clk,
+	&pba_clk,
+	&pbb_clk,
+};
+
+#define NR_GENERIC_CLOCKS	8
+
+static void genclk_mode(struct clk *clk, int enabled)
+{
+	u32 control;
+
+	control = pm_readl(GCCTRL[clk->index]);
+	if (enabled)
+		control |= PM_BIT(GCCTRL_CEN);
+	else
+		control &= PM_BIT(GCCTRL_CEN);
+	pm_writel(GCCTRL[clk->index], control);
+}
+
+static unsigned long genclk_get_rate(struct clk *clk)
+{
+	u32 control;
+	unsigned long div = 1;
+
+	control = pm_readl(GCCTRL[clk->index]);
+	if (control & PM_BIT(GCCTRL_DIVEN))
+		div = 2 * (PM_BFEXT(GCCTRL_DIV, control) + 1);
+
+	return clk->parent->get_rate(clk->parent) / div;
+}
+
+static long genclk_set_rate(struct clk *clk, unsigned long rate, int apply)
+{
+	unsigned long	parent_rate;
+	unsigned long	actual_rate;
+	unsigned long	div;
+	u32		control;
+
+	parent_rate = clk->parent->get_rate(clk->parent);
+	control = pm_readl(GCCTRL[clk->index]);
+
+	if (rate > 3 * parent_rate / 4) {
+		actual_rate = parent_rate;
+		control &= ~PM_BIT(GCCTRL_DIVEN);
+	} else {
+		div = (parent_rate + rate) / (2 * rate) - 1;
+		control = PM_BFINS(GCCTRL_DIV, div, control)
+				| PM_BIT(GCCTRL_DIVEN);
+		actual_rate = parent_rate / (2 * (div + 1));
+	}
+
+	pr_debug("clk %s: new rate %lu (actual rate %lu)\n",
+			clk->name, rate, actual_rate);
+
+	if (apply)
+		pm_writel(GCCTRL[clk->index], control);
+
+	return actual_rate;
+}
+
+static int genclk_set_parent(struct clk *clk, struct clk *parent)
+{
+	unsigned int	i;
+	u32		control;
+
+	pr_debug("clk %s: new parent %s (was %s)\n",
+			clk->name, parent->name,
+			clk->parent ? clk->parent->name : "<none>");
+
+	control = pm_readl(GCCTRL[clk->index]);
+
+	for (i = 0; i < ARRAY_SIZE(genclk_parent); i++) {
+		if (parent == genclk_parent[i]) {
+			control = PM_BFINS(GCCTRL_OSCSEL, i, control);
+			break;
+		}
+	}
+
+	if (i >= ARRAY_SIZE(genclk_parent))
+		return -EINVAL;
+
+	pm_writel(GCCTRL[clk->index], control);
+	clk->parent = parent;
+
+	return 0;
+}
+
+#define DEFINE_GCLK(_name, i)				\
+	static struct clk _name = {			\
+		.name		= #_name,		\
+		.mode		= genclk_mode,		\
+		.get_rate	= genclk_get_rate,	\
+		.set_rate	= genclk_set_rate,	\
+		.set_parent	= genclk_set_parent,	\
+		.index		= i,			\
+	}
+
+DEFINE_GCLK(gclk0, 0);
+DEFINE_GCLK(gclk1, 1);
+DEFINE_GCLK(gclk2, 2);
+DEFINE_GCLK(gclk3, 3);
+DEFINE_GCLK(gclk4, 4);
+DEFINE_GCLK(gclk5, 5);
+
+static void __init genclk_init_parent(struct clk *clk)
+{
+	unsigned int	parent;
+	u32		control;
+
+	BUG_ON(clk->index > NR_GENERIC_CLOCKS);
+
+	control = pm_readl(GCCTRL[clk->index]);
+	parent = PM_BFEXT(GCCTRL_OSCSEL, control);
+	if (parent >= ARRAY_SIZE(genclk_parent)) {
+		/* Current parent is invalid. Reset to a sane value */
+		parent = 0;
+		control = PM_BF(GCCTRL_OSCSEL, parent);
+	}
+
+	clk->parent = genclk_parent[parent];
+}
+
+
+/* --------------------------------------------------------------------
+ *  System peripherals
+ * -------------------------------------------------------------------- */
+static struct dw_dma_platform_data dw_dmac0_data = {
+	.nr_channels	= 4,
+};
+static struct pdca_pdata pdca_data = {
+	.nr_channels	= 20,
+};
+
+static struct resource intc_resource[] = {
+	PBMEM(0xffd00000),
+};
+static struct resource pm_resource[] = {
+	PBMEM(0xffd00400),
+	IRQ(10),
+};
+static struct resource sdc_resource[] = {
+	PBMEM(0xffd00800),
+	IRQ(45),
+};
+static struct resource ast0_resource[] = {
+	PBMEM(0xffd00c00),
+	IRQ(11),
+};
+static struct resource ast1_resource[] = {
+	PBMEM(0xffd01000),
+	IRQ(12),
+};
+static struct resource wdt_resource[] = {
+	PBMEM(0xffd01400),
+};
+static struct resource gpio_resource[] = {
+	PBMEM(0xffd02000),
+	{
+		.start	= 16,
+		.end	= 19,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+static struct resource pdca_resource[] = {
+	{
+		.start	= 0xffe00000,
+		.end	= 0xffe01fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	IRQ(1),
+};
+static struct resource smc_resource[] = {
+	PBMEM(0xffe04400),
+};
+static struct resource dw_dmac0_resource[] = {
+	{
+		.start	= 0xff100000,
+		.end	= 0xff1003ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	IRQ(5),
+};
+
+struct platform_device at32_intc0_device = {
+	.name		= "intc",
+	.resource	= intc_resource,
+	.num_resources	= ARRAY_SIZE(intc_resource),
+};
+static struct platform_device pm_device = {
+	.name		= "pm",
+	.resource	= pm_resource,
+	.num_resources	= ARRAY_SIZE(pm_resource),
+};
+static struct platform_device sdc_device = {
+	.name		= "sdc",
+	.resource	= sdc_resource,
+	.num_resources	= ARRAY_SIZE(sdc_resource),
+};
+static struct platform_device ast0_device = {
+	.name		= "rtc-ast",
+	.id		= 0,
+	.resource	= ast0_resource,
+	.num_resources	= ARRAY_SIZE(ast0_resource),
+};
+static struct platform_device ast1_device = {
+	.name		= "timer-ast",
+	.id		= 1,
+	.resource	= ast1_resource,
+	.num_resources	= ARRAY_SIZE(ast1_resource),
+};
+static struct platform_device wdt_device = {
+	.name		= "at32_wdt",
+	.id		= 0,
+	.resource	= wdt_resource,
+	.num_resources	= ARRAY_SIZE(wdt_resource),
+};
+static struct platform_device gpio_device = {
+	.name		= "gpio",
+	.id		= 0,
+	.resource	= gpio_resource,
+	.num_resources	= ARRAY_SIZE(gpio_resource),
+};
+static struct platform_device pdca_device = {
+	.dev.platform_data = &pdca_data,
+	.name		= "atmel_pdca",
+	.id		= 0,
+	.resource	= pdca_resource,
+	.num_resources	= ARRAY_SIZE(pdca_resource),
+};
+static struct platform_device smc_device = {
+	.name		= "smc",
+	.id		= 0,
+	.resource	= smc_resource,
+	.num_resources	= ARRAY_SIZE(smc_resource),
+};
+static struct platform_device dw_dmac0_device = {
+	.dev.platform_data = &dw_dmac0_data,
+	.name		= "dw_dmac",
+	.id		= 0,
+	.resource	= dw_dmac0_resource,
+	.num_resources	= ARRAY_SIZE(dw_dmac0_resource),
+};
+
+DEV_CLK(pclk, at32_intc0, pba, 0);
+DEV_CLK(pclk, pm, pba, 1);
+DEV_CLK(pclk, sdc, pba, 2);
+DEV_CLK(pclk, ast0, pba, 3);
+DEV_CLK(pclk, ast1, pba, 4);
+DEV_CLK(pclk, wdt, pba, 5);
+DEV_CLK(pclk, gpio, pba, 8);
+DEV_CLK(hclk, pdca, hsb, 9);
+DEV_CLK(pclk, pdca, pbb, 0);
+DEV_CLK(pclk, smc, pbb, 5);
+DEV_CLK(hclk, dw_dmac0, hsb, 10);
+
+static struct clk ebi_hclk = {
+	.name		= "ebi_hclk",
+	.parent		= &hsb_clk,
+	.mode		= hsb_clk_mode,
+	.get_rate	= hsb_clk_get_rate,
+	.users		= 1,
+};
+static struct clk hramc_clk = {
+	.name		= "hramc",
+	.parent		= &hsb_clk,
+	.mode		= hsb_clk_mode,
+	.get_rate	= hsb_clk_get_rate,
+	.users		= 1,
+	.index		= 4,
+};
+static struct clk sdramc_clk = {
+	.name		= "sdramc_clk",
+	.parent		= &pbb_clk,
+	.mode		= pbb_clk_mode,
+	.get_rate	= pbb_clk_get_rate,
+	.users		= 1,
+	.index		= 6,
+};
+
+static int __init system_device_init(void)
+{
+	platform_device_register(&at32_intc0_device);
+	platform_device_register(&pm_device);
+	platform_device_register(&sdc_device);
+	platform_device_register(&ast0_device);
+	platform_device_register(&ast1_device);
+	platform_device_register(&wdt_device);
+	platform_device_register(&gpio_device);
+	platform_device_register(&pdca_device);
+	platform_device_register(&smc_device);
+	platform_device_register(&dw_dmac0_device);
+
+	return 0;
+}
+core_initcall(system_device_init);
+
+/* --------------------------------------------------------------------
+ * HMATRIX
+ * -------------------------------------------------------------------- */
+
+struct clk at32_hmatrix_clk = {
+	.name		= "hmatrix_clk",
+	.parent		= &pbb_clk,
+	.mode		= pbb_clk_mode,
+	.get_rate	= pbb_clk_get_rate,
+	.index		= 8,
+	.users		= 0,
+};
+
+/* --------------------------------------------------------------------
+ *  USART
+ * -------------------------------------------------------------------- */
+
+static struct atmel_uart_data atmel_usart0_data = {
+	.use_dma_tx	= 0,
+	.use_dma_rx	= 0,
+};
+static struct resource atmel_usart0_resource[] = {
+	PBMEM(0xffd03000),
+	IRQ(24),
+};
+static struct platform_device atmel_usart0_device = {
+	.name		= "atmel_usart",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &atmel_usart0_data,
+	},
+	.resource	= atmel_usart0_resource,
+	.num_resources	= ARRAY_SIZE(atmel_usart0_resource),
+};
+DEV_CLK(usart, atmel_usart0, pba, 9);
+
+static struct atmel_uart_data atmel_usart1_data = {
+	.use_dma_tx	= 0,
+	.use_dma_rx	= 0,
+};
+static struct resource atmel_usart1_resource[] = {
+	PBMEM(0xffd03400),
+	IRQ(25),
+};
+static struct platform_device atmel_usart1_device = {
+	.name		= "atmel_usart",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &atmel_usart1_data,
+	},
+	.resource	= atmel_usart1_resource,
+	.num_resources	= ARRAY_SIZE(atmel_usart1_resource),
+};
+DEV_CLK(usart, atmel_usart1, pba, 10);
+
+static struct atmel_uart_data atmel_usart2_data = {
+	.use_dma_tx	= 0,
+	.use_dma_rx	= 0,
+};
+static struct resource atmel_usart2_resource[] = {
+	PBMEM(0xffd03800),
+	IRQ(26),
+};
+static struct platform_device atmel_usart2_device = {
+	.name		= "atmel_usart",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &atmel_usart2_data,
+	},
+	.resource	= atmel_usart2_resource,
+	.num_resources	= ARRAY_SIZE(atmel_usart2_resource),
+};
+DEV_CLK(usart, atmel_usart2, pba, 11);
+
+static struct atmel_uart_data atmel_usart3_data = {
+	.use_dma_tx	= 0,
+	.use_dma_rx	= 0,
+};
+static struct resource atmel_usart3_resource[] = {
+	PBMEM(0xffd03c00),
+	IRQ(27),
+};
+static struct platform_device atmel_usart3_device = {
+	.name		= "atmel_usart",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &atmel_usart3_data,
+	},
+	.resource	= atmel_usart3_resource,
+	.num_resources	= ARRAY_SIZE(atmel_usart3_resource),
+};
+DEV_CLK(usart, atmel_usart3, pba, 12);
+
+static struct atmel_uart_data atmel_usart4_data = {
+	.use_dma_tx	= 0,
+	.use_dma_rx	= 0,
+};
+static struct resource atmel_usart4_resource[] = {
+	PBMEM(0xffd04000),
+	IRQ(28),
+};
+static struct platform_device atmel_usart4_device = {
+	.name		= "atmel_usart",
+	.id		= 4,
+	.dev		= {
+		.platform_data	= &atmel_usart4_data,
+	},
+	.resource	= atmel_usart4_resource,
+	.num_resources	= ARRAY_SIZE(atmel_usart4_resource),
+};
+DEV_CLK(usart, atmel_usart4, pba, 13);
+
+static struct atmel_uart_data atmel_usart5_data = {
+	.use_dma_tx	= 0,
+	.use_dma_rx	= 0,
+};
+static struct resource atmel_usart5_resource[] = {
+	PBMEM(0xffd04400),
+	IRQ(29),
+};
+static struct platform_device atmel_usart5_device = {
+	.name		= "atmel_usart",
+	.id		= 5,
+	.dev		= {
+		.platform_data	= &atmel_usart5_data,
+	},
+	.resource	= atmel_usart5_resource,
+	.num_resources	= ARRAY_SIZE(atmel_usart5_resource),
+};
+DEV_CLK(usart, atmel_usart5, pba, 14);
+
+static void __init configure_usart0_pins(void)
+{
+	/* RXD | TXD */
+	select_peripheral(PB, (1 << 14) | (1 << 15), PERIPH_B, 0);
+}
+
+static void __init configure_usart1_pins(void)
+{
+	/* TXD | RXD */
+	select_peripheral(PA, (1 << 8) | (1 << 9), PERIPH_A, 0);
+}
+
+static void __init configure_usart2_pins(void)
+{
+	/* TXD | RXD */
+	select_peripheral(PA, (1 << 16) | (1 << 17), PERIPH_A, 0);
+}
+
+static void __init configure_usart3_pins(void)
+{
+	/* RXD | TXD */
+	select_peripheral(PC, (1 << 10) | (1 << 11), PERIPH_A, 0);
+}
+
+static void __init configure_usart4_pins(void)
+{
+	/* TXD | RXD */
+	select_peripheral(PA, (1 << 14) | (1 << 15), PERIPH_A, 0);
+}
+
+static void __init configure_usart5_pins(void)
+{
+	/* RXD | TXD */
+	select_peripheral(PA, (1 << 22) | (1 << 23), PERIPH_A, 0);
+}
+
+static struct platform_device *__initdata at32_usarts[6];
+
+void __init at32_map_usart(unsigned int hw_id, unsigned int line)
+{
+	struct platform_device *pdev;
+
+	switch (hw_id) {
+	case 0:
+		pdev = &atmel_usart0_device;
+		configure_usart0_pins();
+		break;
+	case 1:
+		pdev = &atmel_usart1_device;
+		configure_usart1_pins();
+		break;
+	case 2:
+		pdev = &atmel_usart2_device;
+		configure_usart2_pins();
+		break;
+	case 3:
+		pdev = &atmel_usart3_device;
+		configure_usart3_pins();
+		break;
+	case 4:
+		pdev = &atmel_usart4_device;
+		configure_usart4_pins();
+		break;
+	case 5:
+		pdev = &atmel_usart5_device;
+		configure_usart5_pins();
+		break;
+	default:
+		return;
+	}
+
+	if (PXSEG(pdev->resource[0].start) == P4SEG) {
+		/* Addresses in the P4 segment are permanently mapped 1:1 */
+		struct atmel_uart_data *data = pdev->dev.platform_data;
+		data->regs = (void __iomem __force *)pdev->resource[0].start;
+	}
+
+	pdev->id = line;
+	at32_usarts[line] = pdev;
+}
+
+struct platform_device *__init at32_add_device_usart(unsigned int id)
+{
+	platform_device_register(at32_usarts[id]);
+	return at32_usarts[id];
+}
+
+struct platform_device *atmel_default_console_device;
+
+void __init at32_setup_serial_console(unsigned int usart_id)
+{
+	atmel_default_console_device = at32_usarts[usart_id];
+}
+
+/* --------------------------------------------------------------------
+ *  Ethernet
+ * -------------------------------------------------------------------- */
+
+static u64 macb0_dma_mask = DMA_32BIT_MASK;
+static struct resource macb0_resource[] __initdata = {
+	PBMEM(0xffe04000),
+	IRQ(8),
+};
+static struct clk macb0_hclk = {
+	.name		= "hclk",
+	.parent		= &hsb_clk,
+	.mode		= hsb_clk_mode,
+	.get_rate	= hsb_clk_get_rate,
+	.index		= 8,
+};
+static struct clk macb0_pclk = {
+	.name		= "pclk",
+	.parent		= &pbb_clk,
+	.mode		= pbb_clk_mode,
+	.get_rate	= pbb_clk_get_rate,
+	.index		= 4,
+};
+
+struct platform_device *__init
+at32_add_device_eth(unsigned int id, struct eth_platform_data *data)
+{
+	struct platform_device *pdev;
+	u32 pin_mask_a;
+	u32 pin_mask_c;
+
+	if (id != 0 || !data)
+		return NULL;
+
+	pdev = platform_device_alloc("macb", id);
+	if (!pdev)
+		return NULL;
+
+	if (platform_device_add_resources(pdev, macb0_resource,
+				ARRAY_SIZE(macb0_resource)))
+		goto out_free_pdev;
+
+	if (platform_device_add_data(pdev, data,
+				sizeof(struct eth_platform_data)))
+		goto out_free_pdev;
+
+	pin_mask_a  = (1 << 4);  /* RXDV */
+	pin_mask_c  = (1 << 10); /* MDC  */
+	pin_mask_c |= (1 << 11); /* MDIO */
+	pin_mask_c |= (1 << 12); /* TXCK */
+	pin_mask_c |= (1 << 14); /* RXD0 */
+	pin_mask_c |= (1 << 15); /* RXD1 */
+	pin_mask_c |= (1 << 16); /* RXER */
+	pin_mask_c |= (1 << 18); /* TXEN */
+	pin_mask_c |= (1 << 19); /* TXD0 */
+	pin_mask_c |= (1 << 20); /* TXD1 */
+
+	if (!data->is_rmii) {
+		pin_mask_a |= (1<<0);  /* COL  */
+		pin_mask_a |= (1<<1);  /* RXD2 */
+		pin_mask_a |= (1<<2);  /* RXD3 */
+		pin_mask_a |= (1<<3);  /* RXCK */
+		pin_mask_a |= (1<<5);  /* TXER */
+		pin_mask_a |= (1<<6);  /* TXD2 */
+		pin_mask_a |= (1<<7);  /* TXD3 */
+		pin_mask_c |= (1<<13); /* CRS  */
+		pin_mask_c |= (1<<17); /* SPD  */
+	}
+
+	select_peripheral(PA, pin_mask_a, PERIPH_B, 0);
+	select_peripheral(PC, pin_mask_c, PERIPH_C, 0);
+
+	pdev->dev.dma_mask = &macb0_dma_mask;
+	pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+
+	macb0_hclk.dev = &pdev->dev;
+	macb0_pclk.dev = &pdev->dev;
+
+	platform_device_add(pdev);
+
+	return pdev;
+
+out_free_pdev:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* --------------------------------------------------------------------
+ * SPI
+ * -------------------------------------------------------------------- */
+static struct resource atmel_spi_resource[][2] __initdata = {
+	{
+		PBMEM(0xffe05400),
+		IRQ(36),
+	}, {
+		PBMEM(0xffe05800),
+		IRQ(37),
+	}, {
+		PBMEM(0xffe05c00),
+		IRQ(38),
+	}, {
+		PBMEM(0xffe06000),
+		IRQ(39),
+	}
+};
+static struct clk atmel_spi_clk[] = {
+	{
+		.name		= "spi_clk",
+		.parent		= &pbb_clk,
+		.mode		= pbb_clk_mode,
+		.get_rate	= pbb_clk_get_rate,
+		.index		= 9,
+	}, {
+		.name		= "spi_clk",
+		.parent		= &pbb_clk,
+		.mode		= pbb_clk_mode,
+		.get_rate	= pbb_clk_get_rate,
+		.index		= 10,
+	}, {
+		.name		= "spi_clk",
+		.parent		= &pbb_clk,
+		.mode		= pbb_clk_mode,
+		.get_rate	= pbb_clk_get_rate,
+		.index		= 11,
+	}, {
+		.name		= "spi_clk",
+		.parent		= &pbb_clk,
+		.mode		= pbb_clk_mode,
+		.get_rate	= pbb_clk_get_rate,
+		.index		= 12,
+	}
+};
+static int __initdata atmel_spi_pins[][4] = {
+	{
+		/* SPI0 */
+		GPIO_PIN_PB(3), GPIO_PIN_PB(4),
+		GPIO_PIN_PB(5), GPIO_PIN_PB(6),
+	}, {
+		/* SPI1 */
+		GPIO_PIN_PB(4), -1, -1, -1,
+	}, {
+		/* SPI2 */
+		GPIO_PIN_PA(28), -1, -1, -1,
+	}, {
+		/* SPI3 */
+		GPIO_PIN_PA(27), GPIO_PIN_PA(20),
+		GPIO_PIN_PA(29), GPIO_PIN_PA(30),
+	}
+};
+
+
+static void __init at32_spi_setup_dw_dma(unsigned int id,
+		struct atmel_spi_pdata *pdata)
+{
+	struct dw_dma_slave	*rx_dws;
+	struct dw_dma_slave	*tx_dws;
+
+	if (pdata->rx_dma_slave)
+		rx_dws = kmemdup(to_dw_dma_slave(pdata->rx_dma_slave),
+				sizeof(struct dw_dma_slave), GFP_KERNEL);
+	else
+		rx_dws = kzalloc(sizeof(struct dw_dma_slave), GFP_KERNEL);
+	if (pdata->tx_dma_slave)
+		tx_dws = kmemdup(to_dw_dma_slave(pdata->tx_dma_slave),
+				sizeof(struct dw_dma_slave), GFP_KERNEL);
+	else
+		tx_dws = kzalloc(sizeof(struct dw_dma_slave), GFP_KERNEL);
+
+	rx_dws->slave.dma_dev = tx_dws->slave.dma_dev = &dw_dmac0_device.dev;
+	rx_dws->slave.reg_width = tx_dws->slave.reg_width
+		= DMA_SLAVE_WIDTH_8BIT;
+
+	rx_dws->cfg_hi = DWC_CFGH_SRC_PER(2);
+	tx_dws->cfg_hi = DWC_CFGH_DST_PER(3);
+	rx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL
+				| DWC_CFGL_HS_SRC_POL);
+	tx_dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL
+				| DWC_CFGL_HS_SRC_POL);
+
+	pdata->rx_dma_slave = &rx_dws->slave;
+	pdata->tx_dma_slave = &tx_dws->slave;
+}
+
+static void __init at32_spi_setup_pdca(unsigned int id,
+		struct atmel_spi_pdata *pdata)
+{
+	struct pdca_slave	*rx_pslave;
+	struct pdca_slave	*tx_pslave;
+
+	if (pdata->rx_dma_slave)
+		rx_pslave = kmemdup(dma_to_pdca_slave(pdata->rx_dma_slave),
+				sizeof(struct pdca_slave), GFP_KERNEL);
+	else
+		rx_pslave = kzalloc(sizeof(struct pdca_slave), GFP_KERNEL);
+	if (pdata->tx_dma_slave)
+		tx_pslave = kmemdup(dma_to_pdca_slave(pdata->tx_dma_slave),
+				sizeof(struct pdca_slave), GFP_KERNEL);
+	else
+		tx_pslave = kzalloc(sizeof(struct pdca_slave), GFP_KERNEL);
+
+	rx_pslave->slave.dma_dev = &pdca_device.dev;
+	tx_pslave->slave.dma_dev = &pdca_device.dev;
+	rx_pslave->slave.reg_width = DMA_SLAVE_WIDTH_8BIT;
+	tx_pslave->slave.reg_width = DMA_SLAVE_WIDTH_8BIT;
+
+	rx_pslave->tx_periph_id = -1;
+	tx_pslave->rx_periph_id = -1;
+
+	switch (id) {
+	case 1:
+		rx_pslave->rx_periph_id = 6;
+		tx_pslave->tx_periph_id = 17;
+		break;
+	case 2:
+		rx_pslave->rx_periph_id = 7;
+		tx_pslave->tx_periph_id = 18;
+		break;
+	case 3:
+		rx_pslave->rx_periph_id = 8;
+		tx_pslave->tx_periph_id = 19;
+		break;
+	}
+
+	pdata->rx_dma_slave = &rx_pslave->slave;
+	pdata->tx_dma_slave = &tx_pslave->slave;
+}
+
+static void __init
+at32_spi_setup_slaves(unsigned int bus_num, struct spi_board_info *b,
+		unsigned int n, const int *pins)
+{
+	unsigned int	mode;
+	unsigned int	cs;
+	int		pin;
+
+	for (; n; n--, b++) {
+		b->bus_num = bus_num;
+		cs = b->chip_select;
+		if (cs >= 4 || !gpio_is_valid(pins[cs]))
+			continue;
+
+		pin = (int)b->controller_data;
+		if (!pin || !gpio_is_valid(pin)) {
+			pin = pins[cs];
+			b->controller_data = (void *)pin;
+		}
+
+		mode = AT32_GPIOF_OUTPUT;
+		if (!(b->mode & SPI_CS_HIGH))
+			mode |= AT32_GPIOF_HIGH;
+		at32_select_gpio(pin, mode);
+	}
+}
+
+struct platform_device *__init at32_add_device_spi(unsigned int id,
+		struct spi_board_info *b, unsigned int n)
+{
+	struct atmel_spi_pdata	pdata;
+	struct platform_device	*pdev;
+
+	BUILD_BUG_ON(ARRAY_SIZE(atmel_spi_resource)
+			!= ARRAY_SIZE(atmel_spi_clk));
+
+	if (id >= ARRAY_SIZE(atmel_spi_resource))
+		return NULL;
+
+	pdev = platform_device_alloc("atmel_spi", id);
+	if (!pdev)
+		goto fail;
+
+	if (platform_device_add_resources(pdev, atmel_spi_resource[id],
+				ARRAY_SIZE(atmel_spi_resource[id])))
+		goto fail;
+
+	memset(&pdata, 0, sizeof(struct atmel_spi_pdata));
+
+	if (id == 0)
+		at32_spi_setup_dw_dma(id, &pdata);
+	else
+		at32_spi_setup_pdca(id, &pdata);
+	pdata.rx_dma_slave->dev = pdata.tx_dma_slave->dev = &pdev->dev;
+
+	if (platform_device_add_data(pdev, &pdata,
+				sizeof(struct atmel_spi_pdata)))
+		goto fail;
+
+	switch (id) {
+	case 0:
+		/* pullup MISO so a level is always defined */
+		select_peripheral(PB, (1 << 1), PERIPH_A, AT32_GPIOF_PULLUP);
+		/* MOSI | SCK */
+		select_peripheral(PB, (1 << 0) | (1 << 2), PERIPH_A, 0);
+
+		at32_spi_setup_slaves(0, b, n, atmel_spi_pins[0]);
+		break;
+
+	case 1:
+		/* pullup MISO so a level is always defined */
+		select_peripheral(PB, (1 << 7), PERIPH_B, AT32_GPIOF_PULLUP);
+		/* MOSI | SCK */
+		select_peripheral(PB, (1 << 6) | (1 << 5), PERIPH_B, 0);
+
+		at32_spi_setup_slaves(1, b, n, atmel_spi_pins[1]);
+		break;
+
+	case 2:
+		/* pullup MISO so a level is always defined */
+		select_peripheral(PA, (1 << 30), PERIPH_B, AT32_GPIOF_PULLUP);
+		/* MOSI | SCK */
+		select_peripheral(PA, (1 << 31) || (1 << 29), PERIPH_B, 0);
+
+		at32_spi_setup_slaves(2, b, n, atmel_spi_pins[2]);
+		break;
+
+	case 3:
+		/* pullup MISO so a level is always defined */
+		select_peripheral(PA, (1 << 25), PERIPH_A, AT32_GPIOF_PULLUP);
+		/* MOSI | SCK */
+		select_peripheral(PA, (1 << 24) | (1 << 26), PERIPH_A, 0);
+
+		at32_spi_setup_slaves(3, b, n, atmel_spi_pins[3]);
+		break;
+
+	default:
+		goto fail;
+	}
+
+	atmel_spi_clk[id].dev = &pdev->dev;
+	spi_register_board_info(b, n);
+	platform_device_add(pdev);
+
+	return pdev;
+
+fail:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* --------------------------------------------------------------------
+ * MMC
+ * -------------------------------------------------------------------- */
+static struct resource atmel_mci0_resource[] __initdata = {
+	PBMEM(0xfff00000),
+	IRQ(43),
+};
+/* MCI is on the PBC bus, but it is controlled by the PBBMASK register */
+static struct clk atmel_mci0_pclk = {
+	.name		= "mci_clk",
+	.parent		= &pbc_clk,
+	.mode		= pbb_clk_mode,
+	.get_rate	= pbb_clk_get_rate,
+	.index		= 16,
+};
+
+struct platform_device *__init
+at32_add_device_mci(unsigned int id, struct mci_platform_data *data)
+{
+	struct platform_device		*pdev;
+	struct dw_dma_slave		*dws;
+	u32 pin_mask_1 = 0;
+	u32 pin_mask_2 = 0;
+
+	if (id != 0)
+		return NULL;
+
+	/* Must have at least one usable slot */
+	if (!data->slot[0].bus_width && !data->slot[1].bus_width)
+		return NULL;
+
+	pdev = platform_device_alloc("atmel_mci", id);
+	if (!pdev)
+		goto fail;
+
+	if (platform_device_add_resources(pdev, atmel_mci0_resource,
+				ARRAY_SIZE(atmel_mci0_resource)))
+		goto fail;
+
+	if (data->dma_slave)
+		dws = kmemdup(to_dw_dma_slave(data->dma_slave),
+				sizeof(struct dw_dma_slave), GFP_KERNEL);
+	else
+		dws = kzalloc(sizeof(struct dw_dma_slave), GFP_KERNEL);
+
+	dws->slave.dev = &pdev->dev;
+	dws->slave.dma_dev = &dw_dmac0_device.dev;
+	dws->slave.reg_width = DMA_SLAVE_WIDTH_32BIT;
+	dws->cfg_hi = (DWC_CFGH_SRC_PER(0)
+				| DWC_CFGH_DST_PER(1));
+	dws->cfg_lo &= ~(DWC_CFGL_HS_DST_POL
+				| DWC_CFGL_HS_SRC_POL);
+
+	data->dma_slave = &dws->slave;
+
+	if (platform_device_add_data(pdev, data,
+				sizeof(struct mci_platform_data)))
+		goto fail;
+
+	switch (data->slot[0].bus_width) {
+	case 8:
+		pin_mask_1 |= (1 << 20); /* DATA4 */
+		pin_mask_1 |= (1 << 21); /* DATA5 */
+		pin_mask_1 |= (1 << 22); /* DATA6 */
+		pin_mask_1 |= (1 << 23); /* DATA7 */
+		/* fall through */
+	case 4:
+		pin_mask_2 |= (1 << 19); /* DATA1 */
+		pin_mask_2 |= (1 << 20); /* DATA2 */
+		pin_mask_2 |= (1 << 21); /* DATA3 */
+		/* fall through */
+	case 1:
+		pin_mask_2 |= (1 << 18); /* DATA0 */
+		pin_mask_2 |= (1 << 17); /* CMD   */
+
+		select_peripheral(PA, pin_mask_1, PERIPH_D, AT32_GPIOF_PULLUP);
+		select_peripheral(PB, pin_mask_2, PERIPH_A, AT32_GPIOF_PULLUP);
+		select_peripheral(PB, (1 << 16),  PERIPH_A, 0);	/* CLK */
+
+		if (gpio_is_valid(data->slot[0].detect_pin))
+			at32_select_gpio(data->slot[0].detect_pin, 0);
+		if (gpio_is_valid(data->slot[0].wp_pin))
+			at32_select_gpio(data->slot[0].wp_pin, 0);
+
+		break;
+	case 0:
+		/* Slot is unused */
+		break;
+	default:
+		goto fail;
+	}
+
+	pin_mask_1 = 0;
+
+	switch (data->slot[1].bus_width) {
+	case 8:
+		pin_mask_1 |= (1 << 9); /* DATA7 */
+		pin_mask_1 |= (1 << 8); /* DATA6 */
+		pin_mask_1 |= (1 << 7); /* DATA5 */
+		pin_mask_1 |= (1 << 6); /* DATA4 */
+		/* fall through */
+	case 4:
+		pin_mask_1 |= (1 << 5); /* DATA3 */
+		pin_mask_1 |= (1 << 4); /* DATA2 */
+		pin_mask_1 |= (1 << 3); /* DATA1 */
+		/* fall through */
+	case 1:
+		pin_mask_1 |= (1 << 2); /* DATA0 */
+		pin_mask_1 |= (1 << 1); /* CMD   */
+
+		select_peripheral(PC, pin_mask_1, PERIPH_A, AT32_GPIOF_PULLUP);
+		select_peripheral(PC, (1 << 0),   PERIPH_A, 0);	/* CLK */
+
+		if (gpio_is_valid(data->slot[1].detect_pin))
+			at32_select_gpio(data->slot[1].detect_pin, 0);
+		if (gpio_is_valid(data->slot[1].wp_pin))
+			at32_select_gpio(data->slot[1].wp_pin, 0);
+
+		break;
+	case 0:
+		/* Slot is unused */
+		break;
+	default:
+		goto fail;
+	}
+
+	atmel_mci0_pclk.dev = &pdev->dev;
+
+	platform_device_add(pdev);
+	return pdev;
+
+fail:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* --------------------------------------------------------------------
+ *  LCDC
+ * -------------------------------------------------------------------- */
+static u64 atmel_lcdfb0_dma_mask = DMA_32BIT_MASK;
+static struct resource atmel_lcdfb0_resource[] __initdata = {
+	{
+		.start	= 0xff000000,
+		.end	= 0xff000fff,
+		.flags	= IORESOURCE_MEM,
+	},
+	IRQ(3),
+	{
+		/* Placeholder for pre-allocated fb memory */
+		.start	= 0x00000000,
+		.end	= 0x00000000,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct clk atmel_lcdfb0_hck1 = {
+	.name		= "hck1",
+	.parent		= &hsb_clk,
+	.mode		= hsb_clk_mode,
+	.get_rate	= hsb_clk_get_rate,
+	.index		= 7,
+};
+static struct clk atmel_lcdfb0_pixclk = {
+	.name		= "lcdc_clk",
+	.mode		= genclk_mode,
+	.get_rate	= genclk_get_rate,
+	.set_rate	= genclk_set_rate,
+	.set_parent	= genclk_set_parent,
+	.index		= 6,
+};
+
+struct platform_device *__init
+at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data,
+		unsigned long fbmem_start, unsigned long fbmem_len,
+		u64 pin_mask)
+{
+	struct {
+		struct atmel_lcdfb_info	info;
+		struct fb_monspecs	monspecs;
+		struct fb_videomode	modedb[0];
+	} *all_data;
+	struct platform_device	*pdev;
+	unsigned int		data_size;
+	unsigned int		modedb_size;
+	unsigned int		num_resources;
+	int			ret;
+
+	if (id > 0 || !data)
+		return NULL;
+
+	pdev = platform_device_alloc("atmel_lcdfb", id);
+	if (!pdev)
+		return NULL;
+
+	num_resources = ARRAY_SIZE(atmel_lcdfb0_resource);
+	if (fbmem_len) {
+		atmel_lcdfb0_resource[num_resources - 1].start = fbmem_start;
+		atmel_lcdfb0_resource[num_resources - 1].end
+			= fbmem_start + fbmem_len - 1;
+	} else {
+		num_resources--;
+	}
+
+	if (platform_device_add_resources(pdev, atmel_lcdfb0_resource,
+				num_resources))
+		goto error;
+
+	/*
+	 * Allocate all data -- info struct, monspecs and modedb -- in
+	 * a single chunk.
+	 */
+	modedb_size = data->default_monspecs->modedb_len
+			* sizeof(struct fb_videomode);
+	data_size = sizeof(*all_data) + modedb_size;
+	all_data = kmalloc(data_size, GFP_KERNEL);
+	if (!all_data)
+		goto error;
+
+	memcpy(&all_data->info, data, sizeof(struct atmel_lcdfb_info));
+	memcpy(&all_data->monspecs, data->default_monspecs,
+			sizeof(struct fb_monspecs));
+	memcpy(&all_data->modedb, data->default_monspecs->modedb, modedb_size);
+
+	ret = platform_device_add_data(pdev, all_data, data_size);
+	kfree(all_data);
+	if (ret)
+		goto error;
+
+	/*
+	 * Update internal pointers to use memory allocated by
+	 * platform_device_add_data().
+	 */
+	all_data = pdev->dev.platform_data;
+	all_data->info.default_monspecs = &all_data->monspecs;
+	all_data->monspecs.modedb = all_data->modedb;
+
+	select_peripheral(PD, 0x7fffffff,  PERIPH_A, 0);
+
+	pdev->dev.dma_mask = &atmel_lcdfb0_dma_mask;
+	pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+
+	atmel_lcdfb0_hck1.dev = &pdev->dev;
+	atmel_lcdfb0_pixclk.dev = &pdev->dev;
+
+	clk_set_parent(&atmel_lcdfb0_pixclk, &pll0);
+	clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0));
+
+	platform_device_add(pdev);
+	return pdev;
+
+error:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* --------------------------------------------------------------------
+ *  Media Post-Processor (MPOP)
+ * -------------------------------------------------------------------- */
+
+static u64 atmel_mpopfb0_dma_mask = DMA_32BIT_MASK;
+static struct resource atmel_mpopfb0_resource[] = {
+	{
+		/* Configuration interface */
+		.start	= 0xffe02000,
+		.end	= 0xffe02fff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		/* Data interface (output) */
+		.start	= 0xf0000000,
+		.end	= 0xf0ffffff,
+		.flags	= IORESOURCE_MEM,
+	},
+	IRQ(4),
+	{
+		/* Placeholder for pre-allocated fb memory */
+		.start	= 0x00000000,
+		.end	= 0x00000000,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct clk atmel_mpopfb0_hclk = {
+	.name		= "hclk",
+	.parent		= &hsb_clk,
+	.mode		= hsb_clk_mode,
+	.get_rate	= hsb_clk_get_rate,
+	.index		= 12,
+};
+static struct clk atmel_mpopfb0_pclk = {
+	.name		= "pclk",
+	.parent		= &pbb_clk,
+	.mode		= pbb_clk_mode,
+	.get_rate	= pbb_clk_get_rate,
+	.index		= 2,
+};
+
+struct platform_device *__init at32_add_device_mpop(unsigned int id,
+		struct platform_device *lcdc_pdev,
+		unsigned long fbmem_start, unsigned long fbmem_len)
+{
+	struct platform_device		*pdev;
+	struct atmel_mpopfb_info	info;
+	unsigned int			num_resources;
+
+	if (id != 0)
+		return NULL;
+
+	pdev = platform_device_alloc("atmel_mpopfb", id);
+	if (!pdev)
+		return NULL;
+
+	num_resources = ARRAY_SIZE(atmel_mpopfb0_resource);
+	if (fbmem_len) {
+		atmel_mpopfb0_resource[num_resources - 1].start = fbmem_start;
+		atmel_mpopfb0_resource[num_resources - 1].end
+			= fbmem_start + fbmem_len - 1;
+	} else {
+		num_resources--;
+	}
+	if (platform_device_add_resources(pdev, atmel_mpopfb0_resource,
+				num_resources))
+		goto error;
+
+	info.lcdc_pdev = lcdc_pdev;
+	if (platform_device_add_data(pdev, &info, sizeof(info)))
+		goto error;
+
+	pdev->dev.dma_mask = &atmel_mpopfb0_dma_mask;
+	pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+
+	atmel_mpopfb0_hclk.dev = &pdev->dev;
+	atmel_mpopfb0_pclk.dev = &pdev->dev;
+
+	platform_device_add(pdev);
+	return pdev;
+
+error:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* -------------------------------------------------------------------
+ *  USB Host (OHCI/EHCI)
+ * ------------------------------------------------------------------- */
+
+static u64 usbh_dma_mask = DMA_32BIT_MASK;
+
+static unsigned long parent_clk_get_rate(struct clk *clk)
+{
+	return clk->parent->get_rate(clk->parent);
+}
+
+static void parent_clk_mode(struct clk *clk, int enabled)
+{
+	/* Parent clk enabled by clk core */
+}
+
+/*
+ * The UTMI clock is an internally controlled PLL. It is hardwired to
+ * OSC2 and will run at 30 MHz or 60 MHz depending on the internal
+ * UTMI <-> host controller data bus width.
+ *
+ * We can turn it on and off through the Power Manager. That's all.
+ */
+static void utmi_clk_mode(struct clk *clk, int enabled)
+{
+	u32 ppcr = pm_readl(PPCR);
+
+	if (enabled)
+		/* Clear UTMI suspend signal */
+		ppcr |= PM_BIT(PPCR_UTMI_CTRL);
+	else
+		/* Set UTMI suspend signal */
+		ppcr &= ~PM_BIT(PPCR_UTMI_CTRL);
+
+	pm_writel(PPCR, ppcr | PM_BF(PPCR_KEY, 0x55));
+	pm_writel(PPCR, ppcr | PM_BF(PPCR_KEY, 0xaa));
+
+	if (enabled)
+		/* PLL startup time is 2.5 ms */
+		udelay(2500);
+}
+
+static unsigned long utmi_clk_get_rate(struct clk *clk)
+{
+	/*
+	 * Not sure about this, but I think the UTMI interface on
+	 * AP7200 is 16 bits wide, which means 30 MHz PHY clock.
+	 */
+	return 30000000;
+}
+
+static struct clk usbh_utmi_clk = {
+	.name		= "usbh_utmi_clk",
+	.parent		= &osc2,
+	.mode		= utmi_clk_mode,
+	.get_rate	= utmi_clk_get_rate,
+};
+
+static struct clk usbh_hclk = {
+	.name		= "usbh_hclk",
+	.parent		= &hsb_clk,
+	.mode		= hsb_clk_mode,
+	.get_rate	= hsb_clk_get_rate,
+	.index		= 6,
+};
+
+/*
+ * UTMI and HSB clocks are shared between OHCI and EHCI. These wrappers
+ * make sure both can use the clocks as if they had their own.
+ */
+static struct clk ohci_utmi_clk = {
+	.name		= "utmi_clk",
+	.parent		= &usbh_utmi_clk,
+	.mode		= parent_clk_mode,
+	.get_rate	= parent_clk_get_rate,
+};
+static struct clk ohci_hclk = {
+	.name		= "hclk",
+	.parent		= &usbh_hclk,
+	.mode		= parent_clk_mode,
+	.get_rate	= parent_clk_get_rate,
+};
+
+static struct clk ehci_utmi_clk = {
+	.name		= "utmi_clk",
+	.parent		= &usbh_utmi_clk,
+	.mode		= parent_clk_mode,
+	.get_rate	= parent_clk_get_rate,
+};
+static struct clk ehci_hclk = {
+	.name		= "hclk",
+	.parent		= &usbh_hclk,
+	.mode		= parent_clk_mode,
+	.get_rate	= parent_clk_get_rate,
+};
+
+/*
+ * The USBH needs both a 48 MHz and a 12 MHz clock, and the 12 MHz
+ * must be generated by dividing the 48 MHz clock. There's only one
+ * generic clock hooked up to the USBH which we must use to generate
+ * both.
+ *
+ * This can be done because GCLK0 generates an additional "divided
+ * clock", which is the normal clock output further divided by four
+ * (this is hardcoded, but not surprisingly, exactly what we need.)
+ *
+ * So we generate the clocks as follows:
+ *    OSC2 (12 MHz) -> PLL2 (48 MHz) --> GCLK0 undivided (48 MHz)
+ *                                   |-> GCLK0 divided (12 MHz)
+ *
+ * This clock is only used by the OHCI part of the controller, not the
+ * EHCI part.
+ */
+static struct clk ohci_gclk = {
+	.name		= "ohci_clk",
+	.parent		= &gclk0,
+	.mode		= parent_clk_mode,
+	.get_rate	= parent_clk_get_rate,
+};
+
+static struct resource usbh_ohci_resource[] __initdata = {
+	{
+		.start	= 0xff400000,
+		.end	= 0xff400400,
+		.flags	= IORESOURCE_MEM,
+	},
+	IRQ(7),
+};
+
+static struct resource usbh_ehci_resource[] __initdata = {
+	{
+		.start	= 0xff300000,
+		.end	= 0xff300400,
+		.flags	= IORESOURCE_MEM,
+	},
+	IRQ(7),
+};
+
+static void __init usbh_setup_pins(void)
+{
+	static bool already_done __initdata;
+
+	if (!already_done) {
+		already_done = true;
+		/* OC_EN_N | OC_FLAG_N */
+		select_peripheral(PA, (1 << 18) | (1 << 19), PERIPH_D, 0);
+	}
+}
+
+struct platform_device *__init at32_add_device_ohci(unsigned int id)
+{
+	struct platform_device *pdev;
+
+	if (id != 0)
+		return NULL;
+
+	pdev = platform_device_alloc("ohci", id);
+	if (!pdev)
+		goto error;
+
+	if (platform_device_add_resources(pdev, usbh_ohci_resource,
+				ARRAY_SIZE(usbh_ohci_resource)))
+		goto error;
+
+	pdev->dev.dma_mask = &usbh_dma_mask;
+	pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+
+	clk_set_parent(&pll2, &osc2);
+	if (clk_round_rate(&pll2, 48000000) != 48000000) {
+		pr_debug("USBH OHCI: Cannot generate 48 MHz clock\n");
+		goto error;
+	}
+	clk_set_rate(&pll2, 48000000);
+
+	clk_set_parent(&gclk0, &pll2);
+	clk_set_rate(&gclk0, 48000000);
+
+	ohci_utmi_clk.dev = &pdev->dev;
+	ohci_hclk.dev = &pdev->dev;
+	ohci_gclk.dev = &pdev->dev;
+
+	usbh_setup_pins();
+
+	platform_device_add(pdev);
+	return pdev;
+
+error:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+struct platform_device *__init at32_add_device_ehci(unsigned int id)
+{
+	struct platform_device *pdev;
+
+	if (id != 0)
+		return NULL;
+
+	pdev = platform_device_alloc("ehci", id);
+	if (!pdev)
+		goto error;
+
+	if (platform_device_add_resources(pdev, usbh_ehci_resource,
+				ARRAY_SIZE(usbh_ehci_resource)))
+		goto error;
+
+	pdev->dev.dma_mask = &usbh_dma_mask;
+	pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+
+	ehci_utmi_clk.dev = &pdev->dev;
+	ehci_hclk.dev = &pdev->dev;
+
+	usbh_setup_pins();
+
+	platform_device_add(pdev);
+	return pdev;
+
+error:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* -------------------------------------------------------------------
+ *  NAND Flash / SmartMedia
+ * ------------------------------------------------------------------- */
+static struct resource smc_cs3_resource[] __initdata = {
+	{
+		.start	= 0x24000000,
+		.end	= 0x27ffffff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= 0xffe04c00,
+		.end	= 0xffe04fff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+struct platform_device *__init
+at32_add_device_nand(unsigned int id, struct atmel_nand_data *data)
+{
+	struct platform_device *pdev;
+
+	if (id != 0 || !data)
+		return NULL;
+
+	pdev = platform_device_alloc("atmel_nand", id);
+	if (!pdev)
+		goto error;
+
+	if (platform_device_add_resources(pdev, smc_cs3_resource,
+				ARRAY_SIZE(smc_cs3_resource)))
+		goto error;
+
+	if (platform_device_add_data(pdev, data,
+				sizeof(struct atmel_nand_data)))
+		goto error;
+
+	hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_NAND_ENABLE);
+
+	/* NANDOE | NANDWE */
+	select_peripheral(PF, (1 << 0) | (1 << 1), PERIPH_A, 0);
+
+	if (gpio_is_valid(data->enable_pin))
+		at32_select_gpio(data->enable_pin,
+				AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
+	if (gpio_is_valid(data->det_pin))
+		at32_select_gpio(data->det_pin, 0);
+	if (gpio_is_valid(data->rdy_pin))
+		at32_select_gpio(data->rdy_pin, 0);
+
+	platform_device_add(pdev);
+	return pdev;
+
+error:
+	platform_device_put(pdev);
+	return NULL;
+}
+
+/* -------------------------------------------------------------------
+ * Clock list
+ * ------------------------------------------------------------------- */
+static __initdata struct clk *init_clocks[] = {
+	&rcosc,
+	&osc0,
+	&osc1,
+	&osc2,
+	&osc32,
+	&pll0,
+	&pll1,
+	&pll2,
+	&cpu_clk,
+	&hsb_clk,
+	&pba_clk,
+	&pbb_clk,
+	&pbc_clk,
+	&gclk0,
+	&gclk1,
+	&gclk2,
+	&gclk3,
+	&gclk4,
+	&gclk5,
+	&at32_intc0_pclk,
+	&pm_pclk,
+	&sdc_pclk,
+	&ast0_pclk,
+	&ast1_pclk,
+	&wdt_pclk,
+	&gpio_pclk,
+	&pdca_hclk,
+	&pdca_pclk,
+	&ebi_hclk,
+	&hramc_clk,
+	&smc_pclk,
+	&sdramc_clk,
+	&dw_dmac0_hclk,
+	&atmel_usart0_usart,
+	&atmel_usart1_usart,
+	&atmel_usart2_usart,
+	&atmel_usart3_usart,
+	&atmel_usart4_usart,
+	&atmel_usart5_usart,
+	&atmel_spi_clk[0],
+	&atmel_spi_clk[1],
+	&atmel_spi_clk[2],
+	&atmel_spi_clk[3],
+	&macb0_hclk,
+	&macb0_pclk,
+	&atmel_mci0_pclk,
+	&atmel_lcdfb0_hck1,
+	&atmel_lcdfb0_pixclk,
+	&atmel_mpopfb0_hclk,
+	&atmel_mpopfb0_pclk,
+	&usbh_utmi_clk,
+	&usbh_hclk,
+	&ohci_utmi_clk,
+	&ohci_hclk,
+	&ohci_gclk,
+	&ehci_utmi_clk,
+	&ehci_hclk,
+};
+
+static void pll_init_parent(struct clk *pll)
+{
+	u32 ctrl;
+
+	ctrl = pm_readl(PLL[pll->index]);
+	switch (PM_BFEXT(PLLx_PLLOSC, ctrl)) {
+	case 0:
+		pll->parent = &osc0;
+		break;
+	case 1:
+		pll->parent = &osc1;
+		break;
+	case 2:
+		pll->parent = &osc2;
+		break;
+	}
+}
+
+static void ap7200_power_off(void)
+{
+	/*
+	 * Clear all wakeup events so that we don't wake up
+	 * immediately after we shut down.
+	 */
+	sdc_writel(ECR, ~0UL);
+	sdc_readl(STATUS);
+	asm volatile("sleep %0; sub pc, -2"
+			:: "i"(CPU_SLEEP_SHUTDOWN)
+			: "memory");
+}
+
+void __init setup_platform(void)
+{
+	unsigned int	i;
+	u32		cpu_mask;
+	u32		hsb_mask;
+	u32		pba_mask;
+	u32		pbb_mask;
+
+	switch (PM_BFEXT(MCCTRL_MCSEL, pm_readl(MCCTRL))) {
+	case 0:
+		main_clock = &rcosc;
+		break;
+	case 1:
+		main_clock = &osc0;
+		break;
+	case 2:
+		main_clock = &pll0;
+		break;
+	}
+
+	cpu_clk.parent = main_clock;
+
+	pll_init_parent(&pll0);
+	pll_init_parent(&pll1);
+	pll_init_parent(&pll2);
+
+	genclk_init_parent(&gclk0);
+	genclk_init_parent(&gclk1);
+	genclk_init_parent(&gclk2);
+	genclk_init_parent(&gclk3);
+	genclk_init_parent(&gclk4);
+	genclk_init_parent(&gclk5);
+	genclk_init_parent(&atmel_lcdfb0_pixclk);
+
+	/*
+	 * Turn on all clocks that have at least one user already, and
+	 * turn off everything else. We only do this for module
+	 * clocks, and even though it isn't particularly pretty to
+	 * check the address of the mode function, it should do the
+	 * trick...
+	 */
+	cpu_mask = 0x10003;
+	hsb_mask = pba_mask = pbb_mask = 0;
+
+	/* Make sure we don't disable the power manager or the SDRAM */
+	pm_pclk.users = 1;
+	pm_pclk.parent->users = 1;
+	ebi_hclk.users = 1;
+
+	/* Can't recursively call clk_enable() from any of the clk ops */
+	sdc_pclk.users = 1;
+
+	for (i = 0; i < ARRAY_SIZE(init_clocks); i++) {
+		struct clk *clk = init_clocks[i];
+
+		/* first, register clock */
+		at32_clk_register(clk);
+
+		if (clk->users == 0)
+			continue;
+
+		if (clk->mode == &cpu_clk_mode)
+			cpu_mask |= 1 << clk->index;
+		else if (clk->mode == &hsb_clk_mode)
+			hsb_mask |= 1 << clk->index;
+		else if (clk->mode == &pba_clk_mode)
+			pba_mask |= 1 << clk->index;
+		else if (clk->mode == &pbb_clk_mode)
+			pbb_mask |= 1 << clk->index;
+	}
+
+	pm_writel(CPUMASK, cpu_mask);
+	pm_writel(HSBMASK, hsb_mask);
+	pm_writel(PBAMASK, pba_mask);
+	pm_writel(PBBMASK, pbb_mask);
+
+	at32_gpio_init(&gpio_device);
+
+	/* Enter shutdown mode when powering off. This happens very
+	 * early, so board code may still override this. */
+	pm_power_off = ap7200_power_off;
+
+	/* Enable WAKE pin */
+	sdc_writel(CTRL, SDC_BIT(CTRL_PIN_EN) | SDC_BIT(CTRL_AST_EN)
+			| SDC_BIT(CTRL_OCD_EN) | SDC_BIT(CTRL_JTAG_EN)
+			| SDC_BF(CTRL_KEY, 0x55));
+	sdc_writel(CTRL, SDC_BIT(CTRL_PIN_EN) | SDC_BIT(CTRL_AST_EN)
+			| SDC_BIT(CTRL_OCD_EN) | SDC_BIT(CTRL_JTAG_EN)
+			| SDC_BF(CTRL_KEY, 0xaa));
+}
+
+void __init platform_time_init(void)
+{
+	ast_time_init(&ast1_device, AST_CLOCK_PB);
+}
+
+unsigned long at32_get_reset_cause(void)
+{
+	return pm_readl(RCAUSE);
+}
+
+struct gen_pool *sram_pool;
+
+static int __init sram_init(void)
+{
+	struct gen_pool *pool;
+
+	/* 1KiB granularity */
+	pool = gen_pool_create(10, -1);
+	if (!pool)
+		goto fail;
+
+	if (gen_pool_add(pool, 0x08000000, 0x10000, -1))
+		goto err_pool_add;
+
+	sram_pool = pool;
+	return 0;
+
+err_pool_add:
+	gen_pool_destroy(pool);
+fail:
+	pr_err("Failed to create SRAM pool\n");
+	return -ENOMEM;
+}
+core_initcall(sram_init);
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/extint.c linux-2.6.28.2/arch/avr32/mach-at32ap/extint.c
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/extint.c	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/extint.c	2009-01-29 08:52:49.000000000 +0100
@@ -17,6 +17,8 @@
 
 #include <asm/io.h>
 
+#include <mach/cpu.h>
+
 /* EIC register offsets */
 #define EIC_IER					0x0000
 #define EIC_IDR					0x0004
@@ -26,24 +28,18 @@
 #define EIC_MODE				0x0014
 #define EIC_EDGE				0x0018
 #define EIC_LEVEL				0x001c
-#define EIC_NMIC				0x0024
 
-/* Bitfields in NMIC */
-#define EIC_NMIC_ENABLE				(1 << 0)
+/* This is only valid on v1 (AP700x) */
+#define EIC_NMIC				0x0024
+# define EIC_NMIC_ENABLE			(1 << 0)
 
-/* Bit manipulation macros */
-#define EIC_BIT(name)					\
-	(1 << EIC_##name##_OFFSET)
-#define EIC_BF(name,value)				\
-	(((value) & ((1 << EIC_##name##_SIZE) - 1))	\
-	 << EIC_##name##_OFFSET)
-#define EIC_BFEXT(name,value)				\
-	(((value) >> EIC_##name##_OFFSET)		\
-	 & ((1 << EIC_##name##_SIZE) - 1))
-#define EIC_BFINS(name,value,old)			\
-	(((old) & ~(((1 << EIC_##name##_SIZE) - 1)	\
-		    << EIC_##name##_OFFSET))		\
-	 | EIC_BF(name,value))
+/* These are only valid on v3 (AP720x) */
+#define EIC_FILTER				0x0020
+#define EIC_TEST				0x0024
+#define EIC_ASYNC				0x0028
+#define EIC_EN					0x0030
+#define EIC_DIS					0x0034
+#define EIC_CTRL				0x0038
 
 /* Register access macros */
 #define eic_readl(port,reg)				\
@@ -60,36 +56,68 @@
 static struct eic *nmi_eic;
 static bool nmi_enabled;
 
+static inline int eic_version(struct eic *eic)
+{
+	if (cpu_is_at32ap7000())
+		return 1;
+	if (cpu_is_at32ap7200())
+		return 3;
+
+	BUG();
+}
+
+static inline int eic_irq_bitmask(struct eic *eic, unsigned int irq)
+{
+	irq -= eic->first_irq;
+
+	if (eic_version(eic) > 2)
+		irq++;
+	return 1 << irq;
+}
+
 static void eic_ack_irq(unsigned int irq)
 {
 	struct eic *eic = get_irq_chip_data(irq);
-	eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
+	eic_writel(eic, ICR, eic_irq_bitmask(eic, irq));
 }
 
 static void eic_mask_irq(unsigned int irq)
 {
 	struct eic *eic = get_irq_chip_data(irq);
-	eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
+	eic_writel(eic, IDR, eic_irq_bitmask(eic, irq));
 }
 
 static void eic_mask_ack_irq(unsigned int irq)
 {
 	struct eic *eic = get_irq_chip_data(irq);
-	eic_writel(eic, ICR, 1 << (irq - eic->first_irq));
-	eic_writel(eic, IDR, 1 << (irq - eic->first_irq));
+	eic_writel(eic, ICR, eic_irq_bitmask(eic, irq));
+	eic_writel(eic, IDR, eic_irq_bitmask(eic, irq));
 }
 
 static void eic_unmask_irq(unsigned int irq)
 {
 	struct eic *eic = get_irq_chip_data(irq);
-	eic_writel(eic, IER, 1 << (irq - eic->first_irq));
+	eic_writel(eic, IER, eic_irq_bitmask(eic, irq));
+}
+
+/* The following two hooks are only used on v2+ controllers */
+static void eic_enable_irq(unsigned int irq)
+{
+	struct eic *eic = get_irq_chip_data(irq);
+	eic_writel(eic, EN, eic_irq_bitmask(eic, irq));
+}
+
+static void eic_disable_irq(unsigned int irq)
+{
+	struct eic *eic = get_irq_chip_data(irq);
+	eic_writel(eic, DIS, eic_irq_bitmask(eic, irq));
 }
 
 static int eic_set_irq_type(unsigned int irq, unsigned int flow_type)
 {
 	struct eic *eic = get_irq_chip_data(irq);
 	struct irq_desc *desc;
-	unsigned int i = irq - eic->first_irq;
+	unsigned int irq_bitmask = eic_irq_bitmask(eic, irq);
 	u32 mode, edge, level;
 	int ret = 0;
 
@@ -105,20 +133,20 @@
 
 	switch (flow_type) {
 	case IRQ_TYPE_LEVEL_LOW:
-		mode |= 1 << i;
-		level &= ~(1 << i);
+		mode |= irq_bitmask;
+		level &= ~irq_bitmask;
 		break;
 	case IRQ_TYPE_LEVEL_HIGH:
-		mode |= 1 << i;
-		level |= 1 << i;
+		mode |= irq_bitmask;
+		level |= irq_bitmask;
 		break;
 	case IRQ_TYPE_EDGE_RISING:
-		mode &= ~(1 << i);
-		edge |= 1 << i;
+		mode &= ~irq_bitmask;
+		edge |= irq_bitmask;
 		break;
 	case IRQ_TYPE_EDGE_FALLING:
-		mode &= ~(1 << i);
-		edge &= ~(1 << i);
+		mode &= ~irq_bitmask;
+		edge &= ~irq_bitmask;
 		break;
 	default:
 		ret = -EINVAL;
@@ -160,6 +188,11 @@
 	status = eic_readl(eic, ISR);
 	pending = status & eic_readl(eic, IMR);
 
+	if (eic_version(eic) > 1) {
+		status >>= 1;
+		pending >>= 1;
+	}
+
 	while (pending) {
 		i = fls(pending) - 1;
 		pending &= ~(1 << i);
@@ -172,16 +205,34 @@
 {
 	nmi_enabled = true;
 
-	if (nmi_eic)
-		eic_writel(nmi_eic, NMIC, EIC_NMIC_ENABLE);
+	if (nmi_eic) {
+		if (eic_version(nmi_eic) > 2) {
+			eic_writel(nmi_eic, EN, 1 << 0);
+			eic_writel(nmi_eic, IER, 1 << 0);
+		} else if (eic_version(nmi_eic) > 1) {
+			eic_writel(nmi_eic, EN, 1 << 8);
+			eic_writel(nmi_eic, IER, 1 << 8);
+		} else {
+			eic_writel(nmi_eic, NMIC, EIC_NMIC_ENABLE);
+		}
+	}
 
 	return 0;
 }
 
 void nmi_disable(void)
 {
-	if (nmi_eic)
-		eic_writel(nmi_eic, NMIC, 0);
+	if (nmi_eic) {
+		if (eic_version(nmi_eic) > 2) {
+			eic_writel(nmi_eic, IDR, 1 << 0);
+			eic_writel(nmi_eic, DIS, 1 << 0);
+		} else if (eic_version(nmi_eic) > 1) {
+			eic_writel(nmi_eic, IDR, 1 << 8);
+			eic_writel(nmi_eic, DIS, 1 << 8);
+		} else {
+			eic_writel(nmi_eic, NMIC, 0);
+		}
+	}
 
 	nmi_enabled = false;
 }
@@ -230,6 +281,15 @@
 	eic_writel(eic, EDGE, 0UL);
 	eic_writel(eic, LEVEL, 0UL);
 
+	/*
+	 * v2+ controllers have an extra enable/disable/mask set of
+	 * registers.
+	 */
+	if (eic_version(eic) >= 2) {
+		eic_chip.enable = eic_enable_irq;
+		eic_chip.disable = eic_disable_irq;
+	}
+
 	eic->chip = &eic_chip;
 
 	for (i = 0; i < nr_of_irqs; i++) {
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/gpio-v2.c linux-2.6.28.2/arch/avr32/mach-at32ap/gpio-v2.c
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/gpio-v2.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/gpio-v2.c	2009-01-29 08:52:49.000000000 +0100
@@ -0,0 +1,534 @@
+/*
+ * Atmel GPIO Port Multiplexer support
+ *
+ * Copyright (C) 2004-2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+
+#include <mach/portmux.h>
+#include <mach/chip.h>
+
+#include "gpio-v2.h"
+
+/*
+ * One chip corresponds with one bank of I/O registers. They're really
+ * all on the same controller.
+ */
+struct atmel_gpio_chip {
+	void __iomem	*regs;
+	u32		pinmux_mask;
+	struct		gpio_chip chip;
+	char		name[8];
+	unsigned int	bank;
+	int		irq;
+};
+
+/* ...which means we only have one clock and one platform device */
+static struct clk *gpio_clk;
+static struct atmel_gpio_chip gpio_dev[NR_GPIO_BANKS];
+
+/* Pin multiplexing API */
+static DEFINE_SPINLOCK(gpio_lock);
+
+static struct atmel_gpio_chip *to_atmel_gpio_chip(struct gpio_chip *chip)
+{
+	return container_of(chip, struct atmel_gpio_chip, chip);
+}
+
+static struct atmel_gpio_chip *pin_to_chip(unsigned int gpio)
+{
+	struct atmel_gpio_chip *chip;
+	unsigned int index;
+
+	index = gpio >> 5;
+	if (index >= NR_GPIO_BANKS)
+		return NULL;
+	chip = &gpio_dev[index];
+	if (!chip->regs)
+		return NULL;
+
+	return chip;
+}
+
+/* Pin multiplexing API */
+
+void __init at32_select_periph(unsigned int port, u32 pin_mask,
+		unsigned int periph, unsigned long flags)
+{
+	struct atmel_gpio_chip *chip;
+
+	chip = pin_to_chip(port);
+	if (unlikely(!chip)) {
+		printk("GPIO: invalid port %u\n", port);
+		goto fail;
+	}
+
+	/* Test if any of the requested pins is already muxed */
+	spin_lock(&gpio_lock);
+	if (unlikely(gpiochip_is_requested(&chip->chip, port)
+			|| unlikely(pin_mask & chip->pinmux_mask))) {
+		printk(KERN_WARNING "%s: pin(s) busy (requested 0x%x, busy 0x%x)\n",
+		       chip->name, pin_mask, chip->pinmux_mask & pin_mask);
+		spin_unlock(&gpio_lock);
+		goto fail;
+	}
+
+	switch (periph) {
+	case GPIO_PERIPH_A:
+		gpio_writel(chip, PMR0C, pin_mask);
+		gpio_writel(chip, PMR1C, pin_mask);
+		break;
+	case GPIO_PERIPH_B:
+		gpio_writel(chip, PMR0S, pin_mask);
+		gpio_writel(chip, PMR1C, pin_mask);
+		break;
+	case GPIO_PERIPH_C:
+		gpio_writel(chip, PMR0C, pin_mask);
+		gpio_writel(chip, PMR1S, pin_mask);
+		break;
+	case GPIO_PERIPH_D:
+		gpio_writel(chip, PMR0S, pin_mask);
+		gpio_writel(chip, PMR1S, pin_mask);
+		break;
+	default:
+		printk("%s: unknown function for pin mask %u\n",
+				chip->name, pin_mask);
+		goto fail;
+	}
+
+	gpio_writel(chip, PUERS, pin_mask);
+
+	gpio_writel(chip, GPERC, pin_mask);
+	if (!(flags & AT32_GPIOF_PULLUP))
+		gpio_writel(chip, PUERC, pin_mask);
+
+	spin_unlock(&gpio_lock);
+
+	return;
+
+fail:
+	dump_stack();
+}
+
+void __init at32_select_gpio(unsigned int pin, unsigned long flags)
+{
+	struct atmel_gpio_chip *chip;
+	unsigned int pin_index = pin & 0x1f;
+	u32 mask = 1 << pin_index;
+
+	chip = pin_to_chip(pin);
+	if (unlikely(!chip)) {
+		printk("GPIO: invalid pin %u\n", pin);
+		goto fail;
+	}
+
+	if (unlikely(test_and_set_bit(pin_index, &chip->pinmux_mask))) {
+		printk("%s: pin %u is busy\n", chip->name, pin_index);
+		goto fail;
+	}
+
+	if (flags & AT32_GPIOF_PULLUP)
+		gpio_writel(chip, PUERS, mask);
+	else
+		gpio_writel(chip, PUERC, mask);
+	if (flags & AT32_GPIOF_MULTIDRV)
+		gpio_writel(chip, ODMERS, mask);
+	else
+		gpio_writel(chip, ODMERC, mask);
+	if (flags & AT32_GPIOF_DEGLITCH)
+		gpio_writel(chip, GFERS, mask);
+	else
+		gpio_writel(chip, GFERC, mask);
+
+	if (flags & AT32_GPIOF_OUTPUT) {
+		if (flags & AT32_GPIOF_HIGH)
+			gpio_writel(chip, OVRS, mask);
+		else
+			gpio_writel(chip, OVRC, mask);
+		gpio_writel(chip, ODERS, mask);
+	} else {
+		gpio_writel(chip, ODERC, mask);
+	}
+
+	gpio_writel(chip, GPERS, mask);
+
+	return;
+
+fail:
+	dump_stack();
+}
+
+/* Reserve a pin, preventing anyone else from changing its configuration. */
+void __init at32_reserve_pin(unsigned int port, u32 pin_mask)
+{
+	struct atmel_gpio_chip *chip;
+
+	chip = pin_to_chip(port);
+	if (unlikely(!chip)) {
+		printk("GPIO: invalid port %u\n", port);
+		goto fail;
+	}
+
+	/* Test if any of the requested pins is already muxed */
+	spin_lock(&gpio_lock);
+	if (unlikely(pin_mask & chip->pinmux_mask)) {
+		printk(KERN_WARNING "%s: pin(s) busy (req. 0x%x, busy 0x%x)\n",
+			chip->name, pin_mask, chip->pinmux_mask & pin_mask);
+		spin_unlock(&gpio_lock);
+		goto fail;
+	}
+
+	/* Reserve pins */
+	chip->pinmux_mask |= pin_mask;
+	spin_unlock(&gpio_lock);
+	return;
+
+fail:
+	dump_stack();
+}
+
+/*--------------------------------------------------------------------------*/
+
+/* GPIO API */
+
+static int get_pin_state(struct gpio_chip *chip, unsigned int offset)
+{
+	struct atmel_gpio_chip *gpio = to_atmel_gpio_chip(chip);
+
+	return (gpio_readl(gpio, PVR) >> offset) & 1;
+}
+
+static void set_pin_state(struct gpio_chip *chip, unsigned int offset, int high)
+{
+	struct atmel_gpio_chip *gpio = to_atmel_gpio_chip(chip);
+	u32 mask = 1 << offset;
+
+	if (high)
+		gpio_writel(gpio, OVRS, mask);
+	else
+		gpio_writel(gpio, OVRC, mask);
+}
+
+static int direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct atmel_gpio_chip *gpio = to_atmel_gpio_chip(chip);
+	u32 mask = 1 << offset;
+
+	if (!(gpio_readl(gpio, GPER) & mask))
+		return -EINVAL;
+
+	gpio_writel(gpio, ODERC, mask);
+	return 0;
+}
+
+static int direction_output(struct gpio_chip *chip, unsigned int offset,
+		int high)
+{
+	struct atmel_gpio_chip *gpio = to_atmel_gpio_chip(chip);
+	u32 mask = 1 << offset;
+
+	if (!(gpio_readl(gpio, GPER) & mask))
+		return -EINVAL;
+
+	set_pin_state(chip, offset, high);
+	gpio_writel(gpio, ODERS, mask);
+	return 0;
+}
+
+/*--------------------------------------------------------------------------*/
+
+/* GPIO IRQ support */
+
+static void gpio_irq_mask(unsigned irq)
+{
+	unsigned int		pin = irq_to_gpio(irq);
+	struct atmel_gpio_chip	*chip = &gpio_dev[pin >> 5];
+
+	gpio_writel(chip, IERC, 1 << (pin & 0x1f));
+}
+
+static void gpio_irq_unmask(unsigned irq)
+{
+	unsigned int		pin = irq_to_gpio(irq);
+	struct atmel_gpio_chip	*chip = &gpio_dev[pin >> 5];
+
+	gpio_writel(chip, IERS, 1 << (pin & 0x1f));
+}
+
+static int gpio_irq_type(unsigned irq, unsigned type)
+{
+	unsigned int		pin = irq_to_gpio(irq);
+	struct atmel_gpio_chip	*chip = &gpio_dev[pin >> 5];
+	u32			mask = 1 << (pin & 0x1f);
+
+	switch (type) {
+	case IRQ_TYPE_EDGE_FALLING:
+		gpio_writel(chip, IMR0C, mask);
+		gpio_writel(chip, IMR1S, mask);
+		break;
+	case IRQ_TYPE_EDGE_RISING:
+		gpio_writel(chip, IMR0S, mask);
+		gpio_writel(chip, IMR1C, mask);
+		break;
+	case IRQ_TYPE_NONE:
+		/* fall through */
+	case IRQ_TYPE_EDGE_BOTH:
+		gpio_writel(chip, IMR0C, mask);
+		gpio_writel(chip, IMR1C, mask);
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct irq_chip gpio_irqchip = {
+	.name		= "gpio",
+	.mask		= gpio_irq_mask,
+	.unmask		= gpio_irq_unmask,
+	.set_type	= gpio_irq_type,
+};
+
+static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
+{
+	struct atmel_gpio_chip	*chip = get_irq_chip_data(irq);
+	unsigned int		gpio_irq;
+
+	gpio_irq = (unsigned int) get_irq_data(irq);
+	for (;;) {
+		u32		ifr;
+		struct irq_desc	*d;
+
+		/* ack pending GPIO interrupts */
+		ifr = gpio_readl(chip, IFR);
+		if (!ifr)
+			break;
+		do {
+			int pin;
+
+			pin = ffs(ifr) - 1;
+			ifr &= ~(1 << pin);
+			gpio_writel(chip, IFRC, (1 << pin));
+
+			pin += gpio_irq;
+			d = &irq_desc[pin];
+
+			d->handle_irq(pin, d);
+		} while (ifr);
+	}
+}
+
+static void __init
+gpio_irq_setup(struct atmel_gpio_chip *chip, int irq, int gpio_irq)
+{
+	unsigned	i;
+
+	set_irq_chip_data(irq, chip);
+	set_irq_data(irq, (void *) gpio_irq);
+
+	for (i = 0; i < 32; i++, gpio_irq++) {
+		set_irq_chip_data(gpio_irq, chip);
+		set_irq_chip_and_handler(gpio_irq, &gpio_irqchip,
+				handle_simple_irq);
+	}
+
+	set_irq_chained_handler(irq, gpio_irq_handler);
+}
+
+/*--------------------------------------------------------------------------*/
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/seq_file.h>
+
+/*
+ * This shows more info than the generic gpio dump code:
+ * pullups, deglitching, open drain drive.
+ */
+static void gpio_bank_show(struct seq_file *s, struct gpio_chip *chip)
+{
+	struct atmel_gpio_chip *gpio = to_atmel_gpio_chip(chip);
+	u32		oder, ovr, puer, pder, gfer, odmer, ier, imr0, imr1;
+	unsigned int	i;
+	u32		mask;
+
+	oder = gpio_readl(gpio, ODER);
+	ovr = gpio_readl(gpio, OVR);
+	puer = gpio_readl(gpio, PUER);
+	pder = gpio_readl(gpio, PDER);
+	gfer = gpio_readl(gpio, GFER);
+	odmer = gpio_readl(gpio, ODMER);
+	ier = gpio_readl(gpio, IER);
+	imr0 = gpio_readl(gpio, IMR0);
+	imr1 = gpio_readl(gpio, IMR1);
+
+	for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
+		const char *label;
+
+		label = gpiochip_is_requested(chip, i);
+		if (!label)
+			continue;
+
+		seq_printf(s, " gpio-%-3d ", chip->base + i);
+		gpio_decode_pin(s, gpio->bank, i);
+		seq_printf(s, " (%-12s) %s %s", label,
+				(oder & mask) ? "out" : "in",
+				(ovr & mask) ? "hi" : "lo");
+		if ((puer & mask) && !(pder & mask))
+			seq_printf(s, " pull-up");
+		else if (!(puer & mask) && (pder & mask))
+			seq_printf(s, " pull-down");
+		else if ((puer & mask) && (pder & mask))
+			seq_printf(s, " buskeeper");
+		if (gfer & mask)
+			seq_printf(s, " deglitch");
+		if (odmer & mask)
+			seq_printf(s, " open-drain");
+		if ((gpio->irq >= 0) && (ier & mask)) {
+			seq_printf(s, " irq-%d edge-",
+					gpio_to_irq(chip->base + i));
+			if (!(imr0 & mask) && !(imr1 & mask))
+				seq_printf(s, "both");
+			else if ((imr0 & mask) && !(imr1 & mask))
+				seq_printf(s, "rising");
+			else if (!(imr0 & mask) && (imr1 & mask))
+				seq_printf(s, "falling");
+			else
+				seq_printf(s, "INVALID");
+		}
+		seq_printf(s, "\n");
+	}
+}
+
+#else
+#define gpio_bank_show	NULL
+#endif
+
+static int __init gpio_probe(struct platform_device *pdev)
+{
+	struct resource *regs;
+	struct resource *irqs;
+	int irq = -1;
+	unsigned int i;
+
+	BUG_ON(pdev->id >= 1);
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		dev_err(&pdev->dev, "no mmio resource defined\n");
+		return -ENXIO;
+	}
+	irqs = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (irqs)
+		irq = irqs->start;
+
+	for (i = 0; i < NR_GPIO_BANKS; i++) {
+		unsigned int gpio_irq_base;
+		struct atmel_gpio_chip *chip;
+
+		chip = &gpio_dev[i];
+		BUG_ON(!chip->regs);
+
+		chip->chip.label = chip->name;
+		chip->chip.base = i * 32;
+		chip->chip.ngpio = 32;
+
+		chip->chip.direction_input = direction_input;
+		chip->chip.get = get_pin_state;
+		chip->chip.direction_output = direction_output;
+		chip->chip.set = set_pin_state;
+		chip->chip.dbg_show = gpio_bank_show;
+
+		gpiochip_add(&chip->chip);
+
+		gpio_irq_base = GPIO_IRQ_BASE + (i * 32);
+		if (irqs && irq <= irqs->end) {
+			gpio_irq_setup(chip, irq, gpio_irq_base);
+			chip->irq = irq;
+			irq++;
+		} else {
+			chip->irq = -1;
+		}
+
+		platform_set_drvdata(pdev, chip);
+
+		printk(KERN_DEBUG "%s: base 0x%p", chip->name, chip->regs);
+		if (chip->irq >= 0)
+			printk(" irq %d chains %d..%d", irq,
+					gpio_irq_base, gpio_irq_base + 31);
+		printk("\n");
+	}
+
+	return 0;
+}
+
+static struct platform_driver gpio_driver = {
+	.probe		= gpio_probe,
+	.driver		= {
+		.name		= "gpio",
+	},
+};
+
+static int __init gpio_init(void)
+{
+	return platform_driver_register(&gpio_driver);
+}
+postcore_initcall(gpio_init);
+
+void __init at32_gpio_init(struct platform_device *pdev)
+{
+	int i;
+	struct clk *clk;
+	struct resource *regs;
+	void __iomem *iomem_base;
+	struct atmel_gpio_chip *chip;
+
+	if (pdev->id > 0) {
+		dev_err(&pdev->dev, "only one GPIO controller supported\n");
+		return;
+	}
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		dev_err(&pdev->dev, "no mmio resource defined\n");
+		return;
+	}
+
+	clk = clk_get(&pdev->dev, "pclk");
+	if (IS_ERR(clk)) {
+		dev_err(&pdev->dev, "no mck clock defined\n");
+		return;
+	}
+	clk_enable(clk);
+
+	gpio_clk = clk;
+
+	/*
+	 * We may get called too early for ioremap() to work. But we
+	 * know that the GPIO registers are permanently mapped 1:1
+	 */
+	iomem_base = (void __iomem __force *)regs->start;
+
+	for (i = 0; i < NR_GPIO_BANKS; i++) {
+		chip = &gpio_dev[i];
+		snprintf(chip->name, sizeof(chip->name), "gpio%d", i);
+		chip->regs = iomem_base + (i * 0x200);
+		chip->bank = i;
+
+		/* start with irqs disabled and acked */
+		gpio_writel(chip, IERC, ~0UL);
+		gpio_writel(chip, IFRC, ~0UL);
+	}
+}
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/gpio-v2.h linux-2.6.28.2/arch/avr32/mach-at32ap/gpio-v2.h
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/gpio-v2.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/gpio-v2.h	2009-01-29 08:52:49.000000000 +0100
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2008 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 __GPIO_REGS_H__
+#define __GPIO_REGS_H__
+
+/* Register offsets */
+struct gpio_regs {
+	u32	GPER;
+	u32	GPERS;
+	u32	GPERC;
+	u32	GPERT;
+	u32	PMR0;
+	u32	PMR0S;
+	u32	PMR0C;
+	u32	PMR0T;
+	u32	PMR1;
+	u32	PMR1S;
+	u32	PMR1C;
+	u32	PMR1T;
+	u32	__reserved0[4];
+	u32	ODER;
+	u32	ODERS;
+	u32	ODERC;
+	u32	ODERT;
+	u32	OVR;
+	u32	OVRS;
+	u32	OVRC;
+	u32	OVRT;
+	u32	PVR;
+	u32	__reserved_PVRS;
+	u32	__reserved_PVRC;
+	u32	__reserved_PVRT;
+	u32	PUER;
+	u32	PUERS;
+	u32	PUERC;
+	u32	PUERT;
+	u32	PDER;
+	u32	PDERS;
+	u32	PDERC;
+	u32	PDERT;
+	u32	IER;
+	u32	IERS;
+	u32	IERC;
+	u32	IERT;
+	u32	IMR0;
+	u32	IMR0S;
+	u32	IMR0C;
+	u32	IMR0T;
+	u32	IMR1;
+	u32	IMR1S;
+	u32	IMR1C;
+	u32	IMR1T;
+	u32	GFER;
+	u32	GFERS;
+	u32	GFERC;
+	u32	GFERT;
+	u32	IFR;
+	u32	__reserved_IFRS;
+	u32	IFRC;
+	u32	__reserved_IFRT;
+	u32	ODMER;
+	u32	ODMERS;
+	u32	ODMERC;
+	u32	ODMERT;
+	u32	__reserved1[4];
+	u32	ODCR0;
+	u32	ODCR0S;
+	u32	ODCR0C;
+	u32	ODCR0T;
+	u32	ODCR1;
+	u32	ODCR1S;
+	u32	ODCR1C;
+	u32	ODCR1T;
+	u32	__reserved2[4];
+	u32	OSRR0;
+	u32	OSRR0S;
+	u32	OSRR0C;
+	u32	OSRR0T;
+	u32	__reserved3[8];
+	u32	STER;
+	u32	STERS;
+	u32	STERC;
+	u32	STERT;
+	u32	__reserved4[35];
+	u32	VERSION;
+};
+
+/* Register access macros */
+#define __gpio_regs(bank) ((struct gpio_regs __iomem *)(bank)->regs)
+#define gpio_readl(bank, reg)						\
+	__raw_readl(&__gpio_regs(bank)->reg)
+#define gpio_writel(bank, reg, value)					\
+	__raw_writel(value, &__gpio_regs(bank)->reg)
+
+void at32_gpio_init(struct platform_device *pdev);
+
+#endif /* __GPIO_REGS_H__ */
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/hmatrix.c linux-2.6.28.2/arch/avr32/mach-at32ap/hmatrix.c
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/hmatrix.c	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/hmatrix.c	2009-01-29 08:52:49.000000000 +0100
@@ -54,6 +54,81 @@
 }
 
 /**
+ * hmatrix_set_default_master - set default master on a given slave
+ * @slave: HSB slave interface ID
+ * @master: HSB master interface ID
+ */
+void hmatrix_set_default_master(unsigned int slave, unsigned int master)
+{
+	u32 value;
+	unsigned int reg;
+
+	WARN_ON(slave > HMATRIX_MAX_SLAVE
+			|| master > HMATRIX_MASTER_LAST);
+
+	reg = HMATRIX_SCFG(slave);
+
+	clk_enable(&at32_hmatrix_clk);
+	value = __hmatrix_read_reg(reg);
+	value &= ~(HMATRIX_SCFG_FIXED_DEFMSTR(HMATRIX_MAX_SLAVE)
+			| HMATRIX_SCFG_DEFMSTR_MASK);
+
+	switch (master) {
+	case HMATRIX_MASTER_NONE:
+		value |= HMATRIX_SCFG_DEFMSTR_NONE;
+		break;
+	case HMATRIX_MASTER_LAST:
+		value |= HMATRIX_SCFG_DEFMSTR_LAST;
+		break;
+	default:
+		value |= HMATRIX_SCFG_DEFMSTR_FIXED;
+		value |= HMATRIX_SCFG_FIXED_DEFMSTR(master);
+		break;
+	}
+
+	__hmatrix_write_reg(reg, value);
+	__hmatrix_read_reg(reg);
+	clk_disable(&at32_hmatrix_clk);
+}
+
+/**
+ * hmatrix_set_priority - set the priority of a master on a given slave
+ * @slave: HSB slave interface ID
+ * @master: HSB master interface ID
+ * @priority: Priority of @master when competing for access to @slave.
+ *
+ * Note that this is currently broken -- we need some way to enable
+ * fixed-priority arbitration, and that happens to be broken on AP7000
+ * rev C.
+ */
+void hmatrix_set_priority(unsigned int slave, unsigned int master,
+		unsigned int priority)
+{
+	u32 value;
+	unsigned int reg;
+
+	WARN_ON(slave > HMATRIX_MAX_SLAVE
+			|| master > HMATRIX_MAX_MASTER
+			|| priority > HMATRIX_MAX_PRIO);
+
+	clk_enable(&at32_hmatrix_clk);
+	if (master < 8) {
+		reg = HMATRIX_PRAS(slave);
+		value = __hmatrix_read_reg(reg);
+		value &= ~HMATRIX_PRAS_PRIO(master, HMATRIX_MAX_PRIO);
+		value |= HMATRIX_PRAS_PRIO(master, priority);
+	} else {
+		reg = HMATRIX_PRBS(slave);
+		value = __hmatrix_read_reg(reg);
+		value &= ~HMATRIX_PRBS_PRIO(master, HMATRIX_MAX_PRIO);
+		value |= HMATRIX_PRBS_PRIO(master, priority);
+	}
+	__hmatrix_write_reg(reg, value);
+	__hmatrix_read_reg(reg);
+	clk_disable(&at32_hmatrix_clk);
+}
+
+/**
  * hmatrix_sfr_set_bits - set bits in a slave's Special Function Register
  * @slave_id: operate on the SFR belonging to this slave
  * @mask: mask of bits to be set in the SFR
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/hsmc.c linux-2.6.28.2/arch/avr32/mach-at32ap/hsmc.c
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/hsmc.c	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/hsmc.c	2009-01-29 08:52:49.000000000 +0100
@@ -229,10 +229,8 @@
 	if (IS_ERR(pclk))
 		return PTR_ERR(pclk);
 	mck = clk_get(&pdev->dev, "mck");
-	if (IS_ERR(mck)) {
-		ret = PTR_ERR(mck);
-		goto out_put_pclk;
-	}
+	if (IS_ERR(mck))
+		mck = pclk;
 
 	ret = -ENOMEM;
 	hsmc = kzalloc(sizeof(struct hsmc), GFP_KERNEL);
@@ -260,8 +258,8 @@
 	clk_disable(pclk);
 	kfree(hsmc);
 out_put_clocks:
-	clk_put(mck);
-out_put_pclk:
+	if (mck != pclk)
+		clk_put(mck);
 	clk_put(pclk);
 	hsmc = NULL;
 	return ret;
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/at32ap700x.h linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/at32ap700x.h
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/at32ap700x.h	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/at32ap700x.h	2009-01-29 08:52:49.000000000 +0100
@@ -211,4 +211,135 @@
 
 #define ATMEL_LCDC_ALT_15BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_15B_DATA)
 
+/* Bitmask for all EBI data (D16..D31) pins on port E */
+#define ATMEL_EBI_PE_DATA_ALL  (0x0000FFFF)
+
+/* LCDC on port C */
+#define ATMEL_LCDC_PC_CC	(1ULL << 19)
+#define ATMEL_LCDC_PC_HSYNC	(1ULL << 20)
+#define ATMEL_LCDC_PC_PCLK	(1ULL << 21)
+#define ATMEL_LCDC_PC_VSYNC	(1ULL << 22)
+#define ATMEL_LCDC_PC_DVAL	(1ULL << 23)
+#define ATMEL_LCDC_PC_MODE	(1ULL << 24)
+#define ATMEL_LCDC_PC_PWR	(1ULL << 25)
+#define ATMEL_LCDC_PC_DATA0	(1ULL << 26)
+#define ATMEL_LCDC_PC_DATA1	(1ULL << 27)
+#define ATMEL_LCDC_PC_DATA2	(1ULL << 28)
+#define ATMEL_LCDC_PC_DATA3	(1ULL << 29)
+#define ATMEL_LCDC_PC_DATA4	(1ULL << 30)
+#define ATMEL_LCDC_PC_DATA5	(1ULL << 31)
+
+/* LCDC on port D */
+#define ATMEL_LCDC_PD_DATA6	(1ULL << 0)
+#define ATMEL_LCDC_PD_DATA7	(1ULL << 1)
+#define ATMEL_LCDC_PD_DATA8	(1ULL << 2)
+#define ATMEL_LCDC_PD_DATA9	(1ULL << 3)
+#define ATMEL_LCDC_PD_DATA10	(1ULL << 4)
+#define ATMEL_LCDC_PD_DATA11	(1ULL << 5)
+#define ATMEL_LCDC_PD_DATA12	(1ULL << 6)
+#define ATMEL_LCDC_PD_DATA13	(1ULL << 7)
+#define ATMEL_LCDC_PD_DATA14	(1ULL << 8)
+#define ATMEL_LCDC_PD_DATA15	(1ULL << 9)
+#define ATMEL_LCDC_PD_DATA16	(1ULL << 10)
+#define ATMEL_LCDC_PD_DATA17	(1ULL << 11)
+#define ATMEL_LCDC_PD_DATA18	(1ULL << 12)
+#define ATMEL_LCDC_PD_DATA19	(1ULL << 13)
+#define ATMEL_LCDC_PD_DATA20	(1ULL << 14)
+#define ATMEL_LCDC_PD_DATA21	(1ULL << 15)
+#define ATMEL_LCDC_PD_DATA22	(1ULL << 16)
+#define ATMEL_LCDC_PD_DATA23	(1ULL << 17)
+
+/* LCDC on port E */
+#define ATMEL_LCDC_PE_CC	(1ULL << (32 + 0))
+#define ATMEL_LCDC_PE_DVAL	(1ULL << (32 + 1))
+#define ATMEL_LCDC_PE_MODE	(1ULL << (32 + 2))
+#define ATMEL_LCDC_PE_DATA0	(1ULL << (32 + 3))
+#define ATMEL_LCDC_PE_DATA1	(1ULL << (32 + 4))
+#define ATMEL_LCDC_PE_DATA2	(1ULL << (32 + 5))
+#define ATMEL_LCDC_PE_DATA3	(1ULL << (32 + 6))
+#define ATMEL_LCDC_PE_DATA4	(1ULL << (32 + 7))
+#define ATMEL_LCDC_PE_DATA8	(1ULL << (32 + 8))
+#define ATMEL_LCDC_PE_DATA9	(1ULL << (32 + 9))
+#define ATMEL_LCDC_PE_DATA10	(1ULL << (32 + 10))
+#define ATMEL_LCDC_PE_DATA11	(1ULL << (32 + 11))
+#define ATMEL_LCDC_PE_DATA12	(1ULL << (32 + 12))
+#define ATMEL_LCDC_PE_DATA16	(1ULL << (32 + 13))
+#define ATMEL_LCDC_PE_DATA17	(1ULL << (32 + 14))
+#define ATMEL_LCDC_PE_DATA18	(1ULL << (32 + 15))
+#define ATMEL_LCDC_PE_DATA19	(1ULL << (32 + 16))
+#define ATMEL_LCDC_PE_DATA20	(1ULL << (32 + 17))
+#define ATMEL_LCDC_PE_DATA21	(1ULL << (32 + 18))
+
+
+#define ATMEL_LCDC(PORT, PIN)	(ATMEL_LCDC_##PORT##_##PIN)
+
+
+#define ATMEL_LCDC_PRI_24B_DATA	(					\
+		ATMEL_LCDC(PC, DATA0)  | ATMEL_LCDC(PC, DATA1)  |	\
+		ATMEL_LCDC(PC, DATA2)  | ATMEL_LCDC(PC, DATA3)  |	\
+		ATMEL_LCDC(PC, DATA4)  | ATMEL_LCDC(PC, DATA5)  |	\
+		ATMEL_LCDC(PD, DATA6)  | ATMEL_LCDC(PD, DATA7)  |	\
+		ATMEL_LCDC(PD, DATA8)  | ATMEL_LCDC(PD, DATA9)  |	\
+		ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) |	\
+		ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA13) |	\
+		ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) |	\
+		ATMEL_LCDC(PD, DATA16) | ATMEL_LCDC(PD, DATA17) |	\
+		ATMEL_LCDC(PD, DATA18) | ATMEL_LCDC(PD, DATA19) |	\
+		ATMEL_LCDC(PD, DATA20) | ATMEL_LCDC(PD, DATA21) |	\
+		ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
+
+#define ATMEL_LCDC_ALT_24B_DATA (					\
+		ATMEL_LCDC(PE, DATA0)  | ATMEL_LCDC(PE, DATA1)  |	\
+		ATMEL_LCDC(PE, DATA2)  | ATMEL_LCDC(PE, DATA3)  |	\
+		ATMEL_LCDC(PE, DATA4)  | ATMEL_LCDC(PC, DATA5)  |	\
+		ATMEL_LCDC(PD, DATA6)  | ATMEL_LCDC(PD, DATA7)  |	\
+		ATMEL_LCDC(PE, DATA8)  | ATMEL_LCDC(PE, DATA9)  |	\
+		ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) |	\
+		ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PD, DATA13) |	\
+		ATMEL_LCDC(PD, DATA14) | ATMEL_LCDC(PD, DATA15) |	\
+		ATMEL_LCDC(PE, DATA16) | ATMEL_LCDC(PE, DATA17) |	\
+		ATMEL_LCDC(PE, DATA18) | ATMEL_LCDC(PE, DATA19) |	\
+		ATMEL_LCDC(PE, DATA20) | ATMEL_LCDC(PE, DATA21) |	\
+		ATMEL_LCDC(PD, DATA22) | ATMEL_LCDC(PD, DATA23))
+
+#define ATMEL_LCDC_PRI_15B_DATA (					\
+		ATMEL_LCDC(PC, DATA0)  | ATMEL_LCDC(PC, DATA1)  |	\
+		ATMEL_LCDC(PC, DATA2)  | ATMEL_LCDC(PC, DATA3)  |	\
+		ATMEL_LCDC(PC, DATA4)  | ATMEL_LCDC(PC, DATA5)  |	\
+		ATMEL_LCDC(PD, DATA8)  | ATMEL_LCDC(PD, DATA9)  |	\
+		ATMEL_LCDC(PD, DATA10) | ATMEL_LCDC(PD, DATA11) |	\
+		ATMEL_LCDC(PD, DATA12) | ATMEL_LCDC(PD, DATA16) |	\
+		ATMEL_LCDC(PD, DATA17) | ATMEL_LCDC(PD, DATA18) |	\
+		ATMEL_LCDC(PD, DATA19) | ATMEL_LCDC(PD, DATA20))
+
+#define ATMEL_LCDC_ALT_15B_DATA	(					\
+		ATMEL_LCDC(PE, DATA0)  | ATMEL_LCDC(PE, DATA1)  |	\
+		ATMEL_LCDC(PE, DATA2)  | ATMEL_LCDC(PE, DATA3)  |	\
+		ATMEL_LCDC(PE, DATA4)  | ATMEL_LCDC(PC, DATA5)  |	\
+		ATMEL_LCDC(PE, DATA8)  | ATMEL_LCDC(PE, DATA9)  |	\
+		ATMEL_LCDC(PE, DATA10) | ATMEL_LCDC(PE, DATA11) |	\
+		ATMEL_LCDC(PE, DATA12) | ATMEL_LCDC(PE, DATA16) |	\
+		ATMEL_LCDC(PE, DATA17) | ATMEL_LCDC(PE, DATA18) |	\
+		ATMEL_LCDC(PE, DATA19) | ATMEL_LCDC(PE, DATA20))
+
+#define ATMEL_LCDC_PRI_CONTROL (					\
+		ATMEL_LCDC(PC, CC)   | ATMEL_LCDC(PC, DVAL) |		\
+		ATMEL_LCDC(PC, MODE) | ATMEL_LCDC(PC, PWR))
+
+#define ATMEL_LCDC_ALT_CONTROL (					\
+		ATMEL_LCDC(PE, CC)   | ATMEL_LCDC(PE, DVAL) |		\
+		ATMEL_LCDC(PE, MODE) | ATMEL_LCDC(PC, PWR))
+
+#define ATMEL_LCDC_CONTROL (						\
+		ATMEL_LCDC(PC, HSYNC) | ATMEL_LCDC(PC, VSYNC) |		\
+		ATMEL_LCDC(PC, PCLK))
+
+#define ATMEL_LCDC_PRI_24BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_24B_DATA)
+
+#define ATMEL_LCDC_ALT_24BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_24B_DATA)
+
+#define ATMEL_LCDC_PRI_15BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_PRI_15B_DATA)
+
+#define ATMEL_LCDC_ALT_15BIT	(ATMEL_LCDC_CONTROL | ATMEL_LCDC_ALT_15B_DATA)
+
 #endif /* __ASM_ARCH_AT32AP700X_H__ */
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/at32ap720x.h linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/at32ap720x.h
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/at32ap720x.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/at32ap720x.h	2009-01-29 08:52:49.000000000 +0100
@@ -0,0 +1,105 @@
+/*
+ * Pin definitions for AT32AP7200
+ *
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ASM_ARCH_AT32AP7200_H__
+#define __ASM_ARCH_AT32AP7200_H__
+
+#define GPIO_PERIPH_A	0x00
+#define GPIO_PERIPH_B	0x01
+#define GPIO_PERIPH_C	0x02
+#define GPIO_PERIPH_D	0x03
+
+#define NR_GPIO_BANKS	8
+
+/*
+ * Pin numbers identifying specific GPIO pins on the chip. They can
+ * also be converted to IRQ numbers by passing them through
+ * gpio_to_irq().
+ */
+#define GPIO_BASE	(0)
+
+#define GPIO_PA_BASE	(GPIO_BASE + 0 * 32)
+#define GPIO_PB_BASE	(GPIO_BASE + 1 * 32)
+#define GPIO_PC_BASE	(GPIO_BASE + 2 * 32)
+#define GPIO_PD_BASE	(GPIO_BASE + 3 * 32)
+#define GPIO_PE_BASE	(GPIO_BASE + 4 * 32)
+#define GPIO_PF_BASE	(GPIO_BASE + 5 * 32)
+#define GPIO_PX_BASE	(GPIO_BASE + 6 * 32)
+
+#define GPIO_PIN_PA(N)	(GPIO_PA_BASE + (N))
+#define GPIO_PIN_PB(N)	(GPIO_PB_BASE + (N))
+#define GPIO_PIN_PC(N)	(GPIO_PC_BASE + (N))
+#define GPIO_PIN_PD(N)	(GPIO_PD_BASE + (N))
+#define GPIO_PIN_PE(N)	(GPIO_PE_BASE + (N))
+#define GPIO_PIN_PF(N)	(GPIO_PF_BASE + (N))
+#define GPIO_PIN_PX(N)	(GPIO_PX_BASE + (N))
+
+#define gpio_decode_pin(s, bank, offset)				\
+	do {								\
+		switch (bank) {						\
+		case 7:							\
+			offset += 32;					\
+			/* fall through */				\
+		case 6:							\
+			seq_printf(s, "PX%-2u", offset);		\
+			break;						\
+		default:						\
+			seq_printf(s, "P%c%-2u", bank + 'A', offset);	\
+			break;						\
+		}							\
+	} while (0)
+
+/* HSB master IDs */
+#define HMATRIX_MASTER_CPU_ICACHE		 0
+#define HMATRIX_MASTER_CPU_DCACHE		 1
+#define HMATRIX_MASTER_PDCA			 2
+#define HMATRIX_MASTER_LCDC			 4
+#define HMATRIX_MASTER_MPOP_IBI			 5
+#define HMATRIX_MASTER_MPOP_OBI			 6
+#define HMATRIX_MASTER_MPOP_OM			 7
+#define HMATRIX_MASTER_DMACA_M0			 8
+#define HMATRIX_MASTER_DMACA_M1			 9
+#define HMATRIX_MASTER_USBB			10
+#define HMATRIX_MASTER_USBH_EHCI		11
+#define HMATRIX_MASTER_USBH_OHCI		12
+#define HMATRIX_MASTER_MACB			13
+
+/* HSB slave IDs */
+#define HMATRIX_SLAVE_BOOTROM			 0
+#define HMATRIX_SLAVE_PBA			 1
+#define HMATRIX_SLAVE_PBB			 2
+#define HMATRIX_SLAVE_PBC			 3
+#define HMATRIX_SLAVE_SRAM0			 4
+#define HMATRIX_SLAVE_SRAM1			 5
+#define HMATRIX_SLAVE_EBI			 6
+#define HMATRIX_SLAVE_LCDC			 7
+#define HMATRIX_SLAVE_MPOP			 8
+#define HMATRIX_SLAVE_DMACA			 9
+#define HMATRIX_SLAVE_USBB			10
+#define HMATRIX_SLAVE_EHCI			11
+#define HMATRIX_SLAVE_OHCI			12
+
+/* Bits in HMATRIX SFR6 (EBI) */
+#define HMATRIX_EBI_SDRAM_ENABLE		(1 << 1)
+#define HMATRIX_EBI_NAND_ENABLE			(1 << 3)
+#define HMATRIX_EBI_CF0_ENABLE			(1 << 4)
+#define HMATRIX_EBI_CF1_ENABLE			(1 << 5)
+
+/*
+ * Base addresses of controllers that may be accessed early by
+ * platform code.
+ */
+#define GPIO_HW_BASE	0xffd02000
+#define INTC_BASE	0xffd00000
+#define PM_BASE		0xffd00400
+#define SDC_BASE	0xffd00800
+#define SDRAMC_BASE	0xffe04800
+#define HMATRIX_BASE	0xffe05000
+
+#endif /* __ASM_ARCH_AT32AP7200_H__ */
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/chip.h linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/chip.h
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/chip.h	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/chip.h	2009-01-29 08:52:49.000000000 +0100
@@ -12,6 +12,8 @@
 
 #if defined(CONFIG_CPU_AT32AP700X)
 # include <mach/at32ap700x.h>
+#elif defined(CONFIG_CPU_AT32AP720X)
+# include <mach/at32ap720x.h>
 #else
 # error Unknown chip type selected
 #endif
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/cpu.h linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/cpu.h
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/cpu.h	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/cpu.h	2009-01-29 08:52:49.000000000 +0100
@@ -20,6 +20,19 @@
 # define cpu_is_at32ap7000()	(0)
 #endif
 
+#ifdef CONFIG_CPU_AT32AP720X
+# define cpu_is_at32ap7200()	(1)
+#else
+# define cpu_is_at32ap7200()	(0)
+#endif
+
+/*
+ * Unfortunately, only AP700x has a non-broken COUNT/COMPARE
+ * implementation. Other chips need to use different timers. The good
+ * news is that these timers are usually better anyway.
+ */
+#define cpu_has_working_compare()	(cpu_is_at32ap7000())
+
 /*
  * Since this is AVR32, we will never run on any AT91 CPU. But these
  * definitions may reduce clutter in common drivers.
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/hmatrix.h linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/hmatrix.h
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/hmatrix.h	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/hmatrix.h	2009-01-29 08:52:49.000000000 +0100
@@ -15,6 +15,9 @@
 void hmatrix_write_reg(unsigned long offset, u32 value);
 u32 hmatrix_read_reg(unsigned long offset);
 
+void hmatrix_set_default_master(unsigned int slave, unsigned int master);
+void hmatrix_set_priority(unsigned int slave, unsigned int master,
+		unsigned int priority);
 void hmatrix_sfr_set_bits(unsigned int slave_id, u32 mask);
 void hmatrix_sfr_clear_bits(unsigned int slave_id, u32 mask);
 
@@ -33,6 +36,7 @@
 # define HMATRIX_SCFG_DEFMSTR_NONE	(  0 << 16)	/* No default master */
 # define HMATRIX_SCFG_DEFMSTR_LAST	(  1 << 16)	/* Last def master */
 # define HMATRIX_SCFG_DEFMSTR_FIXED	(  2 << 16)	/* Fixed def master */
+# define HMATRIX_SCFG_DEFMSTR_MASK	(  3 << 16)
 # define HMATRIX_SCFG_FIXED_DEFMSTR(m)	((m) << 18)	/* Fixed master ID */
 # define HMATRIX_SCFG_ARBT_ROUND_ROBIN	(  0 << 24)	/* RR arbitration */
 # define HMATRIX_SCFG_ARBT_FIXED_PRIO	(  1 << 24)	/* Fixed priority */
@@ -52,4 +56,12 @@
 /* Special Function Register. Bit definitions are chip-specific */
 #define HMATRIX_SFR(s)			(0x0110 + 4 * (s))
 
+#define HMATRIX_MAX_SLAVE	15
+#define HMATRIX_MAX_MASTER	15
+#define HMATRIX_MAX_PRIO	15
+
+/* Special master IDs for use with hmatrix_set_default_master() */
+#define HMATRIX_MASTER_NONE	16	/* No default master */
+#define HMATRIX_MASTER_LAST	17	/* Last master stays connected */
+
 #endif /* __HMATRIX_H */
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/init.h linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/init.h
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/init.h	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/init.h	2009-01-29 08:52:49.000000000 +0100
@@ -15,4 +15,10 @@
 
 void at32_setup_serial_console(unsigned int usart_id);
 
+/*
+ * Called from time_init() when a broken COUNT/COMPARE implementation
+ * is detected.
+ */
+void platform_time_init(void);
+
 #endif /* __ASM_AVR32_AT32AP_INIT_H__ */
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/irq.h linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/irq.h
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/irq.h	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/irq.h	2009-01-29 08:52:49.000000000 +0100
@@ -6,7 +6,7 @@
 #define AT32_EXTINT(n)	(EIM_IRQ_BASE + (n))
 
 #define GPIO_IRQ_BASE	(EIM_IRQ_BASE + NR_EIM_IRQS)
-#define NR_GPIO_CTLR	(5 /*internal*/ + 1 /*external*/)
+#define NR_GPIO_CTLR	(8 /*internal*/ + 1 /*external*/)
 #define NR_GPIO_IRQS	(NR_GPIO_CTLR * 32)
 
 #define NR_IRQS		(GPIO_IRQ_BASE + NR_GPIO_IRQS)
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/pm.h linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/pm.h
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/include/mach/pm.h	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/include/mach/pm.h	2009-01-29 08:52:49.000000000 +0100
@@ -11,13 +11,17 @@
 #define __ASM_AVR32_ARCH_PM_H
 
 /* Possible arguments to the "sleep" instruction */
-#define CPU_SLEEP_IDLE		0
-#define CPU_SLEEP_FROZEN	1
-#define CPU_SLEEP_STANDBY	2
-#define CPU_SLEEP_STOP		3
-#define CPU_SLEEP_STATIC	5
+#define CPU_SLEEP_IDLE		0x00
+#define CPU_SLEEP_FROZEN	0x01
+#define CPU_SLEEP_STANDBY	0x02
+#define CPU_SLEEP_STOP		0x03
+#define CPU_SLEEP_DEEPSTOP	0x04	/* Not valid on AP700x */
+#define CPU_SLEEP_STATIC	0x05
+#define CPU_SLEEP_SHUTDOWN	0x06	/* Not valid on AP700x */
+#define CPU_SLEEP_UNMASK_IRQ	0x80	/* Not valid on AP700x */
 
 #ifndef __ASSEMBLY__
+#if defined(CONFIG_CPU_AT32AP700X)
 extern void cpu_enter_idle(void);
 extern void cpu_enter_standby(unsigned long sdramc_base);
 
@@ -37,15 +41,57 @@
 {
 	/*
 	 * If we're using the COUNT and COMPARE registers for
-	 * timekeeping, we can't use the IDLE state.
+	 * timekeeping on AP7000, we can't use the IDLE state.
 	 */
 	if (disable_idle_sleep)
 		cpu_relax();
 	else
 		cpu_enter_idle();
 }
+#else
+static inline void cpu_disable_idle_sleep(void)
+{
+
+}
+
+static inline void cpu_enable_idle_sleep(void)
+{
+
+}
+
+static inline void cpu_enter_idle(void)
+{
+	/* Enable interrupts and sleep */
+	asm volatile("sleep %0"
+			:
+			: "i"(CPU_SLEEP_IDLE | CPU_SLEEP_UNMASK_IRQ)
+			: "memory");
+}
+
+static inline void cpu_idle_sleep(void)
+{
+	local_irq_disable();
+	if (!test_thread_flag(TIF_NEED_RESCHED))
+		cpu_enter_idle();
+	local_irq_enable();
+}
+#endif
 
 void intc_set_suspend_handler(unsigned long offset);
+
+extern unsigned long at32_get_reset_cause(void);
+
 #endif
 
+#define AT32_RCAUSE_POR		(1 <<  0)	/* Power-On Reset */
+#define AT32_RCAUSE_BOD		(1 <<  1)	/* Brown-Out Detected */
+#define AT32_RCAUSE_EXT		(1 <<  2)	/* External Reset */
+#define AT32_RCAUSE_WDT		(1 <<  3)	/* Watchdog Timeout */
+#define AT32_RCAUSE_JTAG	(1 <<  4)	/* JTAG Reset */
+#define AT32_RCAUSE_NTAE	(1 <<  5)	/* NanoTrace Access Error */
+#define AT32_RCAUSE_SLEEP	(1 <<  6)	/* Shutdown or Static mode */
+#define AT32_RCAUSE_CPUERR	(1 <<  7)	/* CPU Error */
+#define AT32_RCAUSE_OCDRST	(1 <<  8)	/* OCD Reset */
+#define AT32_RCAUSE_JTAGHARD	(1 <<  9)	/* JTAG Hard Reset */
+
 #endif /* __ASM_AVR32_ARCH_PM_H */
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/Makefile linux-2.6.28.2/arch/avr32/mach-at32ap/Makefile
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/Makefile	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/Makefile	2009-01-29 08:52:49.000000000 +0100
@@ -1,9 +1,14 @@
-obj-y				+= pdc.o clock.o intc.o extint.o pio.o hsmc.o
+obj-y				+= pdc.o clock.o intc.o extint.o hsmc.o
 obj-y				+= hmatrix.o
-obj-$(CONFIG_CPU_AT32AP700X)	+= at32ap700x.o pm-at32ap700x.o
+obj-$(CONFIG_PORTMUX_PIO)	+= pio.o
+obj-$(CONFIG_PORTMUX_GPIO_V2)	+= gpio-v2.o
+obj-$(CONFIG_TIMER_AST)		+= timer-ast.o
 obj-$(CONFIG_CPU_FREQ_AT32AP)	+= cpufreq.o
 obj-$(CONFIG_PM)		+= pm.o
 
+obj-$(CONFIG_CPU_AT32AP700X)	+= at32ap700x.o pm-at32ap700x.o
+obj-$(CONFIG_CPU_AT32AP720X)	+= at32ap720x.o pm-at32ap720x.o
+
 ifeq ($(CONFIG_PM_DEBUG),y)
 CFLAGS_pm.o	+= -DDEBUG
 endif
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/pm-at32ap700x.S linux-2.6.28.2/arch/avr32/mach-at32ap/pm-at32ap700x.S
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/pm-at32ap700x.S	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/pm-at32ap700x.S	2009-01-29 08:52:50.000000000 +0100
@@ -12,12 +12,9 @@
 #include <asm/thread_info.h>
 #include <mach/pm.h>
 
-#include "pm.h"
+#include "pm-v1.h"
 #include "sdramc.h"
 
-/* Same as 0xfff00000 but fits in a 21 bit signed immediate */
-#define PM_BASE	-0x100000
-
 	.section .bss, "wa", @nobits
 	.global	disable_idle_sleep
 	.type	disable_idle_sleep, @object
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/pm-at32ap720x.S linux-2.6.28.2/arch/avr32/mach-at32ap/pm-at32ap720x.S
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/pm-at32ap720x.S	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/pm-at32ap720x.S	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,110 @@
+/*
+ * Low-level Power Management code.
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+#include <mach/pm.h>
+
+#include "pm-v3.h"
+#include "sdramc.h"
+
+#ifdef CONFIG_PM
+	.section .init.text, "ax", @progbits
+
+	.global	pm_exception
+	.type	pm_exception, @function
+pm_exception:
+	/*
+	 * Exceptions are masked when we switch to this handler, so
+	 * we'll only get "unrecoverable" exceptions (offset 0.)
+	 */
+	sub	r12, pc, . - .Lpanic_msg
+	lddpc	pc, .Lpanic_addr
+
+	.align	2
+.Lpanic_addr:
+	.long	panic
+.Lpanic_msg:
+	.asciz	"Unrecoverable exception during suspend\n"
+	.size	pm_exception, . - pm_exception
+
+	.global	pm_irq0
+	.type	pm_irq0, @function
+pm_irq0:
+	/* Disable interrupts and return after the sleep instruction */
+	mfsr	r9, SYSREG_RSR_INT0
+	mtsr	SYSREG_RAR_INT0, r8
+	sbr	r9, SYSREG_GM_OFFSET
+	mtsr	SYSREG_RSR_INT0, r9
+	rete
+
+	/*
+	 * void cpu_enter_standby(unsigned long sdramc_base)
+	 *
+	 * Enter PM_SUSPEND_STANDBY mode. At this point, all drivers
+	 * are suspended and interrupts are disabled. Interrupts
+	 * marked as 'wakeup' event sources may still come along and
+	 * get us out of here.
+	 *
+	 * The SDRAM will be put into self-refresh mode (which does
+	 * not require a clock from the CPU), and the CPU will be put
+	 * into "frozen" mode (HSB bus stopped). The SDRAM controller
+	 * will automatically bring the SDRAM into normal mode on the
+	 * first access, and the power manager will automatically
+	 * start the HSB and CPU clocks upon a wakeup event.
+	 */
+	.global	pm_standby
+	.type	pm_standby, @function
+pm_standby:
+	/*
+	 * interrupts are already masked at this point, and EVBA
+	 * points to pm_exception above.
+	 */
+	ld.w	r10, r12[SDRAMC_LPR]
+	sub	r8, pc, . - 1f		/* return address for irq handler */
+	mov	r11, SDRAMC_LPR_LPCB_SELF_RFR
+	bfins	r10, r11, 0, 2		/* LPCB <- self Refresh */
+	sync	0			/* flush write buffer */
+	st.w	r12[SDRAMC_LPR], r10	/* put SDRAM in self-refresh mode */
+	ld.w	r11, r12[SDRAMC_LPR]
+	sleep	CPU_SLEEP_FROZEN | CPU_SLEEP_UNMASK_IRQ
+1:	mask_interrupts
+	retal	r12
+	.size	pm_standby, . - pm_standby
+
+	.global	pm_suspend_to_ram
+	.type	pm_suspend_to_ram, @function
+pm_suspend_to_ram:
+	/*
+	 * interrupts are already masked at this point, and EVBA
+	 * points to pm_exception above.
+	 */
+	mov	r11, 0
+	cache	r11[2], 8		/* clean all dcache lines */
+	sync	0			/* flush write buffer */
+	ld.w	r10, r12[SDRAMC_LPR]
+	sub	r8, pc, . - 1f		/* return address for irq handler */
+	mov	r11, SDRAMC_LPR_LPCB_SELF_RFR
+	bfins	r10, r11, 0, 2		/* LPCB <- self refresh */
+	st.w	r12[SDRAMC_LPR], r10	/* put SDRAM in self-refresh mode */
+	ld.w	r11, r12[SDRAMC_LPR]
+
+	sleep	CPU_SLEEP_STOP | CPU_SLEEP_UNMASK_IRQ
+1:	mask_interrupts
+
+	retal	r12
+	.size	pm_suspend_to_ram, . - pm_suspend_to_ram
+
+	.global	pm_sram_end
+	.type	pm_sram_end, @function
+pm_sram_end:
+	.size	pm_sram_end, 0
+
+#endif /* CONFIG_PM */
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/pm.h linux-2.6.28.2/arch/avr32/mach-at32ap/pm.h
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/pm.h	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/pm.h	1970-01-01 01:00:00.000000000 +0100
@@ -1,112 +0,0 @@
-/*
- * Register definitions for the Power Manager (PM)
- */
-#ifndef __ARCH_AVR32_MACH_AT32AP_PM_H__
-#define __ARCH_AVR32_MACH_AT32AP_PM_H__
-
-/* PM register offsets */
-#define PM_MCCTRL				0x0000
-#define PM_CKSEL				0x0004
-#define PM_CPU_MASK				0x0008
-#define PM_HSB_MASK				0x000c
-#define PM_PBA_MASK				0x0010
-#define PM_PBB_MASK				0x0014
-#define PM_PLL0					0x0020
-#define PM_PLL1					0x0024
-#define PM_IER					0x0040
-#define PM_IDR					0x0044
-#define PM_IMR					0x0048
-#define PM_ISR					0x004c
-#define PM_ICR					0x0050
-#define PM_GCCTRL(x)				(0x0060 + 4 * (x))
-#define PM_RCAUSE				0x00c0
-
-/* Bitfields in CKSEL */
-#define PM_CPUSEL_OFFSET			0
-#define PM_CPUSEL_SIZE				3
-#define PM_CPUDIV_OFFSET			7
-#define PM_CPUDIV_SIZE				1
-#define PM_HSBSEL_OFFSET			8
-#define PM_HSBSEL_SIZE				3
-#define PM_HSBDIV_OFFSET			15
-#define PM_HSBDIV_SIZE				1
-#define PM_PBASEL_OFFSET			16
-#define PM_PBASEL_SIZE				3
-#define PM_PBADIV_OFFSET			23
-#define PM_PBADIV_SIZE				1
-#define PM_PBBSEL_OFFSET			24
-#define PM_PBBSEL_SIZE				3
-#define PM_PBBDIV_OFFSET			31
-#define PM_PBBDIV_SIZE				1
-
-/* Bitfields in PLL0 */
-#define PM_PLLEN_OFFSET				0
-#define PM_PLLEN_SIZE				1
-#define PM_PLLOSC_OFFSET			1
-#define PM_PLLOSC_SIZE				1
-#define PM_PLLOPT_OFFSET			2
-#define PM_PLLOPT_SIZE				3
-#define PM_PLLDIV_OFFSET			8
-#define PM_PLLDIV_SIZE				8
-#define PM_PLLMUL_OFFSET			16
-#define PM_PLLMUL_SIZE				8
-#define PM_PLLCOUNT_OFFSET			24
-#define PM_PLLCOUNT_SIZE			6
-#define PM_PLLTEST_OFFSET			31
-#define PM_PLLTEST_SIZE				1
-
-/* Bitfields in ICR */
-#define PM_LOCK0_OFFSET				0
-#define PM_LOCK0_SIZE				1
-#define PM_LOCK1_OFFSET				1
-#define PM_LOCK1_SIZE				1
-#define PM_WAKE_OFFSET				2
-#define PM_WAKE_SIZE				1
-#define PM_CKRDY_OFFSET				5
-#define PM_CKRDY_SIZE				1
-#define PM_MSKRDY_OFFSET			6
-#define PM_MSKRDY_SIZE				1
-
-/* Bitfields in GCCTRL0 */
-#define PM_OSCSEL_OFFSET			0
-#define PM_OSCSEL_SIZE				1
-#define PM_PLLSEL_OFFSET			1
-#define PM_PLLSEL_SIZE				1
-#define PM_CEN_OFFSET				2
-#define PM_CEN_SIZE				1
-#define PM_DIVEN_OFFSET				4
-#define PM_DIVEN_SIZE				1
-#define PM_DIV_OFFSET				8
-#define PM_DIV_SIZE				8
-
-/* Bitfields in RCAUSE */
-#define PM_POR_OFFSET				0
-#define PM_POR_SIZE				1
-#define PM_EXT_OFFSET				2
-#define PM_EXT_SIZE				1
-#define PM_WDT_OFFSET				3
-#define PM_WDT_SIZE				1
-#define PM_NTAE_OFFSET				4
-#define PM_NTAE_SIZE				1
-
-/* Bit manipulation macros */
-#define PM_BIT(name)					\
-	(1 << PM_##name##_OFFSET)
-#define PM_BF(name,value)				\
-	(((value) & ((1 << PM_##name##_SIZE) - 1))	\
-	 << PM_##name##_OFFSET)
-#define PM_BFEXT(name,value)				\
-	(((value) >> PM_##name##_OFFSET)		\
-	 & ((1 << PM_##name##_SIZE) - 1))
-#define PM_BFINS(name,value,old)\
-	(((old) & ~(((1 << PM_##name##_SIZE) - 1)	\
-		    << PM_##name##_OFFSET))		\
-	 | PM_BF(name,value))
-
-/* Register access macros */
-#define pm_readl(reg)							\
-	__raw_readl((void __iomem __force *)PM_BASE + PM_##reg)
-#define pm_writel(reg,value)						\
-	__raw_writel((value), (void __iomem __force *)PM_BASE + PM_##reg)
-
-#endif /* __ARCH_AVR32_MACH_AT32AP_PM_H__ */
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/pm-v1.h linux-2.6.28.2/arch/avr32/mach-at32ap/pm-v1.h
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/pm-v1.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/pm-v1.h	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,112 @@
+/*
+ * Register definitions for the Power Manager (PM)
+ */
+#ifndef __ARCH_AVR32_MACH_AT32AP_PM_H__
+#define __ARCH_AVR32_MACH_AT32AP_PM_H__
+
+/* PM register offsets */
+#define PM_MCCTRL				0x0000
+#define PM_CKSEL				0x0004
+#define PM_CPU_MASK				0x0008
+#define PM_HSB_MASK				0x000c
+#define PM_PBA_MASK				0x0010
+#define PM_PBB_MASK				0x0014
+#define PM_PLL0					0x0020
+#define PM_PLL1					0x0024
+#define PM_IER					0x0040
+#define PM_IDR					0x0044
+#define PM_IMR					0x0048
+#define PM_ISR					0x004c
+#define PM_ICR					0x0050
+#define PM_GCCTRL(x)				(0x0060 + 4 * (x))
+#define PM_RCAUSE				0x00c0
+
+/* Bitfields in CKSEL */
+#define PM_CPUSEL_OFFSET			0
+#define PM_CPUSEL_SIZE				3
+#define PM_CPUDIV_OFFSET			7
+#define PM_CPUDIV_SIZE				1
+#define PM_HSBSEL_OFFSET			8
+#define PM_HSBSEL_SIZE				3
+#define PM_HSBDIV_OFFSET			15
+#define PM_HSBDIV_SIZE				1
+#define PM_PBASEL_OFFSET			16
+#define PM_PBASEL_SIZE				3
+#define PM_PBADIV_OFFSET			23
+#define PM_PBADIV_SIZE				1
+#define PM_PBBSEL_OFFSET			24
+#define PM_PBBSEL_SIZE				3
+#define PM_PBBDIV_OFFSET			31
+#define PM_PBBDIV_SIZE				1
+
+/* Bitfields in PLL0 */
+#define PM_PLLEN_OFFSET				0
+#define PM_PLLEN_SIZE				1
+#define PM_PLLOSC_OFFSET			1
+#define PM_PLLOSC_SIZE				1
+#define PM_PLLOPT_OFFSET			2
+#define PM_PLLOPT_SIZE				3
+#define PM_PLLDIV_OFFSET			8
+#define PM_PLLDIV_SIZE				8
+#define PM_PLLMUL_OFFSET			16
+#define PM_PLLMUL_SIZE				8
+#define PM_PLLCOUNT_OFFSET			24
+#define PM_PLLCOUNT_SIZE			6
+#define PM_PLLTEST_OFFSET			31
+#define PM_PLLTEST_SIZE				1
+
+/* Bitfields in ICR */
+#define PM_LOCK0_OFFSET				0
+#define PM_LOCK0_SIZE				1
+#define PM_LOCK1_OFFSET				1
+#define PM_LOCK1_SIZE				1
+#define PM_WAKE_OFFSET				2
+#define PM_WAKE_SIZE				1
+#define PM_CKRDY_OFFSET				5
+#define PM_CKRDY_SIZE				1
+#define PM_MSKRDY_OFFSET			6
+#define PM_MSKRDY_SIZE				1
+
+/* Bitfields in GCCTRL0 */
+#define PM_OSCSEL_OFFSET			0
+#define PM_OSCSEL_SIZE				1
+#define PM_PLLSEL_OFFSET			1
+#define PM_PLLSEL_SIZE				1
+#define PM_CEN_OFFSET				2
+#define PM_CEN_SIZE				1
+#define PM_DIVEN_OFFSET				4
+#define PM_DIVEN_SIZE				1
+#define PM_DIV_OFFSET				8
+#define PM_DIV_SIZE				8
+
+/* Bitfields in RCAUSE */
+#define PM_POR_OFFSET				0
+#define PM_POR_SIZE				1
+#define PM_EXT_OFFSET				2
+#define PM_EXT_SIZE				1
+#define PM_WDT_OFFSET				3
+#define PM_WDT_SIZE				1
+#define PM_NTAE_OFFSET				4
+#define PM_NTAE_SIZE				1
+
+/* Bit manipulation macros */
+#define PM_BIT(name)					\
+	(1 << PM_##name##_OFFSET)
+#define PM_BF(name,value)				\
+	(((value) & ((1 << PM_##name##_SIZE) - 1))	\
+	 << PM_##name##_OFFSET)
+#define PM_BFEXT(name,value)				\
+	(((value) >> PM_##name##_OFFSET)		\
+	 & ((1 << PM_##name##_SIZE) - 1))
+#define PM_BFINS(name,value,old)\
+	(((old) & ~(((1 << PM_##name##_SIZE) - 1)	\
+		    << PM_##name##_OFFSET))		\
+	 | PM_BF(name,value))
+
+/* Register access macros */
+#define pm_readl(reg)							\
+	__raw_readl((void __iomem __force *)PM_BASE + PM_##reg)
+#define pm_writel(reg,value)						\
+	__raw_writel((value), (void __iomem __force *)PM_BASE + PM_##reg)
+
+#endif /* __ARCH_AVR32_MACH_AT32AP_PM_H__ */
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/pm-v3.h linux-2.6.28.2/arch/avr32/mach-at32ap/pm-v3.h
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/pm-v3.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/pm-v3.h	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __PM_V3_H__
+#define __PM_V3_H__
+
+#include <mach/chip.h>
+
+/* PM Register offsets */
+#ifndef __ASSEMBLY__
+struct pm_regs {
+	u32	MCCTRL;			/* Main Clock Control */
+	u32	CKSEL;			/* Clock Select */
+	u32	CPUMASK;		/* CPU Clock Mask */
+	u32	HSBMASK;		/* HSB Clock Mask */
+	u32	PBAMASK;		/* PBA Clock Mask */
+	u32	PBBMASK;		/* PBB Clock Mask */
+	u32	PBADIVMASK;		/* Divided PBA Clock Mask */
+	u32	PBBDIVMASK;		/* Divided PBB Clock Mask */
+	u32	__reserved1[8];
+	u32	PLL[3];			/* PLL Control */
+	u32	__reserved2[13];
+	u32	OSCCTRL[3];		/* Oscillator Control */
+	u32	__reserved3[5];
+	u32	OSCCTRL32;		/* 32 kHz Oscillator Control */
+	u32	__reserved4[7];
+	u32	IER;			/* Interrupt Enable */
+	u32	IDR;			/* Interrupt Disable */
+	u32	IMR;			/* Interrupt Mask */
+	u32	ISR;			/* Interrupt Status */
+	u32	ICR;			/* Interrupt Clear */
+	u32	POSCSR;			/* Power and Oscillator Status */
+	u32	__reserved5[10];
+	u32	GCCTRL[8];		/* Generic Clock Control */
+	u32	__reserved6[8];
+	u32	RCCR;			/* RC Oscillator Calibration */
+	u32	BGCR;			/* Bandgap Calibration */
+	u32	VREGCR;			/* Buck Regulator Calibration */
+	u32	BOD;			/* BOD Level */
+	u32	PPCR;			/* Peripheral Power Control */
+	u32	__reserved7[11];
+	u32	RCAUSE;			/* Reset Cause */
+	u32	WCAUSE;			/* Wake Cause */
+	u32	AWEN;			/* Asynchronous Wake Enable */
+	u32	__reserved8[14];
+	u32	GPLP;			/* General Purpose Low-Power */
+};
+#endif
+
+/* Assembly-friendly register offsets; same as above */
+#define PM_MCCTRL			0x0000
+#define PM_CKSEL			0x0004
+#define PM_CPUMASK			0x0008
+#define PM_HSBMASK			0x000c
+#define PM_PBAMASK			0x0010
+#define PM_PBBMASK			0x0014
+#define PM_PBADIVMASK			0x0018
+#define PM_PBBDIVMASK			0x001c
+#define PM_PLL0				0x0040
+#define PM_PLL1				0x0044
+#define PM_PLL2				0x0048
+#define PM_OSCCTRL0			0x0080
+#define PM_OSCCTRL1			0x0084
+#define PM_OSCCTRL2			0x0088
+#define PM_OSCCTRL32			0x00a0
+#define PM_IER				0x00c0
+#define PM_IDR				0x00c4
+#define PM_IMR				0x00c8
+#define PM_ISR				0x00cc
+#define PM_ICR				0x00d0
+#define PM_POSCSR			0x00d4
+#define PM_GCCTRL			0x0100
+#define PM_RCCR				0x0140
+#define PM_BGCR				0x0144
+#define PM_VREGCR			0x0148
+#define PM_BOD				0x014c
+#define PM_PPCR				0x0150
+#define PM_RC_RCAUSE			0x0180
+#define PM_WCAUSE			0x0184
+#define PM_AWEN				0x0188
+#define PM_GPLP				0x01c0
+
+/* Bits in MCCTRL */
+#define PM_MCCTRL_MCSEL_START		0
+#define PM_MCCTRL_MCSEL_SIZE		2
+#define PM_MCCTRL_OSC0EN_BIT		2
+#define PM_MCCTRL_OSC1EN_BIT		3
+#define PM_MCCTRL_OSC2EN_BIT		4
+#define PM_MCCTRL_CRIPEL_BIT		24
+
+/* Bits in CKSEL */
+#define PM_CKSEL_CPUSEL_START		0
+#define PM_CKSEL_CPUSEL_SIZE		3
+#define PM_CKSEL_CPUDIV_BIT		7
+#define PM_CKSEL_HSBSEL_START		8
+#define PM_CKSEL_HSBSEL_SIZE		3
+#define PM_CKSEL_HSBDIV_BIT		15
+#define PM_CKSEL_PBASEL_START		16
+#define PM_CKSEL_PBASEL_SIZE		3
+#define PM_CKSEL_PBADIV_BIT		23
+#define PM_CKSEL_PBBSEL_START		24
+#define PM_CKSEL_PBBSEL_SIZE		3
+#define PM_CKSEL_PBBDIV_BIT		31
+
+/* Bits in CPUMASK */
+#define PM_CPUMASK_SYSTIMER_BIT		16
+
+/* Bits in PLLx */
+#define PM_PLLx_PLLEN_BIT		0
+#define PM_PLLx_PLLOSC_START		1
+#define PM_PLLx_PLLOSC_SIZE		2
+#define PM_PLLx_PLLOPT_START		3
+#define PM_PLLx_PLLOPT_SIZE		3
+#define PM_PLLx_PLLBPL_BIT		7
+#define PM_PLLx_PLLDIV_START		8
+#define PM_PLLx_PLLDIV_SIZE		6
+#define PM_PLLx_PLLMUL_START		16
+#define PM_PLLx_PLLMUL_SIZE		6
+#define PM_PLLx_PLLCOUNT_START		24
+#define PM_PLLx_PLLCOUNT_SIZE		6
+#define PM_PLLx_PLLIOTESTEN_BIT		30
+#define PM_PLLx_PLLTEST_BIT		31
+
+/* Bits in OSCCTRLx */
+#define PM_OSCCTRLx_MODE_START		0
+#define PM_OSCCTRLx_MODE_SIZE		4
+#define PM_OSCCTRLx_STARTUP_START	8
+#define PM_OSCCTRLx_STARTUP_SIZE	3
+
+/* Bits in OSCCTRL32 */
+#define PM_OSCCTRL32_OSC32EN_BIT	0
+#define PM_OSCCTRL32_MODE_START		8
+#define PM_OSCCTRL32_MODE_SIZE		3
+#define PM_OSCCTRL32_STARTUP_START	16
+#define PM_OSCCTRL32_STARTUP_SIZE	3
+
+/* Bits in IER/IDR/IMR/ISR/ICR */
+#define PM_ISR_OSC0RDY_BIT		0
+#define PM_ISR_OSC1RDY_BIT		1
+#define PM_ISR_OSC2RDY_BIT		2
+#define PM_ISR_OSC32RDY_BIT		7
+#define PM_ISR_LOCK0_BIT		8
+#define PM_ISR_LOCK1_BIT		9
+#define PM_ISR_LOCK2_BIT		10
+#define PM_ISR_LOCK0LOST_BIT		16
+#define PM_ISR_LOCK1LOST_BIT		17
+#define PM_ISR_LOCK2LOST_BIT		18
+#define PM_ISR_CKRDY_BIT		24
+#define PM_ISR_MSKRDY_BIT		25
+#define PM_ISR_WAKE_BIT			26
+#define PM_ISR_BODDET_BIT		27
+#define PM_ISR_PERRDY_BIT		28
+
+/* Bits in POSCSR */
+#define PM_POSCSR_OSC0RDY_BIT		0
+#define PM_POSCSR_OSC1RDY_BIT		1
+#define PM_POSCSR_OSC32RDY_BIT		7
+#define PM_POSCSR_LOCK0_BIT		8
+#define PM_POSCSR_LOCK1_BIT		9
+#define PM_POSCSR_LOCK0LOST_BIT		16
+#define PM_POSCSR_LOCK1LOST_BIT		17
+#define PM_POSCSR_CKRDY_BIT		24
+#define PM_POSCSR_MSKRDY_BIT		25
+#define PM_POSCSR_WAKE_BIT		26
+#define PM_POSCSR_BODDET_BIT		27
+#define PM_POSCSR_PERRDY_BIT		28
+
+/* Bits in GCCTRL */
+#define PM_GCCTRL_CEN_BIT		0
+#define PM_GCCTRL_DIVEN_BIT		1
+#define PM_GCCTRL_OSCSEL_START		8
+#define PM_GCCTRL_OSCSEL_SIZE		4
+#define PM_GCCTRL_DIV_START		16
+#define PM_GCCTRL_DIV_SIZE		8
+
+/* Bits in RCCR */
+#define PM_RCCR_CALIB_START		0
+#define PM_RCCR_CALIB_SIZE		10
+#define PM_RCCR_FCD_BIT			16
+#define PM_RCCR_KEY_START		24
+#define PM_RCCR_KEY_SIZE		8
+
+/* Bits in BGCR */
+#define PM_BGCR_CALIB_START		0
+#define PM_BGCR_CALIB_SIZE		3
+#define PM_BGCR_FCD_BIT			16
+#define PM_BGCR_KEY_START		24
+#define PM_BGCR_KEY_SIZE		8
+
+/* Bits in VREGCR */
+#define PM_VREGCR_CALIB_START		0
+#define PM_VREGCR_CALIB_SIZE		3
+#define PM_VREGCR_FCD_BIT		16
+#define PM_VREGCR_KEY_START		24
+#define PM_VREGCR_KEY_SIZE		8
+
+/* Bits in BOD */
+#define PM_BOD_LEVEL_START		0
+#define PM_BOD_LEVEL_SIZE		6
+#define PM_BOD_HYST_BIT			6
+#define PM_BOD_CTRL_START		8
+#define PM_BOD_CTRL_SIZE		2
+#define PM_BOD_FCD_BIT			16
+#define PM_BOD_KEY_START		24
+#define PM_BOD_KEY_SIZE			8
+
+/* Bits in PPCR */
+#define PM_PPCR_EBI_VOLT_BIT		0
+#define PM_PPCR_UTMI_CTRL_BIT		1
+#define PM_PPCR_KEY_START		24
+#define PM_PPCR_KEY_SIZE		8
+
+/* Bits in RC_RCAUSE */
+#define PM_RC_RCAUSE_POR_BIT		0
+#define PM_RC_RCAUSE_BOD_BIT		1
+#define PM_RC_RCAUSE_EXT_BIT		2
+#define PM_RC_RCAUSE_WDT_BIT		3
+#define PM_RC_RCAUSE_JTAG_BIT		4
+#define PM_RC_RCAUSE_NTAE_BIT		5
+#define PM_RC_RCAUSE_SLEEP_BIT		6
+#define PM_RC_RCAUSE_CPUERR_BIT		7
+#define PM_RC_RCAUSE_OCDRST_BIT		8
+#define PM_RC_RCAUSE_JTAGHARD_BIT	9
+
+/* Bits in WCAUSE */
+#define PM_WCAUSE_PERIPH0_BIT		0
+#define PM_WCAUSE_PERIPH1_BIT		1
+#define PM_WCAUSE_EIC_BIT		16
+#define PM_WCAUSE_RTC_BIT		17
+
+/* Constants for MCCTRL:MCSEL */
+#define PM_MCSEL_SLOW			0
+#define PM_MCSEL_OSC0			1
+#define PM_MCSEL_PLL0			2
+
+/* Constants for OSCCTRLx:MODE */
+#define PM_MODE_EXT_CLOCK		0
+#define PM_MODE_CRYSTAL_ACG		1
+#define PM_MODE_CRYSTAL_G0		4
+#define PM_MODE_CRYSTAL_G1		5
+#define PM_MODE_CRYSTAL_G2		6
+#define PM_MODE_CRYSTAL_G3		7
+
+/* Constants for GCCTRL:OSCSEL */
+#define PM_OSCSEL_SLOW			0
+#define PM_OSCSEL_CLK32			1
+#define PM_OSCSEL_OSC0			2
+#define PM_OSCSEL_OSC1			3
+#define PM_OSCSEL_PLL0			4
+#define PM_OSCSEL_PLL1			5
+
+/* Constants for BOD:CTRL */
+#define PM_CTRL_OFF1			0
+#define PM_CTRL_ENABLED			1
+#define PM_CTRL_ENABLED_NORESET		2
+#define PM_CTRL_OFF2			3
+
+/* Bit manipulation macros */
+#define PM_BIT(name)						\
+	(1 << PM_##name##_BIT)
+#define PM_BF(name,value)					\
+	(((value) & ((1 << PM_##name##_SIZE) - 1))		\
+	 << PM_##name##_START)
+#define PM_BFEXT(name,value)					\
+	(((value) >> PM_##name##_START)				\
+	 & ((1 << PM_##name##_SIZE) - 1))
+#define PM_BFINS(name,value,old)				\
+	(((old) & ~(((1 << PM_##name##_SIZE) - 1)		\
+		    << PM_##name##_START))			\
+	 | PM_BF(name,value))
+
+/* Register access macros */
+#define __pm_regs ((struct pm_regs __iomem __force *)PM_BASE)
+#define pm_readl(reg)						\
+	__raw_readl(&__pm_regs->reg)
+#define pm_writel(reg, value)					\
+	__raw_writel(value, &__pm_regs->reg)
+
+#endif /* __PM_V3_H__ */
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/sdc.h linux-2.6.28.2/arch/avr32/mach-at32ap/sdc.h
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/sdc.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/sdc.h	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,103 @@
+/* SDC */
+
+/* Register offsets */
+#define SDC_CTRL			0x0000
+#define SDC_ASYNC			0x0004
+#define SDC_SYNC			0x0008
+#define SDC_FILTERDUR			0x000c
+#define SDC_OSCCTRL32			0x0010
+#define SDC_STATUS			0x0014
+#define SDC_ECR				0x0018
+#define SDC_IER				0x001c
+#define SDC_IDR				0x0020
+#define SDC_IMR				0x0024
+#define SDC_GPLP			0x0040
+
+/* Bits in CTRL */
+#define SDC_CTRL_PIN_EN_BIT		0
+#define SDC_CTRL_AST_EN_BIT		8
+#define SDC_CTRL_WDT_EN_BIT		9
+#define SDC_CTRL_OCD_EN_BIT		10
+#define SDC_CTRL_JTAG_EN_BIT		11
+#define SDC_CTRL_CORE_POR_TEST_BIT	23
+#define SDC_CTRL_KEY_START		24
+#define SDC_CTRL_KEY_SIZE		8
+
+/* Bits in ASYNC */
+#define SDC_ASYNC_MODE_BIT		4
+#define SDC_ASYNC_POL_BIT		8
+#define SDC_ASYNC_KEY_START		24
+#define SDC_ASYNC_KEY_SIZE		8
+
+/* Bits in SYNC */
+#define SDC_SYNC_EN_BIT			0
+#define SDC_SYNC_MODE_BIT		4
+#define SDC_SYNC_POL_BIT		8
+#define SDC_SYNC_FILTER_BIT		12
+#define SDC_SYNC_KEY_START		24
+#define SDC_SYNC_KEY_SIZE		8
+
+/* Bits in FILTERDUR */
+#define SDC_FILTERDUR_Duration_START	0
+#define SDC_FILTERDUR_Duration_SIZE	16
+#define SDC_FILTERDUR_KEY_START		24
+#define SDC_FILTERDUR_KEY_SIZE		8
+
+/* Bits in OSCCTRL32 */
+#define SDC_OSCCTRL32_OSC32EN_BIT	0
+#define SDC_OSCCTRL32_MODE_START	8
+#define SDC_OSCCTRL32_MODE_SIZE		4
+#define SDC_OSCCTRL32_STARTUP_START	16
+#define SDC_OSCCTRL32_STARTUP_SIZE	3
+#define SDC_OSCCTRL32_KEY_START		24
+#define SDC_OSCCTRL32_KEY_SIZE		8
+
+/* Bits in STATUS */
+#define SDC_STATUS_PIN_EVENT_BIT	0
+#define SDC_STATUS_AST_EVENT_BIT	8
+#define SDC_STATUS_WDT_EVENT_BIT	9
+#define SDC_STATUS_OCD_EVENT_BIT	10
+#define SDC_STATUS_JTAG_EVENT_BIT	11
+#define SDC_STATUS_PIN_BIT		16
+#define SDC_STATUS_BUSY_BIT		24
+#define SDC_STATUS_SWTCH_BIT		30
+#define SDC_STATUS_VBAT_BIT		31
+
+/* Bits in ECR */
+#define SDC_ECR_PIN_EVENT_BIT		0
+#define SDC_ECR_AST_EVENT_BIT		8
+#define SDC_ECR_WDT_EVENT_BIT		9
+#define SDC_ECR_OCD_EVENT_BIT		10
+#define SDC_ECR_JTAG_EVENT_BIT		11
+
+/* Bits in IER */
+#define SDC_IER_PIN_EVENT_BIT		0
+#define SDC_IER_READY_BIT		24
+
+/* Bits in IDR */
+#define SDC_IDR_PIN_EVENT_BIT		0
+#define SDC_IDR_READY_BIT		24
+
+/* Bits in IMR */
+#define SDC_IMR_PIN_EVENT_BIT		0
+#define SDC_IMR_READY_BIT		24
+
+/* Bit manipulation macros */
+#define SDC_BIT(name)						\
+	(1 << SDC_##name##_BIT)
+#define SDC_BF(name,value)					\
+	(((value) & ((1 << SDC_##name##_SIZE) - 1))		\
+	 << SDC_##name##_START)
+#define SDC_BFEXT(name,value)					\
+	(((value) >> SDC_##name##_START)			\
+	 & ((1 << SDC_##name##_SIZE) - 1))
+#define SDC_BFINS(name,value,old)				\
+	(((old) & ~(((1 << SDC_##name##_SIZE) - 1)		\
+		    << SDC_##name##_START))			\
+	 | SDC_BF(name,value))
+
+/* Register access macros */
+#define sdc_readl(reg)						\
+	__raw_readl((void __iomem __force *)(SDC_BASE + SDC_##reg))
+#define sdc_writel(reg, value)					\
+	__raw_writel(value, (void __iomem __force *)(SDC_BASE + SDC_##reg))
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/timer-ast.c linux-2.6.28.2/arch/avr32/mach-at32ap/timer-ast.c
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/timer-ast.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/timer-ast.c	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,191 @@
+/*
+ * Asynchronous Timer (AST) used as clocksource / clockevent
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+
+#include <asm/ast_regs.h>
+
+static void __iomem *ast_regs;
+
+static inline void ast_wait_ready(void)
+{
+	while (ast_readl(ast_regs, SR) & AST_BIT(BUSY))
+		cpu_relax();
+}
+
+static cycle_t read_ast_counter(void)
+{
+	return ast_readl(ast_regs, CV);
+}
+
+static struct clocksource ast_clksrc = {
+	.name	= "ast",
+	.rating	= 400,
+	.read	= read_ast_counter,
+	.mask	= CLOCKSOURCE_MASK(32),
+	.shift	= 16,
+	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static irqreturn_t ast_clkevt_interrupt(int irq, void *dev_id)
+{
+	struct clock_event_device *clkevt = dev_id;
+
+	/*
+	 * We make sure delta is always long enough so that the BUSY
+	 * bit is never set at this point.
+	 */
+	ast_writel(ast_regs, SCR, AST_BIT(ALARM0));
+	clkevt->event_handler(clkevt);
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction ast_clkevt_irqaction = {
+	.handler	= ast_clkevt_interrupt,
+	.flags		= IRQF_TIMER | IRQF_DISABLED,
+	.name		= "timer-ast",
+};
+
+static int ast_next_event(unsigned long delta,
+		struct clock_event_device *clkevt)
+{
+	ast_wait_ready();
+	ast_writel(ast_regs, AR0, ast_readl(ast_regs, CV) + delta);
+
+	return 0;
+}
+
+static void ast_mode(enum clock_event_mode mode,
+		struct clock_event_device *evdev)
+{
+	switch (mode) {
+	case CLOCK_EVT_MODE_ONESHOT:
+	case CLOCK_EVT_MODE_RESUME:
+		/* Make sure we don't trigger an alarm before we get
+		 * around to reprogramming it.
+		 */
+		ast_wait_ready();
+		ast_writel(ast_regs, AR0, ast_readl(ast_regs, CV) - 1);
+		ast_wait_ready();
+		ast_writel(ast_regs, SCR, AST_BIT(ALARM0));
+		ast_wait_ready();
+		ast_writel(ast_regs, IER, AST_BIT(ALARM0));
+		break;
+	case CLOCK_EVT_MODE_UNUSED:
+	case CLOCK_EVT_MODE_SHUTDOWN:
+		ast_writel(ast_regs, IDR, AST_BIT(ALARM0));
+		break;
+	default:
+		BUG();
+	}
+}
+
+static struct clock_event_device ast_clkevt = {
+	.name		= "ast",
+	.features	= CLOCK_EVT_FEAT_ONESHOT,
+	.shift		= 16,
+	.rating		= 400,
+	.cpumask	= CPU_MASK_CPU0,
+	.set_next_event	= ast_next_event,
+	.set_mode	= ast_mode,
+};
+
+void __init ast_time_init(struct platform_device *pdev, unsigned int clksel)
+{
+	struct clk *clk, *pclk;
+	struct resource *regs;
+	unsigned long ast_hz;
+	int irq;
+	int ret;
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		pr_debug("AST: No MMIO resource\n");
+		return;
+	}
+
+	pclk = clk_get(&pdev->dev, "pclk");
+	if (!pclk) {
+		pr_debug("AST: No peripheral clock (pclk)\n");
+		return;
+	}
+	clk_enable(pclk);
+
+	/* Too early for ioremap() */
+	ast_regs = (void __iomem __force *)regs->start;
+
+	switch (clksel) {
+	case AST_CLOCK_SLOW:
+		clk = clk_get(NULL, "rcosc");
+		break;
+	case AST_CLOCK_OSC32:
+		clk = clk_get(NULL, "osc32");
+		break;
+	case AST_CLOCK_PB:
+		clk = pclk;
+		break;
+	case AST_CLOCK_GC:
+		clk = clk_get(&pdev->dev, "gclk");
+		break;
+	default:
+		clk = NULL;
+		break;
+	}
+
+	if (!clk) {
+		pr_debug("AST: clock %u invalid, using pb clock\n", clksel);
+		clk = pclk;
+	}
+	clk_enable(clk);
+
+	ast_writel(ast_regs, CLOCK,
+			AST_BF(CLOCK_CSSEL, clksel) | AST_BIT(CLOCK_CEN));
+	ast_writel(ast_regs, CR, AST_BIT(CR_EN) | AST_BIT(CR_PCLR));
+
+	/* Using hardcoded divide-by-two prescaler */
+	ast_hz = clk_get_rate(clk) / 2;
+	ast_clksrc.mult = clocksource_hz2mult(ast_hz, ast_clksrc.shift);
+
+	ret = clocksource_register(&ast_clksrc);
+	if (ret)
+		pr_debug("AST: could not register clocksource: %d\n", ret);
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		pr_debug("AST: No IRQ resource, won't setup clockevent\n");
+		return;
+	}
+
+	ast_clkevt.mult = div_sc(ast_hz, NSEC_PER_SEC, ast_clkevt.shift);
+	ast_clkevt.max_delta_ns = clockevent_delta2ns((u32)~0U, &ast_clkevt);
+	ast_clkevt.min_delta_ns = clockevent_delta2ns(2, &ast_clkevt) + 100;
+
+	ast_clkevt_irqaction.dev_id = &ast_clkevt;
+
+	ret = setup_irq(irq, &ast_clkevt_irqaction);
+	if (ret) {
+		pr_debug("AST: Could not request IRQ %d: %d\n", irq, ret);
+		return;
+	}
+
+	clockevents_register_device(&ast_clkevt);
+
+	pr_info("Using Asynchronous Timer %d @ %lu.%03lu Mhz"
+			" (regs 0x%p, irq %d)\n",
+			pdev->id, ((ast_hz + 500) / 1000) / 1000,
+			((ast_hz + 500) / 1000) % 1000, ast_regs, irq);
+}
diff -urN linux-2.6.28.2-0rig//arch/avr32/mm/tlb.c linux-2.6.28.2/arch/avr32/mm/tlb.c
--- linux-2.6.28.2-0rig//arch/avr32/mm/tlb.c	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mm/tlb.c	2009-01-29 08:52:50.000000000 +0100
@@ -12,7 +12,13 @@
 #include <asm/mmu_context.h>
 
 /* TODO: Get the correct number from the CONFIG1 system register */
-#define NR_TLB_ENTRIES 32
+#if defined(CONFIG_CPU_AT32AP700X)
+# define NR_TLB_ENTRIES 32
+#elif defined(CONFIG_CPU_AT32AP720X)
+# define NR_TLB_ENTRIES 64
+#else
+# error Unknown CPU type
+#endif
 
 static void show_dtlb_entry(unsigned int index)
 {
@@ -85,9 +91,15 @@
 		u32 tlbar = sysreg_read(TLBARLO);
 
 		rp = 32 - fls(tlbar);
-		if (rp == 32) {
+		if (NR_TLB_ENTRIES > 32 && rp >= 32) {
+			tlbar = sysreg_read(TLBARHI);
+			rp = 64 - fls(tlbar);
+		}
+		if (rp >= NR_TLB_ENTRIES) {
 			rp = 0;
 			sysreg_write(TLBARLO, -1L);
+			if (NR_TLB_ENTRIES > 32)
+				sysreg_write(TLBARHI, -1L);
 		}
 
 		mmucr = SYSREG_BFINS(DRP, rp, mmucr);
@@ -131,16 +143,22 @@
 
 	if (!(mmucr & SYSREG_BIT(MMUCR_N))) {
 		unsigned int entry;
-		u32 tlbarlo;
+		u32 tlbarlo, tlbarhi;
 
 		/* Clear the "valid" bit */
 		sysreg_write(TLBEHI, tlbehi);
 
 		/* mark the entry as "not accessed" */
 		entry = SYSREG_BFEXT(DRP, mmucr);
-		tlbarlo = sysreg_read(TLBARLO);
-		tlbarlo |= (0x80000000UL >> entry);
-		sysreg_write(TLBARLO, tlbarlo);
+		if (NR_TLB_ENTRIES > 32 && entry > 32) {
+			tlbarhi = sysreg_read(TLBARHI);
+			tlbarhi |= (0x80000000UL >> (entry - 32));
+			sysreg_write(TLBARHI, tlbarhi);
+		} else {
+			tlbarlo = sysreg_read(TLBARLO);
+			tlbarlo |= (0x80000000UL >> entry);
+			sysreg_write(TLBARLO, tlbarlo);
+		}
 
 		/* update the entry with valid bit clear */
 		__builtin_tlbw();
@@ -179,9 +197,10 @@
 		unsigned long flags;
 		int size;
 
-		local_irq_save(flags);
 		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 
+		local_irq_save(flags);
+
 		if (size > (MMU_DTLB_ENTRIES / 4)) { /* Too many entries to flush */
 			mm->context = NO_CONTEXT;
 			if (mm == current->mm)
diff -urN linux-2.6.28.2-0rig//drivers/dma/atmel_pdca.c linux-2.6.28.2/drivers/dma/atmel_pdca.c
--- linux-2.6.28.2-0rig//drivers/dma/atmel_pdca.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/drivers/dma/atmel_pdca.c	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,668 @@
+/*
+ * Driver for the Atmel PDCA Peripheral DMA Controller
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#define DEBUG
+#include <linux/atmel_pdca.h>
+#include <linux/clk.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/scatterlist.h>
+#include <linux/spinlock.h>
+
+/*
+ * Since each descriptor can hold a whole scatterlist, we don't need
+ * many of them.
+ */
+#define NR_DESCS_PER_CHANNEL	8
+
+static struct pdca_desc *pdca_desc_entry(struct list_head *node)
+{
+	return list_entry(node, struct pdca_desc, desc_node);
+}
+
+static struct pdca_desc *pdca_next_desc(struct pdca_chan *pch,
+		struct pdca_desc *desc)
+{
+	if (desc->desc_node.next != &pch->queue)
+		return pdca_desc_entry(desc->desc_node.next);
+	return NULL;
+}
+
+static struct pdca_desc *pdca_desc_get(struct pdca_chan *pch)
+{
+	struct pdca_desc		*desc = NULL;
+
+	spin_lock_bh(&pch->lock);
+	if (likely(!list_empty(&pch->freelist))) {
+		desc = pdca_desc_entry(pch->freelist.next);
+		list_del(&desc->desc_node);
+	}
+	spin_unlock_bh(&pch->lock);
+
+	return desc;
+}
+
+static dma_cookie_t pdca_assign_cookie(struct pdca_chan *pch,
+		struct pdca_desc *desc)
+{
+	dma_cookie_t cookie = pch->chan.cookie;
+
+	if (++cookie < 0)
+		cookie = 1;
+
+	pch->chan.cookie = cookie;
+	desc->txd.cookie = cookie;
+
+	return cookie;
+}
+
+static void pdca_desc_done(struct pdca_chan *pch, struct pdca_desc *desc)
+{
+	struct dma_async_tx_descriptor	*txd = &desc->txd;
+	dma_async_tx_callback		callback;
+	void				*param;
+
+	pch->completed = txd->cookie;
+	callback = txd->callback;
+	param = txd->callback_param;
+
+	dev_vdbg(&pch->chan.dev, "  completed %u\n", txd->cookie);
+
+	/*
+	 * We can only handle scatterlists, so this is easy. No other
+	 * drivers do the right thing with scatterlists though...
+	 *
+	 * Note that we ensure that at least one of these flags are
+	 * set when the descriptor is prepared, as we never need to
+	 * unmap the peripheral side.
+	 */
+	if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP))
+		dma_unmap_sg(pch->chan.dev.parent, desc->sg, desc->sg_len,
+				DMA_FROM_DEVICE);
+	if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP))
+		dma_unmap_sg(pch->chan.dev.parent, desc->sg, desc->sg_len,
+				DMA_TO_DEVICE);
+
+	list_move(&desc->desc_node, &pch->freelist);
+
+	if (callback)
+		callback(param);
+}
+
+static void pdca_chan_tasklet(unsigned long param)
+{
+	struct pdca_chan		*pch = (struct pdca_chan *)param;
+	void __iomem			*regs = pch->regs;
+	struct pdca_desc		*cur;
+	struct pdca_desc		*next;
+	struct scatterlist		*cur_sg;
+	struct scatterlist		*next_sg;
+	u32				intflags;
+	u32				status;
+
+	spin_lock(&pch->lock);
+
+	cur = pdca_desc_entry(pch->queue.next);
+	next = pdca_next_desc(pch, cur);
+
+	cur_sg = pch->cur_sg;
+	next_sg = pch->next_sg;
+
+	intflags = PDCA_TERR | PDCA_TRC | PDCA_RCZ;
+
+	status = pdca_readl(regs, ISR);
+	dev_vdbg(&pch->chan.dev, "tasklet: status=%08x\n", status);
+
+	if (status & PDCA_TRC) {
+		if (cur_sg) {
+			if (sg_is_last(cur_sg)) {
+				dev_vdbg(&pch->chan.dev,
+						"  cur sg was last in %u\n",
+						cur->txd.cookie);
+				pdca_desc_done(pch, cur);
+				cur = next;
+				next = NULL;
+			}
+			if (next_sg && sg_is_last(next_sg)) {
+				dev_vdbg(&pch->chan.dev,
+						"  next sg was last in %u\n",
+						cur->txd.cookie);
+				pdca_desc_done(pch, cur);
+				cur = next;
+				next = NULL;
+			}
+			if (!cur) {
+				dev_vdbg(&pch->chan.dev, "  all done\n");
+				pdca_writel(regs, CR, PDCA_CR_TDIS);
+				cur_sg = next_sg = NULL;
+				intflags = 0;
+				goto done;
+			}
+			cur_sg = next_sg ? sg_next(next_sg) : NULL;
+		}
+
+		if (!cur_sg) {
+			dev_vdbg(&pch->chan.dev, "  load sg from %u\n",
+					cur->txd.cookie);
+			cur_sg = cur->sg;
+			pdca_writel(regs, PSR, cur->periph_id);
+			pdca_writel(regs, MR, cur->reg_width);
+		}
+		dev_vdbg(&pch->chan.dev, "  START: %08x count: %08x\n",
+				sg_dma_address(cur_sg),
+				sg_dma_len(cur_sg) >> cur->reg_width);
+		pdca_writel(regs, MAR, sg_dma_address(cur_sg));
+		pdca_writel(regs, TCR, sg_dma_len(cur_sg) >> cur->reg_width);
+
+		next_sg = sg_next(cur_sg);
+		if (!next_sg) {
+			next = pdca_next_desc(pch, cur);
+			if (next && next->reg_width == cur->reg_width
+					&& next->periph_id == cur->periph_id) {
+				dev_vdbg(&pch->chan.dev,
+						"loading next_sg from %u\n",
+						next->txd.cookie);
+				next_sg = next->sg;
+			}
+		}
+		if (next_sg) {
+			dev_vdbg(&pch->chan.dev, "  NEXT: %08x count: %08x\n",
+					sg_dma_address(next_sg),
+					sg_dma_len(next_sg) >> cur->reg_width);
+			pdca_writel(regs, MARR, sg_dma_address(next_sg));
+			pdca_writel(regs, TCRR,
+					sg_dma_len(next_sg) >> cur->reg_width);
+		} else {
+			intflags &= ~PDCA_RCZ;
+		}
+	} else if (next_sg && (status & PDCA_RCZ)) {
+		if (sg_is_last(cur_sg)) {
+			dev_vdbg(&pch->chan.dev, "  cur sg was last in %u\n",
+					cur->txd.cookie);
+			next = pdca_next_desc(pch, cur);
+			pdca_desc_done(pch, cur);
+			cur = next;
+			next = NULL;
+		}
+
+		cur_sg = next_sg;
+		next_sg = sg_next(cur_sg);
+		if (!next_sg) {
+			next = pdca_next_desc(pch, cur);
+			if (next && next->reg_width == cur->reg_width
+					&& next->periph_id == cur->periph_id)
+				next_sg = next->sg;
+		}
+
+		if (next_sg) {
+			dev_vdbg(&pch->chan.dev, "  NEXT: %08x count: %08x\n",
+					sg_dma_address(next_sg),
+					sg_dma_len(next_sg) >> cur->reg_width);
+			pdca_writel(regs, MARR, sg_dma_address(next_sg));
+			pdca_writel(regs, TCRR,
+					sg_dma_len(next_sg) >> cur->reg_width);
+		} else {
+			dev_vdbg(&pch->chan.dev, "  no next sg\n");
+			intflags &= ~PDCA_RCZ;
+		}
+	}
+
+done:
+	if (status & PDCA_TERR) {
+		/*
+		 * Head of queue is busted. We must remove it, clear
+		 * the error and restart the queue.
+		 */
+		pdca_writel(regs, TCRR, 0);
+		pdca_writel(regs, TCR, 0);
+		pdca_writel(regs, CR, PDCA_CR_ECLR);
+		cur_sg = next_sg = NULL;
+
+		if (!cur)
+			dev_err(&pch->chan.dev,
+					"Transfer Error with empty queue\n");
+		else {
+			dev_vdbg(&pch->chan.dev,
+					"  %u is busted\n", cur->txd.cookie);
+			pdca_desc_done(pch, cur);
+		}
+
+		if (list_empty(&pch->queue)) {
+			pdca_writel(regs, CR, PDCA_CR_TDIS);
+			intflags = 0;
+		}
+	}
+
+	pch->cur_sg = cur_sg;
+	pch->next_sg = next_sg;
+
+	dev_vdbg(&pch->chan.dev, "  enabling interrupts: %08x\n", intflags);
+	pdca_writel(regs, IER, intflags);
+	pdca_readl(regs, SR);
+
+	spin_unlock(&pch->lock);
+}
+
+static irqreturn_t pdca_interrupt(int irq, void *dev_id)
+{
+	struct pdca_dev			*pdca = dev_id;
+	struct pdca_chan		*pch;
+	void __iomem			*regs;
+	unsigned long			pending;
+	unsigned int			chan;
+
+	pending = intc_get_pending(irq);
+	if (unlikely(!pending))
+		return IRQ_NONE;
+
+	do {
+		chan = __ffs(pending);
+		pch = &pdca->chan[chan];
+		regs = pch->regs;
+		pdca_writel(regs, IDR, ~0UL);
+		tasklet_schedule(&pch->tasklet);
+		pdca_readl(regs, IMR);
+		pending &= ~(1 << chan);
+	} while (pending);
+
+	return IRQ_HANDLED;
+}
+
+static dma_cookie_t pdca_tx_submit(struct dma_async_tx_descriptor *txd)
+{
+	struct pdca_desc		*desc = txd_to_pdca_desc(txd);
+	struct pdca_chan		*pch = dma_to_pdca_chan(txd->chan);
+	void __iomem			*regs = pch->regs;
+	dma_cookie_t			cookie;
+
+	spin_lock_bh(&pch->lock);
+	cookie = pdca_assign_cookie(pch, desc);
+	dev_vdbg(&pch->chan.dev, "submitted %u\n", cookie);
+	list_add_tail(&desc->desc_node, &pch->queue);
+	pdca_writel(regs, CR, PDCA_CR_TEN);
+	pdca_writel(regs, IER, PDCA_TERR | PDCA_RCZ);
+	/* The tasklet will kickstart the queue if necessary */
+	spin_unlock_bh(&pch->lock);
+
+	return cookie;
+}
+
+static struct dma_async_tx_descriptor *pdca_prep_slave_sg(struct dma_chan *chan,
+		struct scatterlist *sgl, unsigned int sg_len,
+		enum dma_data_direction direction, unsigned long flags)
+{
+	struct pdca_chan		*pch = dma_to_pdca_chan(chan);
+	struct pdca_slave		*pslave = pch->pslave;
+	struct pdca_desc		*desc;
+	unsigned int			periph_id;
+
+	dev_vdbg(&chan->dev, "prep_dma_slave: %s %u segments, flags: %lx\n",
+			direction == DMA_TO_DEVICE ? "OUT" : "IN",
+			sg_len, flags);
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		periph_id = pslave->tx_periph_id;
+		flags |= DMA_COMPL_SKIP_DEST_UNMAP;
+		break;
+	case DMA_FROM_DEVICE:
+		periph_id = pslave->rx_periph_id;
+		flags |= DMA_COMPL_SKIP_SRC_UNMAP;
+		break;
+	default:
+		return NULL;
+	}
+
+	desc = pdca_desc_get(pch);
+	if (!desc) {
+		dev_err(&chan->dev,
+			"not enough descriptors available\n");
+		return NULL;
+	}
+	desc->sg = sgl;
+	desc->sg_len = sg_len;
+	desc->periph_id = periph_id;
+	desc->reg_width = pslave->slave.reg_width;
+	desc->txd.flags = flags;
+
+	return &desc->txd;
+}
+
+static void pdca_terminate_all(struct dma_chan *chan)
+{
+	struct pdca_chan		*pch = dma_to_pdca_chan(chan);
+	struct pdca_desc		*desc, *_desc;
+	void __iomem			*regs = pch->regs;
+
+	spin_lock_bh(&pch->lock);
+	pdca_writel(regs, CR, PDCA_CR_TDIS);
+	pdca_writel(regs, TCRR, 0);
+	pdca_writel(regs, TCR, 0);
+	while (pdca_readl(regs, SR) & PDCA_SR_TEN)
+		cpu_relax();
+
+	list_for_each_entry_safe(desc, _desc, &pch->queue, desc_node)
+		pdca_desc_done(pch, desc);
+	spin_unlock_bh(&pch->lock);
+}
+
+static enum dma_status pdca_is_tx_complete(struct dma_chan *chan,
+		dma_cookie_t cookie, dma_cookie_t *done, dma_cookie_t *used)
+{
+	struct pdca_chan		*pch = dma_to_pdca_chan(chan);
+	dma_cookie_t			last_used;
+	dma_cookie_t			last_complete;
+
+	last_complete = pch->completed;
+	last_used = chan->cookie;
+
+	if (done)
+		*done = last_complete;
+	if (used)
+		*used = last_used;
+
+	return dma_async_is_complete(cookie, last_complete, last_used);
+}
+
+static void pdca_issue_pending(struct dma_chan *chan)
+{
+	/* We always issue descriptors ASAP */
+}
+
+static int pdca_alloc_chan_resources(struct dma_chan *chan,
+		struct dma_client *client)
+{
+	struct pdca_chan		*pch = dma_to_pdca_chan(chan);
+	struct pdca_dev			*pdca = dma_to_pdca_dev(chan->device);
+	struct dma_slave		*slave = client->slave;
+	void __iomem			*regs = pch->regs;
+
+	/*
+	 * Channels doing slave DMA can only handle one client. This
+	 * controller can only do slave DMA.
+	 */
+	if (chan->client_count)
+		return -EBUSY;
+	if (!slave || !slave->dma_dev || slave->dma_dev != pdca->dma.dev)
+		return -EINVAL;
+
+	if (pdca_readl(regs, SR) & PDCA_SR_TEN)
+		dev_err(&chan->dev, "DMA channel not idle!\n");
+
+	/*
+	 * We may get called multiple times if a client rejects the
+	 * channel...
+	 */
+	if (!pch->enabled) {
+		pch->enabled = true;
+		clk_enable(pdca->pclk);
+		clk_enable(pdca->hclk);
+	}
+
+	pch->chan.cookie = pch->completed = 1;
+	pch->pslave = dma_to_pdca_slave(slave);
+
+	while (pch->descs_allocated < NR_DESCS_PER_CHANNEL) {
+		struct pdca_desc	*desc;
+
+		desc = kzalloc(sizeof(struct pdca_desc), GFP_KERNEL);
+		if (!desc) {
+			dev_info(&chan->dev, "only allocated %d descriptors\n",
+					pch->descs_allocated);
+			break;
+		}
+
+		dma_async_tx_descriptor_init(&desc->txd, chan);
+		desc->txd.tx_submit = pdca_tx_submit;
+		desc->txd.flags = DMA_CTRL_ACK;
+		INIT_LIST_HEAD(&desc->txd.tx_list);
+		list_add(&desc->desc_node, &pch->freelist);
+		pch->descs_allocated++;
+	}
+
+	return pch->descs_allocated ? 0 : -ENOMEM;
+}
+
+static void pdca_free_chan_resources(struct dma_chan *chan)
+{
+	struct pdca_chan		*pch = dma_to_pdca_chan(chan);
+	struct pdca_dev			*pdca = dma_to_pdca_dev(chan->device);
+	struct pdca_desc		*desc, *_desc;
+
+	WARN_ON(!list_empty(&pch->queue));
+	WARN_ON(pdca_readl(pch->regs, SR) & PDCA_SR_TEN);
+	WARN_ON(pdca_readl(pch->regs, IMR));
+
+	clk_disable(pdca->hclk);
+	clk_disable(pdca->pclk);
+	pch->enabled = false;
+
+	list_for_each_entry_safe(desc, _desc, &pch->freelist, desc_node) {
+		list_del(&desc->desc_node);
+		kfree(desc);
+	}
+
+	pch->descs_allocated = 0;
+}
+
+static void pdca_suspend_channel(struct pdca_dev *pdca, struct pdca_chan *pch)
+{
+	void __iomem			*regs = pch->regs;
+
+	/*
+	 * REVISIT this whole business.
+	 *
+	 * The plan is to ensure that the PDCA doesn't do any bus
+	 * transactions when we're suspended or shut down. Ideally,
+	 * the client should make sure that all transfers have already
+	 * been completed or terminated when we reach suspend_late(),
+	 * but just in case that didn't happen, we should just stop
+	 * the controller and turn it back on when resuming. Hopefully
+	 * it will simply continue where it left off.
+	 *
+	 * We _probably_ need to save some sort of state to make this
+	 * happen. Or we can just rely on interrupts being globally
+	 * disabled at least until we reach resume_early. But that
+	 * might not be the case for shutdown.
+	 */
+	tasklet_kill(&pch->tasklet);
+	spin_lock_bh(&pch->lock);
+	if (pdca_readl(regs, SR) & PDCA_SR_TEN) {
+		pdca_writel(regs, CR, PDCA_CR_TDIS);
+		while (pdca_readl(regs, SR) & PDCA_SR_TEN)
+			cpu_relax();
+
+		clk_disable(pdca->hclk);
+		clk_disable(pdca->pclk);
+	}
+	spin_unlock_bh(&pch->lock);
+}
+
+static void __init pdca_init_channel(struct pdca_dev *pdca, unsigned int i)
+{
+	struct pdca_chan		*pch = &pdca->chan[i];
+
+	pch->chan.device = &pdca->dma;
+	pch->chan.chan_id = i;
+	pch->regs = pdca->regs + i * PDCA_CHAN_SIZE;
+	tasklet_init(&pch->tasklet, pdca_chan_tasklet, (unsigned long)pch);
+	spin_lock_init(&pch->lock);
+	INIT_LIST_HEAD(&pch->freelist);
+	INIT_LIST_HEAD(&pch->queue);
+
+	list_add_tail(&pch->chan.device_node, &pdca->dma.channels);
+}
+
+static int __init pdca_probe(struct platform_device *pdev)
+{
+	struct pdca_pdata		*pdata;
+	struct resource			*mmio;
+	struct pdca_dev			*pdca;
+	size_t				mmio_len;
+	size_t				size;
+	unsigned int			i;
+	int				irq;
+	int				ret;
+
+	pdata = pdev->dev.platform_data;
+	mmio = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (!pdata || pdata->nr_channels > 32 || !mmio || !irq) {
+		dev_dbg(&pdev->dev, "invalid params from platform code\n");
+		return -EINVAL;
+	}
+
+	mmio_len = mmio->end - mmio->start + 1;
+	if (!request_mem_region(mmio->start, mmio_len, "atmel_pdca")) {
+		dev_dbg(&pdev->dev, "mmio resource busy\n");
+		return -EBUSY;
+	}
+
+	size = sizeof(struct pdca_dev);
+	size += pdata->nr_channels * sizeof(struct pdca_chan);
+	pdca = kzalloc(size, GFP_KERNEL);
+	if (!pdca) {
+		dev_dbg(&pdev->dev, "insufficient memory\n");
+		ret = -ENOMEM;
+		goto err_alloc_pdca;
+	}
+
+	pdca->hclk = clk_get(&pdev->dev, "hclk");
+	if (IS_ERR(pdca->hclk)) {
+		dev_dbg(&pdev->dev, "no HSB clock\n");
+		ret = PTR_ERR(pdca->hclk);
+		goto err_get_hclk;
+	}
+	pdca->pclk = clk_get(&pdev->dev, "pclk");
+	if (IS_ERR(pdca->pclk)) {
+		dev_dbg(&pdev->dev, "no PB clock\n");
+		ret = PTR_ERR(pdca->pclk);
+		goto err_get_pclk;
+	}
+
+	pdca->regs = ioremap(mmio->start, mmio_len);
+	if (!pdca->regs) {
+		dev_dbg(&pdev->dev, "ioremap failed\n");
+		ret = -ENOMEM;
+		goto err_ioremap;
+	}
+
+	INIT_LIST_HEAD(&pdca->dma.channels);
+	for (i = 0; i < pdata->nr_channels; i++, pdca->dma.chancnt++)
+		pdca_init_channel(pdca, i);
+
+	ret = request_irq(irq, pdca_interrupt, 0, pdev->dev.bus_id, pdca);
+	if (ret) {
+		dev_dbg(&pdev->dev, "request_irq failed\n");
+		goto err_irq;
+	}
+
+	dma_cap_set(DMA_SLAVE, pdca->dma.cap_mask);
+	pdca->dma.dev = &pdev->dev;
+	pdca->dma.device_alloc_chan_resources = pdca_alloc_chan_resources;
+	pdca->dma.device_free_chan_resources = pdca_free_chan_resources;
+	pdca->dma.device_prep_slave_sg = pdca_prep_slave_sg;
+	pdca->dma.device_terminate_all = pdca_terminate_all;
+	pdca->dma.device_is_tx_complete = pdca_is_tx_complete;
+	pdca->dma.device_issue_pending = pdca_issue_pending;
+
+	platform_set_drvdata(pdev, pdca);
+	dma_async_device_register(&pdca->dma);
+
+	dev_info(&pdev->dev, "Atmel PDCA at 0x%08lx (irq %d) %u channels\n",
+			(unsigned long)mmio->start, irq, pdca->dma.chancnt);
+
+	return 0;
+
+err_irq:
+	iounmap(pdca->regs);
+err_ioremap:
+	clk_put(pdca->pclk);
+err_get_pclk:
+	clk_put(pdca->hclk);
+err_get_hclk:
+	kfree(pdca);
+err_alloc_pdca:
+	release_resource(mmio);
+	return ret;
+}
+
+static int __exit pdca_remove(struct platform_device *pdev)
+{
+	struct pdca_dev		*pdca = platform_get_drvdata(pdev);
+	struct pdca_chan	*pch;
+	struct resource		*mmio;
+
+	list_for_each_entry(pch, &pdca->dma.channels, chan.device_node)
+		pdca_suspend_channel(pdca, pch);
+
+	dma_async_device_unregister(&pdca->dma);
+	free_irq(platform_get_irq(pdev, 0), pdca);
+	clk_put(pdca->pclk);
+	clk_put(pdca->hclk);
+	iounmap(pdca->regs);
+	kfree(pdca);
+
+	mmio = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	release_resource(mmio);
+
+	return 0;
+}
+
+static void pdca_shutdown(struct platform_device *pdev)
+{
+	struct pdca_dev		*pdca = platform_get_drvdata(pdev);
+	struct pdca_chan	*pch;
+
+	list_for_each_entry(pch, &pdca->dma.channels, chan.device_node)
+		pdca_suspend_channel(pdca, pch);
+}
+
+static int pdca_suspend_late(struct platform_device *pdev, pm_message_t state)
+{
+	return 0;
+}
+
+static int pdca_resume_early(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static struct platform_driver pdca_driver = {
+	.remove		= __exit_p(pdca_remove),
+	.shutdown	= pdca_shutdown,
+	.suspend_late	= pdca_suspend_late,
+	.resume_early	= pdca_resume_early,
+	.driver		= {
+		.name	= "atmel_pdca",
+	},
+};
+
+static int __init pdca_init(void)
+{
+	return platform_driver_probe(&pdca_driver, pdca_probe);
+}
+subsys_initcall(pdca_init);
+
+static void __exit pdca_exit(void)
+{
+	platform_driver_unregister(&pdca_driver);
+}
+module_exit(pdca_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Atmel PDCA DMA Controller driver");
+MODULE_AUTHOR("Haavard Skinnemoen <haavard.skinnemoen@atmel.com>");
diff -urN linux-2.6.28.2-0rig//drivers/dma/dw_dmac.c linux-2.6.28.2/drivers/dma/dw_dmac.c
--- linux-2.6.28.2-0rig//drivers/dma/dw_dmac.c	2009-01-29 08:39:25.000000000 +0100
+++ linux-2.6.28.2/drivers/dma/dw_dmac.c	2009-01-29 08:52:50.000000000 +0100
@@ -545,109 +545,51 @@
 	return NULL;
 }
 
-static struct dma_async_tx_descriptor *
-dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
-		unsigned int sg_len, enum dma_data_direction direction,
-		unsigned long flags)
+static struct dw_desc *dwc_init_slave_descs(struct dw_dma_chan *dwc,
+		struct scatterlist *sgl, unsigned int sg_len,
+		u32 ctllo, dma_addr_t src_reg, dma_addr_t dst_reg,
+		unsigned int reg_width, unsigned long flags)
 {
-	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
-	struct dw_dma_slave	*dws = dwc->dws;
-	struct dw_desc		*prev;
-	struct dw_desc		*first;
-	u32			ctllo;
-	dma_addr_t		reg;
-	unsigned int		reg_width;
-	unsigned int		mem_width;
-	unsigned int		i;
+	struct dma_chan		*chan = &dwc->chan;
 	struct scatterlist	*sg;
+	struct dw_desc		*desc;
+	struct dw_desc		*first = NULL;
+	struct dw_desc		*prev = NULL;
+	unsigned int		align_mask;
+	unsigned int		i;
 	size_t			total_len = 0;
 
-	dev_vdbg(&chan->dev, "prep_dma_slave\n");
-
-	if (unlikely(!dws || !sg_len))
-		return NULL;
-
-	reg_width = dws->slave.reg_width;
-	prev = first = NULL;
-
-	sg_len = dma_map_sg(chan->dev.parent, sgl, sg_len, direction);
-
-	switch (direction) {
-	case DMA_TO_DEVICE:
-		ctllo = (DWC_DEFAULT_CTLLO
-				| DWC_CTLL_DST_WIDTH(reg_width)
-				| DWC_CTLL_DST_FIX
-				| DWC_CTLL_SRC_INC
-				| DWC_CTLL_FC_M2P);
-		reg = dws->slave.tx_reg;
-		for_each_sg(sgl, sg, sg_len, i) {
-			struct dw_desc	*desc;
-			u32		len;
-			u32		mem;
+	align_mask = (1 << reg_width) - 1;
+	for_each_sg(sgl, sg, sg_len, i) {
+		u32		len;
+		u32		desc_len;
+		u32		mem;
+
+		mem = sg_phys(sg);
+		len = sg_dma_len(sg);
+		total_len += len;
 
+		while (len) {
+			desc_len = min(len, DWC_MAX_COUNT << reg_width);
 			desc = dwc_desc_get(dwc);
 			if (!desc) {
 				dev_err(&chan->dev,
 					"not enough descriptors available\n");
 				goto err_desc_get;
 			}
+			len -= desc_len;
 
-			mem = sg_phys(sg);
-			len = sg_dma_len(sg);
-			mem_width = 2;
-			if (unlikely(mem & 3 || len & 3))
-				mem_width = 0;
-
-			desc->lli.sar = mem;
-			desc->lli.dar = reg;
-			desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width);
-			desc->lli.ctlhi = len >> mem_width;
+			if (unlikely((mem & align_mask) || (len & align_mask)))
+				goto err_align;
 
-			if (!first) {
-				first = desc;
-			} else {
-				prev->lli.llp = desc->txd.phys;
-				dma_sync_single_for_device(chan->dev.parent,
-						prev->txd.phys,
-						sizeof(prev->lli),
-						DMA_TO_DEVICE);
-				list_add_tail(&desc->desc_node,
-						&first->txd.tx_list);
-			}
-			prev = desc;
-			total_len += len;
-		}
-		break;
-	case DMA_FROM_DEVICE:
-		ctllo = (DWC_DEFAULT_CTLLO
-				| DWC_CTLL_SRC_WIDTH(reg_width)
-				| DWC_CTLL_DST_INC
-				| DWC_CTLL_SRC_FIX
-				| DWC_CTLL_FC_P2M);
-
-		reg = dws->slave.rx_reg;
-		for_each_sg(sgl, sg, sg_len, i) {
-			struct dw_desc	*desc;
-			u32		len;
-			u32		mem;
-
-			desc = dwc_desc_get(dwc);
-			if (!desc) {
-				dev_err(&chan->dev,
-					"not enough descriptors available\n");
-				goto err_desc_get;
-			}
-
-			mem = sg_phys(sg);
-			len = sg_dma_len(sg);
-			mem_width = 2;
-			if (unlikely(mem & 3 || len & 3))
-				mem_width = 0;
-
-			desc->lli.sar = reg;
-			desc->lli.dar = mem;
-			desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width);
-			desc->lli.ctlhi = len >> reg_width;
+			desc->lli.sar = src_reg ? src_reg : mem;
+			desc->lli.dar = dst_reg ? dst_reg : mem;
+			desc->lli.ctllo = ctllo;
+			desc->lli.ctlhi = desc_len >> reg_width;
+			dev_vdbg(&dwc->chan.dev,
+					"  s%08x d%08x c%08x:%08x\n",
+					desc->lli.sar, desc->lli.dar,
+					ctllo, desc_len >> reg_width);
 
 			if (!first) {
 				first = desc;
@@ -661,11 +603,8 @@
 						&first->txd.tx_list);
 			}
 			prev = desc;
-			total_len += len;
+			mem += desc_len;
 		}
-		break;
-	default:
-		return NULL;
 	}
 
 	if (flags & DMA_PREP_INTERRUPT)
@@ -679,13 +618,69 @@
 
 	first->len = total_len;
 
-	return &first->txd;
+	return first;
 
+err_align:
+	dwc_desc_put(dwc, desc);
 err_desc_get:
 	dwc_desc_put(dwc, first);
 	return NULL;
 }
 
+static struct dma_async_tx_descriptor *
+dwc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
+		unsigned int sg_len, enum dma_data_direction direction,
+		unsigned long flags)
+{
+	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
+	struct dw_dma_slave	*dws = dwc->dws;
+	struct dw_desc		*first;
+	u32			ctllo;
+	unsigned int		reg_width;
+
+	dev_vdbg(&chan->dev, "prep_dma_slave: %s %u segments, flags: %lx\n",
+			direction == DMA_TO_DEVICE ? "OUT" : "IN",
+			sg_len, flags);
+
+	if (unlikely(!dws || !sg_len))
+		return NULL;
+
+	reg_width = dws->slave.reg_width;
+	sg_len = dma_map_sg(chan->dev.parent, sgl, sg_len, direction);
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		ctllo = (DWC_DEFAULT_CTLLO
+				| DWC_CTLL_DST_WIDTH(reg_width)
+				| DWC_CTLL_SRC_WIDTH(reg_width)
+				| DWC_CTLL_DST_FIX
+				| DWC_CTLL_SRC_INC
+				| DWC_CTLL_FC_M2P);
+		first = dwc_init_slave_descs(dwc, sgl, sg_len, ctllo,
+				0, dws->slave.tx_reg, reg_width, flags);
+		break;
+	case DMA_FROM_DEVICE:
+		ctllo = (DWC_DEFAULT_CTLLO
+				| DWC_CTLL_SRC_WIDTH(reg_width)
+				| DWC_CTLL_DST_WIDTH(reg_width)
+				| DWC_CTLL_DST_INC
+				| DWC_CTLL_SRC_FIX
+				| DWC_CTLL_FC_P2M);
+		first = dwc_init_slave_descs(dwc, sgl, sg_len, ctllo,
+				dws->slave.rx_reg, 0, reg_width, flags);
+		break;
+	default:
+		return NULL;
+	}
+
+	if (unlikely(!first)) {
+		dma_unmap_sg(chan->dev.parent, sgl, sg_len, direction);
+		return NULL;
+	}
+
+	return &first->txd;
+}
+
 static void dwc_terminate_all(struct dma_chan *chan)
 {
 	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
@@ -1109,7 +1104,7 @@
 {
 	return platform_driver_probe(&dw_driver, dw_probe);
 }
-module_init(dw_init);
+subsys_initcall(dw_init);
 
 static void __exit dw_exit(void)
 {
diff -urN linux-2.6.28.2-0rig//drivers/dma/Kconfig linux-2.6.28.2/drivers/dma/Kconfig
--- linux-2.6.28.2-0rig//drivers/dma/Kconfig	2009-01-29 08:39:25.000000000 +0100
+++ linux-2.6.28.2/drivers/dma/Kconfig	2009-01-29 08:52:50.000000000 +0100
@@ -38,6 +38,20 @@
 	help
 	  Enable support for the Intel(R) IOP Series RAID engines.
 
+config ATMEL_PDCA
+	tristate "Atmel Peripheral DMA Controller A support"
+	depends on AVR32
+	select DMA_ENGINE
+	default y if CPU_AT32AP7200
+	help
+	  Support the Atmel Peripheral DMA Controller found on AVR32
+	  UC3 chips as well as newer AP7 chips. This controller is
+	  similar to the PDC found on AT32AP7000 and various AT91
+	  chips, but has its own register bank.
+
+	  This controller only supports peripheral (slave) transfers,
+	  not memory-to-memory transfers.
+
 config DW_DMAC
 	tristate "Synopsys DesignWare AHB DMA support"
 	depends on AVR32
diff -urN linux-2.6.28.2-0rig//drivers/dma/Makefile linux-2.6.28.2/drivers/dma/Makefile
--- linux-2.6.28.2-0rig//drivers/dma/Makefile	2009-01-29 08:39:25.000000000 +0100
+++ linux-2.6.28.2/drivers/dma/Makefile	2009-01-29 08:52:50.000000000 +0100
@@ -4,6 +4,7 @@
 obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
 ioatdma-objs := ioat.o ioat_dma.o ioat_dca.o
 obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
+obj-$(CONFIG_ATMEL_PDCA) += atmel_pdca.o
 obj-$(CONFIG_FSL_DMA) += fsldma.o
 obj-$(CONFIG_MV_XOR) += mv_xor.o
 obj-$(CONFIG_DW_DMAC) += dw_dmac.o
diff -urN linux-2.6.28.2-0rig//drivers/mmc/host/atmel-mci-regs.h linux-2.6.28.2/drivers/mmc/host/atmel-mci-regs.h
--- linux-2.6.28.2-0rig//drivers/mmc/host/atmel-mci-regs.h	2009-01-29 08:39:27.000000000 +0100
+++ linux-2.6.28.2/drivers/mmc/host/atmel-mci-regs.h	2009-01-29 08:52:50.000000000 +0100
@@ -10,13 +10,21 @@
 #ifndef __DRIVERS_MMC_ATMEL_MCI_H__
 #define __DRIVERS_MMC_ATMEL_MCI_H__
 
-/* MCI Register Definitions */
+/*
+ * MCI Register Definitions. Registers and bitfields marked with [2]
+ * are only available in MCI2.
+ */
 #define MCI_CR			0x0000	/* Control */
 # define MCI_CR_MCIEN		(  1 <<  0)	/* MCI Enable */
 # define MCI_CR_MCIDIS		(  1 <<  1)	/* MCI Disable */
+# define MCI_CR_PWSEN		(  1 <<  2)	/* Powersave Enable[2] */
+# define MCI_CR_PWSDIS		(  1 <<  3)	/* Powersave Disable[2] */
+# define MCI_CR_IOWAITEN	(  1 <<  4)	/* SDIO Read Wait Enable[2] */
+# define MCI_CR_IOWAITDIS	(  1 <<  5)	/* SDIO Read Wait Disable[2] */
 # define MCI_CR_SWRST		(  1 <<  7)	/* Software Reset */
 #define MCI_MR			0x0004	/* Mode */
 # define MCI_MR_CLKDIV(x)	((x) <<  0)	/* Clock Divider */
+# define MCI_MR_PWSDIV(x)	((x) <<  8)	/* Powersave Divider[2] */
 # define MCI_MR_RDPROOF		(  1 << 11)	/* Read Proof */
 # define MCI_MR_WRPROOF		(  1 << 12)	/* Write Proof */
 #define MCI_DTOR		0x0008	/* Data Timeout */
@@ -56,6 +64,9 @@
 #define MCI_BLKR		0x0018	/* Block */
 # define MCI_BCNT(x)		((x) <<  0)	/* Data Block Count */
 # define MCI_BLKLEN(x)		((x) << 16)	/* Data Block Length */
+#define MCI_CSTOR		0x001c	/* Completion Signal Timeout[2] */
+# define MCI_CSTOCYC(x)		((x) <<  0)	/* CST cycles */
+# define MCI_CSTOMUL(x)		((x) <<  4)	/* CST multiplier */
 #define MCI_RSPR		0x0020	/* Response 0 */
 #define MCI_RSPR1		0x0024	/* Response 1 */
 #define MCI_RSPR2		0x0028	/* Response 2 */
@@ -66,24 +77,45 @@
 #define MCI_IER			0x0044	/* Interrupt Enable */
 #define MCI_IDR			0x0048	/* Interrupt Disable */
 #define MCI_IMR			0x004c	/* Interrupt Mask */
-# define MCI_CMDRDY		(  1 <<   0)	/* Command Ready */
-# define MCI_RXRDY		(  1 <<   1)	/* Receiver Ready */
-# define MCI_TXRDY		(  1 <<   2)	/* Transmitter Ready */
-# define MCI_BLKE		(  1 <<   3)	/* Data Block Ended */
-# define MCI_DTIP		(  1 <<   4)	/* Data Transfer In Progress */
-# define MCI_NOTBUSY		(  1 <<   5)	/* Data Not Busy */
-# define MCI_SDIOIRQA		(  1 <<   8)	/* SDIO IRQ in slot A */
-# define MCI_SDIOIRQB		(  1 <<   9)	/* SDIO IRQ in slot B */
-# define MCI_RINDE		(  1 <<  16)	/* Response Index Error */
-# define MCI_RDIRE		(  1 <<  17)	/* Response Direction Error */
-# define MCI_RCRCE		(  1 <<  18)	/* Response CRC Error */
-# define MCI_RENDE		(  1 <<  19)	/* Response End Bit Error */
-# define MCI_RTOE		(  1 <<  20)	/* Response Time-Out Error */
-# define MCI_DCRCE		(  1 <<  21)	/* Data CRC Error */
-# define MCI_DTOE		(  1 <<  22)	/* Data Time-Out Error */
-# define MCI_OVRE		(  1 <<  30)	/* RX Overrun Error */
-# define MCI_UNRE		(  1 <<  31)	/* TX Underrun Error */
+# define MCI_CMDRDY		(  1 <<  0)	/* Command Ready */
+# define MCI_RXRDY		(  1 <<  1)	/* Receiver Ready */
+# define MCI_TXRDY		(  1 <<  2)	/* Transmitter Ready */
+# define MCI_BLKE		(  1 <<  3)	/* Data Block Ended */
+# define MCI_DTIP		(  1 <<  4)	/* Data Transfer In Progress */
+# define MCI_NOTBUSY		(  1 <<  5)	/* Data Not Busy */
+# define MCI_SDIOIRQA		(  1 <<  8)	/* SDIO IRQ in slot A */
+# define MCI_SDIOIRQB		(  1 <<  9)	/* SDIO IRQ in slot B */
+# define MCI_RINDE		(  1 << 16)	/* Response Index Error */
+# define MCI_RDIRE		(  1 << 17)	/* Response Direction Error */
+# define MCI_RCRCE		(  1 << 18)	/* Response CRC Error */
+# define MCI_RENDE		(  1 << 19)	/* Response End Bit Error */
+# define MCI_RTOE		(  1 << 20)	/* Response Time-Out Error */
+# define MCI_DCRCE		(  1 << 21)	/* Data CRC Error */
+# define MCI_DTOE		(  1 << 22)	/* Data Time-Out Error */
+# define MCI_OVRE		(  1 << 30)	/* RX Overrun Error */
+# define MCI_UNRE		(  1 << 31)	/* TX Underrun Error */
+#define MCI_DMA			0x0050	/* DMA Configuration[2] */
+# define MCI_DMA_OFFSET(x)	((x) <<  0)	/* DMA write buffer offset */
+# define MCI_DMA_CHKSIZE_1	(  0 <<  5)	/* DMA chunk size */
+# define MCI_DMA_CHKSIZE_4	(  1 <<  5)	/* DMA chunk size */
+# define MCI_DMA_CHKSIZE_8	(  2 <<  5)	/* DMA chunk size */
+# define MCI_DMA_CHKSIZE_16	(  3 <<  5)	/* DMA chunk size */
+# define MCI_DMAEN		(  1 <<  8)	/* DMA HW handshake enable */
+#define MCI_CFG			0x0054	/* Configuration[2] */
+# define MCI_CFG_FIFOMODE	(  1 <<  0)	/* Start transfer ASAP */
+# define MCI_CFG_FERRCTRL	(  1 <<  4)	/* xrun flags clear-on-read */
+# define MCI_CFG_HSMODE		(  1 <<  8)	/* Use high-speed signaling */
+# define MCI_CFG_LSYNC		(  1 << 12)	/* Synchronize on last block */
+#define MCI_WPMR		0x00e4	/* Write Protect Mode[2] */
+# define MCI_WP_EN		(  1 <<  0)	/* WP Enable */
+# define MCI_WP_KEY		(0x4d4349 << 8)	/* WP Key */
+#define MCI_WPSR		0x00e8	/* Write Protect Status[2] */
+# define MCI_GET_WP_VS(x)	((x) & 0x0f)
+# define MCI_GET_WP_VSRC(x)	(((x) >> 8) & 0xffff)
+#define MCI_VERSION		0x00fc	/* MCI Core Version[2] */
+#define MCI_FIFO_APERTURE	0x0200	/* FIFO Aperture[2] */
 
+/* This is not including the FIFO Aperture on MCI2 */
 #define MCI_REGS_SIZE		0x100
 
 /* Register access macros */
diff -urN linux-2.6.28.2-0rig//drivers/mmc/host/Kconfig linux-2.6.28.2/drivers/mmc/host/Kconfig
--- linux-2.6.28.2-0rig//drivers/mmc/host/Kconfig	2009-01-29 08:39:27.000000000 +0100
+++ linux-2.6.28.2/drivers/mmc/host/Kconfig	2009-01-29 08:52:50.000000000 +0100
@@ -125,6 +125,17 @@
 
 	  If unsure, say N.
 
+config MMC_ATMELMCI_DMA
+	bool "Atmel MCI DMA support (EXPERIMENTAL)"
+	depends on MMC_ATMELMCI && DMA_ENGINE && EXPERIMENTAL
+	help
+	  Say Y here to have the Atmel MCI driver use a DMA engine to
+	  do data transfers and thus increase the throughput and
+	  reduce the CPU utilization. Note that this is highly
+	  experimental and may cause the driver to lock up.
+
+	  If unsure, say N.
+
 config MMC_IMX
 	tristate "Motorola i.MX Multimedia Card Interface support"
 	depends on ARCH_IMX
diff -urN linux-2.6.28.2-0rig//drivers/mtd/nand/atmel_nand.c linux-2.6.28.2/drivers/mtd/nand/atmel_nand.c
--- linux-2.6.28.2-0rig//drivers/mtd/nand/atmel_nand.c	2009-01-29 08:39:27.000000000 +0100
+++ linux-2.6.28.2/drivers/mtd/nand/atmel_nand.c	2009-01-29 08:52:50.000000000 +0100
@@ -456,7 +456,7 @@
 	platform_set_drvdata(pdev, host);
 	atmel_nand_enable(host);
 
-	if (host->board->det_pin) {
+	if (gpio_is_valid(host->board->det_pin)) {
 		if (gpio_get_value(host->board->det_pin)) {
 			printk("No SmartMedia card inserted.\n");
 			res = ENXIO;
diff -urN linux-2.6.28.2-0rig//drivers/rtc/Kconfig linux-2.6.28.2/drivers/rtc/Kconfig
--- linux-2.6.28.2-0rig//drivers/rtc/Kconfig	2009-01-29 08:39:30.000000000 +0100
+++ linux-2.6.28.2/drivers/rtc/Kconfig	2009-01-29 08:52:50.000000000 +0100
@@ -633,6 +633,22 @@
 	  will be used.  The default of zero is normally OK to use, but
 	  on some systems other software needs to use that register.
 
+config RTC_DRV_AVR32_AST
+	tristate "AVR32 Asynchronous Timer"
+	depends on AVR32
+	help
+	  RTC driver for the AVR32 Asynchronous Timers. The AST is a
+	  simple and flexible timer that can be used both as a
+	  high-resolution system timer and an RTC, depending on what
+	  clock source it is running from.
+
+	  If you say yes here, and add one or more platform_device
+	  called "rtc-ast", those devices will be clocked from a
+	  32.768 kHz crystal oscillator and used as RTCs.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-ast.
+
 config RTC_DRV_BFIN
 	tristate "Blackfin On-Chip RTC"
 	depends on BLACKFIN && !BF561
diff -urN linux-2.6.28.2-0rig//drivers/rtc/Makefile linux-2.6.28.2/drivers/rtc/Makefile
--- linux-2.6.28.2-0rig//drivers/rtc/Makefile	2009-01-29 08:39:30.000000000 +0100
+++ linux-2.6.28.2/drivers/rtc/Makefile	2009-01-29 08:52:50.000000000 +0100
@@ -20,6 +20,7 @@
 obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o
 obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o
 obj-$(CONFIG_RTC_DRV_AT91SAM9)	+= rtc-at91sam9.o
+obj-$(CONFIG_RTC_DRV_AVR32_AST)	+= rtc-ast.o
 obj-$(CONFIG_RTC_DRV_BFIN)	+= rtc-bfin.o
 obj-$(CONFIG_RTC_DRV_CMOS)	+= rtc-cmos.o
 obj-$(CONFIG_RTC_DRV_DS1216)	+= rtc-ds1216.o
diff -urN linux-2.6.28.2-0rig//drivers/rtc/rtc-ast.c linux-2.6.28.2/drivers/rtc/rtc-ast.c
--- linux-2.6.28.2-0rig//drivers/rtc/rtc-ast.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/drivers/rtc/rtc-ast.c	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,546 @@
+/*
+ * An RTC driver for the AVR32 Asynchronous Timer
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#include <asm/ast_regs.h>
+
+/*
+ * The AST - ASynchronous Timer - is built around a simple cycle
+ * counter that can be driven from one of four selectable clocks with
+ * a selectable power-of-two prescaler. It also has two alarms (ALARM0
+ * and ALARM1) and two periodic event generators (PER0 and PER1). The
+ * latter can be driven by different tappings of the same prescaler
+ * that drives the counter.
+ *
+ * This driver uses the 32.768 kHz crystal oscillator as a clock
+ * source and a prescaler that gives a 1 Hz counter frequency. It uses
+ * ALARM0 to support both "old-school" and "wake" alarms, PER0 to
+ * support periodic interrupts (PIE) up to 16.384 kHz (at power-of-two
+ * intervals), and PER1 to support a 1 Hz update interrupt (UIE).
+ *
+ * Watchdog interrupts seem to be undocumented and unsupported by
+ * everyone else, so those are not supported for now.
+ *
+ * The AST can wake the system from any sleep mode given that the
+ * source clock is running. On AT32AP720x, the 32.768 kHz crystal
+ * oscillator runs in all sleep modes except "static" and "shutdown".
+ */
+
+/* 32768 Hz means up to 60 us for synchronization + a bit of slack */
+#define AST_SYNC_TIMEOUT_US	100
+
+#define AST_CLK_RATE		32768
+#define AST_1S_PRESCALER	14	/* log2(32768) - 1 */
+
+struct rtc_ast {
+	/* Protects I/O registers */
+	spinlock_t		lock;
+
+	struct rtc_device	*rtc;
+	void __iomem		*regs;
+	struct clk		*osc32;
+	struct clk		*pclk;
+};
+
+/*
+ * Because the AST is, well, asynchronous, we must make sure we don't
+ * write to certain registers while the previous write is being
+ * synchronized between clock domains. This affects writes to CR, CV,
+ * SCR, WER, PIRx and ARx. To keep the delays minimal, we always
+ * synchronize _before_ writes to these registers.
+ *
+ * This function is also used to synchronize when changing the clock
+ * source, using a different bit in the status register.
+ */
+static int ast_wait_ready(void __iomem *regs, unsigned int busy_mask)
+{
+	unsigned long	timeout = AST_SYNC_TIMEOUT_US;
+
+	while (ast_readl(regs, SR) & busy_mask) {
+		udelay(1);
+		if (--timeout == 0)
+			return -ETIMEDOUT;
+		cpu_relax();
+	}
+
+	return 0;
+}
+
+static void rtc_ast_release(struct device *dev)
+{
+	struct rtc_ast	*ast = dev_get_drvdata(dev);
+
+	/* Disable all interrupts */
+	clk_enable(ast->pclk);
+	ast_writel(ast->regs, IDR, ~0UL);
+	clk_disable(ast->pclk);
+}
+
+static int rtc_ast_ioctl(struct device *dev, unsigned int cmd,
+		unsigned long arg)
+{
+	struct rtc_ast	*ast = dev_get_drvdata(dev);
+	int		ret = 0;
+
+	clk_enable(ast->pclk);
+
+	switch (cmd) {
+		/* REVISIT: Should perhaps verify that irq_task is NULL */
+	case RTC_AIE_ON:
+		ast_writel(ast->regs, IER, AST_BIT(ALARM0));
+		break;
+	case RTC_AIE_OFF:
+		ast_writel(ast->regs, IDR, AST_BIT(ALARM0));
+		break;
+	case RTC_UIE_ON:
+		spin_lock_irq(&ast->lock);
+		ret = ast_wait_ready(ast->regs, AST_BIT(BUSY));
+		if (!ret) {
+			ast_writel(ast->regs, SCR, AST_BIT(PER1));
+			ast_writel(ast->regs, IER, AST_BIT(PER1));
+		}
+		spin_unlock_irq(&ast->lock);
+
+		break;
+	case RTC_UIE_OFF:
+		ast_writel(ast->regs, IDR, AST_BIT(PER1));
+		break;
+#if 0
+	case RTC_PIE_ON:
+		spin_lock_irq(&ast->lock);
+		ret = ast_wait_ready(ast->regs, AST_BIT(BUSY));
+		if (ret)
+			break;
+		ast_writel(ast->regs, SCR, AST_BIT(PER0));
+		spin_unlock_irq(&ast->lock);
+
+		ast_writel(ast->regs, IER, AST_BIT(PER0));
+		break;
+	case RTC_PIE_OFF:
+		ast_writel(ast->regs, IDR, AST_BIT(PER1));
+		break;
+#endif
+	default:
+		ret = -ENOIOCTLCMD;
+		break;
+	}
+
+	clk_disable(ast->pclk);
+
+	return ret;
+}
+
+static int rtc_ast_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct rtc_ast	*ast = dev_get_drvdata(dev);
+
+	clk_enable(ast->pclk);
+	rtc_time_to_tm(ast_readl(ast->regs, CV), tm);
+	clk_disable(ast->pclk);
+
+	return 0;
+}
+
+static int rtc_ast_set_mmss(struct device *dev, unsigned long secs)
+{
+	struct rtc_ast	*ast = dev_get_drvdata(dev);
+	int		ret;
+
+	clk_enable(ast->pclk);
+
+	spin_lock_irq(&ast->lock);
+	ret = ast_wait_ready(ast->regs, AST_BIT(BUSY));
+	if (!ret)
+		ast_writel(ast->regs, CV, secs);
+	spin_unlock_irq(&ast->lock);
+
+	clk_disable(ast->pclk);
+
+	return ret;
+}
+
+static int rtc_ast_set_time(struct device *dev, struct rtc_time *tm)
+{
+	unsigned long	secs;
+	int		ret;
+
+	ret = rtc_tm_to_time(tm, &secs);
+	if (!ret)
+		ret = rtc_ast_set_mmss(dev, secs);
+
+	return ret;
+}
+
+static int rtc_ast_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rtc_ast	*ast = dev_get_drvdata(dev);
+
+	clk_enable(ast->pclk);
+
+	spin_lock_irq(&ast->lock);
+	rtc_time_to_tm(ast_readl(ast->regs, AR0), &alrm->time);
+	alrm->enabled = !!(ast_readl(ast->regs, IMR) & AST_BIT(ALARM0));
+	alrm->pending = !!(ast_readl(ast->regs, SR) & AST_BIT(ALARM0));
+	spin_unlock_irq(&ast->lock);
+
+	clk_disable(ast->pclk);
+
+	return 0;
+}
+
+static int rtc_ast_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rtc_ast	*ast = dev_get_drvdata(dev);
+	unsigned long	seconds;
+	int		ret;
+
+	ret = rtc_tm_to_time(&alrm->time, &seconds);
+	if (ret)
+		return ret;
+
+	clk_enable(ast->pclk);
+
+	/*
+	 * REVISIT: The alarm may trigger before we are done here.
+	 * Who's responsible for handling that?
+	 *
+	 * We don't want to clear the ALARM0 flag before we update AR0
+	 * because the previous value of AR0 might trigger an alarm
+	 * right after we clear the flag.
+	 */
+	spin_lock_irq(&ast->lock);
+	ret = ast_wait_ready(ast->regs, AST_BIT(BUSY));
+	if (ret)
+		goto unlock;
+	ast_writel(ast->regs, AR0, seconds);
+
+	/* Try to avoid synchronization penalty */
+	if (ast_readl(ast->regs, SR) & AST_BIT(ALARM0)) {
+		ret = ast_wait_ready(ast->regs, AST_BIT(BUSY));
+		if (ret)
+			goto unlock;
+		ast_writel(ast->regs, SCR, AST_BIT(ALARM0));
+	}
+
+	if (alrm->enabled)
+		ast_writel(ast->regs, IER, AST_BIT(ALARM0));
+
+unlock:
+	spin_unlock_irq(&ast->lock);
+	clk_disable(ast->pclk);
+
+	return ret;
+}
+
+static int rtc_ast_proc(struct device *dev, struct seq_file *seq)
+{
+	struct rtc_ast	*ast = dev_get_drvdata(dev);
+	u32		imr;
+
+	clk_enable(ast->pclk);
+	imr = ast_readl(ast->regs, IMR);
+	clk_disable(ast->pclk);
+
+	return seq_printf(seq,
+			"periodic_IRQ\t: %s\n"
+			"update_IRQ\t: %s\n"
+			"periodic_freq\t: %d\n",
+			(imr & AST_BIT(PER0)) ? "yes" : "no",
+			(imr & AST_BIT(PER1)) ? "yes" : "no",
+			ast->rtc->irq_freq);
+}
+
+static int rtc_ast_irq_set_freq(struct device *dev, int freq)
+{
+	struct rtc_ast	*ast = dev_get_drvdata(dev);
+	unsigned int	pres_bit;
+	int		ret;
+
+	/* RTC core currently ensures this. */
+	BUG_ON(!freq);
+
+	pres_bit = __ffs(freq);
+	if (pres_bit > AST_1S_PRESCALER)
+		return -EINVAL;
+	pres_bit = AST_1S_PRESCALER - pres_bit;
+
+	clk_enable(ast->pclk);
+
+	spin_lock_irq(&ast->lock);
+	ret = ast_wait_ready(ast->regs, AST_BIT(BUSY));
+	if (ret)
+		goto unlock;
+
+	ast_writel(ast->regs, PIR0, pres_bit);
+
+unlock:
+	spin_unlock_irq(&ast->lock);
+	clk_disable(ast->pclk);
+
+	return ret;
+}
+
+static int rtc_ast_irq_set_state(struct device *dev, int enabled)
+{
+	struct rtc_ast	*ast = dev_get_drvdata(dev);
+	int		ret = 0;
+
+	clk_enable(ast->pclk);
+
+	if (enabled) {
+		spin_lock_irq(&ast->lock);
+		ret = ast_wait_ready(ast->regs, AST_BIT(BUSY));
+		if (!ret) {
+			ast_writel(ast->regs, SCR, AST_BIT(PER0));
+			ast_writel(ast->regs, IER, AST_BIT(PER0));
+		}
+		spin_unlock_irq(&ast->lock);
+	} else {
+		ast_writel(ast->regs, IDR, AST_BIT(PER1));
+	}
+
+	clk_disable(ast->pclk);
+
+	return ret;
+}
+
+static const struct rtc_class_ops rtc_ast_ops = {
+	.release	= rtc_ast_release,
+	.ioctl		= rtc_ast_ioctl,
+	.read_time	= rtc_ast_read_time,
+	.set_time	= rtc_ast_set_time,
+	.read_alarm	= rtc_ast_read_alarm,
+	.set_alarm	= rtc_ast_set_alarm,
+	.proc		= rtc_ast_proc,
+	.set_mmss	= rtc_ast_set_mmss,
+	.irq_set_freq	= rtc_ast_irq_set_freq,
+	.irq_set_state	= rtc_ast_irq_set_state,
+};
+
+static irqreturn_t rtc_ast_interrupt(int irq, void *dev_id)
+{
+	struct rtc_ast	*ast = dev_id;
+	unsigned long	events;
+	unsigned long	num;
+	u32		status;
+	u32		pending;
+	irqreturn_t	ret = IRQ_NONE;
+
+	clk_enable(ast->pclk);
+	spin_lock(&ast->lock);
+
+	status = ast_readl(ast->regs, SR);
+	pending = status & ast_readl(ast->regs, IMR);
+	if (unlikely(!pending))
+		goto out;
+
+	ast_wait_ready(ast->regs, AST_BIT(BUSY));
+	ast_writel(ast->regs, SCR, pending);
+
+	events = RTC_IRQF;
+	num = 0;
+	if (pending & AST_BIT(ALARM0)) {
+		num++;
+		events |= RTC_AF;
+	}
+	if (pending & AST_BIT(PER0)) {
+		num++;
+		events |= RTC_PF;
+	}
+	if (pending & AST_BIT(PER1)) {
+		num++;
+		events |= RTC_UF;
+	}
+
+	rtc_update_irq(ast->rtc, num, events);
+	ret = IRQ_HANDLED;
+
+out:
+	spin_unlock(&ast->lock);
+	clk_disable(ast->pclk);
+
+	return IRQ_HANDLED;
+}
+
+static int __init rtc_ast_probe(struct platform_device *pdev)
+{
+	struct resource	*regs;
+	struct rtc_ast	*ast;
+	int		irq;
+	int		ret;
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		dev_dbg(&pdev->dev, "no mmio resource\n");
+		return -ENXIO;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_dbg(&pdev->dev, "no irq\n");
+		return -ENXIO;
+	}
+
+	ast = kzalloc(sizeof(struct rtc_ast), GFP_KERNEL);
+	if (!ast) {
+		dev_dbg(&pdev->dev, "out of memory\n");
+		return -ENOMEM;
+	}
+
+	ast->osc32 = clk_get(NULL, "osc32k");
+	if (IS_ERR(ast->osc32)) {
+		ret = PTR_ERR(ast->osc32);
+		dev_dbg(&pdev->dev, "no 32 kHz oscillator\n");
+		goto err_osc32;
+	}
+
+	ast->pclk = clk_get(&pdev->dev, "pclk");
+	if (IS_ERR(ast->pclk)) {
+		ret = PTR_ERR(ast->pclk);
+		dev_dbg(&pdev->dev, "no peripheral clock\n");
+		goto err_pclk;
+	}
+
+	spin_lock_init(&ast->lock);
+
+	ast->regs = ioremap(regs->start, regs->end - regs->start + 1);
+	if (!ast->regs) {
+		dev_dbg(&pdev->dev, "failed to map registers\n");
+		ret = -ENOMEM;
+		goto err_ioremap;
+	}
+
+	clk_enable(ast->osc32);
+	clk_enable(ast->pclk);
+
+	/* Initialize the AST if it isn't running already */
+	if (!(ast_readl(ast->regs, CR) & AST_BIT(CR_EN))) {
+		ast_wait_ready(ast->regs, AST_BIT(CLK_BUSY));
+		ast_writel(ast->regs, CLOCK,
+				AST_BF(CLOCK_CSSEL, AST_CLOCK_OSC32)
+				| AST_BIT(CLOCK_CEN));
+		ret = ast_wait_ready(ast->regs, AST_BIT(CLK_BUSY));
+		if (ret) {
+			dev_dbg(&pdev->dev,
+				"timed out selecting clock source\n");
+			goto err_clksel;
+		}
+		ast_wait_ready(ast->regs, AST_BIT(BUSY));
+		ast_writel(ast->regs, CV, 0);
+		ast_wait_ready(ast->regs, AST_BIT(BUSY));
+		ast_writel(ast->regs, CR, AST_BIT(CR_EN) | AST_BIT(CR_PCLR)
+				| AST_BF(CR_PSEL, AST_1S_PRESCALER));
+	}
+
+	ast_writel(ast->regs, IDR, ~0UL);
+	ast_wait_ready(ast->regs, AST_BIT(BUSY));
+	ast_writel(ast->regs, WER, 0);
+	ast_wait_ready(ast->regs, AST_BIT(BUSY));
+	ast_writel(ast->regs, PIR0, AST_1S_PRESCALER);
+	ast_wait_ready(ast->regs, AST_BIT(BUSY));
+	ast_writel(ast->regs, PIR1, AST_1S_PRESCALER);
+
+	ret = request_irq(irq, rtc_ast_interrupt, 0, "rtc-ast", ast);
+	if (ret) {
+		dev_dbg(&pdev->dev, "could not request irq %d\n", irq);
+		goto err_request_irq;
+	}
+
+	ast->rtc = rtc_device_register("rtc-ast", &pdev->dev,
+			&rtc_ast_ops, THIS_MODULE);
+	if (IS_ERR(ast->rtc)) {
+		dev_dbg(&pdev->dev, "could not register rtc device\n");
+		ret = PTR_ERR(ast->rtc);
+		goto err_register;
+	}
+
+	ast->rtc->max_user_freq = AST_CLK_RATE / 2;
+	ast->rtc->irq_freq = 1;
+
+	ast_wait_ready(ast->regs, AST_BIT(BUSY));
+	clk_disable(ast->pclk);
+	platform_set_drvdata(pdev, ast);
+	device_init_wakeup(&pdev->dev, 1);
+
+	dev_info(&pdev->dev, "AVR32 Asynchronous Timer at %08lx irq %d\n",
+			(unsigned long)regs->start, irq);
+
+	return 0;
+
+err_register:
+	free_irq(irq, ast);
+err_request_irq:
+err_clksel:
+	clk_disable(ast->pclk);
+	clk_disable(ast->osc32);
+	iounmap(ast->regs);
+err_ioremap:
+	clk_put(ast->pclk);
+err_pclk:
+	clk_put(ast->osc32);
+err_osc32:
+	kfree(ast);
+	return ret;
+}
+
+static int __exit rtc_ast_remove(struct platform_device *pdev)
+{
+	struct rtc_ast *ast = platform_get_drvdata(pdev);
+
+	device_init_wakeup(&pdev->dev, 0);
+
+	clk_enable(ast->pclk);
+	ast_writel(ast->regs, IDR, ~0UL);
+	ast_readl(ast->regs, IMR);
+	clk_disable(ast->pclk);
+
+	free_irq(platform_get_irq(pdev, 0), ast);
+	rtc_device_unregister(ast->rtc);
+	clk_disable(ast->osc32);
+	iounmap(ast->regs);
+	clk_put(ast->pclk);
+	clk_put(ast->osc32);
+	kfree(ast);
+
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver rtc_ast_driver = {
+	.remove		= __exit_p(rtc_ast_remove),
+	.driver		= {
+		.name	= "rtc-ast",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init rtc_ast_init(void)
+{
+	return platform_driver_probe(&rtc_ast_driver, rtc_ast_probe);
+}
+module_init(rtc_ast_init);
+
+static void __exit rtc_ast_exit(void)
+{
+	platform_driver_unregister(&rtc_ast_driver);
+}
+module_exit(rtc_ast_exit);
+
+MODULE_AUTHOR("Haavard Skinnemoen <haavard.skinnemoen@atmel.com>");
+MODULE_DESCRIPTION("AVR32 Asynchronous Timer RTC");
+MODULE_LICENSE("GPL");
diff -urN linux-2.6.28.2-0rig//drivers/spi/atmel_spi.c linux-2.6.28.2/drivers/spi/atmel_spi.c
--- linux-2.6.28.2-0rig//drivers/spi/atmel_spi.c	2009-01-29 08:39:31.000000000 +0100
+++ linux-2.6.28.2/drivers/spi/atmel_spi.c	2009-01-29 09:29:00.000000000 +0100
@@ -1,306 +1,445 @@
 /*
  * Driver for Atmel AT32 and AT91 SPI Controllers
  *
- * Copyright (C) 2006 Atmel Corporation
+ * Copyright (C) 2006-2008 Atmel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
 
-#include <linux/kernel.h>
-#include <linux/init.h>
 #include <linux/clk.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
 #include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <linux/spi/atmel_spi.h>
 #include <linux/spi/spi.h>
 
-#include <asm/io.h>
-#include <mach/board.h>
-#include <mach/gpio.h>
 #include <mach/cpu.h>
 
 #include "atmel_spi.h"
 
-/*
- * The core SPI transfer engine just talks to a register bank to set up
- * DMA transfers; transfer queue progress is driven by IRQs.  The clock
- * framework provides the base clock, subdivided for each spi_device.
- *
- * Newer controllers, marked with "new_1" flag, have:
- *  - CR.LASTXFER
- *  - SPI_MR.DIV32 may become FDIV or must-be-zero (here: always zero)
- *  - SPI_SR.TXEMPTY, SPI_SR.NSSR (and corresponding irqs)
- *  - SPI_CSRx.CSAAT
- *  - SPI_CSRx.SBCR allows faster clocking
+#define BUFFER_SIZE		PAGE_SIZE
+#define INVALID_DMA_ADDRESS	0xffffffff
+#define MAX_SG_SEGS		8
+
+/**
+ * struct atmel_spi - SPI master controller state
+ * @lock: Spinlock protecting the @queue, @stay and @stopping fields
+ *	as well as the hardware registers.
+ * @regs: Base address of the hardware registers.
+ * @wait: Waitqueue used to wait for DMA completion or errors.
+ * @pending: Number of DMA transfers currently pending.
+ * @pending_bytes: Number of bytes submitted for DMA but not yet
+ *	accounted for.
+ * @error: Data transfer error detected by interrupt handler. When this
+ *	is set to a nonzero value, the DMA engine is stopped, @pending
+ *	is set to 0 and @wait is triggered.
+ * @buffer: Scratch buffer for use when the upper layers didn't provide
+ *	a TX or RX buffer.
+ * @buffer_dma: DMA address of @buffer.
+ * @buffer_size: Length of @buffer in bytes.
+ * @queue: SPI messages queued for transfer.
+ * @workqueue: Per-controller workqueue.
+ * @work: Queue processing work struct.
+ * @stay: If the last SPI message caused the SPI device to stay active,
+ *	this points to the SPI device associated with that message. NULL
+ *	otherwise.
+ * @clk: Bus clock connected to the controller.
+ * @base_hz: Base clock rate in Hz used for baud rate calculations.
+ * @stopping: Queue is being stopped. No new messages are started.
+ * @always_bounce: Always do transfers to/from bounce buffer.
+ * @pdev: Platform device associated with the controller.
  */
 struct atmel_spi {
 	spinlock_t		lock;
-
 	void __iomem		*regs;
-	int			irq;
-	struct clk		*clk;
-	struct platform_device	*pdev;
-	unsigned		new_1:1;
-	struct spi_device	*stay;
 
-	u8			stopping;
-	struct list_head	queue;
-	struct spi_transfer	*current_transfer;
-	unsigned long		current_remaining_bytes;
-	struct spi_transfer	*next_transfer;
-	unsigned long		next_remaining_bytes;
+	wait_queue_head_t	wait;
+	int			pending;
+	size_t			pending_bytes;
+#ifndef CONFIG_SPI_ATMEL_HAVE_PDC
+	struct scatterlist	tx_sg[MAX_SG_SEGS];
+	struct scatterlist	rx_sg[MAX_SG_SEGS];
+	unsigned int		sg_len;
+	struct dma_async_tx_descriptor *tx_desc;
+	struct dma_async_tx_descriptor *rx_desc;
+	struct dma_chan		*tx_chan;
+	struct dma_chan		*rx_chan;
+	struct dma_client	rx_client;
+	struct dma_client	tx_client;
+#endif
+	int			error;
 
 	void			*buffer;
 	dma_addr_t		buffer_dma;
+	size_t			buffer_size;
+
+	struct list_head	queue;
+	struct workqueue_struct	*workqueue;
+	struct work_struct	work;
+	struct spi_device	*stay;
+	struct clk		*clk;
+	unsigned long		base_hz;
+	bool			stopping;
+	bool			always_bounce;
+
+	struct platform_device	*pdev;
+#ifdef CONFIG_DEBUG_FS
+	struct dentry		*debugfs_root;
+#endif
 };
 
-#define BUFFER_SIZE		PAGE_SIZE
-#define INVALID_DMA_ADDRESS	0xffffffff
+/**
+ * struct atmel_spi_device - Controller-specific per-slave state
+ * @npcs_pin: GPIO pin ID hooked up to this SPI slave.
+ * @csr: CSRn register value used when talking to this SPI slave.
+ */
+struct atmel_spi_device {
+	unsigned int		npcs_pin;
+	u32			csr;
+};
 
 /*
- * Earlier SPI controllers (e.g. on at91rm9200) have a design bug whereby
- * they assume that spi slave device state will not change on deselect, so
- * that automagic deselection is OK.  ("NPCSx rises if no data is to be
- * transmitted")  Not so!  Workaround uses nCSx pins as GPIOs; or newer
- * controllers have CSAAT and friends.
- *
- * Since the CSAAT functionality is a bit weird on newer controllers as
- * well, we use GPIO to control nCSx pins on all controllers, updating
- * MR.PCS to avoid confusing the controller.  Using GPIOs also lets us
- * support active-high chipselects despite the controller's belief that
- * only active-low devices/systems exists.
+ * Version 2 of the SPI controller has
+ *  - CR.LASTXFER
+ *  - SPI_MR.DIV32 may become FDIV or must-be-zero (here: always zero)
+ *  - SPI_SR.TXEMPTY, SPI_SR.NSSR (and corresponding irqs)
+ *  - SPI_CSRx.CSAAT
+ *  - SPI_CSRx.SBCR allows faster clocking
  *
- * However, at91rm9200 has a second erratum whereby nCS0 doesn't work
- * right when driven with GPIO.  ("Mode Fault does not allow more than one
- * Master on Chip Select 0.")  No workaround exists for that ... so for
- * nCS0 on that chip, we (a) don't use the GPIO, (b) can't support CS_HIGH,
- * and (c) will trigger that first erratum in some cases.
+ * We can determine the controller version by reading the VERSION
+ * register, but I haven't checked that it exists on all chips, and
+ * this is cheaper anyway.
  */
+static bool atmel_spi_is_v2(void)
+{
+	return !cpu_is_at91rm9200();
+}
 
-static void cs_activate(struct atmel_spi *as, struct spi_device *spi)
+static bool atmel_spi_xfer_is_last(struct spi_message *msg,
+		struct spi_transfer *xfer)
 {
-	unsigned gpio = (unsigned) spi->controller_data;
-	unsigned active = spi->mode & SPI_CS_HIGH;
-	u32 mr;
-	int i;
-	u32 csr;
-	u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0;
-
-	/* Make sure clock polarity is correct */
-	for (i = 0; i < spi->master->num_chipselect; i++) {
-		csr = spi_readl(as, CSR0 + 4 * i);
-		if ((csr ^ cpol) & SPI_BIT(CPOL))
-			spi_writel(as, CSR0 + 4 * i, csr ^ SPI_BIT(CPOL));
-	}
+	return &xfer->transfer_list == msg->transfers.prev;
+}
 
-	mr = spi_readl(as, MR);
-	mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr);
+/*-------------------------------------------------------------------------*/
 
-	dev_dbg(&spi->dev, "activate %u%s, mr %08x\n",
-			gpio, active ? " (high)" : "",
-			mr);
+/*
+ * GCC doesn't eliminate _all_ the dead code, only some of it. In
+ * particular, the file operations appear to be difficult even if the
+ * file operations struct itself gets eliminated.
+ *
+ * So let's do the CPP dance.
+ */
+#ifdef CONFIG_DEBUG_FS
 
-	if (!(cpu_is_at91rm9200() && spi->chip_select == 0))
-		gpio_set_value(gpio, active);
-	spi_writel(as, MR, mr);
-}
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
 
-static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi)
+static int atmel_spi_queue_show(struct seq_file *s, void *v)
 {
-	unsigned gpio = (unsigned) spi->controller_data;
-	unsigned active = spi->mode & SPI_CS_HIGH;
-	u32 mr;
+	struct atmel_spi	*as = s->private;
+	struct spi_message	*msg;
+	struct spi_transfer	*xfer;
 
-	/* only deactivate *this* device; sometimes transfers to
-	 * another device may be active when this routine is called.
-	 */
-	mr = spi_readl(as, MR);
-	if (~SPI_BFEXT(PCS, mr) & (1 << spi->chip_select)) {
-		mr = SPI_BFINS(PCS, 0xf, mr);
-		spi_writel(as, MR, mr);
+	spin_lock_irq(&as->lock);
+	list_for_each_entry(msg, &as->queue, queue) {
+		seq_printf(s, "msg to %s:%s DMA mapped, status %d actual %u\n",
+				msg->spi->dev.bus_id,
+				msg->is_dma_mapped ? "" : " Not",
+				msg->status, msg->actual_length);
+		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+			seq_printf(s, "  t%p r%p l%u%s %u bits %u us %u Hz\n",
+					xfer->tx_buf, xfer->rx_buf, xfer->len,
+					xfer->cs_change ? "cs_change" : "",
+					xfer->bits_per_word,
+					xfer->delay_usecs,
+					xfer->speed_hz);
+		}
 	}
+	spin_unlock_irq(&as->lock);
 
-	dev_dbg(&spi->dev, "DEactivate %u%s, mr %08x\n",
-			gpio, active ? " (low)" : "",
-			mr);
-
-	if (!(cpu_is_at91rm9200() && spi->chip_select == 0))
-		gpio_set_value(gpio, !active);
+	return 0;
 }
 
-static inline int atmel_spi_xfer_is_last(struct spi_message *msg,
-					struct spi_transfer *xfer)
+static int atmel_spi_queue_open(struct inode *inode, struct file *file)
 {
-	return msg->transfers.prev == &xfer->transfer_list;
+	return single_open(file, atmel_spi_queue_show, inode->i_private);
 }
 
-static inline int atmel_spi_xfer_can_be_chained(struct spi_transfer *xfer)
+static const struct file_operations atmel_spi_queue_fops = {
+	.owner		= THIS_MODULE,
+	.open		= atmel_spi_queue_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static void atmel_spi_show_status_reg(struct seq_file *s,
+		const char *regname, u32 value)
 {
-	return xfer->delay_usecs == 0 && !xfer->cs_change;
+	static const char	*sr_bit[] = {
+		[0]	= "RDRF",
+		[1]	= "TDRE",
+		[2]	= "MODF",
+		[3]	= "OVRES",
+		[4]	= "ENDRX",
+		[5]	= "ENDTX",
+		[6]	= "RXBUFF",
+		[7]	= "TXBUFE",
+		[8]	= "NSSR",
+		[9]	= "TXEMPTY",
+		[16]	= "SPIENS",
+	};
+	unsigned int		i;
+
+	seq_printf(s, "%s:\t0x%08x", regname, value);
+	for (i = 0; i < ARRAY_SIZE(sr_bit); i++) {
+		if (value & (1 << i)) {
+			if (sr_bit[i])
+				seq_printf(s, " %s", sr_bit[i]);
+			else
+				seq_printf(s, " UNKNOWN(%u)", i);
+		}
+	}
+	seq_putc(s, '\n');
 }
 
-static void atmel_spi_next_xfer_data(struct spi_master *master,
-				struct spi_transfer *xfer,
-				dma_addr_t *tx_dma,
-				dma_addr_t *rx_dma,
-				u32 *plen)
+static int atmel_spi_regs_show(struct seq_file *s, void *v)
 {
-	struct atmel_spi	*as = spi_master_get_devdata(master);
-	u32			len = *plen;
+	struct atmel_spi	*as = s->private;
+	unsigned int		i;
+	u32			value;
+	u32			*buf;
+
+	buf = kmalloc(0x200, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
-	/* use scratch buffer only when rx or tx data is unspecified */
-	if (xfer->rx_buf)
-		*rx_dma = xfer->rx_dma + xfer->len - len;
-	else {
-		*rx_dma = as->buffer_dma;
-		if (len > BUFFER_SIZE)
-			len = BUFFER_SIZE;
-	}
-	if (xfer->tx_buf)
-		*tx_dma = xfer->tx_dma + xfer->len - len;
-	else {
-		*tx_dma = as->buffer_dma;
-		if (len > BUFFER_SIZE)
-			len = BUFFER_SIZE;
-		memset(as->buffer, 0, len);
-		dma_sync_single_for_device(&as->pdev->dev,
-				as->buffer_dma, len, DMA_TO_DEVICE);
+	/* Grab a more or less consistent snapshot */
+	spin_lock_irq(&as->lock);
+	memcpy_fromio(buf, as->regs, 0x200);
+	spin_unlock_irq(&as->lock);
+
+	value = buf[SPI_MR / 4];
+	seq_printf(s, "MR:\t0x%08x%s%s%s%s%s%s PCS=%x DLYBCS=%u\n",
+			value,
+			(value & SPI_BIT(MSTR)) ? " MSTR" : "",
+			(value & SPI_BIT(PS)) ? " PS" : "",
+			(value & SPI_BIT(PCSDEC)) ? " PCSDEC" : "",
+			(value & SPI_BIT(FDIV)) ? " FDIV" : "",
+			(value & SPI_BIT(MODFDIS)) ? " MODFDIS" : "",
+			(value & SPI_BIT(LLB)) ? " LLB" : "",
+			SPI_BFEXT(PCS, value),
+			SPI_BFEXT(DLYBCS, value));
+
+	atmel_spi_show_status_reg(s, "SR", buf[SPI_SR / 4]);
+	atmel_spi_show_status_reg(s, "IMR", buf[SPI_IMR / 4]);
+
+	for (i = 0; i < 4; i++) {
+		value = buf[SPI_CSR0 / 4 + i];
+		seq_printf(s, "CSR%u:\t0x%08x%s%s%s\n",
+				i, value,
+				(value & SPI_BIT(CPOL)) ? " CPOL" : "",
+				(value & SPI_BIT(NCPHA)) ? " NCPHA" : "",
+				(value & SPI_BIT(CSAAT)) ? " CSAAT" : "");
+		seq_printf(s, "\t\tBITS=%u SCBR=%u DLYBS=%u DLYBCT=%u\n",
+				SPI_BFEXT(BITS, value) + 8,
+				SPI_BFEXT(SCBR, value),
+				SPI_BFEXT(DLYBS, value),
+				SPI_BFEXT(DLYBCT, value));
 	}
 
-	*plen = len;
+	seq_printf(s, "RPR:\t0x%08x\n", buf[SPI_RPR / 4]);
+	seq_printf(s, "RCR:\t0x%08x\n", buf[SPI_RCR / 4]);
+	seq_printf(s, "TPR:\t0x%08x\n", buf[SPI_TPR / 4]);
+	seq_printf(s, "TCR:\t0x%08x\n", buf[SPI_TCR / 4]);
+	seq_printf(s, "RNPR:\t0x%08x\n", buf[SPI_RNPR / 4]);
+	seq_printf(s, "RNCR:\t0x%08x\n", buf[SPI_RNCR / 4]);
+	seq_printf(s, "TNPR:\t0x%08x\n", buf[SPI_TNPR / 4]);
+	seq_printf(s, "TNCR:\t0x%08x\n", buf[SPI_TNCR / 4]);
+
+	value = buf[SPI_PTSR / 4];
+	seq_printf(s, "PTSR:\t0x%08x%s%s\n", value,
+			(value & SPI_BIT(RXTEN)) ? " RXTEN" : "",
+			(value & SPI_BIT(TXTEN)) ? " TXTEN" : "");
+
+	kfree(buf);
+
+	return 0;
 }
 
-/*
- * Submit next transfer for DMA.
- * lock is held, spi irq is blocked
- */
-static void atmel_spi_next_xfer(struct spi_master *master,
-				struct spi_message *msg)
+static int atmel_spi_regs_open(struct inode *inode, struct file *file)
 {
-	struct atmel_spi	*as = spi_master_get_devdata(master);
-	struct spi_transfer	*xfer;
-	u32			len, remaining;
-	u32			ieval;
-	dma_addr_t		tx_dma, rx_dma;
-
-	if (!as->current_transfer)
-		xfer = list_entry(msg->transfers.next,
-				struct spi_transfer, transfer_list);
-	else if (!as->next_transfer)
-		xfer = list_entry(as->current_transfer->transfer_list.next,
-				struct spi_transfer, transfer_list);
-	else
-		xfer = NULL;
-
-	if (xfer) {
-		spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
+	return single_open(file, atmel_spi_regs_show, inode->i_private);
+}
 
-		len = xfer->len;
-		atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len);
-		remaining = xfer->len - len;
+static const struct file_operations atmel_spi_regs_fops = {
+	.owner		= THIS_MODULE,
+	.open		= atmel_spi_regs_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 
-		spi_writel(as, RPR, rx_dma);
-		spi_writel(as, TPR, tx_dma);
+static void atmel_spi_init_debugfs(struct atmel_spi *as)
+{
+	struct dentry	*root;
+	struct dentry	*node;
 
-		if (msg->spi->bits_per_word > 8)
-			len >>= 1;
-		spi_writel(as, RCR, len);
-		spi_writel(as, TCR, len);
+	root = debugfs_create_dir(as->pdev->dev.bus_id, NULL);
+	if (IS_ERR(root))
+		/* Debugfs not enabled */
+		return;
+	if (!root)
+		/* Debugfs enabled, but failed to create directory */
+		goto err_root;
+
+	node = debugfs_create_file("regs", S_IRUSR, root, as,
+			&atmel_spi_regs_fops);
+	if (!node)
+		goto err;
+	node = debugfs_create_file("queue", S_IRUSR, root, as,
+			&atmel_spi_queue_fops);
+	if (!node)
+		goto err;
+
+	as->debugfs_root = root;
+	return;
+
+err:
+	debugfs_remove_recursive(root);
+err_root:
+	dev_err(&as->pdev->dev, "failed to initialize debugfs\n");
+}
 
-		dev_dbg(&msg->spi->dev,
-			"  start xfer %p: len %u tx %p/%08x rx %p/%08x\n",
-			xfer, xfer->len, xfer->tx_buf, xfer->tx_dma,
-			xfer->rx_buf, xfer->rx_dma);
-	} else {
-		xfer = as->next_transfer;
-		remaining = as->next_remaining_bytes;
-	}
+static void atmel_spi_cleanup_debugfs(struct atmel_spi *as)
+{
+	debugfs_remove_recursive(as->debugfs_root);
+}
 
-	as->current_transfer = xfer;
-	as->current_remaining_bytes = remaining;
+#else
+static void atmel_spi_init_debugfs(struct atmel_spi *as)
+{
 
-	if (remaining > 0)
-		len = remaining;
-	else if (!atmel_spi_xfer_is_last(msg, xfer)
-			&& atmel_spi_xfer_can_be_chained(xfer)) {
-		xfer = list_entry(xfer->transfer_list.next,
-				struct spi_transfer, transfer_list);
-		len = xfer->len;
-	} else
-		xfer = NULL;
+}
+static void atmel_spi_cleanup_debugfs(struct atmel_spi *as)
+{
 
-	as->next_transfer = xfer;
+}
+#endif
 
-	if (xfer) {
-		u32	total;
+/*
+ * Earlier SPI controllers (e.g. on at91rm9200) have a design bug whereby
+ * they assume that spi slave device state will not change on deselect, so
+ * that automagic deselection is OK.  ("NPCSx rises if no data is to be
+ * transmitted")  Not so!  Workaround uses nCSx pins as GPIOs; or newer
+ * controllers have CSAAT and friends.
+ *
+ * Since the CSAAT functionality is a bit weird on newer controllers as
+ * well, we use GPIO to control nCSx pins on all controllers, updating
+ * MR.PCS to avoid confusing the controller.  Using GPIOs also lets us
+ * support active-high chipselects despite the controller's belief that
+ * only active-low devices/systems exists.
+ *
+ * However, at91rm9200 has a second erratum whereby nCS0 doesn't work
+ * right when driven with GPIO.  ("Mode Fault does not allow more than one
+ * Master on Chip Select 0.")  No workaround exists for that ... so for
+ * nCS0 on that chip, we (a) don't use the GPIO, (b) can't support CS_HIGH,
+ * and (c) will trigger that first erratum in some cases.
+ *
+ * TODO: Test if the atmel_spi_is_v2() branch below works on
+ * AT91RM9200 if we use some other register than CSR0. However, don't
+ * do this unconditionally since AP7000 has an errata where the BITS
+ * field in CSR0 overrides all other CSRs.
+ */
 
-		total = len;
-		atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len);
-		as->next_remaining_bytes = total - len;
+static void atmel_spi_set_csr(struct atmel_spi *as,
+		struct spi_device *spi, u32 csr)
+{
+	if (atmel_spi_is_v2())
+		spi_writel(as, CSR0, csr);
+	else
+		spi_writel(as, CSR0 + 4 * spi->chip_select, csr);
+}
 
-		spi_writel(as, RNPR, rx_dma);
-		spi_writel(as, TNPR, tx_dma);
+static void cs_activate(struct atmel_spi *as, struct spi_device *spi)
+{
+	struct atmel_spi_device *asd = spi->controller_state;
+	unsigned active = spi->mode & SPI_CS_HIGH;
 
-		if (msg->spi->bits_per_word > 8)
-			len >>= 1;
-		spi_writel(as, RNCR, len);
-		spi_writel(as, TNCR, len);
+	if (atmel_spi_is_v2()) {
+		/*
+		 * Always use CSR0. This ensures that the clock
+		 * switches to the correct idle polarity before we
+		 * toggle the CS.
+		 */
+		atmel_spi_set_csr(as, spi, asd->csr);
+		spi_writel(as, MR, SPI_BF(PCS, 0x0e) | SPI_BIT(MODFDIS)
+				| SPI_BIT(MSTR));
+		spi_readl(as, MR);
+		dev_vdbg(&spi->dev, "activate %u%s, csr0: %08x\n",
+				asd->npcs_pin, active ? " (low)" : "",
+				asd->csr);
 
-		dev_dbg(&msg->spi->dev,
-			"  next xfer %p: len %u tx %p/%08x rx %p/%08x\n",
-			xfer, xfer->len, xfer->tx_buf, xfer->tx_dma,
-			xfer->rx_buf, xfer->rx_dma);
-		ieval = SPI_BIT(ENDRX) | SPI_BIT(OVRES);
+		gpio_set_value(asd->npcs_pin, active);
 	} else {
-		spi_writel(as, RNCR, 0);
-		spi_writel(as, TNCR, 0);
-		ieval = SPI_BIT(RXBUFF) | SPI_BIT(ENDRX) | SPI_BIT(OVRES);
-	}
+		u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0;
+		int i;
+		u32 mr;
+		u32 csr;
+
+		/* Make sure clock polarity is correct */
+		for (i = 0; i < spi->master->num_chipselect; i++) {
+			csr = spi_readl(as, CSR0 + 4 * i);
+			if ((csr ^ cpol) & SPI_BIT(CPOL))
+				spi_writel(as, CSR0 + 4 * i,
+						csr ^ SPI_BIT(CPOL));
+		}
 
-	/* REVISIT: We're waiting for ENDRX before we start the next
-	 * transfer because we need to handle some difficult timing
-	 * issues otherwise. If we wait for ENDTX in one transfer and
-	 * then starts waiting for ENDRX in the next, it's difficult
-	 * to tell the difference between the ENDRX interrupt we're
-	 * actually waiting for and the ENDRX interrupt of the
-	 * previous transfer.
-	 *
-	 * It should be doable, though. Just not now...
-	 */
-	spi_writel(as, IER, ieval);
-	spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN));
+		mr = spi_readl(as, MR);
+		mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr);
+		dev_vdbg(&spi->dev, "activate %u%s, mr: %08x csr: %08x\n",
+				asd->npcs_pin, active ? " (low)" : "",
+				mr, csr);
+		if (spi->chip_select != 0)
+			gpio_set_value(asd->npcs_pin, active);
+		spi_writel(as, MR, mr);
+	}
 }
 
-static void atmel_spi_next_message(struct spi_master *master)
+static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi)
 {
-	struct atmel_spi	*as = spi_master_get_devdata(master);
-	struct spi_message	*msg;
-	struct spi_device	*spi;
-
-	BUG_ON(as->current_transfer);
-
-	msg = list_entry(as->queue.next, struct spi_message, queue);
-	spi = msg->spi;
+	struct atmel_spi_device *asd = spi->controller_state;
+	unsigned active = spi->mode & SPI_CS_HIGH;
+	u32 mr;
 
-	dev_dbg(master->dev.parent, "start message %p for %s\n",
-			msg, spi->dev.bus_id);
+	/* only deactivate *this* device; sometimes transfers to
+	 * another device may be active when this routine is called.
+	 */
+	mr = spi_readl(as, MR);
+	if (~SPI_BFEXT(PCS, mr) & (1 << spi->chip_select)) {
+		mr = SPI_BFINS(PCS, 0xf, mr);
+		spi_writel(as, MR, mr);
+	}
 
-	/* select chip if it's not still active */
-	if (as->stay) {
-		if (as->stay != spi) {
-			cs_deactivate(as, as->stay);
-			cs_activate(as, spi);
-		}
-		as->stay = NULL;
-	} else
-		cs_activate(as, spi);
+	dev_vdbg(&spi->dev, "DEactivate %u%s, mr %08x\n",
+			asd->npcs_pin, active ? " (low)" : "",
+			mr);
 
-	atmel_spi_next_xfer(master, msg);
+	if (atmel_spi_is_v2() || spi->chip_select != 0)
+		gpio_set_value(asd->npcs_pin, !active);
 }
 
 /*
@@ -338,162 +477,460 @@
 	return 0;
 }
 
-static void atmel_spi_dma_unmap_xfer(struct spi_master *master,
+static void atmel_spi_dma_unmap_xfer(struct atmel_spi *as,
 				     struct spi_transfer *xfer)
 {
 	if (xfer->tx_dma != INVALID_DMA_ADDRESS)
-		dma_unmap_single(master->dev.parent, xfer->tx_dma,
+		dma_unmap_single(&as->pdev->dev, xfer->tx_dma,
 				 xfer->len, DMA_TO_DEVICE);
 	if (xfer->rx_dma != INVALID_DMA_ADDRESS)
-		dma_unmap_single(master->dev.parent, xfer->rx_dma,
+		dma_unmap_single(&as->pdev->dev, xfer->rx_dma,
 				 xfer->len, DMA_FROM_DEVICE);
 }
 
-static void
-atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as,
-		struct spi_message *msg, int status, int stay)
+static void atmel_spi_dma_unmap_msg(struct atmel_spi *as, struct spi_message *msg)
 {
-	if (!stay || status < 0)
-		cs_deactivate(as, msg->spi);
-	else
-		as->stay = msg->spi;
+	struct spi_transfer	*xfer;
 
-	list_del(&msg->queue);
-	msg->status = status;
+	if (!msg->is_dma_mapped)
+		list_for_each_entry(xfer, &msg->transfers, transfer_list)
+			atmel_spi_dma_unmap_xfer(as, xfer);
+}
 
-	dev_dbg(master->dev.parent,
-		"xfer complete: %u bytes transferred\n",
-		msg->actual_length);
+static void atmel_spi_handle_error(struct atmel_spi *as,
+		struct spi_message *msg, int err)
+{
+	unsigned int timeout;
 
-	spin_unlock(&as->lock);
-	msg->complete(msg->context);
-	spin_lock(&as->lock);
+	/* Drain the buffers so that the hardware is ready for a new message */
+	for (timeout = 1000; timeout; timeout--)
+		if (spi_readl(as, SR) & SPI_BIT(TXEMPTY))
+			break;
+	if (!timeout)
+		dev_warn(&msg->spi->dev,
+			 "timeout waiting for TXEMPTY");
+	while (spi_readl(as, SR) & SPI_BIT(RDRF))
+		spi_readl(as, RDR);
 
-	as->current_transfer = NULL;
-	as->next_transfer = NULL;
+	/* Clear any overrun happening while cleaning up */
+	spi_readl(as, SR);
 
-	/* continue if needed */
-	if (list_empty(&as->queue) || as->stopping)
-		spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
-	else
-		atmel_spi_next_message(master);
+	msg->status = err;
+	as->error = 0;
 }
 
-static irqreturn_t
-atmel_spi_interrupt(int irq, void *dev_id)
+#ifdef CONFIG_SPI_ATMEL_HAVE_PDC
+static int atmel_spi_wait_idle(struct atmel_spi *as, struct spi_message *msg)
 {
-	struct spi_master	*master = dev_id;
-	struct atmel_spi	*as = spi_master_get_devdata(master);
-	struct spi_message	*msg;
-	struct spi_transfer	*xfer;
-	u32			status, pending, imr;
-	int			ret = IRQ_NONE;
+	int err;
 
-	spin_lock(&as->lock);
+	wait_event(as->wait, as->pending == 0);
+	err = as->error;
+	if (err) {
+		dev_warn(&msg->spi->dev,
+				"transfer error %d (%u/%u remaining)\n",
+				err, spi_readl(as, TCR), spi_readl(as, RCR));
 
-	xfer = as->current_transfer;
-	msg = list_entry(as->queue.next, struct spi_message, queue);
+		spi_writel(as, TNCR, 0);
+		spi_writel(as, RNCR, 0);
+		spi_writel(as, TCR, 0);
+		spi_writel(as, RCR, 0);
 
-	imr = spi_readl(as, IMR);
-	status = spi_readl(as, SR);
-	pending = status & imr;
+		atmel_spi_handle_error(as, msg, err);
 
-	if (pending & SPI_BIT(OVRES)) {
-		int timeout;
+		return err;
+	}
 
-		ret = IRQ_HANDLED;
+	msg->actual_length += as->pending_bytes;
+	as->pending_bytes = 0;
 
-		spi_writel(as, IDR, (SPI_BIT(RXBUFF) | SPI_BIT(ENDRX)
-				     | SPI_BIT(OVRES)));
+	dev_vdbg(&msg->spi->dev, "controller idle, xfered so far: %u\n",
+			msg->actual_length);
+
+	return 0;
+}
+
+static int atmel_spi_submit_xfer(struct atmel_spi *as, struct spi_device *spi,
+		struct spi_message *msg, struct spi_transfer *xfer)
+{
+	unsigned int	bits = xfer->bits_per_word;
+	unsigned int	speed_hz = xfer->speed_hz;
+	unsigned int	submitted = 0;
+	dma_addr_t	rx_dma;
+	dma_addr_t	tx_dma;
+
+	dev_vdbg(&spi->dev, "submit_xfer len %u rx %p tx %p\n",
+			xfer->len, xfer->rx_buf, xfer->tx_buf);
+	dev_vdbg(&spi->dev, "  csc %u bpw %u delay %u speed %u\n",
+			xfer->cs_change, xfer->bits_per_word,
+			xfer->delay_usecs, xfer->speed_hz);
+
+	if (bits || speed_hz) {
+		struct atmel_spi_device *asd;
+		u32 csr;
+
+		if (atmel_spi_wait_idle(as, msg))
+			return 0;
+
+		asd = spi->controller_state;
+		csr = asd->csr;
+
+		if (bits)
+			csr = SPI_BFINS(BITS, csr, bits - 8);
+		if (speed_hz) {
+			u32 scbr = DIV_ROUND_UP(as->base_hz, speed_hz);
+			csr = SPI_BFINS(SCBR, csr, scbr);
+		}
+
+		atmel_spi_set_csr(as, spi, csr);
+	}
+
+	if (!bits)
+		bits = spi->bits_per_word;
+
+	/* PDC stuff starts here */
+	while (submitted < xfer->len) {
+		unsigned long len;
+
+		wait_event(as->wait, as->pending < 2);
 
 		/*
-		 * When we get an overrun, we disregard the current
-		 * transfer. Data will not be copied back from any
-		 * bounce buffer and msg->actual_len will not be
-		 * updated with the last xfer.
-		 *
-		 * We will also not process any remaning transfers in
-		 * the message.
-		 *
-		 * First, stop the transfer and unmap the DMA buffers.
+		 * This gives the RX side a slight advantage, making
+		 * overruns less likely.
 		 */
-		spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
-		if (!msg->is_dma_mapped)
-			atmel_spi_dma_unmap_xfer(master, xfer);
+		spi_writel(as, PTCR, SPI_BIT(TXTDIS));
+
+		len = xfer->len - submitted;
+		if (xfer->rx_buf) {
+			rx_dma = xfer->rx_dma + submitted;
+		} else {
+			rx_dma = as->buffer_dma;
+			len = min(len, BUFFER_SIZE);
+		}
+		if (xfer->tx_buf) {
+			tx_dma = xfer->tx_dma + submitted;
+		} else {
+			tx_dma = as->buffer_dma;
+			len = min(len, BUFFER_SIZE);
+			memset(as->buffer, 0, len);
+		}
+
+		submitted += len;
+		if (bits > 8)
+			len >>= 1;
+
+		spin_lock_irq(&as->lock);
+		if (as->error) {
+			spin_unlock_irq(&as->lock);
+			atmel_spi_wait_idle(as, msg);
+			return 0;
+		}
+
+		spi_writel(as, RNPR, rx_dma);
+		spi_writel(as, RNCR, len);
+		spi_writel(as, TNPR, tx_dma);
+		spi_writel(as, TNCR, len);
+		spi_writel(as, IER, SPI_BIT(RXBUFF) | SPI_BIT(ENDRX)
+				| SPI_BIT(OVRES));
+		spi_writel(as, PTCR, SPI_BIT(RXTEN) | SPI_BIT(TXTEN));
+		as->pending++;
+		spin_unlock_irq(&as->lock);
+	}
 
-		/* REVISIT: udelay in irq is unfriendly */
+	as->pending_bytes += submitted;
+
+	if (xfer->delay_usecs || xfer->cs_change || xfer->bits_per_word
+			|| xfer->speed_hz) {
+		struct atmel_spi_device	*asd = spi->controller_state;
+		int			err;
+
+		err = atmel_spi_wait_idle(as, msg);
 		if (xfer->delay_usecs)
 			udelay(xfer->delay_usecs);
+		atmel_spi_set_csr(as, spi, asd->csr);
+		if (err)
+			return 0;
+
+		if (xfer->cs_change && !atmel_spi_xfer_is_last(msg, xfer)) {
+			cs_deactivate(as, spi);
+			udelay(1);
+			cs_activate(as, spi);
+		}
+	}
 
-		dev_warn(master->dev.parent, "overrun (%u/%u remaining)\n",
-			 spi_readl(as, TCR), spi_readl(as, RCR));
+	return xfer->cs_change;
+}
 
-		/*
-		 * Clean up DMA registers and make sure the data
-		 * registers are empty.
-		 */
-		spi_writel(as, RNCR, 0);
-		spi_writel(as, TNCR, 0);
-		spi_writel(as, RCR, 0);
-		spi_writel(as, TCR, 0);
-		for (timeout = 1000; timeout; timeout--)
-			if (spi_readl(as, SR) & SPI_BIT(TXEMPTY))
-				break;
-		if (!timeout)
-			dev_warn(master->dev.parent,
-				 "timeout waiting for TXEMPTY");
-		while (spi_readl(as, SR) & SPI_BIT(RDRF))
-			spi_readl(as, RDR);
-
-		/* Clear any overrun happening while cleaning up */
-		spi_readl(as, SR);
-
-		atmel_spi_msg_done(master, as, msg, -EIO, 0);
-	} else if (pending & (SPI_BIT(RXBUFF) | SPI_BIT(ENDRX))) {
-		ret = IRQ_HANDLED;
+#else /* Use DMA engine framework, not PDC */
 
-		spi_writel(as, IDR, pending);
+static void atmel_spi_dma_complete(void *param)
+{
+	struct atmel_spi	*as = param;
 
-		if (as->current_remaining_bytes == 0) {
-			msg->actual_length += xfer->len;
+	as->pending = 0;
+	as->sg_len = 0;
+	wake_up(&as->wait);
+}
 
-			if (!msg->is_dma_mapped)
-				atmel_spi_dma_unmap_xfer(master, xfer);
+static int atmel_spi_wait_idle(struct atmel_spi *as, struct spi_message *msg)
+{
+	struct dma_chan			*tx_chan = as->tx_chan;
+	struct dma_chan			*rx_chan = as->rx_chan;
+	struct dma_device		*dma = rx_chan->device;
+	struct dma_async_tx_descriptor	*tx_desc;
+	struct dma_async_tx_descriptor	*rx_desc;
+	int				err;
+
+	dev_vdbg(&msg->spi->dev, "wait_idle: sg_len=%u\n", as->sg_len);
+
+	if (!as->sg_len)
+		return 0;
+
+	sg_mark_end(as->tx_sg + (as->sg_len - 1));
+	sg_mark_end(as->rx_sg + (as->sg_len - 1));
+	as->pending = 1;
+	smp_wmb();
+
+	tx_desc = dma->device_prep_slave_sg(tx_chan,
+			as->tx_sg, as->sg_len, DMA_TO_DEVICE,
+			DMA_COMPL_SKIP_SRC_UNMAP | DMA_CTRL_ACK);
+	rx_desc = dma->device_prep_slave_sg(rx_chan,
+			as->rx_sg, as->sg_len, DMA_FROM_DEVICE,
+			DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_DEST_UNMAP
+			| DMA_CTRL_ACK);
+	rx_desc->callback = atmel_spi_dma_complete;
+	rx_desc->callback_param = as;
+	rx_desc->tx_submit(rx_desc);
+	tx_desc->tx_submit(tx_desc);
+	dma->device_issue_pending(rx_chan);
+	dma->device_issue_pending(tx_chan);
+
+	spi_writel(as, IER, SPI_BIT(OVRES));
+	wait_event(as->wait, !as->pending);
+	spi_writel(as, IDR, SPI_BIT(OVRES));
+	err = as->error;
+	if (err) {
+		dev_warn(&msg->spi->dev, "transfer error %d\n", err);
 
-			/* REVISIT: udelay in irq is unfriendly */
-			if (xfer->delay_usecs)
-				udelay(xfer->delay_usecs);
-
-			if (atmel_spi_xfer_is_last(msg, xfer)) {
-				/* report completed message */
-				atmel_spi_msg_done(master, as, msg, 0,
-						xfer->cs_change);
-			} else {
-				if (xfer->cs_change) {
-					cs_deactivate(as, msg->spi);
-					udelay(1);
-					cs_activate(as, msg->spi);
-				}
+		dma->device_terminate_all(tx_chan);
+		dma->device_terminate_all(rx_chan);
+
+		atmel_spi_handle_error(as, msg, err);
+
+		return err;
+	}
+
+	msg->actual_length += as->pending_bytes;
+	as->pending_bytes = 0;
+	sg_init_table(as->rx_sg, MAX_SG_SEGS);
+	sg_init_table(as->tx_sg, MAX_SG_SEGS);
+
+	dev_vdbg(&msg->spi->dev, "controller idle, xfered so far: %u\n",
+			msg->actual_length);
+
+	return 0;
+}
+
+static int atmel_spi_submit_xfer(struct atmel_spi *as, struct spi_device *spi,
+		struct spi_message *msg, struct spi_transfer *xfer)
+{
+	unsigned int	bits = xfer->bits_per_word;
+	unsigned int	speed_hz = xfer->speed_hz;
+	unsigned int	submitted = 0;
+	unsigned int	i;
+
+	dev_vdbg(&spi->dev, "submit_xfer len %u rx %p tx %p\n",
+			xfer->len, xfer->rx_buf, xfer->tx_buf);
+	dev_vdbg(&spi->dev, "  csc %u bpw %u delay %u speed %u\n",
+			xfer->cs_change, xfer->bits_per_word,
+			xfer->delay_usecs, xfer->speed_hz);
+
+	if (bits || speed_hz) {
+		struct atmel_spi_device *asd;
+		u32 csr;
+
+		if (atmel_spi_wait_idle(as, msg))
+			return 0;
+
+		asd = spi->controller_state;
+		csr = asd->csr;
+
+		if (bits)
+			csr = SPI_BFINS(BITS, csr, bits - 8);
+		if (speed_hz) {
+			u32 scbr = DIV_ROUND_UP(as->base_hz, speed_hz);
+			csr = SPI_BFINS(SCBR, csr, scbr);
+		}
+
+		atmel_spi_set_csr(as, spi, csr);
+	}
+
+	if (!bits)
+		bits = spi->bits_per_word;
+
+	i = as->sg_len;
+	while (submitted < xfer->len) {
+		unsigned long len;
+
+		if (i == MAX_SG_SEGS) {
+			if (atmel_spi_wait_idle(as, msg))
+				return 0;
+			i = 0;
+		}
+
+		len = xfer->len - submitted;
+		if (!xfer->rx_buf || !xfer->tx_buf)
+			len = min(len, BUFFER_SIZE);
+
+		if (xfer->rx_buf) {
+			sg_set_buf(&as->rx_sg[i], xfer->rx_buf + submitted, len);
+			as->rx_sg[i].dma_address = xfer->rx_dma + submitted;
+		} else {
+			sg_set_buf(&as->rx_sg[i], as->buffer, len);
+			as->rx_sg[i].dma_address = as->buffer_dma;
+		}
+		if (xfer->tx_buf) {
+			sg_set_buf(&as->tx_sg[i], xfer->tx_buf + submitted, len);
+			as->tx_sg[i].dma_address = xfer->tx_dma + submitted;
+		} else {
+			sg_set_buf(&as->tx_sg[i], as->buffer, len);
+			as->tx_sg[i].dma_address = as->buffer_dma;
+			memset(as->buffer, 0, len);
+		}
+
+		submitted += len;
+		as->sg_len = ++i;
+	}
+
+	as->pending_bytes += submitted;
 
-				/*
-				 * Not done yet. Submit the next transfer.
-				 *
-				 * FIXME handle protocol options for xfer
-				 */
-				atmel_spi_next_xfer(master, msg);
+	if (xfer->delay_usecs || xfer->cs_change || xfer->bits_per_word
+			|| xfer->speed_hz) {
+		struct atmel_spi_device	*asd = spi->controller_state;
+		int			err;
+
+		err = atmel_spi_wait_idle(as, msg);
+		if (xfer->delay_usecs)
+			udelay(xfer->delay_usecs);
+		atmel_spi_set_csr(as, spi, asd->csr);
+		if (err)
+			return 0;
+
+		if (xfer->cs_change && !atmel_spi_xfer_is_last(msg, xfer)) {
+			cs_deactivate(as, spi);
+			udelay(1);
+			cs_activate(as, spi);
+		}
+	}
+
+	return xfer->cs_change;
+}
+
+#endif /* PDC vs. DMA engine */
+
+static void atmel_spi_work(struct work_struct *work)
+{
+	struct atmel_spi	*as;
+
+	as = container_of(work, struct atmel_spi, work);
+
+	spin_lock_irq(&as->lock);
+	while (!list_empty(&as->queue)) {
+		struct spi_message	*msg;
+		struct spi_transfer	*xfer;
+		struct spi_device	*spi;
+		int			cs_change = 0;
+
+		if (as->stopping)
+			break;
+
+		msg = list_entry(as->queue.next, struct spi_message, queue);
+		spin_unlock_irq(&as->lock);
+
+		spi = msg->spi;
+
+		if (as->stay) {
+			if (as->stay != spi) {
+				cs_deactivate(as, as->stay);
+				cs_activate(as, spi);
 			}
+			as->stay = NULL;
 		} else {
-			/*
-			 * Keep going, we still have data to send in
-			 * the current transfer.
-			 */
-			atmel_spi_next_xfer(master, msg);
+			cs_activate(as, spi);
+		}
+
+#ifndef CONFIG_SPI_ATMEL_HAVE_PDC
+		sg_init_table(as->rx_sg, MAX_SG_SEGS);
+		sg_init_table(as->tx_sg, MAX_SG_SEGS);
+#endif
+
+		list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+			if (msg->status != -EINPROGRESS)
+				break;
+			cs_change = atmel_spi_submit_xfer(as, spi, msg, xfer);
+		}
+
+		if (msg->status == -EINPROGRESS) {
+			if (atmel_spi_wait_idle(as, msg))
+				cs_change = 1;
+			else
+				msg->status = 0;
 		}
+		if (!cs_change)
+			cs_deactivate(as, spi);
+		else
+			as->stay = spi;
+
+		atmel_spi_dma_unmap_msg(as, msg);
+
+		msg->complete(msg->context);
+		spin_lock_irq(&as->lock);
+		list_del(&msg->queue);
 	}
+	spin_unlock_irq(&as->lock);
+}
+
+static irqreturn_t atmel_spi_interrupt(int irq, void *dev_id)
+{
+	struct atmel_spi	*as = dev_id;
+	u32			status;
+	u32			mask;
+	u32			pending;
+
+	spin_lock(&as->lock);
+
+	status = spi_readl(as, SR);
+	mask = spi_readl(as, IMR);
+	pending = status & mask;
+
+	if (pending & SPI_BIT(OVRES)) {
+#ifdef CONFIG_SPI_ATMEL_HAVE_PDC
+		spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
+#endif
+		spi_writel(as, IDR, ~0UL);
+		as->error = -EIO;
+		as->pending = 0;
+#ifdef CONFIG_SPI_ATMEL_HAVE_PDC
+	} else if (pending & SPI_BIT(RXBUFF)) {
+		spi_writel(as, IDR, ~0UL);
+		as->pending = 0;
+	} else if (pending & SPI_BIT(ENDRX)) {
+		spi_writel(as, IDR, SPI_BIT(ENDRX));
+		as->pending--;
+#endif
+	} else {
+		dev_err(&as->pdev->dev,
+			"unexpected interrupt: SR=0x%08x MR=0x%08x\n",
+				status, mask);
+		spi_writel(as, IDR, pending);
+	}
+
+	spi_readl(as, IMR);
+	wake_up(&as->wait);
 
 	spin_unlock(&as->lock);
 
-	return ret;
+	return IRQ_HANDLED;
 }
 
 /* the spi->mode bits understood by this driver: */
@@ -502,6 +939,7 @@
 static int atmel_spi_setup(struct spi_device *spi)
 {
 	struct atmel_spi	*as;
+	struct atmel_spi_device	*asd;
 	u32			scbr, csr;
 	unsigned int		bits = spi->bits_per_word;
 	unsigned long		bus_hz;
@@ -536,21 +974,14 @@
 	}
 
 	/* see notes above re chipselect */
-	if (cpu_is_at91rm9200()
+	if (!atmel_spi_is_v2()
 			&& spi->chip_select == 0
 			&& (spi->mode & SPI_CS_HIGH)) {
 		dev_dbg(&spi->dev, "setup: can't be active-high\n");
 		return -EINVAL;
 	}
 
-	/*
-	 * Pre-new_1 chips start out at half the peripheral
-	 * bus speed.
-	 */
-	bus_hz = clk_get_rate(as->clk);
-	if (!as->new_1)
-		bus_hz /= 2;
-
+	bus_hz = as->base_hz;
 	if (spi->max_speed_hz) {
 		/*
 		 * Calculate the lowest divider that satisfies the
@@ -589,11 +1020,20 @@
 
 	/* chipselect must have been muxed as GPIO (e.g. in board setup) */
 	npcs_pin = (unsigned int)spi->controller_data;
-	if (!spi->controller_state) {
+	asd = spi->controller_state;
+	if (!asd) {
+		asd = kzalloc(sizeof(struct atmel_spi_device), GFP_KERNEL);
+		if (!asd)
+			return -ENOMEM;
+
 		ret = gpio_request(npcs_pin, spi->dev.bus_id);
-		if (ret)
+		if (ret) {
+			kfree(asd);
 			return ret;
-		spi->controller_state = (void *)npcs_pin;
+		}
+
+		asd->npcs_pin = npcs_pin;
+		spi->controller_state = asd;
 		gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH));
 	} else {
 		unsigned long		flags;
@@ -605,11 +1045,14 @@
 		spin_unlock_irqrestore(&as->lock, flags);
 	}
 
+	asd->csr = csr;
+
 	dev_dbg(&spi->dev,
 		"setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n",
 		bus_hz / scbr, bits, spi->mode, spi->chip_select, csr);
 
-	spi_writel(as, CSR0 + 4 * spi->chip_select, csr);
+	if (!atmel_spi_is_v2())
+		spi_writel(as, CSR0 + 4 * spi->chip_select, csr);
 
 	return 0;
 }
@@ -620,74 +1063,81 @@
 	struct spi_transfer	*xfer;
 	unsigned long		flags;
 	struct device		*controller = spi->master->dev.parent;
+	int			ret;
 
 	as = spi_master_get_devdata(spi->master);
 
-	dev_dbg(controller, "new message %p submitted for %s\n",
+	dev_vdbg(controller, "new message %p submitted for %s\n",
 			msg, spi->dev.bus_id);
 
 	if (unlikely(list_empty(&msg->transfers)
 			|| !spi->max_speed_hz))
 		return -EINVAL;
 
-	if (as->stopping)
-		return -ESHUTDOWN;
-
 	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
 		if (!(xfer->tx_buf || xfer->rx_buf) && xfer->len) {
 			dev_dbg(&spi->dev, "missing rx or tx buf\n");
 			return -EINVAL;
 		}
 
-		/* FIXME implement these protocol options!! */
-		if (xfer->bits_per_word || xfer->speed_hz) {
-			dev_dbg(&spi->dev, "no protocol options yet\n");
-			return -ENOPROTOOPT;
+		if (xfer->bits_per_word && (xfer->bits_per_word < 8
+					|| xfer->bits_per_word > 16)) {
+			dev_dbg(&spi->dev, "unsupported bits_per_word\n");
+			return -EINVAL;
+		}
+		if (xfer->speed_hz) {
+			unsigned long divider;
+			divider = DIV_ROUND_UP(as->base_hz, xfer->speed_hz);
+
+			if (divider > 255) {
+				dev_dbg(&spi->dev, "speed_hz too low\n");
+				return -EINVAL;
+			}
 		}
 
 		/*
 		 * DMA map early, for performance (empties dcache ASAP) and
 		 * better fault reporting.  This is a DMA-only driver.
-		 *
-		 * NOTE that if dma_unmap_single() ever starts to do work on
-		 * platforms supported by this driver, we would need to clean
-		 * up mappings for previously-mapped transfers.
 		 */
 		if (!msg->is_dma_mapped) {
-			if (atmel_spi_dma_map_xfer(as, xfer) < 0)
+			if (atmel_spi_dma_map_xfer(as, xfer) < 0) {
+				/* Ick */
+				while (xfer->transfer_list.prev != &msg->transfers) {
+					xfer = list_entry(xfer->transfer_list.prev,
+							struct spi_transfer,
+							transfer_list);
+					atmel_spi_dma_unmap_xfer(as, xfer);
+				}
+
 				return -ENOMEM;
+			}
 		}
 	}
 
-#ifdef VERBOSE
-	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
-		dev_dbg(controller,
-			"  xfer %p: len %u tx %p/%08x rx %p/%08x\n",
-			xfer, xfer->len,
-			xfer->tx_buf, xfer->tx_dma,
-			xfer->rx_buf, xfer->rx_dma);
-	}
-#endif
-
 	msg->status = -EINPROGRESS;
 	msg->actual_length = 0;
 
 	spin_lock_irqsave(&as->lock, flags);
-	list_add_tail(&msg->queue, &as->queue);
-	if (!as->current_transfer)
-		atmel_spi_next_message(spi->master);
+	if (as->stopping) {
+		ret = -ESHUTDOWN;
+	} else {
+		list_add_tail(&msg->queue, &as->queue);
+		queue_work(as->workqueue, &as->work);
+		ret = 0;
+	}
 	spin_unlock_irqrestore(&as->lock, flags);
 
-	return 0;
+	return ret;
 }
 
 static void atmel_spi_cleanup(struct spi_device *spi)
 {
 	struct atmel_spi	*as = spi_master_get_devdata(spi->master);
+	struct atmel_spi_device	*asd = spi->controller_state;
 	unsigned		gpio = (unsigned) spi->controller_data;
 	unsigned long		flags;
 
-	if (!spi->controller_state)
+	if (!asd)
 		return;
 
 	spin_lock_irqsave(&as->lock, flags);
@@ -697,14 +1147,131 @@
 	}
 	spin_unlock_irqrestore(&as->lock, flags);
 
+	spi->controller_state = NULL;
 	gpio_free(gpio);
+	kfree(asd);
+}
+
+static void atmel_spi_stop_queue(struct atmel_spi *as)
+{
+	struct spi_message	*msg;
+
+	/*
+	 * Prevent any new messages from being submitted, cancel any
+	 * submitted but not-yet-started messages, and wait for any
+	 * ongoing messages to complete.
+	 */
+	as->stopping = true;
+	smp_wmb();
+	cancel_work_sync(&as->work);
+
+	/* Terminate anything that was left over */
+	list_for_each_entry(msg, &as->queue, queue) {
+		atmel_spi_dma_unmap_msg(as, msg);
+		msg->status = -ESHUTDOWN;
+		msg->complete(msg->context);
+	}
+}
+
+#ifndef CONFIG_SPI_ATMEL_HAVE_PDC
+static enum dma_state_client atmel_spi_dma_chan_avail(struct atmel_spi *as,
+		struct dma_chan *chan, struct dma_chan **pchan)
+{
+	enum dma_state_client ret = DMA_NAK;
+
+	if (!*pchan) {
+		as->stopping = false;
+		*pchan = chan;
+		ret = DMA_ACK;
+	}
+
+	return ret;
+}
+
+static enum dma_state_client atmel_spi_dma_chan_removed(struct atmel_spi *as,
+		struct dma_chan *chan, struct dma_chan **pchan)
+{
+	enum dma_state_client ret = DMA_NAK;
+
+	if (chan == *pchan) {
+		atmel_spi_stop_queue(as);
+		*pchan = NULL;
+		ret = DMA_ACK;
+	}
+
+	return ret;
+}
+
+static enum dma_state_client atmel_spi_dma_rx_event(struct dma_client *client,
+		struct dma_chan *chan, enum dma_state state)
+{
+	struct atmel_spi	*as;
+	enum dma_state_client	ret = DMA_NAK;
+
+	as = container_of(client, struct atmel_spi, rx_client);
+
+	switch (state) {
+	case DMA_RESOURCE_AVAILABLE:
+		ret = atmel_spi_dma_chan_avail(as, chan, &as->rx_chan);
+		if (ret == DMA_ACK)
+			dev_info(&as->pdev->dev,
+					"Using %s for DMA RX transfers\n",
+					chan->dev.bus_id);
+		break;
+
+	case DMA_RESOURCE_REMOVED:
+		ret = atmel_spi_dma_chan_removed(as, chan, &as->rx_chan);
+		if (ret == DMA_ACK)
+			dev_info(&as->pdev->dev, "Lost %s, queue stopped\n",
+					chan->dev.bus_id);
+		break;
+
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+static enum dma_state_client atmel_spi_dma_tx_event(struct dma_client *client,
+		struct dma_chan *chan, enum dma_state state)
+{
+	struct atmel_spi	*as;
+	enum dma_state_client	ret = DMA_NAK;
+
+	as = container_of(client, struct atmel_spi, tx_client);
+
+	switch (state) {
+	case DMA_RESOURCE_AVAILABLE:
+		ret = atmel_spi_dma_chan_avail(as, chan, &as->tx_chan);
+		if (ret == DMA_ACK)
+			dev_info(&as->pdev->dev,
+					"Using %s for DMA TX transfers\n",
+					chan->dev.bus_id);
+		break;
+
+	case DMA_RESOURCE_REMOVED:
+		ret = atmel_spi_dma_chan_removed(as, chan, &as->tx_chan);
+		if (ret == DMA_ACK)
+			dev_info(&as->pdev->dev, "Lost %s, queue stopped\n",
+					chan->dev.bus_id);
+		break;
+
+	default:
+		break;
+	}
+
+	return ret;
 }
+#endif
 
 /*-------------------------------------------------------------------------*/
 
 static int __init atmel_spi_probe(struct platform_device *pdev)
 {
 	struct resource		*regs;
+	struct resource		*buf;
+	struct atmel_spi_pdata	*pdata;
 	int			irq;
 	struct clk		*clk;
 	int			ret;
@@ -719,6 +1286,14 @@
 	if (irq < 0)
 		return irq;
 
+	pdata = pdev->dev.platform_data;
+#ifndef CONFIG_SPI_ATMEL_HAVE_PDC
+	if (!pdata) {
+		dev_dbg(&pdev->dev, "no platform data\n");
+		return -ENXIO;
+	}
+#endif
+
 	clk = clk_get(&pdev->dev, "spi_clk");
 	if (IS_ERR(clk))
 		return PTR_ERR(clk);
@@ -738,31 +1313,65 @@
 
 	as = spi_master_get_devdata(master);
 
-	/*
-	 * Scratch buffer is used for throwaway rx and tx data.
-	 * It's coherent to minimize dcache pollution.
-	 */
-	as->buffer = dma_alloc_coherent(&pdev->dev, BUFFER_SIZE,
-					&as->buffer_dma, GFP_KERNEL);
-	if (!as->buffer)
-		goto out_free;
+	buf = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (buf) {
+		as->buffer_dma = buf->start;
+		as->buffer_size
+			= rounddown_pow_of_two(buf->end - buf->start + 1);
+		if (as->buffer_size) {
+			as->buffer = (void __force *)ioremap(buf->start,
+					as->buffer_size);
+			if (as->buffer)
+				as->always_bounce = true;
+		}
+	}
+
+	if (!as->buffer) {
+		/*
+		 * Scratch buffer is used for throwaway rx and tx data.
+		 * It's coherent to minimize dcache pollution.
+		 */
+		as->buffer = dma_alloc_coherent(&pdev->dev, BUFFER_SIZE,
+						&as->buffer_dma, GFP_KERNEL);
+		if (!as->buffer)
+			goto out_free;
+	}
 
 	spin_lock_init(&as->lock);
+	init_waitqueue_head(&as->wait);
 	INIT_LIST_HEAD(&as->queue);
+	INIT_WORK(&as->work, atmel_spi_work);
 	as->pdev = pdev;
+	as->clk = clk;
 	as->regs = ioremap(regs->start, (regs->end - regs->start) + 1);
 	if (!as->regs)
 		goto out_free_buffer;
-	as->irq = irq;
-	as->clk = clk;
-	if (!cpu_is_at91rm9200())
-		as->new_1 = 1;
 
-	ret = request_irq(irq, atmel_spi_interrupt, 0,
-			pdev->dev.bus_id, master);
+	ret = request_irq(irq, atmel_spi_interrupt, 0, pdev->dev.bus_id, as);
 	if (ret)
 		goto out_unmap_regs;
 
+	as->workqueue = create_singlethread_workqueue(pdev->dev.bus_id);
+	if (!as->workqueue)
+		goto out_free_irq;
+
+#ifndef CONFIG_SPI_ATMEL_HAVE_PDC
+	as->rx_client.event_callback = atmel_spi_dma_rx_event;
+	dma_cap_set(DMA_SLAVE, as->rx_client.cap_mask);
+	as->rx_client.slave = pdata->rx_dma_slave;
+	pdata->rx_dma_slave->rx_reg = regs->start + SPI_RDR + 3;
+
+	as->tx_client.event_callback = atmel_spi_dma_tx_event;
+	dma_cap_set(DMA_SLAVE, as->tx_client.cap_mask);
+	as->tx_client.slave = pdata->tx_dma_slave;
+	pdata->tx_dma_slave->tx_reg = regs->start + SPI_TDR + 3;
+
+	dma_async_client_register(&as->rx_client);
+	dma_async_client_register(&as->tx_client);
+	dma_async_client_chan_request(&as->rx_client);
+	dma_async_client_chan_request(&as->tx_client);
+#endif
+
 	/* Initialize the hardware */
 	clk_enable(clk);
 	spi_writel(as, CR, SPI_BIT(SWRST));
@@ -771,9 +1380,19 @@
 	spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
 	spi_writel(as, CR, SPI_BIT(SPIEN));
 
+	/* v1 chips start out at half the peripheral bus speed. */
+	as->base_hz = clk_get_rate(clk);
+	if (!atmel_spi_is_v2())
+		as->base_hz /= 2;
+
 	/* go! */
 	dev_info(&pdev->dev, "Atmel SPI Controller at 0x%08lx (irq %d)\n",
 			(unsigned long)regs->start, irq);
+	if (as->always_bounce)
+		dev_info(&pdev->dev, "Using bounce buffer at 0x%08x len %zu\n",
+				as->buffer_dma, as->buffer_size);
+
+	atmel_spi_init_debugfs(as);
 
 	ret = spi_register_master(master);
 	if (ret)
@@ -782,10 +1401,17 @@
 	return 0;
 
 out_reset_hw:
+	atmel_spi_cleanup_debugfs(as);
 	spi_writel(as, CR, SPI_BIT(SWRST));
 	spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
 	clk_disable(clk);
-	free_irq(irq, master);
+#ifndef CONFIG_SPI_ATMEL_HAVE_PDC
+	dma_async_client_unregister(&as->tx_client);
+	dma_async_client_unregister(&as->rx_client);
+#endif
+	destroy_workqueue(as->workqueue);
+out_free_irq:
+	free_irq(irq, as);
 out_unmap_regs:
 	iounmap(as->regs);
 out_free_buffer:
@@ -801,34 +1427,34 @@
 {
 	struct spi_master	*master = platform_get_drvdata(pdev);
 	struct atmel_spi	*as = spi_master_get_devdata(master);
-	struct spi_message	*msg;
 
-	/* reset the hardware and block queue progress */
-	spin_lock_irq(&as->lock);
-	as->stopping = 1;
-	spi_writel(as, CR, SPI_BIT(SWRST));
-	spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */
-	spi_readl(as, SR);
-	spin_unlock_irq(&as->lock);
+	/* Stop the queue */
+	atmel_spi_stop_queue(as);
 
-	/* Terminate remaining queued transfers */
-	list_for_each_entry(msg, &as->queue, queue) {
-		/* REVISIT unmapping the dma is a NOP on ARM and AVR32
-		 * but we shouldn't depend on that...
-		 */
-		msg->status = -ESHUTDOWN;
-		msg->complete(msg->context);
-	}
+	atmel_spi_cleanup_debugfs(as);
 
-	dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
-			as->buffer_dma);
+	/* Shut down the hardware */
+	spi_writel(as, CR, SPI_BIT(SWRST));
+	spi_readl(as, SR);
 
+	/* Clean up */
+	spi_unregister_master(master);
+	free_irq(platform_get_irq(pdev, 0), as);
+#ifndef CONFIG_SPI_ATMEL_HAVE_PDC
+	dma_async_client_unregister(&as->tx_client);
+	dma_async_client_unregister(&as->rx_client);
+#endif
+	destroy_workqueue(as->workqueue);
+	if (as->always_bounce)
+		iounmap((void __iomem __force *)as->buffer);
+	else
+		dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
+				as->buffer_dma);
+	iounmap(as->regs);
 	clk_disable(as->clk);
 	clk_put(as->clk);
-	free_irq(as->irq, master);
-	iounmap(as->regs);
 
-	spi_unregister_master(master);
+	spi_master_put(master);
 
 	return 0;
 }
@@ -840,7 +1466,9 @@
 	struct spi_master	*master = platform_get_drvdata(pdev);
 	struct atmel_spi	*as = spi_master_get_devdata(master);
 
+	atmel_spi_stop_queue(as);
 	clk_disable(as->clk);
+
 	return 0;
 }
 
@@ -850,6 +1478,9 @@
 	struct atmel_spi	*as = spi_master_get_devdata(master);
 
 	clk_enable(as->clk);
+	as->stopping = false;
+	smp_wmb();
+
 	return 0;
 }
 
@@ -871,7 +1502,12 @@
 
 static int __init atmel_spi_init(void)
 {
-	return platform_driver_probe(&atmel_spi_driver, atmel_spi_probe);
+	int ret;
+
+	ret = platform_driver_probe(&atmel_spi_driver, atmel_spi_probe);
+	if (ret)
+		pr_notice("atmel_spi probe failed: %d\n", ret);
+	return ret;
 }
 module_init(atmel_spi_init);
 
@@ -882,6 +1518,6 @@
 module_exit(atmel_spi_exit);
 
 MODULE_DESCRIPTION("Atmel AT32/AT91 SPI Controller driver");
-MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
-MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Haavard Skinnemoen <haavard.skinnemoen@atmel.com>");
+MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:atmel_spi");
diff -urN linux-2.6.28.2-0rig//drivers/spi/Kconfig linux-2.6.28.2/drivers/spi/Kconfig
--- linux-2.6.28.2-0rig//drivers/spi/Kconfig	2009-01-29 08:39:31.000000000 +0100
+++ linux-2.6.28.2/drivers/spi/Kconfig	2009-01-29 08:52:50.000000000 +0100
@@ -53,9 +53,14 @@
 
 comment "SPI Master Controller Drivers"
 
+config SPI_ATMEL_HAVE_PDC
+	def_bool y
+	depends on (ARCH_AT91 || CPU_AT32AP700X)
+
 config SPI_ATMEL
 	tristate "Atmel SPI Controller"
 	depends on (ARCH_AT91 || AVR32)
+	depends on SPI_ATMEL_HAVE_PDC || DMA_ENGINE
 	help
 	  This selects a driver for the Atmel SPI Controller, present on
 	  many AT32 (AVR32) and AT91 (ARM) chips.
diff -urN linux-2.6.28.2-0rig//drivers/usb/host/ehci-avr32.c linux-2.6.28.2/drivers/usb/host/ehci-avr32.c
--- linux-2.6.28.2-0rig//drivers/usb/host/ehci-avr32.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/drivers/usb/host/ehci-avr32.c	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,213 @@
+/*
+ * AVR32 EHCI bus and power management glue
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+static struct clk	*utmi_clk;
+static struct clk	*hclk;
+
+static void ehci_avr32_start_clocks(struct device *dev)
+{
+	dev_vdbg(dev, "starting clocks...\n");
+
+	clk_enable(utmi_clk);
+	clk_enable(hclk);
+}
+
+static void ehci_avr32_stop_clocks(struct device *dev)
+{
+	dev_vdbg(dev, "stopping clocks...\n");
+
+	clk_disable(hclk);
+	clk_disable(utmi_clk);
+}
+
+static int ehci_avr32_setup(struct usb_hcd *hcd)
+{
+	struct device	*dev = hcd->self.controller;
+	struct ehci_hcd	*ehci = hcd_to_ehci(hcd);
+	int		ret;
+
+	ehci_avr32_start_clocks(dev);
+
+	ehci->caps = hcd->regs;
+	ehci->regs = hcd->regs
+		+ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+	dbg_hcs_params(ehci, "reset");
+	dbg_hcc_params(ehci, "reset");
+
+	/* cache this readonly data; minimize chip reads */
+	ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+
+	ret = ehci_halt(ehci);
+	if (ret)
+		goto err;
+
+	/* data structure init */
+	ret = ehci_init(hcd);
+	if (ret)
+		goto err;
+
+	ehci->sbrn = 0x20;
+	ehci_port_power(ehci, 0);
+
+	return 0;
+
+err:
+	ehci_avr32_stop_clocks(dev);
+	return ret;
+}
+
+static void ehci_avr32_shutdown(struct usb_hcd *hcd)
+{
+	ehci_shutdown(hcd);
+	ehci_avr32_stop_clocks(hcd->self.controller);
+}
+
+static const struct hc_driver ehci_avr32_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "AVR32 USBH (EHCI)",
+	.hcd_priv_size		= sizeof(struct ehci_hcd),
+
+	.irq			= ehci_irq,
+	.flags			= HCD_MEMORY | HCD_USB2,
+
+	.reset			= ehci_avr32_setup,
+	.start			= ehci_run,
+	.stop			= ehci_stop,
+	.shutdown		= ehci_avr32_shutdown,
+
+	.urb_enqueue		= ehci_urb_enqueue,
+	.urb_dequeue		= ehci_urb_dequeue,
+	.endpoint_disable	= ehci_endpoint_disable,
+
+	.get_frame_number	= ehci_get_frame,
+
+	.hub_status_data	= ehci_hub_status_data,
+	.hub_control		= ehci_hub_control,
+	.bus_suspend		= ehci_bus_suspend,
+	.bus_resume		= ehci_bus_resume,
+	.relinquish_port	= ehci_relinquish_port,
+	.port_handed_over	= ehci_port_handed_over,
+};
+
+static int ehci_avr32_probe(struct platform_device *pdev)
+{
+	struct resource		*reg_res;
+	struct usb_hcd		*hcd;
+	struct ehci_hcd		*ehci;
+	int			irq;
+	int			ret;
+
+	reg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!reg_res) {
+		dev_dbg(&pdev->dev, "no MMIO resource\n");
+		return -ENXIO;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_dbg(&pdev->dev, "no IRQ resource\n");
+		return -ENXIO;
+	}
+
+	hclk = clk_get(&pdev->dev, "hclk");
+	if (IS_ERR(hclk)) {
+		dev_dbg(&pdev->dev, "no HSB clock\n");
+		return -ENXIO;
+	}
+	utmi_clk = clk_get(&pdev->dev, "utmi_clk");
+	if (IS_ERR(utmi_clk)) {
+		dev_dbg(&pdev->dev, "no UTMI clock\n");
+		ret = -ENXIO;
+		goto err_utmi_clk;
+	}
+
+	if (!request_mem_region(reg_res->start,
+				reg_res->end - reg_res->start + 1,
+				hcd_name)) {
+		dev_dbg(&pdev->dev, "config regs busy\n");
+		ret = -EBUSY;
+		goto err_request_mmio;
+	}
+
+	ret = -ENOMEM;
+
+	hcd = usb_create_hcd(&ehci_avr32_hc_driver, &pdev->dev, "ehci-avr32");
+	if (!hcd) {
+		dev_dbg(&pdev->dev, "failed to create hcd\n");
+		goto err_create_hcd;
+	}
+
+	hcd->rsrc_start = reg_res->start;
+	hcd->rsrc_len = reg_res->end - reg_res->start + 1;
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		dev_dbg(&pdev->dev, "failed to map registers\n");
+		goto err_ioremap;
+	}
+
+	ehci = hcd_to_ehci(hcd);
+	ehci->big_endian_mmio = 1;
+	ehci->big_endian_desc = 1;
+
+	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+	if (ret)
+		goto err_add_hcd;
+
+	return 0;
+
+err_add_hcd:
+	iounmap(hcd->regs);
+err_ioremap:
+	usb_put_hcd(hcd);
+err_create_hcd:
+	release_mem_region(reg_res->start, reg_res->end - reg_res->start + 1);
+err_request_mmio:
+	clk_put(utmi_clk);
+err_utmi_clk:
+	clk_put(hclk);
+
+	return ret;
+}
+
+static int ehci_avr32_remove(struct platform_device *pdev)
+{
+	struct usb_hcd	*hcd = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	usb_remove_hcd(hcd);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+	clk_put(utmi_clk);
+	clk_put(hclk);
+
+	return 0;
+}
+
+/* FIXME */
+#define ehci_avr32_suspend	NULL
+#define ehci_avr32_resume	NULL
+
+static struct platform_driver ehci_hcd_avr32_driver = {
+	.probe		= ehci_avr32_probe,
+	.remove		= ehci_avr32_remove,
+	.suspend	= ehci_avr32_suspend,
+	.resume		= ehci_avr32_resume,
+	.shutdown	= usb_hcd_platform_shutdown,
+	.driver		= {
+		.name	= "ehci",
+	},
+};
diff -urN linux-2.6.28.2-0rig//drivers/usb/host/ehci-hcd.c linux-2.6.28.2/drivers/usb/host/ehci-hcd.c
--- linux-2.6.28.2-0rig//drivers/usb/host/ehci-hcd.c	2009-01-29 08:39:25.000000000 +0100
+++ linux-2.6.28.2/drivers/usb/host/ehci-hcd.c	2009-01-29 08:52:50.000000000 +0100
@@ -1014,6 +1014,11 @@
 #define	PLATFORM_DRIVER		ehci_hcd_au1xxx_driver
 #endif
 
+#ifdef CONFIG_AVR32
+#include "ehci-avr32.c"
+#define PLATFORM_DRIVER		ehci_hcd_avr32_driver
+#endif
+
 #ifdef CONFIG_PPC_PS3
 #include "ehci-ps3.c"
 #define	PS3_SYSTEM_BUS_DRIVER	ps3_ehci_driver
diff -urN linux-2.6.28.2-0rig//drivers/usb/host/Kconfig linux-2.6.28.2/drivers/usb/host/Kconfig
--- linux-2.6.28.2-0rig//drivers/usb/host/Kconfig	2009-01-29 08:39:25.000000000 +0100
+++ linux-2.6.28.2/drivers/usb/host/Kconfig	2009-01-29 08:52:50.000000000 +0100
@@ -73,12 +73,12 @@
 
 config USB_EHCI_BIG_ENDIAN_MMIO
 	bool
-	depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX)
+	depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || ARCH_IXP4XX || AVR32)
 	default y
 
 config USB_EHCI_BIG_ENDIAN_DESC
 	bool
-	depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX)
+	depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || AVR32)
 	default y
 
 config USB_EHCI_FSL
@@ -196,17 +196,19 @@
 config USB_OHCI_BIG_ENDIAN_DESC
 	bool
 	depends on USB_OHCI_HCD
+	default y if AVR32
 	default n
 
 config USB_OHCI_BIG_ENDIAN_MMIO
 	bool
 	depends on USB_OHCI_HCD
+	default y if AVR32
 	default n
 
 config USB_OHCI_LITTLE_ENDIAN
 	bool
 	depends on USB_OHCI_HCD
-	default n if STB03xxx || PPC_MPC52xx
+	default n if STB03xxx || PPC_MPC52xx || AVR32
 	default y
 
 config USB_UHCI_HCD
diff -urN linux-2.6.28.2-0rig//drivers/usb/host/ohci-avr32.c linux-2.6.28.2/drivers/usb/host/ohci-avr32.c
--- linux-2.6.28.2-0rig//drivers/usb/host/ohci-avr32.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/drivers/usb/host/ohci-avr32.c	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,208 @@
+/*
+ * AVR32 OHCI bus and power management glue
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+
+/* Grr! The core layer doesn't let us keep private data anywhere! */
+static struct clk	*ohci_clk;
+static struct clk	*utmi_clk;
+static struct clk	*hclk;
+
+static void ohci_avr32_start_clocks(struct device *dev)
+{
+	dev_vdbg(dev, "starting clocks...\n");
+
+	clk_enable(ohci_clk);
+	clk_enable(utmi_clk);
+	clk_enable(hclk);
+}
+
+static void ohci_avr32_stop_clocks(struct device *dev)
+{
+	dev_vdbg(dev, "stopping clocks...\n");
+
+	clk_disable(hclk);
+	clk_disable(utmi_clk);
+	clk_disable(ohci_clk);
+}
+
+static int ohci_avr32_start(struct usb_hcd *hcd)
+{
+	struct device	*dev = hcd->self.controller;
+	struct ohci_hcd	*ohci = hcd_to_ohci(hcd);
+	int		ret;
+
+	ohci_avr32_start_clocks(dev);
+
+	ret = ohci_init(ohci);
+	if (ret)
+		goto err_ohci_init;
+
+	ret = ohci_run(ohci);
+	if (likely(!ret))
+		return 0;
+
+	ohci_stop(hcd);
+
+err_ohci_init:
+	ohci_avr32_stop_clocks(dev);
+	return ret;
+}
+
+static void ohci_avr32_stop(struct usb_hcd *hcd)
+{
+	ohci_stop(hcd);
+	ohci_avr32_stop_clocks(hcd->self.controller);
+}
+
+static const struct hc_driver ohci_avr32_hc_driver = {
+	.description		= hcd_name,
+	.product_desc		= "AVR32 USBH (OHCI)",
+	.hcd_priv_size		= sizeof(struct ohci_hcd),
+
+	.irq			= ohci_irq,
+	.flags			= HCD_USB11 | HCD_MEMORY,
+
+	.start			= ohci_avr32_start,
+	.stop			= ohci_avr32_stop,
+	.shutdown		= ohci_shutdown,
+
+	.urb_enqueue		= ohci_urb_enqueue,
+	.urb_dequeue		= ohci_urb_dequeue,
+	.endpoint_disable	= ohci_endpoint_disable,
+	.get_frame_number	= ohci_get_frame,
+	.hub_status_data	= ohci_hub_status_data,
+	.hub_control		= ohci_hub_control,
+#ifdef CONFIG_PM
+	.bus_suspend		= ohci_bus_suspend,
+	.bus_resume		= ohci_bus_resume,
+#endif
+	.start_port_reset	= ohci_start_port_reset,
+};
+
+static int ohci_avr32_probe(struct platform_device *pdev)
+{
+	struct resource		*regs;
+	struct usb_hcd		*hcd;
+	int			irq;
+	int			ret;
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		dev_dbg(&pdev->dev, "no MMIO resource\n");
+		return -ENXIO;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_dbg(&pdev->dev, "no IRQ resource\n");
+		return -ENXIO;
+	}
+
+	hclk = clk_get(&pdev->dev, "hclk");
+	if (IS_ERR(hclk)) {
+		dev_dbg(&pdev->dev, "no HSB clock\n");
+		return -ENXIO;
+	}
+	utmi_clk = clk_get(&pdev->dev, "utmi_clk");
+	if (IS_ERR(utmi_clk)) {
+		dev_dbg(&pdev->dev, "no UTMI clock\n");
+		ret = -ENXIO;
+		goto err_utmi_clk;
+	}
+	ohci_clk = clk_get(&pdev->dev, "ohci_clk");
+	if (IS_ERR(ohci_clk)) {
+		dev_dbg(&pdev->dev, "no OHCI clock\n");
+		ret = -ENXIO;
+		goto err_ohci_clk;
+	}
+
+	if (!request_mem_region(regs->start, regs->end - regs->start + 1,
+				hcd_name)) {
+		dev_dbg(&pdev->dev, "config regs busy\n");
+		ret = -EBUSY;
+		goto err_request_mmio;
+	}
+
+	ret = -ENOMEM;
+	hcd = usb_create_hcd(&ohci_avr32_hc_driver, &pdev->dev, "ohci-avr32");
+	if (!hcd) {
+		dev_dbg(&pdev->dev, "failed to create hcd\n");
+		goto err_create_hcd;
+	}
+
+	hcd->rsrc_start = regs->start;
+	hcd->rsrc_len = regs->end - regs->start + 1;
+	hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+	if (!hcd->regs) {
+		dev_dbg(&pdev->dev, "failed to map registers\n");
+		goto err_ioremap;
+	}
+
+	ohci_hcd_init(hcd_to_ohci(hcd));
+
+	ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+	if (ret)
+		goto err_add_hcd;
+
+	return 0;
+
+err_add_hcd:
+	iounmap(hcd->regs);
+err_ioremap:
+	usb_put_hcd(hcd);
+err_create_hcd:
+	release_mem_region(regs->start, regs->end - regs->start + 1);
+err_request_mmio:
+	clk_put(ohci_clk);
+err_ohci_clk:
+	clk_put(utmi_clk);
+err_utmi_clk:
+	clk_put(hclk);
+
+	return ret;
+}
+
+static int ohci_avr32_remove(struct platform_device *pdev)
+{
+	struct usb_hcd	*hcd = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+	usb_remove_hcd(hcd);
+	iounmap(hcd->regs);
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+	clk_put(utmi_clk);
+	clk_put(ohci_clk);
+	clk_put(hclk);
+
+	return 0;
+}
+
+/* FIXME */
+#define ohci_avr32_suspend	NULL
+#define ohci_avr32_resume	NULL
+
+static struct platform_driver ohci_hcd_avr32_driver = {
+	.probe		= ohci_avr32_probe,
+	.remove		= ohci_avr32_remove,
+	.shutdown	= usb_hcd_platform_shutdown,
+	.suspend	= ohci_avr32_suspend,
+	.resume		= ohci_avr32_resume,
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "ohci",
+	},
+};
+MODULE_ALIAS("platform:ohci");
diff -urN linux-2.6.28.2-0rig//drivers/usb/host/ohci.h linux-2.6.28.2/drivers/usb/host/ohci.h
--- linux-2.6.28.2-0rig//drivers/usb/host/ohci.h	2009-01-29 08:39:25.000000000 +0100
+++ linux-2.6.28.2/drivers/usb/host/ohci.h	2009-01-29 08:52:50.000000000 +0100
@@ -646,8 +646,10 @@
  * some big-endian SOC implementations.  Same thing happens with PSW access.
  */
 
-#ifdef CONFIG_PPC_MPC52xx
+#if defined(CONFIG_PPC_MPC52xx)
 #define big_endian_frame_no_quirk(ohci)	(ohci->flags & OHCI_QUIRK_FRAME_NO)
+#elif defined(CONFIG_AVR32)
+#define big_endian_frame_no_quirk(ohci)	1
 #else
 #define big_endian_frame_no_quirk(ohci)	0
 #endif
diff -urN linux-2.6.28.2-0rig//drivers/usb/host/ohci-hcd.c linux-2.6.28.2/drivers/usb/host/ohci-hcd.c
--- linux-2.6.28.2-0rig//drivers/usb/host/ohci-hcd.c	2009-01-29 08:39:25.000000000 +0100
+++ linux-2.6.28.2/drivers/usb/host/ohci-hcd.c	2009-01-29 08:52:50.000000000 +0100
@@ -1042,6 +1042,11 @@
 #define PLATFORM_DRIVER		ohci_hcd_at91_driver
 #endif
 
+#ifdef CONFIG_AVR32
+#include "ohci-avr32.c"
+#define PLATFORM_DRIVER		ohci_hcd_avr32_driver
+#endif
+
 #ifdef CONFIG_ARCH_PNX4008
 #include "ohci-pnx4008.c"
 #define PLATFORM_DRIVER		usb_hcd_pnx4008_driver
diff -urN linux-2.6.28.2-0rig//drivers/usb/Kconfig linux-2.6.28.2/drivers/usb/Kconfig
--- linux-2.6.28.2-0rig//drivers/usb/Kconfig	2009-01-29 08:39:25.000000000 +0100
+++ linux-2.6.28.2/drivers/usb/Kconfig	2009-01-29 08:52:50.000000000 +0100
@@ -56,6 +56,7 @@
 	default y if PPC_83xx
 	default y if SOC_AU1200
 	default y if ARCH_IXP4XX
+	default y if AVR32
 	default PCI
 
 # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
diff -urN linux-2.6.28.2-0rig//drivers/watchdog/at32ap700x_wdt.c linux-2.6.28.2/drivers/watchdog/at32ap700x_wdt.c
--- linux-2.6.28.2-0rig//drivers/watchdog/at32ap700x_wdt.c	2009-01-29 08:39:31.000000000 +0100
+++ linux-2.6.28.2/drivers/watchdog/at32ap700x_wdt.c	1970-01-01 01:00:00.000000000 +0100
@@ -1,449 +0,0 @@
-/*
- * Watchdog driver for Atmel AT32AP700X devices
- *
- * 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 version 2 as
- * published by the Free Software Foundation.
- *
- *
- * Errata: WDT Clear is blocked after WDT Reset
- *
- * A watchdog timer event will, after reset, block writes to the WDT_CLEAR
- * register, preventing the program to clear the next Watchdog Timer Reset.
- *
- * If you still want to use the WDT after a WDT reset a small code can be
- * insterted at the startup checking the AVR32_PM.rcause register for WDT reset
- * and use a GPIO pin to reset the system. This method requires that one of the
- * GPIO pins are available and connected externally to the RESET_N pin. After
- * the GPIO pin has pulled down the reset line the GPIO will be reset and leave
- * the pin tristated with pullup.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/platform_device.h>
-#include <linux/watchdog.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
-#include <linux/spinlock.h>
-
-#define TIMEOUT_MIN		1
-#define TIMEOUT_MAX		2
-#define TIMEOUT_DEFAULT		TIMEOUT_MAX
-
-/* module parameters */
-static int timeout =  TIMEOUT_DEFAULT;
-module_param(timeout, int, 0);
-MODULE_PARM_DESC(timeout,
-		"Timeout value. Limited to be 1 or 2 seconds. (default="
-		__MODULE_STRING(TIMEOUT_DEFAULT) ")");
-
-static int nowayout = WATCHDOG_NOWAYOUT;
-module_param(nowayout, int, 0);
-MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
-		__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-
-/* Watchdog registers and write/read macro */
-#define WDT_CTRL		0x00
-#define WDT_CTRL_EN		   0
-#define WDT_CTRL_PSEL		   8
-#define WDT_CTRL_KEY		  24
-
-#define WDT_CLR			0x04
-
-#define WDT_RCAUSE		0x10
-#define WDT_RCAUSE_POR		   0
-#define WDT_RCAUSE_EXT		   2
-#define WDT_RCAUSE_WDT		   3
-#define WDT_RCAUSE_JTAG		   4
-#define WDT_RCAUSE_SERP		   5
-
-#define WDT_BIT(name)		(1 << WDT_##name)
-#define WDT_BF(name, value)	((value) << WDT_##name)
-
-#define wdt_readl(dev, reg)				\
-	__raw_readl((dev)->regs + WDT_##reg)
-#define wdt_writel(dev, reg, value)			\
-	__raw_writel((value), (dev)->regs + WDT_##reg)
-
-struct wdt_at32ap700x {
-	void __iomem		*regs;
-	spinlock_t		io_lock;
-	int			timeout;
-	int			boot_status;
-	unsigned long		users;
-	struct miscdevice	miscdev;
-};
-
-static struct wdt_at32ap700x *wdt;
-static char expect_release;
-
-/*
- * Disable the watchdog.
- */
-static inline void at32_wdt_stop(void)
-{
-	unsigned long psel;
-
-	spin_lock(&wdt->io_lock);
-	psel = wdt_readl(wdt, CTRL) & WDT_BF(CTRL_PSEL, 0x0f);
-	wdt_writel(wdt, CTRL, psel | WDT_BF(CTRL_KEY, 0x55));
-	wdt_writel(wdt, CTRL, psel | WDT_BF(CTRL_KEY, 0xaa));
-	spin_unlock(&wdt->io_lock);
-}
-
-/*
- * Enable and reset the watchdog.
- */
-static inline void at32_wdt_start(void)
-{
-	/* 0xf is 2^16 divider = 2 sec, 0xe is 2^15 divider = 1 sec */
-	unsigned long psel = (wdt->timeout > 1) ? 0xf : 0xe;
-
-	spin_lock(&wdt->io_lock);
-	wdt_writel(wdt, CTRL, WDT_BIT(CTRL_EN)
-			| WDT_BF(CTRL_PSEL, psel)
-			| WDT_BF(CTRL_KEY, 0x55));
-	wdt_writel(wdt, CTRL, WDT_BIT(CTRL_EN)
-			| WDT_BF(CTRL_PSEL, psel)
-			| WDT_BF(CTRL_KEY, 0xaa));
-	spin_unlock(&wdt->io_lock);
-}
-
-/*
- * Pat the watchdog timer.
- */
-static inline void at32_wdt_pat(void)
-{
-	spin_lock(&wdt->io_lock);
-	wdt_writel(wdt, CLR, 0x42);
-	spin_unlock(&wdt->io_lock);
-}
-
-/*
- * Watchdog device is opened, and watchdog starts running.
- */
-static int at32_wdt_open(struct inode *inode, struct file *file)
-{
-	if (test_and_set_bit(1, &wdt->users))
-		return -EBUSY;
-
-	at32_wdt_start();
-	return nonseekable_open(inode, file);
-}
-
-/*
- * Close the watchdog device.
- */
-static int at32_wdt_close(struct inode *inode, struct file *file)
-{
-	if (expect_release == 42) {
-		at32_wdt_stop();
-	} else {
-		dev_dbg(wdt->miscdev.parent,
-			"unexpected close, not stopping watchdog!\n");
-		at32_wdt_pat();
-	}
-	clear_bit(1, &wdt->users);
-	expect_release = 0;
-	return 0;
-}
-
-/*
- * Change the watchdog time interval.
- */
-static int at32_wdt_settimeout(int time)
-{
-	/*
-	 * All counting occurs at 1 / SLOW_CLOCK (32 kHz) and max prescaler is
-	 * 2 ^ 16 allowing up to 2 seconds timeout.
-	 */
-	if ((time < TIMEOUT_MIN) || (time > TIMEOUT_MAX))
-		return -EINVAL;
-
-	/*
-	 * Set new watchdog time. It will be used when at32_wdt_start() is
-	 * called.
-	 */
-	wdt->timeout = time;
-	return 0;
-}
-
-/*
- * Get the watchdog status.
- */
-static int at32_wdt_get_status(void)
-{
-	int rcause;
-	int status = 0;
-
-	rcause = wdt_readl(wdt, RCAUSE);
-
-	switch (rcause) {
-	case WDT_BIT(RCAUSE_EXT):
-		status = WDIOF_EXTERN1;
-		break;
-	case WDT_BIT(RCAUSE_WDT):
-		status = WDIOF_CARDRESET;
-		break;
-	case WDT_BIT(RCAUSE_POR):  /* fall through */
-	case WDT_BIT(RCAUSE_JTAG): /* fall through */
-	case WDT_BIT(RCAUSE_SERP): /* fall through */
-	default:
-		break;
-	}
-
-	return status;
-}
-
-static struct watchdog_info at32_wdt_info = {
-	.identity	= "at32ap700x watchdog",
-	.options	= WDIOF_SETTIMEOUT |
-			  WDIOF_KEEPALIVEPING |
-			  WDIOF_MAGICCLOSE,
-};
-
-/*
- * Handle commands from user-space.
- */
-static long at32_wdt_ioctl(struct file *file,
-				unsigned int cmd, unsigned long arg)
-{
-	int ret = -ENOTTY;
-	int time;
-	void __user *argp = (void __user *)arg;
-	int __user *p = argp;
-
-	switch (cmd) {
-	case WDIOC_GETSUPPORT:
-		ret = copy_to_user(argp, &at32_wdt_info,
-				sizeof(at32_wdt_info)) ? -EFAULT : 0;
-		break;
-	case WDIOC_GETSTATUS:
-		ret = put_user(0, p);
-		break;
-	case WDIOC_GETBOOTSTATUS:
-		ret = put_user(wdt->boot_status, p);
-		break;
-	case WDIOC_SETOPTIONS:
-		ret = get_user(time, p);
-		if (ret)
-			break;
-		if (time & WDIOS_DISABLECARD)
-			at32_wdt_stop();
-		if (time & WDIOS_ENABLECARD)
-			at32_wdt_start();
-		ret = 0;
-		break;
-	case WDIOC_KEEPALIVE:
-		at32_wdt_pat();
-		ret = 0;
-		break;
-	case WDIOC_SETTIMEOUT:
-		ret = get_user(time, p);
-		if (ret)
-			break;
-		ret = at32_wdt_settimeout(time);
-		if (ret)
-			break;
-		/* Enable new time value */
-		at32_wdt_start();
-		/* fall through */
-	case WDIOC_GETTIMEOUT:
-		ret = put_user(wdt->timeout, p);
-		break;
-	}
-
-	return ret;
-}
-
-static ssize_t at32_wdt_write(struct file *file, const char __user *data,
-				size_t len, loff_t *ppos)
-{
-	/* See if we got the magic character 'V' and reload the timer */
-	if (len) {
-		if (!nowayout) {
-			size_t i;
-
-			/*
-			 * note: just in case someone wrote the magic
-			 * character five months ago...
-			 */
-			expect_release = 0;
-
-			/*
-			 * scan to see whether or not we got the magic
-			 * character
-			 */
-			for (i = 0; i != len; i++) {
-				char c;
-				if (get_user(c, data + i))
-					return -EFAULT;
-				if (c == 'V')
-					expect_release = 42;
-			}
-		}
-		/* someone wrote to us, we should pat the watchdog */
-		at32_wdt_pat();
-	}
-	return len;
-}
-
-static const struct file_operations at32_wdt_fops = {
-	.owner		= THIS_MODULE,
-	.llseek		= no_llseek,
-	.unlocked_ioctl	= at32_wdt_ioctl,
-	.open		= at32_wdt_open,
-	.release	= at32_wdt_close,
-	.write		= at32_wdt_write,
-};
-
-static int __init at32_wdt_probe(struct platform_device *pdev)
-{
-	struct resource	*regs;
-	int ret;
-
-	if (wdt) {
-		dev_dbg(&pdev->dev, "only 1 wdt instance supported.\n");
-		return -EBUSY;
-	}
-
-	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!regs) {
-		dev_dbg(&pdev->dev, "missing mmio resource\n");
-		return -ENXIO;
-	}
-
-	wdt = kzalloc(sizeof(struct wdt_at32ap700x), GFP_KERNEL);
-	if (!wdt) {
-		dev_dbg(&pdev->dev, "no memory for wdt structure\n");
-		return -ENOMEM;
-	}
-
-	wdt->regs = ioremap(regs->start, regs->end - regs->start + 1);
-	if (!wdt->regs) {
-		ret = -ENOMEM;
-		dev_dbg(&pdev->dev, "could not map I/O memory\n");
-		goto err_free;
-	}
-
-	spin_lock_init(&wdt->io_lock);
-	wdt->boot_status = at32_wdt_get_status();
-
-	/* Work-around for watchdog silicon errata. */
-	if (wdt->boot_status & WDIOF_CARDRESET) {
-		dev_info(&pdev->dev, "CPU must be reset with external "
-				"reset or POR due to silicon errata.\n");
-		ret = -EIO;
-		goto err_iounmap;
-	} else {
-		wdt->users = 0;
-	}
-	wdt->miscdev.minor = WATCHDOG_MINOR;
-	wdt->miscdev.name = "watchdog";
-	wdt->miscdev.fops = &at32_wdt_fops;
-
-	if (at32_wdt_settimeout(timeout)) {
-		at32_wdt_settimeout(TIMEOUT_DEFAULT);
-		dev_dbg(&pdev->dev,
-			"default timeout invalid, set to %d sec.\n",
-			TIMEOUT_DEFAULT);
-	}
-
-	ret = misc_register(&wdt->miscdev);
-	if (ret) {
-		dev_dbg(&pdev->dev, "failed to register wdt miscdev\n");
-		goto err_iounmap;
-	}
-
-	platform_set_drvdata(pdev, wdt);
-	wdt->miscdev.parent = &pdev->dev;
-	dev_info(&pdev->dev,
-		"AT32AP700X WDT at 0x%p, timeout %d sec (nowayout=%d)\n",
-		wdt->regs, wdt->timeout, nowayout);
-
-	return 0;
-
-err_iounmap:
-	iounmap(wdt->regs);
-err_free:
-	kfree(wdt);
-	wdt = NULL;
-	return ret;
-}
-
-static int __exit at32_wdt_remove(struct platform_device *pdev)
-{
-	if (wdt && platform_get_drvdata(pdev) == wdt) {
-		/* Stop the timer before we leave */
-		if (!nowayout)
-			at32_wdt_stop();
-
-		misc_deregister(&wdt->miscdev);
-		iounmap(wdt->regs);
-		kfree(wdt);
-		wdt = NULL;
-		platform_set_drvdata(pdev, NULL);
-	}
-	return 0;
-}
-
-static void at32_wdt_shutdown(struct platform_device *pdev)
-{
-	at32_wdt_stop();
-}
-
-#ifdef CONFIG_PM
-static int at32_wdt_suspend(struct platform_device *pdev, pm_message_t message)
-{
-	at32_wdt_stop();
-	return 0;
-}
-
-static int at32_wdt_resume(struct platform_device *pdev)
-{
-	if (wdt->users)
-		at32_wdt_start();
-	return 0;
-}
-#else
-#define at32_wdt_suspend NULL
-#define at32_wdt_resume NULL
-#endif
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:at32_wdt");
-
-static struct platform_driver at32_wdt_driver = {
-	.remove		= __exit_p(at32_wdt_remove),
-	.suspend	= at32_wdt_suspend,
-	.resume		= at32_wdt_resume,
-	.driver		= {
-		.name	= "at32_wdt",
-		.owner	= THIS_MODULE,
-	},
-	.shutdown	= at32_wdt_shutdown,
-};
-
-static int __init at32_wdt_init(void)
-{
-	return platform_driver_probe(&at32_wdt_driver, at32_wdt_probe);
-}
-module_init(at32_wdt_init);
-
-static void __exit at32_wdt_exit(void)
-{
-	platform_driver_unregister(&at32_wdt_driver);
-}
-module_exit(at32_wdt_exit);
-
-MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
-MODULE_DESCRIPTION("Watchdog driver for Atmel AT32AP700X");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff -urN linux-2.6.28.2-0rig//drivers/watchdog/at32_wdt.c linux-2.6.28.2/drivers/watchdog/at32_wdt.c
--- linux-2.6.28.2-0rig//drivers/watchdog/at32_wdt.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/drivers/watchdog/at32_wdt.c	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,620 @@
+/*
+ * Watchdog driver for Atmel AVR32 devices
+ *
+ * Copyright (C) 2005-2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ * AT32AP700x Errata: WDT Clear is blocked after WDT Reset
+ *
+ * A watchdog timer event will, after reset, block writes to the WDT_CLEAR
+ * register, preventing the program to clear the next Watchdog Timer Reset.
+ *
+ * If you still want to use the WDT after a WDT reset a small code can be
+ * insterted at the startup checking the AVR32_PM.rcause register for WDT reset
+ * and use a GPIO pin to reset the system. This method requires that one of the
+ * GPIO pins are available and connected externally to the RESET_N pin. After
+ * the GPIO pin has pulled down the reset line the GPIO will be reset and leave
+ * the pin tristated with pullup.
+ */
+
+#include <linux/clk.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+#include <linux/watchdog.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/log2.h>
+#include <linux/spinlock.h>
+
+#include <mach/cpu.h>
+#include <mach/pm.h>
+
+/*
+ * AT32AP700x uses a 16-bit prescaler. This limits the timeout range
+ * somewhat. Later chips use a 32-bit prescaler.
+ */
+#define TIMEOUT_MIN		1
+#ifdef CONFIG_CPU_AT32AP700X
+# define TIMEOUT_MAX		2
+# define TIMEOUT_DEFAULT	TIMEOUT_MAX
+#else
+# define TIMEOUT_MAX		131072
+# define TIMEOUT_DEFAULT	64
+#endif
+
+/* module parameters */
+static int timeout =  TIMEOUT_DEFAULT;
+module_param(timeout, int, 0);
+MODULE_PARM_DESC(timeout,
+		"Timeout value. Any power of two between 1 and "
+		__MODULE_STRING(TIMEOUT_MAX) " seconds. (default="
+		__MODULE_STRING(TIMEOUT_DEFAULT) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+		__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+/* Watchdog registers and write/read macro */
+#define WDT_CTRL		0x00
+#define WDT_CTRL_EN		   0
+#define WDT_CTRL_PSEL		   8
+#define WDT_CTRL_CEN		  16
+#define WDT_CTRL_CSEL		  17
+#define WDT_CTRL_KEY		  24
+
+#define WDT_CLR			0x04
+
+#define WDT_BIT(name)		(1 << WDT_##name)
+#define WDT_BF(name, value)	((value) << WDT_##name)
+
+#define wdt_readl(dev, reg)				\
+	__raw_readl((dev)->regs + WDT_##reg)
+#define wdt_writel(dev, reg, value)			\
+	__raw_writel((value), (dev)->regs + WDT_##reg)
+
+struct wdt_at32 {
+	void __iomem		*regs;
+	struct clk		*pclk;
+	struct clk		*src_clk;
+	spinlock_t		io_lock;
+	int			timeout;
+	int			boot_status;
+	unsigned long		users;
+	struct miscdevice	miscdev;
+};
+
+static struct wdt_at32 *wdt;
+static char expect_release;
+
+static inline void wdt_clk_enable(struct wdt_at32 *w)
+{
+	if (!cpu_is_at32ap7000())
+		clk_enable(w->pclk);
+}
+
+static inline void wdt_clk_disable(struct wdt_at32 *w)
+{
+	if (!cpu_is_at32ap7000())
+		clk_disable(w->pclk);
+}
+
+static inline int at32_wdt_version(void)
+{
+	if (cpu_is_at32ap7000())
+		return 1;
+	if (cpu_is_at32ap7200())
+		return 3;
+
+	BUG();
+}
+
+static unsigned long at32_wdt_calc_psel(int timeout)
+{
+	if (at32_wdt_version() == 1)
+		/* 0xf is 2^16 divider = 2 sec, 0xe is 2^15 divider = 1 sec */
+		return (timeout > 1) ? 0xf : 0xe;
+
+	return order_base_2(timeout) + 14;
+}
+
+/*
+ * Disable the watchdog.
+ */
+static inline void at32_wdt_stop(void)
+{
+	unsigned long ctrl;
+	unsigned long ctrl_mask = 0;
+
+	switch (at32_wdt_version()) {
+	case 3:
+		ctrl_mask |= (1 << WDT_CTRL_CEN) | (1 << WDT_CTRL_CSEL);
+		/* fall through */
+	case 2:
+		ctrl_mask |= 0x1f << WDT_CTRL_PSEL;
+		break;
+	case 1:
+		ctrl_mask |= 0x0f << WDT_CTRL_PSEL;
+		break;
+	}
+
+	wdt_clk_enable(wdt);
+	spin_lock(&wdt->io_lock);
+	ctrl = wdt_readl(wdt, CTRL);
+	ctrl &= ctrl_mask;
+	wdt_writel(wdt, CTRL, ctrl | WDT_BF(CTRL_KEY, 0x55));
+	wdt_writel(wdt, CTRL, ctrl | WDT_BF(CTRL_KEY, 0xaa));
+	spin_unlock(&wdt->io_lock);
+	wdt_clk_disable(wdt);
+}
+
+/*
+ * Enable and reset the watchdog.
+ */
+static inline void at32_wdt_start(void)
+{
+	unsigned long psel;
+	unsigned long ctrl;
+
+	psel = at32_wdt_calc_psel(wdt->timeout);
+	ctrl = WDT_BIT(CTRL_EN) | WDT_BF(CTRL_PSEL, psel);
+
+	if (at32_wdt_version() >= 3)
+		ctrl |= wdt_readl(wdt, CTRL)
+			& (WDT_BIT(CTRL_CSEL) | WDT_BIT(CTRL_CEN));
+
+	wdt_clk_enable(wdt);
+	spin_lock(&wdt->io_lock);
+	wdt_writel(wdt, CTRL, ctrl | WDT_BF(CTRL_KEY, 0x55));
+	wdt_writel(wdt, CTRL, ctrl | WDT_BF(CTRL_KEY, 0xaa));
+	spin_unlock(&wdt->io_lock);
+	wdt_clk_disable(wdt);
+}
+
+/*
+ * Pat the watchdog timer.
+ */
+static inline void at32_wdt_pat(void)
+{
+	wdt_clk_enable(wdt);
+	spin_lock(&wdt->io_lock);
+	wdt_writel(wdt, CLR, 0x42);
+	spin_unlock(&wdt->io_lock);
+	wdt_clk_disable(wdt);
+}
+
+/*
+ * Watchdog device is opened, and watchdog starts running.
+ */
+static int at32_wdt_open(struct inode *inode, struct file *file)
+{
+	if (test_and_set_bit(1, &wdt->users))
+		return -EBUSY;
+
+	at32_wdt_start();
+	return nonseekable_open(inode, file);
+}
+
+/*
+ * Close the watchdog device.
+ */
+static int at32_wdt_close(struct inode *inode, struct file *file)
+{
+	if (expect_release == 42) {
+		at32_wdt_stop();
+	} else {
+		dev_dbg(wdt->miscdev.parent,
+			"unexpected close, not stopping watchdog!\n");
+		at32_wdt_pat();
+	}
+	clear_bit(1, &wdt->users);
+	expect_release = 0;
+	return 0;
+}
+
+/*
+ * Change the watchdog time interval.
+ */
+static int at32_wdt_settimeout(int time)
+{
+	/*
+	 * All counting occurs at 1 / SLOW_CLOCK (32 kHz) and max
+	 * prescaler is 2 ^ 16 (or 2 ^ 32) allowing up to TIMEOUT_MAX
+	 * seconds timeout.
+	 */
+	if ((time < TIMEOUT_MIN) || (time > TIMEOUT_MAX)
+			|| !is_power_of_2(time))
+		return -EINVAL;
+
+	/*
+	 * Set new watchdog time. It will be used when at32_wdt_start() is
+	 * called.
+	 */
+	wdt->timeout = time;
+	return 0;
+}
+
+/*
+ * Get the watchdog status.
+ */
+static int at32_wdt_get_status(void)
+{
+	int rcause;
+	int status = 0;
+
+	rcause = at32_get_reset_cause();
+
+	switch (rcause) {
+	case AT32_RCAUSE_BOD:
+		status = WDIOF_POWERUNDER;
+		break;
+	case AT32_RCAUSE_EXT:
+		status = WDIOF_EXTERN1;
+		break;
+	case AT32_RCAUSE_JTAG:
+	case AT32_RCAUSE_JTAGHARD:
+	case AT32_RCAUSE_OCDRST:
+		status = WDIOF_EXTERN2;
+		break;
+	case AT32_RCAUSE_WDT:
+		status = WDIOF_CARDRESET;
+		break;
+	case AT32_RCAUSE_POR:
+	case AT32_RCAUSE_NTAE:
+	case AT32_RCAUSE_SLEEP:
+	case AT32_RCAUSE_CPUERR:
+	default:
+		break;
+	}
+
+	return status;
+}
+
+static struct watchdog_info at32_wdt_info = {
+	.identity	= "at32 watchdog",
+	.options	= WDIOF_SETTIMEOUT |
+			  WDIOF_KEEPALIVEPING |
+			  WDIOF_MAGICCLOSE,
+};
+
+/*
+ * Handle commands from user-space.
+ */
+static long at32_wdt_ioctl(struct file *file,
+				unsigned int cmd, unsigned long arg)
+{
+	int ret = -ENOTTY;
+	int time;
+	void __user *argp = (void __user *)arg;
+	int __user *p = argp;
+
+	switch (cmd) {
+	case WDIOC_GETSUPPORT:
+		ret = copy_to_user(argp, &at32_wdt_info,
+				sizeof(at32_wdt_info)) ? -EFAULT : 0;
+		break;
+	case WDIOC_GETSTATUS:
+		ret = put_user(0, p);
+		break;
+	case WDIOC_GETBOOTSTATUS:
+		ret = put_user(wdt->boot_status, p);
+		break;
+	case WDIOC_SETOPTIONS:
+		ret = get_user(time, p);
+		if (ret)
+			break;
+		if (time & WDIOS_DISABLECARD)
+			at32_wdt_stop();
+		if (time & WDIOS_ENABLECARD)
+			at32_wdt_start();
+		ret = 0;
+		break;
+	case WDIOC_KEEPALIVE:
+		at32_wdt_pat();
+		ret = 0;
+		break;
+	case WDIOC_SETTIMEOUT:
+		ret = get_user(time, p);
+		if (ret)
+			break;
+		ret = at32_wdt_settimeout(time);
+		if (ret)
+			break;
+		/* Enable new time value */
+		at32_wdt_start();
+		/* fall through */
+	case WDIOC_GETTIMEOUT:
+		ret = put_user(wdt->timeout, p);
+		break;
+	}
+
+	return ret;
+}
+
+static ssize_t at32_wdt_write(struct file *file, const char __user *data,
+				size_t len, loff_t *ppos)
+{
+	/* See if we got the magic character 'V' and reload the timer */
+	if (len) {
+		if (!nowayout) {
+			size_t i;
+
+			/*
+			 * note: just in case someone wrote the magic
+			 * character five months ago...
+			 */
+			expect_release = 0;
+
+			/*
+			 * scan to see whether or not we got the magic
+			 * character
+			 */
+			for (i = 0; i != len; i++) {
+				char c;
+				if (get_user(c, data + i))
+					return -EFAULT;
+				if (c == 'V')
+					expect_release = 42;
+			}
+		}
+		/* someone wrote to us, we should pat the watchdog */
+		at32_wdt_pat();
+	}
+	return len;
+}
+
+static const struct file_operations at32_wdt_fops = {
+	.owner		= THIS_MODULE,
+	.llseek		= no_llseek,
+	.unlocked_ioctl	= at32_wdt_ioctl,
+	.open		= at32_wdt_open,
+	.release	= at32_wdt_close,
+	.write		= at32_wdt_write,
+};
+
+static int __init at32_wdt_enable_source_clock(struct platform_device *pdev)
+{
+	struct clk	*clk;
+	unsigned int	csel;
+	u32		ctrl;
+
+	/* Only v3+ have selectable source clock */
+	if (at32_wdt_version() < 3)
+		return 0;
+
+	csel = 1;
+
+	/*
+	 * Prefer the much more accurate crystal oscillator in favor
+	 * of the RC oscillator.
+	 */
+	clk = clk_get(NULL, "osc32");
+	if (IS_ERR(clk)) {
+		csel = 0;
+		clk = clk_get(NULL, "rcosc");
+	}
+	if (IS_ERR(clk)) {
+		dev_dbg(&pdev->dev, "No source clock\n");
+		return -ENXIO;
+	}
+
+	clk_enable(clk);
+
+	dev_info(&pdev->dev, "Using 32 kHz %s oscillator\n",
+			csel ? "crystal" : "RC");
+
+	wdt_clk_enable(wdt);
+	ctrl = (csel << WDT_CTRL_CSEL) | (1 << WDT_CTRL_CEN);
+
+	/*
+	 * Make sure the WDT is disabled, and disable any clocks that
+	 * may have been selected earlier.
+	 */
+	wdt_writel(wdt, CTRL, 0x55 << WDT_CTRL_KEY);
+	wdt_writel(wdt, CTRL, 0xaa << WDT_CTRL_KEY);
+
+	/* Wait for the clock to become properly deselected */
+	while (wdt_readl(wdt, CTRL) & (1 << WDT_CTRL_CEN))
+		cpu_relax();
+
+	/* Select the new clock */
+	wdt_writel(wdt, CTRL, ctrl | (0x55 << WDT_CTRL_KEY));
+	wdt_writel(wdt, CTRL, ctrl | (0xaa << WDT_CTRL_KEY));
+
+	/* Wait for the new clock to become usable */
+	while (!(wdt_readl(wdt, CTRL) & (1 << WDT_CTRL_CEN)))
+		cpu_relax();
+
+	wdt_clk_disable(wdt);
+	return 0;
+}
+
+static void at32_wdt_disable_source_clock(void)
+{
+	wdt_clk_enable(wdt);
+
+	wdt_writel(wdt, CTRL, 0x55 << WDT_CTRL_KEY);
+	wdt_writel(wdt, CTRL, 0xaa << WDT_CTRL_KEY);
+
+	/* Wait for the clock to become properly deselected */
+	while (wdt_readl(wdt, CTRL) & (1 << WDT_CTRL_CEN))
+		cpu_relax();
+
+	wdt_clk_disable(wdt);
+}
+
+static int __init at32_wdt_probe(struct platform_device *pdev)
+{
+	struct resource	*regs;
+	int ret;
+
+	if (wdt) {
+		dev_dbg(&pdev->dev, "only 1 wdt instance supported.\n");
+		return -EBUSY;
+	}
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		dev_dbg(&pdev->dev, "missing mmio resource\n");
+		return -ENXIO;
+	}
+
+	wdt = kzalloc(sizeof(struct wdt_at32), GFP_KERNEL);
+	if (!wdt) {
+		dev_dbg(&pdev->dev, "no memory for wdt structure\n");
+		return -ENOMEM;
+	}
+
+	wdt->regs = ioremap(regs->start, regs->end - regs->start + 1);
+	if (!wdt->regs) {
+		ret = -ENOMEM;
+		dev_dbg(&pdev->dev, "could not map I/O memory\n");
+		goto err_free;
+	}
+
+	if (!cpu_is_at32ap7000()) {
+		wdt->pclk = clk_get(&pdev->dev, "pclk");
+		if (IS_ERR(wdt->pclk)) {
+			dev_dbg(&pdev->dev, "no peripheral clock\n");
+			ret = -ENXIO;
+			goto err_iounmap;
+		}
+	}
+
+	ret = at32_wdt_enable_source_clock(pdev);
+	if (ret)
+		goto err_put_clk;
+
+	spin_lock_init(&wdt->io_lock);
+	wdt->boot_status = at32_wdt_get_status();
+
+	/* Work-around for watchdog silicon errata. */
+	if (cpu_is_at32ap7000()
+			&& (wdt->boot_status & WDIOF_CARDRESET)) {
+		dev_info(&pdev->dev, "CPU must be reset with external "
+				"reset or POR due to silicon errata.\n");
+		ret = -EIO;
+		goto err_disable_source_clock;
+	} else {
+		wdt->users = 0;
+	}
+	wdt->miscdev.minor = WATCHDOG_MINOR;
+	wdt->miscdev.name = "watchdog";
+	wdt->miscdev.fops = &at32_wdt_fops;
+
+	if (at32_wdt_settimeout(timeout)) {
+		at32_wdt_settimeout(TIMEOUT_DEFAULT);
+		dev_dbg(&pdev->dev,
+			"default timeout invalid, set to %d sec.\n",
+			TIMEOUT_DEFAULT);
+	}
+
+	ret = misc_register(&wdt->miscdev);
+	if (ret) {
+		dev_dbg(&pdev->dev, "failed to register wdt miscdev\n");
+		goto err_iounmap;
+	}
+
+	platform_set_drvdata(pdev, wdt);
+	wdt->miscdev.parent = &pdev->dev;
+	dev_info(&pdev->dev,
+		"AT32 WDT at 0x%p, timeout %d sec (nowayout=%d)\n",
+		wdt->regs, wdt->timeout, nowayout);
+
+	return 0;
+
+err_disable_source_clock:
+	at32_wdt_disable_source_clock();
+err_put_clk:
+	if (!cpu_is_at32ap7000())
+		clk_put(wdt->pclk);
+err_iounmap:
+	iounmap(wdt->regs);
+err_free:
+	kfree(wdt);
+	wdt = NULL;
+	return ret;
+}
+
+static int __exit at32_wdt_remove(struct platform_device *pdev)
+{
+	if (wdt && platform_get_drvdata(pdev) == wdt) {
+		/* Stop the timer before we leave */
+		if (!nowayout) {
+			at32_wdt_stop();
+			at32_wdt_disable_source_clock();
+		}
+
+		misc_deregister(&wdt->miscdev);
+		if (!cpu_is_at32ap7000())
+			clk_put(wdt->pclk);
+		iounmap(wdt->regs);
+		kfree(wdt);
+		wdt = NULL;
+		platform_set_drvdata(pdev, NULL);
+	}
+	return 0;
+}
+
+static void at32_wdt_shutdown(struct platform_device *pdev)
+{
+	at32_wdt_stop();
+}
+
+#ifdef CONFIG_PM
+static int at32_wdt_suspend(struct platform_device *pdev, pm_message_t message)
+{
+	at32_wdt_stop();
+	return 0;
+}
+
+static int at32_wdt_resume(struct platform_device *pdev)
+{
+	if (wdt->users)
+		at32_wdt_start();
+	return 0;
+}
+#else
+#define at32_wdt_suspend NULL
+#define at32_wdt_resume NULL
+#endif
+
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:at32_wdt");
+
+static struct platform_driver at32_wdt_driver = {
+	.remove		= __exit_p(at32_wdt_remove),
+	.suspend	= at32_wdt_suspend,
+	.resume		= at32_wdt_resume,
+	.driver		= {
+		.name	= "at32_wdt",
+		.owner	= THIS_MODULE,
+	},
+	.shutdown	= at32_wdt_shutdown,
+};
+
+static int __init at32_wdt_init(void)
+{
+	return platform_driver_probe(&at32_wdt_driver, at32_wdt_probe);
+}
+module_init(at32_wdt_init);
+
+static void __exit at32_wdt_exit(void)
+{
+	platform_driver_unregister(&at32_wdt_driver);
+}
+module_exit(at32_wdt_exit);
+
+MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
+MODULE_DESCRIPTION("Watchdog driver for Atmel AVR32 devices");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
diff -urN linux-2.6.28.2-0rig//drivers/watchdog/Kconfig linux-2.6.28.2/drivers/watchdog/Kconfig
--- linux-2.6.28.2-0rig//drivers/watchdog/Kconfig	2009-01-29 08:39:31.000000000 +0100
+++ linux-2.6.28.2/drivers/watchdog/Kconfig	2009-01-29 08:52:50.000000000 +0100
@@ -237,12 +237,12 @@
 
 # AVR32 Architecture
 
-config AT32AP700X_WDT
-	tristate "AT32AP700x watchdog"
-	depends on CPU_AT32AP700X
+config AT32_WDT
+	tristate "AVR32 On-Chip Watchdog Timer"
+	depends on AVR32
 	help
-	  Watchdog timer embedded into AT32AP700x devices. This will reboot
-	  your system when the timeout is reached.
+	  Watchdog timer embedded into AT32AP700x and similar devices.
+	  This will reboot your system when the timeout is reached.
 
 # BLACKFIN Architecture
 
diff -urN linux-2.6.28.2-0rig//drivers/watchdog/Makefile linux-2.6.28.2/drivers/watchdog/Makefile
--- linux-2.6.28.2-0rig//drivers/watchdog/Makefile	2009-01-29 08:39:31.000000000 +0100
+++ linux-2.6.28.2/drivers/watchdog/Makefile	2009-01-29 08:52:50.000000000 +0100
@@ -45,7 +45,7 @@
 # ARM26 Architecture
 
 # AVR32 Architecture
-obj-$(CONFIG_AT32AP700X_WDT) += at32ap700x_wdt.o
+obj-$(CONFIG_AT32_WDT) += at32_wdt.o
 
 # BLACKFIN Architecture
 obj-$(CONFIG_BFIN_WDT) += bfin_wdt.o
diff -urN linux-2.6.28.2-0rig//drivers/video/atmel_lcdfb.c linux-2.6.28.2/drivers/video/atmel_lcdfb.c
--- linux-2.6.28.2-0rig//drivers/video/atmel_lcdfb.c	2009-01-29 08:39:31.000000000 +0100
+++ linux-2.6.28.2/drivers/video/atmel_lcdfb.c	2009-01-29 08:52:50.000000000 +0100
@@ -178,7 +178,7 @@
 static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = {
 	.type		= FB_TYPE_PACKED_PIXELS,
 	.visual		= FB_VISUAL_TRUECOLOR,
-	.xpanstep	= 0,
+	.xpanstep	= 1,
 	.ypanstep	= 1,
 	.ywrapstep	= 0,
 	.accel		= FB_ACCEL_NONE,
@@ -239,7 +239,7 @@
 }
 
 static void atmel_lcdfb_update_dma(struct fb_info *info,
-			       struct fb_var_screeninfo *var)
+                                   struct fb_var_screeninfo *var)
 {
 	struct atmel_lcdfb_info *sinfo = info->par;
 	struct fb_fix_screeninfo *fix = &info->fix;
@@ -251,6 +251,8 @@
 	dma_addr &= ~3UL;
 
 	/* Set framebuffer DMA base address and pixel offset */
+	dev_dbg(info->device, "%s:\n", __func__);
+        dev_dbg(info->device, "  *setting dma addr: 0x%lx \n", dma_addr); 
 	lcdc_writel(sinfo, ATMEL_LCDC_DMABADDR1, dma_addr);
 
 	atmel_lcdfb_update_dma2d(sinfo, var);
@@ -493,6 +495,7 @@
 	dev_dbg(info->device, "  * resolution: %ux%u (%ux%u virtual)\n",
 		 info->var.xres, info->var.yres,
 		 info->var.xres_virtual, info->var.yres_virtual);
+	dev_dbg(info->device, "  * bpp:        %u\n", info->var.bits_per_pixel);
 
 	atmel_lcdfb_stop_nowait(sinfo);
 
@@ -594,7 +597,12 @@
 	lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);
 	/* Enable FIFO & DMA errors */
 	lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI);
-
+        
+        /* !!!HACK for logging end of frame and underruns 
+           when connected to MPOP. */
+        if( info->var.bits_per_pixel == 32 )
+          lcdc_writel(sinfo, ATMEL_LCDC_IER, 0x70);
+        
 	/* ...wait for DMA engine to become idle... */
 	while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
 		msleep(10);
@@ -695,7 +703,7 @@
 }
 
 static int atmel_lcdfb_pan_display(struct fb_var_screeninfo *var,
-			       struct fb_info *info)
+                                   struct fb_info *info)
 {
 	dev_dbg(info->device, "%s\n", __func__);
 
@@ -827,7 +835,8 @@
 	info->fix = atmel_lcdfb_fix;
 
 	/* Enable LCDC Clocks */
-	if (cpu_is_at91sam9261() || cpu_is_at32ap7000()) {
+	if (cpu_is_at91sam9261() || cpu_is_at32ap7000()
+			|| cpu_is_at32ap7200()) {
 		sinfo->bus_clk = clk_get(dev, "hck1");
 		if (IS_ERR(sinfo->bus_clk)) {
 			ret = PTR_ERR(sinfo->bus_clk);
diff -urN linux-2.6.28.2-0rig//drivers/video/atmel_mpopfb.c linux-2.6.28.2/drivers/video/atmel_mpopfb.c
--- linux-2.6.28.2-0rig//drivers/video/atmel_mpopfb.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/drivers/video/atmel_mpopfb.c	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,1127 @@
+/*
+ *  Driver for AT91/AT32 LCD Controller
+ *
+ *  Copyright (C) 2007 Atmel Corporation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#define DEBUG
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+
+#include <mach/board.h>
+#include <mach/cpu.h>
+
+#include <video/atmel_lcdc.h>
+#include <video/atmel_mpop.h>
+
+#define mpop_readl(sinfo, reg)		__raw_readl((sinfo)->mmio+(reg))
+#define mpop_writel(sinfo, reg, val)	__raw_writel((val), (sinfo)->mmio+(reg))
+
+#define	ATMEL_MPOPFB_FBINFO_DEFAULT	(FBINFO_DEFAULT \
+                                         | FBINFO_PARTIAL_PAN_OK        \
+                                         | FBINFO_HWACCEL_XPAN          \
+                                         | FBINFO_HWACCEL_YPAN)
+
+static struct atmel_mpopfb_rgbconv_coeffs atmel_mpop_ycrcb2rgb_coeffs = {
+	.r1 = 298,
+	.r2 = 0,
+	.r3 = 409,
+	.r4 = -56992,
+	.g1 = 298,
+	.g2 = -100,
+	.g3 = -208,
+	.g4 = 34784,
+	.b1 = 298,
+	.b2 = 516,
+	.b3 = 0,
+	.b4 = -70688,
+};
+
+static struct fb_fix_screeninfo atmel_mpopfb_fix __initdata = {
+	.type		= FB_TYPE_PLANES,
+	.visual		= FB_VISUAL_TRUECOLOR,
+	.xpanstep	= 16,
+	.ypanstep	= 1,
+	.ywrapstep	= 1,
+	.accel		= FB_ACCEL_NONE,
+};
+
+static void atmel_mpopfb_update_sar(struct fb_info *info,
+		struct fb_var_screeninfo *var)
+{
+	struct atmel_mpopfb_info *sinfo = info->par;
+	struct fb_fix_screeninfo *fix = &info->fix;
+	u32 y_sar, u_sar, v_sar, o1_sar, o2_sar, cursor_sar, next_sar;
+
+	u32 chroma_xres_virtual;
+	u32 chroma_yres_virtual;
+	u32 chroma_xres;
+	u32 chroma_yres;
+	u32 chroma_xoffset;
+	u32 chroma_yoffset;
+
+	switch (var->bits_per_pixel) {
+	default:
+	case 12:
+		chroma_xres_virtual = var->xres_virtual / 2;
+		chroma_yres_virtual = var->yres_virtual / 2;
+		chroma_xres = var->xres / 2;
+		chroma_yres = var->yres / 2;
+		chroma_xoffset = var->xoffset / 2;
+		chroma_yoffset = var->yoffset / 2;
+		break;
+	case 16:
+		chroma_xres_virtual = var->xres_virtual / 2;
+		chroma_yres_virtual = var->yres_virtual;
+		chroma_xres = var->xres / 2;
+		chroma_yres = var->yres;
+		chroma_xoffset = var->xoffset / 2;
+		chroma_yoffset = var->yoffset;
+		break;
+	case 24:
+		chroma_xres_virtual = var->xres_virtual;
+		chroma_yres_virtual = var->yres_virtual;
+		chroma_xres = var->xres;
+		chroma_yres = var->yres;
+		chroma_xoffset = var->xoffset;
+		chroma_yoffset = var->yoffset;
+		break;
+	}
+
+	/* Setup pointer to YUV planes in YUV framebuffer. */
+	y_sar = fix->smem_start + var->xoffset
+		+ var->yoffset * var->xres_virtual;
+	u_sar = fix->smem_start + var->xres_virtual * var->yres_virtual
+		+ chroma_xoffset + chroma_yoffset * chroma_xres_virtual;
+	v_sar = u_sar + chroma_xres_virtual * chroma_yres_virtual;
+	next_sar = fix->smem_start + var->xres_virtual * var->yres_virtual
+		+ 2 * chroma_xres_virtual * chroma_yres_virtual;
+	o1_sar = next_sar;
+	if (sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY1].enabled)
+		next_sar += sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY1].xsize
+			* sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY1].ysize;
+	o2_sar = next_sar;
+	if (sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY2].enabled)
+		next_sar += sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY2].xsize
+			* sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY2].ysize;
+	cursor_sar = next_sar;
+
+	if (sinfo->baseimg_info.flip) {
+		/* If we flip we must start with the last line in the frame. */
+		y_sar += var->xres_virtual * (var->yres - 1);
+		u_sar += chroma_xres_virtual * (chroma_yres - 1);
+		v_sar += chroma_xres_virtual * (chroma_yres - 1);
+	}
+
+	dev_dbg(info->device, "%s:\n", __func__);
+	dev_dbg(info->device, "  * y_sar = 0x%x\n", y_sar);
+	dev_dbg(info->device, "  * u_sar = 0x%x\n", u_sar);
+	dev_dbg(info->device, "  * v_sar = 0x%x\n", v_sar);
+	dev_dbg(info->device, "  * o1_sar = 0x%x\n", o1_sar);
+	dev_dbg(info->device, "  * o2_sar = 0x%x\n", o2_sar);
+	dev_dbg(info->device, "  * cursor_sar = 0x%x\n", cursor_sar);
+
+	mpop_writel(sinfo, ATMEL_MPOP_Y_SAR, y_sar);
+	mpop_writel(sinfo, ATMEL_MPOP_U_SAR, u_sar);
+	mpop_writel(sinfo, ATMEL_MPOP_V_SAR, v_sar);
+	mpop_writel(sinfo, ATMEL_MPOP_O1_SAR, o1_sar);
+	mpop_writel(sinfo, ATMEL_MPOP_O2_SAR, o2_sar);
+	mpop_writel(sinfo, ATMEL_MPOP_CURSOR_SAR, cursor_sar);
+}
+
+static void atmel_mpopfb_free_video_memory(struct atmel_mpopfb_info *sinfo)
+{
+	struct fb_info *info = sinfo->info;
+
+	dma_free_writecombine(info->device, info->fix.smem_len,
+			(void __force *)info->screen_base,
+			info->fix.smem_start);
+}
+
+/**
+ *	atmel_mpopfb_alloc_video_memory - Allocate framebuffer memory
+ *	@sinfo: the frame buffer to allocate memory for
+ */
+static int atmel_mpopfb_alloc_video_memory(struct atmel_mpopfb_info *sinfo)
+{
+	struct fb_info *info = sinfo->info;
+	struct fb_var_screeninfo *var = &info->var;
+
+	info->fix.smem_len = (var->xres_virtual * var->yres_virtual
+			* ((var->bits_per_pixel + 7) / 8));
+
+	info->screen_base
+		= (void __iomem __force *)dma_alloc_writecombine(info->device,
+				info->fix.smem_len,
+				(dma_addr_t *)&info->fix.smem_start,
+				GFP_KERNEL);
+
+	if (!info->screen_base)
+		return -ENOMEM;
+
+	return 0;
+}
+
+/**
+ *      atmel_mpopfb_check_var - Validates a var passed in.
+ *      @var: frame buffer variable screen structure
+ *      @info: frame buffer structure that represents a single frame buffer
+ *
+ *	Checks to see if the hardware supports the state requested by
+ *	var passed in. This function does not alter the hardware
+ *	state!!!  This means the data stored in struct fb_info and
+ *	struct atmel_mpopfb_info do not change. This includes the var
+ *	inside of struct fb_info.  Do NOT change these. This function
+ *	can be called on its own if we intent to only test a mode and
+ *	not actually set it. The stuff in modedb.c is a example of
+ *	this. If the var passed in is slightly off by what the
+ *	hardware can support then we alter the var PASSED in to what
+ *	we can do. If the hardware doesn't support mode change a
+ *	-EINVAL will be returned by the upper layers. You don't need
+ *	to implement this function then. If you hardware doesn't
+ *	support changing the resolution then this function is not
+ *	needed. In this case the driver would just provide a var that
+ *	represents the static state the screen is in.
+ *
+ *	Returns negative errno on error, or zero on success.
+ */
+static int atmel_mpopfb_check_var(struct fb_var_screeninfo *var,
+		struct fb_info *info)
+{
+	struct device *dev = info->device;
+	struct atmel_mpopfb_info *sinfo = info->par;
+	struct fb_info *lcdc_info = platform_get_drvdata(sinfo->lcdc_pdev);
+
+	dev_dbg(dev, "%s:\n", __func__);
+	dev_dbg(dev, "  resolution: %ux%u\n", var->xres, var->yres);
+	dev_dbg(dev, "  offset: (%u,%u)\n", var->xoffset, var->yoffset);
+	dev_dbg(dev, "  bpp:        %u\n", var->bits_per_pixel);
+
+	/*
+	 *  FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
+	 *  as FB_VMODE_SMOOTH_XPAN is only used internally
+	 */
+
+	if (var->vmode & FB_VMODE_CONUPDATE) {
+		var->vmode |= FB_VMODE_YWRAP;
+		var->xoffset = info->var.xoffset;
+		var->yoffset = info->var.yoffset;
+	}
+
+	/* Horizontal size must be a multiple of 16 pixels */
+
+	/*
+	 *  Some very basic checks
+	 */
+	if (!var->xres)
+		var->xres = 1;
+	if (!var->yres)
+		var->yres = 1;
+	if (var->xres > var->xres_virtual)
+		var->xres_virtual = var->xres;
+	if (var->yres > var->yres_virtual)
+		var->yres_virtual = var->yres;
+	if (var->bits_per_pixel > 16)
+		var->bits_per_pixel = 24;
+	else if (var->bits_per_pixel > 12)
+		var->bits_per_pixel = 16;
+	else
+		var->bits_per_pixel = 12;
+
+	/* Horizontal size and offset must be a multiple of 16 pixels */
+	var->xres = (var->xres + 15) & ~15UL;
+	var->xres_virtual = (var->xres_virtual + 15) & ~15UL;
+	var->xoffset = (var->xoffset + 15) & ~15UL;
+
+	if (var->xres_virtual < var->xoffset + var->xres)
+		var->xres_virtual = var->xoffset + var->xres;
+	if (var->yres_virtual < var->yoffset + var->yres)
+		var->yres_virtual = var->yoffset + var->yres;
+
+	/* Check that the scaled image will fit into the LCD display. */
+	if (sinfo->baseimg_info.xsize > lcdc_info->var.xres) {
+		dev_err(dev, "baseimage is wider than screen: %d > %d\n",
+			sinfo->baseimg_info.xsize, lcdc_info->var.xres);
+		return -EINVAL;
+	}
+
+	if (sinfo->baseimg_info.ysize > lcdc_info->var.yres) {
+		dev_err(dev, "baseimage is higher than screen: %d > %d\n",
+			sinfo->baseimg_info.ysize, lcdc_info->var.yres);
+		return -EINVAL;
+	}
+
+	/* Check that it is possible to scale to given size. */
+	if (ATMEL_MPOP_CALC_SCALE(var->xres, sinfo->baseimg_info.xsize) == 0
+			|| (ATMEL_MPOP_CALC_SCALE(var->xres,
+					sinfo->baseimg_info.xsize)
+				> (4 << ATMEL_MPOP_RESIZE_FRAC_BITS))) {
+		dev_err(dev, "cannot scale from width %d to %d Max %s\n",
+			var->xres, sinfo->baseimg_info.xsize,
+			ATMEL_MPOP_CALC_SCALE(var->xres,
+					      sinfo->baseimg_info.xsize)
+			? "downscale factor is 4!"
+			: "upscale factor is 32");
+		return -EINVAL;
+	}
+
+	if (ATMEL_MPOP_CALC_SCALE(var->yres, sinfo->baseimg_info.ysize) == 0
+			|| (ATMEL_MPOP_CALC_SCALE(var->yres,
+					sinfo->baseimg_info.ysize)
+				> (4 << ATMEL_MPOP_RESIZE_FRAC_BITS))) {
+		dev_err(dev, "cannot scale from height %d to %d Max %s\n",
+			var->yres, sinfo->baseimg_info.ysize,
+			ATMEL_MPOP_CALC_SCALE(var->yres,
+					      sinfo->baseimg_info.ysize)
+			? "downscale factor is 4!"
+			: "upscale factor is 32");
+		return -EINVAL;
+	}
+
+	var->red.msb_right = var->green.msb_right = var->blue.msb_right = 0;
+	var->transp.msb_right = 0;
+	var->transp.offset = var->transp.length = 0;
+
+	switch (var->bits_per_pixel) {
+	case 12:
+	case 16:
+	case 24:
+		var->red.offset = 0;
+		var->green.offset = 8;
+		var->blue.offset = 16;
+		var->red.length = var->green.length = var->blue.length = 8;
+		break;
+	default:
+		dev_err(dev, "color depth %d not supported\n",
+			var->bits_per_pixel);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void atmel_mpopfb_start(struct atmel_mpopfb_info *sinfo)
+{
+	if (!sinfo->running) {
+		dev_dbg(sinfo->info->device, "  * Starting MPOP.\n");
+
+		/* Enable all error interrupts. */
+		mpop_writel(sinfo, ATMEL_MPOP_INTEN, 0x7);
+
+		/*
+		 * Enable the MPOP. When the LCD controller starts
+		 * reading from the slave interface it will start
+		 * generating a frame.
+		 */
+		mpop_writel(sinfo, ATMEL_MPOP_CR,
+			    ATMEL_MPOP_CR_EN_MASK
+			    /*| ATMEL_MPOP_CR_OUT_BGR_MASK */ );
+
+		sinfo->running = 1;
+	}
+}
+
+static void atmel_mpopfb_stop(struct atmel_mpopfb_info *sinfo)
+{
+	if (!sinfo->running)
+		/* Not running. Already stopped. */
+		return;
+
+	dev_dbg(sinfo->info->device, "Stopping MPOP.\n");
+
+	/* Disable the MPOP. This will force the MPOP to be reset. */
+	mpop_writel(sinfo, ATMEL_MPOP_CR, 0);
+
+	/* Disable all interrupts. */
+	mpop_writel(sinfo, ATMEL_MPOP_INTDIS, ~0UL);
+
+	/* Looks like we stopped the MPOP... */
+	dev_dbg(sinfo->info->device, "MPOP stopped.\n");
+
+	sinfo->running = 0;
+}
+
+static void atmel_mpopfb_connect_to_lcdc(struct atmel_mpopfb_info *sinfo)
+{
+	struct fb_info *lcdc_info = platform_get_drvdata(sinfo->lcdc_pdev);
+
+	dev_dbg(sinfo->info->device, "Connecting MPOP to LCDC:\n");
+
+	/* Start the mpop if it is not running. */
+	atmel_mpopfb_start(sinfo);
+
+	if (sinfo->connected_to_lcdc)
+		/* Already connected. */
+		return;
+
+	/*
+	 * Set framebuffer pointer in LCDC to point to the slave
+	 * interface of the MPOP.
+	 */
+	dev_dbg(sinfo->info->device, "  * Attaching to LCDC.\n");
+	sinfo->lcdc_old_smem_start = lcdc_info->fix.smem_start;
+	lcdc_info->fix.smem_start = (unsigned long)sinfo->slave_base;
+	sinfo->lcdc_old_bits_per_pixel = lcdc_info->var.bits_per_pixel;
+	lcdc_info->var.bits_per_pixel = 32;
+
+	/* Force the LCDC to change the configuration. */
+	lcdc_info->fbops->fb_set_par(lcdc_info);
+
+	sinfo->connected_to_lcdc = 1;
+}
+
+static void atmel_mpopfb_disconnect_from_lcdc(struct atmel_mpopfb_info *sinfo)
+{
+	struct fb_info *lcdc_info = platform_get_drvdata(sinfo->lcdc_pdev);
+
+	dev_dbg(sinfo->info->device, "Disconnecting MPOP from LCDC:\n");
+
+	if (!sinfo->connected_to_lcdc)
+		/* Already disconnected. */
+		return;
+
+	/* Restore lcdc's old framebuffer pointer and pixel-format. */
+	lcdc_info->fix.smem_start = sinfo->lcdc_old_smem_start;
+	lcdc_info->var.bits_per_pixel = sinfo->lcdc_old_bits_per_pixel;
+
+	/* Force the LCDC to change the configuration. */
+	lcdc_info->fbops->fb_set_par(lcdc_info);
+
+	sinfo->connected_to_lcdc = 0;
+
+	/* We must stop the mpop to reset it. */
+	atmel_mpopfb_stop(sinfo);
+}
+
+static void atmel_mpopfb_put_overlay_palette(struct atmel_mpopfb_info *sinfo,
+		struct atmel_mpopfb_overlay_palette *palette)
+{
+	int i;
+
+	dev_dbg(sinfo->info->device, "Overlay palette = :\n");
+	for (i = 0; i < 256; i++) {
+		dev_dbg(sinfo->info->device, "%d -> 0x%x\n", i,
+			*((int *)&palette->entry[i]));
+		mpop_writel(sinfo, ATMEL_MPOP_PALETTEDATA + 4 * i,
+			    *((int *)&palette->entry[i]));
+	}
+}
+
+static void atmel_mpopfb_get_overlay_palette(struct atmel_mpopfb_info *sinfo,
+		struct atmel_mpopfb_overlay_palette *palette)
+{
+	int i;
+
+	for (i = 0; i < 256; i++)
+		*((int *)&palette->entry[i]) =
+		    mpop_readl(sinfo, ATMEL_MPOP_PALETTEDATA + 4 * i);
+}
+
+static void atmel_mpopfb_put_cursor_palette(struct atmel_mpopfb_info *sinfo,
+		struct atmel_mpopfb_cursor_palette *palette)
+{
+	int i;
+	for (i = 0; i < 4; i++)
+		mpop_writel(sinfo, ATMEL_MPOP_CURSOR_P0 + 4 * i,
+				*((int *)&palette->entry[i]));
+}
+
+static void atmel_mpopfb_get_cursor_palette(struct atmel_mpopfb_info *sinfo,
+		struct atmel_mpopfb_cursor_palette *palette)
+{
+	int i;
+	for (i = 0; i < 4; i++)
+		*((int *)&palette->entry[i])
+			= mpop_readl(sinfo, ATMEL_MPOP_CURSOR_P0 + 4 * i);
+}
+
+/**
+ *      atmel_mpopfb_set_par - Alters the hardware state.
+ *      @info: frame buffer structure that represents a single frame buffer
+ *
+ *	Using the fb_var_screeninfo in fb_info we set the resolution
+ *	of the this particular framebuffer. This function alters the
+ *	par AND the fb_fix_screeninfo stored in fb_info. It doesn't
+ *	not alter var in fb_info since we are using that data. This
+ *	means we depend on the data in var inside fb_info to be
+ *	supported by the hardware.  atmel_lcdfb_check_var is always called
+ *	before atmel_lcdfb_set_par to ensure this.  Again if you can't
+ *	change the resolution you don't need this function.
+ *
+ */
+static int atmel_mpopfb_set_par(struct fb_info *info)
+{
+	struct atmel_mpopfb_info *sinfo = info->par;
+	struct fb_info *lcdc_info = platform_get_drvdata(sinfo->lcdc_pdev);
+	struct fb_var_screeninfo *var = &info->var;
+
+	u32 yuv_format;
+	u32 xscale, yscale;
+
+	dev_dbg(info->device, "%s:\n", __func__);
+	dev_dbg(info->device, "  * resolution: %ux%u (%ux%u virtual)\n",
+			info->var.xres, info->var.yres,
+			info->var.xres_virtual, info->var.yres_virtual);
+	dev_dbg(info->device, "  * offset: (%u,%u)\n",
+			info->var.xoffset, info->var.yoffset);
+	dev_dbg(info->device, "  * bpp: %u\n", info->var.bits_per_pixel);
+
+	/* Setup the output picture size. We must use the size of the lcdcfb. */
+	dev_dbg(info->device, "  * output frame resolution: %ux%u \n",
+			lcdc_info->var.xres, lcdc_info->var.yres);
+	mpop_writel(sinfo, ATMEL_MPOP_DISP_MAX_COORD,
+			((lcdc_info->var.xres - 1) << ATMEL_MPOP_DISP_MAX_COORD_X_OFFSET)
+			| ((lcdc_info->var.yres - 1) << ATMEL_MPOP_DISP_MAX_COORD_Y_OFFSET));
+
+	/* Setup base picture. */
+
+	switch (var->bits_per_pixel) {
+	default:
+	case 12:
+		yuv_format = ATMEL_MPOP_YUVFORMAT_420;
+		break;
+	case 16:
+		yuv_format = ATMEL_MPOP_YUVFORMAT_422;
+		break;
+	case 24:
+		yuv_format = ATMEL_MPOP_YUVFORMAT_444;
+		break;
+	}
+
+	xscale = ATMEL_MPOP_CALC_SCALE(info->var.xres, sinfo->baseimg_info.xsize);
+	yscale = ATMEL_MPOP_CALC_SCALE(info->var.yres, sinfo->baseimg_info.ysize);
+
+	dev_dbg(info->device, "  * baseimg output size = %ux%u \n",
+			sinfo->baseimg_info.xsize, sinfo->baseimg_info.ysize);
+	dev_dbg(info->device, "  * resize scales = %ux%u \n", xscale, yscale);
+	dev_dbg(info->device, "  * yuv format = %u \n", yuv_format);
+	mpop_writel(sinfo, ATMEL_MPOP_YCR,
+			yuv_format << ATMEL_MPOP_YCR_YUVFORMAT_OFFSET
+			| xscale << ATMEL_MPOP_YCR_XRESIZE_OFFSET
+			| yscale << ATMEL_MPOP_YCR_YRESIZE_OFFSET);
+
+	/* Setup conversion coefficients. */
+	mpop_writel(sinfo, ATMEL_MPOP_R2R1,
+			((sinfo->rgbconv_coeffs.r1 << ATMEL_MPOP_R1_OFFSET) & ATMEL_MPOP_R1_MASK)
+			| ((sinfo->rgbconv_coeffs.r2 << ATMEL_MPOP_R2_OFFSET) & ATMEL_MPOP_R2_MASK));
+	mpop_writel(sinfo, ATMEL_MPOP_R4R3,
+			((sinfo->rgbconv_coeffs.r3 << ATMEL_MPOP_R3_OFFSET) & ATMEL_MPOP_R3_MASK)
+			| ((sinfo->rgbconv_coeffs.r4 << ATMEL_MPOP_R4_OFFSET) & ATMEL_MPOP_R4_MASK));
+	mpop_writel(sinfo, ATMEL_MPOP_G2G1,
+			((sinfo->rgbconv_coeffs.g1 << ATMEL_MPOP_G1_OFFSET) & ATMEL_MPOP_G1_MASK)
+			| ((sinfo->rgbconv_coeffs.g2 << ATMEL_MPOP_G2_OFFSET) & ATMEL_MPOP_G2_MASK));
+	mpop_writel(sinfo, ATMEL_MPOP_G4G3,
+			((sinfo->rgbconv_coeffs.g3 << ATMEL_MPOP_G3_OFFSET) & ATMEL_MPOP_G3_MASK)
+			| ((sinfo->rgbconv_coeffs.g4 << ATMEL_MPOP_G4_OFFSET) & ATMEL_MPOP_G4_MASK));
+	mpop_writel(sinfo, ATMEL_MPOP_B2B1,
+			((sinfo->rgbconv_coeffs.b1 << ATMEL_MPOP_B1_OFFSET) & ATMEL_MPOP_B1_MASK)
+			| ((sinfo->rgbconv_coeffs.b2 << ATMEL_MPOP_B2_OFFSET) & ATMEL_MPOP_B2_MASK));
+	mpop_writel(sinfo, ATMEL_MPOP_B4B3,
+			((sinfo->rgbconv_coeffs.b3 << ATMEL_MPOP_B3_OFFSET) & ATMEL_MPOP_B3_MASK)
+			| ((sinfo->rgbconv_coeffs.b4 << ATMEL_MPOP_B4_OFFSET) & ATMEL_MPOP_B4_MASK));
+
+	info->fix.line_length = info->var.xres_virtual;
+	info->fix.visual = FB_VISUAL_TRUECOLOR;
+
+	/* Setup stride. We can flip the image by negating the 
+	   stride, but we must then set the SAR registers to point
+	   to the last line in the image. */
+	if (sinfo->baseimg_info.flip) {
+		dev_dbg(info->device, "  * flip \n");
+		mpop_writel(sinfo, ATMEL_MPOP_STRIDE, -info->var.xres_virtual);
+	} else
+		mpop_writel(sinfo, ATMEL_MPOP_STRIDE, info->var.xres_virtual);
+
+	/* Setup input image size. */
+	mpop_writel(sinfo, ATMEL_MPOP_YUV_MAX_COORD,
+			((info->var.xres - 1) << ATMEL_MPOP_YUV_MAX_COORD_X_OFFSET)
+			| ((info->var.yres - 1) << ATMEL_MPOP_YUV_MAX_COORD_Y_OFFSET));
+
+	/* Setup size and position of output base image after scaling. */
+	mpop_writel(sinfo, ATMEL_MPOP_RGB_SIZE,
+			sinfo->baseimg_info.xsize << ATMEL_MPOP_RGB_SIZE_X_OFFSET
+			| sinfo->baseimg_info.ysize << ATMEL_MPOP_RGB_SIZE_Y_OFFSET);
+
+	mpop_writel(sinfo, ATMEL_MPOP_RGB_POS,
+			(sinfo->baseimg_info.xpos << ATMEL_MPOP_RGB_POS_X_OFFSET)
+			| (sinfo->baseimg_info.ypos << ATMEL_MPOP_RGB_POS_Y_OFFSET));
+
+	dev_dbg(info->device, "  * baseimg pos: (%u,%u) \n",
+			sinfo->baseimg_info.xpos, sinfo->baseimg_info.ypos);
+
+	/* Setup Word Transfer Count. */
+	mpop_writel(sinfo, ATMEL_MPOP_RGB_WTC,
+			DIV_ROUND_UP(info->var.xres * info->var.yres
+				* var->bits_per_pixel, 32));
+
+	/* Set overlay parameters. */
+	mpop_writel(sinfo, ATMEL_MPOP_O1_POS,
+			(sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY1].xpos << ATMEL_MPOP_O1_POS_O1_POS_X)
+			| (sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY1].ypos << ATMEL_MPOP_O1_POS_O1_POS_Y));
+	mpop_writel(sinfo, ATMEL_MPOP_O1_SIZE,
+			(sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY1].xsize << ATMEL_MPOP_O1_SIZE_O1_SIZE_X)
+			| (sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY1].ysize << ATMEL_MPOP_O1_SIZE_O1_SIZE_Y));
+	mpop_writel(sinfo, ATMEL_MPOP_O1_WTC,
+			DIV_ROUND_UP(sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY1].xsize
+			 * sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY1].ysize, 4));
+
+	mpop_writel(sinfo, ATMEL_MPOP_O2_POS,
+			(sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY2].xpos << ATMEL_MPOP_O2_POS_O2_POS_X)
+			| (sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY2].ypos << ATMEL_MPOP_O2_POS_O2_POS_Y));
+	mpop_writel(sinfo, ATMEL_MPOP_O2_SIZE,
+			(sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY2].xsize << ATMEL_MPOP_O2_SIZE_O2_SIZE_X)
+			| (sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY2].ysize << ATMEL_MPOP_O2_SIZE_O2_SIZE_Y));
+	mpop_writel(sinfo, ATMEL_MPOP_O2_WTC,
+			DIV_ROUND_UP(sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY2].xsize *
+				sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY2].ysize, 4));
+
+	mpop_writel(sinfo, ATMEL_MPOP_CURSOR_POS,
+			(sinfo->overlay_info[ATMEL_MPOPFB_CURSOR].xpos << ATMEL_MPOP_CURSOR_POS_CURSOR_POS_X)
+			| (sinfo->overlay_info[ATMEL_MPOPFB_CURSOR].ypos << ATMEL_MPOP_CURSOR_POS_CURSOR_POS_Y));
+	mpop_writel(sinfo, ATMEL_MPOP_CURSOR_SIZE,
+			(sinfo->overlay_info[ATMEL_MPOPFB_CURSOR].xsize << ATMEL_MPOP_CURSOR_SIZE_CURSOR_SIZE_X)
+			| (sinfo->overlay_info[ATMEL_MPOPFB_CURSOR].ysize << ATMEL_MPOP_CURSOR_SIZE_CURSOR_SIZE_Y));
+	mpop_writel(sinfo, ATMEL_MPOP_CURSOR_WTC,
+			DIV_ROUND_UP(sinfo->overlay_info[ATMEL_MPOPFB_CURSOR].xsize
+				* sinfo->overlay_info[ATMEL_MPOPFB_CURSOR].ysize, 16));
+
+	/* Enable base overlay + any other enabled overlays. */
+	mpop_writel(sinfo, ATMEL_MPOP_OCR, ATMEL_MPOP_OCR_RGBEN_MASK);
+
+	if (sinfo->overlay_info[ATMEL_MPOPFB_CURSOR].enabled)
+		mpop_writel(sinfo, ATMEL_MPOP_OCR,
+				mpop_readl(sinfo, ATMEL_MPOP_OCR)
+				| ATMEL_MPOP_OCR_CURSOREN_MASK);
+	if (sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY1].enabled)
+		mpop_writel(sinfo, ATMEL_MPOP_OCR,
+				mpop_readl(sinfo, ATMEL_MPOP_OCR)
+				| ATMEL_MPOP_OCR_O1EN_MASK);
+	if (sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY2].enabled)
+		mpop_writel(sinfo, ATMEL_MPOP_OCR,
+				mpop_readl(sinfo, ATMEL_MPOP_OCR)
+				| ATMEL_MPOP_OCR_O2EN_MASK);
+
+	/* Set background to black. */
+	mpop_writel(sinfo, ATMEL_MPOP_BGCOLOR, 0);
+
+	/* Setup source address registers */
+	atmel_mpopfb_update_sar(info, &info->var);
+
+	dev_dbg(info->device, "  * DONE\n");
+
+	return 0;
+}
+
+static int atmel_mpopfb_pan_display(struct fb_var_screeninfo *var,
+		struct fb_info *info)
+{
+	dev_dbg(info->device, "%s\n", __func__);
+
+	/* Change source address registers to reflect the panning. */
+	atmel_mpopfb_update_sar(info, var);
+
+	return 0;
+}
+
+static void atmel_mpopfb_put_overlay_info(struct fb_info *info,
+		struct atmel_mpopfb_overlay_info overlay_info)
+{
+	struct atmel_mpopfb_info *sinfo = info->par;
+
+	/* We can update the position now since it is double buffered. */
+	switch (overlay_info.overlay) {
+	case ATMEL_MPOPFB_OVERLAY1:
+		mpop_writel(sinfo, ATMEL_MPOP_O1_POS,
+			(overlay_info.xpos << ATMEL_MPOP_O1_POS_O1_POS_X)
+			| (overlay_info.ypos << ATMEL_MPOP_O1_POS_O1_POS_Y));
+		break;
+	case ATMEL_MPOPFB_OVERLAY2:
+		mpop_writel(sinfo, ATMEL_MPOP_O2_POS,
+			(overlay_info.xpos << ATMEL_MPOP_O2_POS_O2_POS_X)
+			| (overlay_info.ypos << ATMEL_MPOP_O2_POS_O2_POS_Y));
+		break;
+	case ATMEL_MPOPFB_CURSOR:
+		mpop_writel(sinfo, ATMEL_MPOP_CURSOR_POS,
+			(overlay_info.xpos << ATMEL_MPOP_CURSOR_POS_CURSOR_POS_X)
+			| (overlay_info.ypos << ATMEL_MPOP_CURSOR_POS_CURSOR_POS_Y));
+		break;
+	default:
+		dev_warn(info->device, "Unknown overlay type: %d\n",
+				overlay_info.overlay);
+		return;
+	}
+
+	/* Copy the overlay info to the mpopfb info structure. */
+	sinfo->overlay_info[overlay_info.overlay] = overlay_info;
+}
+
+static int atmel_mpopfb_ioctl(struct fb_info *info,
+		unsigned int cmd, unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	struct atmel_mpopfb_info *sinfo = info->par;
+	struct atmel_mpopfb_overlay_info overlay_info;
+
+	switch (cmd) {
+	case ATMEL_MPOP_FBIOPUT_OVERLAY_PALETTE:{
+			struct atmel_mpopfb_overlay_palette palette;
+			if (copy_from_user(&palette, argp, sizeof(palette)))
+				return -EFAULT;
+			atmel_mpopfb_put_overlay_palette(sinfo, &palette);
+			return 0;
+		}
+	case ATMEL_MPOP_FBIOGET_OVERLAY_PALETTE:{
+			struct atmel_mpopfb_overlay_palette palette;
+			atmel_mpopfb_get_overlay_palette(sinfo, &palette);
+			if (copy_to_user(argp, &palette, sizeof(palette)))
+				return -EFAULT;
+			return 0;
+		}
+	case ATMEL_MPOP_FBIOPUT_CURSOR_PALETTE:{
+			struct atmel_mpopfb_cursor_palette palette;
+			if (copy_from_user(&palette, argp, sizeof(palette)))
+				return -EFAULT;
+			atmel_mpopfb_put_cursor_palette(sinfo, &palette);
+			return 0;
+		}
+	case ATMEL_MPOP_FBIOGET_CURSOR_PALETTE:{
+			struct atmel_mpopfb_cursor_palette palette;
+			atmel_mpopfb_get_cursor_palette(sinfo, &palette);
+			if (copy_to_user(argp, &palette, sizeof(palette)))
+				return -EFAULT;
+			return 0;
+		}
+	case ATMEL_MPOP_FBIOPUT_OVERLAY_INFO:
+		if (copy_from_user(&overlay_info, argp, sizeof(overlay_info)))
+			return -EFAULT;
+		atmel_mpopfb_put_overlay_info(info, overlay_info);
+		return 0;
+	case ATMEL_MPOP_FBIOPUT_BASEIMG_INFO:
+		if (copy_from_user(&sinfo->baseimg_info, argp,
+					sizeof(sinfo->baseimg_info)))
+			return -EFAULT;
+
+		/* Check that new baseimg parameters are sane. */
+		if (atmel_mpopfb_check_var(&info->var, info))
+			return -EFAULT;
+
+		/* Update hardware configuration. */
+		atmel_mpopfb_set_par(info);
+		return 0;
+	case ATMEL_MPOP_FBIOGET_BASEIMG_INFO:
+		return copy_to_user(argp, &sinfo->baseimg_info,
+				sizeof(sinfo->baseimg_info)) ? -EFAULT : 0;
+	case ATMEL_MPOP_FBIOPUT_RGBCONV_COEFFS:
+		if (copy_from_user(&sinfo->rgbconv_coeffs, argp,
+					sizeof(sinfo->rgbconv_coeffs)))
+			return -EFAULT;
+
+		/* Update hardware configuration. */
+		if (atmel_mpopfb_set_par(info))
+			return -EFAULT;
+
+		return 0;
+	case ATMEL_MPOP_FBIOGET_RGBCONV_COEFFS:
+		return copy_to_user(argp, &sinfo->rgbconv_coeffs,
+				sizeof(sinfo->rgbconv_coeffs)) ? -EFAULT : 0;
+	case ATMEL_MPOP_FBIO_CONNECT_TO_LCDC:
+		atmel_mpopfb_connect_to_lcdc(sinfo);
+		return 0;
+	case ATMEL_MPOP_FBIO_DISCONNECT_FROM_LCDC:
+		atmel_mpopfb_disconnect_from_lcdc(sinfo);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+
+	/* Force MPOP to be updated with any new parameters. */
+	atmel_mpopfb_set_par(info);
+}
+
+static int atmel_mpopfb_setcolreg(unsigned int regno, unsigned int red,
+				  unsigned int green, unsigned int blue,
+				  unsigned int transp, struct fb_info *info)
+{
+	return 0;
+}
+
+static struct fb_ops atmel_mpopfb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_check_var	= atmel_mpopfb_check_var,
+	.fb_set_par	= atmel_mpopfb_set_par,
+	.fb_setcolreg	= atmel_mpopfb_setcolreg,
+	.fb_pan_display	= atmel_mpopfb_pan_display,
+	.fb_imageblit	= cfb_imageblit,
+	.fb_ioctl	= atmel_mpopfb_ioctl,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+};
+
+static irqreturn_t atmel_mpopfb_interrupt(int irq, void *dev_id)
+{
+	struct fb_info *info = dev_id;
+	struct atmel_mpopfb_info *sinfo = info->par;
+	u32 status;
+
+	/* Check which interrupt we have. */
+	status = mpop_readl(sinfo, ATMEL_MPOP_INTSTATUS);
+
+	/* Clear interrupts. */
+	mpop_writel(sinfo, ATMEL_MPOP_INTCLEAR, status);
+
+	if (status & ATMEL_MPOP_EOP) {
+		/* End Of Picture. Start new picture. */
+		mpop_writel(sinfo, ATMEL_MPOP_CR,
+				ATMEL_MPOP_CR_START_MASK
+				| mpop_readl(sinfo, ATMEL_MPOP_CR));
+	} else if (status & ATMEL_MPOP_OUT) {
+		dev_err(info->dev,
+			"MPOP Output DMA interface Bus Error (address=0x%x)!\n",
+			mpop_readl(sinfo, ATMEL_MPOP_OUT_BEAR));
+	} else if (status & ATMEL_MPOP_YUV) {
+		dev_err(info->dev,
+			"MPOP YUV Picture Fetch DMA interface Bus Error (address=0x%x)!\n",
+			mpop_readl(sinfo, ATMEL_MPOP_YUV_BEAR));
+	} else if (status & ATMEL_MPOP_OVERLAY) {
+		dev_err(info->dev,
+			"MPOP Overlay Picture Fetch DMA interface Bus Error (address=0x%x)!\n",
+			mpop_readl(sinfo, ATMEL_MPOP_OVERLAY_BEAR));
+	}
+
+	dev_dbg(info->device, "%s\n", __func__);
+	dev_dbg(info->device, "  * status: 0x%x \n", status);
+
+	return IRQ_HANDLED;
+}
+
+static int __init atmel_mpopfb_init_fbinfo(struct atmel_mpopfb_info *sinfo)
+{
+	struct fb_info *info = sinfo->info;
+	int ret = 0;
+
+	info->var.activate |= FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
+
+	dev_info(info->device,
+			"%luKiB frame buffer at %08lx (mapped at %p)\n",
+			(unsigned long)info->fix.smem_len / 1024,
+			(unsigned long)info->fix.smem_start, info->screen_base);
+
+	return ret;
+}
+
+static void atmel_mpopfb_start_clock(struct atmel_mpopfb_info *sinfo)
+{
+	clk_enable(sinfo->mpop_hclk);
+	clk_enable(sinfo->mpop_pclk);
+}
+
+static void atmel_mpopfb_stop_clock(struct atmel_mpopfb_info *sinfo)
+{
+	clk_disable(sinfo->mpop_hclk);
+	clk_disable(sinfo->mpop_pclk);
+}
+
+static int __init atmel_mpopfb_probe(struct platform_device *pdev)
+{
+	struct device			*dev = &pdev->dev;
+	struct fb_info			*info;
+	struct fb_info			*lcdc_info;
+	struct atmel_mpopfb_info	*sinfo;
+	struct atmel_mpopfb_info	*pdata_sinfo;
+	struct resource			*regs = NULL;
+	struct resource			*slave = NULL;
+	struct resource			*map = NULL;
+	int				ret;
+
+	dev_dbg(dev, "%s BEGIN\n", __func__);
+
+	ret = -ENOMEM;
+	info = framebuffer_alloc(sizeof(struct atmel_mpopfb_info), dev);
+	if (!info) {
+		dev_err(dev, "cannot allocate memory\n");
+		goto out;
+	}
+
+	sinfo = info->par;
+
+	if (dev->platform_data) {
+		pdata_sinfo = dev->platform_data;
+		sinfo->lcdc_pdev = pdata_sinfo->lcdc_pdev;
+		if (!sinfo->lcdc_pdev) {
+			dev_err(dev, "cannot get hold of lcdcfb device\n");
+			goto free_info;
+		}
+	} else {
+		dev_err(dev, "cannot get default configuration\n");
+		goto free_info;
+	}
+
+	sinfo->info = info;
+	sinfo->pdev = pdev;
+	sinfo->running = 0;
+	sinfo->connected_to_lcdc = 0;
+	sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY1].enabled = 0;
+	sinfo->overlay_info[ATMEL_MPOPFB_OVERLAY2].enabled = 0;
+	sinfo->overlay_info[ATMEL_MPOPFB_CURSOR].enabled = 0;
+
+	/* Setup default info */
+
+	/* Set fb_var_screeninfo equal to that of the lcdcfb driver. */
+	lcdc_info = (struct fb_info *)platform_get_drvdata(sinfo->lcdc_pdev);
+	memcpy(&info->var, &lcdc_info->var, sizeof(struct fb_var_screeninfo));
+
+	/* Set default position of the image on the screen to (0,0) and
+	   no scaling */
+	sinfo->baseimg_info.xpos = 0;
+	sinfo->baseimg_info.ypos = 0;
+	sinfo->baseimg_info.xsize = info->var.xres;
+	sinfo->baseimg_info.ysize = info->var.yres;
+
+	/* Use YCbCr --> RGB converion per default. */
+	memcpy(&sinfo->rgbconv_coeffs, &atmel_mpop_ycrcb2rgb_coeffs,
+	       sizeof(struct atmel_mpopfb_rgbconv_coeffs));
+
+	strcpy(info->fix.id, sinfo->pdev->name);
+	info->flags = ATMEL_MPOPFB_FBINFO_DEFAULT;
+	info->fbops = &atmel_mpopfb_ops;
+
+	//memcpy(&info->monspecs, sinfo->default_monspecs, sizeof(info->monspecs));
+	info->fix = atmel_mpopfb_fix;
+
+	/* Enable MPOP Clocks */
+	sinfo->mpop_hclk = clk_get(dev, "hclk");
+	sinfo->mpop_pclk = clk_get(dev, "pclk");
+	if (IS_ERR(sinfo->mpop_hclk)) {
+		ret = PTR_ERR(sinfo->mpop_hclk);
+		goto put_bus_clk;
+	}
+	if (IS_ERR(sinfo->mpop_pclk)) {
+		ret = PTR_ERR(sinfo->mpop_pclk);
+		goto stop_clk;
+	}
+	atmel_mpopfb_start_clock(sinfo);
+
+	//ret = fb_find_mode(&info->var, info, NULL, info->monspecs.modedb,
+	//                   info->monspecs.modedb_len, info->monspecs.modedb,
+	//                   sinfo->default_bpp);
+	//if (!ret) {
+	//      dev_err(dev, "no suitable video mode found\n");
+	//      goto stop_clk;
+	//}
+
+	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!regs) {
+		dev_err(dev, "resources unusable\n");
+		ret = -ENXIO;
+		goto stop_clk;
+	}
+
+	slave = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (!slave) {
+		dev_err(dev, "slave interface memory resource unusable\n");
+		ret = -ENXIO;
+		goto stop_clk;
+	}
+	sinfo->slave_base = (void *)slave->start;
+
+	sinfo->irq_base = platform_get_irq(pdev, 0);
+	if (sinfo->irq_base < 0) {
+		dev_err(dev, "unable to get irq\n");
+		ret = sinfo->irq_base;
+		goto stop_clk;
+	}
+
+	/* Initialize video memory */
+	map = platform_get_resource(pdev, IORESOURCE_MEM, 2);
+	if (map) {
+		/* use a pre-allocated memory buffer */
+		info->fix.smem_start = map->start;
+		info->fix.smem_len = map->end - map->start + 1;
+		if (!request_mem_region(info->fix.smem_start,
+					info->fix.smem_len, pdev->name)) {
+			//ret = -EBUSY;
+			//goto stop_clk;
+			/* Probably in use by LCD controller. */
+			info->screen_base = lcdc_info->screen_base;
+		} else {
+			info->screen_base =
+			    ioremap(info->fix.smem_start, info->fix.smem_len);
+			if (!info->screen_base)
+				goto release_intmem;
+		}
+	} else {
+		/* alocate memory buffer */
+		ret = atmel_mpopfb_alloc_video_memory(sinfo);
+		if (ret < 0) {
+			dev_err(dev, "cannot allocate mpop framebuffer: %d\n",
+				ret);
+			goto stop_clk;
+		}
+	}
+
+	/* MPOP registers */
+	info->fix.mmio_start = regs->start;
+	info->fix.mmio_len = regs->end - regs->start + 1;
+
+	if (!request_mem_region(info->fix.mmio_start,
+				info->fix.mmio_len, pdev->name)) {
+		ret = -EBUSY;
+		goto free_fb;
+	}
+
+	sinfo->mmio = ioremap(info->fix.mmio_start, info->fix.mmio_len);
+	if (!sinfo->mmio) {
+		dev_err(dev, "cannot map MPOP registers\n");
+		goto release_mem;
+	}
+
+	/* MPOP slave interface */
+	if (!request_mem_region(slave->start,
+				slave->end - slave->start + 1, pdev->name)) {
+		dev_err(dev,
+			"error requesting memory region for MPOP slave interface\n");
+		ret = -EBUSY;
+		goto unmap_mmio;
+	}
+
+	/* interrupt */
+	ret =
+	    request_irq(sinfo->irq_base, atmel_mpopfb_interrupt, 0, pdev->name,
+			info);
+	if (ret) {
+		dev_err(dev, "request_irq failed: %d\n", ret);
+		goto release_mem_slave;
+	}
+
+	ret = atmel_mpopfb_init_fbinfo(sinfo);
+	if (ret < 0) {
+		dev_err(dev, "init fbinfo failed: %d\n", ret);
+		goto unregister_irqs;
+	}
+
+	/*
+	 * This makes sure that our colour bitfield
+	 * descriptors are correctly initialised.
+	 */
+	atmel_mpopfb_check_var(&info->var, info);
+
+	ret = fb_set_var(info, &info->var);
+	if (ret) {
+		dev_warn(dev, "unable to set display parameters\n");
+		goto free_cmap;
+	}
+
+	dev_set_drvdata(dev, info);
+
+	/*
+	 * Tell the world that we're ready to go
+	 */
+	ret = register_framebuffer(info);
+	if (ret < 0) {
+		dev_err(dev, "failed to register framebuffer device: %d\n",
+			ret);
+		goto free_cmap;
+	}
+
+	dev_info(dev, "fb%d: Atmel MPOP at 0x%08lx (mapped at %p), irq %lu\n",
+		 info->node, info->fix.mmio_start, sinfo->mmio,
+		 sinfo->irq_base);
+
+	return 0;
+
+free_cmap:
+	fb_dealloc_cmap(&info->cmap);
+unregister_irqs:
+	free_irq(sinfo->irq_base, info);
+release_mem_slave:
+	release_mem_region(slave->start, slave->end - slave->start + 1);
+unmap_mmio:
+	iounmap(sinfo->mmio);
+release_mem:
+	release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
+free_fb:
+	if (map)
+		iounmap(info->screen_base);
+	else
+		atmel_mpopfb_free_video_memory(sinfo);
+
+release_intmem:
+	if (map)
+		release_mem_region(info->fix.smem_start, info->fix.smem_len);
+stop_clk:
+	atmel_mpopfb_stop_clock(sinfo);
+	clk_put(sinfo->mpop_hclk);
+put_bus_clk:
+	if (sinfo->mpop_pclk)
+		clk_put(sinfo->mpop_pclk);
+free_info:
+	framebuffer_release(info);
+out:
+	dev_dbg(dev, "%s FAILED\n", __func__);
+	return ret;
+}
+
+static int __exit atmel_mpopfb_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct atmel_mpopfb_info *sinfo = info->par;
+
+	if (!sinfo)
+		return 0;
+
+	unregister_framebuffer(info);
+	atmel_mpopfb_stop_clock(sinfo);
+	clk_put(sinfo->mpop_hclk);
+	clk_put(sinfo->mpop_pclk);
+	fb_dealloc_cmap(&info->cmap);
+	free_irq(sinfo->irq_base, info);
+	iounmap(sinfo->mmio);
+	release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
+	if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) {
+		iounmap(info->screen_base);
+		release_mem_region(info->fix.smem_start, info->fix.smem_len);
+	} else {
+		atmel_mpopfb_free_video_memory(sinfo);
+	}
+
+	dev_set_drvdata(dev, NULL);
+	framebuffer_release(info);
+
+	return 0;
+}
+
+static struct platform_driver atmel_mpopfb_driver = {
+	.remove = __exit_p(atmel_mpopfb_remove),
+	.driver.name = "atmel_mpopfb",
+	.driver.owner = THIS_MODULE,
+};
+
+static int __init atmel_mpopfb_init(void)
+{
+	return platform_driver_probe(&atmel_mpopfb_driver, atmel_mpopfb_probe);
+}
+
+static void __exit atmel_mpopfb_exit(void)
+{
+	platform_driver_unregister(&atmel_mpopfb_driver);
+}
+
+module_init(atmel_mpopfb_init);
+module_exit(atmel_mpopfb_exit);
+
+MODULE_DESCRIPTION("AT32 MPOP framebuffer driver");
+MODULE_AUTHOR("Ronny Pedersen <rpedersen@atmel.com>");
+MODULE_LICENSE("GPL");
diff -urN linux-2.6.28.2-0rig//drivers/video/Kconfig linux-2.6.28.2/drivers/video/Kconfig
--- linux-2.6.28.2-0rig//drivers/video/Kconfig	2009-01-29 08:39:31.000000000 +0100
+++ linux-2.6.28.2/drivers/video/Kconfig	2009-01-29 08:52:50.000000000 +0100
@@ -940,6 +940,15 @@
 	help
 	  This enables support for the AT91/AT32 LCD Controller.
 
+config FB_ATMEL_MPOP
+	tristate "AT32 MPOP support"
+	depends on FB && AVR32 && FB_ATMEL
+	select FB_CFB_FILLRECT
+	select FB_CFB_COPYAREA
+	select FB_CFB_IMAGEBLIT
+	help
+	  This enables support for the AT32 MPOP module.
+
 config FB_INTSRAM
 	bool "Frame Buffer in internal SRAM"
 	depends on FB_ATMEL && ARCH_AT91SAM9261
diff -urN linux-2.6.28.2-0rig//drivers/video/Makefile linux-2.6.28.2/drivers/video/Makefile
--- linux-2.6.28.2-0rig//drivers/video/Makefile	2009-01-29 08:39:31.000000000 +0100
+++ linux-2.6.28.2/drivers/video/Makefile	2009-01-29 08:52:50.000000000 +0100
@@ -89,6 +89,7 @@
 obj-$(CONFIG_FB_HIT)              += hitfb.o
 obj-$(CONFIG_FB_EPSON1355)	  += epson1355fb.o
 obj-$(CONFIG_FB_ATMEL)		  += atmel_lcdfb.o
+obj-$(CONFIG_FB_ATMEL_MPOP)	  += atmel_mpopfb.o
 obj-$(CONFIG_FB_PVR2)             += pvr2fb.o
 obj-$(CONFIG_FB_VOODOO1)          += sstfb.o
 obj-$(CONFIG_FB_ARMCLCD)	  += amba-clcd.o
diff -urN linux-2.6.28.2-0rig//include/linux/atmel_mpopfb.h linux-2.6.28.2/include/linux/atmel_mpopfb.h
--- linux-2.6.28.2-0rig//include/linux/atmel_mpopfb.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/include/linux/atmel_mpopfb.h	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,112 @@
+/*
+ *  Header file for AT32 MPOP FB Driver
+ *
+ *  Data structure and register user interface
+ *
+ *  Copyright (C) 2007 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
+ */
+#ifndef __ATMEL_MPOPFB_H__
+#define __ATMEL_MPOPFB_H__
+
+#include <linux/fb.h>
+#include <linux/ioctl.h>
+
+/* Coefficients for conversion to rgb. */
+struct atmel_mpopfb_rgbconv_coeffs {
+	int r1, r2, r3, r4;
+	int g1, g2, g3, g4;
+	int b1, b2, b3, b4;
+};
+
+struct atmel_mpopfb_baseimg_info {
+	/* Position of the mpop base image
+	   in the image sent to the LCD. */
+	unsigned xpos;
+	unsigned ypos;
+
+	/* The size of the base image after scaling. */
+	unsigned xsize;
+	unsigned ysize;
+
+	/* Signal that we should flip the video. */
+	int flip;
+
+};
+
+enum atmel_mpopfb_overlay_type {
+	ATMEL_MPOPFB_OVERLAY1 = 0,
+	ATMEL_MPOPFB_OVERLAY2 = 1,
+	ATMEL_MPOPFB_CURSOR = 2
+};
+
+struct atmel_mpopfb_overlay_info {
+	/* Position of the mpop overlay image
+	   in the image sent to the LCD. */
+	unsigned xpos;
+	unsigned ypos;
+	/* The size of the overlay image. */
+	unsigned xsize;
+	unsigned ysize;
+	/* Signal which overlay this info is for. */
+	enum atmel_mpopfb_overlay_type overlay;
+	/* Signal if the overlay is enabled. */
+	unsigned enabled;
+};
+
+struct atmel_mpopfb_overlay_palette_entry {
+	unsigned char alpha;
+	unsigned char red;
+	unsigned char green;
+	unsigned char blue;
+};
+
+struct atmel_mpopfb_cursor_palette_entry {
+	unsigned char:6;
+	unsigned char invert:1;
+	unsigned char visible:1;
+	unsigned char red;
+	unsigned char green;
+	unsigned char blue;
+};
+
+struct atmel_mpopfb_overlay_palette {
+	struct atmel_mpopfb_overlay_palette_entry entry[256];
+};
+
+struct atmel_mpopfb_cursor_palette {
+	struct atmel_mpopfb_cursor_palette_entry entry[4];
+};
+
+#define ATMEL_MPOP_FBIOPUT_BASEIMG_INFO        _IOW('x',0,struct atmel_mpopfb_baseimg_info)
+#define ATMEL_MPOP_FBIOGET_BASEIMG_INFO        _IOR('x',1,struct atmel_mpopfb_baseimg_info)
+#define ATMEL_MPOP_FBIOPUT_OVERLAY_INFO        _IOW('x',2,struct atmel_mpopfb_overlay_info)
+#define ATMEL_MPOP_FBIO_CONNECT_TO_LCDC        _IO( 'x',4)
+#define ATMEL_MPOP_FBIO_DISCONNECT_FROM_LCDC   _IO( 'x',5)
+#define ATMEL_MPOP_FBIOPUT_RGBCONV_COEFFS      _IOW('x',6,struct atmel_mpopfb_rgbconv_coeffs)
+#define ATMEL_MPOP_FBIOGET_RGBCONV_COEFFS      _IOR('x',7,struct atmel_mpopfb_rgbconv_coeffs)
+#define ATMEL_MPOP_FBIOPUT_OVERLAY_PALETTE     _IOW('x',8,struct atmel_mpopfb_overlay_palette)
+#define ATMEL_MPOP_FBIOGET_OVERLAY_PALETTE     _IOR('x',9,struct atmel_mpopfb_overlay_palette)
+#define ATMEL_MPOP_FBIOPUT_CURSOR_PALETTE      _IOW('x',10,struct atmel_mpopfb_cursor_palette)
+#define ATMEL_MPOP_FBIOGET_CURSOR_PALETTE      _IOR('x',11,struct atmel_mpopfb_cursor_palette)
+
+#define ATMEL_MPOP_RESIZE_FRAC_BITS 5
+#define ATMEL_MPOP_SCALE_FRAC_DIV(a,b)  ((((a) << ATMEL_MPOP_RESIZE_FRAC_BITS))/(b))
+#define ATMEL_MPOP_CALC_SCALE(from_res,to_res)  ATMEL_MPOP_SCALE_FRAC_DIV(from_res, to_res)
+
+#define ATMEL_MPOP_COEFF_FRAC_BITS 8
+
+#endif
diff -urN linux-2.6.28.2-0rig//include/linux/atmel_pdca.h linux-2.6.28.2/include/linux/atmel_pdca.h
--- linux-2.6.28.2-0rig//include/linux/atmel_pdca.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/include/linux/atmel_pdca.h	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,120 @@
+/*
+ * Driver for the Atmel PDCA Peripheral DMA Controller
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __ATMEL_PDCA_H
+#define __ATMEL_PDCA_H
+
+#include <linux/dmaengine.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+
+struct pdca_pdata {
+	unsigned int		nr_channels;
+};
+
+struct pdca_slave {
+	struct dma_slave	slave;
+	u8			tx_periph_id;
+	u8			rx_periph_id;
+};
+
+struct pdca_desc {
+	/* This controller does not support hardware descriptors */
+	struct scatterlist	*sg;
+	int			sg_len;
+	u8			reg_width;
+	u8			periph_id;
+
+	struct list_head	desc_node;
+	struct dma_async_tx_descriptor txd;
+};
+
+struct pdca_chan {
+	struct list_head	freelist;
+	struct list_head	queue;
+
+	spinlock_t		lock;
+	void __iomem		*regs;
+
+	struct scatterlist	*cur_sg;
+	struct scatterlist	*next_sg;
+
+	struct tasklet_struct	tasklet;
+
+	dma_cookie_t		completed;
+	struct dma_chan		chan;
+	struct pdca_slave	*pslave;
+	unsigned int		descs_allocated;
+	bool			enabled;
+};
+
+struct pdca_dev {
+	struct clk		*hclk;
+	struct clk		*pclk;
+	struct dma_device	dma;
+	void __iomem		*regs;
+
+	struct pdca_chan	chan[];
+};
+
+static inline struct pdca_slave *dma_to_pdca_slave(struct dma_slave *slave)
+{
+	return container_of(slave, struct pdca_slave, slave);
+}
+
+static inline struct pdca_desc *txd_to_pdca_desc(
+		struct dma_async_tx_descriptor *txd)
+{
+	return container_of(txd, struct pdca_desc, txd);
+}
+
+static inline struct pdca_chan *dma_to_pdca_chan(struct dma_chan *chan)
+{
+	return container_of(chan, struct pdca_chan, chan);
+}
+
+static inline struct pdca_dev *dma_to_pdca_dev(struct dma_device *dma)
+{
+	return container_of(dma, struct pdca_dev, dma);
+}
+
+/* PDCA per-channel register definitions */
+#define PDCA_MAR		0x0000	/* Memory Address */
+#define PDCA_PSR		0x0004	/* Peripheral Select */
+#define PDCA_TCR		0x0008	/* Transfer Counter */
+#define PDCA_MARR		0x000c	/* Memory Address Reload */
+#define PDCA_TCRR		0x0010	/* Transfer Counter Reload */
+#define PDCA_CR			0x0014	/* Control */
+# define PDCA_CR_TEN		(  1 <<  0)	/* Transfer Enable */
+# define PDCA_CR_TDIS		(  1 <<  1)	/* Transfer Disable */
+# define PDCA_CR_ECLR		(  1 <<  8)	/* Error Clear */
+#define PDCA_MR			0x0018	/* Mode */
+# define PDCA_SIZE_BYTE		(  0 <<  0)	/* 8 bits per transfer */
+# define PDCA_SIZE_HWORD	(  1 <<  0)	/* 16 bits per transfer */
+# define PDCA_SIZE_WORD		(  2 <<  0)	/* 32 bits per transfer */
+#define PDCA_SR			0x001c	/* Status */
+# define PDCA_SR_TEN		(  1 <<  0)	/* Transfer Enabled */
+#define PDCA_IER		0x0020	/* Interrupt Enable */
+#define PDCA_IDR		0x0024	/* Interrupt Disable */
+#define PDCA_IMR		0x0028	/* Interrupt Mask */
+#define PDCA_ISR		0x002c	/* Interrupt Status */
+# define PDCA_RCZ		(  1 <<  0)	/* Reload Counter Zero */
+# define PDCA_TRC		(  1 <<  1)	/* Transfer Complete */
+# define PDCA_TERR		(  1 <<  2)	/* Transfer Error */
+
+/* Address space occupied by one channel */
+#define PDCA_CHAN_SIZE		0x40
+
+#define pdca_readl(base, reg)				\
+	__raw_readl((base) + PDCA_##reg)
+#define pdca_writel(base, reg, value)			\
+	__raw_writel((value), (base) + PDCA_##reg)
+
+#endif /* __ATMEL_PDCA_H */
diff -urN linux-2.6.28.2-0rig//include/linux/Kbuild linux-2.6.28.2/include/linux/Kbuild
--- linux-2.6.28.2-0rig//include/linux/Kbuild	2009-01-29 08:39:39.000000000 +0100
+++ linux-2.6.28.2/include/linux/Kbuild	2009-01-29 08:52:50.000000000 +0100
@@ -23,6 +23,7 @@
 header-y += atmarp.h
 header-y += atmbr2684.h
 header-y += atmclip.h
+header-y += atmel_mpopfb.h
 header-y += atm_eni.h
 header-y += atm_he.h
 header-y += atm_idt77105.h
diff -urN linux-2.6.28.2-0rig//include/linux/spi/atmel_spi.h linux-2.6.28.2/include/linux/spi/atmel_spi.h
--- linux-2.6.28.2-0rig//include/linux/spi/atmel_spi.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/include/linux/spi/atmel_spi.h	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,20 @@
+/*
+ * Driver for Atmel AT32 and AT91 SPI Controllers
+ *
+ * Copyright (C) 2008 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __LINUX_SPI_ATMEL_SPI_H
+#define __LINUX_SPI_ATMEL_SPI_H
+
+struct atmel_spi_pdata {
+#ifndef CONFIG_SPI_ATMEL_HAVE_PDC
+	struct dma_slave	*rx_dma_slave;
+	struct dma_slave	*tx_dma_slave;
+#endif
+};
+
+#endif /* __LINUX_SPI_ATMEL_SPI_H */
diff -urN linux-2.6.28.2-0rig//include/video/atmel_mpop.h linux-2.6.28.2/include/video/atmel_mpop.h
--- linux-2.6.28.2-0rig//include/video/atmel_mpop.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.28.2/include/video/atmel_mpop.h	2009-01-29 08:52:50.000000000 +0100
@@ -0,0 +1,820 @@
+/*
+ *  Header file for AT32 MPOP Controller
+ *
+ *  Data structure and register user interface
+ *
+ *  Copyright (C) 2007 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
+ */
+#ifndef __ATMEL_MPOP_H__
+#define __ATMEL_MPOP_H__
+
+#include <linux/atmel_mpopfb.h>
+
+/* MPOP Controller info data structure */
+struct atmel_mpopfb_info {
+	spinlock_t lock;
+	struct fb_info *info;
+	void __iomem *mmio;
+	unsigned long irq_base;
+	void *slave_base;
+
+	struct platform_device *pdev;
+	struct platform_device *lcdc_pdev;
+	struct clk *mpop_hclk;
+	struct clk *mpop_pclk;
+	unsigned int running;
+	unsigned int connected_to_lcdc;
+	unsigned long lcdc_old_smem_start;
+	unsigned long lcdc_old_bits_per_pixel;
+	struct atmel_mpopfb_baseimg_info baseimg_info;
+	struct atmel_mpopfb_overlay_info overlay_info[3];
+	struct atmel_mpopfb_rgbconv_coeffs rgbconv_coeffs;
+};
+
+/* TODO! Clean up these defines.... */
+#define ATMEL_MPOP_B                                                 0
+#define ATMEL_MPOP_B1                                                0
+#define ATMEL_MPOP_B1_MASK                                  0x00000fff
+#define ATMEL_MPOP_B1_OFFSET                                         0
+#define ATMEL_MPOP_B1_SIZE                                          12
+#define ATMEL_MPOP_B2                                               12
+#define ATMEL_MPOP_B2B1                                     0x00000024
+#define ATMEL_MPOP_B2B1_B1                                           0
+#define ATMEL_MPOP_B2B1_B1_MASK                             0x00000fff
+#define ATMEL_MPOP_B2B1_B1_OFFSET                                    0
+#define ATMEL_MPOP_B2B1_B1_SIZE                                     12
+#define ATMEL_MPOP_B2B1_B2                                          12
+#define ATMEL_MPOP_B2B1_B2_MASK                             0x00fff000
+#define ATMEL_MPOP_B2B1_B2_OFFSET                                   12
+#define ATMEL_MPOP_B2B1_B2_SIZE                                     12
+#define ATMEL_MPOP_B2_MASK                                  0x00fff000
+#define ATMEL_MPOP_B2_OFFSET                                        12
+#define ATMEL_MPOP_B2_SIZE                                          12
+#define ATMEL_MPOP_B3                                                0
+#define ATMEL_MPOP_B3_MASK                                  0x00000fff
+#define ATMEL_MPOP_B3_OFFSET                                         0
+#define ATMEL_MPOP_B3_SIZE                                          12
+#define ATMEL_MPOP_B4                                               12
+#define ATMEL_MPOP_B4B3                                     0x00000028
+#define ATMEL_MPOP_B4B3_B3                                           0
+#define ATMEL_MPOP_B4B3_B3_MASK                             0x00000fff
+#define ATMEL_MPOP_B4B3_B3_OFFSET                                    0
+#define ATMEL_MPOP_B4B3_B3_SIZE                                     12
+#define ATMEL_MPOP_B4B3_B4                                          12
+#define ATMEL_MPOP_B4B3_B4_MASK                             0xfffff000
+#define ATMEL_MPOP_B4B3_B4_OFFSET                                   12
+#define ATMEL_MPOP_B4B3_B4_SIZE                                     20
+#define ATMEL_MPOP_B4_MASK                                  0xfffff000
+#define ATMEL_MPOP_B4_OFFSET                                        12
+#define ATMEL_MPOP_B4_SIZE                                          20
+#define ATMEL_MPOP_BGCOLOR                                  0x00000090
+#define ATMEL_MPOP_BGCOLOR_BGCOLOR                                   0
+#define ATMEL_MPOP_BGCOLOR_BGCOLOR_MASK                     0xffffffff
+#define ATMEL_MPOP_BGCOLOR_BGCOLOR_OFFSET                            0
+#define ATMEL_MPOP_BGCOLOR_BGCOLOR_SIZE                             32
+#define ATMEL_MPOP_BGCOLOR_MASK                             0xffffffff
+#define ATMEL_MPOP_BGCOLOR_OFFSET                                    0
+#define ATMEL_MPOP_BGCOLOR_SIZE                                     32
+#define ATMEL_MPOP_BGR                                               6
+#define ATMEL_MPOP_BGR_MASK                                 0x00000040
+#define ATMEL_MPOP_BGR_OFFSET                                        6
+#define ATMEL_MPOP_BGR_SIZE                                          1
+#define ATMEL_MPOP_B_MASK                                   0x000000ff
+#define ATMEL_MPOP_B_OFFSET                                          0
+#define ATMEL_MPOP_B_SIZE                                            8
+#define ATMEL_MPOP_CACHEDIS                                          8
+#define ATMEL_MPOP_CACHEDIS_MASK                            0x00000100
+#define ATMEL_MPOP_CACHEDIS_OFFSET                                   8
+#define ATMEL_MPOP_CACHEDIS_SIZE                                     1
+#define ATMEL_MPOP_CR                                       0x00000000
+#define ATMEL_MPOP_CR_CACHEDIS                                       8
+#define ATMEL_MPOP_CR_CACHEDIS_MASK                         0x00000100
+#define ATMEL_MPOP_CR_CACHEDIS_OFFSET                                8
+#define ATMEL_MPOP_CR_CACHEDIS_SIZE                                  1
+#define ATMEL_MPOP_CR_EN                                             0
+#define ATMEL_MPOP_CR_EN_MASK                               0x00000001
+#define ATMEL_MPOP_CR_EN_OFFSET                                      0
+#define ATMEL_MPOP_CR_EN_SIZE                                        1
+#define ATMEL_MPOP_CR_OUT_BGR                                        3
+#define ATMEL_MPOP_CR_OUT_BGR_MASK                          0x00000008
+#define ATMEL_MPOP_CR_OUT_BGR_OFFSET                                 3
+#define ATMEL_MPOP_CR_OUT_BGR_SIZE                                   1
+#define ATMEL_MPOP_CR_OUT_CTRL                                       2
+#define ATMEL_MPOP_CR_OUT_CTRL_MASK                         0x00000004
+#define ATMEL_MPOP_CR_OUT_CTRL_OFFSET                                2
+#define ATMEL_MPOP_CR_OUT_CTRL_SIZE                                  1
+#define ATMEL_MPOP_CR_START                                          1
+#define ATMEL_MPOP_CR_START_MASK                            0x00000002
+#define ATMEL_MPOP_CR_START_OFFSET                                   1
+#define ATMEL_MPOP_CR_START_SIZE                                     1
+#define ATMEL_MPOP_CURSOREN                                          0
+#define ATMEL_MPOP_CURSOREN_MASK                            0x00000001
+#define ATMEL_MPOP_CURSOREN_OFFSET                                   0
+#define ATMEL_MPOP_CURSOREN_SIZE                                     1
+#define ATMEL_MPOP_CURSOR_P0                                0x00000080
+#define ATMEL_MPOP_CURSOR_P0_B                                       0
+#define ATMEL_MPOP_CURSOR_P0_B_MASK                         0x000000ff
+#define ATMEL_MPOP_CURSOR_P0_B_OFFSET                                0
+#define ATMEL_MPOP_CURSOR_P0_B_SIZE                                  8
+#define ATMEL_MPOP_CURSOR_P0_G                                       8
+#define ATMEL_MPOP_CURSOR_P0_G_MASK                         0x0000ff00
+#define ATMEL_MPOP_CURSOR_P0_G_OFFSET                                8
+#define ATMEL_MPOP_CURSOR_P0_G_SIZE                                  8
+#define ATMEL_MPOP_CURSOR_P0_INVERT                                 25
+#define ATMEL_MPOP_CURSOR_P0_INVERT_MASK                    0x02000000
+#define ATMEL_MPOP_CURSOR_P0_INVERT_OFFSET                          25
+#define ATMEL_MPOP_CURSOR_P0_INVERT_SIZE                             1
+#define ATMEL_MPOP_CURSOR_P0_R                                      16
+#define ATMEL_MPOP_CURSOR_P0_R_MASK                         0x00ff0000
+#define ATMEL_MPOP_CURSOR_P0_R_OFFSET                               16
+#define ATMEL_MPOP_CURSOR_P0_R_SIZE                                  8
+#define ATMEL_MPOP_CURSOR_P0_VISIBLE                                24
+#define ATMEL_MPOP_CURSOR_P0_VISIBLE_MASK                   0x01000000
+#define ATMEL_MPOP_CURSOR_P0_VISIBLE_OFFSET                         24
+#define ATMEL_MPOP_CURSOR_P0_VISIBLE_SIZE                            1
+#define ATMEL_MPOP_CURSOR_P1                                0x00000084
+#define ATMEL_MPOP_CURSOR_P1_B                                       0
+#define ATMEL_MPOP_CURSOR_P1_B_MASK                         0x000000ff
+#define ATMEL_MPOP_CURSOR_P1_B_OFFSET                                0
+#define ATMEL_MPOP_CURSOR_P1_B_SIZE                                  8
+#define ATMEL_MPOP_CURSOR_P1_G                                       8
+#define ATMEL_MPOP_CURSOR_P1_G_MASK                         0x0000ff00
+#define ATMEL_MPOP_CURSOR_P1_G_OFFSET                                8
+#define ATMEL_MPOP_CURSOR_P1_G_SIZE                                  8
+#define ATMEL_MPOP_CURSOR_P1_INVERT                                 25
+#define ATMEL_MPOP_CURSOR_P1_INVERT_MASK                    0x02000000
+#define ATMEL_MPOP_CURSOR_P1_INVERT_OFFSET                          25
+#define ATMEL_MPOP_CURSOR_P1_INVERT_SIZE                             1
+#define ATMEL_MPOP_CURSOR_P1_R                                      16
+#define ATMEL_MPOP_CURSOR_P1_R_MASK                         0x00ff0000
+#define ATMEL_MPOP_CURSOR_P1_R_OFFSET                               16
+#define ATMEL_MPOP_CURSOR_P1_R_SIZE                                  8
+#define ATMEL_MPOP_CURSOR_P1_VISIBLE                                24
+#define ATMEL_MPOP_CURSOR_P1_VISIBLE_MASK                   0x01000000
+#define ATMEL_MPOP_CURSOR_P1_VISIBLE_OFFSET                         24
+#define ATMEL_MPOP_CURSOR_P1_VISIBLE_SIZE                            1
+#define ATMEL_MPOP_CURSOR_P2                                0x00000088
+#define ATMEL_MPOP_CURSOR_P2_B                                       0
+#define ATMEL_MPOP_CURSOR_P2_B_MASK                         0x000000ff
+#define ATMEL_MPOP_CURSOR_P2_B_OFFSET                                0
+#define ATMEL_MPOP_CURSOR_P2_B_SIZE                                  8
+#define ATMEL_MPOP_CURSOR_P2_G                                       8
+#define ATMEL_MPOP_CURSOR_P2_G_MASK                         0x0000ff00
+#define ATMEL_MPOP_CURSOR_P2_G_OFFSET                                8
+#define ATMEL_MPOP_CURSOR_P2_G_SIZE                                  8
+#define ATMEL_MPOP_CURSOR_P2_INVERT                                 25
+#define ATMEL_MPOP_CURSOR_P2_INVERT_MASK                    0x02000000
+#define ATMEL_MPOP_CURSOR_P2_INVERT_OFFSET                          25
+#define ATMEL_MPOP_CURSOR_P2_INVERT_SIZE                             1
+#define ATMEL_MPOP_CURSOR_P2_R                                      16
+#define ATMEL_MPOP_CURSOR_P2_R_MASK                         0x00ff0000
+#define ATMEL_MPOP_CURSOR_P2_R_OFFSET                               16
+#define ATMEL_MPOP_CURSOR_P2_R_SIZE                                  8
+#define ATMEL_MPOP_CURSOR_P2_VISIBLE                                24
+#define ATMEL_MPOP_CURSOR_P2_VISIBLE_MASK                   0x01000000
+#define ATMEL_MPOP_CURSOR_P2_VISIBLE_OFFSET                         24
+#define ATMEL_MPOP_CURSOR_P2_VISIBLE_SIZE                            1
+#define ATMEL_MPOP_CURSOR_P3                                0x0000008c
+#define ATMEL_MPOP_CURSOR_P3_B                                       0
+#define ATMEL_MPOP_CURSOR_P3_B_MASK                         0x000000ff
+#define ATMEL_MPOP_CURSOR_P3_B_OFFSET                                0
+#define ATMEL_MPOP_CURSOR_P3_B_SIZE                                  8
+#define ATMEL_MPOP_CURSOR_P3_G                                       8
+#define ATMEL_MPOP_CURSOR_P3_G_MASK                         0x0000ff00
+#define ATMEL_MPOP_CURSOR_P3_G_OFFSET                                8
+#define ATMEL_MPOP_CURSOR_P3_G_SIZE                                  8
+#define ATMEL_MPOP_CURSOR_P3_INVERT                                 25
+#define ATMEL_MPOP_CURSOR_P3_INVERT_MASK                    0x02000000
+#define ATMEL_MPOP_CURSOR_P3_INVERT_OFFSET                          25
+#define ATMEL_MPOP_CURSOR_P3_INVERT_SIZE                             1
+#define ATMEL_MPOP_CURSOR_P3_R                                      16
+#define ATMEL_MPOP_CURSOR_P3_R_MASK                         0x00ff0000
+#define ATMEL_MPOP_CURSOR_P3_R_OFFSET                               16
+#define ATMEL_MPOP_CURSOR_P3_R_SIZE                                  8
+#define ATMEL_MPOP_CURSOR_P3_VISIBLE                                24
+#define ATMEL_MPOP_CURSOR_P3_VISIBLE_MASK                   0x01000000
+#define ATMEL_MPOP_CURSOR_P3_VISIBLE_OFFSET                         24
+#define ATMEL_MPOP_CURSOR_P3_VISIBLE_SIZE                            1
+#define ATMEL_MPOP_CURSOR_POS                               0x00000058
+#define ATMEL_MPOP_CURSOR_POS_CURSOR_POS_X                          11
+#define ATMEL_MPOP_CURSOR_POS_CURSOR_POS_X_MASK             0x003ff800
+#define ATMEL_MPOP_CURSOR_POS_CURSOR_POS_X_OFFSET                   11
+#define ATMEL_MPOP_CURSOR_POS_CURSOR_POS_X_SIZE                     11
+#define ATMEL_MPOP_CURSOR_POS_CURSOR_POS_Y                           0
+#define ATMEL_MPOP_CURSOR_POS_CURSOR_POS_Y_MASK             0x000007ff
+#define ATMEL_MPOP_CURSOR_POS_CURSOR_POS_Y_OFFSET                    0
+#define ATMEL_MPOP_CURSOR_POS_CURSOR_POS_Y_SIZE                     11
+#define ATMEL_MPOP_CURSOR_POS_X                                     11
+#define ATMEL_MPOP_CURSOR_POS_X_MASK                        0x003ff800
+#define ATMEL_MPOP_CURSOR_POS_X_OFFSET                              11
+#define ATMEL_MPOP_CURSOR_POS_X_SIZE                                11
+#define ATMEL_MPOP_CURSOR_POS_Y                                      0
+#define ATMEL_MPOP_CURSOR_POS_Y_MASK                        0x000007ff
+#define ATMEL_MPOP_CURSOR_POS_Y_OFFSET                               0
+#define ATMEL_MPOP_CURSOR_POS_Y_SIZE                                11
+#define ATMEL_MPOP_CURSOR_SAR                               0x00000048
+#define ATMEL_MPOP_CURSOR_SAR_CURSOR_SAR                             0
+#define ATMEL_MPOP_CURSOR_SAR_CURSOR_SAR_MASK               0xffffffff
+#define ATMEL_MPOP_CURSOR_SAR_CURSOR_SAR_OFFSET                      0
+#define ATMEL_MPOP_CURSOR_SAR_CURSOR_SAR_SIZE                       32
+#define ATMEL_MPOP_CURSOR_SAR_MASK                          0xffffffff
+#define ATMEL_MPOP_CURSOR_SAR_OFFSET                                 0
+#define ATMEL_MPOP_CURSOR_SAR_SIZE                                  32
+#define ATMEL_MPOP_CURSOR_SIZE                              0x0000006c
+#define ATMEL_MPOP_CURSOR_SIZE_CURSOR_SIZE_X                        11
+#define ATMEL_MPOP_CURSOR_SIZE_CURSOR_SIZE_X_MASK           0x003ff800
+#define ATMEL_MPOP_CURSOR_SIZE_CURSOR_SIZE_X_OFFSET                 11
+#define ATMEL_MPOP_CURSOR_SIZE_CURSOR_SIZE_X_SIZE                   11
+#define ATMEL_MPOP_CURSOR_SIZE_CURSOR_SIZE_Y                         0
+#define ATMEL_MPOP_CURSOR_SIZE_CURSOR_SIZE_Y_MASK           0x000007ff
+#define ATMEL_MPOP_CURSOR_SIZE_CURSOR_SIZE_Y_OFFSET                  0
+#define ATMEL_MPOP_CURSOR_SIZE_CURSOR_SIZE_Y_SIZE                   11
+#define ATMEL_MPOP_CURSOR_SIZE_X                                    11
+#define ATMEL_MPOP_CURSOR_SIZE_X_MASK                       0x003ff800
+#define ATMEL_MPOP_CURSOR_SIZE_X_OFFSET                             11
+#define ATMEL_MPOP_CURSOR_SIZE_X_SIZE                               11
+#define ATMEL_MPOP_CURSOR_SIZE_Y                                     0
+#define ATMEL_MPOP_CURSOR_SIZE_Y_MASK                       0x000007ff
+#define ATMEL_MPOP_CURSOR_SIZE_Y_OFFSET                              0
+#define ATMEL_MPOP_CURSOR_SIZE_Y_SIZE                               11
+#define ATMEL_MPOP_CURSOR_WTC                               0x0000007c
+#define ATMEL_MPOP_CURSOR_WTC_CURSOR_WTC                             0
+#define ATMEL_MPOP_CURSOR_WTC_CURSOR_WTC_MASK               0xffffffff
+#define ATMEL_MPOP_CURSOR_WTC_CURSOR_WTC_OFFSET                      0
+#define ATMEL_MPOP_CURSOR_WTC_CURSOR_WTC_SIZE                       32
+#define ATMEL_MPOP_CURSOR_WTC_MASK                          0xffffffff
+#define ATMEL_MPOP_CURSOR_WTC_OFFSET                                 0
+#define ATMEL_MPOP_CURSOR_WTC_SIZE                                  32
+#define ATMEL_MPOP_DISP_MAX_COORD                           0x00000010
+#define ATMEL_MPOP_DISP_MAX_COORD_DISP_MAX_COORD_X                  11
+#define ATMEL_MPOP_DISP_MAX_COORD_DISP_MAX_COORD_X_MASK     0x003ff800
+#define ATMEL_MPOP_DISP_MAX_COORD_DISP_MAX_COORD_X_OFFSET           11
+#define ATMEL_MPOP_DISP_MAX_COORD_DISP_MAX_COORD_X_SIZE             11
+#define ATMEL_MPOP_DISP_MAX_COORD_DISP_MAX_COORD_Y                   0
+#define ATMEL_MPOP_DISP_MAX_COORD_DISP_MAX_COORD_Y_MASK     0x000007ff
+#define ATMEL_MPOP_DISP_MAX_COORD_DISP_MAX_COORD_Y_OFFSET            0
+#define ATMEL_MPOP_DISP_MAX_COORD_DISP_MAX_COORD_Y_SIZE             11
+#define ATMEL_MPOP_DISP_MAX_COORD_X                                 11
+#define ATMEL_MPOP_DISP_MAX_COORD_X_MASK                    0x003ff800
+#define ATMEL_MPOP_DISP_MAX_COORD_X_OFFSET                          11
+#define ATMEL_MPOP_DISP_MAX_COORD_X_SIZE                            11
+#define ATMEL_MPOP_DISP_MAX_COORD_Y                                  0
+#define ATMEL_MPOP_DISP_MAX_COORD_Y_MASK                    0x000007ff
+#define ATMEL_MPOP_DISP_MAX_COORD_Y_OFFSET                           0
+#define ATMEL_MPOP_DISP_MAX_COORD_Y_SIZE                            11
+#define ATMEL_MPOP_EN                                                0
+#define ATMEL_MPOP_EN_MASK                                  0x00000001
+#define ATMEL_MPOP_EN_OFFSET                                         0
+#define ATMEL_MPOP_EN_SIZE                                           1
+#define ATMEL_MPOP_EOP                                               3
+#define ATMEL_MPOP_EOP_MASK                                 0x00000008
+#define ATMEL_MPOP_EOP_OFFSET                                        3
+#define ATMEL_MPOP_EOP_SIZE                                          1
+#define ATMEL_MPOP_G                                                 8
+#define ATMEL_MPOP_G1                                                0
+#define ATMEL_MPOP_G1_MASK                                  0x00000fff
+#define ATMEL_MPOP_G1_OFFSET                                         0
+#define ATMEL_MPOP_G1_SIZE                                          12
+#define ATMEL_MPOP_G2                                               12
+#define ATMEL_MPOP_G2G1                                     0x0000001c
+#define ATMEL_MPOP_G2G1_G1                                           0
+#define ATMEL_MPOP_G2G1_G1_MASK                             0x00000fff
+#define ATMEL_MPOP_G2G1_G1_OFFSET                                    0
+#define ATMEL_MPOP_G2G1_G1_SIZE                                     12
+#define ATMEL_MPOP_G2G1_G2                                          12
+#define ATMEL_MPOP_G2G1_G2_MASK                             0x00fff000
+#define ATMEL_MPOP_G2G1_G2_OFFSET                                   12
+#define ATMEL_MPOP_G2G1_G2_SIZE                                     12
+#define ATMEL_MPOP_G2_MASK                                  0x00fff000
+#define ATMEL_MPOP_G2_OFFSET                                        12
+#define ATMEL_MPOP_G2_SIZE                                          12
+#define ATMEL_MPOP_G3                                                0
+#define ATMEL_MPOP_G3_MASK                                  0x00000fff
+#define ATMEL_MPOP_G3_OFFSET                                         0
+#define ATMEL_MPOP_G3_SIZE                                          12
+#define ATMEL_MPOP_G4                                               12
+#define ATMEL_MPOP_G4G3                                     0x00000020
+#define ATMEL_MPOP_G4G3_G3                                           0
+#define ATMEL_MPOP_G4G3_G3_MASK                             0x00000fff
+#define ATMEL_MPOP_G4G3_G3_OFFSET                                    0
+#define ATMEL_MPOP_G4G3_G3_SIZE                                     12
+#define ATMEL_MPOP_G4G3_G4                                          12
+#define ATMEL_MPOP_G4G3_G4_MASK                             0xfffff000
+#define ATMEL_MPOP_G4G3_G4_OFFSET                                   12
+#define ATMEL_MPOP_G4G3_G4_SIZE                                     20
+#define ATMEL_MPOP_G4_MASK                                  0xfffff000
+#define ATMEL_MPOP_G4_OFFSET                                        12
+#define ATMEL_MPOP_G4_SIZE                                          20
+#define ATMEL_MPOP_G_MASK                                   0x0000ff00
+#define ATMEL_MPOP_G_OFFSET                                          8
+#define ATMEL_MPOP_G_SIZE                                            8
+#define ATMEL_MPOP_INTCLEAR                                 0x000000b0
+#define ATMEL_MPOP_INTCLEAR_EOP                                      3
+#define ATMEL_MPOP_INTCLEAR_EOP_MASK                        0x00000008
+#define ATMEL_MPOP_INTCLEAR_EOP_OFFSET                               3
+#define ATMEL_MPOP_INTCLEAR_EOP_SIZE                                 1
+#define ATMEL_MPOP_INTCLEAR_OUT                                      2
+#define ATMEL_MPOP_INTCLEAR_OUT_MASK                        0x00000004
+#define ATMEL_MPOP_INTCLEAR_OUT_OFFSET                               2
+#define ATMEL_MPOP_INTCLEAR_OUT_SIZE                                 1
+#define ATMEL_MPOP_INTCLEAR_OVERLAY                                  1
+#define ATMEL_MPOP_INTCLEAR_OVERLAY_MASK                    0x00000002
+#define ATMEL_MPOP_INTCLEAR_OVERLAY_OFFSET                           1
+#define ATMEL_MPOP_INTCLEAR_OVERLAY_SIZE                             1
+#define ATMEL_MPOP_INTCLEAR_SOP                                      4
+#define ATMEL_MPOP_INTCLEAR_SOP_MASK                        0x00000010
+#define ATMEL_MPOP_INTCLEAR_SOP_OFFSET                               4
+#define ATMEL_MPOP_INTCLEAR_SOP_SIZE                                 1
+#define ATMEL_MPOP_INTCLEAR_YUV                                      0
+#define ATMEL_MPOP_INTCLEAR_YUV_MASK                        0x00000001
+#define ATMEL_MPOP_INTCLEAR_YUV_OFFSET                               0
+#define ATMEL_MPOP_INTCLEAR_YUV_SIZE                                 1
+#define ATMEL_MPOP_INTDIS                                   0x000000a4
+#define ATMEL_MPOP_INTDIS_EOP                                        3
+#define ATMEL_MPOP_INTDIS_EOP_MASK                          0x00000008
+#define ATMEL_MPOP_INTDIS_EOP_OFFSET                                 3
+#define ATMEL_MPOP_INTDIS_EOP_SIZE                                   1
+#define ATMEL_MPOP_INTDIS_OUT                                        2
+#define ATMEL_MPOP_INTDIS_OUT_MASK                          0x00000004
+#define ATMEL_MPOP_INTDIS_OUT_OFFSET                                 2
+#define ATMEL_MPOP_INTDIS_OUT_SIZE                                   1
+#define ATMEL_MPOP_INTDIS_OVERLAY                                    1
+#define ATMEL_MPOP_INTDIS_OVERLAY_MASK                      0x00000002
+#define ATMEL_MPOP_INTDIS_OVERLAY_OFFSET                             1
+#define ATMEL_MPOP_INTDIS_OVERLAY_SIZE                               1
+#define ATMEL_MPOP_INTDIS_SOP                                        4
+#define ATMEL_MPOP_INTDIS_SOP_MASK                          0x00000010
+#define ATMEL_MPOP_INTDIS_SOP_OFFSET                                 4
+#define ATMEL_MPOP_INTDIS_SOP_SIZE                                   1
+#define ATMEL_MPOP_INTDIS_YUV                                        0
+#define ATMEL_MPOP_INTDIS_YUV_MASK                          0x00000001
+#define ATMEL_MPOP_INTDIS_YUV_OFFSET                                 0
+#define ATMEL_MPOP_INTDIS_YUV_SIZE                                   1
+#define ATMEL_MPOP_INTEN                                    0x000000a0
+#define ATMEL_MPOP_INTEN_EOP                                         3
+#define ATMEL_MPOP_INTEN_EOP_MASK                           0x00000008
+#define ATMEL_MPOP_INTEN_EOP_OFFSET                                  3
+#define ATMEL_MPOP_INTEN_EOP_SIZE                                    1
+#define ATMEL_MPOP_INTEN_OUT                                         2
+#define ATMEL_MPOP_INTEN_OUT_MASK                           0x00000004
+#define ATMEL_MPOP_INTEN_OUT_OFFSET                                  2
+#define ATMEL_MPOP_INTEN_OUT_SIZE                                    1
+#define ATMEL_MPOP_INTEN_OVERLAY                                     1
+#define ATMEL_MPOP_INTEN_OVERLAY_MASK                       0x00000002
+#define ATMEL_MPOP_INTEN_OVERLAY_OFFSET                              1
+#define ATMEL_MPOP_INTEN_OVERLAY_SIZE                                1
+#define ATMEL_MPOP_INTEN_SOP                                         4
+#define ATMEL_MPOP_INTEN_SOP_MASK                           0x00000010
+#define ATMEL_MPOP_INTEN_SOP_OFFSET                                  4
+#define ATMEL_MPOP_INTEN_SOP_SIZE                                    1
+#define ATMEL_MPOP_INTEN_YUV                                         0
+#define ATMEL_MPOP_INTEN_YUV_MASK                           0x00000001
+#define ATMEL_MPOP_INTEN_YUV_OFFSET                                  0
+#define ATMEL_MPOP_INTEN_YUV_SIZE                                    1
+#define ATMEL_MPOP_INTMASK                                  0x000000a8
+#define ATMEL_MPOP_INTMASK_EOP                                       3
+#define ATMEL_MPOP_INTMASK_EOP_MASK                         0x00000008
+#define ATMEL_MPOP_INTMASK_EOP_OFFSET                                3
+#define ATMEL_MPOP_INTMASK_EOP_SIZE                                  1
+#define ATMEL_MPOP_INTMASK_OUT                                       2
+#define ATMEL_MPOP_INTMASK_OUT_MASK                         0x00000004
+#define ATMEL_MPOP_INTMASK_OUT_OFFSET                                2
+#define ATMEL_MPOP_INTMASK_OUT_SIZE                                  1
+#define ATMEL_MPOP_INTMASK_OVERLAY                                   1
+#define ATMEL_MPOP_INTMASK_OVERLAY_MASK                     0x00000002
+#define ATMEL_MPOP_INTMASK_OVERLAY_OFFSET                            1
+#define ATMEL_MPOP_INTMASK_OVERLAY_SIZE                              1
+#define ATMEL_MPOP_INTMASK_SOP                                       4
+#define ATMEL_MPOP_INTMASK_SOP_MASK                         0x00000010
+#define ATMEL_MPOP_INTMASK_SOP_OFFSET                                4
+#define ATMEL_MPOP_INTMASK_SOP_SIZE                                  1
+#define ATMEL_MPOP_INTMASK_YUV                                       0
+#define ATMEL_MPOP_INTMASK_YUV_MASK                         0x00000001
+#define ATMEL_MPOP_INTMASK_YUV_OFFSET                                0
+#define ATMEL_MPOP_INTMASK_YUV_SIZE                                  1
+#define ATMEL_MPOP_INTSTATUS                                0x000000ac
+#define ATMEL_MPOP_INTSTATUS_EOP                                     3
+#define ATMEL_MPOP_INTSTATUS_EOP_MASK                       0x00000008
+#define ATMEL_MPOP_INTSTATUS_EOP_OFFSET                              3
+#define ATMEL_MPOP_INTSTATUS_EOP_SIZE                                1
+#define ATMEL_MPOP_INTSTATUS_OUT                                     2
+#define ATMEL_MPOP_INTSTATUS_OUT_MASK                       0x00000004
+#define ATMEL_MPOP_INTSTATUS_OUT_OFFSET                              2
+#define ATMEL_MPOP_INTSTATUS_OUT_SIZE                                1
+#define ATMEL_MPOP_INTSTATUS_OVERLAY                                 1
+#define ATMEL_MPOP_INTSTATUS_OVERLAY_MASK                   0x00000002
+#define ATMEL_MPOP_INTSTATUS_OVERLAY_OFFSET                          1
+#define ATMEL_MPOP_INTSTATUS_OVERLAY_SIZE                            1
+#define ATMEL_MPOP_INTSTATUS_SOP                                     4
+#define ATMEL_MPOP_INTSTATUS_SOP_MASK                       0x00000010
+#define ATMEL_MPOP_INTSTATUS_SOP_OFFSET                              4
+#define ATMEL_MPOP_INTSTATUS_SOP_SIZE                                1
+#define ATMEL_MPOP_INTSTATUS_YUV                                     0
+#define ATMEL_MPOP_INTSTATUS_YUV_MASK                       0x00000001
+#define ATMEL_MPOP_INTSTATUS_YUV_OFFSET                              0
+#define ATMEL_MPOP_INTSTATUS_YUV_SIZE                                1
+#define ATMEL_MPOP_INVERT                                           25
+#define ATMEL_MPOP_INVERT_MASK                              0x02000000
+#define ATMEL_MPOP_INVERT_OFFSET                                    25
+#define ATMEL_MPOP_INVERT_SIZE                                       1
+#define ATMEL_MPOP_MSTR_PTR                                 0x0000000c
+#define ATMEL_MPOP_MSTR_PTR_MASK                            0xffffffff
+#define ATMEL_MPOP_MSTR_PTR_MSTR_PTR                                 0
+#define ATMEL_MPOP_MSTR_PTR_MSTR_PTR_MASK                   0xffffffff
+#define ATMEL_MPOP_MSTR_PTR_MSTR_PTR_OFFSET                          0
+#define ATMEL_MPOP_MSTR_PTR_MSTR_PTR_SIZE                           32
+#define ATMEL_MPOP_MSTR_PTR_OFFSET                                   0
+#define ATMEL_MPOP_MSTR_PTR_SIZE                                    32
+#define ATMEL_MPOP_O1EN                                              1
+#define ATMEL_MPOP_O1EN_MASK                                0x00000002
+#define ATMEL_MPOP_O1EN_OFFSET                                       1
+#define ATMEL_MPOP_O1EN_SIZE                                         1
+#define ATMEL_MPOP_O1_POS                                   0x00000050
+#define ATMEL_MPOP_O1_POS_O1_POS_X                                  11
+#define ATMEL_MPOP_O1_POS_O1_POS_X_MASK                     0x003ff800
+#define ATMEL_MPOP_O1_POS_O1_POS_X_OFFSET                           11
+#define ATMEL_MPOP_O1_POS_O1_POS_X_SIZE                             11
+#define ATMEL_MPOP_O1_POS_O1_POS_Y                                   0
+#define ATMEL_MPOP_O1_POS_O1_POS_Y_MASK                     0x000007ff
+#define ATMEL_MPOP_O1_POS_O1_POS_Y_OFFSET                            0
+#define ATMEL_MPOP_O1_POS_O1_POS_Y_SIZE                             11
+#define ATMEL_MPOP_O1_POS_X                                         11
+#define ATMEL_MPOP_O1_POS_X_MASK                            0x003ff800
+#define ATMEL_MPOP_O1_POS_X_OFFSET                                  11
+#define ATMEL_MPOP_O1_POS_X_SIZE                                    11
+#define ATMEL_MPOP_O1_POS_Y                                          0
+#define ATMEL_MPOP_O1_POS_Y_MASK                            0x000007ff
+#define ATMEL_MPOP_O1_POS_Y_OFFSET                                   0
+#define ATMEL_MPOP_O1_POS_Y_SIZE                                    11
+#define ATMEL_MPOP_O1_SAR                                   0x00000040
+#define ATMEL_MPOP_O1_SAR_MASK                              0xffffffff
+#define ATMEL_MPOP_O1_SAR_O1_SAR                                     0
+#define ATMEL_MPOP_O1_SAR_O1_SAR_MASK                       0xffffffff
+#define ATMEL_MPOP_O1_SAR_O1_SAR_OFFSET                              0
+#define ATMEL_MPOP_O1_SAR_O1_SAR_SIZE                               32
+#define ATMEL_MPOP_O1_SAR_OFFSET                                     0
+#define ATMEL_MPOP_O1_SAR_SIZE                                      32
+#define ATMEL_MPOP_O1_SIZE                                  0x00000064
+#define ATMEL_MPOP_O1_SIZE_O1_SIZE_X                                11
+#define ATMEL_MPOP_O1_SIZE_O1_SIZE_X_MASK                   0x003ff800
+#define ATMEL_MPOP_O1_SIZE_O1_SIZE_X_OFFSET                         11
+#define ATMEL_MPOP_O1_SIZE_O1_SIZE_X_SIZE                           11
+#define ATMEL_MPOP_O1_SIZE_O1_SIZE_Y                                 0
+#define ATMEL_MPOP_O1_SIZE_O1_SIZE_Y_MASK                   0x000007ff
+#define ATMEL_MPOP_O1_SIZE_O1_SIZE_Y_OFFSET                          0
+#define ATMEL_MPOP_O1_SIZE_O1_SIZE_Y_SIZE                           11
+#define ATMEL_MPOP_O1_SIZE_X                                        11
+#define ATMEL_MPOP_O1_SIZE_X_MASK                           0x003ff800
+#define ATMEL_MPOP_O1_SIZE_X_OFFSET                                 11
+#define ATMEL_MPOP_O1_SIZE_X_SIZE                                   11
+#define ATMEL_MPOP_O1_SIZE_Y                                         0
+#define ATMEL_MPOP_O1_SIZE_Y_MASK                           0x000007ff
+#define ATMEL_MPOP_O1_SIZE_Y_OFFSET                                  0
+#define ATMEL_MPOP_O1_SIZE_Y_SIZE                                   11
+#define ATMEL_MPOP_O1_WTC                                   0x00000074
+#define ATMEL_MPOP_O1_WTC_MASK                              0xffffffff
+#define ATMEL_MPOP_O1_WTC_O1_WTC                                     0
+#define ATMEL_MPOP_O1_WTC_O1_WTC_MASK                       0xffffffff
+#define ATMEL_MPOP_O1_WTC_O1_WTC_OFFSET                              0
+#define ATMEL_MPOP_O1_WTC_O1_WTC_SIZE                               32
+#define ATMEL_MPOP_O1_WTC_OFFSET                                     0
+#define ATMEL_MPOP_O1_WTC_SIZE                                      32
+#define ATMEL_MPOP_O2EN                                              2
+#define ATMEL_MPOP_O2EN_MASK                                0x00000004
+#define ATMEL_MPOP_O2EN_OFFSET                                       2
+#define ATMEL_MPOP_O2EN_SIZE                                         1
+#define ATMEL_MPOP_O2_POS                                   0x00000054
+#define ATMEL_MPOP_O2_POS_O2_POS_X                                  11
+#define ATMEL_MPOP_O2_POS_O2_POS_X_MASK                     0x003ff800
+#define ATMEL_MPOP_O2_POS_O2_POS_X_OFFSET                           11
+#define ATMEL_MPOP_O2_POS_O2_POS_X_SIZE                             11
+#define ATMEL_MPOP_O2_POS_O2_POS_Y                                   0
+#define ATMEL_MPOP_O2_POS_O2_POS_Y_MASK                     0x000007ff
+#define ATMEL_MPOP_O2_POS_O2_POS_Y_OFFSET                            0
+#define ATMEL_MPOP_O2_POS_O2_POS_Y_SIZE                             11
+#define ATMEL_MPOP_O2_POS_X                                         11
+#define ATMEL_MPOP_O2_POS_X_MASK                            0x003ff800
+#define ATMEL_MPOP_O2_POS_X_OFFSET                                  11
+#define ATMEL_MPOP_O2_POS_X_SIZE                                    11
+#define ATMEL_MPOP_O2_POS_Y                                          0
+#define ATMEL_MPOP_O2_POS_Y_MASK                            0x000007ff
+#define ATMEL_MPOP_O2_POS_Y_OFFSET                                   0
+#define ATMEL_MPOP_O2_POS_Y_SIZE                                    11
+#define ATMEL_MPOP_O2_SAR                                   0x00000044
+#define ATMEL_MPOP_O2_SAR_MASK                              0xffffffff
+#define ATMEL_MPOP_O2_SAR_O2_SAR                                     0
+#define ATMEL_MPOP_O2_SAR_O2_SAR_MASK                       0xffffffff
+#define ATMEL_MPOP_O2_SAR_O2_SAR_OFFSET                              0
+#define ATMEL_MPOP_O2_SAR_O2_SAR_SIZE                               32
+#define ATMEL_MPOP_O2_SAR_OFFSET                                     0
+#define ATMEL_MPOP_O2_SAR_SIZE                                      32
+#define ATMEL_MPOP_O2_SIZE                                  0x00000068
+#define ATMEL_MPOP_O2_SIZE_O2_SIZE_X                                11
+#define ATMEL_MPOP_O2_SIZE_O2_SIZE_X_MASK                   0x003ff800
+#define ATMEL_MPOP_O2_SIZE_O2_SIZE_X_OFFSET                         11
+#define ATMEL_MPOP_O2_SIZE_O2_SIZE_X_SIZE                           11
+#define ATMEL_MPOP_O2_SIZE_O2_SIZE_Y                                 0
+#define ATMEL_MPOP_O2_SIZE_O2_SIZE_Y_MASK                   0x000007ff
+#define ATMEL_MPOP_O2_SIZE_O2_SIZE_Y_OFFSET                          0
+#define ATMEL_MPOP_O2_SIZE_O2_SIZE_Y_SIZE                           11
+#define ATMEL_MPOP_O2_SIZE_X                                        11
+#define ATMEL_MPOP_O2_SIZE_X_MASK                           0x003ff800
+#define ATMEL_MPOP_O2_SIZE_X_OFFSET                                 11
+#define ATMEL_MPOP_O2_SIZE_X_SIZE                                   11
+#define ATMEL_MPOP_O2_SIZE_Y                                         0
+#define ATMEL_MPOP_O2_SIZE_Y_MASK                           0x000007ff
+#define ATMEL_MPOP_O2_SIZE_Y_OFFSET                                  0
+#define ATMEL_MPOP_O2_SIZE_Y_SIZE                                   11
+#define ATMEL_MPOP_O2_WTC                                   0x00000078
+#define ATMEL_MPOP_O2_WTC_MASK                              0xffffffff
+#define ATMEL_MPOP_O2_WTC_O2_WTC                                     0
+#define ATMEL_MPOP_O2_WTC_O2_WTC_MASK                       0xffffffff
+#define ATMEL_MPOP_O2_WTC_O2_WTC_OFFSET                              0
+#define ATMEL_MPOP_O2_WTC_O2_WTC_SIZE                               32
+#define ATMEL_MPOP_O2_WTC_OFFSET                                     0
+#define ATMEL_MPOP_O2_WTC_SIZE                                      32
+#define ATMEL_MPOP_OCR                                      0x00000008
+#define ATMEL_MPOP_OCR_BGR                                           6
+#define ATMEL_MPOP_OCR_BGR_MASK                             0x00000040
+#define ATMEL_MPOP_OCR_BGR_OFFSET                                    6
+#define ATMEL_MPOP_OCR_BGR_SIZE                                      1
+#define ATMEL_MPOP_OCR_CURSOREN                                      0
+#define ATMEL_MPOP_OCR_CURSOREN_MASK                        0x00000001
+#define ATMEL_MPOP_OCR_CURSOREN_OFFSET                               0
+#define ATMEL_MPOP_OCR_CURSOREN_SIZE                                 1
+#define ATMEL_MPOP_OCR_O1EN                                          1
+#define ATMEL_MPOP_OCR_O1EN_MASK                            0x00000002
+#define ATMEL_MPOP_OCR_O1EN_OFFSET                                   1
+#define ATMEL_MPOP_OCR_O1EN_SIZE                                     1
+#define ATMEL_MPOP_OCR_O2EN                                          2
+#define ATMEL_MPOP_OCR_O2EN_MASK                            0x00000004
+#define ATMEL_MPOP_OCR_O2EN_OFFSET                                   2
+#define ATMEL_MPOP_OCR_O2EN_SIZE                                     1
+#define ATMEL_MPOP_OCR_RGBEN                                         3
+#define ATMEL_MPOP_OCR_RGBEN_MASK                           0x00000008
+#define ATMEL_MPOP_OCR_RGBEN_OFFSET                                  3
+#define ATMEL_MPOP_OCR_RGBEN_SIZE                                    1
+#define ATMEL_MPOP_OCR_RGBFORM                                       5
+#define ATMEL_MPOP_OCR_RGBFORM_MASK                         0x00000020
+#define ATMEL_MPOP_OCR_RGBFORM_OFFSET                                5
+#define ATMEL_MPOP_OCR_RGBFORM_SIZE                                  1
+#define ATMEL_MPOP_OCR_RGBSRC                                        4
+#define ATMEL_MPOP_OCR_RGBSRC_MASK                          0x00000010
+#define ATMEL_MPOP_OCR_RGBSRC_OFFSET                                 4
+#define ATMEL_MPOP_OCR_RGBSRC_SIZE                                   1
+#define ATMEL_MPOP_OUT                                               2
+#define ATMEL_MPOP_OUT_BEAR                                 0x0000009c
+#define ATMEL_MPOP_OUT_BEAR_MASK                            0xffffffff
+#define ATMEL_MPOP_OUT_BEAR_OFFSET                                   0
+#define ATMEL_MPOP_OUT_BEAR_OUT_BEAR                                 0
+#define ATMEL_MPOP_OUT_BEAR_OUT_BEAR_MASK                   0xffffffff
+#define ATMEL_MPOP_OUT_BEAR_OUT_BEAR_OFFSET                          0
+#define ATMEL_MPOP_OUT_BEAR_OUT_BEAR_SIZE                           32
+#define ATMEL_MPOP_OUT_BEAR_SIZE                                    32
+#define ATMEL_MPOP_OUT_BGR                                           3
+#define ATMEL_MPOP_OUT_BGR_MASK                             0x00000008
+#define ATMEL_MPOP_OUT_BGR_OFFSET                                    3
+#define ATMEL_MPOP_OUT_BGR_SIZE                                      1
+#define ATMEL_MPOP_OUT_CTRL                                          2
+#define ATMEL_MPOP_OUT_CTRL_MASK                            0x00000004
+#define ATMEL_MPOP_OUT_CTRL_OFFSET                                   2
+#define ATMEL_MPOP_OUT_CTRL_SIZE                                     1
+#define ATMEL_MPOP_OUT_MASK                                 0x00000004
+#define ATMEL_MPOP_OUT_OFFSET                                        2
+#define ATMEL_MPOP_OUT_SIZE                                          1
+#define ATMEL_MPOP_OVERLAY                                           1
+#define ATMEL_MPOP_OVERLAY_BEAR                             0x00000098
+#define ATMEL_MPOP_OVERLAY_BEAR_MASK                        0xffffffff
+#define ATMEL_MPOP_OVERLAY_BEAR_OFFSET                               0
+#define ATMEL_MPOP_OVERLAY_BEAR_OVERLAY_BEAR                         0
+#define ATMEL_MPOP_OVERLAY_BEAR_OVERLAY_BEAR_MASK           0xffffffff
+#define ATMEL_MPOP_OVERLAY_BEAR_OVERLAY_BEAR_OFFSET                  0
+#define ATMEL_MPOP_OVERLAY_BEAR_OVERLAY_BEAR_SIZE                   32
+#define ATMEL_MPOP_OVERLAY_BEAR_SIZE                                32
+#define ATMEL_MPOP_OVERLAY_MASK                             0x00000002
+#define ATMEL_MPOP_OVERLAY_OFFSET                                    1
+#define ATMEL_MPOP_OVERLAY_SIZE                                      1
+#define ATMEL_MPOP_PALETTEDATA                              0x00000400
+#define ATMEL_MPOP_R                                                16
+#define ATMEL_MPOP_R1                                                0
+#define ATMEL_MPOP_R1_MASK                                  0x00000fff
+#define ATMEL_MPOP_R1_OFFSET                                         0
+#define ATMEL_MPOP_R1_SIZE                                          12
+#define ATMEL_MPOP_R2                                               12
+#define ATMEL_MPOP_R2R1                                     0x00000014
+#define ATMEL_MPOP_R2R1_R1                                           0
+#define ATMEL_MPOP_R2R1_R1_MASK                             0x00000fff
+#define ATMEL_MPOP_R2R1_R1_OFFSET                                    0
+#define ATMEL_MPOP_R2R1_R1_SIZE                                     12
+#define ATMEL_MPOP_R2R1_R2                                          12
+#define ATMEL_MPOP_R2R1_R2_MASK                             0x00fff000
+#define ATMEL_MPOP_R2R1_R2_OFFSET                                   12
+#define ATMEL_MPOP_R2R1_R2_SIZE                                     12
+#define ATMEL_MPOP_R2_MASK                                  0x00fff000
+#define ATMEL_MPOP_R2_OFFSET                                        12
+#define ATMEL_MPOP_R2_SIZE                                          12
+#define ATMEL_MPOP_R3                                                0
+#define ATMEL_MPOP_R3_MASK                                  0x00000fff
+#define ATMEL_MPOP_R3_OFFSET                                         0
+#define ATMEL_MPOP_R3_SIZE                                          12
+#define ATMEL_MPOP_R4                                               12
+#define ATMEL_MPOP_R4R3                                     0x00000018
+#define ATMEL_MPOP_R4R3_R3                                           0
+#define ATMEL_MPOP_R4R3_R3_MASK                             0x00000fff
+#define ATMEL_MPOP_R4R3_R3_OFFSET                                    0
+#define ATMEL_MPOP_R4R3_R3_SIZE                                     12
+#define ATMEL_MPOP_R4R3_R4                                          12
+#define ATMEL_MPOP_R4R3_R4_MASK                             0xfffff000
+#define ATMEL_MPOP_R4R3_R4_OFFSET                                   12
+#define ATMEL_MPOP_R4R3_R4_SIZE                                     20
+#define ATMEL_MPOP_R4_MASK                                  0xfffff000
+#define ATMEL_MPOP_R4_OFFSET                                        12
+#define ATMEL_MPOP_R4_SIZE                                          20
+#define ATMEL_MPOP_RGBEN                                             3
+#define ATMEL_MPOP_RGBEN_MASK                               0x00000008
+#define ATMEL_MPOP_RGBEN_OFFSET                                      3
+#define ATMEL_MPOP_RGBEN_SIZE                                        1
+#define ATMEL_MPOP_RGBFORM                                           5
+#define ATMEL_MPOP_RGBFORM_MASK                             0x00000020
+#define ATMEL_MPOP_RGBFORM_OFFSET                                    5
+#define ATMEL_MPOP_RGBFORM_SIZE                                      1
+#define ATMEL_MPOP_RGBSRC                                            4
+#define ATMEL_MPOP_RGBSRC_MASK                              0x00000010
+#define ATMEL_MPOP_RGBSRC_OFFSET                                     4
+#define ATMEL_MPOP_RGBSRC_SIZE                                       1
+#define ATMEL_MPOP_RGB_POS                                  0x0000004c
+#define ATMEL_MPOP_RGB_POS_RGB_POS_X                                11
+#define ATMEL_MPOP_RGB_POS_RGB_POS_X_MASK                   0x003ff800
+#define ATMEL_MPOP_RGB_POS_RGB_POS_X_OFFSET                         11
+#define ATMEL_MPOP_RGB_POS_RGB_POS_X_SIZE                           11
+#define ATMEL_MPOP_RGB_POS_RGB_POS_Y                                 0
+#define ATMEL_MPOP_RGB_POS_RGB_POS_Y_MASK                   0x000007ff
+#define ATMEL_MPOP_RGB_POS_RGB_POS_Y_OFFSET                          0
+#define ATMEL_MPOP_RGB_POS_RGB_POS_Y_SIZE                           11
+#define ATMEL_MPOP_RGB_POS_X                                        11
+#define ATMEL_MPOP_RGB_POS_X_MASK                           0x003ff800
+#define ATMEL_MPOP_RGB_POS_X_OFFSET                                 11
+#define ATMEL_MPOP_RGB_POS_X_SIZE                                   11
+#define ATMEL_MPOP_RGB_POS_Y                                         0
+#define ATMEL_MPOP_RGB_POS_Y_MASK                           0x000007ff
+#define ATMEL_MPOP_RGB_POS_Y_OFFSET                                  0
+#define ATMEL_MPOP_RGB_POS_Y_SIZE                                   11
+#define ATMEL_MPOP_RGB_SAR                                  0x0000003c
+#define ATMEL_MPOP_RGB_SAR_MASK                             0xffffffff
+#define ATMEL_MPOP_RGB_SAR_OFFSET                                    0
+#define ATMEL_MPOP_RGB_SAR_RGB_SAR                                   0
+#define ATMEL_MPOP_RGB_SAR_RGB_SAR_MASK                     0xffffffff
+#define ATMEL_MPOP_RGB_SAR_RGB_SAR_OFFSET                            0
+#define ATMEL_MPOP_RGB_SAR_RGB_SAR_SIZE                             32
+#define ATMEL_MPOP_RGB_SAR_SIZE                                     32
+#define ATMEL_MPOP_RGB_SIZE                                 0x00000060
+#define ATMEL_MPOP_RGB_SIZE_RGB_SIZE_X                              11
+#define ATMEL_MPOP_RGB_SIZE_RGB_SIZE_X_MASK                 0x003ff800
+#define ATMEL_MPOP_RGB_SIZE_RGB_SIZE_X_OFFSET                       11
+#define ATMEL_MPOP_RGB_SIZE_RGB_SIZE_X_SIZE                         11
+#define ATMEL_MPOP_RGB_SIZE_RGB_SIZE_Y                               0
+#define ATMEL_MPOP_RGB_SIZE_RGB_SIZE_Y_MASK                 0x000007ff
+#define ATMEL_MPOP_RGB_SIZE_RGB_SIZE_Y_OFFSET                        0
+#define ATMEL_MPOP_RGB_SIZE_RGB_SIZE_Y_SIZE                         11
+#define ATMEL_MPOP_RGB_SIZE_X                                       11
+#define ATMEL_MPOP_RGB_SIZE_X_MASK                          0x003ff800
+#define ATMEL_MPOP_RGB_SIZE_X_OFFSET                                11
+#define ATMEL_MPOP_RGB_SIZE_X_SIZE                                  11
+#define ATMEL_MPOP_RGB_SIZE_Y                                        0
+#define ATMEL_MPOP_RGB_SIZE_Y_MASK                          0x000007ff
+#define ATMEL_MPOP_RGB_SIZE_Y_OFFSET                                 0
+#define ATMEL_MPOP_RGB_SIZE_Y_SIZE                                  11
+#define ATMEL_MPOP_RGB_WTC                                  0x00000070
+#define ATMEL_MPOP_RGB_WTC_MASK                             0xffffffff
+#define ATMEL_MPOP_RGB_WTC_OFFSET                                    0
+#define ATMEL_MPOP_RGB_WTC_RGB_WTC                                   0
+#define ATMEL_MPOP_RGB_WTC_RGB_WTC_MASK                     0xffffffff
+#define ATMEL_MPOP_RGB_WTC_RGB_WTC_OFFSET                            0
+#define ATMEL_MPOP_RGB_WTC_RGB_WTC_SIZE                             32
+#define ATMEL_MPOP_RGB_WTC_SIZE                                     32
+#define ATMEL_MPOP_R_MASK                                   0x00ff0000
+#define ATMEL_MPOP_R_OFFSET                                         16
+#define ATMEL_MPOP_R_SIZE                                            8
+#define ATMEL_MPOP_SOP                                               4
+#define ATMEL_MPOP_SOP_MASK                                 0x00000010
+#define ATMEL_MPOP_SOP_OFFSET                                        4
+#define ATMEL_MPOP_SOP_SIZE                                          1
+#define ATMEL_MPOP_START                                             1
+#define ATMEL_MPOP_START_MASK                               0x00000002
+#define ATMEL_MPOP_START_OFFSET                                      1
+#define ATMEL_MPOP_START_SIZE                                        1
+#define ATMEL_MPOP_STRIDE                                   0x0000002c
+#define ATMEL_MPOP_STRIDE_MASK                              0xffffffff
+#define ATMEL_MPOP_STRIDE_OFFSET                                     0
+#define ATMEL_MPOP_STRIDE_SIZE                                      32
+#define ATMEL_MPOP_STRIDE_STRIDE                                     0
+#define ATMEL_MPOP_STRIDE_STRIDE_MASK                       0xffffffff
+#define ATMEL_MPOP_STRIDE_STRIDE_OFFSET                              0
+#define ATMEL_MPOP_STRIDE_STRIDE_SIZE                               32
+#define ATMEL_MPOP_U_SAR                                    0x00000034
+#define ATMEL_MPOP_U_SAR_MASK                               0xffffffff
+#define ATMEL_MPOP_U_SAR_OFFSET                                      0
+#define ATMEL_MPOP_U_SAR_SIZE                                       32
+#define ATMEL_MPOP_U_SAR_U_SAR                                       0
+#define ATMEL_MPOP_U_SAR_U_SAR_MASK                         0xffffffff
+#define ATMEL_MPOP_U_SAR_U_SAR_OFFSET                                0
+#define ATMEL_MPOP_U_SAR_U_SAR_SIZE                                 32
+#define ATMEL_MPOP_VISIBLE                                          24
+#define ATMEL_MPOP_VISIBLE_MASK                             0x01000000
+#define ATMEL_MPOP_VISIBLE_OFFSET                                   24
+#define ATMEL_MPOP_VISIBLE_SIZE                                      1
+#define ATMEL_MPOP_V_SAR                                    0x00000038
+#define ATMEL_MPOP_V_SAR_MASK                               0xffffffff
+#define ATMEL_MPOP_V_SAR_OFFSET                                      0
+#define ATMEL_MPOP_V_SAR_SIZE                                       32
+#define ATMEL_MPOP_V_SAR_V_SAR                                       0
+#define ATMEL_MPOP_V_SAR_V_SAR_MASK                         0xffffffff
+#define ATMEL_MPOP_V_SAR_V_SAR_OFFSET                                0
+#define ATMEL_MPOP_V_SAR_V_SAR_SIZE                                 32
+#define ATMEL_MPOP_XRESIZE                                          16
+#define ATMEL_MPOP_XRESIZE_MASK                             0x00ff0000
+#define ATMEL_MPOP_XRESIZE_OFFSET                                   16
+#define ATMEL_MPOP_XRESIZE_SIZE                                      8
+#define ATMEL_MPOP_YCR                                      0x00000004
+#define ATMEL_MPOP_YCR_XRESIZE                                      16
+#define ATMEL_MPOP_YCR_XRESIZE_MASK                         0x00ff0000
+#define ATMEL_MPOP_YCR_XRESIZE_OFFSET                               16
+#define ATMEL_MPOP_YCR_XRESIZE_SIZE                                  8
+#define ATMEL_MPOP_YCR_YRESIZE                                       8
+#define ATMEL_MPOP_YCR_YRESIZE_MASK                         0x0000ff00
+#define ATMEL_MPOP_YCR_YRESIZE_OFFSET                                8
+#define ATMEL_MPOP_YCR_YRESIZE_SIZE                                  8
+#define ATMEL_MPOP_YCR_YUVFORMAT                                     0
+#define ATMEL_MPOP_YCR_YUVFORMAT_MASK                       0x00000003
+#define ATMEL_MPOP_YCR_YUVFORMAT_OFFSET                              0
+#define ATMEL_MPOP_YCR_YUVFORMAT_SIZE                                2
+#define ATMEL_MPOP_YCR_YUVFORMAT_YUVFORMAT_420              0x00000002
+#define ATMEL_MPOP_YCR_YUVFORMAT_YUVFORMAT_422              0x00000001
+#define ATMEL_MPOP_YCR_YUVFORMAT_YUVFORMAT_444              0x00000000
+#define ATMEL_MPOP_YRESIZE                                           8
+#define ATMEL_MPOP_YRESIZE_MASK                             0x0000ff00
+#define ATMEL_MPOP_YRESIZE_OFFSET                                    8
+#define ATMEL_MPOP_YRESIZE_SIZE                                      8
+#define ATMEL_MPOP_YUV                                               0
+#define ATMEL_MPOP_YUVFORMAT                                         0
+#define ATMEL_MPOP_YUVFORMAT_420                            0x00000002
+#define ATMEL_MPOP_YUVFORMAT_422                            0x00000001
+#define ATMEL_MPOP_YUVFORMAT_444                            0x00000000
+#define ATMEL_MPOP_YUVFORMAT_MASK                           0x00000003
+#define ATMEL_MPOP_YUVFORMAT_OFFSET                                  0
+#define ATMEL_MPOP_YUVFORMAT_SIZE                                    2
+#define ATMEL_MPOP_YUVFORMAT_YUVFORMAT_420                  0x00000002
+#define ATMEL_MPOP_YUVFORMAT_YUVFORMAT_422                  0x00000001
+#define ATMEL_MPOP_YUVFORMAT_YUVFORMAT_444                  0x00000000
+#define ATMEL_MPOP_YUV_BEAR                                 0x00000094
+#define ATMEL_MPOP_YUV_BEAR_MASK                            0xffffffff
+#define ATMEL_MPOP_YUV_BEAR_OFFSET                                   0
+#define ATMEL_MPOP_YUV_BEAR_SIZE                                    32
+#define ATMEL_MPOP_YUV_BEAR_YUV_BEAR                                 0
+#define ATMEL_MPOP_YUV_BEAR_YUV_BEAR_MASK                   0xffffffff
+#define ATMEL_MPOP_YUV_BEAR_YUV_BEAR_OFFSET                          0
+#define ATMEL_MPOP_YUV_BEAR_YUV_BEAR_SIZE                           32
+#define ATMEL_MPOP_YUV_MASK                                 0x00000001
+#define ATMEL_MPOP_YUV_MAX_COORD                            0x0000005c
+#define ATMEL_MPOP_YUV_MAX_COORD_X                                  11
+#define ATMEL_MPOP_YUV_MAX_COORD_X_MASK                     0x003ff800
+#define ATMEL_MPOP_YUV_MAX_COORD_X_OFFSET                           11
+#define ATMEL_MPOP_YUV_MAX_COORD_X_SIZE                             11
+#define ATMEL_MPOP_YUV_MAX_COORD_Y                                   0
+#define ATMEL_MPOP_YUV_MAX_COORD_YUV_MAX_COORD_X                    11
+#define ATMEL_MPOP_YUV_MAX_COORD_YUV_MAX_COORD_X_MASK       0x003ff800
+#define ATMEL_MPOP_YUV_MAX_COORD_YUV_MAX_COORD_X_OFFSET             11
+#define ATMEL_MPOP_YUV_MAX_COORD_YUV_MAX_COORD_X_SIZE               11
+#define ATMEL_MPOP_YUV_MAX_COORD_YUV_MAX_COORD_Y                     0
+#define ATMEL_MPOP_YUV_MAX_COORD_YUV_MAX_COORD_Y_MASK       0x000007ff
+#define ATMEL_MPOP_YUV_MAX_COORD_YUV_MAX_COORD_Y_OFFSET              0
+#define ATMEL_MPOP_YUV_MAX_COORD_YUV_MAX_COORD_Y_SIZE               11
+#define ATMEL_MPOP_YUV_MAX_COORD_Y_MASK                     0x000007ff
+#define ATMEL_MPOP_YUV_MAX_COORD_Y_OFFSET                            0
+#define ATMEL_MPOP_YUV_MAX_COORD_Y_SIZE                             11
+#define ATMEL_MPOP_YUV_OFFSET                                        0
+#define ATMEL_MPOP_YUV_SIZE                                          1
+#define ATMEL_MPOP_Y_SAR                                    0x00000030
+#define ATMEL_MPOP_Y_SAR_MASK                               0xffffffff
+#define ATMEL_MPOP_Y_SAR_OFFSET                                      0
+#define ATMEL_MPOP_Y_SAR_SIZE                                       32
+#define ATMEL_MPOP_Y_SAR_Y_SAR                                       0
+#define ATMEL_MPOP_Y_SAR_Y_SAR_MASK                         0xffffffff
+#define ATMEL_MPOP_Y_SAR_Y_SAR_OFFSET                                0
+#define ATMEL_MPOP_Y_SAR_Y_SAR_SIZE                                 32
+
+#endif /* __ATMEL_MPOP_H__ */
diff -urN linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/clock.c linux-2.6.28.2/arch/avr32/mach-at32ap/clock.c
--- linux-2.6.28.2-0rig//arch/avr32/mach-at32ap/clock.c	2009-01-29 08:39:35.000000000 +0100
+++ linux-2.6.28.2/arch/avr32/mach-at32ap/clock.c	2009-01-29 10:16:11.000000000 +0100
@@ -178,7 +178,11 @@
 #include <linux/io.h>
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
-#include "pm.h"
+#if defined(CONFIG_CPU_AT32AP700X)
+# include "pm-v1.h"
+#elif defined(CONFIG_CPU_AT32AP720X)
+# include "pm-v3.h"
+#endif
 
 
 #define	NEST_DELTA	2
@@ -234,19 +238,40 @@
 	struct clk 	*clk;
 
 	/* show all the power manager registers */
-	seq_printf(s, "MCCTRL  = %8x\n", pm_readl(MCCTRL));
-	seq_printf(s, "CKSEL   = %8x\n", pm_readl(CKSEL));
-	seq_printf(s, "CPUMASK = %8x\n", pm_readl(CPU_MASK));
-	seq_printf(s, "HSBMASK = %8x\n", pm_readl(HSB_MASK));
-	seq_printf(s, "PBAMASK = %8x\n", pm_readl(PBA_MASK));
-	seq_printf(s, "PBBMASK = %8x\n", pm_readl(PBB_MASK));
-	seq_printf(s, "PLL0    = %8x\n", pm_readl(PLL0));
-	seq_printf(s, "PLL1    = %8x\n", pm_readl(PLL1));
-	seq_printf(s, "IMR     = %8x\n", pm_readl(IMR));
+	seq_printf(s, "MCCTRL     = %8x\n", pm_readl(MCCTRL));
+	seq_printf(s, "CKSEL      = %8x\n", pm_readl(CKSEL));
+#ifdef CONFIG_CPU_AT32AP700X
+	seq_printf(s, "CPUMASK    = %8x\n", pm_readl(CPU_MASK));
+	seq_printf(s, "HSBMASK    = %8x\n", pm_readl(HSB_MASK));
+	seq_printf(s, "PBAMASK    = %8x\n", pm_readl(PBA_MASK));
+	seq_printf(s, "PBBMASK    = %8x\n", pm_readl(PBB_MASK));
+	seq_printf(s, "PLL0       = %8x\n", pm_readl(PLL0));
+	seq_printf(s, "PLL1       = %8x\n", pm_readl(PLL1));
+#else
+	seq_printf(s, "CPUMASK    = %8x\n", pm_readl(CPUMASK));
+	seq_printf(s, "HSBMASK    = %8x\n", pm_readl(HSBMASK));
+	seq_printf(s, "PBAMASK    = %8x\n", pm_readl(PBAMASK));
+	seq_printf(s, "PBBMASK    = %8x\n", pm_readl(PBBMASK));
+	seq_printf(s, "PBADIVMASK = %8x\n", pm_readl(PBADIVMASK));
+	seq_printf(s, "PBBDIVMASK = %8x\n", pm_readl(PBBDIVMASK));
+	seq_printf(s, "PLL0       = %8x\n", pm_readl(PLL[0]));
+	seq_printf(s, "PLL1       = %8x\n", pm_readl(PLL[1]));
+	seq_printf(s, "PLL2       = %8x\n", pm_readl(PLL[2]));
+	seq_printf(s, "OSCCTRL0   = %8x\n", pm_readl(OSCCTRL[0]));
+	seq_printf(s, "OSCCTRL1   = %8x\n", pm_readl(OSCCTRL[1]));
+	seq_printf(s, "OSCCTRL2   = %8x\n", pm_readl(OSCCTRL[2]));
+	seq_printf(s, "POSCSR     = %8x\n", pm_readl(POSCSR));
+	seq_printf(s, "PPCR       = %8x\n", pm_readl(PPCR));
+#endif
+	seq_printf(s, "IMR        = %8x\n", pm_readl(IMR));
 	for (i = 0; i < 8; i++) {
 		if (i == 5)
 			continue;
-		seq_printf(s, "GCCTRL%d = %8x\n", i, pm_readl(GCCTRL(i)));
+#ifdef CONFIG_CPU_AT32AP700X
+		seq_printf(s, "GCCTRL%d    = %8x\n", i, pm_readl(GCCTRL(i)));
+#else
+		seq_printf(s, "GCCTRL%d    = %8x\n", i, pm_readl(GCCTRL[i]));
+#endif
 	}
 
 	seq_printf(s, "\n");
@@ -269,6 +294,16 @@
 	dump_clock(clk, &r);
 	clk_put(clk);
 
+#ifdef CONFIG_CPU_AT32AP720X
+	clk = clk_get(NULL, "osc2");
+	dump_clock(clk, &r);
+	clk_put(clk);
+
+	clk = clk_get(NULL, "rcosc");
+	dump_clock(clk, &r);
+	clk_put(clk);
+#endif
+
 	spin_unlock(&clk_list_lock);
 
 	return 0;

