diff options
author | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2008-11-25 13:49:57 +0000 |
---|---|---|
committer | kaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2008-11-25 13:49:57 +0000 |
commit | 46aa5e4217aff85d4b63fba17058f697fe534849 (patch) | |
tree | 4e4c4b66b98d94d6b7a95173127c7fad3571e6e0 /target | |
parent | 1c9768ccb3056bdda9d13ae59cc7e7dca08acff5 (diff) |
upgrade avr32 to 2.6.27
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@13345 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target')
-rw-r--r-- | target/linux/avr32/Makefile | 2 | ||||
-rw-r--r-- | target/linux/avr32/config-default | 4 | ||||
-rw-r--r-- | target/linux/avr32/patches/100-git_sync.patch | 16677 |
3 files changed, 4 insertions, 16679 deletions
diff --git a/target/linux/avr32/Makefile b/target/linux/avr32/Makefile index e07cb9aaa6..67524d95f1 100644 --- a/target/linux/avr32/Makefile +++ b/target/linux/avr32/Makefile @@ -10,7 +10,7 @@ ARCH:=avr32 BOARD:=avr32 BOARDNAME:=Atmel AVR32 FEATURES:=squashfs -LINUX_VERSION:=2.6.25.20 +LINUX_VERSION:=2.6.27.7 include $(INCLUDE_DIR)/target.mk diff --git a/target/linux/avr32/config-default b/target/linux/avr32/config-default index 8a0692a60e..60a901a3e9 100644 --- a/target/linux/avr32/config-default +++ b/target/linux/avr32/config-default @@ -41,6 +41,7 @@ CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y CONFIG_GENERIC_GPIO=y # CONFIG_GPIO_DEV is not set +# CONFIG_GPIO_MAX7301 is not set # CONFIG_GPIO_MCP23S08 is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set @@ -139,6 +140,7 @@ CONFIG_QUICKLIST=y # CONFIG_REALTEK_PHY is not set CONFIG_RTC_CLASS=m CONFIG_RTC_DRV_AT32AP700X=m +# CONFIG_RTC_DRV_DS1305 is not set # CONFIG_RTC_DRV_DS1307 is not set # CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1553 is not set @@ -148,6 +150,7 @@ CONFIG_RTC_DRV_AT32AP700X=m # CONFIG_RTC_DRV_M41T80 is not set # CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M41T94 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_RS5C372 is not set @@ -185,7 +188,6 @@ CONFIG_SPI_MASTER=y CONFIG_SSB_POSSIBLE=y CONFIG_SUBARCH_AVR32B=y CONFIG_SYSVIPC_SYSCTL=y -# CONFIG_THERMAL is not set CONFIG_TICK_ONESHOT=y # CONFIG_USB_ARCH_HAS_EHCI is not set # CONFIG_USB_ARCH_HAS_HCD is not set diff --git a/target/linux/avr32/patches/100-git_sync.patch b/target/linux/avr32/patches/100-git_sync.patch deleted file mode 100644 index 6c9fe1eb66..0000000000 --- a/target/linux/avr32/patches/100-git_sync.patch +++ /dev/null @@ -1,16677 +0,0 @@ ---- a/Documentation/serial/driver -+++ b/Documentation/serial/driver -@@ -186,6 +186,17 @@ hardware. - Locking: port_sem taken. - Interrupts: caller dependent. - -+ flush_buffer(port) -+ Flush any write buffers, reset any DMA state and stop any -+ ongoing DMA transfers. -+ -+ This will be called whenever the port->info->xmit circular -+ buffer is cleared. -+ -+ Locking: port->lock taken. -+ Interrupts: locally disabled. -+ This call must not sleep -+ - set_termios(port,termios,oldtermios) - Change the port parameters, including word length, parity, stop - bits. Update read_status_mask and ignore_status_mask to indicate ---- a/arch/avr32/Kconfig -+++ b/arch/avr32/Kconfig -@@ -47,6 +47,9 @@ config RWSEM_GENERIC_SPINLOCK - config GENERIC_TIME - def_bool y - -+config GENERIC_CLOCKEVENTS -+ def_bool y -+ - config RWSEM_XCHGADD_ALGORITHM - def_bool n - -@@ -70,6 +73,8 @@ source "init/Kconfig" - - menu "System Type and features" - -+source "kernel/time/Kconfig" -+ - config SUBARCH_AVR32B - bool - config MMU -@@ -83,6 +88,7 @@ config PLATFORM_AT32AP - select MMU - select PERFORMANCE_COUNTERS - select HAVE_GPIO_LIB -+ select GENERIC_ALLOCATOR - - # - # CPU types -@@ -117,6 +123,9 @@ endchoice - if BOARD_ATSTK1000 - source "arch/avr32/boards/atstk1000/Kconfig" - endif -+if BOARD_ATNGW100 -+source "arch/avr32/boards/atngw100/Kconfig" -+endif - - choice - prompt "Boot loader type" -@@ -142,6 +151,9 @@ config PHYS_OFFSET - - source "kernel/Kconfig.preempt" - -+config QUICKLIST -+ def_bool y -+ - config HAVE_ARCH_BOOTMEM_NODE - def_bool n - -@@ -180,6 +192,10 @@ config NMI_DEBUGGING - be dumped to the console when a Non-Maskable Interrupt - happens. - -+config DW_DMAC -+ tristate "Synopsys DesignWare DMA Controller support" -+ default y if CPU_AT32AP7000 -+ - # FPU emulation goes here - - source "kernel/Kconfig.hz" -@@ -196,6 +212,11 @@ endmenu - - menu "Power management options" - -+config ARCH_SUSPEND_POSSIBLE -+ def_bool y -+ -+source "kernel/power/Kconfig" -+ - menu "CPU Frequency scaling" - - source "drivers/cpufreq/Kconfig" ---- a/arch/avr32/Makefile -+++ b/arch/avr32/Makefile -@@ -32,6 +32,7 @@ core-$(CONFIG_LOADER_U_BOOT) += arch/av - core-y += arch/avr32/kernel/ - core-y += arch/avr32/mm/ - drivers-$(CONFIG_OPROFILE) += arch/avr32/oprofile/ -+drivers-y += arch/avr32/drivers/ - libs-y += arch/avr32/lib/ - - archincdir-$(CONFIG_PLATFORM_AT32AP) := arch-at32ap ---- /dev/null -+++ b/arch/avr32/boards/atngw100/Kconfig -@@ -0,0 +1,12 @@ -+# NGW100 customization -+ -+config BOARD_ATNGW100_I2C_GPIO -+ bool "Use GPIO for i2c instead of built-in TWI module" -+ help -+ The driver for the built-in TWI module has been plagued by -+ various problems, while the i2c-gpio driver is based on the -+ trusty old i2c-algo-bit bitbanging engine, making it work -+ on pretty much any setup. -+ -+ Choose 'Y' here if you're having i2c-related problems and -+ want to rule out the i2c bus driver. ---- a/arch/avr32/boards/atngw100/setup.c -+++ b/arch/avr32/boards/atngw100/setup.c -@@ -25,6 +25,13 @@ - #include <asm/arch/init.h> - #include <asm/arch/portmux.h> - -+/* Oscillator frequencies. These are board-specific */ -+unsigned long at32_board_osc_rates[3] = { -+ [0] = 32768, /* 32.768 kHz on RTC osc */ -+ [1] = 20000000, /* 20 MHz on osc0 */ -+ [2] = 12000000, /* 12 MHz on osc1 */ -+}; -+ - /* Initialized by bootloader-specific startup code. */ - struct tag *bootloader_tags __initdata; - -@@ -37,11 +44,16 @@ static struct eth_platform_data __initda - static struct spi_board_info spi0_board_info[] __initdata = { - { - .modalias = "mtd_dataflash", -- .max_speed_hz = 10000000, -+ .max_speed_hz = 8000000, - .chip_select = 0, - }, - }; - -+static struct mci_platform_data __initdata mci0_data = { -+ .detect_pin = GPIO_PIN_PC(25), -+ .wp_pin = GPIO_PIN_PE(0), -+}; -+ - /* - * The next two functions should go away as the boot loader is - * supposed to initialize the macb address registers with a valid -@@ -124,6 +136,7 @@ static struct platform_device ngw_gpio_l - } - }; - -+#ifdef CONFIG_BOARD_ATNGW100_I2C_GPIO - static struct i2c_gpio_platform_data i2c_gpio_data = { - .sda_pin = GPIO_PIN_PA(6), - .scl_pin = GPIO_PIN_PA(7), -@@ -139,6 +152,7 @@ static struct platform_device i2c_gpio_d - .platform_data = &i2c_gpio_data, - }, - }; -+#endif - - static int __init atngw100_init(void) - { -@@ -157,6 +171,7 @@ static int __init atngw100_init(void) - set_hw_addr(at32_add_device_eth(1, ð_data[1])); - - at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); -+ at32_add_device_mci(0, &mci0_data); - at32_add_device_usba(0, NULL); - - for (i = 0; i < ARRAY_SIZE(ngw_leds); i++) { -@@ -165,11 +180,15 @@ static int __init atngw100_init(void) - } - platform_device_register(&ngw_gpio_leds); - -+#ifdef CONFIG_BOARD_ATNGW100_I2C_GPIO - at32_select_gpio(i2c_gpio_data.sda_pin, - AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - at32_select_gpio(i2c_gpio_data.scl_pin, - AT32_GPIOF_MULTIDRV | AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); - platform_device_register(&i2c_gpio_device); -+#else -+ at32_add_device_twi(0, NULL, 0); -+#endif - - return 0; - } ---- a/arch/avr32/boards/atstk1000/Kconfig -+++ b/arch/avr32/boards/atstk1000/Kconfig -@@ -18,6 +18,10 @@ config BOARD_ATSTK1004 - bool "ATSTK1004" - select CPU_AT32AP7002 - -+config BOARD_ATSTK1006 -+ bool "ATSTK1006" -+ select CPU_AT32AP7000 -+ - endchoice - - -@@ -102,4 +106,60 @@ config BOARD_ATSTK1000_EXTDAC - depends on !BOARD_ATSTK100X_SW1_CUSTOM && !BOARD_ATSTK100X_SW3_CUSTOM - default y - -+config BOARD_ATSTK100X_ENABLE_AC97 -+ bool "Use AC97C instead of ABDAC" -+ help -+ Select this if you want to use the built-in AC97 controller -+ instead of the built-in Audio Bitstream DAC. These share -+ the same I/O pins on the AP7000, so both can't be enabled -+ at the same time. -+ -+ Note that the STK1000 kit doesn't ship with an AC97 codec on -+ board, so say N unless you've got an expansion board with an -+ AC97 codec on it that you want to use. -+ -+config BOARD_ATSTK1000_CF_HACKS -+ bool "ATSTK1000 CompactFlash hacks" -+ depends on !BOARD_ATSTK100X_SW4_CUSTOM -+ help -+ Select this if you have re-routed the CompactFlash RESET and -+ CD signals to GPIOs on your STK1000. This is necessary for -+ reset and card detection to work properly, although some CF -+ cards may be able to cope without reset. -+ -+config BOARD_ATSTK1000_CF_RESET_PIN -+ hex "CompactFlash RESET pin" -+ default 0x30 -+ depends on BOARD_ATSTK1000_CF_HACKS -+ help -+ Select which GPIO pin to use for the CompactFlash RESET -+ signal. This is specified as a hexadecimal number and should -+ be defined as 0x20 * gpio_port + pin. -+ -+ The default is 0x30, which is pin 16 on PIOB, aka GPIO14. -+ -+config BOARD_ATSTK1000_CF_DETECT_PIN -+ hex "CompactFlash DETECT pin" -+ default 0x3e -+ depends on BOARD_ATSTK1000_CF_HACKS -+ help -+ Select which GPIO pin to use for the CompactFlash CD -+ signal. This is specified as a hexadecimal number and should -+ be defined as 0x20 * gpio_port + pin. -+ -+ The default is 0x3e, which is pin 30 on PIOB, aka GPIO15. -+ -+config BOARD_ATSTK100X_ENABLE_PSIF -+ bool "Enable PSIF peripheral (PS/2 support)" -+ default n -+ help -+ Select this if you want to use the PSIF peripheral to hook up PS/2 -+ devices to your STK1000. This will require a hardware modification to -+ work correctly, since PS/2 devices require 5 volt power and signals, -+ while the STK1000 only provides 3.3 volt. -+ -+ Say N if you have not modified the hardware to boost the voltage, say -+ Y if you have level convertion hardware or a PS/2 device capable of -+ operating on 3.3 volt. -+ - endif # stk 1000 ---- a/arch/avr32/boards/atstk1000/Makefile -+++ b/arch/avr32/boards/atstk1000/Makefile -@@ -2,3 +2,4 @@ obj-y += setup.o flash.o - obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o - obj-$(CONFIG_BOARD_ATSTK1003) += atstk1003.o - obj-$(CONFIG_BOARD_ATSTK1004) += atstk1004.o -+obj-$(CONFIG_BOARD_ATSTK1006) += atstk1002.o ---- a/arch/avr32/boards/atstk1000/atstk1002.c -+++ b/arch/avr32/boards/atstk1000/atstk1002.c -@@ -1,7 +1,7 @@ - /* -- * ATSTK1002 daughterboard-specific init code -+ * ATSTK1002/ATSTK1006 daughterboard-specific init code - * -- * Copyright (C) 2005-2006 Atmel Corporation -+ * Copyright (C) 2005-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 -@@ -28,6 +28,80 @@ - - #include "atstk1000.h" - -+/* Oscillator frequencies. These are board specific */ -+unsigned long at32_board_osc_rates[3] = { -+ [0] = 32768, /* 32.768 kHz on RTC osc */ -+ [1] = 20000000, /* 20 MHz on osc0 */ -+ [2] = 12000000, /* 12 MHz on osc1 */ -+}; -+ -+/* -+ * The ATSTK1006 daughterboard is very similar to the ATSTK1002. Both -+ * have the AT32AP7000 chip on board; the difference is that the -+ * STK1006 has 128 MB SDRAM (the STK1002 uses the 8 MB SDRAM chip on -+ * the STK1000 motherboard) and 256 MB NAND flash (the STK1002 has -+ * none.) -+ * -+ * The RAM difference is handled by the boot loader, so the only -+ * difference we end up handling here is the NAND flash. -+ */ -+#ifdef CONFIG_BOARD_ATSTK1006 -+#include <linux/mtd/partitions.h> -+#include <asm/arch/smc.h> -+ -+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, -+ /* WE# high -> RE# low min 60 ns */ -+ .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 = 2, -+ .tdf_mode = 0, -+}; -+ -+static struct mtd_partition nand_partitions[] = { -+ { -+ .name = "main", -+ .offset = 0x00000000, -+ .size = MTDPART_SIZ_FULL, -+ }, -+}; -+ -+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 atstk1006_nand_data __initdata = { -+ .cle = 21, -+ .ale = 22, -+ .rdy_pin = GPIO_PIN_PB(30), -+ .enable_pin = GPIO_PIN_PB(29), -+ .partition_info = nand_part_info, -+}; -+#endif - - struct eth_addr { - u8 addr[6]; -@@ -83,6 +157,19 @@ static struct spi_board_info spi1_board_ - } }; - #endif - -+static struct cf_platform_data __initdata cf0_data = { -+#ifdef CONFIG_BOARD_ATSTK1000_CF_HACKS -+ .detect_pin = CONFIG_BOARD_ATSTK1000_CF_DETECT_PIN, -+ .reset_pin = CONFIG_BOARD_ATSTK1000_CF_RESET_PIN, -+#else -+ .detect_pin = GPIO_PIN_NONE, -+ .reset_pin = GPIO_PIN_NONE, -+#endif -+ .vcc_pin = GPIO_PIN_NONE, -+ .ready_pin = GPIO_PIN_PB(27), -+ .cs = 4, -+}; -+ - /* - * The next two functions should go away as the boot loader is - * supposed to initialize the macb address registers with a valid -@@ -212,6 +299,12 @@ static int __init atstk1002_init(void) - - at32_add_system_devices(); - -+#ifdef CONFIG_BOARD_ATSTK1006 -+ smc_set_timing(&nand_config, &nand_timing); -+ smc_set_configuration(3, &nand_config); -+ at32_add_device_nand(0, &atstk1006_nand_data); -+#endif -+ - #ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM - at32_add_device_usart(1); - #else -@@ -228,16 +321,30 @@ static int __init atstk1002_init(void) - #ifdef CONFIG_BOARD_ATSTK100X_SPI1 - at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); - #endif -+ at32_add_device_twi(0, NULL, 0); -+#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM -+ at32_add_device_mci(0, NULL); -+#endif - #ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM - set_hw_addr(at32_add_device_eth(1, ð_data[1])); - #else - at32_add_device_lcdc(0, &atstk1000_lcdc_data, -- fbmem_start, fbmem_size); -+ fbmem_start, fbmem_size, 0); - #endif - at32_add_device_usba(0, NULL); -+#ifdef CONFIG_BOARD_ATSTK100X_ENABLE_AC97 -+ at32_add_device_ac97c(0, NULL); -+#else -+ at32_add_device_abdac(0); -+#endif - #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM - at32_add_device_ssc(0, ATMEL_SSC_TX); - #endif -+ at32_add_device_cf(0, 2, &cf0_data); -+#ifdef CONFIG_BOARD_ATSTK100X_ENABLE_PSIF -+ at32_add_device_psif(0); -+ at32_add_device_psif(1); -+#endif - - atstk1000_setup_j2_leds(); - atstk1002_setup_extdac(); ---- a/arch/avr32/boards/atstk1000/atstk1003.c -+++ b/arch/avr32/boards/atstk1000/atstk1003.c -@@ -27,6 +27,13 @@ - - #include "atstk1000.h" - -+/* Oscillator frequencies. These are board specific */ -+unsigned long at32_board_osc_rates[3] = { -+ [0] = 32768, /* 32.768 kHz on RTC osc */ -+ [1] = 20000000, /* 20 MHz on osc0 */ -+ [2] = 12000000, /* 12 MHz on osc1 */ -+}; -+ - #ifdef CONFIG_BOARD_ATSTK1000_EXTDAC - static struct at73c213_board_info at73c213_data = { - .ssc_id = 0, -@@ -59,6 +66,19 @@ static struct spi_board_info spi1_board_ - } }; - #endif - -+static struct cf_platform_data __initdata cf0_data = { -+#ifdef CONFIG_BOARD_ATSTK1000_CF_HACKS -+ .detect_pin = CONFIG_BOARD_ATSTK1000_CF_DETECT_PIN, -+ .reset_pin = CONFIG_BOARD_ATSTK1000_CF_RESET_PIN, -+#else -+ .detect_pin = GPIO_PIN_NONE, -+ .reset_pin = GPIO_PIN_NONE, -+#endif -+ .vcc_pin = GPIO_PIN_NONE, -+ .ready_pin = GPIO_PIN_PB(27), -+ .cs = 4, -+}; -+ - #ifdef CONFIG_BOARD_ATSTK1000_EXTDAC - static void __init atstk1003_setup_extdac(void) - { -@@ -147,12 +167,22 @@ static int __init atstk1003_init(void) - at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); - #endif - #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM -- at32_add_device_mci(0); -+ at32_add_device_mci(0, NULL); - #endif - at32_add_device_usba(0, NULL); -+#ifdef CONFIG_BOARD_ATSTK100X_ENABLE_AC97 -+ at32_add_device_ac97c(0, NULL); -+#else -+ at32_add_device_abdac(0); -+#endif - #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM - at32_add_device_ssc(0, ATMEL_SSC_TX); - #endif -+ at32_add_device_cf(0, 2, &cf0_data); -+#ifdef CONFIG_BOARD_ATSTK100X_ENABLE_PSIF -+ at32_add_device_psif(0); -+ at32_add_device_psif(1); -+#endif - - atstk1000_setup_j2_leds(); - atstk1003_setup_extdac(); ---- a/arch/avr32/boards/atstk1000/atstk1004.c -+++ b/arch/avr32/boards/atstk1000/atstk1004.c -@@ -29,6 +29,13 @@ - - #include "atstk1000.h" - -+/* Oscillator frequencies. These are board specific */ -+unsigned long at32_board_osc_rates[3] = { -+ [0] = 32768, /* 32.768 kHz on RTC osc */ -+ [1] = 20000000, /* 20 MHz on osc0 */ -+ [2] = 12000000, /* 12 MHz on osc1 */ -+}; -+ - #ifdef CONFIG_BOARD_ATSTK1000_EXTDAC - static struct at73c213_board_info at73c213_data = { - .ssc_id = 0, -@@ -130,14 +137,23 @@ static int __init atstk1004_init(void) - at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); - #endif - #ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM -- at32_add_device_mci(0); -+ at32_add_device_mci(0, NULL); - #endif - at32_add_device_lcdc(0, &atstk1000_lcdc_data, -- fbmem_start, fbmem_size); -+ fbmem_start, fbmem_size, 0); - at32_add_device_usba(0, NULL); -+#ifdef CONFIG_BOARD_ATSTK100X_ENABLE_AC97 -+ at32_add_device_ac97c(0, NULL); -+#else -+ at32_add_device_abdac(0); -+#endif - #ifndef CONFIG_BOARD_ATSTK100X_SW3_CUSTOM - at32_add_device_ssc(0, ATMEL_SSC_TX); - #endif -+#ifdef CONFIG_BOARD_ATSTK100X_ENABLE_PSIF -+ at32_add_device_psif(0); -+ at32_add_device_psif(1); -+#endif - - atstk1000_setup_j2_leds(); - atstk1004_setup_extdac(); ---- a/arch/avr32/configs/atngw100_defconfig -+++ b/arch/avr32/configs/atngw100_defconfig -@@ -1,7 +1,7 @@ - # - # Automatically generated make config: don't edit --# Linux kernel version: 2.6.24-rc7 --# Wed Jan 9 23:20:41 2008 -+# Linux kernel version: 2.6.25.4 -+# Wed Jun 11 15:23:36 2008 - # - CONFIG_AVR32=y - CONFIG_GENERIC_GPIO=y -@@ -13,10 +13,10 @@ 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_ARCH_SUPPORTS_OPROFILE=y - CONFIG_GENERIC_HWEIGHT=y - CONFIG_GENERIC_CALIBRATE_DELAY=y - CONFIG_GENERIC_BUG=y -@@ -37,17 +37,15 @@ CONFIG_POSIX_MQUEUE=y - CONFIG_BSD_PROCESS_ACCT=y - CONFIG_BSD_PROCESS_ACCT_V3=y - # CONFIG_TASKSTATS is not set --# CONFIG_USER_NS is not set --# CONFIG_PID_NS is not set - # CONFIG_AUDIT is not set - # CONFIG_IKCONFIG is not set - CONFIG_LOG_BUF_SHIFT=14 - # CONFIG_CGROUPS is not set --CONFIG_FAIR_GROUP_SCHED=y --CONFIG_FAIR_USER_SCHED=y --# CONFIG_FAIR_CGROUP_SCHED is not set -+# CONFIG_GROUP_SCHED is not set - CONFIG_SYSFS_DEPRECATED=y -+CONFIG_SYSFS_DEPRECATED_V2=y - # CONFIG_RELAY is not set -+# CONFIG_NAMESPACES is not set - CONFIG_BLK_DEV_INITRD=y - CONFIG_INITRAMFS_SOURCE="" - CONFIG_CC_OPTIMIZE_FOR_SIZE=y -@@ -61,11 +59,13 @@ 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 -@@ -73,6 +73,14 @@ 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_KPROBES=y -+# CONFIG_HAVE_KRETPROBES is not set -+CONFIG_PROC_PAGE_MONITOR=y - CONFIG_SLABINFO=y - CONFIG_RT_MUTEXES=y - # CONFIG_TINY_SHMEM is not set -@@ -101,10 +109,15 @@ CONFIG_IOSCHED_CFQ=y - 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 -@@ -113,6 +126,7 @@ CONFIG_CPU_AT32AP700X=y - CONFIG_CPU_AT32AP7000=y - # CONFIG_BOARD_ATSTK1000 is not set - CONFIG_BOARD_ATNGW100=y -+CONFIG_BOARD_ATNGW100_I2C_GPIO=y - CONFIG_LOADER_U_BOOT=y - - # -@@ -121,6 +135,7 @@ CONFIG_LOADER_U_BOOT=y - # CONFIG_AP700X_32_BIT_SMC is not set - CONFIG_AP700X_16_BIT_SMC=y - # CONFIG_AP700X_8_BIT_SMC is not set -+CONFIG_GPIO_DEV=y - CONFIG_LOAD_ADDRESS=0x10000000 - CONFIG_ENTRY_ADDRESS=0x90000000 - CONFIG_PHYS_OFFSET=0x10000000 -@@ -146,16 +161,26 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 - CONFIG_ZONE_DMA_FLAG=0 - CONFIG_VIRT_TO_BUS=y - # CONFIG_OWNERSHIP_TRACE is not set -+CONFIG_NMI_DEBUGGING=y -+CONFIG_DW_DMAC=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_CMDLINE="" - - # - # Power management options - # -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_PM=y -+# CONFIG_PM_LEGACY is not set -+# CONFIG_PM_DEBUG is not set -+CONFIG_PM_SLEEP=y -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=y - - # - # CPU Frequency scaling -@@ -164,9 +189,9 @@ 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=y -+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set - # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set --# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND 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 -@@ -202,6 +227,7 @@ CONFIG_XFRM=y - CONFIG_XFRM_USER=y - # CONFIG_XFRM_SUB_POLICY is not set - # CONFIG_XFRM_MIGRATE is not set -+# CONFIG_XFRM_STATISTICS is not set - CONFIG_NET_KEY=y - # CONFIG_NET_KEY_MIGRATE is not set - CONFIG_INET=y -@@ -260,82 +286,33 @@ CONFIG_IPV6_SIT=y - # CONFIG_NETWORK_SECMARK is not set - CONFIG_NETFILTER=y - # CONFIG_NETFILTER_DEBUG is not set --CONFIG_BRIDGE_NETFILTER=y -+# CONFIG_NETFILTER_ADVANCED is not set - - # - # Core Netfilter Configuration - # --# CONFIG_NETFILTER_NETLINK is not set --CONFIG_NF_CONNTRACK_ENABLED=m -+CONFIG_NETFILTER_NETLINK=m -+CONFIG_NETFILTER_NETLINK_LOG=m - CONFIG_NF_CONNTRACK=m --CONFIG_NF_CT_ACCT=y --CONFIG_NF_CONNTRACK_MARK=y --# CONFIG_NF_CONNTRACK_EVENTS is not set --CONFIG_NF_CT_PROTO_GRE=m --# CONFIG_NF_CT_PROTO_SCTP is not set --# CONFIG_NF_CT_PROTO_UDPLITE is not set --CONFIG_NF_CONNTRACK_AMANDA=m - CONFIG_NF_CONNTRACK_FTP=m --CONFIG_NF_CONNTRACK_H323=m - CONFIG_NF_CONNTRACK_IRC=m --CONFIG_NF_CONNTRACK_NETBIOS_NS=m --CONFIG_NF_CONNTRACK_PPTP=m --CONFIG_NF_CONNTRACK_SANE=m - CONFIG_NF_CONNTRACK_SIP=m --CONFIG_NF_CONNTRACK_TFTP=m -+CONFIG_NF_CT_NETLINK=m - CONFIG_NETFILTER_XTABLES=y --CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m --# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set --# CONFIG_NETFILTER_XT_TARGET_DSCP is not set - CONFIG_NETFILTER_XT_TARGET_MARK=m --CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m - CONFIG_NETFILTER_XT_TARGET_NFLOG=m --# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set --# CONFIG_NETFILTER_XT_TARGET_TRACE is not set - CONFIG_NETFILTER_XT_TARGET_TCPMSS=m --CONFIG_NETFILTER_XT_MATCH_COMMENT=m --CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m --# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set --CONFIG_NETFILTER_XT_MATCH_CONNMARK=m - CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m --# CONFIG_NETFILTER_XT_MATCH_DCCP is not set --# CONFIG_NETFILTER_XT_MATCH_DSCP is not set --CONFIG_NETFILTER_XT_MATCH_ESP=m --CONFIG_NETFILTER_XT_MATCH_HELPER=m --CONFIG_NETFILTER_XT_MATCH_LENGTH=m --CONFIG_NETFILTER_XT_MATCH_LIMIT=m --CONFIG_NETFILTER_XT_MATCH_MAC=m - CONFIG_NETFILTER_XT_MATCH_MARK=m - CONFIG_NETFILTER_XT_MATCH_POLICY=m --CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m --# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set --CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m --CONFIG_NETFILTER_XT_MATCH_QUOTA=m --CONFIG_NETFILTER_XT_MATCH_REALM=m --# CONFIG_NETFILTER_XT_MATCH_SCTP is not set - CONFIG_NETFILTER_XT_MATCH_STATE=m --CONFIG_NETFILTER_XT_MATCH_STATISTIC=m --CONFIG_NETFILTER_XT_MATCH_STRING=m --CONFIG_NETFILTER_XT_MATCH_TCPMSS=m --# CONFIG_NETFILTER_XT_MATCH_TIME is not set --# CONFIG_NETFILTER_XT_MATCH_U32 is not set --CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m - - # - # IP: Netfilter Configuration - # - CONFIG_NF_CONNTRACK_IPV4=m - CONFIG_NF_CONNTRACK_PROC_COMPAT=y --# CONFIG_IP_NF_QUEUE is not set - CONFIG_IP_NF_IPTABLES=m --CONFIG_IP_NF_MATCH_IPRANGE=m --CONFIG_IP_NF_MATCH_TOS=m --CONFIG_IP_NF_MATCH_RECENT=m --CONFIG_IP_NF_MATCH_ECN=m --CONFIG_IP_NF_MATCH_AH=m --CONFIG_IP_NF_MATCH_TTL=m --CONFIG_IP_NF_MATCH_OWNER=m --CONFIG_IP_NF_MATCH_ADDRTYPE=m - CONFIG_IP_NF_FILTER=m - CONFIG_IP_NF_TARGET_REJECT=m - CONFIG_IP_NF_TARGET_LOG=m -@@ -343,54 +320,25 @@ CONFIG_IP_NF_TARGET_LOG=m - CONFIG_NF_NAT=m - CONFIG_NF_NAT_NEEDED=y - CONFIG_IP_NF_TARGET_MASQUERADE=m --CONFIG_IP_NF_TARGET_REDIRECT=m --CONFIG_IP_NF_TARGET_NETMAP=m --CONFIG_IP_NF_TARGET_SAME=m --CONFIG_NF_NAT_SNMP_BASIC=m --CONFIG_NF_NAT_PROTO_GRE=m - CONFIG_NF_NAT_FTP=m - CONFIG_NF_NAT_IRC=m --CONFIG_NF_NAT_TFTP=m --CONFIG_NF_NAT_AMANDA=m --CONFIG_NF_NAT_PPTP=m --CONFIG_NF_NAT_H323=m -+# CONFIG_NF_NAT_TFTP is not set -+# CONFIG_NF_NAT_AMANDA is not set -+# CONFIG_NF_NAT_PPTP is not set -+# CONFIG_NF_NAT_H323 is not set - CONFIG_NF_NAT_SIP=m - CONFIG_IP_NF_MANGLE=m --CONFIG_IP_NF_TARGET_TOS=m --CONFIG_IP_NF_TARGET_ECN=m --CONFIG_IP_NF_TARGET_TTL=m --CONFIG_IP_NF_TARGET_CLUSTERIP=m --CONFIG_IP_NF_RAW=m --CONFIG_IP_NF_ARPTABLES=m --CONFIG_IP_NF_ARPFILTER=m --CONFIG_IP_NF_ARP_MANGLE=m - - # --# IPv6: Netfilter Configuration (EXPERIMENTAL) -+# IPv6: Netfilter Configuration - # - CONFIG_NF_CONNTRACK_IPV6=m --CONFIG_IP6_NF_QUEUE=m - CONFIG_IP6_NF_IPTABLES=m --CONFIG_IP6_NF_MATCH_RT=m --CONFIG_IP6_NF_MATCH_OPTS=m --CONFIG_IP6_NF_MATCH_FRAG=m --CONFIG_IP6_NF_MATCH_HL=m --CONFIG_IP6_NF_MATCH_OWNER=m - CONFIG_IP6_NF_MATCH_IPV6HEADER=m --CONFIG_IP6_NF_MATCH_AH=m --CONFIG_IP6_NF_MATCH_MH=m --CONFIG_IP6_NF_MATCH_EUI64=m - CONFIG_IP6_NF_FILTER=m - CONFIG_IP6_NF_TARGET_LOG=m - CONFIG_IP6_NF_TARGET_REJECT=m - CONFIG_IP6_NF_MANGLE=m --CONFIG_IP6_NF_TARGET_HL=m --CONFIG_IP6_NF_RAW=m -- --# --# Bridge: Netfilter Configuration --# --# CONFIG_BRIDGE_NF_EBTABLES is not set - # CONFIG_IP_DCCP is not set - # CONFIG_IP_SCTP is not set - # CONFIG_TIPC is not set -@@ -407,7 +355,6 @@ CONFIG_LLC=m - # CONFIG_ECONET is not set - # CONFIG_WAN_ROUTER is not set - # CONFIG_NET_SCHED is not set --CONFIG_NET_CLS_ROUTE=y - - # - # Network testing -@@ -415,6 +362,7 @@ CONFIG_NET_CLS_ROUTE=y - # 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 -@@ -531,11 +479,18 @@ 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_RAM_BLOCKSIZE=1024 -+# CONFIG_BLK_DEV_XIP is not set - # CONFIG_CDROM_PKTCDVD is not set - # CONFIG_ATA_OVER_ETH is not set --# CONFIG_MISC_DEVICES is not set --# CONFIG_IDE is not set -+CONFIG_MISC_DEVICES=y -+# CONFIG_ATMEL_PWM is not set -+CONFIG_ATMEL_TCLIB=y -+CONFIG_ATMEL_TCB_CLKSRC=y -+CONFIG_ATMEL_TCB_CLKSRC_BLOCK=0 -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_ATMEL_SSC is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_HAVE_IDE is not set - - # - # SCSI device support -@@ -568,11 +523,13 @@ CONFIG_PHYLIB=y - # 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 -@@ -599,7 +556,6 @@ CONFIG_PPPOE=m - # CONFIG_PPPOL2TP is not set - # CONFIG_SLIP is not set - CONFIG_SLHC=m --# CONFIG_SHAPER is not set - # CONFIG_NETCONSOLE is not set - # CONFIG_NETPOLL is not set - # CONFIG_NET_POLL_CONTROLLER is not set -@@ -633,6 +589,7 @@ CONFIG_SLHC=m - # - 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 -@@ -640,8 +597,6 @@ CONFIG_UNIX98_PTYS=y - # CONFIG_LEGACY_PTYS is not set - # CONFIG_IPMI_HANDLER is not set - # CONFIG_HW_RANDOM is not set --# CONFIG_RTC is not set --# CONFIG_GEN_RTC is not set - # CONFIG_R3964 is not set - # CONFIG_RAW_DRIVER is not set - # CONFIG_TCG_TPM is not set -@@ -659,6 +614,7 @@ CONFIG_I2C_ALGOBIT=m - # - # I2C Hardware Bus support - # -+CONFIG_I2C_ATMELTWI=m - CONFIG_I2C_GPIO=m - # CONFIG_I2C_OCORES is not set - # CONFIG_I2C_PARPORT_LIGHT is not set -@@ -669,13 +625,12 @@ CONFIG_I2C_GPIO=m - # - # Miscellaneous I2C Chip support - # --# CONFIG_SENSORS_DS1337 is not set --# CONFIG_SENSORS_DS1374 is not set - # CONFIG_DS1682 is not set - # CONFIG_SENSORS_EEPROM is not set - # CONFIG_SENSORS_PCF8574 is not set --# CONFIG_SENSORS_PCA9539 is not set -+# CONFIG_PCF8575 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 -@@ -702,9 +657,27 @@ CONFIG_SPI_ATMEL=y - # CONFIG_SPI_AT25 is not set - CONFIG_SPI_SPIDEV=m - # CONFIG_SPI_TLE62X0 is not set -+CONFIG_HAVE_GPIO_LIB=y -+ -+# -+# GPIO Support -+# -+# CONFIG_DEBUG_GPIO is not set -+ -+# -+# I2C GPIO expanders: -+# -+# CONFIG_GPIO_PCA953X is not set -+# CONFIG_GPIO_PCF857X is not set -+ -+# -+# SPI GPIO expanders: -+# -+# 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_WATCHDOG=y - # CONFIG_WATCHDOG_NOWAYOUT is not set - -@@ -757,10 +730,6 @@ CONFIG_USB_SUPPORT=y - # - # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' - # -- --# --# USB Gadget Support --# - CONFIG_USB_GADGET=y - # CONFIG_USB_GADGET_DEBUG is not set - # CONFIG_USB_GADGET_DEBUG_FILES is not set -@@ -787,21 +756,24 @@ 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_MMC=m -+# CONFIG_USB_G_PRINTER 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=m -+CONFIG_MMC_BLOCK=y - CONFIG_MMC_BLOCK_BOUNCE=y - # CONFIG_SDIO_UART is not set - - # - # MMC/SD Host Controller Drivers - # -+CONFIG_MMC_ATMELMCI=y - CONFIG_MMC_SPI=m -+# CONFIG_MEMSTICK is not set - CONFIG_NEW_LEDS=y - CONFIG_LEDS_CLASS=y - -@@ -844,19 +816,22 @@ CONFIG_RTC_INTF_DEV=y - # 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 - - # - # SPI RTC drivers - # --# CONFIG_RTC_DRV_RS5C348 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_STK17TA8 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 -@@ -874,25 +849,23 @@ CONFIG_RTC_DRV_AT32AP700X=y - # - # 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 - # CONFIG_XFS_FS is not set - # CONFIG_GFS2_FS is not set - # CONFIG_OCFS2_FS is not set --# CONFIG_MINIX_FS is not set --# CONFIG_ROMFS_FS is not set -+# CONFIG_DNOTIFY is not set - CONFIG_INOTIFY=y - CONFIG_INOTIFY_USER=y - # CONFIG_QUOTA is not set --# CONFIG_DNOTIFY is not set - # CONFIG_AUTOFS_FS is not set - # CONFIG_AUTOFS4_FS is not set - CONFIG_FUSE_FS=m -@@ -923,7 +896,7 @@ CONFIG_SYSFS=y - 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 -@@ -948,8 +921,10 @@ CONFIG_JFFS2_RTIME=y - # CONFIG_JFFS2_RUBIN is not set - # CONFIG_CRAMFS is not set - # CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_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 -@@ -1030,11 +1005,6 @@ CONFIG_NLS_ISO8859_1=m - # CONFIG_NLS_KOI8_U is not set - CONFIG_NLS_UTF8=m - # CONFIG_DLM is not set --CONFIG_INSTRUMENTATION=y --CONFIG_PROFILING=y --CONFIG_OPROFILE=m --CONFIG_KPROBES=y --# CONFIG_MARKERS is not set - - # - # Kernel hacking -@@ -1053,6 +1023,7 @@ CONFIG_SCHED_DEBUG=y - # CONFIG_SCHEDSTATS is not set - # CONFIG_TIMER_STATS 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 -@@ -1069,9 +1040,10 @@ CONFIG_DEBUG_BUGVERBOSE=y - # CONFIG_DEBUG_LIST is not set - # CONFIG_DEBUG_SG is not set - CONFIG_FRAME_POINTER=y --# CONFIG_FORCED_INLINING is not set - # 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 -@@ -1084,7 +1056,9 @@ CONFIG_FRAME_POINTER=y - # CONFIG_SECURITY_FILE_CAPABILITIES is not set - CONFIG_CRYPTO=y - CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_AEAD=y - CONFIG_CRYPTO_BLKCIPHER=y -+# CONFIG_CRYPTO_SEQIV is not set - CONFIG_CRYPTO_HASH=y - CONFIG_CRYPTO_MANAGER=y - CONFIG_CRYPTO_HMAC=y -@@ -1103,6 +1077,9 @@ CONFIG_CRYPTO_CBC=y - CONFIG_CRYPTO_PCBC=m - # CONFIG_CRYPTO_LRW is not set - # CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_CTR is not set -+# CONFIG_CRYPTO_GCM is not set -+# CONFIG_CRYPTO_CCM is not set - # CONFIG_CRYPTO_CRYPTD is not set - CONFIG_CRYPTO_DES=y - # CONFIG_CRYPTO_FCRYPT is not set -@@ -1117,12 +1094,14 @@ CONFIG_CRYPTO_ARC4=m - # CONFIG_CRYPTO_KHAZAD is not set - # CONFIG_CRYPTO_ANUBIS is not set - # CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SALSA20 is not set - CONFIG_CRYPTO_DEFLATE=y - # CONFIG_CRYPTO_MICHAEL_MIC is not set - # CONFIG_CRYPTO_CRC32C is not set - # CONFIG_CRYPTO_CAMELLIA is not set - # CONFIG_CRYPTO_TEST is not set --# CONFIG_CRYPTO_AUTHENC is not set -+CONFIG_CRYPTO_AUTHENC=y -+# CONFIG_CRYPTO_LZO is not set - CONFIG_CRYPTO_HW=y - - # -@@ -1137,10 +1116,7 @@ CONFIG_CRC7=m - # CONFIG_LIBCRC32C is not set - CONFIG_ZLIB_INFLATE=y - CONFIG_ZLIB_DEFLATE=y --CONFIG_TEXTSEARCH=y --CONFIG_TEXTSEARCH_KMP=m --CONFIG_TEXTSEARCH_BM=m --CONFIG_TEXTSEARCH_FSM=m -+CONFIG_GENERIC_ALLOCATOR=y - CONFIG_PLIST=y - CONFIG_HAS_IOMEM=y - CONFIG_HAS_IOPORT=y ---- a/arch/avr32/configs/atstk1002_defconfig -+++ b/arch/avr32/configs/atstk1002_defconfig -@@ -1,7 +1,7 @@ - # - # Automatically generated make config: don't edit --# Linux kernel version: 2.6.24-rc7 --# Wed Jan 9 23:07:43 2008 -+# Linux kernel version: 2.6.25.4 -+# Wed Jun 11 15:29:18 2008 - # - CONFIG_AVR32=y - CONFIG_GENERIC_GPIO=y -@@ -13,10 +13,10 @@ 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_ARCH_SUPPORTS_OPROFILE=y - CONFIG_GENERIC_HWEIGHT=y - CONFIG_GENERIC_CALIBRATE_DELAY=y - CONFIG_GENERIC_BUG=y -@@ -36,15 +36,15 @@ CONFIG_SYSVIPC_SYSCTL=y - CONFIG_POSIX_MQUEUE=y - # CONFIG_BSD_PROCESS_ACCT is not set - # CONFIG_TASKSTATS is not set --# CONFIG_USER_NS is not set --# CONFIG_PID_NS is not set - # CONFIG_AUDIT is not set - # CONFIG_IKCONFIG is not set - CONFIG_LOG_BUF_SHIFT=14 - # CONFIG_CGROUPS is not set --# CONFIG_FAIR_GROUP_SCHED 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 -@@ -58,11 +58,13 @@ 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 -@@ -70,6 +72,14 @@ 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_KPROBES=y -+# CONFIG_HAVE_KRETPROBES is not set -+CONFIG_PROC_PAGE_MONITOR=y - CONFIG_SLABINFO=y - CONFIG_RT_MUTEXES=y - # CONFIG_TINY_SHMEM is not set -@@ -98,10 +108,15 @@ CONFIG_IOSCHED_CFQ=y - 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 -@@ -113,12 +128,16 @@ CONFIG_BOARD_ATSTK1000=y - CONFIG_BOARD_ATSTK1002=y - # CONFIG_BOARD_ATSTK1003 is not set - # CONFIG_BOARD_ATSTK1004 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_LED8 is not set - # CONFIG_BOARD_ATSTK1000_J2_RGB is not set - CONFIG_BOARD_ATSTK1000_EXTDAC=y -+# CONFIG_BOARD_ATSTK100X_ENABLE_AC97 is not set -+# CONFIG_BOARD_ATSTK1000_CF_HACKS is not set -+# CONFIG_BOARD_ATSTK100X_ENABLE_PSIF is not set - CONFIG_LOADER_U_BOOT=y - - # -@@ -127,6 +146,7 @@ CONFIG_LOADER_U_BOOT=y - # CONFIG_AP700X_32_BIT_SMC is not set - CONFIG_AP700X_16_BIT_SMC=y - # CONFIG_AP700X_8_BIT_SMC is not set -+CONFIG_GPIO_DEV=y - CONFIG_LOAD_ADDRESS=0x10000000 - CONFIG_ENTRY_ADDRESS=0x90000000 - CONFIG_PHYS_OFFSET=0x10000000 -@@ -152,16 +172,26 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 - CONFIG_ZONE_DMA_FLAG=0 - CONFIG_VIRT_TO_BUS=y - # CONFIG_OWNERSHIP_TRACE is not set -+CONFIG_NMI_DEBUGGING=y -+CONFIG_DW_DMAC=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_CMDLINE="" - - # - # Power management options - # -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_PM=y -+# CONFIG_PM_LEGACY is not set -+# CONFIG_PM_DEBUG is not set -+CONFIG_PM_SLEEP=y -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=y - - # - # CPU Frequency scaling -@@ -170,9 +200,9 @@ 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=y -+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set - # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set --# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND 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 -@@ -208,6 +238,7 @@ 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_NET_KEY=m - # CONFIG_NET_KEY_MIGRATE is not set - CONFIG_INET=y -@@ -279,6 +310,7 @@ CONFIG_LLC=m - # 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 -@@ -395,13 +427,18 @@ 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_RAM_BLOCKSIZE=1024 -+# 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_IDE is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_HAVE_IDE is not set - - # - # SCSI device support -@@ -444,6 +481,7 @@ CONFIG_SCSI_WAIT_SCAN=m - # CONFIG_SCSI_LOWLEVEL is not set - CONFIG_ATA=m - # CONFIG_ATA_NONSTANDARD is not set -+# CONFIG_SATA_MV is not set - CONFIG_PATA_AT32=m - # CONFIG_PATA_PLATFORM is not set - # CONFIG_MD is not set -@@ -469,11 +507,13 @@ CONFIG_PHYLIB=y - # 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 -@@ -500,7 +540,6 @@ CONFIG_PPP_BSDCOMP=m - # CONFIG_PPPOL2TP is not set - # CONFIG_SLIP is not set - CONFIG_SLHC=m --# CONFIG_SHAPER is not set - # CONFIG_NETCONSOLE is not set - # CONFIG_NETPOLL is not set - # CONFIG_NET_POLL_CONTROLLER is not set -@@ -568,6 +607,7 @@ CONFIG_MOUSE_GPIO=m - # - 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 -@@ -575,8 +615,6 @@ CONFIG_UNIX98_PTYS=y - # CONFIG_LEGACY_PTYS is not set - # CONFIG_IPMI_HANDLER is not set - # CONFIG_HW_RANDOM is not set --# CONFIG_RTC is not set --# CONFIG_GEN_RTC is not set - # CONFIG_R3964 is not set - # CONFIG_RAW_DRIVER is not set - # CONFIG_TCG_TPM is not set -@@ -594,6 +632,7 @@ CONFIG_I2C_ALGOBIT=m - # - # I2C Hardware Bus support - # -+CONFIG_I2C_ATMELTWI=m - CONFIG_I2C_GPIO=m - # CONFIG_I2C_OCORES is not set - # CONFIG_I2C_PARPORT_LIGHT is not set -@@ -604,13 +643,12 @@ CONFIG_I2C_GPIO=m - # - # Miscellaneous I2C Chip support - # --# CONFIG_SENSORS_DS1337 is not set --# CONFIG_SENSORS_DS1374 is not set - # CONFIG_DS1682 is not set - # CONFIG_SENSORS_EEPROM is not set - # CONFIG_SENSORS_PCF8574 is not set --# CONFIG_SENSORS_PCA9539 is not set -+# CONFIG_PCF8575 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 -@@ -637,9 +675,27 @@ CONFIG_SPI_ATMEL=y - # CONFIG_SPI_AT25 is not set - CONFIG_SPI_SPIDEV=m - # CONFIG_SPI_TLE62X0 is not set -+CONFIG_HAVE_GPIO_LIB=y -+ -+# -+# GPIO Support -+# -+# CONFIG_DEBUG_GPIO is not set -+ -+# -+# I2C GPIO expanders: -+# -+# CONFIG_GPIO_PCA953X is not set -+# CONFIG_GPIO_PCF857X is not set -+ -+# -+# SPI GPIO expanders: -+# -+# 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_WATCHDOG=y - # CONFIG_WATCHDOG_NOWAYOUT is not set - -@@ -732,12 +788,18 @@ CONFIG_SND_PCM_OSS_PLUGINS=y - # - # Generic devices - # -+CONFIG_SND_AC97_CODEC=m - # 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 - - # -+# AVR32 devices -+# -+CONFIG_SND_ATMEL_AC97=m -+ -+# - # SPI devices - # - CONFIG_SND_AT73C213=m -@@ -753,9 +815,14 @@ CONFIG_SND_AT73C213_TARGET_BITRATE=48000 - # - - # -+# ALSA SoC audio for Freescale SOCs -+# -+ -+# - # Open Sound System - # - # CONFIG_SOUND_PRIME is not set -+CONFIG_AC97_BUS=m - # CONFIG_HID_SUPPORT is not set - CONFIG_USB_SUPPORT=y - # CONFIG_USB_ARCH_HAS_HCD is not set -@@ -765,10 +832,6 @@ CONFIG_USB_SUPPORT=y - # - # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' - # -- --# --# USB Gadget Support --# - CONFIG_USB_GADGET=y - # CONFIG_USB_GADGET_DEBUG is not set - # CONFIG_USB_GADGET_DEBUG_FILES is not set -@@ -796,27 +859,31 @@ 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_MMC=m -+# CONFIG_USB_G_PRINTER 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=m -+CONFIG_MMC_BLOCK=y - CONFIG_MMC_BLOCK_BOUNCE=y - # CONFIG_SDIO_UART is not set - - # - # MMC/SD Host Controller Drivers - # -+CONFIG_MMC_ATMELMCI=y - 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_GPIO=m - - # -@@ -853,19 +920,22 @@ CONFIG_RTC_INTF_DEV=y - # 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 - - # - # SPI RTC drivers - # --# CONFIG_RTC_DRV_RS5C348 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_STK17TA8 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 -@@ -883,13 +953,13 @@ CONFIG_RTC_DRV_AT32AP700X=y - # - # 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 -@@ -897,12 +967,10 @@ CONFIG_JBD=m - # CONFIG_XFS_FS is not set - # CONFIG_GFS2_FS is not set - # CONFIG_OCFS2_FS is not set --CONFIG_MINIX_FS=m --# CONFIG_ROMFS_FS is not set -+# CONFIG_DNOTIFY is not set - CONFIG_INOTIFY=y - CONFIG_INOTIFY_USER=y - # CONFIG_QUOTA is not set --# CONFIG_DNOTIFY is not set - # CONFIG_AUTOFS_FS is not set - # CONFIG_AUTOFS4_FS is not set - CONFIG_FUSE_FS=m -@@ -933,7 +1001,7 @@ CONFIG_SYSFS=y - 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 -@@ -957,8 +1025,10 @@ CONFIG_JFFS2_RTIME=y - # CONFIG_JFFS2_RUBIN is not set - # CONFIG_CRAMFS is not set - # CONFIG_VXFS_FS is not set -+CONFIG_MINIX_FS=m - # 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 -@@ -1028,11 +1098,6 @@ CONFIG_NLS_ISO8859_1=m - # CONFIG_NLS_KOI8_U is not set - CONFIG_NLS_UTF8=m - # CONFIG_DLM is not set --CONFIG_INSTRUMENTATION=y --CONFIG_PROFILING=y --CONFIG_OPROFILE=m --CONFIG_KPROBES=y --# CONFIG_MARKERS is not set - - # - # Kernel hacking -@@ -1051,6 +1116,7 @@ CONFIG_SCHED_DEBUG=y - # CONFIG_SCHEDSTATS is not set - # CONFIG_TIMER_STATS 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 -@@ -1067,9 +1133,10 @@ CONFIG_DEBUG_BUGVERBOSE=y - # CONFIG_DEBUG_LIST is not set - # CONFIG_DEBUG_SG is not set - CONFIG_FRAME_POINTER=y --CONFIG_FORCED_INLINING=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 -@@ -1082,7 +1149,9 @@ CONFIG_FORCED_INLINING=y - # CONFIG_SECURITY_FILE_CAPABILITIES is not set - CONFIG_CRYPTO=y - CONFIG_CRYPTO_ALGAPI=m -+CONFIG_CRYPTO_AEAD=m - CONFIG_CRYPTO_BLKCIPHER=m -+# CONFIG_CRYPTO_SEQIV is not set - CONFIG_CRYPTO_HASH=m - CONFIG_CRYPTO_MANAGER=m - CONFIG_CRYPTO_HMAC=m -@@ -1101,6 +1170,9 @@ CONFIG_CRYPTO_CBC=m - # CONFIG_CRYPTO_PCBC is not set - # CONFIG_CRYPTO_LRW is not set - # CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_CTR is not set -+# CONFIG_CRYPTO_GCM is not set -+# CONFIG_CRYPTO_CCM is not set - # CONFIG_CRYPTO_CRYPTD is not set - CONFIG_CRYPTO_DES=m - # CONFIG_CRYPTO_FCRYPT is not set -@@ -1115,12 +1187,14 @@ CONFIG_CRYPTO_DES=m - # CONFIG_CRYPTO_KHAZAD is not set - # CONFIG_CRYPTO_ANUBIS is not set - # CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SALSA20 is not set - CONFIG_CRYPTO_DEFLATE=m - # CONFIG_CRYPTO_MICHAEL_MIC is not set - # CONFIG_CRYPTO_CRC32C is not set - # CONFIG_CRYPTO_CAMELLIA is not set - # CONFIG_CRYPTO_TEST is not set --# CONFIG_CRYPTO_AUTHENC is not set -+CONFIG_CRYPTO_AUTHENC=m -+# CONFIG_CRYPTO_LZO is not set - # CONFIG_CRYPTO_HW is not set - - # -@@ -1135,6 +1209,7 @@ CONFIG_CRC7=m - # CONFIG_LIBCRC32C is not set - CONFIG_ZLIB_INFLATE=y - CONFIG_ZLIB_DEFLATE=y -+CONFIG_GENERIC_ALLOCATOR=y - CONFIG_PLIST=y - CONFIG_HAS_IOMEM=y - CONFIG_HAS_IOPORT=y ---- a/arch/avr32/configs/atstk1003_defconfig -+++ b/arch/avr32/configs/atstk1003_defconfig -@@ -1,7 +1,7 @@ - # - # Automatically generated make config: don't edit --# Linux kernel version: 2.6.24-rc7 --# Wed Jan 9 22:54:34 2008 -+# Linux kernel version: 2.6.25.4 -+# Wed Jun 11 15:33:36 2008 - # - CONFIG_AVR32=y - CONFIG_GENERIC_GPIO=y -@@ -13,10 +13,10 @@ 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_ARCH_SUPPORTS_OPROFILE=y - CONFIG_GENERIC_HWEIGHT=y - CONFIG_GENERIC_CALIBRATE_DELAY=y - CONFIG_GENERIC_BUG=y -@@ -39,17 +39,15 @@ CONFIG_BSD_PROCESS_ACCT_V3=y - CONFIG_TASKSTATS=y - CONFIG_TASK_DELAY_ACCT=y - # CONFIG_TASK_XACCT is not set --# CONFIG_USER_NS is not set --# CONFIG_PID_NS is not set - CONFIG_AUDIT=y - # CONFIG_IKCONFIG is not set - CONFIG_LOG_BUF_SHIFT=14 - # CONFIG_CGROUPS is not set --CONFIG_FAIR_GROUP_SCHED=y --CONFIG_FAIR_USER_SCHED=y --# CONFIG_FAIR_CGROUP_SCHED 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 -@@ -63,11 +61,13 @@ 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 -@@ -75,6 +75,14 @@ CONFIG_VM_EVENT_COUNTERS=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_KPROBES=y -+# CONFIG_HAVE_KRETPROBES is not set -+CONFIG_PROC_PAGE_MONITOR=y - CONFIG_SLABINFO=y - CONFIG_RT_MUTEXES=y - # CONFIG_TINY_SHMEM is not set -@@ -103,10 +111,15 @@ CONFIG_IOSCHED_CFQ=y - 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 -@@ -118,12 +131,16 @@ CONFIG_BOARD_ATSTK1000=y - # CONFIG_BOARD_ATSTK1002 is not set - CONFIG_BOARD_ATSTK1003=y - # CONFIG_BOARD_ATSTK1004 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_LED8 is not set - # CONFIG_BOARD_ATSTK1000_J2_RGB is not set - CONFIG_BOARD_ATSTK1000_EXTDAC=y -+# CONFIG_BOARD_ATSTK100X_ENABLE_AC97 is not set -+# CONFIG_BOARD_ATSTK1000_CF_HACKS is not set -+# CONFIG_BOARD_ATSTK100X_ENABLE_PSIF is not set - CONFIG_LOADER_U_BOOT=y - - # -@@ -132,6 +149,7 @@ CONFIG_LOADER_U_BOOT=y - # CONFIG_AP700X_32_BIT_SMC is not set - CONFIG_AP700X_16_BIT_SMC=y - # CONFIG_AP700X_8_BIT_SMC is not set -+CONFIG_GPIO_DEV=y - CONFIG_LOAD_ADDRESS=0x10000000 - CONFIG_ENTRY_ADDRESS=0x90000000 - CONFIG_PHYS_OFFSET=0x10000000 -@@ -157,16 +175,26 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 - CONFIG_ZONE_DMA_FLAG=0 - CONFIG_VIRT_TO_BUS=y - # CONFIG_OWNERSHIP_TRACE is not set -+CONFIG_NMI_DEBUGGING=y -+CONFIG_DW_DMAC=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_CMDLINE="" - - # - # Power management options - # -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_PM=y -+# CONFIG_PM_LEGACY is not set -+# CONFIG_PM_DEBUG is not set -+CONFIG_PM_SLEEP=y -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=y - - # - # CPU Frequency scaling -@@ -175,9 +203,9 @@ 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=y -+# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set - # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set --# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND 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 -@@ -260,6 +288,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" - # 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 -@@ -376,13 +405,18 @@ 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_RAM_BLOCKSIZE=1024 -+# 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_IDE is not set -+# CONFIG_ENCLOSURE_SERVICES is not set -+# CONFIG_HAVE_IDE is not set - - # - # SCSI device support -@@ -427,6 +461,7 @@ CONFIG_SCSI_LOWLEVEL=y - # CONFIG_SCSI_DEBUG is not set - CONFIG_ATA=m - # CONFIG_ATA_NONSTANDARD is not set -+# CONFIG_SATA_MV is not set - CONFIG_PATA_AT32=m - # CONFIG_PATA_PLATFORM is not set - # CONFIG_MD is not set -@@ -460,7 +495,6 @@ CONFIG_PPP_BSDCOMP=m - # CONFIG_PPPOL2TP is not set - # CONFIG_SLIP is not set - CONFIG_SLHC=m --# CONFIG_SHAPER is not set - # CONFIG_NETCONSOLE is not set - # CONFIG_NETPOLL is not set - # CONFIG_NET_POLL_CONTROLLER is not set -@@ -528,6 +562,7 @@ CONFIG_MOUSE_GPIO=m - # - 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 -@@ -535,8 +570,6 @@ CONFIG_UNIX98_PTYS=y - # CONFIG_LEGACY_PTYS is not set - # CONFIG_IPMI_HANDLER is not set - # CONFIG_HW_RANDOM is not set --# CONFIG_RTC is not set --# CONFIG_GEN_RTC is not set - # CONFIG_R3964 is not set - # CONFIG_RAW_DRIVER is not set - # CONFIG_TCG_TPM is not set -@@ -554,6 +587,7 @@ CONFIG_I2C_ALGOBIT=m - # - # I2C Hardware Bus support - # -+CONFIG_I2C_ATMELTWI=m - CONFIG_I2C_GPIO=m - # CONFIG_I2C_OCORES is not set - # CONFIG_I2C_PARPORT_LIGHT is not set -@@ -564,13 +598,12 @@ CONFIG_I2C_GPIO=m - # - # Miscellaneous I2C Chip support - # --# CONFIG_SENSORS_DS1337 is not set --# CONFIG_SENSORS_DS1374 is not set - # CONFIG_DS1682 is not set - # CONFIG_SENSORS_EEPROM is not set - # CONFIG_SENSORS_PCF8574 is not set --# CONFIG_SENSORS_PCA9539 is not set -+# CONFIG_PCF8575 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 -@@ -597,9 +630,27 @@ CONFIG_SPI_ATMEL=y - # CONFIG_SPI_AT25 is not set - CONFIG_SPI_SPIDEV=m - # CONFIG_SPI_TLE62X0 is not set -+CONFIG_HAVE_GPIO_LIB=y -+ -+# -+# GPIO Support -+# -+# CONFIG_DEBUG_GPIO is not set -+ -+# -+# I2C GPIO expanders: -+# -+# CONFIG_GPIO_PCA953X is not set -+# CONFIG_GPIO_PCF857X is not set -+ -+# -+# SPI GPIO expanders: -+# -+# 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_WATCHDOG=y - # CONFIG_WATCHDOG_NOWAYOUT is not set - -@@ -665,12 +716,18 @@ CONFIG_SND_VERBOSE_PROCFS=y - # - # Generic devices - # -+CONFIG_SND_AC97_CODEC=m - # 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 - - # -+# AVR32 devices -+# -+CONFIG_SND_ATMEL_AC97=m -+ -+# - # SPI devices - # - CONFIG_SND_AT73C213=m -@@ -686,9 +743,14 @@ CONFIG_SND_AT73C213_TARGET_BITRATE=48000 - # - - # -+# ALSA SoC audio for Freescale SOCs -+# -+ -+# - # Open Sound System - # - # CONFIG_SOUND_PRIME is not set -+CONFIG_AC97_BUS=m - # CONFIG_HID_SUPPORT is not set - CONFIG_USB_SUPPORT=y - # CONFIG_USB_ARCH_HAS_HCD is not set -@@ -698,10 +760,6 @@ CONFIG_USB_SUPPORT=y - # - # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' - # -- --# --# USB Gadget Support --# - CONFIG_USB_GADGET=y - # CONFIG_USB_GADGET_DEBUG is not set - # CONFIG_USB_GADGET_DEBUG_FILES is not set -@@ -729,27 +787,31 @@ 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_MMC=m -+# CONFIG_USB_G_PRINTER 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=m -+CONFIG_MMC_BLOCK=y - # CONFIG_MMC_BLOCK_BOUNCE is not set - # CONFIG_SDIO_UART is not set - - # - # MMC/SD Host Controller Drivers - # -+CONFIG_MMC_ATMELMCI=y - CONFIG_MMC_SPI=m -+# CONFIG_MEMSTICK is not set - CONFIG_NEW_LEDS=y - CONFIG_LEDS_CLASS=y - - # - # LED drivers - # -+CONFIG_LEDS_ATMEL_PWM=m - CONFIG_LEDS_GPIO=y - - # -@@ -786,19 +848,22 @@ CONFIG_RTC_INTF_DEV=y - # 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 - - # - # SPI RTC drivers - # --# CONFIG_RTC_DRV_RS5C348 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_STK17TA8 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 -@@ -816,13 +881,13 @@ CONFIG_UIO=m - # - # 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 -@@ -830,12 +895,10 @@ CONFIG_JBD=m - # CONFIG_XFS_FS is not set - # CONFIG_GFS2_FS is not set - # CONFIG_OCFS2_FS is not set --# CONFIG_MINIX_FS is not set --# CONFIG_ROMFS_FS is not set -+# CONFIG_DNOTIFY is not set - CONFIG_INOTIFY=y - CONFIG_INOTIFY_USER=y - # CONFIG_QUOTA is not set --# CONFIG_DNOTIFY is not set - # CONFIG_AUTOFS_FS is not set - # CONFIG_AUTOFS4_FS is not set - CONFIG_FUSE_FS=m -@@ -866,7 +929,7 @@ CONFIG_SYSFS=y - 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 -@@ -891,8 +954,10 @@ CONFIG_JFFS2_RTIME=y - # CONFIG_JFFS2_RUBIN is not set - # CONFIG_CRAMFS is not set - # CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_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 -@@ -943,11 +1008,6 @@ CONFIG_NLS_ISO8859_1=m - # CONFIG_NLS_KOI8_U is not set - CONFIG_NLS_UTF8=m - # CONFIG_DLM is not set --CONFIG_INSTRUMENTATION=y --CONFIG_PROFILING=y --CONFIG_OPROFILE=m --CONFIG_KPROBES=y --# CONFIG_MARKERS is not set - - # - # Kernel hacking -@@ -965,6 +1025,7 @@ CONFIG_DETECT_SOFTLOCKUP=y - CONFIG_SCHED_DEBUG=y - # CONFIG_SCHEDSTATS is not set - # CONFIG_TIMER_STATS 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 -@@ -981,9 +1042,10 @@ CONFIG_DEBUG_BUGVERBOSE=y - # CONFIG_DEBUG_LIST is not set - # CONFIG_DEBUG_SG is not set - CONFIG_FRAME_POINTER=y --CONFIG_FORCED_INLINING=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 -@@ -1009,6 +1071,7 @@ CONFIG_CRC7=m - CONFIG_AUDIT_GENERIC=y - CONFIG_ZLIB_INFLATE=y - CONFIG_ZLIB_DEFLATE=y -+CONFIG_GENERIC_ALLOCATOR=y - CONFIG_PLIST=y - CONFIG_HAS_IOMEM=y - CONFIG_HAS_IOPORT=y ---- a/arch/avr32/configs/atstk1004_defconfig -+++ b/arch/avr32/configs/atstk1004_defconfig -@@ -1,7 +1,7 @@ - # - # Automatically generated make config: don't edit --# Linux kernel version: 2.6.24-rc7 --# Wed Jan 9 23:04:20 2008 -+# Linux kernel version: 2.6.25.4 -+# Wed Jun 11 15:37:49 2008 - # - CONFIG_AVR32=y - CONFIG_GENERIC_GPIO=y -@@ -13,10 +13,10 @@ 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_ARCH_SUPPORTS_OPROFILE=y - CONFIG_GENERIC_HWEIGHT=y - CONFIG_GENERIC_CALIBRATE_DELAY=y - CONFIG_GENERIC_BUG=y -@@ -34,15 +34,15 @@ CONFIG_LOCALVERSION="" - # CONFIG_POSIX_MQUEUE is not set - # CONFIG_BSD_PROCESS_ACCT is not set - # CONFIG_TASKSTATS is not set --# CONFIG_USER_NS is not set --# CONFIG_PID_NS is not set - # CONFIG_AUDIT is not set - # CONFIG_IKCONFIG is not set - CONFIG_LOG_BUF_SHIFT=14 - # CONFIG_CGROUPS is not set --# CONFIG_FAIR_GROUP_SCHED is not set -+# CONFIG_GROUP_SCHED is not set - CONFIG_SYSFS_DEPRECATED=y -+CONFIG_SYSFS_DEPRECATED_V2=y - # CONFIG_RELAY is not set -+# CONFIG_NAMESPACES is not set - # CONFIG_BLK_DEV_INITRD is not set - CONFIG_CC_OPTIMIZE_FOR_SIZE=y - CONFIG_SYSCTL=y -@@ -54,24 +54,37 @@ 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 is not set - # CONFIG_EPOLL is not set - # CONFIG_SIGNALFD is not set -+# CONFIG_TIMERFD is not set - # CONFIG_EVENTFD is not set - CONFIG_SHMEM=y - CONFIG_VM_EVENT_COUNTERS=y - # CONFIG_SLAB is not set - # CONFIG_SLUB is not set - CONFIG_SLOB=y -+# CONFIG_PROFILING is not set -+# CONFIG_MARKERS is not set -+CONFIG_HAVE_OPROFILE=y -+CONFIG_HAVE_KPROBES=y -+# CONFIG_HAVE_KRETPROBES is not set -+# CONFIG_PROC_PAGE_MONITOR is not set - # CONFIG_TINY_SHMEM is not set - CONFIG_BASE_SMALL=1 - # CONFIG_MODULES is not set - # CONFIG_BLOCK is not set -+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_GENERIC_CLOCKEVENTS_BUILD=y - CONFIG_SUBARCH_AVR32B=y - CONFIG_MMU=y - CONFIG_PERFORMANCE_COUNTERS=y -@@ -83,10 +96,14 @@ CONFIG_BOARD_ATSTK1000=y - # CONFIG_BOARD_ATSTK1002 is not set - # CONFIG_BOARD_ATSTK1003 is not set - CONFIG_BOARD_ATSTK1004=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 is not set - CONFIG_BOARD_ATSTK1000_EXTDAC=y -+# CONFIG_BOARD_ATSTK100X_ENABLE_AC97 is not set -+# CONFIG_BOARD_ATSTK1000_CF_HACKS is not set -+# CONFIG_BOARD_ATSTK100X_ENABLE_PSIF is not set - CONFIG_LOADER_U_BOOT=y - - # -@@ -95,6 +112,7 @@ CONFIG_LOADER_U_BOOT=y - # CONFIG_AP700X_32_BIT_SMC is not set - CONFIG_AP700X_16_BIT_SMC=y - # CONFIG_AP700X_8_BIT_SMC is not set -+# CONFIG_GPIO_DEV is not set - CONFIG_LOAD_ADDRESS=0x10000000 - CONFIG_ENTRY_ADDRESS=0x90000000 - CONFIG_PHYS_OFFSET=0x10000000 -@@ -120,34 +138,26 @@ CONFIG_SPLIT_PTLOCK_CPUS=4 - CONFIG_ZONE_DMA_FLAG=0 - CONFIG_VIRT_TO_BUS=y - # CONFIG_OWNERSHIP_TRACE is not set -+# CONFIG_NMI_DEBUGGING is not set -+CONFIG_DW_DMAC=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_CMDLINE="" - - # - # Power management options - # -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+# CONFIG_PM is not set - - # - # 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=y --# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set --# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set --# 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 -+# CONFIG_CPU_FREQ is not set - - # - # Bus options -@@ -222,6 +232,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic" - # - # CONFIG_NET_PKTGEN 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 -@@ -321,6 +332,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 - # CONFIG_MTD_UBI is not set - # CONFIG_PARPORT is not set - # CONFIG_MISC_DEVICES is not set -+# CONFIG_HAVE_IDE is not set - - # - # SCSI device support -@@ -358,6 +370,7 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 - # - CONFIG_SERIAL_ATMEL=y - CONFIG_SERIAL_ATMEL_CONSOLE=y -+# CONFIG_SERIAL_ATMEL_PDC is not set - # CONFIG_SERIAL_ATMEL_TTYAT is not set - CONFIG_SERIAL_CORE=y - CONFIG_SERIAL_CORE_CONSOLE=y -@@ -365,8 +378,6 @@ CONFIG_UNIX98_PTYS=y - # CONFIG_LEGACY_PTYS is not set - # CONFIG_IPMI_HANDLER is not set - # CONFIG_HW_RANDOM is not set --# CONFIG_RTC is not set --# CONFIG_GEN_RTC is not set - # CONFIG_R3964 is not set - # CONFIG_TCG_TPM is not set - # CONFIG_I2C is not set -@@ -389,9 +400,24 @@ CONFIG_SPI_ATMEL=y - # CONFIG_SPI_AT25 is not set - # CONFIG_SPI_SPIDEV is not set - # CONFIG_SPI_TLE62X0 is not set -+CONFIG_HAVE_GPIO_LIB=y -+ -+# -+# GPIO Support -+# -+ -+# -+# I2C GPIO expanders: -+# -+ -+# -+# SPI GPIO expanders: -+# -+# 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_WATCHDOG=y - # CONFIG_WATCHDOG_NOWAYOUT is not set - -@@ -471,10 +497,6 @@ CONFIG_USB_SUPPORT=y - # - # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' - # -- --# --# USB Gadget Support --# - CONFIG_USB_GADGET=y - # CONFIG_USB_GADGET_DEBUG_FILES is not set - CONFIG_USB_GADGET_SELECTED=y -@@ -499,7 +521,9 @@ CONFIG_USB_ETH=y - # CONFIG_USB_FILE_STORAGE is not set - # CONFIG_USB_G_SERIAL is not set - # CONFIG_USB_MIDI_GADGET is not set -+# CONFIG_USB_G_PRINTER is not set - # CONFIG_MMC is not set -+# CONFIG_MEMSTICK is not set - # CONFIG_NEW_LEDS is not set - CONFIG_RTC_LIB=y - CONFIG_RTC_CLASS=y -@@ -519,15 +543,17 @@ CONFIG_RTC_INTF_DEV=y - # - # SPI RTC drivers - # --# CONFIG_RTC_DRV_RS5C348 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_STK17TA8 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 -@@ -545,9 +571,9 @@ CONFIG_RTC_DRV_AT32AP700X=y - # - # File systems - # -+# CONFIG_DNOTIFY is not set - # CONFIG_INOTIFY is not set - # CONFIG_QUOTA is not set --# CONFIG_DNOTIFY is not set - # CONFIG_AUTOFS_FS is not set - # CONFIG_AUTOFS4_FS is not set - # CONFIG_FUSE_FS is not set -@@ -580,7 +606,6 @@ CONFIG_JFFS2_RTIME=y - # CONFIG_NETWORK_FILESYSTEMS is not set - # CONFIG_NLS is not set - # CONFIG_DLM is not set --# CONFIG_INSTRUMENTATION is not set - - # - # Kernel hacking -@@ -616,6 +641,7 @@ CONFIG_CRC32=y - # CONFIG_LIBCRC32C is not set - CONFIG_ZLIB_INFLATE=y - CONFIG_ZLIB_DEFLATE=y -+CONFIG_GENERIC_ALLOCATOR=y - CONFIG_HAS_IOMEM=y - CONFIG_HAS_IOPORT=y - CONFIG_HAS_DMA=y ---- /dev/null -+++ b/arch/avr32/configs/atstk1006_defconfig -@@ -0,0 +1,1235 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.25.4 -+# Wed Jun 11 15:40:45 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_KPROBES=y -+# CONFIG_HAVE_KRETPROBES is not set -+CONFIG_PROC_PAGE_MONITOR=y -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+# CONFIG_TINY_SHMEM is not set -+CONFIG_BASE_SMALL=1 -+CONFIG_MODULES=y -+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 is not set -+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 -+ -+# -+# 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_PLATFORM_AT32AP=y -+CONFIG_CPU_AT32AP700X=y -+CONFIG_CPU_AT32AP7000=y -+CONFIG_BOARD_ATSTK1000=y -+# CONFIG_BOARD_ATNGW100 is not set -+# CONFIG_BOARD_ATSTK1002 is not set -+# CONFIG_BOARD_ATSTK1003 is not set -+# CONFIG_BOARD_ATSTK1004 is not set -+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_LED8 is not set -+# CONFIG_BOARD_ATSTK1000_J2_RGB is not set -+CONFIG_BOARD_ATSTK1000_EXTDAC=y -+# CONFIG_BOARD_ATSTK100X_ENABLE_AC97 is not set -+# CONFIG_BOARD_ATSTK1000_CF_HACKS is not set -+# CONFIG_BOARD_ATSTK100X_ENABLE_PSIF is not set -+CONFIG_LOADER_U_BOOT=y -+ -+# -+# Atmel AVR32 AP options -+# -+# CONFIG_AP700X_32_BIT_SMC is not set -+CONFIG_AP700X_16_BIT_SMC=y -+# CONFIG_AP700X_8_BIT_SMC is not set -+CONFIG_GPIO_DEV=y -+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_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_SPLIT_PTLOCK_CPUS=4 -+# CONFIG_RESOURCES_64BIT is not set -+CONFIG_ZONE_DMA_FLAG=0 -+CONFIG_VIRT_TO_BUS=y -+# CONFIG_OWNERSHIP_TRACE is not set -+CONFIG_NMI_DEBUGGING=y -+CONFIG_DW_DMAC=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_CMDLINE="" -+ -+# -+# Power management options -+# -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+CONFIG_PM=y -+# CONFIG_PM_LEGACY is not set -+# CONFIG_PM_DEBUG is not set -+CONFIG_PM_SLEEP=y -+CONFIG_SUSPEND=y -+CONFIG_SUSPEND_FREEZER=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_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 -+ -+# -+# Networking -+# -+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_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_TUNNEL=m -+# CONFIG_IPV6_MULTIPLE_TABLES 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=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 -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+# 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_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 is not set -+# 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_ONENAND is not set -+ -+# -+# UBI - Unsorted block images -+# -+CONFIG_MTD_UBI=m -+CONFIG_MTD_UBI_WL_THRESHOLD=4096 -+CONFIG_MTD_UBI_BEB_RESERVE=1 -+CONFIG_MTD_UBI_GLUEBI=y -+ -+# -+# 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_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_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_ATA=m -+# CONFIG_ATA_NONSTANDARD is not set -+# 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_NETDEVICES_MULTIQUEUE is not set -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+CONFIG_TUN=m -+# 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_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=m -+# 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_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 is not set -+# 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 -+ -+# -+# I2C Algorithms -+# -+CONFIG_I2C_ALGOBIT=m -+# CONFIG_I2C_ALGOPCF is not set -+# CONFIG_I2C_ALGOPCA is not set -+ -+# -+# I2C Hardware Bus support -+# -+CONFIG_I2C_ATMELTWI=m -+CONFIG_I2C_GPIO=m -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_STUB is not set -+ -+# -+# Miscellaneous I2C Chip support -+# -+# CONFIG_DS1682 is not set -+# CONFIG_SENSORS_EEPROM is not set -+# CONFIG_SENSORS_PCF8574 is not set -+# CONFIG_PCF8575 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 -+ -+# -+# SPI support -+# -+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_HAVE_GPIO_LIB=y -+ -+# -+# GPIO Support -+# -+# CONFIG_DEBUG_GPIO is not set -+ -+# -+# I2C GPIO expanders: -+# -+# CONFIG_GPIO_PCA953X is not set -+# CONFIG_GPIO_PCF857X is not set -+ -+# -+# SPI GPIO expanders: -+# -+# 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_WATCHDOG=y -+# CONFIG_WATCHDOG_NOWAYOUT is not set -+ -+# -+# Watchdog Device Drivers -+# -+# CONFIG_SOFT_WATCHDOG is not set -+CONFIG_AT32AP700X_WDT=y -+ -+# -+# Sonics Silicon Backplane -+# -+CONFIG_SSB_POSSIBLE=y -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_SM501 is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+# 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_SYS_FOPS is not set -+CONFIG_FB_DEFERRED_IO=y -+# 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_VIRTUAL is not set -+CONFIG_BACKLIGHT_LCD_SUPPORT=y -+CONFIG_LCD_CLASS_DEVICE=y -+CONFIG_LCD_LTV350QV=y -+# CONFIG_BACKLIGHT_CLASS_DEVICE is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+# CONFIG_LOGO is not set -+ -+# -+# Sound -+# -+CONFIG_SOUND=m -+ -+# -+# Advanced Linux Sound Architecture -+# -+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 -+ -+# -+# Generic devices -+# -+CONFIG_SND_AC97_CODEC=m -+# 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 -+ -+# -+# AVR32 devices -+# -+CONFIG_SND_ATMEL_AC97=m -+ -+# -+# SPI devices -+# -+CONFIG_SND_AT73C213=m -+CONFIG_SND_AT73C213_TARGET_BITRATE=48000 -+ -+# -+# System on Chip audio support -+# -+# CONFIG_SND_SOC is not set -+ -+# -+# SoC Audio support for SuperH -+# -+ -+# -+# ALSA SoC audio for Freescale SOCs -+# -+ -+# -+# Open Sound System -+# -+# CONFIG_SOUND_PRIME is not set -+CONFIG_AC97_BUS=m -+# 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 -+ -+# -+# 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 -+CONFIG_USB_ATMEL_USBA=y -+# CONFIG_USB_GADGET_FSL_USB2 is not set -+# CONFIG_USB_GADGET_NET2280 is not set -+# CONFIG_USB_GADGET_PXA2XX is not set -+# CONFIG_USB_GADGET_M66592 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_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 -+ -+# -+# MMC/SD Host Controller Drivers -+# -+CONFIG_MMC_ATMELMCI=y -+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_GPIO=m -+ -+# -+# LED Triggers -+# -+CONFIG_LEDS_TRIGGERS=y -+CONFIG_LEDS_TRIGGER_TIMER=m -+CONFIG_LEDS_TRIGGER_HEARTBEAT=m -+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 -+ -+# -+# SPI RTC drivers -+# -+# 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=y -+ -+# -+# Userspace I/O -+# -+# 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_GFS2_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 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_CRAMFS is not set -+# CONFIG_VXFS_FS is not set -+CONFIG_MINIX_FS=m -+# 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_NFS_DIRECTIO is not set -+# CONFIG_NFSD is not set -+CONFIG_ROOT_NFS=y -+CONFIG_LOCKD=y -+CONFIG_LOCKD_V4=y -+CONFIG_NFS_COMMON=y -+CONFIG_SUNRPC=y -+# CONFIG_SUNRPC_BIND34 is not set -+# 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_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_SCHED_DEBUG=y -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_TIMER_STATS 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_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 -+CONFIG_CRYPTO_ALGAPI=m -+CONFIG_CRYPTO_AEAD=m -+CONFIG_CRYPTO_BLKCIPHER=m -+# CONFIG_CRYPTO_SEQIV is not set -+CONFIG_CRYPTO_HASH=m -+CONFIG_CRYPTO_MANAGER=m -+CONFIG_CRYPTO_HMAC=m -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=m -+CONFIG_CRYPTO_SHA1=m -+# CONFIG_CRYPTO_SHA256 is not set -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_WP512 is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_GF128MUL is not set -+# CONFIG_CRYPTO_ECB is not set -+CONFIG_CRYPTO_CBC=m -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_CTR is not set -+# CONFIG_CRYPTO_GCM is not set -+# CONFIG_CRYPTO_CCM is not set -+# CONFIG_CRYPTO_CRYPTD is not set -+CONFIG_CRYPTO_DES=m -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_AES is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_ARC4 is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_ANUBIS is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+CONFIG_CRYPTO_DEFLATE=m -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_CRC32C is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_TEST is not set -+CONFIG_CRYPTO_AUTHENC=m -+# CONFIG_CRYPTO_LZO is not set -+# CONFIG_CRYPTO_HW is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+CONFIG_CRC_CCITT=m -+# CONFIG_CRC16 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_GENERIC_ALLOCATOR=y -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT=y -+CONFIG_HAS_DMA=y ---- /dev/null -+++ b/arch/avr32/drivers/Makefile -@@ -0,0 +1 @@ -+obj-$(CONFIG_DW_DMAC) += dw-dmac.o ---- /dev/null -+++ b/arch/avr32/drivers/dw-dmac.c -@@ -0,0 +1,761 @@ -+/* -+ * Driver for the Synopsys DesignWare DMA Controller -+ * -+ * 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/clk.h> -+#include <linux/device.h> -+#include <linux/dma-mapping.h> -+#include <linux/dmapool.h> -+#include <linux/init.h> -+#include <linux/interrupt.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+ -+#include <asm/dma-controller.h> -+#include <asm/io.h> -+ -+#include "dw-dmac.h" -+ -+#define DMAC_NR_CHANNELS 3 -+#define DMAC_MAX_BLOCKSIZE 4095 -+ -+enum { -+ CH_STATE_FREE = 0, -+ CH_STATE_ALLOCATED, -+ CH_STATE_BUSY, -+}; -+ -+struct dw_dma_lli { -+ dma_addr_t sar; -+ dma_addr_t dar; -+ dma_addr_t llp; -+ u32 ctllo; -+ u32 ctlhi; -+ u32 sstat; -+ u32 dstat; -+}; -+ -+struct dw_dma_block { -+ struct dw_dma_lli *lli_vaddr; -+ dma_addr_t lli_dma_addr; -+}; -+ -+struct dw_dma_channel { -+ unsigned int state; -+ int is_cyclic; -+ struct dma_request_sg *req_sg; -+ struct dma_request_cyclic *req_cyclic; -+ unsigned int nr_blocks; -+ int direction; -+ struct dw_dma_block *block; -+}; -+ -+struct dw_dma_controller { -+ spinlock_t lock; -+ void * __iomem regs; -+ struct dma_pool *lli_pool; -+ struct clk *hclk; -+ struct dma_controller dma; -+ struct dw_dma_channel channel[DMAC_NR_CHANNELS]; -+}; -+#define to_dw_dmac(dmac) container_of(dmac, struct dw_dma_controller, dma) -+ -+#define dmac_writel_hi(dmac, reg, value) \ -+ __raw_writel((value), (dmac)->regs + DW_DMAC_##reg + 4) -+#define dmac_readl_hi(dmac, reg) \ -+ __raw_readl((dmac)->regs + DW_DMAC_##reg + 4) -+#define dmac_writel_lo(dmac, reg, value) \ -+ __raw_writel((value), (dmac)->regs + DW_DMAC_##reg) -+#define dmac_readl_lo(dmac, reg) \ -+ __raw_readl((dmac)->regs + DW_DMAC_##reg) -+#define dmac_chan_writel_hi(dmac, chan, reg, value) \ -+ __raw_writel((value), ((dmac)->regs + 0x58 * (chan) \ -+ + DW_DMAC_CHAN_##reg + 4)) -+#define dmac_chan_readl_hi(dmac, chan, reg) \ -+ __raw_readl((dmac)->regs + 0x58 * (chan) + DW_DMAC_CHAN_##reg + 4) -+#define dmac_chan_writel_lo(dmac, chan, reg, value) \ -+ __raw_writel((value), (dmac)->regs + 0x58 * (chan) + DW_DMAC_CHAN_##reg) -+#define dmac_chan_readl_lo(dmac, chan, reg) \ -+ __raw_readl((dmac)->regs + 0x58 * (chan) + DW_DMAC_CHAN_##reg) -+#define set_channel_bit(dmac, reg, chan) \ -+ dmac_writel_lo(dmac, reg, (1 << (chan)) | (1 << ((chan) + 8))) -+#define clear_channel_bit(dmac, reg, chan) \ -+ dmac_writel_lo(dmac, reg, (0 << (chan)) | (1 << ((chan) + 8))) -+ -+static int dmac_alloc_channel(struct dma_controller *_dmac) -+{ -+ struct dw_dma_controller *dmac = to_dw_dmac(_dmac); -+ struct dw_dma_channel *chan; -+ unsigned long flags; -+ int i; -+ -+ spin_lock_irqsave(&dmac->lock, flags); -+ for (i = 0; i < DMAC_NR_CHANNELS; i++) -+ if (dmac->channel[i].state == CH_STATE_FREE) -+ break; -+ -+ if (i < DMAC_NR_CHANNELS) { -+ chan = &dmac->channel[i]; -+ chan->state = CH_STATE_ALLOCATED; -+ } else { -+ i = -EBUSY; -+ } -+ -+ spin_unlock_irqrestore(&dmac->lock, flags); -+ -+ return i; -+} -+ -+static void dmac_release_channel(struct dma_controller *_dmac, int channel) -+{ -+ struct dw_dma_controller *dmac = to_dw_dmac(_dmac); -+ -+ BUG_ON(channel >= DMAC_NR_CHANNELS -+ || dmac->channel[channel].state != CH_STATE_ALLOCATED); -+ -+ dmac->channel[channel].state = CH_STATE_FREE; -+} -+ -+static struct dw_dma_block *allocate_blocks(struct dw_dma_controller *dmac, -+ unsigned int nr_blocks) -+{ -+ struct dw_dma_block *block; -+ void *p; -+ unsigned int i; -+ -+ block = kmalloc(nr_blocks * sizeof(*block), -+ GFP_KERNEL); -+ if (unlikely(!block)) -+ return NULL; -+ -+ for (i = 0; i < nr_blocks; i++) { -+ p = dma_pool_alloc(dmac->lli_pool, GFP_KERNEL, -+ &block[i].lli_dma_addr); -+ block[i].lli_vaddr = p; -+ if (unlikely(!p)) -+ goto fail; -+ } -+ -+ return block; -+ -+fail: -+ for (i = 0; i < nr_blocks; i++) { -+ if (!block[i].lli_vaddr) -+ break; -+ dma_pool_free(dmac->lli_pool, block[i].lli_vaddr, -+ block[i].lli_dma_addr); -+ } -+ kfree(block); -+ return NULL; -+} -+ -+static void cleanup_channel(struct dw_dma_controller *dmac, -+ struct dw_dma_channel *chan) -+{ -+ unsigned int i; -+ -+ if (chan->nr_blocks > 1) { -+ for (i = 0; i < chan->nr_blocks; i++) -+ dma_pool_free(dmac->lli_pool, chan->block[i].lli_vaddr, -+ chan->block[i].lli_dma_addr); -+ kfree(chan->block); -+ } -+ -+ chan->state = CH_STATE_ALLOCATED; -+} -+ -+static int dmac_prepare_request_sg(struct dma_controller *_dmac, -+ struct dma_request_sg *req) -+{ -+ struct dw_dma_controller *dmac = to_dw_dmac(_dmac); -+ struct dw_dma_channel *chan; -+ unsigned long ctlhi, ctllo, cfghi, cfglo; -+ unsigned long block_size; -+ unsigned int nr_blocks; -+ int ret, i, direction; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&dmac->lock, flags); -+ -+ ret = -EINVAL; -+ if (req->req.channel >= DMAC_NR_CHANNELS -+ || dmac->channel[req->req.channel].state != CH_STATE_ALLOCATED -+ || req->block_size > DMAC_MAX_BLOCKSIZE) { -+ spin_unlock_irqrestore(&dmac->lock, flags); -+ return -EINVAL; -+ } -+ -+ chan = &dmac->channel[req->req.channel]; -+ chan->state = CH_STATE_BUSY; -+ chan->req_sg = req; -+ chan->is_cyclic = 0; -+ -+ /* -+ * We have marked the channel as busy, so no need to keep the -+ * lock as long as we only touch the channel-specific -+ * registers -+ */ -+ spin_unlock_irqrestore(&dmac->lock, flags); -+ -+ /* -+ * There may be limitations in the driver and/or the DMA -+ * controller that prevents us from sending a whole -+ * scatterlist item in one go. Taking this into account, -+ * calculate the number of block transfers we need to set up. -+ * -+ * FIXME: Let the peripheral driver know about the maximum -+ * block size we support. We really don't want to use a -+ * different block size than what was suggested by the -+ * peripheral. -+ * -+ * Each block will get its own Linked List Item (LLI) below. -+ */ -+ block_size = req->block_size; -+ nr_blocks = req->nr_blocks; -+ pr_debug("block_size %lu, nr_blocks %u nr_sg = %u\n", -+ block_size, nr_blocks, req->nr_sg); -+ -+ BUG_ON(nr_blocks == 0); -+ chan->nr_blocks = nr_blocks; -+ -+ ret = -EINVAL; -+ cfglo = cfghi = 0; -+ switch (req->direction) { -+ case DMA_DIR_MEM_TO_PERIPH: -+ direction = DMA_TO_DEVICE; -+ cfghi = req->periph_id << (43 - 32); -+ break; -+ -+ case DMA_DIR_PERIPH_TO_MEM: -+ direction = DMA_FROM_DEVICE; -+ cfghi = req->periph_id << (39 - 32); -+ break; -+ default: -+ goto out_unclaim_channel; -+ } -+ -+ chan->direction = direction; -+ -+ dmac_chan_writel_hi(dmac, req->req.channel, CFG, cfghi); -+ dmac_chan_writel_lo(dmac, req->req.channel, CFG, cfglo); -+ -+ ctlhi = block_size >> req->width; -+ ctllo = ((req->direction << 20) -+ // | (1 << 14) | (1 << 11) // source/dest burst trans len -+ | (req->width << 4) | (req->width << 1) -+ | (1 << 0)); // interrupt enable -+ -+ if (nr_blocks == 1) { -+ /* Only one block: No need to use block chaining */ -+ if (direction == DMA_TO_DEVICE) { -+ dmac_chan_writel_lo(dmac, req->req.channel, SAR, -+ req->sg->dma_address); -+ dmac_chan_writel_lo(dmac, req->req.channel, DAR, -+ req->data_reg); -+ ctllo |= 2 << 7; // no dst increment -+ } else { -+ dmac_chan_writel_lo(dmac, req->req.channel, SAR, -+ req->data_reg); -+ dmac_chan_writel_lo(dmac, req->req.channel, DAR, -+ req->sg->dma_address); -+ ctllo |= 2 << 9; // no src increment -+ } -+ dmac_chan_writel_lo(dmac, req->req.channel, CTL, ctllo); -+ dmac_chan_writel_hi(dmac, req->req.channel, CTL, ctlhi); -+ pr_debug("ctl hi:lo 0x%lx:%lx\n", ctlhi, ctllo); -+ } else { -+ struct dw_dma_lli *lli, *lli_prev = NULL; -+ int j = 0, offset = 0; -+ -+ ret = -ENOMEM; -+ chan->block = allocate_blocks(dmac, nr_blocks); -+ if (!chan->block) -+ goto out_unclaim_channel; -+ -+ if (direction == DMA_TO_DEVICE) -+ ctllo |= 1 << 28 | 1 << 27 | 2 << 7; -+ else -+ ctllo |= 1 << 28 | 1 << 27 | 2 << 9; -+ -+ /* -+ * Map scatterlist items to blocks. One scatterlist -+ * item may need more than one block for the reasons -+ * mentioned above. -+ */ -+ for (i = 0; i < nr_blocks; i++) { -+ lli = chan->block[i].lli_vaddr; -+ if (lli_prev) { -+ lli_prev->llp = chan->block[i].lli_dma_addr; -+ pr_debug("lli[%d] (0x%p/0x%x): 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ i - 1, chan->block[i - 1].lli_vaddr, -+ chan->block[i - 1].lli_dma_addr, -+ lli_prev->sar, lli_prev->dar, lli_prev->llp, -+ lli_prev->ctllo, lli_prev->ctlhi); -+ } -+ lli->llp = 0; -+ lli->ctllo = ctllo; -+ lli->ctlhi = ctlhi; -+ if (direction == DMA_TO_DEVICE) { -+ lli->sar = req->sg[j].dma_address + offset; -+ lli->dar = req->data_reg; -+ } else { -+ lli->sar = req->data_reg; -+ lli->dar = req->sg[j].dma_address + offset; -+ } -+ lli_prev = lli; -+ -+ offset += block_size; -+ if (offset > req->sg[j].length) { -+ j++; -+ offset = 0; -+ } -+ } -+ -+ pr_debug("lli[%d] (0x%p/0x%x): 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ i - 1, chan->block[i - 1].lli_vaddr, -+ chan->block[i - 1].lli_dma_addr, lli_prev->sar, -+ lli_prev->dar, lli_prev->llp, -+ lli_prev->ctllo, lli_prev->ctlhi); -+ -+ /* -+ * SAR, DAR and CTL are initialized from the LLI. We -+ * only have to enable the LLI bits in CTL. -+ */ -+ dmac_chan_writel_hi(dmac, req->req.channel, CTL, 0); -+ dmac_chan_writel_lo(dmac, req->req.channel, LLP, -+ chan->block[0].lli_dma_addr); -+ dmac_chan_writel_lo(dmac, req->req.channel, CTL, 1 << 28 | 1 << 27); -+ } -+ -+ set_channel_bit(dmac, MASK_XFER, req->req.channel); -+ set_channel_bit(dmac, MASK_ERROR, req->req.channel); -+ if (req->req.block_complete) -+ set_channel_bit(dmac, MASK_BLOCK, req->req.channel); -+ else -+ clear_channel_bit(dmac, MASK_BLOCK, req->req.channel); -+ -+ return 0; -+ -+out_unclaim_channel: -+ chan->state = CH_STATE_ALLOCATED; -+ return ret; -+} -+ -+static int dmac_prepare_request_cyclic(struct dma_controller *_dmac, -+ struct dma_request_cyclic *req) -+{ -+ struct dw_dma_controller *dmac = to_dw_dmac(_dmac); -+ struct dw_dma_channel *chan; -+ unsigned long ctlhi, ctllo, cfghi, cfglo; -+ unsigned long block_size; -+ int ret, i, direction; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&dmac->lock, flags); -+ -+ block_size = (req->buffer_size/req->periods) >> req->width; -+ -+ ret = -EINVAL; -+ if (req->req.channel >= DMAC_NR_CHANNELS -+ || dmac->channel[req->req.channel].state != CH_STATE_ALLOCATED -+ || (req->periods == 0) -+ || block_size > DMAC_MAX_BLOCKSIZE) { -+ spin_unlock_irqrestore(&dmac->lock, flags); -+ return -EINVAL; -+ } -+ -+ chan = &dmac->channel[req->req.channel]; -+ chan->state = CH_STATE_BUSY; -+ chan->is_cyclic = 1; -+ chan->req_cyclic = req; -+ -+ /* -+ * We have marked the channel as busy, so no need to keep the -+ * lock as long as we only touch the channel-specific -+ * registers -+ */ -+ spin_unlock_irqrestore(&dmac->lock, flags); -+ -+ /* -+ Setup -+ */ -+ BUG_ON(req->buffer_size % req->periods); -+ /* printk(KERN_INFO "block_size = %lu, periods = %u\n", block_size, req->periods); */ -+ -+ chan->nr_blocks = req->periods; -+ -+ ret = -EINVAL; -+ cfglo = cfghi = 0; -+ switch (req->direction) { -+ case DMA_DIR_MEM_TO_PERIPH: -+ direction = DMA_TO_DEVICE; -+ cfghi = req->periph_id << (43 - 32); -+ break; -+ -+ case DMA_DIR_PERIPH_TO_MEM: -+ direction = DMA_FROM_DEVICE; -+ cfghi = req->periph_id << (39 - 32); -+ break; -+ default: -+ goto out_unclaim_channel; -+ } -+ -+ chan->direction = direction; -+ -+ dmac_chan_writel_hi(dmac, req->req.channel, CFG, cfghi); -+ dmac_chan_writel_lo(dmac, req->req.channel, CFG, cfglo); -+ -+ ctlhi = block_size; -+ ctllo = ((req->direction << 20) -+ | (req->width << 4) | (req->width << 1) -+ | (1 << 0)); // interrupt enable -+ -+ { -+ struct dw_dma_lli *lli = NULL, *lli_prev = NULL; -+ -+ ret = -ENOMEM; -+ chan->block = allocate_blocks(dmac, req->periods); -+ if (!chan->block) -+ goto out_unclaim_channel; -+ -+ if (direction == DMA_TO_DEVICE) -+ ctllo |= 1 << 28 | 1 << 27 | 2 << 7; -+ else -+ ctllo |= 1 << 28 | 1 << 27 | 2 << 9; -+ -+ /* -+ * Set up a linked list items where each period gets -+ * an item. The linked list item for the last period -+ * points back to the star of the buffer making a -+ * cyclic buffer. -+ */ -+ for (i = 0; i < req->periods; i++) { -+ lli = chan->block[i].lli_vaddr; -+ if (lli_prev) { -+ lli_prev->llp = chan->block[i].lli_dma_addr; -+ /* printk(KERN_INFO "lli[%d] (0x%p/0x%x): 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ i - 1, chan->block[i - 1].lli_vaddr, -+ chan->block[i - 1].lli_dma_addr, -+ lli_prev->sar, lli_prev->dar, lli_prev->llp, -+ lli_prev->ctllo, lli_prev->ctlhi);*/ -+ } -+ lli->llp = 0; -+ lli->ctllo = ctllo; -+ lli->ctlhi = ctlhi; -+ if (direction == DMA_TO_DEVICE) { -+ lli->sar = req->buffer_start + i*(block_size << req->width); -+ lli->dar = req->data_reg; -+ } else { -+ lli->sar = req->data_reg; -+ lli->dar = req->buffer_start + i*(block_size << req->width); -+ } -+ lli_prev = lli; -+ } -+ lli->llp = chan->block[0].lli_dma_addr; -+ -+ /*printk(KERN_INFO "lli[%d] (0x%p/0x%x): 0x%x 0x%x 0x%x 0x%x 0x%x\n", -+ i - 1, chan->block[i - 1].lli_vaddr, -+ chan->block[i - 1].lli_dma_addr, lli_prev->sar, -+ lli_prev->dar, lli_prev->llp, -+ lli_prev->ctllo, lli_prev->ctlhi); */ -+ -+ /* -+ * SAR, DAR and CTL are initialized from the LLI. We -+ * only have to enable the LLI bits in CTL. -+ */ -+ dmac_chan_writel_lo(dmac, req->req.channel, LLP, -+ chan->block[0].lli_dma_addr); -+ dmac_chan_writel_lo(dmac, req->req.channel, CTL, 1 << 28 | 1 << 27); -+ } -+ -+ clear_channel_bit(dmac, MASK_XFER, req->req.channel); -+ set_channel_bit(dmac, MASK_ERROR, req->req.channel); -+ if (req->req.block_complete) -+ set_channel_bit(dmac, MASK_BLOCK, req->req.channel); -+ else -+ clear_channel_bit(dmac, MASK_BLOCK, req->req.channel); -+ -+ return 0; -+ -+out_unclaim_channel: -+ chan->state = CH_STATE_ALLOCATED; -+ return ret; -+} -+ -+static int dmac_start_request(struct dma_controller *_dmac, -+ unsigned int channel) -+{ -+ struct dw_dma_controller *dmac = to_dw_dmac(_dmac); -+ -+ BUG_ON(channel >= DMAC_NR_CHANNELS); -+ -+ set_channel_bit(dmac, CH_EN, channel); -+ -+ return 0; -+} -+ -+static dma_addr_t dmac_get_current_pos(struct dma_controller *_dmac, -+ unsigned int channel) -+{ -+ struct dw_dma_controller *dmac = to_dw_dmac(_dmac); -+ struct dw_dma_channel *chan; -+ dma_addr_t current_pos; -+ -+ BUG_ON(channel >= DMAC_NR_CHANNELS); -+ -+ chan = &dmac->channel[channel]; -+ -+ switch (chan->direction) { -+ case DMA_TO_DEVICE: -+ current_pos = dmac_chan_readl_lo(dmac, channel, SAR); -+ break; -+ case DMA_FROM_DEVICE: -+ current_pos = dmac_chan_readl_lo(dmac, channel, DAR); -+ break; -+ default: -+ return 0; -+ } -+ -+ -+ if (!current_pos) { -+ if (chan->is_cyclic) { -+ current_pos = chan->req_cyclic->buffer_start; -+ } else { -+ current_pos = chan->req_sg->sg->dma_address; -+ } -+ } -+ -+ return current_pos; -+} -+ -+ -+static int dmac_stop_request(struct dma_controller *_dmac, -+ unsigned int channel) -+{ -+ struct dw_dma_controller *dmac = to_dw_dmac(_dmac); -+ struct dw_dma_channel *chan; -+ -+ BUG_ON(channel >= DMAC_NR_CHANNELS); -+ -+ chan = &dmac->channel[channel]; -+ pr_debug("stop: st%u s%08x d%08x l%08x ctl0x%08x:0x%08x\n", -+ chan->state, dmac_chan_readl_lo(dmac, channel, SAR), -+ dmac_chan_readl_lo(dmac, channel, DAR), -+ dmac_chan_readl_lo(dmac, channel, LLP), -+ dmac_chan_readl_hi(dmac, channel, CTL), -+ dmac_chan_readl_lo(dmac, channel, CTL)); -+ -+ if (chan->state == CH_STATE_BUSY) { -+ clear_channel_bit(dmac, CH_EN, channel); -+ cleanup_channel(dmac, &dmac->channel[channel]); -+ } -+ -+ return 0; -+} -+ -+ -+static void dmac_block_complete(struct dw_dma_controller *dmac) -+{ -+ struct dw_dma_channel *chan; -+ unsigned long status, chanid; -+ -+ status = dmac_readl_lo(dmac, STATUS_BLOCK); -+ -+ while (status) { -+ struct dma_request *req; -+ chanid = __ffs(status); -+ chan = &dmac->channel[chanid]; -+ -+ if (chan->is_cyclic) { -+ BUG_ON(!chan->req_cyclic -+ || !chan->req_cyclic->req.block_complete); -+ req = &chan->req_cyclic->req; -+ } else { -+ BUG_ON(!chan->req_sg || !chan->req_sg->req.block_complete); -+ req = &chan->req_sg->req; -+ } -+ dmac_writel_lo(dmac, CLEAR_BLOCK, 1 << chanid); -+ req->block_complete(req); -+ status = dmac_readl_lo(dmac, STATUS_BLOCK); -+ } -+} -+ -+static void dmac_xfer_complete(struct dw_dma_controller *dmac) -+{ -+ struct dw_dma_channel *chan; -+ struct dma_request *req; -+ unsigned long status, chanid; -+ -+ status = dmac_readl_lo(dmac, STATUS_XFER); -+ -+ while (status) { -+ chanid = __ffs(status); -+ chan = &dmac->channel[chanid]; -+ -+ dmac_writel_lo(dmac, CLEAR_XFER, 1 << chanid); -+ -+ req = &chan->req_sg->req; -+ BUG_ON(!req); -+ cleanup_channel(dmac, chan); -+ if (req->xfer_complete) -+ req->xfer_complete(req); -+ -+ status = dmac_readl_lo(dmac, STATUS_XFER); -+ } -+} -+ -+static void dmac_error(struct dw_dma_controller *dmac) -+{ -+ struct dw_dma_channel *chan; -+ unsigned long status, chanid; -+ -+ status = dmac_readl_lo(dmac, STATUS_ERROR); -+ -+ while (status) { -+ struct dma_request *req; -+ -+ chanid = __ffs(status); -+ chan = &dmac->channel[chanid]; -+ -+ dmac_writel_lo(dmac, CLEAR_ERROR, 1 << chanid); -+ clear_channel_bit(dmac, CH_EN, chanid); -+ -+ if (chan->is_cyclic) { -+ BUG_ON(!chan->req_cyclic); -+ req = &chan->req_cyclic->req; -+ } else { -+ BUG_ON(!chan->req_sg); -+ req = &chan->req_sg->req; -+ } -+ -+ cleanup_channel(dmac, chan); -+ if (req->error) -+ req->error(req); -+ -+ status = dmac_readl_lo(dmac, STATUS_XFER); -+ } -+} -+ -+static irqreturn_t dmac_interrupt(int irq, void *dev_id) -+{ -+ struct dw_dma_controller *dmac = dev_id; -+ unsigned long status; -+ int ret = IRQ_NONE; -+ -+ spin_lock(&dmac->lock); -+ -+ status = dmac_readl_lo(dmac, STATUS_INT); -+ -+ while (status) { -+ ret = IRQ_HANDLED; -+ if (status & 0x10) -+ dmac_error(dmac); -+ if (status & 0x02) -+ dmac_block_complete(dmac); -+ if (status & 0x01) -+ dmac_xfer_complete(dmac); -+ -+ status = dmac_readl_lo(dmac, STATUS_INT); -+ } -+ -+ spin_unlock(&dmac->lock); -+ return ret; -+} -+ -+static int __devinit dmac_probe(struct platform_device *pdev) -+{ -+ struct dw_dma_controller *dmac; -+ struct resource *regs; -+ int ret; -+ -+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!regs) -+ return -ENXIO; -+ -+ dmac = kmalloc(sizeof(*dmac), GFP_KERNEL); -+ if (!dmac) -+ return -ENOMEM; -+ memset(dmac, 0, sizeof(*dmac)); -+ -+ dmac->hclk = clk_get(&pdev->dev, "hclk"); -+ if (IS_ERR(dmac->hclk)) { -+ ret = PTR_ERR(dmac->hclk); -+ goto out_free_dmac; -+ } -+ clk_enable(dmac->hclk); -+ -+ ret = -ENOMEM; -+ dmac->lli_pool = dma_pool_create("dmac", &pdev->dev, -+ sizeof(struct dw_dma_lli), 4, 0); -+ if (!dmac->lli_pool) -+ goto out_disable_clk; -+ -+ spin_lock_init(&dmac->lock); -+ dmac->dma.dev = &pdev->dev; -+ dmac->dma.alloc_channel = dmac_alloc_channel; -+ dmac->dma.release_channel = dmac_release_channel; -+ dmac->dma.prepare_request_sg = dmac_prepare_request_sg; -+ dmac->dma.prepare_request_cyclic = dmac_prepare_request_cyclic; -+ dmac->dma.start_request = dmac_start_request; -+ dmac->dma.stop_request = dmac_stop_request; -+ dmac->dma.get_current_pos = dmac_get_current_pos; -+ -+ dmac->regs = ioremap(regs->start, regs->end - regs->start + 1); -+ if (!dmac->regs) -+ goto out_free_pool; -+ -+ ret = request_irq(platform_get_irq(pdev, 0), dmac_interrupt, -+ IRQF_SAMPLE_RANDOM, pdev->name, dmac); -+ if (ret) -+ goto out_unmap_regs; -+ -+ /* Enable the DMA controller */ -+ dmac_writel_lo(dmac, CFG, 1); -+ -+ register_dma_controller(&dmac->dma); -+ -+ printk(KERN_INFO -+ "dmac%d: DesignWare DMA controller at 0x%p irq %d\n", -+ dmac->dma.id, dmac->regs, platform_get_irq(pdev, 0)); -+ -+ return 0; -+ -+out_unmap_regs: -+ iounmap(dmac->regs); -+out_free_pool: -+ dma_pool_destroy(dmac->lli_pool); -+out_disable_clk: -+ clk_disable(dmac->hclk); -+ clk_put(dmac->hclk); -+out_free_dmac: -+ kfree(dmac); -+ return ret; -+} -+ -+static struct platform_driver dmac_driver = { -+ .probe = dmac_probe, -+ .driver = { -+ .name = "dmaca", -+ }, -+}; -+ -+static int __init dmac_init(void) -+{ -+ return platform_driver_register(&dmac_driver); -+} -+subsys_initcall(dmac_init); -+ -+static void __exit dmac_exit(void) -+{ -+ platform_driver_unregister(&dmac_driver); -+} -+module_exit(dmac_exit); -+ -+MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver"); -+MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/arch/avr32/drivers/dw-dmac.h -@@ -0,0 +1,42 @@ -+/* -+ * Driver for the Synopsys DesignWare DMA Controller -+ * -+ * 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. -+ */ -+#ifndef __AVR32_DW_DMAC_H__ -+#define __AVR32_DW_DMAC_H__ -+ -+#define DW_DMAC_CFG 0x398 -+#define DW_DMAC_CH_EN 0x3a0 -+ -+#define DW_DMAC_STATUS_XFER 0x2e8 -+#define DW_DMAC_STATUS_BLOCK 0x2f0 -+#define DW_DMAC_STATUS_ERROR 0x308 -+ -+#define DW_DMAC_MASK_XFER 0x310 -+#define DW_DMAC_MASK_BLOCK 0x318 -+#define DW_DMAC_MASK_ERROR 0x330 -+ -+#define DW_DMAC_CLEAR_XFER 0x338 -+#define DW_DMAC_CLEAR_BLOCK 0x340 -+#define DW_DMAC_CLEAR_ERROR 0x358 -+ -+#define DW_DMAC_STATUS_INT 0x360 -+ -+#define DW_DMAC_CHAN_SAR 0x000 -+#define DW_DMAC_CHAN_DAR 0x008 -+#define DW_DMAC_CHAN_LLP 0x010 -+#define DW_DMAC_CHAN_CTL 0x018 -+#define DW_DMAC_CHAN_SSTAT 0x020 -+#define DW_DMAC_CHAN_DSTAT 0x028 -+#define DW_DMAC_CHAN_SSTATAR 0x030 -+#define DW_DMAC_CHAN_DSTATAR 0x038 -+#define DW_DMAC_CHAN_CFG 0x040 -+#define DW_DMAC_CHAN_SGR 0x048 -+#define DW_DMAC_CHAN_DSR 0x050 -+ -+#endif /* __AVR32_DW_DMAC_H__ */ ---- a/arch/avr32/kernel/Makefile -+++ b/arch/avr32/kernel/Makefile -@@ -9,6 +9,7 @@ obj-y += syscall_table.o syscall-stub - obj-y += setup.o traps.o semaphore.o ocd.o ptrace.o - obj-y += signal.o sys_avr32.o process.o time.o - obj-y += init_task.o switch_to.o cpu.o -+obj-y += dma-controller.o - obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o - obj-$(CONFIG_KPROBES) += kprobes.o - obj-$(CONFIG_STACKTRACE) += stacktrace.o ---- a/arch/avr32/kernel/avr32_ksyms.c -+++ b/arch/avr32/kernel/avr32_ksyms.c -@@ -29,7 +29,9 @@ EXPORT_SYMBOL(__avr32_asr64); - */ - EXPORT_SYMBOL(memset); - EXPORT_SYMBOL(memcpy); -+ - EXPORT_SYMBOL(clear_page); -+EXPORT_SYMBOL(copy_page); - - /* - * Userspace access stuff. -@@ -41,6 +43,8 @@ EXPORT_SYMBOL(strncpy_from_user); - EXPORT_SYMBOL(__strncpy_from_user); - EXPORT_SYMBOL(clear_user); - EXPORT_SYMBOL(__clear_user); -+EXPORT_SYMBOL(strnlen_user); -+ - EXPORT_SYMBOL(csum_partial); - EXPORT_SYMBOL(csum_partial_copy_generic); - ---- /dev/null -+++ b/arch/avr32/kernel/dma-controller.c -@@ -0,0 +1,34 @@ -+/* -+ * Preliminary DMA controller framework for AVR32 -+ * -+ * 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 <asm/dma-controller.h> -+ -+static LIST_HEAD(controllers); -+ -+int register_dma_controller(struct dma_controller *dmac) -+{ -+ static int next_id; -+ -+ dmac->id = next_id++; -+ list_add_tail(&dmac->list, &controllers); -+ -+ return 0; -+} -+EXPORT_SYMBOL(register_dma_controller); -+ -+struct dma_controller *find_dma_controller(int id) -+{ -+ struct dma_controller *dmac; -+ -+ list_for_each_entry(dmac, &controllers, list) -+ if (dmac->id == id) -+ return dmac; -+ return NULL; -+} -+EXPORT_SYMBOL(find_dma_controller); ---- a/arch/avr32/kernel/entry-avr32b.S -+++ b/arch/avr32/kernel/entry-avr32b.S -@@ -74,50 +74,41 @@ exception_vectors: - .align 2 - bral do_dtlb_modified - -- /* -- * r0 : PGD/PT/PTE -- * r1 : Offending address -- * r2 : Scratch register -- * r3 : Cause (5, 12 or 13) -- */ - #define tlbmiss_save pushm r0-r3 - #define tlbmiss_restore popm r0-r3 - -- .section .tlbx.ex.text,"ax",@progbits -+ .org 0x50 - .global itlb_miss - itlb_miss: - tlbmiss_save - rjmp tlb_miss_common - -- .section .tlbr.ex.text,"ax",@progbits -+ .org 0x60 - dtlb_miss_read: - tlbmiss_save - rjmp tlb_miss_common - -- .section .tlbw.ex.text,"ax",@progbits -+ .org 0x70 - dtlb_miss_write: - tlbmiss_save - - .global tlb_miss_common -+ .align 2 - tlb_miss_common: - mfsr r0, SYSREG_TLBEAR - mfsr r1, SYSREG_PTBR - -- /* Is it the vmalloc space? */ -- bld r0, 31 -- brcs handle_vmalloc_miss -- -- /* First level lookup */ -+ /* -+ * First level lookup: The PGD contains virtual pointers to -+ * the second-level page tables, but they may be NULL if not -+ * present. -+ */ - pgtbl_lookup: - lsr r2, r0, PGDIR_SHIFT - ld.w r3, r1[r2 << 2] - bfextu r1, r0, PAGE_SHIFT, PGDIR_SHIFT - PAGE_SHIFT -- bld r3, _PAGE_BIT_PRESENT -- brcc page_table_not_present -- -- /* Translate to virtual address in P1. */ -- andl r3, 0xf000 -- sbr r3, 31 -+ cp.w r3, 0 -+ breq page_table_not_present - - /* Second level lookup */ - ld.w r2, r3[r1 << 2] -@@ -148,16 +139,55 @@ pgtbl_lookup: - tlbmiss_restore - rete - --handle_vmalloc_miss: -- /* Simply do the lookup in init's page table */ -+ /* The slow path of the TLB miss handler */ -+ .align 2 -+page_table_not_present: -+ /* Do we need to synchronize with swapper_pg_dir? */ -+ bld r0, 31 -+ brcs sync_with_swapper_pg_dir -+ -+page_not_present: -+ tlbmiss_restore -+ sub sp, 4 -+ stmts --sp, r0-lr -+ rcall save_full_context_ex -+ mfsr r12, SYSREG_ECR -+ mov r11, sp -+ rcall do_page_fault -+ rjmp ret_from_exception -+ -+ .align 2 -+sync_with_swapper_pg_dir: -+ /* -+ * If swapper_pg_dir contains a non-NULL second-level page -+ * table pointer, copy it into the current PGD. If not, we -+ * must handle it as a full-blown page fault. -+ * -+ * Jumping back to pgtbl_lookup causes an unnecessary lookup, -+ * but it is guaranteed to be a cache hit, it won't happen -+ * very often, and we absolutely do not want to sacrifice any -+ * performance in the fast path in order to improve this. -+ */ - mov r1, lo(swapper_pg_dir) - orh r1, hi(swapper_pg_dir) -+ ld.w r3, r1[r2 << 2] -+ cp.w r3, 0 -+ breq page_not_present -+ mfsr r1, SYSREG_PTBR -+ st.w r1[r2 << 2], r3 - rjmp pgtbl_lookup - -+ /* -+ * We currently have two bytes left at this point until we -+ * crash into the system call handler... -+ * -+ * Don't worry, the assembler will let us know. -+ */ -+ - - /* --- System Call --- */ - -- .section .scall.text,"ax",@progbits -+ .org 0x100 - system_call: - #ifdef CONFIG_PREEMPT - mask_interrupts -@@ -266,18 +296,6 @@ syscall_exit_work: - brcc syscall_exit_cont - rjmp enter_monitor_mode - -- /* The slow path of the TLB miss handler */ --page_table_not_present: --page_not_present: -- tlbmiss_restore -- sub sp, 4 -- stmts --sp, r0-lr -- rcall save_full_context_ex -- mfsr r12, SYSREG_ECR -- mov r11, sp -- rcall do_page_fault -- rjmp ret_from_exception -- - /* This function expects to find offending PC in SYSREG_RAR_EX */ - .type save_full_context_ex, @function - .align 2 -@@ -741,26 +759,6 @@ irq_level\level: - - .section .irq.text,"ax",@progbits - --.global cpu_idle_sleep --cpu_idle_sleep: -- mask_interrupts -- get_thread_info r8 -- ld.w r9, r8[TI_flags] -- bld r9, TIF_NEED_RESCHED -- brcs cpu_idle_enable_int_and_exit -- sbr r9, TIF_CPU_GOING_TO_SLEEP -- st.w r8[TI_flags], r9 -- unmask_interrupts -- sleep 0 --cpu_idle_skip_sleep: -- mask_interrupts -- ld.w r9, r8[TI_flags] -- cbr r9, TIF_CPU_GOING_TO_SLEEP -- st.w r8[TI_flags], r9 --cpu_idle_enable_int_and_exit: -- unmask_interrupts -- retal r12 -- - .global irq_level0 - .global irq_level1 - .global irq_level2 ---- a/arch/avr32/kernel/process.c -+++ b/arch/avr32/kernel/process.c -@@ -18,11 +18,11 @@ - #include <asm/sysreg.h> - #include <asm/ocd.h> - -+#include <asm/arch/pm.h> -+ - void (*pm_power_off)(void) = NULL; - EXPORT_SYMBOL(pm_power_off); - --extern void cpu_idle_sleep(void); -- - /* - * This file handles the architecture-dependent parts of process handling.. - */ -@@ -54,6 +54,8 @@ void machine_halt(void) - - void machine_power_off(void) - { -+ if (pm_power_off) -+ pm_power_off(); - } - - void machine_restart(char *cmd) ---- a/arch/avr32/kernel/setup.c -+++ b/arch/avr32/kernel/setup.c -@@ -274,6 +274,8 @@ static int __init early_parse_fbmem(char - printk(KERN_WARNING - "Failed to allocate framebuffer memory\n"); - fbmem_size = 0; -+ } else { -+ memset(__va(fbmem_start), 0, fbmem_size); - } - } - ---- a/arch/avr32/kernel/signal.c -+++ b/arch/avr32/kernel/signal.c -@@ -93,6 +93,9 @@ asmlinkage int sys_rt_sigreturn(struct p - if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) - goto badframe; - -+ if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) -+ goto badframe; -+ - pr_debug("Context restored: pc = %08lx, lr = %08lx, sp = %08lx\n", - regs->pc, regs->lr, regs->sp); - ---- a/arch/avr32/kernel/time.c -+++ b/arch/avr32/kernel/time.c -@@ -1,233 +1,147 @@ - /* - * Copyright (C) 2004-2007 Atmel Corporation - * -- * Based on MIPS implementation arch/mips/kernel/time.c -- * Copyright 2001 MontaVista Software Inc. -- * - * 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/clocksource.h> --#include <linux/time.h> --#include <linux/module.h> -+#include <linux/clockchips.h> -+#include <linux/init.h> - #include <linux/interrupt.h> - #include <linux/irq.h> --#include <linux/kernel_stat.h> --#include <linux/errno.h> --#include <linux/init.h> --#include <linux/profile.h> --#include <linux/sysdev.h> --#include <linux/err.h> -+#include <linux/kernel.h> -+#include <linux/time.h> - --#include <asm/div64.h> - #include <asm/sysreg.h> --#include <asm/io.h> --#include <asm/sections.h> - --/* how many counter cycles in a jiffy? */ --static u32 cycles_per_jiffy; -+#include <asm/arch/pm.h> - --/* the count value for the next timer interrupt */ --static u32 expirelo; - --cycle_t __weak read_cycle_count(void) -+static cycle_t read_cycle_count(void) - { - return (cycle_t)sysreg_read(COUNT); - } - --struct clocksource __weak clocksource_avr32 = { -- .name = "avr32", -- .rating = 350, -+/* -+ * The architectural cycle count registers are a fine clocksource unless -+ * the system idle loop use sleep states like "idle": the CPU cycles -+ * measured by COUNT (and COMPARE) don't happen during sleep states. -+ * Their duration also changes if cpufreq changes the CPU clock rate. -+ * So we rate the clocksource using COUNT as very low quality. -+ */ -+static struct clocksource counter = { -+ .name = "avr32_counter", -+ .rating = 50, - .read = read_cycle_count, - .mask = CLOCKSOURCE_MASK(32), - .shift = 16, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, - }; - --irqreturn_t __weak timer_interrupt(int irq, void *dev_id); -- --struct irqaction timer_irqaction = { -- .handler = timer_interrupt, -- .flags = IRQF_DISABLED, -- .name = "timer", --}; -- --/* -- * By default we provide the null RTC ops -- */ --static unsigned long null_rtc_get_time(void) --{ -- return mktime(2007, 1, 1, 0, 0, 0); --} -- --static int null_rtc_set_time(unsigned long sec) -+static irqreturn_t timer_interrupt(int irq, void *dev_id) - { -- return 0; --} -- --static unsigned long (*rtc_get_time)(void) = null_rtc_get_time; --static int (*rtc_set_time)(unsigned long) = null_rtc_set_time; -+ struct clock_event_device *evdev = dev_id; - --static void avr32_timer_ack(void) --{ -- u32 count; -- -- /* Ack this timer interrupt and set the next one */ -- expirelo += cycles_per_jiffy; -- /* setting COMPARE to 0 stops the COUNT-COMPARE */ -- if (expirelo == 0) { -- sysreg_write(COMPARE, expirelo + 1); -- } else { -- sysreg_write(COMPARE, expirelo); -- } -+ /* -+ * Disable the interrupt until the clockevent subsystem -+ * reprograms it. -+ */ -+ sysreg_write(COMPARE, 0); - -- /* Check to see if we have missed any timer interrupts */ -- count = sysreg_read(COUNT); -- if ((count - expirelo) < 0x7fffffff) { -- expirelo = count + cycles_per_jiffy; -- sysreg_write(COMPARE, expirelo); -- } -+ evdev->event_handler(evdev); -+ return IRQ_HANDLED; - } - --int __weak avr32_hpt_init(void) --{ -- int ret; -- unsigned long mult, shift, count_hz; -- -- count_hz = clk_get_rate(boot_cpu_data.clk); -- shift = clocksource_avr32.shift; -- mult = clocksource_hz2mult(count_hz, shift); -- clocksource_avr32.mult = mult; -- -- { -- u64 tmp; -- -- tmp = TICK_NSEC; -- tmp <<= shift; -- tmp += mult / 2; -- do_div(tmp, mult); -- -- cycles_per_jiffy = tmp; -- } -+static struct irqaction timer_irqaction = { -+ .handler = timer_interrupt, -+ .flags = IRQF_TIMER | IRQF_DISABLED, -+ .name = "avr32_comparator", -+}; - -- ret = setup_irq(0, &timer_irqaction); -- if (ret) { -- pr_debug("timer: could not request IRQ 0: %d\n", ret); -- return -ENODEV; -- } -+static int comparator_next_event(unsigned long delta, -+ struct clock_event_device *evdev) -+{ -+ unsigned long flags; - -- printk(KERN_INFO "timer: AT32AP COUNT-COMPARE at irq 0, " -- "%lu.%03lu MHz\n", -- ((count_hz + 500) / 1000) / 1000, -- ((count_hz + 500) / 1000) % 1000); -+ raw_local_irq_save(flags); - -- return 0; --} -+ /* The time to read COUNT then update COMPARE must be less -+ * than the min_delta_ns value for this clockevent source. -+ */ -+ sysreg_write(COMPARE, (sysreg_read(COUNT) + delta) ? : 1); - --/* -- * Taken from MIPS c0_hpt_timer_init(). -- * -- * The reason COUNT is written twice is probably to make sure we don't get any -- * timer interrupts while we are messing with the counter. -- */ --int __weak avr32_hpt_start(void) --{ -- u32 count = sysreg_read(COUNT); -- expirelo = (count / cycles_per_jiffy + 1) * cycles_per_jiffy; -- sysreg_write(COUNT, expirelo - cycles_per_jiffy); -- sysreg_write(COMPARE, expirelo); -- sysreg_write(COUNT, count); -+ raw_local_irq_restore(flags); - - return 0; - } - --/* -- * local_timer_interrupt() does profiling and process accounting on a -- * per-CPU basis. -- * -- * In UP mode, it is invoked from the (global) timer_interrupt. -- */ --void local_timer_interrupt(int irq, void *dev_id) -+static void comparator_mode(enum clock_event_mode mode, -+ struct clock_event_device *evdev) - { -- if (current->pid) -- profile_tick(CPU_PROFILING); -- update_process_times(user_mode(get_irq_regs())); -+ switch (mode) { -+ case CLOCK_EVT_MODE_ONESHOT: -+ pr_debug("%s: start\n", evdev->name); -+ /* FALLTHROUGH */ -+ case CLOCK_EVT_MODE_RESUME: -+ cpu_disable_idle_sleep(); -+ break; -+ case CLOCK_EVT_MODE_UNUSED: -+ case CLOCK_EVT_MODE_SHUTDOWN: -+ sysreg_write(COMPARE, 0); -+ pr_debug("%s: stop\n", evdev->name); -+ cpu_enable_idle_sleep(); -+ break; -+ default: -+ BUG(); -+ } - } - --irqreturn_t __weak timer_interrupt(int irq, void *dev_id) --{ -- /* ack timer interrupt and try to set next interrupt */ -- avr32_timer_ack(); -- -- /* -- * Call the generic timer interrupt handler -- */ -- write_seqlock(&xtime_lock); -- do_timer(1); -- write_sequnlock(&xtime_lock); -- -- /* -- * In UP mode, we call local_timer_interrupt() to do profiling -- * and process accounting. -- * -- * SMP is not supported yet. -- */ -- local_timer_interrupt(irq, dev_id); -- -- return IRQ_HANDLED; --} -+static struct clock_event_device comparator = { -+ .name = "avr32_comparator", -+ .features = CLOCK_EVT_FEAT_ONESHOT, -+ .shift = 16, -+ .rating = 50, -+ .cpumask = CPU_MASK_CPU0, -+ .set_next_event = comparator_next_event, -+ .set_mode = comparator_mode, -+}; - - void __init time_init(void) - { -+ unsigned long counter_hz; - int ret; - -- /* -- * Make sure we don't get any COMPARE interrupts before we can -- * handle them. -- */ -- sysreg_write(COMPARE, 0); -- -- xtime.tv_sec = rtc_get_time(); -+ xtime.tv_sec = mktime(2007, 1, 1, 0, 0, 0); - xtime.tv_nsec = 0; - - set_normalized_timespec(&wall_to_monotonic, - -xtime.tv_sec, -xtime.tv_nsec); - -- ret = avr32_hpt_init(); -- if (ret) { -- pr_debug("timer: failed setup: %d\n", ret); -- return; -- } -+ /* figure rate for counter */ -+ counter_hz = clk_get_rate(boot_cpu_data.clk); -+ counter.mult = clocksource_hz2mult(counter_hz, counter.shift); - -- ret = clocksource_register(&clocksource_avr32); -+ ret = clocksource_register(&counter); - if (ret) - pr_debug("timer: could not register clocksource: %d\n", ret); - -- ret = avr32_hpt_start(); -- if (ret) { -- pr_debug("timer: failed starting: %d\n", ret); -- 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; - --static struct sysdev_class timer_class = { -- .name = "timer", --}; -+ sysreg_write(COMPARE, 0); -+ timer_irqaction.dev_id = &comparator; - --static struct sys_device timer_device = { -- .id = 0, -- .cls = &timer_class, --}; -+ ret = setup_irq(0, &timer_irqaction); -+ if (ret) -+ pr_debug("timer: could not request IRQ 0: %d\n", ret); -+ else { -+ clockevents_register_device(&comparator); - --static int __init init_timer_sysfs(void) --{ -- int err = sysdev_class_register(&timer_class); -- if (!err) -- err = sysdev_register(&timer_device); -- return err; -+ pr_info("%s: irq 0, %lu.%03lu MHz\n", comparator.name, -+ ((counter_hz + 500) / 1000) / 1000, -+ ((counter_hz + 500) / 1000) % 1000); -+ } - } -- --device_initcall(init_timer_sysfs); ---- a/arch/avr32/kernel/vmlinux.lds.S -+++ b/arch/avr32/kernel/vmlinux.lds.S -@@ -68,14 +68,6 @@ SECTIONS - _evba = .; - _text = .; - *(.ex.text) -- . = 0x50; -- *(.tlbx.ex.text) -- . = 0x60; -- *(.tlbr.ex.text) -- . = 0x70; -- *(.tlbw.ex.text) -- . = 0x100; -- *(.scall.text) - *(.irq.text) - KPROBES_TEXT - TEXT_TEXT -@@ -107,6 +99,10 @@ SECTIONS - */ - *(.data.init_task) - -+ /* Then, the page-aligned data */ -+ . = ALIGN(PAGE_SIZE); -+ *(.data.page_aligned) -+ - /* Then, the cacheline aligned data */ - . = ALIGN(L1_CACHE_BYTES); - *(.data.cacheline_aligned) ---- a/arch/avr32/lib/io-readsb.S -+++ b/arch/avr32/lib/io-readsb.S -@@ -41,7 +41,7 @@ __raw_readsb: - 2: sub r10, -4 - reteq r12 - --3: ld.uh r8, r12[0] -+3: ld.ub r8, r12[0] - sub r10, 1 - st.b r11++, r8 - brne 3b ---- a/arch/avr32/mach-at32ap/Kconfig -+++ b/arch/avr32/mach-at32ap/Kconfig -@@ -26,6 +26,13 @@ config AP700X_8_BIT_SMC - - endchoice - -+config GPIO_DEV -+ bool "GPIO /dev interface" -+ select CONFIGFS_FS -+ default n -+ help -+ Say `Y' to enable a /dev interface to the GPIO pins. -+ - endmenu - - endif # PLATFORM_AT32AP ---- a/arch/avr32/mach-at32ap/Makefile -+++ b/arch/avr32/mach-at32ap/Makefile -@@ -1,4 +1,9 @@ --obj-y += at32ap.o clock.o intc.o extint.o pio.o hsmc.o --obj-$(CONFIG_CPU_AT32AP700X) += at32ap700x.o --obj-$(CONFIG_CPU_AT32AP700X) += time-tc.o -+obj-y += pdc.o clock.o intc.o extint.o pio.o hsmc.o -+obj-$(CONFIG_CPU_AT32AP700X) += at32ap700x.o pm-at32ap700x.o - obj-$(CONFIG_CPU_FREQ_AT32AP) += cpufreq.o -+obj-$(CONFIG_GPIO_DEV) += gpio-dev.o -+obj-$(CONFIG_PM) += pm.o -+ -+ifeq ($(CONFIG_PM_DEBUG),y) -+CFLAGS_pm.o += -DDEBUG -+endif ---- a/arch/avr32/mach-at32ap/at32ap.c -+++ /dev/null -@@ -1,56 +0,0 @@ --/* -- * Copyright (C) 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/clk.h> --#include <linux/err.h> --#include <linux/init.h> --#include <linux/platform_device.h> -- --#include <asm/arch/init.h> -- --void __init setup_platform(void) --{ -- at32_clock_init(); -- at32_portmux_init(); --} -- --static int __init pdc_probe(struct platform_device *pdev) --{ -- struct clk *pclk, *hclk; -- -- pclk = clk_get(&pdev->dev, "pclk"); -- if (IS_ERR(pclk)) { -- dev_err(&pdev->dev, "no pclk defined\n"); -- return PTR_ERR(pclk); -- } -- hclk = clk_get(&pdev->dev, "hclk"); -- if (IS_ERR(hclk)) { -- dev_err(&pdev->dev, "no hclk defined\n"); -- clk_put(pclk); -- return PTR_ERR(hclk); -- } -- -- clk_enable(pclk); -- clk_enable(hclk); -- -- dev_info(&pdev->dev, "Atmel Peripheral DMA Controller enabled\n"); -- return 0; --} -- --static struct platform_driver pdc_driver = { -- .probe = pdc_probe, -- .driver = { -- .name = "pdc", -- }, --}; -- --static int __init pdc_init(void) --{ -- return platform_driver_register(&pdc_driver); --} --arch_initcall(pdc_init); ---- a/arch/avr32/mach-at32ap/at32ap700x.c -+++ b/arch/avr32/mach-at32ap/at32ap700x.c -@@ -6,11 +6,13 @@ - * published by the Free Software Foundation. - */ - #include <linux/clk.h> -+#include <linux/delay.h> - #include <linux/fb.h> - #include <linux/init.h> - #include <linux/platform_device.h> - #include <linux/dma-mapping.h> - #include <linux/spi/spi.h> -+#include <linux/usb/atmel_usba_udc.h> - - #include <asm/io.h> - #include <asm/irq.h> -@@ -18,6 +20,7 @@ - #include <asm/arch/at32ap700x.h> - #include <asm/arch/board.h> - #include <asm/arch/portmux.h> -+#include <asm/arch/sram.h> - - #include <video/atmel_lcdc.h> - -@@ -91,25 +94,18 @@ static struct clk devname##_##_name = { - - static DEFINE_SPINLOCK(pm_lock); - --unsigned long at32ap7000_osc_rates[3] = { -- [0] = 32768, -- /* FIXME: these are ATSTK1002-specific */ -- [1] = 20000000, -- [2] = 12000000, --}; -+static struct clk osc0; -+static struct clk osc1; - - static unsigned long osc_get_rate(struct clk *clk) - { -- return at32ap7000_osc_rates[clk->index]; -+ return at32_board_osc_rates[clk->index]; - } - - static unsigned long pll_get_rate(struct clk *clk, unsigned long control) - { - unsigned long div, mul, rate; - -- if (!(control & PM_BIT(PLLEN))) -- return 0; -- - div = PM_BFEXT(PLLDIV, control) + 1; - mul = PM_BFEXT(PLLMUL, control) + 1; - -@@ -120,6 +116,71 @@ static unsigned long pll_get_rate(struct - return rate; - } - -+static long pll_set_rate(struct clk *clk, unsigned long rate, -+ u32 *pll_ctrl) -+{ -+ unsigned long mul; -+ 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 pll_in; -+ unsigned long actual = 0; -+ unsigned long rate_error; -+ unsigned long rate_error_prev = ~0UL; -+ u32 ctrl; -+ -+ /* Rate must be between 80 MHz and 200 Mhz. */ -+ if (rate < 80000000UL || rate > 200000000UL) -+ return -EINVAL; -+ -+ ctrl = PM_BF(PLLOPT, 4); -+ base = clk->parent->get_rate(clk->parent); -+ -+ /* PLL input frequency must be between 6 MHz and 32 MHz. */ -+ div_min = DIV_ROUND_UP(base, 32000000UL); -+ div_max = base / 6000000UL; -+ -+ if (div_max < div_min) -+ return -EINVAL; -+ -+ for (div = div_min; div <= div_max; div++) { -+ pll_in = (base + div / 2) / div; -+ mul = (rate + pll_in / 2) / pll_in; -+ -+ if (mul == 0) -+ 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 |= PM_BF(PLLMUL, mul_best_fit - 1); -+ ctrl |= PM_BF(PLLDIV, div_best_fit - 1); -+ ctrl |= PM_BF(PLLCOUNT, 16); -+ -+ if (clk->parent == &osc1) -+ ctrl |= PM_BIT(PLLOSC); -+ -+ *pll_ctrl = ctrl; -+ -+ return actual; -+} -+ - static unsigned long pll0_get_rate(struct clk *clk) - { - u32 control; -@@ -129,6 +190,41 @@ static unsigned long pll0_get_rate(struc - return pll_get_rate(clk, control); - } - -+static void pll1_mode(struct clk *clk, int enabled) -+{ -+ unsigned long timeout; -+ u32 status; -+ u32 ctrl; -+ -+ ctrl = pm_readl(PLL1); -+ -+ if (enabled) { -+ if (!PM_BFEXT(PLLMUL, ctrl) && !PM_BFEXT(PLLDIV, ctrl)) { -+ pr_debug("clk %s: failed to enable, rate not set\n", -+ clk->name); -+ return; -+ } -+ -+ ctrl |= PM_BIT(PLLEN); -+ pm_writel(PLL1, ctrl); -+ -+ /* Wait for PLL lock. */ -+ for (timeout = 10000; timeout; timeout--) { -+ status = pm_readl(ISR); -+ if (status & PM_BIT(LOCK1)) -+ break; -+ udelay(10); -+ } -+ -+ if (!(status & PM_BIT(LOCK1))) -+ printk(KERN_ERR "clk %s: timeout waiting for lock\n", -+ clk->name); -+ } else { -+ ctrl &= ~PM_BIT(PLLEN); -+ pm_writel(PLL1, ctrl); -+ } -+} -+ - static unsigned long pll1_get_rate(struct clk *clk) - { - u32 control; -@@ -138,6 +234,49 @@ static unsigned long pll1_get_rate(struc - return pll_get_rate(clk, control); - } - -+static long pll1_set_rate(struct clk *clk, unsigned long rate, int apply) -+{ -+ u32 ctrl = 0; -+ unsigned long actual_rate; -+ -+ actual_rate = pll_set_rate(clk, rate, &ctrl); -+ -+ if (apply) { -+ if (actual_rate != 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_rate); -+ pm_writel(PLL1, ctrl); -+ } -+ -+ return actual_rate; -+} -+ -+static int pll1_set_parent(struct clk *clk, struct clk *parent) -+{ -+ u32 ctrl; -+ -+ if (clk->users > 0) -+ return -EBUSY; -+ -+ ctrl = pm_readl(PLL1); -+ WARN_ON(ctrl & PM_BIT(PLLEN)); -+ -+ if (parent == &osc0) -+ ctrl &= ~PM_BIT(PLLOSC); -+ else if (parent == &osc1) -+ ctrl |= PM_BIT(PLLOSC); -+ else -+ return -EINVAL; -+ -+ pm_writel(PLL1, ctrl); -+ clk->parent = parent; -+ -+ return 0; -+} -+ - /* - * The AT32AP7000 has five primary clock sources: One 32kHz - * oscillator, two crystal oscillators and two PLLs. -@@ -166,7 +305,10 @@ static struct clk pll0 = { - }; - static struct clk pll1 = { - .name = "pll1", -+ .mode = pll1_mode, - .get_rate = pll1_get_rate, -+ .set_rate = pll1_set_rate, -+ .set_parent = pll1_set_parent, - .parent = &osc0, - }; - -@@ -534,6 +676,14 @@ static struct clk hramc_clk = { - .users = 1, - .index = 3, - }; -+static struct clk sdramc_clk = { -+ .name = "sdramc_clk", -+ .parent = &pbb_clk, -+ .mode = pbb_clk_mode, -+ .get_rate = pbb_clk_get_rate, -+ .users = 1, -+ .index = 14, -+}; - - static struct resource smc0_resource[] = { - PBMEM(0xfff03400), -@@ -605,19 +755,32 @@ static inline void set_ebi_sfr_bits(u32 - } - - /* -------------------------------------------------------------------- -- * System Timer/Counter (TC) -+ * Timer/Counter (TC) - * -------------------------------------------------------------------- */ --static struct resource at32_systc0_resource[] = { -+ -+static struct resource at32_tcb0_resource[] = { - PBMEM(0xfff00c00), - IRQ(22), - }; --struct platform_device at32_systc0_device = { -- .name = "systc", -+static struct platform_device at32_tcb0_device = { -+ .name = "atmel_tcb", - .id = 0, -- .resource = at32_systc0_resource, -- .num_resources = ARRAY_SIZE(at32_systc0_resource), -+ .resource = at32_tcb0_resource, -+ .num_resources = ARRAY_SIZE(at32_tcb0_resource), -+}; -+DEV_CLK(t0_clk, at32_tcb0, pbb, 3); -+ -+static struct resource at32_tcb1_resource[] = { -+ PBMEM(0xfff01000), -+ IRQ(23), -+}; -+static struct platform_device at32_tcb1_device = { -+ .name = "atmel_tcb", -+ .id = 1, -+ .resource = at32_tcb1_resource, -+ .num_resources = ARRAY_SIZE(at32_tcb1_resource), - }; --DEV_CLK(pclk, at32_systc0, pbb, 3); -+DEV_CLK(t0_clk, at32_tcb1, pbb, 4); - - /* -------------------------------------------------------------------- - * PIO -@@ -669,7 +832,8 @@ void __init at32_add_system_devices(void - platform_device_register(&pdc_device); - platform_device_register(&dmaca0_device); - -- platform_device_register(&at32_systc0_device); -+ platform_device_register(&at32_tcb0_device); -+ platform_device_register(&at32_tcb1_device); - - platform_device_register(&pio0_device); - platform_device_register(&pio1_device); -@@ -679,6 +843,81 @@ void __init at32_add_system_devices(void - } - - /* -------------------------------------------------------------------- -+ * PSIF -+ * -------------------------------------------------------------------- */ -+static struct resource atmel_psif0_resource[] __initdata = { -+ { -+ .start = 0xffe03c00, -+ .end = 0xffe03cff, -+ .flags = IORESOURCE_MEM, -+ }, -+ IRQ(18), -+}; -+static struct clk atmel_psif0_pclk = { -+ .name = "pclk", -+ .parent = &pba_clk, -+ .mode = pba_clk_mode, -+ .get_rate = pba_clk_get_rate, -+ .index = 15, -+}; -+ -+static struct resource atmel_psif1_resource[] __initdata = { -+ { -+ .start = 0xffe03d00, -+ .end = 0xffe03dff, -+ .flags = IORESOURCE_MEM, -+ }, -+ IRQ(18), -+}; -+static struct clk atmel_psif1_pclk = { -+ .name = "pclk", -+ .parent = &pba_clk, -+ .mode = pba_clk_mode, -+ .get_rate = pba_clk_get_rate, -+ .index = 15, -+}; -+ -+struct platform_device *__init at32_add_device_psif(unsigned int id) -+{ -+ struct platform_device *pdev; -+ -+ if (!(id == 0 || id == 1)) -+ return NULL; -+ -+ pdev = platform_device_alloc("atmel_psif", id); -+ if (!pdev) -+ return NULL; -+ -+ switch (id) { -+ case 0: -+ if (platform_device_add_resources(pdev, atmel_psif0_resource, -+ ARRAY_SIZE(atmel_psif0_resource))) -+ goto err_add_resources; -+ atmel_psif0_pclk.dev = &pdev->dev; -+ select_peripheral(PA(8), PERIPH_A, 0); /* CLOCK */ -+ select_peripheral(PA(9), PERIPH_A, 0); /* DATA */ -+ break; -+ case 1: -+ if (platform_device_add_resources(pdev, atmel_psif1_resource, -+ ARRAY_SIZE(atmel_psif1_resource))) -+ goto err_add_resources; -+ atmel_psif1_pclk.dev = &pdev->dev; -+ select_peripheral(PB(11), PERIPH_A, 0); /* CLOCK */ -+ select_peripheral(PB(12), PERIPH_A, 0); /* DATA */ -+ break; -+ default: -+ return NULL; -+ } -+ -+ platform_device_add(pdev); -+ return pdev; -+ -+err_add_resources: -+ platform_device_put(pdev); -+ return NULL; -+} -+ -+/* -------------------------------------------------------------------- - * USART - * -------------------------------------------------------------------- */ - -@@ -951,7 +1190,8 @@ at32_add_device_spi(unsigned int id, str - switch (id) { - case 0: - pdev = &atmel_spi0_device; -- select_peripheral(PA(0), PERIPH_A, 0); /* MISO */ -+ /* pullup MISO so a level is always defined */ -+ select_peripheral(PA(0), PERIPH_A, AT32_GPIOF_PULLUP); - select_peripheral(PA(1), PERIPH_A, 0); /* MOSI */ - select_peripheral(PA(2), PERIPH_A, 0); /* SCK */ - at32_spi_setup_slaves(0, b, n, spi0_pins); -@@ -959,7 +1199,8 @@ at32_add_device_spi(unsigned int id, str - - case 1: - pdev = &atmel_spi1_device; -- select_peripheral(PB(0), PERIPH_B, 0); /* MISO */ -+ /* pullup MISO so a level is always defined */ -+ select_peripheral(PB(0), PERIPH_B, AT32_GPIOF_PULLUP); - select_peripheral(PB(1), PERIPH_B, 0); /* MOSI */ - select_peripheral(PB(5), PERIPH_B, 0); /* SCK */ - at32_spi_setup_slaves(1, b, n, spi1_pins); -@@ -989,7 +1230,9 @@ static struct clk atmel_twi0_pclk = { - .index = 2, - }; - --struct platform_device *__init at32_add_device_twi(unsigned int id) -+struct platform_device *__init at32_add_device_twi(unsigned int id, -+ struct i2c_board_info *b, -+ unsigned int n) - { - struct platform_device *pdev; - -@@ -1009,6 +1252,9 @@ struct platform_device *__init at32_add_ - - atmel_twi0_pclk.dev = &pdev->dev; - -+ if (b) -+ i2c_register_board_info(id, b, n); -+ - platform_device_add(pdev); - return pdev; - -@@ -1032,7 +1278,8 @@ static struct clk atmel_mci0_pclk = { - .index = 9, - }; - --struct platform_device *__init at32_add_device_mci(unsigned int id) -+struct platform_device *__init -+at32_add_device_mci(unsigned int id, struct mci_platform_data *data) - { - struct platform_device *pdev; - -@@ -1041,11 +1288,15 @@ struct platform_device *__init at32_add_ - - pdev = platform_device_alloc("atmel_mci", id); - if (!pdev) -- return NULL; -+ goto fail; - - if (platform_device_add_resources(pdev, atmel_mci0_resource, - ARRAY_SIZE(atmel_mci0_resource))) -- goto err_add_resources; -+ goto fail; -+ -+ if (data && platform_device_add_data(pdev, data, -+ sizeof(struct mci_platform_data))) -+ goto fail; - - select_peripheral(PA(10), PERIPH_A, 0); /* CLK */ - select_peripheral(PA(11), PERIPH_A, 0); /* CMD */ -@@ -1054,12 +1305,19 @@ struct platform_device *__init at32_add_ - select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */ - select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */ - -+ if (data) { -+ if (data->detect_pin != GPIO_PIN_NONE) -+ at32_select_gpio(data->detect_pin, 0); -+ if (data->wp_pin != GPIO_PIN_NONE) -+ at32_select_gpio(data->wp_pin, 0); -+ } -+ - atmel_mci0_pclk.dev = &pdev->dev; - - platform_device_add(pdev); - return pdev; - --err_add_resources: -+fail: - platform_device_put(pdev); - return NULL; - } -@@ -1097,7 +1355,8 @@ static struct clk atmel_lcdfb0_pixclk = - - struct platform_device *__init - at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, -- unsigned long fbmem_start, unsigned long fbmem_len) -+ unsigned long fbmem_start, unsigned long fbmem_len, -+ unsigned int pin_config) - { - struct platform_device *pdev; - struct atmel_lcdfb_info *info; -@@ -1124,37 +1383,77 @@ at32_add_device_lcdc(unsigned int id, st - switch (id) { - case 0: - pdev = &atmel_lcdfb0_device; -- select_peripheral(PC(19), PERIPH_A, 0); /* CC */ -- select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */ -- select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */ -- select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */ -- select_peripheral(PC(23), PERIPH_A, 0); /* DVAL */ -- select_peripheral(PC(24), PERIPH_A, 0); /* MODE */ -- select_peripheral(PC(25), PERIPH_A, 0); /* PWR */ -- select_peripheral(PC(26), PERIPH_A, 0); /* DATA0 */ -- select_peripheral(PC(27), PERIPH_A, 0); /* DATA1 */ -- select_peripheral(PC(28), PERIPH_A, 0); /* DATA2 */ -- select_peripheral(PC(29), PERIPH_A, 0); /* DATA3 */ -- select_peripheral(PC(30), PERIPH_A, 0); /* DATA4 */ -- select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */ -- select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */ -- select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */ -- select_peripheral(PD(2), PERIPH_A, 0); /* DATA8 */ -- select_peripheral(PD(3), PERIPH_A, 0); /* DATA9 */ -- select_peripheral(PD(4), PERIPH_A, 0); /* DATA10 */ -- select_peripheral(PD(5), PERIPH_A, 0); /* DATA11 */ -- select_peripheral(PD(6), PERIPH_A, 0); /* DATA12 */ -- select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */ -- select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */ -- select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */ -- select_peripheral(PD(10), PERIPH_A, 0); /* DATA16 */ -- select_peripheral(PD(11), PERIPH_A, 0); /* DATA17 */ -- select_peripheral(PD(12), PERIPH_A, 0); /* DATA18 */ -- select_peripheral(PD(13), PERIPH_A, 0); /* DATA19 */ -- select_peripheral(PD(14), PERIPH_A, 0); /* DATA20 */ -- select_peripheral(PD(15), PERIPH_A, 0); /* DATA21 */ -- select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */ -- select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */ -+ -+ switch (pin_config) { -+ case 0: -+ select_peripheral(PC(19), PERIPH_A, 0); /* CC */ -+ select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */ -+ select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */ -+ select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */ -+ select_peripheral(PC(23), PERIPH_A, 0); /* DVAL */ -+ select_peripheral(PC(24), PERIPH_A, 0); /* MODE */ -+ select_peripheral(PC(25), PERIPH_A, 0); /* PWR */ -+ select_peripheral(PC(26), PERIPH_A, 0); /* DATA0 */ -+ select_peripheral(PC(27), PERIPH_A, 0); /* DATA1 */ -+ select_peripheral(PC(28), PERIPH_A, 0); /* DATA2 */ -+ select_peripheral(PC(29), PERIPH_A, 0); /* DATA3 */ -+ select_peripheral(PC(30), PERIPH_A, 0); /* DATA4 */ -+ select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */ -+ select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */ -+ select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */ -+ select_peripheral(PD(2), PERIPH_A, 0); /* DATA8 */ -+ select_peripheral(PD(3), PERIPH_A, 0); /* DATA9 */ -+ select_peripheral(PD(4), PERIPH_A, 0); /* DATA10 */ -+ select_peripheral(PD(5), PERIPH_A, 0); /* DATA11 */ -+ select_peripheral(PD(6), PERIPH_A, 0); /* DATA12 */ -+ select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */ -+ select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */ -+ select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */ -+ select_peripheral(PD(10), PERIPH_A, 0); /* DATA16 */ -+ select_peripheral(PD(11), PERIPH_A, 0); /* DATA17 */ -+ select_peripheral(PD(12), PERIPH_A, 0); /* DATA18 */ -+ select_peripheral(PD(13), PERIPH_A, 0); /* DATA19 */ -+ select_peripheral(PD(14), PERIPH_A, 0); /* DATA20 */ -+ select_peripheral(PD(15), PERIPH_A, 0); /* DATA21 */ -+ select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */ -+ select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */ -+ break; -+ case 1: -+ select_peripheral(PE(0), PERIPH_B, 0); /* CC */ -+ select_peripheral(PC(20), PERIPH_A, 0); /* HSYNC */ -+ select_peripheral(PC(21), PERIPH_A, 0); /* PCLK */ -+ select_peripheral(PC(22), PERIPH_A, 0); /* VSYNC */ -+ select_peripheral(PE(1), PERIPH_B, 0); /* DVAL */ -+ select_peripheral(PE(2), PERIPH_B, 0); /* MODE */ -+ select_peripheral(PC(25), PERIPH_A, 0); /* PWR */ -+ select_peripheral(PE(3), PERIPH_B, 0); /* DATA0 */ -+ select_peripheral(PE(4), PERIPH_B, 0); /* DATA1 */ -+ select_peripheral(PE(5), PERIPH_B, 0); /* DATA2 */ -+ select_peripheral(PE(6), PERIPH_B, 0); /* DATA3 */ -+ select_peripheral(PE(7), PERIPH_B, 0); /* DATA4 */ -+ select_peripheral(PC(31), PERIPH_A, 0); /* DATA5 */ -+ select_peripheral(PD(0), PERIPH_A, 0); /* DATA6 */ -+ select_peripheral(PD(1), PERIPH_A, 0); /* DATA7 */ -+ select_peripheral(PE(8), PERIPH_B, 0); /* DATA8 */ -+ select_peripheral(PE(9), PERIPH_B, 0); /* DATA9 */ -+ select_peripheral(PE(10), PERIPH_B, 0); /* DATA10 */ -+ select_peripheral(PE(11), PERIPH_B, 0); /* DATA11 */ -+ select_peripheral(PE(12), PERIPH_B, 0); /* DATA12 */ -+ select_peripheral(PD(7), PERIPH_A, 0); /* DATA13 */ -+ select_peripheral(PD(8), PERIPH_A, 0); /* DATA14 */ -+ select_peripheral(PD(9), PERIPH_A, 0); /* DATA15 */ -+ select_peripheral(PE(13), PERIPH_B, 0); /* DATA16 */ -+ select_peripheral(PE(14), PERIPH_B, 0); /* DATA17 */ -+ select_peripheral(PE(15), PERIPH_B, 0); /* DATA18 */ -+ select_peripheral(PE(16), PERIPH_B, 0); /* DATA19 */ -+ select_peripheral(PE(17), PERIPH_B, 0); /* DATA20 */ -+ select_peripheral(PE(18), PERIPH_B, 0); /* DATA21 */ -+ select_peripheral(PD(16), PERIPH_A, 0); /* DATA22 */ -+ select_peripheral(PD(17), PERIPH_A, 0); /* DATA23 */ -+ break; -+ default: -+ goto err_invalid_id; -+ } - - clk_set_parent(&atmel_lcdfb0_pixclk, &pll0); - clk_set_rate(&atmel_lcdfb0_pixclk, clk_get_rate(&pll0)); -@@ -1351,9 +1650,39 @@ static struct clk usba0_hclk = { - .index = 6, - }; - -+#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ -+ [idx] = { \ -+ .name = nam, \ -+ .index = idx, \ -+ .fifo_size = maxpkt, \ -+ .nr_banks = maxbk, \ -+ .can_dma = dma, \ -+ .can_isoc = isoc, \ -+ } -+ -+static struct usba_ep_data at32_usba_ep[] __initdata = { -+ EP("ep0", 0, 64, 1, 0, 0), -+ EP("ep1", 1, 512, 2, 1, 1), -+ EP("ep2", 2, 512, 2, 1, 1), -+ EP("ep3-int", 3, 64, 3, 1, 0), -+ EP("ep4-int", 4, 64, 3, 1, 0), -+ EP("ep5", 5, 1024, 3, 1, 1), -+ EP("ep6", 6, 1024, 3, 1, 1), -+}; -+ -+#undef EP -+ - struct platform_device *__init - at32_add_device_usba(unsigned int id, struct usba_platform_data *data) - { -+ /* -+ * pdata doesn't have room for any endpoints, so we need to -+ * append room for the ones we need right after it. -+ */ -+ struct { -+ struct usba_platform_data pdata; -+ struct usba_ep_data ep[7]; -+ } usba_data; - struct platform_device *pdev; - - if (id != 0) -@@ -1367,13 +1696,20 @@ at32_add_device_usba(unsigned int id, st - ARRAY_SIZE(usba0_resource))) - goto out_free_pdev; - -- if (data) { -- if (platform_device_add_data(pdev, data, sizeof(*data))) -- goto out_free_pdev; -+ if (data) -+ usba_data.pdata.vbus_pin = data->vbus_pin; -+ else -+ usba_data.pdata.vbus_pin = -EINVAL; - -- if (data->vbus_pin != GPIO_PIN_NONE) -- at32_select_gpio(data->vbus_pin, 0); -- } -+ data = &usba_data.pdata; -+ data->num_ep = ARRAY_SIZE(at32_usba_ep); -+ memcpy(data->ep, at32_usba_ep, sizeof(at32_usba_ep)); -+ -+ if (platform_device_add_data(pdev, data, sizeof(usba_data))) -+ goto out_free_pdev; -+ -+ if (data->vbus_pin >= 0) -+ at32_select_gpio(data->vbus_pin, 0); - - usba0_pclk.dev = &pdev->dev; - usba0_hclk.dev = &pdev->dev; -@@ -1526,6 +1862,58 @@ fail: - #endif - - /* -------------------------------------------------------------------- -+ * NAND Flash / SmartMedia -+ * -------------------------------------------------------------------- */ -+static struct resource smc_cs3_resource[] __initdata = { -+ { -+ .start = 0x0c000000, -+ .end = 0x0fffffff, -+ .flags = IORESOURCE_MEM, -+ }, { -+ .start = 0xfff03c00, -+ .end = 0xfff03fff, -+ .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 fail; -+ -+ if (platform_device_add_resources(pdev, smc_cs3_resource, -+ ARRAY_SIZE(smc_cs3_resource))) -+ goto fail; -+ -+ if (platform_device_add_data(pdev, data, -+ sizeof(struct atmel_nand_data))) -+ goto fail; -+ -+ set_ebi_sfr_bits(HMATRIX_BIT(CS3A)); -+ if (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) -+ at32_select_gpio(data->det_pin, 0); -+ -+ platform_device_add(pdev); -+ return pdev; -+ -+fail: -+ platform_device_put(pdev); -+ return NULL; -+} -+ -+/* -------------------------------------------------------------------- - * AC97C - * -------------------------------------------------------------------- */ - static struct resource atmel_ac97c0_resource[] __initdata = { -@@ -1540,9 +1928,11 @@ static struct clk atmel_ac97c0_pclk = { - .index = 10, - }; - --struct platform_device *__init at32_add_device_ac97c(unsigned int id) -+struct platform_device *__init -+at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data) - { - struct platform_device *pdev; -+ struct ac97c_platform_data _data; - - if (id != 0) - return NULL; -@@ -1553,19 +1943,37 @@ struct platform_device *__init at32_add_ - - if (platform_device_add_resources(pdev, atmel_ac97c0_resource, - ARRAY_SIZE(atmel_ac97c0_resource))) -- goto err_add_resources; -+ goto fail; - -- select_peripheral(PB(20), PERIPH_B, 0); /* SYNC */ -- select_peripheral(PB(21), PERIPH_B, 0); /* SDO */ -- select_peripheral(PB(22), PERIPH_B, 0); /* SDI */ -- select_peripheral(PB(23), PERIPH_B, 0); /* SCLK */ -+ if (!data) { -+ data = &_data; -+ memset(data, 0, sizeof(struct ac97c_platform_data)); -+ data->reset_pin = GPIO_PIN_NONE; -+ } -+ -+ data->dma_rx_periph_id = 3; -+ data->dma_tx_periph_id = 4; -+ data->dma_controller_id = 0; -+ -+ if (platform_device_add_data(pdev, data, -+ sizeof(struct ac97c_platform_data))) -+ goto fail; -+ -+ select_peripheral(PB(20), PERIPH_B, 0); /* SDO */ -+ select_peripheral(PB(21), PERIPH_B, 0); /* SYNC */ -+ select_peripheral(PB(22), PERIPH_B, 0); /* SCLK */ -+ select_peripheral(PB(23), PERIPH_B, 0); /* SDI */ -+ -+ /* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */ -+ if (data->reset_pin != GPIO_PIN_NONE) -+ at32_select_gpio(data->reset_pin, 0); - - atmel_ac97c0_pclk.dev = &pdev->dev; - - platform_device_add(pdev); - return pdev; - --err_add_resources: -+fail: - platform_device_put(pdev); - return NULL; - } -@@ -1683,6 +2091,7 @@ struct clk *at32_clock_list[] = { - &hmatrix_clk, - &ebi_clk, - &hramc_clk, -+ &sdramc_clk, - &smc0_pclk, - &smc0_mck, - &pdc_hclk, -@@ -1694,7 +2103,10 @@ struct clk *at32_clock_list[] = { - &pio2_mck, - &pio3_mck, - &pio4_mck, -- &at32_systc0_pclk, -+ &at32_tcb0_t0_clk, -+ &at32_tcb1_t0_clk, -+ &atmel_psif0_pclk, -+ &atmel_psif1_pclk, - &atmel_usart0_usart, - &atmel_usart1_usart, - &atmel_usart2_usart, -@@ -1730,16 +2142,7 @@ struct clk *at32_clock_list[] = { - }; - unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list); - --void __init at32_portmux_init(void) --{ -- at32_init_pio(&pio0_device); -- at32_init_pio(&pio1_device); -- at32_init_pio(&pio2_device); -- at32_init_pio(&pio3_device); -- at32_init_pio(&pio4_device); --} -- --void __init at32_clock_init(void) -+void __init setup_platform(void) - { - u32 cpu_mask = 0, hsb_mask = 0, pba_mask = 0, pbb_mask = 0; - int i; -@@ -1794,4 +2197,36 @@ void __init at32_clock_init(void) - pm_writel(HSB_MASK, hsb_mask); - pm_writel(PBA_MASK, pba_mask); - pm_writel(PBB_MASK, pbb_mask); -+ -+ /* Initialize the port muxes */ -+ at32_init_pio(&pio0_device); -+ at32_init_pio(&pio1_device); -+ at32_init_pio(&pio2_device); -+ at32_init_pio(&pio3_device); -+ at32_init_pio(&pio4_device); -+} -+ -+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, 0x24000000, 0x8000, -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); ---- a/arch/avr32/mach-at32ap/cpufreq.c -+++ b/arch/avr32/mach-at32ap/cpufreq.c -@@ -108,5 +108,4 @@ static int __init at32_cpufreq_init(void - { - return cpufreq_register_driver(&at32_driver); - } -- --arch_initcall(at32_cpufreq_init); -+late_initcall(at32_cpufreq_init); ---- /dev/null -+++ b/arch/avr32/mach-at32ap/gpio-dev.c -@@ -0,0 +1,573 @@ -+/* -+ * GPIO /dev and configfs interface -+ * -+ * Copyright (C) 2006-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. -+ */ -+#include <linux/kernel.h> -+#include <linux/configfs.h> -+#include <linux/cdev.h> -+#include <linux/device.h> -+#include <linux/fs.h> -+#include <linux/interrupt.h> -+#include <linux/module.h> -+#include <linux/poll.h> -+#include <linux/uaccess.h> -+#include <linux/wait.h> -+ -+#include <asm/gpio.h> -+#include <asm/arch/portmux.h> -+ -+#define GPIO_DEV_MAX 8 -+ -+static struct class *gpio_dev_class; -+static dev_t gpio_devt; -+ -+struct gpio_item { -+ spinlock_t lock; -+ -+ int enabled; -+ int initialized; -+ int port; -+ u32 pin_mask; -+ u32 oe_mask; -+ -+ /* Pin state last time we read it (for blocking reads) */ -+ u32 pin_state; -+ int changed; -+ -+ wait_queue_head_t change_wq; -+ struct fasync_struct *async_queue; -+ -+ int id; -+ struct class_device *gpio_dev; -+ struct cdev char_dev; -+ struct config_item item; -+}; -+ -+struct gpio_attribute { -+ struct configfs_attribute attr; -+ ssize_t (*show)(struct gpio_item *, char *); -+ ssize_t (*store)(struct gpio_item *, const char *, size_t); -+}; -+ -+static irqreturn_t gpio_dev_interrupt(int irq, void *dev_id) -+{ -+ struct gpio_item *gpio = dev_id; -+ u32 old_state, new_state; -+ -+ old_state = gpio->pin_state; -+ new_state = at32_gpio_get_value_multiple(gpio->port, gpio->pin_mask); -+ gpio->pin_state = new_state; -+ -+ if (new_state != old_state) { -+ gpio->changed = 1; -+ wake_up_interruptible(&gpio->change_wq); -+ -+ if (gpio->async_queue) -+ kill_fasync(&gpio->async_queue, SIGIO, POLL_IN); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static int gpio_dev_open(struct inode *inode, struct file *file) -+{ -+ struct gpio_item *gpio = container_of(inode->i_cdev, -+ struct gpio_item, -+ char_dev); -+ unsigned int irq; -+ unsigned int i; -+ int ret; -+ -+ nonseekable_open(inode, file); -+ config_item_get(&gpio->item); -+ file->private_data = gpio; -+ -+ gpio->pin_state = at32_gpio_get_value_multiple(gpio->port, -+ gpio->pin_mask); -+ gpio->changed = 1; -+ -+ for (i = 0; i < 32; i++) { -+ if (gpio->pin_mask & (1 << i)) { -+ irq = gpio_to_irq(32 * gpio->port + i); -+ ret = request_irq(irq, gpio_dev_interrupt, 0, -+ "gpio-dev", gpio); -+ if (ret) -+ goto err_irq; -+ } -+ } -+ -+ return 0; -+ -+err_irq: -+ while (i--) { -+ if (gpio->pin_mask & (1 << i)) { -+ irq = gpio_to_irq(32 * gpio->port + i); -+ free_irq(irq, gpio); -+ } -+ } -+ -+ config_item_put(&gpio->item); -+ -+ return ret; -+} -+ -+static int gpio_dev_fasync(int fd, struct file *file, int mode) -+{ -+ struct gpio_item *gpio = file->private_data; -+ -+ return fasync_helper(fd, file, mode, &gpio->async_queue); -+} -+ -+static int gpio_dev_release(struct inode *inode, struct file *file) -+{ -+ struct gpio_item *gpio = file->private_data; -+ unsigned int irq; -+ unsigned int i; -+ -+ gpio_dev_fasync(-1, file, 0); -+ -+ for (i = 0; i < 32; i++) { -+ if (gpio->pin_mask & (1 << i)) { -+ irq = gpio_to_irq(32 * gpio->port + i); -+ free_irq(irq, gpio); -+ } -+ } -+ -+ config_item_put(&gpio->item); -+ -+ return 0; -+} -+ -+static unsigned int gpio_dev_poll(struct file *file, poll_table *wait) -+{ -+ struct gpio_item *gpio = file->private_data; -+ unsigned int mask = 0; -+ -+ poll_wait(file, &gpio->change_wq, wait); -+ if (gpio->changed) -+ mask |= POLLIN | POLLRDNORM; -+ -+ return mask; -+} -+ -+static ssize_t gpio_dev_read(struct file *file, char __user *buf, -+ size_t count, loff_t *offset) -+{ -+ struct gpio_item *gpio = file->private_data; -+ u32 value; -+ -+ spin_lock_irq(&gpio->lock); -+ while (!gpio->changed) { -+ spin_unlock_irq(&gpio->lock); -+ -+ if (file->f_flags & O_NONBLOCK) -+ return -EAGAIN; -+ -+ if (wait_event_interruptible(gpio->change_wq, gpio->changed)) -+ return -ERESTARTSYS; -+ -+ spin_lock_irq(&gpio->lock); -+ } -+ -+ gpio->changed = 0; -+ value = at32_gpio_get_value_multiple(gpio->port, gpio->pin_mask); -+ -+ spin_unlock_irq(&gpio->lock); -+ -+ count = min(count, (size_t)4); -+ if (copy_to_user(buf, &value, count)) -+ return -EFAULT; -+ -+ return count; -+} -+ -+static ssize_t gpio_dev_write(struct file *file, const char __user *buf, -+ size_t count, loff_t *offset) -+{ -+ struct gpio_item *gpio = file->private_data; -+ u32 value = 0; -+ u32 mask = ~0UL; -+ -+ count = min(count, (size_t)4); -+ if (copy_from_user(&value, buf, count)) -+ return -EFAULT; -+ -+ /* Assuming big endian */ -+ mask <<= (4 - count) * 8; -+ mask &= gpio->pin_mask; -+ -+ at32_gpio_set_value_multiple(gpio->port, value, mask); -+ -+ return count; -+} -+ -+static struct file_operations gpio_dev_fops = { -+ .owner = THIS_MODULE, -+ .llseek = no_llseek, -+ .open = gpio_dev_open, -+ .release = gpio_dev_release, -+ .fasync = gpio_dev_fasync, -+ .poll = gpio_dev_poll, -+ .read = gpio_dev_read, -+ .write = gpio_dev_write, -+}; -+ -+static struct gpio_item *to_gpio_item(struct config_item *item) -+{ -+ return item ? container_of(item, struct gpio_item, item) : NULL; -+} -+ -+static ssize_t gpio_show_gpio_id(struct gpio_item *gpio, char *page) -+{ -+ return sprintf(page, "%d\n", gpio->port); -+} -+ -+static ssize_t gpio_store_gpio_id(struct gpio_item *gpio, -+ const char *page, size_t count) -+{ -+ unsigned long id; -+ char *p = (char *)page; -+ ssize_t ret = -EINVAL; -+ -+ id = simple_strtoul(p, &p, 0); -+ if (!p || (*p && (*p != '\n'))) -+ return -EINVAL; -+ -+ /* Switching PIO is not allowed when live... */ -+ spin_lock(&gpio->lock); -+ if (!gpio->enabled) { -+ ret = -ENXIO; -+ if (at32_gpio_port_is_valid(id)) { -+ gpio->port = id; -+ ret = count; -+ } -+ } -+ spin_unlock(&gpio->lock); -+ -+ return ret; -+} -+ -+static ssize_t gpio_show_pin_mask(struct gpio_item *gpio, char *page) -+{ -+ return sprintf(page, "0x%08x\n", gpio->pin_mask); -+} -+ -+static ssize_t gpio_store_pin_mask(struct gpio_item *gpio, -+ const char *page, size_t count) -+{ -+ u32 new_mask; -+ char *p = (char *)page; -+ ssize_t ret = -EINVAL; -+ -+ new_mask = simple_strtoul(p, &p, 0); -+ if (!p || (*p && (*p != '\n'))) -+ return -EINVAL; -+ -+ /* Can't update the pin mask while live. */ -+ spin_lock(&gpio->lock); -+ if (!gpio->enabled) { -+ gpio->oe_mask &= new_mask; -+ gpio->pin_mask = new_mask; -+ ret = count; -+ } -+ spin_unlock(&gpio->lock); -+ -+ return ret; -+} -+ -+static ssize_t gpio_show_oe_mask(struct gpio_item *gpio, char *page) -+{ -+ return sprintf(page, "0x%08x\n", gpio->oe_mask); -+} -+ -+static ssize_t gpio_store_oe_mask(struct gpio_item *gpio, -+ const char *page, size_t count) -+{ -+ u32 mask; -+ char *p = (char *)page; -+ ssize_t ret = -EINVAL; -+ -+ mask = simple_strtoul(p, &p, 0); -+ if (!p || (*p && (*p != '\n'))) -+ return -EINVAL; -+ -+ spin_lock(&gpio->lock); -+ if (!gpio->enabled) { -+ gpio->oe_mask = mask & gpio->pin_mask; -+ ret = count; -+ } -+ spin_unlock(&gpio->lock); -+ -+ return ret; -+} -+ -+static ssize_t gpio_show_enabled(struct gpio_item *gpio, char *page) -+{ -+ return sprintf(page, "%d\n", gpio->enabled); -+} -+ -+static ssize_t gpio_store_enabled(struct gpio_item *gpio, -+ const char *page, size_t count) -+{ -+ char *p = (char *)page; -+ int enabled; -+ int ret; -+ -+ enabled = simple_strtoul(p, &p, 0); -+ if (!p || (*p && (*p != '\n'))) -+ return -EINVAL; -+ -+ /* make it a boolean value */ -+ enabled = !!enabled; -+ -+ if (gpio->enabled == enabled) -+ /* No change; do nothing. */ -+ return count; -+ -+ BUG_ON(gpio->id >= GPIO_DEV_MAX); -+ -+ if (!enabled) { -+ class_device_unregister(gpio->gpio_dev); -+ cdev_del(&gpio->char_dev); -+ at32_deselect_pins(gpio->port, gpio->pin_mask); -+ gpio->initialized = 0; -+ } else { -+ if (gpio->port < 0 || !gpio->pin_mask) -+ return -ENODEV; -+ } -+ -+ /* Disallow any updates to gpio_id or pin_mask */ -+ spin_lock(&gpio->lock); -+ gpio->enabled = enabled; -+ spin_unlock(&gpio->lock); -+ -+ if (!enabled) -+ return count; -+ -+ /* Now, try to allocate the pins */ -+ ret = at32_select_gpio_pins(gpio->port, gpio->pin_mask, gpio->oe_mask); -+ if (ret) -+ goto err_alloc_pins; -+ -+ gpio->initialized = 1; -+ -+ cdev_init(&gpio->char_dev, &gpio_dev_fops); -+ gpio->char_dev.owner = THIS_MODULE; -+ ret = cdev_add(&gpio->char_dev, MKDEV(MAJOR(gpio_devt), gpio->id), 1); -+ if (ret < 0) -+ goto err_cdev_add; -+ gpio->gpio_dev = class_device_create(gpio_dev_class, NULL, -+ MKDEV(MAJOR(gpio_devt), gpio->id), -+ NULL, -+ "gpio%d", gpio->id); -+ if (IS_ERR(gpio->gpio_dev)) { -+ printk(KERN_ERR "failed to create gpio%d\n", gpio->id); -+ ret = PTR_ERR(gpio->gpio_dev); -+ goto err_class_dev; -+ } -+ -+ printk(KERN_INFO "created gpio%d (port%d/0x%08x) as (%d:%d)\n", -+ gpio->id, gpio->port, gpio->pin_mask, -+ MAJOR(gpio->gpio_dev->devt), MINOR(gpio->gpio_dev->devt)); -+ -+ return 0; -+ -+err_class_dev: -+ cdev_del(&gpio->char_dev); -+err_cdev_add: -+ at32_deselect_pins(gpio->port, gpio->pin_mask); -+ gpio->initialized = 0; -+err_alloc_pins: -+ spin_lock(&gpio->lock); -+ gpio->enabled = 0; -+ spin_unlock(&gpio->lock); -+ -+ return ret; -+} -+ -+static struct gpio_attribute gpio_item_attr_gpio_id = { -+ .attr = { -+ .ca_owner = THIS_MODULE, -+ .ca_name = "gpio_id", -+ .ca_mode = S_IRUGO | S_IWUSR, -+ }, -+ .show = gpio_show_gpio_id, -+ .store = gpio_store_gpio_id, -+}; -+static struct gpio_attribute gpio_item_attr_pin_mask = { -+ .attr = { -+ .ca_owner = THIS_MODULE, -+ .ca_name = "pin_mask", -+ .ca_mode = S_IRUGO | S_IWUSR, -+ }, -+ .show = gpio_show_pin_mask, -+ .store = gpio_store_pin_mask, -+}; -+static struct gpio_attribute gpio_item_attr_oe_mask = { -+ .attr = { -+ .ca_owner = THIS_MODULE, -+ .ca_name = "oe_mask", -+ .ca_mode = S_IRUGO | S_IWUSR, -+ }, -+ .show = gpio_show_oe_mask, -+ .store = gpio_store_oe_mask, -+}; -+static struct gpio_attribute gpio_item_attr_enabled = { -+ .attr = { -+ .ca_owner = THIS_MODULE, -+ .ca_name = "enabled", -+ .ca_mode = S_IRUGO | S_IWUSR, -+ }, -+ .show = gpio_show_enabled, -+ .store = gpio_store_enabled, -+}; -+ -+static struct configfs_attribute *gpio_item_attrs[] = { -+ &gpio_item_attr_gpio_id.attr, -+ &gpio_item_attr_pin_mask.attr, -+ &gpio_item_attr_oe_mask.attr, -+ &gpio_item_attr_enabled.attr, -+ NULL, -+}; -+ -+static ssize_t gpio_show_attr(struct config_item *item, -+ struct configfs_attribute *attr, -+ char *page) -+{ -+ struct gpio_item *gpio_item = to_gpio_item(item); -+ struct gpio_attribute *gpio_attr -+ = container_of(attr, struct gpio_attribute, attr); -+ ssize_t ret = 0; -+ -+ if (gpio_attr->show) -+ ret = gpio_attr->show(gpio_item, page); -+ return ret; -+} -+ -+static ssize_t gpio_store_attr(struct config_item *item, -+ struct configfs_attribute *attr, -+ const char *page, size_t count) -+{ -+ struct gpio_item *gpio_item = to_gpio_item(item); -+ struct gpio_attribute *gpio_attr -+ = container_of(attr, struct gpio_attribute, attr); -+ ssize_t ret = -EINVAL; -+ -+ if (gpio_attr->store) -+ ret = gpio_attr->store(gpio_item, page, count); -+ return ret; -+} -+ -+static void gpio_release(struct config_item *item) -+{ -+ kfree(to_gpio_item(item)); -+} -+ -+static struct configfs_item_operations gpio_item_ops = { -+ .release = gpio_release, -+ .show_attribute = gpio_show_attr, -+ .store_attribute = gpio_store_attr, -+}; -+ -+static struct config_item_type gpio_item_type = { -+ .ct_item_ops = &gpio_item_ops, -+ .ct_attrs = gpio_item_attrs, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct config_item *gpio_make_item(struct config_group *group, -+ const char *name) -+{ -+ static int next_id; -+ struct gpio_item *gpio; -+ -+ if (next_id >= GPIO_DEV_MAX) -+ return NULL; -+ -+ gpio = kzalloc(sizeof(struct gpio_item), GFP_KERNEL); -+ if (!gpio) -+ return NULL; -+ -+ gpio->id = next_id++; -+ config_item_init_type_name(&gpio->item, name, &gpio_item_type); -+ spin_lock_init(&gpio->lock); -+ init_waitqueue_head(&gpio->change_wq); -+ -+ return &gpio->item; -+} -+ -+static void gpio_drop_item(struct config_group *group, -+ struct config_item *item) -+{ -+ struct gpio_item *gpio = to_gpio_item(item); -+ -+ spin_lock(&gpio->lock); -+ if (gpio->enabled) { -+ class_device_unregister(gpio->gpio_dev); -+ cdev_del(&gpio->char_dev); -+ } -+ -+ if (gpio->initialized) { -+ at32_deselect_pins(gpio->port, gpio->pin_mask); -+ gpio->initialized = 0; -+ gpio->enabled = 0; -+ } -+ spin_unlock(&gpio->lock); -+} -+ -+static struct configfs_group_operations gpio_group_ops = { -+ .make_item = gpio_make_item, -+ .drop_item = gpio_drop_item, -+}; -+ -+static struct config_item_type gpio_group_type = { -+ .ct_group_ops = &gpio_group_ops, -+ .ct_owner = THIS_MODULE, -+}; -+ -+static struct configfs_subsystem gpio_subsys = { -+ .su_group = { -+ .cg_item = { -+ .ci_namebuf = "gpio", -+ .ci_type = &gpio_group_type, -+ }, -+ }, -+}; -+ -+static int __init gpio_dev_init(void) -+{ -+ int err; -+ -+ gpio_dev_class = class_create(THIS_MODULE, "gpio-dev"); -+ if (IS_ERR(gpio_dev_class)) { -+ err = PTR_ERR(gpio_dev_class); -+ goto err_class_create; -+ } -+ -+ err = alloc_chrdev_region(&gpio_devt, 0, GPIO_DEV_MAX, "gpio"); -+ if (err < 0) -+ goto err_alloc_chrdev; -+ -+ /* Configfs initialization */ -+ config_group_init(&gpio_subsys.su_group); -+ mutex_init(&gpio_subsys.su_mutex); -+ err = configfs_register_subsystem(&gpio_subsys); -+ if (err) -+ goto err_register_subsys; -+ -+ return 0; -+ -+err_register_subsys: -+ unregister_chrdev_region(gpio_devt, GPIO_DEV_MAX); -+err_alloc_chrdev: -+ class_destroy(gpio_dev_class); -+err_class_create: -+ printk(KERN_WARNING "Failed to initialize gpio /dev interface\n"); -+ return err; -+} -+late_initcall(gpio_dev_init); ---- a/arch/avr32/mach-at32ap/hsmc.c -+++ b/arch/avr32/mach-at32ap/hsmc.c -@@ -278,4 +278,4 @@ static int __init hsmc_init(void) - { - return platform_driver_register(&hsmc_driver); - } --arch_initcall(hsmc_init); -+core_initcall(hsmc_init); ---- a/arch/avr32/mach-at32ap/intc.c -+++ b/arch/avr32/mach-at32ap/intc.c -@@ -1,5 +1,5 @@ - /* -- * 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 -@@ -12,15 +12,20 @@ - #include <linux/interrupt.h> - #include <linux/irq.h> - #include <linux/platform_device.h> -+#include <linux/sysdev.h> - --#include <asm/intc.h> - #include <asm/io.h> - - #include "intc.h" - - struct intc { -- void __iomem *regs; -- struct irq_chip chip; -+ void __iomem *regs; -+ struct irq_chip chip; -+ struct sys_device sysdev; -+#ifdef CONFIG_PM -+ unsigned long suspend_ipr; -+ unsigned long saved_ipr[64]; -+#endif - }; - - extern struct platform_device at32_intc0_device; -@@ -137,6 +142,74 @@ fail: - panic("Interrupt controller initialization failed!\n"); - } - -+#ifdef CONFIG_PM -+void intc_set_suspend_handler(unsigned long offset) -+{ -+ intc0.suspend_ipr = offset; -+} -+ -+static int intc_suspend(struct sys_device *sdev, pm_message_t state) -+{ -+ struct intc *intc = container_of(sdev, struct intc, sysdev); -+ int i; -+ -+ if (unlikely(!irqs_disabled())) { -+ pr_err("intc_suspend: called with interrupts enabled\n"); -+ return -EINVAL; -+ } -+ -+ if (unlikely(!intc->suspend_ipr)) { -+ pr_err("intc_suspend: suspend_ipr not initialized\n"); -+ return -EINVAL; -+ } -+ -+ for (i = 0; i < 64; i++) { -+ intc->saved_ipr[i] = intc_readl(intc, INTPR0 + 4 * i); -+ intc_writel(intc, INTPR0 + 4 * i, intc->suspend_ipr); -+ } -+ -+ return 0; -+} -+ -+static int intc_resume(struct sys_device *sdev) -+{ -+ struct intc *intc = container_of(sdev, struct intc, sysdev); -+ int i; -+ -+ WARN_ON(!irqs_disabled()); -+ -+ for (i = 0; i < 64; i++) -+ intc_writel(intc, INTPR0 + 4 * i, intc->saved_ipr[i]); -+ -+ return 0; -+} -+#else -+#define intc_suspend NULL -+#define intc_resume NULL -+#endif -+ -+static struct sysdev_class intc_class = { -+ .name = "intc", -+ .suspend = intc_suspend, -+ .resume = intc_resume, -+}; -+ -+static int __init intc_init_sysdev(void) -+{ -+ int ret; -+ -+ ret = sysdev_class_register(&intc_class); -+ if (ret) -+ return ret; -+ -+ intc0.sysdev.id = 0; -+ intc0.sysdev.cls = &intc_class; -+ ret = sysdev_register(&intc0.sysdev); -+ -+ return ret; -+} -+device_initcall(intc_init_sysdev); -+ - unsigned long intc_get_pending(unsigned int group) - { - return intc_readl(&intc0, INTREQ0 + 4 * group); ---- /dev/null -+++ b/arch/avr32/mach-at32ap/pdc.c -@@ -0,0 +1,48 @@ -+/* -+ * Copyright (C) 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/clk.h> -+#include <linux/err.h> -+#include <linux/init.h> -+#include <linux/platform_device.h> -+ -+static int __init pdc_probe(struct platform_device *pdev) -+{ -+ struct clk *pclk, *hclk; -+ -+ pclk = clk_get(&pdev->dev, "pclk"); -+ if (IS_ERR(pclk)) { -+ dev_err(&pdev->dev, "no pclk defined\n"); -+ return PTR_ERR(pclk); -+ } -+ hclk = clk_get(&pdev->dev, "hclk"); -+ if (IS_ERR(hclk)) { -+ dev_err(&pdev->dev, "no hclk defined\n"); -+ clk_put(pclk); -+ return PTR_ERR(hclk); -+ } -+ -+ clk_enable(pclk); -+ clk_enable(hclk); -+ -+ dev_info(&pdev->dev, "Atmel Peripheral DMA Controller enabled\n"); -+ return 0; -+} -+ -+static struct platform_driver pdc_driver = { -+ .probe = pdc_probe, -+ .driver = { -+ .name = "pdc", -+ }, -+}; -+ -+static int __init pdc_init(void) -+{ -+ return platform_driver_register(&pdc_driver); -+} -+arch_initcall(pdc_init); ---- a/arch/avr32/mach-at32ap/pio.c -+++ b/arch/avr32/mach-at32ap/pio.c -@@ -157,6 +157,82 @@ fail: - dump_stack(); - } - -+#ifdef CONFIG_GPIO_DEV -+ -+/* Gang allocators and accessors; used by the GPIO /dev driver */ -+int at32_gpio_port_is_valid(unsigned int port) -+{ -+ return port < MAX_NR_PIO_DEVICES && pio_dev[port].regs != NULL; -+} -+ -+int at32_select_gpio_pins(unsigned int port, u32 pins, u32 oe_mask) -+{ -+ struct pio_device *pio; -+ u32 old, new; -+ -+ pio = &pio_dev[port]; -+ BUG_ON(port > ARRAY_SIZE(pio_dev) || !pio->regs || (oe_mask & ~pins)); -+ -+ /* Try to allocate the pins */ -+ do { -+ old = pio->pinmux_mask; -+ if (old & pins) -+ return -EBUSY; -+ -+ new = old | pins; -+ } while (cmpxchg(&pio->pinmux_mask, old, new) != old); -+ -+ /* That went well, now configure the port */ -+ pio_writel(pio, OER, oe_mask); -+ pio_writel(pio, PER, pins); -+ -+ return 0; -+} -+ -+void at32_deselect_pins(unsigned int port, u32 pins) -+{ -+ struct pio_device *pio; -+ u32 old, new; -+ -+ pio = &pio_dev[port]; -+ BUG_ON(port > ARRAY_SIZE(pio_dev) || !pio->regs); -+ -+ /* Return to a "safe" mux configuration */ -+ pio_writel(pio, PUER, pins); -+ pio_writel(pio, ODR, pins); -+ -+ /* Deallocate the pins */ -+ do { -+ old = pio->pinmux_mask; -+ new = old & ~pins; -+ } while (cmpxchg(&pio->pinmux_mask, old, new) != old); -+} -+ -+u32 at32_gpio_get_value_multiple(unsigned int port, u32 pins) -+{ -+ struct pio_device *pio; -+ -+ pio = &pio_dev[port]; -+ BUG_ON(port > ARRAY_SIZE(pio_dev) || !pio->regs); -+ -+ return pio_readl(pio, PDSR) & pins; -+} -+ -+void at32_gpio_set_value_multiple(unsigned int port, u32 value, u32 mask) -+{ -+ struct pio_device *pio; -+ -+ pio = &pio_dev[port]; -+ BUG_ON(port > ARRAY_SIZE(pio_dev) || !pio->regs); -+ -+ /* No atomic updates for now... */ -+ pio_writel(pio, CODR, ~value & mask); -+ pio_writel(pio, SODR, value & mask); -+} -+ -+#endif /* CONFIG_GPIO_DEV */ -+ -+ - /*--------------------------------------------------------------------------*/ - - /* GPIO API */ -@@ -318,6 +394,8 @@ static void pio_bank_show(struct seq_fil - const char *label; - - label = gpiochip_is_requested(chip, i); -+ if (!label && (imr & mask)) -+ label = "[irq]"; - if (!label) - continue; - ---- a/arch/avr32/mach-at32ap/pio.h -+++ b/arch/avr32/mach-at32ap/pio.h -@@ -57,7 +57,7 @@ - - /* Bitfields in IFDR */ - --/* Bitfields in ISFR */ -+/* Bitfields in IFSR */ - - /* Bitfields in SODR */ - ---- /dev/null -+++ b/arch/avr32/mach-at32ap/pm-at32ap700x.S -@@ -0,0 +1,174 @@ -+/* -+ * 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 <asm/arch/pm.h> -+ -+#include "pm.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 -+disable_idle_sleep: -+ .int 4 -+ .size disable_idle_sleep, . - disable_idle_sleep -+ -+ /* Keep this close to the irq handlers */ -+ .section .irq.text, "ax", @progbits -+ -+ /* -+ * void cpu_enter_idle(void) -+ * -+ * Put the CPU into "idle" mode, in which it will consume -+ * significantly less power. -+ * -+ * If an interrupt comes along in the window between -+ * unmask_interrupts and the sleep instruction below, the -+ * interrupt code will adjust the return address so that we -+ * never execute the sleep instruction. This is required -+ * because the AP7000 doesn't unmask interrupts when entering -+ * sleep modes; later CPUs may not need this workaround. -+ */ -+ .global cpu_enter_idle -+ .type cpu_enter_idle, @function -+cpu_enter_idle: -+ mask_interrupts -+ get_thread_info r8 -+ ld.w r9, r8[TI_flags] -+ bld r9, TIF_NEED_RESCHED -+ brcs .Lret_from_sleep -+ sbr r9, TIF_CPU_GOING_TO_SLEEP -+ st.w r8[TI_flags], r9 -+ unmask_interrupts -+ sleep CPU_SLEEP_IDLE -+ .size cpu_idle_sleep, . - cpu_idle_sleep -+ -+ /* -+ * Common return path for PM functions that don't run from -+ * SRAM. -+ */ -+ .global cpu_idle_skip_sleep -+ .type cpu_idle_skip_sleep, @function -+cpu_idle_skip_sleep: -+ mask_interrupts -+ ld.w r9, r8[TI_flags] -+ cbr r9, TIF_CPU_GOING_TO_SLEEP -+ st.w r8[TI_flags], r9 -+.Lret_from_sleep: -+ unmask_interrupts -+ retal r12 -+ .size cpu_idle_skip_sleep, . - cpu_idle_skip_sleep -+ -+#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. -+ * -+ * This code uses the same "skip sleep" technique as above. -+ * It is very important that we jump directly to -+ * cpu_after_sleep after the sleep instruction since that's -+ * where we'll end up if the interrupt handler decides that we -+ * need to skip the sleep instruction. -+ */ -+ .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], r11 /* put SDRAM in self-refresh mode */ -+ ld.w r11, r12[SDRAMC_LPR] -+ unmask_interrupts -+ sleep CPU_SLEEP_FROZEN -+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] -+ -+ unmask_interrupts -+ sleep CPU_SLEEP_STOP -+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 */ ---- /dev/null -+++ b/arch/avr32/mach-at32ap/pm.c -@@ -0,0 +1,245 @@ -+/* -+ * AVR32 AP Power Management -+ * -+ * 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/io.h> -+#include <linux/suspend.h> -+#include <linux/vmalloc.h> -+ -+#include <asm/cacheflush.h> -+#include <asm/sysreg.h> -+ -+#include <asm/arch/pm.h> -+#include <asm/arch/sram.h> -+ -+/* FIXME: This is only valid for AP7000 */ -+#define SDRAMC_BASE 0xfff03800 -+ -+#include "sdramc.h" -+ -+#define SRAM_PAGE_FLAGS (SYSREG_BIT(TLBELO_D) | SYSREG_BF(SZ, 1) \ -+ | SYSREG_BF(AP, 3) | SYSREG_BIT(G)) -+ -+ -+static unsigned long pm_sram_start; -+static size_t pm_sram_size; -+static struct vm_struct *pm_sram_area; -+ -+static void (*avr32_pm_enter_standby)(unsigned long sdramc_base); -+static void (*avr32_pm_enter_str)(unsigned long sdramc_base); -+ -+/* -+ * Must be called with interrupts disabled. Exceptions will be masked -+ * on return (i.e. all exceptions will be "unrecoverable".) -+ */ -+static void *avr32_pm_map_sram(void) -+{ -+ unsigned long vaddr; -+ unsigned long page_addr; -+ u32 tlbehi; -+ u32 mmucr; -+ -+ vaddr = (unsigned long)pm_sram_area->addr; -+ page_addr = pm_sram_start & PAGE_MASK; -+ -+ /* -+ * Mask exceptions and grab the first TLB entry. We won't be -+ * needing it while sleeping. -+ */ -+ asm volatile("ssrf %0" : : "i"(SYSREG_EM_OFFSET) : "memory"); -+ -+ mmucr = sysreg_read(MMUCR); -+ tlbehi = sysreg_read(TLBEHI); -+ sysreg_write(MMUCR, SYSREG_BFINS(DRP, 0, mmucr)); -+ -+ tlbehi = SYSREG_BF(ASID, SYSREG_BFEXT(ASID, tlbehi)); -+ tlbehi |= vaddr & PAGE_MASK; -+ tlbehi |= SYSREG_BIT(TLBEHI_V); -+ -+ sysreg_write(TLBELO, page_addr | SRAM_PAGE_FLAGS); -+ sysreg_write(TLBEHI, tlbehi); -+ __builtin_tlbw(); -+ -+ return (void *)(vaddr + pm_sram_start - page_addr); -+} -+ -+/* -+ * Must be called with interrupts disabled. Exceptions will be -+ * unmasked on return. -+ */ -+static void avr32_pm_unmap_sram(void) -+{ -+ u32 mmucr; -+ u32 tlbehi; -+ u32 tlbarlo; -+ -+ /* Going to update TLB entry at index 0 */ -+ mmucr = sysreg_read(MMUCR); -+ tlbehi = sysreg_read(TLBEHI); -+ sysreg_write(MMUCR, SYSREG_BFINS(DRP, 0, mmucr)); -+ -+ /* Clear the "valid" bit */ -+ tlbehi = SYSREG_BF(ASID, SYSREG_BFEXT(ASID, tlbehi)); -+ sysreg_write(TLBEHI, tlbehi); -+ -+ /* Mark it as "not accessed" */ -+ tlbarlo = sysreg_read(TLBARLO); -+ sysreg_write(TLBARLO, tlbarlo | 0x80000000U); -+ -+ /* Update the TLB */ -+ __builtin_tlbw(); -+ -+ /* Unmask exceptions */ -+ asm volatile("csrf %0" : : "i"(SYSREG_EM_OFFSET) : "memory"); -+} -+ -+static int avr32_pm_valid_state(suspend_state_t state) -+{ -+ switch (state) { -+ case PM_SUSPEND_ON: -+ case PM_SUSPEND_STANDBY: -+ case PM_SUSPEND_MEM: -+ return 1; -+ -+ default: -+ return 0; -+ } -+} -+ -+static int avr32_pm_enter(suspend_state_t state) -+{ -+ u32 lpr_saved; -+ u32 evba_saved; -+ void *sram; -+ -+ switch (state) { -+ case PM_SUSPEND_STANDBY: -+ sram = avr32_pm_map_sram(); -+ -+ /* Switch to in-sram exception handlers */ -+ evba_saved = sysreg_read(EVBA); -+ sysreg_write(EVBA, (unsigned long)sram); -+ -+ /* -+ * Save the LPR register so that we can re-enable -+ * SDRAM Low Power mode on resume. -+ */ -+ lpr_saved = sdramc_readl(LPR); -+ pr_debug("%s: Entering standby...\n", __func__); -+ avr32_pm_enter_standby(SDRAMC_BASE); -+ sdramc_writel(LPR, lpr_saved); -+ -+ /* Switch back to regular exception handlers */ -+ sysreg_write(EVBA, evba_saved); -+ -+ avr32_pm_unmap_sram(); -+ break; -+ -+ case PM_SUSPEND_MEM: -+ sram = avr32_pm_map_sram(); -+ -+ /* Switch to in-sram exception handlers */ -+ evba_saved = sysreg_read(EVBA); -+ sysreg_write(EVBA, (unsigned long)sram); -+ -+ /* -+ * Save the LPR register so that we can re-enable -+ * SDRAM Low Power mode on resume. -+ */ -+ lpr_saved = sdramc_readl(LPR); -+ pr_debug("%s: Entering suspend-to-ram...\n", __func__); -+ avr32_pm_enter_str(SDRAMC_BASE); -+ sdramc_writel(LPR, lpr_saved); -+ -+ /* Switch back to regular exception handlers */ -+ sysreg_write(EVBA, evba_saved); -+ -+ avr32_pm_unmap_sram(); -+ break; -+ -+ case PM_SUSPEND_ON: -+ pr_debug("%s: Entering idle...\n", __func__); -+ cpu_enter_idle(); -+ break; -+ -+ default: -+ pr_debug("%s: Invalid suspend state %d\n", __func__, state); -+ goto out; -+ } -+ -+ pr_debug("%s: wakeup\n", __func__); -+ -+out: -+ return 0; -+} -+ -+static struct platform_suspend_ops avr32_pm_ops = { -+ .valid = avr32_pm_valid_state, -+ .enter = avr32_pm_enter, -+}; -+ -+static unsigned long avr32_pm_offset(void *symbol) -+{ -+ extern u8 pm_exception[]; -+ -+ return (unsigned long)symbol - (unsigned long)pm_exception; -+} -+ -+static int __init avr32_pm_init(void) -+{ -+ extern u8 pm_exception[]; -+ extern u8 pm_irq0[]; -+ extern u8 pm_standby[]; -+ extern u8 pm_suspend_to_ram[]; -+ extern u8 pm_sram_end[]; -+ void *dst; -+ -+ /* -+ * To keep things simple, we depend on not needing more than a -+ * single page. -+ */ -+ pm_sram_size = avr32_pm_offset(pm_sram_end); -+ if (pm_sram_size > PAGE_SIZE) -+ goto err; -+ -+ pm_sram_start = sram_alloc(pm_sram_size); -+ if (!pm_sram_start) -+ goto err_alloc_sram; -+ -+ /* Grab a virtual area we can use later on. */ -+ pm_sram_area = get_vm_area(pm_sram_size, VM_IOREMAP); -+ if (!pm_sram_area) -+ goto err_vm_area; -+ pm_sram_area->phys_addr = pm_sram_start; -+ -+ local_irq_disable(); -+ dst = avr32_pm_map_sram(); -+ memcpy(dst, pm_exception, pm_sram_size); -+ flush_dcache_region(dst, pm_sram_size); -+ invalidate_icache_region(dst, pm_sram_size); -+ avr32_pm_unmap_sram(); -+ local_irq_enable(); -+ -+ avr32_pm_enter_standby = dst + avr32_pm_offset(pm_standby); -+ avr32_pm_enter_str = dst + avr32_pm_offset(pm_suspend_to_ram); -+ intc_set_suspend_handler(avr32_pm_offset(pm_irq0)); -+ -+ suspend_set_ops(&avr32_pm_ops); -+ -+ printk("AVR32 AP Power Management enabled\n"); -+ -+ return 0; -+ -+err_vm_area: -+ sram_free(pm_sram_start, pm_sram_size); -+err_alloc_sram: -+err: -+ pr_err("AVR32 Power Management initialization failed\n"); -+ return -ENOMEM; -+} -+arch_initcall(avr32_pm_init); ---- /dev/null -+++ b/arch/avr32/mach-at32ap/sdramc.h -@@ -0,0 +1,76 @@ -+/* -+ * Register definitions for the AT32AP SDRAM 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. -+ */ -+ -+/* Register offsets */ -+#define SDRAMC_MR 0x0000 -+#define SDRAMC_TR 0x0004 -+#define SDRAMC_CR 0x0008 -+#define SDRAMC_HSR 0x000c -+#define SDRAMC_LPR 0x0010 -+#define SDRAMC_IER 0x0014 -+#define SDRAMC_IDR 0x0018 -+#define SDRAMC_IMR 0x001c -+#define SDRAMC_ISR 0x0020 -+#define SDRAMC_MDR 0x0024 -+ -+/* MR - Mode Register */ -+#define SDRAMC_MR_MODE_NORMAL ( 0 << 0) -+#define SDRAMC_MR_MODE_NOP ( 1 << 0) -+#define SDRAMC_MR_MODE_BANKS_PRECHARGE ( 2 << 0) -+#define SDRAMC_MR_MODE_LOAD_MODE ( 3 << 0) -+#define SDRAMC_MR_MODE_AUTO_REFRESH ( 4 << 0) -+#define SDRAMC_MR_MODE_EXT_LOAD_MODE ( 5 << 0) -+#define SDRAMC_MR_MODE_POWER_DOWN ( 6 << 0) -+ -+/* CR - Configuration Register */ -+#define SDRAMC_CR_NC_8_BITS ( 0 << 0) -+#define SDRAMC_CR_NC_9_BITS ( 1 << 0) -+#define SDRAMC_CR_NC_10_BITS ( 2 << 0) -+#define SDRAMC_CR_NC_11_BITS ( 3 << 0) -+#define SDRAMC_CR_NR_11_BITS ( 0 << 2) -+#define SDRAMC_CR_NR_12_BITS ( 1 << 2) -+#define SDRAMC_CR_NR_13_BITS ( 2 << 2) -+#define SDRAMC_CR_NB_2_BANKS ( 0 << 4) -+#define SDRAMC_CR_NB_4_BANKS ( 1 << 4) -+#define SDRAMC_CR_CAS(x) ((x) << 5) -+#define SDRAMC_CR_DBW_32_BITS ( 0 << 7) -+#define SDRAMC_CR_DBW_16_BITS ( 1 << 7) -+#define SDRAMC_CR_TWR(x) ((x) << 8) -+#define SDRAMC_CR_TRC(x) ((x) << 12) -+#define SDRAMC_CR_TRP(x) ((x) << 16) -+#define SDRAMC_CR_TRCD(x) ((x) << 20) -+#define SDRAMC_CR_TRAS(x) ((x) << 24) -+#define SDRAMC_CR_TXSR(x) ((x) << 28) -+ -+/* HSR - High Speed Register */ -+#define SDRAMC_HSR_DA ( 1 << 0) -+ -+/* LPR - Low Power Register */ -+#define SDRAMC_LPR_LPCB_INHIBIT ( 0 << 0) -+#define SDRAMC_LPR_LPCB_SELF_RFR ( 1 << 0) -+#define SDRAMC_LPR_LPCB_PDOWN ( 2 << 0) -+#define SDRAMC_LPR_LPCB_DEEP_PDOWN ( 3 << 0) -+#define SDRAMC_LPR_PASR(x) ((x) << 4) -+#define SDRAMC_LPR_TCSR(x) ((x) << 8) -+#define SDRAMC_LPR_DS(x) ((x) << 10) -+#define SDRAMC_LPR_TIMEOUT(x) ((x) << 12) -+ -+/* IER/IDR/IMR/ISR - Interrupt Enable/Disable/Mask/Status Register */ -+#define SDRAMC_ISR_RES ( 1 << 0) -+ -+/* MDR - Memory Device Register */ -+#define SDRAMC_MDR_MD_SDRAM ( 0 << 0) -+#define SDRAMC_MDR_MD_LOW_PWR_SDRAM ( 1 << 0) -+ -+/* Register access macros */ -+#define sdramc_readl(reg) \ -+ __raw_readl((void __iomem __force *)SDRAMC_BASE + SDRAMC_##reg) -+#define sdramc_writel(reg, value) \ -+ __raw_writel(value, (void __iomem __force *)SDRAMC_BASE + SDRAMC_##reg) ---- a/arch/avr32/mach-at32ap/time-tc.c -+++ /dev/null -@@ -1,218 +0,0 @@ --/* -- * Copyright (C) 2004-2007 Atmel Corporation -- * -- * Based on MIPS implementation arch/mips/kernel/time.c -- * Copyright 2001 MontaVista Software Inc. -- * -- * 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/clocksource.h> --#include <linux/time.h> --#include <linux/module.h> --#include <linux/interrupt.h> --#include <linux/irq.h> --#include <linux/kernel_stat.h> --#include <linux/errno.h> --#include <linux/init.h> --#include <linux/profile.h> --#include <linux/sysdev.h> --#include <linux/err.h> -- --#include <asm/div64.h> --#include <asm/sysreg.h> --#include <asm/io.h> --#include <asm/sections.h> -- --#include <asm/arch/time.h> -- --/* how many counter cycles in a jiffy? */ --static u32 cycles_per_jiffy; -- --/* the count value for the next timer interrupt */ --static u32 expirelo; -- --/* the I/O registers of the TC module */ --static void __iomem *ioregs; -- --cycle_t read_cycle_count(void) --{ -- return (cycle_t)timer_read(ioregs, 0, CV); --} -- --struct clocksource clocksource_avr32 = { -- .name = "avr32", -- .rating = 342, -- .read = read_cycle_count, -- .mask = CLOCKSOURCE_MASK(16), -- .shift = 16, -- .flags = CLOCK_SOURCE_IS_CONTINUOUS, --}; -- --static void avr32_timer_ack(void) --{ -- u16 count = expirelo; -- -- /* Ack this timer interrupt and set the next one, use a u16 -- * variable so it will wrap around correctly */ -- count += cycles_per_jiffy; -- expirelo = count; -- timer_write(ioregs, 0, RC, expirelo); -- -- /* Check to see if we have missed any timer interrupts */ -- count = timer_read(ioregs, 0, CV); -- if ((count - expirelo) < 0x7fff) { -- expirelo = count + cycles_per_jiffy; -- timer_write(ioregs, 0, RC, expirelo); -- } --} -- --u32 avr32_hpt_read(void) --{ -- return timer_read(ioregs, 0, CV); --} -- --static int avr32_timer_calc_div_and_set_jiffies(struct clk *pclk) --{ -- unsigned int cycles_max = (clocksource_avr32.mask + 1) / 2; -- unsigned int divs[] = { 4, 8, 16, 32 }; -- int divs_size = ARRAY_SIZE(divs); -- int i = 0; -- unsigned long count_hz; -- unsigned long shift; -- unsigned long mult; -- int clock_div = -1; -- u64 tmp; -- -- shift = clocksource_avr32.shift; -- -- do { -- count_hz = clk_get_rate(pclk) / divs[i]; -- mult = clocksource_hz2mult(count_hz, shift); -- clocksource_avr32.mult = mult; -- -- tmp = TICK_NSEC; -- tmp <<= shift; -- tmp += mult / 2; -- do_div(tmp, mult); -- -- cycles_per_jiffy = tmp; -- } while (cycles_per_jiffy > cycles_max && ++i < divs_size); -- -- clock_div = i + 1; -- -- if (clock_div > divs_size) { -- pr_debug("timer: could not calculate clock divider\n"); -- return -EFAULT; -- } -- -- /* Set the clock divider */ -- timer_write(ioregs, 0, CMR, TIMER_BF(CMR_TCCLKS, clock_div)); -- -- return 0; --} -- --int avr32_hpt_init(unsigned int count) --{ -- struct resource *regs; -- struct clk *pclk; -- int irq = -1; -- int ret = 0; -- -- ret = -ENXIO; -- -- irq = platform_get_irq(&at32_systc0_device, 0); -- if (irq < 0) { -- pr_debug("timer: could not get irq\n"); -- goto out_error; -- } -- -- pclk = clk_get(&at32_systc0_device.dev, "pclk"); -- if (IS_ERR(pclk)) { -- pr_debug("timer: could not get clk: %ld\n", PTR_ERR(pclk)); -- goto out_error; -- } -- clk_enable(pclk); -- -- regs = platform_get_resource(&at32_systc0_device, IORESOURCE_MEM, 0); -- if (!regs) { -- pr_debug("timer: could not get resource\n"); -- goto out_error_clk; -- } -- -- ioregs = ioremap(regs->start, regs->end - regs->start + 1); -- if (!ioregs) { -- pr_debug("timer: could not get ioregs\n"); -- goto out_error_clk; -- } -- -- ret = avr32_timer_calc_div_and_set_jiffies(pclk); -- if (ret) -- goto out_error_io; -- -- ret = setup_irq(irq, &timer_irqaction); -- if (ret) { -- pr_debug("timer: could not request irq %d: %d\n", -- irq, ret); -- goto out_error_io; -- } -- -- expirelo = (timer_read(ioregs, 0, CV) / cycles_per_jiffy + 1) -- * cycles_per_jiffy; -- -- /* Enable clock and interrupts on RC compare */ -- timer_write(ioregs, 0, CCR, TIMER_BIT(CCR_CLKEN)); -- timer_write(ioregs, 0, IER, TIMER_BIT(IER_CPCS)); -- /* Set cycles to first interrupt */ -- timer_write(ioregs, 0, RC, expirelo); -- -- printk(KERN_INFO "timer: AT32AP system timer/counter at 0x%p irq %d\n", -- ioregs, irq); -- -- return 0; -- --out_error_io: -- iounmap(ioregs); --out_error_clk: -- clk_put(pclk); --out_error: -- return ret; --} -- --int avr32_hpt_start(void) --{ -- timer_write(ioregs, 0, CCR, TIMER_BIT(CCR_SWTRG)); -- return 0; --} -- --irqreturn_t timer_interrupt(int irq, void *dev_id) --{ -- unsigned int sr = timer_read(ioregs, 0, SR); -- -- if (sr & TIMER_BIT(SR_CPCS)) { -- /* ack timer interrupt and try to set next interrupt */ -- avr32_timer_ack(); -- -- /* -- * Call the generic timer interrupt handler -- */ -- write_seqlock(&xtime_lock); -- do_timer(1); -- write_sequnlock(&xtime_lock); -- -- /* -- * In UP mode, we call local_timer_interrupt() to do profiling -- * and process accounting. -- * -- * SMP is not supported yet. -- */ -- local_timer_interrupt(irq, dev_id); -- -- return IRQ_HANDLED; -- } -- -- return IRQ_NONE; --} ---- a/arch/avr32/mm/init.c -+++ b/arch/avr32/mm/init.c -@@ -11,6 +11,7 @@ - #include <linux/swap.h> - #include <linux/init.h> - #include <linux/mmzone.h> -+#include <linux/module.h> - #include <linux/bootmem.h> - #include <linux/pagemap.h> - #include <linux/nodemask.h> -@@ -23,20 +24,20 @@ - #include <asm/setup.h> - #include <asm/sections.h> - -+#define __page_aligned __attribute__((section(".data.page_aligned"))) -+ - DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); - --pgd_t swapper_pg_dir[PTRS_PER_PGD]; -+pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned; - - struct page *empty_zero_page; -+EXPORT_SYMBOL(empty_zero_page); - - /* - * Cache of MMU context last used. - */ - unsigned long mmu_context_cache = NO_CONTEXT; - --#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT) --#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn) -- - void show_mem(void) - { - int total = 0, reserved = 0, cached = 0; -@@ -109,19 +110,9 @@ void __init paging_init(void) - zero_page = alloc_bootmem_low_pages_node(NODE_DATA(0), - PAGE_SIZE); - -- { -- pgd_t *pg_dir; -- int i; -- -- pg_dir = swapper_pg_dir; -- sysreg_write(PTBR, (unsigned long)pg_dir); -- -- for (i = 0; i < PTRS_PER_PGD; i++) -- pgd_val(pg_dir[i]) = 0; -- -- enable_mmu(); -- printk ("CPU: Paging enabled\n"); -- } -+ sysreg_write(PTBR, (unsigned long)swapper_pg_dir); -+ enable_mmu(); -+ printk ("CPU: Paging enabled\n"); - - for_each_online_node(nid) { - pg_data_t *pgdat = NODE_DATA(nid); ---- a/arch/avr32/mm/tlb.c -+++ b/arch/avr32/mm/tlb.c -@@ -11,21 +11,21 @@ - - #include <asm/mmu_context.h> - --#define _TLBEHI_I 0x100 -+/* TODO: Get the correct number from the CONFIG1 system register */ -+#define NR_TLB_ENTRIES 32 - --void show_dtlb_entry(unsigned int index) -+static void show_dtlb_entry(unsigned int index) - { -- unsigned int tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save; -+ u32 tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save; - unsigned long flags; - - local_irq_save(flags); - mmucr_save = sysreg_read(MMUCR); - tlbehi_save = sysreg_read(TLBEHI); -- mmucr = mmucr_save & 0x13; -- mmucr |= index << 14; -+ mmucr = SYSREG_BFINS(DRP, index, mmucr_save); - sysreg_write(MMUCR, mmucr); - -- asm volatile("tlbr" : : : "memory"); -+ __builtin_tlbr(); - cpu_sync_pipeline(); - - tlbehi = sysreg_read(TLBEHI); -@@ -33,15 +33,17 @@ void show_dtlb_entry(unsigned int index) - - printk("%2u: %c %c %02x %05x %05x %o %o %c %c %c %c\n", - index, -- (tlbehi & 0x200)?'1':'0', -- (tlbelo & 0x100)?'1':'0', -- (tlbehi & 0xff), -- (tlbehi >> 12), (tlbelo >> 12), -- (tlbelo >> 4) & 7, (tlbelo >> 2) & 3, -- (tlbelo & 0x200)?'1':'0', -- (tlbelo & 0x080)?'1':'0', -- (tlbelo & 0x001)?'1':'0', -- (tlbelo & 0x002)?'1':'0'); -+ SYSREG_BFEXT(TLBEHI_V, tlbehi) ? '1' : '0', -+ SYSREG_BFEXT(G, tlbelo) ? '1' : '0', -+ SYSREG_BFEXT(ASID, tlbehi), -+ SYSREG_BFEXT(VPN, tlbehi) >> 2, -+ SYSREG_BFEXT(PFN, tlbelo) >> 2, -+ SYSREG_BFEXT(AP, tlbelo), -+ SYSREG_BFEXT(SZ, tlbelo), -+ SYSREG_BFEXT(TLBELO_C, tlbelo) ? 'C' : ' ', -+ SYSREG_BFEXT(B, tlbelo) ? 'B' : ' ', -+ SYSREG_BFEXT(W, tlbelo) ? 'W' : ' ', -+ SYSREG_BFEXT(TLBELO_D, tlbelo) ? 'D' : ' '); - - sysreg_write(MMUCR, mmucr_save); - sysreg_write(TLBEHI, tlbehi_save); -@@ -54,29 +56,33 @@ void dump_dtlb(void) - unsigned int i; - - printk("ID V G ASID VPN PFN AP SZ C B W D\n"); -- for (i = 0; i < 32; i++) -+ for (i = 0; i < NR_TLB_ENTRIES; i++) - show_dtlb_entry(i); - } - --static unsigned long last_mmucr; -- --static inline void set_replacement_pointer(unsigned shift) -+static void update_dtlb(unsigned long address, pte_t pte) - { -- unsigned long mmucr, mmucr_save; -+ u32 tlbehi; -+ u32 mmucr; - -- mmucr = mmucr_save = sysreg_read(MMUCR); -+ /* -+ * We're not changing the ASID here, so no need to flush the -+ * pipeline. -+ */ -+ tlbehi = sysreg_read(TLBEHI); -+ tlbehi = SYSREG_BF(ASID, SYSREG_BFEXT(ASID, tlbehi)); -+ tlbehi |= address & MMU_VPN_MASK; -+ tlbehi |= SYSREG_BIT(TLBEHI_V); -+ sysreg_write(TLBEHI, tlbehi); - - /* Does this mapping already exist? */ -- __asm__ __volatile__( -- " tlbs\n" -- " mfsr %0, %1" -- : "=r"(mmucr) -- : "i"(SYSREG_MMUCR)); -+ __builtin_tlbs(); -+ mmucr = sysreg_read(MMUCR); - - if (mmucr & SYSREG_BIT(MMUCR_N)) { - /* Not found -- pick a not-recently-accessed entry */ -- unsigned long rp; -- unsigned long tlbar = sysreg_read(TLBARLO); -+ unsigned int rp; -+ u32 tlbar = sysreg_read(TLBARLO); - - rp = 32 - fls(tlbar); - if (rp == 32) { -@@ -84,30 +90,14 @@ static inline void set_replacement_point - sysreg_write(TLBARLO, -1L); - } - -- mmucr &= 0x13; -- mmucr |= (rp << shift); -- -+ mmucr = SYSREG_BFINS(DRP, rp, mmucr); - sysreg_write(MMUCR, mmucr); - } - -- last_mmucr = mmucr; --} -- --static void update_dtlb(unsigned long address, pte_t pte, unsigned long asid) --{ -- unsigned long vpn; -- -- vpn = (address & MMU_VPN_MASK) | _TLBEHI_VALID | asid; -- sysreg_write(TLBEHI, vpn); -- cpu_sync_pipeline(); -- -- set_replacement_pointer(14); -- - sysreg_write(TLBELO, pte_val(pte) & _PAGE_FLAGS_HARDWARE_MASK); - - /* Let's go */ -- asm volatile("nop\n\ttlbw" : : : "memory"); -- cpu_sync_pipeline(); -+ __builtin_tlbw(); - } - - void update_mmu_cache(struct vm_area_struct *vma, -@@ -120,39 +110,40 @@ void update_mmu_cache(struct vm_area_str - return; - - local_irq_save(flags); -- update_dtlb(address, pte, get_asid()); -+ update_dtlb(address, pte); - local_irq_restore(flags); - } - --void __flush_tlb_page(unsigned long asid, unsigned long page) -+static void __flush_tlb_page(unsigned long asid, unsigned long page) - { -- unsigned long mmucr, tlbehi; -+ u32 mmucr, tlbehi; - -- page |= asid; -- sysreg_write(TLBEHI, page); -- cpu_sync_pipeline(); -- asm volatile("tlbs"); -+ /* -+ * Caller is responsible for masking out non-PFN bits in page -+ * and changing the current ASID if necessary. This means that -+ * we don't need to flush the pipeline after writing TLBEHI. -+ */ -+ tlbehi = page | asid; -+ sysreg_write(TLBEHI, tlbehi); -+ -+ __builtin_tlbs(); - mmucr = sysreg_read(MMUCR); - - if (!(mmucr & SYSREG_BIT(MMUCR_N))) { -- unsigned long tlbarlo; -- unsigned long entry; -+ unsigned int entry; -+ u32 tlbarlo; - - /* Clear the "valid" bit */ -- tlbehi = sysreg_read(TLBEHI); -- tlbehi &= ~_TLBEHI_VALID; - sysreg_write(TLBEHI, tlbehi); -- cpu_sync_pipeline(); - - /* mark the entry as "not accessed" */ -- entry = (mmucr >> 14) & 0x3f; -+ entry = SYSREG_BFEXT(DRP, mmucr); - tlbarlo = sysreg_read(TLBARLO); -- tlbarlo |= (0x80000000 >> entry); -+ tlbarlo |= (0x80000000UL >> entry); - sysreg_write(TLBARLO, tlbarlo); - - /* update the entry with valid bit clear */ -- asm volatile("tlbw"); -- cpu_sync_pipeline(); -+ __builtin_tlbw(); - } - } - -@@ -190,17 +181,22 @@ void flush_tlb_range(struct vm_area_stru - - local_irq_save(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; -+ - if (size > (MMU_DTLB_ENTRIES / 4)) { /* Too many entries to flush */ - mm->context = NO_CONTEXT; - if (mm == current->mm) - activate_context(mm); - } else { -- unsigned long asid = mm->context & MMU_CONTEXT_ASID_MASK; -- unsigned long saved_asid = MMU_NO_ASID; -+ unsigned long asid; -+ unsigned long saved_asid; -+ -+ asid = mm->context & MMU_CONTEXT_ASID_MASK; -+ saved_asid = MMU_NO_ASID; - - start &= PAGE_MASK; - end += (PAGE_SIZE - 1); - end &= PAGE_MASK; -+ - if (mm != current->mm) { - saved_asid = get_asid(); - set_asid(asid); -@@ -218,33 +214,34 @@ void flush_tlb_range(struct vm_area_stru - } - - /* -- * TODO: If this is only called for addresses > TASK_SIZE, we can probably -- * skip the ASID stuff and just use the Global bit... -+ * This function depends on the pages to be flushed having the G -+ * (global) bit set in their pte. This is true for all -+ * PAGE_KERNEL(_RO) pages. - */ - void flush_tlb_kernel_range(unsigned long start, unsigned long end) - { - unsigned long flags; - int size; - -- local_irq_save(flags); - size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - if (size > (MMU_DTLB_ENTRIES / 4)) { /* Too many entries to flush */ - flush_tlb_all(); - } else { -- unsigned long asid = init_mm.context & MMU_CONTEXT_ASID_MASK; -- unsigned long saved_asid = get_asid(); -+ unsigned long asid; -+ -+ local_irq_save(flags); -+ asid = get_asid(); - - start &= PAGE_MASK; - end += (PAGE_SIZE - 1); - end &= PAGE_MASK; -- set_asid(asid); -+ - while (start < end) { - __flush_tlb_page(asid, start); - start += PAGE_SIZE; - } -- set_asid(saved_asid); -+ local_irq_restore(flags); - } -- local_irq_restore(flags); - } - - void flush_tlb_mm(struct mm_struct *mm) -@@ -280,7 +277,7 @@ static void *tlb_start(struct seq_file * - { - static unsigned long tlb_index; - -- if (*pos >= 32) -+ if (*pos >= NR_TLB_ENTRIES) - return NULL; - - tlb_index = 0; -@@ -291,7 +288,7 @@ static void *tlb_next(struct seq_file *t - { - unsigned long *index = v; - -- if (*index >= 31) -+ if (*index >= NR_TLB_ENTRIES - 1) - return NULL; - - ++*pos; -@@ -313,16 +310,16 @@ static int tlb_show(struct seq_file *tlb - if (*index == 0) - seq_puts(tlb, "ID V G ASID VPN PFN AP SZ C B W D\n"); - -- BUG_ON(*index >= 32); -+ BUG_ON(*index >= NR_TLB_ENTRIES); - - local_irq_save(flags); - mmucr_save = sysreg_read(MMUCR); - tlbehi_save = sysreg_read(TLBEHI); -- mmucr = mmucr_save & 0x13; -- mmucr |= *index << 14; -+ mmucr = SYSREG_BFINS(DRP, *index, mmucr_save); - sysreg_write(MMUCR, mmucr); - -- asm volatile("tlbr" : : : "memory"); -+ /* TLBR might change the ASID */ -+ __builtin_tlbr(); - cpu_sync_pipeline(); - - tlbehi = sysreg_read(TLBEHI); -@@ -334,16 +331,18 @@ static int tlb_show(struct seq_file *tlb - local_irq_restore(flags); - - seq_printf(tlb, "%2lu: %c %c %02x %05x %05x %o %o %c %c %c %c\n", -- *index, -- (tlbehi & 0x200)?'1':'0', -- (tlbelo & 0x100)?'1':'0', -- (tlbehi & 0xff), -- (tlbehi >> 12), (tlbelo >> 12), -- (tlbelo >> 4) & 7, (tlbelo >> 2) & 3, -- (tlbelo & 0x200)?'1':'0', -- (tlbelo & 0x080)?'1':'0', -- (tlbelo & 0x001)?'1':'0', -- (tlbelo & 0x002)?'1':'0'); -+ *index, -+ SYSREG_BFEXT(TLBEHI_V, tlbehi) ? '1' : '0', -+ SYSREG_BFEXT(G, tlbelo) ? '1' : '0', -+ SYSREG_BFEXT(ASID, tlbehi), -+ SYSREG_BFEXT(VPN, tlbehi) >> 2, -+ SYSREG_BFEXT(PFN, tlbelo) >> 2, -+ SYSREG_BFEXT(AP, tlbelo), -+ SYSREG_BFEXT(SZ, tlbelo), -+ SYSREG_BFEXT(TLBELO_C, tlbelo) ? '1' : '0', -+ SYSREG_BFEXT(B, tlbelo) ? '1' : '0', -+ SYSREG_BFEXT(W, tlbelo) ? '1' : '0', -+ SYSREG_BFEXT(TLBELO_D, tlbelo) ? '1' : '0'); - - return 0; - } ---- a/arch/avr32/oprofile/op_model_avr32.c -+++ b/arch/avr32/oprofile/op_model_avr32.c -@@ -16,7 +16,6 @@ - #include <linux/sched.h> - #include <linux/types.h> - --#include <asm/intc.h> - #include <asm/sysreg.h> - #include <asm/system.h> - ---- a/drivers/char/Kconfig -+++ b/drivers/char/Kconfig -@@ -706,7 +706,7 @@ config NVRAM - - config RTC - tristate "Enhanced Real Time Clock Support" -- depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV && !ARM && !SUPERH && !S390 -+ depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV && !ARM && !SUPERH && !S390 && !AVR32 - ---help--- - If you say Y here and create a character special file /dev/rtc with - major number 10 and minor number 135 using mknod ("man mknod"), you -@@ -776,7 +776,7 @@ config SGI_IP27_RTC - - config GEN_RTC - tristate "Generic /dev/rtc emulation" -- depends on RTC!=y && !IA64 && !ARM && !M32R && !MIPS && !SPARC && !FRV && !S390 && !SUPERH -+ depends on RTC!=y && !IA64 && !ARM && !M32R && !MIPS && !SPARC && !FRV && !S390 && !SUPERH && !AVR32 - ---help--- - If you say Y here and create a character special file /dev/rtc with - major number 10 and minor number 135 using mknod ("man mknod"), you ---- a/drivers/char/keyboard.c -+++ b/drivers/char/keyboard.c -@@ -1033,7 +1033,8 @@ DECLARE_TASKLET_DISABLED(keyboard_taskle - #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\ - defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\ - defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\ -- (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) -+ (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) ||\ -+ defined(CONFIG_AVR32) - - #define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\ - ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001)) ---- a/drivers/clocksource/Makefile -+++ b/drivers/clocksource/Makefile -@@ -1,3 +1,4 @@ -+obj-$(CONFIG_ATMEL_TCB_CLKSRC) += tcb_clksrc.o - obj-$(CONFIG_X86_CYCLONE_TIMER) += cyclone.o - obj-$(CONFIG_X86_PM_TIMER) += acpi_pm.o - obj-$(CONFIG_SCx200HR_TIMER) += scx200_hrt.o ---- /dev/null -+++ b/drivers/clocksource/tcb_clksrc.c -@@ -0,0 +1,302 @@ -+#include <linux/init.h> -+#include <linux/clocksource.h> -+#include <linux/clockchips.h> -+#include <linux/interrupt.h> -+#include <linux/irq.h> -+ -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/ioport.h> -+#include <linux/io.h> -+#include <linux/platform_device.h> -+#include <linux/atmel_tc.h> -+ -+ -+/* -+ * We're configured to use a specific TC block, one that's not hooked -+ * up to external hardware, to provide a time solution: -+ * -+ * - Two channels combine to create a free-running 32 bit counter -+ * with a base rate of 5+ MHz, packaged as a clocksource (with -+ * resolution better than 200 nsec). -+ * -+ * - The third channel may be used to provide a 16-bit clockevent -+ * source, used in either periodic or oneshot mode. This runs -+ * at 32 KiHZ, and can handle delays of up to two seconds. -+ * -+ * A boot clocksource and clockevent source are also currently needed, -+ * unless the relevant platforms (ARM/AT91, AVR32/AT32) are changed so -+ * this code can be used when init_timers() is called, well before most -+ * devices are set up. (Some low end AT91 parts, which can run uClinux, -+ * have only the timers in one TC block... they currently don't support -+ * the tclib code, because of that initialization issue.) -+ * -+ * REVISIT behavior during system suspend states... we should disable -+ * all clocks and save the power. Easily done for clockevent devices, -+ * but clocksources won't necessarily get the needed notifications. -+ * For deeper system sleep states, this will be mandatory... -+ */ -+ -+static void __iomem *tcaddr; -+ -+static cycle_t tc_get_cycles(void) -+{ -+ unsigned long flags; -+ u32 lower, upper; -+ -+ raw_local_irq_save(flags); -+ do { -+ upper = __raw_readl(tcaddr + ATMEL_TC_REG(1, CV)); -+ lower = __raw_readl(tcaddr + ATMEL_TC_REG(0, CV)); -+ } while (upper != __raw_readl(tcaddr + ATMEL_TC_REG(1, CV))); -+ -+ raw_local_irq_restore(flags); -+ return (upper << 16) | lower; -+} -+ -+static struct clocksource clksrc = { -+ .name = "tcb_clksrc", -+ .rating = 200, -+ .read = tc_get_cycles, -+ .mask = CLOCKSOURCE_MASK(32), -+ .shift = 18, -+ .flags = CLOCK_SOURCE_IS_CONTINUOUS, -+}; -+ -+#ifdef CONFIG_GENERIC_CLOCKEVENTS -+ -+struct tc_clkevt_device { -+ struct clock_event_device clkevt; -+ struct clk *clk; -+ void __iomem *regs; -+}; -+ -+static struct tc_clkevt_device *to_tc_clkevt(struct clock_event_device *clkevt) -+{ -+ return container_of(clkevt, struct tc_clkevt_device, clkevt); -+} -+ -+/* For now, we always use the 32K clock ... this optimizes for NO_HZ, -+ * because using one of the divided clocks would usually mean the -+ * tick rate can never be less than several dozen Hz (vs 0.5 Hz). -+ * -+ * A divided clock could be good for high resolution timers, since -+ * 30.5 usec resolution can seem "low". -+ */ -+static u32 timer_clock; -+ -+static void tc_mode(enum clock_event_mode m, struct clock_event_device *d) -+{ -+ struct tc_clkevt_device *tcd = to_tc_clkevt(d); -+ void __iomem *regs = tcd->regs; -+ -+ if (tcd->clkevt.mode == CLOCK_EVT_MODE_PERIODIC -+ || tcd->clkevt.mode == CLOCK_EVT_MODE_ONESHOT) { -+ __raw_writel(0xff, regs + ATMEL_TC_REG(2, IDR)); -+ __raw_writel(ATMEL_TC_CLKDIS, regs + ATMEL_TC_REG(2, CCR)); -+ clk_disable(tcd->clk); -+ } -+ -+ switch (m) { -+ -+ /* By not making the gentime core emulate periodic mode on top -+ * of oneshot, we get lower overhead and improved accuracy. -+ */ -+ case CLOCK_EVT_MODE_PERIODIC: -+ clk_enable(tcd->clk); -+ -+ /* slow clock, count up to RC, then irq and restart */ -+ __raw_writel(timer_clock -+ | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, -+ regs + ATMEL_TC_REG(2, CMR)); -+ __raw_writel((32768 + HZ/2) / HZ, tcaddr + ATMEL_TC_REG(2, RC)); -+ -+ /* Enable clock and interrupts on RC compare */ -+ __raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); -+ -+ /* go go gadget! */ -+ __raw_writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG, -+ regs + ATMEL_TC_REG(2, CCR)); -+ break; -+ -+ case CLOCK_EVT_MODE_ONESHOT: -+ clk_enable(tcd->clk); -+ -+ /* slow clock, count up to RC, then irq and stop */ -+ __raw_writel(timer_clock | ATMEL_TC_CPCSTOP -+ | ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO, -+ regs + ATMEL_TC_REG(2, CMR)); -+ __raw_writel(ATMEL_TC_CPCS, regs + ATMEL_TC_REG(2, IER)); -+ -+ /* set_next_event() configures and starts the timer */ -+ break; -+ -+ default: -+ break; -+ } -+} -+ -+static int tc_next_event(unsigned long delta, struct clock_event_device *d) -+{ -+ __raw_writel(delta, tcaddr + ATMEL_TC_REG(2, RC)); -+ -+ /* go go gadget! */ -+ __raw_writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG, -+ tcaddr + ATMEL_TC_REG(2, CCR)); -+ return 0; -+} -+ -+static struct tc_clkevt_device clkevt = { -+ .clkevt = { -+ .name = "tc_clkevt", -+ .features = CLOCK_EVT_FEAT_PERIODIC -+ | CLOCK_EVT_FEAT_ONESHOT, -+ .shift = 32, -+ /* Should be lower than at91rm9200's system timer */ -+ .rating = 125, -+ .cpumask = CPU_MASK_CPU0, -+ .set_next_event = tc_next_event, -+ .set_mode = tc_mode, -+ }, -+}; -+ -+static irqreturn_t ch2_irq(int irq, void *handle) -+{ -+ struct tc_clkevt_device *dev = handle; -+ unsigned int sr; -+ -+ sr = __raw_readl(dev->regs + ATMEL_TC_REG(2, SR)); -+ if (sr & ATMEL_TC_CPCS) { -+ dev->clkevt.event_handler(&dev->clkevt); -+ return IRQ_HANDLED; -+ } -+ -+ return IRQ_NONE; -+} -+ -+static struct irqaction tc_irqaction = { -+ .name = "tc_clkevt", -+ .flags = IRQF_TIMER | IRQF_DISABLED, -+ .handler = ch2_irq, -+}; -+ -+static void __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) -+{ -+ struct clk *t2_clk = tc->clk[2]; -+ int irq = tc->irq[2]; -+ -+ clkevt.regs = tc->regs; -+ clkevt.clk = t2_clk; -+ tc_irqaction.dev_id = &clkevt; -+ -+ timer_clock = clk32k_divisor_idx; -+ -+ clkevt.clkevt.mult = div_sc(32768, NSEC_PER_SEC, clkevt.clkevt.shift); -+ clkevt.clkevt.max_delta_ns -+ = clockevent_delta2ns(0xffff, &clkevt.clkevt); -+ clkevt.clkevt.min_delta_ns = clockevent_delta2ns(1, &clkevt.clkevt) + 1; -+ -+ setup_irq(irq, &tc_irqaction); -+ -+ clockevents_register_device(&clkevt.clkevt); -+} -+ -+#else /* !CONFIG_GENERIC_CLOCKEVENTS */ -+ -+static void __init setup_clkevents(struct atmel_tc *tc, int clk32k_divisor_idx) -+{ -+ /* NOTHING */ -+} -+ -+#endif -+ -+static int __init tcb_clksrc_init(void) -+{ -+ static char bootinfo[] __initdata -+ = KERN_DEBUG "%s: tc%d at %d.%03d MHz\n"; -+ -+ struct platform_device *pdev; -+ struct atmel_tc *tc; -+ struct clk *t0_clk; -+ u32 rate, divided_rate = 0; -+ int best_divisor_idx = -1; -+ int clk32k_divisor_idx = -1; -+ int i; -+ -+ tc = atmel_tc_alloc(CONFIG_ATMEL_TCB_CLKSRC_BLOCK, clksrc.name); -+ if (!tc) { -+ pr_debug("can't alloc TC for clocksource\n"); -+ return -ENODEV; -+ } -+ tcaddr = tc->regs; -+ pdev = tc->pdev; -+ -+ t0_clk = tc->clk[0]; -+ clk_enable(t0_clk); -+ -+ /* How fast will we be counting? Pick something over 5 MHz. */ -+ rate = (u32) clk_get_rate(t0_clk); -+ for (i = 0; i < 5; i++) { -+ unsigned divisor = atmel_tc_divisors[i]; -+ unsigned tmp; -+ -+ /* remember 32 KiHz clock for later */ -+ if (!divisor) { -+ clk32k_divisor_idx = i; -+ continue; -+ } -+ -+ tmp = rate / divisor; -+ pr_debug("TC: %u / %-3u [%d] --> %u\n", rate, divisor, i, tmp); -+ if (best_divisor_idx > 0) { -+ if (tmp < 5 * 1000 * 1000) -+ continue; -+ } -+ divided_rate = tmp; -+ best_divisor_idx = i; -+ } -+ -+ clksrc.mult = clocksource_hz2mult(divided_rate, clksrc.shift); -+ -+ printk(bootinfo, clksrc.name, CONFIG_ATMEL_TCB_CLKSRC_BLOCK, -+ divided_rate / 1000000, -+ ((divided_rate + 500000) % 1000000) / 1000); -+ -+ /* tclib will give us three clocks no matter what the -+ * underlying platform supports. -+ */ -+ clk_enable(tc->clk[1]); -+ -+ /* channel 0: waveform mode, input mclk/8, clock TIOA0 on overflow */ -+ __raw_writel(best_divisor_idx /* likely divide-by-8 */ -+ | ATMEL_TC_WAVE -+ | ATMEL_TC_WAVESEL_UP /* free-run */ -+ | ATMEL_TC_ACPA_SET /* TIOA0 rises at 0 */ -+ | ATMEL_TC_ACPC_CLEAR, /* (duty cycle 50%) */ -+ tcaddr + ATMEL_TC_REG(0, CMR)); -+ __raw_writel(0x0000, tcaddr + ATMEL_TC_REG(0, RA)); -+ __raw_writel(0x8000, tcaddr + ATMEL_TC_REG(0, RC)); -+ __raw_writel(0xff, tcaddr + ATMEL_TC_REG(0, IDR)); /* no irqs */ -+ __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(0, CCR)); -+ -+ /* channel 1: waveform mode, input TIOA0 */ -+ __raw_writel(ATMEL_TC_XC1 /* input: TIOA0 */ -+ | ATMEL_TC_WAVE -+ | ATMEL_TC_WAVESEL_UP, /* free-run */ -+ tcaddr + ATMEL_TC_REG(1, CMR)); -+ __raw_writel(0xff, tcaddr + ATMEL_TC_REG(1, IDR)); /* no irqs */ -+ __raw_writel(ATMEL_TC_CLKEN, tcaddr + ATMEL_TC_REG(1, CCR)); -+ -+ /* chain channel 0 to channel 1, then reset all the timers */ -+ __raw_writel(ATMEL_TC_TC1XC1S_TIOA0, tcaddr + ATMEL_TC_BMR); -+ __raw_writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR); -+ -+ /* and away we go! */ -+ clocksource_register(&clksrc); -+ -+ /* channel 2: periodic and oneshot timer support */ -+ setup_clkevents(tc, clk32k_divisor_idx); -+ -+ return 0; -+} -+arch_initcall(tcb_clksrc_init); ---- a/drivers/i2c/busses/Kconfig -+++ b/drivers/i2c/busses/Kconfig -@@ -88,6 +88,14 @@ config I2C_AT91 - to support combined I2C messages. Use the i2c-gpio driver - unless your system can cope with those limitations. - -+config I2C_ATMELTWI -+ tristate "Atmel Two-Wire Interface (TWI)" -+ depends on I2C && (ARCH_AT91 || PLATFORM_AT32AP) -+ help -+ Atmel on-chip TWI controller. Say Y if you have an AT32 or -+ AT91-based device and want to use its built-in TWI -+ functionality. -+ - config I2C_AU1550 - tristate "Au1550/Au1200 SMBus interface" - depends on SOC_AU1550 || SOC_AU1200 ---- a/drivers/i2c/busses/Makefile -+++ b/drivers/i2c/busses/Makefile -@@ -52,6 +52,7 @@ obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o - obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o - obj-$(CONFIG_SCx200_ACB) += scx200_acb.o - obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o -+obj-$(CONFIG_I2C_ATMELTWI) += i2c-atmeltwi.o - - ifeq ($(CONFIG_I2C_DEBUG_BUS),y) - EXTRA_CFLAGS += -DDEBUG ---- /dev/null -+++ b/drivers/i2c/busses/i2c-atmeltwi.c -@@ -0,0 +1,436 @@ -+/* -+ * i2c Support for Atmel's Two-Wire Interface (TWI) -+ * -+ * Based on the work of Copyright (C) 2004 Rick Bronson -+ * Converted to 2.6 by Andrew Victor <andrew at sanpeople.com> -+ * Ported to AVR32 and heavily modified by Espen Krangnes -+ * <ekrangnes at atmel.com> -+ * -+ * Copyright (C) 2006 Atmel Corporation -+ * -+ * Borrowed heavily from the original work by: -+ * Copyright (C) 2000 Philip Edelbrock <phil at stimpy.netroedge.com> -+ * -+ * Partialy rewriten by Karel Hojdar <cmkaho at seznam.cz> -+ * bugs removed, interrupt routine markedly rewritten -+ * -+ * 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. -+ */ -+#undef VERBOSE_DEBUG -+ -+#include <linux/module.h> -+#include <linux/slab.h> -+#include <linux/i2c.h> -+#include <linux/init.h> -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/interrupt.h> -+#include <linux/platform_device.h> -+#include <linux/completion.h> -+#include <linux/io.h> -+ -+#include "i2c-atmeltwi.h" -+ -+static unsigned int baudrate = 100 * 1000; -+module_param(baudrate, uint, S_IRUGO); -+MODULE_PARM_DESC(baudrate, "The TWI baudrate"); -+ -+ -+struct atmel_twi { -+ void __iomem *regs; -+ struct i2c_adapter adapter; -+ struct clk *pclk; -+ struct completion comp; -+ u32 mask; -+ u8 *buf; -+ u16 len; -+ u16 acks_left; -+ int status; -+ unsigned int irq; -+ -+}; -+#define to_atmel_twi(adap) container_of(adap, struct atmel_twi, adapter) -+ -+/* -+ * (Re)Initialize the TWI hardware registers. -+ */ -+static int twi_hwinit(struct atmel_twi *twi) -+{ -+ unsigned long cdiv, ckdiv = 0; -+ -+ /* REVISIT: wait till SCL is high before resetting; otherwise, -+ * some versions will wedge forever. -+ */ -+ -+ twi_writel(twi, IDR, ~0UL); -+ twi_writel(twi, CR, TWI_BIT(SWRST)); /*Reset peripheral*/ -+ twi_readl(twi, SR); -+ -+ cdiv = (clk_get_rate(twi->pclk) / (2 * baudrate)) - 4; -+ -+ while (cdiv > 255) { -+ ckdiv++; -+ cdiv = cdiv >> 1; -+ } -+ -+ /* REVISIT: there are various errata to consider re CDIV and CHDIV -+ * here, at least on at91 parts. -+ */ -+ -+ if (ckdiv > 7) -+ return -EINVAL; -+ else -+ twi_writel(twi, CWGR, TWI_BF(CKDIV, ckdiv) -+ | TWI_BF(CHDIV, cdiv) -+ | TWI_BF(CLDIV, cdiv)); -+ return 0; -+} -+ -+/* -+ * Waits for the i2c status register to set the specified bitmask -+ * Returns 0 if timed out ... ~100ms is much longer than the SMBus -+ * limit, but I2C has no limit at all. -+ */ -+static int twi_complete(struct atmel_twi *twi, u32 mask) -+{ -+ int timeout = msecs_to_jiffies(100); -+ -+ mask |= TWI_BIT(TXCOMP); -+ twi->mask = mask | TWI_BIT(NACK) | TWI_BIT(OVRE); -+ init_completion(&twi->comp); -+ -+ twi_writel(twi, IER, mask); -+ -+ if (!wait_for_completion_timeout(&twi->comp, timeout)) { -+ /* RESET TWI interface */ -+ twi_writel(twi, CR, TWI_BIT(SWRST)); -+ -+ /* Reinitialize TWI */ -+ twi_hwinit(twi); -+ -+ return -ETIMEDOUT; -+ } -+ return 0; -+} -+ -+/* -+ * Generic i2c master transfer entrypoint. -+ */ -+static int twi_xfer(struct i2c_adapter *adap, struct i2c_msg *pmsg, int num) -+{ -+ struct atmel_twi *twi = to_atmel_twi(adap); -+ int i; -+ -+ dev_dbg(&adap->dev, "twi_xfer: processing %d messages:\n", num); -+ -+ twi->status = 0; -+ for (i = 0; i < num; i++, pmsg++) { -+ twi->len = pmsg->len; -+ twi->buf = pmsg->buf; -+ twi->acks_left = pmsg->len; -+ twi_writel(twi, MMR, TWI_BF(DADR, pmsg->addr) | -+ (pmsg->flags & I2C_M_RD ? TWI_BIT(MREAD) : 0)); -+ twi_writel(twi, IADR, TWI_BF(IADR, pmsg->addr)); -+ -+ dev_dbg(&adap->dev, -+ "#%d: %s %d byte%s %s dev 0x%02x\n", -+ i, -+ pmsg->flags & I2C_M_RD ? "reading" : "writing", -+ pmsg->len, -+ pmsg->len > 1 ? "s" : "", -+ pmsg->flags & I2C_M_RD ? "from" : "to", pmsg->addr); -+ -+ /* enable */ -+ twi_writel(twi, CR, TWI_BIT(MSEN)); -+ -+ if (pmsg->flags & I2C_M_RD) { -+ /* cleanup after previous RX overruns */ -+ while (twi_readl(twi, SR) & TWI_BIT(RXRDY)) -+ twi_readl(twi, RHR); -+ -+ if (twi->len == 1) -+ twi_writel(twi, CR, -+ TWI_BIT(START) | TWI_BIT(STOP)); -+ else -+ twi_writel(twi, CR, TWI_BIT(START)); -+ -+ if (twi_complete(twi, TWI_BIT(RXRDY)) == -ETIMEDOUT) { -+ dev_dbg(&adap->dev, "RX[%d] timeout. " -+ "Stopped with %d bytes left\n", -+ i, twi->acks_left); -+ return -ETIMEDOUT; -+ } -+ } else { -+ twi_writel(twi, THR, twi->buf[0]); -+ twi->acks_left--; -+ /* REVISIT: some chips don't start automagically: -+ * twi_writel(twi, CR, TWI_BIT(START)); -+ */ -+ if (twi_complete(twi, TWI_BIT(TXRDY)) == -ETIMEDOUT) { -+ dev_dbg(&adap->dev, "TX[%d] timeout. " -+ "Stopped with %d bytes left\n", -+ i, twi->acks_left); -+ return -ETIMEDOUT; -+ } -+ /* REVISIT: an erratum workaround may be needed here; -+ * see sam9261 "STOP not generated" (START either). -+ */ -+ } -+ -+ /* Disable TWI interface */ -+ twi_writel(twi, CR, TWI_BIT(MSDIS)); -+ -+ if (twi->status) -+ return twi->status; -+ -+ /* WARNING: This driver lies about properly supporting -+ * repeated start, or it would *ALWAYS* return here. It -+ * has issued a STOP. Continuing is a false claim -- that -+ * a second (or third, etc.) message is part of the same -+ * "combined" (no STOPs between parts) message. -+ */ -+ -+ } /* end cur msg */ -+ -+ return i; -+} -+ -+ -+static irqreturn_t twi_interrupt(int irq, void *dev_id) -+{ -+ struct atmel_twi *twi = dev_id; -+ int status = twi_readl(twi, SR); -+ -+ /* Save state for later debug prints */ -+ int old_status = status; -+ -+ if (twi->mask & status) { -+ -+ status &= twi->mask; -+ -+ if (status & TWI_BIT(RXRDY)) { -+ if ((status & TWI_BIT(OVRE)) && twi->acks_left) { -+ /* Note weakness in fault reporting model: -+ * we can't say "the first N of these data -+ * bytes are valid". -+ */ -+ dev_err(&twi->adapter.dev, -+ "OVERRUN RX! %04x, lost %d\n", -+ old_status, twi->acks_left); -+ twi->acks_left = 0; -+ twi_writel(twi, CR, TWI_BIT(STOP)); -+ twi->status = -EOVERFLOW; -+ } else if (twi->acks_left > 0) { -+ twi->buf[twi->len - twi->acks_left] = -+ twi_readl(twi, RHR); -+ twi->acks_left--; -+ } -+ if (status & TWI_BIT(TXCOMP)) -+ goto done; -+ if (twi->acks_left == 1) -+ twi_writel(twi, CR, TWI_BIT(STOP)); -+ -+ } else if (status & (TWI_BIT(NACK) | TWI_BIT(TXCOMP))) { -+ goto done; -+ -+ } else if (status & TWI_BIT(TXRDY)) { -+ if (twi->acks_left > 0) { -+ twi_writel(twi, THR, -+ twi->buf[twi->len - twi->acks_left]); -+ twi->acks_left--; -+ } else -+ twi_writel(twi, CR, TWI_BIT(STOP)); -+ } -+ -+ if (twi->acks_left == 0) -+ twi_writel(twi, IDR, ~TWI_BIT(TXCOMP)); -+ } -+ -+ /* enabling this message helps trigger overruns/underruns ... */ -+ dev_vdbg(&twi->adapter.dev, -+ "ISR: SR 0x%04X, mask 0x%04X, acks %i\n", -+ old_status, -+ twi->acks_left ? twi->mask : TWI_BIT(TXCOMP), -+ twi->acks_left); -+ -+ return IRQ_HANDLED; -+ -+done: -+ /* Note weak fault reporting model: we can't report how many -+ * bytes we sent before the NAK, or let upper layers choose -+ * whether to continue. The I2C stack doesn't allow that... -+ */ -+ if (status & TWI_BIT(NACK)) { -+ dev_dbg(&twi->adapter.dev, "NACK received! %d to go\n", -+ twi->acks_left); -+ twi->status = -EPIPE; -+ -+ /* TX underrun morphs automagically into a premature STOP; -+ * we'll probably observe UVRE even when it's not documented. -+ */ -+ } else if (twi->acks_left && (twi->mask & TWI_BIT(TXRDY))) { -+ dev_err(&twi->adapter.dev, "UNDERRUN TX! %04x, %d to go\n", -+ old_status, twi->acks_left); -+ twi->status = -ENOSR; -+ } -+ -+ twi_writel(twi, IDR, ~0UL); -+ complete(&twi->comp); -+ -+ dev_dbg(&twi->adapter.dev, "ISR: SR 0x%04X, acks %i --> %d\n", -+ old_status, twi->acks_left, twi->status); -+ -+ return IRQ_HANDLED; -+} -+ -+ -+/* -+ * Return list of supported functionality. -+ * -+ * NOTE: see warning above about repeated starts; this driver is falsely -+ * claiming to support "combined" transfers. The mid-message STOPs mean -+ * some slaves will never work with this driver. (Use i2c-gpio...) -+ */ -+static u32 twi_func(struct i2c_adapter *adapter) -+{ -+ return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL) -+ & ~I2C_FUNC_SMBUS_QUICK; -+} -+ -+static struct i2c_algorithm twi_algorithm = { -+ .master_xfer = twi_xfer, -+ .functionality = twi_func, -+}; -+ -+/* -+ * Main initialization routine. -+ */ -+static int __init twi_probe(struct platform_device *pdev) -+{ -+ struct atmel_twi *twi; -+ struct resource *regs; -+ struct clk *pclk; -+ struct i2c_adapter *adapter; -+ int rc, irq; -+ -+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!regs) -+ return -ENXIO; -+ -+ pclk = clk_get(&pdev->dev, "twi_pclk"); -+ if (IS_ERR(pclk)) -+ return PTR_ERR(pclk); -+ clk_enable(pclk); -+ -+ rc = -ENOMEM; -+ twi = kzalloc(sizeof(struct atmel_twi), GFP_KERNEL); -+ if (!twi) { -+ dev_dbg(&pdev->dev, "can't allocate interface!\n"); -+ goto err_alloc_twi; -+ } -+ -+ twi->pclk = pclk; -+ twi->regs = ioremap(regs->start, regs->end - regs->start + 1); -+ if (!twi->regs) -+ goto err_ioremap; -+ -+ irq = platform_get_irq(pdev, 0); -+ rc = request_irq(irq, twi_interrupt, 0, "twi", twi); -+ if (rc) { -+ dev_dbg(&pdev->dev, "can't bind irq!\n"); -+ goto err_irq; -+ } -+ twi->irq = irq; -+ -+ rc = twi_hwinit(twi); -+ if (rc) { -+ dev_err(&pdev->dev, "Unable to set baudrate\n"); -+ goto err_hw_init; -+ } -+ -+ adapter = &twi->adapter; -+ sprintf(adapter->name, "TWI"); -+ adapter->algo = &twi_algorithm; -+ adapter->class = I2C_CLASS_ALL; -+ adapter->nr = pdev->id; -+ adapter->dev.parent = &pdev->dev; -+ -+ platform_set_drvdata(pdev, twi); -+ -+ rc = i2c_add_numbered_adapter(adapter); -+ if (rc) { -+ dev_dbg(&pdev->dev, "Adapter %s registration failed\n", -+ adapter->name); -+ goto err_register; -+ } -+ -+ dev_info(&pdev->dev, -+ "Atmel TWI/I2C adapter (baudrate %dk) at 0x%08lx.\n", -+ baudrate/1000, (unsigned long)regs->start); -+ -+ return 0; -+ -+ -+err_register: -+ platform_set_drvdata(pdev, NULL); -+ -+err_hw_init: -+ free_irq(irq, twi); -+ -+err_irq: -+ iounmap(twi->regs); -+ -+err_ioremap: -+ kfree(twi); -+ -+err_alloc_twi: -+ clk_disable(pclk); -+ clk_put(pclk); -+ -+ return rc; -+} -+ -+static int __exit twi_remove(struct platform_device *pdev) -+{ -+ struct atmel_twi *twi = platform_get_drvdata(pdev); -+ int res; -+ -+ platform_set_drvdata(pdev, NULL); -+ res = i2c_del_adapter(&twi->adapter); -+ twi_writel(twi, CR, TWI_BIT(MSDIS)); -+ iounmap(twi->regs); -+ clk_disable(twi->pclk); -+ clk_put(twi->pclk); -+ free_irq(twi->irq, twi); -+ kfree(twi); -+ -+ return res; -+} -+ -+static struct platform_driver twi_driver = { -+ .remove = __exit_p(twi_remove), -+ .driver = { -+ .name = "atmel_twi", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init atmel_twi_init(void) -+{ -+ return platform_driver_probe(&twi_driver, twi_probe); -+} -+ -+static void __exit atmel_twi_exit(void) -+{ -+ platform_driver_unregister(&twi_driver); -+} -+ -+module_init(atmel_twi_init); -+module_exit(atmel_twi_exit); -+ -+MODULE_AUTHOR("Espen Krangnes"); -+MODULE_DESCRIPTION("I2C driver for Atmel TWI"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/drivers/i2c/busses/i2c-atmeltwi.h -@@ -0,0 +1,117 @@ -+/* -+ * Register definitions for the Atmel Two-Wire Interface -+ */ -+ -+#ifndef __ATMELTWI_H__ -+#define __ATMELTWI_H__ -+ -+/* TWI register offsets */ -+#define TWI_CR 0x0000 -+#define TWI_MMR 0x0004 -+#define TWI_SMR 0x0008 -+#define TWI_IADR 0x000c -+#define TWI_CWGR 0x0010 -+#define TWI_SR 0x0020 -+#define TWI_IER 0x0024 -+#define TWI_IDR 0x0028 -+#define TWI_IMR 0x002c -+#define TWI_RHR 0x0030 -+#define TWI_THR 0x0034 -+ -+/* Bitfields in CR */ -+#define TWI_START_OFFSET 0 -+#define TWI_START_SIZE 1 -+#define TWI_STOP_OFFSET 1 -+#define TWI_STOP_SIZE 1 -+#define TWI_MSEN_OFFSET 2 -+#define TWI_MSEN_SIZE 1 -+#define TWI_MSDIS_OFFSET 3 -+#define TWI_MSDIS_SIZE 1 -+#define TWI_SVEN_OFFSET 4 -+#define TWI_SVEN_SIZE 1 -+#define TWI_SVDIS_OFFSET 5 -+#define TWI_SVDIS_SIZE 1 -+#define TWI_SWRST_OFFSET 7 -+#define TWI_SWRST_SIZE 1 -+ -+/* Bitfields in MMR */ -+#define TWI_IADRSZ_OFFSET 8 -+#define TWI_IADRSZ_SIZE 2 -+#define TWI_MREAD_OFFSET 12 -+#define TWI_MREAD_SIZE 1 -+#define TWI_DADR_OFFSET 16 -+#define TWI_DADR_SIZE 7 -+ -+/* Bitfields in SMR */ -+#define TWI_SADR_OFFSET 16 -+#define TWI_SADR_SIZE 7 -+ -+/* Bitfields in IADR */ -+#define TWI_IADR_OFFSET 0 -+#define TWI_IADR_SIZE 24 -+ -+/* Bitfields in CWGR */ -+#define TWI_CLDIV_OFFSET 0 -+#define TWI_CLDIV_SIZE 8 -+#define TWI_CHDIV_OFFSET 8 -+#define TWI_CHDIV_SIZE 8 -+#define TWI_CKDIV_OFFSET 16 -+#define TWI_CKDIV_SIZE 3 -+ -+/* Bitfields in SR */ -+#define TWI_TXCOMP_OFFSET 0 -+#define TWI_TXCOMP_SIZE 1 -+#define TWI_RXRDY_OFFSET 1 -+#define TWI_RXRDY_SIZE 1 -+#define TWI_TXRDY_OFFSET 2 -+#define TWI_TXRDY_SIZE 1 -+#define TWI_SVDIR_OFFSET 3 -+#define TWI_SVDIR_SIZE 1 -+#define TWI_SVACC_OFFSET 4 -+#define TWI_SVACC_SIZE 1 -+#define TWI_GCACC_OFFSET 5 -+#define TWI_GCACC_SIZE 1 -+#define TWI_OVRE_OFFSET 6 -+#define TWI_OVRE_SIZE 1 -+#define TWI_UNRE_OFFSET 7 -+#define TWI_UNRE_SIZE 1 -+#define TWI_NACK_OFFSET 8 -+#define TWI_NACK_SIZE 1 -+#define TWI_ARBLST_OFFSET 9 -+#define TWI_ARBLST_SIZE 1 -+ -+/* Bitfields in RHR */ -+#define TWI_RXDATA_OFFSET 0 -+#define TWI_RXDATA_SIZE 8 -+ -+/* Bitfields in THR */ -+#define TWI_TXDATA_OFFSET 0 -+#define TWI_TXDATA_SIZE 8 -+ -+/* Constants for IADRSZ */ -+#define TWI_IADRSZ_NO_ADDR 0 -+#define TWI_IADRSZ_ONE_BYTE 1 -+#define TWI_IADRSZ_TWO_BYTES 2 -+#define TWI_IADRSZ_THREE_BYTES 3 -+ -+/* Bit manipulation macros */ -+#define TWI_BIT(name) \ -+ (1 << TWI_##name##_OFFSET) -+#define TWI_BF(name, value) \ -+ (((value) & ((1 << TWI_##name##_SIZE) - 1)) \ -+ << TWI_##name##_OFFSET) -+#define TWI_BFEXT(name, value) \ -+ (((value) >> TWI_##name##_OFFSET) \ -+ & ((1 << TWI_##name##_SIZE) - 1)) -+#define TWI_BFINS(name, value, old) \ -+ (((old) & ~(((1 << TWI_##name##_SIZE) - 1) \ -+ << TWI_##name##_OFFSET)) \ -+ | TWI_BF(name, (value))) -+ -+/* Register access macros */ -+#define twi_readl(port, reg) \ -+ __raw_readl((port)->regs + TWI_##reg) -+#define twi_writel(port, reg, value) \ -+ __raw_writel((value), (port)->regs + TWI_##reg) -+ -+#endif /* __ATMELTWI_H__ */ ---- a/drivers/input/serio/Kconfig -+++ b/drivers/input/serio/Kconfig -@@ -88,6 +88,17 @@ config SERIO_RPCKBD - To compile this driver as a module, choose M here: the - module will be called rpckbd. - -+config SERIO_AT32PSIF -+ tristate "AVR32 PSIF PS/2 keyboard and mouse controller" -+ depends on AVR32 -+ default n -+ help -+ Say Y here if you want to use the PSIF peripheral on AVR32 devices -+ and connect a PS/2 keyboard and/or mouse to it. -+ -+ To compile this driver as a module, choose M here: the module will -+ be called at32psif. -+ - config SERIO_AMBAKMI - tristate "AMBA KMI keyboard controller" - depends on ARM_AMBA ---- a/drivers/input/serio/Makefile -+++ b/drivers/input/serio/Makefile -@@ -12,6 +12,7 @@ obj-$(CONFIG_SERIO_CT82C710) += ct82c710 - obj-$(CONFIG_SERIO_RPCKBD) += rpckbd.o - obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o - obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o -+obj-$(CONFIG_SERIO_AT32PSIF) += at32psif.o - obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o - obj-$(CONFIG_SERIO_GSCPS2) += gscps2.o - obj-$(CONFIG_HP_SDC) += hp_sdc.o ---- /dev/null -+++ b/drivers/input/serio/at32psif.c -@@ -0,0 +1,351 @@ -+/* -+ * Copyright (C) 2007 Atmel Corporation -+ * -+ * Driver for the AT32AP700X PS/2 controller (PSIF). -+ * -+ * 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/module.h> -+#include <linux/device.h> -+#include <linux/init.h> -+#include <linux/serio.h> -+#include <linux/timer.h> -+#include <linux/interrupt.h> -+#include <linux/err.h> -+#include <linux/io.h> -+#include <linux/clk.h> -+#include <linux/platform_device.h> -+ -+#include "at32psif.h" -+ -+#define PSIF_BUF_SIZE 16 -+ -+#define ring_is_empty(_psif) (_psif->head == _psif->tail) -+#define ring_next_head(_psif) ((_psif->head + 1) & (PSIF_BUF_SIZE - 1)) -+#define ring_next_tail(_psif) ((_psif->tail + 1) & (PSIF_BUF_SIZE - 1)) -+ -+struct psif { -+ struct platform_device *pdev; -+ struct clk *pclk; -+ struct serio *io; -+ struct timer_list tx_timer; -+ void __iomem *regs; -+ unsigned int irq; -+ unsigned int open; -+ /* Prevent concurrent writes to circular buffer. */ -+ spinlock_t lock; -+ unsigned int head; -+ unsigned int tail; -+ unsigned char buffer[PSIF_BUF_SIZE]; -+}; -+ -+static irqreturn_t psif_interrupt(int irq, void *_ptr) -+{ -+ struct psif *psif = _ptr; -+ int retval = IRQ_NONE; -+ unsigned int io_flags = 0; -+ unsigned long status; -+ -+ status = psif_readl(psif, SR); -+ -+ if (status & PSIF_BIT(RXRDY)) { -+ unsigned char val = (unsigned char) psif_readl(psif, RHR); -+ -+ if (status & PSIF_BIT(PARITY)) -+ io_flags |= SERIO_PARITY; -+ if (status & PSIF_BIT(OVRUN)) -+ dev_err(&psif->pdev->dev, "overrun read error\n"); -+ -+ serio_interrupt(psif->io, val, io_flags); -+ -+ retval = IRQ_HANDLED; -+ } -+ -+ spin_lock(&psif->lock); -+ -+ if (status & PSIF_BIT(TXEMPTY)) { -+ if (status & PSIF_BIT(NACK)) -+ dev_err(&psif->pdev->dev, "NACK error\n"); -+ -+ psif_writel(psif, IDR, PSIF_BIT(TXEMPTY)); -+ -+ if (!ring_is_empty(psif)) -+ mod_timer(&psif->tx_timer, -+ jiffies + msecs_to_jiffies(1)); -+ -+ retval = IRQ_HANDLED; -+ } -+ -+ spin_unlock(&psif->lock); -+ -+ return retval; -+} -+ -+static void psif_transmit_data(unsigned long data) -+{ -+ struct psif *psif = (struct psif *)data; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&psif->lock, flags); -+ -+ psif_writel(psif, THR, psif->buffer[psif->tail]); -+ psif->tail = ring_next_tail(psif); -+ -+ if (!ring_is_empty(psif)) -+ psif_writel(psif, IER, PSIF_BIT(TXEMPTY)); -+ -+ spin_unlock_irqrestore(&psif->lock, flags); -+} -+ -+static int psif_write(struct serio *io, unsigned char val) -+{ -+ struct psif *psif = io->port_data; -+ unsigned long flags; -+ unsigned int head; -+ -+ spin_lock_irqsave(&psif->lock, flags); -+ -+ head = ring_next_head(psif); -+ -+ if (head != psif->tail) { -+ psif->buffer[psif->head] = val; -+ psif->head = head; -+ } else { -+ dev_err(&psif->pdev->dev, "underrun write error\n"); -+ } -+ -+ spin_unlock_irqrestore(&psif->lock, flags); -+ -+ /* Make sure TXEMPTY interrupt is enabled. */ -+ psif_writel(psif, IER, PSIF_BIT(TXEMPTY)); -+ -+ return 0; -+} -+ -+static int psif_open(struct serio *io) -+{ -+ struct psif *psif = io->port_data; -+ int retval; -+ -+ retval = clk_enable(psif->pclk); -+ if (retval) -+ goto out; -+ -+ psif_writel(psif, CR, PSIF_BIT(CR_TXEN) | PSIF_BIT(CR_RXEN)); -+ psif_writel(psif, IER, PSIF_BIT(RXRDY)); -+ -+ psif->open = 1; -+out: -+ return retval; -+} -+ -+static void psif_close(struct serio *io) -+{ -+ struct psif *psif = io->port_data; -+ -+ psif->open = 0; -+ -+ psif_writel(psif, IDR, ~0UL); -+ psif_writel(psif, CR, PSIF_BIT(CR_TXDIS) | PSIF_BIT(CR_RXDIS)); -+ -+ clk_disable(psif->pclk); -+} -+ -+static void psif_set_prescaler(struct psif *psif) -+{ -+ unsigned long prscv; -+ unsigned long rate = clk_get_rate(psif->pclk); -+ -+ /* PRSCV = Pulse length (100 us) * PSIF module frequency. */ -+ prscv = 100 * (rate / 1000000UL); -+ -+ if (prscv > ((1<<PSIF_PSR_PRSCV_SIZE) - 1)) { -+ prscv = (1<<PSIF_PSR_PRSCV_SIZE) - 1; -+ dev_dbg(&psif->pdev->dev, "pclk too fast, " -+ "prescaler set to max\n"); -+ } -+ -+ clk_enable(psif->pclk); -+ psif_writel(psif, PSR, prscv); -+ clk_disable(psif->pclk); -+} -+ -+static int __init psif_probe(struct platform_device *pdev) -+{ -+ struct resource *regs; -+ struct psif *psif; -+ struct serio *io; -+ struct clk *pclk; -+ int irq; -+ int ret; -+ -+ psif = kzalloc(sizeof(struct psif), GFP_KERNEL); -+ if (!psif) { -+ dev_dbg(&pdev->dev, "out of memory\n"); -+ ret = -ENOMEM; -+ goto out; -+ } -+ psif->pdev = pdev; -+ -+ io = kzalloc(sizeof(struct serio), GFP_KERNEL); -+ if (!io) { -+ dev_dbg(&pdev->dev, "out of memory\n"); -+ ret = -ENOMEM; -+ goto out_free_psif; -+ } -+ psif->io = io; -+ -+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!regs) { -+ dev_dbg(&pdev->dev, "no mmio resources defined\n"); -+ ret = -ENOMEM; -+ goto out_free_io; -+ } -+ -+ psif->regs = ioremap(regs->start, regs->end - regs->start + 1); -+ if (!psif->regs) { -+ ret = -ENOMEM; -+ dev_dbg(&pdev->dev, "could not map I/O memory\n"); -+ goto out_free_io; -+ } -+ -+ pclk = clk_get(&pdev->dev, "pclk"); -+ if (IS_ERR(pclk)) { -+ dev_dbg(&pdev->dev, "could not get peripheral clock\n"); -+ ret = PTR_ERR(pclk); -+ goto out_iounmap; -+ } -+ psif->pclk = pclk; -+ -+ /* Reset the PSIF to enter at a known state. */ -+ ret = clk_enable(pclk); -+ if (ret) { -+ dev_dbg(&pdev->dev, "could not enable pclk\n"); -+ goto out_put_clk; -+ } -+ psif_writel(psif, CR, PSIF_BIT(CR_SWRST)); -+ clk_disable(pclk); -+ -+ setup_timer(&psif->tx_timer, psif_transmit_data, (unsigned long)psif); -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) { -+ dev_dbg(&pdev->dev, "could not get irq\n"); -+ ret = -ENXIO; -+ goto out_put_clk; -+ } -+ ret = request_irq(irq, psif_interrupt, IRQF_SHARED, "at32psif", psif); -+ if (ret) { -+ dev_dbg(&pdev->dev, "could not request irq %d\n", irq); -+ goto out_put_clk; -+ } -+ psif->irq = irq; -+ -+ io->id.type = SERIO_8042; -+ io->write = psif_write; -+ io->open = psif_open; -+ io->close = psif_close; -+ strlcpy(io->name, pdev->dev.bus_id, sizeof(io->name)); -+ strlcpy(io->phys, pdev->dev.bus_id, sizeof(io->phys)); -+ io->port_data = psif; -+ io->dev.parent = &pdev->dev; -+ -+ psif_set_prescaler(psif); -+ -+ spin_lock_init(&psif->lock); -+ serio_register_port(psif->io); -+ platform_set_drvdata(pdev, psif); -+ -+ dev_info(&pdev->dev, "Atmel AVR32 PSIF PS/2 driver on 0x%08x irq %d\n", -+ (int)psif->regs, psif->irq); -+ -+ return 0; -+ -+out_put_clk: -+ clk_put(psif->pclk); -+out_iounmap: -+ iounmap(psif->regs); -+out_free_io: -+ kfree(io); -+out_free_psif: -+ kfree(psif); -+out: -+ return ret; -+} -+ -+static int __exit psif_remove(struct platform_device *pdev) -+{ -+ struct psif *psif = platform_get_drvdata(pdev); -+ -+ psif_writel(psif, IDR, ~0UL); -+ psif_writel(psif, CR, PSIF_BIT(CR_TXDIS) | PSIF_BIT(CR_RXDIS)); -+ -+ serio_unregister_port(psif->io); -+ iounmap(psif->regs); -+ free_irq(psif->irq, psif); -+ clk_put(psif->pclk); -+ kfree(psif); -+ -+ platform_set_drvdata(pdev, NULL); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int psif_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ struct psif *psif = platform_get_drvdata(pdev); -+ -+ if (psif->open) { -+ psif_writel(psif, CR, PSIF_BIT(CR_RXDIS) | PSIF_BIT(CR_TXDIS)); -+ clk_disable(psif->pclk); -+ } -+ -+ return 0; -+} -+ -+static int psif_resume(struct platform_device *pdev) -+{ -+ struct psif *psif = platform_get_drvdata(pdev); -+ -+ if (psif->open) { -+ clk_enable(psif->pclk); -+ psif_set_prescaler(psif); -+ psif_writel(psif, CR, PSIF_BIT(CR_RXEN) | PSIF_BIT(CR_TXEN)); -+ } -+ -+ return 0; -+} -+#else -+#define psif_suspend NULL -+#define psif_resume NULL -+#endif -+ -+static struct platform_driver psif_driver = { -+ .remove = __exit_p(psif_remove), -+ .driver = { -+ .name = "atmel_psif", -+ }, -+ .suspend = psif_suspend, -+ .resume = psif_resume, -+}; -+ -+static int __init psif_init(void) -+{ -+ return platform_driver_probe(&psif_driver, psif_probe); -+} -+ -+static void __exit psif_exit(void) -+{ -+ platform_driver_unregister(&psif_driver); -+} -+ -+module_init(psif_init); -+module_exit(psif_exit); -+ -+MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>"); -+MODULE_DESCRIPTION("Atmel AVR32 PSIF PS/2 driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/drivers/input/serio/at32psif.h -@@ -0,0 +1,82 @@ -+/* -+ * Copyright (C) 2007 Atmel Corporation -+ * -+ * Driver for the AT32AP700X PS/2 controller (PSIF). -+ * -+ * 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 _AT32PSIF_H -+#define _AT32PSIF_H -+ -+/* PSIF register offsets */ -+#define PSIF_CR 0x00 -+#define PSIF_RHR 0x04 -+#define PSIF_THR 0x08 -+#define PSIF_SR 0x10 -+#define PSIF_IER 0x14 -+#define PSIF_IDR 0x18 -+#define PSIF_IMR 0x1c -+#define PSIF_PSR 0x24 -+ -+/* Bitfields in control register. */ -+#define PSIF_CR_RXDIS_OFFSET 1 -+#define PSIF_CR_RXDIS_SIZE 1 -+#define PSIF_CR_RXEN_OFFSET 0 -+#define PSIF_CR_RXEN_SIZE 1 -+#define PSIF_CR_SWRST_OFFSET 15 -+#define PSIF_CR_SWRST_SIZE 1 -+#define PSIF_CR_TXDIS_OFFSET 9 -+#define PSIF_CR_TXDIS_SIZE 1 -+#define PSIF_CR_TXEN_OFFSET 8 -+#define PSIF_CR_TXEN_SIZE 1 -+ -+/* Bitfields in interrupt disable, enable, mask and status register. */ -+#define PSIF_NACK_OFFSET 8 -+#define PSIF_NACK_SIZE 1 -+#define PSIF_OVRUN_OFFSET 5 -+#define PSIF_OVRUN_SIZE 1 -+#define PSIF_PARITY_OFFSET 9 -+#define PSIF_PARITY_SIZE 1 -+#define PSIF_RXRDY_OFFSET 4 -+#define PSIF_RXRDY_SIZE 1 -+#define PSIF_TXEMPTY_OFFSET 1 -+#define PSIF_TXEMPTY_SIZE 1 -+#define PSIF_TXRDY_OFFSET 0 -+#define PSIF_TXRDY_SIZE 1 -+ -+/* Bitfields in prescale register. */ -+#define PSIF_PSR_PRSCV_OFFSET 0 -+#define PSIF_PSR_PRSCV_SIZE 12 -+ -+/* Bitfields in receive hold register. */ -+#define PSIF_RHR_RXDATA_OFFSET 0 -+#define PSIF_RHR_RXDATA_SIZE 8 -+ -+/* Bitfields in transmit hold register. */ -+#define PSIF_THR_TXDATA_OFFSET 0 -+#define PSIF_THR_TXDATA_SIZE 8 -+ -+/* Bit manipulation macros */ -+#define PSIF_BIT(name) \ -+ (1 << PSIF_##name##_OFFSET) -+#define PSIF_BF(name, value) \ -+ (((value) & ((1 << PSIF_##name##_SIZE) - 1)) \ -+ << PSIF_##name##_OFFSET) -+#define PSIF_BFEXT(name, value)\ -+ (((value) >> PSIF_##name##_OFFSET) \ -+ & ((1 << PSIF_##name##_SIZE) - 1)) -+#define PSIF_BFINS(name, value, old) \ -+ (((old) & ~(((1 << PSIF_##name##_SIZE) - 1) \ -+ << PSIF_##name##_OFFSET)) \ -+ | PSIF_BF(name, value)) -+ -+/* Register access macros */ -+#define psif_readl(port, reg) \ -+ __raw_readl((port)->regs + PSIF_##reg) -+#define psif_writel(port, reg, value) \ -+ __raw_writel((value), (port)->regs + PSIF_##reg) -+ -+#endif /* _AT32PSIF_H */ ---- a/drivers/misc/Kconfig -+++ b/drivers/misc/Kconfig -@@ -22,6 +22,39 @@ config ATMEL_PWM - purposes including software controlled power-efficent backlights - on LCD displays, motor control, and waveform generation. - -+config ATMEL_TCLIB -+ bool "Atmel AT32/AT91 Timer/Counter Library" -+ depends on (AVR32 || ARCH_AT91) -+ help -+ Select this if you want a library to allocate the Timer/Counter -+ blocks found on many Atmel processors. This facilitates using -+ these blocks by different drivers despite processor differences. -+ -+config ATMEL_TCB_CLKSRC -+ bool "TC Block Clocksource" -+ depends on ATMEL_TCLIB && GENERIC_TIME -+ default y -+ help -+ Select this to get a high precision clocksource based on a -+ TC block with a 5+ MHz base clock rate. Two timer channels -+ are combined to make a single 32-bit timer. -+ -+ When GENERIC_CLOCKEVENTS is defined, the third timer channel -+ may be used as a clock event device supporting oneshot mode -+ (delays of up to two seconds) based on the 32 KiHz clock. -+ -+config ATMEL_TCB_CLKSRC_BLOCK -+ int -+ depends on ATMEL_TCB_CLKSRC -+ prompt "TC Block" if ARCH_AT91RM9200 || ARCH_AT91SAM9260 || CPU_AT32AP700X -+ default 0 -+ range 0 1 -+ help -+ Some chips provide more than one TC block, so you have the -+ choice of which one to use for the clock framework. The other -+ TC can be used for other purposes, such as PWM generation and -+ interval timing. -+ - config IBM_ASM - tristate "Device driver for IBM RSA service processor" - depends on X86 && PCI && INPUT && EXPERIMENTAL ---- a/drivers/misc/Makefile -+++ b/drivers/misc/Makefile -@@ -10,6 +10,7 @@ obj-$(CONFIG_ACER_WMI) += acer-wmi.o - obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o - obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o - obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o -+obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o - obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o - obj-$(CONFIG_LKDTM) += lkdtm.o - obj-$(CONFIG_TIFM_CORE) += tifm_core.o ---- /dev/null -+++ b/drivers/misc/atmel_tclib.c -@@ -0,0 +1,161 @@ -+#include <linux/atmel_tc.h> -+#include <linux/clk.h> -+#include <linux/err.h> -+#include <linux/init.h> -+#include <linux/io.h> -+#include <linux/ioport.h> -+#include <linux/kernel.h> -+#include <linux/platform_device.h> -+ -+/* Number of bytes to reserve for the iomem resource */ -+#define ATMEL_TC_IOMEM_SIZE 256 -+ -+ -+/* -+ * This is a thin library to solve the problem of how to portably allocate -+ * one of the TC blocks. For simplicity, it doesn't currently expect to -+ * share individual timers between different drivers. -+ */ -+ -+#if defined(CONFIG_AVR32) -+/* AVR32 has these divide PBB */ -+const u8 atmel_tc_divisors[5] = { 0, 4, 8, 16, 32, }; -+EXPORT_SYMBOL(atmel_tc_divisors); -+ -+#elif defined(CONFIG_ARCH_AT91) -+/* AT91 has these divide MCK */ -+const u8 atmel_tc_divisors[5] = { 2, 8, 32, 128, 0, }; -+EXPORT_SYMBOL(atmel_tc_divisors); -+ -+#endif -+ -+static DEFINE_SPINLOCK(tc_list_lock); -+static LIST_HEAD(tc_list); -+ -+/** -+ * atmel_tc_alloc - allocate a specified TC block -+ * @block: which block to allocate -+ * @name: name to be associated with the iomem resource -+ * -+ * Caller allocates a block. If it is available, a pointer to a -+ * pre-initialized struct atmel_tc is returned. The caller can access -+ * the registers directly through the "regs" field. -+ */ -+struct atmel_tc *atmel_tc_alloc(unsigned block, const char *name) -+{ -+ struct atmel_tc *tc; -+ struct platform_device *pdev = NULL; -+ struct resource *r; -+ -+ spin_lock(&tc_list_lock); -+ list_for_each_entry(tc, &tc_list, node) { -+ if (tc->pdev->id == block) { -+ pdev = tc->pdev; -+ break; -+ } -+ } -+ -+ if (!pdev || tc->iomem) -+ goto fail; -+ -+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ r = request_mem_region(r->start, ATMEL_TC_IOMEM_SIZE, name); -+ if (!r) -+ goto fail; -+ -+ tc->regs = ioremap(r->start, ATMEL_TC_IOMEM_SIZE); -+ if (!tc->regs) -+ goto fail_ioremap; -+ -+ tc->iomem = r; -+ -+out: -+ spin_unlock(&tc_list_lock); -+ return tc; -+ -+fail_ioremap: -+ release_resource(r); -+fail: -+ tc = NULL; -+ goto out; -+} -+EXPORT_SYMBOL_GPL(atmel_tc_alloc); -+ -+/** -+ * atmel_tc_free - release a specified TC block -+ * @tc: Timer/counter block that was returned by atmel_tc_alloc() -+ * -+ * This reverses the effect of atmel_tc_alloc(), unmapping the I/O -+ * registers, invalidating the resource returned by that routine and -+ * making the TC available to other drivers. -+ */ -+void atmel_tc_free(struct atmel_tc *tc) -+{ -+ spin_lock(&tc_list_lock); -+ if (tc->regs) { -+ iounmap(tc->regs); -+ release_resource(tc->iomem); -+ tc->regs = NULL; -+ tc->iomem = NULL; -+ } -+ spin_unlock(&tc_list_lock); -+} -+EXPORT_SYMBOL_GPL(atmel_tc_free); -+ -+static int __init tc_probe(struct platform_device *pdev) -+{ -+ struct atmel_tc *tc; -+ struct clk *clk; -+ int irq; -+ -+ if (!platform_get_resource(pdev, IORESOURCE_MEM, 0)) -+ return -EINVAL; -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) -+ return -EINVAL; -+ -+ tc = kzalloc(sizeof(struct atmel_tc), GFP_KERNEL); -+ if (!tc) -+ return -ENOMEM; -+ -+ tc->pdev = pdev; -+ -+ clk = clk_get(&pdev->dev, "t0_clk"); -+ if (IS_ERR(clk)) { -+ kfree(tc); -+ return -EINVAL; -+ } -+ -+ tc->clk[0] = clk; -+ tc->clk[1] = clk_get(&pdev->dev, "t1_clk"); -+ if (IS_ERR(tc->clk[1])) -+ tc->clk[1] = clk; -+ tc->clk[2] = clk_get(&pdev->dev, "t2_clk"); -+ if (IS_ERR(tc->clk[2])) -+ tc->clk[2] = clk; -+ -+ tc->irq[0] = irq; -+ tc->irq[1] = platform_get_irq(pdev, 1); -+ if (tc->irq[1] < 0) -+ tc->irq[1] = irq; -+ tc->irq[2] = platform_get_irq(pdev, 2); -+ if (tc->irq[2] < 0) -+ tc->irq[2] = irq; -+ -+ spin_lock(&tc_list_lock); -+ list_add_tail(&tc->node, &tc_list); -+ spin_unlock(&tc_list_lock); -+ -+ return 0; -+} -+ -+static struct platform_driver tc_driver = { -+ .driver.name = "atmel_tcb", -+}; -+ -+static int __init tc_init(void) -+{ -+ return platform_driver_probe(&tc_driver, tc_probe); -+} -+arch_initcall(tc_init); ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -91,6 +91,16 @@ config MMC_AT91 - - If unsure, say N. - -+config MMC_ATMELMCI -+ tristate "Atmel Multimedia Card Interface support" -+ depends on AVR32 && MMC -+ help -+ This selects the Atmel Multimedia Card Interface. If you have -+ a AT91 (ARM) or AT32 (AVR32) platform with a Multimedia Card -+ slot, say Y or M here. -+ -+ If unsure, say N. -+ - config MMC_IMX - tristate "Motorola i.MX Multimedia Card Interface support" - depends on ARCH_IMX ---- a/drivers/mmc/host/Makefile -+++ b/drivers/mmc/host/Makefile -@@ -15,6 +15,7 @@ obj-$(CONFIG_MMC_WBSD) += wbsd.o - obj-$(CONFIG_MMC_AU1X) += au1xmmc.o - obj-$(CONFIG_MMC_OMAP) += omap.o - obj-$(CONFIG_MMC_AT91) += at91_mci.o -+obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o - obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o - obj-$(CONFIG_MMC_SPI) += mmc_spi.o - obj-$(CONFIG_GPIOMMC) += gpiommc.o ---- /dev/null -+++ b/drivers/mmc/host/atmel-mci.c -@@ -0,0 +1,1234 @@ -+/* -+ * Atmel MultiMedia Card Interface driver -+ * -+ * Copyright (C) 2004-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/blkdev.h> -+#include <linux/clk.h> -+#include <linux/device.h> -+#include <linux/dma-mapping.h> -+#include <linux/init.h> -+#include <linux/interrupt.h> -+#include <linux/ioport.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+ -+#include <linux/mmc/host.h> -+ -+#include <asm/dma-controller.h> -+#include <asm/io.h> -+#include <asm/arch/board.h> -+#include <asm/arch/gpio.h> -+ -+#include "atmel-mci.h" -+ -+#define DRIVER_NAME "atmel_mci" -+ -+#define MCI_DATA_ERROR_FLAGS (MCI_BIT(DCRCE) | MCI_BIT(DTOE) | \ -+ MCI_BIT(OVRE) | MCI_BIT(UNRE)) -+ -+enum { -+ EVENT_CMD_COMPLETE = 0, -+ EVENT_DATA_COMPLETE, -+ EVENT_DATA_ERROR, -+ EVENT_STOP_SENT, -+ EVENT_STOP_COMPLETE, -+ EVENT_DMA_COMPLETE, -+ EVENT_DMA_ERROR, -+}; -+ -+struct atmel_mci_dma { -+ struct dma_request_sg req; -+ unsigned short rx_periph_id; -+ unsigned short tx_periph_id; -+}; -+ -+struct atmel_mci { -+ struct mmc_host *mmc; -+ void __iomem *regs; -+ struct atmel_mci_dma dma; -+ -+ struct mmc_request *mrq; -+ struct mmc_command *cmd; -+ struct mmc_data *data; -+ -+ u32 cmd_status; -+ u32 data_status; -+ u32 stop_status; -+ u32 stop_cmdr; -+ -+ struct tasklet_struct tasklet; -+ unsigned long pending_events; -+ unsigned long completed_events; -+ -+ int present; -+ int detect_pin; -+ int wp_pin; -+ -+ /* For detect pin debouncing */ -+ struct timer_list detect_timer; -+ -+ unsigned long bus_hz; -+ unsigned long mapbase; -+ struct clk *mck; -+ struct platform_device *pdev; -+ -+ int pending_stop; -+#ifdef CONFIG_DEBUG_FS -+ struct dentry *debugfs_root; -+ struct dentry *debugfs_regs; -+ struct dentry *debugfs_req; -+ struct dentry *debugfs_pending_events; -+ struct dentry *debugfs_completed_events; -+#endif -+}; -+ -+/* Those printks take an awful lot of time... */ -+#ifndef DEBUG -+static unsigned int fmax = 15000000U; -+#else -+static unsigned int fmax = 1000000U; -+#endif -+module_param(fmax, uint, 0444); -+MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock"); -+ -+/* Test bit macros for completed events */ -+#define mci_cmd_is_complete(host) \ -+ test_bit(EVENT_CMD_COMPLETE, &host->completed_events) -+#define mci_data_is_complete(host) \ -+ test_bit(EVENT_DATA_COMPLETE, &host->completed_events) -+#define mci_data_error_is_complete(host) \ -+ test_bit(EVENT_DATA_ERROR, &host->completed_events) -+#define mci_stop_sent_is_complete(host) \ -+ test_bit(EVENT_STOP_SENT, &host->completed_events) -+#define mci_stop_is_complete(host) \ -+ test_bit(EVENT_STOP_COMPLETE, &host->completed_events) -+#define mci_dma_is_complete(host) \ -+ test_bit(EVENT_DMA_COMPLETE, &host->completed_events) -+#define mci_dma_error_is_complete(host) \ -+ test_bit(EVENT_DMA_ERROR, &host->completed_events) -+ -+/* Test and clear bit macros for pending events */ -+#define mci_clear_cmd_is_pending(host) \ -+ test_and_clear_bit(EVENT_CMD_COMPLETE, &host->pending_events) -+#define mci_clear_data_is_pending(host) \ -+ test_and_clear_bit(EVENT_DATA_COMPLETE, &host->pending_events) -+#define mci_clear_data_error_is_pending(host) \ -+ test_and_clear_bit(EVENT_DATA_ERROR, &host->pending_events) -+#define mci_clear_stop_sent_is_pending(host) \ -+ test_and_clear_bit(EVENT_STOP_SENT, &host->pending_events) -+#define mci_clear_stop_is_pending(host) \ -+ test_and_clear_bit(EVENT_STOP_COMPLETE, &host->pending_events) -+#define mci_clear_dma_error_is_pending(host) \ -+ test_and_clear_bit(EVENT_DMA_ERROR, &host->pending_events) -+ -+/* Test and set bit macros for completed events */ -+#define mci_set_cmd_is_completed(host) \ -+ test_and_set_bit(EVENT_CMD_COMPLETE, &host->completed_events) -+#define mci_set_data_is_completed(host) \ -+ test_and_set_bit(EVENT_DATA_COMPLETE, &host->completed_events) -+#define mci_set_data_error_is_completed(host) \ -+ test_and_set_bit(EVENT_DATA_ERROR, &host->completed_events) -+#define mci_set_stop_sent_is_completed(host) \ -+ test_and_set_bit(EVENT_STOP_SENT, &host->completed_events) -+#define mci_set_stop_is_completed(host) \ -+ test_and_set_bit(EVENT_STOP_COMPLETE, &host->completed_events) -+#define mci_set_dma_error_is_completed(host) \ -+ test_and_set_bit(EVENT_DMA_ERROR, &host->completed_events) -+ -+/* Set bit macros for completed events */ -+#define mci_set_cmd_complete(host) \ -+ set_bit(EVENT_CMD_COMPLETE, &host->completed_events) -+#define mci_set_data_complete(host) \ -+ set_bit(EVENT_DATA_COMPLETE, &host->completed_events) -+#define mci_set_data_error_complete(host) \ -+ set_bit(EVENT_DATA_ERROR, &host->completed_events) -+#define mci_set_stop_sent_complete(host) \ -+ set_bit(EVENT_STOP_SENT, &host->completed_events) -+#define mci_set_stop_complete(host) \ -+ set_bit(EVENT_STOP_COMPLETE, &host->completed_events) -+#define mci_set_dma_complete(host) \ -+ set_bit(EVENT_DMA_COMPLETE, &host->completed_events) -+#define mci_set_dma_error_complete(host) \ -+ set_bit(EVENT_DMA_ERROR, &host->completed_events) -+ -+/* Set bit macros for pending events */ -+#define mci_set_cmd_pending(host) \ -+ set_bit(EVENT_CMD_COMPLETE, &host->pending_events) -+#define mci_set_data_pending(host) \ -+ set_bit(EVENT_DATA_COMPLETE, &host->pending_events) -+#define mci_set_data_error_pending(host) \ -+ set_bit(EVENT_DATA_ERROR, &host->pending_events) -+#define mci_set_stop_sent_pending(host) \ -+ set_bit(EVENT_STOP_SENT, &host->pending_events) -+#define mci_set_stop_pending(host) \ -+ set_bit(EVENT_STOP_COMPLETE, &host->pending_events) -+#define mci_set_dma_error_pending(host) \ -+ set_bit(EVENT_DMA_ERROR, &host->pending_events) -+ -+/* Clear bit macros for pending events */ -+#define mci_clear_cmd_pending(host) \ -+ clear_bit(EVENT_CMD_COMPLETE, &host->pending_events) -+#define mci_clear_data_pending(host) \ -+ clear_bit(EVENT_DATA_COMPLETE, &host->pending_events) -+#define mci_clear_data_error_pending(host) \ -+ clear_bit(EVENT_DATA_ERROR, &host->pending_events) -+#define mci_clear_stop_sent_pending(host) \ -+ clear_bit(EVENT_STOP_SENT, &host->pending_events) -+#define mci_clear_stop_pending(host) \ -+ clear_bit(EVENT_STOP_COMPLETE, &host->pending_events) -+#define mci_clear_dma_error_pending(host) \ -+ clear_bit(EVENT_DMA_ERROR, &host->pending_events) -+ -+ -+#ifdef CONFIG_DEBUG_FS -+#include <linux/debugfs.h> -+ -+#define DBG_REQ_BUF_SIZE (4096 - sizeof(unsigned int)) -+ -+struct req_dbg_data { -+ unsigned int nbytes; -+ char str[DBG_REQ_BUF_SIZE]; -+}; -+ -+static int req_dbg_open(struct inode *inode, struct file *file) -+{ -+ struct atmel_mci *host; -+ struct mmc_request *mrq; -+ struct mmc_command *cmd, *stop; -+ struct mmc_data *data; -+ struct req_dbg_data *priv; -+ char *str; -+ unsigned long n = 0; -+ -+ priv = kzalloc(DBG_REQ_BUF_SIZE, GFP_KERNEL); -+ if (!priv) -+ return -ENOMEM; -+ str = priv->str; -+ -+ mutex_lock(&inode->i_mutex); -+ host = inode->i_private; -+ -+ spin_lock_irq(&host->mmc->lock); -+ mrq = host->mrq; -+ if (mrq) { -+ cmd = mrq->cmd; -+ data = mrq->data; -+ stop = mrq->stop; -+ n = snprintf(str, DBG_REQ_BUF_SIZE, -+ "CMD%u(0x%x) %x %x %x %x %x (err %u)\n", -+ cmd->opcode, cmd->arg, cmd->flags, -+ cmd->resp[0], cmd->resp[1], cmd->resp[2], -+ cmd->resp[3], cmd->error); -+ if (n < DBG_REQ_BUF_SIZE && data) -+ n += snprintf(str + n, DBG_REQ_BUF_SIZE - n, -+ "DATA %u * %u (%u) %x (err %u)\n", -+ data->blocks, data->blksz, -+ data->bytes_xfered, data->flags, -+ data->error); -+ if (n < DBG_REQ_BUF_SIZE && stop) -+ n += snprintf(str + n, DBG_REQ_BUF_SIZE - n, -+ "CMD%u(0x%x) %x %x %x %x %x (err %u)\n", -+ stop->opcode, stop->arg, stop->flags, -+ stop->resp[0], stop->resp[1], -+ stop->resp[2], stop->resp[3], -+ stop->error); -+ } -+ spin_unlock_irq(&host->mmc->lock); -+ mutex_unlock(&inode->i_mutex); -+ -+ priv->nbytes = min(n, DBG_REQ_BUF_SIZE); -+ file->private_data = priv; -+ -+ return 0; -+} -+ -+static ssize_t req_dbg_read(struct file *file, char __user *buf, -+ size_t nbytes, loff_t *ppos) -+{ -+ struct req_dbg_data *priv = file->private_data; -+ -+ return simple_read_from_buffer(buf, nbytes, ppos, -+ priv->str, priv->nbytes); -+} -+ -+static int req_dbg_release(struct inode *inode, struct file *file) -+{ -+ kfree(file->private_data); -+ return 0; -+} -+ -+static const struct file_operations req_dbg_fops = { -+ .owner = THIS_MODULE, -+ .open = req_dbg_open, -+ .llseek = no_llseek, -+ .read = req_dbg_read, -+ .release = req_dbg_release, -+}; -+ -+static int regs_dbg_open(struct inode *inode, struct file *file) -+{ -+ struct atmel_mci *host; -+ unsigned int i; -+ u32 *data; -+ int ret = -ENOMEM; -+ -+ mutex_lock(&inode->i_mutex); -+ host = inode->i_private; -+ data = kmalloc(inode->i_size, GFP_KERNEL); -+ if (!data) -+ goto out; -+ -+ spin_lock_irq(&host->mmc->lock); -+ for (i = 0; i < inode->i_size / 4; i++) -+ data[i] = __raw_readl(host->regs + i * 4); -+ spin_unlock_irq(&host->mmc->lock); -+ -+ file->private_data = data; -+ ret = 0; -+ -+out: -+ mutex_unlock(&inode->i_mutex); -+ -+ return ret; -+} -+ -+static ssize_t regs_dbg_read(struct file *file, char __user *buf, -+ size_t nbytes, loff_t *ppos) -+{ -+ struct inode *inode = file->f_dentry->d_inode; -+ int ret; -+ -+ mutex_lock(&inode->i_mutex); -+ ret = simple_read_from_buffer(buf, nbytes, ppos, -+ file->private_data, -+ file->f_dentry->d_inode->i_size); -+ mutex_unlock(&inode->i_mutex); -+ -+ return ret; -+} -+ -+static int regs_dbg_release(struct inode *inode, struct file *file) -+{ -+ kfree(file->private_data); -+ return 0; -+} -+ -+static const struct file_operations regs_dbg_fops = { -+ .owner = THIS_MODULE, -+ .open = regs_dbg_open, -+ .llseek = generic_file_llseek, -+ .read = regs_dbg_read, -+ .release = regs_dbg_release, -+}; -+ -+static void atmci_init_debugfs(struct atmel_mci *host) -+{ -+ struct mmc_host *mmc; -+ struct dentry *root, *regs; -+ struct resource *res; -+ -+ mmc = host->mmc; -+ root = debugfs_create_dir(mmc_hostname(mmc), NULL); -+ if (IS_ERR(root) || !root) -+ goto err_root; -+ host->debugfs_root = root; -+ -+ regs = debugfs_create_file("regs", 0400, root, host, ®s_dbg_fops); -+ if (!regs) -+ goto err_regs; -+ -+ res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0); -+ regs->d_inode->i_size = res->end - res->start + 1; -+ host->debugfs_regs = regs; -+ -+ host->debugfs_req = debugfs_create_file("req", 0400, root, -+ host, &req_dbg_fops); -+ if (!host->debugfs_req) -+ goto err_req; -+ -+ host->debugfs_pending_events -+ = debugfs_create_u32("pending_events", 0400, root, -+ (u32 *)&host->pending_events); -+ if (!host->debugfs_pending_events) -+ goto err_pending_events; -+ -+ host->debugfs_completed_events -+ = debugfs_create_u32("completed_events", 0400, root, -+ (u32 *)&host->completed_events); -+ if (!host->debugfs_completed_events) -+ goto err_completed_events; -+ -+ return; -+ -+err_completed_events: -+ debugfs_remove(host->debugfs_pending_events); -+err_pending_events: -+ debugfs_remove(host->debugfs_req); -+err_req: -+ debugfs_remove(host->debugfs_regs); -+err_regs: -+ debugfs_remove(host->debugfs_root); -+err_root: -+ host->debugfs_root = NULL; -+ dev_err(&host->pdev->dev, -+ "failed to initialize debugfs for %s\n", -+ mmc_hostname(mmc)); -+} -+ -+static void atmci_cleanup_debugfs(struct atmel_mci *host) -+{ -+ if (host->debugfs_root) { -+ debugfs_remove(host->debugfs_completed_events); -+ debugfs_remove(host->debugfs_pending_events); -+ debugfs_remove(host->debugfs_req); -+ debugfs_remove(host->debugfs_regs); -+ debugfs_remove(host->debugfs_root); -+ host->debugfs_root = NULL; -+ } -+} -+#else -+static inline void atmci_init_debugfs(struct atmel_mci *host) -+{ -+ -+} -+ -+static inline void atmci_cleanup_debugfs(struct atmel_mci *host) -+{ -+ -+} -+#endif /* CONFIG_DEBUG_FS */ -+ -+static inline unsigned int ns_to_clocks(struct atmel_mci *host, -+ unsigned int ns) -+{ -+ return (ns * (host->bus_hz / 1000000) + 999) / 1000; -+} -+ -+static void atmci_set_timeout(struct atmel_mci *host, -+ struct mmc_data *data) -+{ -+ static unsigned dtomul_to_shift[] = { -+ 0, 4, 7, 8, 10, 12, 16, 20 -+ }; -+ unsigned timeout; -+ unsigned dtocyc, dtomul; -+ -+ timeout = ns_to_clocks(host, data->timeout_ns) + data->timeout_clks; -+ -+ for (dtomul = 0; dtomul < 8; dtomul++) { -+ unsigned shift = dtomul_to_shift[dtomul]; -+ dtocyc = (timeout + (1 << shift) - 1) >> shift; -+ if (dtocyc < 15) -+ break; -+ } -+ -+ if (dtomul >= 8) { -+ dtomul = 7; -+ dtocyc = 15; -+ } -+ -+ dev_dbg(&host->mmc->class_dev, "setting timeout to %u cycles\n", -+ dtocyc << dtomul_to_shift[dtomul]); -+ mci_writel(host, DTOR, (MCI_BF(DTOMUL, dtomul) -+ | MCI_BF(DTOCYC, dtocyc))); -+} -+ -+/* -+ * Return mask with command flags to be enabled for this command. -+ */ -+static u32 atmci_prepare_command(struct mmc_host *mmc, -+ struct mmc_command *cmd) -+{ -+ u32 cmdr; -+ -+ cmd->error = 0; -+ -+ cmdr = MCI_BF(CMDNB, cmd->opcode); -+ -+ if (cmd->flags & MMC_RSP_PRESENT) { -+ if (cmd->flags & MMC_RSP_136) -+ cmdr |= MCI_BF(RSPTYP, MCI_RSPTYP_136_BIT); -+ else -+ cmdr |= MCI_BF(RSPTYP, MCI_RSPTYP_48_BIT); -+ } -+ -+ /* -+ * This should really be MAXLAT_5 for CMD2 and ACMD41, but -+ * it's too difficult to determine whether this is an ACMD or -+ * not. Better make it 64. -+ */ -+ cmdr |= MCI_BIT(MAXLAT); -+ -+ if (mmc->ios.bus_mode == MMC_BUSMODE_OPENDRAIN) -+ cmdr |= MCI_BIT(OPDCMD); -+ -+ dev_dbg(&mmc->class_dev, -+ "cmd: op %02x arg %08x flags %08x, cmdflags %08lx\n", -+ cmd->opcode, cmd->arg, cmd->flags, (unsigned long)cmdr); -+ -+ return cmdr; -+} -+ -+static void atmci_start_command(struct atmel_mci *host, -+ struct mmc_command *cmd, -+ u32 cmd_flags) -+{ -+ WARN_ON(host->cmd); -+ host->cmd = cmd; -+ -+ mci_writel(host, ARGR, cmd->arg); -+ mci_writel(host, CMDR, cmd_flags); -+ -+ if (cmd->data) -+ dma_start_request(host->dma.req.req.dmac, -+ host->dma.req.req.channel); -+} -+ -+/* -+ * Returns a mask of flags to be set in the command register when the -+ * command to start the transfer is to be sent. -+ */ -+static u32 atmci_prepare_data(struct mmc_host *mmc, struct mmc_data *data) -+{ -+ struct atmel_mci *host = mmc_priv(mmc); -+ u32 cmd_flags; -+ -+ WARN_ON(host->data); -+ host->data = data; -+ -+ atmci_set_timeout(host, data); -+ mci_writel(host, BLKR, (MCI_BF(BCNT, data->blocks) -+ | MCI_BF(BLKLEN, data->blksz))); -+ host->dma.req.block_size = data->blksz; -+ host->dma.req.nr_blocks = data->blocks; -+ -+ cmd_flags = MCI_BF(TRCMD, MCI_TRCMD_START_TRANS); -+ if (data->flags & MMC_DATA_STREAM) -+ cmd_flags |= MCI_BF(TRTYP, MCI_TRTYP_STREAM); -+ else if (data->blocks > 1) -+ cmd_flags |= MCI_BF(TRTYP, MCI_TRTYP_MULTI_BLOCK); -+ else -+ cmd_flags |= MCI_BF(TRTYP, MCI_TRTYP_BLOCK); -+ -+ if (data->flags & MMC_DATA_READ) { -+ cmd_flags |= MCI_BIT(TRDIR); -+ host->dma.req.nr_sg -+ = dma_map_sg(&host->pdev->dev, data->sg, -+ data->sg_len, DMA_FROM_DEVICE); -+ host->dma.req.periph_id = host->dma.rx_periph_id; -+ host->dma.req.direction = DMA_DIR_PERIPH_TO_MEM; -+ host->dma.req.data_reg = host->mapbase + MCI_RDR; -+ } else { -+ host->dma.req.nr_sg -+ = dma_map_sg(&host->pdev->dev, data->sg, -+ data->sg_len, DMA_TO_DEVICE); -+ host->dma.req.periph_id = host->dma.tx_periph_id; -+ host->dma.req.direction = DMA_DIR_MEM_TO_PERIPH; -+ host->dma.req.data_reg = host->mapbase + MCI_TDR; -+ } -+ host->dma.req.sg = data->sg; -+ -+ dma_prepare_request_sg(host->dma.req.req.dmac, &host->dma.req); -+ -+ return cmd_flags; -+} -+ -+static void atmci_request(struct mmc_host *mmc, struct mmc_request *mrq) -+{ -+ struct atmel_mci *host = mmc_priv(mmc); -+ struct mmc_data *data = mrq->data; -+ u32 iflags; -+ u32 cmdflags = 0; -+ -+ iflags = mci_readl(host, IMR); -+ if (iflags) -+ dev_warn(&mmc->class_dev, "WARNING: IMR=0x%08x\n", -+ mci_readl(host, IMR)); -+ -+ WARN_ON(host->mrq != NULL); -+ -+ /* -+ * We may "know" the card is gone even though there's still an -+ * electrical connection. If so, we really need to communicate -+ * this to the MMC core since there won't be any more -+ * interrupts as the card is completely removed. Otherwise, -+ * the MMC core might believe the card is still there even -+ * though the card was just removed very slowly. -+ */ -+ if (!host->present) { -+ mrq->cmd->error = -ENOMEDIUM; -+ mmc_request_done(mmc, mrq); -+ return; -+ } -+ -+ host->mrq = mrq; -+ host->pending_events = 0; -+ host->completed_events = 0; -+ -+ iflags = MCI_BIT(CMDRDY); -+ cmdflags = atmci_prepare_command(mmc, mrq->cmd); -+ -+ if (mrq->stop) { -+ WARN_ON(!data); -+ -+ host->stop_cmdr = atmci_prepare_command(mmc, mrq->stop); -+ host->stop_cmdr |= MCI_BF(TRCMD, MCI_TRCMD_STOP_TRANS); -+ if (!(data->flags & MMC_DATA_WRITE)) -+ host->stop_cmdr |= MCI_BIT(TRDIR); -+ if (data->flags & MMC_DATA_STREAM) -+ host->stop_cmdr |= MCI_BF(TRTYP, MCI_TRTYP_STREAM); -+ else -+ host->stop_cmdr |= MCI_BF(TRTYP, MCI_TRTYP_MULTI_BLOCK); -+ } -+ if (data) { -+ cmdflags |= atmci_prepare_data(mmc, data); -+ iflags |= MCI_DATA_ERROR_FLAGS; -+ } -+ -+ atmci_start_command(host, mrq->cmd, cmdflags); -+ mci_writel(host, IER, iflags); -+} -+ -+static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ struct atmel_mci *host = mmc_priv(mmc); -+ u32 mr; -+ -+ if (ios->clock) { -+ u32 clkdiv; -+ -+ /* Set clock rate */ -+ clkdiv = DIV_ROUND_UP(host->bus_hz, 2 * ios->clock) - 1; -+ if (clkdiv > 255) { -+ dev_warn(&mmc->class_dev, -+ "clock %u too slow; using %lu\n", -+ ios->clock, host->bus_hz / (2 * 256)); -+ clkdiv = 255; -+ } -+ -+ mr = mci_readl(host, MR); -+ mr = MCI_BFINS(CLKDIV, clkdiv, mr) -+ | MCI_BIT(WRPROOF) | MCI_BIT(RDPROOF); -+ mci_writel(host, MR, mr); -+ -+ /* Enable the MCI controller */ -+ mci_writel(host, CR, MCI_BIT(MCIEN)); -+ } else { -+ /* Disable the MCI controller */ -+ mci_writel(host, CR, MCI_BIT(MCIDIS)); -+ } -+ -+ switch (ios->bus_width) { -+ case MMC_BUS_WIDTH_1: -+ mci_writel(host, SDCR, 0); -+ break; -+ case MMC_BUS_WIDTH_4: -+ mci_writel(host, SDCR, MCI_BIT(SDCBUS)); -+ break; -+ } -+ -+ switch (ios->power_mode) { -+ case MMC_POWER_ON: -+ /* Send init sequence (74 clock cycles) */ -+ mci_writel(host, IDR, ~0UL); -+ mci_writel(host, CMDR, MCI_BF(SPCMD, MCI_SPCMD_INIT_CMD)); -+ while (!(mci_readl(host, SR) & MCI_BIT(CMDRDY))) -+ cpu_relax(); -+ break; -+ default: -+ /* -+ * TODO: None of the currently available AVR32-based -+ * boards allow MMC power to be turned off. Implement -+ * power control when this can be tested properly. -+ */ -+ break; -+ } -+} -+ -+static int atmci_get_ro(struct mmc_host *mmc) -+{ -+ int read_only = 0; -+ struct atmel_mci *host = mmc_priv(mmc); -+ -+ if (host->wp_pin >= 0) { -+ read_only = gpio_get_value(host->wp_pin); -+ dev_dbg(&mmc->class_dev, "card is %s\n", -+ read_only ? "read-only" : "read-write"); -+ } else { -+ dev_dbg(&mmc->class_dev, -+ "no pin for checking read-only switch." -+ " Assuming write-enable.\n"); -+ } -+ -+ return read_only; -+} -+ -+static struct mmc_host_ops atmci_ops = { -+ .request = atmci_request, -+ .set_ios = atmci_set_ios, -+ .get_ro = atmci_get_ro, -+}; -+ -+static void atmci_request_end(struct mmc_host *mmc, struct mmc_request *mrq) -+{ -+ struct atmel_mci *host = mmc_priv(mmc); -+ -+ WARN_ON(host->cmd || host->data); -+ host->mrq = NULL; -+ -+ mmc_request_done(mmc, mrq); -+} -+ -+static void send_stop_cmd(struct mmc_host *mmc, struct mmc_data *data, -+ u32 flags) -+{ -+ struct atmel_mci *host = mmc_priv(mmc); -+ -+ atmci_start_command(host, data->stop, host->stop_cmdr | flags); -+ mci_writel(host, IER, MCI_BIT(CMDRDY)); -+} -+ -+static void atmci_data_complete(struct atmel_mci *host, struct mmc_data *data) -+{ -+ host->data = NULL; -+ dma_unmap_sg(&host->pdev->dev, data->sg, host->dma.req.nr_sg, -+ ((data->flags & MMC_DATA_WRITE) -+ ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); -+ -+ /* -+ * Data might complete before command for very short transfers -+ * (like READ_SCR) -+ */ -+ if (mci_cmd_is_complete(host) -+ && (!data->stop || mci_stop_is_complete(host))) -+ atmci_request_end(host->mmc, data->mrq); -+} -+ -+static void atmci_command_complete(struct atmel_mci *host, -+ struct mmc_command *cmd, u32 status) -+{ -+ if (status & MCI_BIT(RTOE)) -+ cmd->error = -ETIMEDOUT; -+ else if ((cmd->flags & MMC_RSP_CRC) -+ && (status & MCI_BIT(RCRCE))) -+ cmd->error = -EILSEQ; -+ else if (status & (MCI_BIT(RINDE) | MCI_BIT(RDIRE) | MCI_BIT(RENDE))) -+ cmd->error = -EIO; -+ -+ if (cmd->error) { -+ dev_dbg(&host->mmc->class_dev, -+ "command error: op=0x%x status=0x%08x\n", -+ cmd->opcode, status); -+ -+ if (cmd->data) { -+ dma_stop_request(host->dma.req.req.dmac, -+ host->dma.req.req.channel); -+ mci_writel(host, IDR, MCI_BIT(NOTBUSY) -+ | MCI_DATA_ERROR_FLAGS); -+ host->data = NULL; -+ } -+ } -+} -+ -+static void atmci_detect_change(unsigned long data) -+{ -+ struct atmel_mci *host = (struct atmel_mci *)data; -+ struct mmc_request *mrq = host->mrq; -+ int present; -+ -+ /* -+ * atmci_remove() sets detect_pin to -1 before freeing the -+ * interrupt. We must not re-enable the interrupt if it has -+ * been freed. -+ */ -+ smp_rmb(); -+ if (host->detect_pin < 0) -+ return; -+ -+ enable_irq(gpio_to_irq(host->detect_pin)); -+ present = !gpio_get_value(host->detect_pin); -+ -+ dev_vdbg(&host->pdev->dev, "detect change: %d (was %d)\n", -+ present, host->present); -+ -+ if (present != host->present) { -+ dev_dbg(&host->mmc->class_dev, "card %s\n", -+ present ? "inserted" : "removed"); -+ host->present = present; -+ -+ /* Reset controller if card is gone */ -+ if (!present) { -+ mci_writel(host, CR, MCI_BIT(SWRST)); -+ mci_writel(host, IDR, ~0UL); -+ mci_writel(host, CR, MCI_BIT(MCIEN)); -+ } -+ -+ /* Clean up queue if present */ -+ if (mrq) { -+ if (!mci_cmd_is_complete(host)) -+ mrq->cmd->error = -ENOMEDIUM; -+ if (mrq->data && !mci_data_is_complete(host) -+ && !mci_data_error_is_complete(host)) { -+ dma_stop_request(host->dma.req.req.dmac, -+ host->dma.req.req.channel); -+ host->data->error = -ENOMEDIUM; -+ atmci_data_complete(host, host->data); -+ } -+ if (mrq->stop && !mci_stop_is_complete(host)) -+ mrq->stop->error = -ENOMEDIUM; -+ -+ host->cmd = NULL; -+ atmci_request_end(host->mmc, mrq); -+ } -+ -+ mmc_detect_change(host->mmc, 0); -+ } -+} -+ -+static void atmci_tasklet_func(unsigned long priv) -+{ -+ struct mmc_host *mmc = (struct mmc_host *)priv; -+ struct atmel_mci *host = mmc_priv(mmc); -+ struct mmc_request *mrq = host->mrq; -+ struct mmc_data *data = host->data; -+ -+ dev_vdbg(&mmc->class_dev, -+ "tasklet: pending/completed/mask %lx/%lx/%x\n", -+ host->pending_events, host->completed_events, -+ mci_readl(host, IMR)); -+ -+ if (mci_clear_cmd_is_pending(host)) { -+ mci_set_cmd_complete(host); -+ atmci_command_complete(host, mrq->cmd, host->cmd_status); -+ if (!host->data || mci_data_is_complete(host) -+ || mci_data_error_is_complete(host)) -+ atmci_request_end(mmc, mrq); -+ } -+ if (mci_clear_stop_is_pending(host)) { -+ mci_set_stop_complete(host); -+ atmci_command_complete(host, mrq->stop, host->stop_status); -+ if (mci_data_is_complete(host) -+ || mci_data_error_is_complete(host)) -+ atmci_request_end(mmc, mrq); -+ } -+ if (mci_clear_dma_error_is_pending(host)) { -+ mci_set_dma_error_complete(host); -+ mci_clear_data_pending(host); -+ -+ /* DMA controller got bus error => invalid address */ -+ data->error = -EIO; -+ -+ dev_dbg(&mmc->class_dev, "dma error after %u bytes xfered\n", -+ host->data->bytes_xfered); -+ -+ if (data->stop -+ && !mci_set_stop_sent_is_completed(host)) -+ /* TODO: Check if card is still present */ -+ send_stop_cmd(host->mmc, data, 0); -+ -+ atmci_data_complete(host, data); -+ } -+ if (mci_clear_data_error_is_pending(host)) { -+ u32 status = host->data_status; -+ -+ mci_set_data_error_complete(host); -+ mci_clear_data_pending(host); -+ -+ dma_stop_request(host->dma.req.req.dmac, -+ host->dma.req.req.channel); -+ -+ if (status & MCI_BIT(DCRCE)) { -+ dev_dbg(&mmc->class_dev, "data CRC error\n"); -+ data->error = -EILSEQ; -+ } else if (status & MCI_BIT(DTOE)) { -+ dev_dbg(&mmc->class_dev, "data timeout error\n"); -+ data->error = -ETIMEDOUT; -+ } else { -+ dev_dbg(&mmc->class_dev, "data FIFO error\n"); -+ data->error = -EIO; -+ } -+ dev_dbg(&mmc->class_dev, "bytes xfered: %u\n", -+ data->bytes_xfered); -+ -+ if (data->stop -+ && !mci_set_stop_sent_is_completed(host)) -+ /* TODO: Check if card is still present */ -+ send_stop_cmd(host->mmc, data, 0); -+ -+ atmci_data_complete(host, data); -+ } -+ if (mci_clear_data_is_pending(host)) { -+ mci_set_data_complete(host); -+ data->bytes_xfered = data->blocks * data->blksz; -+ atmci_data_complete(host, data); -+ } -+ /* See if there is a pending STOP which can be sent */ -+ if (host->pending_stop && mci_cmd_is_complete(host)) { -+ host->pending_stop = 0; -+ if (mrq->stop && !mci_set_stop_sent_is_completed(host)) -+ send_stop_cmd(host->mmc, mrq->data, 0); -+ } -+} -+ -+static void atmci_cmd_interrupt(struct mmc_host *mmc, u32 status) -+{ -+ struct atmel_mci *host = mmc_priv(mmc); -+ struct mmc_command *cmd = host->cmd; -+ -+ /* -+ * Read the response now so that we're free to send a new -+ * command immediately. -+ */ -+ cmd->resp[0] = mci_readl(host, RSPR); -+ cmd->resp[1] = mci_readl(host, RSPR); -+ cmd->resp[2] = mci_readl(host, RSPR); -+ cmd->resp[3] = mci_readl(host, RSPR); -+ -+ mci_writel(host, IDR, MCI_BIT(CMDRDY)); -+ host->cmd = NULL; -+ -+ if (mci_stop_sent_is_complete(host)) { -+ host->stop_status = status; -+ mci_set_stop_pending(host); -+ } else { -+ struct mmc_request *mrq = host->mrq; -+ -+ if (mrq->stop && mci_dma_is_complete(host) -+ && !mci_set_stop_sent_is_completed(host)) -+ send_stop_cmd(host->mmc, mrq->data, 0); -+ host->cmd_status = status; -+ mci_set_cmd_pending(host); -+ } -+ -+ tasklet_schedule(&host->tasklet); -+} -+ -+static void atmci_xfer_complete(struct dma_request *_req) -+{ -+ struct dma_request_sg *req = to_dma_request_sg(_req); -+ struct atmel_mci_dma *dma; -+ struct atmel_mci *host; -+ struct mmc_data *data; -+ -+ dma = container_of(req, struct atmel_mci_dma, req); -+ host = container_of(dma, struct atmel_mci, dma); -+ data = host->data; -+ -+ /* -+ * This callback may be called before we see the CMDRDY -+ * interrupt under heavy irq load (possibly caused by other -+ * drivers) or when interrupts are disabled for a long time. -+ */ -+ mci_set_dma_complete(host); -+ -+ if (data->stop) { -+ if (!mci_cmd_is_complete(host)) { -+ /* Just remember a STOP must be sent */ -+ host->pending_stop = 1; -+ } else if (!mci_set_stop_sent_is_completed(host)) { -+ send_stop_cmd(host->mmc, data, 0); -+ host->pending_stop = 0; -+ } -+ } -+ -+ /* -+ * Regardless of what the documentation says, we have to wait -+ * for NOTBUSY even after block read operations. -+ * -+ * When the DMA transfer is complete, the controller may still -+ * be reading the CRC from the card, i.e. the data transfer is -+ * still in progress and we haven't seen all the potential -+ * error bits yet. -+ */ -+ mci_writel(host, IER, MCI_BIT(NOTBUSY)); -+} -+ -+static void atmci_dma_error(struct dma_request *_req) -+{ -+ struct dma_request_sg *req = to_dma_request_sg(_req); -+ struct atmel_mci_dma *dma; -+ struct atmel_mci *host; -+ -+ dma = container_of(req, struct atmel_mci_dma, req); -+ host = container_of(dma, struct atmel_mci, dma); -+ -+ mci_writel(host, IDR, (MCI_BIT(NOTBUSY) -+ | MCI_DATA_ERROR_FLAGS)); -+ -+ mci_set_dma_error_pending(host); -+ tasklet_schedule(&host->tasklet); -+} -+ -+static irqreturn_t atmci_interrupt(int irq, void *dev_id) -+{ -+ struct mmc_host *mmc = dev_id; -+ struct atmel_mci *host = mmc_priv(mmc); -+ u32 status, mask, pending; -+ -+ spin_lock(&mmc->lock); -+ -+ status = mci_readl(host, SR); -+ mask = mci_readl(host, IMR); -+ pending = status & mask; -+ -+ do { -+ if (pending & MCI_DATA_ERROR_FLAGS) { -+ mci_writel(host, IDR, (MCI_BIT(NOTBUSY) -+ | MCI_DATA_ERROR_FLAGS)); -+ host->data_status = status; -+ mci_set_data_error_pending(host); -+ tasklet_schedule(&host->tasklet); -+ break; -+ } -+ if (pending & MCI_BIT(CMDRDY)) -+ atmci_cmd_interrupt(mmc, status); -+ if (pending & MCI_BIT(NOTBUSY)) { -+ mci_writel(host, IDR, (MCI_BIT(NOTBUSY) -+ | MCI_DATA_ERROR_FLAGS)); -+ mci_set_data_pending(host); -+ tasklet_schedule(&host->tasklet); -+ } -+ -+ status = mci_readl(host, SR); -+ mask = mci_readl(host, IMR); -+ pending = status & mask; -+ } while (pending); -+ -+ spin_unlock(&mmc->lock); -+ -+ return IRQ_HANDLED; -+} -+ -+static irqreturn_t atmci_detect_interrupt(int irq, void *dev_id) -+{ -+ struct mmc_host *mmc = dev_id; -+ struct atmel_mci *host = mmc_priv(mmc); -+ -+ /* -+ * Disable interrupts until the pin has stabilized and check -+ * the state then. Use mod_timer() since we may be in the -+ * middle of the timer routine when this interrupt triggers. -+ */ -+ disable_irq_nosync(irq); -+ mod_timer(&host->detect_timer, jiffies + msecs_to_jiffies(20)); -+ -+ return IRQ_HANDLED; -+} -+ -+static int __devinit atmci_probe(struct platform_device *pdev) -+{ -+ struct mci_platform_data *board; -+ struct atmel_mci *host; -+ struct mmc_host *mmc; -+ struct resource *regs; -+ int irq; -+ int ret; -+ -+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!regs) -+ return -ENXIO; -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) -+ return irq; -+ -+ board = pdev->dev.platform_data; -+ -+ mmc = mmc_alloc_host(sizeof(struct atmel_mci), &pdev->dev); -+ if (!mmc) -+ return -ENOMEM; -+ -+ host = mmc_priv(mmc); -+ host->pdev = pdev; -+ host->mmc = mmc; -+ if (board) { -+ host->detect_pin = board->detect_pin; -+ host->wp_pin = board->wp_pin; -+ } else { -+ host->detect_pin = -1; -+ host->wp_pin = -1; -+ } -+ -+ host->mck = clk_get(&pdev->dev, "mci_clk"); -+ if (IS_ERR(host->mck)) { -+ ret = PTR_ERR(host->mck); -+ goto out_free_host; -+ } -+ clk_enable(host->mck); -+ -+ ret = -ENOMEM; -+ host->regs = ioremap(regs->start, regs->end - regs->start + 1); -+ if (!host->regs) -+ goto out_disable_clk; -+ -+ host->bus_hz = clk_get_rate(host->mck); -+ host->mapbase = regs->start; -+ -+ mmc->ops = &atmci_ops; -+ mmc->f_min = (host->bus_hz + 511) / 512; -+ mmc->f_max = min((unsigned int)(host->bus_hz / 2), fmax); -+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; -+ mmc->caps |= MMC_CAP_4_BIT_DATA; -+ -+ tasklet_init(&host->tasklet, atmci_tasklet_func, (unsigned long)mmc); -+ -+ ret = request_irq(irq, atmci_interrupt, 0, "mmci", mmc); -+ if (ret) -+ goto out_unmap; -+ -+ /* Assume card is present if we don't have a detect pin */ -+ host->present = 1; -+ if (host->detect_pin >= 0) { -+ if (gpio_request(host->detect_pin, "mmc_detect")) { -+ dev_dbg(&mmc->class_dev, "no detect pin available\n"); -+ host->detect_pin = -1; -+ } else { -+ host->present = !gpio_get_value(host->detect_pin); -+ } -+ } -+ if (host->wp_pin >= 0) { -+ if (gpio_request(host->wp_pin, "mmc_wp")) { -+ dev_dbg(&mmc->class_dev, "no WP pin available\n"); -+ host->wp_pin = -1; -+ } -+ } -+ -+ /* TODO: Get this information from platform data */ -+ ret = -ENOMEM; -+ host->dma.req.req.dmac = find_dma_controller(0); -+ if (!host->dma.req.req.dmac) { -+ dev_dbg(&mmc->class_dev, "no DMA controller available\n"); -+ goto out_free_irq; -+ } -+ ret = dma_alloc_channel(host->dma.req.req.dmac); -+ if (ret < 0) { -+ dev_dbg(&mmc->class_dev, "unable to allocate DMA channel\n"); -+ goto out_free_irq; -+ } -+ host->dma.req.req.channel = ret; -+ host->dma.req.width = DMA_WIDTH_32BIT; -+ host->dma.req.req.xfer_complete = atmci_xfer_complete; -+ host->dma.req.req.block_complete = NULL; // atmci_block_complete; -+ host->dma.req.req.error = atmci_dma_error; -+ host->dma.rx_periph_id = 0; -+ host->dma.tx_periph_id = 1; -+ -+ mci_writel(host, CR, MCI_BIT(SWRST)); -+ mci_writel(host, IDR, ~0UL); -+ -+ platform_set_drvdata(pdev, host); -+ -+ mmc_add_host(mmc); -+ -+ if (host->detect_pin >= 0) { -+ setup_timer(&host->detect_timer, atmci_detect_change, -+ (unsigned long)host); -+ -+ ret = request_irq(gpio_to_irq(host->detect_pin), -+ atmci_detect_interrupt, -+ IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, -+ DRIVER_NAME, mmc); -+ if (ret) { -+ dev_dbg(&mmc->class_dev, -+ "could not request IRQ %d for detect pin\n", -+ gpio_to_irq(host->detect_pin)); -+ gpio_free(host->detect_pin); -+ host->detect_pin = -1; -+ } -+ } -+ -+ dev_info(&mmc->class_dev, "Atmel MCI controller at 0x%08lx irq %d\n", -+ host->mapbase, irq); -+ -+ atmci_init_debugfs(host); -+ -+ return 0; -+ -+out_free_irq: -+ if (host->detect_pin >= 0) -+ gpio_free(host->detect_pin); -+ if (host->wp_pin >= 0) -+ gpio_free(host->wp_pin); -+ free_irq(irq, mmc); -+out_unmap: -+ iounmap(host->regs); -+out_disable_clk: -+ clk_disable(host->mck); -+ clk_put(host->mck); -+out_free_host: -+ mmc_free_host(mmc); -+ return ret; -+} -+ -+static int __devexit atmci_remove(struct platform_device *pdev) -+{ -+ struct atmel_mci *host = platform_get_drvdata(pdev); -+ -+ platform_set_drvdata(pdev, NULL); -+ -+ if (host) { -+ atmci_cleanup_debugfs(host); -+ -+ if (host->detect_pin >= 0) { -+ int pin = host->detect_pin; -+ -+ /* Make sure our timer doesn't enable the interrupt */ -+ host->detect_pin = -1; -+ smp_wmb(); -+ -+ free_irq(gpio_to_irq(pin), host->mmc); -+ del_timer_sync(&host->detect_timer); -+ cancel_delayed_work(&host->mmc->detect); -+ gpio_free(pin); -+ } -+ -+ mmc_remove_host(host->mmc); -+ -+ mci_writel(host, IDR, ~0UL); -+ mci_writel(host, CR, MCI_BIT(MCIDIS)); -+ mci_readl(host, SR); -+ -+ dma_release_channel(host->dma.req.req.dmac, -+ host->dma.req.req.channel); -+ -+ if (host->wp_pin >= 0) -+ gpio_free(host->wp_pin); -+ -+ free_irq(platform_get_irq(pdev, 0), host->mmc); -+ iounmap(host->regs); -+ -+ clk_disable(host->mck); -+ clk_put(host->mck); -+ -+ mmc_free_host(host->mmc); -+ } -+ return 0; -+} -+ -+static struct platform_driver atmci_driver = { -+ .probe = atmci_probe, -+ .remove = __devexit_p(atmci_remove), -+ .driver = { -+ .name = DRIVER_NAME, -+ }, -+}; -+ -+static int __init atmci_init(void) -+{ -+ return platform_driver_register(&atmci_driver); -+} -+ -+static void __exit atmci_exit(void) -+{ -+ platform_driver_unregister(&atmci_driver); -+} -+ -+module_init(atmci_init); -+module_exit(atmci_exit); -+ -+MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/drivers/mmc/host/atmel-mci.h -@@ -0,0 +1,192 @@ -+/* -+ * Atmel MultiMedia Card Interface driver -+ * -+ * Copyright (C) 2004-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. -+ */ -+#ifndef __DRIVERS_MMC_ATMEL_MCI_H__ -+#define __DRIVERS_MMC_ATMEL_MCI_H__ -+ -+/* MCI register offsets */ -+#define MCI_CR 0x0000 -+#define MCI_MR 0x0004 -+#define MCI_DTOR 0x0008 -+#define MCI_SDCR 0x000c -+#define MCI_ARGR 0x0010 -+#define MCI_CMDR 0x0014 -+#define MCI_BLKR 0x0018 -+#define MCI_RSPR 0x0020 -+#define MCI_RSPR1 0x0024 -+#define MCI_RSPR2 0x0028 -+#define MCI_RSPR3 0x002c -+#define MCI_RDR 0x0030 -+#define MCI_TDR 0x0034 -+#define MCI_SR 0x0040 -+#define MCI_IER 0x0044 -+#define MCI_IDR 0x0048 -+#define MCI_IMR 0x004c -+ -+/* Bitfields in CR */ -+#define MCI_MCIEN_OFFSET 0 -+#define MCI_MCIEN_SIZE 1 -+#define MCI_MCIDIS_OFFSET 1 -+#define MCI_MCIDIS_SIZE 1 -+#define MCI_PWSEN_OFFSET 2 -+#define MCI_PWSEN_SIZE 1 -+#define MCI_PWSDIS_OFFSET 3 -+#define MCI_PWSDIS_SIZE 1 -+#define MCI_SWRST_OFFSET 7 -+#define MCI_SWRST_SIZE 1 -+ -+/* Bitfields in MR */ -+#define MCI_CLKDIV_OFFSET 0 -+#define MCI_CLKDIV_SIZE 8 -+#define MCI_PWSDIV_OFFSET 8 -+#define MCI_PWSDIV_SIZE 3 -+#define MCI_RDPROOF_OFFSET 11 -+#define MCI_RDPROOF_SIZE 1 -+#define MCI_WRPROOF_OFFSET 12 -+#define MCI_WRPROOF_SIZE 1 -+#define MCI_DMAPADV_OFFSET 14 -+#define MCI_DMAPADV_SIZE 1 -+#define MCI_BLKLEN_OFFSET 16 -+#define MCI_BLKLEN_SIZE 16 -+ -+/* Bitfields in DTOR */ -+#define MCI_DTOCYC_OFFSET 0 -+#define MCI_DTOCYC_SIZE 4 -+#define MCI_DTOMUL_OFFSET 4 -+#define MCI_DTOMUL_SIZE 3 -+ -+/* Bitfields in SDCR */ -+#define MCI_SDCSEL_OFFSET 0 -+#define MCI_SDCSEL_SIZE 4 -+#define MCI_SDCBUS_OFFSET 7 -+#define MCI_SDCBUS_SIZE 1 -+ -+/* Bitfields in ARGR */ -+#define MCI_ARG_OFFSET 0 -+#define MCI_ARG_SIZE 32 -+ -+/* Bitfields in CMDR */ -+#define MCI_CMDNB_OFFSET 0 -+#define MCI_CMDNB_SIZE 6 -+#define MCI_RSPTYP_OFFSET 6 -+#define MCI_RSPTYP_SIZE 2 -+#define MCI_SPCMD_OFFSET 8 -+#define MCI_SPCMD_SIZE 3 -+#define MCI_OPDCMD_OFFSET 11 -+#define MCI_OPDCMD_SIZE 1 -+#define MCI_MAXLAT_OFFSET 12 -+#define MCI_MAXLAT_SIZE 1 -+#define MCI_TRCMD_OFFSET 16 -+#define MCI_TRCMD_SIZE 2 -+#define MCI_TRDIR_OFFSET 18 -+#define MCI_TRDIR_SIZE 1 -+#define MCI_TRTYP_OFFSET 19 -+#define MCI_TRTYP_SIZE 2 -+ -+/* Bitfields in BLKR */ -+#define MCI_BCNT_OFFSET 0 -+#define MCI_BCNT_SIZE 16 -+ -+/* Bitfields in RSPRn */ -+#define MCI_RSP_OFFSET 0 -+#define MCI_RSP_SIZE 32 -+ -+/* Bitfields in SR/IER/IDR/IMR */ -+#define MCI_CMDRDY_OFFSET 0 -+#define MCI_CMDRDY_SIZE 1 -+#define MCI_RXRDY_OFFSET 1 -+#define MCI_RXRDY_SIZE 1 -+#define MCI_TXRDY_OFFSET 2 -+#define MCI_TXRDY_SIZE 1 -+#define MCI_BLKE_OFFSET 3 -+#define MCI_BLKE_SIZE 1 -+#define MCI_DTIP_OFFSET 4 -+#define MCI_DTIP_SIZE 1 -+#define MCI_NOTBUSY_OFFSET 5 -+#define MCI_NOTBUSY_SIZE 1 -+#define MCI_ENDRX_OFFSET 6 -+#define MCI_ENDRX_SIZE 1 -+#define MCI_ENDTX_OFFSET 7 -+#define MCI_ENDTX_SIZE 1 -+#define MCI_RXBUFF_OFFSET 14 -+#define MCI_RXBUFF_SIZE 1 -+#define MCI_TXBUFE_OFFSET 15 -+#define MCI_TXBUFE_SIZE 1 -+#define MCI_RINDE_OFFSET 16 -+#define MCI_RINDE_SIZE 1 -+#define MCI_RDIRE_OFFSET 17 -+#define MCI_RDIRE_SIZE 1 -+#define MCI_RCRCE_OFFSET 18 -+#define MCI_RCRCE_SIZE 1 -+#define MCI_RENDE_OFFSET 19 -+#define MCI_RENDE_SIZE 1 -+#define MCI_RTOE_OFFSET 20 -+#define MCI_RTOE_SIZE 1 -+#define MCI_DCRCE_OFFSET 21 -+#define MCI_DCRCE_SIZE 1 -+#define MCI_DTOE_OFFSET 22 -+#define MCI_DTOE_SIZE 1 -+#define MCI_OVRE_OFFSET 30 -+#define MCI_OVRE_SIZE 1 -+#define MCI_UNRE_OFFSET 31 -+#define MCI_UNRE_SIZE 1 -+ -+/* Constants for DTOMUL */ -+#define MCI_DTOMUL_1_CYCLE 0 -+#define MCI_DTOMUL_16_CYCLES 1 -+#define MCI_DTOMUL_128_CYCLES 2 -+#define MCI_DTOMUL_256_CYCLES 3 -+#define MCI_DTOMUL_1024_CYCLES 4 -+#define MCI_DTOMUL_4096_CYCLES 5 -+#define MCI_DTOMUL_65536_CYCLES 6 -+#define MCI_DTOMUL_1048576_CYCLES 7 -+ -+/* Constants for RSPTYP */ -+#define MCI_RSPTYP_NO_RESP 0 -+#define MCI_RSPTYP_48_BIT 1 -+#define MCI_RSPTYP_136_BIT 2 -+ -+/* Constants for SPCMD */ -+#define MCI_SPCMD_NO_SPEC_CMD 0 -+#define MCI_SPCMD_INIT_CMD 1 -+#define MCI_SPCMD_SYNC_CMD 2 -+#define MCI_SPCMD_INT_CMD 4 -+#define MCI_SPCMD_INT_RESP 5 -+ -+/* Constants for TRCMD */ -+#define MCI_TRCMD_NO_TRANS 0 -+#define MCI_TRCMD_START_TRANS 1 -+#define MCI_TRCMD_STOP_TRANS 2 -+ -+/* Constants for TRTYP */ -+#define MCI_TRTYP_BLOCK 0 -+#define MCI_TRTYP_MULTI_BLOCK 1 -+#define MCI_TRTYP_STREAM 2 -+ -+/* Bit manipulation macros */ -+#define MCI_BIT(name) \ -+ (1 << MCI_##name##_OFFSET) -+#define MCI_BF(name,value) \ -+ (((value) & ((1 << MCI_##name##_SIZE) - 1)) \ -+ << MCI_##name##_OFFSET) -+#define MCI_BFEXT(name,value) \ -+ (((value) >> MCI_##name##_OFFSET) \ -+ & ((1 << MCI_##name##_SIZE) - 1)) -+#define MCI_BFINS(name,value,old) \ -+ (((old) & ~(((1 << MCI_##name##_SIZE) - 1) \ -+ << MCI_##name##_OFFSET)) \ -+ | MCI_BF(name,value)) -+ -+/* Register access macros */ -+#define mci_readl(port,reg) \ -+ __raw_readl((port)->regs + MCI_##reg) -+#define mci_writel(port,reg,value) \ -+ __raw_writel((value), (port)->regs + MCI_##reg) -+ -+#endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */ ---- a/drivers/mtd/nand/Kconfig -+++ b/drivers/mtd/nand/Kconfig -@@ -272,12 +272,54 @@ config MTD_NAND_CS553X - - If you say "m", the module will be called "cs553x_nand.ko". - --config MTD_NAND_AT91 -- bool "Support for NAND Flash / SmartMedia on AT91" -- depends on ARCH_AT91 -+config MTD_NAND_ATMEL -+ bool "Support for NAND Flash / SmartMedia on AT91 and AVR32" -+ depends on ARCH_AT91 || AVR32 - help - Enables support for NAND Flash / Smart Media Card interface -- on Atmel AT91 processors. -+ on Atmel AT91 and AVR32 processors. -+choice -+ prompt "ECC management for NAND Flash / SmartMedia on AT91 / AVR32" -+ depends on MTD_NAND_ATMEL -+ -+config MTD_NAND_ATMEL_ECC_HW -+ bool "Hardware ECC" -+ depends on ARCH_AT91SAM9263 || ARCH_AT91SAM9260 || AVR32 -+ help -+ Use hardware ECC instead of software ECC when the chip -+ supports it. -+ -+ The hardware ECC controller is capable of single bit error -+ correction and 2-bit random detection per page. -+ -+ NB : hardware and software ECC schemes are incompatible. -+ If you switch from one to another, you'll have to erase your -+ mtd partition. -+ -+ If unsure, say Y -+ -+config MTD_NAND_ATMEL_ECC_SOFT -+ bool "Software ECC" -+ help -+ Use software ECC. -+ -+ NB : hardware and software ECC schemes are incompatible. -+ If you switch from one to another, you'll have to erase your -+ mtd partition. -+ -+config MTD_NAND_ATMEL_ECC_NONE -+ bool "No ECC (testing only, DANGEROUS)" -+ depends on DEBUG_KERNEL -+ help -+ No ECC will be used. -+ It's not a good idea and it should be reserved for testing -+ purpose only. -+ -+ If unsure, say N -+ -+ endchoice -+ -+endchoice - - config MTD_NAND_CM_X270 - tristate "Support for NAND Flash on CM-X270 modules" ---- a/drivers/mtd/nand/Makefile -+++ b/drivers/mtd/nand/Makefile -@@ -24,7 +24,7 @@ obj-$(CONFIG_MTD_NAND_TS7250) += ts7250 - obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o - obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o - obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o --obj-$(CONFIG_MTD_NAND_AT91) += at91_nand.o -+obj-$(CONFIG_MTD_NAND_ATMEL) += atmel_nand.o - obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o - obj-$(CONFIG_MTD_NAND_BASLER_EXCITE) += excite_nandflash.o - obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o ---- a/drivers/mtd/nand/at91_nand.c -+++ /dev/null -@@ -1,236 +0,0 @@ --/* -- * drivers/mtd/nand/at91_nand.c -- * -- * Copyright (C) 2003 Rick Bronson -- * -- * Derived from drivers/mtd/nand/autcpu12.c -- * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) -- * -- * Derived from drivers/mtd/spia.c -- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) -- * -- * 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/slab.h> --#include <linux/module.h> --#include <linux/platform_device.h> --#include <linux/mtd/mtd.h> --#include <linux/mtd/nand.h> --#include <linux/mtd/partitions.h> -- --#include <asm/io.h> --#include <asm/sizes.h> -- --#include <asm/hardware.h> --#include <asm/arch/board.h> --#include <asm/arch/gpio.h> -- --struct at91_nand_host { -- struct nand_chip nand_chip; -- struct mtd_info mtd; -- void __iomem *io_base; -- struct at91_nand_data *board; --}; -- --/* -- * Hardware specific access to control-lines -- */ --static void at91_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) --{ -- struct nand_chip *nand_chip = mtd->priv; -- struct at91_nand_host *host = nand_chip->priv; -- -- if (cmd == NAND_CMD_NONE) -- return; -- -- if (ctrl & NAND_CLE) -- writeb(cmd, host->io_base + (1 << host->board->cle)); -- else -- writeb(cmd, host->io_base + (1 << host->board->ale)); --} -- --/* -- * Read the Device Ready pin. -- */ --static int at91_nand_device_ready(struct mtd_info *mtd) --{ -- struct nand_chip *nand_chip = mtd->priv; -- struct at91_nand_host *host = nand_chip->priv; -- -- return at91_get_gpio_value(host->board->rdy_pin); --} -- --/* -- * Enable NAND. -- */ --static void at91_nand_enable(struct at91_nand_host *host) --{ -- if (host->board->enable_pin) -- at91_set_gpio_value(host->board->enable_pin, 0); --} -- --/* -- * Disable NAND. -- */ --static void at91_nand_disable(struct at91_nand_host *host) --{ -- if (host->board->enable_pin) -- at91_set_gpio_value(host->board->enable_pin, 1); --} -- --#ifdef CONFIG_MTD_PARTITIONS --const char *part_probes[] = { "cmdlinepart", NULL }; --#endif -- --/* -- * Probe for the NAND device. -- */ --static int __init at91_nand_probe(struct platform_device *pdev) --{ -- struct at91_nand_host *host; -- struct mtd_info *mtd; -- struct nand_chip *nand_chip; -- int res; -- --#ifdef CONFIG_MTD_PARTITIONS -- struct mtd_partition *partitions = NULL; -- int num_partitions = 0; --#endif -- -- /* Allocate memory for the device structure (and zero it) */ -- host = kzalloc(sizeof(struct at91_nand_host), GFP_KERNEL); -- if (!host) { -- printk(KERN_ERR "at91_nand: failed to allocate device structure.\n"); -- return -ENOMEM; -- } -- -- host->io_base = ioremap(pdev->resource[0].start, -- pdev->resource[0].end - pdev->resource[0].start + 1); -- if (host->io_base == NULL) { -- printk(KERN_ERR "at91_nand: ioremap failed\n"); -- kfree(host); -- return -EIO; -- } -- -- mtd = &host->mtd; -- nand_chip = &host->nand_chip; -- host->board = pdev->dev.platform_data; -- -- nand_chip->priv = host; /* link the private data structures */ -- mtd->priv = nand_chip; -- mtd->owner = THIS_MODULE; -- -- /* Set address of NAND IO lines */ -- nand_chip->IO_ADDR_R = host->io_base; -- nand_chip->IO_ADDR_W = host->io_base; -- nand_chip->cmd_ctrl = at91_nand_cmd_ctrl; -- -- if (host->board->rdy_pin) -- nand_chip->dev_ready = at91_nand_device_ready; -- -- nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */ -- nand_chip->chip_delay = 20; /* 20us command delay time */ -- -- if (host->board->bus_width_16) /* 16-bit bus width */ -- nand_chip->options |= NAND_BUSWIDTH_16; -- -- platform_set_drvdata(pdev, host); -- at91_nand_enable(host); -- -- if (host->board->det_pin) { -- if (at91_get_gpio_value(host->board->det_pin)) { -- printk ("No SmartMedia card inserted.\n"); -- res = ENXIO; -- goto out; -- } -- } -- -- /* Scan to find existance of the device */ -- if (nand_scan(mtd, 1)) { -- res = -ENXIO; -- goto out; -- } -- --#ifdef CONFIG_MTD_PARTITIONS --#ifdef CONFIG_MTD_CMDLINE_PARTS -- mtd->name = "at91_nand"; -- num_partitions = parse_mtd_partitions(mtd, part_probes, -- &partitions, 0); --#endif -- if (num_partitions <= 0 && host->board->partition_info) -- partitions = host->board->partition_info(mtd->size, -- &num_partitions); -- -- if ((!partitions) || (num_partitions == 0)) { -- printk(KERN_ERR "at91_nand: No parititions defined, or unsupported device.\n"); -- res = ENXIO; -- goto release; -- } -- -- res = add_mtd_partitions(mtd, partitions, num_partitions); --#else -- res = add_mtd_device(mtd); --#endif -- -- if (!res) -- return res; -- --release: -- nand_release(mtd); --out: -- at91_nand_disable(host); -- platform_set_drvdata(pdev, NULL); -- iounmap(host->io_base); -- kfree(host); -- return res; --} -- --/* -- * Remove a NAND device. -- */ --static int __devexit at91_nand_remove(struct platform_device *pdev) --{ -- struct at91_nand_host *host = platform_get_drvdata(pdev); -- struct mtd_info *mtd = &host->mtd; -- -- nand_release(mtd); -- -- at91_nand_disable(host); -- -- iounmap(host->io_base); -- kfree(host); -- -- return 0; --} -- --static struct platform_driver at91_nand_driver = { -- .probe = at91_nand_probe, -- .remove = at91_nand_remove, -- .driver = { -- .name = "at91_nand", -- .owner = THIS_MODULE, -- }, --}; -- --static int __init at91_nand_init(void) --{ -- return platform_driver_register(&at91_nand_driver); --} -- -- --static void __exit at91_nand_exit(void) --{ -- platform_driver_unregister(&at91_nand_driver); --} -- -- --module_init(at91_nand_init); --module_exit(at91_nand_exit); -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Rick Bronson"); --MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91RM9200"); ---- /dev/null -+++ b/drivers/mtd/nand/atmel_nand.c -@@ -0,0 +1,650 @@ -+/* -+ * Copyright (C) 2003 Rick Bronson -+ * -+ * Derived from drivers/mtd/nand/autcpu12.c -+ * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) -+ * -+ * Derived from drivers/mtd/spia.c -+ * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) -+ * -+ * -+ * Add Hardware ECC support for AT91SAM9260 / AT91SAM9263 -+ * Richard Genoud (richard.genoud@gmail.com), Adeneo Copyright (C) 2007 -+ * -+ * Derived from Das U-Boot source code -+ * (u-boot-1.1.5/board/atmel/at91sam9263ek/nand.c) -+ * (C) Copyright 2006 ATMEL Rousset, Lacressonniere Nicolas -+ * -+ * -+ * 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/slab.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/mtd/mtd.h> -+#include <linux/mtd/nand.h> -+#include <linux/mtd/partitions.h> -+ -+#include <linux/gpio.h> -+#include <linux/io.h> -+ -+#include <asm/arch/board.h> -+#include <asm/arch/cpu.h> -+ -+#ifdef CONFIG_MTD_NAND_ATMEL_ECC_HW -+#define hard_ecc 1 -+#else -+#define hard_ecc 0 -+#endif -+ -+#ifdef CONFIG_MTD_NAND_ATMEL_ECC_NONE -+#define no_ecc 1 -+#else -+#define no_ecc 0 -+#endif -+ -+/* Register access macros */ -+#define ecc_readl(add, reg) \ -+ __raw_readl(add + ATMEL_ECC_##reg) -+#define ecc_writel(add, reg, value) \ -+ __raw_writel((value), add + ATMEL_ECC_##reg) -+ -+#include "atmel_nand_ecc.h" /* Hardware ECC registers */ -+ -+/* oob layout for large page size -+ * bad block info is on bytes 0 and 1 -+ * the bytes have to be consecutives to avoid -+ * several NAND_CMD_RNDOUT during read -+ */ -+static struct nand_ecclayout atmel_oobinfo_large = { -+ .eccbytes = 4, -+ .eccpos = {60, 61, 62, 63}, -+ .oobfree = { -+ {2, 58} -+ }, -+}; -+ -+/* oob layout for small page size -+ * bad block info is on bytes 4 and 5 -+ * the bytes have to be consecutives to avoid -+ * several NAND_CMD_RNDOUT during read -+ */ -+static struct nand_ecclayout atmel_oobinfo_small = { -+ .eccbytes = 4, -+ .eccpos = {0, 1, 2, 3}, -+ .oobfree = { -+ {6, 10} -+ }, -+}; -+ -+struct atmel_nand_host { -+ struct nand_chip nand_chip; -+ struct mtd_info mtd; -+ void __iomem *io_base; -+ struct atmel_nand_data *board; -+ struct device *dev; -+ void __iomem *ecc; -+}; -+ -+/* -+ * Enable NAND. -+ */ -+static void atmel_nand_enable(struct atmel_nand_host *host) -+{ -+ if (host->board->enable_pin) -+ gpio_set_value(host->board->enable_pin, 0); -+} -+ -+/* -+ * Disable NAND. -+ */ -+static void atmel_nand_disable(struct atmel_nand_host *host) -+{ -+ if (host->board->enable_pin) -+ gpio_set_value(host->board->enable_pin, 1); -+} -+ -+/* -+ * Hardware specific access to control-lines -+ */ -+static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) -+{ -+ struct nand_chip *nand_chip = mtd->priv; -+ struct atmel_nand_host *host = nand_chip->priv; -+ -+ if (ctrl & NAND_CTRL_CHANGE) { -+ if (ctrl & NAND_NCE) -+ atmel_nand_enable(host); -+ else -+ atmel_nand_disable(host); -+ } -+ if (cmd == NAND_CMD_NONE) -+ return; -+ -+ if (ctrl & NAND_CLE) -+ writeb(cmd, host->io_base + (1 << host->board->cle)); -+ else -+ writeb(cmd, host->io_base + (1 << host->board->ale)); -+} -+ -+/* -+ * Read the Device Ready pin. -+ */ -+static int atmel_nand_device_ready(struct mtd_info *mtd) -+{ -+ struct nand_chip *nand_chip = mtd->priv; -+ struct atmel_nand_host *host = nand_chip->priv; -+ -+ return gpio_get_value(host->board->rdy_pin); -+} -+ -+/* -+ * Minimal-overhead PIO for data access. -+ */ -+static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) -+{ -+ struct nand_chip *nand_chip = mtd->priv; -+ -+ __raw_readsb(nand_chip->IO_ADDR_R, buf, len); -+} -+ -+static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) -+{ -+ struct nand_chip *nand_chip = mtd->priv; -+ -+ __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2); -+} -+ -+static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) -+{ -+ struct nand_chip *nand_chip = mtd->priv; -+ -+ __raw_writesb(nand_chip->IO_ADDR_W, buf, len); -+} -+ -+static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len) -+{ -+ struct nand_chip *nand_chip = mtd->priv; -+ -+ __raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2); -+} -+ -+/* -+ * write oob for small pages -+ */ -+static int atmel_nand_write_oob_512(struct mtd_info *mtd, -+ struct nand_chip *chip, int page) -+{ -+ int chunk = chip->ecc.bytes + chip->ecc.prepad + chip->ecc.postpad; -+ int eccsize = chip->ecc.size, length = mtd->oobsize; -+ int len, pos, status = 0; -+ const uint8_t *bufpoi = chip->oob_poi; -+ -+ pos = eccsize + chunk; -+ -+ chip->cmdfunc(mtd, NAND_CMD_SEQIN, pos, page); -+ len = min_t(int, length, chunk); -+ chip->write_buf(mtd, bufpoi, len); -+ bufpoi += len; -+ length -= len; -+ if (length > 0) -+ chip->write_buf(mtd, bufpoi, length); -+ -+ chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); -+ status = chip->waitfunc(mtd, chip); -+ -+ return status & NAND_STATUS_FAIL ? -EIO : 0; -+ -+} -+ -+/* -+ * read oob for small pages -+ */ -+static int atmel_nand_read_oob_512(struct mtd_info *mtd, -+ struct nand_chip *chip, int page, int sndcmd) -+{ -+ if (sndcmd) { -+ chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); -+ sndcmd = 0; -+ } -+ chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); -+ return sndcmd; -+} -+ -+/* -+ * Calculate HW ECC -+ * -+ * function called after a write -+ * -+ * mtd: MTD block structure -+ * dat: raw data (unused) -+ * ecc_code: buffer for ECC -+ */ -+static int atmel_nand_calculate(struct mtd_info *mtd, -+ const u_char *dat, unsigned char *ecc_code) -+{ -+ struct nand_chip *nand_chip = mtd->priv; -+ struct atmel_nand_host *host = nand_chip->priv; -+ uint32_t *eccpos = nand_chip->ecc.layout->eccpos; -+ unsigned int ecc_value; -+ -+ /* get the first 2 ECC bytes */ -+ ecc_value = ecc_readl(host->ecc, PR); -+ -+ ecc_code[eccpos[0]] = ecc_value & 0xFF; -+ ecc_code[eccpos[1]] = (ecc_value >> 8) & 0xFF; -+ -+ /* get the last 2 ECC bytes */ -+ ecc_value = ecc_readl(host->ecc, NPR) & ATMEL_ECC_NPARITY; -+ -+ ecc_code[eccpos[2]] = ecc_value & 0xFF; -+ ecc_code[eccpos[3]] = (ecc_value >> 8) & 0xFF; -+ -+ return 0; -+} -+ -+/* -+ * HW ECC read page function -+ * -+ * mtd: mtd info structure -+ * chip: nand chip info structure -+ * buf: buffer to store read data -+ */ -+static int atmel_nand_read_page(struct mtd_info *mtd, -+ struct nand_chip *chip, uint8_t *buf) -+{ -+ int eccsize = chip->ecc.size; -+ int eccbytes = chip->ecc.bytes; -+ uint32_t *eccpos = chip->ecc.layout->eccpos; -+ uint8_t *p = buf; -+ uint8_t *oob = chip->oob_poi; -+ uint8_t *ecc_pos; -+ int stat; -+ -+ /* -+ * Errata: ALE is incorrectly wired up to the ECC controller -+ * on the AP7000, so it will include the address cycles in the -+ * ECC calculation. -+ * -+ * Workaround: Reset the parity registers before reading the -+ * actual data. -+ */ -+ if (cpu_is_at32ap7000()) { -+ struct atmel_nand_host *host = chip->priv; -+ ecc_writel(host->ecc, CR, ATMEL_ECC_RST); -+ } -+ -+ /* read the page */ -+ chip->read_buf(mtd, p, eccsize); -+ -+ /* move to ECC position if needed */ -+ if (eccpos[0] != 0) { -+ /* This only works on large pages -+ * because the ECC controller waits for -+ * NAND_CMD_RNDOUTSTART after the -+ * NAND_CMD_RNDOUT. -+ * anyway, for small pages, the eccpos[0] == 0 -+ */ -+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, -+ mtd->writesize + eccpos[0], -1); -+ } -+ -+ /* the ECC controller needs to read the ECC just after the data */ -+ ecc_pos = oob + eccpos[0]; -+ chip->read_buf(mtd, ecc_pos, eccbytes); -+ -+ /* check if there's an error */ -+ stat = chip->ecc.correct(mtd, p, oob, NULL); -+ -+ if (stat < 0) -+ mtd->ecc_stats.failed++; -+ else -+ mtd->ecc_stats.corrected += stat; -+ -+ /* get back to oob start (end of page) */ -+ chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -1); -+ -+ /* read the oob */ -+ chip->read_buf(mtd, oob, mtd->oobsize); -+ -+ return 0; -+} -+ -+/* -+ * HW ECC Correction -+ * -+ * function called after a read -+ * -+ * mtd: MTD block structure -+ * dat: raw data read from the chip -+ * read_ecc: ECC from the chip (unused) -+ * isnull: unused -+ * -+ * Detect and correct a 1 bit error for a page -+ */ -+static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, -+ u_char *read_ecc, u_char *isnull) -+{ -+ struct nand_chip *nand_chip = mtd->priv; -+ struct atmel_nand_host *host = nand_chip->priv; -+ unsigned int ecc_status; -+ unsigned int ecc_word, ecc_bit; -+ -+ /* get the status from the Status Register */ -+ ecc_status = ecc_readl(host->ecc, SR); -+ -+ /* if there's no error */ -+ if (likely(!(ecc_status & ATMEL_ECC_RECERR))) -+ return 0; -+ -+ /* get error bit offset (4 bits) */ -+ ecc_bit = ecc_readl(host->ecc, PR) & ATMEL_ECC_BITADDR; -+ /* get word address (12 bits) */ -+ ecc_word = ecc_readl(host->ecc, PR) & ATMEL_ECC_WORDADDR; -+ ecc_word >>= 4; -+ -+ /* if there are multiple errors */ -+ if (ecc_status & ATMEL_ECC_MULERR) { -+ /* check if it is a freshly erased block -+ * (filled with 0xff) */ -+ if ((ecc_bit == ATMEL_ECC_BITADDR) -+ && (ecc_word == (ATMEL_ECC_WORDADDR >> 4))) { -+ /* the block has just been erased, return OK */ -+ return 0; -+ } -+ /* it doesn't seems to be a freshly -+ * erased block. -+ * We can't correct so many errors */ -+ dev_dbg(host->dev, "atmel_nand : multiple errors detected." -+ " Unable to correct.\n"); -+ return -EIO; -+ } -+ -+ /* if there's a single bit error : we can correct it */ -+ if (ecc_status & ATMEL_ECC_ECCERR) { -+ /* there's nothing much to do here. -+ * the bit error is on the ECC itself. -+ */ -+ dev_dbg(host->dev, "atmel_nand : one bit error on ECC code." -+ " Nothing to correct\n"); -+ return 0; -+ } -+ -+ dev_dbg(host->dev, "atmel_nand : one bit error on data." -+ " (word offset in the page :" -+ " 0x%x bit offset : 0x%x)\n", -+ ecc_word, ecc_bit); -+ /* correct the error */ -+ if (nand_chip->options & NAND_BUSWIDTH_16) { -+ /* 16 bits words */ -+ ((unsigned short *) dat)[ecc_word] ^= (1 << ecc_bit); -+ } else { -+ /* 8 bits words */ -+ dat[ecc_word] ^= (1 << ecc_bit); -+ } -+ dev_dbg(host->dev, "atmel_nand : error corrected\n"); -+ return 1; -+} -+ -+/* -+ * Enable HW ECC : unused on most chips -+ */ -+static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) -+{ -+ if (cpu_is_at32ap7000()) { -+ struct nand_chip *nand_chip = mtd->priv; -+ struct atmel_nand_host *host = nand_chip->priv; -+ ecc_writel(host->ecc, CR, ATMEL_ECC_RST); -+ } -+} -+ -+#ifdef CONFIG_MTD_PARTITIONS -+static const char *part_probes[] = { "cmdlinepart", NULL }; -+#endif -+ -+/* -+ * Probe for the NAND device. -+ */ -+static int __init atmel_nand_probe(struct platform_device *pdev) -+{ -+ struct atmel_nand_host *host; -+ struct mtd_info *mtd; -+ struct nand_chip *nand_chip; -+ struct resource *regs; -+ struct resource *mem; -+ int res; -+ -+#ifdef CONFIG_MTD_PARTITIONS -+ struct mtd_partition *partitions = NULL; -+ int num_partitions = 0; -+#endif -+ -+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!mem) { -+ printk(KERN_ERR "atmel_nand: can't get I/O resource mem\n"); -+ return -ENXIO; -+ } -+ -+ /* Allocate memory for the device structure (and zero it) */ -+ host = kzalloc(sizeof(struct atmel_nand_host), GFP_KERNEL); -+ if (!host) { -+ printk(KERN_ERR "atmel_nand: failed to allocate device structure.\n"); -+ return -ENOMEM; -+ } -+ -+ host->io_base = ioremap(mem->start, mem->end - mem->start + 1); -+ if (host->io_base == NULL) { -+ printk(KERN_ERR "atmel_nand: ioremap failed\n"); -+ res = -EIO; -+ goto err_nand_ioremap; -+ } -+ -+ mtd = &host->mtd; -+ nand_chip = &host->nand_chip; -+ host->board = pdev->dev.platform_data; -+ host->dev = &pdev->dev; -+ -+ nand_chip->priv = host; /* link the private data structures */ -+ mtd->priv = nand_chip; -+ mtd->owner = THIS_MODULE; -+ -+ /* Set address of NAND IO lines */ -+ nand_chip->IO_ADDR_R = host->io_base; -+ nand_chip->IO_ADDR_W = host->io_base; -+ nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl; -+ -+ if (host->board->rdy_pin) -+ nand_chip->dev_ready = atmel_nand_device_ready; -+ -+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (!regs && hard_ecc) { -+ printk(KERN_ERR "atmel_nand: can't get I/O resource " -+ "regs\nFalling back on software ECC\n"); -+ } -+ -+ nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */ -+ if (no_ecc) -+ nand_chip->ecc.mode = NAND_ECC_NONE; -+ if (hard_ecc && regs) { -+ host->ecc = ioremap(regs->start, regs->end - regs->start + 1); -+ if (host->ecc == NULL) { -+ printk(KERN_ERR "atmel_nand: ioremap failed\n"); -+ res = -EIO; -+ goto err_ecc_ioremap; -+ } -+ nand_chip->ecc.mode = NAND_ECC_HW_SYNDROME; -+ nand_chip->ecc.calculate = atmel_nand_calculate; -+ nand_chip->ecc.correct = atmel_nand_correct; -+ nand_chip->ecc.hwctl = atmel_nand_hwctl; -+ nand_chip->ecc.read_page = atmel_nand_read_page; -+ nand_chip->ecc.bytes = 4; -+ nand_chip->ecc.prepad = 0; -+ nand_chip->ecc.postpad = 0; -+ } -+ -+ nand_chip->chip_delay = 20; /* 20us command delay time */ -+ -+ if (host->board->bus_width_16) { /* 16-bit bus width */ -+ nand_chip->options |= NAND_BUSWIDTH_16; -+ nand_chip->read_buf = atmel_read_buf16; -+ nand_chip->write_buf = atmel_write_buf16; -+ } else { -+ nand_chip->read_buf = atmel_read_buf; -+ nand_chip->write_buf = atmel_write_buf; -+ } -+ -+ platform_set_drvdata(pdev, host); -+ atmel_nand_enable(host); -+ -+ if (host->board->det_pin) { -+ if (gpio_get_value(host->board->det_pin)) { -+ printk("No SmartMedia card inserted.\n"); -+ res = ENXIO; -+ goto err_no_card; -+ } -+ } -+ -+ /* first scan to find the device and get the page size */ -+ if (nand_scan_ident(mtd, 1)) { -+ res = -ENXIO; -+ goto err_scan_ident; -+ } -+ -+ if (nand_chip->ecc.mode == NAND_ECC_HW_SYNDROME) { -+ /* ECC is calculated for the whole page (1 step) */ -+ nand_chip->ecc.size = mtd->writesize; -+ -+ /* set ECC page size and oob layout */ -+ switch (mtd->writesize) { -+ case 512: -+ nand_chip->ecc.layout = &atmel_oobinfo_small; -+ nand_chip->ecc.read_oob = atmel_nand_read_oob_512; -+ nand_chip->ecc.write_oob = atmel_nand_write_oob_512; -+ ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528); -+ break; -+ case 1024: -+ nand_chip->ecc.layout = &atmel_oobinfo_large; -+ ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_1056); -+ break; -+ case 2048: -+ nand_chip->ecc.layout = &atmel_oobinfo_large; -+ ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_2112); -+ break; -+ case 4096: -+ nand_chip->ecc.layout = &atmel_oobinfo_large; -+ ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_4224); -+ break; -+ default: -+ /* page size not handled by HW ECC */ -+ /* switching back to soft ECC */ -+ nand_chip->ecc.mode = NAND_ECC_SOFT; -+ nand_chip->ecc.calculate = NULL; -+ nand_chip->ecc.correct = NULL; -+ nand_chip->ecc.hwctl = NULL; -+ nand_chip->ecc.read_page = NULL; -+ nand_chip->ecc.postpad = 0; -+ nand_chip->ecc.prepad = 0; -+ nand_chip->ecc.bytes = 0; -+ break; -+ } -+ } -+ -+ /* second phase scan */ -+ if (nand_scan_tail(mtd)) { -+ res = -ENXIO; -+ goto err_scan_tail; -+ } -+ -+#ifdef CONFIG_MTD_PARTITIONS -+#ifdef CONFIG_MTD_CMDLINE_PARTS -+ mtd->name = "atmel_nand"; -+ num_partitions = parse_mtd_partitions(mtd, part_probes, -+ &partitions, 0); -+#endif -+ if (num_partitions <= 0 && host->board->partition_info) -+ partitions = host->board->partition_info(mtd->size, -+ &num_partitions); -+ -+ if ((!partitions) || (num_partitions == 0)) { -+ printk(KERN_ERR "atmel_nand: No parititions defined, or unsupported device.\n"); -+ res = ENXIO; -+ goto err_no_partitions; -+ } -+ -+ res = add_mtd_partitions(mtd, partitions, num_partitions); -+#else -+ res = add_mtd_device(mtd); -+#endif -+ -+ if (!res) -+ return res; -+ -+#ifdef CONFIG_MTD_PARTITIONS -+err_no_partitions: -+#endif -+ nand_release(mtd); -+err_scan_tail: -+err_scan_ident: -+err_no_card: -+ atmel_nand_disable(host); -+ platform_set_drvdata(pdev, NULL); -+ if (host->ecc) -+ iounmap(host->ecc); -+err_ecc_ioremap: -+ iounmap(host->io_base); -+err_nand_ioremap: -+ kfree(host); -+ return res; -+} -+ -+/* -+ * Remove a NAND device. -+ */ -+static int __exit atmel_nand_remove(struct platform_device *pdev) -+{ -+ struct atmel_nand_host *host = platform_get_drvdata(pdev); -+ struct mtd_info *mtd = &host->mtd; -+ -+ nand_release(mtd); -+ -+ atmel_nand_disable(host); -+ -+ if (host->ecc) -+ iounmap(host->ecc); -+ iounmap(host->io_base); -+ kfree(host); -+ -+ return 0; -+} -+ -+static struct platform_driver atmel_nand_driver = { -+ .remove = __exit_p(atmel_nand_remove), -+ .driver = { -+ .name = "atmel_nand", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init atmel_nand_init(void) -+{ -+ return platform_driver_probe(&atmel_nand_driver, atmel_nand_probe); -+} -+ -+ -+static void __exit atmel_nand_exit(void) -+{ -+ platform_driver_unregister(&atmel_nand_driver); -+} -+ -+ -+module_init(atmel_nand_init); -+module_exit(atmel_nand_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Rick Bronson"); -+MODULE_DESCRIPTION("NAND/SmartMedia driver for AT91 / AVR32"); -+MODULE_ALIAS("platform:atmel_nand"); ---- /dev/null -+++ b/drivers/mtd/nand/atmel_nand_ecc.h -@@ -0,0 +1,36 @@ -+/* -+ * Error Corrected Code Controller (ECC) - System peripherals regsters. -+ * Based on AT91SAM9260 datasheet revision B. -+ * -+ * 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. -+ */ -+ -+#ifndef ATMEL_NAND_ECC_H -+#define ATMEL_NAND_ECC_H -+ -+#define ATMEL_ECC_CR 0x00 /* Control register */ -+#define ATMEL_ECC_RST (1 << 0) /* Reset parity */ -+ -+#define ATMEL_ECC_MR 0x04 /* Mode register */ -+#define ATMEL_ECC_PAGESIZE (3 << 0) /* Page Size */ -+#define ATMEL_ECC_PAGESIZE_528 (0) -+#define ATMEL_ECC_PAGESIZE_1056 (1) -+#define ATMEL_ECC_PAGESIZE_2112 (2) -+#define ATMEL_ECC_PAGESIZE_4224 (3) -+ -+#define ATMEL_ECC_SR 0x08 /* Status register */ -+#define ATMEL_ECC_RECERR (1 << 0) /* Recoverable Error */ -+#define ATMEL_ECC_ECCERR (1 << 1) /* ECC Single Bit Error */ -+#define ATMEL_ECC_MULERR (1 << 2) /* Multiple Errors */ -+ -+#define ATMEL_ECC_PR 0x0c /* Parity register */ -+#define ATMEL_ECC_BITADDR (0xf << 0) /* Bit Error Address */ -+#define ATMEL_ECC_WORDADDR (0xfff << 4) /* Word Error Address */ -+ -+#define ATMEL_ECC_NPR 0x10 /* NParity register */ -+#define ATMEL_ECC_NPARITY (0xffff << 0) /* NParity */ -+ -+#endif ---- a/drivers/mtd/nand/bf5xx_nand.c -+++ b/drivers/mtd/nand/bf5xx_nand.c -@@ -803,3 +803,4 @@ module_exit(bf5xx_nand_exit); - MODULE_LICENSE("GPL"); - MODULE_AUTHOR(DRV_AUTHOR); - MODULE_DESCRIPTION(DRV_DESC); -+MODULE_ALIAS("platform:" DRV_NAME); ---- a/drivers/mtd/nand/ndfc.c -+++ b/drivers/mtd/nand/ndfc.c -@@ -317,3 +317,5 @@ module_exit(ndfc_nand_exit); - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>"); - MODULE_DESCRIPTION("Platform driver for NDFC"); -+MODULE_ALIAS("platform:ndfc-chip"); -+MODULE_ALIAS("platform:ndfc-nand"); ---- a/drivers/mtd/nand/orion_nand.c -+++ b/drivers/mtd/nand/orion_nand.c -@@ -169,3 +169,4 @@ module_exit(orion_nand_exit); - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Tzachi Perelstein"); - MODULE_DESCRIPTION("NAND glue for Orion platforms"); -+MODULE_ALIAS("platform:orion_nand"); ---- a/drivers/mtd/nand/plat_nand.c -+++ b/drivers/mtd/nand/plat_nand.c -@@ -161,3 +161,4 @@ module_exit(plat_nand_exit); - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Vitaly Wool"); - MODULE_DESCRIPTION("Simple generic NAND driver"); -+MODULE_ALIAS("platform:gen_nand"); ---- a/drivers/mtd/nand/s3c2410.c -+++ b/drivers/mtd/nand/s3c2410.c -@@ -927,3 +927,6 @@ module_exit(s3c2410_nand_exit); - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); - MODULE_DESCRIPTION("S3C24XX MTD NAND driver"); -+MODULE_ALIAS("platform:s3c2410-nand"); -+MODULE_ALIAS("platform:s3c2412-nand"); -+MODULE_ALIAS("platform:s3c2440-nand"); ---- a/drivers/net/macb.c -+++ b/drivers/net/macb.c -@@ -1277,8 +1277,45 @@ static int __exit macb_remove(struct pla - return 0; - } - -+#ifdef CONFIG_PM -+static int macb_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ struct net_device *netdev = platform_get_drvdata(pdev); -+ struct macb *bp = netdev_priv(netdev); -+ -+ netif_device_detach(netdev); -+ -+#ifndef CONFIG_ARCH_AT91 -+ clk_disable(bp->hclk); -+#endif -+ clk_disable(bp->pclk); -+ -+ return 0; -+} -+ -+static int macb_resume(struct platform_device *pdev) -+{ -+ struct net_device *netdev = platform_get_drvdata(pdev); -+ struct macb *bp = netdev_priv(netdev); -+ -+ clk_enable(bp->pclk); -+#ifndef CONFIG_ARCH_AT91 -+ clk_enable(bp->hclk); -+#endif -+ -+ netif_device_attach(netdev); -+ -+ return 0; -+} -+#else -+#define macb_suspend NULL -+#define macb_resume NULL -+#endif -+ - static struct platform_driver macb_driver = { - .remove = __exit_p(macb_remove), -+ .suspend = macb_suspend, -+ .resume = macb_resume, - .driver = { - .name = "macb", - }, ---- a/drivers/parport/Kconfig -+++ b/drivers/parport/Kconfig -@@ -36,7 +36,7 @@ if PARPORT - config PARPORT_PC - tristate "PC-style hardware" - depends on (!SPARC64 || PCI) && !SPARC32 && !M32R && !FRV && \ -- (!M68K || ISA) && !MN10300 -+ (!M68K || ISA) && !MN10300 && !AVR32 - ---help--- - You should say Y here if you have a PC-style parallel port. All - IBM PC compatible computers and some Alphas have PC-style ---- a/drivers/pcmcia/Kconfig -+++ b/drivers/pcmcia/Kconfig -@@ -277,6 +277,13 @@ config ELECTRA_CF - Say Y here to support the CompactFlash controller on the - PA Semi Electra eval board. - -+config AT32_CF -+ tristate "AT32AP CompactFlash Controller" -+ depends on PCMCIA && AVR32 && PLATFORM_AT32AP -+ help -+ Say Y here to support the CompactFlash controller on AT32 chips. -+ Or choose M to compile the driver as a module named "at32_cf". -+ - config PCCARD_NONSTATIC - tristate - ---- a/drivers/pcmcia/Makefile -+++ b/drivers/pcmcia/Makefile -@@ -38,6 +38,7 @@ obj-$(CONFIG_PCMCIA_VRC4173) += vrc417 - obj-$(CONFIG_OMAP_CF) += omap_cf.o - obj-$(CONFIG_AT91_CF) += at91_cf.o - obj-$(CONFIG_ELECTRA_CF) += electra_cf.o -+obj-$(CONFIG_AT32_CF) += at32_cf.o - - sa11xx_core-y += soc_common.o sa11xx_base.o - pxa2xx_core-y += soc_common.o pxa2xx_base.o ---- /dev/null -+++ b/drivers/pcmcia/at32_cf.c -@@ -0,0 +1,533 @@ -+/* -+ * Driver for AVR32 Static Memory Controller: CompactFlash support -+ * -+ * Copyright (C) 2006 Atmel Norway -+ * -+ * 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. -+ * -+ * The full GNU General Public License is included in this -+ * distribution in the file called COPYING. -+ */ -+#include <linux/module.h> -+#include <linux/kernel.h> -+#include <linux/platform_device.h> -+#include <linux/init.h> -+#include <linux/device.h> -+#include <linux/delay.h> -+#include <linux/interrupt.h> -+#include <linux/err.h> -+#include <linux/clk.h> -+#include <linux/dma-mapping.h> -+ -+#include <pcmcia/ss.h> -+ -+#include <asm/gpio.h> -+#include <asm/io.h> -+#include <asm/arch/board.h> -+ -+#include <asm/arch/smc.h> -+ -+struct at32_cf_socket { -+ struct pcmcia_socket socket; -+ int detect_pin; -+ int reset_pin; -+ int vcc_pin; -+ int ready_pin; -+ struct resource res_attr; -+ struct resource res_mem; -+ struct resource res_io; -+ struct smc_config smc; -+ unsigned int irq; -+ unsigned int cf_cs; -+ socket_state_t state; -+ unsigned present:1; -+}; -+#define to_at32_cf(sock) container_of(sock, struct at32_cf_socket, socket) -+ -+/* -+ * We have the following memory layout relative to the base address: -+ * -+ * Alt IDE Mode: 00e0 0000 -> 00ff ffff -+ * True IDE Mode: 00c0 0000 -> 00df ffff -+ * I/O memory: 0080 0000 -> 00bf ffff -+ * Common memory: 0040 0000 -> 007f ffff -+ * Attribute memory: 0000 0000 -> 003f ffff -+ */ -+#define CF_ATTR_OFFSET 0x00000000 -+#define CF_MEM_OFFSET 0x00400000 -+#define CF_IO_OFFSET 0x00800000 -+#define CF_RES_SIZE 4096 -+ -+#ifdef DEBUG -+ -+static int pc_debug; -+module_param(pc_debug, int, 0644); -+ -+static void at32_cf_debug(struct at32_cf_socket *cf, const char *func, -+ int level, const char *fmt, ...) -+{ -+ va_list args; -+ -+ if (pc_debug > level) { -+ printk(KERN_DEBUG "at32_cf/%u: %s: ", cf->cf_cs, func); -+ va_start(args, fmt); -+ vprintk(fmt, args); -+ va_end(args); -+ } -+} -+ -+#define debug(cf, lvl, fmt, arg...) \ -+ at32_cf_debug(cf, __func__, lvl, fmt, ##arg) -+ -+#else -+#define debug(cf, lvl, fmt, arg...) do { } while (0) -+#endif -+ -+static inline int at32_cf_present(struct at32_cf_socket *cf) -+{ -+ int present = 1; -+ -+ /* If we don't have a detect pin, assume the card is present */ -+ if (cf->detect_pin >= 0) -+ present = !gpio_get_value(cf->detect_pin); -+ -+ return present; -+} -+ -+static irqreturn_t at32_cf_irq(int irq, void *dev_id) -+{ -+ struct at32_cf_socket *cf = dev_id; -+ unsigned int present; -+ -+ present = at32_cf_present(cf); -+ if (present != cf->present) { -+ cf->present = present; -+ debug(cf, 3, "card %s\n", present ? "present" : "gone"); -+ pcmcia_parse_events(&cf->socket, SS_DETECT); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static int at32_cf_get_status(struct pcmcia_socket *sock, u_int *value) -+{ -+ struct at32_cf_socket *cf; -+ u_int status = 0; -+ -+ cf = container_of(sock, struct at32_cf_socket, socket); -+ -+ if (at32_cf_present(cf)) { -+ /* NOTE: gpio on AP7xxx is 3.3V */ -+ status = SS_DETECT | SS_3VCARD; -+ if (cf->ready_pin < 0 || gpio_get_value(cf->ready_pin)) -+ status |= SS_READY; -+ if (cf->vcc_pin < 0 || gpio_get_value(cf->vcc_pin)) -+ status |= SS_POWERON; -+ } -+ -+ *value = status; -+ return 0; -+} -+ -+static int at32_cf_set_socket(struct pcmcia_socket *sock, socket_state_t *state) -+{ -+ struct at32_cf_socket *cf = container_of(sock, struct at32_cf_socket, socket); -+ -+ debug(cf, 2, "mask: %s%s%s%s%s%sflags: %s%s%s%s%s%sVcc %d Vpp %d irq %d\n", -+ (state->csc_mask==0)?"<NONE> ":"", -+ (state->csc_mask&SS_DETECT)?"DETECT ":"", -+ (state->csc_mask&SS_READY)?"READY ":"", -+ (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"", -+ (state->csc_mask&SS_BATWARN)?"BATWARN ":"", -+ (state->csc_mask&SS_STSCHG)?"STSCHG ":"", -+ (state->flags==0)?"<NONE> ":"", -+ (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"", -+ (state->flags&SS_IOCARD)?"IOCARD ":"", -+ (state->flags&SS_RESET)?"RESET ":"", -+ (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"", -+ (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"", -+ state->Vcc, state->Vpp, state->io_irq); -+ -+ /* -+ * TODO: Allow boards to override this in case they have level -+ * converters. -+ */ -+ switch (state->Vcc) { -+ case 0: -+ if (cf->vcc_pin >= 0) -+ gpio_set_value(cf->vcc_pin, 0); -+ break; -+ case 33: -+ if (cf->vcc_pin >= 0) -+ gpio_set_value(cf->vcc_pin, 1); -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ if (cf->reset_pin >= 0) -+ gpio_set_value(cf->reset_pin, state->flags & SS_RESET); -+ -+ cf->state = *state; -+ -+ return 0; -+} -+ -+static int at32_cf_socket_init(struct pcmcia_socket *sock) -+{ -+ debug(to_at32_cf(sock), 2, "called\n"); -+ -+ return 0; -+} -+ -+static int at32_cf_suspend(struct pcmcia_socket *sock) -+{ -+ debug(to_at32_cf(sock), 2, "called\n"); -+ -+ at32_cf_set_socket(sock, &dead_socket); -+ -+ return 0; -+} -+ -+static int at32_cf_set_io_map(struct pcmcia_socket *sock, -+ struct pccard_io_map *map) -+{ -+ struct at32_cf_socket *cf = container_of(sock, struct at32_cf_socket, socket); -+ int retval; -+ -+ debug(cf, 2, "map %u speed %u start 0x%08x stop 0x%08x\n", -+ map->map, map->speed, map->start, map->stop); -+ debug(cf, 2, "flags: %s%s%s%s%s%s%s%s\n", -+ (map->flags == 0) ? "<NONE>":"", -+ (map->flags & MAP_ACTIVE) ? "ACTIVE " : "", -+ (map->flags & MAP_16BIT) ? "16BIT " : "", -+ (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "", -+ (map->flags & MAP_0WS) ? "0WS " : "", -+ (map->flags & MAP_WRPROT) ? "WRPROT " : "", -+ (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "", -+ (map->flags & MAP_PREFETCH) ? "PREFETCH " : ""); -+ -+ map->flags &= MAP_ACTIVE | MAP_16BIT | MAP_USE_WAIT; -+ -+ if (map->flags & MAP_16BIT) -+ cf->smc.bus_width = 2; -+ else -+ cf->smc.bus_width = 1; -+ -+ if (map->flags & MAP_USE_WAIT) -+ cf->smc.nwait_mode = 3; -+ else -+ cf->smc.nwait_mode = 0; -+ -+ retval = smc_set_configuration(cf->cf_cs, &cf->smc); -+ if (retval) { -+ printk(KERN_ERR "at32_cf: could not set up SMC for I/O\n"); -+ return retval; -+ } -+ -+ map->start = cf->socket.io_offset; -+ map->stop = map->start + CF_RES_SIZE - 1; -+ -+ return 0; -+} -+ -+static int -+at32_cf_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map) -+{ -+ struct at32_cf_socket *cf; -+ struct resource *res; -+ int retval; -+ -+ cf = container_of(sock, struct at32_cf_socket, socket); -+ -+ debug(cf, 2, "map %u speed %u card_start %08x\n", -+ map->map, map->speed, map->card_start); -+ debug(cf, 2, "flags: %s%s%s%s%s%s%s%s\n", -+ (map->flags==0)?"<NONE>":"", -+ (map->flags&MAP_ACTIVE)?"ACTIVE ":"", -+ (map->flags&MAP_16BIT)?"16BIT ":"", -+ (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"", -+ (map->flags&MAP_0WS)?"0WS ":"", -+ (map->flags&MAP_WRPROT)?"WRPROT ":"", -+ (map->flags&MAP_ATTRIB)?"ATTRIB ":"", -+ (map->flags&MAP_USE_WAIT)?"USE_WAIT ":""); -+ -+ if (map->card_start) -+ return -EINVAL; -+ -+ map->flags &= MAP_ACTIVE | MAP_ATTRIB | MAP_16BIT | MAP_USE_WAIT; -+ -+ if (map->flags & MAP_ATTRIB) { -+ res = &cf->res_attr; -+ -+ /* Linksys WCF12 seems to use WAIT when reading CIS */ -+ map->flags |= MAP_USE_WAIT; -+ } else { -+ res = &cf->res_mem; -+ } -+ -+ if (map->flags & MAP_USE_WAIT) -+ cf->smc.nwait_mode = 3; -+ else -+ cf->smc.nwait_mode = 0; -+ -+ retval = smc_set_configuration(cf->cf_cs, &cf->smc); -+ if (retval) { -+ printk(KERN_ERR "at32_cf: could not set up SMC for mem\n"); -+ return retval; -+ } -+ -+ map->static_start = res->start; -+ -+ return 0; -+} -+ -+static struct pccard_operations at32_cf_ops = { -+ .init = at32_cf_socket_init, -+ .suspend = at32_cf_suspend, -+ .get_status = at32_cf_get_status, -+ .set_socket = at32_cf_set_socket, -+ .set_io_map = at32_cf_set_io_map, -+ .set_mem_map = at32_cf_set_mem_map, -+}; -+ -+static int __init request_pin(struct platform_device *pdev, -+ unsigned int pin, const char *name) -+{ -+ if (gpio_request(pin, name)) { -+ dev_warn(&pdev->dev, "failed to request %s pin\n", name); -+ return -1; -+ } -+ -+ return pin; -+} -+ -+static struct smc_timing at32_cf_timing __initdata = { -+ .ncs_read_setup = 30, -+ .nrd_setup = 100, -+ .ncs_write_setup = 30, -+ .nwe_setup = 100, -+ -+ .ncs_read_pulse = 360, -+ .nrd_pulse = 290, -+ .ncs_write_pulse = 360, -+ .nwe_pulse = 290, -+ -+ .read_cycle = 420, -+ .write_cycle = 420, -+}; -+ -+static int __init at32_cf_probe(struct platform_device *pdev) -+{ -+ struct at32_cf_socket *cf; -+ struct cf_platform_data *board = pdev->dev.platform_data; -+ struct resource *res_skt; -+ int irq; -+ int ret; -+ -+ dev_dbg(&pdev->dev, "probe"); -+ -+ if (!board) -+ return -ENXIO; -+ -+ res_skt = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!res_skt) -+ return -ENXIO; -+ -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) -+ return irq; -+ -+ cf = kzalloc(sizeof(struct at32_cf_socket), GFP_KERNEL); -+ if (!cf) -+ return -ENOMEM; -+ -+ cf->detect_pin = -1; -+ cf->reset_pin = -1; -+ cf->vcc_pin = -1; -+ cf->ready_pin = -1; -+ cf->cf_cs = board->cs; -+ -+ if (board->detect_pin != GPIO_PIN_NONE) -+ cf->detect_pin = request_pin(pdev, board->detect_pin, -+ "cf_detect"); -+ if (board->reset_pin != GPIO_PIN_NONE) -+ cf->reset_pin = request_pin(pdev, board->reset_pin, -+ "cf_reset"); -+ if (board->vcc_pin != GPIO_PIN_NONE) -+ cf->vcc_pin = request_pin(pdev, board->vcc_pin, -+ "cf_vcc"); -+ if (board->ready_pin != GPIO_PIN_NONE) -+ /* READY is also used for irq through EIM */ -+ cf->ready_pin = board->ready_pin; -+ -+ debug(cf, 2, "pins: detect=%d reset=%d vcc=%d\n", -+ cf->detect_pin, cf->reset_pin, cf->vcc_pin); -+ -+ cf->socket.pci_irq = irq; -+ cf->socket.ops = &at32_cf_ops; -+ cf->socket.resource_ops = &pccard_static_ops; -+ cf->socket.dev.parent = &pdev->dev; -+ cf->socket.owner = THIS_MODULE; -+ cf->socket.features = -+ SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP | SS_CAP_PCCARD; -+ cf->socket.map_size = CF_RES_SIZE; -+ -+ cf->res_attr.start = res_skt->start + CF_ATTR_OFFSET; -+ cf->res_attr.end = cf->res_attr.start + CF_RES_SIZE - 1; -+ cf->res_attr.name = "attribute"; -+ cf->res_attr.flags = IORESOURCE_MEM; -+ ret = request_resource(res_skt, &cf->res_attr); -+ if (ret) -+ goto err_request_res_attr; -+ -+ cf->res_mem.start = res_skt->start + CF_MEM_OFFSET; -+ cf->res_mem.end = cf->res_mem.start + CF_RES_SIZE - 1; -+ cf->res_mem.name = "memory"; -+ cf->res_mem.flags = IORESOURCE_MEM; -+ ret = request_resource(res_skt, &cf->res_mem); -+ if (ret) -+ goto err_request_res_mem; -+ -+ cf->res_io.start = res_skt->start + CF_IO_OFFSET; -+ cf->res_io.end = cf->res_io.start + CF_RES_SIZE - 1; -+ cf->res_io.name = "io"; -+ cf->res_io.flags = IORESOURCE_MEM; -+ ret = request_resource(res_skt, &cf->res_io); -+ if (ret) -+ goto err_request_res_io; -+ -+ cf->socket.io_offset = cf->res_io.start; -+ -+ if (cf->detect_pin >= 0) { -+ ret = request_irq(gpio_to_irq(cf->detect_pin), at32_cf_irq, -+ IRQF_SHARED, "cf_detect", cf); -+ if (ret) { -+ debug(cf, 1, -+ "failed to request cf_detect interrupt\n"); -+ goto err_detect_irq; -+ } -+ } -+ -+ cf->present = at32_cf_present(cf); -+ -+ /* Setup SMC timings */ -+ smc_set_timing(&cf->smc, &at32_cf_timing); -+ -+ cf->smc.bus_width = 2; -+ cf->smc.nrd_controlled = 1; -+ cf->smc.nwe_controlled = 1; -+ cf->smc.nwait_mode = 0; -+ cf->smc.byte_write = 0; -+ cf->smc.tdf_cycles = 8; -+ cf->smc.tdf_mode = 0; -+ -+ ret = smc_set_configuration(cf->cf_cs, &cf->smc); -+ if (ret) { -+ debug(cf, 1, "failed to configure SMC\n", ret); -+ goto err_smc; -+ } -+ -+ ret = pcmcia_register_socket(&cf->socket); -+ if (ret) { -+ debug(cf, 1, "failed to register socket: %d\n", ret); -+ goto err_register_socket; -+ } -+ -+ if (cf->reset_pin >= 0) -+ gpio_direction_output(cf->reset_pin, 0); -+ -+ platform_set_drvdata(pdev, cf); -+ -+ dev_info(&pdev->dev, "Atmel SMC CF interface at 0x%08lx\n", -+ (unsigned long)res_skt->start); -+ -+ return 0; -+ -+err_register_socket: -+err_smc: -+ if (cf->detect_pin >= 0) -+ free_irq(gpio_to_irq(cf->detect_pin), cf); -+err_detect_irq: -+ release_resource(&cf->res_io); -+err_request_res_io: -+ release_resource(&cf->res_mem); -+err_request_res_mem: -+ release_resource(&cf->res_attr); -+err_request_res_attr: -+ if (cf->vcc_pin >= 0) -+ gpio_free(cf->vcc_pin); -+ if (cf->reset_pin >= 0) -+ gpio_free(cf->reset_pin); -+ if (cf->detect_pin >= 0) -+ gpio_free(cf->detect_pin); -+ kfree(cf); -+ -+ return ret; -+} -+ -+static int __exit at32_cf_remove(struct platform_device *pdev) -+{ -+ struct at32_cf_socket *cf = platform_get_drvdata(pdev); -+ -+ pcmcia_unregister_socket(&cf->socket); -+ if (cf->detect_pin >= 0) { -+ free_irq(gpio_to_irq(cf->detect_pin), cf); -+ gpio_free(cf->detect_pin); -+ } -+ if (cf->vcc_pin >= 0) -+ gpio_free(cf->vcc_pin); -+ if (cf->reset_pin >= 0) -+ gpio_free(cf->reset_pin); -+ -+ release_resource(&cf->res_io); -+ release_resource(&cf->res_mem); -+ release_resource(&cf->res_attr); -+ kfree(cf); -+ platform_set_drvdata(pdev, NULL); -+ -+ return 0; -+} -+ -+static struct platform_driver at32_cf_driver = { -+ .remove = __exit_p(at32_cf_remove), -+ .driver = { -+ .name = "at32_cf", -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+static int __init at32_cf_init(void) -+{ -+ int ret; -+ -+ ret = platform_driver_probe(&at32_cf_driver, at32_cf_probe); -+ if (ret) -+ printk(KERN_ERR "at32_cf: probe failed: %d\n", ret); -+ return ret; -+} -+ -+static void __exit at32_cf_exit(void) -+{ -+ platform_driver_unregister(&at32_cf_driver); -+} -+ -+module_init(at32_cf_init); -+module_exit(at32_cf_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Driver for SMC PCMCIA interface"); -+MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>"); ---- a/drivers/rtc/rtc-at32ap700x.c -+++ b/drivers/rtc/rtc-at32ap700x.c -@@ -262,6 +262,7 @@ static int __init at32_rtc_probe(struct - } - - platform_set_drvdata(pdev, rtc); -+ device_init_wakeup(&pdev->dev, 1); - - dev_info(&pdev->dev, "Atmel RTC for AT32AP700x at %08lx irq %ld\n", - (unsigned long)rtc->regs, rtc->irq); -@@ -281,6 +282,8 @@ static int __exit at32_rtc_remove(struct - { - struct rtc_at32ap700x *rtc = platform_get_drvdata(pdev); - -+ device_init_wakeup(&pdev->dev, 0); -+ - free_irq(rtc->irq, rtc); - iounmap(rtc->regs); - rtc_device_unregister(rtc->rtc); ---- a/drivers/serial/atmel_serial.c -+++ b/drivers/serial/atmel_serial.c -@@ -957,6 +957,20 @@ static void atmel_shutdown(struct uart_p - } - - /* -+ * Flush any TX data submitted for DMA. Called when the TX circular -+ * buffer is reset. -+ */ -+static void atmel_flush_buffer(struct uart_port *port) -+{ -+ struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); -+ -+ if (atmel_use_dma_tx(port)) { -+ UART_PUT_TCR(port, 0); -+ atmel_port->pdc_tx.ofs = 0; -+ } -+} -+ -+/* - * Power / Clock management. - */ - static void atmel_serial_pm(struct uart_port *port, unsigned int state, -@@ -1190,6 +1204,7 @@ static struct uart_ops atmel_pops = { - .break_ctl = atmel_break_ctl, - .startup = atmel_startup, - .shutdown = atmel_shutdown, -+ .flush_buffer = atmel_flush_buffer, - .set_termios = atmel_set_termios, - .type = atmel_type, - .release_port = atmel_release_port, -@@ -1440,6 +1455,15 @@ static struct uart_driver atmel_uart = { - }; - - #ifdef CONFIG_PM -+static bool atmel_serial_clk_will_stop(void) -+{ -+#ifdef CONFIG_ARCH_AT91 -+ return at91_suspend_entering_slow_clock(); -+#else -+ return false; -+#endif -+} -+ - static int atmel_serial_suspend(struct platform_device *pdev, - pm_message_t state) - { -@@ -1447,7 +1471,7 @@ static int atmel_serial_suspend(struct p - struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); - - if (device_may_wakeup(&pdev->dev) -- && !at91_suspend_entering_slow_clock()) -+ && !atmel_serial_clk_will_stop()) - enable_irq_wake(port->irq); - else { - uart_suspend_port(&atmel_uart, port); ---- a/drivers/serial/serial_core.c -+++ b/drivers/serial/serial_core.c -@@ -552,6 +552,8 @@ static void uart_flush_buffer(struct tty - - spin_lock_irqsave(&port->lock, flags); - uart_circ_clear(&state->info->xmit); -+ if (port->ops->flush_buffer) -+ port->ops->flush_buffer(port); - spin_unlock_irqrestore(&port->lock, flags); - tty_wakeup(tty); - } ---- a/drivers/spi/atmel_spi.c -+++ b/drivers/spi/atmel_spi.c -@@ -51,9 +51,7 @@ struct atmel_spi { - 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; -+ unsigned long remaining_bytes; - - void *buffer; - dma_addr_t buffer_dma; -@@ -133,48 +131,6 @@ static void cs_deactivate(struct atmel_s - gpio_set_value(gpio, !active); - } - --static inline int atmel_spi_xfer_is_last(struct spi_message *msg, -- struct spi_transfer *xfer) --{ -- return msg->transfers.prev == &xfer->transfer_list; --} -- --static inline int atmel_spi_xfer_can_be_chained(struct spi_transfer *xfer) --{ -- return xfer->delay_usecs == 0 && !xfer->cs_change; --} -- --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) --{ -- struct atmel_spi *as = spi_master_get_devdata(master); -- u32 len = *plen; -- -- /* 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); -- } -- -- *plen = len; --} -- - /* - * Submit next transfer for DMA. - * lock is held, spi irq is blocked -@@ -184,78 +140,53 @@ static void atmel_spi_next_xfer(struct s - { - struct atmel_spi *as = spi_master_get_devdata(master); - struct spi_transfer *xfer; -- u32 len, remaining, total; -+ u32 len; - 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) { -- len = xfer->len; -- atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); -- remaining = xfer->len - len; -- -- spi_writel(as, RPR, rx_dma); -- spi_writel(as, TPR, tx_dma); -- -- if (msg->spi->bits_per_word > 8) -- len >>= 1; -- spi_writel(as, RCR, len); -- spi_writel(as, TCR, len); -- -- 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; -+ xfer = as->current_transfer; -+ if (!xfer || as->remaining_bytes == 0) { -+ if (xfer) -+ xfer = list_entry(xfer->transfer_list.next, -+ struct spi_transfer, transfer_list); -+ else -+ xfer = list_entry(msg->transfers.next, -+ struct spi_transfer, transfer_list); -+ as->remaining_bytes = xfer->len; -+ as->current_transfer = xfer; - } - -- as->current_transfer = xfer; -- as->current_remaining_bytes = remaining; -- -- 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; -+ len = as->remaining_bytes; - -- as->next_transfer = xfer; -+ tx_dma = xfer->tx_dma + xfer->len - len; -+ rx_dma = xfer->rx_dma + xfer->len - len; - -- if (xfer) { -- total = len; -- atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); -- as->next_remaining_bytes = total - len; -- -- spi_writel(as, RNPR, rx_dma); -- spi_writel(as, TNPR, tx_dma); -- -- if (msg->spi->bits_per_word > 8) -- len >>= 1; -- spi_writel(as, RNCR, len); -- spi_writel(as, TNCR, len); -- -- 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); -- } else { -- spi_writel(as, RNCR, 0); -- spi_writel(as, TNCR, 0); -+ /* use scratch buffer only when rx or tx data is unspecified */ -+ if (!xfer->rx_buf) { -+ rx_dma = as->buffer_dma; -+ if (len > BUFFER_SIZE) -+ len = BUFFER_SIZE; - } -+ if (!xfer->tx_buf) { -+ 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); -+ } -+ -+ spi_writel(as, RPR, rx_dma); -+ spi_writel(as, TPR, tx_dma); - -- /* REVISIT: We're waiting for ENDRX before we start the next -+ as->remaining_bytes -= len; -+ if (msg->spi->bits_per_word > 8) -+ len >>= 1; -+ -+ /* REVISIT: when xfer->delay_usecs == 0, the PDC "next transfer" -+ * mechanism might help avoid the IRQ latency between transfers -+ * (and improve the nCS0 errata handling on at91rm9200 chips) -+ * -+ * We're also 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 -@@ -265,7 +196,17 @@ static void atmel_spi_next_xfer(struct s - * - * It should be doable, though. Just not now... - */ -+ spi_writel(as, TNCR, 0); -+ spi_writel(as, RNCR, 0); - spi_writel(as, IER, SPI_BIT(ENDRX) | SPI_BIT(OVRES)); -+ -+ dev_dbg(&msg->spi->dev, -+ " start xfer %p: len %u tx %p/%08x rx %p/%08x imr %03x\n", -+ xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, -+ xfer->rx_buf, xfer->rx_dma, spi_readl(as, IMR)); -+ -+ spi_writel(as, RCR, len); -+ spi_writel(as, TCR, len); - spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN)); - } - -@@ -363,7 +304,6 @@ atmel_spi_msg_done(struct spi_master *ma - spin_lock(&as->lock); - - as->current_transfer = NULL; -- as->next_transfer = NULL; - - /* continue if needed */ - if (list_empty(&as->queue) || as->stopping) -@@ -447,7 +387,7 @@ atmel_spi_interrupt(int irq, void *dev_i - - spi_writel(as, IDR, pending); - -- if (as->current_remaining_bytes == 0) { -+ if (as->remaining_bytes == 0) { - msg->actual_length += xfer->len; - - if (!msg->is_dma_mapped) -@@ -457,7 +397,7 @@ atmel_spi_interrupt(int irq, void *dev_i - if (xfer->delay_usecs) - udelay(xfer->delay_usecs); - -- if (atmel_spi_xfer_is_last(msg, xfer)) { -+ if (msg->transfers.prev == &xfer->transfer_list) { - /* report completed message */ - atmel_spi_msg_done(master, as, msg, 0, - xfer->cs_change); ---- a/drivers/usb/gadget/Kconfig -+++ b/drivers/usb/gadget/Kconfig -@@ -118,10 +118,10 @@ config USB_AMD5536UDC - config USB_GADGET_ATMEL_USBA - boolean "Atmel USBA" - select USB_GADGET_DUALSPEED -- depends on AVR32 -+ depends on AVR32 || ARCH_AT91CAP9 - help - USBA is the integrated high-speed USB Device controller on -- the AT32AP700x processors from Atmel. -+ the AT32AP700x and AT91CAP9 processors from Atmel. - - config USB_ATMEL_USBA - tristate ---- a/drivers/usb/gadget/atmel_usba_udc.c -+++ b/drivers/usb/gadget/atmel_usba_udc.c -@@ -18,6 +18,7 @@ - #include <linux/platform_device.h> - #include <linux/usb/ch9.h> - #include <linux/usb/gadget.h> -+#include <linux/usb/atmel_usba_udc.h> - #include <linux/delay.h> - - #include <asm/gpio.h> -@@ -27,6 +28,7 @@ - - - static struct usba_udc the_udc; -+static struct usba_ep *usba_ep; - - #ifdef CONFIG_USB_GADGET_DEBUG_FS - #include <linux/debugfs.h> -@@ -324,53 +326,28 @@ static int vbus_is_present(struct usba_u - return 1; - } - --static void copy_to_fifo(void __iomem *fifo, const void *buf, int len) --{ -- unsigned long tmp; -+#if defined(CONFIG_AVR32) - -- DBG(DBG_FIFO, "copy to FIFO (len %d):\n", len); -- for (; len > 0; len -= 4, buf += 4, fifo += 4) { -- tmp = *(unsigned long *)buf; -- if (len >= 4) { -- DBG(DBG_FIFO, " -> %08lx\n", tmp); -- __raw_writel(tmp, fifo); -- } else { -- do { -- DBG(DBG_FIFO, " -> %02lx\n", tmp >> 24); -- __raw_writeb(tmp >> 24, fifo); -- fifo++; -- tmp <<= 8; -- } while (--len); -- break; -- } -- } -+static void toggle_bias(int is_on) -+{ - } - --static void copy_from_fifo(void *buf, void __iomem *fifo, int len) -+#elif defined(CONFIG_ARCH_AT91) -+ -+#include <asm/arch/at91_pmc.h> -+ -+static void toggle_bias(int is_on) - { -- union { -- unsigned long *w; -- unsigned char *b; -- } p; -- unsigned long tmp; -- -- DBG(DBG_FIFO, "copy from FIFO (len %d):\n", len); -- for (p.w = buf; len > 0; len -= 4, p.w++, fifo += 4) { -- if (len >= 4) { -- tmp = __raw_readl(fifo); -- *p.w = tmp; -- DBG(DBG_FIFO, " -> %08lx\n", tmp); -- } else { -- do { -- tmp = __raw_readb(fifo); -- *p.b = tmp; -- DBG(DBG_FIFO, " -> %02lx\n", tmp); -- fifo++, p.b++; -- } while (--len); -- } -- } -+ unsigned int uckr = at91_sys_read(AT91_CKGR_UCKR); -+ -+ if (is_on) -+ at91_sys_write(AT91_CKGR_UCKR, uckr | AT91_PMC_BIASEN); -+ else -+ at91_sys_write(AT91_CKGR_UCKR, uckr & ~(AT91_PMC_BIASEN)); - } - -+#endif /* CONFIG_ARCH_AT91 */ -+ - static void next_fifo_transaction(struct usba_ep *ep, struct usba_request *req) - { - unsigned int transaction_len; -@@ -387,7 +364,7 @@ static void next_fifo_transaction(struct - ep->ep.name, req, transaction_len, - req->last_transaction ? ", done" : ""); - -- copy_to_fifo(ep->fifo, req->req.buf + req->req.actual, transaction_len); -+ memcpy_toio(ep->fifo, req->req.buf + req->req.actual, transaction_len); - usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY); - req->req.actual += transaction_len; - } -@@ -476,7 +453,7 @@ static void receive_data(struct usba_ep - bytecount = req->req.length - req->req.actual; - } - -- copy_from_fifo(req->req.buf + req->req.actual, -+ memcpy_fromio(req->req.buf + req->req.actual, - ep->fifo, bytecount); - req->req.actual += bytecount; - -@@ -1029,33 +1006,6 @@ static const struct usb_gadget_ops usba_ - .set_selfpowered = usba_udc_set_selfpowered, - }; - --#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ --{ \ -- .ep = { \ -- .ops = &usba_ep_ops, \ -- .name = nam, \ -- .maxpacket = maxpkt, \ -- }, \ -- .udc = &the_udc, \ -- .queue = LIST_HEAD_INIT(usba_ep[idx].queue), \ -- .fifo_size = maxpkt, \ -- .nr_banks = maxbk, \ -- .index = idx, \ -- .can_dma = dma, \ -- .can_isoc = isoc, \ --} -- --static struct usba_ep usba_ep[] = { -- EP("ep0", 0, 64, 1, 0, 0), -- EP("ep1in-bulk", 1, 512, 2, 1, 1), -- EP("ep2out-bulk", 2, 512, 2, 1, 1), -- EP("ep3in-int", 3, 64, 3, 1, 0), -- EP("ep4out-int", 4, 64, 3, 1, 0), -- EP("ep5in-iso", 5, 1024, 3, 1, 1), -- EP("ep6out-iso", 6, 1024, 3, 1, 1), --}; --#undef EP -- - static struct usb_endpoint_descriptor usba_ep0_desc = { - .bLength = USB_DT_ENDPOINT_SIZE, - .bDescriptorType = USB_DT_ENDPOINT, -@@ -1074,7 +1024,6 @@ static void nop_release(struct device *d - static struct usba_udc the_udc = { - .gadget = { - .ops = &usba_udc_ops, -- .ep0 = &usba_ep[0].ep, - .ep_list = LIST_HEAD_INIT(the_udc.gadget.ep_list), - .is_dualspeed = 1, - .name = "atmel_usba_udc", -@@ -1231,7 +1180,7 @@ static int do_test_mode(struct usba_udc - } else { - usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE); - usba_writel(udc, TST, USBA_TST_PKT_MODE); -- copy_to_fifo(ep->fifo, test_packet_buffer, -+ memcpy_toio(ep->fifo, test_packet_buffer, - sizeof(test_packet_buffer)); - usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY); - dev_info(dev, "Entering Test_Packet mode...\n"); -@@ -1530,13 +1479,13 @@ restart: - DBG(DBG_HW, "Packet length: %u\n", pkt_len); - if (pkt_len != sizeof(crq)) { - pr_warning("udc: Invalid packet length %u " -- "(expected %lu)\n", pkt_len, sizeof(crq)); -+ "(expected %zu)\n", pkt_len, sizeof(crq)); - set_protocol_stall(udc, ep); - return; - } - - DBG(DBG_FIFO, "Copying ctrl request from 0x%p:\n", ep->fifo); -- copy_from_fifo(crq.data, ep->fifo, sizeof(crq)); -+ memcpy_fromio(crq.data, ep->fifo, sizeof(crq)); - - /* Free up one bank in the FIFO so that we can - * generate or receive a reply right away. */ -@@ -1688,6 +1637,7 @@ static irqreturn_t usba_udc_irq(int irq, - DBG(DBG_INT, "irq, status=%#08x\n", status); - - if (status & USBA_DET_SUSPEND) { -+ toggle_bias(0); - usba_writel(udc, INT_CLR, USBA_DET_SUSPEND); - DBG(DBG_BUS, "Suspend detected\n"); - if (udc->gadget.speed != USB_SPEED_UNKNOWN -@@ -1699,6 +1649,7 @@ static irqreturn_t usba_udc_irq(int irq, - } - - if (status & USBA_WAKE_UP) { -+ toggle_bias(1); - usba_writel(udc, INT_CLR, USBA_WAKE_UP); - DBG(DBG_BUS, "Wake Up CPU detected\n"); - } -@@ -1792,12 +1743,14 @@ static irqreturn_t usba_vbus_irq(int irq - vbus = gpio_get_value(udc->vbus_pin); - if (vbus != udc->vbus_prev) { - if (vbus) { -- usba_writel(udc, CTRL, USBA_EN_USBA); -+ toggle_bias(1); -+ usba_writel(udc, CTRL, USBA_ENABLE_MASK); - usba_writel(udc, INT_ENB, USBA_END_OF_RESET); - } else { - udc->gadget.speed = USB_SPEED_UNKNOWN; - reset_all_endpoints(udc); -- usba_writel(udc, CTRL, 0); -+ toggle_bias(0); -+ usba_writel(udc, CTRL, USBA_DISABLE_MASK); - spin_unlock(&udc->lock); - udc->driver->disconnect(&udc->gadget); - spin_lock(&udc->lock); -@@ -1850,7 +1803,8 @@ int usb_gadget_register_driver(struct us - /* If Vbus is present, enable the controller and wait for reset */ - spin_lock_irqsave(&udc->lock, flags); - if (vbus_is_present(udc) && udc->vbus_prev == 0) { -- usba_writel(udc, CTRL, USBA_EN_USBA); -+ toggle_bias(1); -+ usba_writel(udc, CTRL, USBA_ENABLE_MASK); - usba_writel(udc, INT_ENB, USBA_END_OF_RESET); - } - spin_unlock_irqrestore(&udc->lock, flags); -@@ -1883,7 +1837,8 @@ int usb_gadget_unregister_driver(struct - spin_unlock_irqrestore(&udc->lock, flags); - - /* This will also disable the DP pullup */ -- usba_writel(udc, CTRL, 0); -+ toggle_bias(0); -+ usba_writel(udc, CTRL, USBA_DISABLE_MASK); - - driver->unbind(&udc->gadget); - udc->gadget.dev.driver = NULL; -@@ -1908,7 +1863,7 @@ static int __init usba_udc_probe(struct - - regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID); - fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID); -- if (!regs || !fifo) -+ if (!regs || !fifo || !pdata) - return -ENXIO; - - irq = platform_get_irq(pdev, 0); -@@ -1953,19 +1908,48 @@ static int __init usba_udc_probe(struct - - /* Make sure we start from a clean slate */ - clk_enable(pclk); -- usba_writel(udc, CTRL, 0); -+ toggle_bias(0); -+ usba_writel(udc, CTRL, USBA_DISABLE_MASK); - clk_disable(pclk); - -+ usba_ep = kmalloc(sizeof(struct usba_ep) * pdata->num_ep, -+ GFP_KERNEL); -+ if (!usba_ep) -+ goto err_alloc_ep; -+ -+ the_udc.gadget.ep0 = &usba_ep[0].ep; -+ - INIT_LIST_HEAD(&usba_ep[0].ep.ep_list); - usba_ep[0].ep_regs = udc->regs + USBA_EPT_BASE(0); - usba_ep[0].dma_regs = udc->regs + USBA_DMA_BASE(0); - usba_ep[0].fifo = udc->fifo + USBA_FIFO_BASE(0); -- for (i = 1; i < ARRAY_SIZE(usba_ep); i++) { -+ usba_ep[0].ep.ops = &usba_ep_ops; -+ usba_ep[0].ep.name = pdata->ep[0].name; -+ usba_ep[0].ep.maxpacket = pdata->ep[0].fifo_size; -+ usba_ep[0].udc = &the_udc; -+ INIT_LIST_HEAD(&usba_ep[0].queue); -+ usba_ep[0].fifo_size = pdata->ep[0].fifo_size; -+ usba_ep[0].nr_banks = pdata->ep[0].nr_banks; -+ usba_ep[0].index = pdata->ep[0].index; -+ usba_ep[0].can_dma = pdata->ep[0].can_dma; -+ usba_ep[0].can_isoc = pdata->ep[0].can_isoc; -+ -+ for (i = 1; i < pdata->num_ep; i++) { - struct usba_ep *ep = &usba_ep[i]; - - ep->ep_regs = udc->regs + USBA_EPT_BASE(i); - ep->dma_regs = udc->regs + USBA_DMA_BASE(i); - ep->fifo = udc->fifo + USBA_FIFO_BASE(i); -+ ep->ep.ops = &usba_ep_ops; -+ ep->ep.name = pdata->ep[i].name; -+ ep->ep.maxpacket = pdata->ep[i].fifo_size; -+ ep->udc = &the_udc; -+ INIT_LIST_HEAD(&ep->queue); -+ ep->fifo_size = pdata->ep[i].fifo_size; -+ ep->nr_banks = pdata->ep[i].nr_banks; -+ ep->index = pdata->ep[i].index; -+ ep->can_dma = pdata->ep[i].can_dma; -+ ep->can_isoc = pdata->ep[i].can_isoc; - - list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); - } -@@ -1984,7 +1968,7 @@ static int __init usba_udc_probe(struct - goto err_device_add; - } - -- if (pdata && pdata->vbus_pin != GPIO_PIN_NONE) { -+ if (pdata->vbus_pin >= 0) { - if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) { - udc->vbus_pin = pdata->vbus_pin; - -@@ -2004,7 +1988,7 @@ static int __init usba_udc_probe(struct - } - - usba_init_debugfs(udc); -- for (i = 1; i < ARRAY_SIZE(usba_ep); i++) -+ for (i = 1; i < pdata->num_ep; i++) - usba_ep_init_debugfs(udc, &usba_ep[i]); - - return 0; -@@ -2012,6 +1996,8 @@ static int __init usba_udc_probe(struct - err_device_add: - free_irq(irq, udc); - err_request_irq: -+ kfree(usba_ep); -+err_alloc_ep: - iounmap(udc->fifo); - err_map_fifo: - iounmap(udc->regs); -@@ -2029,10 +2015,11 @@ static int __exit usba_udc_remove(struct - { - struct usba_udc *udc; - int i; -+ struct usba_platform_data *pdata = pdev->dev.platform_data; - - udc = platform_get_drvdata(pdev); - -- for (i = 1; i < ARRAY_SIZE(usba_ep); i++) -+ for (i = 1; i < pdata->num_ep; i++) - usba_ep_cleanup_debugfs(&usba_ep[i]); - usba_cleanup_debugfs(udc); - -@@ -2040,6 +2027,7 @@ static int __exit usba_udc_remove(struct - gpio_free(udc->vbus_pin); - - free_irq(udc->irq, udc); -+ kfree(usba_ep); - iounmap(udc->fifo); - iounmap(udc->regs); - clk_put(udc->hclk); ---- a/drivers/usb/gadget/atmel_usba_udc.h -+++ b/drivers/usb/gadget/atmel_usba_udc.h -@@ -41,6 +41,15 @@ - #define USBA_EN_USBA (1 << 8) - #define USBA_DETACH (1 << 9) - #define USBA_REMOTE_WAKE_UP (1 << 10) -+#define USBA_PULLD_DIS (1 << 11) -+ -+#if defined(CONFIG_AVR32) -+#define USBA_ENABLE_MASK USBA_EN_USBA -+#define USBA_DISABLE_MASK 0 -+#elif defined(CONFIG_ARCH_AT91) -+#define USBA_ENABLE_MASK (USBA_EN_USBA | USBA_PULLD_DIS) -+#define USBA_DISABLE_MASK USBA_DETACH -+#endif /* CONFIG_ARCH_AT91 */ - - /* Bitfields in FNUM */ - #define USBA_MICRO_FRAME_NUM_OFFSET 0 ---- a/drivers/video/atmel_lcdfb.c -+++ b/drivers/video/atmel_lcdfb.c -@@ -38,7 +38,9 @@ - #endif - - #if defined(CONFIG_ARCH_AT91) --#define ATMEL_LCDFB_FBINFO_DEFAULT FBINFO_DEFAULT -+#define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \ -+ | FBINFO_PARTIAL_PAN_OK \ -+ | FBINFO_HWACCEL_YPAN) - - static inline void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo, - struct fb_var_screeninfo *var) -@@ -176,7 +178,7 @@ static struct fb_fix_screeninfo atmel_lc - .type = FB_TYPE_PACKED_PIXELS, - .visual = FB_VISUAL_TRUECOLOR, - .xpanstep = 0, -- .ypanstep = 0, -+ .ypanstep = 1, - .ywrapstep = 0, - .accel = FB_ACCEL_NONE, - }; -@@ -250,6 +252,8 @@ static int atmel_lcdfb_alloc_video_memor - return -ENOMEM; - } - -+ memset(info->screen_base, 0, info->fix.smem_len); -+ - return 0; - } - -@@ -634,7 +638,6 @@ static int __init atmel_lcdfb_init_fbinf - struct fb_info *info = sinfo->info; - int ret = 0; - -- memset_io(info->screen_base, 0, info->fix.smem_len); - info->var.activate |= FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW; - - dev_info(info->device, -@@ -764,6 +767,11 @@ static int __init atmel_lcdfb_probe(stru - info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len); - if (!info->screen_base) - goto release_intmem; -+ -+ /* -+ * Don't clear the framebuffer -- someone may have set -+ * up a splash image. -+ */ - } else { - /* alocate memory buffer */ - ret = atmel_lcdfb_alloc_video_memory(sinfo); ---- a/fs/fs-writeback.c -+++ b/fs/fs-writeback.c -@@ -385,8 +385,6 @@ __writeback_single_inode(struct inode *i - * WB_SYNC_HOLD is a hack for sys_sync(): reattach the inode to sb->s_dirty so - * that it can be located for waiting on in __writeback_single_inode(). - * -- * Called under inode_lock. -- * - * If `bdi' is non-zero then we're being asked to writeback a specific queue. - * This function assumes that the blockdev superblock's inodes are backed by - * a variety of queues, so all inodes are searched. For other superblocks, -@@ -402,11 +400,12 @@ __writeback_single_inode(struct inode *i - * on the writer throttling path, and we get decent balancing between many - * throttled threads: we don't want them all piling up on inode_sync_wait. - */ --static void --sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc) -+void generic_sync_sb_inodes(struct super_block *sb, -+ struct writeback_control *wbc) - { - const unsigned long start = jiffies; /* livelock avoidance */ - -+ spin_lock(&inode_lock); - if (!wbc->for_kupdate || list_empty(&sb->s_io)) - queue_io(sb, wbc->older_than_this); - -@@ -485,8 +484,16 @@ sync_sb_inodes(struct super_block *sb, s - if (!list_empty(&sb->s_more_io)) - wbc->more_io = 1; - } -+ spin_unlock(&inode_lock); - return; /* Leave any unwritten inodes on s_io */ - } -+EXPORT_SYMBOL_GPL(generic_sync_sb_inodes); -+ -+static void sync_sb_inodes(struct super_block *sb, -+ struct writeback_control *wbc) -+{ -+ generic_sync_sb_inodes(sb, wbc); -+} - - /* - * Start writeback of dirty pagecache data against all unlocked inodes. -@@ -526,11 +533,8 @@ restart: - * be unmounted by the time it is released. - */ - if (down_read_trylock(&sb->s_umount)) { -- if (sb->s_root) { -- spin_lock(&inode_lock); -+ if (sb->s_root) - sync_sb_inodes(sb, wbc); -- spin_unlock(&inode_lock); -- } - up_read(&sb->s_umount); - } - spin_lock(&sb_lock); -@@ -568,9 +572,7 @@ void sync_inodes_sb(struct super_block * - (inodes_stat.nr_inodes - inodes_stat.nr_unused) + - nr_dirty + nr_unstable; - wbc.nr_to_write += wbc.nr_to_write / 2; /* Bit more for luck */ -- spin_lock(&inode_lock); - sync_sb_inodes(sb, &wbc); -- spin_unlock(&inode_lock); - } - - /* ---- a/include/asm-avr32/arch-at32ap/board.h -+++ b/include/asm-avr32/arch-at32ap/board.h -@@ -8,6 +8,12 @@ - - #define GPIO_PIN_NONE (-1) - -+/* -+ * Clock rates for various on-board oscillators. The number of entries -+ * in this array is chip-dependent. -+ */ -+extern unsigned long at32_board_osc_rates[]; -+ - /* Add basic devices: system manager, interrupt controller, portmuxes, etc. */ - void at32_add_system_devices(void); - -@@ -36,11 +42,10 @@ at32_add_device_spi(unsigned int id, str - struct atmel_lcdfb_info; - struct platform_device * - at32_add_device_lcdc(unsigned int id, struct atmel_lcdfb_info *data, -- unsigned long fbmem_start, unsigned long fbmem_len); -+ unsigned long fbmem_start, unsigned long fbmem_len, -+ unsigned int pin_config); - --struct usba_platform_data { -- int vbus_pin; --}; -+struct usba_platform_data; - struct platform_device * - at32_add_device_usba(unsigned int id, struct usba_platform_data *data); - -@@ -68,9 +73,27 @@ struct platform_device *at32_add_device_ - struct platform_device * - at32_add_device_ssc(unsigned int id, unsigned int flags); - --struct platform_device *at32_add_device_twi(unsigned int id); --struct platform_device *at32_add_device_mci(unsigned int id); --struct platform_device *at32_add_device_ac97c(unsigned int id); -+struct i2c_board_info; -+struct platform_device *at32_add_device_twi(unsigned int id, -+ struct i2c_board_info *b, -+ unsigned int n); -+ -+struct mci_platform_data { -+ int detect_pin; -+ int wp_pin; -+}; -+struct platform_device * -+at32_add_device_mci(unsigned int id, struct mci_platform_data *data); -+ -+struct ac97c_platform_data { -+ unsigned short dma_rx_periph_id; -+ unsigned short dma_tx_periph_id; -+ unsigned short dma_controller_id; -+ int reset_pin; -+}; -+struct platform_device * -+at32_add_device_ac97c(unsigned int id, struct ac97c_platform_data *data); -+ - struct platform_device *at32_add_device_abdac(unsigned int id); - - struct cf_platform_data { -@@ -84,4 +107,20 @@ struct platform_device * - at32_add_device_cf(unsigned int id, unsigned int extint, - struct cf_platform_data *data); - -+struct platform_device * -+at32_add_device_psif(unsigned int id); -+ -+/* NAND / SmartMedia */ -+struct atmel_nand_data { -+ int enable_pin; /* chip enable */ -+ int det_pin; /* card detect */ -+ int rdy_pin; /* ready/busy */ -+ u8 ale; /* address line number connected to ALE */ -+ u8 cle; /* address line number connected to CLE */ -+ u8 bus_width_16; /* buswidth is 16 bit */ -+ struct mtd_partition *(*partition_info)(int size, int *num_partitions); -+}; -+struct platform_device * -+at32_add_device_nand(unsigned int id, struct atmel_nand_data *data); -+ - #endif /* __ASM_ARCH_BOARD_H */ ---- a/include/asm-avr32/arch-at32ap/init.h -+++ b/include/asm-avr32/arch-at32ap/init.h -@@ -13,10 +13,6 @@ - void setup_platform(void); - void setup_board(void); - --/* Called by setup_platform */ --void at32_clock_init(void); --void at32_portmux_init(void); -- - void at32_setup_serial_console(unsigned int usart_id); - - #endif /* __ASM_AVR32_AT32AP_INIT_H__ */ ---- /dev/null -+++ b/include/asm-avr32/arch-at32ap/pm.h -@@ -0,0 +1,51 @@ -+/* -+ * AVR32 AP Power Management. -+ * -+ * 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 __ASM_AVR32_ARCH_PM_H -+#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 -+ -+#ifndef __ASSEMBLY__ -+extern void cpu_enter_idle(void); -+extern void cpu_enter_standby(unsigned long sdramc_base); -+ -+extern bool disable_idle_sleep; -+ -+static inline void cpu_disable_idle_sleep(void) -+{ -+ disable_idle_sleep = true; -+} -+ -+static inline void cpu_enable_idle_sleep(void) -+{ -+ disable_idle_sleep = false; -+} -+ -+static inline void cpu_idle_sleep(void) -+{ -+ /* -+ * If we're using the COUNT and COMPARE registers for -+ * timekeeping, we can't use the IDLE state. -+ */ -+ if (disable_idle_sleep) -+ cpu_relax(); -+ else -+ cpu_enter_idle(); -+} -+ -+void intc_set_suspend_handler(unsigned long offset); -+#endif -+ -+#endif /* __ASM_AVR32_ARCH_PM_H */ ---- a/include/asm-avr32/arch-at32ap/portmux.h -+++ b/include/asm-avr32/arch-at32ap/portmux.h -@@ -26,4 +26,16 @@ void at32_select_periph(unsigned int pin - void at32_select_gpio(unsigned int pin, unsigned long flags); - void at32_reserve_pin(unsigned int pin); - -+#ifdef CONFIG_GPIO_DEV -+ -+/* Gang allocators and accessors; used by the GPIO /dev driver */ -+int at32_gpio_port_is_valid(unsigned int port); -+int at32_select_gpio_pins(unsigned int port, u32 pins, u32 oe_mask); -+void at32_deselect_pins(unsigned int port, u32 pins); -+ -+u32 at32_gpio_get_value_multiple(unsigned int port, u32 pins); -+void at32_gpio_set_value_multiple(unsigned int port, u32 value, u32 mask); -+ -+#endif /* CONFIG_GPIO_DEV */ -+ - #endif /* __ASM_ARCH_PORTMUX_H__ */ ---- /dev/null -+++ b/include/asm-avr32/arch-at32ap/sram.h -@@ -0,0 +1,30 @@ -+/* -+ * Simple SRAM allocator -+ * -+ * 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 __ASM_AVR32_ARCH_SRAM_H -+#define __ASM_AVR32_ARCH_SRAM_H -+ -+#include <linux/genalloc.h> -+ -+extern struct gen_pool *sram_pool; -+ -+static inline unsigned long sram_alloc(size_t len) -+{ -+ if (!sram_pool) -+ return 0UL; -+ -+ return gen_pool_alloc(sram_pool, len); -+} -+ -+static inline void sram_free(unsigned long addr, size_t len) -+{ -+ return gen_pool_free(sram_pool, addr, len); -+} -+ -+#endif /* __ASM_AVR32_ARCH_SRAM_H */ ---- a/include/asm-avr32/arch-at32ap/time.h -+++ /dev/null -@@ -1,112 +0,0 @@ --/* -- * 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_AVR32_ARCH_AT32AP_TIME_H --#define _ASM_AVR32_ARCH_AT32AP_TIME_H -- --#include <linux/platform_device.h> -- --extern struct irqaction timer_irqaction; --extern struct platform_device at32_systc0_device; --extern void local_timer_interrupt(int irq, void *dev_id); -- --#define TIMER_BCR 0x000000c0 --#define TIMER_BCR_SYNC 0 --#define TIMER_BMR 0x000000c4 --#define TIMER_BMR_TC0XC0S 0 --#define TIMER_BMR_TC1XC1S 2 --#define TIMER_BMR_TC2XC2S 4 --#define TIMER_CCR 0x00000000 --#define TIMER_CCR_CLKDIS 1 --#define TIMER_CCR_CLKEN 0 --#define TIMER_CCR_SWTRG 2 --#define TIMER_CMR 0x00000004 --#define TIMER_CMR_ABETRG 10 --#define TIMER_CMR_ACPA 16 --#define TIMER_CMR_ACPC 18 --#define TIMER_CMR_AEEVT 20 --#define TIMER_CMR_ASWTRG 22 --#define TIMER_CMR_BCPB 24 --#define TIMER_CMR_BCPC 26 --#define TIMER_CMR_BEEVT 28 --#define TIMER_CMR_BSWTRG 30 --#define TIMER_CMR_BURST 4 --#define TIMER_CMR_CLKI 3 --#define TIMER_CMR_CPCDIS 7 --#define TIMER_CMR_CPCSTOP 6 --#define TIMER_CMR_CPCTRG 14 --#define TIMER_CMR_EEVT 10 --#define TIMER_CMR_EEVTEDG 8 --#define TIMER_CMR_ENETRG 12 --#define TIMER_CMR_ETRGEDG 8 --#define TIMER_CMR_LDBDIS 7 --#define TIMER_CMR_LDBSTOP 6 --#define TIMER_CMR_LDRA 16 --#define TIMER_CMR_LDRB 18 --#define TIMER_CMR_TCCLKS 0 --#define TIMER_CMR_WAVE 15 --#define TIMER_CMR_WAVSEL 13 --#define TIMER_CV 0x00000010 --#define TIMER_CV_CV 0 --#define TIMER_IDR 0x00000028 --#define TIMER_IDR_COVFS 0 --#define TIMER_IDR_CPAS 2 --#define TIMER_IDR_CPBS 3 --#define TIMER_IDR_CPCS 4 --#define TIMER_IDR_ETRGS 7 --#define TIMER_IDR_LDRAS 5 --#define TIMER_IDR_LDRBS 6 --#define TIMER_IDR_LOVRS 1 --#define TIMER_IER 0x00000024 --#define TIMER_IER_COVFS 0 --#define TIMER_IER_CPAS 2 --#define TIMER_IER_CPBS 3 --#define TIMER_IER_CPCS 4 --#define TIMER_IER_ETRGS 7 --#define TIMER_IER_LDRAS 5 --#define TIMER_IER_LDRBS 6 --#define TIMER_IER_LOVRS 1 --#define TIMER_IMR 0x0000002c --#define TIMER_IMR_COVFS 0 --#define TIMER_IMR_CPAS 2 --#define TIMER_IMR_CPBS 3 --#define TIMER_IMR_CPCS 4 --#define TIMER_IMR_ETRGS 7 --#define TIMER_IMR_LDRAS 5 --#define TIMER_IMR_LDRBS 6 --#define TIMER_IMR_LOVRS 1 --#define TIMER_RA 0x00000014 --#define TIMER_RA_RA 0 --#define TIMER_RB 0x00000018 --#define TIMER_RB_RB 0 --#define TIMER_RC 0x0000001c --#define TIMER_RC_RC 0 --#define TIMER_SR 0x00000020 --#define TIMER_SR_CLKSTA 16 --#define TIMER_SR_COVFS 0 --#define TIMER_SR_CPAS 2 --#define TIMER_SR_CPBS 3 --#define TIMER_SR_CPCS 4 --#define TIMER_SR_ETRGS 7 --#define TIMER_SR_LDRAS 5 --#define TIMER_SR_LDRBS 6 --#define TIMER_SR_LOVRS 1 --#define TIMER_SR_MTIOA 17 --#define TIMER_SR_MTIOB 18 -- --/* Bit manipulation macros */ --#define TIMER_BIT(name) (1 << TIMER_##name) --#define TIMER_BF(name,value) ((value) << TIMER_##name) -- --/* Register access macros */ --#define timer_read(port,instance,reg) \ -- __raw_readl(port + (0x40 * instance) + TIMER_##reg) --#define timer_write(port,instance,reg,value) \ -- __raw_writel((value), port + (0x40 * instance) + TIMER_##reg) -- --#endif /* _ASM_AVR32_ARCH_AT32AP_TIME_H */ ---- a/include/asm-avr32/asm.h -+++ b/include/asm-avr32/asm.h -@@ -12,10 +12,10 @@ - #include <asm/asm-offsets.h> - #include <asm/thread_info.h> - --#define mask_interrupts ssrf SR_GM_BIT --#define mask_exceptions ssrf SR_EM_BIT --#define unmask_interrupts csrf SR_GM_BIT --#define unmask_exceptions csrf SR_EM_BIT -+#define mask_interrupts ssrf SYSREG_GM_OFFSET -+#define mask_exceptions ssrf SYSREG_EM_OFFSET -+#define unmask_interrupts csrf SYSREG_GM_OFFSET -+#define unmask_exceptions csrf SYSREG_EM_OFFSET - - #ifdef CONFIG_FRAME_POINTER - .macro save_fp ---- /dev/null -+++ b/include/asm-avr32/dma-controller.h -@@ -0,0 +1,166 @@ -+/* -+ * 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. -+ */ -+#ifndef __ASM_AVR32_DMA_CONTROLLER_H -+#define __ASM_AVR32_DMA_CONTROLLER_H -+ -+#include <linux/device.h> -+ -+#define DMA_DIR_MEM_TO_MEM 0x0000 -+#define DMA_DIR_MEM_TO_PERIPH 0x0001 -+#define DMA_DIR_PERIPH_TO_MEM 0x0002 -+#define DMA_DIR_PERIPH_TO_PERIPH 0x0003 -+ -+#define DMA_WIDTH_8BIT 0 -+#define DMA_WIDTH_16BIT 1 -+#define DMA_WIDTH_32BIT 2 -+ -+struct dma_request { -+ struct dma_controller *dmac; -+ struct list_head list; -+ -+ unsigned short channel; -+ -+ void (*xfer_complete)(struct dma_request *req); -+ void (*block_complete)(struct dma_request *req); -+ void (*error)(struct dma_request *req); -+}; -+ -+struct dma_request_sg { -+ struct dma_request req; -+ -+ int nr_sg; -+ struct scatterlist *sg; -+ unsigned long block_size; -+ unsigned int nr_blocks; -+ -+ dma_addr_t data_reg; -+ unsigned short periph_id; -+ -+ unsigned char direction; -+ unsigned char width; -+}; -+#define to_dma_request_sg(_req) \ -+ container_of(_req, struct dma_request_sg, req) -+ -+struct dma_request_cyclic { -+ struct dma_request req; -+ -+ int periods; -+ unsigned long buffer_size; -+ -+ dma_addr_t buffer_start; -+ dma_addr_t data_reg; -+ -+ unsigned short periph_id; -+ unsigned char direction; -+ unsigned char width; -+ -+ void *dev_id; -+}; -+#define to_dma_request_cyclic(_req) \ -+ container_of(_req, struct dma_request_cyclic, req) -+ -+struct dma_request_memcpy { -+ struct dma_request req; -+ -+ dma_addr_t src_addr; -+ unsigned int src_width; -+ unsigned int src_stride; -+ -+ dma_addr_t dst_addr; -+ unsigned int dst_width; -+ unsigned int dst_stride; -+ -+ size_t length; -+ -+ unsigned short src_reverse:1; -+ unsigned short dst_reverse:1; -+}; -+#define to_dma_request_memcpy(_req) \ -+ container_of(_req, struct dma_request_memcpy, req) -+ -+struct dma_controller { -+ struct list_head list; -+ int id; -+ struct device *dev; -+ -+ int (*alloc_channel)(struct dma_controller *dmac); -+ void (*release_channel)(struct dma_controller *dmac, -+ int channel); -+ int (*prepare_request_sg)(struct dma_controller *dmac, -+ struct dma_request_sg *req); -+ int (*prepare_request_cyclic)(struct dma_controller *dmac, -+ struct dma_request_cyclic *req); -+ int (*prepare_request_memcpy)(struct dma_controller *dmac, -+ struct dma_request_memcpy *req); -+ int (*start_request)(struct dma_controller *dmac, -+ unsigned int channel); -+ int (*stop_request)(struct dma_controller *dmac, -+ unsigned int channel); -+ dma_addr_t (*get_current_pos)(struct dma_controller *dmac, -+ unsigned int channel); -+}; -+ -+static inline int -+dma_alloc_channel(struct dma_controller *dmac) -+{ -+ return dmac->alloc_channel(dmac); -+} -+ -+static inline void -+dma_release_channel(struct dma_controller *dmac, int chan) -+{ -+ dmac->release_channel(dmac, chan); -+} -+ -+static inline int -+dma_prepare_request_sg(struct dma_controller *dmac, -+ struct dma_request_sg *req) -+{ -+ return dmac->prepare_request_sg(dmac, req); -+} -+ -+static inline int -+dma_prepare_request_cyclic(struct dma_controller *dmac, -+ struct dma_request_cyclic *req) -+{ -+ return dmac->prepare_request_cyclic(dmac, req); -+} -+ -+static inline int -+dma_prepare_request_memcpy(struct dma_controller *dmac, -+ struct dma_request_memcpy *req) -+{ -+ return dmac->prepare_request_memcpy(dmac, req); -+} -+ -+static inline int -+dma_start_request(struct dma_controller *dmac, -+ unsigned int channel) -+{ -+ return dmac->start_request(dmac, channel); -+} -+ -+static inline int -+dma_stop_request(struct dma_controller *dmac, -+ unsigned int channel) -+{ -+ return dmac->stop_request(dmac, channel); -+} -+ -+static inline dma_addr_t -+dma_get_current_pos(struct dma_controller *dmac, -+ unsigned int channel) -+{ -+ return dmac->get_current_pos(dmac, channel); -+} -+ -+extern int register_dma_controller(struct dma_controller *dmac); -+extern struct dma_controller *find_dma_controller(int id); -+ -+#endif /* __ASM_AVR32_DMA_CONTROLLER_H */ ---- a/include/asm-avr32/intc.h -+++ /dev/null -@@ -1,128 +0,0 @@ --#ifndef __ASM_AVR32_INTC_H --#define __ASM_AVR32_INTC_H -- --#include <linux/sysdev.h> --#include <linux/interrupt.h> -- --struct irq_controller; --struct irqaction; --struct pt_regs; -- --struct platform_device; -- --/* Information about the internal interrupt controller */ --struct intc_device { -- /* ioremapped address of configuration block */ -- void __iomem *regs; -- -- /* the physical device */ -- struct platform_device *pdev; -- -- /* Number of interrupt lines per group. */ -- unsigned int irqs_per_group; -- -- /* The highest group ID + 1 */ -- unsigned int nr_groups; -- -- /* -- * Bitfield indicating which groups are actually in use. The -- * size of the array is -- * ceil(group_max / (8 * sizeof(unsigned int))). -- */ -- unsigned int group_mask[]; --}; -- --struct irq_controller_class { -- /* -- * A short name identifying this kind of controller. -- */ -- const char *typename; -- /* -- * Handle the IRQ. Must do any necessary acking and masking. -- */ -- irqreturn_t (*handle)(int irq, void *dev_id, struct pt_regs *regs); -- /* -- * Register a new IRQ handler. -- */ -- int (*setup)(struct irq_controller *ctrl, unsigned int irq, -- struct irqaction *action); -- /* -- * Unregister a IRQ handler. -- */ -- void (*free)(struct irq_controller *ctrl, unsigned int irq, -- void *dev_id); -- /* -- * Mask the IRQ in the interrupt controller. -- */ -- void (*mask)(struct irq_controller *ctrl, unsigned int irq); -- /* -- * Unmask the IRQ in the interrupt controller. -- */ -- void (*unmask)(struct irq_controller *ctrl, unsigned int irq); -- /* -- * Set the type of the IRQ. See below for possible types. -- * Return -EINVAL if a given type is not supported -- */ -- int (*set_type)(struct irq_controller *ctrl, unsigned int irq, -- unsigned int type); -- /* -- * Return the IRQ type currently set -- */ -- unsigned int (*get_type)(struct irq_controller *ctrl, unsigned int irq); --}; -- --struct irq_controller { -- struct irq_controller_class *class; -- unsigned int irq_group; -- unsigned int first_irq; -- unsigned int nr_irqs; -- struct list_head list; --}; -- --struct intc_group_desc { -- struct irq_controller *ctrl; -- irqreturn_t (*handle)(int, void *, struct pt_regs *); -- unsigned long flags; -- void *dev_id; -- const char *devname; --}; -- --/* -- * The internal interrupt controller. Defined in board/part-specific -- * devices.c. -- * TODO: Should probably be defined per-cpu. -- */ --extern struct intc_device intc; -- --extern int request_internal_irq(unsigned int irq, -- irqreturn_t (*handler)(int, void *, struct pt_regs *), -- unsigned long irqflags, -- const char *devname, void *dev_id); --extern void free_internal_irq(unsigned int irq); -- --/* Only used by time_init() */ --extern int setup_internal_irq(unsigned int irq, struct intc_group_desc *desc); -- --/* -- * Set interrupt priority for a given group. `group' can be found by -- * using irq_to_group(irq). Priority can be from 0 (lowest) to 3 -- * (highest). Higher-priority interrupts will preempt lower-priority -- * interrupts (unless interrupts are masked globally). -- * -- * This function does not check for conflicts within a group. -- */ --extern int intc_set_priority(unsigned int group, -- unsigned int priority); -- --/* -- * Returns a bitmask of pending interrupts in a group. -- */ --extern unsigned long intc_get_pending(unsigned int group); -- --/* -- * Register a new external interrupt controller. Returns the first -- * external IRQ number that is assigned to the new controller. -- */ --extern int intc_register_controller(struct irq_controller *ctrl); -- --#endif /* __ASM_AVR32_INTC_H */ ---- a/include/asm-avr32/irq.h -+++ b/include/asm-avr32/irq.h -@@ -14,6 +14,11 @@ - #ifndef __ASSEMBLER__ - int nmi_enable(void); - void nmi_disable(void); -+ -+/* -+ * Returns a bitmask of pending interrupts in a group. -+ */ -+extern unsigned long intc_get_pending(unsigned int group); - #endif - - #endif /* __ASM_AVR32_IOCTLS_H */ ---- a/include/asm-avr32/mmu_context.h -+++ b/include/asm-avr32/mmu_context.h -@@ -13,7 +13,6 @@ - #define __ASM_AVR32_MMU_CONTEXT_H - - #include <asm/tlbflush.h> --#include <asm/pgalloc.h> - #include <asm/sysreg.h> - #include <asm-generic/mm_hooks.h> - ---- a/include/asm-avr32/page.h -+++ b/include/asm-avr32/page.h -@@ -8,13 +8,11 @@ - #ifndef __ASM_AVR32_PAGE_H - #define __ASM_AVR32_PAGE_H - -+#include <linux/const.h> -+ - /* PAGE_SHIFT determines the page size */ - #define PAGE_SHIFT 12 --#ifdef __ASSEMBLY__ --#define PAGE_SIZE (1 << PAGE_SHIFT) --#else --#define PAGE_SIZE (1UL << PAGE_SHIFT) --#endif -+#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) - #define PAGE_MASK (~(PAGE_SIZE-1)) - #define PTE_MASK PAGE_MASK - ---- a/include/asm-avr32/pci.h -+++ b/include/asm-avr32/pci.h -@@ -5,4 +5,6 @@ - - #define PCI_DMA_BUS_IS_PHYS (1) - -+#include <asm-generic/pci-dma-compat.h> -+ - #endif /* __ASM_AVR32_PCI_H__ */ ---- a/include/asm-avr32/pgalloc.h -+++ b/include/asm-avr32/pgalloc.h -@@ -8,65 +8,79 @@ - #ifndef __ASM_AVR32_PGALLOC_H - #define __ASM_AVR32_PGALLOC_H - --#include <asm/processor.h> --#include <linux/threads.h> --#include <linux/slab.h> --#include <linux/mm.h> -+#include <linux/quicklist.h> -+#include <asm/page.h> -+#include <asm/pgtable.h> - --#define pmd_populate_kernel(mm, pmd, pte) \ -- set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))) -+#define QUICK_PGD 0 /* Preserve kernel mappings over free */ -+#define QUICK_PT 1 /* Zero on free */ - --static __inline__ void pmd_populate(struct mm_struct *mm, pmd_t *pmd, -+static inline void pmd_populate_kernel(struct mm_struct *mm, -+ pmd_t *pmd, pte_t *pte) -+{ -+ set_pmd(pmd, __pmd((unsigned long)pte)); -+} -+ -+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, - pgtable_t pte) - { -- set_pmd(pmd, __pmd(_PAGE_TABLE + page_to_phys(pte))); -+ set_pmd(pmd, __pmd((unsigned long)page_address(pte))); - } - #define pmd_pgtable(pmd) pmd_page(pmd) - -+static inline void pgd_ctor(void *x) -+{ -+ pgd_t *pgd = x; -+ -+ memcpy(pgd + USER_PTRS_PER_PGD, -+ swapper_pg_dir + USER_PTRS_PER_PGD, -+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); -+} -+ - /* - * Allocate and free page tables - */ --static __inline__ pgd_t *pgd_alloc(struct mm_struct *mm) -+static inline pgd_t *pgd_alloc(struct mm_struct *mm) - { -- return kcalloc(USER_PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL); -+ return quicklist_alloc(QUICK_PGD, GFP_KERNEL | __GFP_REPEAT, pgd_ctor); - } - - static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) - { -- kfree(pgd); -+ quicklist_free(QUICK_PGD, NULL, pgd); - } - - static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, - unsigned long address) - { -- pte_t *pte; -- -- pte = (pte_t *)get_zeroed_page(GFP_KERNEL | __GFP_REPEAT); -- -- return pte; -+ return quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); - } - --static inline struct page *pte_alloc_one(struct mm_struct *mm, -+static inline pgtable_t pte_alloc_one(struct mm_struct *mm, - unsigned long address) - { -- struct page *pte; -+ struct page *page; -+ void *pg; - -- pte = alloc_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO); -- if (!pte) -+ pg = quicklist_alloc(QUICK_PT, GFP_KERNEL | __GFP_REPEAT, NULL); -+ if (!pg) - return NULL; -- pgtable_page_ctor(pte); -- return pte; -+ -+ page = virt_to_page(pg); -+ pgtable_page_ctor(page); -+ -+ return page; - } - - static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) - { -- free_page((unsigned long)pte); -+ quicklist_free(QUICK_PT, NULL, pte); - } - - static inline void pte_free(struct mm_struct *mm, pgtable_t pte) - { - pgtable_page_dtor(pte); -- __free_page(pte); -+ quicklist_free_page(QUICK_PT, NULL, pte); - } - - #define __pte_free_tlb(tlb,pte) \ -@@ -75,6 +89,10 @@ do { \ - tlb_remove_page((tlb), pte); \ - } while (0) - --#define check_pgt_cache() do { } while(0) -+static inline void check_pgt_cache(void) -+{ -+ quicklist_trim(QUICK_PGD, NULL, 25, 16); -+ quicklist_trim(QUICK_PT, NULL, 25, 16); -+} - - #endif /* __ASM_AVR32_PGALLOC_H */ ---- a/include/asm-avr32/pgtable.h -+++ b/include/asm-avr32/pgtable.h -@@ -129,13 +129,6 @@ extern struct page *empty_zero_page; - - #define _PAGE_FLAGS_CACHE_MASK (_PAGE_CACHABLE | _PAGE_BUFFER | _PAGE_WT) - --/* TODO: Check for saneness */ --/* User-mode page table flags (to be set in a pgd or pmd entry) */ --#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_TYPE_SMALL | _PAGE_RW \ -- | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) --/* Kernel-mode page table flags */ --#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_TYPE_SMALL | _PAGE_RW \ -- | _PAGE_ACCESSED | _PAGE_DIRTY) - /* Flags that may be modified by software */ - #define _PAGE_CHG_MASK (PTE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY \ - | _PAGE_FLAGS_CACHE_MASK) -@@ -254,10 +247,14 @@ static inline pte_t pte_mkyoung(pte_t pt - } - - #define pmd_none(x) (!pmd_val(x)) --#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) --#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) --#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) \ -- != _KERNPG_TABLE) -+#define pmd_present(x) (pmd_val(x)) -+ -+static inline void pmd_clear(pmd_t *pmdp) -+{ -+ set_pmd(pmdp, __pmd(0)); -+} -+ -+#define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK) - - /* - * Permanent address of a page. We don't support highmem, so this is -@@ -295,19 +292,16 @@ static inline pte_t pte_modify(pte_t pte - - #define page_pte(page) page_pte_prot(page, __pgprot(0)) - --#define pmd_page_vaddr(pmd) \ -- ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) -- --#define pmd_page(pmd) (phys_to_page(pmd_val(pmd))) -+#define pmd_page_vaddr(pmd) pmd_val(pmd) -+#define pmd_page(pmd) (virt_to_page(pmd_val(pmd))) - - /* to find an entry in a page-table-directory. */ --#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) --#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address)) --#define pgd_offset_current(address) \ -- ((pgd_t *)__mfsr(SYSREG_PTBR) + pgd_index(address)) -+#define pgd_index(address) (((address) >> PGDIR_SHIFT) \ -+ & (PTRS_PER_PGD - 1)) -+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) - - /* to find an entry in a kernel page-table-directory */ --#define pgd_offset_k(address) pgd_offset(&init_mm, address) -+#define pgd_offset_k(address) pgd_offset(&init_mm, address) - - /* Find an entry in the third-level page table.. */ - #define pte_index(address) \ ---- /dev/null -+++ b/include/asm-avr32/serial.h -@@ -0,0 +1,13 @@ -+#ifndef _ASM_SERIAL_H -+#define _ASM_SERIAL_H -+ -+/* -+ * This assumes you have a 1.8432 MHz clock for your UART. -+ * -+ * It'd be nice if someone built a serial card with a 24.576 MHz -+ * clock, since the 16550A is capable of handling a top speed of 1.5 -+ * megabits/second; but this requires the faster clock. -+ */ -+#define BASE_BAUD (1843200 / 16) -+ -+#endif /* _ASM_SERIAL_H */ ---- a/include/asm-avr32/thread_info.h -+++ b/include/asm-avr32/thread_info.h -@@ -88,6 +88,7 @@ static inline struct thread_info *curren - #define TIF_MEMDIE 6 - #define TIF_RESTORE_SIGMASK 7 /* restore signal mask in do_signal */ - #define TIF_CPU_GOING_TO_SLEEP 8 /* CPU is entering sleep 0 mode */ -+#define TIF_FREEZE 29 - #define TIF_DEBUG 30 /* debugging enabled */ - #define TIF_USERSPACE 31 /* true if FS sets userspace */ - ---- a/include/asm-avr32/tlbflush.h -+++ b/include/asm-avr32/tlbflush.h -@@ -26,7 +26,6 @@ extern void flush_tlb_mm(struct mm_struc - extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, - unsigned long end); - extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); --extern void __flush_tlb_page(unsigned long asid, unsigned long page); - - extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); - ---- /dev/null -+++ b/include/asm-avr32/xor.h -@@ -0,0 +1,6 @@ -+#ifndef _ASM_XOR_H -+#define _ASM_XOR_H -+ -+#include <asm-generic/xor.h> -+ -+#endif ---- /dev/null -+++ b/include/linux/atmel_tc.h -@@ -0,0 +1,252 @@ -+/* -+ * Timer/Counter Unit (TC) registers. -+ * -+ * 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. -+ */ -+ -+#ifndef ATMEL_TC_H -+#define ATMEL_TC_H -+ -+#include <linux/compiler.h> -+#include <linux/list.h> -+ -+/* -+ * Many 32-bit Atmel SOCs include one or more TC blocks, each of which holds -+ * three general-purpose 16-bit timers. These timers share one register bank. -+ * Depending on the SOC, each timer may have its own clock and IRQ, or those -+ * may be shared by the whole TC block. -+ * -+ * These TC blocks may have up to nine external pins: TCLK0..2 signals for -+ * clocks or clock gates, and per-timer TIOA and TIOB signals used for PWM -+ * or triggering. Those pins need to be set up for use with the TC block, -+ * else they will be used as GPIOs or for a different controller. -+ * -+ * Although we expect each TC block to have a platform_device node, those -+ * nodes are not what drivers bind to. Instead, they ask for a specific -+ * TC block, by number ... which is a common approach on systems with many -+ * timers. Then they use clk_get() and platform_get_irq() to get clock and -+ * IRQ resources. -+ */ -+ -+struct clk; -+ -+/** -+ * struct atmel_tc - information about a Timer/Counter Block -+ * @pdev: physical device -+ * @iomem: resource associated with the I/O register -+ * @regs: mapping through which the I/O registers can be accessed -+ * @irq: irq for each of the three channels -+ * @clk: internal clock source for each of the three channels -+ * @node: list node, for tclib internal use -+ * -+ * On some platforms, each TC channel has its own clocks and IRQs, -+ * while on others, all TC channels share the same clock and IRQ. -+ * Drivers should clk_enable() all the clocks they need even though -+ * all the entries in @clk may point to the same physical clock. -+ * Likewise, drivers should request irqs independently for each -+ * channel, but they must use IRQF_SHARED in case some of the entries -+ * in @irq are actually the same IRQ. -+ */ -+struct atmel_tc { -+ struct platform_device *pdev; -+ struct resource *iomem; -+ void __iomem *regs; -+ int irq[3]; -+ struct clk *clk[3]; -+ struct list_head node; -+}; -+ -+extern struct atmel_tc *atmel_tc_alloc(unsigned block, const char *name); -+extern void atmel_tc_free(struct atmel_tc *tc); -+ -+/* platform-specific ATMEL_TC_TIMER_CLOCKx divisors (0 means 32KiHz) */ -+extern const u8 atmel_tc_divisors[5]; -+ -+ -+/* -+ * Two registers have block-wide controls. These are: configuring the three -+ * "external" clocks (or event sources) used by the timer channels; and -+ * synchronizing the timers by resetting them all at once. -+ * -+ * "External" can mean "external to chip" using the TCLK0, TCLK1, or TCLK2 -+ * signals. Or, it can mean "external to timer", using the TIOA output from -+ * one of the other two timers that's being run in waveform mode. -+ */ -+ -+#define ATMEL_TC_BCR 0xc0 /* TC Block Control Register */ -+#define ATMEL_TC_SYNC (1 << 0) /* synchronize timers */ -+ -+#define ATMEL_TC_BMR 0xc4 /* TC Block Mode Register */ -+#define ATMEL_TC_TC0XC0S (3 << 0) /* external clock 0 source */ -+#define ATMEL_TC_TC0XC0S_TCLK0 (0 << 0) -+#define ATMEL_TC_TC0XC0S_NONE (1 << 0) -+#define ATMEL_TC_TC0XC0S_TIOA1 (2 << 0) -+#define ATMEL_TC_TC0XC0S_TIOA2 (3 << 0) -+#define ATMEL_TC_TC1XC1S (3 << 2) /* external clock 1 source */ -+#define ATMEL_TC_TC1XC1S_TCLK1 (0 << 2) -+#define ATMEL_TC_TC1XC1S_NONE (1 << 2) -+#define ATMEL_TC_TC1XC1S_TIOA0 (2 << 2) -+#define ATMEL_TC_TC1XC1S_TIOA2 (3 << 2) -+#define ATMEL_TC_TC2XC2S (3 << 4) /* external clock 2 source */ -+#define ATMEL_TC_TC2XC2S_TCLK2 (0 << 4) -+#define ATMEL_TC_TC2XC2S_NONE (1 << 4) -+#define ATMEL_TC_TC2XC2S_TIOA0 (2 << 4) -+#define ATMEL_TC_TC2XC2S_TIOA1 (3 << 4) -+ -+ -+/* -+ * Each TC block has three "channels", each with one counter and controls. -+ * -+ * Note that the semantics of ATMEL_TC_TIMER_CLOCKx (input clock selection -+ * when it's not "external") is silicon-specific. AT91 platforms use one -+ * set of definitions; AVR32 platforms use a different set. Don't hard-wire -+ * such knowledge into your code, use the global "atmel_tc_divisors" ... -+ * where index N is the divisor for clock N+1, else zero to indicate it uses -+ * the 32 KiHz clock. -+ * -+ * The timers can be chained in various ways, and operated in "waveform" -+ * generation mode (including PWM) or "capture" mode (to time events). In -+ * both modes, behavior can be configured in many ways. -+ * -+ * Each timer has two I/O pins, TIOA and TIOB. Waveform mode uses TIOA as a -+ * PWM output, and TIOB as either another PWM or as a trigger. Capture mode -+ * uses them only as inputs. -+ */ -+#define ATMEL_TC_CHAN(idx) ((idx)*0x40) -+#define ATMEL_TC_REG(idx, reg) (ATMEL_TC_CHAN(idx) + ATMEL_TC_ ## reg) -+ -+#define ATMEL_TC_CCR 0x00 /* Channel Control Register */ -+#define ATMEL_TC_CLKEN (1 << 0) /* clock enable */ -+#define ATMEL_TC_CLKDIS (1 << 1) /* clock disable */ -+#define ATMEL_TC_SWTRG (1 << 2) /* software trigger */ -+ -+#define ATMEL_TC_CMR 0x04 /* Channel Mode Register */ -+ -+/* Both modes share some CMR bits */ -+#define ATMEL_TC_TCCLKS (7 << 0) /* clock source */ -+#define ATMEL_TC_TIMER_CLOCK1 (0 << 0) -+#define ATMEL_TC_TIMER_CLOCK2 (1 << 0) -+#define ATMEL_TC_TIMER_CLOCK3 (2 << 0) -+#define ATMEL_TC_TIMER_CLOCK4 (3 << 0) -+#define ATMEL_TC_TIMER_CLOCK5 (4 << 0) -+#define ATMEL_TC_XC0 (5 << 0) -+#define ATMEL_TC_XC1 (6 << 0) -+#define ATMEL_TC_XC2 (7 << 0) -+#define ATMEL_TC_CLKI (1 << 3) /* clock invert */ -+#define ATMEL_TC_BURST (3 << 4) /* clock gating */ -+#define ATMEL_TC_GATE_NONE (0 << 4) -+#define ATMEL_TC_GATE_XC0 (1 << 4) -+#define ATMEL_TC_GATE_XC1 (2 << 4) -+#define ATMEL_TC_GATE_XC2 (3 << 4) -+#define ATMEL_TC_WAVE (1 << 15) /* true = Waveform mode */ -+ -+/* CAPTURE mode CMR bits */ -+#define ATMEL_TC_LDBSTOP (1 << 6) /* counter stops on RB load */ -+#define ATMEL_TC_LDBDIS (1 << 7) /* counter disable on RB load */ -+#define ATMEL_TC_ETRGEDG (3 << 8) /* external trigger edge */ -+#define ATMEL_TC_ETRGEDG_NONE (0 << 8) -+#define ATMEL_TC_ETRGEDG_RISING (1 << 8) -+#define ATMEL_TC_ETRGEDG_FALLING (2 << 8) -+#define ATMEL_TC_ETRGEDG_BOTH (3 << 8) -+#define ATMEL_TC_ABETRG (1 << 10) /* external trigger is TIOA? */ -+#define ATMEL_TC_CPCTRG (1 << 14) /* RC compare trigger enable */ -+#define ATMEL_TC_LDRA (3 << 16) /* RA loading edge (of TIOA) */ -+#define ATMEL_TC_LDRA_NONE (0 << 16) -+#define ATMEL_TC_LDRA_RISING (1 << 16) -+#define ATMEL_TC_LDRA_FALLING (2 << 16) -+#define ATMEL_TC_LDRA_BOTH (3 << 16) -+#define ATMEL_TC_LDRB (3 << 18) /* RB loading edge (of TIOA) */ -+#define ATMEL_TC_LDRB_NONE (0 << 18) -+#define ATMEL_TC_LDRB_RISING (1 << 18) -+#define ATMEL_TC_LDRB_FALLING (2 << 18) -+#define ATMEL_TC_LDRB_BOTH (3 << 18) -+ -+/* WAVEFORM mode CMR bits */ -+#define ATMEL_TC_CPCSTOP (1 << 6) /* RC compare stops counter */ -+#define ATMEL_TC_CPCDIS (1 << 7) /* RC compare disables counter */ -+#define ATMEL_TC_EEVTEDG (3 << 8) /* external event edge */ -+#define ATMEL_TC_EEVTEDG_NONE (0 << 8) -+#define ATMEL_TC_EEVTEDG_RISING (1 << 8) -+#define ATMEL_TC_EEVTEDG_FALLING (2 << 8) -+#define ATMEL_TC_EEVTEDG_BOTH (3 << 8) -+#define ATMEL_TC_EEVT (3 << 10) /* external event source */ -+#define ATMEL_TC_EEVT_TIOB (0 << 10) -+#define ATMEL_TC_EEVT_XC0 (1 << 10) -+#define ATMEL_TC_EEVT_XC1 (2 << 10) -+#define ATMEL_TC_EEVT_XC2 (3 << 10) -+#define ATMEL_TC_ENETRG (1 << 12) /* external event is trigger */ -+#define ATMEL_TC_WAVESEL (3 << 13) /* waveform type */ -+#define ATMEL_TC_WAVESEL_UP (0 << 13) -+#define ATMEL_TC_WAVESEL_UPDOWN (1 << 13) -+#define ATMEL_TC_WAVESEL_UP_AUTO (2 << 13) -+#define ATMEL_TC_WAVESEL_UPDOWN_AUTO (3 << 13) -+#define ATMEL_TC_ACPA (3 << 16) /* RA compare changes TIOA */ -+#define ATMEL_TC_ACPA_NONE (0 << 16) -+#define ATMEL_TC_ACPA_SET (1 << 16) -+#define ATMEL_TC_ACPA_CLEAR (2 << 16) -+#define ATMEL_TC_ACPA_TOGGLE (3 << 16) -+#define ATMEL_TC_ACPC (3 << 18) /* RC compare changes TIOA */ -+#define ATMEL_TC_ACPC_NONE (0 << 18) -+#define ATMEL_TC_ACPC_SET (1 << 18) -+#define ATMEL_TC_ACPC_CLEAR (2 << 18) -+#define ATMEL_TC_ACPC_TOGGLE (3 << 18) -+#define ATMEL_TC_AEEVT (3 << 20) /* external event changes TIOA */ -+#define ATMEL_TC_AEEVT_NONE (0 << 20) -+#define ATMEL_TC_AEEVT_SET (1 << 20) -+#define ATMEL_TC_AEEVT_CLEAR (2 << 20) -+#define ATMEL_TC_AEEVT_TOGGLE (3 << 20) -+#define ATMEL_TC_ASWTRG (3 << 22) /* software trigger changes TIOA */ -+#define ATMEL_TC_ASWTRG_NONE (0 << 22) -+#define ATMEL_TC_ASWTRG_SET (1 << 22) -+#define ATMEL_TC_ASWTRG_CLEAR (2 << 22) -+#define ATMEL_TC_ASWTRG_TOGGLE (3 << 22) -+#define ATMEL_TC_BCPB (3 << 24) /* RB compare changes TIOB */ -+#define ATMEL_TC_BCPB_NONE (0 << 24) -+#define ATMEL_TC_BCPB_SET (1 << 24) -+#define ATMEL_TC_BCPB_CLEAR (2 << 24) -+#define ATMEL_TC_BCPB_TOGGLE (3 << 24) -+#define ATMEL_TC_BCPC (3 << 26) /* RC compare changes TIOB */ -+#define ATMEL_TC_BCPC_NONE (0 << 26) -+#define ATMEL_TC_BCPC_SET (1 << 26) -+#define ATMEL_TC_BCPC_CLEAR (2 << 26) -+#define ATMEL_TC_BCPC_TOGGLE (3 << 26) -+#define ATMEL_TC_BEEVT (3 << 28) /* external event changes TIOB */ -+#define ATMEL_TC_BEEVT_NONE (0 << 28) -+#define ATMEL_TC_BEEVT_SET (1 << 28) -+#define ATMEL_TC_BEEVT_CLEAR (2 << 28) -+#define ATMEL_TC_BEEVT_TOGGLE (3 << 28) -+#define ATMEL_TC_BSWTRG (3 << 30) /* software trigger changes TIOB */ -+#define ATMEL_TC_BSWTRG_NONE (0 << 30) -+#define ATMEL_TC_BSWTRG_SET (1 << 30) -+#define ATMEL_TC_BSWTRG_CLEAR (2 << 30) -+#define ATMEL_TC_BSWTRG_TOGGLE (3 << 30) -+ -+#define ATMEL_TC_CV 0x10 /* counter Value */ -+#define ATMEL_TC_RA 0x14 /* register A */ -+#define ATMEL_TC_RB 0x18 /* register B */ -+#define ATMEL_TC_RC 0x1c /* register C */ -+ -+#define ATMEL_TC_SR 0x20 /* status (read-only) */ -+/* Status-only flags */ -+#define ATMEL_TC_CLKSTA (1 << 16) /* clock enabled */ -+#define ATMEL_TC_MTIOA (1 << 17) /* TIOA mirror */ -+#define ATMEL_TC_MTIOB (1 << 18) /* TIOB mirror */ -+ -+#define ATMEL_TC_IER 0x24 /* interrupt enable (write-only) */ -+#define ATMEL_TC_IDR 0x28 /* interrupt disable (write-only) */ -+#define ATMEL_TC_IMR 0x2c /* interrupt mask (read-only) */ -+ -+/* Status and IRQ flags */ -+#define ATMEL_TC_COVFS (1 << 0) /* counter overflow */ -+#define ATMEL_TC_LOVRS (1 << 1) /* load overrun */ -+#define ATMEL_TC_CPAS (1 << 2) /* RA compare */ -+#define ATMEL_TC_CPBS (1 << 3) /* RB compare */ -+#define ATMEL_TC_CPCS (1 << 4) /* RC compare */ -+#define ATMEL_TC_LDRAS (1 << 5) /* RA loading */ -+#define ATMEL_TC_LDRBS (1 << 6) /* RB loading */ -+#define ATMEL_TC_ETRGS (1 << 7) /* external trigger */ -+ -+#endif ---- a/include/linux/fs.h -+++ b/include/linux/fs.h -@@ -1692,6 +1692,8 @@ static inline void invalidate_remote_ino - extern int invalidate_inode_pages2(struct address_space *mapping); - extern int invalidate_inode_pages2_range(struct address_space *mapping, - pgoff_t start, pgoff_t end); -+extern void generic_sync_sb_inodes(struct super_block *sb, -+ struct writeback_control *wbc); - extern int write_inode_now(struct inode *, int); - extern int filemap_fdatawrite(struct address_space *); - extern int filemap_flush(struct address_space *); ---- a/include/linux/serial_core.h -+++ b/include/linux/serial_core.h -@@ -188,6 +188,7 @@ struct uart_ops { - void (*break_ctl)(struct uart_port *, int ctl); - int (*startup)(struct uart_port *); - void (*shutdown)(struct uart_port *); -+ void (*flush_buffer)(struct uart_port *); - void (*set_termios)(struct uart_port *, struct ktermios *new, - struct ktermios *old); - void (*pm)(struct uart_port *, unsigned int state, ---- /dev/null -+++ b/include/linux/usb/atmel_usba_udc.h -@@ -0,0 +1,22 @@ -+/* -+ * Platform data definitions for Atmel USBA gadget driver. -+ */ -+#ifndef __LINUX_USB_USBA_H -+#define __LINUX_USB_USBA_H -+ -+struct usba_ep_data { -+ char *name; -+ int index; -+ int fifo_size; -+ int nr_banks; -+ int can_dma; -+ int can_isoc; -+}; -+ -+struct usba_platform_data { -+ int vbus_pin; -+ int num_ep; -+ struct usba_ep_data ep[0]; -+}; -+ -+#endif /* __LINUX_USB_USBA_H */ ---- a/mm/Kconfig -+++ b/mm/Kconfig -@@ -187,7 +187,7 @@ config BOUNCE - config NR_QUICK - int - depends on QUICKLIST -- default "2" if SUPERH -+ default "2" if SUPERH || AVR32 - default "1" - - config VIRT_TO_BUS ---- a/sound/Kconfig -+++ b/sound/Kconfig -@@ -63,6 +63,8 @@ source "sound/aoa/Kconfig" - - source "sound/arm/Kconfig" - -+source "sound/avr32/Kconfig" -+ - if SPI - source "sound/spi/Kconfig" - endif ---- a/sound/Makefile -+++ b/sound/Makefile -@@ -6,7 +6,7 @@ obj-$(CONFIG_SOUND_PRIME) += sound_firmw - obj-$(CONFIG_SOUND_PRIME) += oss/ - obj-$(CONFIG_DMASOUND) += oss/ - obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \ -- sparc/ spi/ parisc/ pcmcia/ mips/ soc/ -+ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ avr32/ - obj-$(CONFIG_SND_AOA) += aoa/ - - # This one must be compilable even if sound is configured out ---- /dev/null -+++ b/sound/avr32/Kconfig -@@ -0,0 +1,11 @@ -+menu "AVR32 devices" -+ depends on SND != n && AVR32 -+ -+config SND_ATMEL_AC97 -+ tristate "Atmel AC97 Controller Driver" -+ select SND_PCM -+ select SND_AC97_CODEC -+ help -+ ALSA sound driver for the Atmel AC97 controller. -+ -+endmenu ---- /dev/null -+++ b/sound/avr32/Makefile -@@ -0,0 +1,3 @@ -+snd-atmel-ac97-objs := ac97c.o -+ -+obj-$(CONFIG_SND_ATMEL_AC97) += snd-atmel-ac97.o ---- /dev/null -+++ b/sound/avr32/ac97c.c -@@ -0,0 +1,951 @@ -+/* -+ * Driver for the Atmel AC97 controller -+ * -+ * Copyright (C) 2005-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. -+ */ -+#include <linux/clk.h> -+#include <linux/delay.h> -+#include <linux/dma-mapping.h> -+#include <linux/gpio.h> -+#include <linux/init.h> -+#include <linux/interrupt.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/mutex.h> -+#include <linux/io.h> -+ -+#include <sound/core.h> -+#include <sound/initval.h> -+#include <sound/pcm.h> -+#include <sound/pcm_params.h> -+#include <sound/ac97_codec.h> -+#include <sound/memalloc.h> -+ -+#include <asm/arch/board.h> -+#include <asm/dma-controller.h> -+ -+#include "ac97c.h" -+ -+/* Serialize access to opened */ -+static DEFINE_MUTEX(opened_mutex); -+ -+struct atmel_ac97_dma_info { -+ struct dma_request_cyclic req_tx; -+ struct dma_request_cyclic req_rx; -+ unsigned short rx_periph_id; -+ unsigned short tx_periph_id; -+ unsigned short controller; -+}; -+ -+struct atmel_ac97 { -+ /* Serialize access to opened */ -+ spinlock_t lock; -+ void __iomem *regs; -+ struct snd_pcm_substream *playback_substream; -+ struct snd_pcm_substream *capture_substream; -+ struct snd_card *card; -+ struct snd_pcm *pcm; -+ struct snd_ac97 *ac97; -+ struct snd_ac97_bus *ac97_bus; -+ int opened; -+ int period; -+ int reset_pin; -+ u64 cur_format; -+ unsigned int cur_rate; -+ struct clk *mck; -+ struct platform_device *pdev; -+ struct atmel_ac97_dma_info dma; -+}; -+ -+#define get_chip(card) ((struct atmel_ac97 *)(card)->private_data) -+ -+#define ac97c_writel(chip, reg, val) \ -+ __raw_writel((val), (chip)->regs + AC97C_##reg) -+#define ac97c_readl(chip, reg) \ -+ __raw_readl((chip)->regs + AC97C_##reg) -+ -+/* -+ * PCM part -+ */ -+static struct snd_pcm_hardware snd_atmel_ac97_playback_hw = { -+ .info = (SNDRV_PCM_INFO_INTERLEAVED -+ | SNDRV_PCM_INFO_MMAP -+ | SNDRV_PCM_INFO_MMAP_VALID -+ | SNDRV_PCM_INFO_BLOCK_TRANSFER -+ | SNDRV_PCM_INFO_JOINT_DUPLEX), -+ .formats = (SNDRV_PCM_FMTBIT_S16_BE -+ | SNDRV_PCM_FMTBIT_S16_LE), -+ .rates = (SNDRV_PCM_RATE_CONTINUOUS), -+ .rate_min = 4000, -+ .rate_max = 48000, -+ .channels_min = 1, -+ .channels_max = 6, -+ .buffer_bytes_max = 64*1024, -+ .period_bytes_min = 512, -+ .period_bytes_max = 4095, -+ .periods_min = 8, -+ .periods_max = 1024, -+}; -+ -+static struct snd_pcm_hardware snd_atmel_ac97_capture_hw = { -+ .info = (SNDRV_PCM_INFO_INTERLEAVED -+ | SNDRV_PCM_INFO_MMAP -+ | SNDRV_PCM_INFO_MMAP_VALID -+ | SNDRV_PCM_INFO_BLOCK_TRANSFER -+ | SNDRV_PCM_INFO_JOINT_DUPLEX), -+ .formats = (SNDRV_PCM_FMTBIT_S16_BE -+ | SNDRV_PCM_FMTBIT_S16_LE), -+ .rates = (SNDRV_PCM_RATE_CONTINUOUS), -+ .rate_min = 4000, -+ .rate_max = 48000, -+ .channels_min = 1, -+ .channels_max = 2, -+ .buffer_bytes_max = 64*1024, -+ .period_bytes_min = 512, -+ .period_bytes_max = 4095, -+ .periods_min = 8, -+ .periods_max = 1024, -+}; -+ -+/* -+ * PCM functions -+ */ -+static int -+snd_atmel_ac97_playback_open(struct snd_pcm_substream *substream) -+{ -+ struct atmel_ac97 *chip = snd_pcm_substream_chip(substream); -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ -+ mutex_lock(&opened_mutex); -+ chip->opened++; -+ runtime->hw = snd_atmel_ac97_playback_hw; -+ if (chip->cur_rate) { -+ runtime->hw.rate_min = chip->cur_rate; -+ runtime->hw.rate_max = chip->cur_rate; -+ } -+ if (chip->cur_format) -+ runtime->hw.formats = (1ULL << chip->cur_format); -+ mutex_unlock(&opened_mutex); -+ chip->playback_substream = substream; -+ chip->period = 0; -+ return 0; -+} -+ -+static int -+snd_atmel_ac97_capture_open(struct snd_pcm_substream *substream) -+{ -+ struct atmel_ac97 *chip = snd_pcm_substream_chip(substream); -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ -+ mutex_lock(&opened_mutex); -+ chip->opened++; -+ runtime->hw = snd_atmel_ac97_capture_hw; -+ if (chip->cur_rate) { -+ runtime->hw.rate_min = chip->cur_rate; -+ runtime->hw.rate_max = chip->cur_rate; -+ } -+ if (chip->cur_format) -+ runtime->hw.formats = (1ULL << chip->cur_format); -+ mutex_unlock(&opened_mutex); -+ chip->capture_substream = substream; -+ chip->period = 0; -+ return 0; -+} -+ -+static int snd_atmel_ac97_playback_close(struct snd_pcm_substream *substream) -+{ -+ struct atmel_ac97 *chip = snd_pcm_substream_chip(substream); -+ mutex_lock(&opened_mutex); -+ chip->opened--; -+ if (!chip->opened) { -+ chip->cur_rate = 0; -+ chip->cur_format = 0; -+ } -+ mutex_unlock(&opened_mutex); -+ return 0; -+} -+ -+static int snd_atmel_ac97_capture_close(struct snd_pcm_substream *substream) -+{ -+ struct atmel_ac97 *chip = snd_pcm_substream_chip(substream); -+ mutex_lock(&opened_mutex); -+ chip->opened--; -+ if (!chip->opened) { -+ chip->cur_rate = 0; -+ chip->cur_format = 0; -+ } -+ mutex_unlock(&opened_mutex); -+ return 0; -+} -+ -+static int -+snd_atmel_ac97_playback_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *hw_params) -+{ -+ struct atmel_ac97 *chip = snd_pcm_substream_chip(substream); -+ int err; -+ -+ err = snd_pcm_lib_malloc_pages(substream, -+ params_buffer_bytes(hw_params)); -+ if (err < 0) -+ return err; -+ -+ /* Set restrictions to params */ -+ mutex_lock(&opened_mutex); -+ chip->cur_rate = params_rate(hw_params); -+ chip->cur_format = params_format(hw_params); -+ mutex_unlock(&opened_mutex); -+ -+ return 0; -+} -+ -+static int -+snd_atmel_ac97_capture_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *hw_params) -+{ -+ struct atmel_ac97 *chip = snd_pcm_substream_chip(substream); -+ int err; -+ -+ err = snd_pcm_lib_malloc_pages(substream, -+ params_buffer_bytes(hw_params)); -+ if (err < 0) -+ return err; -+ -+ /* Set restrictions to params */ -+ mutex_lock(&opened_mutex); -+ chip->cur_rate = params_rate(hw_params); -+ chip->cur_format = params_format(hw_params); -+ mutex_unlock(&opened_mutex); -+ -+ return 0; -+} -+ -+static int snd_atmel_ac97_playback_hw_free(struct snd_pcm_substream *substream) -+{ -+ return snd_pcm_lib_free_pages(substream); -+} -+ -+static int snd_atmel_ac97_capture_hw_free(struct snd_pcm_substream *substream) -+{ -+ -+ return snd_pcm_lib_free_pages(substream); -+} -+ -+static int snd_atmel_ac97_playback_prepare(struct snd_pcm_substream *substream) -+{ -+ struct atmel_ac97 *chip = snd_pcm_substream_chip(substream); -+ struct platform_device *pdev = chip->pdev; -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ int block_size = frames_to_bytes(runtime, runtime->period_size); -+ unsigned long word = 0; -+ unsigned long buffer_size = 0; -+ -+ dma_sync_single_for_device(&pdev->dev, runtime->dma_addr, -+ block_size * 2, DMA_TO_DEVICE); -+ -+ /* Assign slots to channels */ -+ switch (substream->runtime->channels) { -+ case 1: -+ word |= AC97C_CH_ASSIGN(PCM_LEFT, A); -+ break; -+ case 2: -+ /* Assign Left and Right slot to Channel A */ -+ word |= AC97C_CH_ASSIGN(PCM_LEFT, A) -+ | AC97C_CH_ASSIGN(PCM_RIGHT, A); -+ break; -+ default: -+ /* TODO: support more than two channels */ -+ return -EINVAL; -+ break; -+ } -+ ac97c_writel(chip, OCA, word); -+ -+ /* Configure sample format and size */ -+ word = AC97C_CMR_PDCEN | AC97C_CMR_SIZE_16; -+ -+ switch (runtime->format) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ word |= AC97C_CMR_CEM_LITTLE; -+ break; -+ case SNDRV_PCM_FORMAT_S16_BE: /* fall through */ -+ default: -+ word &= ~AC97C_CMR_CEM_LITTLE; -+ break; -+ } -+ -+ ac97c_writel(chip, CAMR, word); -+ -+ /* Set variable rate if needed */ -+ if (runtime->rate != 48000) { -+ word = ac97c_readl(chip, MR); -+ word |= AC97C_MR_VRA; -+ ac97c_writel(chip, MR, word); -+ } else { -+ /* Clear Variable Rate Bit */ -+ word = ac97c_readl(chip, MR); -+ word &= ~AC97C_MR_VRA; -+ ac97c_writel(chip, MR, word); -+ } -+ -+ /* Set rate */ -+ snd_ac97_set_rate(chip->ac97, AC97_PCM_FRONT_DAC_RATE, runtime->rate); -+ -+ buffer_size = frames_to_bytes(runtime, runtime->period_size) * -+ runtime->periods; -+ -+ chip->dma.req_tx.buffer_size = buffer_size; -+ chip->dma.req_tx.periods = runtime->periods; -+ -+ BUG_ON(chip->dma.req_tx.buffer_size != -+ (chip->dma.req_tx.periods * -+ frames_to_bytes(runtime, runtime->period_size))); -+ -+ chip->dma.req_tx.buffer_start = runtime->dma_addr; -+ chip->dma.req_tx.data_reg = (dma_addr_t)(chip->regs + AC97C_CATHR + 2); -+ chip->dma.req_tx.periph_id = chip->dma.tx_periph_id; -+ chip->dma.req_tx.direction = DMA_DIR_MEM_TO_PERIPH; -+ chip->dma.req_tx.width = DMA_WIDTH_16BIT; -+ chip->dma.req_tx.dev_id = chip; -+ -+ return 0; -+} -+ -+static int snd_atmel_ac97_capture_prepare(struct snd_pcm_substream *substream) -+{ -+ struct atmel_ac97 *chip = snd_pcm_substream_chip(substream); -+ struct platform_device *pdev = chip->pdev; -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ int block_size = frames_to_bytes(runtime, runtime->period_size); -+ unsigned long word = 0; -+ unsigned long buffer_size = 0; -+ -+ dma_sync_single_for_device(&pdev->dev, runtime->dma_addr, -+ block_size * 2, DMA_FROM_DEVICE); -+ -+ /* Assign slots to channels */ -+ switch (substream->runtime->channels) { -+ case 1: -+ word |= AC97C_CH_ASSIGN(PCM_LEFT, A); -+ break; -+ case 2: -+ /* Assign Left and Right slot to Channel A */ -+ word |= AC97C_CH_ASSIGN(PCM_LEFT, A) -+ | AC97C_CH_ASSIGN(PCM_RIGHT, A); -+ break; -+ default: -+ /* TODO: support more than two channels */ -+ return -EINVAL; -+ break; -+ } -+ ac97c_writel(chip, ICA, word); -+ -+ /* Configure sample format and size */ -+ word = AC97C_CMR_PDCEN | AC97C_CMR_SIZE_16; -+ -+ switch (runtime->format) { -+ case SNDRV_PCM_FORMAT_S16_LE: -+ word |= AC97C_CMR_CEM_LITTLE; -+ break; -+ case SNDRV_PCM_FORMAT_S16_BE: -+ default: -+ word &= ~(AC97C_CMR_CEM_LITTLE); -+ break; -+ } -+ -+ ac97c_writel(chip, CAMR, word); -+ -+ /* Set variable rate if needed */ -+ if (runtime->rate != 48000) { -+ word = ac97c_readl(chip, MR); -+ word |= AC97C_MR_VRA; -+ ac97c_writel(chip, MR, word); -+ } else { -+ /* Clear Variable Rate Bit */ -+ word = ac97c_readl(chip, MR); -+ word &= ~(AC97C_MR_VRA); -+ ac97c_writel(chip, MR, word); -+ } -+ -+ /* Set rate */ -+ snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate); -+ -+ buffer_size = frames_to_bytes(runtime, runtime->period_size) * -+ runtime->periods; -+ -+ chip->dma.req_rx.buffer_size = buffer_size; -+ chip->dma.req_rx.periods = runtime->periods; -+ -+ BUG_ON(chip->dma.req_rx.buffer_size != -+ (chip->dma.req_rx.periods * -+ frames_to_bytes(runtime, runtime->period_size))); -+ -+ chip->dma.req_rx.buffer_start = runtime->dma_addr; -+ chip->dma.req_rx.data_reg = (dma_addr_t)(chip->regs + AC97C_CARHR + 2); -+ chip->dma.req_rx.periph_id = chip->dma.rx_periph_id; -+ chip->dma.req_rx.direction = DMA_DIR_PERIPH_TO_MEM; -+ chip->dma.req_rx.width = DMA_WIDTH_16BIT; -+ chip->dma.req_rx.dev_id = chip; -+ -+ return 0; -+} -+ -+ static int -+snd_atmel_ac97_playback_trigger(struct snd_pcm_substream *substream, int cmd) -+{ -+ struct atmel_ac97 *chip = snd_pcm_substream_chip(substream); -+ unsigned long camr; -+ int flags, err = 0; -+ -+ spin_lock_irqsave(&chip->lock, flags); -+ camr = ac97c_readl(chip, CAMR); -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ err = dma_prepare_request_cyclic(chip->dma.req_tx.req.dmac, -+ &chip->dma.req_tx); -+ dma_start_request(chip->dma.req_tx.req.dmac, -+ chip->dma.req_tx.req.channel); -+ camr |= AC97C_CMR_CENA; -+ break; -+ case SNDRV_PCM_TRIGGER_STOP: -+ err = dma_stop_request(chip->dma.req_tx.req.dmac, -+ chip->dma.req_tx.req.channel); -+ if (chip->opened <= 1) -+ camr &= ~AC97C_CMR_CENA; -+ break; -+ default: -+ err = -EINVAL; -+ break; -+ } -+ -+ ac97c_writel(chip, CAMR, camr); -+ -+ spin_unlock_irqrestore(&chip->lock, flags); -+ return err; -+} -+ -+ static int -+snd_atmel_ac97_capture_trigger(struct snd_pcm_substream *substream, int cmd) -+{ -+ struct atmel_ac97 *chip = snd_pcm_substream_chip(substream); -+ unsigned long camr; -+ int flags, err = 0; -+ -+ spin_lock_irqsave(&chip->lock, flags); -+ camr = ac97c_readl(chip, CAMR); -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ err = dma_prepare_request_cyclic(chip->dma.req_rx.req.dmac, -+ &chip->dma.req_rx); -+ dma_start_request(chip->dma.req_rx.req.dmac, -+ chip->dma.req_rx.req.channel); -+ camr |= AC97C_CMR_CENA; -+ break; -+ case SNDRV_PCM_TRIGGER_STOP: -+ err = dma_stop_request(chip->dma.req_rx.req.dmac, -+ chip->dma.req_rx.req.channel); -+ mutex_lock(&opened_mutex); -+ if (chip->opened <= 1) -+ camr &= ~AC97C_CMR_CENA; -+ mutex_unlock(&opened_mutex); -+ break; -+ default: -+ err = -EINVAL; -+ break; -+ } -+ -+ ac97c_writel(chip, CAMR, camr); -+ -+ spin_unlock_irqrestore(&chip->lock, flags); -+ return err; -+} -+ -+ static snd_pcm_uframes_t -+snd_atmel_ac97_playback_pointer(struct snd_pcm_substream *substream) -+{ -+ struct atmel_ac97 *chip = snd_pcm_substream_chip(substream); -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ snd_pcm_uframes_t pos; -+ unsigned long bytes; -+ -+ bytes = (dma_get_current_pos -+ (chip->dma.req_tx.req.dmac, -+ chip->dma.req_tx.req.channel) - runtime->dma_addr); -+ pos = bytes_to_frames(runtime, bytes); -+ if (pos >= runtime->buffer_size) -+ pos -= runtime->buffer_size; -+ -+ return pos; -+} -+ -+ static snd_pcm_uframes_t -+snd_atmel_ac97_capture_pointer(struct snd_pcm_substream *substream) -+{ -+ struct atmel_ac97 *chip = snd_pcm_substream_chip(substream); -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ snd_pcm_uframes_t pos; -+ unsigned long bytes; -+ -+ bytes = (dma_get_current_pos -+ (chip->dma.req_rx.req.dmac, -+ chip->dma.req_rx.req.channel) -+ - runtime->dma_addr); -+ pos = bytes_to_frames(runtime, bytes); -+ if (pos >= runtime->buffer_size) -+ pos -= runtime->buffer_size; -+ -+ -+ return pos; -+} -+ -+static struct snd_pcm_ops atmel_ac97_playback_ops = { -+ .open = snd_atmel_ac97_playback_open, -+ .close = snd_atmel_ac97_playback_close, -+ .ioctl = snd_pcm_lib_ioctl, -+ .hw_params = snd_atmel_ac97_playback_hw_params, -+ .hw_free = snd_atmel_ac97_playback_hw_free, -+ .prepare = snd_atmel_ac97_playback_prepare, -+ .trigger = snd_atmel_ac97_playback_trigger, -+ .pointer = snd_atmel_ac97_playback_pointer, -+}; -+ -+static struct snd_pcm_ops atmel_ac97_capture_ops = { -+ .open = snd_atmel_ac97_capture_open, -+ .close = snd_atmel_ac97_capture_close, -+ .ioctl = snd_pcm_lib_ioctl, -+ .hw_params = snd_atmel_ac97_capture_hw_params, -+ .hw_free = snd_atmel_ac97_capture_hw_free, -+ .prepare = snd_atmel_ac97_capture_prepare, -+ .trigger = snd_atmel_ac97_capture_trigger, -+ .pointer = snd_atmel_ac97_capture_pointer, -+}; -+ -+static struct ac97_pcm atmel_ac97_pcm_defs[] __devinitdata = { -+ /* Playback */ -+ { -+ .exclusive = 1, -+ .r = { { -+ .slots = ((1 << AC97_SLOT_PCM_LEFT) -+ | (1 << AC97_SLOT_PCM_RIGHT) -+ | (1 << AC97_SLOT_PCM_CENTER) -+ | (1 << AC97_SLOT_PCM_SLEFT) -+ | (1 << AC97_SLOT_PCM_SRIGHT) -+ | (1 << AC97_SLOT_LFE)), -+ } } -+ }, -+ /* PCM in */ -+ { -+ .stream = 1, -+ .exclusive = 1, -+ .r = { { -+ .slots = ((1 << AC97_SLOT_PCM_LEFT) -+ | (1 << AC97_SLOT_PCM_RIGHT)), -+ } } -+ }, -+ /* Mic in */ -+ { -+ .stream = 1, -+ .exclusive = 1, -+ .r = { { -+ .slots = (1<<AC97_SLOT_MIC), -+ } } -+ }, -+}; -+ -+static int __devinit snd_atmel_ac97_pcm_new(struct atmel_ac97 *chip) -+{ -+ struct snd_pcm *pcm; -+ int err; -+ -+ err = snd_ac97_pcm_assign(chip->ac97_bus, -+ ARRAY_SIZE(atmel_ac97_pcm_defs), -+ atmel_ac97_pcm_defs); -+ if (err) -+ return err; -+ -+ err = snd_pcm_new(chip->card, "Atmel-AC97", 0, 1, 1, &pcm); -+ if (err) -+ return err; -+ -+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, -+ &atmel_ac97_playback_ops); -+ -+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, -+ &atmel_ac97_capture_ops); -+ -+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, -+ &chip->pdev->dev, -+ 128 * 1024, 128 * 1024); -+ -+ pcm->private_data = chip; -+ pcm->info_flags = 0; -+ strcpy(pcm->name, "Atmel-AC97"); -+ chip->pcm = pcm; -+ -+ return 0; -+} -+ -+/* -+ * Mixer part. -+ */ -+static int snd_atmel_ac97_mixer_new(struct atmel_ac97 *chip) -+{ -+ int err; -+ struct snd_ac97_template template; -+ -+ memset(&template, 0, sizeof(template)); -+ template.private_data = chip; -+ err = snd_ac97_mixer(chip->ac97_bus, &template, &chip->ac97); -+ -+ return err; -+} -+ -+static void atmel_ac97_error(struct dma_request *_req) -+{ -+ struct dma_request_cyclic *req = to_dma_request_cyclic(_req); -+ struct atmel_ac97 *chip = req->dev_id; -+ -+ dev_dbg(&chip->pdev->dev, "DMA Controller error, channel %d\n", -+ req->req.channel); -+} -+ -+static void atmel_ac97_block_complete(struct dma_request *_req) -+{ -+ struct dma_request_cyclic *req = to_dma_request_cyclic(_req); -+ struct atmel_ac97 *chip = req->dev_id; -+ if (req->periph_id == chip->dma.tx_periph_id) -+ snd_pcm_period_elapsed(chip->playback_substream); -+ else -+ snd_pcm_period_elapsed(chip->capture_substream); -+} -+ -+/* -+ * Codec part. -+ */ -+static void snd_atmel_ac97_write(struct snd_ac97 *ac97, unsigned short reg, -+ unsigned short val) -+{ -+ struct atmel_ac97 *chip = get_chip(ac97); -+ unsigned long word; -+ int timeout = 40; -+ -+ word = (reg & 0x7f) << 16 | val; -+ -+ do { -+ if (ac97c_readl(chip, COSR) & AC97C_CSR_TXRDY) { -+ ac97c_writel(chip, COTHR, word); -+ return; -+ } -+ udelay(1); -+ } while (--timeout); -+ -+ dev_dbg(&chip->pdev->dev, "codec write timeout\n"); -+} -+ -+static unsigned short snd_atmel_ac97_read(struct snd_ac97 *ac97, -+ unsigned short reg) -+{ -+ struct atmel_ac97 *chip = get_chip(ac97); -+ unsigned long word; -+ int timeout = 40; -+ int write = 10; -+ -+ word = (0x80 | (reg & 0x7f)) << 16; -+ -+ if ((ac97c_readl(chip, COSR) & AC97C_CSR_RXRDY) != 0) -+ ac97c_readl(chip, CORHR); -+ -+retry_write: -+ timeout = 40; -+ -+ do { -+ if ((ac97c_readl(chip, COSR) & AC97C_CSR_TXRDY) != 0) { -+ ac97c_writel(chip, COTHR, word); -+ goto read_reg; -+ } -+ udelay(10); -+ } while (--timeout); -+ -+ if (!--write) -+ goto timed_out; -+ goto retry_write; -+ -+read_reg: -+ do { -+ if ((ac97c_readl(chip, COSR) & AC97C_CSR_RXRDY) != 0) { -+ unsigned short val = ac97c_readl(chip, CORHR); -+ return val; -+ } -+ udelay(10); -+ } while (--timeout); -+ -+ if (!--write) -+ goto timed_out; -+ goto retry_write; -+ -+timed_out: -+ dev_dbg(&chip->pdev->dev, "codec read timeout\n"); -+ return 0xffff; -+} -+ -+static void snd_atmel_ac97_reset(struct atmel_ac97 *chip) -+{ -+ /* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */ -+ if (chip->reset_pin >= 0) { -+ gpio_set_value(chip->reset_pin, 0); -+ /* AC97 v2.2 specifications says minimum 1 us. */ -+ udelay(5); -+ gpio_set_value(chip->reset_pin, 1); -+ } -+ -+ ac97c_writel(chip, MR, AC97C_MR_WRST); -+ mdelay(1); -+ ac97c_writel(chip, MR, AC97C_MR_ENA); -+} -+ -+static void snd_atmel_ac97_destroy(struct snd_card *card) -+{ -+ struct atmel_ac97 *chip = get_chip(card); -+ -+ if (chip->regs) -+ iounmap(chip->regs); -+ -+ if (chip->mck) { -+ clk_disable(chip->mck); -+ clk_put(chip->mck); -+ } -+ -+ if (chip->dma.req_tx.req.dmac) { -+ dma_release_channel(chip->dma.req_tx.req.dmac, -+ chip->dma.req_tx.req.channel); -+ } -+ if (chip->dma.req_rx.req.dmac) { -+ dma_release_channel(chip->dma.req_rx.req.dmac, -+ chip->dma.req_rx.req.channel); -+ } -+} -+ -+static int __devinit snd_atmel_ac97_create(struct snd_card *card, -+ struct platform_device *pdev) -+{ -+ static struct snd_ac97_bus_ops ops = { -+ .write = snd_atmel_ac97_write, -+ .read = snd_atmel_ac97_read, -+ }; -+ struct atmel_ac97 *chip = get_chip(card); -+ struct ac97c_platform_data *pdata; -+ struct resource *regs; -+ struct clk *mck; -+ int err; -+ -+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!regs) -+ return -ENXIO; -+ -+ pdata = pdev->dev.platform_data; -+ if (!pdata) -+ return -ENXIO; -+ -+ chip->reset_pin = pdata->reset_pin; -+ -+ /* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */ -+ if (chip->reset_pin >= 0) { -+ if (gpio_request(chip->reset_pin, chip->card->shortname)) { -+ dev_dbg(&pdev->dev, "ac97: reset pin not available\n"); -+ chip->reset_pin = -1; -+ } else { -+ gpio_direction_output(chip->reset_pin, 1); -+ } -+ } -+ -+ chip->dma.rx_periph_id = pdata->dma_rx_periph_id; -+ chip->dma.tx_periph_id = pdata->dma_tx_periph_id; -+ chip->dma.controller = pdata->dma_controller_id; -+ -+ mck = clk_get(&pdev->dev, "pclk"); -+ if (IS_ERR(mck)) -+ return PTR_ERR(mck); -+ clk_enable(mck); -+ chip->mck = mck; -+ -+ card->private_free = snd_atmel_ac97_destroy; -+ -+ spin_lock_init(&chip->lock); -+ chip->card = card; -+ chip->pdev = pdev; -+ -+ chip->regs = ioremap(regs->start, regs->end - regs->start + 1); -+ if (!chip->regs) -+ return -ENOMEM; -+ -+ snd_card_set_dev(card, &pdev->dev); -+ -+ err = snd_ac97_bus(card, 0, &ops, chip, &chip->ac97_bus); -+ -+ return err; -+} -+ -+static int __devinit snd_atmel_ac97_probe(struct platform_device *pdev) -+{ -+ static int dev; -+ struct snd_card *card; -+ struct atmel_ac97 *chip; -+ int err; -+ int ch; -+ -+ mutex_init(&opened_mutex); -+ -+ err = -ENOMEM; -+ card = snd_card_new(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, -+ THIS_MODULE, sizeof(struct atmel_ac97)); -+ if (!card) -+ goto out; -+ -+ chip = get_chip(card); -+ chip->reset_pin = -1; -+ -+ err = snd_atmel_ac97_create(card, pdev); -+ if (err) -+ goto out_free_card; -+ -+ snd_atmel_ac97_reset(chip); -+ -+ err = snd_atmel_ac97_mixer_new(chip); -+ if (err) -+ goto out_free_card; -+ -+ err = snd_atmel_ac97_pcm_new(chip); -+ if (err) -+ goto out_free_card; -+ -+ chip->dma.req_tx.req.dmac = find_dma_controller(chip->dma.controller); -+ if (!chip->dma.req_tx.req.dmac) { -+ dev_dbg(&chip->pdev->dev, "DMA controller for TX missing\n"); -+ err = -ENODEV; -+ goto out_free_card; -+ } -+ chip->dma.req_rx.req.dmac = find_dma_controller(chip->dma.controller); -+ if (!chip->dma.req_rx.req.dmac) { -+ dev_dbg(&chip->pdev->dev, "DMA controller for RX missing\n"); -+ err = -ENODEV; -+ goto out_free_card; -+ } -+ -+ ch = dma_alloc_channel(chip->dma.req_tx.req.dmac); -+ if (ch < 0) { -+ dev_dbg(&chip->pdev->dev, -+ "could not allocate TX DMA channel\n"); -+ err = ch; -+ goto out_free_card; -+ } -+ chip->dma.req_tx.req.channel = ch; -+ chip->dma.req_tx.width = DMA_WIDTH_16BIT; -+ chip->dma.req_tx.req.block_complete = atmel_ac97_block_complete; -+ chip->dma.req_tx.req.error = atmel_ac97_error; -+ -+ ch = dma_alloc_channel(chip->dma.req_rx.req.dmac); -+ if (ch < 0) { -+ dev_dbg(&chip->pdev->dev, -+ "could not allocate RX DMA channel\n"); -+ err = ch; -+ goto out_free_card; -+ } -+ chip->dma.req_rx.req.channel = ch; -+ chip->dma.req_rx.width = DMA_WIDTH_16BIT; -+ chip->dma.req_rx.req.block_complete = atmel_ac97_block_complete; -+ chip->dma.req_rx.req.error = atmel_ac97_error; -+ -+ strcpy(card->driver, "atmel_ac97c"); -+ strcpy(card->shortname, "atmel_ac97c"); -+ sprintf(card->longname, "Atmel AVR32 AC97 controller"); -+ -+ err = snd_card_register(card); -+ if (err) -+ goto out_free_card; -+ -+ platform_set_drvdata(pdev, card); -+ dev++; -+ -+ dev_info(&pdev->dev, "Atmel AVR32 AC97 controller at 0x%p\n", -+ chip->regs); -+ -+ return 0; -+ -+out_free_card: -+ /* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */ -+ if (chip->reset_pin >= 0) -+ gpio_free(chip->reset_pin); -+ snd_card_free(card); -+out: -+ return err; -+} -+ -+#ifdef CONFIG_PM -+ static int -+snd_atmel_ac97_suspend(struct platform_device *pdev, pm_message_t msg) -+{ -+ struct snd_card *card = platform_get_drvdata(pdev); -+ struct atmel_ac97 *chip = card->private_data; -+ -+ clk_disable(chip->mck); -+ -+ return 0; -+} -+ -+static int snd_atmel_ac97_resume(struct platform_device *pdev) -+{ -+ struct snd_card *card = platform_get_drvdata(pdev); -+ struct atmel_ac97 *chip = card->private_data; -+ -+ clk_enable(chip->mck); -+ -+ return 0; -+} -+#else -+#define snd_atmel_ac97_suspend NULL -+#define snd_atmel_ac97_resume NULL -+#endif -+ -+static int __devexit snd_atmel_ac97_remove(struct platform_device *pdev) -+{ -+ struct snd_card *card = platform_get_drvdata(pdev); -+ struct atmel_ac97 *chip = get_chip(card); -+ -+ /* TODO: gpio_is_valid(data->reset_pin) with kernel 2.6.26. */ -+ if (chip->reset_pin >= 0) -+ gpio_free(chip->reset_pin); -+ snd_card_free(card); -+ platform_set_drvdata(pdev, NULL); -+ return 0; -+} -+ -+static struct platform_driver atmel_ac97_driver = { -+ .remove = __devexit_p(snd_atmel_ac97_remove), -+ .driver = { -+ .name = "atmel_ac97c", -+ }, -+ .suspend = snd_atmel_ac97_suspend, -+ .resume = snd_atmel_ac97_resume, -+}; -+ -+static int __init atmel_ac97_init(void) -+{ -+ return platform_driver_probe(&atmel_ac97_driver, -+ snd_atmel_ac97_probe); -+} -+module_init(atmel_ac97_init); -+ -+static void __exit atmel_ac97_exit(void) -+{ -+ platform_driver_unregister(&atmel_ac97_driver); -+} -+module_exit(atmel_ac97_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Driver for Atmel AC97 Controller"); -+MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); ---- /dev/null -+++ b/sound/avr32/ac97c.h -@@ -0,0 +1,71 @@ -+/* -+ * Register definitions for the Atmel AC97 Controller. -+ * -+ * 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. -+ */ -+#ifndef __SOUND_AVR32_AC97C_H -+#define __SOUND_AVR32_AC97C_H -+ -+#define AC97C_MR 0x08 -+#define AC97C_ICA 0x10 -+#define AC97C_OCA 0x14 -+#define AC97C_CARHR 0x20 -+#define AC97C_CATHR 0x24 -+#define AC97C_CASR 0x28 -+#define AC97C_CAMR 0x2c -+#define AC97C_CBRHR 0x30 -+#define AC97C_CBTHR 0x34 -+#define AC97C_CBSR 0x38 -+#define AC97C_CBMR 0x3c -+#define AC97C_CORHR 0x40 -+#define AC97C_COTHR 0x44 -+#define AC97C_COSR 0x48 -+#define AC97C_COMR 0x4c -+#define AC97C_SR 0x50 -+#define AC97C_IER 0x54 -+#define AC97C_IDR 0x58 -+#define AC97C_IMR 0x5c -+#define AC97C_VERSION 0xfc -+ -+#define AC97C_CATPR PDC_TPR -+#define AC97C_CATCR PDC_TCR -+#define AC97C_CATNPR PDC_TNPR -+#define AC97C_CATNCR PDC_TNCR -+#define AC97C_CARPR PDC_RPR -+#define AC97C_CARCR PDC_RCR -+#define AC97C_CARNPR PDC_RNPR -+#define AC97C_CARNCR PDC_RNCR -+#define AC97C_PTCR PDC_PTCR -+ -+#define AC97C_MR_ENA (1 << 0) -+#define AC97C_MR_WRST (1 << 1) -+#define AC97C_MR_VRA (1 << 2) -+ -+#define AC97C_CSR_TXRDY (1 << 0) -+#define AC97C_CSR_UNRUN (1 << 2) -+#define AC97C_CSR_RXRDY (1 << 4) -+#define AC97C_CSR_ENDTX (1 << 10) -+#define AC97C_CSR_ENDRX (1 << 14) -+ -+#define AC97C_CMR_SIZE_20 (0 << 16) -+#define AC97C_CMR_SIZE_18 (1 << 16) -+#define AC97C_CMR_SIZE_16 (2 << 16) -+#define AC97C_CMR_SIZE_10 (3 << 16) -+#define AC97C_CMR_CEM_LITTLE (1 << 18) -+#define AC97C_CMR_CEM_BIG (0 << 18) -+#define AC97C_CMR_CENA (1 << 21) -+#define AC97C_CMR_PDCEN (1 << 22) -+ -+#define AC97C_SR_CAEVT (1 << 3) -+ -+#define AC97C_CH_ASSIGN(slot, channel) \ -+ (AC97C_CHANNEL_##channel << (3 * (AC97_SLOT_##slot - 3))) -+#define AC97C_CHANNEL_NONE 0x0 -+#define AC97C_CHANNEL_A 0x1 -+#define AC97C_CHANNEL_B 0x2 -+ -+#endif /* __SOUND_AVR32_AC97C_H */ ---- a/sound/oss/Kconfig -+++ b/sound/oss/Kconfig -@@ -654,3 +654,7 @@ config SOUND_SH_DAC_AUDIO_CHANNEL - int "DAC channel" - default "1" - depends on SOUND_SH_DAC_AUDIO -+ -+config SOUND_AT32_ABDAC -+ tristate "Atmel AT32 Audio Bitstream DAC (ABDAC) support" -+ depends on SOUND_PRIME && AVR32 ---- a/sound/oss/Makefile -+++ b/sound/oss/Makefile -@@ -9,6 +9,7 @@ obj-$(CONFIG_SOUND_OSS) += sound.o - - # Please leave it as is, cause the link order is significant ! - -+obj-$(CONFIG_SOUND_AT32_ABDAC) += at32_abdac.o - obj-$(CONFIG_SOUND_SH_DAC_AUDIO) += sh_dac_audio.o - obj-$(CONFIG_SOUND_HAL2) += hal2.o - obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o ---- /dev/null -+++ b/sound/oss/at32_abdac.c -@@ -0,0 +1,722 @@ -+/* -+ * OSS Sound Driver for the Atmel AT32 on-chip DAC. -+ * -+ * Copyright (C) 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/clk.h> -+#include <linux/dma-mapping.h> -+#include <linux/fs.h> -+#include <linux/init.h> -+#include <linux/interrupt.h> -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/platform_device.h> -+#include <linux/sound.h> -+#include <linux/soundcard.h> -+ -+#include <asm/byteorder.h> -+#include <asm/dma-controller.h> -+#include <asm/io.h> -+#include <asm/uaccess.h> -+ -+/* We want to use the "bizarre" swap-bytes-in-each-halfword macro */ -+#include <linux/byteorder/swabb.h> -+ -+#include "at32_abdac.h" -+ -+#define DMA_BUFFER_SIZE 32768 -+#define DMA_PERIOD_SHIFT 10 -+#define DMA_PERIOD_SIZE (1 << DMA_PERIOD_SHIFT) -+#define DMA_WRITE_THRESHOLD DMA_PERIOD_SIZE -+ -+struct sound_settings { -+ unsigned int format; -+ unsigned int channels; -+ unsigned int sample_rate; -+ /* log2(bytes per sample) */ -+ unsigned int input_order; -+}; -+ -+struct at32_dac { -+ spinlock_t lock; -+ void __iomem *regs; -+ -+ /* head and tail refer to number of words */ -+ struct { -+ u32 *buf; -+ int head; -+ int tail; -+ } dma; -+ -+ struct semaphore sem; -+ wait_queue_head_t write_wait; -+ -+ /* -+ * Read at most ucount bytes from ubuf, translate to 2-channel -+ * signed 16-bit big endian format and write to the DMA buffer -+ * as long as there is room left. Return the number of bytes -+ * successfully copied from ubuf, or -EFAULT if the first -+ * sample from ubuf couldn't be read. This function is not -+ * called unless there is room for at least one sample (4 -+ * bytes) in the DMA buffer. -+ */ -+ ssize_t (*trans)(struct at32_dac *dac, const char __user *ubuf, -+ size_t ucount); -+ -+ struct sound_settings dsp_settings; -+ struct dma_request_cyclic req; -+ -+ struct clk *mck; -+ struct clk *sample_clk; -+ struct platform_device *pdev; -+ int busy; -+ int playing; -+ int dev_dsp; -+}; -+static struct at32_dac *the_dac; -+ -+static inline unsigned int abdac_get_head(struct at32_dac *dac) -+{ -+ return dac->dma.head & ((DMA_BUFFER_SIZE / 4) - 1); -+} -+ -+static inline unsigned int abdac_get_tail(struct at32_dac *dac) -+{ -+ return dac->dma.tail & ((DMA_BUFFER_SIZE / 4) - 1); -+} -+ -+static inline unsigned int abdac_dma_space(struct at32_dac *dac) -+{ -+ unsigned int space; -+ -+ space = ((dac->dma.tail - dac->dma.head - 1) -+ & ((DMA_BUFFER_SIZE / 4) - 1)); -+ return space; -+} -+ -+static void abdac_update_dma_tail(struct at32_dac *dac) -+{ -+ dma_addr_t dma_addr; -+ unsigned int new_tail; -+ -+ if (dac->playing) { -+ dma_addr = dma_get_current_pos(dac->req.req.dmac, -+ dac->req.req.channel); -+ new_tail = (dma_addr - dac->req.buffer_start) / 4; -+ if (new_tail >= dac->dma.head -+ && (dac->dma.tail < dac->dma.head -+ || dac->dma.tail > new_tail)) -+ dev_notice(&dac->pdev->dev, "DMA underrun detected!\n"); -+ dac->dma.tail = new_tail; -+ dev_dbg(&dac->pdev->dev, "update tail: 0x%x - 0x%x = %u\n", -+ dma_addr, dac->req.buffer_start, dac->dma.tail); -+ } -+} -+ -+static int abdac_start(struct at32_dac *dac) -+{ -+ int ret; -+ -+ if (dac->playing) -+ return 0; -+ -+ memset(dac->dma.buf, 0, DMA_BUFFER_SIZE); -+ -+ clk_enable(dac->sample_clk); -+ -+ ret = dma_prepare_request_cyclic(dac->req.req.dmac, &dac->req); -+ if (ret) -+ goto out_stop_clock; -+ -+ dev_dbg(&dac->pdev->dev, "starting DMA...\n"); -+ ret = dma_start_request(dac->req.req.dmac, dac->req.req.channel); -+ if (ret) -+ goto out_stop_request; -+ -+ dac_writel(dac, CTRL, DAC_BIT(EN)); -+ dac->playing = 1; -+ -+ return 0; -+ -+out_stop_request: -+ dma_stop_request(dac->req.req.dmac, -+ dac->req.req.channel); -+out_stop_clock: -+ clk_disable(dac->sample_clk); -+ return ret; -+} -+ -+static int abdac_stop(struct at32_dac *dac) -+{ -+ if (dac->playing) { -+ dma_stop_request(dac->req.req.dmac, dac->req.req.channel); -+ dac_writel(dac, DATA, 0); -+ dac_writel(dac, CTRL, 0); -+ dac->playing = 0; -+ clk_disable(dac->sample_clk); -+ } -+ -+ return 0; -+} -+ -+static int abdac_dma_prepare(struct at32_dac *dac) -+{ -+ dac->dma.buf = dma_alloc_coherent(&dac->pdev->dev, DMA_BUFFER_SIZE, -+ &dac->req.buffer_start, GFP_KERNEL); -+ if (!dac->dma.buf) -+ return -ENOMEM; -+ -+ dac->dma.head = dac->dma.tail = 0; -+ dac->req.periods = DMA_BUFFER_SIZE / DMA_PERIOD_SIZE; -+ dac->req.buffer_size = DMA_BUFFER_SIZE; -+ -+ return 0; -+} -+ -+static void abdac_dma_cleanup(struct at32_dac *dac) -+{ -+ if (dac->dma.buf) -+ dma_free_coherent(&dac->pdev->dev, DMA_BUFFER_SIZE, -+ dac->dma.buf, dac->req.buffer_start); -+ dac->dma.buf = NULL; -+} -+ -+static void abdac_dma_block_complete(struct dma_request *req) -+{ -+ struct dma_request_cyclic *creq = to_dma_request_cyclic(req); -+ struct at32_dac *dac = container_of(creq, struct at32_dac, req); -+ -+ wake_up(&dac->write_wait); -+} -+ -+static void abdac_dma_error(struct dma_request *req) -+{ -+ struct dma_request_cyclic *creq = to_dma_request_cyclic(req); -+ struct at32_dac *dac = container_of(creq, struct at32_dac, req); -+ -+ dev_err(&dac->pdev->dev, "DMA error\n"); -+} -+ -+static irqreturn_t abdac_interrupt(int irq, void *dev_id) -+{ -+ struct at32_dac *dac = dev_id; -+ u32 status; -+ -+ status = dac_readl(dac, INT_STATUS); -+ if (status & DAC_BIT(UNDERRUN)) { -+ dev_err(&dac->pdev->dev, "Underrun detected!\n"); -+ dac_writel(dac, INT_CLR, DAC_BIT(UNDERRUN)); -+ } else { -+ dev_err(&dac->pdev->dev, "Spurious interrupt (status=0x%x)\n", -+ status); -+ dac_writel(dac, INT_CLR, status); -+ } -+ -+ return IRQ_HANDLED; -+} -+ -+static ssize_t trans_s16be(struct at32_dac *dac, const char __user *ubuf, -+ size_t ucount) -+{ -+ ssize_t ret; -+ -+ if (dac->dsp_settings.channels == 2) { -+ const u32 __user *up = (const u32 __user *)ubuf; -+ u32 sample; -+ -+ for (ret = 0; ret < (ssize_t)(ucount - 3); ret += 4) { -+ if (!abdac_dma_space(dac)) -+ break; -+ -+ if (unlikely(__get_user(sample, up++))) { -+ if (ret == 0) -+ ret = -EFAULT; -+ break; -+ } -+ dac->dma.buf[abdac_get_head(dac)] = sample; -+ dac->dma.head++; -+ } -+ } else { -+ const u16 __user *up = (const u16 __user *)ubuf; -+ u16 sample; -+ -+ for (ret = 0; ret < (ssize_t)(ucount - 1); ret += 2) { -+ if (!abdac_dma_space(dac)) -+ break; -+ -+ if (unlikely(__get_user(sample, up++))) { -+ if (ret == 0) -+ ret = -EFAULT; -+ break; -+ } -+ dac->dma.buf[abdac_get_head(dac)] -+ = (sample << 16) | sample; -+ dac->dma.head++; -+ } -+ } -+ -+ return ret; -+} -+ -+static ssize_t trans_s16le(struct at32_dac *dac, const char __user *ubuf, -+ size_t ucount) -+{ -+ ssize_t ret; -+ -+ if (dac->dsp_settings.channels == 2) { -+ const u32 __user *up = (const u32 __user *)ubuf; -+ u32 sample; -+ -+ for (ret = 0; ret < (ssize_t)(ucount - 3); ret += 4) { -+ if (!abdac_dma_space(dac)) -+ break; -+ -+ if (unlikely(__get_user(sample, up++))) { -+ if (ret == 0) -+ ret = -EFAULT; -+ break; -+ } -+ /* Swap bytes in each halfword */ -+ dac->dma.buf[abdac_get_head(dac)] = swahb32(sample); -+ dac->dma.head++; -+ } -+ } else { -+ const u16 __user *up = (const u16 __user *)ubuf; -+ u16 sample; -+ -+ for (ret = 0; ret < (ssize_t)(ucount - 1); ret += 2) { -+ if (!abdac_dma_space(dac)) -+ break; -+ -+ if (unlikely(__get_user(sample, up++))) { -+ if (ret == 0) -+ ret = -EFAULT; -+ break; -+ } -+ sample = swab16(sample); -+ dac->dma.buf[abdac_get_head(dac)] -+ = (sample << 16) | sample; -+ dac->dma.head++; -+ } -+ } -+ -+ return ret; -+} -+ -+static ssize_t abdac_dma_translate_from_user(struct at32_dac *dac, -+ const char __user *buffer, -+ size_t count) -+{ -+ /* At least one buffer must be available at this point */ -+ dev_dbg(&dac->pdev->dev, "copying %zu bytes from user...\n", count); -+ -+ return dac->trans(dac, buffer, count); -+} -+ -+static int abdac_set_format(struct at32_dac *dac, int format) -+{ -+ unsigned int order; -+ -+ switch (format) { -+ case AFMT_S16_BE: -+ order = 1; -+ dac->trans = trans_s16be; -+ break; -+ case AFMT_S16_LE: -+ order = 1; -+ dac->trans = trans_s16le; -+ break; -+ default: -+ dev_dbg(&dac->pdev->dev, "unsupported format: %d\n", format); -+ return -EINVAL; -+ } -+ -+ if (dac->dsp_settings.channels == 2) -+ order++; -+ -+ dac->dsp_settings.input_order = order; -+ dac->dsp_settings.format = format; -+ return 0; -+} -+ -+static int abdac_set_sample_rate(struct at32_dac *dac, unsigned long rate) -+{ -+ unsigned long new_rate; -+ int ret; -+ -+ ret = clk_set_rate(dac->sample_clk, 256 * rate); -+ if (ret < 0) -+ return ret; -+ -+ /* TODO: mplayer seems to have a problem with this */ -+#if 0 -+ new_rate = clk_get_rate(dac->sample_clk); -+ dac->dsp_settings.sample_rate = new_rate / 256; -+#else -+ dac->dsp_settings.sample_rate = rate; -+#endif -+ -+ return 0; -+} -+ -+static ssize_t abdac_dsp_write(struct file *file, -+ const char __user *buffer, -+ size_t count, loff_t *ppos) -+{ -+ struct at32_dac *dac = file->private_data; -+ DECLARE_WAITQUEUE(wait, current); -+ unsigned int avail; -+ ssize_t copied; -+ ssize_t ret; -+ -+ /* Avoid address space checking in the translation functions */ -+ if (!access_ok(buffer, count, VERIFY_READ)) -+ return -EFAULT; -+ -+ down(&dac->sem); -+ -+ if (!dac->dma.buf) { -+ ret = abdac_dma_prepare(dac); -+ if (ret) -+ goto out; -+ } -+ -+ add_wait_queue(&dac->write_wait, &wait); -+ ret = 0; -+ while (count > 0) { -+ do { -+ abdac_update_dma_tail(dac); -+ avail = abdac_dma_space(dac); -+ set_current_state(TASK_INTERRUPTIBLE); -+ if (avail >= DMA_WRITE_THRESHOLD) -+ break; -+ -+ if (file->f_flags & O_NONBLOCK) { -+ if (!ret) -+ ret = -EAGAIN; -+ goto out; -+ } -+ -+ pr_debug("Going to wait (avail = %u, count = %zu)\n", -+ avail, count); -+ -+ up(&dac->sem); -+ schedule(); -+ if (signal_pending(current)) { -+ if (!ret) -+ ret = -ERESTARTSYS; -+ goto out_nosem; -+ } -+ down(&dac->sem); -+ } while (1); -+ -+ copied = abdac_dma_translate_from_user(dac, buffer, count); -+ if (copied < 0) { -+ if (!ret) -+ ret = -EFAULT; -+ goto out; -+ } -+ -+ abdac_start(dac); -+ -+ count -= copied; -+ ret += copied; -+ } -+ -+out: -+ up(&dac->sem); -+out_nosem: -+ remove_wait_queue(&dac->write_wait, &wait); -+ set_current_state(TASK_RUNNING); -+ return ret; -+} -+ -+static int abdac_dsp_ioctl(struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct at32_dac *dac = file->private_data; -+ int __user *up = (int __user *)arg; -+ struct audio_buf_info abinfo; -+ int val, ret; -+ -+ switch (cmd) { -+ case OSS_GETVERSION: -+ return put_user(SOUND_VERSION, up); -+ -+ case SNDCTL_DSP_SPEED: -+ if (get_user(val, up)) -+ return -EFAULT; -+ if (val >= 0) { -+ abdac_stop(dac); -+ ret = abdac_set_sample_rate(dac, val); -+ if (ret) -+ return ret; -+ } -+ return put_user(dac->dsp_settings.sample_rate, up); -+ -+ case SNDCTL_DSP_STEREO: -+ if (get_user(val, up)) -+ return -EFAULT; -+ abdac_stop(dac); -+ if (val && dac->dsp_settings.channels == 1) -+ dac->dsp_settings.input_order++; -+ else if (!val && dac->dsp_settings.channels != 1) -+ dac->dsp_settings.input_order--; -+ dac->dsp_settings.channels = val ? 2 : 1; -+ return 0; -+ -+ case SNDCTL_DSP_CHANNELS: -+ if (get_user(val, up)) -+ return -EFAULT; -+ -+ if (val) { -+ if (val < 0 || val > 2) -+ return -EINVAL; -+ -+ abdac_stop(dac); -+ dac->dsp_settings.input_order -+ += val - dac->dsp_settings.channels; -+ dac->dsp_settings.channels = val; -+ } -+ return put_user(val, (int *)arg); -+ -+ case SNDCTL_DSP_GETFMTS: -+ return put_user(AFMT_S16_BE | AFMT_S16_BE, up); -+ -+ case SNDCTL_DSP_SETFMT: -+ if (get_user(val, up)) -+ return -EFAULT; -+ -+ if (val == AFMT_QUERY) { -+ val = dac->dsp_settings.format; -+ } else { -+ ret = abdac_set_format(dac, val); -+ if (ret) -+ return ret; -+ } -+ return put_user(val, up); -+ -+ case SNDCTL_DSP_GETOSPACE: -+ abdac_update_dma_tail(dac); -+ abinfo.fragsize = ((1 << dac->dsp_settings.input_order) -+ * (DMA_PERIOD_SIZE / 4)); -+ abinfo.bytes = (abdac_dma_space(dac) -+ << dac->dsp_settings.input_order); -+ abinfo.fragstotal = ((DMA_BUFFER_SIZE * 4) -+ >> (DMA_PERIOD_SHIFT -+ + dac->dsp_settings.input_order)); -+ abinfo.fragments = ((abinfo.bytes -+ >> dac->dsp_settings.input_order) -+ / (DMA_PERIOD_SIZE / 4)); -+ pr_debug("fragments=%d fragstotal=%d fragsize=%d bytes=%d\n", -+ abinfo.fragments, abinfo.fragstotal, abinfo.fragsize, -+ abinfo.bytes); -+ return copy_to_user(up, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; -+ -+ default: -+ dev_dbg(&dac->pdev->dev, "Unimplemented ioctl cmd: 0x%x\n", cmd); -+ return -EINVAL; -+ } -+} -+ -+static int abdac_dsp_open(struct inode *inode, struct file *file) -+{ -+ struct at32_dac *dac = the_dac; -+ int ret; -+ -+ if (file->f_mode & FMODE_READ) -+ return -ENXIO; -+ -+ down(&dac->sem); -+ ret = -EBUSY; -+ if (dac->busy) -+ goto out; -+ -+ dac->dma.head = dac->dma.tail = 0; -+ -+ /* FIXME: What are the correct defaults? */ -+ dac->dsp_settings.channels = 2; -+ abdac_set_format(dac, AFMT_S16_BE); -+ ret = abdac_set_sample_rate(dac, 8000); -+ if (ret) -+ goto out; -+ -+ file->private_data = dac; -+ dac->busy = 1; -+ -+ ret = 0; -+ -+out: -+ up(&dac->sem); -+ return ret; -+} -+ -+static int abdac_dsp_release(struct inode *inode, struct file *file) -+{ -+ struct at32_dac *dac = file->private_data; -+ -+ down(&dac->sem); -+ -+ abdac_stop(dac); -+ abdac_dma_cleanup(dac); -+ dac->busy = 0; -+ -+ up(&dac->sem); -+ -+ return 0; -+} -+ -+static struct file_operations abdac_dsp_fops = { -+ .owner = THIS_MODULE, -+ .llseek = no_llseek, -+ .write = abdac_dsp_write, -+ .ioctl = abdac_dsp_ioctl, -+ .open = abdac_dsp_open, -+ .release = abdac_dsp_release, -+}; -+ -+static int __init abdac_probe(struct platform_device *pdev) -+{ -+ struct at32_dac *dac; -+ struct resource *regs; -+ struct clk *mck; -+ struct clk *sample_clk; -+ int irq; -+ int ret; -+ -+ if (the_dac) -+ return -EBUSY; -+ -+ regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!regs) -+ return -ENXIO; -+ irq = platform_get_irq(pdev, 0); -+ if (irq < 0) -+ return irq; -+ -+ mck = clk_get(&pdev->dev, "pclk"); -+ if (IS_ERR(mck)) -+ return PTR_ERR(mck); -+ sample_clk = clk_get(&pdev->dev, "sample_clk"); -+ if (IS_ERR(sample_clk)) { -+ ret = PTR_ERR(sample_clk); -+ goto out_put_mck; -+ } -+ clk_enable(mck); -+ -+ ret = -ENOMEM; -+ dac = kzalloc(sizeof(struct at32_dac), GFP_KERNEL); -+ if (!dac) -+ goto out_disable_clk; -+ -+ spin_lock_init(&dac->lock); -+ init_MUTEX(&dac->sem); -+ init_waitqueue_head(&dac->write_wait); -+ dac->pdev = pdev; -+ dac->mck = mck; -+ dac->sample_clk = sample_clk; -+ -+ dac->regs = ioremap(regs->start, regs->end - regs->start + 1); -+ if (!dac->regs) -+ goto out_free_dac; -+ -+ ret = request_irq(irq, abdac_interrupt, 0, "dac", dac); -+ if (ret) -+ goto out_unmap_regs; -+ -+ /* FIXME */ -+ dac->req.req.dmac = find_dma_controller(0); -+ if (!dac->req.req.dmac) -+ goto out_free_irq; -+ -+ ret = dma_alloc_channel(dac->req.req.dmac); -+ if (ret < 0) -+ goto out_free_irq; -+ -+ dac->req.req.channel = ret; -+ dac->req.req.block_complete = abdac_dma_block_complete; -+ dac->req.req.error = abdac_dma_error; -+ dac->req.data_reg = regs->start + DAC_DATA; -+ dac->req.periph_id = 2; /* FIXME */ -+ dac->req.direction = DMA_DIR_MEM_TO_PERIPH; -+ dac->req.width = DMA_WIDTH_32BIT; -+ -+ /* Make sure the DAC is silent and disabled */ -+ dac_writel(dac, DATA, 0); -+ dac_writel(dac, CTRL, 0); -+ -+ ret = register_sound_dsp(&abdac_dsp_fops, -1); -+ if (ret < 0) -+ goto out_free_dma; -+ dac->dev_dsp = ret; -+ -+ /* TODO: Register mixer */ -+ -+ the_dac = dac; -+ platform_set_drvdata(pdev, dac); -+ -+ return 0; -+ -+out_free_dma: -+ dma_release_channel(dac->req.req.dmac, dac->req.req.channel); -+out_free_irq: -+ free_irq(irq, dac); -+out_unmap_regs: -+ iounmap(dac->regs); -+out_free_dac: -+ kfree(dac); -+out_disable_clk: -+ clk_disable(mck); -+ clk_put(sample_clk); -+out_put_mck: -+ clk_put(mck); -+ return ret; -+} -+ -+static int __exit abdac_remove(struct platform_device *pdev) -+{ -+ struct at32_dac *dac; -+ -+ dac = platform_get_drvdata(pdev); -+ if (dac) { -+ unregister_sound_dsp(dac->dev_dsp); -+ dma_release_channel(dac->req.req.dmac, dac->req.req.channel); -+ free_irq(platform_get_irq(pdev, 0), dac); -+ iounmap(dac->regs); -+ clk_disable(dac->mck); -+ clk_put(dac->sample_clk); -+ clk_put(dac->mck); -+ kfree(dac); -+ platform_set_drvdata(pdev, NULL); -+ the_dac = NULL; -+ } -+ -+ return 0; -+} -+ -+static struct platform_driver abdac_driver = { -+ .remove = __exit_p(abdac_remove), -+ .driver = { -+ .name = "abdac", -+ }, -+}; -+ -+static int __init abdac_init(void) -+{ -+ return platform_driver_probe(&abdac_driver, abdac_probe); -+} -+module_init(abdac_init); -+ -+static void __exit abdac_exit(void) -+{ -+ platform_driver_unregister(&abdac_driver); -+} -+module_exit(abdac_exit); -+ -+MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); -+MODULE_DESCRIPTION("Sound Driver for the Atmel AT32 ABDAC"); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/sound/oss/at32_abdac.h -@@ -0,0 +1,59 @@ -+/* -+ * Register definitions for the Atmel AT32 on-chip DAC. -+ * -+ * Copyright (C) 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. -+ */ -+#ifndef __SOUND_OSS_AT32_ABDAC_H__ -+#define __SOUND_OSS_AT32_ABDAC_H__ -+ -+/* DAC register offsets */ -+#define DAC_DATA 0x0000 -+#define DAC_CTRL 0x0008 -+#define DAC_INT_MASK 0x000c -+#define DAC_INT_EN 0x0010 -+#define DAC_INT_DIS 0x0014 -+#define DAC_INT_CLR 0x0018 -+#define DAC_INT_STATUS 0x001c -+#define DAC_PDC_DATA 0x0020 -+ -+/* Bitfields in CTRL */ -+#define DAC_SWAP_OFFSET 30 -+#define DAC_SWAP_SIZE 1 -+#define DAC_EN_OFFSET 31 -+#define DAC_EN_SIZE 1 -+ -+/* Bitfields in INT_MASK/INT_EN/INT_DIS/INT_STATUS/INT_CLR */ -+#define DAC_UNDERRUN_OFFSET 28 -+#define DAC_UNDERRUN_SIZE 1 -+#define DAC_TX_READY_OFFSET 29 -+#define DAC_TX_READY_SIZE 1 -+#define DAC_TX_BUFFER_EMPTY_OFFSET 30 -+#define DAC_TX_BUFFER_EMPTY_SIZE 1 -+#define DAC_CHANNEL_TX_END_OFFSET 31 -+#define DAC_CHANNEL_TX_END_SIZE 1 -+ -+/* Bit manipulation macros */ -+#define DAC_BIT(name) \ -+ (1 << DAC_##name##_OFFSET) -+#define DAC_BF(name, value) \ -+ (((value) & ((1 << DAC_##name##_SIZE) - 1)) \ -+ << DAC_##name##_OFFSET) -+#define DAC_BFEXT(name, value) \ -+ (((value) >> DAC_##name##_OFFSET) \ -+ & ((1 << DAC_##name##_SIZE) - 1)) -+#define DAC_BFINS(name, value, old) \ -+ (((old) & ~(((1 << DAC_##name##_SIZE) - 1) \ -+ << DAC_##name##_OFFSET)) \ -+ | DAC_BF(name,value)) -+ -+/* Register access macros */ -+#define dac_readl(port, reg) \ -+ __raw_readl((port)->regs + DAC_##reg) -+#define dac_writel(port, reg, value) \ -+ __raw_writel((value), (port)->regs + DAC_##reg) -+ -+#endif /* __SOUND_OSS_AT32_ABDAC_H__ */ ---- a/sound/spi/at73c213.c -+++ b/sound/spi/at73c213.c -@@ -737,7 +737,7 @@ cleanup: - /* - * Device functions - */ --static int snd_at73c213_ssc_init(struct snd_at73c213 *chip) -+static int __devinit snd_at73c213_ssc_init(struct snd_at73c213 *chip) - { - /* - * Continuous clock output. -@@ -767,7 +767,7 @@ static int snd_at73c213_ssc_init(struct - return 0; - } - --static int snd_at73c213_chip_init(struct snd_at73c213 *chip) -+static int __devinit snd_at73c213_chip_init(struct snd_at73c213 *chip) - { - int retval; - unsigned char dac_ctrl = 0; -@@ -933,7 +933,7 @@ out: - return retval; - } - --static int snd_at73c213_probe(struct spi_device *spi) -+static int __devinit snd_at73c213_probe(struct spi_device *spi) - { - struct snd_card *card; - struct snd_at73c213 *chip; |