TARGET_DEVICE_TABLE:=$(ATMEL_TARGET)/device_table.txt
TARGET_SKELETON_LINKS:=$(ATMEL_TARGET)/skel.tar.gz
+ifeq ($(BR2_avr32),y)
+KERNEL_HEADERS_PATCH_DIR=target/device/Atmel/arch-avr32/kernel-headers-2.6.28.2
+endif
+
ifneq ($(COPYTO),)
TARGET_ATMEL_COPYTO:=$(strip $(subst ",, $(BR2_COPYTO)))
else
--- /dev/null
+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, ð_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;
+
--- /dev/null
+From f26e2224d46430ac4f6c0ddeb518f5766ba62b16 Mon Sep 17 00:00:00 2001
+From: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
+Date: Wed, 26 Nov 2008 14:10:45 +0100
+Subject: [PATCH 2/3] atmel_mpopfb: remove define DEBUG to disable debug output
+
+Signed-off-by: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
+
+diff --git a/drivers/video/atmel_mpopfb.c b/drivers/video/atmel_mpopfb.c
+index 0a07f7b..3b4b668 100644
+--- a/drivers/video/atmel_mpopfb.c
++++ b/drivers/video/atmel_mpopfb.c
+@@ -8,8 +8,6 @@
+ * more details.
+ */
+
+-#define DEBUG
+-
+ #include <linux/clk.h>
+ #include <linux/delay.h>
+ #include <linux/dma-mapping.h>
+--
+1.5.6.3
+
--- /dev/null
+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 2009-01-29 09:41:04.000000000 +0100
++++ linux-2.6.28.2/drivers/video/atmel_mpopfb.c 2009-01-29 09:43:46.000000000 +0100
+@@ -315,6 +315,10 @@
+ static void atmel_mpopfb_start(struct atmel_mpopfb_info *sinfo)
+ {
+ if (!sinfo->running) {
++ unsigned int line_cache_disable =
++ sinfo->baseimg_info.line_cache_disable ?
++ ATMEL_MPOP_CR_CACHEDIS_MASK : 0;
++
+ dev_dbg(sinfo->info->device, " * Starting MPOP.\n");
+
+ /* Enable all error interrupts. */
+@@ -325,9 +329,9 @@
+ * 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 */ );
++ mpop_writel(sinfo, ATMEL_MPOP_CR, ATMEL_MPOP_CR_EN_MASK
++ | line_cache_disable
++ | ATMEL_MPOP_CR_OUT_BGR_MASK);
+
+ sinfo->running = 1;
+ }
+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 2009-01-29 09:41:04.000000000 +0100
++++ linux-2.6.28.2/include/linux/atmel_mpopfb.h 2009-01-29 09:43:46.000000000 +0100
+@@ -42,9 +42,11 @@
+ unsigned xsize;
+ unsigned ysize;
+
+- /* Signal that we should flip the video. */
++ /* Signal for flipping the video. */
+ int flip;
+
++ /* Signal for disabling the line cache. */
++ int line_cache_disable;
+ };
+
+ enum atmel_mpopfb_overlay_type {
--- /dev/null
+Index: linux-2.6.27.6/arch/avr32/include/asm/byteorder.h
+===================================================================
+--- linux-2.6.27.6.orig/arch/avr32/include/asm/byteorder.h 2008-11-28 16:47:15.000000000 +0100
++++ linux-2.6.27.6/arch/avr32/include/asm/byteorder.h 2008-11-28 16:47:31.000000000 +0100
+@@ -7,8 +7,9 @@
+ #include <asm/types.h>
+ #include <linux/compiler.h>
+
+-#define __BIG_ENDIAN
++#define __BIG_ENDIAN 4321
+ #define __SWAB_64_THRU_32__
++#define __BYTEORDER_HAS_U64__
+
+ #ifdef __CHECKER__
+ extern unsigned long __builtin_bswap_32(unsigned long x);
+@@ -33,5 +34,5 @@
+ #define __arch_swab32 __arch_swab32
+ #endif
+
+-#include <linux/byteorder.h>
++#include <linux/byteorder/big_endian.h>
+ #endif /* __ASM_AVR32_BYTEORDER_H */
+Index: linux-2.6.27.6/arch/avr32/mach-at32ap/include/mach/io.h
+===================================================================
+--- linux-2.6.27.6.orig/arch/avr32/mach-at32ap/include/mach/io.h 2008-11-28 16:47:58.000000000 +0100
++++ linux-2.6.27.6/arch/avr32/mach-at32ap/include/mach/io.h 2008-11-28 16:48:15.000000000 +0100
+@@ -1,7 +1,7 @@
+ #ifndef __ASM_AVR32_ARCH_AT32AP_IO_H
+ #define __ASM_AVR32_ARCH_AT32AP_IO_H
+
+-#include <linux/swab.h>
++#include <linux/byteorder/swabb.h>
+
+ #if defined(CONFIG_AP700X_32_BIT_SMC)
+ # define __swizzle_addr_b(addr) (addr ^ 3UL)
--- /dev/null
+diff -urN linux-2.6.28.2-0rig//arch/avr32/boards/atstk1000/atstk1002.c linux-2.6.28.2/arch/avr32/boards/atstk1000/atstk1002.c
+--- linux-2.6.28.2-0rig//arch/avr32/boards/atstk1000/atstk1002.c 2009-01-29 08:39:35.000000000 +0100
++++ linux-2.6.28.2/arch/avr32/boards/atstk1000/atstk1002.c 2009-01-29 09:50:56.000000000 +0100
+@@ -99,6 +99,7 @@
+ static struct atmel_nand_data atstk1006_nand_data __initdata = {
+ .cle = 21,
+ .ale = 22,
++ .det_pin = GPIO_PIN_NONE,
+ .rdy_pin = GPIO_PIN_PB(30),
+ .enable_pin = GPIO_PIN_PB(29),
+ .partition_info = nand_part_info,
+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 09:41:04.000000000 +0100
++++ linux-2.6.28.2/arch/avr32/mach-at32ap/at32ap700x.c 2009-01-29 09:50:56.000000000 +0100
+@@ -1972,13 +1972,14 @@
+ goto fail;
+
+ hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_NAND_ENABLE);
+- if (data->enable_pin)
++
++ if (gpio_is_valid(data->enable_pin))
+ at32_select_gpio(data->enable_pin,
+ AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
+- if (data->rdy_pin)
+- at32_select_gpio(data->rdy_pin, 0);
+- if (data->det_pin)
++ 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;
TARGET_SKELETON=$(VALKA_PATH)/target_skeleton
TARGET_DEVICE_TABLE=$(VALKA_PATH)/device_table.txt
+KERNEL_HEADERS_PATCH_DIR=target/device/Atmel/arch-avr32/kernel-headers-2.6.28.2
valka_status:
@echo "***************************************************************"
config BR2_KERNEL_HEADERS_PATCH_DIR
bool "Add additional headers from $(KERNEL_HEADERS_PATCH_DIR)"
- depends on BR2_KERNEL_HEADERS_2_6_20_4 || BR2_KERNEL_HEADERS_2_6_21_5 || BR2_KERNEL_HEADERS_2_6_22_1 || BR2_KERNEL_HEADERS_2_6_22_10
+ depends on BR2_KERNEL_HEADERS_2_6_20_4 || BR2_KERNEL_HEADERS_2_6_21_5 || BR2_KERNEL_HEADERS_2_6_22_1 || BR2_KERNEL_HEADERS_2_6_22_10 || BR2_KERNEL_HEADERS_2_6_28
help
Apply additional kernel patches defined by KERNEL_HEADERS_PATCH_DIR
in your board directory.
+++ /dev/null
-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, ð_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;
-
+++ /dev/null
-From f26e2224d46430ac4f6c0ddeb518f5766ba62b16 Mon Sep 17 00:00:00 2001
-From: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
-Date: Wed, 26 Nov 2008 14:10:45 +0100
-Subject: [PATCH 2/3] atmel_mpopfb: remove define DEBUG to disable debug output
-
-Signed-off-by: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
-
-diff --git a/drivers/video/atmel_mpopfb.c b/drivers/video/atmel_mpopfb.c
-index 0a07f7b..3b4b668 100644
---- a/drivers/video/atmel_mpopfb.c
-+++ b/drivers/video/atmel_mpopfb.c
-@@ -8,8 +8,6 @@
- * more details.
- */
-
--#define DEBUG
--
- #include <linux/clk.h>
- #include <linux/delay.h>
- #include <linux/dma-mapping.h>
---
-1.5.6.3
-
+++ /dev/null
-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 2009-01-29 09:41:04.000000000 +0100
-+++ linux-2.6.28.2/drivers/video/atmel_mpopfb.c 2009-01-29 09:43:46.000000000 +0100
-@@ -315,6 +315,10 @@
- static void atmel_mpopfb_start(struct atmel_mpopfb_info *sinfo)
- {
- if (!sinfo->running) {
-+ unsigned int line_cache_disable =
-+ sinfo->baseimg_info.line_cache_disable ?
-+ ATMEL_MPOP_CR_CACHEDIS_MASK : 0;
-+
- dev_dbg(sinfo->info->device, " * Starting MPOP.\n");
-
- /* Enable all error interrupts. */
-@@ -325,9 +329,9 @@
- * 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 */ );
-+ mpop_writel(sinfo, ATMEL_MPOP_CR, ATMEL_MPOP_CR_EN_MASK
-+ | line_cache_disable
-+ | ATMEL_MPOP_CR_OUT_BGR_MASK);
-
- sinfo->running = 1;
- }
-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 2009-01-29 09:41:04.000000000 +0100
-+++ linux-2.6.28.2/include/linux/atmel_mpopfb.h 2009-01-29 09:43:46.000000000 +0100
-@@ -42,9 +42,11 @@
- unsigned xsize;
- unsigned ysize;
-
-- /* Signal that we should flip the video. */
-+ /* Signal for flipping the video. */
- int flip;
-
-+ /* Signal for disabling the line cache. */
-+ int line_cache_disable;
- };
-
- enum atmel_mpopfb_overlay_type {
+++ /dev/null
-Index: linux-2.6.27.6/arch/avr32/include/asm/byteorder.h
-===================================================================
---- linux-2.6.27.6.orig/arch/avr32/include/asm/byteorder.h 2008-11-28 16:47:15.000000000 +0100
-+++ linux-2.6.27.6/arch/avr32/include/asm/byteorder.h 2008-11-28 16:47:31.000000000 +0100
-@@ -7,8 +7,9 @@
- #include <asm/types.h>
- #include <linux/compiler.h>
-
--#define __BIG_ENDIAN
-+#define __BIG_ENDIAN 4321
- #define __SWAB_64_THRU_32__
-+#define __BYTEORDER_HAS_U64__
-
- #ifdef __CHECKER__
- extern unsigned long __builtin_bswap_32(unsigned long x);
-@@ -33,5 +34,5 @@
- #define __arch_swab32 __arch_swab32
- #endif
-
--#include <linux/byteorder.h>
-+#include <linux/byteorder/big_endian.h>
- #endif /* __ASM_AVR32_BYTEORDER_H */
-Index: linux-2.6.27.6/arch/avr32/mach-at32ap/include/mach/io.h
-===================================================================
---- linux-2.6.27.6.orig/arch/avr32/mach-at32ap/include/mach/io.h 2008-11-28 16:47:58.000000000 +0100
-+++ linux-2.6.27.6/arch/avr32/mach-at32ap/include/mach/io.h 2008-11-28 16:48:15.000000000 +0100
-@@ -1,7 +1,7 @@
- #ifndef __ASM_AVR32_ARCH_AT32AP_IO_H
- #define __ASM_AVR32_ARCH_AT32AP_IO_H
-
--#include <linux/swab.h>
-+#include <linux/byteorder/swabb.h>
-
- #if defined(CONFIG_AP700X_32_BIT_SMC)
- # define __swizzle_addr_b(addr) (addr ^ 3UL)
+++ /dev/null
-diff -urN linux-2.6.28.2-0rig//arch/avr32/boards/atstk1000/atstk1002.c linux-2.6.28.2/arch/avr32/boards/atstk1000/atstk1002.c
---- linux-2.6.28.2-0rig//arch/avr32/boards/atstk1000/atstk1002.c 2009-01-29 08:39:35.000000000 +0100
-+++ linux-2.6.28.2/arch/avr32/boards/atstk1000/atstk1002.c 2009-01-29 09:50:56.000000000 +0100
-@@ -99,6 +99,7 @@
- static struct atmel_nand_data atstk1006_nand_data __initdata = {
- .cle = 21,
- .ale = 22,
-+ .det_pin = GPIO_PIN_NONE,
- .rdy_pin = GPIO_PIN_PB(30),
- .enable_pin = GPIO_PIN_PB(29),
- .partition_info = nand_part_info,
-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 09:41:04.000000000 +0100
-+++ linux-2.6.28.2/arch/avr32/mach-at32ap/at32ap700x.c 2009-01-29 09:50:56.000000000 +0100
-@@ -1972,13 +1972,14 @@
- goto fail;
-
- hmatrix_sfr_set_bits(HMATRIX_SLAVE_EBI, HMATRIX_EBI_NAND_ENABLE);
-- if (data->enable_pin)
-+
-+ if (gpio_is_valid(data->enable_pin))
- at32_select_gpio(data->enable_pin,
- AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
-- if (data->rdy_pin)
-- at32_select_gpio(data->rdy_pin, 0);
-- if (data->det_pin)
-+ 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;