diff -x .git -Nur linux-2.6.22.1/arch/avr32/boards/atngw100/Kconfig linux-avr32.git/arch/avr32/boards/atngw100/Kconfig --- linux-2.6.22.1/arch/avr32/boards/atngw100/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-avr32.git/arch/avr32/boards/atngw100/Kconfig 2007-07-13 11:24:16.000000000 +0200 @@ -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. diff -x .git -Nur linux-2.6.22.1/arch/avr32/boards/atngw100/setup.c linux-avr32.git/arch/avr32/boards/atngw100/setup.c --- linux-2.6.22.1/arch/avr32/boards/atngw100/setup.c 2007-07-10 20:56:30.000000000 +0200 +++ linux-avr32.git/arch/avr32/boards/atngw100/setup.c 2007-07-13 11:24:16.000000000 +0200 @@ -9,10 +9,12 @@ */ #include #include +#include #include #include #include #include +#include #include #include @@ -21,6 +23,7 @@ #include #include #include +#include /* Initialized by bootloader-specific startup code. */ struct tag *bootloader_tags __initdata; @@ -39,6 +42,11 @@ }, }; +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 @@ -100,8 +108,46 @@ at32_setup_serial_console(0); } +static const struct gpio_led ngw_leds[] = { + { .name = "sys", .gpio = GPIO_PIN_PA(16), .active_low = 1, + .default_trigger = "heartbeat", + }, + { .name = "a", .gpio = GPIO_PIN_PA(19), .active_low = 1, }, + { .name = "b", .gpio = GPIO_PIN_PE(19), .active_low = 1, }, +}; + +static const struct gpio_led_platform_data ngw_led_data = { + .num_leds = ARRAY_SIZE(ngw_leds), + .leds = (void *) ngw_leds, +}; + +static struct platform_device ngw_gpio_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = (void *) &ngw_led_data, + } +}; + +#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), +}; + +static struct platform_device i2c_gpio_device = { + .name = "i2c-gpio", + .id = 0, + .dev = { + .platform_data = &i2c_gpio_data, + }, +}; +#endif + static int __init atngw100_init(void) { + unsigned i; + /* * ATNGW100 uses 16-bit SDRAM interface, so we don't need to * reserve any pins for it. @@ -115,6 +161,22 @@ 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++) { + at32_select_gpio(ngw_leds[i].gpio, + AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH); + } + platform_device_register(&ngw_gpio_leds); + +#ifdef CONFIG_BOARD_ATNGW100_I2C_GPIO + at32_select_gpio(i2c_gpio_data.sda_pin, 0); + at32_select_gpio(i2c_gpio_data.scl_pin, 0); + platform_device_register(&i2c_gpio_device); +#else + at32_add_device_twi(0); +#endif return 0; } diff -x .git -Nur linux-2.6.22.1/arch/avr32/boards/atstk1000/atstk1002.c linux-avr32.git/arch/avr32/boards/atstk1000/atstk1002.c --- linux-2.6.22.1/arch/avr32/boards/atstk1000/atstk1002.c 2007-07-10 20:56:30.000000000 +0200 +++ linux-avr32.git/arch/avr32/boards/atstk1000/atstk1002.c 2007-07-12 13:59:49.000000000 +0200 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -27,7 +28,6 @@ #include "atstk1000.h" -#define SW2_DEFAULT /* MMCI and UART_A available */ struct eth_addr { u8 addr[6]; @@ -36,6 +36,7 @@ static struct eth_addr __initdata hw_addr[2]; static struct eth_platform_data __initdata eth_data[2]; +#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM static struct spi_board_info spi0_board_info[] __initdata = { { /* QVGA display */ @@ -45,6 +46,18 @@ .mode = SPI_MODE_3, }, }; +#endif + +#ifdef CONFIG_BOARD_ATSTK1002_SPI1 +static struct spi_board_info spi1_board_info[] __initdata = { { + /* patch in custom entries here */ +} }; +#endif + +static struct mci_platform_data __initdata mci0_data = { + .detect_pin = GPIO_PIN_NONE, + .wp_pin = GPIO_PIN_NONE, +}; /* * The next two functions should go away as the boot loader is @@ -101,12 +114,71 @@ clk_put(pclk); } -void __init setup_board(void) +#ifdef CONFIG_BOARD_ATSTK1002_J2_LED + +static struct gpio_led stk_j2_led[] = { +#ifdef CONFIG_BOARD_ATSTK1002_J2_LED8 +#define LEDSTRING "J2 jumpered to LED8" + { .name = "led0:amber", .gpio = GPIO_PIN_PB( 8), }, + { .name = "led1:amber", .gpio = GPIO_PIN_PB( 9), }, + { .name = "led2:amber", .gpio = GPIO_PIN_PB(10), }, + { .name = "led3:amber", .gpio = GPIO_PIN_PB(13), }, + { .name = "led4:amber", .gpio = GPIO_PIN_PB(14), }, + { .name = "led5:amber", .gpio = GPIO_PIN_PB(15), }, + { .name = "led6:amber", .gpio = GPIO_PIN_PB(16), }, + { .name = "led7:amber", .gpio = GPIO_PIN_PB(30), + .default_trigger = "heartbeat", }, +#else /* RGB */ +#define LEDSTRING "J2 jumpered to RGB LEDs" + { .name = "r1:red", .gpio = GPIO_PIN_PB( 8), }, + { .name = "g1:green", .gpio = GPIO_PIN_PB(10), }, + { .name = "b1:blue", .gpio = GPIO_PIN_PB(14), }, + + { .name = "r2:red", .gpio = GPIO_PIN_PB( 9), + .default_trigger = "heartbeat", }, + { .name = "g2:green", .gpio = GPIO_PIN_PB(13), }, + { .name = "b2:blue", .gpio = GPIO_PIN_PB(15), + .default_trigger = "heartbeat", }, + /* PB16, PB30 unused */ +#endif +}; + +static struct gpio_led_platform_data stk_j2_led_data = { + .num_leds = ARRAY_SIZE(stk_j2_led), + .leds = stk_j2_led, +}; + +static struct platform_device stk_j2_led_dev = { + .name = "leds-gpio", + .id = 2, /* gpio block J2 */ + .dev = { + .platform_data = &stk_j2_led_data, + }, +}; + +static void setup_j2_leds(void) { -#ifdef SW2_DEFAULT - at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */ + unsigned i; + + for (i = 0; i < ARRAY_SIZE(stk_j2_led); i++) + at32_select_gpio(stk_j2_led[i].gpio, AT32_GPIOF_OUTPUT); + + printk("STK1002: " LEDSTRING "\n"); + platform_device_register(&stk_j2_led_dev); +} + #else +static void setup_j2_leds(void) +{ +} +#endif + +void __init setup_board(void) +{ +#ifdef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM at32_map_usart(0, 1); /* USART 0/B: /dev/ttyS1, IRDA */ +#else + at32_map_usart(1, 0); /* USART 1/A: /dev/ttyS0, DB9 */ #endif /* USART 2/unused: expansion connector */ at32_map_usart(3, 2); /* USART 3/C: /dev/ttyS2, DB9 */ @@ -140,18 +212,40 @@ at32_add_system_devices(); -#ifdef SW2_DEFAULT - at32_add_device_usart(0); -#else +#ifdef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM at32_add_device_usart(1); +#else + at32_add_device_usart(0); #endif at32_add_device_usart(2); +#ifndef CONFIG_BOARD_ATSTK1002_SW6_CUSTOM set_hw_addr(at32_add_device_eth(0, ð_data[0])); - - at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); +#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); +#endif + +#ifndef CONFIG_BOARD_ATSTK1002_SW1_CUSTOM + at32_add_device_spi(0, spi0_board_info, ARRAY_SIZE(spi0_board_info)); +#endif +#ifdef CONFIG_BOARD_ATSTK1002_SPI1 + at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info)); +#endif + at32_add_device_twi(0); +#ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM + at32_add_device_mci(0, &mci0_data); +#endif + at32_add_device_usba(0, NULL); + at32_add_device_abdac(0); +#ifndef CONFIG_BOARD_ATSTK1002_SW3_CUSTOM + at32_add_device_ssc(0, ATMEL_SSC_TX); +#endif + + setup_j2_leds(); return 0; } diff -x .git -Nur linux-2.6.22.1/arch/avr32/boards/atstk1000/Kconfig linux-avr32.git/arch/avr32/boards/atstk1000/Kconfig --- linux-2.6.22.1/arch/avr32/boards/atstk1000/Kconfig 1970-01-01 01:00:00.000000000 +0100 +++ linux-avr32.git/arch/avr32/boards/atstk1000/Kconfig 2007-07-12 13:59:49.000000000 +0200 @@ -0,0 +1,79 @@ +# STK1000 customization + +if BOARD_ATSTK1002 + +config BOARD_ATSTK1002_CUSTOM + bool "Non-default STK-1002 jumper settings" + help + You will normally leave the jumpers on the CPU card at their + default settings. If you need to use certain peripherals, + you will need to change some of those jumpers. + +if BOARD_ATSTK1002_CUSTOM + +config BOARD_ATSTK1002_SW1_CUSTOM + bool "SW1: use SSC1 (not SPI0)" + help + This also prevents using the external DAC as an audio interface, + and means you can't initialize the on-board QVGA display. + +config BOARD_ATSTK1002_SW2_CUSTOM + bool "SW2: use IRDA or TIMER0 (not UART-A, MMC/SD, and PS2-A)" + help + If you change this you'll want an updated boot loader putting + the console on UART-C not UART-A. + +config BOARD_ATSTK1002_SW3_CUSTOM + bool "SW3: use TIMER1 (not SSC0 and GCLK)" + help + This also prevents using the external DAC as an audio interface. + +config BOARD_ATSTK1002_SW4_CUSTOM + bool "SW4: use ISI/Camera (not GPIOs, SPI1, and PS2-B)" + help + To use the camera interface you'll need a custom card (on the + PCI-format connector) connect a video sensor. + +config BOARD_ATSTK1002_SW5_CUSTOM + bool "SW5: use MACB1 (not LCDC)" + +config BOARD_ATSTK1002_SW6_CUSTOM + bool "SW6: more GPIOs (not MACB0)" + +endif # custom + +config BOARD_ATSTK1002_SPI1 + bool "Configure SPI1 controller" + depends on !BOARD_ATSTK1002_SW4_CUSTOM + help + All the signals for the second SPI controller are available on + GPIO lines and accessed through the J1 jumper block. Say "y" + here to configure that SPI controller. + +config BOARD_ATSTK1002_J2_LED + bool + default BOARD_ATSTK1002_J2_LED8 || BOARD_ATSTK1002_J2_RGB + +choice + prompt "LEDs connected to J2:" + depends on LEDS_GPIO && !BOARD_ATSTK1002_SW4_CUSTOM + optional + help + Select this if you have jumpered the J2 jumper block to the + LED0..LED7 amber leds, or to the RGB leds, using a ten-pin + IDC cable. A default "heartbeat" trigger is provided, but + you can of course override this. + +config BOARD_ATSTK1002_J2_LED8 + bool "LED0..LED7" + help + Select this if J2 is jumpered to LED0..LED7 amber leds. + +config BOARD_ATSTK1002_J2_RGB + bool "RGB leds" + help + Select this if J2 is jumpered to the RGB leds. + +endchoice + +endif # stk 1002 diff -x .git -Nur linux-2.6.22.1/arch/avr32/configs/atngw100_defconfig linux-avr32.git/arch/avr32/configs/atngw100_defconfig --- linux-2.6.22.1/arch/avr32/configs/atngw100_defconfig 2007-07-10 20:56:30.000000000 +0200 +++ linux-avr32.git/arch/avr32/configs/atngw100_defconfig 2007-07-13 11:24:16.000000000 +0200 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22-rc5 -# Sat Jun 23 15:40:05 2007 +# Linux kernel version: 2.6.22.atmel.1 +# Thu Jul 12 17:49:20 2007 # CONFIG_AVR32=y CONFIG_GENERIC_GPIO=y @@ -114,6 +114,7 @@ CONFIG_CPU_AT32AP7000=y # CONFIG_BOARD_ATSTK1000 is not set CONFIG_BOARD_ATNGW100=y +# CONFIG_BOARD_ATNGW100_I2C_GPIO is not set CONFIG_LOADER_U_BOOT=y # @@ -122,6 +123,7 @@ # CONFIG_AP7000_32_BIT_SMC is not set CONFIG_AP7000_16_BIT_SMC=y # CONFIG_AP7000_8_BIT_SMC is not set +CONFIG_GPIO_DEV=y CONFIG_LOAD_ADDRESS=0x10000000 CONFIG_ENTRY_ADDRESS=0x90000000 CONFIG_PHYS_OFFSET=0x10000000 @@ -145,6 +147,7 @@ # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 # CONFIG_OWNERSHIP_TRACE is not set +CONFIG_DW_DMAC=y # CONFIG_HZ_100 is not set CONFIG_HZ_250=y # CONFIG_HZ_300 is not set @@ -153,6 +156,27 @@ CONFIG_CMDLINE="" # +# Power managment options +# + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=m +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +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 @@ -187,13 +211,8 @@ # CONFIG_NET_KEY_MIGRATE is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set +# CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_FIB_HASH=y -# CONFIG_IP_MULTIPLE_TABLES is not set -# CONFIG_IP_ROUTE_MULTIPATH is not set -# CONFIG_IP_ROUTE_VERBOSE is not set CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y # CONFIG_IP_PNP_BOOTP is not set @@ -240,6 +259,7 @@ # CONFIG_NETWORK_SECMARK is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y # # Core Netfilter Configuration @@ -284,6 +304,7 @@ 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 @@ -359,13 +380,19 @@ 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 # CONFIG_ATM is not set -# CONFIG_BRIDGE is not set +CONFIG_BRIDGE=m CONFIG_VLAN_8021Q=m # CONFIG_DECNET is not set +CONFIG_LLC=m # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -521,7 +548,6 @@ # # Misc devices # -# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -545,13 +571,26 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set CONFIG_TUN=m -# CONFIG_PHYLIB 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_FIXED_PHY is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MII=y +# CONFIG_MII is not set CONFIG_MACB=y # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set @@ -625,7 +664,15 @@ # IPMI # # CONFIG_IPMI_HANDLER is not set -# CONFIG_WATCHDOG 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 +CONFIG_AT32AP700X_WDT_TIMEOUT=2 # CONFIG_HW_RANDOM is not set # CONFIG_RTC is not set # CONFIG_GEN_RTC is not set @@ -636,7 +683,42 @@ # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_I2C 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_ATMELTWI_BAUDRATE=100000 +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_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 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 @@ -655,7 +737,7 @@ # SPI Protocol Masters # # CONFIG_SPI_AT25 is not set -# CONFIG_SPI_SPIDEV is not set +CONFIG_SPI_SPIDEV=m # # Dallas's 1-wire bus @@ -706,21 +788,59 @@ # # USB Gadget Support # -# CONFIG_USB_GADGET is not set -# CONFIG_MMC is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=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_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +CONFIG_USB_GADGET_ATMEL_USBA=y +CONFIG_USB_ATMEL_USBA=y +# CONFIG_USB_GADGET_OMAP 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_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_ATMELMCI=y # # LED devices # -# CONFIG_NEW_LEDS is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y # # LED drivers # +CONFIG_LEDS_GPIO=y # # LED Triggers # +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y # # InfiniBand support @@ -733,7 +853,51 @@ # # Real Time Clock # -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +# CONFIG_RTC_DEBUG is not set + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=y +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +# CONFIG_RTC_DRV_TEST is not set + +# +# I2C RTC drivers +# +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_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 + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_MAX6902 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_AT32AP700X=y # # DMA Engine support @@ -767,7 +931,8 @@ # CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set -# CONFIG_INOTIFY 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 @@ -922,7 +1087,7 @@ CONFIG_ENABLE_MUST_CHECK=y CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set +CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set diff -x .git -Nur linux-2.6.22.1/arch/avr32/configs/atstk1002_defconfig linux-avr32.git/arch/avr32/configs/atstk1002_defconfig --- linux-2.6.22.1/arch/avr32/configs/atstk1002_defconfig 2007-07-10 20:56:30.000000000 +0200 +++ linux-avr32.git/arch/avr32/configs/atstk1002_defconfig 2007-07-13 11:24:16.000000000 +0200 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.22-rc5 -# Sat Jun 23 15:32:08 2007 +# Linux kernel version: 2.6.22.atmel.1 +# Thu Jul 12 19:34:17 2007 # CONFIG_AVR32=y CONFIG_GENERIC_GPIO=y @@ -80,10 +80,10 @@ # CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set +CONFIG_KMOD=y # # Block layer @@ -99,12 +99,12 @@ CONFIG_IOSCHED_NOOP=y # CONFIG_IOSCHED_AS is not set # CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set +CONFIG_IOSCHED_CFQ=y # CONFIG_DEFAULT_AS is not set # CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="cfq" # # System Type and features @@ -117,6 +117,11 @@ CONFIG_BOARD_ATSTK1002=y CONFIG_BOARD_ATSTK1000=y # CONFIG_BOARD_ATNGW100 is not set +# CONFIG_BOARD_ATSTK1002_CUSTOM is not set +# CONFIG_BOARD_ATSTK1002_SPI1 is not set +# CONFIG_BOARD_ATSTK1002_J2_LED is not set +# CONFIG_BOARD_ATSTK1002_J2_LED8 is not set +# CONFIG_BOARD_ATSTK1002_J2_RGB is not set CONFIG_LOADER_U_BOOT=y # @@ -125,6 +130,7 @@ # CONFIG_AP7000_32_BIT_SMC is not set CONFIG_AP7000_16_BIT_SMC=y # CONFIG_AP7000_8_BIT_SMC is not set +CONFIG_GPIO_DEV=y CONFIG_LOAD_ADDRESS=0x10000000 CONFIG_ENTRY_ADDRESS=0x90000000 CONFIG_PHYS_OFFSET=0x10000000 @@ -148,6 +154,7 @@ # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 # CONFIG_OWNERSHIP_TRACE is not set +CONFIG_DW_DMAC=y # CONFIG_HZ_100 is not set CONFIG_HZ_250=y # CONFIG_HZ_300 is not set @@ -156,6 +163,27 @@ CONFIG_CMDLINE="" # +# Power managment options +# + +# +# CPU Frequency scaling +# +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_TABLE=y +# CONFIG_CPU_FREQ_DEBUG is not set +CONFIG_CPU_FREQ_STAT=m +# CONFIG_CPU_FREQ_STAT_DETAILS is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +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 @@ -327,6 +355,8 @@ # # Self-contained MTD device drivers # +CONFIG_MTD_DATAFLASH=m +# CONFIG_MTD_M25P80 is not set # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set @@ -373,7 +403,6 @@ # # Misc devices # -# CONFIG_BLINK is not set # CONFIG_IDE is not set # @@ -397,13 +426,26 @@ # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set CONFIG_TUN=m -# CONFIG_PHYLIB 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=y +# 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_FIXED_PHY is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MII=y +# CONFIG_MII is not set CONFIG_MACB=y # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set @@ -443,7 +485,42 @@ # # Input device support # -# CONFIG_INPUT is not set +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_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# 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 @@ -477,7 +554,15 @@ # IPMI # # CONFIG_IPMI_HANDLER is not set -# CONFIG_WATCHDOG 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 +CONFIG_AT32AP700X_WDT_TIMEOUT=2 # CONFIG_HW_RANDOM is not set # CONFIG_RTC is not set # CONFIG_GEN_RTC is not set @@ -488,13 +573,61 @@ # TPM devices # # CONFIG_TCG_TPM is not set -# CONFIG_I2C 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_ATMELTWI_BAUDRATE=100000 +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_STUB is not set + +# +# Miscellaneous I2C Chip support +# +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set +# CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_MAX6875 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 is not set -# CONFIG_SPI_MASTER is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +CONFIG_SPI_ATMEL=y +# CONFIG_SPI_BITBANG is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_AT25 is not set +CONFIG_SPI_SPIDEV=m # # Dallas's 1-wire bus @@ -517,14 +650,40 @@ # # Graphics support # -# CONFIG_BACKLIGHT_LCD_SUPPORT 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_VGASTATE is not set -# CONFIG_FB 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_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_LOGO is not set # # Sound @@ -532,6 +691,11 @@ # CONFIG_SOUND is not set # +# HID Devices +# +# CONFIG_HID is not set + +# # USB support # # CONFIG_USB_ARCH_HAS_HCD is not set @@ -545,21 +709,59 @@ # # USB Gadget Support # -# CONFIG_USB_GADGET is not set -# CONFIG_MMC is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG_FILES is not set +CONFIG_USB_GADGET_SELECTED=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_GOKU is not set +# CONFIG_USB_GADGET_LH7A40X is not set +CONFIG_USB_GADGET_ATMEL_USBA=y +CONFIG_USB_ATMEL_USBA=y +# CONFIG_USB_GADGET_OMAP 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_MMC=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_UNSAFE_RESUME is not set + +# +# MMC/SD Card Drivers +# +CONFIG_MMC_BLOCK=y + +# +# MMC/SD Host Controller Drivers +# +CONFIG_MMC_ATMELMCI=y # # LED devices # -# CONFIG_NEW_LEDS is not set +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m # # LED drivers # +CONFIG_LEDS_GPIO=m # # LED Triggers # +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=m # # InfiniBand support @@ -572,7 +774,50 @@ # # Real Time Clock # -# CONFIG_RTC_CLASS is not set +CONFIG_RTC_LIB=y +CONFIG_RTC_CLASS=y +# CONFIG_RTC_HCTOSYS is not set +# 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_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 + +# +# SPI RTC drivers +# +# CONFIG_RTC_DRV_RS5C348 is not set +# CONFIG_RTC_DRV_MAX6902 is not set + +# +# Platform RTC drivers +# +# CONFIG_RTC_DRV_DS1553 is not set +# CONFIG_RTC_DRV_DS1742 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_V3020 is not set + +# +# on-CPU RTC drivers +# +CONFIG_RTC_DRV_AT32AP700X=y # # DMA Engine support @@ -590,11 +835,14 @@ # # 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 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 @@ -609,7 +857,7 @@ # CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set +CONFIG_FUSE_FS=m # # CD-ROM/DVD Filesystems @@ -638,7 +886,7 @@ # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -CONFIG_CONFIGFS_FS=m +CONFIG_CONFIGFS_FS=y # # Miscellaneous filesystems @@ -683,8 +931,14 @@ # 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_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_WEAK_PW_HASH is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_DEBUG2 is not set +# CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set diff -x .git -Nur linux-2.6.22.1/arch/avr32/drivers/dw-dmac.c linux-avr32.git/arch/avr32/drivers/dw-dmac.c --- linux-2.6.22.1/arch/avr32/drivers/dw-dmac.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-avr32.git/arch/avr32/drivers/dw-dmac.c 2007-07-13 11:24:16.000000000 +0200 @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 "); +MODULE_LICENSE("GPL"); diff -x .git -Nur linux-2.6.22.1/arch/avr32/drivers/dw-dmac.h linux-avr32.git/arch/avr32/drivers/dw-dmac.h --- linux-2.6.22.1/arch/avr32/drivers/dw-dmac.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-avr32.git/arch/avr32/drivers/dw-dmac.h 2007-06-06 11:33:46.000000000 +0200 @@ -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__ */ diff -x .git -Nur linux-2.6.22.1/arch/avr32/drivers/Makefile linux-avr32.git/arch/avr32/drivers/Makefile --- linux-2.6.22.1/arch/avr32/drivers/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-avr32.git/arch/avr32/drivers/Makefile 2007-06-06 11:33:46.000000000 +0200 @@ -0,0 +1 @@ +obj-$(CONFIG_DW_DMAC) += dw-dmac.o diff -x .git -Nur linux-2.6.22.1/arch/avr32/Kconfig linux-avr32.git/arch/avr32/Kconfig --- linux-2.6.22.1/arch/avr32/Kconfig 2007-07-10 20:56:30.000000000 +0200 +++ linux-avr32.git/arch/avr32/Kconfig 2007-07-13 11:24:16.000000000 +0200 @@ -113,6 +113,13 @@ bool "ATNGW100 Network Gateway" 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" default LOADER_U_BOOT @@ -171,6 +178,10 @@ enabling Nexus-compliant debuggers to keep track of the PID of the currently executing task. +config DW_DMAC + tristate "Synopsys DesignWare DMA Controller support" + default y if CPU_AT32AP7000 + # FPU emulation goes here source "kernel/Kconfig.hz" @@ -185,6 +196,27 @@ endmenu +menu "Power managment options" + +menu "CPU Frequency scaling" + +source "drivers/cpufreq/Kconfig" + +config CPU_FREQ_AT32AP + bool "CPU frequency driver for AT32AP" + depends on CPU_FREQ && PLATFORM_AT32AP + default n + help + This enables the CPU frequency driver for AT32AP processors. + + For details, take a look in . + + If in doubt, say N. + +endmenu + +endmenu + menu "Bus options" config PCI diff -x .git -Nur linux-2.6.22.1/arch/avr32/kernel/dma-controller.c linux-avr32.git/arch/avr32/kernel/dma-controller.c --- linux-2.6.22.1/arch/avr32/kernel/dma-controller.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-avr32.git/arch/avr32/kernel/dma-controller.c 2007-06-06 11:33:46.000000000 +0200 @@ -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 + +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); diff -x .git -Nur linux-2.6.22.1/arch/avr32/kernel/Makefile linux-avr32.git/arch/avr32/kernel/Makefile --- linux-2.6.22.1/arch/avr32/kernel/Makefile 2007-07-10 20:56:30.000000000 +0200 +++ linux-avr32.git/arch/avr32/kernel/Makefile 2007-06-06 11:33:46.000000000 +0200 @@ -9,6 +9,7 @@ obj-y += setup.o traps.o semaphore.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 diff -x .git -Nur linux-2.6.22.1/arch/avr32/mach-at32ap/at32ap7000.c linux-avr32.git/arch/avr32/mach-at32ap/at32ap7000.c --- linux-2.6.22.1/arch/avr32/mach-at32ap/at32ap7000.c 2007-07-10 20:56:30.000000000 +0200 +++ linux-avr32.git/arch/avr32/mach-at32ap/at32ap7000.c 2007-07-12 13:59:49.000000000 +0200 @@ -17,14 +17,20 @@ #include #include #include -#include #include