propagate from branch 'org.openembedded.dev' (head a6b798a43c05aef43ed650ab880f3edd38...
authorKoen Kooi <koen@openembedded.org>
Wed, 31 Oct 2007 13:46:47 +0000 (13:46 +0000)
committerKoen Kooi <koen@openembedded.org>
Wed, 31 Oct 2007 13:46:47 +0000 (13:46 +0000)
            to branch 'org.openembedded.dev.avr32' (head 77e1041de2eef682f183f3f5199826818cb9c5b1)

152 files changed:
conf/distro/angstrom-2008.1.conf
conf/machine/at32stk1000.conf
conf/machine/atngw100.conf
packages/avahi/avahi_0.6.21.bb
packages/avahi/files/avr32-ipv6-fix.patch [new file with mode: 0644]
packages/binutils/binutils-2.17/503-avr32-fix-got-offset-init.patch [new file with mode: 0644]
packages/binutils/binutils_2.17.bb
packages/busybox/busybox-1.2.1/avr32/.mtn2git_empty [new file with mode: 0644]
packages/busybox/busybox-1.2.1/avr32/defconfig [new file with mode: 0644]
packages/busybox/busybox-1.2.1/install-should-unlink-dest-if-it-exists.patch [new file with mode: 0644]
packages/busybox/busybox_1.2.1.bb
packages/busybox/files/install-should-unlink-dest-if-it-exists.patch [new file with mode: 0644]
packages/gcc/avr32-gcc-cross_4.1.2.bb [new file with mode: 0644]
packages/gcc/avr32-gcc_4.1.2.bb [new file with mode: 0644]
packages/gcc/gcc-cross_4.1.2.bb
packages/gcc/gcc-package-cross.inc
packages/gcc/gcc_4.1.2.bb
packages/libmad/files/.mtn2git_empty [new file with mode: 0644]
packages/libmad/files/libmad-0.15.1b-avr32-optimization.patch [new file with mode: 0644]
packages/libmad/libmad_0.15.1b.bb
packages/linux/linux-2.6.18/.mtn2git_empty [new file with mode: 0644]
packages/linux/linux-2.6.18/0001-AVR32-Fix-compile-error-with-gcc-4.1.patch [new file with mode: 0755]
packages/linux/linux-2.6.18/add-all-parameters-to-smc-driver.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/add-default-atngw-defconfig.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/add-flush_buffer-operation-to-uart_ops.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/add-hmatrix-support.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/add-ide-header.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/add-intc_pending_irq-to-intc.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/add-mach-specific-kconfig.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/at32-dac-oss-driver-clk-fix.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/at32-dac-oss-driver.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/at32ap7000-dmac-driver.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/at32ap7000-platform_device-definitions.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/at32stk1000/.mtn2git_empty [new file with mode: 0644]
packages/linux/linux-2.6.18/at32stk1000/defconfig [new file with mode: 0644]
packages/linux/linux-2.6.18/at73c213-alsa-driver.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atmel-ac97c-alsa-driver.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atmel-husb2-udc-driver.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atmel-lcdc-framebuffer-driver.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atmel-macb-ethernet-driver.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atmel-mci-debugfs.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atmel-mci-init-nr_blocks-in-dma-request.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atmel-mmc-host-driver.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atmel-spi-master-driver.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atmel-twi-driver.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atmel-usart3-driver.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atmel-version.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atmel_spi-handle-rx-overrun.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atmel_spi-send-zeroes-when-tx_buf-is-not-set.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atngw100/.mtn2git_empty [new file with mode: 0644]
packages/linux/linux-2.6.18/atngw100/defconfig [new file with mode: 0644]
packages/linux/linux-2.6.18/atstk1000-add-platform-data-for-mmc.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atstk1000-board-fix-fbmem-setup.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/atstk1000-instantiate-devices.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-arch-neutral-gpio-api.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-arch.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-checkstack.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-dma-controller-framework.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-dont-include-asm-delay-h.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-drop-GFP_COMP-for-DMA-memory-allocations.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-fix-oprofile-interrupts.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-gpio-dev.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-increment-pointer-when-parsing-for-fbmem_start.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-little-endian-read-write-bwl.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-move-ethernet-tag-parsing-to-board-specific-code.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-network-gateway-support.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-oprofile.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-sound.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-time-add-shared-interrupts.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32-unistd-h-move-ifdef-kernel.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/avr32_defconfig [new file with mode: 0644]
packages/linux/linux-2.6.18/dmac-add-explicit-blockcount-to-dma_request_sg.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/dmac-stopping-idle-channel-is-not-fatal.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/dont-include-map-h-from-physmap-h.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/fix-alpha-color-bitfield.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/fix-gpio-prototypes.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/fix-lcd-display-off-by-two-problem.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/fix-usart3-rx-BUG.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/gpio-define-pio-none.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/gpio-dev-blocking-read.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/gpio-dev-robustness.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/husb2_udc-test-mode.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/jffs2_can_mark_obsolete-should-return-0-for-dataflash.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/kbuild-add-unifdef.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/kbuild-replace-use-of-strlcpy-with-a-dedicated-implmentation-in-unifdef.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/kbuild-use-in-kernel-unifdef.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/lcdc-do-not-clear-mem-if-fbmem_start-is-set.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/lcdc-fix-possible-null-pointer-and-match-guard-time-to-uboot.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/lcdc-wait-for-vsync.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/ltv350qv-add-initial_power_state-param.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/ltv350qv-lcd-driver.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/mmc-add-bit-manipulating-macros.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/mmc-add-detect-card-and-wp-support.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/mmc-add-platform-data.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/mmc-core-dma-fix.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/mtd-fix-atmel-pri-for-cmdset-0001-and-cmdset-0002.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/mtd-unlock-nor-flash-automatically-where-necessary.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/ngw-fix-usart-initialization.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/ngw100-change-spi-clock-on-dataflash.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/pio-deglitch.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/pio-interrupt-controller.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/rename-ttyUS-to-ttyS-or-ttyAT.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/renumber-usart-devices.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/spi-fix-spi-busnum-to-master-buffer-and-bus_num-0.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/spi-reduce-dlybs-and-dlybct.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/spi-set-kset-of-master-class-dev-explicitly.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/update-atstk1002_defconfig.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/usart-make-rx-timeout-baudrate-independent.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/usb-ethernet-align-all-descriptors-on-a-word-boundary.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/usb-ethernet-define-cdc-capability-for-husb2.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/usb-file-storage-align-all-descriptors-on-a-word-boundary.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/usb-serial-align-all-descriptors-on-a-word-boundary.patch [new file with mode: 0644]
packages/linux/linux-2.6.18/usb-zero-align-all-descriptors-on-a-word-boundary.patch [new file with mode: 0644]
packages/linux/linux/atngw100/.mtn2git_empty [new file with mode: 0644]
packages/linux/linux/atngw100/defconfig [new file with mode: 0644]
packages/linux/linux_2.6.18.bb [new file with mode: 0644]
packages/mplayer/files/mplayer-1.0rc1-atmel.2.patch [new file with mode: 0644]
packages/mplayer/mplayer_0.0+1.0rc1.bb
packages/uclibc/uclibc-0.9.28/avr32/avr32-arch-2.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/avr32-linkrelax-option.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/avr32-string-ops.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/fix-__libc_fcntl64-varargs-prototype.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/fix-broken-__libc_open-declaration.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/fix-getrusage-argument-type.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/ldd-avr32-support.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/ldso-always-inline-_dl_memcpy.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/ldso-always-inline-syscalls.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/ldso-avr32-2.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/ldso-avr32-needs-CONSTANT_STRING_GOT_FIXUP.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/ldso-avr32-startup-hack.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/ldso-define-MAP_FAILED.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/let-optimized-stringops-override-default-ones.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/libpthread-avr32.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/no-create_module-on-avr32.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/remove-bogus-version-hack-and-just-use-asm-generic-if-it-exists.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/sync-fcntl-h-with-linux-kernel.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/uClibc-0.9.28-avr32-20060621.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/uClibc-0.9.28-avr32-20061019.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/uClibc.config
packages/uclibc/uclibc-0.9.28/avr32/uclibc-avr32-kernheaders.spec [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/uclibc-avr32-no-msoft-float.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/avr32/uclibc-makefile.patch [new file with mode: 0644]
packages/uclibc/uclibc.inc
packages/uclibc/uclibc/.mtn2git_empty [new file with mode: 0644]
packages/uclibc/uclibc_0.9.28.bb
packages/util-linux/files/fdiskbsdlabel-avr32.patch [new file with mode: 0644]
packages/util-linux/util-linux_2.12r.bb
packages/xorg-xserver/files/.mtn2git_empty [new file with mode: 0644]
packages/xorg-xserver/files/xorg-avr32-support.diff [new file with mode: 0644]
packages/xorg-xserver/xserver-kdrive_1.3.0.0.bb
packages/xorg-xserver/xserver-kdrive_1.4.bb
site/avr32-common

index 98e1c6e..976ac38 100644 (file)
@@ -6,12 +6,22 @@
 #@MAINTAINER: Michael 'Mickey' Lauer <mickey@Vanille-media.de>
 #@--------------------------------------------------------------------
 
+
+# Use Xorg R7.3 release
+require conf/distro/include/preferred-xorg-versions-X11R7.3.inc
+
+
 # This is a testbed for unstable and/or untested things, while angstrom-2007.1 
 # is aiming for stability and a release.
 # Use this at your own risk, we welcome bugreports filed at 
 #    http://bugs.openembedded.org
 # In doubt, use DISTRO="angstrom-2007.1"
 
+#Preferred version for the kernel on various machines
+PREFERRED_VERSION_linux-handhelds-2.6 ?= "2.6.21-hh16"
+
+require conf/distro/angstrom-2007.1.conf
+
 #DISTRO_VERSION = "2008.1"
 DISTRO_VERSION = "2008.1-test-${DATE}"
 DISTRO_REVISION = "1"
@@ -82,106 +92,16 @@ PREFERRED_VERSION_udev                     = "115"
 # Our patched-to-hell busybox 1.2.1 is getting old and unmaintanable
 PREFERRED_VERSION_busybox               = "1.7.2" 
 
-PREFERRED_PROVIDER_avahi = "avahi"
 
-#Small machines prefer kdrive, but we might ship full Xorg in other images
-PREFERRED_PROVIDER_virtual/xserver  ?= "xserver-kdrive"
-PREFERRED_PROVIDER_xserver          ?= "xserver-kdrive"
+#avr32 only has patches for binutils 2.17 and gcc 4.1.2 in OE
+PREFERRED_VERSION_gcc_avr32               = "4.1.2"
+PREFERRED_VERSION_gcc-cross_avr32         = "4.1.2"
+PREFERRED_VERSION_gcc-cross-sdk_avr32     = "4.1.2"
+PREFERRED_VERSION_gcc-cross-initial_avr32 = "4.1.2"
+PREFERRED_VERSION_binutils_avr32 = "2.17"
+PREFERRED_VERSION_binutils-cross_avr32 = "2.17"
+PREFERRED_VERSION_binutils-cross-sdk_avr32 = "2.17"
+#there's is no avr32 patch for 0.9.29
+PREFERRED_VERSION_uclibc_avr32 = "0.9.28"
+PREFERRED_VERSION_uclibc-initial_avr32 = "0.9.28"
 
-#Loads preferred versions from files, these have weak assigments (?=), so put them at the bottom
-require conf/distro/include/preferred-gpe-versions-2.8.inc
-require conf/distro/include/preferred-e-versions.inc
-require conf/distro/include/preferred-xorg-versions-X11R7.3.inc
-require conf/distro/include/preferred-openmoko-versions.inc
-
-
-# Virtuals:
-PREFERRED_PROVIDER_virtual/${TARGET_PREFIX}gcc-initial = "gcc-cross-initial"
-PREFERRED_PROVIDER_virtual/${TARGET_PREFIX}gcc = "gcc-cross"
-PREFERRED_PROVIDER_virtual/${TARGET_PREFIX}g++ = "gcc-cross"
-
-#Set preferred provider for the C library that is used to build the crosscompiler (NPTL voodoo)
-PREFERRED_PROVIDER_virtual/${TARGET_PREFIX}libc-for-gcc               = "glibc-intermediate"
-PREFERRED_PROVIDER_virtual/arm-angstrom-linux-gnueabi-libc-for-gcc    = "glibc-intermediate"
-PREFERRED_PROVIDER_virtual/armeb-angstrom-linux-gnueabi-libc-for-gcc  = "glibc-intermediate"
-PREFERRED_PROVIDER_virtual/arm-angstrom-linux-libc-for-gcc            = "glibc-intermediate"
-PREFERRED_PROVIDER_virtual/powerpc-angstrom-linux-libc-for-gcc        = "glibc-intermediate"
-PREFERRED_PROVIDER_virtual/mipsel-angstrom-linux-libc-for-gcc         = "glibc-intermediate"
-PREFERRED_PROVIDER_virtual/sparc-angstrom-linux-libc-for-gcc          = "glibc-intermediate"
-
-PREFERRED_PROVIDER_virtual/arm-angstrom-linux-uclibcgnueabi-libc-for-gcc    = "uclibc-initial"
-PREFERRED_PROVIDER_virtual/armeb-angstrom-linux-uclibcgnueabi-libc-for-gcc  = "uclibc-initial"
-
-# hostap stuff, we prefer the in-kernel modules, but those don't work for all machines
-PREFERRED_PROVIDER_hostap-conf                      ?= "hostap-conf"
-PREFERRED_PROVIDER_hostap-modules_h2200             ?= "hostap-modules"
-PREFERRED_PROVIDER_hostap-modules_hx4700            ?= "hostap-modules"
-
-PREFERRED_PROVIDER_virtual/db           ?= "db"
-PREFERRED_PROVIDER_virtual/db-native    ?= "db-native"
-PREFERRED_PROVIDER_virtual/libsdl       ?= "libsdl-x11"
-PREFERRED_PROVIDER_virtual/libx11       ?= "libx11"
-PREFERRED_PROVIDER_virtual/libxine      ?= "libxine-x11"
-PREFERRED_PROVIDER_virtual/xserver      ?= "xserver-kdrive"
-
-# Others:
-PREFERRED_PROVIDER_dbus-glib             = "dbus-glib"
-PREFERRED_PROVIDER_esound              ?= "pulseaudio"
-PREFERRED_PROVIDER_gconf                ?= "gconf-dbus"
-PREFERRED_PROVIDER_gnome-vfs            ?= "gnome-vfs"
-PREFERRED_PROVIDER_gnome-vfs-plugin-file ?= "gnome-vfs"
-PREFERRED_PROVIDER_tslib                ?= "tslib"
-PREFERRED_PROVIDER_tslib-conf           ?= "tslib"
-PREFERRED_PROVIDER_libgpewidget         ?= "libgpewidget"
-PREFERRED_PROVIDER_ntp                  ?= "ntp"
-PREFERRED_PROVIDER_hotplug               = "udev"
-PREFERRED_PROVIDER_libxss                = "libxss"
-
-# we don't ship gtk-directfb by default
-PREFERRED_PROVIDER_gtk+                   ?= "gtk+"
-PREFERRED_PROVIDER_gdk-pixbuf-loader-ani  ?= "gtk+"
-PREFERRED_PROVIDER_gdk-pixbuf-loader-bmpg ?= "gtk+"
-PREFERRED_PROVIDER_gdk-pixbuf-loader-gif  ?= "gtk+"
-PREFERRED_PROVIDER_gdk-pixbuf-loader-ico  ?= "gtk+"
-PREFERRED_PROVIDER_gdk-pixbuf-loader-jpeg ?= "gtk+"
-PREFERRED_PROVIDER_gdk-pixbuf-loader-pcx  ?= "gtk+"
-PREFERRED_PROVIDER_gdk-pixbuf-loader-png  ?= "gtk+"
-PREFERRED_PROVIDER_gdk-pixbuf-loader-pnm  ?= "gtk+"
-PREFERRED_PROVIDER_gdk-pixbuf-loader-ras  ?= "gtk+"
-PREFERRED_PROVIDER_gdk-pixbuf-loader-tga  ?= "gtk+"
-PREFERRED_PROVIDER_gdk-pixbuf-loader-wbmp ?= "gtk+"
-PREFERRED_PROVIDER_gdk-pixbuf-loader-xbm  ?= "gtk+"
-PREFERRED_PROVIDER_gdk-pixbuf-loader-xpm  ?= "gtk+"
-
-
-#Silence a warning during parsing
-PREFERRED_PROVIDER_task-bootstrap = "task-bootstrap"
-
-#This is needed to get a correct PACKAGE_ARCH for packages that have PACKAGE_ARCH = ${MACHINE_ARCH}
-ARM_ABI ?= "${@['','oabi'][bb.data.getVar('MACHINE',d) in ['collie','h3600', 'h3800', 'simpad', 'htcwallaby']]}"
-require conf/distro/include/angstrom${ARM_ABI}.inc
-
-# do some task-base stuff here
-
-# We want to ship extra debug utils in the rootfs when doing a debug build 
-DEBUG_APPS ?= ""
-DEBUG_APPS += '${@base_conditional("DISTRO_TYPE", "release", "", "tslib-tests tslib-calibrate gdb strace procps",d)}'
-
-# Angstrom want to ship some extra stuff. This should be moved into task-base eventually
-# contains ipkg specific stuff as well :(
-DISTRO_EXTRA_RDEPENDS += "\
-    update-modules \
-    ${@base_contains("MACHINE_FEATURES", "screen", "psplash", "",d)} \   
-    angstrom-version \
-    ipkg ipkg-collateral \
-    util-linux-mount util-linux-umount \
-    avahi-daemon \
-    avahi-autoipd \
-    ${DEBUG_APPS} \
-    "
-
-DISTRO_EXTRA_RRECOMMENDS += " \
-    kernel-module-vfat \
-    kernel-module-ext2 \
-    kernel-module-af-packet \
-    "
index 2231f80..343c6aa 100644 (file)
@@ -11,7 +11,7 @@ PREFERRED_PROVIDER_xserver = "xserver-kdrive"
 #don't try to access tty1
 USE_VT = "0"
 
-MACHINE_FEATURES = "kernel26 alsa ext2 usbhost usbgadget screen"
+MACHINE_FEATURES = "kernel26 alsa ext2 usbgadget touchscreen screen"
 
 # used by sysvinit_2
 SERIAL_CONSOLE = "115200"
@@ -21,3 +21,7 @@ ROOT_FLASH_SIZE = "8"
 EXTRA_IMAGECMD_jffs2 = " --big-endian --pagesize=4096 --eraseblock=65536"
 
 KERNEL_IMAGETYPE = "uImage"
+PREFERRED_VERSION_u-boot = "1.1.4"
+
+ROOTFS_POSTPROCESS_COMMAND += " rm ${IMAGE_ROOTFS}/boot/uImage* ;"
+
index 4df1030..6acc3d7 100644 (file)
@@ -9,7 +9,7 @@ PREFERRED_PROVIDER_xserver = "xserver-kdrive"
 #don't try to access tty1
 USE_VT = "0"
 
-MACHINE_FEATURES = "kernel26 ext2 usbhost usbgadget"
+MACHINE_FEATURES = "kernel26 ext2 usbgadget"
 
 # used by sysvinit_2
 SERIAL_CONSOLE = "115200"
@@ -18,4 +18,7 @@ SERIAL_CONSOLE = "115200"
 ROOT_FLASH_SIZE = "8"
 EXTRA_IMAGECMD_jffs2 = " --big-endian --pagesize=4096 --eraseblock=65536"
 
+PREFERRED_VERSION_u-boot = "1.1.4"
 KERNEL_IMAGETYPE = "uImage"
+
+ROOTFS_POSTPROCESS_COMMAND += " rm ${IMAGE_ROOTFS}/boot/uImage* ;"
index fa3fef0..2c30fbc 100644 (file)
@@ -2,3 +2,4 @@ require avahi.inc
 PR = "r1"
 
 SRC_URI += "file://dbus-pre-1.1.1-support.patch;patch=1"
+SRC_URI += "file://avr32-ipv6-fix.patch;patch=1"
diff --git a/packages/avahi/files/avr32-ipv6-fix.patch b/packages/avahi/files/avr32-ipv6-fix.patch
new file mode 100644 (file)
index 0000000..f0710a1
--- /dev/null
@@ -0,0 +1,42 @@
+--- /tmp/socket.c      2007-09-14 14:03:01.395330465 +0200
++++ avahi-0.6.21/avahi-core/socket.c   2007-09-14 14:08:42.081140297 +0200
+@@ -66,6 +66,39 @@
+ #endif
+ #endif
++#define IPV6_ADDRFORM           1
++#define IPV6_2292PKTINFO        2
++#define IPV6_2292HOPOPTS        3
++#define IPV6_2292DSTOPTS        4
++#define IPV6_2292RTHDR          5
++#define IPV6_2292PKTOPTIONS     6
++#define IPV6_CHECKSUM           7
++#define IPV6_2292HOPLIMIT       8
++#define IPV6_NEXTHOP            9
++#define IPV6_AUTHHDR            10      /* obsolete */
++#define IPV6_FLOWINFO           11
++
++#define IPV6_UNICAST_HOPS       16
++#define IPV6_MULTICAST_IF       17
++#define IPV6_MULTICAST_HOPS     18
++#define IPV6_MULTICAST_LOOP     19
++#define IPV6_ADD_MEMBERSHIP     20
++#define IPV6_DROP_MEMBERSHIP    21
++#define IPV6_ROUTER_ALERT       22
++#define IPV6_MTU_DISCOVER       23
++#define IPV6_MTU                24
++#define IPV6_RECVERR            25
++#define IPV6_V6ONLY             26
++#define IPV6_JOIN_ANYCAST       27
++#define IPV6_LEAVE_ANYCAST      28
++
++/* IPV6_MTU_DISCOVER values */
++#define IPV6_PMTUDISC_DONT              0
++#define IPV6_PMTUDISC_WANT              1
++#define IPV6_PMTUDISC_DO                2
++#define IPV6_PMTUDISC_PROBE             3
++
++
+ static void mdns_mcast_group_ipv4(struct sockaddr_in *ret_sa) {
+     assert(ret_sa);
diff --git a/packages/binutils/binutils-2.17/503-avr32-fix-got-offset-init.patch b/packages/binutils/binutils-2.17/503-avr32-fix-got-offset-init.patch
new file mode 100644 (file)
index 0000000..66add3a
--- /dev/null
@@ -0,0 +1,12 @@
+stelios@Athena:~/proj/oplinux-0.2/org.openembedded.dev/packages/binutils$ cat binutils-2.17/503-avr32-fix-got-offset-init.patch \r
+--- a/bfd/elf32-avr32.c 2007-05-31 17:00:13.000000000 +0200\r
++++ b/bfd/elf32-avr32.c 2007-05-30 14:07:25.000000000 +0200\r
+@@ -395,6 +395,8 @@ avr32_elf_link_hash_table_create(bfd *ab\r
+   /* Prevent the BFD core from creating bogus got_entry pointers */\r
+   ret->root.init_got_refcount.glist = NULL;\r
+   ret->root.init_plt_refcount.glist = NULL;\r
++  ret->root.init_got_offset.glist = NULL;\r
++  ret->root.init_plt_offset.glist = NULL;\r
\r
+   return &ret->root.root;\r
+ }
\ No newline at end of file
index 8d38f3a..69e1149 100644 (file)
@@ -1,6 +1,6 @@
 require binutils.inc
 
-PR = "r1"
+PR = "r2"
 
 SRC_URI = \
     "http://ftp.gnu.org/gnu/binutils/binutils-${PV}.tar.bz2 \
@@ -21,6 +21,7 @@ SRC_URI += "\
         http://avr32linux.org/twiki/pub/Main/DevelopmentTools/500-avr32.patch.gz;patch=1 \
         http://avr32linux.org/twiki/pub/Main/DevelopmentTools/501-avr32-sreldyn-fix.patch.gz;patch=1 \
        http://avr32linux.org/twiki/pub/Main/DevelopmentTools/502-avr32-bfd-dont-allow-direct-refs-to-bss.patch.gz;patch=1 \
+        file://503-avr32-fix-got-offset-init.patch;patch=1 \
 "
 
 # Zecke's OSX fixes
diff --git a/packages/busybox/busybox-1.2.1/avr32/.mtn2git_empty b/packages/busybox/busybox-1.2.1/avr32/.mtn2git_empty
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/packages/busybox/busybox-1.2.1/avr32/defconfig b/packages/busybox/busybox-1.2.1/avr32/defconfig
new file mode 100644 (file)
index 0000000..b15f162
--- /dev/null
@@ -0,0 +1,643 @@
+#
+# Automatically generated make config: don't edit
+#
+HAVE_DOT_CONFIG=y
+
+#
+# Busybox Settings
+#
+
+#
+# General Configuration
+#
+# CONFIG_NITPICK is not set
+# CONFIG_FEATURE_BUFFERS_USE_MALLOC is not set
+# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set
+# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set
+CONFIG_SHOW_USAGE=y
+# CONFIG_FEATURE_VERBOSE_USAGE is not set
+# CONFIG_FEATURE_COMPRESS_USAGE is not set
+# CONFIG_FEATURE_INSTALLER is not set
+CONFIG_LOCALE_SUPPORT=y
+CONFIG_GETOPT_LONG=y
+CONFIG_FEATURE_DEVPTS=y
+# CONFIG_FEATURE_CLEAN_UP is not set
+# CONFIG_FEATURE_SUID is not set
+# CONFIG_FEATURE_SUID_CONFIG is not set
+# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set
+# CONFIG_SELINUX is not set
+CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
+
+#
+# Build Options
+#
+# CONFIG_STATIC is not set
+# CONFIG_BUILD_LIBBUSYBOX is not set
+# CONFIG_FEATURE_FULL_LIBBUSYBOX is not set
+# CONFIG_FEATURE_SHARED_BUSYBOX is not set
+CONFIG_LFS=y
+USING_CROSS_COMPILER=y
+CROSS_COMPILER_PREFIX="avr32-angstrom-linux-uclibc-"
+CONFIG_BUILD_AT_ONCE=y
+
+#
+# Debugging Options
+#
+# CONFIG_DEBUG is not set
+# CONFIG_DEBUG_PESSIMIZE is not set
+# CONFIG_NO_DEBUG_LIB is not set
+# CONFIG_DMALLOC is not set
+# CONFIG_EFENCE is not set
+CONFIG_DEBUG_YANK_SUSv2=y
+
+#
+# Installation Options
+#
+# CONFIG_INSTALL_NO_USR is not set
+CONFIG_INSTALL_APPLET_SYMLINKS=y
+# CONFIG_INSTALL_APPLET_HARDLINKS is not set
+# CONFIG_INSTALL_APPLET_DONT is not set
+PREFIX="./_install"
+
+#
+# Busybox Library Tuning
+#
+CONFIG_MD5_SIZE_VS_SPEED=2
+
+#
+# Applets
+#
+
+#
+# Archival Utilities
+#
+CONFIG_AR=y
+# CONFIG_FEATURE_AR_LONG_FILENAMES is not set
+CONFIG_BUNZIP2=y
+CONFIG_CPIO=y
+# CONFIG_DPKG is not set
+# CONFIG_DPKG_DEB is not set
+# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set
+CONFIG_GUNZIP=y
+# CONFIG_FEATURE_GUNZIP_UNCOMPRESS is not set
+CONFIG_GZIP=y
+# CONFIG_RPM2CPIO is not set
+# CONFIG_RPM is not set
+CONFIG_TAR=y
+CONFIG_FEATURE_TAR_CREATE=y
+CONFIG_FEATURE_TAR_BZIP2=y
+# CONFIG_FEATURE_TAR_LZMA is not set
+CONFIG_FEATURE_TAR_FROM=y
+CONFIG_FEATURE_TAR_GZIP=y
+# CONFIG_FEATURE_TAR_COMPRESS is not set
+# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set
+CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y
+# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set
+# CONFIG_UNCOMPRESS is not set
+# CONFIG_UNLZMA is not set
+# CONFIG_FEATURE_LZMA_FAST is not set
+CONFIG_UNZIP=y
+
+#
+# Common options for cpio and tar
+#
+# CONFIG_FEATURE_UNARCHIVE_TAPE is not set
+# CONFIG_FEATURE_DEB_TAR_GZ is not set
+# CONFIG_FEATURE_DEB_TAR_BZ2 is not set
+# CONFIG_FEATURE_DEB_TAR_LZMA is not set
+
+#
+# Coreutils
+#
+CONFIG_BASENAME=y
+# CONFIG_CAL is not set
+CONFIG_CAT=y
+# CONFIG_CATV is not set
+CONFIG_CHGRP=y
+CONFIG_CHMOD=y
+CONFIG_CHOWN=y
+CONFIG_CHROOT=y
+# CONFIG_CKSUM is not set
+# CONFIG_CMP is not set
+# CONFIG_COMM is not set
+CONFIG_CP=y
+CONFIG_CUT=y
+CONFIG_DATE=y
+# CONFIG_FEATURE_DATE_ISOFMT is not set
+CONFIG_DD=y
+CONFIG_FEATURE_DD_SIGNAL_HANDLING=y
+# CONFIG_FEATURE_DD_IBS_OBS is not set
+CONFIG_DF=y
+CONFIG_DIFF=y
+CONFIG_FEATURE_DIFF_BINARY=y
+CONFIG_FEATURE_DIFF_DIR=y
+# CONFIG_FEATURE_DIFF_MINIMAL is not set
+CONFIG_DIRNAME=y
+# CONFIG_DOS2UNIX is not set
+# CONFIG_UNIX2DOS is not set
+CONFIG_DU=y
+CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y
+CONFIG_ECHO=y
+CONFIG_FEATURE_FANCY_ECHO=y
+CONFIG_ENV=y
+CONFIG_FEATURE_ENV_LONG_OPTIONS=y
+CONFIG_EXPR=y
+# CONFIG_EXPR_MATH_SUPPORT_64 is not set
+CONFIG_FALSE=y
+# CONFIG_FOLD is not set
+CONFIG_HEAD=y
+# CONFIG_FEATURE_FANCY_HEAD is not set
+# CONFIG_HOSTID is not set
+CONFIG_ID=y
+# CONFIG_INSTALL is not set
+# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set
+# CONFIG_LENGTH is not set
+CONFIG_LN=y
+CONFIG_LOGNAME=y
+CONFIG_LS=y
+CONFIG_FEATURE_LS_FILETYPES=y
+CONFIG_FEATURE_LS_FOLLOWLINKS=y
+CONFIG_FEATURE_LS_RECURSIVE=y
+CONFIG_FEATURE_LS_SORTFILES=y
+CONFIG_FEATURE_LS_TIMESTAMPS=y
+CONFIG_FEATURE_LS_USERNAME=y
+CONFIG_FEATURE_LS_COLOR=y
+# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set
+# CONFIG_MD5SUM is not set
+CONFIG_MKDIR=y
+CONFIG_FEATURE_MKDIR_LONG_OPTIONS=y
+CONFIG_MKFIFO=y
+CONFIG_MKNOD=y
+CONFIG_MV=y
+# CONFIG_FEATURE_MV_LONG_OPTIONS is not set
+# CONFIG_NICE is not set
+CONFIG_NOHUP=y
+CONFIG_OD=y
+# CONFIG_PRINTENV is not set
+CONFIG_PRINTF=y
+CONFIG_PWD=y
+CONFIG_REALPATH=y
+CONFIG_RM=y
+CONFIG_RMDIR=y
+CONFIG_SEQ=y
+# CONFIG_SHA1SUM is not set
+CONFIG_SLEEP=y
+CONFIG_FEATURE_FANCY_SLEEP=y
+CONFIG_SORT=y
+CONFIG_FEATURE_SORT_BIG=y
+# CONFIG_STAT is not set
+# CONFIG_FEATURE_STAT_FORMAT is not set
+CONFIG_STTY=y
+# CONFIG_SUM is not set
+CONFIG_SYNC=y
+CONFIG_TAIL=y
+CONFIG_FEATURE_FANCY_TAIL=y
+CONFIG_TEE=y
+# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set
+CONFIG_TEST=y
+# CONFIG_FEATURE_TEST_64 is not set
+CONFIG_TOUCH=y
+CONFIG_TR=y
+CONFIG_FEATURE_TR_CLASSES=y
+# CONFIG_FEATURE_TR_EQUIV is not set
+CONFIG_TRUE=y
+CONFIG_TTY=y
+CONFIG_UNAME=y
+CONFIG_UNIQ=y
+CONFIG_USLEEP=y
+# CONFIG_UUDECODE is not set
+# CONFIG_UUENCODE is not set
+CONFIG_WATCH=y
+CONFIG_WC=y
+CONFIG_WHO=y
+CONFIG_WHOAMI=y
+CONFIG_YES=y
+
+#
+# Common options for cp and mv
+#
+# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set
+
+#
+# Common options for ls, more and telnet
+#
+CONFIG_FEATURE_AUTOWIDTH=y
+
+#
+# Common options for df, du, ls
+#
+CONFIG_FEATURE_HUMAN_READABLE=y
+# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set
+
+#
+# Console Utilities
+#
+CONFIG_CHVT=y
+CONFIG_CLEAR=y
+CONFIG_DEALLOCVT=y
+CONFIG_DUMPKMAP=y
+CONFIG_LOADFONT=y
+CONFIG_LOADKMAP=y
+CONFIG_OPENVT=y
+CONFIG_RESET=y
+CONFIG_SETCONSOLE=y
+# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set
+# CONFIG_SETKEYCODES is not set
+# CONFIG_SETLOGCONS is not set
+
+#
+# Debian Utilities
+#
+CONFIG_MKTEMP=y
+# CONFIG_PIPE_PROGRESS is not set
+CONFIG_READLINK=y
+CONFIG_FEATURE_READLINK_FOLLOW=y
+CONFIG_RUN_PARTS=y
+# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set
+CONFIG_START_STOP_DAEMON=y
+CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y
+CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS=y
+CONFIG_WHICH=y
+
+#
+# Editors
+#
+CONFIG_AWK=y
+CONFIG_FEATURE_AWK_MATH=y
+# CONFIG_ED is not set
+CONFIG_PATCH=y
+CONFIG_SED=y
+CONFIG_VI=y
+CONFIG_FEATURE_VI_COLON=y
+CONFIG_FEATURE_VI_YANKMARK=y
+CONFIG_FEATURE_VI_SEARCH=y
+CONFIG_FEATURE_VI_USE_SIGNALS=y
+# CONFIG_FEATURE_VI_DOT_CMD is not set
+# CONFIG_FEATURE_VI_READONLY is not set
+# CONFIG_FEATURE_VI_SETOPTS is not set
+# CONFIG_FEATURE_VI_SET is not set
+CONFIG_FEATURE_VI_WIN_RESIZE=y
+CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y
+
+#
+# Finding Utilities
+#
+CONFIG_FIND=y
+CONFIG_FEATURE_FIND_PRINT0=y
+CONFIG_FEATURE_FIND_MTIME=y
+CONFIG_FEATURE_FIND_MMIN=y
+CONFIG_FEATURE_FIND_PERM=y
+CONFIG_FEATURE_FIND_TYPE=y
+CONFIG_FEATURE_FIND_XDEV=y
+CONFIG_FEATURE_FIND_NEWER=y
+# CONFIG_FEATURE_FIND_INUM is not set
+CONFIG_FEATURE_FIND_EXEC=y
+CONFIG_GREP=y
+CONFIG_FEATURE_GREP_EGREP_ALIAS=y
+CONFIG_FEATURE_GREP_FGREP_ALIAS=y
+CONFIG_FEATURE_GREP_CONTEXT=y
+CONFIG_XARGS=y
+# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set
+# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set
+
+#
+# Init Utilities
+#
+# CONFIG_INIT is not set
+# CONFIG_DEBUG_INIT is not set
+# CONFIG_FEATURE_USE_INITTAB is not set
+# CONFIG_FEATURE_INIT_SCTTY is not set
+# CONFIG_FEATURE_EXTRA_QUIET is not set
+# CONFIG_FEATURE_INIT_COREDUMPS is not set
+# CONFIG_FEATURE_INITRD is not set
+# CONFIG_HALT is not set
+# CONFIG_MESG is not set
+
+#
+# Login/Password Management Utilities
+#
+# CONFIG_FEATURE_SHADOWPASSWDS is not set
+# CONFIG_USE_BB_SHADOW is not set
+# CONFIG_USE_BB_PWD_GRP is not set
+# CONFIG_ADDGROUP is not set
+# CONFIG_DELGROUP is not set
+# CONFIG_ADDUSER is not set
+# CONFIG_DELUSER is not set
+# CONFIG_GETTY is not set
+CONFIG_FEATURE_UTMP=y
+# CONFIG_FEATURE_WTMP is not set
+# CONFIG_LOGIN is not set
+# CONFIG_FEATURE_SECURETTY is not set
+# CONFIG_PASSWD is not set
+# CONFIG_SU is not set
+# CONFIG_SULOGIN is not set
+# CONFIG_VLOCK is not set
+
+#
+# Linux Ext2 FS Progs
+#
+CONFIG_CHATTR=y
+CONFIG_E2FSCK=y
+CONFIG_FSCK=y
+# CONFIG_LSATTR is not set
+CONFIG_MKE2FS=y
+# CONFIG_TUNE2FS is not set
+# CONFIG_E2LABEL is not set
+# CONFIG_FINDFS is not set
+
+#
+# Linux Module Utilities
+#
+CONFIG_INSMOD=y
+# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set
+# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set
+# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set
+# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set
+CONFIG_RMMOD=y
+CONFIG_LSMOD=y
+# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set
+CONFIG_MODPROBE=y
+CONFIG_FEATURE_MODPROBE_MULTIPLE_OPTIONS=y
+
+#
+# Options common to multiple modutils
+#
+CONFIG_FEATURE_CHECK_TAINTED_MODULE=y
+# CONFIG_FEATURE_2_4_MODULES is not set
+CONFIG_FEATURE_2_6_MODULES=y
+# CONFIG_FEATURE_QUERY_MODULE_INTERFACE is not set
+
+#
+# Linux System Utilities
+#
+CONFIG_DMESG=y
+CONFIG_FBSET=y
+CONFIG_FEATURE_FBSET_FANCY=y
+CONFIG_FEATURE_FBSET_READMODE=y
+# CONFIG_FDFLUSH is not set
+# CONFIG_FDFORMAT is not set
+CONFIG_FDISK=y
+FDISK_SUPPORT_LARGE_DISKS=y
+CONFIG_FEATURE_FDISK_WRITABLE=y
+# CONFIG_FEATURE_AIX_LABEL is not set
+# CONFIG_FEATURE_SGI_LABEL is not set
+# CONFIG_FEATURE_SUN_LABEL is not set
+# CONFIG_FEATURE_OSF_LABEL is not set
+# CONFIG_FEATURE_FDISK_ADVANCED is not set
+# CONFIG_FREERAMDISK is not set
+CONFIG_FSCK_MINIX=y
+CONFIG_MKFS_MINIX=y
+
+#
+# Minix filesystem support
+#
+CONFIG_FEATURE_MINIX2=y
+# CONFIG_GETOPT is not set
+CONFIG_HEXDUMP=y
+CONFIG_HWCLOCK=y
+CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS=y
+CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS=y
+# CONFIG_IPCRM is not set
+# CONFIG_IPCS is not set
+CONFIG_LOSETUP=y
+# CONFIG_MDEV is not set
+# CONFIG_FEATURE_MDEV_CONF is not set
+# CONFIG_FEATURE_MDEV_EXEC is not set
+CONFIG_MKSWAP=y
+# CONFIG_FEATURE_MKSWAP_V0 is not set
+CONFIG_MORE=y
+CONFIG_FEATURE_USE_TERMIOS=y
+CONFIG_MOUNT=y
+CONFIG_FEATURE_MOUNT_NFS=y
+CONFIG_PIVOT_ROOT=y
+CONFIG_RDATE=y
+# CONFIG_READPROFILE is not set
+# CONFIG_SETARCH is not set
+CONFIG_SWAPONOFF=y
+CONFIG_SWITCH_ROOT=y
+CONFIG_UMOUNT=y
+# CONFIG_FEATURE_UMOUNT_ALL is not set
+
+#
+# Common options for mount/umount
+#
+CONFIG_FEATURE_MOUNT_LOOP=y
+# CONFIG_FEATURE_MTAB_SUPPORT is not set
+
+#
+# Miscellaneous Utilities
+#
+# CONFIG_ADJTIMEX is not set
+# CONFIG_BBCONFIG is not set
+# CONFIG_CROND is not set
+# CONFIG_DEBUG_CROND_OPTION is not set
+# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set
+# CONFIG_CRONTAB is not set
+CONFIG_DC=y
+# CONFIG_DEVFSD is not set
+# CONFIG_DEVFSD_MODLOAD is not set
+# CONFIG_DEVFSD_FG_NP is not set
+# CONFIG_DEVFSD_VERBOSE is not set
+# CONFIG_FEATURE_DEVFS is not set
+# CONFIG_EJECT is not set
+# CONFIG_LAST is not set
+CONFIG_LESS=y
+CONFIG_FEATURE_LESS_BRACKETS=y
+CONFIG_FEATURE_LESS_FLAGS=y
+# CONFIG_FEATURE_LESS_FLAGCS is not set
+# CONFIG_FEATURE_LESS_MARKS is not set
+# CONFIG_FEATURE_LESS_REGEXP is not set
+# CONFIG_HDPARM is not set
+# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set
+# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set
+# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set
+# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set
+# CONFIG_MAKEDEVS is not set
+# CONFIG_FEATURE_MAKEDEVS_LEAF is not set
+# CONFIG_FEATURE_MAKEDEVS_TABLE is not set
+# CONFIG_MOUNTPOINT is not set
+# CONFIG_MT is not set
+# CONFIG_RUNLEVEL is not set
+# CONFIG_RX is not set
+CONFIG_STRINGS=y
+# CONFIG_SETSID is not set
+# CONFIG_TASKSET is not set
+CONFIG_TIME=y
+# CONFIG_WATCHDOG is not set
+
+#
+# Networking Utilities
+#
+CONFIG_FEATURE_IPV6=y
+# CONFIG_ARPING is not set
+# CONFIG_DNSD is not set
+# CONFIG_ETHER_WAKE is not set
+# CONFIG_FAKEIDENTD is not set
+# CONFIG_FTPGET is not set
+# CONFIG_FTPPUT is not set
+# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set
+CONFIG_HOSTNAME=y
+# CONFIG_HTTPD is not set
+# CONFIG_FEATURE_HTTPD_WITHOUT_INETD is not set
+# CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP is not set
+# CONFIG_FEATURE_HTTPD_SETUID is not set
+# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set
+# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set
+# CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES is not set
+# CONFIG_FEATURE_HTTPD_CGI is not set
+# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set
+# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set
+# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set
+CONFIG_IFCONFIG=y
+CONFIG_FEATURE_IFCONFIG_STATUS=y
+# CONFIG_FEATURE_IFCONFIG_SLIP is not set
+# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set
+CONFIG_FEATURE_IFCONFIG_HW=y
+# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set
+CONFIG_IFUPDOWN=y
+# CONFIG_FEATURE_IFUPDOWN_IP is not set
+CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN=y
+CONFIG_FEATURE_IFUPDOWN_IPV4=y
+CONFIG_FEATURE_IFUPDOWN_IPV6=y
+# CONFIG_FEATURE_IFUPDOWN_IPX is not set
+CONFIG_FEATURE_IFUPDOWN_MAPPING=y
+# CONFIG_INETD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set
+# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set
+# CONFIG_FEATURE_INETD_RPC is not set
+CONFIG_IP=y
+CONFIG_FEATURE_IP_ADDRESS=y
+CONFIG_FEATURE_IP_LINK=y
+CONFIG_FEATURE_IP_ROUTE=y
+CONFIG_FEATURE_IP_TUNNEL=y
+# CONFIG_FEATURE_IP_SHORT_FORMS is not set
+# CONFIG_IPADDR is not set
+# CONFIG_IPLINK is not set
+# CONFIG_IPROUTE is not set
+# CONFIG_IPTUNNEL is not set
+# CONFIG_IPCALC is not set
+# CONFIG_FEATURE_IPCALC_FANCY is not set
+# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set
+# CONFIG_NAMEIF is not set
+CONFIG_NC=y
+# CONFIG_NC_GAPING_SECURITY_HOLE is not set
+CONFIG_NETSTAT=y
+CONFIG_NSLOOKUP=y
+CONFIG_PING=y
+CONFIG_FEATURE_FANCY_PING=y
+CONFIG_PING6=y
+CONFIG_FEATURE_FANCY_PING6=y
+CONFIG_ROUTE=y
+CONFIG_TELNET=y
+# CONFIG_FEATURE_TELNET_TTYPE is not set
+CONFIG_FEATURE_TELNET_AUTOLOGIN=y
+# CONFIG_TELNETD is not set
+# CONFIG_FEATURE_TELNETD_INETD is not set
+CONFIG_TFTP=y
+CONFIG_FEATURE_TFTP_GET=y
+CONFIG_FEATURE_TFTP_PUT=y
+# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set
+# CONFIG_DEBUG_TFTP is not set
+CONFIG_TRACEROUTE=y
+# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set
+# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set
+# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set
+
+#
+# udhcp Server/Client
+#
+CONFIG_APP_UDHCPD=y
+CONFIG_APP_UDHCPC=y
+CONFIG_APP_DUMPLEASES=y
+CONFIG_FEATURE_UDHCP_SYSLOG=y
+# CONFIG_FEATURE_UDHCP_DEBUG is not set
+# CONFIG_VCONFIG is not set
+CONFIG_WGET=y
+CONFIG_FEATURE_WGET_STATUSBAR=y
+CONFIG_FEATURE_WGET_AUTHENTICATION=y
+CONFIG_FEATURE_WGET_IP6_LITERAL=y
+CONFIG_FEATURE_WGET_LONG_OPTIONS=y
+# CONFIG_ZCIP is not set
+
+#
+# Process Utilities
+#
+CONFIG_FREE=y
+CONFIG_FUSER=y
+CONFIG_KILL=y
+CONFIG_KILLALL=y
+CONFIG_PIDOF=y
+# CONFIG_FEATURE_PIDOF_SINGLE is not set
+# CONFIG_FEATURE_PIDOF_OMIT is not set
+CONFIG_PS=y
+CONFIG_FEATURE_PS_WIDE=y
+CONFIG_RENICE=y
+CONFIG_BB_SYSCTL=y
+CONFIG_TOP=y
+CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y
+CONFIG_UPTIME=y
+
+#
+# Shells
+#
+CONFIG_FEATURE_SH_IS_ASH=y
+# CONFIG_FEATURE_SH_IS_HUSH is not set
+# CONFIG_FEATURE_SH_IS_LASH is not set
+# CONFIG_FEATURE_SH_IS_MSH is not set
+# CONFIG_FEATURE_SH_IS_NONE is not set
+CONFIG_ASH=y
+
+#
+# Ash Shell Options
+#
+CONFIG_ASH_JOB_CONTROL=y
+# CONFIG_ASH_READ_NCHARS is not set
+# CONFIG_ASH_READ_TIMEOUT is not set
+CONFIG_ASH_ALIAS=y
+CONFIG_ASH_MATH_SUPPORT=y
+# CONFIG_ASH_MATH_SUPPORT_64 is not set
+CONFIG_ASH_GETOPTS=y
+# CONFIG_ASH_BUILTIN_ECHO is not set
+CONFIG_ASH_BUILTIN_TEST=y
+# CONFIG_ASH_CMDCMD is not set
+# CONFIG_ASH_MAIL is not set
+CONFIG_ASH_OPTIMIZE_FOR_SIZE=y
+# CONFIG_ASH_RANDOM_SUPPORT is not set
+CONFIG_ASH_EXPAND_PRMT=y
+# CONFIG_HUSH is not set
+# CONFIG_LASH is not set
+# CONFIG_MSH is not set
+
+#
+# Bourne Shell Options
+#
+CONFIG_FEATURE_SH_EXTRA_QUIET=y
+# CONFIG_FEATURE_SH_STANDALONE_SHELL is not set
+CONFIG_FEATURE_COMMAND_EDITING=y
+# CONFIG_FEATURE_COMMAND_EDITING_VI is not set
+CONFIG_FEATURE_COMMAND_HISTORY=63
+# CONFIG_FEATURE_COMMAND_SAVEHISTORY is not set
+CONFIG_FEATURE_COMMAND_TAB_COMPLETION=y
+# CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION is not set
+CONFIG_FEATURE_SH_FANCY_PROMPT=y
+
+#
+# System Logging Utilities
+#
+CONFIG_SYSLOGD=y
+CONFIG_FEATURE_ROTATE_LOGFILE=y
+CONFIG_FEATURE_REMOTE_LOG=y
+CONFIG_FEATURE_IPC_SYSLOG=y
+CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16
+CONFIG_LOGREAD=y
+CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING=y
+CONFIG_KLOGD=y
+CONFIG_LOGGER=y
diff --git a/packages/busybox/busybox-1.2.1/install-should-unlink-dest-if-it-exists.patch b/packages/busybox/busybox-1.2.1/install-should-unlink-dest-if-it-exists.patch
new file mode 100644 (file)
index 0000000..4bec313
--- /dev/null
@@ -0,0 +1,53 @@
+---
+ coreutils/install.c |    2 +-
+ include/libbb.h     |    3 ++-
+ libbb/copy_file.c   |    9 +++++++++
+ 3 files changed, 12 insertions(+), 2 deletions(-)
+
+Index: busybox-1.2.1/coreutils/install.c
+===================================================================
+--- busybox-1.2.1.orig/coreutils/install.c     2006-10-19 16:33:48.000000000 +0200
++++ busybox-1.2.1/coreutils/install.c  2006-10-19 16:35:58.000000000 +0200
+@@ -59,7 +59,7 @@ int install_main(int argc, char **argv)
+       char *gid_str = "-1";
+       char *uid_str = "-1";
+       char *mode_str = "0755";
+-      int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE;
++      int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE | FILEUTILS_NO_TRUNC;
+       int ret = EXIT_SUCCESS, flags, i, isdir;
+ #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS
+Index: busybox-1.2.1/include/libbb.h
+===================================================================
+--- busybox-1.2.1.orig/include/libbb.h 2006-10-19 16:24:50.000000000 +0200
++++ busybox-1.2.1/include/libbb.h      2006-10-19 16:32:40.000000000 +0200
+@@ -345,7 +345,8 @@ enum {     /* DO NOT CHANGE THESE VALUES!  c
+       FILEUTILS_DEREFERENCE = 2,
+       FILEUTILS_RECUR = 4,
+       FILEUTILS_FORCE = 8,
+-      FILEUTILS_INTERACTIVE = 16
++      FILEUTILS_INTERACTIVE = 16,
++      FILEUTILS_NO_TRUNC = 32
+ };
+ extern const char *bb_applet_name;
+Index: busybox-1.2.1/libbb/copy_file.c
+===================================================================
+--- busybox-1.2.1.orig/libbb/copy_file.c       2006-10-19 16:26:53.000000000 +0200
++++ busybox-1.2.1/libbb/copy_file.c    2006-10-19 16:32:28.000000000 +0200
+@@ -136,6 +136,15 @@ int copy_file(const char *source, const 
+                               }
+                       }
++                      if (flags & FILEUTILS_NO_TRUNC) {
++                              if (unlink(dest) < 0) {
++                                      bb_perror_msg("unable to remove `%s'", dest);
++                                      close(src_fd);
++                                      return -1;
++                              }
++                              goto dest_removed;
++                      }
++
+                       dst_fd = open(dest, O_WRONLY|O_TRUNC);
+                       if (dst_fd == -1) {
+                               if (!(flags & FILEUTILS_FORCE)) {
index 054649e..773c5e1 100644 (file)
@@ -1,11 +1,13 @@
 require busybox.inc
 
-PR = "r13"
+PR = "r14"
 
 SRC_URI += "file://wget-long-options.patch;patch=1 \
           file://df_rootfs.patch;patch=1 \
            file://defconfig"
 
+SRC_URI_append_avr32 = " file://install-should-unlink-dest-if-it-exists.patch;patch=1"
+
 do_configure () {
        install -m 0644 ${WORKDIR}/defconfig ${S}/.config.oe
 
diff --git a/packages/busybox/files/install-should-unlink-dest-if-it-exists.patch b/packages/busybox/files/install-should-unlink-dest-if-it-exists.patch
new file mode 100644 (file)
index 0000000..4bec313
--- /dev/null
@@ -0,0 +1,53 @@
+---
+ coreutils/install.c |    2 +-
+ include/libbb.h     |    3 ++-
+ libbb/copy_file.c   |    9 +++++++++
+ 3 files changed, 12 insertions(+), 2 deletions(-)
+
+Index: busybox-1.2.1/coreutils/install.c
+===================================================================
+--- busybox-1.2.1.orig/coreutils/install.c     2006-10-19 16:33:48.000000000 +0200
++++ busybox-1.2.1/coreutils/install.c  2006-10-19 16:35:58.000000000 +0200
+@@ -59,7 +59,7 @@ int install_main(int argc, char **argv)
+       char *gid_str = "-1";
+       char *uid_str = "-1";
+       char *mode_str = "0755";
+-      int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE;
++      int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE | FILEUTILS_NO_TRUNC;
+       int ret = EXIT_SUCCESS, flags, i, isdir;
+ #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS
+Index: busybox-1.2.1/include/libbb.h
+===================================================================
+--- busybox-1.2.1.orig/include/libbb.h 2006-10-19 16:24:50.000000000 +0200
++++ busybox-1.2.1/include/libbb.h      2006-10-19 16:32:40.000000000 +0200
+@@ -345,7 +345,8 @@ enum {     /* DO NOT CHANGE THESE VALUES!  c
+       FILEUTILS_DEREFERENCE = 2,
+       FILEUTILS_RECUR = 4,
+       FILEUTILS_FORCE = 8,
+-      FILEUTILS_INTERACTIVE = 16
++      FILEUTILS_INTERACTIVE = 16,
++      FILEUTILS_NO_TRUNC = 32
+ };
+ extern const char *bb_applet_name;
+Index: busybox-1.2.1/libbb/copy_file.c
+===================================================================
+--- busybox-1.2.1.orig/libbb/copy_file.c       2006-10-19 16:26:53.000000000 +0200
++++ busybox-1.2.1/libbb/copy_file.c    2006-10-19 16:32:28.000000000 +0200
+@@ -136,6 +136,15 @@ int copy_file(const char *source, const 
+                               }
+                       }
++                      if (flags & FILEUTILS_NO_TRUNC) {
++                              if (unlink(dest) < 0) {
++                                      bb_perror_msg("unable to remove `%s'", dest);
++                                      close(src_fd);
++                                      return -1;
++                              }
++                              goto dest_removed;
++                      }
++
+                       dst_fd = open(dest, O_WRONLY|O_TRUNC);
+                       if (dst_fd == -1) {
+                               if (!(flags & FILEUTILS_FORCE)) {
diff --git a/packages/gcc/avr32-gcc-cross_4.1.2.bb b/packages/gcc/avr32-gcc-cross_4.1.2.bb
new file mode 100644 (file)
index 0000000..765619a
--- /dev/null
@@ -0,0 +1,22 @@
+require avr32-gcc_${PV}.bb
+# path mangling, needed by the cross packaging
+require gcc-paths-cross.inc
+inherit cross
+FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/gcc-${PV}"
+# NOTE: split PR.  If the main .oe changes something that affects its *build*
+# remember to increment this one too.
+PR = "r1"
+
+DEPENDS = "virtual/${TARGET_PREFIX}binutils virtual/${TARGET_PREFIX}libc-for-gcc gmp-native mpfr-native"
+PROVIDES = "virtual/${TARGET_PREFIX}gcc virtual/${TARGET_PREFIX}g++"
+
+# cross build
+require gcc3-build-cross.inc
+# cross packaging
+require gcc-package-cross.inc
+
+SRC_URI_append_fail-fast = " file://zecke-no-host-includes.patch;patch=1 "
+
+EXTRA_OECONF += "  --disable-libmudflap \
+                   --disable-libunwind-exceptions \
+                   --with-mpfr=${STAGING_DIR}/${BUILD_SYS}"
diff --git a/packages/gcc/avr32-gcc_4.1.2.bb b/packages/gcc/avr32-gcc_4.1.2.bb
new file mode 100644 (file)
index 0000000..fd46172
--- /dev/null
@@ -0,0 +1,24 @@
+require gcc_${PV}.bb
+
+PR = "r1"
+
+FILESPATH = "${@base_set_filespath([ '${FILE_DIRNAME}/gcc-4.1.2', '${FILE_DIRNAME}/gcc', '${FILE_DIRNAME}/files', '${FILE_DIRNAME}' ], d)}"
+
+SRC_URI = "http://www.angstrom-distribution.org/unstable/sources/gcc-4.1.2-atmel.1.1.0.tar.gz \
+#           file://100-uclibc-conf.patch;patch=1 \
+#           file://200-uclibc-locale.patch;patch=1 \
+#           file://300-libstdc++-pic.patch;patch=1 \
+           file://301-missing-execinfo_h.patch;patch=1 \
+           file://302-c99-snprintf.patch;patch=1 \
+           file://303-c99-complex-ugly-hack.patch;patch=1 \
+           file://304-index_macro.patch;patch=1 \
+           file://602-sdk-libstdc++-includes.patch;patch=1 \
+           file://gcc41-configure.in.patch;patch=1 \
+           file://ldflags.patch;patch=1 \
+           file://zecke-xgcc-cpp.patch;patch=1 \
+           file://cache-amnesia.patch;patch=1 \
+          "
+
+do_compile_prepend() {
+ln -sf ${S}/libstdc++-v3/config/os/uclibc/ ${S}/libstdc++-v3/config/os/uclibc-linux 
+}
index 8204e2c..518a6a7 100644 (file)
@@ -17,4 +17,6 @@ require gcc-package-cross.inc
 
 SRC_URI_append_fail-fast = " file://zecke-no-host-includes.patch;patch=1 "
 
+EXTRA_OECONF_append_avr32= "  --disable-libmudflap "
+
 EXTRA_OECONF += "--disable-libunwind-exceptions --with-mpfr=${STAGING_DIR_NATIVE}${layout_exec_prefix}"
index 0875d1a..3dcf86c 100644 (file)
@@ -43,7 +43,7 @@ do_install () {
                 # Already in the right location
                 :
         elif [ -f ${D}${prefix}/lib/libgcc_s.so.? ]; then
-                mv -f ${D}${prefix}/lib/libgcc_s.so* ${D}${target_base_libdir}
+                mv -f ${D}${prefix}/lib/libgcc_s.so* ${D}${target_base_libdir} || true
 
         elif [  -f ${D}${prefix}/*/lib/nof/libgcc_s.so.? ]; then
                 mv -f ${D}${prefix}/*/lib/nof/libgcc_s.so* ${D}${target_base_libdir}
@@ -75,7 +75,7 @@ do_install () {
        if [ "x${OLD_INHIBIT_PACKAGE_STRIP}" != "x1" ]; then
                ${TARGET_PREFIX}strip ${D}${target_libdir}/libstdc++.so.*
                ${TARGET_PREFIX}strip ${D}${target_libdir}/libg2c.so.* || true
-               ${TARGET_PREFIX}strip ${D}${target_base_libdir}/libgcc_s.so.*
+               ${TARGET_PREFIX}strip ${D}${target_base_libdir}/libgcc_s.so.* || true
                ${TARGET_PREFIX}strip ${D}${target_libdir}/libgfortran*.so* || true
        fi
 }
index 0f8cfa4..9d3d3e3 100644 (file)
@@ -36,6 +36,25 @@ SRC_URI = "ftp://ftp.gnu.org/pub/gnu/gcc/gcc-4.1.2/gcc-4.1.2.tar.bz2 \
 
 SRC_URI_append_sh3  = " file://sh3-installfix-fixheaders.patch;patch=1 "
 
+SRC_URI_avr32 = "http://www.angstrom-distribution.org/unstable/sources/gcc-4.1.2-atmel.1.1.0.tar.gz \
+#           file://100-uclibc-conf.patch;patch=1 \
+#           file://200-uclibc-locale.patch;patch=1 \
+#           file://300-libstdc++-pic.patch;patch=1 \
+           file://301-missing-execinfo_h.patch;patch=1 \
+           file://302-c99-snprintf.patch;patch=1 \
+           file://303-c99-complex-ugly-hack.patch;patch=1 \
+           file://304-index_macro.patch;patch=1 \
+           file://602-sdk-libstdc++-includes.patch;patch=1 \
+           file://gcc41-configure.in.patch;patch=1 \
+           file://ldflags.patch;patch=1 \
+           file://zecke-xgcc-cpp.patch;patch=1 \
+           file://cache-amnesia.patch;patch=1 \
+           "
+
+do_compile_prepend_avr32() {
+       ln -sf ${S}/libstdc++-v3/config/os/uclibc/ ${S}/libstdc++-v3/config/os/uclibc-linux
+}
+
 #Set the fortran bits
 # ',fortran' or '', not 'f77' like gcc3 had
 FORTRAN = ""
diff --git a/packages/libmad/files/.mtn2git_empty b/packages/libmad/files/.mtn2git_empty
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/packages/libmad/files/libmad-0.15.1b-avr32-optimization.patch b/packages/libmad/files/libmad-0.15.1b-avr32-optimization.patch
new file mode 100644 (file)
index 0000000..f6620f5
--- /dev/null
@@ -0,0 +1,2922 @@
+diff --git a/bit.c b/bit.c
+index c2bfb24..262ce3a 100644
+--- a/bit.c
++++ b/bit.c
+@@ -25,12 +25,6 @@
+ # include "global.h"
+-# ifdef HAVE_LIMITS_H
+-#  include <limits.h>
+-# else
+-#  define CHAR_BIT  8
+-# endif
+-
+ # include "bit.h"
+ /*
+@@ -81,6 +75,8 @@ unsigned short const crc_table[256] = {
+ # define CRC_POLY  0x8005
++#ifndef FPM_AVR32
++
+ /*
+  * NAME:      bit->init()
+  * DESCRIPTION:       initialize bit pointer struct
+@@ -190,6 +186,8 @@ void mad_bit_write(struct mad_bitptr *bitptr, unsigned int len,
+ }
+ # endif
++#endif
++
+ /*
+  * NAME:      bit->crc()
+  * DESCRIPTION:       compute CRC-check word
+diff --git a/bit.h b/bit.h
+index 5a51570..70f550a 100644
+--- a/bit.h
++++ b/bit.h
+@@ -22,6 +22,92 @@
+ # ifndef LIBMAD_BIT_H
+ # define LIBMAD_BIT_H
++# ifdef HAVE_LIMITS_H
++#  include <limits.h>
++# else
++#  define CHAR_BIT  8
++# endif
++
++#ifdef FPM_AVR32
++
++struct mad_bitptr {
++  unsigned char const *byte;
++  unsigned int read_bytes;
++};
++
++/*
++ * NAME:      bit->init()
++ * DESCRIPTION:       initialize bit pointer struct
++ */
++static void mad_bit_init(struct mad_bitptr *bitptr, unsigned char const *byte)
++{
++  bitptr->byte  = byte;
++  bitptr->read_bytes  = 0;
++}
++
++/*
++ * NAME:      bit->length()
++ * DESCRIPTION:       return number of bits between start and end points
++ */
++static unsigned int mad_bit_length(struct mad_bitptr const *begin,
++                          struct mad_bitptr const *end)
++{
++  return (end->read_bytes - begin->read_bytes) +
++    8 * (end->byte - begin->byte);
++}
++
++/*
++ * NAME:      bit->nextbyte()
++ * DESCRIPTION:       return pointer to next unprocessed byte
++ */
++static unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *bitptr)
++{
++  return bitptr->byte + ((bitptr->read_bytes + 0x7) >> 3);
++}
++
++/*
++ * NAME:      bit->skip()
++ * DESCRIPTION:       advance bit pointer
++ */
++static void mad_bit_skip(struct mad_bitptr *bitptr, unsigned int len)
++{
++  bitptr->read_bytes += len;
++  bitptr->byte += (bitptr->read_bytes >> 3);
++  bitptr->read_bytes &=  0x7;
++}
++
++/*
++ * NAME:      bit->read()
++ * DESCRIPTION:       read an arbitrary number of bits and return their UIMSBF value
++ */
++static unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len)
++{
++  register unsigned long value;
++
++  if (!len)
++    return 0;
++
++  value = *(unsigned int *)bitptr->byte;
++
++  value <<= bitptr->read_bytes;
++  value >>= (32 - len);
++
++  bitptr->read_bytes += len;
++  bitptr->byte += (bitptr->read_bytes >> 3);
++  bitptr->read_bytes &=  0x7;
++
++  return value;
++}
++
++# define mad_bit_finish(bitptr)               /* nothing */
++
++static unsigned long  mad_bit_bitsleft(struct mad_bitptr *bitptr)
++{
++  return (8 - (bitptr)->read_bytes);
++}
++
++#else /* #ifdef FPM_AVR32 */
++
+ struct mad_bitptr {
+   unsigned char const *byte;
+   unsigned short cache;
+@@ -42,6 +128,8 @@ void mad_bit_skip(struct mad_bitptr *, unsigned int);
+ unsigned long mad_bit_read(struct mad_bitptr *, unsigned int);
+ void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long);
++#endif
++
+ unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short);
+ # endif
+diff --git a/configure b/configure
+index ee421cc..7a9f0c8 100755
+--- a/configure
++++ b/configure
+@@ -1048,7 +1048,7 @@ Optional Features:
+   --enable-speed          optimize for speed over accuracy
+   --enable-accuracy       optimize for accuracy over speed
+   --enable-fpm=ARCH       use ARCH-specific fixed-point math routines (one of:
+-                          intel, arm, mips, sparc, ppc, 64bit, default)
++                          intel, arm, avr32, mips, sparc, ppc, 64bit, default)
+   --enable-sso            use subband synthesis optimization
+   --disable-aso           disable architecture-specific optimizations
+   --enable-strict-iso     use strict ISO/IEC interpretations
+@@ -21477,6 +21477,7 @@ if test "${enable_fpm+set}" = set; then
+       no|default|approx) FPM="DEFAULT" ;;
+       intel|i?86)        FPM="INTEL"   ;;
+       arm)               FPM="ARM"     ;;
++      avr32)             FPM="AVR32"   ;;
+       mips)              FPM="MIPS"    ;;
+       sparc)             FPM="SPARC"   ;;
+       ppc|powerpc)       FPM="PPC"     ;;
+@@ -21498,6 +21499,7 @@ then
+     case "$host" in
+       i?86-*)     FPM="INTEL"  ;;
+       arm*-*)     FPM="ARM"    ;;
++      avr32*-*)   FPM="AVR32"  ;;
+       mips*-*)    FPM="MIPS"   ;;
+       sparc*-*)   FPM="SPARC"  ;;
+       powerpc*-*) FPM="PPC"    ;;
+@@ -21554,6 +21556,11 @@ then
+           ASO="$ASO -DASO_IMDCT"
+           ASO_OBJS="imdct_l_arm.lo"
+           ;;
++      avr32*-*)
++          ASO="$ASO -DASO_INTERLEAVE2"
++          ASO="$ASO -DASO_ZEROCHECK"
++          ASO_OBJS="dct32_avr32.lo synth_avr32.lo imdct_avr32.lo"
++          ;;
+       mips*-*)
+           ASO="$ASO -DASO_INTERLEAVE2"
+           ASO="$ASO -DASO_ZEROCHECK"
+diff --git a/configure.ac b/configure.ac
+index 9b79399..063cb9b 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -274,13 +274,14 @@ fi
+ AC_MSG_CHECKING(for architecture-specific fixed-point math routines)
+ AC_ARG_ENABLE(fpm, AC_HELP_STRING([--enable-fpm=ARCH],
+                  [use ARCH-specific fixed-point math routines
+-                  (one of: intel, arm, mips, sparc, ppc, 64bit, default)]),
++                  (one of: intel, arm, avr32, mips, sparc, ppc, 64bit, default)]),
+ [
+     case "$enableval" in
+       yes)                             ;;
+       no|default|approx) FPM="DEFAULT" ;;
+       intel|i?86)        FPM="INTEL"   ;;
+       arm)               FPM="ARM"     ;;
++      avr32)             FPM="AVR32"   ;;
+       mips)              FPM="MIPS"    ;;
+       sparc)             FPM="SPARC"   ;;
+       ppc|powerpc)       FPM="PPC"     ;;
+@@ -298,6 +299,7 @@ then
+     case "$host" in
+       i?86-*)     FPM="INTEL"  ;;
+       arm*-*)     FPM="ARM"    ;;
++      avr32*-*)   FPM="AVR32"  ;;
+       mips*-*)    FPM="MIPS"   ;;
+       sparc*-*)   FPM="SPARC"  ;;
+       powerpc*-*) FPM="PPC"    ;;
+@@ -343,6 +345,11 @@ then
+           ASO="$ASO -DASO_IMDCT"
+           ASO_OBJS="imdct_l_arm.lo"
+           ;;
++      avr32*-*)
++          ASO="$ASO -DASO_INTERLEAVE2"
++          ASO="$ASO -DASO_ZEROCHECK"
++          ASO_OBJS="dct32_avr32.lo synth_avr32.lo imdct_avr32.lo"
++          ;;
+       mips*-*)
+           ASO="$ASO -DASO_INTERLEAVE2"
+           ASO="$ASO -DASO_ZEROCHECK"
+diff --git a/dct32_avr32.S b/dct32_avr32.S
+new file mode 100644
+index 0000000..7513340
+--- /dev/null
++++ b/dct32_avr32.S
+@@ -0,0 +1,780 @@
++/*
++   Optimized 32-point Discrete Cosine Transform (DCT)
++   Copyright 2003-2006 Atmel Corporation.
++
++   Written by Ronny Pedersen, 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. */
++
++#define       SHIFT   12
++#define MAD_F_SCALEBITS 28
++#define SLOTS 8
++
++#define MAD_F(x)      ((x + (1 << 15)) >> 16)
++
++#  define costab1     MAD_F(0x7fd8878e)
++#  define costab2     MAD_F(0x7f62368f)
++#  define costab3     MAD_F(0x7e9d55fc)
++#  define costab4     MAD_F(0x7d8a5f40)
++#  define costab5     MAD_F(0x7c29fbee)
++#  define costab6     MAD_F(0x7a7d055b)
++#  define costab7     MAD_F(0x78848414)
++#  define costab8     MAD_F(0x7641af3d)
++#  define costab9     MAD_F(0x73b5ebd1)
++#  define costab10    MAD_F(0x70e2cbc6)
++#  define costab11    MAD_F(0x6dca0d14)
++#  define costab12    MAD_F(0x6a6d98a4)
++#  define costab13    MAD_F(0x66cf8120)
++#  define costab14    MAD_F(0x62f201ac)
++#  define costab15    MAD_F(0x5ed77c8a)
++#  define costab16    MAD_F(0x5a82799a)
++#  define costab17    MAD_F(0x55f5a4d2)
++#  define costab18    MAD_F(0x5133cc94)
++#  define costab19    MAD_F(0x4c3fdff4)
++#  define costab20    MAD_F(0x471cece7)
++#  define costab21    MAD_F(0x41ce1e65)
++#  define costab22    MAD_F(0x3c56ba70)
++#  define costab23    MAD_F(0x36ba2014)
++#  define costab24    MAD_F(0x30fbc54d)
++#  define costab25    MAD_F(0x2b1f34eb)
++#  define costab26    MAD_F(0x25280c5e)
++#  define costab27    MAD_F(0x1f19f97b)
++#  define costab28    MAD_F(0x18f8b83c)
++#  define costab29    MAD_F(0x12c8106f)
++#  define costab30    MAD_F(0x0c8bd35e)
++#  define costab31    MAD_F(0x0647d97c)
++
++
++      .macro  butterfly2_in out1, out2, out3, out4, in, idx_in1, idx_in2, idx_in3, idx_in4, coeff1, coeff2, tmplo, tmphi
++      mov     \tmplo, \coeff1
++      ld.w    \out1, \in[\idx_in1 * 4]
++      ld.w    \out2, \in[\idx_in2 * 4]
++      ld.w    \out3, \in[\idx_in3 * 4]
++      ld.w    \out4, \in[\idx_in4 * 4]
++      sub     \tmphi, \out1, \out2
++      add     \out1, \out2
++      mulsatrndwh.w   \out2, \tmphi, \tmplo:b
++
++      sub     \tmphi, \out3, \out4
++      mov     \tmplo, \coeff2
++      add     \out3, \out4
++      mulsatrndwh.w   \out4, \tmphi, \tmplo:b
++      .endm
++
++      .macro  butterfly2      in1, in2, in3, in4, coeff1, tmplo, tmphi, tmp
++      mov     \tmp, \coeff1
++      sub     \tmphi, \in1, \in2
++      add     \in1, \in2
++      mulsatrndwh.w   \in2, \tmphi, \tmp:b
++
++      sub     \tmphi, \in3, \in4
++      add     \in3, \in4
++      mulsatrndwh.w   \in4, \tmphi, \tmp:b
++      .endm
++
++      .macro  butterfly4      in1, in2, in3, in4, in5, in6, in7, in8, coeff1, tmplo, tmphi, tmp
++      mov     \tmp, \coeff1
++      sub     \tmphi, \in1, \in2
++      add     \in1, \in2
++      mulsatrndwh.w   \in2, \tmphi, \tmp:b
++
++      sub     \tmphi, \in3, \in4
++      add     \in3, \in4
++      mulsatrndwh.w   \in4, \tmphi, \tmp:b
++
++      sub     \tmphi, \in5, \in6
++      add     \in5, \in6
++      mulsatrndwh.w   \in6, \tmphi, \tmp:b
++
++      sub     \tmphi, \in7, \in8
++      add     \in7, \in8
++      mulsatrndwh.w   \in8, \tmphi, \tmp:b
++      .endm
++
++      .macro  scale   reg
++      .endm
++
++/*void dct32( mad_fixed_t const in[32], unsigned int slot,
++              mad_fixed_t lo[16][8], mad_fixed_t hi[16][8]) */
++
++      .global dct32_avr32
++dct32_avr32:
++      stm     --sp, r0-r7, r9-r11, lr
++
++      sub     sp, 32*4
++
++/*    t0   = in[0]  + in[31];  t16  = MUL(in[0]  - in[31], costab1);
++      t1   = in[15] + in[16];  t17  = MUL(in[15] - in[16], costab31); */
++      butterfly2_in   r4/*t0*/, r5/*t16*/, r6/*t1*/, r7/*t17*/, r12, 0, 31, 15, 16, costab1, costab31, r10, r11
++
++/*    t41  = t16 + t17;
++      t59  = MUL(t16 - t17, costab2);
++      t33  =   t0  + t1;
++      t50  = MUL(t0  - t1,  costab2);*/
++      butterfly2      r5/*t41*/, r7/*t59*/, r4/*t33*/, r6/*t50*/, costab2, r10, r11, lr
++
++/*    t2   = in[7]  + in[24];  t18  = MUL(in[7]  - in[24], costab15);
++      t3   = in[8]  + in[23];  t19  = MUL(in[8]  - in[23], costab17); */
++      butterfly2_in   r0/*t2*/, r1/*t18*/, r2/*t3*/, r3/*t19*/, r12, 7, 24, 8, 23, costab15, costab17, r10, r11
++
++/*    t42  = t18 + t19;
++      t60  = MUL(t18 - t19, costab30);
++      t34  = t2  + t3;
++      t51  = MUL(t2  - t3,  costab30); */
++      butterfly2      r1/*t42*/, r3/*t60*/, r0/*t34*/, r2/*t51*/, costab30, r10, r11, lr
++
++/*    t73  = t41 + t42;  t94  = MUL(t41 - t42, costab4);
++      t83  = t59 + t60;  t106 = MUL(t59 - t60, costab4); */
++
++
++/*    t69  = t33 + t34;  t89  = MUL(t33 - t34, costab4);
++      t78  = t50 + t51;  t100 = MUL(t50 - t51, costab4); */
++      butterfly4      r5/*t73*/, r1/*t94*/, r7/*t83*/, r3/*t106*/,r4/*t69*/, r0/*t89*/, r6/*t78*/, r2/*t100*/, costab4, r10, r11, lr
++
++/*    Store away the computed butterflies:
++      sp[0-7] = t83, t78, t73, t69, t106, t100, t94, t89 */
++      stm     sp, r0-r7
++
++
++/*    t4   = in[3]  + in[28];  t20  = MUL(in[3]  - in[28], costab7);
++      t5   = in[12] + in[19];  t21  = MUL(in[12] - in[19], costab25); */
++      butterfly2_in   r4/*t4*/, r5/*t20*/, r6/*t5*/, r7/*t21*/, r12, 3, 28, 12, 19, costab7, costab25, r10, r11
++
++/*    t43  = t20 + t21;
++      t61  = MUL(t20 - t21, costab14);
++      t35  = t4  + t5;
++      t52  = MUL(t4  - t5,  costab14); */
++      butterfly2      r5/*t43*/, r7/*t61*/, r4/*t35*/, r6/*t52*/, costab14, r10, r11, lr
++
++/*    t6   = in[4]  + in[27];  t22  = MUL(in[4]  - in[27], costab9);
++      t7   = in[11] + in[20];  t23  = MUL(in[11] - in[20], costab23); */
++      butterfly2_in   r0/*t6*/, r1/*t22*/, r2/*t7*/, r3/*t23*/, r12, 4, 27, 11, 20, costab9, costab23, r10, r11
++
++/*    t44  = t22 + t23;
++      t62  = MUL(t22 - t23, costab18);
++      t36  = t6  + t7;
++      t53  = MUL(t6  - t7,  costab18); */
++      butterfly2      r1/*t44*/, r3/*t62*/, r0/*t36*/, r2/*t53*/, costab18, r10, r11, lr
++
++/*    t74  = t43 + t44;  t95  = MUL(t43 - t44, costab28);
++      t84  = t61 + t62;  t107 = MUL(t61 - t62, costab28); */
++
++/*    t70  = t35 + t36;  t90  = MUL(t35 - t36, costab28);
++      t79  = t52 + t53;  t101 = MUL(t52 - t53, costab28); */
++      butterfly4      r5/*t74*/, r1/*t95*/, r7/*t84*/, r3/*t107*/, r4/*t70*/, r0/*t90*/, r6/*t79*/, r2/*t101*/, costab28, r10, r11, lr
++
++/*    Store away the computed butterflies:
++      sp[8-15] = t84, t79, t74, t70, t107, t101, t95, t90 */
++      sub     r10, sp, -8*4
++      stm     r10, r0-r7
++
++
++/*    t8   = in[1]  + in[30];  t24  = MUL(in[1]  - in[30], costab3);
++      t9   = in[14] + in[17];  t25  = MUL(in[14] - in[17], costab29); */
++      butterfly2_in   r4/*t8*/, r5/*t24*/, r6/*t9*/, r7/*t25*/, r12, 1, 30, 14, 17, costab3, costab29, r10, r11
++
++
++/*    t45  = t24 + t25;
++      t63  = MUL(t24 - t25, costab6);
++      t37  = t8  + t9;
++      t54  = MUL(t8  - t9,  costab6); */
++      butterfly2      r5/*t45*/, r7/*t63*/, r4/*t37*/, r6/*t54*/, costab6, r10, r11, lr
++
++/*    t10  = in[6]  + in[25];  t26  = MUL(in[6]  - in[25], costab13);
++      t11  = in[9]  + in[22];  t27  = MUL(in[9]  - in[22], costab19); */
++      butterfly2_in   r0/*t10*/, r1/*t26*/, r2/*t11*/, r3/*t27*/, r12, 6, 25, 9, 22, costab13, costab19, r10, r11
++
++/*    t46  = t26 + t27;
++      t64  = MUL(t26 - t27, costab26);
++      t38  = t10 + t11;
++      t55  = MUL(t10 - t11, costab26); */
++      butterfly2      r1/*t46*/, r3/*t64*/, r0/*t38*/, r2/*t55*/, costab26, r10, r11, lr
++
++/*    t75  = t45 + t46;  t96  = MUL(t45 - t46, costab12);
++      t85  = t63 + t64;  t108 = MUL(t63 - t64, costab12); */
++
++/*    t71  = t37 + t38;  t91  = MUL(t37 - t38, costab12);
++      t80  = t54 + t55;  t102 = MUL(t54 - t55, costab12); */
++      butterfly4      r5/*t75*/, r1/*t96*/, r7/*t85*/, r3/*t108*/, r4/*t71*/, r0/*t91*/, r6/*t80*/, r2/*t102*/, costab12, r10, r11, lr
++
++/*    Store away the computed butterflies:
++      sp[16-23] = t85, t80, t75, t71, t108, t102, t96, t91 */
++      sub     r10, sp, -16*4
++      stm     r10, r0-r7
++
++/*    t12  = in[2]  + in[29];  t28  = MUL(in[2]  - in[29], costab5);
++      t13  = in[13] + in[18];  t29  = MUL(in[13] - in[18], costab27); */
++      butterfly2_in   r4/*t12*/, r5/*t28*/, r6/*t13*/, r7/*t29*/, r12, 2, 29, 13, 18, costab5, costab27, r10, r11
++
++/*    t47  = t28 + t29;
++      t65  = MUL(t28 - t29, costab10);
++      t39  = t12 + t13;
++      t56  = MUL(t12 - t13, costab10); */
++      butterfly2      r5/*t47*/, r7/*t65*/, r4/*t39*/, r6/*t56*/, costab10, r10, r11, lr
++
++/*    t14  = in[5]  + in[26];  t30  = MUL(in[5]  - in[26], costab11);
++      t15  = in[10] + in[21];  t31  = MUL(in[10] - in[21], costab21);*/
++      butterfly2_in   r0/*t14*/, r1/*t30*/, r2/*t15*/, r3/*t31*/, r12, 5, 26, 10, 21, costab11, costab21, r10, r11
++
++/*    t48  = t30 + t31;
++      t66  = MUL(t30 - t31, costab22);
++      t40  = t14 + t15;
++      t57  = MUL(t14 - t15, costab22);*/
++      butterfly2      r1/*t48*/, r3/*t66*/, r0/*t40*/, r2/*t57*/, costab22, r10, r11, lr
++
++/*    t76  = t47 + t48;  t97  = MUL(t47 - t48, costab20);
++      t86  = t65 + t66;  t109 = MUL(t65 - t66, costab20);*/
++
++/*    t72  = t39 + t40;  t92  = MUL(t39 - t40, costab20);
++      t81  = t56 + t57;  t103 = MUL(t56 - t57, costab20);*/
++      butterfly4      r5/*t76*/, r1/*t97*/, r7/*t86*/, r3/*t109*/,r4/*t72*/, r0/*t92*/, r6/*t81*/, r2/*t103*/, costab20, r10, r11, lr
++
++/*    Store away the computed butterflies:
++      sp[24-31] = t86, t81, t76, t72, t109, t103, t97, t92 */
++      sub     r10, sp, -24*4
++      stm     r10, r0-r7
++
++/*      We now have the following on the stack:
++
++      sp[0-7] = t83, t78, t73, t69, t106, t100, t94, t89
++      sp[8-15] = t84, t79, t74, t70, t107, t101, t95, t90
++      sp[16-23] = t85, t80, t75, t71, t108, t102, t96, t91
++      sp[24-31] = t86, t81, t76, t72, t109, t103, t97, t92    */
++
++/*    Load    {r0...r7} = { t72, t76, t71, t75, t70, t74, t69, t73 } */
++      ld.d    r6, sp[2*4]
++      ld.d    r4, sp[10*4]
++      ld.d    r2, sp[18*4]
++      ld.d    r0, sp[26*4]
++
++
++/*    t113 = t69  + t70;
++      t141 = MUL(t69 - t70, costab8);
++
++      t115 = t73  + t74;
++      t144 = MUL(t73 - t74, costab8); */
++      butterfly2      r6/*t113*/, r4/*t141*/, r7/*t115*/, r5/*t144*/, costab8, r10, r11, lr
++
++/*    t114 = t71  + t72;
++      t142 = MUL(t71 - t72, costab24);
++
++      t116 = t75  + t76;
++      t145 = MUL(t75 - t76, costab24); */
++      butterfly2      r2/*t114*/, r0/*t142*/, r3/*t116*/, r1/*t145*/, costab24, r10, r11, lr
++
++
++/*
++      t191 = t113 + t114;
++      t192 = MUL(t113 - t114, costab16)
++
++      t32  = t115 + t116;
++      t177 = MUL(t115 - t116, costab16) ;
++
++      t143 = t141 + t142;
++      t190 = MUL(t141 - t142, costab16) ;
++
++      t146 = t144 + t145;
++      t184 = MUL(t144 - t145, costab16) ; */
++      butterfly4      r6/*t191*/, r2/*t192*/, r7/*t32*/, r3/*t177*/, r4/*t143*/, r0/*190*/, r5/*t146*/, r1/*t184*/, costab16, r10, r11, lr
++
++/*    Store away the computed butterflies:
++      sp[2-3] = t32, t191
++      sp[10-11] = t146, t143
++      sp[18-19] = t177, t192
++      sp[26-27] = t184, t190 */
++      st.d    sp[2*4] , r6
++      st.d    sp[10*4], r4
++      st.d    sp[18*4], r2
++      st.d    sp[26*4], r0
++
++/*    Load    {r0...r7} = { t81, t86, t80, t85, t79, t84, t78, t83 } */
++      ld.d    r6, sp[0*4]
++      ld.d    r4, sp[8*4]
++      ld.d    r2, sp[16*4]
++      ld.d    r0, sp[24*4]
++
++
++/*    t118 = t78  + t79;
++      t148 = MUL(t78 - t79, costab8);
++
++      t121 = t83  + t84;
++      t152 = MUL(t83 - t84, costab8); */
++      butterfly2      r6/*t118*/, r4/*t148*/, r7/*t121*/, r5/*t152*/, costab8, r10, r11, lr
++
++/*    t119 = t80  + t81;
++      t149 = MUL(t80 - t81, costab24);
++
++      t122 = t85  + t86;
++      t153 = MUL(t85 - t86, costab24); */
++      butterfly2      r2/*t119*/, r0/*t149*/, r3/*t122*/, r1/*t153*/, costab24, r10, r11, lr
++
++
++
++/*    t58  = t118 + t119;
++      t178 = MUL(t118 - t119, costab16) ;
++
++      t67  = t121 + t122;
++      t179 = MUL(t121 - t122, costab16) ;
++
++      t150 = t148 + t149;
++      t185 = MUL(t148 - t149, costab16) ;
++
++      t154 = t152 + t153;
++      t186 = MUL(t152 - t153, costab16) ; */
++      butterfly4      r6/*t58*/, r2/*t178*/, r7/*t67*/, r3/*t179*/, r4/*t150*/, r0/*185*/, r5/*t154*/, r1/*t186*/, costab16, r10, r11, lr
++
++/*    Store away the computed butterflies:
++      sp[0-1] = t67, t58
++      sp[8-9] = t154, t150
++      sp[16-17] = t179, t178
++      sp[24-25] = t186, t185 */
++      st.d    sp[0*4] , r6
++      st.d    sp[8*4], r4
++      st.d    sp[16*4], r2
++      st.d    sp[24*4], r0
++
++/*    Load    {r0...r7} = { t92, t97, t91, t96, t90, t95, t89, t94 } */
++      ld.d    r6, sp[6*4]
++      ld.d    r4, sp[14*4]
++      ld.d    r2, sp[22*4]
++      ld.d    r0, sp[30*4]
++
++
++/*    t125 = t89  + t90;
++      t157 = MUL(t89 - t90, costab8);
++
++      t128 = t94  + t95;
++      t161 = MUL(t94 - t95, costab8); */
++      butterfly2      r6/*t125*/, r4/*t157*/, r7/*t128*/, r5/*t161*/, costab8, r10, r11, lr
++
++/*    t126 = t91  + t92;
++      t158 = MUL(t91 - t92, costab24);
++
++      t129 = t96  + t97;
++      t162 = MUL(t96 - t97, costab24); */
++      butterfly2      r2/*t126*/, r0/*t158*/, r3/*t129*/, r1/*t162*/, costab24, r10, r11, lr
++
++
++/*
++      t93  = t125 + t126;
++      t180 = MUL(t125 - t126, costab16) ;
++
++      t98  = t128 + t129;
++      t181 = MUL(t128 - t129, costab16) ;
++
++      t159 = t157 + t158;
++      t187 = MUL(t157 - t158, costab16) ;
++
++      t163 = t161 + t162;
++      t188 = MUL(t161 - t162, costab16) ; */
++      butterfly4      r6/*t93*/, r2/*t180*/, r7/*t98*/, r3/*t181*/, r4/*t159*/, r0/*187*/, r5/*t163*/, r1/*t188*/, costab16, r10, r11, lr
++
++
++/*    Store away the computed butterflies:
++      sp[6-7] = t98, t93
++      sp[14-15] = t163, t159
++      sp[22-23] = t181, t180
++      sp[30-31] = t188, t187 */
++      st.d    sp[6*4] , r6
++      st.d    sp[14*4], r4
++      st.d    sp[22*4], r2
++      st.d    sp[30*4], r0
++
++/*    Load    {r0...r7} = { t103, t109, t102, t108, t101, t107, t100, t106 } */
++      ld.d    r6, sp[4*4]
++      ld.d    r4, sp[12*4]
++      ld.d    r2, sp[20*4]
++      ld.d    r0, sp[28*4]
++
++
++
++/*    t132 = t100 + t101;
++      t166 = MUL(t100 - t101, costab8);
++
++      t136 = t106 + t107;
++      t171 = MUL(t106 - t107, costab8); */
++      butterfly2      r6/*t132*/, r4/*t166*/, r7/*t136*/, r5/*t171*/, costab8, r10, r11, lr
++
++/*    t133 = t102 + t103;
++      t167 = MUL(t102 - t103, costab24);
++
++      t137 = t108 + t109;
++      t172 = MUL(t108 - t109, costab24);*/
++      butterfly2      r2/*t133*/, r0/*t167*/, r3/*t137*/, r1/*t172*/, costab24, r10, r11, lr
++
++
++/*    t104 = t132 + t133;
++      t182 = MUL(t132 - t133, costab16) ;
++
++      t110 = t136 + t137;
++      t183 = MUL(t136 - t137, costab16) ;
++
++      t168 = t166 + t167;
++      t189 = MUL(t166 - t167, costab16) ;
++
++      t173 = t171 + t172;
++      t208 = MUL(t171 - t172, costab16) ; */
++      butterfly4      r6/*t104*/, r2/*t182*/, r7/*t110*/, r3/*t183*/, r4/*t168*/, r0/*189*/, r5/*t173*/, r1/*t208*/, costab16, r10, r11, lr
++
++/*    Store away the computed butterflies:
++      sp[4-5] = t110, t104
++      sp[12-13] = t173, t168
++      sp[20-21] = t183, t182
++      sp[28-29] = t208, t189 */
++      st.d    sp[4*4] , r6
++      st.d    sp[12*4], r4
++      st.d    sp[20*4], r2
++      st.d    sp[28*4], r0
++
++/*    Now we have the following stack
++
++      sp[0-7]   = t67,  t58 , t32,  t191, t110, t104, t98,  t93
++      sp[8-15]  = t154, t150, t146, t143, t173, t168, t163, t159
++      sp[16-23] = t179, t178, t177, t192, t183, t182, t181, t180
++      sp[24-31] = t186, t185, t184, t190, t208, t189, t188, t187
++*/
++
++      /* Get slot, lo and hi from stack */
++      lddsp   lr, sp[32*4 + 4] /*slot*/
++      lddsp   r12, sp[32*4 + 8] /*lo*/
++      lddsp   r11, sp[32*4 + 12] /*hi*/
++
++      add     r12, r12, lr << 2
++      add     r11, r11, lr << 2
++
++
++/*    t49  = -(t67 * 2) + t32;
++       hi[14][slot] = SHIFT(t32);
++      t87  = -(t110 * 2) + t67;
++      t138 = -(t173 * 2) + t110;
++      t203 = -(t208 * 2) + t173; */
++
++      lddsp   r0/*t67*/, sp[0]
++      lddsp   r1/*t32*/, sp[2*4]
++      lddsp   r2/*t110*/, sp[4*4]
++      lddsp   r3/*t173*/, sp[12*4]
++      lddsp   r5/*t208*/, sp[28*4]
++
++      sub     r4/*t49*/, r1, r0 << 1
++      scale   r1
++      sub     r0/*t87*/, r0, r2 << 1
++      st.w    r11[14*SLOTS*4], r1
++      sub     r2/*t138*/, r2, r3 << 1
++      sub     r1/*t203*/, r3, r5 << 1
++
++/*      Live: r0 = t87, r1= t203, r2= t138, r4 = t49
++      Free:   r3, r5, r6, r7, r8, r9, r10, lr  */
++
++/*    t68  = (t98 * 2) + t49;
++      hi[12][slot] = SHIFT(-t49);
++      t130 = -(t163 * 2) + t98;
++      t201 = -(t188 * 2) + t163;
++      t200 = -(t186 * 2) + t154;
++      t111 = (t154 * 2) + t87;
++      t77  = -(-(t87 * 2) - t68);
++      t88  = (t146 * 2) + t77;
++      t199 = -(t184 * 2) + t146;
++      hi[ 8][slot] = SHIFT(-t77);
++      hi[10][slot] = SHIFT(t68);*/
++      lddsp   r3/*t98*/, sp[6*4]
++      lddsp   r5/*t163*/, sp[14*4]
++      lddsp   r6/*t188*/, sp[30*4]
++      lddsp   r10/*t186*/, sp[24*4]
++
++      add     r7/*t68*/, r4, r3 << 1
++      neg     r4
++      scale   r4
++      lddsp   r9/*t154*/, sp[8*4]
++      sub     r3/*t130*/, r3, r5 << 1
++      st.w    r11[12*SLOTS*4], r4
++      sub     r8/*t201*/, r5, r6 << 1
++      sub     r4/*t200*/, r9, r10 << 1
++      lddsp   lr/*t146*/, sp[10*4]
++      lddsp   r6/*t184*/, sp[26*4]
++      add     r10/*t111*/, r0, r9 << 1
++      add     r5/*t77*/,r7, r0 << 1
++      add     r0/*t88*/, r5, lr << 1
++      sub     r6/*t199*/, lr, r6 << 1
++      neg     r5
++      scale   r5
++      scale   r7
++      st.w    r11[8*SLOTS*4], r5
++      st.w    r11[10*SLOTS*4], r7
++
++/*      Live: r0 = t88, r1= t203, r2= t138, r3 = t130, r4 = t200,
++              r6 = 199, r8 = t201, r10 = t111
++      Free:   r5, r7, r9, lr    */
++
++
++/*
++      t123 = -(-(t138 * 2) - t111);
++      t174 = (t183 * 2) + t138;
++      t99  = -(t111 * 2) + t88;
++      hi[ 6][slot] = SHIFT(t88); */
++      lddsp   r5/*t183*/, sp[20*4]
++
++      add     r7/*t123*/, r10, r2 << 1
++      sub     r10/*t99*/, r0, r10 << 1
++      scale   r0
++      add     r2/*t174*/, r2, r5 << 1
++      st.w    r11[6*SLOTS*4], r0
++
++/*      Live: r1 = t203, r2 = t174, r3 = t130, r4 = t200,
++              r6 = t199, r7 = t123, r8 = t201, r10 = t99
++      Free:   r0, r5, r9, lr    */
++
++/*    t112 = -(t130 * 2) + t99;
++      t164 = (t181 * 2) + t130;
++      hi[ 4][slot] = SHIFT(-t99); */
++      lddsp   r0/*t181*/, sp[22*4]
++
++      sub     r5/*t112*/, r10, r3 << 1
++      neg     r10
++      scale   r10
++      add     r3/*164*/, r3, r0 << 1
++      st.w    r11[4*SLOTS*4], r10
++
++/*      Live: r1 = t203, r2 = t174, r3 = t164, r4 = t200,
++              r5 = t112, r6 = t199, r7 = t123, r8 = t201
++      Free:   r0, r9, r10, lr    */
++
++
++/*    t117 = -(-(t123 * 2) - t112);
++      t139 = (t179 * 2) + t123;
++      hi[ 2][slot] = SHIFT(t112); */
++      lddsp   r0/*t179*/, sp[16*4]
++
++      add     r9/*t117*/, r5, r7 << 1
++      scale   r5
++      add     r7/*t139*/, r7, r0 << 1
++      st.w    r11[2*SLOTS*4], r5
++
++/*      Live: r1 = t203, r2 = t174, r3 = t164, r4 = t200,
++              r6 = t199, r7 = t139, r8 = t201, r9 = t117
++      Free:   r0, r5, r10, lr    */
++
++/*    t155 = -(t174 * 2) + t139;
++      t204 = -(-(t203 * 2) - t174);
++      t124 = (t177 * 2) + t117;
++      hi[ 0][slot] = SHIFT(-t117);
++      t131 = -(t139 * 2) + t124;
++      lo[ 1][slot] = SHIFT(t124);*/
++      lddsp   r0/*t177*/, sp[18*4]
++
++      sub     r5/*t155*/, r7, r2 << 1
++      add     r2/*t204*/, r2, r1 << 1
++      add     r0/*t124*/, r9, r0 << 1
++      neg     r9
++      scale   r9
++      sub     r7/*t131*/, r0, r7 << 1
++      scale   r0
++      st.w    r11[0*SLOTS*4], r9
++      st.w    r12[1*SLOTS*4], r0
++
++/*      Live: r2 = t204, r3 = t164, r4 = t200,
++              r5 = t155, r6 = t199, r7 = t131, r8 = t201
++      Free:   r0, r1, r9, r10, lr    */
++
++/*    t140 = (t164 * 2) + t131;
++      lo[ 3][slot] = SHIFT(-t131);
++      t202 = -(-(t201 * 2) - t164);  */
++      add     r0/*t140*/, r7, r3 << 1
++      neg     r7
++      scale   r7
++      add     r3/*t202*/, r3, r8 << 1
++      st.w    r12[3*SLOTS*4], r7
++
++/*      Live: r0 = t140, r2 = t204, r3 = t202, r4 = t200,
++              r5 = t155, r6 = t199
++      Free:   r1, r7, r8, r9, r10, lr    */
++
++
++/*    t147 = -(-(t155 * 2) - t140);
++      lo[ 5][slot] = SHIFT(t140);
++      t175 = -(t200 * 2) + t155;
++      t156 = -(t199 * 2) + t147;
++      lo[ 7][slot] = SHIFT(-t147); */
++      add     r1/*t147*/, r0, r5 << 1
++      scale   r0
++      sub     r5/*t175*/, r5, r4 << 1
++      sub     r4/*156*/, r1, r6 << 1
++      neg     r1
++      scale   r1
++      st.w    r12[5*SLOTS*4], r0
++      st.w    r12[7*SLOTS*4], r1
++
++/*      Live: r2 = t204, r3 = t202,
++              r4 = t156, r5 = t175
++      Free:   r0, r1, r6, r7, r8, r9, r10, lr    */
++
++
++/*    t205 = -(-(t204 * 2) - t175);
++      t165 = -(t175 * 2) + t156;
++      lo[ 9][slot] = SHIFT(t156);
++      t176 = -(t202 * 2) + t165;
++      lo[11][slot] = SHIFT(-t165);
++      t206 = -(-(t205 * 2) - t176);
++      lo[15][slot] = SHIFT(-t206)
++      lo[13][slot] = SHIFT(t176) */
++      add     r0/*t205*/, r5, r2 << 1
++      sub     r1/*t165*/, r4, r5 << 1
++      scale   r4
++      sub     r3/*t176*/, r1, r3 << 1
++      st.w    r12[9*SLOTS*4], r4
++      neg     r1
++      scale   r1
++      add     r6/*t206*/, r3, r0 << 1
++      neg     r6
++      scale   r6
++      scale   r3
++      st.w    r12[11*SLOTS*4], r1
++      st.w    r12[15*SLOTS*4], r6
++      st.w    r12[13*SLOTS*4], r3
++
++/*    t193 = -((t190 * 2) - t143)
++      hi[ 7][slot] = SHIFT(t143);
++      lo[ 8][slot] = SHIFT(-t193);
++      t82  = -(t104 * 2) + t58;
++      hi[13][slot] = SHIFT(t58);
++      t134 = -(t168 * 2) + t104;
++      t196 = -(t189 * 2) + t168; */
++
++      lddsp   r0/*t190*/, sp[27*4]
++      lddsp   r1/*t143*/, sp[11*4]
++      lddsp   r2/*t104*/, sp[5*4]
++      lddsp   r3/*t58*/, sp[1*4]
++      lddsp   r4/*t168*/, sp[13*4]
++      lddsp   r5/*t189*/, sp[29*4]
++      sub     r0/*t193*/, r1, r0 << 1
++      neg     r0
++      scale   r1
++      scale   r0
++      st.w    r11[7*SLOTS*4], r1
++      st.w    r12[8*SLOTS*4], r0
++      sub     r0/*t82*/, r3, r2 << 1
++      scale   r3
++      sub     r2/*t134*/, r2, r4 << 1
++      sub     r4/*t196*/, r4, r5 << 1
++      st.w    r11[13*SLOTS*4], r3
++
++/*      Live: r0 = t82, r2 = t134,
++              r4 = t196
++      Free:   r1, r3, r5, r6, r7, r8, r9, r10, lr    */
++
++
++
++/*
++
++      t207 = -(t185 * 2) + t150;
++      t105 = (t150 * 2) + t82;
++      hi[ 9][slot] = SHIFT(-t82);
++      t120 = -(-(t134 * 2) - t105);
++      hi[ 5][slot] = SHIFT(t105);
++      t169 = (t182 * 2) + t134;
++
++      t135 = (t178 * 2) + t120;
++      hi[ 1][slot] = SHIFT(-t120);
++      t197 = -(-(t196 * 2) - t169);
++      t151 = -(t169 * 2) + t135;
++      lo[ 2][slot] = SHIFT(t135); */
++      lddsp   r1/*t185*/, sp[25*4]
++      lddsp   r3/*t150*/, sp[9*4]
++      lddsp   r5/*t182*/, sp[21*4]
++      lddsp   r8/*t178*/, sp[17*4]
++
++      sub     r6/*t207*/, r3, r1 << 1
++      add     r3/*t105*/, r0, r3 << 1
++      neg     r0
++      scale   r0
++      add     r7/*t120*/, r3, r2 << 1
++      scale   r3
++      st.w    r11[9*SLOTS*4], r0
++      st.w    r11[5*SLOTS*4], r3
++      add     r2/*t169*/, r2, r5 << 1
++      add     r8/*t135*/, r7, r8 << 1
++      neg     r7
++      scale   r7
++      add     r4/*t197*/, r2, r4 << 1
++      sub     r2/*t151*/, r8, r2 << 1
++      scale   r8
++      st.w    r11[1*SLOTS*4], r7
++      st.w    r12[2*SLOTS*4], r8
++
++/*      Live: r2 = t151, r4 = t197, r6 = t207
++
++      Free:   r0, r1, r3, r5, r7, r8, r9, r10, lr    */
++
++
++
++/*    t170 = -(t207 * 2) + t151;
++      lo[ 6][slot] = SHIFT(-t151);
++
++      t198 = -(-(t197 * 2) - t170);
++      lo[10][slot] = SHIFT(t170);
++      lo[14][slot] = SHIFT(-t198);
++
++      t127 = -(t159 * 2) + t93;
++      hi[11][slot] = SHIFT(t93);
++      t194 = -(t187 * 2) + t159;   */
++      lddsp   r0/*t159*/, sp[15*4]
++      lddsp   r1/*t93*/, sp[7*4]
++      lddsp   r3/*t187*/, sp[31*4]
++      sub     r5/*t170*/, r2, r6 << 1
++      neg     r2
++      scale   r2
++      add     r4/*t198*/,r5, r4 << 1
++      neg     r4
++      scale   r5
++      scale   r4
++      st.w    r12[6*SLOTS*4], r2
++      st.w    r12[10*SLOTS*4], r5
++      st.w    r12[14*SLOTS*4], r4
++      sub     r7/*t127*/, r1, r0 << 1
++      scale   r1
++      sub     r0/*t194*/, r0, r3 << 1
++      st.w    r11[11*SLOTS*4], r1
++
++
++/*      Live: r0 = t194, r7 = t127
++      Free:   r1, r2, r3, r4, r6, r5, r8, r9, r10, lr    */
++
++/*    t160 = (t180 * 2) + t127;
++      hi[ 3][slot] = SHIFT(-t127);
++      t195 = -(-(t194 * 2) - t160);
++      lo[ 4][slot] = SHIFT(t160);
++      lo[12][slot] = SHIFT(-t195);
++
++      hi[15][slot] = SHIFT(t191);
++      lo[ 0][slot] = SHIFT(t192); */
++      lddsp   r1/*t180*/, sp[23*4]
++      lddsp   r2/*t191*/, sp[3*4]
++      lddsp   r3/*t192*/, sp[19*4]
++      add     r4/*t160*/, r7, r1 << 1
++      neg     r7
++      scale   r7
++      add     r6/*t195*/, r4, r0 << 1
++      scale   r4
++      neg     r6
++      scale   r6
++      st.w    r11[3*SLOTS*4], r7
++      st.w    r12[4*SLOTS*4], r4
++      st.w    r12[12*SLOTS*4], r6
++      scale   r2
++      scale   r3
++      st.w    r11[15*SLOTS*4], r2
++      st.w    r12[0*SLOTS*4], r3
++
++      sub     sp, -32*4
++      ldm     sp++,r0-r7, r9-r11, pc
+diff --git a/fixed.h b/fixed.h
+index 4b58abf..0a1350a 100644
+--- a/fixed.h
++++ b/fixed.h
+@@ -237,6 +237,46 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y)
+ #   define MAD_F_SCALEBITS  MAD_F_FRACBITS
+ #  endif
++/* --- AVR32 ----------------------------------------------------------------- */
++
++# elif defined(FPM_AVR32)
++
++typedef   signed short mad_coeff_t;
++
++struct DWstruct {int high, low;};
++
++typedef union {
++  struct DWstruct s;
++  long long ll;
++} DWunion;
++
++#  define MAD_F_MLX(hi, lo, x, y)  \
++  { register DWunion __res; \
++    __res.ll = (long long)x * (long long)y; \
++    /*    asm ("muls.d\t%0, %1, %2" : "=r" (__res.ll) : "r" (x), "r" (y));*/ \
++    hi = __res.s.high; \
++    lo = __res.s.low; }
++
++#  define MAD_F_MLA(hi, lo, x, y)  \
++  { register DWunion __res; \
++    __res.s.high = hi; \
++    __res.s.low = lo; \
++    __res.ll += (long long)x * (long long)y; \
++/*  asm ("macs.d\t%0, %1, %2" : "+r" (__res.ll) : "r" (x), "r" (y));*/ \
++    hi = __res.s.high; \
++    lo = __res.s.low; }
++
++
++#  define MAD_F_MLN(hi, lo)  \
++    asm ("neg %0\n"  \
++       "acr   %1\n"  \
++         "neg   %1"    \
++       : "+r" (lo), "+r" (hi) \
++       :: "cc")
++
++
++#  define MAD_F_SCALEBITS  MAD_F_FRACBITS
++
+ /* --- ARM ----------------------------------------------------------------- */
+ # elif defined(FPM_ARM)
+@@ -433,6 +473,8 @@ mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y)
+  *
+  * Pre-rounding is required to stay within the limits of compliance.
+  */
++typedef   signed int mad_coeff_t;
++
+ #  if defined(OPT_SPEED)
+ #   define mad_f_mul(x, y)    (((x) >> 12) * ((y) >> 16))
+ #  else
+diff --git a/imdct_avr32.S b/imdct_avr32.S
+new file mode 100644
+index 0000000..d0ee6b4
+--- /dev/null
++++ b/imdct_avr32.S
+@@ -0,0 +1,789 @@
++/*
++   Optimized 36-point Inverse Modified Cosine Transform (IMDCT)
++   Copyright 2003-2006 Atmel Corporation.
++
++   Written by Ronny Pedersen, 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. */
++
++#define MAD_F(x) ((x + (1 << 13)) >> 14)
++
++      .public imdct36_avr32
++
++/*
++      void imdct36(mad_fixed_t const x[18], mad_fixed_t y[36])
++      {
++      mad_fixed_t tmp[18];
++      int i;
++*/
++/* DCT-IV */
++imdct36_avr32:
++      pushm   r0-r7,r11,lr
++      sub     sp, 4*18
++/*
++      {
++      mad_fixed_t tmp2[18];
++      int i;
++
++      /* scale[i] = 2 * cos(PI * (2 * i + 1) / (4 * 18)) */
++/*
++      static mad_fixed_t const scale[18] = {
++      MAD_F(0x1ff833fa), MAD_F(0x1fb9ea93), MAD_F(0x1f3dd120),
++      MAD_F(0x1e84d969), MAD_F(0x1d906bcf), MAD_F(0x1c62648b),
++      MAD_F(0x1afd100f), MAD_F(0x1963268b), MAD_F(0x1797c6a4),
++      MAD_F(0x159e6f5b), MAD_F(0x137af940), MAD_F(0x11318ef3),
++      MAD_F(0x0ec6a507), MAD_F(0x0c3ef153), MAD_F(0x099f61c5),
++      MAD_F(0x06ed12c5), MAD_F(0x042d4544), MAD_F(0x0165547c)
++      };
++*/
++
++  /* scaling */
++
++/*
++      for (i = 0; i < 18; i += 3) {
++              tmp2[i + 0] = mad_f_mul(x[i + 0], scale[i + 0]);
++              tmp2[i + 1] = mad_f_mul(x[i + 1], scale[i + 1]);
++              tmp2[i + 2] = mad_f_mul(x[i + 2], scale[i + 2]);
++        }
++*/
++      /* even input butterfly */
++
++/*
++      for (i = 0; i < 9; i += 3) {
++              tmp3[i + 0] = tmp2[i + 0] + tmp2[18 - (i + 0) - 1];
++              tmp3[i + 1] = tmp2[i + 1] + tmp2[18 - (i + 1) - 1];
++              tmp3[i + 2] = tmp2[i + 2] + tmp2[18 - (i + 2) - 1];
++        }
++      for (i = 0; i < 9; i += 3) {
++              tmp4[i + 0] = tmp2[i + 0] - tmp2[18 - (i + 0) - 1];
++              tmp4[i + 1] = tmp2[i + 1] - tmp2[18 - (i + 1) - 1];
++              tmp4[i + 2] = tmp2[i + 2] - tmp2[18 - (i + 2) - 1];
++        }
++*/
++
++      ld.d    r8, r12[0]                              /*r8 = x[1], r9 = x[0]*/
++      ld.d    r0, pc[scale_dctIV - .]                 /*r0 = {scale[2], scale[3]}, r1 = { scale[0], scale[1] }*/
++      ld.d    r2, r12[2*4]                            /*r2 = x[3], r3 = x[2]*/
++      ld.d    r4, pc[scale_dctIV - . + 14*2]          /*r4 = {scale[16], scale[17]}, r5 = { scale[14], scale[15] }*/
++      mulsatrndwh.w   r9/*tmp2[0]*/, r9, r1:t         /*tmp2[0] = mad_f_mul(x[0], scale[0]) */
++      ld.d    r6, r12[16*4]                           /*r6 = x[17], r7 = x[16]*/
++      mulsatrndwh.w   r8/*tmp2[1]*/, r8, r1:b         /*tmp2[1] = mad_f_mul(x[1], scale[1]) */
++      mulsatrndwh.w   r3/*tmp2[2]*/, r3, r0:t         /*tmp2[2] = mad_f_mul(x[2], scale[2]) */
++      mulsatrndwh.w   r2/*tmp2[3]*/, r2, r0:b         /*tmp2[3] = mad_f_mul(x[3], scale[3]) */
++      ld.d    r0, r12[14*4]                           /*r0 = x[15], r1 = x[14]*/
++      mulsatrndwh.w   r7/*tmp2[16]*/, r7, r4:t        /*tmp2[16] = mad_f_mul(x[16], scale[16]) */
++      mulsatrndwh.w   r6/*tmp2[17]*/, r6, r4:b        /*tmp2[17] = mad_f_mul(x[17], scale[17]) */
++      mulsatrndwh.w   r1/*tmp2[14]*/, r1, r5:t        /*tmp2[14] = mad_f_mul(x[14], scale[14]) */
++      mulsatrndwh.w   r0/*tmp2[15]*/, r0, r5:b        /*tmp2[15] = mad_f_mul(x[15], scale[15]) */
++
++      ld.d    r4, r12[4*4]                            /*r4 = x[5], r5 = x[4]*/
++
++      sub             lr/*tmp4[0]*/, r9, r6
++      add             r6/*tmp3[0]*/, r9, r6
++      sub             r10/*tmp4[1]*/, r8, r7
++      add             r7/*tmp3[1]*/, r8, r7
++      sub             r9/*tmp4[2]*/, r3, r0
++      add             r0/*tmp3[2]*/, r3, r0
++      sub             r8/*tmp4[3]*/, r2, r1
++      add             r1/*tmp3[3]*/, r2, r1
++
++      ld.d    r2, pc[scale_dctIV - . + 4*2]           /*r2 = {scale[6], scale[7]}, r3 = { scale[4], scale[5] }*/
++
++      stm             --sp, r8-r10, lr                /*sp[0] = tmp4[0],sp[1] = tmp4[1],
++                                                        sp[2] = tmp4[2],sp[3] = tmp4[3] */
++
++      /* Registers used:      r0 = tmp3[2], r1 = tmp3[3], r6 = tmp3[0], r7 = tmp3[1], r12 = x
++         Free registers:      r2-r5, r8-r11, lr
++      */
++      ld.d    r8, r12[6*4]                            /*r8 = x[7], r9 = x[6]*/
++      ld.d    r10, pc[scale_dctIV - . + 10*2]         /*r10 = {scale[12], scale[13]}, r11 = { scale[10], scale[11] }*/
++      mulsatrndwh.w   r5/*tmp2[4]*/, r5, r3:t         /*tmp2[4] = mad_f_mul(x[4], scale[4]) */
++      mulsatrndwh.w   r4/*tmp2[5]*/, r4, r3:b         /*tmp2[5] = mad_f_mul(x[5], scale[5]) */
++      mulsatrndwh.w   r9/*tmp2[6]*/, r9, r2:t         /*tmp2[6] = mad_f_mul(x[6], scale[6]) */
++      mulsatrndwh.w   r8/*tmp2[7]*/, r8, r2:b         /*tmp2[7] = mad_f_mul(x[7], scale[7]) */
++
++      ld.d    r2, r12[12*4]                           /*r2 = x[13], r3 = x[12]*/
++      ld.w    lr, r12[11*4]                           /*lr = x[11] */
++      mulsatrndwh.w   r3/*tmp2[12]*/, r3, r10:t       /*tmp2[12] = mad_f_mul(x[12], scale[12]) */
++      mulsatrndwh.w   r2/*tmp2[13]*/, r2, r10:b       /*tmp2[13] = mad_f_mul(x[13], scale[13]) */
++      ld.w    r10, r12[10*4]                          /*r10 = x[10] */
++      mulsatrndwh.w   lr/*tmp2[11]*/, lr, r11:b       /*tmp2[11] = mad_f_mul(x[11], scale[11]) */
++      mulsatrndwh.w   r10/*tmp2[10]*/, r10, r11:t     /*tmp2[10] = mad_f_mul(x[10], scale[10]) */
++
++      sub     r11/*tmp4[4]*/, r5, r2
++      add     r2/*tmp3[4]*/, r5, r2
++      sub     r5/*tmp4[5]*/, r4, r3
++      add     r3/*tmp3[5]*/, r4, r3
++      sub     r4/*tmp4[6]*/, r9, lr
++      add     lr/*tmp3[6]*/, r9, lr
++      sub     r9/*tmp4[7]*/, r8, r10
++      add     r10/*tmp3[7]*/, r8, r10
++      lddpc   r8, scale_dctIV + 8*2                   /*r8 = {scale[8], scale[9]} */
++
++      stm     --sp, r4, r5, r9, r11                   /*sp[0] = tmp4[4],sp[1] = tmp4[7],
++                                                        sp[2] = tmp4[5],sp[3] = tmp4[6] */
++      ld.d    r4, r12[8*4]                            /*r4 = x[9], r5 = x[8]*/
++      mulsatrndwh.w   r5/*tmp2[8]*/, r5, r8:t         /*tmp2[8] = mad_f_mul(x[8], scale[8]) */
++      mulsatrndwh.w   r4/*tmp2[9]*/, r4, r8:b         /*tmp2[9] = mad_f_mul(x[9], scale[9]) */
++      sub             r9/*tmp4[8]*/, r5, r4
++      add             r5/*tmp3[8]*/, r5, r4
++
++      st.w    --sp, r9                                /* sp[0] = tmp4[8] */
++
++      /* Registers used:
++
++              r0=tmp3[2], r1=tmp3[3], r2=tmp3[4], r3=tmp3[5], r5=tmp3[8], r6 = tmp3[0],
++              r7 = tmp3[1], r10=tmp3[7], lr=tmp3[6]
++         Free registers:
++              r4, r8, r9, r11, r12
++      */
++
++
++  /* SDCT-II */
++/*
++
++      {
++      mad_fixed_t tmp3[9];
++      int i;
++*/
++      /* scale[i] = 2 * cos(PI * (2 * i + 1) / (2 * 18)) */
++/*
++      static mad_fixed_t const scale[9] = {
++      MAD_F(0x1fe0d3b4), MAD_F(0x1ee8dd47), MAD_F(0x1d007930),
++      MAD_F(0x1a367e59), MAD_F(0x16a09e66), MAD_F(0x125abcf8),
++      MAD_F(0x0d8616bc), MAD_F(0x08483ee1), MAD_F(0x02c9fad7)
++      };
++*/
++  /* divide the 18-point SDCT-II into two 9-point SDCT-IIs */
++
++
++  /* fastdct */
++
++/*
++      {
++      mad_fixed_t a0,  a1,  a2,  a3,  a4,  a5,  a6,  a7,  a8,  a9,  a10, a11, a12;
++      mad_fixed_t a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25;
++      mad_fixed_t m0,  m1,  m2,  m3,  m4,  m5,  m6,  m7;
++*/
++//      enum {
++//        c0 =  MAD_F(0x1f838b8d),  /* 2 * cos( 1 * PI / 18) */
++//        c1 =  MAD_F(0x1bb67ae8),  /* 2 * cos( 3 * PI / 18) */
++//        c2 =  MAD_F(0x18836fa3),  /* 2 * cos( 4 * PI / 18) */
++//        c3 =  MAD_F(0x1491b752),  /* 2 * cos( 5 * PI / 18) */
++//        c4 =  MAD_F(0x0af1d43a),  /* 2 * cos( 7 * PI / 18) */
++//        c5 =  MAD_F(0x058e86a0),  /* 2 * cos( 8 * PI / 18) */
++//        c6 = -MAD_F(0x1e11f642)   /* 2 * cos(16 * PI / 18) */
++//      };
++
++/*
++      a2 = tmp3[6] + tmp3[2];
++      a6 = tmp3[8] + tmp3[0];
++      a11 = a2  - a6;
++      m5 = mad_f_mul(a11, -c6) ;
++      a4 = tmp3[1] + tmp3[7];
++
++      a18 =     tmp3[4] + a4;
++      a19 = -2 * tmp3[4] + a4;
++
++      a0 = tmp3[3] + tmp3[5];
++
++*/
++      add     r11/*a4*/, r7, r10
++      add     r12/*a18*/, r2, r11
++      sub     r11/*a19*/, r11, r2<<1
++
++      add     r4/*a2*/, lr, r0
++      add     r8/*a6*/, r5, r6
++      sub     r9/*a11*/, r4, r8
++
++      st.d    --sp, r0        /* sp[0] = tmp3[3], sp1[1] = tmp3[2]*/
++
++      mov     r2, MAD_F(0x1e11f642)
++      mulsatrndwh.w   r9/*m5*/, r9, r2:b
++
++      add     r2/*a0*/, r1, r3
++
++      /* Registers used:
++
++              r2=a0, r3=tmp3[5], r4=a2, r5=tmp3[8], r6 = tmp3[0],
++              r7 = tmp3[1], r8=a6, r10=tmp3[7], r9=m5, r11=a19, r12=a18,lr=tmp3[6]
++         Free registers:
++              r0, r1
++      */
++
++/*
++      a8  = a0  + a2;
++      a12 = a8  + a6;
++      a10 = a0  - a6;
++      a9  = a0  - a2;
++      m7 = mad_f_mul(a9,  -c2) ;
++      m6 = mad_f_mul(a10, -c5) ;
++*/
++
++      add     r0/*a8*/, r2, r4
++      add     r0/*a12*/, r8
++      rsub    r8/*a10*/, r2
++      sub     r2/*a9*/, r4
++      mov     r1, -MAD_F(0x18836fa3)
++      mulsatrndwh.w   r2/*m7*/, r2, r1:b
++      mov     r1, -MAD_F(0x058e86a0)
++      mulsatrndwh.w   r8/*m6*/, r8, r1:b
++
++      /* Registers used:
++
++              r0=a12, r2=m7, r3=tmp3[5], r5=tmp3[8], r6 = tmp3[0],
++              r7 = tmp3[1], r8=m6, r10=tmp3[7], r9=m5, r11=a19, r12=a18,lr=tmp3[6]
++         Free registers:
++              r1, r4
++      */
++
++
++/*
++      a21 = -a19 - (m5 << 1);
++      tmp[ 8] = a21 - (m6 << 1);
++
++      a20 = a19 - (m5 << 1);
++      tmp[ 4] = (m7 << 1)  + a20;
++      a22 = -a19 + (m6 << 1);
++      tmp[16] = a22 + (m7 << 1);
++      tmp[ 0] = a18 + a12;
++      tmp[12] = a12 - 2 * a18;
++*/
++      add     r1/*a21*/, r11, r9 << 1
++      neg     r1
++      sub     r1/*tmp[8]*/, r1, r8 << 1
++      stdsp   sp[4*11/*tmp3[..] on the stack*/ + 8*4], r1
++      sub     r4/*a20*/, r11, r9 << 1
++      add     r4/*tmp[4]*/, r4, r2 << 1
++      stdsp   sp[4*11/*tmp3[..] on the stack*/ + 4*4], r4
++      neg     r11
++      add     r1/*a22*/, r11, r8 << 1
++      add     r1/*tmp[16]*/, r1, r2 << 1
++      stdsp   sp[4*11/*tmp3[..] on the stack*/ + 16*4], r1
++      add     r4, r12, r0
++      sub     r1, r0, r12 << 1
++      stdsp   sp[4*11/*tmp3[..] on the stack*/ + 0*4], r4
++      stdsp   sp[4*11/*tmp3[..] on the stack*/ + 12*4], r1
++
++      ld.d    r0, sp++
++
++      /* Registers used:
++
++              r0 = tmp3[2], r1 = tmp3[3], r3=tmp3[5], r5=tmp3[8], r6 = tmp3[0],
++              r7 = tmp3[1], r10=tmp3[7], r11=a19, lr=tmp3[6]
++         Free registers:
++              r2,r4,r8,r9,r12
++      */
++
++/*
++      a5 = tmp3[1] - tmp3[7];
++      a7 = tmp3[8] - tmp3[0];
++      a3 = tmp3[6] - tmp3[2];
++      a1 = tmp3[3] - tmp3[5];
++      a13 = a1  - a3;
++      a14 = a13 + a7;
++      m3 = mad_f_mul(a14, -c1) ;
++      m4 = mad_f_mul(a5,  -c1) ;
++      tmp[ 6] = m3 << 1;
++*/
++      sub     r7/*a5*/, r10
++      sub     r2/*a7*/, r5, r6
++      sub     r4/*a3*/, lr, r0
++      sub     r8/*a1*/, r1, r3
++      sub     r9/*a13*/, r8, r4
++      add     r12/*a14*/, r9, r2
++      mov     r0, -MAD_F(0x1bb67ae8)
++      mulsatrndwh.w   r12/*m3*/, r12, r0:b
++      mulsatrndwh.w   r7/*m4*/, r7, r0:b
++      lsl     r12, 1
++      stdsp   sp[4*9/*tmp3[..] on the stack*/ + 6*4], r12
++
++      /* Registers used:
++              r2 = a7, r4 = a3, r7 = m4, r8 = a1, r12 = m3
++
++         Free registers:
++              r0, r1, r3, r5, r6, r10, r9, r11, lr
++      */
++
++
++/*
++      a15 = a3  + a7;
++      m2 = mad_f_mul(a15, -c4) ;
++      a17 = a1  + a3;
++      m0 = mad_f_mul(a17, -c3) ;
++      a23 = (m4 << 1)  + (m2 << 1);
++      tmp[14] = a23 + (m0 << 1); */
++      add     r0/*a15*/, r4, r2
++      mov     r1, -MAD_F(0x0af1d43a)
++      mulsatrndwh.w   r0/*m2*/, r0, r1:b
++      mov     r3, -MAD_F(0x1491b752)
++      add     r5/*a17*/, r8, r4
++      mulsatrndwh.w   r5/*m0*/, r5, r3:b
++      lsl     r7, 1
++      add     r6/*a23*/, r7, r0 << 1
++      add     r6/*tmp[14]*/, r6, r5 << 1
++      stdsp   sp[4*9/*tmp3[..] on the stack*/ + 14*4], r6
++
++      /* Registers used:
++              r0 = m2, r2 = a7, r5 = m0, r7 = m4, r8 = a1
++
++         Free registers:
++              r1, r3, r4, r6, r10, r9, r11, lr
++      */
++
++/*
++      a16 = a1  - a7;
++      m1 = mad_f_mul(a16, -c0) ;
++      a24 = (m4 << 1)  - (m2 << 1);
++      tmp[10] = a24 - (m1 << 1);
++
++      a25 = (m4 << 1)  + (m1 << 1);
++      tmp[ 2] = (m0 << 1)  - a25;
++*/
++      sub     r3/*a16*/, r8, r2
++      mov     r4,  -MAD_F(0x1f838b8d)
++      mulsatrndwh.w   r3/*m1*/, r3, r4:b
++      sub     r1/*a24*/, r7, r0 << 1
++      sub     r1/*tmp[10]*/, r1, r3 << 1
++      stdsp   sp[4*9/*tmp3[..] on the stack*/ + 10*4], r1
++      add     r7/*a25*/, r7, r3 << 1
++      sub     r7, r7, r5 << 1
++      neg     r7
++      stdsp   sp[4*9/*tmp3[..] on the stack*/ + 2*4], r7
++
++
++
++
++  /* output to every other slot for convenience */
++
++  /*} */
++  /* End fastdct */
++
++  /* odd input butterfly and scaling */
++
++
++      /*  On the stack:
++              sp[0] = tmp4[8], sp[1] = tmp4[4],sp[2] = tmp4[7], sp[3] = tmp4[5],sp[4] = tmp4[6]
++              sp[5] = tmp4[0], sp[6] = tmp4[1],sp[7] = tmp4[2],sp[8] = tmp4[3]
++      */
++
++  /*
++        tmp3[0] = mad_f_mul(tmp4[0], scale[0]);
++        tmp3[1] = mad_f_mul(tmp4[1], scale[1]) << 1;
++        tmp3[2] = mad_f_mul(tmp4[2], scale[2]);
++        tmp3[3] = mad_f_mul(tmp4[3], scale[3]) << 1;
++        tmp3[4] = mad_f_mul(tmp4[4], scale[4]);
++        tmp3[5] = mad_f_mul(tmp4[5], scale[5]);
++        tmp3[6] = mad_f_mul(tmp4[6], scale[6]) << 1;
++        tmp3[7] = mad_f_mul(tmp4[7], scale[7]);
++        tmp3[8] = mad_f_mul(tmp4[8], scale[8]) << 1;
++  */
++      /* Registers used:
++              r1 = tmp4[3], r2 = tmp4[2], r3 = tmp4[1], r4 = tmp4[0], r7 = tmp4[6]
++              r10 = tmp4[5], r11 = tmp4[7], r12 = tmp4[4], lr = tmp4[8]
++
++         Free registers:
++              r0, r5, r6, r8, r9
++      */
++      ld.d    r8, pc[ scale_sdctII - . + 4*2] /* r8 = { scale[6], scale[7] }, r9 = { scale[4], scale[5]} */
++      ldm     sp++, r1, r2, r3, r4, r7, r10, r11, r12, lr
++      mov     r5, MAD_F(0x02c9fad7)           /* r3 = scale[8] */
++      mulsatrndwh.w   r5/*tmp3[8]*/, lr, r5:b
++      mulsatrndwh.w   lr/*tmp3[6]*/, r7, r8:t
++      ld.d    r6, pc[ scale_sdctII - . + 0*2] /* r6 = { scale[2], scale[3] }, r7 = { scale[0], scale[1]} */
++      lsl     lr, 1
++      lsl     r5, 1
++      mulsatrndwh.w   r0/*tmp3[2]*/, r2, r6:t
++      mulsatrndwh.w   r1/*tmp3[3]*/, r1, r6:b
++      mulsatrndwh.w   r6/*tmp3[0]*/, r4, r7:t
++      mulsatrndwh.w   r7/*tmp3[1]*/, r3, r7:b
++      mulsatrndwh.w   r3/*tmp3[5]*/, r10, r9:b
++      mulsatrndwh.w   r2/*tmp3[4]*/, r12, r9:t
++      mulsatrndwh.w   r9/*tmp3[7]*/, r11, r8:b
++      lsl     r1, 1
++      lsl     r7, 1
++
++
++  /* fastdct */
++
++/*
++      {
++      mad_fixed_t a0,  a1,  a2,  a3,  a4,  a5,  a6,  a7,  a8,  a9,  a10, a11, a12;
++      mad_fixed_t a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25;
++      mad_fixed_t m0,  m1,  m2,  m3,  m4,  m5,  m6,  m7;
++*/
++//      enum {
++//        c0 =  MAD_F(0x1f838b8d),  /* 2 * cos( 1 * PI / 18) */
++//        c1 =  MAD_F(0x1bb67ae8),  /* 2 * cos( 3 * PI / 18) */
++//        c2 =  MAD_F(0x18836fa3),  /* 2 * cos( 4 * PI / 18) */
++//        c3 =  MAD_F(0x1491b752),  /* 2 * cos( 5 * PI / 18) */
++//        c4 =  MAD_F(0x0af1d43a),  /* 2 * cos( 7 * PI / 18) */
++//        c5 =  MAD_F(0x058e86a0),  /* 2 * cos( 8 * PI / 18) */
++//        c6 = -MAD_F(0x1e11f642)   /* 2 * cos(16 * PI / 18) */
++//      };
++
++      /* Registers used:
++
++              r0=tmp3[2], r1=tmp3[3], r2=tmp3[4], r3=tmp3[5], r5=tmp3[8], r6 = tmp3[0],
++              r7 = tmp3[1], r9=tmp3[7], lr=tmp3[6]
++         Free registers:
++              r4, r8, r10, r11, r12
++      */
++
++/*
++      a2 = tmp3[6] + (tmp3[2] << 1);
++      a6 = tmp3[8] + (tmp3[0] << 1);
++      a11 = a2 - a6;
++      m5 = mad_f_mul(a11, c6) ;
++      a4 = tmp3[1] + (tmp3[7] << 1);
++
++      a18 =     (tmp3[4] << 1) + a4;
++      a19 = -2 * (tmp3[4] << 1) + a4;
++
++      a0 = tmp3[3] + (tmp3[5] << 1);
++
++*/
++      add     r11/*a4*/, r7, r9 << 1
++      add     r12/*a18*/, r11, r2 << 1
++      sub     r11/*a19*/, r11, r2 << 2
++
++      add     r4/*a2*/, lr, r0 << 1
++      add     r8/*a6*/, r5, r6 << 1
++      sub     r10/*a11*/, r4, r8
++
++      st.d    --sp, r0        /* sp[0] = tmp3[3], sp1[1] = tmp3[2]*/
++
++      mov     r2, -MAD_F(0x1e11f642)
++      mulsatrndwh.w   r10/*m5*/, r10, r2:b
++
++      add     r2/*a0*/, r1, r3 << 1
++
++      /* Registers used:
++
++              r2=a0, r3=tmp3[5], r4=a2, r5=tmp3[8], r6 = tmp3[0],
++              r7 = tmp3[1], r8=a6, r9=tmp3[7], r10=m5, r11=a19, r12=a18,lr=tmp3[6]
++         Free registers:
++              r0, r1
++      */
++
++/*
++      a8  = a0  + a2;
++      a12 = a8  + a6;
++      a10 = a0  - a6;
++      a9  = a0  - a2;
++      m7 = mad_f_mul(a9,  -c2) ;
++      m6 = mad_f_mul(a10, -c5) ;
++*/
++
++      add     r0/*a8*/, r2, r4
++      add     r0/*a12*/, r8
++      rsub    r8/*a10*/, r2
++      sub     r2/*a9*/, r4
++      mov     r1, -MAD_F(0x18836fa3)
++      mulsatrndwh.w   r2/*m7*/, r2, r1:b
++      mov     r1, -MAD_F(0x058e86a0)
++      mulsatrndwh.w   r8/*m6*/, r8, r1:b
++
++      /* Registers used:
++
++              r0=a12, r2=m7, r3=tmp3[5], r5=tmp3[8], r6 = tmp3[0],
++              r7 = tmp3[1], r8=m6, r9=tmp3[7], r10=m5, r11=a19, r12=a18,lr=tmp3[6]
++         Free registers:
++              r1, r4
++      */
++
++
++/*
++      a21 = -a19 + (m5 << 1);
++      tmp[ 9] = a21 - (m6 << 1);
++
++      a20 = -(-a19 - (m5 << 1));
++      tmp[ 5] = (m7 << 1)  + a20;
++      a22 = -a19 + (m6 << 1);
++      tmp[17] = a22 + (m7 << 1);
++      tmp[ 1] = a18 + a12;
++      tmp[13] = a12 - 2 * a18;
++*/
++      sub     r1/*a21*/, r11, r10 << 1
++      neg     r1
++      sub     r1/*tmp[9]*/, r1, r8 << 1
++      stdsp   sp[4*2/*tmp3[..] on the stack*/ + 9*4], r1
++      add     r4/*a20*/, r11, r10 << 1
++      add     r4/*tmp[5]*/, r4, r2 << 1
++      stdsp   sp[4*2/*tmp3[..] on the stack*/ + 5*4], r4
++      neg     r11
++      add     r1/*a22*/, r11, r8 << 1
++      add     r1/*tmp[17]*/, r1, r2 << 1
++      stdsp   sp[4*2/*tmp3[..] on the stack*/ + 17*4], r1
++      add     r4, r12, r0
++      sub     r1, r0, r12 << 1
++      stdsp   sp[4*2/*tmp3[..] on the stack*/ + 1*4], r4
++      stdsp   sp[4*2/*tmp3[..] on the stack*/ + 13*4], r1
++
++      ld.d    r0, sp++
++
++      /* Registers used:
++
++              r0 = tmp3[2], r1 = tmp3[3], r3=tmp3[5], r5=tmp3[8], r6 = tmp3[0],
++              r7 = tmp3[1], r9=tmp3[7], r11=a19, lr=tmp3[6]
++         Free registers:
++              r2,r4,r8,r10,r12
++      */
++
++/*
++      a5 = tmp3[1] - (tmp3[7] << 1);
++      a7 = tmp3[8] - (tmp3[0] << 1);
++      a3 = tmp3[6] - (tmp3[2] << 1);
++      a1 = tmp3[3] - (tmp3[5] << 1);
++      a13 = a1  - a3;
++      a14 = a13 + a7;
++      m3 = mad_f_mul(a14, -c1) ;
++      m4 = mad_f_mul(a5,  -c1) ;
++      tmp[ 7] = m3 << 1;
++*/
++      sub     r7/*a5*/, r7, r9 << 1
++      sub     r2/*a7*/, r5, r6 << 1
++      sub     r4/*a3*/, lr, r0 << 1
++      sub     r8/*a1*/, r1, r3 << 1
++      sub     r10/*a13*/, r8, r4
++      add     r12/*a14*/, r10, r2
++      mov     r0, -MAD_F(0x1bb67ae8)
++      mulsatrndwh.w   r12/*m3*/, r12, r0:b
++      mulsatrndwh.w   r7/*m4*/, r7, r0:b
++      lsl     r12, 1
++      stdsp   sp[7*4], r12
++
++      /* Registers used:
++              r2 = a7, r4 = a3, r7 = m4, r8 = a1, r12 = m3
++
++         Free registers:
++              r0, r1, r3, r5, r6, r9, r10, r11, lr
++      */
++
++
++/*
++      a15 = a3  + a7;
++      m2 = mad_f_mul(a15, -c4) ;
++      a17 = a1  + a3;
++      m0 = mad_f_mul(a17, -c3) ;
++      a23 = (m4 << 1)  + (m2 << 1);
++      tmp[15] = a23 + (m0 << 1); */
++      add     r0/*a15*/, r4, r2
++      mov     r1, -MAD_F(0x0af1d43a)
++      mulsatrndwh.w   r0/*m2*/, r0, r1:b
++      mov     r3, -MAD_F(0x1491b752)
++      add     r5/*a17*/, r8, r4
++      mulsatrndwh.w   r5/*m0*/, r5, r3:b
++      lsl     r7, 1
++      add     r6/*a23*/, r7, r0 << 1
++      add     r6/*tmp[15]*/, r6, r5 << 1
++      stdsp   sp[15*4], r6
++
++      /* Registers used:
++              r0 = m2, r2 = a7, r5 = m0, r7 = m4, r8 = a1
++
++         Free registers:
++              r1, r3, r4, r6, r9, r10, r11, lr
++      */
++
++/*
++      a16 = a1  - a7;
++      m1 = mad_f_mul(a16, -c0) ;
++      a24 = (m4 << 1)  - (m2 << 1);
++      tmp[11] = a24 - (m1 << 1);
++
++      a25 = (m4 << 1)  + (m1 << 1);
++      tmp[ 3] = (m0 << 1)  - a25;
++*/
++      sub     r3/*a16*/, r8, r2
++      mov     r4,  -MAD_F(0x1f838b8d)
++      mulsatrndwh.w   r3/*m1*/, r3, r4:b
++      sub     r1/*a24*/, r7, r0 << 1
++      sub     r1/*tmp[11]*/, r1, r3 << 1
++      stdsp   sp[11*4], r1
++      add     r7/*a25*/, r7, r3 << 1
++      sub     r7, r7, r5 << 1
++      neg     r7
++      lddsp   r12, sp[4*18+4] /* Get y from stack */
++      stdsp   sp[3*4], r7
++
++
++  /* output to every other slot for convenience */
++
++  /* End fastdct */
++
++  /* output accumulation */
++
++/*    for (i = 3; i < 18; i += 8) {
++        tmp[i + 0] -= tmp[(i + 0) - 2];
++        tmp[i + 2] -= tmp[(i + 2) - 2];
++        tmp[i + 4] -= tmp[(i + 4) - 2];
++        tmp[i + 6] -= tmp[(i + 6) - 2];
++      }
++      }
++*/
++
++/* End  SDCT-II */
++
++
++
++  /* scale reduction and output accumulation */
++
++/*
++      for (i = 1; i < 17; i += 4) {
++        tmp[i + 0] = tmp[i + 0]  - tmp[(i + 0) - 1];
++        tmp[i + 1] = tmp[i + 1]  - tmp[(i + 1) - 1];
++        tmp[i + 2] = tmp[i + 2]  - tmp[(i + 2) - 1];
++        tmp[i + 3] = tmp[i + 3]  - tmp[(i + 3) - 1];
++      }
++      tmp[17] = tmp[17] - tmp[16];
++      }
++*/
++/* End  DCT-IV */
++
++
++  /* convert 18-point DCT-IV to 36-point IMDCT */
++
++/*
++      for (i =  0; i <  9; i += 3) {
++        y[i + 0] =  tmp[9 + (i + 0)];
++        y[i + 1] =  tmp[9 + (i + 1)];
++        y[i + 2] =  tmp[9 + (i + 2)];
++      }
++      for (i =  9; i < 27; i += 3) {
++        y[i + 0] = -tmp[36 - (9 + (i + 0)) - 1];
++        y[i + 1] = -tmp[36 - (9 + (i + 1)) - 1];
++        y[i + 2] = -tmp[36 - (9 + (i + 2)) - 1];
++      }
++      for (i = 27; i < 36; i += 3) {
++        y[i + 0] = -tmp[(i + 0) - 27];
++        y[i + 1] = -tmp[(i + 1) - 27];
++        y[i + 2] = -tmp[(i + 2) - 27];
++      }
++      }
++*/
++
++      /* Registers used:
++              r0 = tmp[8], r1 = tmp[7], r2 = tmp[6], r3 = tmp[5], r4 = tmp[4]
++              r5 = tmp[3], r6 = tmp[2], r7 = tmp[1], r8 = tmp[0], r12 = y
++
++         Free registers:
++              r9, r10, r11, lr
++      */
++
++      ldm     sp++, r0-r8     /* Get tmp[0]-tmp[8] from stack */
++      sub     r5, r7          /* tmp[3] -= tmp[1]*/
++      sub     r3, r5          /* tmp[5] -= tmp[3]*/
++      sub     r1, r3          /* tmp[7] -= tmp[5]*/
++
++      sub     r7, r8          /* tmp[1] -= tmp[0]*/
++      sub     r6, r7          /* tmp[2] -= tmp[1]*/
++      sub     r5, r6          /* tmp[3] -= tmp[2]*/
++      neg     r8
++      st.w    r12[26*4], r8   /* y[26] = -tmp[0] */
++      st.w    r12[27*4], r8   /* y[27] = -tmp[0] */
++      neg     r7
++      neg     r6
++      st.w    r12[25*4], r7   /* y[25] = -tmp[1] */
++      st.w    r12[24*4], r6   /* y[24] = -tmp[2] */
++      st.d    r12[28*4], r6   /* y[28] = -tmp[1], y[29] = -tmp[2]*/
++
++      sub     r4, r5          /* tmp[4] -= tmp[3]*/
++      sub     r3, r4          /* tmp[5] -= tmp[4]*/
++      neg     r5
++      neg     r4
++      st.w    r12[23*4], r5   /* y[23] = -tmp[3] */
++      st.w    r12[22*4], r4   /* y[22] = -tmp[4] */
++      st.d    r12[30*4], r4   /* y[30] = -tmp[3], y[31] = -tmp[4]*/
++
++      ldm     sp++, r4-r11,lr /* Get tmp[9]-tmp[17] from stack */
++
++      sub     r2, r3          /* tmp[6] -= tmp[5]*/
++
++      sub     lr, r1          /* tmp[9] -= tmp[7]*/
++      sub     r10, lr         /* tmp[11] -= tmp[9]*/
++      sub     r8, r10         /* tmp[13] -= tmp[11]*/
++      sub     r6, r8          /* tmp[15] -= tmp[13]*/
++      sub     r4, r6          /* tmp[17] -= tmp[15]*/
++
++      sub     r1, r2          /* tmp[7] -= tmp[6]*/
++      sub     r0, r1          /* tmp[8] -= tmp[7]*/
++      neg     r3
++      neg     r2
++      st.w    r12[21*4], r3   /* y[21] = -tmp[5] */
++      st.w    r12[20*4], r2   /* y[20] = -tmp[6] */
++      st.d    r12[32*4], r2   /* y[32] = -tmp[5], y[33] = -tmp[6]*/
++
++      sub     lr, r0          /* tmp[9] -= tmp[8]*/
++      sub     r11, lr         /* tmp[10] -= tmp[9]*/
++      neg     r1
++      neg     r0
++      st.w    r12[19*4], r1   /* y[19] = -tmp[7] */
++      st.w    r12[18*4], r0   /* y[18] = -tmp[8] */
++      st.d    r12[34*4], r0   /* y[34] = -tmp[7], y[35] = -tmp[8]*/
++
++      sub     r10, r11        /* tmp[11] -= tmp[10]*/
++      sub     r9, r10         /* tmp[12] -= tmp[11]*/
++
++      st.w    r12[0*4], lr    /* y[0] = tmp[9]*/
++      neg     lr
++      st.w    r12[17*4], lr   /* y[17] = -tmp[9]*/
++      st.d    r12[1*4], r10   /* y[1] = tmp[10], y[2] = tmp[11] */
++      neg     r11
++      neg     r10
++      st.w    r12[16*4], r11  /* y[16] = -tmp[10] */
++      st.w    r12[15*4], r10  /* y[15] = -tmp[11] */
++
++
++      sub     r8, r9          /* tmp[13] -= tmp[12]*/
++      sub     r7, r8          /* tmp[14] -= tmp[13]*/
++      st.d    r12[3*4], r8    /* y[3] = tmp[12], y[4] = tmp[13] */
++      neg     r9
++      neg     r8
++      st.w    r12[14*4], r9   /* y[14] = -tmp[12] */
++      st.w    r12[13*4], r8   /* y[13] = -tmp[13] */
++
++      sub     r6, r7          /* tmp[15] -= tmp[14]*/
++      sub     r5, r6          /* tmp[16] -= tmp[15]*/
++      sub     r4, r5          /* tmp[17] -= tmp[16]*/
++
++      st.d    r12[5*4], r6    /* y[5] = tmp[14], y[6] = tmp[15] */
++      neg     r7
++      neg     r6
++      st.w    r12[12*4], r7   /* y[12] = -tmp[14] */
++      st.w    r12[11*4], r6   /* y[11] = -tmp[15] */
++
++      st.d    r12[7*4], r4    /* y[7] = tmp[16], y[8] = tmp[17] */
++      neg     r5
++      neg     r4
++      st.w    r12[10*4], r5   /* y[10] = -tmp[16] */
++      st.w    r12[9*4], r4    /* y[9] = -tmp[17] */
++
++      popm    r0-r7,r11,pc
++
++      .align  2
++scale_dctIV:
++      .short  MAD_F(0x1ff833fa), MAD_F(0x1fb9ea93), MAD_F(0x1f3dd120)
++      .short  MAD_F(0x1e84d969), MAD_F(0x1d906bcf), MAD_F(0x1c62648b)
++      .short  MAD_F(0x1afd100f), MAD_F(0x1963268b), MAD_F(0x1797c6a4)
++      .short  MAD_F(0x159e6f5b), MAD_F(0x137af940), MAD_F(0x11318ef3)
++      .short  MAD_F(0x0ec6a507), MAD_F(0x0c3ef153), MAD_F(0x099f61c5)
++      .short  MAD_F(0x06ed12c5), MAD_F(0x042d4544), MAD_F(0x0165547c)
++
++      .align  2
++scale_sdctII:
++      .short  MAD_F(0x1fe0d3b4), MAD_F(0x1ee8dd47), MAD_F(0x1d007930)
++      .short  MAD_F(0x1a367e59), MAD_F(0x16a09e66), MAD_F(0x125abcf8)
++      .short  MAD_F(0x0d8616bc), MAD_F(0x08483ee1), MAD_F(0x02c9fad7)
+diff --git a/layer3.c b/layer3.c
+index 4e5d3fa..dffdab3 100644
+--- a/layer3.c
++++ b/layer3.c
+@@ -378,6 +378,11 @@ mad_fixed_t const ca[8] = {
+   -MAD_F(0x003a2847) /* -0.014198569 */, -MAD_F(0x000f27b4) /* -0.003699975 */
+ };
++#ifdef FPM_AVR32
++# undef MAD_F
++# define MAD_F(x) ((x + (1 << 12)) >> 13)
++#endif
++
+ /*
+  * IMDCT coefficients for short blocks
+  * derived from section 2.4.3.4.10.2 of ISO/IEC 11172-3
+@@ -386,7 +391,7 @@ mad_fixed_t const ca[8] = {
+  * imdct_s[i /odd][k] = cos((PI / 24) * (2 * (6 + (i-1)/2) + 7) * (2 * k + 1))
+  */
+ static
+-mad_fixed_t const imdct_s[6][6] = {
++mad_coeff_t const imdct_s[6][6] = {
+ # include "imdct_s.dat"
+ };
+@@ -398,7 +403,7 @@ mad_fixed_t const imdct_s[6][6] = {
+  * window_l[i] = sin((PI / 36) * (i + 1/2))
+  */
+ static
+-mad_fixed_t const window_l[36] = {
++mad_coeff_t const window_l[36] = {
+   MAD_F(0x00b2aa3e) /* 0.043619387 */, MAD_F(0x0216a2a2) /* 0.130526192 */,
+   MAD_F(0x03768962) /* 0.216439614 */, MAD_F(0x04cfb0e2) /* 0.300705800 */,
+   MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x07635284) /* 0.461748613 */,
+@@ -429,7 +434,7 @@ mad_fixed_t const window_l[36] = {
+  * window_s[i] = sin((PI / 12) * (i + 1/2))
+  */
+ static
+-mad_fixed_t const window_s[12] = {
++mad_coeff_t const window_s[12] = {
+   MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x061f78aa) /* 0.382683432 */,
+   MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0cb19346) /* 0.793353340 */,
+   MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0fdcf549) /* 0.991444861 */,
+@@ -438,6 +443,11 @@ mad_fixed_t const window_s[12] = {
+   MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0216a2a2) /* 0.130526192 */,
+ };
++#ifdef FPM_AVR32
++# undef MAD_F
++# define MAD_F(x)             ((mad_fixed_t) (x##L))
++#endif
++
+ /*
+  * coefficients for intensity stereo processing
+  * derived from section 2.4.3.4.9.3 of ISO/IEC 11172-3
+@@ -879,6 +889,42 @@ void III_exponents(struct channel const *channel,
+  * NAME:      III_requantize()
+  * DESCRIPTION:       requantize one (positive) value
+  */
++
++#if 0
++/*static*/
++mad_fixed_t III_requantize(unsigned int value, signed int exp)
++{
++  register mad_fixed_t tmp2, tmp3;
++  long long tmp_d;
++
++  asm ("asr\t%0, %1, 2\n"
++       "ld.w\t%2, %4[%5 << 2]\n"
++       "sub\t%1, %1, %0 << 2\n"
++       "asr\t%3, %2, 7\n"
++       "andl\t%2, 0x7f, COH\n"
++       "add\t%0, %2\n"
++       "lsl\t%m0,%3,%0\n"
++       "neg\t%0\n"
++       "asr\t%3,%3,%0\n"
++       "add\t%2, %6, %1 << 2\n"
++       "ld.w\t%2, %2[12]\n"
++       "cp.w\t%0, 0\n"
++       "movlt\t%3, %m0\n"
++       "muls.d\t%0, %3, %2\n"
++       "cp.w\t%1, 0\n"
++       "breq\t0f\n"
++       "lsr\t%0, %0, 28\n"
++       "or\t%3, %0, %m0 << 4\n"
++       "0:\n"
++       : "=&r"(tmp_d), "+r"(exp), "=&r"(tmp2), "=&r"(tmp3)
++       : "r"(&rq_table), "r"(value), "r"(root_table));
++
++
++  return tmp3;
++}
++
++#else
++
+ static
+ mad_fixed_t III_requantize(unsigned int value, signed int exp)
+ {
+@@ -918,6 +964,7 @@ mad_fixed_t III_requantize(unsigned int value, signed int exp)
+   return frac ? mad_f_mul(requantized, root_table[3 + frac]) : requantized;
+ }
++#endif
+ /* we must take care that sz >= bits and sz < sizeof(long) lest bits == 0 */
+ # define MASK(cache, sz, bits)        \
+@@ -2054,27 +2101,42 @@ void imdct36(mad_fixed_t const X[18], mad_fixed_t x[36])
+ }
+ #  endif
++
++#ifdef FPM_AVR32
++# undef  mad_f_mul
++# define mad_f_mul(x, y) __builtin_mulsatrndwh_w(x, y)
++#endif
++
+ /*
+  * NAME:      III_imdct_l()
+  * DESCRIPTION:       perform IMDCT and windowing for long blocks
+  */
+ static
+-void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36],
++void III_imdct_l(mad_fixed_t /*const*/ X[18], mad_fixed_t z[36],
+                unsigned int block_type)
+ {
+   unsigned int i;
++  mad_fixed_t *z_ptr;
++  mad_coeff_t *w_ptr;
+   /* IMDCT */
++#ifdef FPM_AVR32
++  imdct36_avr32(X, z);
++#else
+   imdct36(X, z);
++#endif
+   /* windowing */
++  z_ptr = &z[0];
++  w_ptr = &window_l[0];
++
+   switch (block_type) {
+   case 0:  /* normal window */
+ # if defined(ASO_INTERLEAVE1)
+     {
+-      register mad_fixed_t tmp1, tmp2;
++      register mad_coeff_t tmp1, tmp2;
+       tmp1 = window_l[0];
+       tmp2 = window_l[1];
+@@ -2091,15 +2153,16 @@ void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36],
+     }
+ # elif defined(ASO_INTERLEAVE2)
+     {
+-      register mad_fixed_t tmp1, tmp2;
++      register mad_fixed_t tmp1;
++      register mad_coeff_t tmp2;
+-      tmp1 = z[0];
+-      tmp2 = window_l[0];
++      tmp1 = *z_ptr;
++      tmp2 = *w_ptr++;
+       for (i = 0; i < 35; ++i) {
+-      z[i] = mad_f_mul(tmp1, tmp2);
+-      tmp1 = z[i + 1];
+-      tmp2 = window_l[i + 1];
++      *z_ptr++ = mad_f_mul(tmp1, tmp2);
++      tmp1 = *z_ptr;
++      tmp2 = *w_ptr++;
+       }
+       z[35] = mad_f_mul(tmp1, tmp2);
+@@ -2118,23 +2181,28 @@ void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36],
+   case 1:  /* start block */
+     for (i =  0; i < 18; i += 3) {
+-      z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
+-      z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
+-      z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
++      *(z_ptr++) = mad_f_mul(*z_ptr, *w_ptr++);
++      *(z_ptr++) = mad_f_mul(*z_ptr, *w_ptr++);
++      *(z_ptr++) = mad_f_mul(*z_ptr, *w_ptr++);
+     }
++    z_ptr += 6;
++    w_ptr = &window_s[6];
+     /*  (i = 18; i < 24; ++i) z[i] unchanged */
+-    for (i = 24; i < 30; ++i) z[i] = mad_f_mul(z[i], window_s[i - 18]);
+-    for (i = 30; i < 36; ++i) z[i] = 0;
++    for (i = 24; i < 30; ++i) *z_ptr++ = mad_f_mul(*z_ptr, *w_ptr++);
++    for (i = 30; i < 36; ++i) *z_ptr++ = 0;
+     break;
+   case 3:  /* stop block */
+-    for (i =  0; i <  6; ++i) z[i] = 0;
+-    for (i =  6; i < 12; ++i) z[i] = mad_f_mul(z[i], window_s[i - 6]);
++    w_ptr = &window_s[0];
++    for (i =  0; i <  6; ++i) *z_ptr++ = 0;
++    for (i =  6; i < 12; ++i) *z_ptr++ = mad_f_mul(*z_ptr, *w_ptr++);
+     /*  (i = 12; i < 18; ++i) z[i] unchanged */
++    w_ptr = &window_l[18];
++    z_ptr += 6;
+     for (i = 18; i < 36; i += 3) {
+-      z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
+-      z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
+-      z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
++      *z_ptr++ = mad_f_mul(*z_ptr, *w_ptr++ );
++      *z_ptr++ = mad_f_mul(*z_ptr, *w_ptr++);
++      *z_ptr++ = mad_f_mul(*z_ptr, *w_ptr++);
+     }
+     break;
+   }
+@@ -2146,10 +2214,10 @@ void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36],
+  * DESCRIPTION:       perform IMDCT and windowing for short blocks
+  */
+ static
+-void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36])
++void III_imdct_s(mad_fixed_t /*const*/ X[18], mad_fixed_t z[36])
+ {
+   mad_fixed_t y[36], *yptr;
+-  mad_fixed_t const *wptr;
++  mad_coeff_t const *wptr;
+   int w, i;
+   register mad_fixed64hi_t hi;
+   register mad_fixed64lo_t lo;
+@@ -2159,11 +2227,56 @@ void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36])
+   yptr = &y[0];
+   for (w = 0; w < 3; ++w) {
+-    register mad_fixed_t const (*s)[6];
++    register mad_coeff_t const (*s)[6];
+     s = imdct_s;
+     for (i = 0; i < 3; ++i) {
++#ifdef FPM_AVR32
++      register long long int acc, tmp1, tmp2, tmp3, tmp4;
++      asm volatile ("ld.d\t%0, %5++\n"
++                    "ld.d\t%1, %6[0]\n"
++                    "ld.d\t%2, %6[2*4]\n"
++                    "ld.d\t%3, %6[4*4]\n"
++                    "mulwh.d\t%4, %m1, %m0:t\n"
++                    "macwh.d\t%4, %1, %m0:b\n"
++                    "ld.w\t%m0, %5++\n"
++                    "macwh.d\t%4, %m2, %0:t\n"
++                    "macwh.d\t%4, %2, %0:b\n"
++                    "macwh.d\t%4, %m3, %m0:t\n"
++                    "macwh.d\t%4, %3, %m0:b\n"
++                    "ld.d\t%0, %5++\n"
++                    "rol\t%4\n"
++                    "rol\t%m4\n"
++                    : "=&r"(tmp1), "=&r"(tmp2), "=&r"(tmp3), "=&r"(tmp4),
++                      "=&r"(acc), "+r"(s)
++                    : "r"(X));
++
++      asm volatile ("st.w\t%1[0], %m0\n"
++                    "neg\t%m0\n"
++                    "st.w\t%2[5*4], %m0\n"
++                    : "+r"(acc)
++                    : "r"(&yptr[i]), "r"(&yptr[-i]));
++
++      asm volatile ("mulwh.d\t%4, %m1, %m0:t\n"
++                    "macwh.d\t%4, %1, %m0:b\n"
++                    "ld.w\t%m0, %5++\n"
++                    "macwh.d\t%4, %m2, %0:t\n"
++                    "macwh.d\t%4, %2, %0:b\n"
++                    "macwh.d\t%4, %m3, %m0:t\n"
++                    "macwh.d\t%4, %3, %m0:b\n"
++                    "rol\t%4\n"
++                    "rol\t%m4\n"
++                    : "+r"(tmp1), "+r"(tmp2), "+r"(tmp3), "+r"(tmp4),
++                      "=&r"(acc), "+r"(s)
++                    : "r"(X));
++
++      asm volatile (  "st.w\t%1[6*4], %m0\n"
++                      "st.w\t%2[11*4], %m0\n"
++                      :: "r"(acc), "r"(&yptr[i]), "r"(&yptr[-i]));
++
++
++#else
+       MAD_F_ML0(hi, lo, X[0], (*s)[0]);
+       MAD_F_MLA(hi, lo, X[1], (*s)[1]);
+       MAD_F_MLA(hi, lo, X[2], (*s)[2]);
+@@ -2187,6 +2300,7 @@ void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36])
+       yptr[11 - i] = yptr[i + 6];
+       ++s;
++#endif
+     }
+     yptr += 12;
+@@ -2198,6 +2312,196 @@ void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36])
+   yptr = &y[0];
+   wptr = &window_s[0];
++#ifdef FPM_AVR32
++  /*    z[0] = 0;
++        z[1] = 0;
++        z[2] = 0;
++        z[3] = 0;
++        z[4] = 0;
++        z[5] = 0;
++        z[30] = 0;
++        z[31] = 0;
++        z[32] = 0;
++        z[33] = 0;
++        z[34] = 0;
++        z[35] = 0;
++  */
++  {
++    register long long int tmp, tmp2, tmp3, w0123, w4567, w891011;
++    asm volatile ("mov\t%m0, 0\n"
++                  "mov\t%0, %m0\n"
++                  "st.d\t%1[0], %0\n"
++                  "st.d\t%1[2*4], %0\n"
++                  "st.d\t%1[4*4], %0\n"
++                  "st.d\t%1[30*4], %0\n"
++                  "st.d\t%1[32*4], %0\n"
++                  "st.d\t%1[34*4], %0\n"
++                  : "=&r"(tmp) : "r"(z));
++
++
++
++    /*
++            z[6] = mad_f_mul(yptr [0], wptr[0]);
++            z[7] = mad_f_mul(yptr [1], wptr[1]);
++            z[8] = mad_f_mul(yptr [2], wptr[2]);
++            z[9] = mad_f_mul(yptr [3], wptr[3]);
++            z[10] = mad_f_mul(yptr[4], wptr[4]);
++            z[11] = mad_f_mul(yptr[5], wptr[5]);
++            z[24] = mad_f_mul(yptr [30], wptr[6]);
++            z[25] = mad_f_mul(yptr [31], wptr[7]);
++            z[26] = mad_f_mul(yptr [32], wptr[8]);
++            z[27] = mad_f_mul(yptr [33], wptr[9]);
++            z[28] = mad_f_mul(yptr[34], wptr[10]);
++            z[29] = mad_f_mul(yptr[35], wptr[11]);
++    */
++
++
++    asm volatile ("ld.d\t%0, %5[0*4]\n"
++                  "ld.d\t%3, %6[0*4]\n"
++                  "ld.d\t%1, %5[2*4]\n"
++                  "ld.d\t%2, %5[4*4]\n"
++                  "mulsatrndwh.w\t%m3, %m3, %m0:t\n"
++                  "mulsatrndwh.w\t%3, %3, %m0:b\n"
++                  "ld.d\t%4, %6[2*4]\n"
++                  "st.d\t%7[6*4], %3\n"
++
++                  "mulsatrndwh.w\t%m4, %m4, %0:t\n"
++                  "mulsatrndwh.w\t%4, %4, %0:b\n"
++                  "ld.d\t%3, %6[4*4]\n"
++                  "st.d\t%7[8*4], %4\n"
++
++                  "mulsatrndwh.w\t%m3, %m3, %m1:t\n"
++                  "mulsatrndwh.w\t%3, %3, %m1:b\n"
++                  "ld.d\t%4, %6[30*4]\n"
++                  "st.d\t%7[10*4], %3\n"
++
++                  "mulsatrndwh.w\t%m4, %m4, %1:t\n"
++                  "mulsatrndwh.w\t%4, %4, %1:b\n"
++                  "ld.d\t%3, %6[32*4]\n"
++                  "st.d\t%7[24*4], %4\n"
++
++                  "mulsatrndwh.w\t%m3, %m3, %m2:t\n"
++                  "mulsatrndwh.w\t%3, %3, %m2:b\n"
++                  "ld.d\t%4, %6[34*4]\n"
++                  "st.d\t%7[26*4], %3\n"
++
++                  "mulsatrndwh.w\t%m4, %m4, %2:t\n"
++                  "mulsatrndwh.w\t%4, %4, %2:b\n"
++                  "st.d\t%7[28*4], %4\n"
++
++                  : "=&r"(w0123), "=&r"(w4567), "=&r"(w891011), "=&r"(tmp), "=&r"(tmp2)
++                  : "r"(wptr), "r"(yptr), "r"(z));
++    /*
++       MAD_F_ML0(hi, lo, yptr[6], wptr[6]);
++       MAD_F_MLA(hi, lo, yptr[12], wptr[0]);
++       z[12] = MAD_F_MLZ(hi, lo);
++       MAD_F_ML0(hi, lo, yptr[7], wptr[7]);
++       MAD_F_MLA(hi, lo, yptr[13], wptr[1]);
++       z[13] = MAD_F_MLZ(hi, lo);
++       MAD_F_ML0(hi, lo, yptr[8], wptr[8]);
++       MAD_F_MLA(hi, lo, yptr[14], wptr[2]);
++       z[14] = MAD_F_MLZ(hi, lo);
++       MAD_F_ML0(hi, lo, yptr[9], wptr[9]);
++       MAD_F_MLA(hi, lo, yptr[15], wptr[3]);
++       z[15] = MAD_F_MLZ(hi, lo);
++       MAD_F_ML0(hi, lo, yptr[10], wptr[10]);
++       MAD_F_MLA(hi, lo, yptr[16], wptr[4]);
++       z[16] = MAD_F_MLZ(hi, lo);
++       MAD_F_ML0(hi, lo, yptr[11], wptr[11]);
++       MAD_F_MLA(hi, lo, yptr[17], wptr[5]);
++       z[17] = MAD_F_MLZ(hi, lo);
++
++       MAD_F_ML0(hi, lo, yptr[18], wptr[6]);
++       MAD_F_MLA(hi, lo, yptr[24], wptr[0]);
++       z[18] = MAD_F_MLZ(hi, lo);
++       MAD_F_ML0(hi, lo, yptr[19], wptr[7]);
++       MAD_F_MLA(hi, lo, yptr[25], wptr[1]);
++       z[19] = MAD_F_MLZ(hi, lo);
++       MAD_F_ML0(hi, lo, yptr[20], wptr[8]);
++       MAD_F_MLA(hi, lo, yptr[26], wptr[2]);
++       z[20] = MAD_F_MLZ(hi, lo);
++       MAD_F_ML0(hi, lo, yptr[21], wptr[9]);
++       MAD_F_MLA(hi, lo, yptr[27], wptr[3]);
++       z[21] = MAD_F_MLZ(hi, lo);
++       MAD_F_ML0(hi, lo, yptr[22], wptr[10]);
++       MAD_F_MLA(hi, lo, yptr[28], wptr[4]);
++       z[22] = MAD_F_MLZ(hi, lo);
++       MAD_F_ML0(hi, lo, yptr[23], wptr[11]);
++       MAD_F_MLA(hi, lo, yptr[29], wptr[5]);
++       z[23] = MAD_F_MLZ(hi, lo);*/
++
++
++    asm volatile ("ld.d\t%0, %3[6*4]\n"
++                  "ld.d\t%1, %3[12*4]\n"
++                  "mulwh.d\t%2, %m0, %5:t\n"
++                  "macwh.d\t%2, %m1, %m4:t\n"
++                  "mulwh.d\t%0, %0, %5:b\n"
++                  "macwh.d\t%0, %1, %m4:b\n"
++                  "lsl\t%m2, 1\n"
++                  "lsl\t%2, %m0, 1\n"
++                  "st.d\t%6[12*4], %2\n"
++
++                  "ld.d\t%0, %3[18*4]\n"
++                  "ld.d\t%1, %3[24*4]\n"
++                  "mulwh.d\t%2, %m0, %5:t\n"
++                  "macwh.d\t%2, %m1, %m4:t\n"
++                  "mulwh.d\t%0, %0, %5:b\n"
++                  "macwh.d\t%0, %1, %m4:b\n"
++                  "lsl\t%m2, 1\n"
++                  "lsl\t%2, %m0, 1\n"
++                  "st.d\t%6[18*4], %2\n"
++
++                  : "=&r"(tmp), "=&r"(tmp2), "=&r"(tmp3)
++                  : "r"(yptr), "r"(w0123), "r"(w4567), "r"(z));
++
++    asm volatile ("ld.d\t%0, %3[8*4]\n"
++                  "ld.d\t%1, %3[14*4]\n"
++                  "mulwh.d\t%2, %m0, %m5:t\n"
++                  "macwh.d\t%2, %m1, %4:t\n"
++                  "mulwh.d\t%0, %0, %m5:b\n"
++                  "macwh.d\t%0, %1, %4:b\n"
++                  "lsl\t%m2, 1\n"
++                  "lsl\t%2, %m0, 1\n"
++                  "st.d\t%6[14*4], %2\n"
++
++                  "ld.d\t%0, %3[20*4]\n"
++                  "ld.d\t%1, %3[26*4]\n"
++                  "mulwh.d\t%2, %m0, %m5:t\n"
++                  "macwh.d\t%2, %m1, %4:t\n"
++                  "mulwh.d\t%0, %0, %m5:b\n"
++                  "macwh.d\t%0, %1, %4:b\n"
++                  "lsl\t%m2, 1\n"
++                  "lsl\t%2, %m0, 1\n"
++                  "st.d\t%6[20*4], %2\n"
++
++                  : "=&r"(tmp), "=&r"(tmp2), "=&r"(tmp3)
++                  : "r"(yptr), "r"(w0123), "r"(w891011), "r"(z));
++
++    asm volatile ("ld.d\t%0, %3[10*4]\n"
++                  "ld.d\t%1, %3[16*4]\n"
++                  "mulwh.d\t%2, %m0, %5:t\n"
++                  "macwh.d\t%2, %m1, %m4:t\n"
++                  "mulwh.d\t%0, %0, %5:b\n"
++                  "macwh.d\t%0, %1, %m4:b\n"
++                  "lsl\t%m2, 1\n"
++                  "lsl\t%2, %m0, 1\n"
++                  "st.d\t%6[16*4], %2\n"
++
++                  "ld.d\t%0, %3[22*4]\n"
++                  "ld.d\t%1, %3[28*4]\n"
++                  "mulwh.d\t%2, %m0, %5:t\n"
++                  "macwh.d\t%2, %m1, %m4:t\n"
++                  "mulwh.d\t%0, %0, %5:b\n"
++                  "macwh.d\t%0, %1, %m4:b\n"
++                  "lsl\t%m2, 1\n"
++                  "lsl\t%2, %m0, 1\n"
++                  "st.d\t%6[22*4], %2\n"
++
++                  : "=&r"(tmp), "=&r"(tmp2), "=&r"(tmp3)
++                  : "r"(yptr), "r"(w4567), "r"(w891011), "r"(z));
++
++  }
++#else
+   for (i = 0; i < 6; ++i) {
+     z[i +  0] = 0;
+     z[i +  6] = mad_f_mul(yptr[ 0 + 0], wptr[0]);
+@@ -2218,8 +2522,15 @@ void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36])
+     ++yptr;
+     ++wptr;
+   }
++#endif
+ }
++#ifdef FPM_AVR32
++# undef  mad_f_mul
++# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) *  \
++                               (((y) + (1L << 15)) >> 16))
++#endif
++
+ /*
+  * NAME:      III_overlap()
+  * DESCRIPTION:       perform overlap-add of windowed IMDCT outputs
+diff --git a/synth.c b/synth.c
+index 1d28d43..f42d49b 100644
+--- a/synth.c
++++ b/synth.c
+@@ -29,20 +29,6 @@
+ # include "frame.h"
+ # include "synth.h"
+-/*
+- * NAME:      synth->init()
+- * DESCRIPTION:       initialize synth struct
+- */
+-void mad_synth_init(struct mad_synth *synth)
+-{
+-  mad_synth_mute(synth);
+-
+-  synth->phase = 0;
+-
+-  synth->pcm.samplerate = 0;
+-  synth->pcm.channels   = 0;
+-  synth->pcm.length     = 0;
+-}
+ /*
+  * NAME:      synth->mute()
+@@ -88,6 +74,10 @@ void mad_synth_mute(struct mad_synth *synth)
+ /* FPM_DEFAULT without OPT_SSO will actually lose accuracy and performance */
++# if defined(FPM_AVR32)
++#  define OPT_SSO
++# endif
++
+ # if defined(FPM_DEFAULT) && !defined(OPT_SSO)
+ #  define OPT_SSO
+ # endif
+@@ -522,9 +512,15 @@ void dct32(mad_fixed_t const in[32], unsigned int slot,
+ #  endif
+ #  define ML0(hi, lo, x, y)   ((lo)  = (x) * (y))
+ #  define MLA(hi, lo, x, y)   ((lo) += (x) * (y))
+-#  define MLN(hi, lo)         ((lo)  = -(lo))
+-#  define MLZ(hi, lo)         ((void) (hi), (mad_fixed_t) (lo))
+-#  define SHIFT(x)            ((x) >> 2)
++#  if defined(FPM_AVR32)
++#   define MLN(hi, lo)                MAD_F_MLN((hi), (lo))
++#   define MLZ(hi, lo)                (hi)
++#   define SHIFT(x)           ((x) << 2)
++#  else
++#   define MLN(hi, lo)                ((lo)  = -(lo))
++#   define MLZ(hi, lo)                ((void) (hi), (mad_fixed_t) (lo))
++#   define SHIFT(x)           ((x) >> 2)
++#  endif
+ #  define PRESHIFT(x)         ((MAD_F(x) + (1L << 13)) >> 14)
+ # else
+ #  define ML0(hi, lo, x, y)   MAD_F_ML0((hi), (lo), (x), (y))
+@@ -541,11 +537,54 @@ void dct32(mad_fixed_t const in[32], unsigned int slot,
+ #  endif
+ # endif
++/*
++ * NAME:      synth->init()
++ * DESCRIPTION:       initialize synth struct
++ */
++
++#ifdef FPM_AVR32
++short Dmod[17][33];
++#endif
++
+ static
++#ifdef FPM_AVR32
++short const D[17][32] = {
++#else
+ mad_fixed_t const D[17][32] = {
++#endif
+ # include "D.dat"
+ };
++void mad_synth_init(struct mad_synth *synth)
++{
++
++  mad_synth_mute(synth);
++
++  synth->phase = 0;
++
++  synth->pcm.samplerate = 0;
++  synth->pcm.channels   = 0;
++  synth->pcm.length     = 0;
++
++#ifdef FPM_AVR32
++  {
++    int i, j;
++    for ( i = 0; i < 17; i++ ){
++      for ( j = 0; j < 32; j++ ){
++        if ( j & 1 ){
++          Dmod[i][17 + (j >> 1)]= D[i][j];
++        } else {
++          Dmod[i][(j >> 1)]= D[i][j];
++        }
++      }
++
++      Dmod[i][16]= Dmod[i][16+8];
++    }
++  }
++#endif
++
++}
++
+ # if defined(ASO_SYNTH)
+ void synth_full(struct mad_synth *, struct mad_frame const *,
+               unsigned int, unsigned int);
+@@ -560,9 +599,13 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
+ {
+   unsigned int phase, ch, s, sb, pe, po;
+   mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8];
+-  mad_fixed_t const (*sbsample)[36][32];
++  mad_fixed_t /*const*/ (*sbsample)[36][32];
+   register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
++#ifdef FPM_AVR32
++  register short const (*Dptr)[32], *ptr;
++#else
+   register mad_fixed_t const (*Dptr)[32], *ptr;
++#endif
+   register mad_fixed64hi_t hi;
+   register mad_fixed64lo_t lo;
+@@ -573,6 +616,20 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
+     pcm1     = synth->pcm.samples[ch];
+     for (s = 0; s < ns; ++s) {
++#  ifdef FPM_AVR32
++/*
++  int i;
++  for ( i = 0; i < 32; i++ ){
++  (*sbsample)[s][i] = ((*sbsample)[s][i] + (1 << 13)) & 0xFFFFC000;
++  }
++*/
++      dct32_avr32((*sbsample)[s], phase >> 1,
++          (*filter)[0][phase & 1], (*filter)[1][phase & 1]);
++      /*      printf("dct32: %d\n", GET_CYCLES);*/
++      pcm1 = synth_avr32(phase, (mad_fixed_t *)filter, \
++                         pcm1, (short *)&Dmod[0]);
++      /*      printf("synth_window: %d\n", GET_CYCLES);*/
++#  else
+       dct32((*sbsample)[s], phase >> 1,
+           (*filter)[0][phase & 1], (*filter)[1][phase & 1]);
+@@ -679,6 +736,7 @@ void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
+       MLA(hi, lo, (*fo)[7], ptr[ 2]);
+       *pcm1 = SHIFT(-MLZ(hi, lo));
++#  endif
+       pcm1 += 16;
+       phase = (phase + 1) % 16;
+diff --git a/synth_avr32.S b/synth_avr32.S
+new file mode 100644
+index 0000000..701077b
+--- /dev/null
++++ b/synth_avr32.S
+@@ -0,0 +1,394 @@
++/*
++   Optimized function for speeding up synthesis filter
++   in MPEG Audio Decoding.
++   Copyright 2003-2006 Atmel Corporation.
++
++   Written by Ronny Pedersen and Lars Even AlmÃ¥s, 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. */
++
++
++/* *****************
++   Defining macros
++   ***************** */
++
++      .macro  window_1        f, ptr, acc, ptr_offset, mul, tmp1_lo, tmp1_hi, tmp2_lo, tmp2_hi, tmp3_lo, tmp3_hi
++      ld.d            \tmp1_lo, \f[0*4]                       /* tmp1 = { f[0], f[1] } */
++      ld.w            \tmp2_lo, \ptr[0*2+\ptr_offset*2]       /* tmp2_lo = { ptr[0], ptr[1] }*/
++      ld.d            \tmp3_lo, \f[6*4]                       /* tmp3 = { f[6], f[7] } */
++      ld.w            \tmp2_hi, \ptr[6*2+\ptr_offset*2]       /* tmp2_hi = { ptr[6], ptr[7] }*/
++      .if \mul
++      mulwh.d         \acc, \tmp1_hi, \tmp2_lo:t              /* f[0] * ptr[0]*/
++      .else
++      macwh.d         \acc, \tmp1_hi, \tmp2_lo:t              /* f[0] * ptr[0]*/
++      .endif
++      macwh.d         \acc, \tmp3_lo, \tmp2_lo:b              /* f[7] * ptr[1]*/
++      ld.w            \tmp2_lo, \ptr[2*2+\ptr_offset*2]       /* tmp2_lo = { ptr[2], ptr[3] }*/
++      macwh.d         \acc, \tmp1_lo, \tmp2_hi:b              /* f[1] * ptr[7]*/
++      ld.d            \tmp1_lo, \f[2*4]                       /* tmp1 = { f[2], f[3] } */
++
++      macwh.d         \acc, \tmp3_hi, \tmp2_lo:t              /* f[6] * ptr[2]*/
++      macwh.d         \acc, \tmp1_hi, \tmp2_hi:t              /* f[2] * ptr[6]*/
++      ld.d            \tmp3_lo, \f[4*4]                       /* tmp3 = { f[4], f[5] } */
++      ld.w            \tmp2_hi, \ptr[4*2+\ptr_offset*2]       /* tmp2_hi = { ptr[4], ptr[5] }*/
++      macwh.d         \acc, \tmp3_lo, \tmp2_lo:b              /* f[5] * ptr[3]*/
++
++      macwh.d         \acc, \tmp1_lo, \tmp2_hi:b              /* f[3] * ptr[5]*/
++      macwh.d         \acc, \tmp3_hi, \tmp2_hi:t              /* f[4] * ptr[4]*/
++      .endm
++
++      .macro  window_2        f, ptr, acc, ptr_offset, mul, tmp1_lo, tmp1_hi, tmp2_lo, tmp2_hi, tmp3_lo, tmp3_hi
++      ld.d            \tmp1_lo, \f[0*4]                       /* tmp1 = { f[0], f[1] } */
++      ld.w            \tmp2_lo, \ptr[7*2+\ptr_offset*2]       /* tmp2_lo = { ptr[7], ptr[8] }*/
++      ld.d            \tmp3_lo, \f[2*4]                       /* tmp3 = { f[2], f[3] } */
++      ld.w            \tmp2_hi, \ptr[9*2+\ptr_offset*2]       /* tmp2_hi = { ptr[9], ptr[10] }*/
++      .if \mul
++      mulwh.d         \acc, \tmp1_hi, \tmp2_lo:t              /* f[0] * ptr[7]*/
++      .else
++      macwh.d         \acc, \tmp1_hi, \tmp2_lo:t              /* f[0] * ptr[7]*/
++      .endif
++      macwh.d         \acc, \tmp1_lo, \tmp2_lo:b              /* f[1] * ptr[8]*/
++
++      ld.d            \tmp1_lo, \f[4*4]                       /* tmp1 = { f[4], f[5] } */
++      ld.w            \tmp2_lo, \ptr[11*2+\ptr_offset*2]      /* tmp2_lo = { ptr[11], ptr[12] }*/
++
++      macwh.d         \acc, \tmp3_hi, \tmp2_hi:t              /* f[2] * ptr[9]*/
++      macwh.d         \acc, \tmp3_lo, \tmp2_hi:b              /* f[3] * ptr[10]*/
++
++      ld.d            \tmp3_lo, \f[6*4]                       /* tmp3 = { f[6], f[7] } */
++      ld.w            \tmp2_hi, \ptr[13*2+\ptr_offset*2]      /* tmp2_hi = { ptr[13], ptr[14] }*/
++
++      macwh.d         \acc, \tmp1_hi, \tmp2_lo:t              /* f[4] * ptr[11]*/
++      macwh.d         \acc, \tmp1_lo, \tmp2_lo:b              /* f[5] * ptr[12]*/
++      macwh.d         \acc, \tmp3_hi, \tmp2_hi:t              /* f[6] * ptr[13]*/
++      macwh.d         \acc, \tmp3_lo, \tmp2_hi:b              /* f[7] * ptr[14]*/
++      .endm
++
++      .macro  scale   res, d_lo, d_hi
++      lsl             \d_hi, 2
++      .endm
++
++/* **********************
++   Starting main function
++   ********************** */
++
++/* Function synth_avr32 is called from synth.c with arguments:
++             phase, filter, *pcm1, &D[0]              */
++
++      .global synth_avr32
++synth_avr32:
++      pushm           r0-r7, lr
++      sub             sp, 8
++
++      /* R12 = phase, R11 = filter, R10 = pcm1, r9 = D*/
++      bld             r12, 0
++      brcc            synth_even
++
++      /* Filter for odd phases */
++
++      /*      fe = &(*filter)[0][1][0];
++              fx = &(*filter)[0][0][0];
++              fo = &(*filter)[1][0][0]; */
++      sub             lr /*fe*/, r11, -16*8*4
++      sub             r8 /*fo*/, r11, -16*8*4*2
++
++      /*      pe = phase >> 1; */
++      lsr             r12, 1
++      stdsp           sp[4], r12
++      /*      ptr = (short const *)Dmod + pe; */
++      add             r12, r9, r12 << 1
++
++      /*      ML0(hi, lo, (*fx)[0], ptr[0 + 17]);
++              MLA(hi, lo, (*fx)[1], ptr[7 + 17]);
++              MLA(hi, lo, (*fx)[2], ptr[6 + 17]);
++              MLA(hi, lo, (*fx)[3], ptr[5 + 17]);
++              MLA(hi, lo, (*fx)[4], ptr[4 + 17]);
++              MLA(hi, lo, (*fx)[5], ptr[3 + 17]);
++              MLA(hi, lo, (*fx)[6], ptr[2 + 17]);
++              MLA(hi, lo, (*fx)[7], ptr[1 + 17]); */
++      window_1        r11/*fx*/,r12/*ptr*/,r0/*acc*/,17/*off*/,1/*mul*/,r2,r3,r4,r5,r6,r7
++
++    /*                MLN(hi, lo); */
++      neg             r0
++      acr             r1
++      neg             r1
++
++    /*                MLA(hi, lo, (*fe)[0], ptr[0]);
++              MLA(hi, lo, (*fe)[1], ptr[7]);
++              MLA(hi, lo, (*fe)[2], ptr[6]);
++                MLA(hi, lo, (*fe)[3], ptr[5]);
++                MLA(hi, lo, (*fe)[4], ptr[4]);
++                MLA(hi, lo, (*fe)[5], ptr[3]);
++                MLA(hi, lo, (*fe)[6], ptr[2]);
++                MLA(hi, lo, (*fe)[7], ptr[1]); */
++      window_1        lr/*fe*/,r12/*ptr*/,r0/*acc*/,0/*off*/,0/*mac*/,r2,r3,r4,r5,r6,r7
++
++    /*                *pcm1++ = SHIFT(MLZ(hi, lo));
++
++              pcm2 = pcm1 + 31; */
++      scale           r1, r0, r1
++      st.w            r10/*pcm_1*/++, r1
++      sub             r11/*pcm2*/, r10, -4*31
++
++    /*                for (sb = 1; sb < 16; ++sb) { */
++      mov             r2, 15
++      stdsp           sp[0], r2
++odd_loop:
++    /*                ++fe;
++              ptr += 33; */
++      sub             lr /*fe*/, -8*4
++      sub             r12, -33*2
++
++    /*                ML0(hi, lo, (*fo)[0], ptr[0 + 17]);
++              MLA(hi, lo, (*fo)[1], ptr[7 + 17]);
++              MLA(hi, lo, (*fo)[2], ptr[6 + 17]);
++              MLA(hi, lo, (*fo)[3], ptr[5 + 17]);
++              MLA(hi, lo, (*fo)[4], ptr[4 + 17]);
++              MLA(hi, lo, (*fo)[5], ptr[3 + 17]);
++              MLA(hi, lo, (*fo)[6], ptr[2 + 17]);
++              MLA(hi, lo, (*fo)[7], ptr[1 + 17]); */
++      window_1        r8/*fo*/,r12/*ptr*/,r0/*acc*/,17/*off*/,1/*mul*/,r2,r3,r4,r5,r6,r7
++    /*                MLN(hi, lo); */
++
++      neg             r0
++      acr             r1
++      neg             r1
++
++    /*                MLA(hi, lo, (*fe)[7], ptr[1]);
++              MLA(hi, lo, (*fe)[6], ptr[2]);
++              MLA(hi, lo, (*fe)[5], ptr[3]);
++              MLA(hi, lo, (*fe)[4], ptr[4]);
++              MLA(hi, lo, (*fe)[3], ptr[5]);
++              MLA(hi, lo, (*fe)[2], ptr[6]);
++              MLA(hi, lo, (*fe)[1], ptr[7]);
++              MLA(hi, lo, (*fe)[0], ptr[0]); */
++      window_1        lr/*fe*/,r12/*ptr*/,r0/*acc*/,0/*off*/,0/*mac*/,r2,r3,r4,r5,r6,r7
++
++    /*        ptr -= 2*pe; */
++      lddsp           r2, sp[4]
++
++    /*                *pcm1++ = SHIFT(MLZ(hi, lo)); */
++
++      scale           r1, r0, r1
++      sub             r12/*ptr*/, r12, r2/*pe*/<< 2
++      st.w            r10/*pcm_1*/++, r1
++
++
++    /*                ML0(hi, lo, (*fe)[0], ptr[7  + 17]);
++              MLA(hi, lo, (*fe)[1], ptr[8  + 17]);
++              MLA(hi, lo, (*fe)[2], ptr[9  + 17]);
++              MLA(hi, lo, (*fe)[3], ptr[10 + 17]);
++              MLA(hi, lo, (*fe)[4], ptr[11 + 17]);
++              MLA(hi, lo, (*fe)[5], ptr[12 + 17]);
++              MLA(hi, lo, (*fe)[6], ptr[13 + 17]);
++              MLA(hi, lo, (*fe)[7], ptr[14 + 17]); */
++      window_2        lr/*fe*/,r12/*ptr*/,r0/*acc*/,17/*off*/,1/*mul*/,r2,r3,r4,r5,r6,r7
++    /*                MLA(hi, lo, (*fo)[7], ptr[14]);
++              MLA(hi, lo, (*fo)[6], ptr[13]);
++              MLA(hi, lo, (*fo)[5], ptr[12]);
++              MLA(hi, lo, (*fo)[4], ptr[11]);
++              MLA(hi, lo, (*fo)[3], ptr[10]);
++              MLA(hi, lo, (*fo)[2], ptr[9]);
++              MLA(hi, lo, (*fo)[1], ptr[8]);
++              MLA(hi, lo, (*fo)[0], ptr[7]); */
++      window_2        r8/*fo*/,r12/*ptr*/,r0/*acc*/,0/*off*/,0/*mac*/,r2,r3,r4,r5,r6,r7
++
++
++    /*                *pcm2-- = SHIFT(MLZ(hi, lo)); */
++      lddsp           r3, sp[4]
++      lddsp           r2, sp[0]
++      scale           r1, r0, r1
++      st.w            --r11/*pcm_2*/, r1
++
++    /*                ptr += 2*pe; */
++      add             r12/*ptr*/, r12, r3/*pe*/<< 2
++
++    /*                ++fo;
++              } */
++      sub             r8/*fo*/, -8*4
++
++      sub             r2, 1
++      stdsp           sp[0], r2
++      brne            odd_loop
++
++    /*                ptr += 33; */
++      sub             r12/*ptr*/, -33*2
++
++    /*                ML0(hi, lo, (*fo)[0], ptr[0 + 17]);
++              MLA(hi, lo, (*fo)[1], ptr[7 + 17]);
++              MLA(hi, lo, (*fo)[2], ptr[6 + 17]);
++              MLA(hi, lo, (*fo)[3], ptr[5 + 17]);
++              MLA(hi, lo, (*fo)[4], ptr[4 + 17]);
++              MLA(hi, lo, (*fo)[5], ptr[3 + 17]);
++              MLA(hi, lo, (*fo)[6], ptr[2 + 17]);
++              MLA(hi, lo, (*fo)[7], ptr[1 + 17]); */
++      window_1        r8/*fo*/,r12/*ptr*/,r0/*acc*/,17/*off*/,1/*mul*/,r2,r3,r4,r5,r6,r7
++
++      rjmp            synth_end
++synth_even:
++      /* Filter for even phases */
++
++      /*      fe = &(*filter)[0][0][0];
++              fx = &(*filter)[0][1][0];
++              fo = &(*filter)[1][1][0]; */
++      sub             lr /*fx*/, r11, -16*8*4
++      sub             r8 /*fo*/, r11, -(16*8*4*2 + 16*8*4)
++
++      /*      po = ((phase - 1) & 0xF) >> 1; */
++      sub             r12, 1
++      andl            r12, 0xe, COH
++      stdsp           sp[4], r12
++      /*      ptr = (short const *)Dmod + po; */
++      add             r12, r9, r12
++
++      /*      ML0(hi, lo, (*fx)[0], ptr[0 + 17]);
++              MLA(hi, lo, (*fx)[1], ptr[7 + 17]);
++              MLA(hi, lo, (*fx)[2], ptr[6 + 17]);
++              MLA(hi, lo, (*fx)[3], ptr[5 + 17]);
++              MLA(hi, lo, (*fx)[4], ptr[4 + 17]);
++              MLA(hi, lo, (*fx)[5], ptr[3 + 17]);
++              MLA(hi, lo, (*fx)[6], ptr[2 + 17]);
++              MLA(hi, lo, (*fx)[7], ptr[1 + 17]); */
++      window_1        lr/*fx*/,r12/*ptr*/,r0/*acc*/,17/*off*/,1/*mul*/,r2,r3,r4,r5,r6,r7
++
++    /*                MLN(hi, lo); */
++      neg             r0
++      acr             r1
++      neg             r1
++
++    /*                MLA(hi, lo, (*fe)[0], ptr[0 + 1]);
++              MLA(hi, lo, (*fe)[1], ptr[7 + 1]);
++              MLA(hi, lo, (*fe)[2], ptr[6 + 1]);
++                MLA(hi, lo, (*fe)[3], ptr[5 + 1]);
++                MLA(hi, lo, (*fe)[4], ptr[4 + 1]);
++                MLA(hi, lo, (*fe)[5], ptr[3 + 1]);
++                MLA(hi, lo, (*fe)[6], ptr[2 + 1]);
++                MLA(hi, lo, (*fe)[7], ptr[1 + 1]); */
++      window_1        r11/*fe*/,r12/*ptr*/,r0/*acc*/,1/*off*/,0/*mac*/,r2,r3,r4,r5,r6,r7
++
++    /*                *pcm1++ = SHIFT(MLZ(hi, lo));
++
++              pcm2 = pcm1 + 31; */
++      scale           r1, r0, r1
++      st.w            r10/*pcm_1*/++, r1
++      sub             lr/*pcm2*/, r10, -4*31
++
++    /*                for (sb = 1; sb < 16; ++sb) { */
++      mov             r2, 15
++      stdsp           sp[0], r2
++even_loop:
++    /*                ++fe;
++              ptr += 33; */
++      sub             r11 /*fe*/, -8*4
++      sub             r12, -33*2
++
++    /*                ML0(hi, lo, (*fo)[0], ptr[0 + 17]);
++              MLA(hi, lo, (*fo)[1], ptr[7 + 17]);
++              MLA(hi, lo, (*fo)[2], ptr[6 + 17]);
++              MLA(hi, lo, (*fo)[3], ptr[5 + 17]);
++              MLA(hi, lo, (*fo)[4], ptr[4 + 17]);
++              MLA(hi, lo, (*fo)[5], ptr[3 + 17]);
++              MLA(hi, lo, (*fo)[6], ptr[2 + 17]);
++              MLA(hi, lo, (*fo)[7], ptr[1 + 17]); */
++      window_1        r8/*fo*/,r12/*ptr*/,r0/*acc*/,17/*off*/,1/*mul*/,r2,r3,r4,r5,r6,r7
++    /*                MLN(hi, lo); */
++      neg             r0
++      acr             r1
++      neg             r1
++
++    /*                MLA(hi, lo, (*fe)[7], ptr[1 + 1]);
++              MLA(hi, lo, (*fe)[6], ptr[2 + 1]);
++              MLA(hi, lo, (*fe)[5], ptr[3 + 1]);
++              MLA(hi, lo, (*fe)[4], ptr[4 + 1]);
++              MLA(hi, lo, (*fe)[3], ptr[5 + 1]);
++              MLA(hi, lo, (*fe)[2], ptr[6 + 1]);
++              MLA(hi, lo, (*fe)[1], ptr[7 + 1]);
++              MLA(hi, lo, (*fe)[0], ptr[0 + 1]); */
++      window_1        r11/*fe*/,r12/*ptr*/,r0/*acc*/,1/*off*/,0/*mac*/,r2,r3,r4,r5,r6,r7
++
++    /*                *pcm1++ = SHIFT(MLZ(hi, lo)); */
++      lddsp           r2, sp[4]
++      scale           r1, r0, r1
++    /*        ptr -= 2*po; */
++      sub             r12/*ptr*/, r12, r2/*po*/<< 1
++      st.w            r10/*pcm_1*/++, r1
++
++
++    /*                ML0(hi, lo, (*fe)[0], ptr[7  + 17 - 1]);
++              MLA(hi, lo, (*fe)[1], ptr[8  + 17 - 1]);
++              MLA(hi, lo, (*fe)[2], ptr[9  + 17 - 1]);
++              MLA(hi, lo, (*fe)[3], ptr[10 + 17 - 1]);
++              MLA(hi, lo, (*fe)[4], ptr[11 + 17 - 1]);
++              MLA(hi, lo, (*fe)[5], ptr[12 + 17 - 1]);
++              MLA(hi, lo, (*fe)[6], ptr[13 + 17 - 1]);
++              MLA(hi, lo, (*fe)[7], ptr[14 + 17 - 1]); */
++      window_2        r11/*fe*/,r12/*ptr*/,r0/*acc*/,16/*off*/,1/*mul*/,r2,r3,r4,r5,r6,r7
++    /*                MLA(hi, lo, (*fo)[7], ptr[14]);
++              MLA(hi, lo, (*fo)[6], ptr[13]);
++              MLA(hi, lo, (*fo)[5], ptr[12]);
++              MLA(hi, lo, (*fo)[4], ptr[11]);
++              MLA(hi, lo, (*fo)[3], ptr[10]);
++              MLA(hi, lo, (*fo)[2], ptr[9]);
++              MLA(hi, lo, (*fo)[1], ptr[8]);
++              MLA(hi, lo, (*fo)[0], ptr[7]); */
++      window_2        r8/*fo*/,r12/*ptr*/,r0/*acc*/,0/*off*/,0/*mac*/,r2,r3,r4,r5,r6,r7
++
++
++    /*                *pcm2-- = SHIFT(MLZ(hi, lo)); */
++      lddsp           r3, sp[4]
++      lddsp           r2, sp[0]
++      scale           r1, r0, r1
++      st.w            --lr/*pcm_2*/, r1
++
++    /*                ptr += 2*po; */
++      add             r12/*ptr*/, r12, r3/*po*/<< 1
++
++    /*                ++fo;
++              } */
++      sub             r8/*fo*/, -8*4
++
++      sub             r2, 1
++      stdsp           sp[0], r2
++      brne            even_loop
++
++    /*                ptr += 33; */
++      sub             r12/*ptr*/, -33*2
++
++    /*                ML0(hi, lo, (*fo)[0], ptr[0 + 17]);
++              MLA(hi, lo, (*fo)[1], ptr[7 + 17]);
++              MLA(hi, lo, (*fo)[2], ptr[6 + 17]);
++              MLA(hi, lo, (*fo)[3], ptr[5 + 17]);
++              MLA(hi, lo, (*fo)[4], ptr[4 + 17]);
++              MLA(hi, lo, (*fo)[5], ptr[3 + 17]);
++              MLA(hi, lo, (*fo)[6], ptr[2 + 17]);
++              MLA(hi, lo, (*fo)[7], ptr[1 + 17]); */
++      window_1        r8/*fo*/,r12/*ptr*/,r0/*acc*/,17/*off*/,1/*mul*/,r2,r3,r4,r5,r6,r7
++
++
++
++synth_end:
++   /*         *pcm1 = SHIFT(-MLZ(hi, lo)); */
++      scale           r1, r0, r1
++      neg             r1
++      st.w            r10/*pcm_1*/, r1
++
++      mov             r12, r10
++      sub             sp, -8
++      popm            r0-r7, pc
++
++
++
++
++
index 4e48623..9669cbd 100644 (file)
@@ -4,9 +4,13 @@ PRIORITY = "optional"
 DEPENDS = "libid3tag"
 LICENSE = "GPL"
 
+PR = "r1"
+
 SRC_URI = "${SOURCEFORGE_MIRROR}/mad/libmad-${PV}.tar.gz"
 S = "${WORKDIR}/libmad-${PV}"
 
+SRC_URI_append_avr32 = " file://libmad-0.15.1b-avr32-optimization.patch;patch=1"
+
 inherit autotools
 
 EXTRA_OECONF = "-enable-speed --enable-shared"
diff --git a/packages/linux/linux-2.6.18/.mtn2git_empty b/packages/linux/linux-2.6.18/.mtn2git_empty
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/packages/linux/linux-2.6.18/0001-AVR32-Fix-compile-error-with-gcc-4.1.patch b/packages/linux/linux-2.6.18/0001-AVR32-Fix-compile-error-with-gcc-4.1.patch
new file mode 100755 (executable)
index 0000000..2b43045
--- /dev/null
@@ -0,0 +1,71 @@
+From 8224ca195874525533665bbcd23b6da1e575aa4d Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Fri, 27 Apr 2007 14:21:47 +0200
+Subject: [AVR32] Fix compile error with gcc 4.1
+
+gcc 4.1 doesn't seem to like const variables as inline assembly
+outputs. Drop support for reading 64-bit values using get_user() so
+that we can use an unsigned long to hold the result regardless of the
+actual size. This should be safe since many architectures, including
+i386, doesn't support reading 64-bit values with get_user().
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+---
+ include/asm-avr32/uaccess.h |   13 ++++---------
+ 1 files changed, 4 insertions(+), 9 deletions(-)
+
+diff --git a/include/asm-avr32/uaccess.h b/include/asm-avr32/uaccess.h
+index 74a679e..ed09239 100644
+--- a/include/asm-avr32/uaccess.h
++++ b/include/asm-avr32/uaccess.h
+@@ -181,24 +181,23 @@ extern int __put_user_bad(void);
+ #define __get_user_nocheck(x, ptr, size)                              \
+ ({                                                                    \
+-      typeof(*(ptr)) __gu_val = (typeof(*(ptr)) __force)0;            \
++      unsigned long __gu_val = 0;                                     \
+       int __gu_err = 0;                                               \
+                                                                       \
+       switch (size) {                                                 \
+       case 1: __get_user_asm("ub", __gu_val, ptr, __gu_err); break;   \
+       case 2: __get_user_asm("uh", __gu_val, ptr, __gu_err); break;   \
+       case 4: __get_user_asm("w", __gu_val, ptr, __gu_err); break;    \
+-      case 8: __get_user_asm("d", __gu_val, ptr, __gu_err); break;    \
+       default: __gu_err = __get_user_bad(); break;                    \
+       }                                                               \
+                                                                       \
+-      x = __gu_val;                                                   \
++      x = (typeof(*(ptr)))__gu_val;                                   \
+       __gu_err;                                                       \
+ })
+ #define __get_user_check(x, ptr, size)                                        \
+ ({                                                                    \
+-      typeof(*(ptr)) __gu_val = (typeof(*(ptr)) __force)0;            \
++      unsigned long __gu_val = 0;                                     \
+       const typeof(*(ptr)) __user * __gu_addr = (ptr);                \
+       int __gu_err = 0;                                               \
+                                                                       \
+@@ -216,10 +215,6 @@ extern int __put_user_bad(void);
+                       __get_user_asm("w", __gu_val, __gu_addr,        \
+                                      __gu_err);                       \
+                       break;                                          \
+-              case 8:                                                 \
+-                      __get_user_asm("d", __gu_val, __gu_addr,        \
+-                                     __gu_err);                       \
+-                      break;                                          \
+               default:                                                \
+                       __gu_err = __get_user_bad();                    \
+                       break;                                          \
+@@ -227,7 +222,7 @@ extern int __put_user_bad(void);
+       } else {                                                        \
+               __gu_err = -EFAULT;                                     \
+       }                                                               \
+-      x = __gu_val;                                                   \
++      x = (typeof(*(ptr)))__gu_val;                                   \
+       __gu_err;                                                       \
+ })
+-- 
+1.4.4.4
+
diff --git a/packages/linux/linux-2.6.18/add-all-parameters-to-smc-driver.patch b/packages/linux/linux-2.6.18/add-all-parameters-to-smc-driver.patch
new file mode 100644 (file)
index 0000000..ec4de30
--- /dev/null
@@ -0,0 +1,73 @@
+--- linux-2.6.18-orig/arch/avr32/mach-at32ap/hsmc.c    2006-09-26 15:01:28.000000000 +0200
++++ linux-2.6.18/arch/avr32/mach-at32ap/hsmc.c 2006-10-18 14:03:35.000000000 +0200
+@@ -75,12 +75,35 @@ int smc_set_configuration(int cs, const 
+               return -EINVAL;
+       }
++      switch (config->nwait_mode) {
++      case 0:
++              mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_DISABLED);
++              break;
++      case 1:
++              mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_RESERVED);
++              break;
++      case 2:
++              mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_FROZEN);
++              break;
++      case 3:
++              mode |= HSMC_BF(EXNW_MODE, HSMC_EXNW_MODE_READY);
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      if (config->tdf_cycles) {
++              mode |= HSMC_BF(TDF_CYCLES, config->tdf_cycles);
++      }
++
+       if (config->nrd_controlled)
+               mode |= HSMC_BIT(READ_MODE);
+       if (config->nwe_controlled)
+               mode |= HSMC_BIT(WRITE_MODE);
+       if (config->byte_write)
+               mode |= HSMC_BIT(BAT);
++      if (config->tdf_mode)
++              mode |= HSMC_BIT(TDF_MODE);
+       pr_debug("smc cs%d: setup/%08x pulse/%08x cycle/%08x mode/%08x\n",
+                cs, setup, pulse, cycle, mode);
+--- linux-2.6.18-orig/include/asm-avr32/arch-at32ap/smc.h      2006-09-26 15:01:30.000000000 +0200
++++ linux-2.6.18/include/asm-avr32/arch-at32ap/smc.h   2006-10-18 13:36:06.000000000 +0200
+@@ -48,10 +48,32 @@ struct smc_config {
+       unsigned int    nwe_controlled:1;
+       /*
++       * 0: NWAIT is disabled
++       * 1: Reserved
++       * 2: NWAIT is frozen mode
++       * 3: NWAIT in ready mode
++       */
++      unsigned int    nwait_mode:2;
++
++      /*
+        * 0: Byte select access type
+        * 1: Byte write access type
+        */
+       unsigned int    byte_write:1;
++
++      /*
++       * Number of clock cycles before data is released after
++       * the rising edge of the read controlling signal
++       *
++       * Total cycles from SMC is tdf_cycles + 1
++       */
++      unsigned int    tdf_cycles:4;
++
++      /*
++       * 0: TDF optimization disabled
++       * 1: TDF optimization enabled
++       */
++      unsigned int    tdf_mode:1;
+ };
+ extern int smc_set_configuration(int cs, const struct smc_config *config);
diff --git a/packages/linux/linux-2.6.18/add-default-atngw-defconfig.patch b/packages/linux/linux-2.6.18/add-default-atngw-defconfig.patch
new file mode 100644 (file)
index 0000000..233416e
--- /dev/null
@@ -0,0 +1,975 @@
+Index: linux-2.6.18/arch/avr32/configs/atngw_defconfig
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18/arch/avr32/configs/atngw_defconfig    2007-01-10 10:15:54.000000000 +0100
+@@ -0,0 +1,970 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.18-at0
++# Wed Jan 10 10:13:31 2007
++#
++CONFIG_AVR32=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_TIME=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++
++#
++# General setup
++#
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++CONFIG_SYSVIPC=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++# CONFIG_TASKSTATS is not set
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++# CONFIG_RELAY is not set
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_EMBEDDED=y
++CONFIG_SYSCTL=y
++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_BASE_FULL is not set
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
++CONFIG_SHMEM=y
++CONFIG_SLAB=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_RT_MUTEXES=y
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=1
++# CONFIG_SLOB is not set
++
++#
++# Loadable module support
++#
++CONFIG_MODULES=y
++CONFIG_MODULE_UNLOAD=y
++CONFIG_MODULE_FORCE_UNLOAD=y
++# CONFIG_MODVERSIONS is not set
++# CONFIG_MODULE_SRCVERSION_ALL is not set
++CONFIG_KMOD=y
++
++#
++# Block layer
++#
++# CONFIG_BLK_DEV_IO_TRACE 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"
++
++#
++# System Type and features
++#
++CONFIG_SUBARCH_AVR32B=y
++CONFIG_MMU=y
++CONFIG_PERFORMANCE_COUNTERS=y
++CONFIG_PLATFORM_AT32AP=y
++CONFIG_CPU_AT32AP7000=y
++# CONFIG_BOARD_ATSTK1000 is not set
++CONFIG_BOARD_ATNGW=y
++CONFIG_LOADER_U_BOOT=y
++
++#
++# Atmel AVR32 AP options
++#
++CONFIG_PIO_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_SPLIT_PTLOCK_CPUS=4
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_OWNERSHIP_TRACE is not set
++CONFIG_DW_DMAC=y
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++CONFIG_CMDLINE=""
++
++#
++# Bus options
++#
++
++#
++# PCCARD (PCMCIA/CardBus) support
++#
++# 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_NETDEBUG is not set
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++# CONFIG_NET_KEY is not set
++CONFIG_INET=y
++# CONFIG_IP_MULTICAST is not set
++CONFIG_IP_ADVANCED_ROUTER=y
++CONFIG_ASK_IP_FIB_HASH=y
++# CONFIG_IP_FIB_TRIE 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
++# CONFIG_IP_PNP_RARP is not set
++# CONFIG_NET_IPIP is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_BIC=y
++
++#
++# IP: Virtual Server Configuration
++#
++# CONFIG_IP_VS is not set
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++CONFIG_NETFILTER=y
++# CONFIG_NETFILTER_DEBUG is not set
++
++#
++# Core Netfilter Configuration
++#
++# CONFIG_NETFILTER_NETLINK is not set
++CONFIG_NETFILTER_XTABLES=y
++# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
++# CONFIG_NETFILTER_XT_TARGET_MARK is not set
++# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
++# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
++# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
++# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
++# CONFIG_NETFILTER_XT_MATCH_ESP is not set
++# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
++# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
++# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
++# CONFIG_NETFILTER_XT_MATCH_MAC is not set
++# CONFIG_NETFILTER_XT_MATCH_MARK is not set
++# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
++# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
++# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
++# CONFIG_NETFILTER_XT_MATCH_REALM is not set
++# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
++CONFIG_NETFILTER_XT_MATCH_STATE=y
++# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
++# CONFIG_NETFILTER_XT_MATCH_STRING is not set
++# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
++
++#
++# IP: Netfilter Configuration
++#
++CONFIG_IP_NF_CONNTRACK=y
++# CONFIG_IP_NF_CT_ACCT is not set
++# CONFIG_IP_NF_CONNTRACK_MARK is not set
++# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
++# CONFIG_IP_NF_CT_PROTO_SCTP is not set
++# CONFIG_IP_NF_FTP is not set
++# CONFIG_IP_NF_IRC is not set
++# CONFIG_IP_NF_NETBIOS_NS is not set
++# CONFIG_IP_NF_TFTP is not set
++# CONFIG_IP_NF_AMANDA is not set
++# CONFIG_IP_NF_PPTP is not set
++# CONFIG_IP_NF_H323 is not set
++# CONFIG_IP_NF_SIP is not set
++# CONFIG_IP_NF_QUEUE is not set
++CONFIG_IP_NF_IPTABLES=y
++# CONFIG_IP_NF_MATCH_IPRANGE is not set
++# CONFIG_IP_NF_MATCH_TOS is not set
++# CONFIG_IP_NF_MATCH_RECENT is not set
++# CONFIG_IP_NF_MATCH_ECN is not set
++# CONFIG_IP_NF_MATCH_DSCP is not set
++# CONFIG_IP_NF_MATCH_AH is not set
++# CONFIG_IP_NF_MATCH_TTL is not set
++# CONFIG_IP_NF_MATCH_OWNER is not set
++# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
++# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
++CONFIG_IP_NF_FILTER=y
++CONFIG_IP_NF_TARGET_REJECT=y
++CONFIG_IP_NF_TARGET_LOG=y
++# CONFIG_IP_NF_TARGET_ULOG is not set
++# CONFIG_IP_NF_TARGET_TCPMSS is not set
++CONFIG_IP_NF_NAT=y
++CONFIG_IP_NF_NAT_NEEDED=y
++CONFIG_IP_NF_TARGET_MASQUERADE=y
++CONFIG_IP_NF_TARGET_REDIRECT=y
++# CONFIG_IP_NF_TARGET_NETMAP is not set
++# CONFIG_IP_NF_TARGET_SAME is not set
++# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
++# CONFIG_IP_NF_MANGLE is not set
++# CONFIG_IP_NF_RAW is not set
++# CONFIG_IP_NF_ARPTABLES is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_SCTP is not set
++
++#
++# TIPC Configuration (EXPERIMENTAL)
++#
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# 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
++
++#
++# QoS and/or fair queueing
++#
++# CONFIG_NET_SCHED is not set
++
++#
++# Network testing
++#
++# CONFIG_NET_PKTGEN is not set
++# CONFIG_HAMRADIO is not set
++# CONFIG_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_IEEE80211 is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_STANDALONE=y
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++# CONFIG_FW_LOADER is not set
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_SYS_HYPERVISOR is not set
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++# CONFIG_CONNECTOR is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++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 is not set
++
++#
++# User Modules And Translation Layers
++#
++CONFIG_MTD_CHAR=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
++
++#
++# 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
++# CONFIG_MTD_OBSOLETE_CHIPS is not set
++
++#
++# Mapping drivers for chip access
++#
++# CONFIG_MTD_COMPLEX_MAPPINGS is not set
++CONFIG_MTD_PHYSMAP=y
++CONFIG_MTD_PHYSMAP_START=0x80000000
++CONFIG_MTD_PHYSMAP_LEN=0x0
++CONFIG_MTD_PHYSMAP_BANKWIDTH=2
++# CONFIG_MTD_PLATRAM is not set
++
++#
++# Self-contained MTD device drivers
++#
++CONFIG_MTD_DATAFLASH=y
++# CONFIG_MTD_M25P80 is not set
++# 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
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# OneNAND Flash Device Drivers
++#
++# CONFIG_MTD_ONENAND is not set
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Plug and Play support
++#
++
++#
++# Block devices
++#
++# CONFIG_BLK_DEV_COW_COMMON is not set
++CONFIG_BLK_DEV_LOOP=y
++# 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_RAM_BLOCKSIZE=1024
++CONFIG_BLK_DEV_INITRD=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Fusion MPT device support
++#
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++
++#
++# I2O device support
++#
++
++#
++# Network device support
++#
++CONFIG_NETDEVICES=y
++# CONFIG_DUMMY is not set
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++# CONFIG_TUN is not set
++
++#
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_MACB=y
++
++#
++# Ethernet (1000 Mbit)
++#
++
++#
++# Ethernet (10000 Mbit)
++#
++
++#
++# Token Ring devices
++#
++
++#
++# Wireless LAN (non-hamradio)
++#
++# CONFIG_NET_RADIO is not set
++
++#
++# Wan interfaces
++#
++# CONFIG_WAN is not set
++# CONFIG_PPP is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Telephony Support
++#
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT 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_TTYAT is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
++
++#
++# IPMI
++#
++# CONFIG_IPMI_HANDLER is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_RAW_DRIVER is not set
++
++#
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++# CONFIG_TELCLOCK is not set
++
++#
++# I2C support
++#
++CONFIG_I2C=m
++CONFIG_I2C_CHARDEV=m
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# 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_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_PCA_ISA 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=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
++#
++
++#
++# Dallas's 1-wire bus
++#
++
++#
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++CONFIG_VIDEO_V4L2=y
++
++#
++# Digital Video Broadcasting Devices
++#
++# CONFIG_DVB is not set
++
++#
++# Graphics support
++#
++# CONFIG_FIRMWARE_EDID is not set
++# CONFIG_FB is not set
++# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# 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'
++#
++
++#
++# USB Gadget Support
++#
++CONFIG_USB_GADGET=m
++# CONFIG_USB_GADGET_DEBUG_FILES is not set
++CONFIG_USB_GADGET_SELECTED=y
++# 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_HUSB2DEV=y
++CONFIG_USB_HUSB2DEV=m
++# 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 is not set
++# CONFIG_USB_ETH is not set
++# CONFIG_USB_GADGETFS is not set
++CONFIG_USB_FILE_STORAGE=m
++# CONFIG_USB_FILE_STORAGE_TEST is not set
++# CONFIG_USB_G_SERIAL is not set
++
++#
++# MMC/SD Card support
++#
++CONFIG_MMC=m
++# CONFIG_MMC_DEBUG is not set
++CONFIG_MMC_BLOCK=m
++CONFIG_MMC_ATMELMCI=m
++
++#
++# LED devices
++#
++# CONFIG_NEW_LEDS is not set
++
++#
++# LED drivers
++#
++
++#
++# LED Triggers
++#
++
++#
++# InfiniBand support
++#
++
++#
++# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
++#
++
++#
++# Real Time Clock
++#
++# CONFIG_RTC_CLASS is not set
++
++#
++# DMA Engine support
++#
++# CONFIG_DMA_ENGINE is not set
++
++#
++# DMA Clients
++#
++
++#
++# DMA Devices
++#
++
++#
++# 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_JBD=y
++# CONFIG_JBD_DEBUG is not set
++# CONFIG_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++# CONFIG_MINIX_FS is not set
++# CONFIG_ROMFS_FS 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=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=850
++CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
++# CONFIG_NTFS_FS is not set
++
++#
++# Pseudo filesystems
++#
++CONFIG_PROC_FS=y
++# CONFIG_PROC_KCORE is not set
++CONFIG_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++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_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# 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_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
++# CONFIG_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Network File Systems
++#
++CONFIG_NFS_FS=y
++# CONFIG_NFS_V3 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_NFS_COMMON=y
++CONFIG_SUNRPC=y
++# CONFIG_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 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
++# CONFIG_9P_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++
++#
++# Native Language Support
++#
++CONFIG_NLS=y
++CONFIG_NLS_DEFAULT="iso8859-1"
++# CONFIG_NLS_CODEPAGE_437 is not set
++# CONFIG_NLS_CODEPAGE_737 is not set
++# CONFIG_NLS_CODEPAGE_775 is not set
++CONFIG_NLS_CODEPAGE_850=y
++# 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=y
++# 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=y
++
++#
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
++# Kernel hacking
++#
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++# CONFIG_PRINTK_TIME is not set
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_LOG_BUF_SHIFT=14
++CONFIG_DETECT_SOFTLOCKUP=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_DEBUG_SLAB 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_RWSEMS 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_FS is not set
++# CONFIG_DEBUG_VM is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_UNWIND_INFO is not set
++# CONFIG_FORCED_INLINING is not set
++# CONFIG_RCU_TORTURE_TEST is not set
++# CONFIG_KPROBES is not set
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Hardware crypto devices
++#
++
++#
++# Library routines
++#
++# CONFIG_CRC_CCITT is not set
++# CONFIG_CRC16 is not set
++CONFIG_CRC32=y
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
diff --git a/packages/linux/linux-2.6.18/add-flush_buffer-operation-to-uart_ops.patch b/packages/linux/linux-2.6.18/add-flush_buffer-operation-to-uart_ops.patch
new file mode 100644 (file)
index 0000000..0c9b919
--- /dev/null
@@ -0,0 +1,71 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Thu Feb 2 15:48:50 2006 +0100
+Subject: [PATCH] Add flush_buffer() operation to uart_ops
+
+Serial drivers using DMA (like the Atmel USART3 driver) tend to get
+very confused when the xmit buffer is flushed and nobody told them.
+They also tend to spew a lot of garbage since the DMA engine keeps
+running after the buffer is flushed and possibly refilled with
+unrelated data.
+
+This patch adds a new flush_buffer operation to the uart_ops struct,
+along with a call to it from uart_flush_buffer() right after the xmit
+buffer has been cleared. The driver can implement this in order to
+syncronize its internal DMA state with the xmit buffer when the buffer
+is flushed.
+
+---
+
+ Documentation/serial/driver  |   11 +++++++++++
+ drivers/serial/serial_core.c |    2 ++
+ include/linux/serial_core.h  |    1 +
+ 3 files changed, 14 insertions(+)
+
+Index: linux-2.6.16-avr32/Documentation/serial/driver
+===================================================================
+--- linux-2.6.16-avr32.orig/Documentation/serial/driver        2006-03-20 06:53:29.000000000 +0100
++++ linux-2.6.16-avr32/Documentation/serial/driver     2006-04-03 18:57:11.000000000 +0200
+@@ -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
+Index: linux-2.6.16-avr32/drivers/serial/serial_core.c
+===================================================================
+--- linux-2.6.16-avr32.orig/drivers/serial/serial_core.c       2006-03-20 06:53:29.000000000 +0100
++++ linux-2.6.16-avr32/drivers/serial/serial_core.c    2006-04-03 18:57:11.000000000 +0200
+@@ -556,6 +556,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);
+ }
+Index: linux-2.6.16-avr32/include/linux/serial_core.h
+===================================================================
+--- linux-2.6.16-avr32.orig/include/linux/serial_core.h        2006-03-20 06:53:29.000000000 +0100
++++ linux-2.6.16-avr32/include/linux/serial_core.h     2006-04-03 18:57:11.000000000 +0200
+@@ -164,6 +164,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 termios *new,
+                                      struct termios *old);
+       void            (*pm)(struct uart_port *, unsigned int state,
diff --git a/packages/linux/linux-2.6.18/add-hmatrix-support.patch b/packages/linux/linux-2.6.18/add-hmatrix-support.patch
new file mode 100644 (file)
index 0000000..4387cac
--- /dev/null
@@ -0,0 +1,414 @@
+---
+ arch/avr32/mach-at32ap/hmatrix2.h |  377 ++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 377 insertions(+)
+
+Index: linux-2.6.18/arch/avr32/mach-at32ap/hmatrix2.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18/arch/avr32/mach-at32ap/hmatrix2.h     2006-11-03 14:57:10.000000000 +0100
+@@ -0,0 +1,377 @@
++/*
++ * Register definitions for HMATRIX2
++ *
++ * AHB Matrix
++ */
++#ifndef __ASM_AVR32_HMATRIX2_H__
++#define __ASM_AVR32_HMATRIX2_H__
++
++/* HMATRIX2 base address */
++#define HMATRIX2_BASE                         (void *)0xfff00800
++
++/* HMATRIX2 register offsets */
++#define HMATRIX2_MCFG0                          0x0000
++#define HMATRIX2_MCFG1                          0x0004
++#define HMATRIX2_MCFG2                          0x0008
++#define HMATRIX2_MCFG3                          0x000c
++#define HMATRIX2_MCFG4                          0x0010
++#define HMATRIX2_MCFG5                          0x0014
++#define HMATRIX2_MCFG6                          0x0018
++#define HMATRIX2_MCFG7                          0x001c
++#define HMATRIX2_MCFG8                          0x0020
++#define HMATRIX2_MCFG9                          0x0024
++#define HMATRIX2_MCFG10                         0x0028
++#define HMATRIX2_MCFG11                         0x002c
++#define HMATRIX2_MCFG12                         0x0030
++#define HMATRIX2_MCFG13                         0x0034
++#define HMATRIX2_MCFG14                         0x0038
++#define HMATRIX2_MCFG15                         0x003c
++#define HMATRIX2_SCFG0                          0x0040
++#define HMATRIX2_SCFG1                          0x0044
++#define HMATRIX2_SCFG2                          0x0048
++#define HMATRIX2_SCFG3                          0x004c
++#define HMATRIX2_SCFG4                          0x0050
++#define HMATRIX2_SCFG5                          0x0054
++#define HMATRIX2_SCFG6                          0x0058
++#define HMATRIX2_SCFG7                          0x005c
++#define HMATRIX2_SCFG8                          0x0060
++#define HMATRIX2_SCFG9                          0x0064
++#define HMATRIX2_SCFG10                         0x0068
++#define HMATRIX2_SCFG11                         0x006c
++#define HMATRIX2_SCFG12                         0x0070
++#define HMATRIX2_SCFG13                         0x0074
++#define HMATRIX2_SCFG14                         0x0078
++#define HMATRIX2_SCFG15                         0x007c
++#define HMATRIX2_PRAS                           0x0080
++#define HMATRIX2_PRBS                           0x0084
++#define HMATRIX2_PRAS1                          0x0088
++#define HMATRIX2_PRBS1                          0x008c
++#define HMATRIX2_PRAS2                          0x0090
++#define HMATRIX2_PRBS2                          0x0094
++#define HMATRIX2_PRAS3                          0x0098
++#define HMATRIX2_PRBS3                          0x009c
++#define HMATRIX2_PRAS4                          0x00a0
++#define HMATRIX2_PRBS4                          0x00a4
++#define HMATRIX2_PRAS5                          0x00a8
++#define HMATRIX2_PRBS5                          0x00ac
++#define HMATRIX2_PRAS6                          0x00b0
++#define HMATRIX2_PRBS6                          0x00b4
++#define HMATRIX2_PRAS7                          0x00b8
++#define HMATRIX2_PRBS7                          0x00bc
++#define HMATRIX2_PRAS8                          0x00c0
++#define HMATRIX2_PRBS8                          0x00c4
++#define HMATRIX2_PRAS9                          0x00c8
++#define HMATRIX2_PRBS9                          0x00cc
++#define HMATRIX2_PRAS10                         0x00d0
++#define HMATRIX2_PRBS10                         0x00d4
++#define HMATRIX2_PRAS11                         0x00d8
++#define HMATRIX2_PRBS11                         0x00dc
++#define HMATRIX2_PRAS12                         0x00e0
++#define HMATRIX2_PRBS12                         0x00e4
++#define HMATRIX2_PRAS13                         0x00e8
++#define HMATRIX2_PRBS13                         0x00ec
++#define HMATRIX2_PRAS14                         0x00f0
++#define HMATRIX2_PRBS14                         0x00f4
++#define HMATRIX2_PRAS15                         0x00f8
++#define HMATRIX2_PRBS15                         0x00fc
++#define HMATRIX2_MRCR                           0x0100
++#define HMATRIX2_SFR0                           0x0110
++#define HMATRIX2_SFR1                           0x0114
++#define HMATRIX2_SFR2                           0x0118
++#define HMATRIX2_SFR3                           0x011c
++#define HMATRIX2_SFR4                           0x0120
++#define HMATRIX2_SFR5                           0x0124
++#define HMATRIX2_SFR6                           0x0128
++#define HMATRIX2_SFR7                           0x012c
++#define HMATRIX2_SFR8                           0x0130
++#define HMATRIX2_SFR9                           0x0134
++#define HMATRIX2_SFR10                          0x0138
++#define HMATRIX2_SFR11                          0x013c
++#define HMATRIX2_SFR12                          0x0140
++#define HMATRIX2_SFR13                          0x0144
++#define HMATRIX2_SFR14                          0x0148
++#define HMATRIX2_SFR15                          0x014c
++#define HMATRIX2_VERSION                        0x01fc
++
++/* Bitfields in MCFG0 */
++#define HMATRIX2_ULBT_OFFSET                    0
++#define HMATRIX2_ULBT_SIZE                      3
++
++/* Bitfields in MCFG1 */
++
++/* Bitfields in MCFG2 */
++
++/* Bitfields in MCFG3 */
++
++/* Bitfields in MCFG4 */
++
++/* Bitfields in MCFG5 */
++
++/* Bitfields in MCFG6 */
++
++/* Bitfields in MCFG7 */
++
++/* Bitfields in MCFG8 */
++
++/* Bitfields in MCFG9 */
++
++/* Bitfields in MCFG10 */
++
++/* Bitfields in MCFG11 */
++
++/* Bitfields in MCFG12 */
++
++/* Bitfields in MCFG13 */
++
++/* Bitfields in MCFG14 */
++
++/* Bitfields in MCFG15 */
++
++/* Bitfields in SCFG0 */
++#define HMATRIX2_SLOT_CYCLE_OFFSET              0
++#define HMATRIX2_SLOT_CYCLE_SIZE                8
++#define HMATRIX2_DEFMSTR_TYPE_OFFSET            16
++#define HMATRIX2_DEFMSTR_TYPE_SIZE              2
++#define HMATRIX2_FIXED_DEFMSTR_OFFSET           18
++#define HMATRIX2_FIXED_DEFMSTR_SIZE             4
++#define HMATRIX2_ARBT_OFFSET                    24
++#define HMATRIX2_ARBT_SIZE                      2
++
++/* Bitfields in SCFG1 */
++
++/* Bitfields in SCFG2 */
++
++/* Bitfields in SCFG3 */
++
++/* Bitfields in SCFG4 */
++
++/* Bitfields in SCFG5 */
++
++/* Bitfields in SCFG6 */
++
++/* Bitfields in SCFG7 */
++
++/* Bitfields in SCFG8 */
++
++/* Bitfields in SCFG9 */
++
++/* Bitfields in SCFG10 */
++
++/* Bitfields in SCFG11 */
++
++/* Bitfields in SCFG12 */
++
++/* Bitfields in SCFG13 */
++
++/* Bitfields in SCFG14 */
++
++/* Bitfields in SCFG15 */
++
++/* Bitfields in PRAS */
++#define HMATRIX2_M0PR_OFFSET                    0
++#define HMATRIX2_M0PR_SIZE                      4
++#define HMATRIX2_M1PR_OFFSET                    4
++#define HMATRIX2_M1PR_SIZE                      4
++#define HMATRIX2_M2PR_OFFSET                    8
++#define HMATRIX2_M2PR_SIZE                      4
++#define HMATRIX2_M3PR_OFFSET                    12
++#define HMATRIX2_M3PR_SIZE                      4
++#define HMATRIX2_M4PR_OFFSET                    16
++#define HMATRIX2_M4PR_SIZE                      4
++#define HMATRIX2_M5PR_OFFSET                    20
++#define HMATRIX2_M5PR_SIZE                      4
++#define HMATRIX2_M6PR_OFFSET                    24
++#define HMATRIX2_M6PR_SIZE                      4
++#define HMATRIX2_M7PR_OFFSET                    28
++#define HMATRIX2_M7PR_SIZE                      4
++
++/* Bitfields in PRBS */
++#define HMATRIX2_M8PR_OFFSET                    0
++#define HMATRIX2_M8PR_SIZE                      4
++#define HMATRIX2_M9PR_OFFSET                    4
++#define HMATRIX2_M9PR_SIZE                      4
++#define HMATRIX2_M10PR_OFFSET                   8
++#define HMATRIX2_M10PR_SIZE                     4
++#define HMATRIX2_M11PR_OFFSET                   12
++#define HMATRIX2_M11PR_SIZE                     4
++#define HMATRIX2_M12PR_OFFSET                   16
++#define HMATRIX2_M12PR_SIZE                     4
++#define HMATRIX2_M13PR_OFFSET                   20
++#define HMATRIX2_M13PR_SIZE                     4
++#define HMATRIX2_M14PR_OFFSET                   24
++#define HMATRIX2_M14PR_SIZE                     4
++#define HMATRIX2_M15PR_OFFSET                   28
++#define HMATRIX2_M15PR_SIZE                     4
++
++/* Bitfields in PRAS1 */
++
++/* Bitfields in PRBS1 */
++
++/* Bitfields in PRAS2 */
++
++/* Bitfields in PRBS2 */
++
++/* Bitfields in PRAS3 */
++
++/* Bitfields in PRBS3 */
++
++/* Bitfields in PRAS4 */
++
++/* Bitfields in PRBS4 */
++
++/* Bitfields in PRAS5 */
++
++/* Bitfields in PRBS5 */
++
++/* Bitfields in PRAS6 */
++
++/* Bitfields in PRBS6 */
++
++/* Bitfields in PRAS7 */
++
++/* Bitfields in PRBS7 */
++
++/* Bitfields in PRAS8 */
++
++/* Bitfields in PRBS8 */
++
++/* Bitfields in PRAS9 */
++
++/* Bitfields in PRBS9 */
++
++/* Bitfields in PRAS10 */
++
++/* Bitfields in PRBS10 */
++
++/* Bitfields in PRAS11 */
++
++/* Bitfields in PRBS11 */
++
++/* Bitfields in PRAS12 */
++
++/* Bitfields in PRBS12 */
++
++/* Bitfields in PRAS13 */
++
++/* Bitfields in PRBS13 */
++
++/* Bitfields in PRAS14 */
++
++/* Bitfields in PRBS14 */
++
++/* Bitfields in PRAS15 */
++
++/* Bitfields in PRBS15 */
++
++/* Bitfields in MRCR */
++#define HMATRIX2_RBC0_OFFSET                    0
++#define HMATRIX2_RBC0_SIZE                      1
++#define HMATRIX2_RBC1_OFFSET                    1
++#define HMATRIX2_RBC1_SIZE                      1
++#define HMATRIX2_RBC2_OFFSET                    2
++#define HMATRIX2_RBC2_SIZE                      1
++#define HMATRIX2_RBC3_OFFSET                    3
++#define HMATRIX2_RBC3_SIZE                      1
++#define HMATRIX2_RBC4_OFFSET                    4
++#define HMATRIX2_RBC4_SIZE                      1
++#define HMATRIX2_RBC5_OFFSET                    5
++#define HMATRIX2_RBC5_SIZE                      1
++#define HMATRIX2_RBC6_OFFSET                    6
++#define HMATRIX2_RBC6_SIZE                      1
++#define HMATRIX2_RBC7_OFFSET                    7
++#define HMATRIX2_RBC7_SIZE                      1
++#define HMATRIX2_RBC8_OFFSET                    8
++#define HMATRIX2_RBC8_SIZE                      1
++#define HMATRIX2_RBC9_OFFSET                    9
++#define HMATRIX2_RBC9_SIZE                      1
++#define HMATRIX2_RBC10_OFFSET                   10
++#define HMATRIX2_RBC10_SIZE                     1
++#define HMATRIX2_RBC11_OFFSET                   11
++#define HMATRIX2_RBC11_SIZE                     1
++#define HMATRIX2_RBC12_OFFSET                   12
++#define HMATRIX2_RBC12_SIZE                     1
++#define HMATRIX2_RBC13_OFFSET                   13
++#define HMATRIX2_RBC13_SIZE                     1
++#define HMATRIX2_RBC14_OFFSET                   14
++#define HMATRIX2_RBC14_SIZE                     1
++#define HMATRIX2_RBC15_OFFSET                   15
++#define HMATRIX2_RBC15_SIZE                     1
++
++/* Bitfields in SFR0 */
++#define HMATRIX2_SFR_OFFSET                     0
++#define HMATRIX2_SFR_SIZE                       32
++
++/* Bitfields in SFR1 */
++
++/* Bitfields in SFR2 */
++
++/* Bitfields in SFR3 */
++
++/* Bitfields in SFR4 */
++#define HMATRIX2_CS1A_OFFSET                    1
++#define HMATRIX2_CS1A_SIZE                      1
++#define HMATRIX2_CS3A_OFFSET                    3
++#define HMATRIX2_CS3A_SIZE                      1
++#define HMATRIX2_CS4A_OFFSET                    4
++#define HMATRIX2_CS4A_SIZE                      1
++#define HMATRIX2_CS5A_OFFSET                    5
++#define HMATRIX2_CS5A_SIZE                      1
++#define HMATRIX2_DBPUC_OFFSET                   8
++#define HMATRIX2_DBPUC_SIZE                     1
++
++/* Bitfields in SFR5 */
++
++/* Bitfields in SFR6 */
++
++/* Bitfields in SFR7 */
++
++/* Bitfields in SFR8 */
++
++/* Bitfields in SFR9 */
++
++/* Bitfields in SFR10 */
++
++/* Bitfields in SFR11 */
++
++/* Bitfields in SFR12 */
++
++/* Bitfields in SFR13 */
++
++/* Bitfields in SFR14 */
++
++/* Bitfields in SFR15 */
++
++/* Bitfields in VERSION */
++#define HMATRIX2_VERSION_OFFSET                 0
++#define HMATRIX2_VERSION_SIZE                   12
++#define HMATRIX2_MFN_OFFSET                     16
++#define HMATRIX2_MFN_SIZE                       3
++
++/* Constants for ULBT */
++#define HMATRIX2_ULBT_INFINITE                  0
++#define HMATRIX2_ULBT_SINGLE                    1
++#define HMATRIX2_ULBT_FOUR_BEAT                 2
++#define HMATRIX2_ULBT_SIXTEEN_BEAT              4
++
++/* Constants for DEFMSTR_TYPE */
++#define HMATRIX2_DEFMSTR_TYPE_NO_DEFAULT        0
++#define HMATRIX2_DEFMSTR_TYPE_LAST_DEFAULT      1
++#define HMATRIX2_DEFMSTR_TYPE_FIXED_DEFAULT     2
++
++/* Constants for ARBT */
++#define HMATRIX2_ARBT_ROUND_ROBIN               0
++#define HMATRIX2_ARBT_FIXED_PRIORITY            1
++
++/* Bit manipulation macros */
++#define HMATRIX2_BIT(name)                      (1 << HMATRIX2_##name##_OFFSET)
++#define HMATRIX2_BF(name,value)                 (((value) & ((1 << HMATRIX2_##name##_SIZE) - 1)) << HMATRIX2_##name##_OFFSET)
++#define HMATRIX2_BFEXT(name,value)              (((value) >> HMATRIX2_##name##_OFFSET) & ((1 << HMATRIX2_##name##_SIZE) - 1))
++#define HMATRIX2_BFINS(name,value,old)          (((old) & ~(((1 << HMATRIX2_##name##_SIZE) - 1) << HMATRIX2_##name##_OFFSET)) | HMATRIX2_BF(name,value))
++
++/* Register access macros */
++#define hmatrix2_readl(base,reg)                      \
++      __raw_readl(base + HMATRIX2_##reg)
++#define hmatrix2_writel(base,reg,value)                       \
++      __raw_writel((value), base + HMATRIX2_##reg)
++
++#endif /* __ASM_AVR32_HMATRIX2_H__ */
+Index: linux-2.6.18/arch/avr32/mach-at32ap/at32ap7000.c
+===================================================================
+--- linux-2.6.18.orig/arch/avr32/mach-at32ap/at32ap7000.c      2006-11-03 14:57:26.000000000 +0100
++++ linux-2.6.18/arch/avr32/mach-at32ap/at32ap7000.c   2006-11-03 15:25:01.000000000 +0100
+@@ -466,6 +466,15 @@
+       .users          = 1,
+ };
++static struct clk hmatrix2_clk = {
++      .name           = "hmatrix2",
++      .parent         = &pbb_clk,
++      .mode           = pbb_clk_mode,
++      .get_rate       = pbb_clk_get_rate,
++      .users          = 1,
++      .index          = 2,
++};
++
+ static struct resource dmac0_resource[] = {
+       {
+               .start  = 0xff200000,
+@@ -1096,6 +1096,7 @@
+       &pdc_pclk,
+       &dmac0_hclk,
+       &pico_clk,
++      &hmatrix2_clk,
+       &pio0_mck,
+       &pio1_mck,
+       &pio2_mck,
diff --git a/packages/linux/linux-2.6.18/add-ide-header.patch b/packages/linux/linux-2.6.18/add-ide-header.patch
new file mode 100644 (file)
index 0000000..76bd35b
--- /dev/null
@@ -0,0 +1,41 @@
+Index: linux-2.6.18/include/asm-avr32/ide.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18/include/asm-avr32/ide.h       2006-10-24 15:12:02.000000000 +0200
+@@ -0,0 +1,36 @@
++/*
++ *  linux/include/asm-arm/ide.h
++ *
++ *  Copyright (C) 1994-1996  Linus Torvalds & authors
++ */
++
++/*
++ *  This file contains the ARM architecture specific IDE code.
++ */
++
++#ifndef __ASMAVR32_IDE_H
++#define __ASMAVR32_IDE_H
++
++#ifdef __KERNEL__
++
++#ifndef MAX_HWIFS
++#define MAX_HWIFS     4
++#endif
++
++#if !defined(CONFIG_ARCH_L7200)
++# define IDE_ARCH_OBSOLETE_INIT
++# ifdef CONFIG_ARCH_CLPS7500
++#  define ide_default_io_ctl(base)    ((base) + 0x206) /* obsolete */
++# else
++#  define ide_default_io_ctl(base)    (0)
++# endif
++#endif /* !ARCH_L7200 */
++
++#define __ide_mm_insw(port,addr,len)  readsw(port,addr,len)
++#define __ide_mm_insl(port,addr,len)  readsl(port,addr,len)
++#define __ide_mm_outsw(port,addr,len) writesw(port,addr,len)
++#define __ide_mm_outsl(port,addr,len) writesl(port,addr,len)
++
++#endif /* __KERNEL__ */
++
++#endif /* __ASMAVR32_IDE_H */
diff --git a/packages/linux/linux-2.6.18/add-intc_pending_irq-to-intc.patch b/packages/linux/linux-2.6.18/add-intc_pending_irq-to-intc.patch
new file mode 100644 (file)
index 0000000..6d99de8
--- /dev/null
@@ -0,0 +1,10 @@
+--- linux-2.6.18.orig/arch/avr32/mach-at32ap/intc.c    2006-11-06 14:36:50.000000000 +0100
++++ linux-2.6.18/arch/avr32/mach-at32ap/intc.c 2006-11-06 15:09:39.000000000 +0100
+@@ -131,3 +131,7 @@
+       panic("Interrupt controller initialization failed!\n");
+ }
++unsigned long intc_get_pending(int group)
++{
++      return intc_readl(&intc0, INTREQ0 + 4 * group);
++}
diff --git a/packages/linux/linux-2.6.18/add-mach-specific-kconfig.patch b/packages/linux/linux-2.6.18/add-mach-specific-kconfig.patch
new file mode 100644 (file)
index 0000000..6f6e8f4
--- /dev/null
@@ -0,0 +1,30 @@
+---
+ arch/avr32/Kconfig             |    2 ++
+ arch/avr32/mach-at32ap/Kconfig |    7 +++++++
+ 2 files changed, 9 insertions(+)
+
+Index: linux-2.6.18-avr32/arch/avr32/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/Kconfig 2006-10-24 13:30:29.000000000 +0200
++++ linux-2.6.18-avr32/arch/avr32/Kconfig      2006-10-24 13:32:07.000000000 +0200
+@@ -107,6 +107,8 @@ config     LOADER_U_BOOT
+       bool "U-Boot (or similar) bootloader"
+ endchoice
++source "arch/avr32/mach-at32ap/Kconfig"
++
+ config LOAD_ADDRESS
+       hex
+       default 0x10000000 if LOADER_U_BOOT=y && CPU_AT32AP7000=y
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/Kconfig
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/Kconfig  2006-10-24 13:46:51.000000000 +0200
+@@ -0,0 +1,7 @@
++if PLATFORM_AT32AP
++
++menu "Atmel AVR32 AP options"
++
++endmenu
++
++endif
diff --git a/packages/linux/linux-2.6.18/at32-dac-oss-driver-clk-fix.patch b/packages/linux/linux-2.6.18/at32-dac-oss-driver-clk-fix.patch
new file mode 100644 (file)
index 0000000..927cdc5
--- /dev/null
@@ -0,0 +1,175 @@
+---
+ sound/oss/at32dac.c |   72 +++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 43 insertions(+), 29 deletions(-)
+
+Index: linux-2.6.18-avr32/sound/oss/at32dac.c
+===================================================================
+--- linux-2.6.18-avr32.orig/sound/oss/at32dac.c        2006-11-01 14:30:47.000000000 +0100
++++ linux-2.6.18-avr32/sound/oss/at32dac.c     2006-11-01 14:32:05.000000000 +0100
+@@ -71,6 +71,7 @@ struct at32_dac {
+       struct dma_request_cyclic req;
+       struct clk *mck;
++      struct clk *sample_clk;
+       struct platform_device *pdev;
+       int busy;
+       int playing;
+@@ -116,24 +117,6 @@ static void at32dac_update_dma_tail(stru
+       }
+ }
+-static int at32dac_start_genclock(struct at32_dac *dac)
+-{
+-      unsigned int div;
+-
+-      div = ((clk_get_rate(boot_cpu_data.clk) + 256 * dac->dsp_settings.sample_rate)
+-             / (512 * dac->dsp_settings.sample_rate) - 1);
+-      pr_debug("Real sample rate: %llu (div=%u)\n",
+-               boot_cpu_data.cpu_hz / (512 * (div + 1)), div);
+-      writel((div << 8) | 0x16, (void __iomem *)(0xfff00060 + 4 * 6));
+-
+-      return 0;
+-}
+-
+-static void at32dac_stop_genclock(struct at32_dac *dac)
+-{
+-      writel(0, (void __iomem *)(0xfff00060 + 4 * 6));
+-}
+-
+ static int at32dac_start(struct at32_dac *dac)
+ {
+       int ret;
+@@ -143,13 +126,11 @@ static int at32dac_start(struct at32_dac
+       memset(dac->dma.buf, 0, DMA_BUFFER_SIZE);
+-      ret = at32dac_start_genclock(dac);
+-      if (ret)
+-              return ret;
++      clk_enable(dac->sample_clk);
+       ret = dma_prepare_request_cyclic(dac->req.req.dmac, &dac->req);
+       if (ret)
+-              goto out_stop_genclock;
++              goto out_stop_clock;
+       pr_debug("Starting DMA...\n");
+       ret = dma_start_request(dac->req.req.dmac, dac->req.req.channel);
+@@ -164,8 +145,8 @@ static int at32dac_start(struct at32_dac
+ out_stop_request:
+       dma_stop_request(dac->req.req.dmac,
+                        dac->req.req.channel);
+-out_stop_genclock:
+-      at32dac_stop_genclock(dac);
++out_stop_clock:
++      clk_disable(dac->sample_clk);
+       return ret;
+ }
+@@ -176,7 +157,7 @@ static int at32dac_stop(struct at32_dac 
+               dac_writel(dac, DATA, 0);
+               dac_writel(dac, CTRL, 0);
+               dac->playing = 0;
+-              at32dac_stop_genclock(dac);
++              clk_disable(dac->sample_clk);
+       }
+       return 0;
+@@ -360,6 +341,26 @@ static int at32dac_set_format(struct at3
+       return 0;
+ }
++static int at32dac_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 at32dac_dsp_write(struct file *file,
+                                const char __user *buffer,
+                                size_t count, loff_t *ppos)
+@@ -449,7 +450,9 @@ static int at32dac_dsp_ioctl(struct inod
+                       return -EFAULT;
+               if (val >= 0) {
+                       at32dac_stop(dac);
+-                      dac->dsp_settings.sample_rate = val;
++                      ret = at32dac_set_sample_rate(dac, val);
++                      if (ret)
++                              return ret;
+               }
+               return put_user(dac->dsp_settings.sample_rate, up);
+@@ -534,10 +537,11 @@ static int at32dac_dsp_open(struct inode
+       dac->dma.head = dac->dma.tail = 0;
+       /* FIXME: What are the correct defaults?  */
+-      dac->dsp_settings.format = AFMT_S16_BE;
+       dac->dsp_settings.channels = 2;
+-      dac->dsp_settings.sample_rate = 8000;
+-      dac->dsp_settings.input_order = 2;
++      at32dac_set_format(dac, AFMT_S16_BE);
++      ret = at32dac_set_sample_rate(dac, 8000);
++      if (ret)
++              goto out;
+       file->private_data = dac;
+       dac->busy = 1;
+@@ -578,6 +582,7 @@ static int __devinit at32dac_probe(struc
+       struct at32_dac *dac;
+       struct resource *regs;
+       struct clk *mck;
++      struct clk *sample_clk;
+       int irq;
+       int ret;
+@@ -594,6 +599,11 @@ static int __devinit at32dac_probe(struc
+       mck = clk_get(&pdev->dev, "mck");
+       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;
+@@ -606,6 +616,7 @@ static int __devinit at32dac_probe(struc
+       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)
+@@ -658,6 +669,8 @@ out_free_dac:
+       kfree(dac);
+ out_disable_clk:
+       clk_disable(mck);
++      clk_put(sample_clk);
++out_put_mck:
+       clk_put(mck);
+       return ret;
+ }
+@@ -673,6 +686,7 @@ static int __devexit at32dac_remove(stru
+               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);
diff --git a/packages/linux/linux-2.6.18/at32-dac-oss-driver.patch b/packages/linux/linux-2.6.18/at32-dac-oss-driver.patch
new file mode 100644 (file)
index 0000000..92a17f9
--- /dev/null
@@ -0,0 +1,819 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Mon Apr 3 17:38:29 2006 +0200
+Subject: [PATCH] OSS driver for the AT32 on-chip digital DAC
+
+---
+
+ sound/oss/Kconfig   |    4 
+ sound/oss/Makefile  |    1 
+ sound/oss/at32dac.c |  707 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ sound/oss/at32dac.h |   65 ++++
+ 4 files changed, 777 insertions(+)
+
+Index: linux-2.6.18-avr32/sound/oss/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/sound/oss/Kconfig  2006-11-02 15:54:18.000000000 +0100
++++ linux-2.6.18-avr32/sound/oss/Kconfig       2006-11-02 15:56:20.000000000 +0100
+@@ -869,3 +869,7 @@ config SOUND_SH_DAC_AUDIO_CHANNEL
+       int "DAC channel"
+       default "1"
+       depends on SOUND_SH_DAC_AUDIO
++
++config SOUND_AT32_DAC
++      tristate "Atmel AT32 On-chip DAC support"
++      depends on SOUND_PRIME && AVR32
+Index: linux-2.6.18-avr32/sound/oss/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/sound/oss/Makefile 2006-11-02 15:54:18.000000000 +0100
++++ linux-2.6.18-avr32/sound/oss/Makefile      2006-11-02 15:56:20.000000000 +0100
+@@ -10,6 +10,7 @@ obj-$(CONFIG_SOUND_CS4232)   += cs4232.o a
+ # Please leave it as is, cause the link order is significant !
++obj-$(CONFIG_SOUND_AT32_DAC)  += at32dac.o
+ obj-$(CONFIG_SOUND_SH_DAC_AUDIO)      += sh_dac_audio.o
+ obj-$(CONFIG_SOUND_HAL2)      += hal2.o
+ obj-$(CONFIG_SOUND_AEDSP16)   += aedsp16.o
+Index: linux-2.6.18-avr32/sound/oss/at32dac.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/sound/oss/at32dac.c     2006-11-02 15:56:20.000000000 +0100
+@@ -0,0 +1,707 @@
++/*
++ * 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 "at32dac.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.
++       */
++      int (*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 platform_device *pdev;
++      int busy;
++      int playing;
++      int dev_dsp;
++};
++static struct at32_dac *the_dac;
++
++static inline unsigned int at32dac_get_head(struct at32_dac *dac)
++{
++      return dac->dma.head & ((DMA_BUFFER_SIZE / 4) - 1);
++}
++
++static inline unsigned int at32dac_get_tail(struct at32_dac *dac)
++{
++      return dac->dma.tail & ((DMA_BUFFER_SIZE / 4) - 1);
++}
++
++static inline unsigned int at32dac_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 at32dac_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))
++                      printk(KERN_NOTICE "at32dac: underrun\n");
++              dac->dma.tail = new_tail;
++              pr_debug("update tail: 0x%x - 0x%x = %u\n",
++                       dma_addr, dac->req.buffer_start, dac->dma.tail);
++      }
++}
++
++static int at32dac_start_genclock(struct at32_dac *dac)
++{
++      unsigned int div;
++
++      div = ((clk_get_rate(boot_cpu_data.clk) + 256 * dac->dsp_settings.sample_rate)
++             / (512 * dac->dsp_settings.sample_rate) - 1);
++      pr_debug("Real sample rate: %llu (div=%u)\n",
++               boot_cpu_data.cpu_hz / (512 * (div + 1)), div);
++      writel((div << 8) | 0x16, (void __iomem *)(0xfff00060 + 4 * 6));
++
++      return 0;
++}
++
++static void at32dac_stop_genclock(struct at32_dac *dac)
++{
++      writel(0, (void __iomem *)(0xfff00060 + 4 * 6));
++}
++
++static int at32dac_start(struct at32_dac *dac)
++{
++      int ret;
++
++      if (dac->playing)
++              return 0;
++
++      memset(dac->dma.buf, 0, DMA_BUFFER_SIZE);
++
++      ret = at32dac_start_genclock(dac);
++      if (ret)
++              return ret;
++
++      ret = dma_prepare_request_cyclic(dac->req.req.dmac, &dac->req);
++      if (ret)
++              goto out_stop_genclock;
++
++      pr_debug("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_genclock:
++      at32dac_stop_genclock(dac);
++      return ret;
++}
++
++static int at32dac_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;
++              at32dac_stop_genclock(dac);
++      }
++
++      return 0;
++}
++
++static int at32dac_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 at32dac_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 at32dac_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 at32dac_dma_error(struct dma_request *req)
++{
++      printk(KERN_ERR "at32dac: DMA error\n");
++}
++
++static irqreturn_t at32dac_interrupt(int irq, void *dev_id,
++                                   struct pt_regs *regs)
++{
++      struct at32_dac *dac = dev_id;
++      u32 status;
++
++      status = dac_readl(dac, INT_STATUS);
++      if (status & DAC_BIT(UNDERRUN)) {
++              printk(KERN_ERR "at32dac: Underrun detected\n");
++              dac_writel(dac, INT_CLR, DAC_BIT(UNDERRUN));
++      } else {
++              printk(KERN_ERR "at32dac: 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 (!at32dac_dma_space(dac))
++                              break;
++
++                      if (unlikely(__get_user(sample, up++))) {
++                              if (ret == 0)
++                                      ret = -EFAULT;
++                              break;
++                      }
++                      dac->dma.buf[at32dac_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 (!at32dac_dma_space(dac))
++                              break;
++
++                      if (unlikely(__get_user(sample, up++))) {
++                              if (ret == 0)
++                                      ret = -EFAULT;
++                              break;
++                      }
++                      dac->dma.buf[at32dac_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 (!at32dac_dma_space(dac))
++                              break;
++
++                      if (unlikely(__get_user(sample, up++))) {
++                              if (ret == 0)
++                                      ret = -EFAULT;
++                              break;
++                      }
++                      /* Swap bytes in each halfword */
++                      dac->dma.buf[at32dac_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 (!at32dac_dma_space(dac))
++                              break;
++
++                      if (unlikely(__get_user(sample, up++))) {
++                              if (ret == 0)
++                                      ret = -EFAULT;
++                              break;
++                      }
++                      sample = swab16(sample);
++                      dac->dma.buf[at32dac_get_head(dac)]
++                              = (sample << 16) | sample;
++                      dac->dma.head++;
++              }
++      }
++
++      return ret;
++}
++
++static ssize_t at32dac_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 */
++      pr_debug("at32dac: Copying %zu bytes from user...\n", count);
++
++      return dac->trans(dac, buffer, count);
++}
++
++static int at32dac_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:
++              printk("at32dac: 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 ssize_t at32dac_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 = at32dac_dma_prepare(dac);
++              if (ret)
++                      goto out;
++      }
++
++      add_wait_queue(&dac->write_wait, &wait);
++      ret = 0;
++      while (count > 0) {
++              do {
++                      at32dac_update_dma_tail(dac);
++                      avail = at32dac_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 = at32dac_dma_translate_from_user(dac, buffer, count);
++              if (copied < 0) {
++                      if (!ret)
++                              ret = -EFAULT;
++                      goto out;
++              }
++
++              at32dac_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 at32dac_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) {
++                      at32dac_stop(dac);
++                      dac->dsp_settings.sample_rate = val;
++              }
++              return put_user(dac->dsp_settings.sample_rate, up);
++
++      case SNDCTL_DSP_STEREO:
++              if (get_user(val, up))
++                      return -EFAULT;
++              at32dac_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;
++
++                      at32dac_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 = at32dac_set_format(dac, val);
++                      if (ret)
++                              return ret;
++              }
++              return put_user(val, up);
++
++      case SNDCTL_DSP_GETOSPACE:
++              at32dac_update_dma_tail(dac);
++              abinfo.fragsize = ((1 << dac->dsp_settings.input_order)
++                                 * (DMA_PERIOD_SIZE / 4));
++              abinfo.bytes = (at32dac_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:
++              printk("at32dac: Unimplemented ioctl cmd: 0x%x\n", cmd);
++              return -EINVAL;
++      }
++}
++
++static int at32dac_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.format = AFMT_S16_BE;
++      dac->dsp_settings.channels = 2;
++      dac->dsp_settings.sample_rate = 8000;
++      dac->dsp_settings.input_order = 2;
++
++      file->private_data = dac;
++      dac->busy = 1;
++
++      ret = 0;
++
++out:
++      up(&dac->sem);
++      return ret;
++}
++
++static int at32dac_dsp_release(struct inode *inode, struct file *file)
++{
++      struct at32_dac *dac = file->private_data;
++
++      down(&dac->sem);
++
++      at32dac_stop(dac);
++      at32dac_dma_cleanup(dac);
++      dac->busy = 0;
++
++      up(&dac->sem);
++
++      return 0;
++}
++
++static struct file_operations at32dac_dsp_fops = {
++      .owner          = THIS_MODULE,
++      .llseek         = no_llseek,
++      .write          = at32dac_dsp_write,
++      .ioctl          = at32dac_dsp_ioctl,
++      .open           = at32dac_dsp_open,
++      .release        = at32dac_dsp_release,
++};
++
++static int __devinit at32dac_probe(struct platform_device *pdev)
++{
++      struct at32_dac *dac;
++      struct resource *regs;
++      struct clk *mck;
++      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, "mck");
++      if (IS_ERR(mck))
++              return PTR_ERR(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->regs = ioremap(regs->start, regs->end - regs->start + 1);
++      if (!dac->regs)
++              goto out_free_dac;
++
++      ret = request_irq(irq, at32dac_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 = at32dac_dma_block_complete;
++      dac->req.req.error = at32dac_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(&at32dac_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(mck);
++      return ret;
++}
++
++static int __devexit at32dac_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->mck);
++              kfree(dac);
++              platform_set_drvdata(pdev, NULL);
++              the_dac = NULL;
++      }
++
++      return 0;
++}
++
++static struct platform_driver at32dac_driver = {
++      .probe          = at32dac_probe,
++      .remove         = __devexit_p(at32dac_remove),
++      .driver         = {
++              .name   = "dac",
++      },
++};
++
++static int __init at32dac_init(void)
++{
++      return platform_driver_register(&at32dac_driver);
++}
++module_init(at32dac_init);
++
++static void __exit at32dac_exit(void)
++{
++      platform_driver_unregister(&at32dac_driver);
++}
++module_exit(at32dac_exit);
++
++MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
++MODULE_DESCRIPTION("DMA Sound Driver for the Atmel AT32 on-chip DAC");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.18-avr32/sound/oss/at32dac.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/sound/oss/at32dac.h     2006-11-02 15:57:01.000000000 +0100
+@@ -0,0 +1,65 @@
++/*
++ * 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 __ASM_AVR32_DAC_H__
++#define __ASM_AVR32_DAC_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 DATA */
++#define DAC_DATA_OFFSET                         0
++#define DAC_DATA_SIZE                           32
++
++/* 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 */
++
++/* Bitfields in INT_EN */
++
++/* Bitfields in INT_DIS */
++#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
++
++/* Bitfields in INT_CLR */
++#define DAC_UNDERRUN_OFFSET                     28
++#define DAC_UNDERRUN_SIZE                       1
++
++/* Bitfields in INT_STATUS */
++
++/* Bitfields in PDC_DATA */
++
++/* 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 /* __ASM_AVR32_DAC_H__ */
diff --git a/packages/linux/linux-2.6.18/at32ap7000-dmac-driver.patch b/packages/linux/linux-2.6.18/at32ap7000-dmac-driver.patch
new file mode 100644 (file)
index 0000000..dfe5f6a
--- /dev/null
@@ -0,0 +1,855 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Fri Dec 2 13:24:24 2005 +0100
+Subject: [PATCH] AVR32: DesignWare DMA Controller
+
+This patch adds a driver for the Synopsys DesignWare DMA Controller.
+
+---
+
+ arch/avr32/Kconfig           |    4 
+ arch/avr32/Makefile          |    1 
+ arch/avr32/drivers/Makefile  |    1 
+ arch/avr32/drivers/dw-dmac.c |  754 +++++++++++++++++++++++++++++++++++++++++++
+ arch/avr32/drivers/dw-dmac.h |   42 ++
+ 5 files changed, 802 insertions(+)
+
+Index: linux-2.6.18-avr32/arch/avr32/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/Makefile        2006-11-02 14:17:29.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/Makefile     2006-11-02 15:53:13.000000000 +0100
+@@ -30,6 +30,7 @@ core-$(CONFIG_BOARD_ATSTK1000)               += arch/
+ core-$(CONFIG_LOADER_U_BOOT)          += arch/avr32/boot/u-boot/
+ core-y                                        += arch/avr32/kernel/
+ core-y                                        += arch/avr32/mm/
++drivers-y                             += arch/avr32/drivers/
+ drivers-$(CONFIG_OPROFILE)            += arch/avr32/oprofile/
+ libs-y                                        += arch/avr32/lib/
+Index: linux-2.6.18-avr32/arch/avr32/drivers/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/drivers/Makefile     2006-11-02 14:17:29.000000000 +0100
+@@ -0,0 +1 @@
++obj-$(CONFIG_DW_DMAC)                 += dw-dmac.o
+Index: linux-2.6.18-avr32/arch/avr32/drivers/dw-dmac.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/drivers/dw-dmac.c    2006-11-02 15:55:35.000000000 +0100
+@@ -0,0 +1,754 @@
++/*
++ * 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 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;
++      int ret, i, nr_blocks, 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;
++      pr_debug("block_size = %lu, nr_sg = %u\n", block_size, req->nr_sg);
++      for (i = 0, nr_blocks = 0; i < req->nr_sg; i++) {
++              pr_debug("sg[i].length = %u\n", req->sg[i].length);
++              BUG_ON(req->sg[i].length % block_size);
++              nr_blocks += req->sg[i].length / block_size;
++      }
++
++      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);
++      } 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_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 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_stop_request(struct dma_controller *_dmac,
++                             unsigned int channel)
++{
++      struct dw_dma_controller *dmac = to_dw_dmac(_dmac);
++
++      BUG_ON(channel >= DMAC_NR_CHANNELS);
++
++      BUG_ON(dmac->channel[channel].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 pt_regs *regs)
++{
++      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,
++                        SA_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           = "dmac",
++      },
++};
++
++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");
+Index: linux-2.6.18-avr32/arch/avr32/drivers/dw-dmac.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/drivers/dw-dmac.h    2006-11-02 14:17:29.000000000 +0100
+@@ -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__ */
+Index: linux-2.6.18-avr32/arch/avr32/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/Kconfig 2006-11-02 14:17:29.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/Kconfig      2006-11-02 15:53:13.000000000 +0100
+@@ -157,6 +157,10 @@ config OWNERSHIP_TRACE
+         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"
diff --git a/packages/linux/linux-2.6.18/at32ap7000-platform_device-definitions.patch b/packages/linux/linux-2.6.18/at32ap7000-platform_device-definitions.patch
new file mode 100644 (file)
index 0000000..6f1e98a
--- /dev/null
@@ -0,0 +1,445 @@
+---
+ arch/avr32/mach-at32ap/at32ap7000.c   |  325 ++++++++++++++++++++++++++++++++--
+ include/asm-avr32/arch-at32ap/board.h |    6 
+ 2 files changed, 313 insertions(+), 18 deletions(-)
+
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap7000.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/at32ap7000.c        2006-11-29 16:31:03.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap7000.c     2006-11-29 16:44:49.000000000 +0100
+@@ -9,6 +9,8 @@
+ #include <linux/init.h>
+ #include <linux/platform_device.h>
++#include <linux/spi/spi.h>
++
+ #include <asm/io.h>
+ #include <asm/arch/at32ap7000.h>
+@@ -464,6 +466,17 @@ static struct clk pico_clk = {
+       .users          = 1,
+ };
++static struct resource dmac0_resource[] = {
++      {
++              .start  = 0xff200000,
++              .end    = 0xff20ffff,
++              .flags  = IORESOURCE_MEM,
++      },
++      IRQ(2),
++};
++DEFINE_DEV(dmac, 0);
++DEV_CLK(hclk, dmac0, hsb, 10);
++
+ /* --------------------------------------------------------------------
+  *  PIO
+  * -------------------------------------------------------------------- */
+@@ -504,6 +517,7 @@ void __init at32_add_system_devices(void
+       platform_device_register(&at32_intc0_device);
+       platform_device_register(&smc0_device);
+       platform_device_register(&pdc_device);
++      platform_device_register(&dmac0_device);
+       platform_device_register(&pio0_device);
+       platform_device_register(&pio1_device);
+@@ -644,6 +658,15 @@ DEFINE_DEV_DATA(macb, 0);
+ DEV_CLK(hclk, macb0, hsb, 8);
+ DEV_CLK(pclk, macb0, pbb, 6);
++static struct eth_platform_data macb1_data;
++static struct resource macb1_resource[] = {
++      PBMEM(0xfff01c00),
++      IRQ(26),
++};
++DEFINE_DEV_DATA(macb, 1);
++DEV_CLK(hclk, macb1, hsb, 9);
++DEV_CLK(pclk, macb1, pbb, 7);
++
+ struct platform_device *__init
+ at32_add_device_eth(unsigned int id, struct eth_platform_data *data)
+ {
+@@ -677,6 +700,33 @@ at32_add_device_eth(unsigned int id, str
+               }
+               break;
++      case 1:
++              pdev = &macb1_device;
++
++              select_peripheral(PD(13), PERIPH_B, 0); /* TXD0 */
++              select_peripheral(PD(14), PERIPH_B, 0); /* TXD1 */
++              select_peripheral(PD(11), PERIPH_B, 0); /* TXEN */
++              select_peripheral(PD(12), PERIPH_B, 0); /* TXCK */
++              select_peripheral(PD(10), PERIPH_B, 0); /* RXD0 */
++              select_peripheral(PD(6),  PERIPH_B, 0); /* RXD1 */
++              select_peripheral(PD(5),  PERIPH_B, 0); /* RXER */
++              select_peripheral(PD(4),  PERIPH_B, 0); /* RXDV */
++              select_peripheral(PD(3),  PERIPH_B, 0); /* MDC  */
++              select_peripheral(PD(2),  PERIPH_B, 0); /* MDIO */
++
++              if (!data->is_rmii) {
++                      select_peripheral(PC(19), PERIPH_B, 0); /* COL  */
++                      select_peripheral(PC(23), PERIPH_B, 0); /* CRS  */
++                      select_peripheral(PC(26), PERIPH_B, 0); /* TXER */
++                      select_peripheral(PC(27), PERIPH_B, 0); /* TXD2 */
++                      select_peripheral(PC(28), PERIPH_B, 0); /* TXD3 */
++                      select_peripheral(PC(29), PERIPH_B, 0); /* RXD2 */
++                      select_peripheral(PC(30), PERIPH_B, 0); /* RXD3 */
++                      select_peripheral(PC(24), PERIPH_B, 0); /* RXCK */
++                      select_peripheral(PD(15), PERIPH_B, 0); /* SPD  */
++              }
++              break;
++
+       default:
+               return NULL;
+       }
+@@ -688,14 +738,53 @@ at32_add_device_eth(unsigned int id, str
+ }
+ /* --------------------------------------------------------------------
++ * MMC
++ * -------------------------------------------------------------------- */
++static struct resource mmci0_resource[] = {
++      PBMEM(0xfff02400),
++      IRQ(28),
++};
++DEFINE_DEV(mmci, 0);
++DEV_CLK(mck, mmci0, pbb, 9);
++
++struct platform_device *__init at32_add_device_mmci(unsigned int id)
++{
++      struct platform_device *pdev;
++
++      switch (id) {
++      case 0:
++              pdev = &mmci0_device;
++              select_peripheral(PA(10), PERIPH_A, 0); /* CLK   */
++              select_peripheral(PA(11), PERIPH_A, 0); /* CMD   */
++              select_peripheral(PA(12), PERIPH_A, 0); /* DATA0 */
++              select_peripheral(PA(13), PERIPH_A, 0); /* DATA1 */
++              select_peripheral(PA(14), PERIPH_A, 0); /* DATA2 */
++              select_peripheral(PA(15), PERIPH_A, 0); /* DATA3 */
++              break;
++      default:
++              return NULL;
++      }
++
++      platform_device_register(pdev);
++      return pdev;
++}
++
++/* --------------------------------------------------------------------
+  *  SPI
+  * -------------------------------------------------------------------- */
+-static struct resource spi0_resource[] = {
++static struct resource atmel_spi0_resource[] = {
+       PBMEM(0xffe00000),
+       IRQ(3),
+ };
+-DEFINE_DEV(spi, 0);
+-DEV_CLK(mck, spi0, pba, 0);
++DEFINE_DEV(atmel_spi, 0);
++DEV_CLK(pclk, atmel_spi0, pba, 0);
++
++static struct resource atmel_spi1_resource[] = {
++      PBMEM(0xffe00400),
++      IRQ(4),
++};
++DEFINE_DEV(atmel_spi, 1);
++DEV_CLK(pclk, atmel_spi1, pba, 1);
+ struct platform_device *__init at32_add_device_spi(unsigned int id)
+ {
+@@ -703,13 +792,96 @@ struct platform_device *__init at32_add_
+       switch (id) {
+       case 0:
+-              pdev = &spi0_device;
++              pdev = &atmel_spi0_device;
+               select_peripheral(PA(0), PERIPH_A, 0);  /* MISO  */
+               select_peripheral(PA(1), PERIPH_A, 0);  /* MOSI  */
+               select_peripheral(PA(2), PERIPH_A, 0);  /* SCK   */
+-              select_peripheral(PA(3), PERIPH_A, 0);  /* NPCS0 */
+-              select_peripheral(PA(4), PERIPH_A, 0);  /* NPCS1 */
+-              select_peripheral(PA(5), PERIPH_A, 0);  /* NPCS2 */
++
++              /* NPCS[2:0] */
++              at32_select_gpio(GPIO_PIN_PA(3),
++                               AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
++              at32_select_gpio(GPIO_PIN_PA(4),
++                               AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
++              at32_select_gpio(GPIO_PIN_PA(5),
++                               AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
++              break;
++
++      case 1:
++              pdev = &atmel_spi1_device;
++              select_peripheral(PB(0), PERIPH_B, 0);  /* MISO  */
++              select_peripheral(PB(1), PERIPH_B, 0);  /* MOSI  */
++              select_peripheral(PB(5), PERIPH_B, 0);  /* SCK   */
++
++              /* NPCS[2:0] */
++              at32_select_gpio(GPIO_PIN_PA(2),
++                               AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
++              at32_select_gpio(GPIO_PIN_PA(3),
++                               AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
++              at32_select_gpio(GPIO_PIN_PA(4),
++                               AT32_GPIOF_OUTPUT | AT32_GPIOF_HIGH);
++
++      default:
++              return NULL;
++      }
++
++      platform_device_register(pdev);
++      return pdev;
++}
++
++/* --------------------------------------------------------------------
++ *  USB Device Controller
++ * -------------------------------------------------------------------- */
++static struct resource usb0_resource[] = {
++      {
++              .start          = 0xff300000,
++              .end            = 0xff3fffff,
++              .flags          = IORESOURCE_MEM,
++      },
++      PBMEM(0xfff03000),
++      IRQ(31),
++};
++DEFINE_DEV(usb, 0);
++DEV_CLK(pclk, usb0, pbb, 12);
++DEV_CLK(hclk, usb0, hsb, 6);
++
++struct platform_device *__init at32_add_device_usb(unsigned int id)
++{
++      struct platform_device *pdev;
++
++      switch (id) {
++      case 0:
++              pdev = &usb0_device;
++              /* USB pads are not multiplexed */
++              break;
++      default:
++              return NULL;
++      }
++
++      platform_device_register(pdev);
++      return pdev;
++}
++
++/* --------------------------------------------------------------------
++ *  TWI
++ * -------------------------------------------------------------------- */
++
++static struct resource atmel_twi0_resource[] = {
++      PBMEM(0xffe00800),
++      IRQ(5),
++};
++DEFINE_DEV(atmel_twi, 0);
++DEV_CLK(pclk,atmel_twi0,pba,2);
++
++struct platform_device *__init
++at32_add_device_twi(unsigned int id)
++{
++      struct platform_device *pdev;
++
++      switch (id) {
++      case 0:
++              pdev = &atmel_twi0_device;
++              select_peripheral(PA(6),  PERIPH_A, 0); /* SDA  */
++              select_peripheral(PA(7),  PERIPH_A, 0); /* SCL  */
+               break;
+       default:
+@@ -765,16 +937,16 @@ at32_add_device_lcdc(unsigned int id, st
+               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(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 */
+@@ -799,6 +971,111 @@ at32_add_device_lcdc(unsigned int id, st
+       return pdev;
+ }
++/* --------------------------------------------------------------------
++ *  Sound
++ * -------------------------------------------------------------------- */
++static struct resource ac97c0_resource[] = {
++      PBMEM(0xfff02800),
++      IRQ(29),
++};
++DEFINE_DEV(ac97c, 0);
++DEV_CLK(mck, ac97c0, pbb, 10);
++
++struct platform_device *__init
++at32_add_device_ac97c(unsigned int id)
++{
++      struct platform_device *pdev;
++
++      switch (id) {
++      case 0:
++              pdev = &ac97c0_device;
++              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 */
++              break;
++      default:
++              return NULL;
++      }
++
++      platform_device_register(pdev);
++      return pdev;
++}
++
++static struct spi_board_info at73c2130_data = {
++      .max_speed_hz   = 200000,
++      .controller_data = (void *)GPIO_PIN_PA(3),
++      .modalias       = "at73c213",
++      .bus_num        = 0,
++      .chip_select    = 0,
++};
++static struct resource at73c2130_resource[] = {
++      PBMEM(0xffe01c00),
++      IRQ(10),
++};
++DEFINE_DEV_DATA(at73c213, 0);
++DEV_CLK(mck, at73c2130, pba, 7);
++
++struct platform_device *__init
++at32_add_device_at73c213(unsigned int id)
++{
++      struct platform_device *pdev;
++
++      switch (id) {
++      case 0:
++              pdev = &at73c2130_device;
++              select_peripheral(PA(21), PERIPH_A, 0); /* RX_FSYNC     */
++              select_peripheral(PA(22), PERIPH_A, 0); /* RX_CLOCK     */
++              select_peripheral(PA(23), PERIPH_A, 0); /* TX_CLOCK     */
++              select_peripheral(PA(24), PERIPH_A, 0); /* TX_FSYNC     */
++              select_peripheral(PA(25), PERIPH_A, 0); /* TX_DATA      */
++              select_peripheral(PA(26), PERIPH_A, 0); /* RX_DATA      */
++              break;
++      default:
++              return NULL;
++      }
++
++      platform_device_register(pdev);
++      return pdev;
++}
++
++static struct resource dac0_resource[] = {
++      PBMEM(0xfff02000),
++      IRQ(27),
++};
++DEFINE_DEV(dac, 0);
++DEV_CLK(mck, dac0, pbb, 8);
++static struct clk dac0_sample_clk = {
++      .name           = "sample_clk",
++      .dev            = &dac0_device.dev,
++      .mode           = genclk_mode,
++      .get_rate       = genclk_get_rate,
++      .set_rate       = genclk_set_rate,
++      .set_parent     = genclk_set_parent,
++      .index          = 6,
++};
++
++struct platform_device *__init
++at32_add_device_dac(unsigned int id)
++{
++      struct platform_device *pdev;
++
++      switch (id) {
++      case 0:
++              pdev = &dac0_device;
++              select_peripheral(PB(20), PERIPH_A, 0); /* DATA1        */
++              select_peripheral(PB(21), PERIPH_A, 0); /* DATA0        */
++              select_peripheral(PB(22), PERIPH_A, 0); /* DATAN1       */
++              select_peripheral(PB(23), PERIPH_A, 0); /* DATAN0       */
++              break;
++      default:
++              return NULL;
++      }
++
++      platform_device_register(pdev);
++      return pdev;
++}
++
+ struct clk *at32_clock_list[] = {
+       &osc32k,
+       &osc0,
+@@ -817,6 +1094,7 @@ struct clk *at32_clock_list[] = {
+       &smc0_mck,
+       &pdc_hclk,
+       &pdc_pclk,
++      &dmac0_hclk,
+       &pico_clk,
+       &pio0_mck,
+       &pio1_mck,
+@@ -828,9 +1106,20 @@ struct clk *at32_clock_list[] = {
+       &usart3_usart,
+       &macb0_hclk,
+       &macb0_pclk,
+-      &spi0_mck,
++      &macb1_hclk,
++      &macb1_pclk,
++      &atmel_spi0_pclk,
++      &atmel_spi1_pclk,
++      &atmel_twi0_pclk,
++      &mmci0_mck,
++      &usb0_pclk,
++      &usb0_hclk,
+       &lcdc0_hclk,
+       &lcdc0_pixclk,
++      &ac97c0_mck,
++      &at73c2130_mck,
++      &dac0_mck,
++      &dac0_sample_clk,
+ };
+ unsigned int at32_nr_clocks = ARRAY_SIZE(at32_clock_list);
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/board.h
+===================================================================
+--- linux-2.6.18-avr32.orig/include/asm-avr32/arch-at32ap/board.h      2006-11-29 16:31:03.000000000 +0100
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/board.h   2006-11-29 16:31:42.000000000 +0100
+@@ -24,13 +24,19 @@ struct eth_platform_data {
+ struct platform_device *
+ at32_add_device_eth(unsigned int id, struct eth_platform_data *data);
++struct platform_device *at32_add_device_mmci(unsigned int id);
+ struct platform_device *at32_add_device_spi(unsigned int id);
++struct platform_device *at32_add_device_twi(unsigned int id);
+ struct lcdc_platform_data {
+       unsigned long fbmem_start;
+       unsigned long fbmem_size;
+ };
++struct platform_device *__init at32_add_device_usb(unsigned int id);
+ struct platform_device *
+ at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data);
++struct platform_device *__init at32_add_device_dac(unsigned int id);
++struct platform_device *__init at32_add_device_at73c213(unsigned int id);
++struct platform_device *__init at32_add_device_ac97c(unsigned int id);
+ #endif /* __ASM_ARCH_BOARD_H */
diff --git a/packages/linux/linux-2.6.18/at32stk1000/.mtn2git_empty b/packages/linux/linux-2.6.18/at32stk1000/.mtn2git_empty
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/packages/linux/linux-2.6.18/at32stk1000/defconfig b/packages/linux/linux-2.6.18/at32stk1000/defconfig
new file mode 100644 (file)
index 0000000..b4aced9
--- /dev/null
@@ -0,0 +1,990 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-at0
+# Thu Jan 11 15:37:42 2007
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL=y
+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_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=1
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+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=y
+
+#
+# Block layer
+#
+# CONFIG_BLK_DEV_IO_TRACE is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# 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"
+
+#
+# System Type and features
+#
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP7000=y
+CONFIG_BOARD_ATSTK1002=y
+CONFIG_BOARD_ATSTK1000=y
+# CONFIG_BOARD_ATNGW is not set
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+CONFIG_PIO_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_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_OWNERSHIP_TRACE is not set
+CONFIG_DW_DMAC=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_CMDLINE=""
+
+#
+# Bus options
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# 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_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY 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 is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# 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
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+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_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL 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
+# CONFIG_MTD_OBSOLETE_CHIPS 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 is not set
+# 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# 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_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# 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 is not set
+# CONFIG_PPP_MPPE is not set
+CONFIG_PPPOE=m
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# 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 is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING 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_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# 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_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_DS1337 is not set
+# CONFIG_SENSORS_DS1374 is not set
+CONFIG_SENSORS_EEPROM=m
+# 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=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
+#
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# 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
+CONFIG_FB_SIDSA=y
+CONFIG_FB_SIDSA_DEFAULT_BPP=24
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_DEVICE=y
+CONFIG_LCD_LTV350QV=y
+
+#
+# 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_AC97_BUS=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
+
+#
+# ALSA AVR32 devices
+#
+CONFIG_SND_ATMEL_AC97=m
+# CONFIG_SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS is not set
+# CONFIG_SND_ATMEL_AC97C_USE_PDC is not set
+CONFIG_SND_AT73C213=m
+# CONFIG_SND_AT73C213_USE_ALSA_MALLOC_CALLS is not set
+
+#
+# Open Sound System
+#
+CONFIG_SOUND_PRIME=m
+# CONFIG_OSS_OBSOLETE_DRIVER is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+CONFIG_SOUND_AT32_DAC=m
+
+#
+# USB support
+#
+# 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'
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=m
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_SELECTED=y
+# 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_HUSB2DEV=y
+CONFIG_USB_HUSB2DEV=m
+# 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
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_ATMELMCI=y
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# File systems
+#
+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_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+CONFIG_ROMFS_FS=y
+# 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=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_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+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_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# 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_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+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_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 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
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+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=m
+# 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
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB 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_RWSEMS 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_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_KPROBES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/packages/linux/linux-2.6.18/at73c213-alsa-driver.patch b/packages/linux/linux-2.6.18/at73c213-alsa-driver.patch
new file mode 100644 (file)
index 0000000..ceb12cc
--- /dev/null
@@ -0,0 +1,1485 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
+Date: Fri Apr 28 15:30:44 2006 +0200
+Subject: [PATCH] at73c213 ALSA driver
+
+This driver uses the SSC and SPI modules to communicate with an at73c213
+sound chip on the AT32STK1000.
+
+---
+
+ sound/avr32/Kconfig    |   20 
+ sound/avr32/Makefile   |    3 
+ sound/avr32/at73c213.c | 1296 +++++++++++++++++++++++++++++++++++++++++++++++++
+ sound/avr32/at73c213.h |  120 ++++
+ 4 files changed, 1439 insertions(+)
+ create mode 100644 sound/avr32/at73c213.c
+ create mode 100644 sound/avr32/at73c213.h
+
+859730d5cbe00b7935c4e30d179c5c5b096deb3c
+Index: linux-2.6.18-avr32/sound/avr32/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/sound/avr32/Kconfig        2006-11-02 15:56:20.000000000 +0100
++++ linux-2.6.18-avr32/sound/avr32/Kconfig     2006-11-02 15:56:20.000000000 +0100
+@@ -28,4 +28,24 @@ config SND_ATMEL_AC97C_USE_PDC
+         Say Y if PDC (Peripheral DMA Controller) is used for DMA transfers
+         to/from the Atmel AC97C instead of using the generic DMA framework.
++config SND_AT73C213
++      tristate "Atmel AT73C213 DAC driver"
++      depends on SND && SPI_ATMEL
++      select SND_PCM
++      help
++        Say Y here if you want to use the Atmel AT73C213 external
++        DAC on the ATSTK1000 development board.
++
++        To compile this driver as a module, choose M here: the
++        module will be called snd-at73c213.
++
++config SND_AT73C213_USE_ALSA_MALLOC_CALLS
++      bool "Use the built-in malloc calls in the alsa driver"
++      default n
++      depends on SND_AT73C213
++      help
++        Say Y if the built-in malloc calls in the alsa driver should be
++        used instead of the native dma_alloc_coherent and dma_free_coherent
++        function calls. Enabling this feature may brake the rmmod feature.
++
+ endmenu
+Index: linux-2.6.18-avr32/sound/avr32/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/sound/avr32/Makefile       2006-11-02 15:56:20.000000000 +0100
++++ linux-2.6.18-avr32/sound/avr32/Makefile    2006-11-02 15:56:20.000000000 +0100
+@@ -4,3 +4,6 @@
+ snd-atmel-ac97-objs           := ac97c.o
+ obj-$(CONFIG_SND_ATMEL_AC97)  += snd-atmel-ac97.o
++
++snd-at73c213-objs             := at73c213.o
++obj-$(CONFIG_SND_AT73C213)    += snd-at73c213.o
+Index: linux-2.6.18-avr32/sound/avr32/at73c213.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/sound/avr32/at73c213.c  2006-11-02 16:01:55.000000000 +0100
+@@ -0,0 +1,1296 @@
++/*
++ * Driver for the at73c213 16-bit stereo DAC on Atmel ATSTK1000
++ *
++ * 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.
++ */
++#undef DEBUG
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/device.h>
++#include <linux/dma-mapping.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/kmod.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include <sound/initval.h>
++#include <sound/driver.h>
++#include <sound/control.h>
++#include <sound/core.h>
++#include <sound/pcm.h>
++#ifndef SND_AT73C213_USE_ALSA_MALLOC_CALLS
++#include <sound/memalloc.h>
++#endif
++
++#include <linux/spi/spi.h>
++
++#include <asm/io.h>
++#include <asm/processor.h>
++
++#include "at73c213.h"
++
++/* module parameters */
++static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
++static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
++static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
++
++/* Register defines */
++#define PIOA_BASE     0xFFE02800
++#define SSC0_BASE     0xFFE01C00
++#define PM_BASE               0xFFF00000
++
++#define PM_CKSEL      0x04
++#define PM_APBAMASK   0x10
++#define PM_GCCTRL     0x60
++
++#define PIO_PER               0x00
++#define PIO_PDR               0x04
++#define PIO_PUER      0x64
++#define PIO_ASR               0x70
++#define PIO_BSR               0x74
++
++#define SSC_CMR               0x04
++#define SSC_CR                0x00
++#define SSC_TCMR      0x18
++#define SSC_TFMR      0x1C
++
++/* SSC register definitions */
++#define SSC_CR                0x00
++#define SSC_CMR               0x04
++#define SSC_TCMR      0x18
++#define SSC_TFMR      0x1C
++#define SSC_THR               0x24
++#define SSC_SR                0x40
++#define SSC_IER               0x44
++#define SSC_IDR               0x48
++#define SSC_IMR               0x4C
++
++/* SSC fields definitions */
++#define SSC_CR_TXEN   0x00000100
++#define SSC_CR_TXDIS  0x00000200
++#define SSC_CR_SWRST  0x00008000
++
++/* SSC interrupt definitions */
++#define SSC0_IRQ      10
++#define SSC_INT_ENDTX 0x00000004
++#define SSC_INT_TXBUFE        0x00000008
++
++/* PDC register definitions */
++#define PDC_RPR               0x100
++#define PDC_RCR               0x104
++#define PDC_TPR               0x108
++#define PDC_TCR               0x10c
++#define PDC_RNPR      0x110
++#define PDC_RNCR      0x114
++#define PDC_TNPR      0x118
++#define PDC_TNCR      0x11c
++#define PDC_PTCR      0x120
++#define PDC_PTSR      0x124
++
++/* PDC fields definitions */
++#define PDC_PTCR_RXTEN        0x0001
++#define PDC_PTCR_RXTDIS       0x0002
++#define PDC_PTCR_TXTEN        0x0100
++#define PDC_PTCR_TXTDIS 0x0200
++
++static int bitrate;
++static int gclk_div;
++static int ssc_div;
++static int spi = 0;
++static int ssc = 1;
++
++module_param(spi, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(spi, "Which SPI interface to use to communicate with the at73c213");
++module_param(ssc, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(ssc, "Which SSC interface to use to communicate with the at73c213");
++
++/* Initial AT73C213 register values */
++static unsigned char snd_at73c213_original_image[18] =
++{
++      0x00,   /* 00 - CTRL    */
++      0x05,   /* 01 - LLIG    */
++      0x05,   /* 02 - RLIG    */
++      0x08,   /* 03 - LPMG    */
++      0x08,   /* 04 - RPMG    */
++      0x00,   /* 05 - LLOG    */
++      0x00,   /* 06 - RLOG    */
++      0x22,   /* 07 - OLC     */
++      0x09,   /* 08 - MC      */
++      0x00,   /* 09 - CSFC    */
++      0x00,   /* 0A - MISC    */
++      0x00,   /* 0B -         */
++      0x00,   /* 0C - PRECH   */
++      0x05,   /* 0D - AUXG    */
++      0x00,   /* 0E -         */
++      0x00,   /* 0F -         */
++      0x00,   /* 10 - RST     */
++      0x00,   /* 11 - PA_CTRL */
++};
++
++/* chip-specific data */
++struct snd_at73c213 {
++      snd_card_t              *card;
++      snd_pcm_t               *pcm;
++      snd_pcm_substream_t     *substream;
++      int                     irq;
++      int                     period;
++      void __iomem            *regs;
++      struct clk              *ssc_clk;
++      struct spi_device       *spi;
++      u8                      spi_wbuffer[2];
++      u8                      spi_rbuffer[2];
++      /* image of the SPI registers in AT73C213 */
++      u8                      image[18];
++      spinlock_t              lock;
++      struct platform_device  *pdev;
++};
++
++#define get_chip(card) ((struct snd_at73c213 *)card->private_data)
++
++static int
++snd_at73c213_write_reg(struct snd_at73c213 *chip, u8 reg, u8 val)
++{
++      struct spi_message msg;
++      struct spi_transfer msg_xfer = {
++              .len            = 2,
++              .cs_change      = 0,
++      };
++
++      spi_message_init(&msg);
++
++      chip->spi_wbuffer[0] = reg;
++      chip->spi_wbuffer[1] = val;
++
++      msg_xfer.tx_buf = chip->spi_wbuffer;
++      msg_xfer.rx_buf = chip->spi_rbuffer;
++      spi_message_add_tail(&msg_xfer, &msg);
++
++      return spi_sync(chip->spi, &msg);
++}
++
++#define write_reg(_spi, reg, val)                             \
++      do {                                                    \
++              retval = snd_at73c213_write_reg(_spi, reg, val);        \
++              if (retval)                                     \
++                      goto out;                               \
++      } while (0)
++
++static snd_pcm_hardware_t snd_at73c213_playback_hw = {
++      .info           = SNDRV_PCM_INFO_INTERLEAVED |
++                        SNDRV_PCM_INFO_BLOCK_TRANSFER,
++      .formats        = SNDRV_PCM_FMTBIT_S16_BE,
++      .rates          = SNDRV_PCM_RATE_CONTINUOUS,
++      .rate_min       = 8000,  /* This will be overwritten with bitrate */
++      .rate_max       = 50000, /* This will be overwritten with bitrate */
++      .channels_min   = 2,
++      .channels_max   = 2,
++      .buffer_bytes_max = 64 * 1024 - 1,
++      .period_bytes_min = 512,
++      .period_bytes_max = 64 * 1024 - 1,
++      .periods_min    = 4,
++      .periods_max    = 1024,
++};
++
++/* calculate and set bitrate and divisions */
++static int snd_at73c213_set_bitrate_and_div(void)
++{
++      extern struct avr32_cpuinfo boot_cpu_data;
++      unsigned long pll0_hz, apba_hz;
++      unsigned long apba_realdiv, gclk_realdiv, ssc_realdiv, wanted_bitrate;
++      char cpusel, ahbsel, apbasel;
++      int regval;
++
++      regval = __raw_readl((void __iomem *)PM_BASE + PM_CKSEL);
++      wanted_bitrate = 48000;
++
++      cpusel = regval & 0x07;
++      ahbsel = (regval>>8) & 0x07;
++      apbasel = (regval>>16) & 0x07;
++
++      /* FIXME: Use the clk framework for this */
++      if ((regval&(1<<7)) != 0) {
++              pll0_hz = clk_get_rate(boot_cpu_data.clk)/(1<<(cpusel+1));
++      } else {
++              pll0_hz = clk_get_rate(boot_cpu_data.clk);
++      }
++
++      if ((regval&(1<<23)) != 0) {
++              apba_hz = pll0_hz/(1<<(apbasel+1));
++              apba_realdiv = (1<<(apbasel+1));
++      } else {
++              apba_hz = pll0_hz;
++              apba_realdiv = 1;
++      }
++
++calculate:
++      /* Adjust bitrate as close as possible to 48000 Hz */
++      gclk_realdiv = pll0_hz/(wanted_bitrate*256);
++      ssc_realdiv = 2 * apba_realdiv * gclk_realdiv;
++
++      if ((gclk_realdiv % 2) == 0)
++              goto setbitrates;
++
++      if(wanted_bitrate >= 22050 && wanted_bitrate <= 48000)
++              wanted_bitrate -= 50;
++      else if (wanted_bitrate < 22050)
++              wanted_bitrate = 48050;
++      else if (wanted_bitrate <= 50000)
++              wanted_bitrate += 50;
++      else {
++              printk(KERN_ERR "at73c213 could not set dividers for a valid bitrate\n");
++              return -EINVAL;
++      }
++
++      goto calculate;
++
++setbitrates:
++      bitrate = pll0_hz/(gclk_realdiv*256);
++      gclk_div = (gclk_realdiv/2)-1;
++      ssc_realdiv = 2*apba_realdiv*gclk_realdiv;
++      ssc_div = ssc_realdiv/(2*apba_realdiv);
++
++      printk(KERN_INFO "at73c213: bitrate is %d Hz\n", bitrate);
++
++      return 0;
++}
++
++/* open callback */
++static int snd_at73c213_pcm_open(snd_pcm_substream_t *substream)
++{
++      struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
++      snd_pcm_runtime_t *runtime = substream->runtime;
++
++      snd_at73c213_playback_hw.rate_min = bitrate;
++      snd_at73c213_playback_hw.rate_max = bitrate;
++      runtime->hw = snd_at73c213_playback_hw;
++      chip->substream = substream;
++
++      return 0;
++}
++
++/* close callback */
++static int snd_at73c213_pcm_close(snd_pcm_substream_t *substream)
++{
++      struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
++      chip->substream = NULL;
++      return 0;
++}
++
++/* hw_params callback */
++static int snd_at73c213_pcm_hw_params(snd_pcm_substream_t *substream,
++                               snd_pcm_hw_params_t *hw_params)
++{
++#ifdef SND_AT73C213_USE_ALSA_MALLOC_CALLS
++      return snd_pcm_lib_malloc_pages(substream,
++                                      params_buffer_bytes(hw_params));
++#else
++      int pg;
++      size_t size = params_buffer_bytes(hw_params);
++      struct snd_pcm_runtime *runtime;
++      struct snd_dma_buffer *dmab = NULL;
++
++      substream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV;
++      snd_assert(substream != NULL, return -EINVAL);
++      runtime = substream->runtime;
++      snd_assert(runtime != NULL, return -EINVAL);
++
++      /* check if buffer is already allocated */
++      if (runtime->dma_buffer_p) {
++              size_t size_previouse;
++              int pg_previouse;
++
++              /* new buffer is smaler than previouse allocated buffer */
++              if (runtime->dma_buffer_p->bytes >= size) {
++                      runtime->dma_bytes = size;
++                      return 0; /* don't change buffer size */
++              }
++
++              size_previouse = runtime->dma_buffer_p->bytes;
++              pg_previouse = get_order(size_previouse);
++
++              dma_free_coherent(runtime->dma_buffer_p->dev.dev,
++                              PAGE_SIZE << pg_previouse,
++                              runtime->dma_buffer_p->area,
++                              runtime->dma_buffer_p->addr);
++
++              kfree(runtime->dma_buffer_p);
++      }
++
++      dmab = kzalloc(sizeof(*dmab), GFP_KERNEL);
++      if (!dmab)
++              return -ENOMEM;
++
++      dmab->dev = substream->dma_buffer.dev;
++      dmab->bytes = 0;
++
++      pg = get_order(size);
++
++      dmab->area = dma_alloc_coherent(
++                      substream->dma_buffer.dev.dev,
++                      PAGE_SIZE << pg,
++                      (dma_addr_t *)&dmab->addr,
++                      GFP_KERNEL);
++
++      if (!dmab->area) {
++              kfree(dmab);
++              return -ENOMEM;
++      }
++
++      dmab->bytes = size;
++      snd_pcm_set_runtime_buffer(substream, dmab);
++      runtime->dma_bytes = size;
++      return 1;
++#endif
++}
++
++/* hw_free callback */
++static int snd_at73c213_pcm_hw_free(snd_pcm_substream_t *substream)
++{
++#ifdef SND_AT73C213_USE_ALSA_MALLOC_CALLS
++      return snd_pcm_lib_free_pages(substream);
++#else
++      int pg;
++      struct snd_pcm_runtime *runtime;
++      struct snd_dma_buffer *dmab = NULL;
++
++      snd_assert(substream != NULL, return -EINVAL);
++      runtime = substream->runtime;
++      snd_assert(runtime != NULL, return -EINVAL);
++      dmab = runtime->dma_buffer_p;
++
++      if (!dmab)
++              return 0;
++
++      if (!dmab->area)
++              return 0;
++
++      pg = get_order(dmab->bytes);
++      dma_free_coherent(dmab->dev.dev, PAGE_SIZE << pg, dmab->area, dmab->addr);
++      kfree(runtime->dma_buffer_p);
++      snd_pcm_set_runtime_buffer(substream, NULL);
++      return 0;
++#endif
++}
++
++/* prepare callback */
++static int snd_at73c213_pcm_prepare(snd_pcm_substream_t *substream)
++{
++      struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
++      struct platform_device *pdev = chip->pdev;
++      snd_pcm_runtime_t *runtime = substream->runtime;
++      int block_size;
++
++      block_size = frames_to_bytes(runtime, runtime->period_size);
++
++      chip->period = 0;
++
++      /* Make sure that our data are actually readable by the SSC */
++      dma_sync_single_for_device(&pdev->dev, runtime->dma_addr,
++                      block_size, DMA_TO_DEVICE);
++      dma_sync_single_for_device(&pdev->dev, runtime->dma_addr + block_size,
++                      block_size, DMA_TO_DEVICE);
++
++      __raw_writel(runtime->dma_addr, chip->regs + PDC_TPR);
++      __raw_writel(runtime->period_size * 2, chip->regs + PDC_TCR);
++      __raw_writel(runtime->dma_addr + block_size, chip->regs + PDC_TNPR);
++      __raw_writel(runtime->period_size * 2, chip->regs + PDC_TNCR);
++
++      return 0;
++}
++
++/* trigger callback */
++static int snd_at73c213_pcm_trigger(snd_pcm_substream_t *substream,
++                                 int cmd)
++{
++      struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
++      int retval = 0;
++      int flags = 0;
++
++      spin_lock_irqsave(&chip->lock, flags);
++
++      switch (cmd) {
++      case SNDRV_PCM_TRIGGER_START:
++              __raw_writel(SSC_INT_ENDTX, chip->regs + SSC_IER);
++              __raw_writel(PDC_PTCR_TXTEN, chip->regs + PDC_PTCR);
++              break;
++      case SNDRV_PCM_TRIGGER_STOP:
++              __raw_writel(PDC_PTCR_TXTDIS, chip->regs + PDC_PTCR);
++              __raw_writel(SSC_INT_ENDTX, chip->regs + SSC_IDR);
++              break;
++      default:
++              printk(KERN_WARNING "at73c213: spuriouse command %x\n", cmd);
++              retval = -EINVAL;
++              break;
++      }
++
++      spin_unlock_irqrestore(&chip->lock, flags);
++
++      return retval;
++}
++
++/* pointer callback */
++static snd_pcm_uframes_t snd_at73c213_pcm_pointer(snd_pcm_substream_t *substream)
++{
++      struct snd_at73c213 *chip = snd_pcm_substream_chip(substream);
++      snd_pcm_runtime_t *runtime = substream->runtime;
++      snd_pcm_uframes_t pos;
++      unsigned long bytes;
++
++      bytes = __raw_readl(chip->regs + PDC_TPR) - runtime->dma_addr;
++
++      pos = bytes_to_frames(runtime, bytes);
++      if (pos >= runtime->buffer_size)
++              pos -= runtime->buffer_size;
++
++      return pos;
++}
++
++/* operators */
++static snd_pcm_ops_t at73c213_playback_ops = {
++      .open           = snd_at73c213_pcm_open,
++      .close          = snd_at73c213_pcm_close,
++      .ioctl          = snd_pcm_lib_ioctl,
++      .hw_params      = snd_at73c213_pcm_hw_params,
++      .hw_free        = snd_at73c213_pcm_hw_free,
++      .prepare        = snd_at73c213_pcm_prepare,
++      .trigger        = snd_at73c213_pcm_trigger,
++      .pointer        = snd_at73c213_pcm_pointer,
++};
++
++/* free a pcm device */
++static void snd_at73c213_pcm_free(snd_pcm_t *pcm)
++{
++      struct snd_at73c213 *chip = snd_pcm_chip(pcm);
++      if (chip->pcm != 0 ) {
++#ifdef SND_AT73C213_USE_ALSA_MALLOC_CALLS
++              snd_pcm_lib_preallocate_free_for_all(chip->pcm);
++#endif
++              chip->pcm = NULL;
++      }
++}
++
++/* create a new pcm device */
++static int __devinit snd_at73c213_new_pcm(struct snd_at73c213 *chip, int device)
++{
++      snd_pcm_t *pcm;
++      int retval;
++
++      retval = snd_pcm_new(chip->card, chip->card->shortname, device, 1, 0, &pcm);
++      if (retval < 0)
++              return retval;
++
++      pcm->private_data = chip;
++      pcm->private_free = snd_at73c213_pcm_free;
++      pcm->info_flags = SNDRV_PCM_INFO_BLOCK_TRANSFER;
++      strcpy(pcm->name, "at73c213");
++      chip->pcm = pcm;
++
++      snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &at73c213_playback_ops);
++
++#ifdef SND_AT73C213_USE_ALSA_MALLOC_CALLS
++      snd_pcm_lib_preallocate_pages_for_all(chip->pcm, SNDRV_DMA_TYPE_DEV,
++                      &chip->pdev->dev, 64 * 1024, 64 * 1024);
++#endif
++
++      return 0;
++}
++
++static irqreturn_t snd_at73c213_interrupt(int irq, void *dev_id,
++                                       struct pt_regs *regs)
++{
++      struct snd_at73c213 *chip = dev_id;
++      struct platform_device *pdev = chip->pdev;
++      snd_pcm_runtime_t *runtime = chip->substream->runtime;
++      u32 status;
++      int offset, next_period, block_size;
++
++      spin_lock(&chip->lock);
++
++      block_size = frames_to_bytes(runtime, runtime->period_size);
++
++      status = __raw_readl(chip->regs + SSC_IMR);
++
++      if (status & SSC_INT_ENDTX) {
++              chip->period++;
++              if (chip->period == runtime->periods)
++                      chip->period = 0;
++              next_period = chip->period + 1;
++              if (next_period == runtime->periods)
++                      next_period = 0;
++
++              offset = block_size * next_period;
++
++              /* Make sure that our data are actually readable by the SSC */
++              dma_sync_single_for_device(&pdev->dev, runtime->dma_addr + offset,
++                              block_size, DMA_TO_DEVICE);
++              __raw_writel(runtime->dma_addr + offset, chip->regs + PDC_TNPR);
++              __raw_writel(runtime->period_size * 2, chip->regs + PDC_TNCR);
++
++              if (next_period == 0) {
++                      (void)__raw_readl(chip->regs + PDC_TPR);
++                      (void)__raw_readl(chip->regs + PDC_TCR);
++              }
++      } else {
++              printk(KERN_WARNING
++                     "Spurious SSC interrupt, status = 0x%08lx\n",
++                     (unsigned long)status);
++              __raw_writel(status, chip->regs + SSC_IDR);
++      }
++
++      (void)__raw_readl(chip->regs + SSC_IMR);
++      spin_unlock(&chip->lock);
++
++      if (status & SSC_INT_ENDTX)
++              snd_pcm_period_elapsed(chip->substream);
++
++      return IRQ_HANDLED;
++}
++
++/*
++ * Mixer functions
++ */
++#if 0 /* Function not in use */
++static int snd_at73c213_mono_info(struct snd_kcontrol *kcontrol,
++                                struct snd_ctl_elem_info *uinfo)
++{
++      unsigned long mask = (kcontrol->private_value >> 16) & 0xff;
++
++      uinfo->type = (mask == 1) ?
++              SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
++      uinfo->count = 1;
++      uinfo->value.integer.min = 0;
++      uinfo->value.integer.max = mask;
++
++      return 0;
++}
++#endif
++
++static int snd_at73c213_mono_get(struct snd_kcontrol *kcontrol,
++                               struct snd_ctl_elem_value *ucontrol)
++{
++      struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
++      unsigned long flags;
++      int reg = kcontrol->private_value & 0xff;
++      int shift = (kcontrol->private_value >> 8) & 0xff;
++      int mask = (kcontrol->private_value >> 16) & 0xff;
++      int invert = (kcontrol->private_value >> 24) & 0xff;
++
++      spin_lock_irqsave(&chip->lock, flags);
++
++      ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & mask;
++
++      if (invert)
++              ucontrol->value.integer.value[0] =
++                      (mask - ucontrol->value.integer.value[0]);
++
++      spin_unlock_irqrestore(&chip->lock, flags);
++
++      return 0;
++}
++
++static int snd_at73c213_mono_put(struct snd_kcontrol *kcontrol,
++                               struct snd_ctl_elem_value *ucontrol)
++{
++      struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
++      unsigned long flags;
++      int reg = kcontrol->private_value & 0xff;
++      int shift = (kcontrol->private_value >> 8) & 0xff;
++      int mask = (kcontrol->private_value >> 16) & 0xff;
++      int invert = (kcontrol->private_value >> 24) & 0xff;
++      int change, retval;
++      unsigned short val;
++
++      val = (ucontrol->value.integer.value[0] & mask);
++      if (invert)
++              val = mask - val;
++      val <<= shift;
++
++      spin_lock_irqsave(&chip->lock, flags);
++
++      val = (chip->image[reg] & ~(mask << shift)) | val;
++      change = val != chip->image[reg];
++      write_reg(chip, reg, val);
++
++      chip->image[reg] = val;
++
++      spin_unlock_irqrestore(&chip->lock, flags);
++
++      return change;
++
++out:
++      return retval;
++}
++
++static int snd_at73c213_stereo_info(struct snd_kcontrol *kcontrol,
++                                struct snd_ctl_elem_info *uinfo)
++{
++      int mask = (kcontrol->private_value >> 24) & 0xFF;
++
++      uinfo->type = mask == 1 ?
++              SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
++      uinfo->count = 2;
++      uinfo->value.integer.min = 0;
++      uinfo->value.integer.max = mask;
++
++      return 0;
++}
++
++static int snd_at73c213_stereo_get(struct snd_kcontrol *kcontrol,
++                               struct snd_ctl_elem_value *ucontrol)
++{
++      struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
++      unsigned long flags;
++      int left_reg = kcontrol->private_value & 0xff;
++      int right_reg = (kcontrol->private_value >> 8) & 0xff;
++      int shift_left = (kcontrol->private_value >> 16) & 0x07;
++      int shift_right = (kcontrol->private_value >> 19) & 0x07;
++      int mask = (kcontrol->private_value >> 24) & 0xff;
++      int invert = (kcontrol->private_value >> 22) & 1;
++
++      spin_lock_irqsave(&chip->lock, flags);
++
++      ucontrol->value.integer.value[0] =
++              (chip->image[left_reg] >> shift_left) & mask;
++      ucontrol->value.integer.value[1] =
++              (chip->image[right_reg] >> shift_right) & mask;
++
++      if (invert) {
++              ucontrol->value.integer.value[0] =
++                      (mask - ucontrol->value.integer.value[0]);
++              ucontrol->value.integer.value[1] =
++                      (mask - ucontrol->value.integer.value[1]);
++      }
++
++      spin_unlock_irqrestore(&chip->lock, flags);
++
++      return 0;
++}
++
++static int snd_at73c213_stereo_put(struct snd_kcontrol *kcontrol,
++                               struct snd_ctl_elem_value *ucontrol)
++{
++      struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
++      unsigned long flags;
++      int left_reg = kcontrol->private_value & 0xff;
++      int right_reg = (kcontrol->private_value >> 8) & 0xff;
++      int shift_left = (kcontrol->private_value >> 16) & 0x07;
++      int shift_right = (kcontrol->private_value >> 19) & 0x07;
++      int mask = (kcontrol->private_value >> 24) & 0xff;
++      int invert = (kcontrol->private_value >> 22) & 1;
++      int change, retval;
++      unsigned short val1, val2;
++
++      val1 = ucontrol->value.integer.value[0] & mask;
++      val2 = ucontrol->value.integer.value[1] & mask;
++      if (invert) {
++              val1 = mask - val1;
++              val2 = mask - val2;
++      }
++      val1 <<= shift_left;
++      val2 <<= shift_right;
++
++      spin_lock_irqsave(&chip->lock, flags);
++
++      val1 = (chip->image[left_reg] & ~(mask << shift_left)) | val1;
++      val2 = (chip->image[right_reg] & ~(mask << shift_right)) | val2;
++      change = val1 != chip->image[left_reg] || val2 != chip->image[right_reg];
++      write_reg(chip, left_reg, val1);
++      write_reg(chip, right_reg, val2);
++
++      chip->image[left_reg] = val1;
++      chip->image[right_reg] = val2;
++
++      spin_unlock_irqrestore(&chip->lock, flags);
++
++      return change;
++
++out:
++      return retval;
++}
++
++static int snd_at73c213_mono_switch_info(struct snd_kcontrol *kcontrol,
++                                struct snd_ctl_elem_info *uinfo)
++{
++      uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
++      uinfo->count = 1;
++      uinfo->value.integer.min = 0;
++      uinfo->value.integer.max = 1;
++
++      return 0;
++}
++
++static int snd_at73c213_mono_switch_get(struct snd_kcontrol *kcontrol,
++                               struct snd_ctl_elem_value *ucontrol)
++{
++      struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
++      unsigned long flags;
++      int reg = kcontrol->private_value & 0xff;
++      int shift = (kcontrol->private_value >> 8) & 0xff;
++      int invert = (kcontrol->private_value >> 24) & 0xff;
++
++      spin_lock_irqsave(&chip->lock, flags);
++
++      ucontrol->value.integer.value[0] = (chip->image[reg] >> shift) & 0x01;
++
++      if (invert)
++              ucontrol->value.integer.value[0] =
++                      (0x01 - ucontrol->value.integer.value[0]);
++
++      spin_unlock_irqrestore(&chip->lock, flags);
++
++      return 0;
++}
++
++static int snd_at73c213_mono_switch_put(struct snd_kcontrol *kcontrol,
++                               struct snd_ctl_elem_value *ucontrol)
++{
++      struct snd_at73c213 *chip = snd_kcontrol_chip(kcontrol);
++      unsigned long flags;
++      int reg = kcontrol->private_value & 0xff;
++      int shift = (kcontrol->private_value >> 8) & 0xff;
++      int mask = (kcontrol->private_value >> 16) & 0xff;
++      int invert = (kcontrol->private_value >> 24) & 0xff;
++      int change, retval;
++      unsigned short val;
++
++      if (ucontrol->value.integer.value[0])
++              val = mask;
++      else
++              val = 0;
++
++      if (invert)
++              val = mask - val;
++      val <<= shift;
++
++      spin_lock_irqsave(&chip->lock, flags);
++
++      val |= (chip->image[reg] & ~(mask << shift));
++      change = val != chip->image[reg];
++
++      write_reg(chip, reg, val);
++
++      chip->image[reg] = val;
++
++      spin_unlock_irqrestore(&chip->lock, flags);
++
++      return change;
++
++out:
++      return retval;
++}
++
++static int snd_at73c213_pa_volume_info(struct snd_kcontrol *kcontrol,
++                                struct snd_ctl_elem_info *uinfo)
++{
++      uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
++      uinfo->count = 1;
++      uinfo->value.integer.min = 0;
++      uinfo->value.integer.max = ((kcontrol->private_value >> 16) & 0xFF) - 1;
++
++      return 0;
++}
++
++static int snd_at73c213_line_capture_volume_info(
++              struct snd_kcontrol *kcontrol,
++              struct snd_ctl_elem_info *uinfo)
++{
++      uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
++      uinfo->count = 2;
++      uinfo->value.integer.min = 14;
++      uinfo->value.integer.max = 31;
++
++      return 0;
++}
++
++static int snd_at73c213_aux_capture_volume_info(
++              struct snd_kcontrol *kcontrol,
++              struct snd_ctl_elem_info *uinfo)
++{
++      uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
++      uinfo->count = 1;
++      uinfo->value.integer.min = 14;
++      uinfo->value.integer.max = 31;
++
++      return 0;
++}
++
++#define AT73C213_MONO(xname, xindex, reg, shift, mask, invert) \
++{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
++  .info = snd_at73c213_mono_info, \
++  .get = snd_at73c213_mono_get, .put = snd_at73c213_mono_put, \
++  .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
++
++#define AT73C213_MONO_SWITCH(xname, xindex, reg, shift, mask, invert) \
++{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
++  .info = snd_at73c213_mono_switch_info, \
++  .get = snd_at73c213_mono_switch_get, .put = snd_at73c213_mono_switch_put, \
++  .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
++
++#define AT73C213_STEREO(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
++{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
++  .info = snd_at73c213_stereo_info, \
++  .get = snd_at73c213_stereo_get, .put = snd_at73c213_stereo_put, \
++  .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
++
++static struct snd_kcontrol_new snd_at73c213_controls[] __devinitdata = {
++AT73C213_STEREO("Master Playback Volume", 0, DAC_LMPG, DAC_RMPG, 0, 0, 0x1F, 1),
++AT73C213_STEREO("Master Playback Switch", 0, DAC_LMPG, DAC_RMPG, 5, 5, 1, 1),
++AT73C213_STEREO("PCM Playback Volume", 0, DAC_LLOG, DAC_RLOG, 0, 0, 0x1F, 1),
++AT73C213_STEREO("PCM Playback Switch", 0, DAC_LLOG, DAC_RLOG, 5, 5, 1, 1),
++AT73C213_MONO_SWITCH("Mono PA Playback Switch", 0, DAC_CTRL, DAC_CTRL_ONPADRV, 0x01, 0),
++{
++      .iface  = SNDRV_CTL_ELEM_IFACE_MIXER,
++      .name   = "PA Playback Volume",
++      .index  = 0,
++      .info   = snd_at73c213_pa_volume_info,
++      .get    = snd_at73c213_mono_get,
++      .put    = snd_at73c213_mono_put,
++      .private_value  = PA_CTRL|(PA_CTRL_APAGAIN<<8)|(0x0F<<16)|(1<<24),
++},
++AT73C213_MONO_SWITCH("PA High Gain Playback Switch", 0, PA_CTRL, PA_CTRL_APALP, 0x01, 1),
++AT73C213_MONO_SWITCH("PA Playback Switch", 0, PA_CTRL, PA_CTRL_APAON, 0x01, 0),
++{
++      .iface  = SNDRV_CTL_ELEM_IFACE_MIXER,
++      .name   = "Aux Capture Volume",
++      .index  = 0,
++      .info   = snd_at73c213_aux_capture_volume_info,
++      .get    = snd_at73c213_mono_get,
++      .put    = snd_at73c213_mono_put,
++      .private_value  = DAC_AUXG|(0<<8)|(0x1F<<16)|(1<<24),
++},
++AT73C213_MONO_SWITCH("Aux Capture Switch", 0, DAC_CTRL, DAC_CTRL_ONAUXIN, 0x01, 0),
++{
++      .iface  = SNDRV_CTL_ELEM_IFACE_MIXER,
++      .name   = "Line Capture Volume",
++      .index  = 0,
++      .info   = snd_at73c213_line_capture_volume_info,
++      .get    = snd_at73c213_stereo_get,
++      .put    = snd_at73c213_stereo_put,
++      .private_value  = DAC_LLIG|(DAC_RLIG<<8)|(0<<16)|(0<<19)|(0x1F<<24)|(1<<22),
++},
++AT73C213_MONO_SWITCH("Line Capture Switch", 0, DAC_CTRL, 0, 0x03, 0),
++};
++
++static int __devinit snd_at73c213_mixer(struct snd_at73c213 *chip)
++{
++      struct snd_card *card;
++      int errval, idx;
++
++      if (chip == NULL || chip->pcm == NULL)
++              return -EINVAL;
++
++      card = chip->card;
++
++      strcpy(card->mixername, chip->pcm->name);
++
++      for (idx = 0; idx < ARRAY_SIZE(snd_at73c213_controls); idx++) {
++              if ((errval = snd_ctl_add(card,
++                                     snd_ctl_new1(&snd_at73c213_controls[idx],
++                                                  chip))) < 0)
++                      return errval;
++      }
++
++      return 0;
++}
++
++/*
++ * Device functions
++ */
++static int snd_at73c213_chip_init(struct snd_at73c213 *chip)
++{
++      int retval;
++      unsigned char dac_ctrl = 0;
++
++      /* XXX: Unmask the APB clock for SSC0 */
++      __raw_writel(__raw_readl((void __iomem *)PM_BASE + PM_APBAMASK)|(1<<7),
++                      (void __iomem *)PM_BASE + PM_APBAMASK);
++
++      /* Wait for clock to be stable */
++      msleep(10);
++
++      retval = snd_at73c213_set_bitrate_and_div();
++      if (retval)
++              goto out;
++
++      /* Reset the SSC */
++      __raw_writel(SSC_CR_SWRST, chip->regs + SSC_CR);
++
++      /* Enable GCLK0 */
++      __raw_writel((1<<30), (void __iomem *)(PIOA_BASE + PIO_PDR));
++      __raw_writel((1<<30), (void __iomem *)(PIOA_BASE + PIO_ASR));
++      __raw_writel(((gclk_div<<8)|0x10|0x04|0x02), (void __iomem *)(PM_BASE + PM_GCCTRL));
++
++      /* Enable SSC and setup for I2S */
++      __raw_writel(ssc_div, chip->regs + SSC_CMR);
++
++      /* CKO, START, STTDLY, PERIOD */
++      __raw_writel((1<<2)|(4<<8)|(1<<16)|(15<<24), chip->regs + SSC_TCMR);
++
++      /* DATLEN, MSBF, DATNB, FSLEN, FSOS */
++      __raw_writel((15<<0)|(1<<7)|(1<<8)|(15<<16)|(1<<20), chip->regs + SSC_TFMR);
++
++      /* Initialize at73c213 on SPI bus */
++      /* Reset the device */
++      write_reg(chip, DAC_RST, 0x04);
++      msleep(1);
++      write_reg(chip, DAC_RST, 0x03);
++
++      /* Turn on precharge */
++      write_reg(chip, DAC_PRECH, 0xFF);
++      write_reg(chip, PA_CTRL, (1<<PA_CTRL_APAPRECH));
++      write_reg(chip, DAC_CTRL, (1<<DAC_CTRL_ONLNOL)|(1<<DAC_CTRL_ONLNOR));
++
++      msleep(50);
++
++      /* Stop precharging PA */
++      write_reg(chip, PA_CTRL, (1<<PA_CTRL_APALP)|0x0F);
++      chip->image[PA_CTRL] = (1<<PA_CTRL_APALP)|0x0F;
++
++      msleep(450);
++
++      /* Stop precharging, turn on master power */
++      write_reg(chip, DAC_PRECH, (1<<DAC_PRECH_ONMSTR));
++      chip->image[DAC_PRECH] = (1<<DAC_PRECH_ONMSTR);
++
++      msleep(1);
++
++      /* Turn on DAC */
++      dac_ctrl = (1<<DAC_CTRL_ONDACL)|(1<<DAC_CTRL_ONDACR)|
++                      (1<<DAC_CTRL_ONLNOL)|(1<<DAC_CTRL_ONLNOR);
++
++      write_reg(chip, DAC_CTRL, dac_ctrl);
++      chip->image[DAC_CTRL] = dac_ctrl;
++
++      /* Mute sound */
++      write_reg(chip, DAC_LMPG, 0x3F);
++      chip->image[DAC_LMPG] = 0x3F;
++      write_reg(chip, DAC_RMPG, 0x3F);
++      chip->image[DAC_RMPG] = 0x3F;
++      write_reg(chip, DAC_LLOG, 0x3F);
++      chip->image[DAC_LLOG] = 0x3F;
++      write_reg(chip, DAC_RLOG, 0x3F);
++      chip->image[DAC_RLOG] = 0x3F;
++      write_reg(chip, DAC_LLIG, 0x11);
++      chip->image[DAC_LLIG] = 0x11;
++      write_reg(chip, DAC_RLIG, 0x11);
++      chip->image[DAC_RLIG] = 0x11;
++      write_reg(chip, DAC_AUXG, 0x11);
++      chip->image[DAC_AUXG] = 0x11;
++
++      /* Turn on SSC transmitter */
++      __raw_writel(SSC_CR_TXEN, chip->regs + SSC_CR);
++
++out:
++      return retval;
++}
++
++static int snd_at73c213_dev_free(snd_device_t *device)
++{
++      struct snd_at73c213 *chip = device->device_data;
++
++      if (chip->regs) {
++              __raw_writel(SSC_CR_TXDIS, chip->regs + SSC_CR);
++              iounmap(chip->regs);
++      }
++
++      if (chip->irq >= 0)
++              free_irq(chip->irq, chip);
++
++      if (chip->ssc_clk) {
++              clk_disable(chip->ssc_clk);
++              clk_put(chip->ssc_clk);
++      }
++
++      return 0;
++}
++
++static int __devinit snd_at73c213_create(snd_card_t *card,
++                                       struct platform_device *pdev)
++{
++      static snd_device_ops_t ops = {
++              .dev_free       = snd_at73c213_dev_free,
++      };
++      struct snd_at73c213 *chip = get_chip(card);
++      struct resource *regs;
++      struct clk *ssc_clk;
++      int irq, retval;
++
++      regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!regs)
++              return -ENXIO;
++      irq = platform_get_irq(pdev, 0);
++      if (irq < 0)
++              return irq;
++
++      ssc_clk = clk_get(&pdev->dev, "mck");
++      if (IS_ERR(ssc_clk))
++              return PTR_ERR(ssc_clk);
++      clk_enable(ssc_clk);
++      chip->ssc_clk = ssc_clk;
++
++      spin_lock_init(&chip->lock);
++      chip->card = card;
++      chip->pdev = pdev;
++      chip->irq = -1;
++
++      retval = -ENOMEM;
++
++      retval = spi_setup(chip->spi);
++      if (retval)
++              goto out;
++
++      chip->regs = ioremap(regs->start, regs->end - regs->start + 1);
++      if (!chip->regs)
++              goto out;
++
++      retval = request_irq(irq, snd_at73c213_interrupt, 0, "at73c213", chip);
++      if (retval) {
++              snd_printk("unable to request IRQ%d\n", irq);
++              goto out;
++      }
++      chip->irq = irq;
++
++      memcpy(&chip->image, &snd_at73c213_original_image,
++                      sizeof(snd_at73c213_original_image));
++
++      retval = snd_at73c213_chip_init(chip);
++      if (retval)
++              goto out;
++
++      retval = snd_at73c213_new_pcm(chip, 0);
++      if (retval)
++              goto out;
++
++      retval = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
++      if (retval)
++              goto out;
++
++      retval = snd_at73c213_mixer(chip);
++      if (retval)
++              goto out;
++
++      snd_card_set_dev(card, &pdev->dev);
++
++out:
++      return retval;
++}
++
++static int __devinit snd_at73c213_probe(struct platform_device *pdev)
++{
++      static int dev;
++      struct spi_board_info *binfo;
++      struct spi_master *smaster;
++      struct snd_at73c213 *chip;
++      snd_card_t *card;
++      int retval;
++
++      if (dev >= SNDRV_CARDS)
++              return -ENODEV;
++      if (!enable[dev]) {
++              dev++;
++              return -ENOENT;
++      }
++
++      if (spi < 0 || ssc < 0)
++              return -ENODEV;
++
++      retval = -ENOMEM;
++      card = snd_card_new(index[dev], id[dev], THIS_MODULE,
++                          sizeof(struct snd_at73c213));
++      if (!card)
++              goto out;
++
++      chip = card->private_data;
++
++      retval = -ENODEV;
++
++      /* Get the SPI bus */
++      binfo = pdev->dev.platform_data;
++      if (!binfo) {
++              printk(KERN_WARNING "at73c213: could not get platform data\n");
++              goto out;
++      }
++
++      smaster = spi_busnum_to_master(spi);
++      if (!smaster) {
++              request_module("spi1");
++              smaster = spi_busnum_to_master(spi);
++              if (!smaster) {
++                      printk(KERN_WARNING
++                                      "at73c213: could not get "
++                                      "SPI bus %d, remembered to load "
++                                      "the spi_atmel module?\n", spi);
++                      goto out;
++              }
++      }
++
++      chip->spi = spi_new_device(smaster, binfo);
++      if (!chip->spi) {
++              printk(KERN_WARNING "at73c213: could not get SPI device %d\n", spi);
++              goto out;
++      }
++
++      chip->spi->mode = SPI_MODE_1;
++      chip->spi->bits_per_word = 8;
++
++      retval = snd_at73c213_create(card, pdev);
++      if (retval)
++              goto out_free_card;
++
++      strcpy(card->driver, "at73c213");
++      strcpy(card->shortname, "at73c213 (AVR32 STK1000)");
++      sprintf(card->longname, "%s at %p (irq %i)", card->shortname, chip->regs, chip->irq);
++
++      retval = snd_card_register(card);
++      if (retval)
++              goto out_free_card;
++
++      platform_set_drvdata(pdev, card);
++      dev++;
++      return 0;
++
++out_free_card:
++      snd_card_free(card);
++out:
++      return retval;
++}
++
++static int __devexit snd_at73c213_remove(struct platform_device *pdev)
++{
++      struct snd_card *card = platform_get_drvdata(pdev);
++      struct snd_at73c213 *chip = card->private_data;
++      int retval;
++
++      /* Stop playback */
++      __raw_writel(SSC_CR_TXDIS, chip->regs + SSC_CR);
++
++      /* Stop GLCK0 */
++      __raw_writel(0, (void __iomem *)PM_BASE + PM_GCCTRL);
++
++      /* Mute sound */
++      write_reg(chip, DAC_LMPG, 0x3F);
++      chip->image[DAC_LMPG] = 0x3F;
++      write_reg(chip, DAC_RMPG, 0x3F);
++      chip->image[DAC_RMPG] = 0x3F;
++      write_reg(chip, DAC_LLOG, 0x3F);
++      chip->image[DAC_LLOG] = 0x3F;
++      write_reg(chip, DAC_RLOG, 0x3F);
++      chip->image[DAC_RLOG] = 0x3F;
++      write_reg(chip, DAC_LLIG, 0x11);
++      chip->image[DAC_LLIG] = 0x11;
++      write_reg(chip, DAC_RLIG, 0x11);
++      chip->image[DAC_RLIG] = 0x11;
++      write_reg(chip, DAC_AUXG, 0x11);
++      chip->image[DAC_AUXG] = 0x11;
++
++      /* Turn off PA */
++      write_reg(chip, PA_CTRL, (chip->image[PA_CTRL]|0x0F));
++      chip->image[PA_CTRL] |= 0x0F;
++      msleep(10);
++      write_reg(chip, PA_CTRL, (1<<PA_CTRL_APALP)|0x0F);
++      chip->image[PA_CTRL] = (1<<PA_CTRL_APALP)|0x0F;
++
++      /* Turn off external DAC */
++      write_reg(chip, DAC_CTRL, 0x0C);
++      chip->image[DAC_CTRL] = 0x0C;
++      msleep(2);
++      write_reg(chip, DAC_CTRL, 0x00);
++      chip->image[DAC_CTRL] = 0x00;
++
++      /* Turn off master power */
++      write_reg(chip, DAC_PRECH, 0x00);
++      chip->image[DAC_PRECH] = 0x00;
++
++      msleep(10);
++
++out:
++      if (chip->spi)
++              spi_unregister_device(chip->spi);
++
++      if (card) {
++              snd_card_free(card);
++              platform_set_drvdata(pdev, NULL);
++      }
++
++      return 0;
++}
++
++#ifdef CONFIG_PM
++static int snd_at73c213_suspend(struct platform_device *pdev, pm_message_t state, u32 level)
++{
++      struct snd_card *card = at32_get_drvdata(pdev);
++      struct snd_at73c213 *chip = card->private_data;
++
++      printk(KERN_DEBUG "at73c213: suspending\n");
++
++      /* Stop SSC and GCLK0 */
++
++      spi_suspend(chip->spi, state);
++
++      return 0;
++}
++
++static int snd_at73c213_resume(struct platform_device *pdev, u32 level)
++{
++      struct snd_card *card = at32_get_drvdata(pdev);
++      struct snd_at73c213 *chip = card->private_data;
++
++      printk(KERN_DEBUG "at73c213: resuming\n");
++
++      /* Start GLCK0 and SSC */
++
++      spi_resume(chip->spi);
++
++      return 0;
++}
++#endif /* CONFIG_PM */
++
++/* Driver core initialization */
++static struct platform_driver at73c213_driver = {
++      .probe          = snd_at73c213_probe,
++      .remove         = __devexit_p(snd_at73c213_remove),
++      .driver         = {
++              .name   = "at73c213",
++      }
++#ifdef CONFIG_PM
++      .resume         = snd_at73c213_resume,
++      .suspend        = snd_at73c213_suspend,
++#endif
++};
++
++static int __init at73c213_init(void)
++{
++      return platform_driver_register(&at73c213_driver);
++}
++
++static void __exit at73c213_exit(void)
++{
++      platform_driver_unregister(&at73c213_driver);
++}
++
++MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
++MODULE_DESCRIPTION("Sound driver for at73c213 on STK1000");
++MODULE_LICENSE("GPL");
++
++module_init(at73c213_init);
++module_exit(at73c213_exit);
++
+Index: linux-2.6.18-avr32/sound/avr32/at73c213.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/sound/avr32/at73c213.h  2006-11-02 15:56:20.000000000 +0100
+@@ -0,0 +1,120 @@
++/*
++ * Driver for the AT73C213 16-bit stereo DAC on Atmel ATSTK1000
++ *
++ * 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.
++ */
++
++#ifndef _SND_AT73C213_MIXER_H_
++#define _SND_AT73C213_MIXER_H_
++
++/* DAC control register */
++#define DAC_CTRL              0x00
++#define DAC_CTRL_ONPADRV      7
++#define DAC_CTRL_ONAUXIN      6
++#define DAC_CTRL_ONDACR               5
++#define DAC_CTRL_ONDACL               4
++#define DAC_CTRL_ONLNOR               3
++#define DAC_CTRL_ONLNOL               2
++#define DAC_CTRL_ONLNIR               1
++#define DAC_CTRL_ONLNIL               0
++
++/* DAC left line in gain register */
++#define DAC_LLIG              0x01
++#define DAC_LLIG_LLIG         0
++
++/* DAC right line in gain register */
++#define DAC_RLIG              0x02
++#define DAC_RLIG_RLIG         0
++
++/* DAC Left Master Playback Gain Register */
++#define DAC_LMPG              0x03
++#define DAC_LMPG_LMPG         0
++
++/* DAC Right Master Playback Gain Register */
++#define DAC_RMPG              0x04
++#define DAC_RMPG_RMPG         0
++
++/* DAC Left Line Out Gain Register */
++#define DAC_LLOG              0x05
++#define DAC_LLOG_LLOG         0
++
++/* DAC Right Line Out Gain Register */
++#define DAC_RLOG              0x06
++#define DAC_RLOG_RLOG         0
++
++/* DAC Output Level Control Register */
++#define DAC_OLC                       0x07
++#define DAC_OLC_RSHORT                7
++#define DAC_OLC_ROLC          4
++#define DAC_OLC_LSHORT                3
++#define DAC_OLC_LOLC          0
++
++/* DAC Mixer Control Register */
++#define DAC_MC                        0x08
++#define DAC_MC_INVR           5
++#define DAC_MC_INVL           4
++#define DAC_MC_RMSMIN2                3
++#define DAC_MC_RMSMIN1                2
++#define DAC_MC_LMSMIN2                1
++#define DAC_MC_LMSMIN1                0
++
++/* DAC Clock and Sampling Frequency Control Register */
++#define DAC_CSFC              0x09
++#define DAC_CSFC_OVRSEL               4
++
++/* DAC Miscellaneous Register */
++#define DAC_MISC              0x0A
++#define DAC_MISC_VCMCAPSEL    7
++#define DAC_MISC_DINTSEL      4
++#define DAC_MISC_DITHEN               3
++#define DAC_MISC_DEEMPEN      2
++#define DAC_MISC_NBITS                0
++
++/* DAC Precharge Control Register */
++#define DAC_PRECH             0x0C
++#define DAC_PRECH_PRCHGPDRV   7
++#define DAC_PRECH_PRCHGAUX1   6
++#define DAC_PRECH_PRCHGLNOR   5
++#define DAC_PRECH_PRCHGLNOL   4
++#define DAC_PRECH_PRCHGLNIR   3
++#define DAC_PRECH_PRCHGLNIL   2
++#define DAC_PRECH_PRCHG               1
++#define DAC_PRECH_ONMSTR      0
++
++/* DAC Auxiliary Input Gain Control Register */
++#define DAC_AUXG              0x0D
++#define DAC_AUXG_AUXG         0
++
++/* DAC Reset Register */
++#define DAC_RST                       0x10
++#define DAC_RST_RESMASK               2
++#define DAC_RST_RESFILZ               1
++#define DAC_RST_RSTZ          0
++
++/* Power Amplifier Control Register */
++#define PA_CTRL                       0x11
++#define PA_CTRL_APAON         6
++#define PA_CTRL_APAPRECH      5
++#define PA_CTRL_APALP         4
++#define PA_CTRL_APAGAIN               0
++
++#endif
++
diff --git a/packages/linux/linux-2.6.18/atmel-ac97c-alsa-driver.patch b/packages/linux/linux-2.6.18/atmel-ac97c-alsa-driver.patch
new file mode 100644 (file)
index 0000000..fe3d2ee
--- /dev/null
@@ -0,0 +1,1383 @@
+---
+ sound/avr32/Kconfig  |   25 +
+ sound/avr32/Makefile |    3 
+ sound/avr32/ac97c.c  | 1250 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ sound/avr32/ac97c.h  |   71 ++
+ 4 files changed, 1349 insertions(+)
+
+Index: linux-2.6.18-avr32/sound/avr32/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/sound/avr32/Kconfig        2006-11-02 15:56:20.000000000 +0100
++++ linux-2.6.18-avr32/sound/avr32/Kconfig     2006-11-02 16:02:29.000000000 +0100
+@@ -3,4 +3,29 @@
+ menu "ALSA AVR32 devices"
+       depends on SND != n && AVR32
++config SND_ATMEL_AC97
++      tristate "Atmel AC97 Controller Driver"
++      depends on SND
++      select SND_PCM
++      select SND_AC97_CODEC
++      help
++        ALSA sound driver for the Atmel AC97 controller.
++
++config SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS
++      bool "Use the built-in malloc calls in the alsa driver"
++      default n
++      depends on SND_ATMEL_AC97
++      help
++        Say Y if the built-in malloc calls in the alsa driver should be
++        used instead of the native dma_alloc_coherent and dma_free_coherent
++        function calls. Enabling this feature may break the rmmod feature.
++
++config SND_ATMEL_AC97C_USE_PDC
++      bool "Use PDC for DMA transfers to/from the Atmel AC97 Controller"
++      default n
++      depends on SND_ATMEL_AC97
++      help
++        Say Y if PDC (Peripheral DMA Controller) is used for DMA transfers
++        to/from the Atmel AC97C instead of using the generic DMA framework.
++
+ endmenu
+Index: linux-2.6.18-avr32/sound/avr32/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/sound/avr32/Makefile       2006-11-02 15:56:20.000000000 +0100
++++ linux-2.6.18-avr32/sound/avr32/Makefile    2006-11-02 16:02:29.000000000 +0100
+@@ -1,3 +1,6 @@
+ #
+ # Makefile for ALSA
+ #
++
++snd-atmel-ac97-objs           := ac97c.o
++obj-$(CONFIG_SND_ATMEL_AC97)  += snd-atmel-ac97.o
+Index: linux-2.6.18-avr32/sound/avr32/ac97c.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/sound/avr32/ac97c.c     2006-11-02 16:02:56.000000000 +0100
+@@ -0,0 +1,1250 @@
++/*
++ * Driver 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.
++ */
++#include <linux/clk.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/mutex.h>
++
++#include <sound/driver.h>
++#include <sound/core.h>
++#include <sound/initval.h>
++#include <sound/pcm.h>
++#include <sound/pcm_params.h>
++#include <sound/ac97_codec.h>
++#ifndef SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS
++#include <sound/memalloc.h>
++#endif
++
++#include <asm/io.h>
++
++#include "ac97c.h"
++
++static DEFINE_MUTEX(opened_mutex);
++
++/* module parameters */
++static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
++static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
++static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
++
++module_param_array(index, int, NULL, 0444);
++MODULE_PARM_DESC(index, "Index value for AC97 controller");
++module_param_array(id, charp, NULL, 0444);
++MODULE_PARM_DESC(id, "ID string for AC97 controller");
++module_param_array(enable, bool, NULL, 0444);
++MODULE_PARM_DESC(enable, "Enable AC97 controller");
++
++#ifndef CONFIG_SND_ATMEL_AC97C_USE_PDC
++#include <asm/dma-controller.h>
++
++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;
++};
++#endif
++
++
++typedef struct atmel_ac97 {
++      spinlock_t lock;
++      void __iomem *regs;
++      int period;
++
++      snd_pcm_substream_t *playback_substream;
++      snd_pcm_substream_t *capture_substream;
++      snd_card_t *card;
++      snd_pcm_t *pcm;
++      ac97_t *ac97;
++      ac97_bus_t *ac97_bus;
++      int irq;
++      int opened;
++      u64 cur_format;
++      unsigned int cur_rate;
++      struct clk *mck;
++      struct platform_device *pdev;
++        struct atmel_ac97_dma_info dma;
++} atmel_ac97_t;
++#define get_chip(card) ((atmel_ac97_t *)(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 snd_pcm_hardware_t 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,
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++      .period_bytes_max       = 64*1024,
++#else
++      .period_bytes_max       = 4095,
++#endif
++      .periods_min            = 8,
++      .periods_max            = 1024,
++};
++
++static snd_pcm_hardware_t 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,
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++      .period_bytes_max       = 64*1024,
++#else
++      .period_bytes_max       = 4095,
++#endif
++      .periods_min            = 8,
++      .periods_max            = 1024,
++};
++
++/* Joint full duplex variables */
++unsigned int hw_rates[1];
++unsigned int hw_formats[1];
++struct snd_pcm_hw_constraint_list hw_constraint_rates;
++struct snd_pcm_hw_constraint_list hw_constraint_formats;
++
++/*
++ * PCM functions
++ */
++static int
++snd_atmel_ac97_playback_open(snd_pcm_substream_t *substream)
++{
++      atmel_ac97_t *chip = snd_pcm_substream_chip(substream);
++      snd_pcm_runtime_t *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(snd_pcm_substream_t *substream)
++{
++      atmel_ac97_t *chip = snd_pcm_substream_chip(substream);
++      snd_pcm_runtime_t *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(snd_pcm_substream_t *substream)
++{
++      atmel_ac97_t *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(snd_pcm_substream_t *substream)
++{
++      atmel_ac97_t *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(snd_pcm_substream_t *substream,
++                                  snd_pcm_hw_params_t *hw_params)
++{
++      atmel_ac97_t *chip = snd_pcm_substream_chip(substream);
++#ifdef SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS
++      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 err;
++#else
++      int pg;
++      size_t size = params_buffer_bytes(hw_params);
++      struct snd_pcm_runtime *runtime;
++      struct snd_dma_buffer *dmab = NULL;
++
++      substream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV;
++      snd_assert(substream != NULL, return -EINVAL);
++      runtime = substream->runtime;
++      snd_assert(runtime != NULL, return -EINVAL);
++
++      /* 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);
++
++      /* check if buffer is already allocated */
++      if (runtime->dma_buffer_p) {
++              size_t size_previouse;
++              int pg_previouse;
++
++              /* new buffer is smaler than previouse allocated buffer */
++              if (runtime->dma_buffer_p->bytes >= size) {
++                      runtime->dma_bytes = size;
++                      return 0; /* don't change buffer size */
++              }
++
++              size_previouse = runtime->dma_buffer_p->bytes;
++              pg_previouse = get_order(size_previouse);
++
++              dma_free_coherent(runtime->dma_buffer_p->dev.dev,
++                              PAGE_SIZE << pg_previouse,
++                              runtime->dma_buffer_p->area,
++                              runtime->dma_buffer_p->addr);
++
++              kfree(runtime->dma_buffer_p);
++      }
++
++      dmab = kzalloc(sizeof(*dmab), GFP_KERNEL);
++      if (!dmab)
++              return -ENOMEM;
++
++      dmab->dev = substream->dma_buffer.dev;
++      dmab->bytes = 0;
++
++      pg = get_order(size);
++
++      dmab->area = dma_alloc_coherent(
++                      substream->dma_buffer.dev.dev,
++                      PAGE_SIZE << pg,
++                      (dma_addr_t *)&dmab->addr,
++                      GFP_KERNEL);
++
++      if (!dmab->area) {
++              kfree(dmab);
++              return -ENOMEM;
++      }
++
++      dmab->bytes = size;
++
++      snd_pcm_set_runtime_buffer(substream, dmab);
++      runtime->dma_bytes = size;
++      return 1;
++#endif
++}
++
++static int snd_atmel_ac97_capture_hw_params(snd_pcm_substream_t *substream,
++                                  snd_pcm_hw_params_t *hw_params)
++{
++      atmel_ac97_t *chip = snd_pcm_substream_chip(substream);
++#ifdef SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS
++      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 err;
++#else
++      int pg;
++      size_t size = params_buffer_bytes(hw_params);
++      struct snd_pcm_runtime *runtime;
++      struct snd_dma_buffer *dmab = NULL;
++
++      substream->dma_buffer.dev.type = SNDRV_DMA_TYPE_DEV;
++      snd_assert(substream != NULL, return -EINVAL);
++      runtime = substream->runtime;
++      snd_assert(runtime != NULL, return -EINVAL);
++
++      /* 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);
++
++      /* check if buffer is already allocated */
++      if (runtime->dma_buffer_p) {
++              size_t size_previouse;
++              int pg_previouse;
++
++              /* new buffer is smaler than previouse allocated buffer */
++              if (runtime->dma_buffer_p->bytes >= size) {
++                      runtime->dma_bytes = size;
++                      return 0; /* don't change buffer size */
++              }
++
++              size_previouse = runtime->dma_buffer_p->bytes;
++              pg_previouse = get_order(size_previouse);
++
++              dma_free_coherent(runtime->dma_buffer_p->dev.dev,
++                              PAGE_SIZE << pg_previouse,
++                              runtime->dma_buffer_p->area,
++                              runtime->dma_buffer_p->addr);
++
++              kfree(runtime->dma_buffer_p);
++      }
++
++      dmab = kzalloc(sizeof(*dmab), GFP_KERNEL);
++      if (!dmab)
++              return -ENOMEM;
++
++      dmab->dev = substream->dma_buffer.dev;
++      dmab->bytes = 0;
++
++      pg = get_order(size);
++
++      dmab->area = dma_alloc_coherent(
++                      substream->dma_buffer.dev.dev,
++                      PAGE_SIZE << pg,
++                      (dma_addr_t *)&dmab->addr,
++                      GFP_KERNEL);
++
++      if (!dmab->area) {
++              kfree(dmab);
++              return -ENOMEM;
++      }
++
++      dmab->bytes = size;
++
++      snd_pcm_set_runtime_buffer(substream, dmab);
++      runtime->dma_bytes = size;
++      return 1;
++#endif
++}
++
++static int snd_atmel_ac97_playback_hw_free(snd_pcm_substream_t *substream)
++{
++#ifdef SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS
++      return snd_pcm_lib_free_pages(substream);
++#else
++      int pg;
++      struct snd_pcm_runtime *runtime;
++      struct snd_dma_buffer *dmab = NULL;
++
++      snd_assert(substream != NULL, return -EINVAL);
++      runtime = substream->runtime;
++      snd_assert(runtime != NULL, return -EINVAL);
++      dmab = runtime->dma_buffer_p;
++
++      if (!dmab)
++              return 0;
++
++      if (!dmab->area)
++              return 0;
++
++      pg = get_order(dmab->bytes);
++      dma_free_coherent(dmab->dev.dev, PAGE_SIZE << pg, dmab->area, dmab->addr);
++      kfree(runtime->dma_buffer_p);
++      snd_pcm_set_runtime_buffer(substream, NULL);
++      return 0;
++#endif
++}
++
++static int snd_atmel_ac97_capture_hw_free(snd_pcm_substream_t *substream)
++{
++
++#ifdef SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS
++      return snd_pcm_lib_free_pages(substream);
++#else
++      int pg;
++      struct snd_pcm_runtime *runtime;
++      struct snd_dma_buffer *dmab = NULL;
++
++      snd_assert(substream != NULL, return -EINVAL);
++      runtime = substream->runtime;
++      snd_assert(runtime != NULL, return -EINVAL);
++      dmab = runtime->dma_buffer_p;
++
++      if (!dmab)
++              return 0;
++
++      if (!dmab->area)
++              return 0;
++
++      pg = get_order(dmab->bytes);
++      dma_free_coherent(dmab->dev.dev, PAGE_SIZE << pg, dmab->area, dmab->addr);
++      kfree(runtime->dma_buffer_p);
++      snd_pcm_set_runtime_buffer(substream, NULL);
++      return 0;
++#endif
++}
++
++static int snd_atmel_ac97_playback_prepare(snd_pcm_substream_t *substream)
++{
++      atmel_ac97_t *chip = snd_pcm_substream_chip(substream);
++      struct platform_device *pdev = chip->pdev;
++      snd_pcm_runtime_t *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:
++        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);
++
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++      /* Initialize and start the PDC */
++        ac97c_writel(chip, CATPR, runtime->dma_addr);
++      ac97c_writel(chip, CATCR, block_size / 4);
++      ac97c_writel(chip, CATNPR, runtime->dma_addr + block_size);
++      ac97c_writel(chip, CATNCR, block_size / 4);
++      ac97c_writel(chip, PTCR, PDC_PTCR_TXTEN);
++      /* Enable Channel A interrupts */
++      ac97c_writel(chip, IER, AC97C_SR_CAEVT);
++#else
++      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;
++#endif
++
++      return 0;
++}
++
++static int snd_atmel_ac97_capture_prepare(snd_pcm_substream_t *substream)
++{
++      atmel_ac97_t *chip = snd_pcm_substream_chip(substream);
++      struct platform_device *pdev = chip->pdev;
++      snd_pcm_runtime_t *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);
++
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++      /* Initialize and start the PDC */
++      ac97c_writel(chip, CARPR, runtime->dma_addr);
++      ac97c_writel(chip, CARCR, block_size / 4);
++      ac97c_writel(chip, CARNPR, runtime->dma_addr + block_size);
++      ac97c_writel(chip, CARNCR, block_size / 4);
++      ac97c_writel(chip, PTCR, PDC_PTCR_RXEN);
++      /* Enable Channel A interrupts */
++      ac97c_writel(chip, IER, AC97C_SR_CAEVT);
++#else
++      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;
++#endif
++
++      return 0;
++}
++
++static int snd_atmel_ac97_playback_trigger(snd_pcm_substream_t *substream, int cmd)
++{
++      atmel_ac97_t *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
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++                              |AC97C_CMR_TXRDY
++#endif
++                      );
++              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
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++                                      |AC97C_CMR_TXRDY
++#endif
++                               );
++              }
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++              else {
++                      camr &= ~(AC97C_CMR_TXRDY);
++              }
++#endif
++              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(snd_pcm_substream_t *substream, int cmd)
++{
++      atmel_ac97_t *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
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++                       | AC97C_CMR_RXRDY
++#endif
++                      );
++              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
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++                                      | AC97C_CMR_RXRDY
++#endif
++                               );
++              }
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++              else {
++                        camr &= ~(AC97C_CSR_RXRDY);
++              }
++#endif
++              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(snd_pcm_substream_t *substream)
++{
++      atmel_ac97_t *chip = snd_pcm_substream_chip(substream);
++      snd_pcm_runtime_t *runtime = substream->runtime;
++      snd_pcm_uframes_t pos;
++      unsigned long bytes;
++
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++      bytes = ac97c_readl(chip, CATPR) - runtime->dma_addr;
++#else
++        bytes = (dma_get_current_pos
++                      (chip->dma.req_tx.req.dmac,
++                       chip->dma.req_tx.req.channel) - runtime->dma_addr);
++#endif
++      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(snd_pcm_substream_t *substream)
++{
++      atmel_ac97_t *chip = snd_pcm_substream_chip(substream);
++      snd_pcm_runtime_t *runtime = substream->runtime;
++      snd_pcm_uframes_t pos;
++      unsigned long bytes;
++
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++      bytes = ac97c_readl(chip, CARPR) - runtime->dma_addr;
++#else
++        bytes = (dma_get_current_pos
++                      (chip->dma.req_rx.req.dmac,chip->dma.req_rx.req.channel) -
++                      runtime->dma_addr);
++#endif
++      pos = bytes_to_frames(runtime, bytes);
++      if (pos >= runtime->buffer_size)
++              pos -= runtime->buffer_size;
++
++
++      return pos;
++}
++
++static snd_pcm_ops_t 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 snd_pcm_ops_t 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(atmel_ac97_t *chip)
++{
++      snd_pcm_t *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);
++
++#ifdef SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS
++      snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
++                                            &chip->pdev->dev,
++                                            128 * 1024, 128 * 1024);
++#endif
++
++      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(atmel_ac97_t *chip)
++{
++      int err;
++      ac97_template_t template;
++
++      memset(&template, 0, sizeof(template));
++      template.private_data = chip;
++      err = snd_ac97_mixer(chip->ac97_bus, &template, &chip->ac97);
++
++      return err;
++}
++
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++static irqreturn_t snd_atmel_ac97_interrupt(int irq, void *dev_id,
++                                          struct pt_regs *regs)
++{
++      atmel_ac97_t *chip = dev_id;
++      unsigned long status;
++
++      status = ac97c_readl(chip, SR);
++
++      if (status & AC97C_SR_CAEVT) {
++              snd_pcm_runtime_t *runtime;
++              int offset, next_period, block_size;
++              unsigned long casr;
++
++              /* FIXME: separate playback from capture */
++              runtime = chip->playback_substream->runtime;
++              block_size = frames_to_bytes(runtime, runtime->period_size);
++
++              casr = ac97c_readl(chip, CASR);
++
++              if (casr & AC97C_CSR_ENDTX) {
++                      chip->period++;
++                      if (chip->period == runtime->periods)
++                              chip->period = 0;
++                      next_period = chip->period + 1;
++                      if (next_period == runtime->periods)
++                              next_period = 0;
++
++                      offset = block_size * next_period;
++
++                      ac97c_writel(chip, CATNPR,
++                                   runtime->dma_addr + offset);
++                      ac97c_writel(chip, CATNCR, block_size / 4);
++
++                      snd_pcm_period_elapsed(chip->playback_substream);
++              }
++              else if (casr & AC97C_CSR_ENDRX) {
++                      chip->period++;
++                      if (chip->period == runtime->periods)
++                              chip->period = 0;
++                      next_period = chip->period + 1;
++                      if (next_period == runtime->periods)
++                              next_period = 0;
++
++                      offset = block_size * next_period;
++
++                      ac97c_writel(chip, CARNPR,
++                                   runtime->dma_addr + offset);
++                      ac97c_writel(chip, CARNCR, block_size / 4);
++
++                      snd_pcm_period_elapsed(chip->capture_substream);
++              } else {
++                      snd_printk(KERN_INFO
++                             "atmel-ac97: spurious interrupt, status = 0x%08lx\n",
++                             (unsigned long)casr);
++              }
++      } else {
++              snd_printk(KERN_INFO
++                     "atmel-ac97: spurious interrupt, status = 0x%08lx\n",
++                     status);
++      }
++
++      (volatile int)ac97c_readl(chip, SR);
++
++      return IRQ_HANDLED;
++}
++
++#else
++
++static void atmel_ac97_error(struct dma_request *_req)
++{
++      struct dma_request_cyclic *req = to_dma_request_cyclic(_req);
++
++      printk(KERN_WARNING
++             "DMA Controller error, channel %d (AC97C)\n",
++             req->req.channel);
++}
++
++static void atmel_ac97_block_complete(struct dma_request *_req)
++{
++      struct dma_request_cyclic *req = to_dma_request_cyclic(_req);
++      atmel_ac97_t *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);
++}
++
++#endif
++
++/* CODEC part */
++
++static void snd_atmel_ac97_write(ac97_t *ac97, unsigned short reg,
++                               unsigned short val)
++{
++      atmel_ac97_t *chip = ac97->private_data;
++      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);
++
++      snd_printk(KERN_WARNING "atmel-ac97: codec write timeout\n");
++}
++
++static unsigned short snd_atmel_ac97_read(ac97_t *ac97,
++                                        unsigned short reg)
++{
++      atmel_ac97_t *chip = ac97->private_data;
++      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;
++                }
++              mdelay(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;
++              }
++              mdelay(10);
++      } while (--timeout);
++
++      if (!--write)
++              goto timed_out;
++      goto retry_write;
++
++timed_out:
++      snd_printk(KERN_INFO "atmel-ac97: codec read timeout\n");
++      return 0xffff;
++}
++
++static void snd_atmel_ac97_reset(atmel_ac97_t *chip)
++{
++      /* TODO: Perform hard reset of codec as well */
++      ac97c_writel(chip, MR, AC97C_MR_WRST);
++      mdelay(1);
++      ac97c_writel(chip, MR, AC97C_MR_ENA);
++}
++
++static void snd_atmel_ac97_destroy(snd_card_t *card)
++{
++      atmel_ac97_t *chip = get_chip(card);
++
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++      if (chip->irq != -1)
++              free_irq(chip->irq, chip);
++#endif
++      if (chip->regs)
++              iounmap(chip->regs);
++
++      if (chip->mck) {
++              clk_disable(chip->mck);
++              clk_put(chip->mck);
++      }
++
++#ifndef CONFIG_SND_ATMEL_AC97C_USE_PDC
++        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);
++        }
++#endif
++}
++
++static int __devinit snd_atmel_ac97_create(snd_card_t *card,
++                                         struct platform_device *pdev)
++{
++      static ac97_bus_ops_t ops = {
++              .write  = snd_atmel_ac97_write,
++              .read   = snd_atmel_ac97_read,
++      };
++      atmel_ac97_t *chip = get_chip(card);
++      struct resource *regs;
++      struct clk *mck;
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++      int irq;
++#endif
++        int err;
++
++      regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!regs)
++              return -ENXIO;
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++      irq = platform_get_irq(pdev, 0);
++      if (irq < 0)
++              return irq;
++#endif
++
++      mck = clk_get(&pdev->dev, "mck");
++      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->irq = -1;
++
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++      err = request_irq(irq, snd_atmel_ac97_interrupt, 0,
++                        "ac97", chip);
++      if (err) {
++              snd_printk("unable to request IRQ%d\n", irq);
++              return err;
++      }
++      chip->irq = irq;
++#endif
++
++      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;
++      snd_card_t *card;
++      atmel_ac97_t *chip;
++      int err;
++        int ch;
++
++      if (dev >= SNDRV_CARDS)
++              return -ENODEV;
++      if (!enable[dev]) {
++              dev++;
++              return -ENOENT;
++      }
++
++      err = -ENOMEM;
++
++      mutex_init(&opened_mutex);
++
++      card = snd_card_new(index[dev], id[dev], THIS_MODULE,
++                          sizeof(atmel_ac97_t));
++      if (!card)
++              goto out;
++      chip = get_chip(card);
++
++      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;
++
++#ifndef CONFIG_SND_ATMEL_AC97C_USE_PDC
++      /* TODO: Get this information from the platform device */
++      chip->dma.req_tx.req.dmac = find_dma_controller(0);
++      if (!chip->dma.req_tx.req.dmac) {
++              printk(KERN_ERR
++                     "atmel-ac97c: No DMA controller for TX, aborting\n");
++              goto out_free_card;
++      }
++      chip->dma.req_rx.req.dmac = find_dma_controller(0);
++      if (!chip->dma.req_rx.req.dmac) {
++              snd_printk(KERN_ERR
++                     "atmel-ac97c: No DMA controller available for RX, aborting\n");
++              goto out_free_card;
++      }
++
++      chip->dma.rx_periph_id = 3;
++      chip->dma.tx_periph_id = 4;
++
++      ch = dma_alloc_channel(chip->dma.req_tx.req.dmac);
++      if (ch < 0) {
++              printk(KERN_ERR
++                     "atmel-ac97c: Unable to allocate TX DMA channel, aborting\n");
++              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) {
++              snd_printk(KERN_ERR
++                     "atmel-ac97c: Unable to allocate RX DMA channel, aborting\n");
++              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;
++#endif
++
++      strcpy(card->driver, "ac97c");
++      strcpy(card->shortname, "Atmel-AC97");
++#ifdef CONFIG_SND_ATMEL_AC97C_USE_PDC
++      sprintf(card->longname, "Atmel AVR32 AC97 Controller at 0x%p, irq %i",
++              chip->regs, chip->irq);
++#else
++      sprintf(card->longname, "Atmel AVR32 AC97 Controller at 0x%p, dma rx %i and tx %i",
++              chip->regs, chip->dma.rx_periph_id, chip->dma.tx_periph_id);
++#endif
++
++      err = snd_card_register(card);
++      if (err)
++              goto out_free_card;
++
++      platform_set_drvdata(pdev, card);
++      dev++;
++      return 0;
++
++out_free_card:
++      snd_card_free(card);
++out:
++      return err;
++}
++
++static int __devexit snd_atmel_ac97_remove(struct platform_device *pdev)
++{
++      snd_card_t *card = platform_get_drvdata(pdev);
++
++      snd_card_free(card);
++      platform_set_drvdata(pdev, NULL);
++      return 0;
++}
++
++static struct platform_driver atmel_ac97_driver = {
++      .probe          = snd_atmel_ac97_probe,
++      .remove         = __devexit_p(snd_atmel_ac97_remove),
++      .driver         = {
++              .name   = "ac97c",
++      },
++};
++
++static int __init atmel_ac97_init(void)
++{
++      return platform_driver_register(&atmel_ac97_driver);
++}
++
++static void __exit atmel_ac97_exit(void)
++{
++      platform_driver_unregister(&atmel_ac97_driver);
++}
++
++module_init(atmel_ac97_init);
++module_exit(atmel_ac97_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Driver for Atmel AC97 Controller");
++MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
+Index: linux-2.6.18-avr32/sound/avr32/ac97c.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/sound/avr32/ac97c.h     2006-11-02 15:56:20.000000000 +0100
+@@ -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 */
diff --git a/packages/linux/linux-2.6.18/atmel-husb2-udc-driver.patch b/packages/linux/linux-2.6.18/atmel-husb2-udc-driver.patch
new file mode 100644 (file)
index 0000000..f46a8f1
--- /dev/null
@@ -0,0 +1,2488 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Fri Nov 18 18:13:25 2005 +0100
+Subject: [PATCH] Driver for the Atmel HUSB2 Device Controller
+
+This adds the driver for the Atmel HUSB2 Device Controller.
+
+---
+
+ drivers/usb/gadget/Kconfig        |   10 
+ drivers/usb/gadget/Makefile       |    1 
+ drivers/usb/gadget/gadget_chips.h |    8 
+ drivers/usb/gadget/husb2_udc.c    | 1998 ++++++++++++++++++++++++++++++++++++++
+ drivers/usb/gadget/husb2_udc.h    |  406 +++++++
+ 5 files changed, 2423 insertions(+)
+
+Index: linux-2.6.18-avr32/drivers/usb/gadget/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/usb/gadget/Kconfig 2006-11-02 15:54:18.000000000 +0100
++++ linux-2.6.18-avr32/drivers/usb/gadget/Kconfig      2006-11-02 15:56:20.000000000 +0100
+@@ -154,6 +154,16 @@ config USB_LH7A40X
+       default USB_GADGET
+       select USB_GADGET_SELECTED
++config USB_GADGET_HUSB2DEV
++      boolean "Atmel HUSB2DEVICE"
++      select USB_GADGET_DUALSPEED
++      depends on AVR32
++
++config USB_HUSB2DEV
++      tristate
++      depends on USB_GADGET_HUSB2DEV
++      default USB_GADGET
++      select USB_GADGET_SELECTED
+ config USB_GADGET_OMAP
+       boolean "OMAP USB Device Controller"
+Index: linux-2.6.18-avr32/drivers/usb/gadget/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/usb/gadget/Makefile        2006-11-02 15:54:18.000000000 +0100
++++ linux-2.6.18-avr32/drivers/usb/gadget/Makefile     2006-11-02 15:56:20.000000000 +0100
+@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_GOKU)         += goku_udc.o
+ obj-$(CONFIG_USB_OMAP)                += omap_udc.o
+ obj-$(CONFIG_USB_LH7A40X)     += lh7a40x_udc.o
+ obj-$(CONFIG_USB_AT91)                += at91_udc.o
++obj-$(CONFIG_USB_HUSB2DEV)    += husb2_udc.o
+ #
+ # USB gadget drivers
+Index: linux-2.6.18-avr32/drivers/usb/gadget/gadget_chips.h
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/usb/gadget/gadget_chips.h  2006-11-02 15:54:18.000000000 +0100
++++ linux-2.6.18-avr32/drivers/usb/gadget/gadget_chips.h       2006-11-02 15:56:20.000000000 +0100
+@@ -75,6 +75,12 @@
+ #define       gadget_is_pxa27x(g)     0
+ #endif
++#ifdef CONFIG_USB_GADGET_HUSB2DEV
++#define gadget_is_husb2dev(g) !strcmp("husb2_udc", (g)->name)
++#else
++#define gadget_is_husb2dev(g) 0
++#endif
++
+ #ifdef CONFIG_USB_GADGET_S3C2410
+ #define gadget_is_s3c2410(g)    !strcmp("s3c2410_udc", (g)->name)
+ #else
+@@ -169,5 +175,7 @@ static inline int usb_gadget_controller_
+               return 0x16;
+       else if (gadget_is_mpc8272(gadget))
+               return 0x17;
++      else if (gadget_is_husb2dev(gadget))
++              return 0x80;
+       return -ENOENT;
+ }
+Index: linux-2.6.18-avr32/drivers/usb/gadget/husb2_udc.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/drivers/usb/gadget/husb2_udc.c  2006-11-02 16:06:40.000000000 +0100
+@@ -0,0 +1,1998 @@
++/*
++ * Driver for the Atmel HUSB2device high speed USB device 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.
++ */
++#undef DEBUG
++
++#include <linux/config.h>
++#include <linux/clk.h>
++#include <linux/module.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/device.h>
++#include <linux/dma-mapping.h>
++#include <linux/list.h>
++#include <linux/platform_device.h>
++#include <linux/usb_ch9.h>
++#include <linux/usb_gadget.h>
++#include <linux/dmapool.h>
++#include <linux/delay.h>
++
++#include <asm/io.h>
++
++#include "husb2_udc.h"
++
++#define DRIVER_VERSION        "0.9"
++
++#define DMA_ADDR_INVALID (~(dma_addr_t)0)
++
++#define FIFO_IOMEM_ID 0
++#define CTRL_IOMEM_ID 1
++
++#ifdef DEBUG
++#define DBG_ERR               0x0001  /* report all error returns */
++#define DBG_HW                0x0002  /* debug hardware initialization */
++#define DBG_GADGET    0x0004  /* calls to/from gadget driver */
++#define DBG_INT               0x0008  /* interrupts */
++#define DBG_BUS               0x0010  /* report changes in bus state */
++#define DBG_QUEUE     0x0020  /* debug request queue processing */
++#define DBG_FIFO      0x0040  /* debug FIFO contents */
++#define DBG_DMA               0x0080  /* debug DMA handling */
++#define DBG_REQ               0x0100  /* print out queued request length */
++#define DBG_ALL               0xffff
++#define DBG_NONE      0x0000
++
++#define DEBUG_LEVEL   (DBG_ERR|DBG_REQ)
++#define DBG(level, fmt, ...)                                  \
++      do {                                                    \
++              if ((level) & DEBUG_LEVEL)                      \
++                      printk(KERN_DEBUG "udc: " fmt, ## __VA_ARGS__); \
++      } while (0)
++#else
++#define DBG(level, fmt...)
++#endif
++
++static struct husb2_udc the_udc;
++
++#ifdef CONFIG_DEBUG_FS
++#include <linux/debugfs.h>
++#include <asm/uaccess.h>
++
++static int queue_dbg_open(struct inode *inode, struct file *file)
++{
++      struct husb2_ep *ep = inode->u.generic_ip;
++      struct husb2_request *req, *req_copy;
++      struct list_head *queue_data;
++
++      queue_data = kmalloc(sizeof(*queue_data), GFP_KERNEL);
++      if (!queue_data)
++              return -ENOMEM;
++      INIT_LIST_HEAD(queue_data);
++
++      spin_lock_irq(&ep->udc->lock);
++      list_for_each_entry(req, &ep->queue, queue) {
++              req_copy = kmalloc(sizeof(*req_copy), GFP_ATOMIC);
++              if (!req_copy)
++                      goto fail;
++              memcpy(req_copy, req, sizeof(*req_copy));
++              list_add_tail(&req_copy->queue, queue_data);
++      }
++      spin_unlock_irq(&ep->udc->lock);
++
++      file->private_data = queue_data;
++      return 0;
++
++fail:
++      spin_unlock_irq(&ep->udc->lock);
++      list_for_each_entry_safe(req, req_copy, queue_data, queue) {
++              list_del(&req->queue);
++              kfree(req);
++      }
++      kfree(queue_data);
++      return -ENOMEM;
++}
++
++/*
++ * bbbbbbbb llllllll IZS sssss nnnn FDL\n\0
++ *
++ * b: buffer address
++ * l: buffer length
++ * I/i: interrupt/no interrupt
++ * Z/z: zero/no zero
++ * S/s: short ok/short not ok
++ * s: status
++ * n: nr_packets
++ * F/f: submitted/not submitted to FIFO
++ * D/d: using/not using DMA
++ * L/l: last transaction/not last transaction
++ */
++static ssize_t queue_dbg_read(struct file *file, char __user *buf,
++                            size_t nbytes, loff_t *ppos)
++{
++      struct list_head *queue = file->private_data;
++      struct husb2_request *req, *tmp_req;
++      size_t len, remaining, actual = 0;
++      char tmpbuf[38];
++
++      if (!access_ok(VERIFY_WRITE, buf, nbytes))
++              return -EFAULT;
++
++      mutex_lock(&file->f_dentry->d_inode->i_mutex);
++      list_for_each_entry_safe(req, tmp_req, queue, queue) {
++              len = snprintf(tmpbuf, sizeof(tmpbuf),
++                             "%8p %08x %c%c%c %5d %4u %c%c%c\n",
++                             req->req.buf, req->req.length,
++                             req->req.no_interrupt ? 'i' : 'I',
++                             req->req.zero ? 'Z' : 'z',
++                             req->req.short_not_ok ? 's' : 'S',
++                             req->req.status,
++                             req->nr_pkts,
++                             req->submitted ? 'F' : 'f',
++                             req->using_dma ? 'D' : 'd',
++                             req->last_transaction ? 'L' : 'l');
++              len = min(len, sizeof(tmpbuf));
++              if (len > nbytes)
++                      break;
++
++              list_del(&req->queue);
++              kfree(req);
++
++              remaining = __copy_to_user(buf, tmpbuf, len);
++              actual += len - remaining;
++              if (remaining)
++                      break;
++
++              nbytes -= len;
++              buf += len;
++      }
++      mutex_unlock(&file->f_dentry->d_inode->i_mutex);
++
++      return actual;
++}
++
++static int queue_dbg_release(struct inode *inode, struct file *file)
++{
++      struct list_head *queue_data = file->private_data;
++      struct husb2_request *req, *tmp_req;
++
++      list_for_each_entry_safe(req, tmp_req, queue_data, queue) {
++              list_del(&req->queue);
++              kfree(req);
++      }
++      kfree(queue_data);
++      return 0;
++}
++
++static int regs_dbg_open(struct inode *inode, struct file *file)
++{
++      struct husb2_udc *udc;
++      unsigned int i;
++      u32 *data;
++      int ret = -ENOMEM;
++
++      mutex_lock(&inode->i_mutex);
++      udc = inode->u.generic_ip;
++      data = kmalloc(inode->i_size, GFP_KERNEL);
++      if (!data)
++              goto out;
++
++      spin_lock_irq(&udc->lock);
++      for (i = 0; i < inode->i_size / 4; i++)
++              data[i] = __raw_readl(udc->regs + i * 4);
++      spin_unlock_irq(&udc->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;
++}
++
++const struct file_operations queue_dbg_fops = {
++      .owner          = THIS_MODULE,
++      .open           = queue_dbg_open,
++      .llseek         = no_llseek,
++      .read           = queue_dbg_read,
++      .release        = queue_dbg_release,
++};
++
++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 husb2_ep_init_debugfs(struct husb2_udc *udc,
++                                struct husb2_ep *ep)
++{
++      struct dentry *ep_root;
++
++      ep_root = debugfs_create_dir(ep_name(ep), udc->debugfs_root);
++      if (!ep_root)
++              goto err_root;
++      ep->debugfs_dir = ep_root;
++
++      ep->debugfs_queue = debugfs_create_file("queue", 0400, ep_root,
++                                              ep, &queue_dbg_fops);
++      if (!ep->debugfs_queue)
++              goto err_queue;
++
++      if (ep_can_dma(ep)) {
++              ep->debugfs_dma_status
++                      = debugfs_create_u32("dma_status", 0400, ep_root,
++                                           &ep->last_dma_status);
++              if (!ep->debugfs_dma_status)
++                      goto err_dma_status;
++      }
++
++      return;
++
++err_dma_status:
++      debugfs_remove(ep->debugfs_queue);
++err_queue:
++      debugfs_remove(ep_root);
++err_root:
++      dev_err(&ep->udc->pdev->dev,
++              "failed to create debugfs directory for %s\n", ep_name(ep));
++}
++
++static void husb2_ep_cleanup_debugfs(struct husb2_ep *ep)
++{
++      debugfs_remove(ep->debugfs_queue);
++      debugfs_remove(ep->debugfs_dma_status);
++      debugfs_remove(ep->debugfs_dir);
++      ep->debugfs_dma_status = NULL;
++      ep->debugfs_dir = NULL;
++}
++
++static void husb2_init_debugfs(struct husb2_udc *udc)
++{
++      struct dentry *root, *regs;
++      struct resource *regs_resource;
++
++      root = debugfs_create_dir(udc->gadget.name, NULL);
++      if (IS_ERR(root) || !root)
++              goto err_root;
++      udc->debugfs_root = root;
++
++      regs = debugfs_create_file("regs", 0400, root, udc, &regs_dbg_fops);
++      if (!regs)
++              goto err_regs;
++
++      regs_resource = platform_get_resource(udc->pdev, IORESOURCE_MEM,
++                                            CTRL_IOMEM_ID);
++      regs->d_inode->i_size = regs_resource->end - regs_resource->start + 1;
++      udc->debugfs_regs = regs;
++
++      husb2_ep_init_debugfs(udc, to_husb2_ep(udc->gadget.ep0));
++
++      return;
++
++err_regs:
++      debugfs_remove(root);
++err_root:
++      udc->debugfs_root = NULL;
++      dev_err(&udc->pdev->dev, "debugfs is not available\n");
++}
++
++static void husb2_cleanup_debugfs(struct husb2_udc *udc)
++{
++      husb2_ep_cleanup_debugfs(to_husb2_ep(udc->gadget.ep0));
++      debugfs_remove(udc->debugfs_regs);
++      debugfs_remove(udc->debugfs_root);
++      udc->debugfs_regs = NULL;
++      udc->debugfs_root = NULL;
++}
++#else
++static inline void husb2_ep_init_debugfs(struct husb2_udc *udc,
++                                       struct husb2_ep *ep)
++{
++
++}
++
++static inline void husb2_ep_cleanup_debugfs(struct husb2_ep *ep)
++{
++
++}
++
++static inline void husb2_init_debugfs(struct husb2_udc *udc)
++{
++
++}
++
++static inline void husb2_cleanup_debugfs(struct husb2_udc *udc)
++{
++
++}
++#endif
++
++static void copy_to_fifo(void __iomem *fifo, void *buf, int len)
++{
++      unsigned long tmp;
++
++      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 copy_from_fifo(void *buf, void __iomem *fifo, int len)
++{
++      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);
++              }
++      }
++}
++
++static void next_fifo_transaction(struct husb2_ep *ep,
++                                struct husb2_request *req)
++{
++      unsigned int transaction_len;
++
++      transaction_len = req->req.length - req->req.actual;
++      req->last_transaction = 1;
++      if (transaction_len > ep->ep.maxpacket) {
++              transaction_len = ep->ep.maxpacket;
++              req->last_transaction = 0;
++      } else if (transaction_len == ep->ep.maxpacket
++                 && req->req.zero) {
++              req->last_transaction = 0;
++      }
++      DBG(DBG_QUEUE, "%s: submit_transaction, req %p (length %d)%s\n",
++          ep_name(ep), req, transaction_len,
++          req->last_transaction ? ", done" : "");
++
++      copy_to_fifo(ep->fifo, req->req.buf + req->req.actual, transaction_len);
++      husb2_ep_writel(ep, SET_STA, HUSB2_BIT(TX_PK_RDY));
++      req->req.actual += transaction_len;
++}
++
++static void submit_request(struct husb2_ep *ep, struct husb2_request *req)
++{
++      DBG(DBG_QUEUE, "%s: submit_request: req %p (length %d)\n",
++          ep_name(ep), req, req->req.length);
++
++      req->req.actual = 0;
++      req->submitted = 1;
++
++      if (req->using_dma) {
++              if (req->req.length == 0) {
++                      husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(TX_PK_RDY));
++              } else {
++                      husb2_ep_writel(ep, CTL_DIS, HUSB2_BIT(TX_PK_RDY));
++                      husb2_dma_writel(ep, NXT_DSC,
++                                       req->packet[0].desc_dma);
++                      husb2_dma_writel(ep, CONTROL, HUSB2_BIT(DMA_LINK));
++              }
++      } else {
++              next_fifo_transaction(ep, req);
++              if (req->last_transaction)
++                      husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(TX_COMPLETE));
++              else
++                      husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(TX_PK_RDY));
++      }
++}
++
++static void submit_next_request(struct husb2_ep *ep)
++{
++      struct husb2_request *req;
++
++      if (list_empty(&ep->queue)) {
++              husb2_ep_writel(ep, CTL_DIS, (HUSB2_BIT(TX_PK_RDY)
++                                            | HUSB2_BIT(RX_BK_RDY)));
++              return;
++      }
++
++      req = list_entry(ep->queue.next, struct husb2_request, queue);
++      if (!req->submitted)
++              submit_request(ep, req);
++}
++
++static void send_status(struct husb2_udc *udc, struct husb2_ep *ep)
++{
++      ep->state = STATUS_STAGE_IN;
++      husb2_ep_writel(ep, SET_STA, HUSB2_BIT(TX_PK_RDY));
++      husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(TX_COMPLETE));
++}
++
++static void receive_data(struct husb2_ep *ep)
++{
++      struct husb2_udc *udc = ep->udc;
++      struct husb2_request *req;
++      unsigned long status;
++      unsigned int bytecount, nr_busy;
++      int is_complete = 0;
++
++      status = husb2_ep_readl(ep, STA);
++      nr_busy = HUSB2_BFEXT(BUSY_BANKS, status);
++
++      DBG(DBG_QUEUE, "receive data: nr_busy=%u\n", nr_busy);
++
++      while (nr_busy > 0) {
++              if (list_empty(&ep->queue)) {
++                      husb2_ep_writel(ep, CTL_DIS, HUSB2_BIT(RX_BK_RDY));
++                      break;
++              }
++              req = list_entry(ep->queue.next,
++                               struct husb2_request, queue);
++
++              bytecount = HUSB2_BFEXT(BYTE_COUNT, status);
++
++              if (status & (1 << 31))
++                      is_complete = 1;
++              if (req->req.actual + bytecount >= req->req.length) {
++                      is_complete = 1;
++                      bytecount = req->req.length - req->req.actual;
++              }
++
++              copy_from_fifo(req->req.buf + req->req.actual,
++                             ep->fifo, bytecount);
++              req->req.actual += bytecount;
++
++              husb2_ep_writel(ep, CLR_STA, HUSB2_BIT(RX_BK_RDY));
++
++              if (is_complete) {
++                      DBG(DBG_QUEUE, "%s: request done\n", ep_name(ep));
++                      req->req.status = 0;
++                      list_del_init(&req->queue);
++                      req->req.complete(&ep->ep, &req->req);
++              }
++
++              status = husb2_ep_readl(ep, STA);
++              nr_busy = HUSB2_BFEXT(BUSY_BANKS, status);
++
++              if (is_complete && ep_is_control(ep)) {
++                      BUG_ON(nr_busy != 0);
++                      send_status(udc, ep);
++                      break;
++              }
++      }
++}
++
++static void request_complete(struct husb2_ep *ep,
++                           struct husb2_request *req,
++                           int status)
++{
++      struct husb2_udc *udc = ep->udc;
++      int i;
++
++      BUG_ON(!list_empty(&req->queue));
++
++      if (req->req.status == -EINPROGRESS)
++              req->req.status = status;
++
++      if (req->packet) {
++              for (i = 0; i < req->nr_pkts; i++)
++                      dma_pool_free(udc->desc_pool, req->packet[i].desc,
++                                    req->packet[i].desc_dma);
++              kfree(req->packet);
++              req->packet = NULL;
++              dma_unmap_single(&udc->pdev->dev,
++                               req->req.dma, req->req.length,
++                               (ep_is_in(ep)
++                                ? DMA_TO_DEVICE : DMA_FROM_DEVICE));
++              req->req.dma = DMA_ADDR_INVALID;
++      }
++
++      DBG(DBG_GADGET | DBG_REQ,
++          "%s: req %p complete: status %d, actual %u\n",
++          ep_name(ep), req, req->req.status, req->req.actual);
++      req->req.complete(&ep->ep, &req->req);
++}
++
++static void request_complete_list(struct husb2_ep *ep,
++                                struct list_head *list,
++                                int status)
++{
++      struct husb2_request *req, *tmp_req;
++
++      list_for_each_entry_safe(req, tmp_req, list, queue) {
++              list_del_init(&req->queue);
++              request_complete(ep, req, status);
++      }
++}
++
++static int husb2_ep_enable(struct usb_ep *_ep,
++                         const struct usb_endpoint_descriptor *desc)
++{
++      struct husb2_ep *ep = to_husb2_ep(_ep);
++      struct husb2_udc *udc = ep->udc;
++      unsigned long flags, ept_cfg, maxpacket;
++
++      DBG(DBG_GADGET, "%s: ep_enable: desc=%p\n", ep_name(ep), desc);
++
++      maxpacket = le16_to_cpu(desc->wMaxPacketSize);
++
++      if (ep->index == 0
++          || desc->bDescriptorType != USB_DT_ENDPOINT
++          || ((desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK)
++              != ep->index)
++          || maxpacket == 0
++          || maxpacket > ep->fifo_size) {
++              DBG(DBG_ERR, "ep_enable: Invalid argument");
++              return -EINVAL;
++      }
++
++      if (((desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
++           == USB_ENDPOINT_XFER_ISOC)
++          && !(ep->capabilities & HUSB2_EP_CAP_ISOC)) {
++              DBG(DBG_ERR, "ep_enable: %s is not isoc capable\n",
++                  ep_name(ep));
++              return -EINVAL;
++      }
++
++      if (maxpacket <= 8)
++              ept_cfg = HUSB2_BF(EPT_SIZE, HUSB2_EPT_SIZE_8);
++      else
++              /* LSB is bit 1, not 0 */
++              ept_cfg = HUSB2_BF(EPT_SIZE, fls(maxpacket - 1) - 3);
++      DBG(DBG_HW, "%s: EPT_SIZE = %lu (maxpacket = %lu)\n",
++          ep_name(ep), ept_cfg, maxpacket);
++
++      if ((desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
++              ept_cfg |= HUSB2_BIT(EPT_DIR);
++
++      switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
++      case USB_ENDPOINT_XFER_CONTROL:
++              ept_cfg |= HUSB2_BF(EPT_TYPE, HUSB2_EPT_TYPE_CONTROL);
++              break;
++      case USB_ENDPOINT_XFER_ISOC:
++              ept_cfg |= HUSB2_BF(EPT_TYPE, HUSB2_EPT_TYPE_ISO);
++              break;
++      case USB_ENDPOINT_XFER_BULK:
++              ept_cfg |= HUSB2_BF(EPT_TYPE, HUSB2_EPT_TYPE_BULK);
++              break;
++      case USB_ENDPOINT_XFER_INT:
++              ept_cfg |= HUSB2_BF(EPT_TYPE, HUSB2_EPT_TYPE_INT);
++              break;
++      }
++      ept_cfg |= HUSB2_BF(BK_NUMBER, ep->nr_banks);
++
++      spin_lock_irqsave(&ep->udc->lock, flags);
++
++      if (ep->desc) {
++              spin_unlock_irqrestore(&ep->udc->lock, flags);
++              DBG(DBG_ERR, "ep%d already enabled\n", ep->index);
++              return -EBUSY;
++      }
++
++      ep->desc = desc;
++      ep->ep.maxpacket = maxpacket;
++
++      husb2_ep_writel(ep, CFG, ept_cfg);
++      husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(EPT_ENABLE));
++
++      if (ep_can_dma(ep)) {
++              husb2_writel(udc, INT_ENB,
++                           (husb2_readl(udc, INT_ENB)
++                            | HUSB2_BF(EPT_INT, 1 << ep->index)
++                            | HUSB2_BF(DMA_INT, 1 << ep->index)));
++              husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(AUTO_VALID));
++      } else {
++              husb2_writel(udc, INT_ENB,
++                           (husb2_readl(udc, INT_ENB)
++                            | HUSB2_BF(EPT_INT, 1 << ep->index)));
++      }
++
++      spin_unlock_irqrestore(&udc->lock, flags);
++
++      DBG(DBG_HW, "EPT_CFG%d after init: %#08lx\n", ep->index,
++          (unsigned long)husb2_ep_readl(ep, CFG));
++      DBG(DBG_HW, "INT_ENB after init: %#08lx\n",
++          (unsigned long)husb2_readl(udc, INT_ENB));
++
++      husb2_ep_init_debugfs(udc, ep);
++
++      return 0;
++}
++
++static int husb2_ep_disable(struct usb_ep *_ep)
++{
++      struct husb2_ep *ep = to_husb2_ep(_ep);
++      struct husb2_udc *udc = ep->udc;
++      LIST_HEAD(req_list);
++      unsigned long flags;
++
++      DBG(DBG_GADGET, "ep_disable: %s\n", ep_name(ep));
++
++      husb2_ep_cleanup_debugfs(ep);
++
++      spin_lock_irqsave(&udc->lock, flags);
++
++      if (!ep->desc) {
++              spin_unlock_irqrestore(&udc->lock, flags);
++              DBG(DBG_ERR, "ep_disable: %s not enabled\n",
++                  ep_name(ep));
++              return -EINVAL;
++      }
++      ep->desc = NULL;
++
++      list_splice_init(&ep->queue, &req_list);
++      if (ep_can_dma(ep)) {
++              husb2_dma_writel(ep, CONTROL, 0);
++              husb2_dma_writel(ep, ADDRESS, 0);
++              husb2_dma_readl(ep, STATUS);
++      }
++      husb2_ep_writel(ep, CTL_DIS, HUSB2_BIT(EPT_ENABLE));
++      husb2_writel(udc, INT_ENB, (husb2_readl(udc, INT_ENB)
++                                  & ~HUSB2_BF(EPT_INT, 1 << ep->index)));
++
++      spin_unlock_irqrestore(&udc->lock, flags);
++
++      request_complete_list(ep, &req_list, -ESHUTDOWN);
++
++      return 0;
++}
++
++static struct usb_request *
++husb2_ep_alloc_request(struct usb_ep *_ep, unsigned gfp_flags)
++{
++      struct husb2_request *req;
++
++      DBG(DBG_GADGET, "ep_alloc_request: %p, 0x%x\n", _ep, gfp_flags);
++
++      req = kzalloc(sizeof(*req), gfp_flags);
++      if (!req)
++              return NULL;
++
++      INIT_LIST_HEAD(&req->queue);
++      req->req.dma = DMA_ADDR_INVALID;
++
++      return &req->req;
++}
++
++static void
++husb2_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
++{
++      struct husb2_request *req = to_husb2_req(_req);
++
++      DBG(DBG_GADGET, "ep_free_request: %p, %p\n", _ep, _req);
++
++      kfree(req);
++}
++
++static void *husb2_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes,
++                                 dma_addr_t *dma, unsigned gfp_flags)
++{
++      struct husb2_ep *ep = to_husb2_ep(_ep);
++      void *buf;
++
++      /*
++       * We depend on kmalloc() returning cache-aligned memory. This
++       * is normally guaranteed as long as we allocate a whole
++       * cacheline or more.
++       *
++       * When CONFIG_DEBUG_SLAB is enabled, however, the slab
++       * allocator inserts red zones and ownership information,
++       * causing the slab objects to be misaligned.
++       *
++       * One alternative would be to use dma_alloc_coherent, but
++       * that would make us unable to allocate anything less than a
++       * page at a time.
++       */
++#ifdef CONFIG_DEBUG_SLAB
++# error The HUSB2 UDC driver breaks with SLAB debugging enabled
++#endif
++
++      if (bytes < L1_CACHE_BYTES)
++              bytes = L1_CACHE_BYTES;
++
++      buf = kmalloc(bytes, gfp_flags);
++
++      /*
++       * Seems like we have to map the buffer any chance we get.
++       * ether.c wants us to initialize the dma member of a
++       * different request than the one receiving the buffer, so one
++       * never knows...
++       *
++       * Ah, screw it.  The ether driver is probably wrong, and this
++       * is not the right place to do the mapping.  The driver
++       * shouldn't mess with our DMA mappings anyway.
++       */
++      *dma = DMA_ADDR_INVALID;
++
++      DBG(DBG_GADGET, "ep_alloc_buffer: %s, %u, 0x%x -> %p\n",
++          ep_name(ep), bytes, gfp_flags, buf);
++
++      return buf;
++}
++
++static void husb2_ep_free_buffer(struct usb_ep *_ep, void *buf,
++                               dma_addr_t dma, unsigned bytes)
++{
++      DBG(DBG_GADGET, "ep_free_buffer: %s, buf %p (size %u)\n",
++          _ep->name, buf, bytes);
++      kfree(buf);
++}
++
++static int queue_dma(struct husb2_udc *udc, struct husb2_ep *ep,
++                   struct husb2_request *req, unsigned int direction,
++                   gfp_t gfp_flags)
++{
++      struct husb2_packet *pkt, *prev_pkt;
++      unsigned int pkt_size, nr_pkts, i;
++      unsigned int residue;
++      dma_addr_t addr;
++      unsigned long flags;
++      u32 ctrl;
++
++      req->using_dma = 1;
++
++      if (req->req.length == 0) {
++              if (!req->req.zero)
++                      return -EINVAL;
++              req->send_zlp = 1;
++
++              spin_lock_irqsave(&udc->lock, flags);
++              husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(TX_PK_RDY));
++              list_add_tail(&req->queue, &ep->queue);
++              spin_unlock_irqrestore(&udc->lock, flags);
++
++              return 0;
++      }
++
++      if (req->req.dma == DMA_ADDR_INVALID)
++              req->req.dma = dma_map_single(&udc->pdev->dev,
++                                            req->req.buf,
++                                            req->req.length,
++                                            direction);
++      else
++              dma_sync_single_for_device(&udc->pdev->dev,
++                                         req->req.dma,
++                                         req->req.length,
++                                         direction);
++
++      pkt_size = ep->ep.maxpacket;
++      nr_pkts = req->req.length / pkt_size;
++      residue = req->req.length % pkt_size;
++      if (residue != 0)
++              nr_pkts++;
++      else if (req->req.zero && ep_is_in(ep))
++              /* ensure last packet is short */
++              req->send_zlp = 1;
++
++      req->nr_pkts = nr_pkts;
++
++      req->packet = kzalloc(sizeof(*req->packet) * nr_pkts, gfp_flags);
++      if (!req->packet)
++              goto out_of_memory;
++
++      addr = req->req.dma;
++      ctrl = (HUSB2_BF(DMA_BUF_LEN, pkt_size)
++              | HUSB2_BIT(DMA_CH_EN) | HUSB2_BIT(DMA_LINK)
++              | HUSB2_BIT(DMA_END_TR_EN) | HUSB2_BIT(DMA_END_TR_IE));
++      prev_pkt = NULL;
++      pkt = NULL;
++      DBG(DBG_DMA, "DMA descriptors:\n");
++      for (i = 0; i < nr_pkts; i++) {
++              pkt = &req->packet[i];
++              pkt->desc = dma_pool_alloc(udc->desc_pool, gfp_flags,
++                                         &pkt->desc_dma);
++              if (!pkt->desc)
++                      goto out_of_memory;
++
++              if (prev_pkt) {
++                      prev_pkt->desc->next = pkt->desc_dma;
++                      DBG(DBG_DMA, "[%d] n%08x a%08x c%08x\n",
++                          i - 1, prev_pkt->desc->next, prev_pkt->desc->addr,
++                          prev_pkt->desc->ctrl);
++              }
++              prev_pkt = pkt;
++
++              pkt->desc->addr = addr;
++              pkt->desc->ctrl = ctrl;
++              addr += pkt_size;
++      }
++
++      /* special care is needed for the last packet... */
++      ctrl = (HUSB2_BIT(DMA_CH_EN)
++              | HUSB2_BIT(DMA_END_TR_EN) | HUSB2_BIT(DMA_END_TR_IE)
++              | HUSB2_BIT(DMA_END_BUF_IE));
++      if (ep_is_in(ep))
++              ctrl |= HUSB2_BIT(DMA_END_BUF_EN);
++      if (req->req.zero || residue)
++              ctrl |= HUSB2_BF(DMA_BUF_LEN, residue);
++      else
++              ctrl |= HUSB2_BF(DMA_BUF_LEN, pkt_size);
++      pkt->desc->ctrl = ctrl;
++
++      DBG(DBG_DMA, "[%d] n%08x a%08x c%08x\n",
++          i - 1, prev_pkt->desc->next, prev_pkt->desc->addr,
++          prev_pkt->desc->ctrl);
++
++      /* Add this request to the queue and try to chain the DMA descriptors */
++      spin_lock_irqsave(&udc->lock, flags);
++
++      /* If the DMA controller is idle, start it */
++      if (list_empty(&ep->queue)) {
++              husb2_dma_writel(ep, NXT_DSC, req->packet[0].desc_dma);
++              husb2_dma_writel(ep, CONTROL, HUSB2_BIT(DMA_LINK));
++      }
++
++      list_add_tail(&req->queue, &ep->queue);
++
++      spin_unlock_irqrestore(&udc->lock, flags);
++
++      return 0;
++
++out_of_memory:
++      printk(KERN_ERR "ERROR: Could not allocate DMA memory for endpoint %s\n",
++             ep_name(ep));
++      if (req->packet) {
++              for (i = 0; i < nr_pkts; i++)
++                      if (req->packet[i].desc)
++                              dma_pool_free(udc->desc_pool,
++                                            req->packet[i].desc,
++                                            req->packet[i].desc_dma);
++              kfree(req->packet);
++      }
++
++      return -ENOMEM;
++}
++
++static int husb2_ep_queue(struct usb_ep *_ep, struct usb_request *_req,
++                        gfp_t gfp_flags)
++{
++      struct husb2_request *req = to_husb2_req(_req);
++      struct husb2_ep *ep = to_husb2_ep(_ep);
++      struct husb2_udc *udc = ep->udc;
++      unsigned long flags;
++      int direction_in = 0;
++
++      DBG(DBG_GADGET | DBG_QUEUE | DBG_REQ,
++          "%s: queue req %p, len %u\n", ep_name(ep), req, _req->length);
++
++      if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN)
++              return -ESHUTDOWN;
++      if (!ep->desc)
++              return -ENODEV;
++
++      req->nr_pkts = 0;
++      req->submitted = 0;
++      req->using_dma = 0;
++      req->last_transaction = 0;
++      req->send_zlp = 0;
++
++      BUG_ON(req->packet);
++
++      if (ep_is_in(ep)
++          || (ep_is_control(ep) && (ep->state == DATA_STAGE_IN
++                                    || ep->state == STATUS_STAGE_IN)))
++              direction_in = 1;
++
++      _req->status = -EINPROGRESS;
++      _req->actual = 0;
++
++      if (ep_can_dma(ep)) {
++              return queue_dma(udc, ep, req, (direction_in
++                                              ? DMA_TO_DEVICE
++                                              : DMA_FROM_DEVICE),
++                               gfp_flags);
++      } else {
++              spin_lock_irqsave(&udc->lock, flags);
++              list_add_tail(&req->queue, &ep->queue);
++
++              if (direction_in)
++                      husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(TX_PK_RDY));
++              else
++                      husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(RX_BK_RDY));
++              spin_unlock_irqrestore(&udc->lock, flags);
++      }
++
++      return 0;
++}
++
++static void husb2_update_req(struct husb2_ep *ep, struct husb2_request *req,
++                           u32 status)
++{
++      struct husb2_dma_desc *desc;
++      dma_addr_t from;
++      dma_addr_t addr;
++      size_t size;
++      unsigned int i;
++
++      addr = husb2_dma_readl(ep, ADDRESS);
++      req->req.actual = 0;
++
++      for (i = 0; i < req->nr_pkts; i++) {
++              desc = req->packet[i].desc;
++              from = desc->addr;
++              size = HUSB2_BFEXT(DMA_BUF_LEN, desc->ctrl);
++
++              req->req.actual += size;
++
++              DBG(DBG_DMA, " from=%#08x, size=%#zx\n", from, size);
++
++              if (from <= addr && (from + size) >= addr)
++                      break;
++      }
++
++      req->req.actual -= HUSB2_BFEXT(DMA_BUF_LEN, status);
++}
++
++static int stop_dma(struct husb2_ep *ep, u32 *pstatus)
++{
++      unsigned int timeout;
++      u32 status;
++
++      /*
++       * Stop the DMA controller. When writing both CH_EN
++       * and LINK to 0, the other bits are not affected.
++       */
++      husb2_dma_writel(ep, CONTROL, 0);
++
++      /* Wait for the FIFO to empty */
++      for (timeout = 40; timeout; --timeout) {
++              status = husb2_dma_readl(ep, STATUS);
++              if (!(status & HUSB2_BIT(DMA_CH_EN)))
++                      break;
++              udelay(1);
++      }
++
++      if (pstatus)
++              *pstatus = status;
++
++      if (timeout == 0) {
++              dev_err(&ep->udc->pdev->dev,
++                      "%s: timed out waiting for DMA FIFO to empty\n",
++                      ep_name(ep));
++              return -ETIMEDOUT;
++      }
++
++      return 0;
++}
++
++static int husb2_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
++{
++      struct husb2_ep *ep = to_husb2_ep(_ep);
++      struct husb2_udc *udc = ep->udc;
++      struct husb2_request *req = to_husb2_req(_req);
++      unsigned long flags;
++      u32 status;
++
++      DBG(DBG_GADGET | DBG_QUEUE, "ep_dequeue: %s, req %p\n", ep_name(ep), req);
++
++      spin_lock_irqsave(&udc->lock, flags);
++
++      if (req->using_dma) {
++              /*
++               * If this request is currently being transferred,
++               * stop the DMA controller and reset the FIFO.
++               */
++              if (ep->queue.next == &req->queue) {
++                      status = husb2_dma_readl(ep, STATUS);
++                      if (status & HUSB2_BIT(DMA_CH_EN))
++                              stop_dma(ep, &status);
++
++#ifdef CONFIG_DEBUG_FS
++                      ep->last_dma_status = status;
++#endif
++
++                      husb2_writel(udc, EPT_RST,
++                                   1 << ep_index(ep));
++
++                      husb2_update_req(ep, req, status);
++              }
++      }
++
++      /*
++       * Errors should stop the queue from advancing until the
++       * completion function returns.
++       */
++      list_del_init(&req->queue);
++      spin_unlock_irqrestore(&udc->lock, flags);
++
++      request_complete(ep, req, -ECONNRESET);
++
++      /* Process the next request if any */
++      spin_lock_irqsave(&udc->lock, flags);
++      submit_next_request(ep);
++      spin_unlock_irqrestore(&udc->lock, flags);
++
++      return 0;
++}
++
++static int husb2_ep_set_halt(struct usb_ep *_ep, int value)
++{
++      struct husb2_ep *ep = to_husb2_ep(_ep);
++      struct husb2_udc *udc = ep->udc;
++      unsigned long flags;
++      int ret = 0;
++
++      DBG(DBG_GADGET, "endpoint %s: %s HALT\n", ep_name(ep),
++          value ? "set" : "clear");
++
++      if (!ep->desc) {
++              DBG(DBG_ERR, "Attempted to halt uninitialized ep %s\n",
++                  ep_name(ep));
++              return -ENODEV;
++      }
++      if (ep_is_isochronous(ep)) {
++              DBG(DBG_ERR, "Attempted to halt isochronous ep %s\n",
++                  ep_name(ep));
++              return -ENOTTY;
++      }
++
++      spin_lock_irqsave(&udc->lock, flags);
++
++      /*
++       * We can't halt IN endpoints while there are still data to be
++       * transferred
++       */
++      if (!list_empty(&ep->queue)
++          || ((value && ep_is_in(ep)
++               && (husb2_ep_readl(ep, STA)
++                   & HUSB2_BF(BUSY_BANKS, -1L))))) {
++              ret = -EAGAIN;
++      } else {
++              if (value)
++                      husb2_ep_writel(ep, SET_STA, HUSB2_BIT(FORCE_STALL));
++              else
++                      husb2_ep_writel(ep, CLR_STA, (HUSB2_BIT(FORCE_STALL)
++                                                    | HUSB2_BIT(TOGGLE_SEQ)));
++              husb2_ep_readl(ep, STA);
++      }
++
++      spin_unlock_irqrestore(&udc->lock, flags);
++
++      return ret;
++}
++
++static int husb2_ep_fifo_status(struct usb_ep *_ep)
++{
++      struct husb2_ep *ep = to_husb2_ep(_ep);
++
++      return HUSB2_BFEXT(BYTE_COUNT, husb2_ep_readl(ep, STA));
++}
++
++static void husb2_ep_fifo_flush(struct usb_ep *_ep)
++{
++      struct husb2_ep *ep = to_husb2_ep(_ep);
++      struct husb2_udc *udc = ep->udc;
++
++      husb2_writel(udc, EPT_RST, 1 << ep->index);
++}
++
++struct usb_ep_ops husb2_ep_ops = {
++      .enable         = husb2_ep_enable,
++      .disable        = husb2_ep_disable,
++      .alloc_request  = husb2_ep_alloc_request,
++      .free_request   = husb2_ep_free_request,
++      .alloc_buffer   = husb2_ep_alloc_buffer,
++      .free_buffer    = husb2_ep_free_buffer,
++      .queue          = husb2_ep_queue,
++      .dequeue        = husb2_ep_dequeue,
++      .set_halt       = husb2_ep_set_halt,
++      .fifo_status    = husb2_ep_fifo_status,
++      .fifo_flush     = husb2_ep_fifo_flush,
++};
++
++static int husb2_udc_get_frame(struct usb_gadget *gadget)
++{
++      struct husb2_udc *udc = to_husb2_udc(gadget);
++
++      return HUSB2_BFEXT(FRAME_NUMBER, husb2_readl(udc, FNUM));
++}
++
++struct usb_gadget_ops husb2_udc_ops = {
++      .get_frame      = husb2_udc_get_frame,
++};
++
++#define EP(nam, type, idx, caps) {                            \
++      .ep     = {                                             \
++              .ops            = &husb2_ep_ops,                \
++              .name           = nam,                          \
++              .maxpacket      = type##_FIFO_SIZE,             \
++      },                                                      \
++      .udc            = &the_udc,                             \
++      .queue          = LIST_HEAD_INIT(husb2_ep[idx].queue),  \
++      .fifo_size      = type##_FIFO_SIZE,                     \
++      .nr_banks       = type##_NR_BANKS,                      \
++      .index          = idx,                                  \
++      .capabilities   = caps,                                 \
++}
++
++static struct husb2_ep husb2_ep[] = {
++      EP("ep0", EP0, 0, 0),
++      EP("ep1in-bulk", BULK, 1, HUSB2_EP_CAP_DMA),
++      EP("ep2out-bulk", BULK, 2, HUSB2_EP_CAP_DMA),
++      EP("ep3in-iso", ISO, 3, HUSB2_EP_CAP_DMA | HUSB2_EP_CAP_ISOC),
++      EP("ep4out-iso", ISO, 4, HUSB2_EP_CAP_DMA | HUSB2_EP_CAP_ISOC),
++      EP("ep5in-int", INT, 5, HUSB2_EP_CAP_DMA),
++      EP("ep6out-int", INT, 6, HUSB2_EP_CAP_DMA),
++};
++#undef EP
++
++static struct usb_endpoint_descriptor husb2_ep0_desc = {
++      .bLength = USB_DT_ENDPOINT_SIZE,
++      .bDescriptorType = USB_DT_ENDPOINT,
++      .bEndpointAddress = 0,
++      .bmAttributes = USB_ENDPOINT_XFER_CONTROL,
++      .wMaxPacketSize = __constant_cpu_to_le16(64),
++      /* FIXME: I have no idea what to put here */
++      .bInterval = 1,
++};
++
++static void nop_release(struct device *dev)
++{
++
++}
++
++static struct husb2_udc the_udc = {
++      .gadget = {
++              .ops            = &husb2_udc_ops,
++              .ep0            = &husb2_ep[0].ep,
++              .ep_list        = LIST_HEAD_INIT(the_udc.gadget.ep_list),
++              .is_dualspeed   = 1,
++              .name           = "husb2_udc",
++              .dev    = {
++                      .bus_id         = "gadget",
++                      .release        = nop_release,
++              },
++      },
++
++      .lock   = SPIN_LOCK_UNLOCKED,
++};
++
++static void udc_enable(struct husb2_udc *udc)
++{
++      struct husb2_ep *ep0 = &husb2_ep[0];
++
++      /* Enable the controller */
++      husb2_writel(udc, CTRL, HUSB2_BIT(EN_HUSB2));
++
++      /* Reset all endpoints and enable basic interrupts */
++      husb2_writel(udc, EPT_RST, ~0UL);
++      husb2_writel(udc, INT_ENB, (HUSB2_BIT(DET_SUSPEND)
++                                  | HUSB2_BIT(END_OF_RESET)
++                                  | HUSB2_BIT(END_OF_RESUME)));
++
++      /* Configure endpoint 0 */
++      ep0->desc = &husb2_ep0_desc;
++
++      husb2_writel(udc, EPT_RST, 1 << 0);
++      husb2_ep_writel(ep0, CTL_ENB, HUSB2_BIT(EPT_ENABLE));
++      husb2_ep_writel(ep0, CFG, (HUSB2_BF(EPT_SIZE, EP0_EPT_SIZE)
++                                 | HUSB2_BF(EPT_TYPE, HUSB2_EPT_TYPE_CONTROL)
++                                 | HUSB2_BF(BK_NUMBER, HUSB2_BK_NUMBER_ONE)));
++
++      husb2_ep_writel(ep0, CTL_ENB, HUSB2_BIT(RX_SETUP));
++      husb2_writel(udc, INT_ENB, (husb2_readl(udc, INT_ENB)
++                                  | HUSB2_BF(EPT_INT, 1)));
++
++      if (!(husb2_ep_readl(ep0, CFG) & HUSB2_BIT(EPT_MAPPED)))
++              dev_warn(&udc->pdev->dev,
++                     "WARNING: EP0 configuration is invalid!\n");
++}
++
++static void udc_disable(struct husb2_udc *udc)
++{
++      udc->gadget.speed = USB_SPEED_UNKNOWN;
++
++      husb2_writel(udc, CTRL, 0);
++}
++
++/*
++ * Called with interrupts disabled and udc->lock held.
++ */
++static void reset_all_endpoints(struct husb2_udc *udc)
++{
++      struct husb2_ep *ep;
++      struct husb2_request *req, *tmp_req;
++
++      husb2_writel(udc, EPT_RST, ~0UL);
++
++      ep = to_husb2_ep(udc->gadget.ep0);
++      list_for_each_entry_safe(req, tmp_req, &ep->queue, queue) {
++              list_del_init(&req->queue);
++              request_complete(ep, req, -ECONNRESET);
++      }
++      BUG_ON(!list_empty(&ep->queue));
++
++      list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
++              if (ep->desc)
++                      husb2_ep_disable(&ep->ep);
++      }
++}
++
++static struct husb2_ep *get_ep_by_addr(struct husb2_udc *udc, u16 wIndex)
++{
++      struct husb2_ep *ep;
++
++      if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
++              return to_husb2_ep(udc->gadget.ep0);
++
++      list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) {
++              u8 bEndpointAddress;
++
++              if (!ep->desc)
++                      continue;
++              bEndpointAddress = ep->desc->bEndpointAddress;
++              if ((wIndex ^ bEndpointAddress) & USB_DIR_IN)
++                      continue;
++              if ((wIndex & USB_ENDPOINT_NUMBER_MASK)
++                  == (bEndpointAddress & USB_ENDPOINT_NUMBER_MASK))
++                      return ep;
++      }
++
++      return NULL;
++}
++
++/* Called with interrupts disabled and udc->lock held */
++static inline void set_protocol_stall(struct husb2_udc *udc,
++                                    struct husb2_ep *ep)
++{
++      husb2_ep_writel(ep, SET_STA, HUSB2_BIT(FORCE_STALL));
++      ep->state = WAIT_FOR_SETUP;
++}
++
++static inline int is_stalled(struct husb2_udc *udc, struct husb2_ep *ep)
++{
++      if (husb2_ep_readl(ep, STA) & HUSB2_BIT(FORCE_STALL))
++              return 1;
++      return 0;
++}
++
++static inline void set_address(struct husb2_udc *udc, unsigned int addr)
++{
++      u32 regval;
++
++      DBG(DBG_BUS, "setting address %u...\n", addr);
++      regval = husb2_readl(udc, CTRL);
++      regval = HUSB2_BFINS(DEV_ADDR, addr, regval);
++      husb2_writel(udc, CTRL, regval);
++}
++
++static int handle_ep0_setup(struct husb2_udc *udc, struct husb2_ep *ep,
++                          struct usb_ctrlrequest *crq)
++{
++      switch (crq->bRequest) {
++      case USB_REQ_GET_STATUS: {
++              u16 status;
++
++              if (crq->bRequestType == (USB_DIR_IN | USB_RECIP_DEVICE)) {
++                      /* Self-powered, no remote wakeup */
++                      status = __constant_cpu_to_le16(1 << 0);
++              } else if (crq->bRequestType
++                         == (USB_DIR_IN | USB_RECIP_INTERFACE)) {
++                      status = __constant_cpu_to_le16(0);
++              } else if (crq->bRequestType
++                         == (USB_DIR_IN | USB_RECIP_ENDPOINT)) {
++                      struct husb2_ep *target;
++
++                      target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
++                      if (!target)
++                              goto stall;
++
++                      status = 0;
++                      if (is_stalled(udc, target))
++                              status |= __constant_cpu_to_le16(1);
++              } else {
++                      goto delegate;
++              }
++
++              /* Write directly to the FIFO. No queueing is done. */
++              if(crq->wLength != __constant_cpu_to_le16(sizeof(status)))
++                      goto stall;
++              ep->state = DATA_STAGE_IN;
++              __raw_writew(status, ep->fifo);
++              husb2_ep_writel(ep, SET_STA, HUSB2_BIT(TX_PK_RDY));
++              break;
++      }
++
++      case USB_REQ_CLEAR_FEATURE: {
++              if (crq->bRequestType == USB_RECIP_DEVICE) {
++                      /* We don't support TEST_MODE */
++                      goto stall;
++              } else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
++                      struct husb2_ep *target;
++
++                      if (crq->wValue != __constant_cpu_to_le16(USB_ENDPOINT_HALT)
++                          || crq->wLength != __constant_cpu_to_le16(0))
++                              goto stall;
++                      target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
++                      if (!target)
++                              goto stall;
++
++                      husb2_ep_writel(target, CLR_STA, (HUSB2_BIT(FORCE_STALL)
++                                                        | HUSB2_BIT(TOGGLE_SEQ)));
++              } else {
++                      goto delegate;
++              }
++
++              send_status(udc, ep);
++              break;
++      }
++
++      case USB_REQ_SET_FEATURE: {
++              if (crq->bRequestType == USB_RECIP_DEVICE) {
++                      /* We don't support TEST_MODE */
++                      goto stall;
++              } else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
++                      struct husb2_ep *target;
++
++                      if (crq->wValue != __constant_cpu_to_le16(USB_ENDPOINT_HALT)
++                          || crq->wLength != __constant_cpu_to_le16(0))
++                              goto stall;
++
++                      target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex));
++                      if (!target)
++                              goto stall;
++
++                      husb2_ep_writel(target, SET_STA, HUSB2_BIT(FORCE_STALL));
++              } else
++                      goto delegate;
++
++              send_status(udc, ep);
++              break;
++      }
++
++      case USB_REQ_SET_ADDRESS:
++              if (crq->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE))
++                      goto delegate;
++
++              set_address(udc, le16_to_cpu(crq->wValue));
++              send_status(udc, ep);
++              ep->state = STATUS_STAGE_ADDR;
++              break;
++
++      default:
++      delegate:
++              return udc->driver->setup(&udc->gadget, crq);
++      }
++
++      return 0;
++
++stall:
++      printk(KERN_ERR
++             "udc: %s: Invalid setup request: %02x.%02x v%04x i%04x l%d, "
++             "halting endpoint...\n",
++             ep_name(ep), crq->bRequestType, crq->bRequest,
++             le16_to_cpu(crq->wValue), le16_to_cpu(crq->wIndex),
++             le16_to_cpu(crq->wLength));
++      set_protocol_stall(udc, ep);
++      return -1;
++}
++
++static void husb2_control_irq(struct husb2_udc *udc, struct husb2_ep *ep)
++{
++      struct husb2_request *req;
++      u32 epstatus;
++      u32 epctrl;
++
++restart:
++      epstatus = husb2_ep_readl(ep, STA);
++      epctrl = husb2_ep_readl(ep, CTL);
++
++      DBG(DBG_INT, "%s: interrupt, status: 0x%08x\n",
++          ep_name(ep), epstatus);
++
++      req = NULL;
++      if (!list_empty(&ep->queue))
++              req = list_entry(ep->queue.next,
++                               struct husb2_request, queue);
++
++      if ((epctrl & HUSB2_BIT(TX_PK_RDY))
++          && !(epstatus & HUSB2_BIT(TX_PK_RDY))) {
++              DBG(DBG_BUS, "tx pk rdy: %d\n", ep->state);
++
++              if (req->submitted)
++                      next_fifo_transaction(ep, req);
++              else
++                      submit_request(ep, req);
++
++              if (req->last_transaction) {
++                      husb2_ep_writel(ep, CTL_DIS, HUSB2_BIT(TX_PK_RDY));
++                      husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(TX_COMPLETE));
++              }
++              goto restart;
++      }
++      if ((epstatus & epctrl) & HUSB2_BIT(TX_COMPLETE)) {
++              husb2_ep_writel(ep, CLR_STA, HUSB2_BIT(TX_COMPLETE));
++              DBG(DBG_BUS, "txc: %d\n", ep->state);
++
++              switch (ep->state) {
++              case DATA_STAGE_IN:
++                      husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(RX_BK_RDY));
++                      husb2_ep_writel(ep, CTL_DIS,
++                                      HUSB2_BIT(TX_COMPLETE));
++                      ep->state = STATUS_STAGE_OUT;
++                      break;
++              case STATUS_STAGE_ADDR:
++                      /* Activate our new address */
++                      husb2_writel(udc, CTRL, (husb2_readl(udc, CTRL)
++                                               | HUSB2_BIT(FADDR_EN)));
++                      husb2_ep_writel(ep, CTL_DIS,
++                                      HUSB2_BIT(TX_COMPLETE));
++                      ep->state = WAIT_FOR_SETUP;
++                      break;
++              case STATUS_STAGE_IN:
++                      if (req) {
++                              list_del_init(&req->queue);
++                              request_complete(ep, req, 0);
++                              submit_next_request(ep);
++                      }
++                      BUG_ON(!list_empty(&ep->queue));
++                      husb2_ep_writel(ep, CTL_DIS,
++                                      HUSB2_BIT(TX_COMPLETE));
++                      ep->state = WAIT_FOR_SETUP;
++                      break;
++              default:
++                      printk(KERN_ERR
++                             "udc: %s: TXCOMP: Invalid endpoint state %d, "
++                             "halting endpoint...\n",
++                             ep_name(ep), ep->state);
++                      set_protocol_stall(udc, ep);
++                      break;
++              }
++
++              goto restart;
++      }
++      if ((epstatus & epctrl) & HUSB2_BIT(RX_BK_RDY)) {
++              DBG(DBG_BUS, "rxc: %d\n", ep->state);
++
++              switch (ep->state) {
++              case STATUS_STAGE_OUT:
++                      husb2_ep_writel(ep, CLR_STA, HUSB2_BIT(RX_BK_RDY));
++
++                      if (req) {
++                              list_del_init(&req->queue);
++                              request_complete(ep, req, 0);
++                      }
++                      husb2_ep_writel(ep, CTL_DIS, HUSB2_BIT(RX_BK_RDY));
++                      ep->state = WAIT_FOR_SETUP;
++                      break;
++
++              case DATA_STAGE_OUT:
++                      receive_data(ep);
++                      break;
++
++              default:
++                      husb2_ep_writel(ep, CLR_STA, HUSB2_BIT(RX_BK_RDY));
++                      set_protocol_stall(udc, ep);
++                      printk(KERN_ERR
++                             "udc: %s: RXRDY: Invalid endpoint state %d, "
++                             "halting endpoint...\n",
++                             ep_name(ep), ep->state);
++                      break;
++              }
++
++              goto restart;
++      }
++      if (epstatus & HUSB2_BIT(RX_SETUP)) {
++              union {
++                      struct usb_ctrlrequest crq;
++                      unsigned long data[2];
++              } crq;
++              unsigned int pkt_len;
++              int ret;
++
++              if (ep->state != WAIT_FOR_SETUP) {
++                      /*
++                       * Didn't expect a SETUP packet at this
++                       * point. Clean up any pending requests (which
++                       * may be successful).
++                       */
++                      int status = -EPROTO;
++
++                      /*
++                       * RXRDY is dropped when SETUP packets arrive.
++                       * Just pretend we received the status packet.
++                       */
++                      if (ep->state == STATUS_STAGE_OUT)
++                              status = 0;
++
++                      if (req) {
++                              list_del_init(&req->queue);
++                              request_complete(ep, req, status);
++                      }
++                      BUG_ON(!list_empty(&ep->queue));
++              }
++
++              pkt_len = HUSB2_BFEXT(BYTE_COUNT, husb2_ep_readl(ep, STA));
++              DBG(DBG_HW, "Packet length: %u\n", pkt_len);
++              BUG_ON(pkt_len != sizeof(crq));
++
++              DBG(DBG_FIFO, "Copying ctrl request from 0x%p:\n", ep->fifo);
++              copy_from_fifo(crq.data, ep->fifo, sizeof(crq));
++
++              /* Free up one bank in the FIFO so that we can
++               * generate or receive a reply right away. */
++              husb2_ep_writel(ep, CLR_STA, HUSB2_BIT(RX_SETUP));
++
++              /* printk(KERN_DEBUG "setup: %d: %02x.%02x\n",
++                     ep->state, crq.crq.bRequestType,
++                     crq.crq.bRequest); */
++
++              if (crq.crq.bRequestType & USB_DIR_IN) {
++                      /*
++                       * The USB 2.0 spec states that "if wLength is
++                       * zero, there is no data transfer phase."
++                       * However, testusb #14 seems to actually
++                       * expect a data phase even if wLength = 0...
++                       */
++                      ep->state = DATA_STAGE_IN;
++              } else {
++                      if (crq.crq.wLength != __constant_cpu_to_le16(0))
++                              ep->state = DATA_STAGE_OUT;
++                      else
++                              ep->state = STATUS_STAGE_IN;
++              }
++
++              ret = -1;
++              if (ep->index == 0)
++                      ret = handle_ep0_setup(udc, ep, &crq.crq);
++              else
++                      ret = udc->driver->setup(&udc->gadget, &crq.crq);
++
++              DBG(DBG_BUS, "req %02x.%02x, length %d, state %d, ret %d\n",
++                  crq.crq.bRequestType, crq.crq.bRequest,
++                  le16_to_cpu(crq.crq.wLength), ep->state, ret);
++
++              if (ret < 0) {
++                      /* Let the host know that we failed */
++                      set_protocol_stall(udc, ep);
++              }
++      }
++}
++
++static void husb2_ep_irq(struct husb2_udc *udc, struct husb2_ep *ep)
++{
++      struct husb2_request *req;
++      u32 epstatus;
++      u32 epctrl;
++
++      epstatus = husb2_ep_readl(ep, STA);
++      epctrl = husb2_ep_readl(ep, CTL);
++
++      DBG(DBG_INT, "%s: interrupt, status: 0x%08x\n",
++          ep_name(ep), epstatus);
++
++      while ((epctrl & HUSB2_BIT(TX_PK_RDY))
++             && !(epstatus & HUSB2_BIT(TX_PK_RDY))) {
++              BUG_ON(!ep_is_in(ep));
++
++              DBG(DBG_BUS, "%s: TX PK ready\n", ep_name(ep));
++
++              if (list_empty(&ep->queue)) {
++                      dev_warn(&udc->pdev->dev, "ep_irq: queue empty\n");
++                      husb2_ep_writel(ep, CTL_DIS, HUSB2_BIT(TX_PK_RDY));
++                      return;
++              }
++
++              req = list_entry(ep->queue.next, struct husb2_request, queue);
++
++              if (req->using_dma) {
++                      BUG_ON(!req->send_zlp);
++
++                      /* Send a zero-length packet */
++                      husb2_ep_writel(ep, SET_STA,
++                                      HUSB2_BIT(TX_PK_RDY));
++                      husb2_ep_writel(ep, CTL_DIS,
++                                      HUSB2_BIT(TX_PK_RDY));
++                      list_del_init(&req->queue);
++                      submit_next_request(ep);
++                      request_complete(ep, req, 0);
++              } else {
++                      if (req->submitted)
++                              next_fifo_transaction(ep, req);
++                      else
++                              submit_request(ep, req);
++
++                      if (req->last_transaction) {
++                              list_del_init(&req->queue);
++                              submit_next_request(ep);
++                              request_complete(ep, req, 0);
++                      }
++              }
++
++              epstatus = husb2_ep_readl(ep, STA);
++              epctrl = husb2_ep_readl(ep, CTL);
++      }
++      if ((epstatus & epctrl) & HUSB2_BIT(RX_BK_RDY)) {
++              BUG_ON(ep_is_in(ep));
++
++              DBG(DBG_BUS, "%s: RX data ready\n", ep_name(ep));
++              receive_data(ep);
++              husb2_ep_writel(ep, CLR_STA, HUSB2_BIT(RX_BK_RDY));
++      }
++}
++
++static void husb2_dma_irq(struct husb2_udc *udc, struct husb2_ep *ep)
++{
++      struct husb2_request *req;
++      u32 status, control, pending;
++
++      status = husb2_dma_readl(ep, STATUS);
++      control = husb2_dma_readl(ep, CONTROL);
++#ifdef CONFIG_DEBUG_FS
++      ep->last_dma_status = status;
++#endif
++      pending = status & control;
++      DBG(DBG_INT, "dma irq, status=%#08x, pending=%#08x, control=%#08x\n",
++          status, pending, control);
++
++      BUG_ON(status & HUSB2_BIT(DMA_CH_EN));
++
++      if (list_empty(&ep->queue))
++              /* Might happen if a reset comes along at the right moment */
++              return;
++
++      if (pending & (HUSB2_BIT(DMA_END_TR_ST) | HUSB2_BIT(DMA_END_BUF_ST))) {
++              req = list_entry(ep->queue.next, struct husb2_request, queue);
++              husb2_update_req(ep, req, status);
++
++              if (req->send_zlp) {
++                      husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(TX_PK_RDY));
++              } else {
++                      list_del_init(&req->queue);
++                      submit_next_request(ep);
++                      request_complete(ep, req, 0);
++              }
++      }
++}
++
++static irqreturn_t husb2_udc_irq(int irq, void *devid, struct pt_regs *regs)
++{
++      struct husb2_udc *udc = devid;
++      u32 status;
++      u32 dma_status;
++      u32 ep_status;
++
++      spin_lock(&udc->lock);
++
++      status = husb2_readl(udc, INT_STA);
++      DBG(DBG_INT, "irq, status=%#08x\n", status);
++
++      if (status & HUSB2_BIT(DET_SUSPEND)) {
++              husb2_writel(udc, INT_CLR, HUSB2_BIT(DET_SUSPEND));
++              //DBG(DBG_BUS, "Suspend detected\n");
++              if (udc->gadget.speed != USB_SPEED_UNKNOWN
++                  && udc->driver && udc->driver->suspend)
++                      udc->driver->suspend(&udc->gadget);
++      }
++
++      if (status & HUSB2_BIT(WAKE_UP)) {
++              husb2_writel(udc, INT_CLR, HUSB2_BIT(WAKE_UP));
++              //DBG(DBG_BUS, "Wake Up CPU detected\n");
++      }
++
++      if (status & HUSB2_BIT(END_OF_RESUME)) {
++              husb2_writel(udc, INT_CLR, HUSB2_BIT(END_OF_RESUME));
++              DBG(DBG_BUS, "Resume detected\n");
++              if (udc->gadget.speed != USB_SPEED_UNKNOWN
++                  && udc->driver && udc->driver->resume)
++                      udc->driver->resume(&udc->gadget);
++      }
++
++      dma_status = HUSB2_BFEXT(DMA_INT, status);
++      if (dma_status) {
++              int i;
++
++              for (i = 1; i < HUSB2_NR_ENDPOINTS; i++)
++                      if (dma_status & (1 << i))
++                              husb2_dma_irq(udc, &husb2_ep[i]);
++      }
++
++      ep_status = HUSB2_BFEXT(EPT_INT, status);
++      if (ep_status) {
++              int i;
++
++              for (i = 0; i < HUSB2_NR_ENDPOINTS; i++)
++                      if (ep_status & (1 << i)) {
++                              if (ep_is_control(&husb2_ep[i]))
++                                      husb2_control_irq(udc, &husb2_ep[i]);
++                              else
++                                      husb2_ep_irq(udc, &husb2_ep[i]);
++                      }
++      }
++
++      if (status & HUSB2_BIT(END_OF_RESET)) {
++              husb2_writel(udc, INT_CLR, HUSB2_BIT(END_OF_RESET));
++              if (status & HUSB2_BIT(HIGH_SPEED)) {
++                      DBG(DBG_BUS, "High-speed bus reset detected\n");
++                      udc->gadget.speed = USB_SPEED_HIGH;
++              } else {
++                      DBG(DBG_BUS, "Full-speed bus reset detected\n");
++                      udc->gadget.speed = USB_SPEED_FULL;
++              }
++              /* Better start from scratch... */
++              reset_all_endpoints(udc);
++              husb2_ep[0].state = WAIT_FOR_SETUP;
++              udc_enable(udc);
++      }
++
++      spin_unlock(&udc->lock);
++
++      return IRQ_HANDLED;
++}
++
++int usb_gadget_register_driver(struct usb_gadget_driver *driver)
++{
++      struct husb2_udc *udc = &the_udc;
++      int ret;
++
++      spin_lock(&udc->lock);
++
++      ret = -ENODEV;
++      if (!udc->pdev)
++              goto out;
++      ret = -EBUSY;
++      if (udc->driver)
++              goto out;
++
++      udc->driver = driver;
++      udc->gadget.dev.driver = &driver->driver;
++
++      device_add(&udc->gadget.dev);
++      ret = driver->bind(&udc->gadget);
++      if (ret) {
++              DBG(DBG_ERR, "Could not bind to driver %s: error %d\n",
++                  driver->driver.name, ret);
++              device_del(&udc->gadget.dev);
++
++              udc->driver = NULL;
++              udc->gadget.dev.driver = NULL;
++              goto out;
++      }
++
++      /* TODO: Create sysfs files */
++
++      DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name);
++      udc_enable(udc);
++
++out:
++      spin_unlock(&udc->lock);
++      return ret;
++}
++EXPORT_SYMBOL(usb_gadget_register_driver);
++
++int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
++{
++      struct husb2_udc *udc = &the_udc;
++      int ret;
++
++      spin_lock(&udc->lock);
++
++      ret = -ENODEV;
++      if (!udc->pdev)
++              goto out;
++      ret = -EINVAL;
++      if (driver != udc->driver)
++              goto out;
++
++      local_irq_disable();
++      udc_disable(udc);
++      local_irq_enable();
++
++      driver->unbind(&udc->gadget);
++      udc->driver = NULL;
++
++      device_del(&udc->gadget.dev);
++
++      /* TODO: Remove sysfs files */
++
++      DBG(DBG_GADGET, "unregistered driver `%s'\n", driver->driver.name);
++
++out:
++      spin_unlock(&udc->lock);
++      return ret;
++}
++EXPORT_SYMBOL(usb_gadget_unregister_driver);
++
++static int __devinit husb2_udc_probe(struct platform_device *pdev)
++{
++      struct resource *regs, *fifo;
++      struct clk *pclk, *hclk;
++      struct husb2_udc *udc = &the_udc;
++      int irq, ret, i;
++
++      regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID);
++      fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID);
++      if (!regs || !fifo)
++              return -ENXIO;
++
++      irq = platform_get_irq(pdev, 0);
++      if (irq < 0)
++              return irq;
++
++      pclk = clk_get(&pdev->dev, "pclk");
++      if (IS_ERR(pclk))
++              return PTR_ERR(pclk);
++      hclk = clk_get(&pdev->dev, "hclk");
++      if (IS_ERR(hclk)) {
++              ret = PTR_ERR(hclk);
++              goto out_put_pclk;
++      }
++
++      clk_enable(pclk);
++      clk_enable(hclk);
++
++      udc->pdev = pdev;
++      udc->pclk = pclk;
++      udc->hclk = hclk;
++
++      ret = -ENOMEM;
++      udc->regs = ioremap(regs->start, regs->end - regs->start + 1);
++      if (!udc->regs) {
++              dev_err(&pdev->dev, "Unable to map I/O memory, aborting.\n");
++              goto out_disable_clocks;
++      }
++      dev_info(&pdev->dev, "MMIO registers at 0x%08lx mapped at %p\n",
++               (unsigned long)regs->start, udc->regs);
++      udc->fifo = ioremap(fifo->start, fifo->end - fifo->start + 1);
++      if (!udc->fifo) {
++              dev_err(&pdev->dev, "Unable to map FIFO, aborting.\n");
++              goto out_unmap_regs;
++      }
++      dev_info(&pdev->dev, "FIFO at 0x%08lx mapped at %p\n",
++               (unsigned long)fifo->start, udc->fifo);
++
++      device_initialize(&udc->gadget.dev);
++      udc->gadget.dev.parent = &pdev->dev;
++      udc->gadget.dev.dma_mask = pdev->dev.dma_mask;
++
++      /* The 3-word descriptors must be 4-word aligned... */
++      udc->desc_pool = dma_pool_create("husb2-desc", &pdev->dev,
++                                       sizeof(struct husb2_dma_desc),
++                                       16, 0);
++      if (!udc->desc_pool) {
++              dev_err(&pdev->dev, "Cannot create descriptor DMA pool\n");
++              goto out_unmap_fifo;
++      }
++
++      platform_set_drvdata(pdev, udc);
++
++      udc_disable(udc);
++
++      INIT_LIST_HEAD(&husb2_ep[0].ep.ep_list);
++      husb2_ep[0].ep_regs = udc->regs + HUSB2_EPT_BASE(0);
++      husb2_ep[0].dma_regs = udc->regs + HUSB2_DMA_BASE(0);
++      husb2_ep[0].fifo = udc->fifo + HUSB2_FIFO_BASE(0);
++      for (i = 1; i < ARRAY_SIZE(husb2_ep); i++) {
++              struct husb2_ep *ep = &husb2_ep[i];
++
++              ep->ep_regs = udc->regs + HUSB2_EPT_BASE(i);
++              ep->dma_regs = udc->regs + HUSB2_DMA_BASE(i);
++              ep->fifo = udc->fifo + HUSB2_FIFO_BASE(i);
++
++              list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list);
++      }
++
++      ret = request_irq(irq, husb2_udc_irq, SA_SAMPLE_RANDOM,
++                        "husb2_udc", udc);
++      if (ret) {
++              dev_err(&pdev->dev, "Cannot request irq %d (error %d)\n",
++                      irq, ret);
++              goto out_free_pool;
++      }
++      udc->irq = irq;
++
++      husb2_init_debugfs(udc);
++
++      return 0;
++
++out_free_pool:
++      dma_pool_destroy(udc->desc_pool);
++out_unmap_fifo:
++      iounmap(udc->fifo);
++out_unmap_regs:
++      iounmap(udc->regs);
++out_disable_clocks:
++      clk_disable(hclk);
++      clk_disable(pclk);
++      clk_put(hclk);
++out_put_pclk:
++      clk_put(pclk);
++
++      platform_set_drvdata(pdev, NULL);
++
++      return ret;
++}
++
++static int __devexit husb2_udc_remove(struct platform_device *pdev)
++{
++      struct husb2_udc *udc;
++
++      udc = platform_get_drvdata(pdev);
++      if (!udc)
++              return 0;
++
++      husb2_cleanup_debugfs(udc);
++
++      free_irq(udc->irq, udc);
++      dma_pool_destroy(udc->desc_pool);
++      iounmap(udc->fifo);
++      iounmap(udc->regs);
++      clk_disable(udc->hclk);
++      clk_disable(udc->pclk);
++      clk_put(udc->hclk);
++      clk_put(udc->pclk);
++      platform_set_drvdata(pdev, NULL);
++
++      return 0;
++}
++
++static struct platform_driver udc_driver = {
++      .probe          = husb2_udc_probe,
++      .remove         = __devexit_p(husb2_udc_remove),
++      .driver         = {
++              .name           = "usb",
++      },
++};
++
++static int __init udc_init(void)
++{
++      printk(KERN_INFO "husb2device: Driver version %s\n", DRIVER_VERSION);
++      return platform_driver_register(&udc_driver);
++}
++module_init(udc_init);
++
++static void __exit udc_exit(void)
++{
++      platform_driver_unregister(&udc_driver);
++}
++module_exit(udc_exit);
++
++MODULE_DESCRIPTION("Atmel HUSB2 Device Controller driver");
++MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.18-avr32/drivers/usb/gadget/husb2_udc.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/drivers/usb/gadget/husb2_udc.h  2006-11-02 16:03:44.000000000 +0100
+@@ -0,0 +1,406 @@
++/*
++ * Driver for the Atmel HUSB2device high speed USB device 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 __LINUX_USB_GADGET_HUSB2_UDC_H__
++#define __LINUX_USB_GADGET_HUSB2_UDC_H__
++
++/* USB register offsets */
++#define HUSB2_CTRL                            0x0000
++#define HUSB2_FNUM                            0x0004
++#define HUSB2_INT_ENB                         0x0010
++#define HUSB2_INT_STA                         0x0014
++#define HUSB2_INT_CLR                         0x0018
++#define HUSB2_EPT_RST                         0x001c
++#define HUSB2_TST_SOF_CNT                     0x00d0
++#define HUSB2_TST_CNT_A                               0x00d4
++#define HUSB2_TST_CNT_B                               0x00d8
++#define HUSB2_TST_MODE_REG                    0x00dc
++#define HUSB2_TST                             0x00f0
++
++/* USB endpoint register offsets */
++#define HUSB2_EPT_CFG                         0x0000
++#define HUSB2_EPT_CTL_ENB                     0x0004
++#define HUSB2_EPT_CTL_DIS                     0x0008
++#define HUSB2_EPT_CTL                         0x000c
++#define HUSB2_EPT_SET_STA                     0x0014
++#define HUSB2_EPT_CLR_STA                     0x0018
++#define HUSB2_EPT_STA                         0x001c
++
++/* USB DMA register offsets */
++#define HUSB2_DMA_NXT_DSC                     0x0000
++#define HUSB2_DMA_ADDRESS                     0x0004
++#define HUSB2_DMA_CONTROL                     0x0008
++#define HUSB2_DMA_STATUS                      0x000c
++
++/* Bitfields in CTRL */
++#define HUSB2_DEV_ADDR_OFFSET                 0
++#define HUSB2_DEV_ADDR_SIZE                   7
++#define HUSB2_FADDR_EN_OFFSET                 7
++#define HUSB2_FADDR_EN_SIZE                   1
++#define HUSB2_EN_HUSB2_OFFSET                 8
++#define HUSB2_EN_HUSB2_SIZE                   1
++#define HUSB2_DETACH_OFFSET                   9
++#define HUSB2_DETACH_SIZE                     1
++#define HUSB2_REMOTE_WAKE_UP_OFFSET           10
++#define HUSB2_REMOTE_WAKE_UP_SIZE             1
++
++/* Bitfields in FNUM */
++#define HUSB2_MICRO_FRAME_NUM_OFFSET          0
++#define HUSB2_MICRO_FRAME_NUM_SIZE            3
++#define HUSB2_FRAME_NUMBER_OFFSET             3
++#define HUSB2_FRAME_NUMBER_SIZE                       11
++#define HUSB2_FRAME_NUM_ERROR_OFFSET          31
++#define HUSB2_FRAME_NUM_ERROR_SIZE            1
++
++/* Bitfields in INT_ENB/INT_STA/INT_CLR */
++#define HUSB2_HIGH_SPEED_OFFSET                       0
++#define HUSB2_HIGH_SPEED_SIZE                 1
++#define HUSB2_DET_SUSPEND_OFFSET              1
++#define HUSB2_DET_SUSPEND_SIZE                        1
++#define HUSB2_MICRO_SOF_OFFSET                        2
++#define HUSB2_MICRO_SOF_SIZE                  1
++#define HUSB2_SOF_OFFSET                      3
++#define HUSB2_SOF_SIZE                                1
++#define HUSB2_END_OF_RESET_OFFSET             4
++#define HUSB2_END_OF_RESET_SIZE                       1
++#define HUSB2_WAKE_UP_OFFSET                  5
++#define HUSB2_WAKE_UP_SIZE                    1
++#define HUSB2_END_OF_RESUME_OFFSET            6
++#define HUSB2_END_OF_RESUME_SIZE              1
++#define HUSB2_UPSTREAM_RESUME_OFFSET          7
++#define HUSB2_UPSTREAM_RESUME_SIZE            1
++#define HUSB2_EPT_INT_OFFSET                  8
++#define HUSB2_EPT_INT_SIZE                    16
++#define HUSB2_DMA_INT_OFFSET                  24
++#define HUSB2_DMA_INT_SIZE                    8
++
++/* Bitfields in EPT_RST */
++#define HUSB2_RST_OFFSET                      0
++#define HUSB2_RST_SIZE                                16
++
++/* Bitfields in TST_SOF_CNT */
++#define HUSB2_SOF_CNT_MAX_OFFSET              0
++#define HUSB2_SOF_CNT_MAX_SIZE                        7
++#define HUSB2_SOF_CNT_LOAD_OFFSET             7
++#define HUSB2_SOF_CNT_LOAD_SIZE                       1
++
++/* Bitfields in TST_CNT_A */
++#define HUSB2_CNT_A_MAX_OFFSET                        0
++#define HUSB2_CNT_A_MAX_SIZE                  7
++#define HUSB2_CNT_A_LOAD_OFFSET                       7
++#define HUSB2_CNT_A_LOAD_SIZE                 1
++
++/* Bitfields in TST_CNT_B */
++#define HUSB2_CNT_B_MAX_OFFSET                        0
++#define HUSB2_CNT_B_MAX_SIZE                  7
++#define HUSB2_CNT_B_LOAD_OFFSET                       7
++#define HUSB2_CNT_B_LOAD_SIZE                 1
++
++/* Bitfields in TST_MODE_REG */
++#define HUSB2_TST_MODE_OFFSET                 0
++#define HUSB2_TST_MODE_SIZE                   6
++
++/* Bitfields in HUSB2_TST */
++#define HUSB2_SPEED_CFG_OFFSET                        0
++#define HUSB2_SPEED_CFG_SIZE                  2
++#define HUSB2_TST_J_MODE_OFFSET                       2
++#define HUSB2_TST_J_MODE_SIZE                 1
++#define HUSB2_TST_K_MODE_OFFSET                       3
++#define HUSB2_TST_K_MODE_SIZE                 1
++#define HUSB2_TST_PKT_MODE_OFFSE              4
++#define HUSB2_TST_PKT_MODE_SIZE                       1
++#define HUSB2_OPMODE2_OFFSET                  5
++#define HUSB2_OPMODE2_SIZE                    1
++
++/* Bitfields in EPT_CFG */
++#define HUSB2_EPT_SIZE_OFFSET                 0
++#define HUSB2_EPT_SIZE_SIZE                   3
++#define HUSB2_EPT_DIR_OFFSET                  3
++#define HUSB2_EPT_DIR_SIZE                    1
++#define HUSB2_EPT_TYPE_OFFSET                 4
++#define HUSB2_EPT_TYPE_SIZE                   2
++#define HUSB2_BK_NUMBER_OFFSET                        6
++#define HUSB2_BK_NUMBER_SIZE                  2
++#define HUSB2_NB_TRANS_OFFSET                 8
++#define HUSB2_NB_TRANS_SIZE                   2
++#define HUSB2_EPT_MAPPED_OFFSET                       31
++#define HUSB2_EPT_MAPPED_SIZE                 1
++
++/* Bitfields in EPT_CTL/EPT_CTL_ENB/EPT_CTL_DIS */
++#define HUSB2_EPT_ENABLE_OFFSET                       0
++#define HUSB2_EPT_ENABLE_SIZE                 1
++#define HUSB2_AUTO_VALID_OFFSET                       1
++#define HUSB2_AUTO_VALID_SIZE                 1
++#define HUSB2_INT_DIS_DMA_OFFSET              3
++#define HUSB2_INT_DIS_DMA_SIZE                        1
++#define HUSB2_NYET_DIS_OFFSET                 4
++#define HUSB2_NYET_DIS_SIZE                   1
++#define HUSB2_DATAX_RX_OFFSET                 6
++#define HUSB2_DATAX_RX_SIZE                   1
++#define HUSB2_MDATA_RX_OFFSET                 7
++#define HUSB2_MDATA_RX_SIZE                   1
++/* Bits 8-15 and 31 enable interrupts for respective bits in EPT_STA */
++#define HUSB2_BUSY_BANK_IE_OFFSET             18
++#define HUSB2_BUSY_BANK_IE_SIZE                       1
++
++/* Bitfields in EPT_SET_STA/EPT_CLR_STA/EPT_STA */
++#define HUSB2_FORCE_STALL_OFFSET              5
++#define HUSB2_FORCE_STALL_SIZE                        1
++#define HUSB2_TOGGLE_SEQ_OFFSET                       6
++#define HUSB2_TOGGLE_SEQ_SIZE                 2
++#define HUSB2_ERR_OVFLW_OFFSET                        8
++#define HUSB2_ERR_OVFLW_SIZE                  1
++#define HUSB2_RX_BK_RDY_OFFSET                        9
++#define HUSB2_RX_BK_RDY_SIZE                  1
++#define HUSB2_KILL_BANK_OFFSET                        9
++#define HUSB2_KILL_BANK_SIZE                  1
++#define HUSB2_TX_COMPLETE_OFFSET              10
++#define HUSB2_TX_COMPLETE_SIZE                        1
++#define HUSB2_TX_PK_RDY_OFFSET                        11
++#define HUSB2_TX_PK_RDY_SIZE                  1
++#define HUSB2_ISO_ERR_TRANS_OFFSET            11
++#define HUSB2_ISO_ERR_TRANS_SIZE              1
++#define HUSB2_RX_SETUP_OFFSET                 12
++#define HUSB2_RX_SETUP_SIZE                   1
++#define HUSB2_ISO_ERR_FLOW_OFFSET             12
++#define HUSB2_ISO_ERR_FLOW_SIZE                       1
++#define HUSB2_STALL_SENT_OFFSET                       13
++#define HUSB2_STALL_SENT_SIZE                 1
++#define HUSB2_ISO_ERR_CRC_OFFSET              13
++#define HUSB2_ISO_ERR_CRC_SIZE                        1
++#define HUSB2_ISO_ERR_NBTRANS_OFFSET          13
++#define HUSB2_ISO_ERR_NBTRANS_SIZE            1
++#define HUSB2_NAK_IN_OFFSET                   14
++#define HUSB2_NAK_IN_SIZE                     1
++#define HUSB2_ISO_ERR_FLUSH_OFFSET            14
++#define HUSB2_ISO_ERR_FLUSH_SIZE              1
++#define HUSB2_NAK_OUT_OFFSET                  15
++#define HUSB2_NAK_OUT_SIZE                    1
++#define HUSB2_CURRENT_BANK_OFFSET             16
++#define HUSB2_CURRENT_BANK_SIZE                       2
++#define HUSB2_BUSY_BANKS_OFFSET                       18
++#define HUSB2_BUSY_BANKS_SIZE                 2
++#define HUSB2_BYTE_COUNT_OFFSET                       20
++#define HUSB2_BYTE_COUNT_SIZE                 11
++#define HUSB2_SHORT_PACKET_OFFSET             31
++#define HUSB2_SHORT_PACKET_SIZE                       1
++
++/* Bitfields in DMA_CONTROL */
++#define HUSB2_DMA_CH_EN_OFFSET                        0
++#define HUSB2_DMA_CH_EN_SIZE                  1
++#define HUSB2_DMA_LINK_OFFSET                 1
++#define HUSB2_DMA_LINK_SIZE                   1
++#define HUSB2_DMA_END_TR_EN_OFFSET            2
++#define HUSB2_DMA_END_TR_EN_SIZE              1
++#define HUSB2_DMA_END_BUF_EN_OFFSET           3
++#define HUSB2_DMA_END_BUF_EN_SIZE             1
++#define HUSB2_DMA_END_TR_IE_OFFSET            4
++#define HUSB2_DMA_END_TR_IE_SIZE              1
++#define HUSB2_DMA_END_BUF_IE_OFFSET           5
++#define HUSB2_DMA_END_BUF_IE_SIZE             1
++#define HUSB2_DMA_DESC_LOAD_IE_OFFSET         6
++#define HUSB2_DMA_DESC_LOAD_IE_SIZE           1
++#define HUSB2_DMA_BURST_LOCK_OFFSET           7
++#define HUSB2_DMA_BURST_LOCK_SIZE             1
++#define HUSB2_DMA_BUF_LEN_OFFSET              16
++#define HUSB2_DMA_BUF_LEN_SIZE                        16
++
++/* Bitfields in DMA_STATUS */
++#define HUSB2_DMA_CH_ACTIVE_OFFSET            1
++#define HUSB2_DMA_CH_ACTIVE_SIZE              1
++#define HUSB2_DMA_END_TR_ST_OFFSET            4
++#define HUSB2_DMA_END_TR_ST_SIZE              1
++#define HUSB2_DMA_END_BUF_ST_OFFSET           5
++#define HUSB2_DMA_END_BUF_ST_SIZE             1
++#define HUSB2_DMA_DESC_LOAD_ST_OFFSET         6
++#define HUSB2_DMA_DESC_LOAD_ST_SIZE           1
++
++/* Constants for SPEED_CFG */
++#define HUSB2_SPEED_CFG_NORMAL                        0
++#define HUSB2_SPEED_CFG_FORCE_HIGH            2
++#define HUSB2_SPEED_CFG_FORCE_FULL            3
++
++/* Constants for EPT_SIZE */
++#define HUSB2_EPT_SIZE_8                      0
++#define HUSB2_EPT_SIZE_16                     1
++#define HUSB2_EPT_SIZE_32                     2
++#define HUSB2_EPT_SIZE_64                     3
++#define HUSB2_EPT_SIZE_128                    4
++#define HUSB2_EPT_SIZE_256                    5
++#define HUSB2_EPT_SIZE_512                    6
++#define HUSB2_EPT_SIZE_1024                   7
++
++/* Constants for EPT_TYPE */
++#define HUSB2_EPT_TYPE_CONTROL                        0
++#define HUSB2_EPT_TYPE_ISO                    1
++#define HUSB2_EPT_TYPE_BULK                   2
++#define HUSB2_EPT_TYPE_INT                    3
++
++/* Constants for BK_NUMBER */
++#define HUSB2_BK_NUMBER_ZERO                  0
++#define HUSB2_BK_NUMBER_ONE                   1
++#define HUSB2_BK_NUMBER_DOUBLE                        2
++#define HUSB2_BK_NUMBER_TRIPLE                        3
++
++/* Bit manipulation macros */
++#define HUSB2_BIT(name)                                               \
++      (1 << HUSB2_##name##_OFFSET)
++#define HUSB2_BF(name,value)                                  \
++      (((value) & ((1 << HUSB2_##name##_SIZE) - 1))           \
++       << HUSB2_##name##_OFFSET)
++#define HUSB2_BFEXT(name,value)                                       \
++      (((value) >> HUSB2_##name##_OFFSET)                     \
++       & ((1 << HUSB2_##name##_SIZE) - 1))
++#define HUSB2_BFINS(name,value,old)                           \
++      (((old) & ~(((1 << HUSB2_##name##_SIZE) - 1)            \
++                  << HUSB2_##name##_OFFSET))                  \
++       | HUSB2_BF(name,value))
++
++/* Register access macros */
++#define husb2_readl(udc,reg)                                  \
++      __raw_readl((udc)->regs + HUSB2_##reg)
++#define husb2_writel(udc,reg,value)                           \
++      __raw_writel((value), (udc)->regs + HUSB2_##reg)
++#define husb2_ep_readl(ep,reg)                                        \
++      __raw_readl((ep)->ep_regs + HUSB2_EPT_##reg)
++#define husb2_ep_writel(ep,reg,value)                         \
++      __raw_writel((value), (ep)->ep_regs + HUSB2_EPT_##reg)
++#define husb2_dma_readl(ep,reg)                                       \
++      __raw_readl((ep)->dma_regs + HUSB2_DMA_##reg)
++#define husb2_dma_writel(ep,reg,value)                                \
++      __raw_writel((value), (ep)->dma_regs + HUSB2_DMA_##reg)
++
++/* Calculate base address for a given endpoint or DMA controller */
++#define HUSB2_EPT_BASE(x)                     (0x100 + (x) * 0x20)
++#define HUSB2_DMA_BASE(x)                     (0x300 + (x) * 0x10)
++#define HUSB2_FIFO_BASE(x)                    ((x) << 16)
++
++/* Synth parameters */
++#define HUSB2_NR_ENDPOINTS    7
++
++#define EP0_FIFO_SIZE         64
++#define EP0_EPT_SIZE          HUSB2_EPT_SIZE_64
++#define EP0_NR_BANKS          1
++#define BULK_FIFO_SIZE                512
++#define BULK_EPT_SIZE         HUSB2_EPT_SIZE_512
++#define BULK_NR_BANKS         2
++#define ISO_FIFO_SIZE         1024
++#define ISO_EPT_SIZE          HUSB2_EPT_SIZE_1024
++#define ISO_NR_BANKS          3
++#define INT_FIFO_SIZE         64
++#define INT_EPT_SIZE          HUSB2_EPT_SIZE_64
++#define INT_NR_BANKS          3
++
++enum husb2_ctrl_state {
++      WAIT_FOR_SETUP,
++      DATA_STAGE_IN,
++      DATA_STAGE_OUT,
++      STATUS_STAGE_IN,
++      STATUS_STAGE_OUT,
++      STATUS_STAGE_ADDR,
++};
++/*
++  EP_STATE_IDLE,
++  EP_STATE_SETUP,
++  EP_STATE_IN_DATA,
++  EP_STATE_OUT_DATA,
++  EP_STATE_SET_ADDR_STATUS,
++  EP_STATE_RX_STATUS,
++  EP_STATE_TX_STATUS,
++  EP_STATE_HALT,
++*/
++
++struct husb2_dma_desc {
++      dma_addr_t next;
++      dma_addr_t addr;
++      u32 ctrl;
++};
++
++struct husb2_ep {
++      int                                     state;
++      void __iomem                            *ep_regs;
++      void __iomem                            *dma_regs;
++      void __iomem                            *fifo;
++      struct usb_ep                           ep;
++      struct husb2_udc                        *udc;
++
++      struct list_head                        queue;
++      const struct usb_endpoint_descriptor    *desc;
++
++      u16                                     fifo_size;
++      u8                                      nr_banks;
++      u8                                      index;
++      u8                                      capabilities;
++
++#ifdef CONFIG_DEBUG_FS
++      u32                                     last_dma_status;
++      struct dentry                           *debugfs_dir;
++      struct dentry                           *debugfs_queue;
++      struct dentry                           *debugfs_dma_status;
++#endif
++};
++#define HUSB2_EP_CAP_ISOC     0x0001
++#define HUSB2_EP_CAP_DMA      0x0002
++
++struct husb2_packet {
++      struct husb2_dma_desc                   *desc;
++      dma_addr_t                              desc_dma;
++};
++
++struct husb2_request {
++      struct usb_request                      req;
++      struct list_head                        queue;
++
++      struct husb2_packet                     *packet;
++      unsigned int                            nr_pkts;
++
++      unsigned int                            submitted:1;
++      unsigned int                            using_dma:1;
++      unsigned int                            last_transaction:1;
++      unsigned int                            send_zlp:1;
++};
++
++struct husb2_udc {
++      spinlock_t lock;
++
++      void __iomem *regs;
++      void __iomem *fifo;
++
++      struct dma_pool *desc_pool;
++
++      struct usb_gadget gadget;
++      struct usb_gadget_driver *driver;
++      struct platform_device *pdev;
++      int irq;
++      struct clk *pclk;
++      struct clk *hclk;
++
++#ifdef CONFIG_DEBUG_FS
++      struct dentry *debugfs_root;
++      struct dentry *debugfs_regs;
++#endif
++};
++
++#define to_husb2_ep(x) container_of((x), struct husb2_ep, ep)
++#define to_husb2_req(x) container_of((x), struct husb2_request, req)
++#define to_husb2_udc(x) container_of((x), struct husb2_udc, gadget)
++
++#define ep_index(ep)  ((ep)->index)
++#define ep_can_dma(ep)        ((ep)->capabilities & HUSB2_EP_CAP_DMA)
++#define ep_is_in(ep)  (((ep)->desc->bEndpointAddress                  \
++                               & USB_ENDPOINT_DIR_MASK)               \
++                       == USB_DIR_IN)
++#define ep_is_isochronous(ep)                                         \
++      (((ep)->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)        \
++       == USB_ENDPOINT_XFER_ISOC)
++#define ep_is_control(ep) (ep_index(ep) == 0)
++#define ep_name(ep)   ((ep)->ep.name)
++#define ep_is_idle(ep)        ((ep)->state == EP_STATE_IDLE)
++
++#endif /* __LINUX_USB_GADGET_HUSB2_H */
diff --git a/packages/linux/linux-2.6.18/atmel-lcdc-framebuffer-driver.patch b/packages/linux/linux-2.6.18/atmel-lcdc-framebuffer-driver.patch
new file mode 100644 (file)
index 0000000..d4c9204
--- /dev/null
@@ -0,0 +1,1192 @@
+---
+ drivers/video/Kconfig           |   22 +
+ drivers/video/Makefile          |    1 
+ drivers/video/fbmem.c           |    6 
+ drivers/video/sidsafb.c         |  805 ++++++++++++++++++++++++++++++++++++++++
+ include/asm-avr32/periph/lcdc.h |  271 +++++++++++++
+ include/linux/fb.h              |    3 
+ 6 files changed, 1107 insertions(+), 1 deletion(-)
+
+Index: linux-2.6.18-avr32/drivers/video/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/video/Kconfig      2006-11-02 15:54:18.000000000 +0100
++++ linux-2.6.18-avr32/drivers/video/Kconfig   2006-11-02 15:56:20.000000000 +0100
+@@ -271,6 +271,28 @@ config FB_SA1100
+         If you plan to use the LCD display with your SA-1100 system, say
+         Y here.
++config FB_SIDSA
++      tristate "SIDSA LCDC support"
++      select FB_CFB_FILLRECT
++      select FB_CFB_COPYAREA
++      select FB_CFB_IMAGEBLIT
++      depends on FB && AVR32
++      help
++        This enables support for the SIDSA LCD Controller.
++
++config FB_SIDSA_DEFAULT_BPP
++      int "SIDSA LCDC default color depth"
++      default 24
++      depends on FB_SIDSA
++      help
++        Specify the maximum color depth you want to be able to
++        support. This, together with the resolution of the LCD
++        panel, determines the amount of framebuffer memory allocated
++        when the driver is initialized.
++
++        Allowable values are 1, 2, 4, 8, 16, 24 and 32. If unsure,
++        say 24.
++
+ config FB_IMX
+       tristate "Motorola i.MX LCD support"
+       depends on FB && ARM && ARCH_IMX
+Index: linux-2.6.18-avr32/drivers/video/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/video/Makefile     2006-11-02 15:54:18.000000000 +0100
++++ linux-2.6.18-avr32/drivers/video/Makefile  2006-11-02 15:56:20.000000000 +0100
+@@ -75,6 +75,7 @@ obj-$(CONFIG_FB_HP300)            += hpf
+ obj-$(CONFIG_FB_G364)             += g364fb.o
+ obj-$(CONFIG_FB_SA1100)           += sa1100fb.o
+ obj-$(CONFIG_FB_SUN3)             += sun3fb.o
++obj-$(CONFIG_FB_SIDSA)                  += sidsafb.o
+ obj-$(CONFIG_FB_HIT)              += hitfb.o
+ obj-$(CONFIG_FB_EPSON1355)      += epson1355fb.o
+ obj-$(CONFIG_FB_PVR2)             += pvr2fb.o
+Index: linux-2.6.18-avr32/drivers/video/fbmem.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/video/fbmem.c      2006-11-02 15:54:18.000000000 +0100
++++ linux-2.6.18-avr32/drivers/video/fbmem.c   2006-11-02 15:56:20.000000000 +0100
+@@ -1153,6 +1153,7 @@ fb_mmap(struct file *file, struct vm_are
+       /* frame buffer memory */
+       start = info->fix.smem_start;
+       len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
++      pr_debug("fb_mmap: start = 0x%08lx, len = 0x%08lx\n", start, len);
+       if (off >= len) {
+               /* memory mapped io */
+               off -= len;
+@@ -1168,6 +1169,7 @@ fb_mmap(struct file *file, struct vm_are
+       if ((vma->vm_end - vma->vm_start + off) > len)
+               return -EINVAL;
+       off += start;
++      pr_debug("fb_mmap: off = 0x%08lx\n", off);
+       vma->vm_pgoff = off >> PAGE_SHIFT;
+       /* This is an IO map - tell maydump to skip this VMA */
+       vma->vm_flags |= VM_IO | VM_RESERVED;
+@@ -1198,6 +1200,10 @@ fb_mmap(struct file *file, struct vm_are
+       pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
+ #elif defined(__arm__) || defined(__sh__) || defined(__m32r__)
+       vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
++#elif defined(__avr32__)
++      vma->vm_page_prot = __pgprot((pgprot_val(vma->vm_page_prot)
++                                    & ~_PAGE_CACHABLE)
++                                   | (_PAGE_BUFFER | _PAGE_DIRTY));
+ #elif defined(__ia64__)
+       if (efi_range_is_wc(vma->vm_start, vma->vm_end - vma->vm_start))
+               vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+Index: linux-2.6.18-avr32/drivers/video/sidsafb.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/drivers/video/sidsafb.c 2006-11-02 16:07:55.000000000 +0100
+@@ -0,0 +1,805 @@
++/*
++ * Framebuffer Driver for Atmel/SIDSA LCD Controller
++ *
++ * 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.
++ */
++#undef DEBUG
++
++#include <linux/config.h>
++#include <linux/clk.h>
++#include <linux/kernel.h>
++#include <linux/dma-mapping.h>
++#include <linux/interrupt.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++#include <linux/delay.h>
++#include <linux/platform_device.h>
++
++#include <asm/arch/board.h>
++
++#include <asm/periph/lcdc.h>
++
++/* More or less configurable parameters */
++#define SIDSAFB_FIFO_SIZE             512
++#define SIDSAFB_DMA_BURST_LEN         8
++
++/* TODO: These should be autogenerated from part description file */
++#define LCDC_DISTYPE_STN_MONO         0
++#define LCDC_DISTYPE_STN_COLOR                1
++#define LCDC_DISTYPE_TFT              2
++#define LCDC_LUT                      0xc00
++
++struct sidsafb_info {
++      spinlock_t              lock;
++      struct fb_info *        info;
++      void __iomem *          regs;
++      unsigned long           irq_base;
++      wait_queue_head_t       vsync_wait;
++      unsigned int            guard_time;
++      struct clk              *hclk;
++      struct clk              *pixclk;
++      struct platform_device  *pdev;
++      u32                     pseudo_palette[16];
++};
++
++/*
++ * How large framebuffer to allocate if none was provided by the
++ * platform. This default is the smallest we can possibly get away
++ * with.
++ */
++static unsigned long fb_size = (320 * 240);
++
++#if 0
++static struct fb_videomode sony_modes[] = {
++      {
++              .refresh        = 48,
++              .xres           = 240,          .yres           = 160,
++              .pixclock       = 520833,
++
++              .left_margin    = 7,            .right_margin   = 9,
++              .upper_margin   = 19,           .lower_margin   = 20,
++              .hsync_len      = 9,            .vsync_len      = 2,
++
++              .sync           = 0,
++              .vmode          = FB_VMODE_NONINTERLACED,
++      },
++};
++#endif
++
++#if 0
++static struct fb_videomode vga_modes[] = {
++      {
++              .refresh        = 122,
++              .xres           = 320,          .yres           = 240,
++              .pixclock       = 80000,
++
++              .left_margin    = 10,           .right_margin   = 20,
++              .upper_margin   = 30,           .lower_margin   = 5,
++              .hsync_len      = 20,           .vsync_len      = 3,
++
++              .sync           = 0,
++              .vmode          = FB_VMODE_NONINTERLACED,
++      },
++      {
++              .refresh        = 70,
++              .xres           = 640,          .yres           = 480,
++              .pixclock       = 40000,
++
++              .left_margin    = 10,           .right_margin   = 20,
++              .upper_margin   = 30,           .lower_margin   = 5,
++              .hsync_len      = 20,           .vsync_len      = 3,
++
++              .sync           = 0,
++              .vmode          = FB_VMODE_NONINTERLACED,
++      },
++};
++#else
++static struct fb_videomode samsung_modes[] = {
++      {
++              .refresh        = 75,
++              .xres           = 320,          .yres           = 240,
++              .pixclock       = 145111,
++
++              .left_margin    = 17,           .right_margin   = 33,
++              .upper_margin   = 8,            .lower_margin   = 10,
++              .hsync_len      = 16,           .vsync_len      = 1,
++
++              .sync           = FB_SYNC_PCLK_RISING,
++              .vmode          = FB_VMODE_NONINTERLACED,
++      },
++};
++#endif
++
++#if 1
++static struct fb_monspecs default_monspecs = {
++      .modedb         = samsung_modes,
++      .manufacturer   = "SNG",
++      .monitor        = "LCD panel",
++      .serial_no      = "xxxx",
++      .ascii          = "yyyy",
++      .modedb_len     = ARRAY_SIZE(samsung_modes),
++      .hfmin          = 14820,
++      .hfmax          = 22230,
++      .vfmin          = 60,
++      .vfmax          = 90,
++      .dclkmax        = 30000000,
++};
++#endif
++
++#if 0
++static struct fb_monspecs default_monspecs = {
++      .modedb         = sony_modes,
++      .manufacturer   = "SNY",        /* 4 chars?!? */
++      .monitor        = "LCD panel",
++      .serial_no      = "xxxx",
++      .ascii          = "yyyy",
++      .modedb_len     = ARRAY_SIZE(sony_modes),
++      .hfmin          = 7000,
++      .hfmax          = 8000,
++      .vfmin          = 45,
++      .vfmax          = 50,
++};
++// #else
++static struct fb_monspecs default_monspecs = {
++      .modedb         = vga_modes,
++      .manufacturer   = "VGA",
++      .monitor        = "Generic VGA",
++      .serial_no      = "xxxx",
++      .ascii          = "yyyy",
++      .modedb_len     = ARRAY_SIZE(vga_modes),
++      .hfmin          = 30000,
++      .hfmax          = 64000,
++      .vfmin          = 50,
++      .vfmax          = 150,
++};
++#endif
++
++/* Driver defaults */
++static struct fb_fix_screeninfo sidsafb_fix __devinitdata = {
++      .id             = "sidsafb",
++      .type           = FB_TYPE_PACKED_PIXELS,
++      .visual         = FB_VISUAL_TRUECOLOR,
++      .xpanstep       = 1,
++      .ypanstep       = 1,
++      .ywrapstep      = 0,
++      .accel          = FB_ACCEL_NONE,
++};
++
++static void sidsafb_update_dma(struct fb_info *info,
++                             struct fb_var_screeninfo *var)
++{
++      struct sidsafb_info *sinfo = info->par;
++      struct fb_fix_screeninfo *fix = &info->fix;
++      unsigned long dma_addr;
++      unsigned long pixeloff;
++      unsigned long dma2dcfg;
++
++      dma_addr = (fix->smem_start + var->yoffset * fix->line_length
++                  + var->xoffset * var->bits_per_pixel / 8);
++
++      dma_addr &= ~3UL;
++      pixeloff = LCDC_MKBF(DMA2DCFG_PIXELOFF, var->xoffset * var->bits_per_pixel);
++
++      /* Set framebuffer DMA base address and pixel offset */
++      lcdc_writel(sinfo, DMABADDR1, dma_addr);
++      dma2dcfg = lcdc_readl(sinfo, DMA2DCFG);
++      dma2dcfg = LCDC_INSBF(DMA2DCFG_PIXELOFF, pixeloff, dma2dcfg);
++      lcdc_writel(sinfo, DMA2DCFG, dma2dcfg);
++
++      /* Update configuration */
++      lcdc_writel(sinfo, DMACON, (lcdc_readl(sinfo, DMACON)
++                                  | LCDC_BIT(DMACON_DMAUPDT)));
++}
++
++/**
++ *      sidsafb_check_var - Validates a var passed in.
++ *      @var: frame buffer variable screen structure
++ *      @info: frame buffer structure that represents a single frame buffer
++ *
++ *    Checks to see if the hardware supports the state requested by
++ *    var passed in. This function does not alter the hardware
++ *    state!!!  This means the data stored in struct fb_info and
++ *    struct sidsafb_info do not change. This includes the var
++ *    inside of struct fb_info.  Do NOT change these. This function
++ *    can be called on its own if we intent to only test a mode and
++ *    not actually set it. The stuff in modedb.c is a example of
++ *    this. If the var passed in is slightly off by what the
++ *    hardware can support then we alter the var PASSED in to what
++ *    we can do. If the hardware doesn't support mode change a
++ *    -EINVAL will be returned by the upper layers. You don't need
++ *    to implement this function then. If you hardware doesn't
++ *    support changing the resolution then this function is not
++ *    needed. In this case the driver would just provide a var that
++ *    represents the static state the screen is in.
++ *
++ *    Returns negative errno on error, or zero on success.
++ */
++static int sidsafb_check_var(struct fb_var_screeninfo *var,
++                           struct fb_info *info)
++{
++      unsigned long new_fb_size;
++
++      pr_debug("sidsafb_check_var:\n");
++      pr_debug("  resolution: %ux%u\n", var->xres, var->yres);
++      pr_debug("  pixclk:     %llu Hz\n", 1000000000000ULL / var->pixclock);
++      pr_debug("  bpp:        %u\n", var->bits_per_pixel);
++
++      new_fb_size = (var->xres_virtual * var->yres_virtual
++                     * ((var->bits_per_pixel + 7) / 8));
++      if (new_fb_size > info->fix.smem_len) {
++              printk(KERN_NOTICE
++                     "sidsafb: %uB framebuffer too small for %ux%ux%u\n",
++                     info->fix.smem_len, var->xres_virtual,
++                     var->yres_virtual, var->bits_per_pixel);
++              return -EINVAL;
++      }
++
++      /* Force same alignment for each line */
++      var->xres = (var->xres + 3) & ~3UL;
++      var->xres_virtual = (var->xres_virtual + 3) & ~3UL;
++
++      var->red.msb_right = var->green.msb_right = var->blue.msb_right = 0;
++      var->transp.offset = var->transp.length = 0;
++
++      switch (var->bits_per_pixel) {
++      case 2:
++      case 4:
++      case 8:
++              var->red.offset = var->green.offset = var->blue.offset = 0;
++              var->red.length = var->green.length = var->blue.length
++                      = var->bits_per_pixel;
++              break;
++      case 15:
++      case 16:
++              /*
++               * Bit 16 is the "intensity" bit, I think. Not sure
++               * what we're going to use that for...
++               */
++              var->red.offset = 0;
++              var->green.offset = 5;
++              var->blue.offset = 10;
++              var->red.length = 5;
++              var->green.length = 5;
++              var->blue.length = 5;
++              break;
++      case 24:
++      case 32:
++              var->red.offset = 16;
++              var->green.offset = 8;
++              var->blue.offset = 0;
++              var->red.length = var->green.length = var->blue.length = 8;
++              break;
++      default:
++              printk(KERN_NOTICE "sidsafb: color depth %d not supported\n",
++                     var->bits_per_pixel);
++              return -EINVAL;
++      }
++
++      var->xoffset = var->yoffset = 0;
++      var->red.msb_right = var->green.msb_right = var->blue.msb_right =
++              var->transp.msb_right = 0;
++
++      return 0;
++}
++
++/**
++ *      sidsafb_set_par - Alters the hardware state.
++ *      @info: frame buffer structure that represents a single frame buffer
++ *
++ *    Using the fb_var_screeninfo in fb_info we set the resolution
++ *    of the this particular framebuffer. This function alters the
++ *    par AND the fb_fix_screeninfo stored in fb_info. It doesn't
++ *    not alter var in fb_info since we are using that data. This
++ *    means we depend on the data in var inside fb_info to be
++ *    supported by the hardware.  sidsafb_check_var is always called
++ *    before sidsafb_set_par to ensure this.  Again if you can't
++ *    change the resolution you don't need this function.
++ *
++ */
++static int sidsafb_set_par(struct fb_info *info)
++{
++      struct sidsafb_info *sinfo = info->par;
++      unsigned long value;
++
++      pr_debug("sidsafb_set_par:\n");
++      pr_debug("  * resolution: %ux%u (%ux%u virtual)\n",
++               info->var.xres, info->var.yres,
++               info->var.xres_virtual, info->var.yres_virtual);
++
++      /* Turn off the LCD controller and the DMA controller */
++      pr_debug("writing 0x%08x to %p\n",
++               LCDC_MKBF(PWRCON_GUARD_TIME, sinfo->guard_time),
++               sinfo->regs + LCDC_PWRCON);
++      lcdc_writel(sinfo, PWRCON,
++                  LCDC_MKBF(PWRCON_GUARD_TIME, sinfo->guard_time));
++      pr_debug("writing 0 to %p\n", sinfo->regs + LCDC_DMACON);
++      lcdc_writel(sinfo, DMACON, 0);
++
++      info->fix.line_length = (info->var.xres_virtual
++                               * (info->var.bits_per_pixel / 8));
++
++      if (info->var.bits_per_pixel <= 8)
++              info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
++      else
++              info->fix.visual = FB_VISUAL_TRUECOLOR;
++
++      /* Re-initialize the DMA engine... */
++      pr_debug("  * update DMA engine\n");
++      sidsafb_update_dma(info, &info->var);
++
++      /* ...set frame size and burst length = 8 words (?) */
++      value = LCDC_MKBF(DMAFRMCFG_FRMSIZE,
++                        (info->var.yres * info->fix.line_length + 3) / 4);
++      value |= LCDC_MKBF(DMAFRMCFG_BRSTLEN, (SIDSAFB_DMA_BURST_LEN - 1));
++      lcdc_writel(sinfo, DMAFRMCFG, value);
++
++      /* ...set 2D configuration (necessary for xres_virtual != xres) */
++      value = LCDC_MKBF(DMA2DCFG_ADDRINC,
++                        info->var.xres_virtual - info->var.xres);
++      lcdc_writel(sinfo, DMA2DCFG, value);
++
++      /* ...wait for DMA engine to become idle... */
++      while (lcdc_readl(sinfo, DMACON) & LCDC_BIT(DMACON_DMABUSY))
++              msleep(10);
++
++      pr_debug("  * re-enable DMA engine\n");
++      /* ...and enable it with updated configuration */
++      lcdc_writel(sinfo, DMACON, (LCDC_BIT(DMACON_DMAEN)
++                                  | LCDC_BIT(DMACON_DMAUPDT)
++                                  | LCDC_BIT(DMACON_DMA2DEN)));
++
++      /* Now, the LCD core... */
++
++      /* Set pixel clock. */
++      value = (clk_get_rate(sinfo->pixclk) / 100000) * info->var.pixclock;
++      value /= 10000000;
++      value = (value + 1) / 2;
++      if (value == 0) {
++              printk("sidsafb: Bypassing lcdc_pclk divider\n");
++              lcdc_writel(sinfo, LCDCON1, LCDC_BIT(LCDCON1_BYPASS));
++      } else {
++              lcdc_writel(sinfo, LCDCON1, LCDC_MKBF(LCDCON1_CLKVAL, value - 1));
++      }
++
++      /* Initialize control register 2 */
++      value = (LCDC_BIT(LCDCON2_CLKMOD)
++               | LCDC_MKBF(LCDCON2_DISTYPE, LCDC_DISTYPE_TFT));
++      if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
++              value |= LCDC_BIT(LCDCON2_INVLINE);
++      if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
++              value |= LCDC_BIT(LCDCON2_INVFRAME);
++      if (info->var.sync & FB_SYNC_PCLK_RISING)
++              value |= LCDC_BIT(LCDCON2_INVCLK);
++
++      switch (info->var.bits_per_pixel) {
++      case 1: value |= LCDC_MKBF(LCDCON2_PIXELSIZE, 0); break;
++      case 2: value |= LCDC_MKBF(LCDCON2_PIXELSIZE, 1); break;
++      case 4: value |= LCDC_MKBF(LCDCON2_PIXELSIZE, 2); break;
++      case 8: value |= LCDC_MKBF(LCDCON2_PIXELSIZE, 3); break;
++      case 15: /* fall through */
++      case 16: value |= LCDC_MKBF(LCDCON2_PIXELSIZE, 4); break;
++      case 24: value |= LCDC_MKBF(LCDCON2_PIXELSIZE, 5); break;
++      case 32: value |= LCDC_MKBF(LCDCON2_PIXELSIZE, 6); break;
++      default: BUG(); break;
++      }
++      pr_debug("  * LCDCON2 = %08lx\n", value);
++      lcdc_writel(sinfo, LCDCON2, value);
++
++      /* Vertical timing */
++      value = LCDC_MKBF(LCDTIM1_VPW, info->var.vsync_len - 1);
++      value |= LCDC_MKBF(LCDTIM1_VBP, info->var.upper_margin);
++      value |= LCDC_MKBF(LCDTIM1_VFP, info->var.lower_margin);
++      pr_debug("  * LCDTIM1 = %08lx\n", value);
++      lcdc_writel(sinfo, LCDTIM1, value);
++
++      /* Horizontal timing */
++      value = LCDC_MKBF(LCDTIM2_HFP, info->var.right_margin - 1);
++      value |= LCDC_MKBF(LCDTIM2_HPW, info->var.hsync_len - 1);
++      value |= LCDC_MKBF(LCDTIM2_HBP, info->var.left_margin - 1);
++      pr_debug("  * LCDTIM2 = %08lx\n", value);
++      lcdc_writel(sinfo, LCDTIM2, value);
++
++      /* Display size */
++      value = LCDC_MKBF(LCDFRMCFG_LINESIZE, info->var.xres - 1);
++      value |= LCDC_MKBF(LCDFRMCFG_LINEVAL, info->var.yres - 1);
++      lcdc_writel(sinfo, LCDFRMCFG, value);
++
++      /* FIFO Threshold: Use formula from data sheet */
++      value = SIDSAFB_FIFO_SIZE - (2 * SIDSAFB_DMA_BURST_LEN + 3);
++      lcdc_writel(sinfo, LCDFIFO, value);
++
++      /* Toggle LCD_MODE every frame */
++      lcdc_writel(sinfo, LCDMVAL, 0);
++
++      /* Disable all interrupts */
++      lcdc_writel(sinfo, LCD_IDR, ~0UL);
++
++      /* Wait for the LCDC core to become idle and enable it */
++      while(lcdc_readl(sinfo, PWRCON) & LCDC_BIT(PWRCON_LCD_BUSY))
++              msleep(10);
++
++      pr_debug("  * re-enable LCD core\n");
++      lcdc_writel(sinfo, PWRCON,
++                  LCDC_MKBF(PWRCON_GUARD_TIME, sinfo->guard_time)
++                  | LCDC_BIT(PWRCON_LCD_PWR));
++
++      pr_debug("  * DONE\n");
++      return 0;
++}
++
++static inline u_int chan_to_field(u_int chan, const struct fb_bitfield *bf)
++{
++      chan &= 0xffff;
++      chan >>= 16 - bf->length;
++      return chan << bf->offset;
++}
++
++/**
++ *    sidsafb_setcolreg - Optional function. Sets a color register.
++ *      @regno: Which register in the CLUT we are programming
++ *      @red: The red value which can be up to 16 bits wide
++ *    @green: The green value which can be up to 16 bits wide
++ *    @blue:  The blue value which can be up to 16 bits wide.
++ *    @transp: If supported the alpha value which can be up to 16 bits wide.
++ *      @info: frame buffer info structure
++ *
++ *    Set a single color register. The values supplied have a 16 bit
++ *    magnitude which needs to be scaled in this function for the hardware.
++ *    Things to take into consideration are how many color registers, if
++ *    any, are supported with the current color visual. With truecolor mode
++ *    no color palettes are supported. Here a psuedo palette is created
++ *    which we store the value in pseudo_palette in struct fb_info. For
++ *    pseudocolor mode we have a limited color palette. To deal with this
++ *    we can program what color is displayed for a particular pixel value.
++ *    DirectColor is similar in that we can program each color field. If
++ *    we have a static colormap we don't need to implement this function.
++ *
++ *    Returns negative errno on error, or zero on success. In an
++ *    ideal world, this would have been the case, but as it turns
++ *    out, the other drivers return 1 on failure, so that's what
++ *    we're going to do.
++ */
++static int sidsafb_setcolreg(unsigned int regno, unsigned int red,
++                           unsigned int green, unsigned int blue,
++                           unsigned int transp, struct fb_info *info)
++{
++      struct sidsafb_info *sinfo = info->par;
++      unsigned int val;
++      u32 *pal;
++      int ret = 1;
++
++      if (info->var.grayscale)
++              red = green = blue = (19595 * red + 38470 * green
++                                    + 7471 * blue) >> 16;
++
++      switch (info->fix.visual) {
++      case FB_VISUAL_TRUECOLOR:
++              if (regno < 16) {
++                      pal = info->pseudo_palette;
++
++                      val  = chan_to_field(red, &info->var.red);
++                      val |= chan_to_field(green, &info->var.green);
++                      val |= chan_to_field(blue, &info->var.blue);
++
++                      pal[regno] = val;
++                      ret = 0;
++              }
++              break;
++
++      case FB_VISUAL_PSEUDOCOLOR:
++              if (regno < 256) {
++                      val  = ((red   >> 11) & 0x001f);
++                      val |= ((green >>  6) & 0x03e0);
++                      val |= ((blue  >>  1) & 0x7c00);
++
++                      /*
++                       * TODO: intensity bit. Maybe something like
++                       *   ~(red[10] ^ green[10] ^ blue[10]) & 1
++                       */
++
++                      lcdc_writel(sinfo, LUT + regno * 4, val);
++                      ret = 0;
++              }
++              break;
++      }
++
++      return ret;
++}
++
++static int sidsafb_pan_display(struct fb_var_screeninfo *var,
++                             struct fb_info *info)
++{
++      pr_debug("sidsafb_pan_display\n");
++
++      sidsafb_update_dma(info, var);
++
++      return 0;
++}
++
++static struct fb_ops sidsafb_ops = {
++      .owner          = THIS_MODULE,
++      .fb_check_var   = sidsafb_check_var,
++      .fb_set_par     = sidsafb_set_par,
++      .fb_setcolreg   = sidsafb_setcolreg,
++      .fb_pan_display = sidsafb_pan_display,
++      .fb_fillrect    = cfb_fillrect,
++      .fb_copyarea    = cfb_copyarea,
++      .fb_imageblit   = cfb_imageblit,
++};
++
++static irqreturn_t sidsafb_interrupt(int irq, void *dev_id,
++                                   struct pt_regs *regs)
++{
++      struct fb_info *info = dev_id;
++      struct sidsafb_info *sinfo = info->par;
++      u32 status;
++
++      status = lcdc_readl(sinfo, LCD_ISR);
++      while (status) {
++              if (status & LCDC_BIT(LCD_ISR_EOFIS)) {
++                      pr_debug("sidsafb: DMA End Of Frame interrupt\n");
++
++                      lcdc_writel(sinfo, LCD_ICR, LCDC_BIT(LCD_ICR_EOFIC));
++                      status &= ~LCDC_BIT(LCD_ISR_EOFIS);
++                      wake_up(&sinfo->vsync_wait);
++              }
++
++              if (status) {
++                      printk(KERN_ERR
++                             "LCDC: Interrupts still pending: 0x%x\n",
++                             status);
++                      lcdc_writel(sinfo, LCD_IDR, status);
++              }
++
++              status = lcdc_readl(sinfo, LCD_ISR);
++      }
++
++      return IRQ_HANDLED;
++}
++
++static void __devinit init_pseudo_palette(u32 *palette)
++{
++      static const u32 init_palette[16] = {
++              0x000000,
++              0xaa0000,
++              0x00aa00,
++              0xaa5500,
++              0x0000aa,
++              0xaa00aa,
++              0x00aaaa,
++              0xaaaaaa,
++              0x555555,
++              0xff5555,
++              0x55ff55,
++              0xffff55,
++              0x5555ff,
++              0xff55ff,
++              0x55ffff,
++              0xffffff
++      };
++
++      memcpy(palette, init_palette, sizeof(init_palette));
++}
++
++static int __devinit sidsafb_set_fbinfo(struct sidsafb_info *sinfo)
++{
++      struct fb_info *info = sinfo->info;
++
++      init_pseudo_palette(sinfo->pseudo_palette);
++
++      info->flags             = (FBINFO_DEFAULT
++                                 | FBINFO_PARTIAL_PAN_OK
++                                 | FBINFO_HWACCEL_XPAN
++                                 | FBINFO_HWACCEL_YPAN);
++      memcpy(&info->fix, &sidsafb_fix, sizeof(info->fix));
++      memcpy(&info->monspecs, &default_monspecs, sizeof(info->monspecs));
++      info->fbops             = &sidsafb_ops;
++      info->pseudo_palette    = sinfo->pseudo_palette;
++
++      init_waitqueue_head(&sinfo->vsync_wait);
++
++      return 0;
++}
++
++static int __devinit sidsafb_probe(struct platform_device *pdev)
++{
++      struct lcdc_platform_data *fb_data = pdev->dev.platform_data;
++      struct fb_info *info;
++      struct sidsafb_info *sinfo;
++      const struct resource *mmio_resource;
++      int ret;
++
++      pr_debug("sidsafb_probe BEGIN\n");
++
++      mmio_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!mmio_resource) {
++              dev_err(&pdev->dev, "no MMIO resource found\n");
++              return -ENXIO;
++      }
++
++      ret = -ENOMEM;
++      info = framebuffer_alloc(sizeof(struct sidsafb_info), &pdev->dev);
++      if (!info) {
++              dev_err(&pdev->dev, "failed to allocate memory\n");
++              goto out;
++      }
++
++      sinfo = info->par;
++      sinfo->info = info;
++      sinfo->pdev = pdev;
++      sinfo->guard_time = 1;
++
++      spin_lock_init(&sinfo->lock);
++      sidsafb_set_fbinfo(sinfo);
++      info->fix.mmio_start = mmio_resource->start;
++      info->fix.mmio_len = mmio_resource->end - mmio_resource->start + 1;
++      sinfo->irq_base = platform_get_irq(pdev, 0);
++
++      sinfo->hclk = clk_get(&pdev->dev, "hclk");
++      if (IS_ERR(sinfo->hclk)) {
++              dev_err(&pdev->dev, "failed to get hclk\n");
++              ret = PTR_ERR(sinfo->hclk);
++              goto free_info;
++      }
++      sinfo->pixclk = clk_get(&pdev->dev, "pixclk");
++      if (IS_ERR(sinfo->pixclk)) {
++              dev_err(&pdev->dev, "failed to get pixel clock\n");
++              ret = PTR_ERR(sinfo->hclk);
++              goto put_hclk;
++      }
++
++      clk_enable(sinfo->hclk);
++      clk_enable(sinfo->pixclk);
++
++      /* Use platform-supplied framebuffer memory if available */
++      if (fb_data && fb_data->fbmem_size != 0) {
++              info->fix.smem_start = fb_data->fbmem_start;
++              info->fix.smem_len = fb_data->fbmem_size;
++              info->screen_base = ioremap(info->fix.smem_start,
++                                          info->fix.smem_len);
++      } else {
++              dma_addr_t paddr;
++
++              info->fix.smem_len = fb_size;
++              info->screen_base = dma_alloc_coherent(&pdev->dev, fb_size,
++                                                     &paddr, GFP_KERNEL);
++              info->fix.smem_start = paddr;
++      }
++
++      if (!info->screen_base) {
++              printk(KERN_ERR "sidsafb: Could not allocate framebuffer\n");
++              goto disable_clocks;
++      }
++
++      sinfo->regs = ioremap(info->fix.mmio_start, info->fix.mmio_len);
++      if (!sinfo->regs) {
++              printk(KERN_ERR "sidsafb: Could not map LCDC registers\n");
++              goto free_fb;
++      }
++
++      ret = fb_find_mode(&info->var, info, NULL, info->monspecs.modedb,
++                         info->monspecs.modedb_len, info->monspecs.modedb,
++                         CONFIG_FB_SIDSA_DEFAULT_BPP);
++      if (!ret) {
++              printk(KERN_ERR "sidsafb: No suitable video mode found\n");
++              goto unmap_regs;
++      }
++
++      ret = request_irq(sinfo->irq_base, sidsafb_interrupt, 0,
++                        "sidsafb", info);
++      if (ret)
++              goto unmap_regs;
++
++      /* Allocate colormap */
++      if (fb_alloc_cmap(&info->cmap, 256, 0)) {
++              ret = -ENOMEM;
++              goto unregister_irqs;
++      }
++
++      /*
++       * Tell the world that we're ready to go
++       */
++      ret = register_framebuffer(info);
++      if (ret)
++              goto free_cmap;
++
++      printk("fb%d: Atmel LCDC at 0x%08lx (mapped at %p), irq %lu\n",
++             info->node, info->fix.mmio_start, sinfo->regs, sinfo->irq_base);
++
++      platform_set_drvdata(pdev, info);
++
++      memset_io(info->screen_base, 0, info->fix.smem_len);
++      info->var.activate |= FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
++      ret = fb_set_var(info, &info->var);
++      if (ret)
++              printk(KERN_WARNING
++                     "sidsafb: Unable to set display parameters\n");
++      info->var.activate &= ~(FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW);
++
++      pr_debug("sidsafb_probe SUCCESS\n");
++      return 0;
++
++
++free_cmap:
++      fb_dealloc_cmap(&info->cmap);
++unregister_irqs:
++      free_irq(sinfo->irq_base, info);
++unmap_regs:
++      iounmap(sinfo->regs);
++free_fb:
++      if (!fb_data || fb_data->fbmem_size == 0)
++              dma_free_coherent(&pdev->dev, info->fix.smem_len,
++                                (void __force *)info->screen_base,
++                                info->fix.smem_start);
++disable_clocks:
++      clk_disable(sinfo->pixclk);
++      clk_disable(sinfo->hclk);
++      clk_put(sinfo->pixclk);
++put_hclk:
++      clk_put(sinfo->hclk);
++free_info:
++      framebuffer_release(info);
++out:
++      pr_debug("sidsafb_probe FAILED\n");
++      return ret;
++}
++
++static int __devexit sidsafb_remove(struct platform_device *pdev)
++{
++      struct lcdc_platform_data *fb_data = pdev->dev.platform_data;
++      struct fb_info *info = platform_get_drvdata(pdev);
++      struct sidsafb_info *sinfo;
++
++      if (!info)
++              return 0;
++      sinfo = info->par;
++
++      /* TODO: Restore original state */
++      unregister_framebuffer(info);
++
++      fb_dealloc_cmap(&info->cmap);
++      free_irq(sinfo->irq_base, info);
++      iounmap(sinfo->regs);
++      if (!fb_data || fb_data->fbmem_size == 0)
++              dma_free_coherent(&pdev->dev, info->fix.smem_len,
++                                (void __force *)info->screen_base,
++                                info->fix.smem_start);
++      clk_disable(sinfo->hclk);
++      clk_put(sinfo->hclk);
++      platform_set_drvdata(pdev, NULL);
++      framebuffer_release(info);
++
++      return 0;
++}
++
++static struct platform_driver sidsafb_driver = {
++      .probe          = sidsafb_probe,
++      .remove         = __devexit_p(sidsafb_remove),
++      .driver         = {
++              .name           = "lcdc",
++      },
++};
++
++int __init sidsafb_init(void)
++{
++      return platform_driver_register(&sidsafb_driver);
++}
++
++static void __exit sidsafb_exit(void)
++{
++      platform_driver_unregister(&sidsafb_driver);
++}
++
++module_init(sidsafb_init);
++module_exit(sidsafb_exit);
++
++module_param(fb_size, ulong, 0644);
++MODULE_PARM_DESC(fb_size, "Minimum framebuffer size to allocate");
++
++MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
++MODULE_DESCRIPTION("Atmel/SIDSA LCD Controller framebuffer driver");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.18-avr32/include/asm-avr32/periph/lcdc.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/periph/lcdc.h 2006-11-02 16:08:35.000000000 +0100
+@@ -0,0 +1,271 @@
++/*
++ * Register definitions for Atmel/SIDSA LCD Controller
++ *
++ * 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 __ASM_AVR32_PERIPH_LCDC_H__
++#define __ASM_AVR32_PERIPH_LCDC_H__
++
++#define LCDC_CONTRAST_CTR                       0x00000840
++# define LCDC_CONTRAST_CTR_ENA_OFFSET           3
++# define LCDC_CONTRAST_CTR_ENA_SIZE             1
++# define LCDC_CONTRAST_CTR_POL_OFFSET           2
++# define LCDC_CONTRAST_CTR_POL_SIZE             1
++# define LCDC_CONTRAST_CTR_PS_OFFSET            0
++# define LCDC_CONTRAST_CTR_PS_SIZE              2
++#define LCDC_CONTRAST_VAL                       0x00000844
++# define LCDC_CONTRAST_VAL_CVAL_OFFSET          0
++# define LCDC_CONTRAST_VAL_CVAL_SIZE            8
++#define LCDC_DMABADDR1                          0x00000000
++# define LCDC_DMABADDR1_BADDR_U_OFFSET          0
++# define LCDC_DMABADDR1_BADDR_U_SIZE            32
++#define LCDC_DMABADDR2                          0x00000004
++# define LCDC_DMABADDR2_BADDR_L_OFFSET          0
++# define LCDC_DMABADDR2_BADDR_L_SIZE            32
++#define LCDC_DMACON                             0x0000001C
++# define LCDC_DMACON_DMABUSY_OFFSET             2
++# define LCDC_DMACON_DMABUSY_SIZE               1
++# define LCDC_DMACON_DMAEN_OFFSET               0
++# define LCDC_DMACON_DMAEN_SIZE                 1
++# define LCDC_DMACON_DMARST_OFFSET              1
++# define LCDC_DMACON_DMARST_SIZE                1
++# define LCDC_DMACON_DMAUPDT_OFFSET             3
++# define LCDC_DMACON_DMAUPDT_SIZE               1
++# define LCDC_DMACON_DMA2DEN_OFFSET             4
++# define LCDC_DMACON_DMA2DEN_SIZE               1
++#define LCDC_DMAFRMADD1                         0x00000010
++# define LCDC_DMAFRMADD1_FRMADD_U_OFFSET        0
++# define LCDC_DMAFRMADD1_FRMADD_U_SIZE          32
++#define LCDC_DMAFRMADD2                         0x00000014
++# define LCDC_DMAFRMADD2_FRMADD_L_OFFSET        0
++# define LCDC_DMAFRMADD2_FRMADD_L_SIZE          32
++#define LCDC_DMAFRMCFG                          0x00000018
++# define LCDC_DMAFRMCFG_BRSTLEN_OFFSET          24
++# define LCDC_DMAFRMCFG_BRSTLEN_SIZE            7
++# define LCDC_DMAFRMCFG_FRMSIZE_OFFSET          0
++# define LCDC_DMAFRMCFG_FRMSIZE_SIZE            23
++#define LCDC_DMAFRMPT1                          0x00000008
++# define LCDC_DMAFRMPT1_FRMPT_U_OFFSET          0
++# define LCDC_DMAFRMPT1_FRMPT_U_SIZE            23
++#define LCDC_DMAFRMPT2                          0x0000000C
++# define LCDC_DMAFRMPT2_FRMPT_L_OFFSET          0
++# define LCDC_DMAFRMPT2_FRMPT_L_SIZE            23
++#define LCDC_DMA2DCFG                           0x00000020
++# define LCDC_DMA2DCFG_ADDRINC_OFFSET           0
++# define LCDC_DMA2DCFG_ADDRINC_SIZE             16
++# define LCDC_DMA2DCFG_PIXELOFF_OFFSET          24
++# define LCDC_DMA2DCFG_PIXELOFF_SIZE            5
++#define LCDC_DP1_2                              0x0000081C
++# define LCDC_DP1_2_DP1_2_OFFSET                0
++# define LCDC_DP1_2_DP1_2_SIZE                  8
++#define LCDC_DP2_3                              0x00000828
++# define LCDC_DP2_3_DP2_3_OFFSET                0
++# define LCDC_DP2_3_DP2_3_SIZE                  12
++#define LCDC_DP3_4                              0x00000830
++# define LCDC_DP3_4_DP3_4_OFFSET                0
++# define LCDC_DP3_4_DP3_4_SIZE                  16
++#define LCDC_DP3_5                              0x00000824
++# define LCDC_DP3_5_DP3_5_OFFSET                0
++# define LCDC_DP3_5_DP3_5_SIZE                  20
++#define LCDC_DP4_5                              0x00000834
++# define LCDC_DP4_5_DP4_5_OFFSET                0
++# define LCDC_DP4_5_DP4_5_SIZE                  20
++#define LCDC_DP4_7                              0x00000820
++# define LCDC_DP4_7_DP4_7_OFFSET                0
++# define LCDC_DP4_7_DP4_7_SIZE                  28
++#define LCDC_DP5_7                              0x0000082C
++# define LCDC_DP5_7_DP5_7_OFFSET                0
++# define LCDC_DP5_7_DP5_7_SIZE                  28
++#define LCDC_DP6_7                              0x00000838
++# define LCDC_DP6_7_DP6_7_OFFSET                0
++# define LCDC_DP6_7_DP6_7_SIZE                  28
++#define LCDC_LCDCON1                            0x00000800
++# define LCDC_LCDCON1_BYPASS_OFFSET             0
++# define LCDC_LCDCON1_BYPASS_SIZE               1
++# define LCDC_LCDCON1_CLKVAL_OFFSET             12
++# define LCDC_LCDCON1_CLKVAL_SIZE               9
++# define LCDC_LCDCON1_LINECNT_OFFSET            21
++# define LCDC_LCDCON1_LINECNT_SIZE              11
++#define LCDC_LCDCON2                            0x00000804
++# define LCDC_LCDCON2_CLKMOD_OFFSET             15
++# define LCDC_LCDCON2_CLKMOD_SIZE               1
++# define LCDC_LCDCON2_DISTYPE_OFFSET            0
++# define LCDC_LCDCON2_DISTYPE_SIZE              2
++# define LCDC_LCDCON2_IFWIDTH_OFFSET            3
++# define LCDC_LCDCON2_IFWIDTH_SIZE              2
++# define LCDC_LCDCON2_INVCLK_OFFSET             11
++# define LCDC_LCDCON2_INVCLK_SIZE               1
++# define LCDC_LCDCON2_INVDVAL_OFFSET            12
++# define LCDC_LCDCON2_INVDVAL_SIZE              1
++# define LCDC_LCDCON2_INVFRAME_OFFSET           9
++# define LCDC_LCDCON2_INVFRAME_SIZE             1
++# define LCDC_LCDCON2_INVLINE_OFFSET            10
++# define LCDC_LCDCON2_INVLINE_SIZE              1
++# define LCDC_LCDCON2_INVVD_OFFSET              8
++# define LCDC_LCDCON2_INVVD_SIZE                1
++# define LCDC_LCDCON2_MEMOR_OFFSET              30
++# define LCDC_LCDCON2_MEMOR_SIZE                2
++# define LCDC_LCDCON2_PIXELSIZE_OFFSET          5
++# define LCDC_LCDCON2_PIXELSIZE_SIZE            3
++# define LCDC_LCDCON2_SCANMOD_OFFSET            2
++# define LCDC_LCDCON2_SCANMOD_SIZE              1
++#define LCDC_LCDFIFO                            0x00000814
++# define LCDC_LCDFIFO_FIFOTH_OFFSET             0
++# define LCDC_LCDFIFO_FIFOTH_SIZE               16
++#define LCDC_LCDFRMCFG                          0x00000810
++# define LCDC_LCDFRMCFG_LINESIZE_OFFSET         21
++# define LCDC_LCDFRMCFG_LINESIZE_SIZE           11
++# define LCDC_LCDFRMCFG_LINEVAL_OFFSET          0
++# define LCDC_LCDFRMCFG_LINEVAL_SIZE            11
++#define LCDC_LCDMVAL                            0x00000818
++# define LCDC_LCDMVAL_MMODE_OFFSET              31
++# define LCDC_LCDMVAL_MMODE_SIZE                1
++# define LCDC_LCDMVAL_MVAL_OFFSET               0
++# define LCDC_LCDMVAL_MVAL_SIZE                 8
++#define LCDC_LCDTIM1                            0x00000808
++# define LCDC_LCDTIM1_VBP_OFFSET                8
++# define LCDC_LCDTIM1_VBP_SIZE                  8
++# define LCDC_LCDTIM1_VFP_OFFSET                0
++# define LCDC_LCDTIM1_VFP_SIZE                  8
++# define LCDC_LCDTIM1_VHDLY_OFFSET              24
++# define LCDC_LCDTIM1_VHDLY_SIZE                4
++# define LCDC_LCDTIM1_VPW_OFFSET                16
++# define LCDC_LCDTIM1_VPW_SIZE                  6
++#define LCDC_LCDTIM2                            0x0000080C
++# define LCDC_LCDTIM2_HBP_OFFSET                0
++# define LCDC_LCDTIM2_HBP_SIZE                  8
++# define LCDC_LCDTIM2_HFP_OFFSET                21
++# define LCDC_LCDTIM2_HFP_SIZE                  11
++# define LCDC_LCDTIM2_HPW_OFFSET                8
++# define LCDC_LCDTIM2_HPW_SIZE                  6
++#define LCDC_LCD_GPR                            0x0000085C
++# define LCDC_LCD_GPR_GPRB0_OFFSET              0
++# define LCDC_LCD_GPR_GPRB0_SIZE                1
++# define LCDC_LCD_GPR_GPRB1_OFFSET              1
++# define LCDC_LCD_GPR_GPRB1_SIZE                1
++# define LCDC_LCD_GPR_GPRB2_OFFSET              2
++# define LCDC_LCD_GPR_GPRB2_SIZE                1
++# define LCDC_LCD_GPR_GPRB3_OFFSET              3
++# define LCDC_LCD_GPR_GPRB3_SIZE                1
++# define LCDC_LCD_GPR_GPRB4_OFFSET              4
++# define LCDC_LCD_GPR_GPRB4_SIZE                1
++# define LCDC_LCD_GPR_GPRB5_OFFSET              5
++# define LCDC_LCD_GPR_GPRB5_SIZE                1
++# define LCDC_LCD_GPR_GPRB6_OFFSET              6
++# define LCDC_LCD_GPR_GPRB6_SIZE                1
++# define LCDC_LCD_GPR_GPRB7_OFFSET              7
++# define LCDC_LCD_GPR_GPRB7_SIZE                1
++#define LCDC_LCD_ICR                            0x00000858
++# define LCDC_LCD_ICR_EOFIC_OFFSET              2
++# define LCDC_LCD_ICR_EOFIC_SIZE                1
++# define LCDC_LCD_ICR_LNIC_OFFSET               0
++# define LCDC_LCD_ICR_LNIC_SIZE                 1
++# define LCDC_LCD_ICR_LSTLNIC_OFFSET            1
++# define LCDC_LCD_ICR_LSTLNIC_SIZE              1
++# define LCDC_LCD_ICR_MERIC_OFFSET              6
++# define LCDC_LCD_ICR_MERIC_SIZE                1
++# define LCDC_LCD_ICR_OWRIC_OFFSET              5
++# define LCDC_LCD_ICR_OWRIC_SIZE                1
++# define LCDC_LCD_ICR_UFLWIC_OFFSET             4
++# define LCDC_LCD_ICR_UFLWIC_SIZE               1
++#define LCDC_LCD_IDR                            0x0000084C
++# define LCDC_LCD_IDR_EOFID_OFFSET              2
++# define LCDC_LCD_IDR_EOFID_SIZE                1
++# define LCDC_LCD_IDR_LNID_OFFSET               0
++# define LCDC_LCD_IDR_LNID_SIZE                 1
++# define LCDC_LCD_IDR_LSTLNID_OFFSET            1
++# define LCDC_LCD_IDR_LSTLNID_SIZE              1
++# define LCDC_LCD_IDR_MERID_OFFSET              6
++# define LCDC_LCD_IDR_MERID_SIZE                1
++# define LCDC_LCD_IDR_OWRID_OFFSET              5
++# define LCDC_LCD_IDR_OWRID_SIZE                1
++# define LCDC_LCD_IDR_UFLWID_OFFSET             4
++# define LCDC_LCD_IDR_UFLWID_SIZE               1
++#define LCDC_LCD_IER                            0x00000848
++# define LCDC_LCD_IER_EOFIE_OFFSET              2
++# define LCDC_LCD_IER_EOFIE_SIZE                1
++# define LCDC_LCD_IER_LNIE_OFFSET               0
++# define LCDC_LCD_IER_LNIE_SIZE                 1
++# define LCDC_LCD_IER_LSTLNIE_OFFSET            1
++# define LCDC_LCD_IER_LSTLNIE_SIZE              1
++# define LCDC_LCD_IER_MERIE_OFFSET              6
++# define LCDC_LCD_IER_MERIE_SIZE                1
++# define LCDC_LCD_IER_OWRIE_OFFSET              5
++# define LCDC_LCD_IER_OWRIE_SIZE                1
++# define LCDC_LCD_IER_UFLWIE_OFFSET             4
++# define LCDC_LCD_IER_UFLWIE_SIZE               1
++#define LCDC_LCD_IMR                            0x00000850
++# define LCDC_LCD_IMR_EOFIM_OFFSET              2
++# define LCDC_LCD_IMR_EOFIM_SIZE                1
++# define LCDC_LCD_IMR_LNIM_OFFSET               0
++# define LCDC_LCD_IMR_LNIM_SIZE                 1
++# define LCDC_LCD_IMR_LSTLNIM_OFFSET            1
++# define LCDC_LCD_IMR_LSTLNIM_SIZE              1
++# define LCDC_LCD_IMR_MERIM_OFFSET              6
++# define LCDC_LCD_IMR_MERIM_SIZE                1
++# define LCDC_LCD_IMR_OWRIM_OFFSET              5
++# define LCDC_LCD_IMR_OWRIM_SIZE                1
++# define LCDC_LCD_IMR_UFLWIM_OFFSET             4
++# define LCDC_LCD_IMR_UFLWIM_SIZE               1
++#define LCDC_LCD_IRR                            0x00000864
++# define LCDC_LCD_IRR_EOFIR_OFFSET              2
++# define LCDC_LCD_IRR_EOFIR_SIZE                1
++# define LCDC_LCD_IRR_LNIR_OFFSET               0
++# define LCDC_LCD_IRR_LNIR_SIZE                 1
++# define LCDC_LCD_IRR_LSTLNIR_OFFSET            1
++# define LCDC_LCD_IRR_LSTLNIR_SIZE              1
++# define LCDC_LCD_IRR_MERIR_OFFSET              6
++# define LCDC_LCD_IRR_MERIR_SIZE                1
++# define LCDC_LCD_IRR_OWRIR_OFFSET              5
++# define LCDC_LCD_IRR_OWRIR_SIZE                1
++# define LCDC_LCD_IRR_UFLWIR_OFFSET             4
++# define LCDC_LCD_IRR_UFLWIR_SIZE               1
++#define LCDC_LCD_ISR                            0x00000854
++# define LCDC_LCD_ISR_EOFIS_OFFSET              2
++# define LCDC_LCD_ISR_EOFIS_SIZE                1
++# define LCDC_LCD_ISR_LNIS_OFFSET               0
++# define LCDC_LCD_ISR_LNIS_SIZE                 1
++# define LCDC_LCD_ISR_LSTLNIS_OFFSET            1
++# define LCDC_LCD_ISR_LSTLNIS_SIZE              1
++# define LCDC_LCD_ISR_MERIS_OFFSET              6
++# define LCDC_LCD_ISR_MERIS_SIZE                1
++# define LCDC_LCD_ISR_OWRIS_OFFSET              5
++# define LCDC_LCD_ISR_OWRIS_SIZE                1
++# define LCDC_LCD_ISR_UFLWIS_OFFSET             4
++# define LCDC_LCD_ISR_UFLWIS_SIZE               1
++#define LCDC_LCD_ITR                            0x00000860
++# define LCDC_LCD_ITR_EOFIT_OFFSET              2
++# define LCDC_LCD_ITR_EOFIT_SIZE                1
++# define LCDC_LCD_ITR_LNIT_OFFSET               0
++# define LCDC_LCD_ITR_LNIT_SIZE                 1
++# define LCDC_LCD_ITR_LSTLNIT_OFFSET            1
++# define LCDC_LCD_ITR_LSTLNIT_SIZE              1
++# define LCDC_LCD_ITR_MERIT_OFFSET              6
++# define LCDC_LCD_ITR_MERIT_SIZE                1
++# define LCDC_LCD_ITR_OWRIT_OFFSET              5
++# define LCDC_LCD_ITR_OWRIT_SIZE                1
++# define LCDC_LCD_ITR_UFLWIT_OFFSET             4
++# define LCDC_LCD_ITR_UFLWIT_SIZE               1
++#define LCDC_PWRCON                             0x0000083C
++# define LCDC_PWRCON_GUARD_TIME_OFFSET          1
++# define LCDC_PWRCON_GUARD_TIME_SIZE            7
++# define LCDC_PWRCON_LCD_BUSY_OFFSET            31
++# define LCDC_PWRCON_LCD_BUSY_SIZE              1
++# define LCDC_PWRCON_LCD_PWR_OFFSET             0
++# define LCDC_PWRCON_LCD_PWR_SIZE               1
++
++#define LCDC_BIT(name)                          (1 << LCDC_##name##_OFFSET)
++#define LCDC_MKBF(name,value)                   (((value) & ((1 << LCDC_##name##_SIZE) - 1)) << LCDC_##name##_OFFSET)
++#define LCDC_GETBF(name,value)                  (((value) >> LCDC_##name##_OFFSET) & ((1 << LCDC_##name##_SIZE) - 1))
++#define LCDC_INSBF(name,value,old)              (((old) & ~(((1 << LCDC_##name##_SIZE) - 1) << LCDC_##name##_OFFSET)) | LCDC_MKBF(name, value))
++
++#define lcdc_readl(port,reg)                          \
++      __raw_readl((port)->regs + LCDC_##reg)
++#define lcdc_writel(port,reg,value)                   \
++      __raw_writel((value), (port)->regs + LCDC_##reg)
++
++#endif /* __ASM_AVR32_PERIPH_LCDC_H__ */
+Index: linux-2.6.18-avr32/include/linux/fb.h
+===================================================================
+--- linux-2.6.18-avr32.orig/include/linux/fb.h 2006-11-02 15:54:18.000000000 +0100
++++ linux-2.6.18-avr32/include/linux/fb.h      2006-11-02 15:56:20.000000000 +0100
+@@ -191,6 +191,7 @@ struct fb_bitfield {
+                                       /* vtotal = 144d/288n/576i => PAL  */
+                                       /* vtotal = 121d/242n/484i => NTSC */
+ #define FB_SYNC_ON_GREEN      32      /* sync on green */
++#define FB_SYNC_PCLK_RISING   64      /* pixel data sampled on rising pclk */
+ #define FB_VMODE_NONINTERLACED  0     /* non interlaced */
+ #define FB_VMODE_INTERLACED   1       /* interlaced   */
+@@ -825,7 +826,7 @@ struct fb_info {
+ #define fb_writeq sbus_writeq
+ #define fb_memset sbus_memset_io
+-#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || (defined(__sh__) && !defined(__SH5__)) || defined(__powerpc__)
++#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || (defined(__sh__) && !defined(__SH5__)) || defined(__powerpc__) || defined(__avr32__)
+ #define fb_readb __raw_readb
+ #define fb_readw __raw_readw
diff --git a/packages/linux/linux-2.6.18/atmel-macb-ethernet-driver.patch b/packages/linux/linux-2.6.18/atmel-macb-ethernet-driver.patch
new file mode 100644 (file)
index 0000000..e8c54e1
--- /dev/null
@@ -0,0 +1,1614 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Thu, 29 Jun 2006 15:02:49 +0200
+Subject: [PATCH] Atmel MACB ethernet driver
+
+This is a network device driver for the Atmel MACB interface, which
+is present on the AT32AP7000 device from Atmel. I think it's basically
+the same as the EMAC interface on AT91, so it should possibly be
+merged with the at91_ether driver some time in the future. At the
+moment, however, the at91_ether driver has quite a lot of at91-
+specific dependencies so it's hard to reuse on AVR32.
+
+This is basically the same patch as the one distributed with the
+AT32STK1000 BSP version 1.0, converted to use platform_device and
+struct clk instead of at32_device.
+
+---
+ drivers/net/Kconfig  |   11 
+ drivers/net/Makefile |    2 
+ drivers/net/macb.c   | 1159 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ drivers/net/macb.h   |  387 +++++++++++++++++
+ 4 files changed, 1559 insertions(+)
+
+Index: linux-2.6.18-avr32/drivers/net/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/net/Kconfig        2006-11-02 14:16:07.000000000 +0100
++++ linux-2.6.18-avr32/drivers/net/Kconfig     2006-11-02 14:17:29.000000000 +0100
+@@ -185,6 +185,17 @@ config MII
+         or internal device.  It is safe to say Y or M here even if your
+         ethernet card lack MII.
++config MACB
++      tristate "Atmel MACB support"
++      depends on NET_ETHERNET && AVR32
++      select MII
++      help
++        The Atmel MACB ethernet interface is found on many AT32 and AT91
++        parts. Say Y to include support for the MACB chip.
++
++        To compile this driver as a module, choose M here: the module
++        will be called macb.
++
+ source "drivers/net/arm/Kconfig"
+ config MACE
+Index: linux-2.6.18-avr32/drivers/net/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/net/Makefile       2006-11-02 14:16:07.000000000 +0100
++++ linux-2.6.18-avr32/drivers/net/Makefile    2006-11-02 14:17:29.000000000 +0100
+@@ -202,6 +202,8 @@ obj-$(CONFIG_SMC911X) += smc911x.o
+ obj-$(CONFIG_DM9000) += dm9000.o
+ obj-$(CONFIG_FEC_8XX) += fec_8xx/
++obj-$(CONFIG_MACB) += macb.o
++
+ obj-$(CONFIG_ARM) += arm/
+ obj-$(CONFIG_DEV_APPLETALK) += appletalk/
+ obj-$(CONFIG_TR) += tokenring/
+Index: linux-2.6.18-avr32/drivers/net/macb.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/drivers/net/macb.c      2006-11-02 16:33:48.000000000 +0100
+@@ -0,0 +1,1159 @@
++/*
++ * Atmel MACB Ethernet Controller 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/clk.h>
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/kernel.h>
++#include <linux/types.h>
++#include <linux/slab.h>
++#include <linux/init.h>
++#include <linux/netdevice.h>
++#include <linux/etherdevice.h>
++#include <linux/mii.h>
++#include <linux/mutex.h>
++#include <linux/dma-mapping.h>
++#include <linux/ethtool.h>
++#include <linux/platform_device.h>
++
++#include <asm/arch/board.h>
++
++#include "macb.h"
++
++#define to_net_dev(class) container_of(class, struct net_device, class_dev)
++
++#define RX_BUFFER_SIZE                128
++#define RX_RING_SIZE          512
++#define RX_RING_BYTES         (sizeof(struct dma_desc) * RX_RING_SIZE)
++
++/* Make the IP header word-aligned (the ethernet header is 14 bytes) */
++#define RX_OFFSET             2
++
++#define TX_RING_SIZE          128
++#define DEF_TX_RING_PENDING   (TX_RING_SIZE - 1)
++#define TX_RING_BYTES         (sizeof(struct dma_desc) * TX_RING_SIZE)
++
++#define TX_RING_GAP(bp)                                               \
++      (TX_RING_SIZE - (bp)->tx_pending)
++#define TX_BUFFS_AVAIL(bp)                                    \
++      (((bp)->tx_tail <= (bp)->tx_head) ?                     \
++       (bp)->tx_tail + (bp)->tx_pending - (bp)->tx_head :     \
++       (bp)->tx_tail - (bp)->tx_head - TX_RING_GAP(bp))
++#define NEXT_TX(n)            (((n) + 1) & (TX_RING_SIZE - 1))
++
++#define NEXT_RX(n)            (((n) + 1) & (RX_RING_SIZE - 1))
++
++/* minimum number of free TX descriptors before waking up TX process */
++#define MACB_TX_WAKEUP_THRESH (TX_RING_SIZE / 4)
++
++#define MACB_RX_INT_FLAGS     (MACB_BIT(RCOMP) | MACB_BIT(RXUBR)      \
++                               | MACB_BIT(ISR_ROVR))
++
++static void __macb_set_hwaddr(struct macb *bp)
++{
++      u32 bottom;
++      u16 top;
++
++      bottom = cpu_to_le32(*((u32 *)bp->dev->dev_addr));
++      macb_writel(bp, SA1B, bottom);
++      top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4)));
++      macb_writel(bp, SA1T, top);
++}
++
++static void macb_enable_mdio(struct macb *bp)
++{
++      unsigned long flags;
++      u32 reg;
++
++      spin_lock_irqsave(&bp->lock, flags);
++      reg = macb_readl(bp, NCR);
++      reg |= MACB_BIT(MPE);
++      macb_writel(bp, NCR, reg);
++      macb_writel(bp, IER, MACB_BIT(MFD));
++      spin_unlock_irqrestore(&bp->lock, flags);
++}
++
++static void macb_disable_mdio(struct macb *bp)
++{
++      unsigned long flags;
++      u32 reg;
++
++      spin_lock_irqsave(&bp->lock, flags);
++      reg = macb_readl(bp, NCR);
++      reg &= ~MACB_BIT(MPE);
++      macb_writel(bp, NCR, reg);
++      macb_writel(bp, IDR, MACB_BIT(MFD));
++      spin_unlock_irqrestore(&bp->lock, flags);
++}
++
++static int macb_mdio_read(struct net_device *dev, int phy_id, int location)
++{
++      struct macb *bp = netdev_priv(dev);
++      int value;
++
++      mutex_lock(&bp->mdio_mutex);
++
++      macb_enable_mdio(bp);
++      macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
++                            | MACB_BF(RW, MACB_MAN_READ)
++                            | MACB_BF(PHYA, phy_id)
++                            | MACB_BF(REGA, location)
++                            | MACB_BF(CODE, MACB_MAN_CODE)));
++
++      wait_for_completion(&bp->mdio_complete);
++
++      value = MACB_BFEXT(DATA, macb_readl(bp, MAN));
++      macb_disable_mdio(bp);
++      mutex_unlock(&bp->mdio_mutex);
++
++      return value;
++}
++
++static void macb_mdio_write(struct net_device *dev, int phy_id,
++                          int location, int val)
++{
++      struct macb *bp = netdev_priv(dev);
++
++      dev_dbg(&bp->pdev->dev, "mdio_write %02x:%02x <- %04x\n",
++              phy_id, location, val);
++
++      mutex_lock(&bp->mdio_mutex);
++      macb_enable_mdio(bp);
++
++      macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
++                            | MACB_BF(RW, MACB_MAN_WRITE)
++                            | MACB_BF(PHYA, phy_id)
++                            | MACB_BF(REGA, location)
++                            | MACB_BF(CODE, MACB_MAN_CODE)
++                            | MACB_BF(DATA, val)));
++
++      wait_for_completion(&bp->mdio_complete);
++
++      macb_disable_mdio(bp);
++      mutex_unlock(&bp->mdio_mutex);
++}
++
++static void macb_set_media(struct macb *bp, int media)
++{
++      u32 reg;
++
++      spin_lock_irq(&bp->lock);
++      reg = macb_readl(bp, NCFGR);
++      reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
++      if (media & (ADVERTISE_100HALF | ADVERTISE_100FULL))
++              reg |= MACB_BIT(SPD);
++      if (media & ADVERTISE_FULL)
++              reg |= MACB_BIT(FD);
++      macb_writel(bp, NCFGR, reg);
++      spin_unlock_irq(&bp->lock);
++}
++
++static void macb_check_media(struct macb *bp, int ok_to_print, int init_media)
++{
++      struct mii_if_info *mii = &bp->mii;
++      unsigned int old_carrier, new_carrier;
++      int advertise, lpa, media, duplex;
++
++      /* if forced media, go no further */
++      if (mii->force_media)
++              return;
++
++      /* check current and old link status */
++      old_carrier = netif_carrier_ok(mii->dev) ? 1 : 0;
++      new_carrier = (unsigned int) mii_link_ok(mii);
++
++      /* if carrier state did not change, assume nothing else did */
++      if (!init_media && old_carrier == new_carrier)
++              return;
++
++      /* no carrier, nothing much to do */
++      if (!new_carrier) {
++              netif_carrier_off(mii->dev);
++              printk(KERN_INFO "%s: link down\n", mii->dev->name);
++              return;
++      }
++
++      /*
++       * we have carrier, see who's on the other end
++       */
++      netif_carrier_on(mii->dev);
++
++      /* get MII advertise and LPA values */
++      if (!init_media && mii->advertising) {
++              advertise = mii->advertising;
++      } else {
++              advertise = mii->mdio_read(mii->dev, mii->phy_id, MII_ADVERTISE);
++              mii->advertising = advertise;
++      }
++      lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA);
++
++      /* figure out media and duplex from advertise and LPA values */
++      media = mii_nway_result(lpa & advertise);
++      duplex = (media & ADVERTISE_FULL) ? 1 : 0;
++
++      if (ok_to_print)
++              printk(KERN_INFO "%s: link up, %sMbps, %s-duplex, lpa 0x%04X\n",
++                     mii->dev->name,
++                     media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? "100" : "10",
++                     duplex ? "full" : "half", lpa);
++
++      mii->full_duplex = duplex;
++
++      /* Let the MAC know about the new link state */
++      macb_set_media(bp, media);
++}
++
++static void macb_update_stats(struct macb *bp)
++{
++      u32 __iomem *reg = bp->regs + MACB_PFR;
++      u32 *p = &bp->hw_stats.rx_pause_frames;
++      u32 *end = &bp->hw_stats.tx_pause_frames + 1;
++
++      WARN_ON((unsigned long)(end - p - 1) != (MACB_TPF - MACB_PFR) / 4);
++
++      for(; p < end; p++, reg++)
++              *p += __raw_readl(reg);
++}
++
++static void macb_periodic_task(void *arg)
++{
++      struct macb *bp = arg;
++
++      macb_update_stats(bp);
++      macb_check_media(bp, 1, 0);
++
++      schedule_delayed_work(&bp->periodic_task, HZ);
++}
++
++static void macb_tx(struct macb *bp)
++{
++      unsigned int tail;
++      unsigned int head;
++      u32 status;
++
++      status = macb_readl(bp, TSR);
++      macb_writel(bp, TSR, status);
++
++      dev_dbg(&bp->pdev->dev, "macb_tx status = %02lx\n",
++              (unsigned long)status);
++
++      if (status & MACB_BIT(UND)) {
++              printk(KERN_ERR "%s: TX underrun, resetting buffers\n",
++                     bp->dev->name);
++              bp->tx_head = bp->tx_tail = 0;
++      }
++
++      if (!(status & MACB_BIT(COMP)))
++              /*
++               * This may happen when a buffer becomes complete
++               * between reading the ISR and scanning the
++               * descriptors.  Nothing to worry about.
++               */
++              return;
++
++      head = bp->tx_head;
++      for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) {
++              struct ring_info *rp = &bp->tx_skb[tail];
++              struct sk_buff *skb = rp->skb;
++              u32 bufstat;
++
++              BUG_ON(skb == NULL);
++
++              rmb();
++              bufstat = bp->tx_ring[tail].ctrl;
++
++              if (!(bufstat & MACB_BIT(TX_USED)))
++                      break;
++
++              dev_dbg(&bp->pdev->dev, "skb %u (data %p) TX complete\n",
++                      tail, skb->data);
++              dma_unmap_single(&bp->pdev->dev, rp->mapping, skb->len,
++                               DMA_TO_DEVICE);
++              bp->stats.tx_packets++;
++              bp->stats.tx_bytes += skb->len;
++              rp->skb = NULL;
++              dev_kfree_skb_irq(skb);
++      }
++
++      bp->tx_tail = tail;
++      if (netif_queue_stopped(bp->dev) &&
++          TX_BUFFS_AVAIL(bp) > MACB_TX_WAKEUP_THRESH)
++              netif_wake_queue(bp->dev);
++}
++
++static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
++                       unsigned int last_frag)
++{
++      unsigned int len;
++      unsigned int frag;
++      unsigned int offset = 0;
++      struct sk_buff *skb;
++
++      len = MACB_BFEXT(RX_FRMLEN, bp->rx_ring[last_frag].ctrl);
++
++      dev_dbg(&bp->pdev->dev, "macb_rx_frame frags %u - %u (len %u)\n",
++              first_frag, last_frag, len);
++
++      skb = dev_alloc_skb(len + RX_OFFSET);
++      if (!skb) {
++              bp->stats.rx_dropped++;
++              for (frag = first_frag; ; frag = NEXT_RX(frag)) {
++                      bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
++                      if (frag == last_frag)
++                              break;
++              }
++              wmb();
++              return 1;
++      }
++
++      skb_reserve(skb, RX_OFFSET);
++      skb->dev = bp->dev;
++      skb->ip_summed = CHECKSUM_NONE;
++      skb_put(skb, len);
++
++      for (frag = first_frag; ; frag = NEXT_RX(frag)) {
++              unsigned int frag_len = RX_BUFFER_SIZE;
++
++              if (offset + frag_len > len) {
++                      BUG_ON(frag != last_frag);
++                      frag_len = len - offset;
++              }
++              memcpy(skb->data + offset,
++                     bp->rx_buffers + (RX_BUFFER_SIZE * frag),
++                     frag_len);
++              offset += RX_BUFFER_SIZE;
++              bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
++              wmb();
++
++              if (frag == last_frag)
++                      break;
++      }
++
++      skb->protocol = eth_type_trans(skb, bp->dev);
++
++      bp->stats.rx_packets++;
++      bp->stats.rx_bytes += len;
++      bp->dev->last_rx = jiffies;
++      dev_dbg(&bp->pdev->dev, "received skb of length %u, csum: %08x\n",
++              skb->len, skb->csum);
++      netif_receive_skb(skb);
++
++      return 0;
++}
++
++/* Mark DMA descriptors from begin up to and not including end as unused */
++static void discard_partial_frame(struct macb *bp, unsigned int begin,
++                                unsigned int end)
++{
++      unsigned int frag;
++
++      for (frag = begin; frag != end; frag = NEXT_RX(frag))
++              bp->rx_ring[frag].addr &= ~MACB_BIT(RX_USED);
++      wmb();
++
++      /*
++       * When this happens, the hardware stats registers for
++       * whatever caused this is updated, so we don't have to record
++       * anything.
++       */
++}
++
++static int macb_rx(struct macb *bp, int budget)
++{
++      int received = 0;
++      unsigned int tail = bp->rx_tail;
++      int first_frag = -1;
++
++      for (; budget > 0; tail = NEXT_RX(tail)) {
++              u32 addr, ctrl;
++
++              rmb();
++              addr = bp->rx_ring[tail].addr;
++              ctrl = bp->rx_ring[tail].ctrl;
++
++              if (!(addr & MACB_BIT(RX_USED)))
++                      break;
++
++              if (ctrl & MACB_BIT(RX_SOF)) {
++                      if (first_frag != -1)
++                              discard_partial_frame(bp, first_frag, tail);
++                      first_frag = tail;
++              }
++
++              if (ctrl & MACB_BIT(RX_EOF)) {
++                      int dropped;
++                      BUG_ON(first_frag == -1);
++
++                      dropped = macb_rx_frame(bp, first_frag, tail);
++                      first_frag = -1;
++                      if (!dropped) {
++                              received++;
++                              budget--;
++                      }
++              }
++      }
++
++      if (first_frag != -1)
++              bp->rx_tail = first_frag;
++      else
++              bp->rx_tail = tail;
++
++      return received;
++}
++
++static int macb_poll(struct net_device *dev, int *budget)
++{
++      struct macb *bp = netdev_priv(dev);
++      int orig_budget, work_done, retval = 0;
++      u32 status;
++
++      status = macb_readl(bp, RSR);
++      macb_writel(bp, RSR, status);
++
++      if (!status) {
++              /*
++               * This may happen if an interrupt was pending before
++               * this function was called last time, and no packets
++               * have been received since.
++               */
++              netif_rx_complete(dev);
++              goto out;
++      }
++
++      dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n",
++              (unsigned long)status, *budget);
++
++      if (!(status & MACB_BIT(REC))) {
++              dev_warn(&bp->pdev->dev,
++                       "No RX buffers complete, status = %02lx\n",
++                       (unsigned long)status);
++              netif_rx_complete(dev);
++              goto out;
++      }
++
++      orig_budget = *budget;
++      if (orig_budget > dev->quota)
++              orig_budget = dev->quota;
++
++      work_done = macb_rx(bp, orig_budget);
++      if (work_done < orig_budget) {
++              netif_rx_complete(dev);
++              retval = 0;
++      } else {
++              retval = 1;
++      }
++
++      /*
++       * We've done what we can to clean the buffers. Make sure we
++       * get notified when new packets arrive.
++       */
++out:
++      macb_writel(bp, IER, MACB_RX_INT_FLAGS);
++
++      /* TODO: Handle errors */
++
++      return retval;
++}
++
++static irqreturn_t macb_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++      struct net_device *dev = dev_id;
++      struct macb *bp = netdev_priv(dev);
++      u32 status;
++
++      status = macb_readl(bp, ISR);
++
++      if (unlikely(!status))
++              return IRQ_NONE;
++
++      spin_lock(&bp->lock);
++
++      /* close possible race with dev_close */
++      if (unlikely(!netif_running(dev))) {
++              macb_writel(bp, IDR, ~0UL);
++              spin_unlock(&bp->lock);
++              return IRQ_HANDLED;
++      }
++
++      while (status) {
++              if (status & MACB_BIT(MFD))
++                      complete(&bp->mdio_complete);
++
++              if (status & MACB_RX_INT_FLAGS) {
++                      if (netif_rx_schedule_prep(dev)) {
++                              /*
++                               * There's no point taking any more interrupts
++                               * until we have processed the buffers
++                               */
++                              macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
++                              dev_dbg(&bp->pdev->dev, "scheduling RX softirq\n");
++                              __netif_rx_schedule(dev);
++                      }
++              }
++
++              if (status & (MACB_BIT(TCOMP) | MACB_BIT(ISR_TUND)))
++                      macb_tx(bp);
++
++              /*
++               * Link change detection isn't possible with RMII, so we'll
++               * add that if/when we get our hands on a full-blown MII PHY.
++               */
++
++              if (status & MACB_BIT(HRESP)) {
++                      /*
++                       * TODO: Reset the hardware, and maybe move the printk
++                       * to a lower-priority context as well (work queue?)
++                       */
++                      printk(KERN_ERR "%s: DMA bus error: HRESP not OK\n",
++                             dev->name);
++              }
++
++              status = macb_readl(bp, ISR);
++      }
++
++      spin_unlock(&bp->lock);
++
++      return IRQ_HANDLED;
++}
++
++static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++      struct macb *bp = netdev_priv(dev);
++      dma_addr_t mapping;
++      unsigned int len, entry;
++      u32 ctrl;
++
++#ifdef DEBUG
++      int i;
++      dev_dbg(&bp->pdev->dev,
++              "start_xmit: len %u head %p data %p tail %p end %p\n",
++              skb->len, skb->head, skb->data, skb->tail, skb->end);
++      dev_dbg(&bp->pdev->dev,
++              "data:");
++      for (i = 0; i < 16; i++)
++              printk(" %02x", (unsigned int)skb->data[i]);
++      printk("\n");
++#endif
++
++      len = skb->len;
++      spin_lock_irq(&bp->lock);
++
++      /* This is a hard error, log it. */
++      if (TX_BUFFS_AVAIL(bp) < 1) {
++              netif_stop_queue(dev);
++              spin_unlock_irq(&bp->lock);
++              dev_err(&bp->pdev->dev,
++                      "BUG! Tx Ring full when queue awake!\n");
++              dev_dbg(&bp->pdev->dev, "tx_head = %u, tx_tail = %u\n",
++                      bp->tx_head, bp->tx_tail);
++              return 1;
++      }
++
++      entry = bp->tx_head;
++      dev_dbg(&bp->pdev->dev, "Allocated ring entry %u\n", entry);
++      mapping = dma_map_single(&bp->pdev->dev, skb->data,
++                               len, DMA_TO_DEVICE);
++      bp->tx_skb[entry].skb = skb;
++      bp->tx_skb[entry].mapping = mapping;
++      dev_dbg(&bp->pdev->dev, "Mapped skb data %p to DMA addr %08lx\n",
++              skb->data, (unsigned long)mapping);
++
++      ctrl = MACB_BF(TX_FRMLEN, len);
++      ctrl |= MACB_BIT(TX_LAST);
++      if (entry == (TX_RING_SIZE - 1))
++              ctrl |= MACB_BIT(TX_WRAP);
++
++      bp->tx_ring[entry].addr = mapping;
++      bp->tx_ring[entry].ctrl = ctrl;
++      wmb();
++
++      entry = NEXT_TX(entry);
++      bp->tx_head = entry;
++
++      macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
++
++      if (TX_BUFFS_AVAIL(bp) < 1)
++              netif_stop_queue(dev);
++
++      spin_unlock_irq(&bp->lock);
++
++      dev->trans_start = jiffies;
++
++      return 0;
++}
++
++static void macb_free_consistent(struct macb *bp)
++{
++      if (bp->tx_skb) {
++              kfree(bp->tx_skb);
++              bp->tx_skb = NULL;
++      }
++      if (bp->rx_ring) {
++              dma_free_coherent(&bp->pdev->dev, RX_RING_BYTES,
++                                bp->rx_ring, bp->rx_ring_dma);
++              bp->rx_ring = NULL;
++      }
++      if (bp->tx_ring) {
++              dma_free_coherent(&bp->pdev->dev, TX_RING_BYTES,
++                                bp->tx_ring, bp->tx_ring_dma);
++              bp->tx_ring = NULL;
++      }
++      if (bp->rx_buffers) {
++              dma_free_coherent(&bp->pdev->dev,
++                                RX_RING_SIZE * RX_BUFFER_SIZE,
++                                bp->rx_buffers, bp->rx_buffers_dma);
++              bp->rx_buffers = NULL;
++      }
++}
++
++static int macb_alloc_consistent(struct macb *bp)
++{
++      int size;
++
++      size = TX_RING_SIZE * sizeof(struct ring_info);
++      bp->tx_skb = kmalloc(size, GFP_KERNEL);
++      if (!bp->tx_skb)
++              goto out_err;
++
++      size = RX_RING_BYTES;
++      bp->rx_ring = dma_alloc_coherent(&bp->pdev->dev, size,
++                                       &bp->rx_ring_dma, GFP_KERNEL);
++      if (!bp->rx_ring)
++              goto out_err;
++      dev_dbg(&bp->pdev->dev,
++              "Allocated RX ring of %d bytes at %08lx (mapped %p)\n",
++              size, (unsigned long)bp->rx_ring_dma, bp->rx_ring);
++
++      size = TX_RING_BYTES;
++      bp->tx_ring = dma_alloc_coherent(&bp->pdev->dev, size,
++                                       &bp->tx_ring_dma, GFP_KERNEL);
++      if (!bp->tx_ring)
++              goto out_err;
++      dev_dbg(&bp->pdev->dev,
++              "Allocated TX ring of %d bytes at %08lx (mapped %p)\n",
++              size, (unsigned long)bp->tx_ring_dma, bp->tx_ring);
++
++      size = RX_RING_SIZE * RX_BUFFER_SIZE;
++      bp->rx_buffers = dma_alloc_coherent(&bp->pdev->dev, size,
++                                          &bp->rx_buffers_dma, GFP_KERNEL);
++      if (!bp->rx_buffers)
++              goto out_err;
++      dev_dbg(&bp->pdev->dev,
++              "Allocated RX buffers of %d bytes at %08lx (mapped %p)\n",
++              size, (unsigned long)bp->rx_buffers_dma, bp->rx_buffers);
++
++      return 0;
++
++out_err:
++      macb_free_consistent(bp);
++      return -ENOMEM;
++}
++
++static void macb_init_rings(struct macb *bp)
++{
++      int i;
++      dma_addr_t addr;
++
++      addr = bp->rx_buffers_dma;
++      for (i = 0; i < RX_RING_SIZE; i++) {
++              bp->rx_ring[i].addr = addr;
++              bp->rx_ring[i].ctrl = 0;
++              addr += RX_BUFFER_SIZE;
++      }
++      bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
++
++      for (i = 0; i < TX_RING_SIZE; i++) {
++              bp->tx_ring[i].addr = 0;
++              bp->tx_ring[i].ctrl = MACB_BIT(TX_USED);
++      }
++      bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
++
++      bp->rx_tail = bp->tx_head = bp->tx_tail = 0;
++}
++
++static void macb_reset_hw(struct macb *bp)
++{
++      /* Make sure we have the write buffer for ourselves */
++      wmb();
++
++      /*
++       * Disable RX and TX (XXX: Should we halt the transmission
++       * more gracefully?)
++       */
++      macb_writel(bp, NCR, 0);
++
++      /* Clear the stats registers (XXX: Update stats first?) */
++      macb_writel(bp, NCR, MACB_BIT(CLRSTAT));
++
++      /* Clear all status flags */
++      macb_writel(bp, TSR, ~0UL);
++      macb_writel(bp, RSR, ~0UL);
++
++      /* Disable all interrupts */
++      macb_writel(bp, IDR, ~0UL);
++      macb_readl(bp, ISR);
++}
++
++static void macb_init_hw(struct macb *bp)
++{
++      unsigned long pclk_hz;
++      u32 config;
++
++      macb_reset_hw(bp);
++      __macb_set_hwaddr(bp);
++
++      /* Set RMII mode */
++      macb_writel(bp, USRIO, MACB_BIT(RMII));
++
++      /* Initialize Network Configuration Register */
++      pclk_hz = clk_get_rate(bp->pclk);
++      if (pclk_hz <= 20000000)
++              config = MACB_BF(CLK, MACB_CLK_DIV8);
++      else if (pclk_hz <= 40000000)
++              config = MACB_BF(CLK, MACB_CLK_DIV16);
++      else if (pclk_hz <= 80000000)
++              config = MACB_BF(CLK, MACB_CLK_DIV32);
++      else
++              config = MACB_BF(CLK, MACB_CLK_DIV64);
++
++      config |= MACB_BIT(PAE);                /* PAuse Enable */
++      config |= MACB_BIT(DRFCS);              /* Discard Rx FCS */
++      if (bp->dev->flags & IFF_PROMISC)
++              config |= MACB_BIT(CAF);        /* Copy All Frames */
++      if (!(bp->dev->flags & IFF_BROADCAST))
++              config |= MACB_BIT(NBC);        /* No BroadCast */
++      macb_writel(bp, NCFGR, config);
++
++      /* Initialize TX and RX buffers */
++      macb_writel(bp, RBQP, bp->rx_ring_dma);
++      macb_writel(bp, TBQP, bp->tx_ring_dma);
++
++      /* Enable TX and RX */
++      macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE));
++
++      /* Enable interrupts */
++      macb_writel(bp, IER, (MACB_BIT(RCOMP)
++                            | MACB_BIT(RXUBR)
++                            | MACB_BIT(ISR_TUND)
++                            | MACB_BIT(ISR_RLE)
++                            | MACB_BIT(TXERR)
++                            | MACB_BIT(TCOMP)
++                            | MACB_BIT(ISR_ROVR)
++                            | MACB_BIT(HRESP)));
++}
++
++static void macb_init_phy(struct net_device *dev)
++{
++      struct macb *bp = netdev_priv(dev);
++
++      /* Set some reasonable default settings */
++      macb_mdio_write(dev, bp->mii.phy_id, MII_ADVERTISE,
++                      ADVERTISE_CSMA | ADVERTISE_ALL);
++      macb_mdio_write(dev, bp->mii.phy_id, MII_BMCR,
++                      (BMCR_SPEED100 | BMCR_ANENABLE
++                       | BMCR_ANRESTART | BMCR_FULLDPLX));
++}
++
++static int macb_open(struct net_device *dev)
++{
++      struct macb *bp = netdev_priv(dev);
++      int err;
++
++      dev_dbg(&bp->pdev->dev, "open\n");
++
++      err = macb_alloc_consistent(bp);
++      if (err) {
++              printk(KERN_ERR
++                     "%s: Unable to allocate DMA memory (error %d)\n",
++                     dev->name, err);
++              return err;
++      }
++
++      macb_init_rings(bp);
++      macb_init_hw(bp);
++      macb_init_phy(dev);
++
++      macb_check_media(bp, 1, 1);
++      netif_start_queue(dev);
++
++      schedule_delayed_work(&bp->periodic_task, HZ);
++
++      return 0;
++}
++
++static int macb_close(struct net_device *dev)
++{
++      struct macb *bp = netdev_priv(dev);
++      unsigned long flags;
++
++      cancel_rearming_delayed_work(&bp->periodic_task);
++
++      netif_stop_queue(dev);
++
++      spin_lock_irqsave(&bp->lock, flags);
++      macb_reset_hw(bp);
++      netif_carrier_off(dev);
++      spin_unlock_irqrestore(&bp->lock, flags);
++
++      macb_free_consistent(bp);
++
++      return 0;
++}
++
++static struct net_device_stats *macb_get_stats(struct net_device *dev)
++{
++      struct macb *bp = netdev_priv(dev);
++      struct net_device_stats *nstat = &bp->stats;
++      struct macb_stats *hwstat = &bp->hw_stats;
++
++      /* Convert HW stats into netdevice stats */
++      nstat->rx_errors = (hwstat->rx_fcs_errors +
++                          hwstat->rx_align_errors +
++                          hwstat->rx_resource_errors +
++                          hwstat->rx_overruns +
++                          hwstat->rx_oversize_pkts +
++                          hwstat->rx_jabbers +
++                          hwstat->rx_undersize_pkts +
++                          hwstat->sqe_test_errors +
++                          hwstat->rx_length_mismatch);
++      nstat->tx_errors = (hwstat->tx_late_cols +
++                          hwstat->tx_excessive_cols +
++                          hwstat->tx_underruns +
++                          hwstat->tx_carrier_errors);
++      nstat->collisions = (hwstat->tx_single_cols +
++                           hwstat->tx_multiple_cols +
++                           hwstat->tx_excessive_cols);
++      nstat->rx_length_errors = (hwstat->rx_oversize_pkts +
++                                 hwstat->rx_jabbers +
++                                 hwstat->rx_undersize_pkts +
++                                 hwstat->rx_length_mismatch);
++      nstat->rx_over_errors = hwstat->rx_resource_errors;
++      nstat->rx_crc_errors = hwstat->rx_fcs_errors;
++      nstat->rx_frame_errors = hwstat->rx_align_errors;
++      nstat->rx_fifo_errors = hwstat->rx_overruns;
++      /* XXX: What does "missed" mean? */
++      nstat->tx_aborted_errors = hwstat->tx_excessive_cols;
++      nstat->tx_carrier_errors = hwstat->tx_carrier_errors;
++      nstat->tx_fifo_errors = hwstat->tx_underruns;
++      /* Don't know about heartbeat or window errors... */
++
++      return nstat;
++}
++
++static int macb_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++      struct macb *bp = netdev_priv(dev);
++      int ret;
++      unsigned long flags;
++
++      spin_lock_irqsave(&bp->lock, flags);
++      ret = mii_ethtool_gset(&bp->mii, cmd);
++      spin_unlock_irqrestore(&bp->lock, flags);
++
++      return ret;
++}
++
++static int macb_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++      struct macb *bp = netdev_priv(dev);
++      int ret;
++      unsigned long flags;
++
++      spin_lock_irqsave(&bp->lock, flags);
++      ret = mii_ethtool_sset(&bp->mii, cmd);
++      spin_unlock_irqrestore(&bp->lock, flags);
++
++      return ret;
++}
++
++static void macb_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
++{
++      struct macb *bp = netdev_priv(dev);
++
++      strcpy(info->driver, bp->pdev->dev.driver->name);
++      strcpy(info->version, "$Revision: 1.14 $");
++      strcpy(info->bus_info, bp->pdev->dev.bus_id);
++}
++
++static int macb_nway_reset(struct net_device *dev)
++{
++      struct macb *bp = netdev_priv(dev);
++      return mii_nway_restart(&bp->mii);
++}
++
++static struct ethtool_ops macb_ethtool_ops = {
++      .get_settings           = macb_get_settings,
++      .set_settings           = macb_set_settings,
++      .get_drvinfo            = macb_get_drvinfo,
++      .nway_reset             = macb_nway_reset,
++      .get_link               = ethtool_op_get_link,
++};
++
++static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
++{
++      struct macb *bp = netdev_priv(dev);
++      int ret;
++      unsigned long flags;
++
++      if (!netif_running(dev))
++              return -EINVAL;
++
++      spin_lock_irqsave(&bp->lock, flags);
++      ret = generic_mii_ioctl(&bp->mii, if_mii(rq), cmd, NULL);
++      spin_unlock_irqrestore(&bp->lock, flags);
++
++      return ret;
++}
++
++static ssize_t macb_mii_show(const struct class_device *cd, char *buf,
++                      unsigned long addr)
++{
++      struct net_device *dev = to_net_dev(cd);
++      struct macb *bp = netdev_priv(dev);
++      ssize_t ret = -EINVAL;
++
++      if (netif_running(dev)) {
++              int value;
++              value = macb_mdio_read(dev, bp->mii.phy_id, addr);
++              ret = sprintf(buf, "0x%04x\n", (uint16_t)value);
++      }
++
++      return ret;
++}
++
++#define MII_ENTRY(name, addr)                                 \
++static ssize_t show_##name(struct class_device *cd, char *buf)        \
++{                                                             \
++      return macb_mii_show(cd, buf, addr);                    \
++}                                                             \
++static CLASS_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
++
++MII_ENTRY(bmcr, MII_BMCR);
++MII_ENTRY(bmsr, MII_BMSR);
++MII_ENTRY(physid1, MII_PHYSID1);
++MII_ENTRY(physid2, MII_PHYSID2);
++MII_ENTRY(advertise, MII_ADVERTISE);
++MII_ENTRY(lpa, MII_LPA);
++MII_ENTRY(expansion, MII_EXPANSION);
++
++static struct attribute *macb_mii_attrs[] = {
++      &class_device_attr_bmcr.attr,
++      &class_device_attr_bmsr.attr,
++      &class_device_attr_physid1.attr,
++      &class_device_attr_physid2.attr,
++      &class_device_attr_advertise.attr,
++      &class_device_attr_lpa.attr,
++      &class_device_attr_expansion.attr,
++      NULL,
++};
++
++static struct attribute_group macb_mii_group = {
++      .name   = "mii",
++      .attrs  = macb_mii_attrs,
++};
++
++static void macb_unregister_sysfs(struct net_device *net)
++{
++      struct class_device *class_dev = &net->class_dev;
++
++      sysfs_remove_group(&class_dev->kobj, &macb_mii_group);
++}
++
++static int macb_register_sysfs(struct net_device *net)
++{
++      struct class_device *class_dev = &net->class_dev;
++      int ret;
++
++      ret = sysfs_create_group(&class_dev->kobj, &macb_mii_group);
++      if (ret)
++              printk(KERN_WARNING
++                     "%s: sysfs mii attribute registration failed: %d\n",
++                     net->name, ret);
++      return ret;
++}
++static int __devinit macb_probe(struct platform_device *pdev)
++{
++      struct eth_platform_data *pdata;
++      struct resource *regs;
++      struct net_device *dev;
++      struct macb *bp;
++      int err = -ENXIO;
++
++      regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!regs) {
++              dev_err(&pdev->dev, "no mmio resource defined\n");
++              goto err_out;
++      }
++
++      err = -ENOMEM;
++      dev = alloc_etherdev(sizeof(*bp));
++      if (!dev) {
++              dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n");
++              goto err_out;
++      }
++
++      SET_MODULE_OWNER(dev);
++      SET_NETDEV_DEV(dev, &pdev->dev);
++
++      /* TODO: Actually, we have some interesting features... */
++      dev->features |= 0;
++
++      bp = netdev_priv(dev);
++      bp->pdev = pdev;
++      bp->dev = dev;
++
++      spin_lock_init(&bp->lock);
++
++      bp->pclk = clk_get(&pdev->dev, "pclk");
++      if (IS_ERR(bp->pclk)) {
++              dev_err(&pdev->dev, "failed to get pclk\n");
++              goto err_out_free_dev;
++      }
++      bp->hclk = clk_get(&pdev->dev, "hclk");
++      if (IS_ERR(bp->hclk)) {
++              dev_err(&pdev->dev, "failed to get hclk\n");
++              goto err_out_put_pclk;
++      }
++
++      clk_enable(bp->pclk);
++      clk_enable(bp->hclk);
++
++      bp->regs = ioremap(regs->start, regs->end - regs->start + 1);
++      if (!bp->regs) {
++              dev_err(&pdev->dev, "failed to map registers, aborting.\n");
++              err = -ENOMEM;
++              goto err_out_disable_clocks;
++      }
++
++      dev->irq = platform_get_irq(pdev, 0);
++      err = request_irq(dev->irq, macb_interrupt, SA_SAMPLE_RANDOM,
++                        dev->name, dev);
++      if (err) {
++              printk(KERN_ERR
++                     "%s: Unable to request IRQ %d (error %d)\n",
++                     dev->name, dev->irq, err);
++              goto err_out_iounmap;
++      }
++
++      dev->open = macb_open;
++      dev->stop = macb_close;
++      dev->hard_start_xmit = macb_start_xmit;
++      dev->get_stats = macb_get_stats;
++      dev->do_ioctl = macb_ioctl;
++      dev->poll = macb_poll;
++      dev->weight = 64;
++      dev->ethtool_ops = &macb_ethtool_ops;
++
++      dev->base_addr = regs->start;
++
++      INIT_WORK(&bp->periodic_task, macb_periodic_task, bp);
++      mutex_init(&bp->mdio_mutex);
++      init_completion(&bp->mdio_complete);
++
++      bp->mii.dev = dev;
++      bp->mii.mdio_read = macb_mdio_read;
++      bp->mii.mdio_write = macb_mdio_write;
++
++      pdata = pdev->dev.platform_data;
++      if (!pdata) {
++              dev_err(&pdev->dev, "Cannot determine hw address\n");
++              goto err_out_free_irq;
++      }
++
++      memcpy(dev->dev_addr, pdata->hw_addr, dev->addr_len);
++      bp->mii.phy_id = pdata->mii_phy_addr;
++      bp->mii.phy_id_mask = 0x1f;
++      bp->mii.reg_num_mask = 0x1f;
++
++      bp->tx_pending = DEF_TX_RING_PENDING;
++
++      err = register_netdev(dev);
++      if (err) {
++              dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
++              goto err_out_free_irq;
++      }
++
++      platform_set_drvdata(pdev, dev);
++
++      macb_register_sysfs(dev);
++
++      printk(KERN_INFO "%s: Atmel MACB at 0x%08lx irq %d "
++             "(%02x:%02x:%02x:%02x:%02x:%02x)\n",
++             dev->name, dev->base_addr, dev->irq,
++             dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
++             dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
++
++      return 0;
++
++err_out_free_irq:
++      free_irq(dev->irq, dev);
++err_out_iounmap:
++      iounmap(bp->regs);
++err_out_disable_clocks:
++      clk_disable(bp->hclk);
++      clk_disable(bp->pclk);
++      clk_put(bp->hclk);
++err_out_put_pclk:
++      clk_put(bp->pclk);
++err_out_free_dev:
++      free_netdev(dev);
++err_out:
++      platform_set_drvdata(pdev, NULL);
++      return err;
++}
++
++static int __devexit macb_remove(struct platform_device *pdev)
++{
++      struct net_device *dev;
++      struct macb *bp;
++
++      dev = platform_get_drvdata(pdev);
++
++      if (dev) {
++              bp = netdev_priv(dev);
++              macb_unregister_sysfs(dev);
++              unregister_netdev(dev);
++              free_irq(dev->irq, dev);
++              iounmap(bp->regs);
++              clk_disable(bp->hclk);
++              clk_disable(bp->pclk);
++              clk_put(bp->hclk);
++              clk_put(bp->pclk);
++              free_netdev(dev);
++              platform_set_drvdata(pdev, NULL);
++      }
++
++      return 0;
++}
++
++static struct platform_driver macb_driver = {
++      .probe          = macb_probe,
++      .remove         = __devexit_p(macb_remove),
++      .driver         = {
++              .name           = "macb",
++      },
++};
++
++static int __init macb_init(void)
++{
++      return platform_driver_register(&macb_driver);
++}
++
++static void __exit macb_exit(void)
++{
++      platform_driver_unregister(&macb_driver);
++}
++
++module_init(macb_init);
++module_exit(macb_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Atmel MACB Ethernet driver");
++MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
+Index: linux-2.6.18-avr32/drivers/net/macb.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/drivers/net/macb.h      2006-11-02 16:33:26.000000000 +0100
+@@ -0,0 +1,387 @@
++/*
++ * Atmel MACB Ethernet Controller 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 _MACB_H
++#define _MACB_H
++
++/* MACB register offsets */
++#define MACB_NCR                              0x0000
++#define MACB_NCFGR                            0x0004
++#define MACB_NSR                              0x0008
++#define MACB_TSR                              0x0014
++#define MACB_RBQP                             0x0018
++#define MACB_TBQP                             0x001c
++#define MACB_RSR                              0x0020
++#define MACB_ISR                              0x0024
++#define MACB_IER                              0x0028
++#define MACB_IDR                              0x002c
++#define MACB_IMR                              0x0030
++#define MACB_MAN                              0x0034
++#define MACB_PTR                              0x0038
++#define MACB_PFR                              0x003c
++#define MACB_FTO                              0x0040
++#define MACB_SCF                              0x0044
++#define MACB_MCF                              0x0048
++#define MACB_FRO                              0x004c
++#define MACB_FCSE                             0x0050
++#define MACB_ALE                              0x0054
++#define MACB_DTF                              0x0058
++#define MACB_LCOL                             0x005c
++#define MACB_EXCOL                            0x0060
++#define MACB_TUND                             0x0064
++#define MACB_CSE                              0x0068
++#define MACB_RRE                              0x006c
++#define MACB_ROVR                             0x0070
++#define MACB_RSE                              0x0074
++#define MACB_ELE                              0x0078
++#define MACB_RJA                              0x007c
++#define MACB_USF                              0x0080
++#define MACB_STE                              0x0084
++#define MACB_RLE                              0x0088
++#define MACB_TPF                              0x008c
++#define MACB_HRB                              0x0090
++#define MACB_HRT                              0x0094
++#define MACB_SA1B                             0x0098
++#define MACB_SA1T                             0x009c
++#define MACB_SA2B                             0x00a0
++#define MACB_SA2T                             0x00a4
++#define MACB_SA3B                             0x00a8
++#define MACB_SA3T                             0x00ac
++#define MACB_SA4B                             0x00b0
++#define MACB_SA4T                             0x00b4
++#define MACB_TID                              0x00b8
++#define MACB_TPQ                              0x00bc
++#define MACB_USRIO                            0x00c0
++#define MACB_WOL                              0x00c4
++
++/* Bitfields in NCR */
++#define MACB_LB_OFFSET                                0
++#define MACB_LB_SIZE                          1
++#define MACB_LLB_OFFSET                               1
++#define MACB_LLB_SIZE                         1
++#define MACB_RE_OFFSET                                2
++#define MACB_RE_SIZE                          1
++#define MACB_TE_OFFSET                                3
++#define MACB_TE_SIZE                          1
++#define MACB_MPE_OFFSET                               4
++#define MACB_MPE_SIZE                         1
++#define MACB_CLRSTAT_OFFSET                   5
++#define MACB_CLRSTAT_SIZE                     1
++#define MACB_INCSTAT_OFFSET                   6
++#define MACB_INCSTAT_SIZE                     1
++#define MACB_WESTAT_OFFSET                    7
++#define MACB_WESTAT_SIZE                      1
++#define MACB_BP_OFFSET                                8
++#define MACB_BP_SIZE                          1
++#define MACB_TSTART_OFFSET                    9
++#define MACB_TSTART_SIZE                      1
++#define MACB_THALT_OFFSET                     10
++#define MACB_THALT_SIZE                               1
++#define MACB_NCR_TPF_OFFSET                   11
++#define MACB_NCR_TPF_SIZE                     1
++#define MACB_TZQ_OFFSET                               12
++#define MACB_TZQ_SIZE                         1
++
++/* Bitfields in NCFGR */
++#define MACB_SPD_OFFSET                               0
++#define MACB_SPD_SIZE                         1
++#define MACB_FD_OFFSET                                1
++#define MACB_FD_SIZE                          1
++#define MACB_BIT_RATE_OFFSET                  2
++#define MACB_BIT_RATE_SIZE                    1
++#define MACB_JFRAME_OFFSET                    3
++#define MACB_JFRAME_SIZE                      1
++#define MACB_CAF_OFFSET                               4
++#define MACB_CAF_SIZE                         1
++#define MACB_NBC_OFFSET                               5
++#define MACB_NBC_SIZE                         1
++#define MACB_NCFGR_MTI_OFFSET                 6
++#define MACB_NCFGR_MTI_SIZE                   1
++#define MACB_UNI_OFFSET                               7
++#define MACB_UNI_SIZE                         1
++#define MACB_BIG_OFFSET                               8
++#define MACB_BIG_SIZE                         1
++#define MACB_EAE_OFFSET                               9
++#define MACB_EAE_SIZE                         1
++#define MACB_CLK_OFFSET                               10
++#define MACB_CLK_SIZE                         2
++#define MACB_RTY_OFFSET                               12
++#define MACB_RTY_SIZE                         1
++#define MACB_PAE_OFFSET                               13
++#define MACB_PAE_SIZE                         1
++#define MACB_RBOF_OFFSET                      14
++#define MACB_RBOF_SIZE                                2
++#define MACB_RLCE_OFFSET                      16
++#define MACB_RLCE_SIZE                                1
++#define MACB_DRFCS_OFFSET                     17
++#define MACB_DRFCS_SIZE                               1
++#define MACB_EFRHD_OFFSET                     18
++#define MACB_EFRHD_SIZE                               1
++#define MACB_IRXFCS_OFFSET                    19
++#define MACB_IRXFCS_SIZE                      1
++
++/* Bitfields in NSR */
++#define MACB_NSR_LINK_OFFSET                  0
++#define MACB_NSR_LINK_SIZE                    1
++#define MACB_MDIO_OFFSET                      1
++#define MACB_MDIO_SIZE                                1
++#define MACB_IDLE_OFFSET                      2
++#define MACB_IDLE_SIZE                                1
++
++/* Bitfields in TSR */
++#define MACB_UBR_OFFSET                               0
++#define MACB_UBR_SIZE                         1
++#define MACB_COL_OFFSET                               1
++#define MACB_COL_SIZE                         1
++#define MACB_TSR_RLE_OFFSET                   2
++#define MACB_TSR_RLE_SIZE                     1
++#define MACB_TGO_OFFSET                               3
++#define MACB_TGO_SIZE                         1
++#define MACB_BEX_OFFSET                               4
++#define MACB_BEX_SIZE                         1
++#define MACB_COMP_OFFSET                      5
++#define MACB_COMP_SIZE                                1
++#define MACB_UND_OFFSET                               6
++#define MACB_UND_SIZE                         1
++
++/* Bitfields in RSR */
++#define MACB_BNA_OFFSET                               0
++#define MACB_BNA_SIZE                         1
++#define MACB_REC_OFFSET                               1
++#define MACB_REC_SIZE                         1
++#define MACB_OVR_OFFSET                               2
++#define MACB_OVR_SIZE                         1
++
++/* Bitfields in ISR/IER/IDR/IMR */
++#define MACB_MFD_OFFSET                               0
++#define MACB_MFD_SIZE                         1
++#define MACB_RCOMP_OFFSET                     1
++#define MACB_RCOMP_SIZE                               1
++#define MACB_RXUBR_OFFSET                     2
++#define MACB_RXUBR_SIZE                               1
++#define MACB_TXUBR_OFFSET                     3
++#define MACB_TXUBR_SIZE                               1
++#define MACB_ISR_TUND_OFFSET                  4
++#define MACB_ISR_TUND_SIZE                    1
++#define MACB_ISR_RLE_OFFSET                   5
++#define MACB_ISR_RLE_SIZE                     1
++#define MACB_TXERR_OFFSET                     6
++#define MACB_TXERR_SIZE                               1
++#define MACB_TCOMP_OFFSET                     7
++#define MACB_TCOMP_SIZE                               1
++#define MACB_ISR_LINK_OFFSET                  9
++#define MACB_ISR_LINK_SIZE                    1
++#define MACB_ISR_ROVR_OFFSET                  10
++#define MACB_ISR_ROVR_SIZE                    1
++#define MACB_HRESP_OFFSET                     11
++#define MACB_HRESP_SIZE                               1
++#define MACB_PFR_OFFSET                               12
++#define MACB_PFR_SIZE                         1
++#define MACB_PTZ_OFFSET                               13
++#define MACB_PTZ_SIZE                         1
++
++/* Bitfields in MAN */
++#define MACB_DATA_OFFSET                      0
++#define MACB_DATA_SIZE                                16
++#define MACB_CODE_OFFSET                      16
++#define MACB_CODE_SIZE                                2
++#define MACB_REGA_OFFSET                      18
++#define MACB_REGA_SIZE                                5
++#define MACB_PHYA_OFFSET                      23
++#define MACB_PHYA_SIZE                                5
++#define MACB_RW_OFFSET                                28
++#define MACB_RW_SIZE                          2
++#define MACB_SOF_OFFSET                               30
++#define MACB_SOF_SIZE                         2
++
++/* Bitfields in USRIO */
++#define MACB_RMII_OFFSET                      0
++#define MACB_RMII_SIZE                                1
++#define MACB_EAM_OFFSET                               1
++#define MACB_EAM_SIZE                         1
++#define MACB_TX_PAUSE_OFFSET                  2
++#define MACB_TX_PAUSE_SIZE                    1
++#define MACB_TX_PAUSE_ZERO_OFFSET             3
++#define MACB_TX_PAUSE_ZERO_SIZE                       1
++
++/* Bitfields in WOL */
++#define MACB_IP_OFFSET                                0
++#define MACB_IP_SIZE                          16
++#define MACB_MAG_OFFSET                               16
++#define MACB_MAG_SIZE                         1
++#define MACB_ARP_OFFSET                               17
++#define MACB_ARP_SIZE                         1
++#define MACB_SA1_OFFSET                               18
++#define MACB_SA1_SIZE                         1
++#define MACB_WOL_MTI_OFFSET                   19
++#define MACB_WOL_MTI_SIZE                     1
++
++/* Constants for CLK */
++#define MACB_CLK_DIV8                         0
++#define MACB_CLK_DIV16                                1
++#define MACB_CLK_DIV32                                2
++#define MACB_CLK_DIV64                                3
++
++/* Constants for MAN register */
++#define MACB_MAN_SOF                          1
++#define MACB_MAN_WRITE                                1
++#define MACB_MAN_READ                         2
++#define MACB_MAN_CODE                         2
++
++/* Bit manipulation macros */
++#define MACB_BIT(name)                                        \
++      (1 << MACB_##name##_OFFSET)
++#define MACB_BF(name,value)                           \
++      (((value) & ((1 << MACB_##name##_SIZE) - 1))    \
++       << MACB_##name##_OFFSET)
++#define MACB_BFEXT(name,value)\
++      (((value) >> MACB_##name##_OFFSET)              \
++       & ((1 << MACB_##name##_SIZE) - 1))
++#define MACB_BFINS(name,value,old)                    \
++      (((old) & ~(((1 << MACB_##name##_SIZE) - 1)     \
++                  << MACB_##name##_OFFSET))           \
++       | MACB_BF(name,value))
++
++/* Register access macros */
++#define macb_readl(port,reg)                          \
++      __raw_readl((port)->regs + MACB_##reg)
++#define macb_writel(port,reg,value)                   \
++      __raw_writel((value), (port)->regs + MACB_##reg)
++
++struct dma_desc {
++      u32     addr;
++      u32     ctrl;
++};
++
++/* DMA descriptor bitfields */
++#define MACB_RX_USED_OFFSET                   0
++#define MACB_RX_USED_SIZE                     1
++#define MACB_RX_WRAP_OFFSET                   1
++#define MACB_RX_WRAP_SIZE                     1
++#define MACB_RX_WADDR_OFFSET                  2
++#define MACB_RX_WADDR_SIZE                    30
++
++#define MACB_RX_FRMLEN_OFFSET                 0
++#define MACB_RX_FRMLEN_SIZE                   12
++#define MACB_RX_OFFSET_OFFSET                 12
++#define MACB_RX_OFFSET_SIZE                   2
++#define MACB_RX_SOF_OFFSET                    14
++#define MACB_RX_SOF_SIZE                      1
++#define MACB_RX_EOF_OFFSET                    15
++#define MACB_RX_EOF_SIZE                      1
++#define MACB_RX_CFI_OFFSET                    16
++#define MACB_RX_CFI_SIZE                      1
++#define MACB_RX_VLAN_PRI_OFFSET                       17
++#define MACB_RX_VLAN_PRI_SIZE                 3
++#define MACB_RX_PRI_TAG_OFFSET                        20
++#define MACB_RX_PRI_TAG_SIZE                  1
++#define MACB_RX_VLAN_TAG_OFFSET                       21
++#define MACB_RX_VLAN_TAG_SIZE                 1
++#define MACB_RX_TYPEID_MATCH_OFFSET           22
++#define MACB_RX_TYPEID_MATCH_SIZE             1
++#define MACB_RX_SA4_MATCH_OFFSET              23
++#define MACB_RX_SA4_MATCH_SIZE                        1
++#define MACB_RX_SA3_MATCH_OFFSET              24
++#define MACB_RX_SA3_MATCH_SIZE                        1
++#define MACB_RX_SA2_MATCH_OFFSET              25
++#define MACB_RX_SA2_MATCH_SIZE                        1
++#define MACB_RX_SA1_MATCH_OFFSET              26
++#define MACB_RX_SA1_MATCH_SIZE                        1
++#define MACB_RX_EXT_MATCH_OFFSET              28
++#define MACB_RX_EXT_MATCH_SIZE                        1
++#define MACB_RX_UHASH_MATCH_OFFSET            29
++#define MACB_RX_UHASH_MATCH_SIZE              1
++#define MACB_RX_MHASH_MATCH_OFFSET            30
++#define MACB_RX_MHASH_MATCH_SIZE              1
++#define MACB_RX_BROADCAST_OFFSET              31
++#define MACB_RX_BROADCAST_SIZE                        1
++
++#define MACB_TX_FRMLEN_OFFSET                 0
++#define MACB_TX_FRMLEN_SIZE                   11
++#define MACB_TX_LAST_OFFSET                   15
++#define MACB_TX_LAST_SIZE                     1
++#define MACB_TX_NOCRC_OFFSET                  16
++#define MACB_TX_NOCRC_SIZE                    1
++#define MACB_TX_BUF_EXHAUSTED_OFFSET          27
++#define MACB_TX_BUF_EXHAUSTED_SIZE            1
++#define MACB_TX_UNDERRUN_OFFSET                       28
++#define MACB_TX_UNDERRUN_SIZE                 1
++#define MACB_TX_ERROR_OFFSET                  29
++#define MACB_TX_ERROR_SIZE                    1
++#define MACB_TX_WRAP_OFFSET                   30
++#define MACB_TX_WRAP_SIZE                     1
++#define MACB_TX_USED_OFFSET                   31
++#define MACB_TX_USED_SIZE                     1
++
++struct ring_info {
++      struct sk_buff          *skb;
++      dma_addr_t              mapping;
++};
++
++/*
++ * Hardware-collected statistics. Used when updating the network
++ * device stats by a periodic timer.
++ */
++struct macb_stats {
++      u32     rx_pause_frames;
++      u32     tx_ok;
++      u32     tx_single_cols;
++      u32     tx_multiple_cols;
++      u32     rx_ok;
++      u32     rx_fcs_errors;
++      u32     rx_align_errors;
++      u32     tx_deferred;
++      u32     tx_late_cols;
++      u32     tx_excessive_cols;
++      u32     tx_underruns;
++      u32     tx_carrier_errors;
++      u32     rx_resource_errors;
++      u32     rx_overruns;
++      u32     rx_symbol_errors;
++      u32     rx_oversize_pkts;
++      u32     rx_jabbers;
++      u32     rx_undersize_pkts;
++      u32     sqe_test_errors;
++      u32     rx_length_mismatch;
++      u32     tx_pause_frames;
++};
++
++struct macb {
++      void __iomem            *regs;
++
++      unsigned int            rx_tail;
++      struct dma_desc         *rx_ring;
++      void                    *rx_buffers;
++
++      unsigned int            tx_head, tx_tail;
++      struct dma_desc         *tx_ring;
++      struct ring_info        *tx_skb;
++
++      spinlock_t              lock;
++      struct platform_device  *pdev;
++      struct clk              *pclk;
++      struct clk              *hclk;
++      struct net_device       *dev;
++      struct net_device_stats stats;
++      struct macb_stats       hw_stats;
++
++      dma_addr_t              rx_ring_dma;
++      dma_addr_t              tx_ring_dma;
++      dma_addr_t              rx_buffers_dma;
++
++      unsigned int            rx_pending, tx_pending;
++
++      struct work_struct      periodic_task;
++
++      struct mutex            mdio_mutex;
++      struct completion       mdio_complete;
++      struct mii_if_info      mii;
++};
++
++#endif /* _MACB_H */
diff --git a/packages/linux/linux-2.6.18/atmel-mci-debugfs.patch b/packages/linux/linux-2.6.18/atmel-mci-debugfs.patch
new file mode 100644 (file)
index 0000000..4570bd8
--- /dev/null
@@ -0,0 +1,278 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Sun, 14 Jan 2007 19:07:06 +0100
+Subject: [ATMEL MCI] Add debugfs support
+
+Export some of the atmel-mci driver state through debugfs. More
+specifically:
+  * The MCI hardware registers
+  * The request currently being processed
+  * Pending and processed event masks
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+---
+ drivers/mmc/atmel-mci.c |  230 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 230 insertions(+)
+
+Index: linux-2.6.18-avr32/drivers/mmc/atmel-mci.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/mmc/atmel-mci.c    2007-01-15 15:35:45.000000000 +0100
++++ linux-2.6.18-avr32/drivers/mmc/atmel-mci.c 2007-01-15 15:38:05.000000000 +0100
+@@ -79,6 +79,14 @@ struct atmel_mci {
+       struct clk              *mck;
+       struct mmci_platform_data *board;
+       struct platform_device  *pdev;
++
++#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... */
+@@ -90,6 +98,224 @@ static unsigned int fmax = 1000000U;
+ module_param(fmax, uint, 0444);
+ MODULE_PARM_DESC(fmax, "Max frequency in Hz of the MMC bus clock");
++#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->u.generic_ip;
++
++      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 int 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->u.generic_ip;
++      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, &regs_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)
+ {
+@@ -709,6 +935,8 @@ static int __devinit atmci_probe(struct 
+       printk(KERN_INFO "%s: Atmel MCI controller at 0x%08lx irq %d\n",
+              mmc_hostname(mmc), host->mapbase, irq);
++      atmci_init_debugfs(host);
++
+       return 0;
+ out_free_irq:
+@@ -734,6 +962,8 @@ static int __devexit atmci_remove(struct
+       platform_set_drvdata(pdev, NULL);
+       if (host) {
++              atmci_cleanup_debugfs(host);
++
+               mmc_remove_host(host->mmc);
+               mci_writel(host, IDR, ~0UL);
diff --git a/packages/linux/linux-2.6.18/atmel-mci-init-nr_blocks-in-dma-request.patch b/packages/linux/linux-2.6.18/atmel-mci-init-nr_blocks-in-dma-request.patch
new file mode 100644 (file)
index 0000000..d6d91ae
--- /dev/null
@@ -0,0 +1,47 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Sun, 14 Jan 2007 19:07:06 +0100
+Subject: [ATMEL MCI] Initialize the nr_blocks member of the dma request
+
+It seems like the mmc driver might get asked to write less data
+than what is available in the associated scatterlist. Previously,
+the dmac driver assumed that an sg request should transfer all
+the data in the scatterlist, which would break in this case.
+
+Resolve this by passing the number of blocks to transfer explicitly.
+This will probably fix a number of cases where the mmc controller
+seemed to be out of sync with the dma controller.
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+---
+ drivers/mmc/atmel-mci.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+Index: linux-2.6.18-avr32/drivers/mmc/atmel-mci.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/mmc/atmel-mci.c    2007-01-15 15:39:13.000000000 +0100
++++ linux-2.6.18-avr32/drivers/mmc/atmel-mci.c 2007-01-15 15:39:25.000000000 +0100
+@@ -51,7 +51,6 @@ struct atmel_mci_dma {
+       struct dma_request_sg   req;
+       unsigned short          rx_periph_id;
+       unsigned short          tx_periph_id;
+-      int                     blocks_left;
+ };
+ struct atmel_mci {
+@@ -428,6 +427,7 @@ static u32 atmci_prepare_data(struct mmc
+       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)
+@@ -454,7 +454,6 @@ static u32 atmci_prepare_data(struct mmc
+               host->dma.req.data_reg = host->mapbase + MCI_TDR;
+       }
+       host->dma.req.sg = data->sg;
+-      host->dma.blocks_left = data->blocks;
+       dma_prepare_request_sg(host->dma.req.req.dmac, &host->dma.req);
diff --git a/packages/linux/linux-2.6.18/atmel-mmc-host-driver.patch b/packages/linux/linux-2.6.18/atmel-mmc-host-driver.patch
new file mode 100644 (file)
index 0000000..b7d7e8a
--- /dev/null
@@ -0,0 +1,986 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Fri Nov 18 17:20:29 2005 +0100
+Subject: [PATCH] AVR32: MMC Host Driver
+
+---
+
+ drivers/mmc/Kconfig     |   10 
+ drivers/mmc/Makefile    |    1 
+ drivers/mmc/atmel-mci.c |  738 ++++++++++++++++++++++++++++++++++++++++++++++++
+ drivers/mmc/atmel-mci.h |  192 ++++++++++++
+ 4 files changed, 941 insertions(+)
+
+Index: linux-2.6.18-avr32/drivers/mmc/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/mmc/Kconfig        2007-01-15 10:14:40.000000000 +0100
++++ linux-2.6.18-avr32/drivers/mmc/Kconfig     2007-01-15 10:14:46.000000000 +0100
+@@ -71,6 +71,16 @@ config MMC_OMAP
+         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_WBSD
+       tristate "Winbond W83L51xD SD/MMC Card Interface support"
+       depends on MMC && ISA_DMA_API
+Index: linux-2.6.18-avr32/drivers/mmc/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/mmc/Makefile       2007-01-15 10:14:40.000000000 +0100
++++ linux-2.6.18-avr32/drivers/mmc/Makefile    2007-01-15 10:14:46.000000000 +0100
+@@ -23,6 +23,7 @@ obj-$(CONFIG_MMC_WBSD)               += wbsd.o
+ obj-$(CONFIG_MMC_AU1X)                += au1xmmc.o
+ obj-$(CONFIG_MMC_OMAP)                += omap.o
+ obj-$(CONFIG_MMC_AT91RM9200)  += at91_mci.o
++obj-$(CONFIG_MMC_ATMELMCI)    += atmel-mci.o
+ mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o
+Index: linux-2.6.18-avr32/drivers/mmc/atmel-mci.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/drivers/mmc/atmel-mci.c 2007-01-15 10:31:55.000000000 +0100
+@@ -0,0 +1,738 @@
++/*
++ * 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 <linux/mmc/protocol.h>
++
++#include <asm/dma-controller.h>
++#include <asm/io.h>
++
++#include "atmel-mci.h"
++
++#define DRIVER_NAME "mmci"
++
++#define MCI_CMD_ERROR_FLAGS   (MCI_BIT(RINDE) | MCI_BIT(RDIRE) |      \
++                               MCI_BIT(RCRCE) | MCI_BIT(RENDE) |      \
++                               MCI_BIT(RTOE))
++#define MCI_DATA_ERROR_FLAGS  (MCI_BIT(DCRCE) | MCI_BIT(DTOE) |       \
++                               MCI_BIT(OVRE) | MCI_BIT(UNRE))
++
++enum {
++      EVENT_CMD_COMPLETE = 0,
++      EVENT_CMD_ERROR,
++      EVENT_DATA_COMPLETE,
++      EVENT_DATA_ERROR,
++      EVENT_STOP_SENT,
++      EVENT_STOP_COMPLETE,
++      EVENT_STOP_ERROR,
++      EVENT_DMA_ERROR,
++};
++
++struct atmel_mci_dma {
++      struct dma_request_sg   req;
++      unsigned short          rx_periph_id;
++      unsigned short          tx_periph_id;
++      int                     blocks_left;
++};
++
++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                     stop_cmdr;
++      u32                     stop_iflags;
++
++      struct tasklet_struct   tasklet;
++      unsigned long           pending_events;
++      unsigned long           completed_events;
++      u32                     error_status;
++
++      unsigned long           bus_hz;
++      unsigned long           mapbase;
++      struct clk              *mck;
++      struct platform_device  *pdev;
++};
++
++/* 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");
++
++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;
++      }
++
++      pr_debug("%s: setting timeout to %u cycles\n",
++               mmc_hostname(host->mmc),
++               dtocyc << dtomul_to_shift[dtomul]);
++      mci_writel(host, DTOR, (MCI_BF(DTOMUL, dtomul)
++                              | MCI_BF(DTOCYC, dtocyc)));
++}
++
++/*
++ * Return mask with interrupt flags to be handled for this command.
++ */
++static u32 atmci_prepare_command(struct mmc_host *mmc,
++                               struct mmc_command *cmd,
++                               u32 *cmd_flags)
++{
++      u32 cmdr;
++      u32 iflags;
++
++      cmd->error = MMC_ERR_NONE;
++
++      cmdr = 0;
++      BUG_ON(MCI_BFEXT(CMDNB, cmdr) != 0);
++      cmdr = MCI_BFINS(CMDNB, cmd->opcode, cmdr);
++
++      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);
++
++      iflags = MCI_BIT(CMDRDY) | MCI_CMD_ERROR_FLAGS;
++      if (!(cmd->flags & MMC_RSP_CRC))
++              iflags &= ~MCI_BIT(RCRCE);
++
++      pr_debug("%s: cmd: op %02x arg %08x flags %08x, cmdflags %08lx\n",
++               mmc_hostname(mmc), cmd->opcode, cmd->arg, cmd->flags,
++               (unsigned long)cmdr);
++
++      *cmd_flags = cmdr;
++      return iflags;
++}
++
++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;
++
++      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;
++      host->dma.blocks_left = data->blocks;
++
++      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)
++              printk("WARNING: IMR=0x%08x\n", mci_readl(host, IMR));
++
++      WARN_ON(host->mrq != NULL);
++      host->mrq = mrq;
++      host->pending_events = 0;
++      host->completed_events = 0;
++
++      iflags = atmci_prepare_command(mmc, mrq->cmd, &cmdflags);
++
++      if (mrq->stop) {
++              BUG_ON(!data);
++
++              host->stop_iflags = atmci_prepare_command(mmc, mrq->stop,
++                                                        &host->stop_cmdr);
++              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);
++
++      if (ios->clock) {
++              u32 clkdiv;
++
++              clkdiv = host->bus_hz / (2 * ios->clock) - 1;
++              if (clkdiv > 255)
++                      clkdiv = 255;
++              mci_writel(host, MR, (clkdiv
++                                    | MCI_BIT(WRPROOF)
++                                    | MCI_BIT(RDPROOF)));
++      }
++
++      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_OFF:
++              mci_writel(host, CR, MCI_BIT(MCIDIS));
++              break;
++      case MMC_POWER_UP:
++              mci_writel(host, CR, MCI_BIT(SWRST));
++              break;
++      case MMC_POWER_ON:
++              mci_writel(host, CR, MCI_BIT(MCIEN));
++              break;
++      }
++}
++
++static struct mmc_host_ops atmci_ops = {
++      .request        = atmci_request,
++      .set_ios        = atmci_set_ios,
++};
++
++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, host->stop_iflags);
++}
++
++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 (test_bit(EVENT_CMD_COMPLETE, &host->completed_events)
++          && (!data->stop
++              || test_bit(EVENT_STOP_COMPLETE, &host->completed_events)))
++              atmci_request_end(host->mmc, data->mrq);
++}
++
++static void atmci_command_error(struct mmc_host *mmc,
++                              struct mmc_command *cmd,
++                              u32 status)
++{
++      pr_debug("%s: command error: status=0x%08x\n",
++               mmc_hostname(mmc), status);
++
++      if (status & MCI_BIT(RTOE))
++              cmd->error = MMC_ERR_TIMEOUT;
++      else if (status & MCI_BIT(RCRCE))
++              cmd->error = MMC_ERR_BADCRC;
++      else
++              cmd->error = MMC_ERR_FAILED;
++}
++
++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;
++
++      pr_debug("atmci_tasklet: pending/completed/mask %lx/%lx/%x\n",
++               host->pending_events, host->completed_events,
++               mci_readl(host, IMR));
++
++      if (test_and_clear_bit(EVENT_CMD_ERROR, &host->pending_events)) {
++              struct mmc_command *cmd;
++
++              set_bit(EVENT_CMD_ERROR, &host->completed_events);
++              clear_bit(EVENT_CMD_COMPLETE, &host->pending_events);
++              cmd = host->mrq->cmd;
++
++              if (cmd->data) {
++                      dma_stop_request(host->dma.req.req.dmac,
++                                       host->dma.req.req.channel);
++                      host->data = NULL;
++              }
++
++              atmci_command_error(mmc, cmd, host->error_status);
++              atmci_request_end(mmc, cmd->mrq);
++      }
++      if (test_and_clear_bit(EVENT_STOP_ERROR, &host->pending_events)) {
++              set_bit(EVENT_STOP_ERROR, &host->completed_events);
++              clear_bit(EVENT_STOP_COMPLETE, &host->pending_events);
++              atmci_command_error(mmc, host->mrq->stop,
++                                  host->error_status);
++              if (!host->data)
++                      atmci_request_end(mmc, host->mrq);
++      }
++      if (test_and_clear_bit(EVENT_CMD_COMPLETE, &host->pending_events)) {
++              set_bit(EVENT_CMD_COMPLETE, &host->completed_events);
++              if (!mrq->data
++                  || test_bit(EVENT_DATA_COMPLETE, &host->completed_events))
++                      atmci_request_end(mmc, mrq);
++      }
++      if (test_and_clear_bit(EVENT_STOP_COMPLETE, &host->pending_events)) {
++              set_bit(EVENT_STOP_COMPLETE, &host->completed_events);
++              if (test_bit(EVENT_DATA_COMPLETE, &host->completed_events))
++                      atmci_request_end(mmc, mrq);
++      }
++      if (test_and_clear_bit(EVENT_DMA_ERROR, &host->pending_events)) {
++              set_bit(EVENT_DMA_ERROR, &host->completed_events);
++              clear_bit(EVENT_DATA_COMPLETE, &host->pending_events);
++
++              /* DMA controller got bus error => invalid address */
++              data->error = MMC_ERR_INVALID;
++
++              printk(KERN_DEBUG "%s: dma error after %u bytes xfered\n",
++                     mmc_hostname(mmc), host->data->bytes_xfered);
++
++              if (data->stop
++                  && !test_and_set_bit(EVENT_STOP_SENT,
++                                       &host->completed_events))
++                      /* TODO: Check if card is still present */
++                      send_stop_cmd(host->mmc, data, 0);
++
++              atmci_data_complete(host, data);
++      }
++      if (test_and_clear_bit(EVENT_DATA_ERROR, &host->pending_events)) {
++              u32 status = host->error_status;
++
++              set_bit(EVENT_DATA_ERROR, &host->completed_events);
++              clear_bit(EVENT_DATA_COMPLETE, &host->pending_events);
++
++              dma_stop_request(host->dma.req.req.dmac,
++                               host->dma.req.req.channel);
++
++              printk(KERN_DEBUG "%s: data error: status=0x%08x\n",
++                     mmc_hostname(host->mmc), status);
++
++              if (status & MCI_BIT(DCRCE)) {
++                      printk(KERN_DEBUG "%s: Data CRC error\n",
++                             mmc_hostname(host->mmc));
++                      data->error = MMC_ERR_BADCRC;
++              } else if (status & MCI_BIT(DTOE)) {
++                      printk(KERN_DEBUG "%s: Data Timeout error\n",
++                             mmc_hostname(host->mmc));
++                      data->error = MMC_ERR_TIMEOUT;
++              } else {
++                      printk(KERN_DEBUG "%s: Data FIFO error\n",
++                             mmc_hostname(host->mmc));
++                      data->error = MMC_ERR_FIFO;
++              }
++              printk(KERN_DEBUG "%s: Bytes xfered: %u\n",
++                     mmc_hostname(host->mmc), data->bytes_xfered);
++
++              if (data->stop
++                  && !test_and_set_bit(EVENT_STOP_SENT, &host->completed_events))
++                      /* TODO: Check if card is still present */
++                      send_stop_cmd(host->mmc, data, 0);
++
++              atmci_data_complete(host, data);
++      }
++      if (test_and_clear_bit(EVENT_DATA_COMPLETE, &host->pending_events)) {
++              set_bit(EVENT_DATA_COMPLETE, &host->completed_events);
++              data->bytes_xfered = data->blocks * data->blksz;
++              atmci_data_complete(host, data);
++      }
++}
++
++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) | MCI_CMD_ERROR_FLAGS);
++      host->cmd = NULL;
++
++      if (test_bit(EVENT_STOP_SENT, &host->completed_events))
++              set_bit(EVENT_STOP_COMPLETE, &host->pending_events);
++      else
++              set_bit(EVENT_CMD_COMPLETE, &host->pending_events);
++
++      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;
++
++      if (data->stop && !test_and_set_bit(EVENT_STOP_SENT,
++                                          &host->completed_events))
++              send_stop_cmd(host->mmc, data, 0);
++
++      if (data->flags & MMC_DATA_READ) {
++              mci_writel(host, IDR, MCI_DATA_ERROR_FLAGS);
++              set_bit(EVENT_DATA_COMPLETE, &host->pending_events);
++              tasklet_schedule(&host->tasklet);
++      } else {
++              /*
++               * For the WRITE case, wait for NOTBUSY. This function
++               * is called when everything has been written to the
++               * controller, not when the card is done programming.
++               */
++              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));
++
++      set_bit(EVENT_DMA_ERROR, &host->pending_events);
++      tasklet_schedule(&host->tasklet);
++}
++
++static irqreturn_t atmci_interrupt(int irq, void *dev_id,
++                                 struct pt_regs *regs)
++{
++      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_CMD_ERROR_FLAGS) {
++                      mci_writel(host, IDR, (MCI_BIT(CMDRDY)
++                                             | MCI_BIT(NOTBUSY)
++                                             | MCI_CMD_ERROR_FLAGS
++                                             | MCI_DATA_ERROR_FLAGS));
++                      host->error_status = status;
++                      host->cmd = NULL;
++                      if (test_bit(EVENT_STOP_SENT, &host->completed_events))
++                              set_bit(EVENT_STOP_ERROR, &host->pending_events);
++                      else
++                              set_bit(EVENT_CMD_ERROR, &host->pending_events);
++                      tasklet_schedule(&host->tasklet);
++                      break;
++              }
++              if (pending & MCI_DATA_ERROR_FLAGS) {
++                      mci_writel(host, IDR, (MCI_BIT(NOTBUSY)
++                                             | MCI_DATA_ERROR_FLAGS));
++                      host->error_status = status;
++                      set_bit(EVENT_DATA_ERROR, &host->pending_events);
++                      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));
++                      set_bit(EVENT_DATA_COMPLETE, &host->pending_events);
++                      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 int __devinit atmci_probe(struct platform_device *pdev)
++{
++      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;
++
++      mmc = mmc_alloc_host(sizeof(struct atmel_mci), &pdev->dev);
++      if (!mmc)
++              return -ENOMEM;
++
++      host = mmc_priv(mmc);
++      host->pdev = pdev;
++      host->mmc = mmc;
++
++      host->mck = clk_get(&pdev->dev, "mck");
++      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  = 0x00100000;
++      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;
++
++      /* TODO: Get this information from platform data */
++      ret = -ENOMEM;
++      host->dma.req.req.dmac = find_dma_controller(0);
++      if (!host->dma.req.req.dmac) {
++              printk(KERN_ERR
++                     "mmci: No DMA controller available, aborting\n");
++              goto out_free_irq;
++      }
++      ret = dma_alloc_channel(host->dma.req.req.dmac);
++      if (ret < 0) {
++              printk(KERN_ERR
++                     "mmci: Unable to allocate DMA channel, aborting\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);
++      mci_writel(host, CR, MCI_BIT(MCIEN));
++
++      platform_set_drvdata(pdev, host);
++
++      mmc_add_host(mmc);
++
++      printk(KERN_INFO "%s: Atmel MCI controller at 0x%08lx irq %d\n",
++             mmc_hostname(mmc), host->mapbase, irq);
++
++      return 0;
++
++out_free_irq:
++      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) {
++              mmc_remove_host(host->mmc);
++
++              mci_writel(host, IDR, ~0UL);
++              mci_writel(host, CR, MCI_BIT(MCIDIS));
++              mci_readl(host, SR);
++
++              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");
+Index: linux-2.6.18-avr32/drivers/mmc/atmel-mci.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/drivers/mmc/atmel-mci.h 2007-01-15 10:31:36.000000000 +0100
+@@ -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__ */
diff --git a/packages/linux/linux-2.6.18/atmel-spi-master-driver.patch b/packages/linux/linux-2.6.18/atmel-spi-master-driver.patch
new file mode 100644 (file)
index 0000000..d45f3c5
--- /dev/null
@@ -0,0 +1,990 @@
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+
+On Mon, 5 Jun 2006 06:49:52 -0700
+David Brownell <david-b@pacbell.net> wrote:
+
+> Here's an updated version that compiles and partially runs
+> in the at91 world.  If the avr32 code would switch to standard
+> APIs like <linux/platform_device.h> and <linux/clk.h> it should
+> behave there too, somewhat.  Ignore the extra debug crap.
+
+Here's another update which includes most of the fixes in Dave's
+version and which has been verified on my STK1000 board.
+
+I had some trouble getting your version to turn on the display
+correctly, so I've reworked it as a series of smaller changes to figure
+out what broke it. You should probably verify that I didn't leave out
+anything important.
+
+Also, I didn't find CONFIG_SPI_AT91_MANUAL_CS defined anywhere, nor did
+I find cpu_is_at91sam9261() so I left out those changes.
+
+Can any of you test this on AT91 somehow? I'm not completely up to
+speed on my AT91RM9200-EK yet. Anyone else I should Cc?
+
+I can send you individual patches if you want. Here's the shortlog:
+
+Atmel SPI Driver
+spi_atmel: convert to platform_device framework
+spi_atmel: fix broken parameter validation in setup() and transfer()
+spi_atmel: Revert core workaround for max_speed_hz=0
+spi_atmel: Divide len by two if bits_per_word > 8
+spi_atmel: Enable ENDRX interrupt when rx_buf is set
+spi_atmel: Fix incorrect locking in interrupt routine
+spi_atmel: Line up variable declarations
+spi_atmel: Add some FIXMEs from David Brownell's patch
+spi_atmel: Header file cleanup
+spi_atmel: Introduce new_1 flag and use in sck speed setting
+spi_atmel: Move SPI_ATMEL above SPI_BITBANG
+Make SPI_ATMEL available to AT91
+
+
+>>From nobody Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Thu Apr 6 10:33:21 2006 +0200
+Subject: [PATCH] Atmel SPI Driver
+
+SPI master driver for the Atmel AT32/AT91 SPI Controller.
+
+UPDATED:
+       - against 2.6.17 + latest kernel.org GIT
+       - "at32_device" stuff removed from core of driver
+       - add platform_device glue, so at91 compiles
+       - use clock framework
+       - understand "old" (rm9200) vs "new" (sam9261, ap7000) silicon
+         (only different scbr definition, not csaat etc.)
+       - remove bogus spi core tweaks
+       - various fixes and cleanups
+
+The following changes from atmel-spi-driver-3.patch have been dropped:
+       - CONFIG_SPI_AT91_MANUAL_CS stuff. I can't find the symbol
+         anywhere
+       - DMA IRQ optimization by unmasking TXEMPTY when starting xfer
+       - All the code setting CSAAT.
+
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+
+On Mon, 5 Jun 2006 06:49:52 -0700
+David Brownell <david-b@pacbell.net> wrote:
+
+> Here's an updated version that compiles and partially runs
+> in the at91 world.  If the avr32 code would switch to standard
+> APIs like <linux/platform_device.h> and <linux/clk.h> it should
+> behave there too, somewhat.  Ignore the extra debug crap.
+
+Here's another update which includes most of the fixes in Dave's
+version and which has been verified on my STK1000 board.
+
+I had some trouble getting your version to turn on the display
+correctly, so I've reworked it as a series of smaller changes to figure
+out what broke it. You should probably verify that I didn't leave out
+anything important.
+
+Also, I didn't find CONFIG_SPI_AT91_MANUAL_CS defined anywhere, nor did
+I find cpu_is_at91sam9261() so I left out those changes.
+
+Can any of you test this on AT91 somehow? I'm not completely up to
+speed on my AT91RM9200-EK yet. Anyone else I should Cc?
+
+I can send you individual patches if you want. Here's the shortlog:
+
+Atmel SPI Driver
+spi_atmel: convert to platform_device framework
+spi_atmel: fix broken parameter validation in setup() and transfer()
+spi_atmel: Revert core workaround for max_speed_hz=0
+spi_atmel: Divide len by two if bits_per_word > 8
+spi_atmel: Enable ENDRX interrupt when rx_buf is set
+spi_atmel: Fix incorrect locking in interrupt routine
+spi_atmel: Line up variable declarations
+spi_atmel: Add some FIXMEs from David Brownell's patch
+spi_atmel: Header file cleanup
+spi_atmel: Introduce new_1 flag and use in sck speed setting
+spi_atmel: Move SPI_ATMEL above SPI_BITBANG
+Make SPI_ATMEL available to AT91
+
+
+>>From nobody Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Thu Apr 6 10:33:21 2006 +0200
+Subject: [PATCH] Atmel SPI Driver
+
+SPI master driver for the Atmel AT32/AT91 SPI Controller.
+
+UPDATED:
+       - against 2.6.17 + latest kernel.org GIT
+       - "at32_device" stuff removed from core of driver
+       - add platform_device glue, so at91 compiles
+       - use clock framework
+       - understand "old" (rm9200) vs "new" (sam9261, ap7000) silicon
+         (only different scbr definition, not csaat etc.)
+       - remove bogus spi core tweaks
+       - various fixes and cleanups
+
+The following changes from atmel-spi-driver-3.patch have been dropped:
+       - CONFIG_SPI_AT91_MANUAL_CS stuff. I can't find the symbol
+         anywhere
+       - DMA IRQ optimization by unmasking TXEMPTY when starting xfer
+       - All the code setting CSAAT.
+
+---
+ drivers/spi/Kconfig     |    7 
+ drivers/spi/Makefile    |    1 
+ drivers/spi/atmel_spi.c |  648 ++++++++++++++++++++++++++++++++++++++++++++++++
+ drivers/spi/atmel_spi.h |  167 ++++++++++++
+ 4 files changed, 823 insertions(+)
+
+Index: linux-2.6.18-avr32/drivers/spi/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/spi/Kconfig        2006-11-29 16:55:10.000000000 +0100
++++ linux-2.6.18-avr32/drivers/spi/Kconfig     2006-11-29 16:55:59.000000000 +0100
+@@ -51,6 +51,13 @@ config SPI_MASTER
+ comment "SPI Master Controller Drivers"
+       depends on SPI_MASTER
++config SPI_ATMEL
++      tristate "Atmel SPI Controller"
++      depends on (ARCH_AT91 || AVR32) && SPI_MASTER
++      help
++        This selects a driver for the Atmel SPI Controller, present on
++        many AT32 (AVR32) and AT91 (ARM) chips.
++
+ config SPI_BITBANG
+       tristate "Bitbanging SPI master"
+       depends on SPI_MASTER && EXPERIMENTAL
+Index: linux-2.6.18-avr32/drivers/spi/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/spi/Makefile       2006-11-29 16:55:10.000000000 +0100
++++ linux-2.6.18-avr32/drivers/spi/Makefile    2006-11-29 16:55:59.000000000 +0100
+@@ -12,6 +12,7 @@ obj-$(CONFIG_SPI_MASTER)             += spi.o
+ # SPI master controller drivers (bus)
+ obj-$(CONFIG_SPI_BITBANG)             += spi_bitbang.o
++obj-$(CONFIG_SPI_ATMEL)                       += atmel_spi.o
+ obj-$(CONFIG_SPI_BUTTERFLY)           += spi_butterfly.o
+ obj-$(CONFIG_SPI_PXA2XX)              += pxa2xx_spi.o
+ obj-$(CONFIG_SPI_MPC83xx)             += spi_mpc83xx.o
+Index: linux-2.6.18-avr32/drivers/spi/atmel_spi.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/drivers/spi/atmel_spi.c 2006-11-29 17:10:19.000000000 +0100
+@@ -0,0 +1,648 @@
++/*
++ * Driver for Atmel AT32 and AT91 SPI Controllers
++ *
++ * 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/kernel.h>
++#include <linux/init.h>
++#include <linux/clk.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++#include <linux/delay.h>
++#include <linux/dma-mapping.h>
++#include <linux/err.h>
++#include <linux/interrupt.h>
++#include <linux/spi/spi.h>
++
++#include <asm/io.h>
++#include <asm/arch/board.h>
++#include <asm/arch/gpio.h>
++
++#include "atmel_spi.h"
++
++/*
++ * The core SPI transfer engine just talks to a register bank to set up
++ * DMA transfers; transfer queue progress is driven by IRQs.  The clock
++ * framework provides the base clock, subdivided for each spi_device.
++ *
++ * Newer controllers, marked with "new_1" flag, have:
++ *  - CR.LASTXFER
++ *  - SPI_MR.DIV32 may become FDIV or must-be-zero (here: always zero)
++ *  - SPI_SR.TXEMPTY, SPI_SR.NSSR (and corresponding irqs)
++ *  - SPI_CSRx.CSAAT
++ *  - SPI_CSRx.SBCR allows faster clocking
++ */
++struct atmel_spi {
++      spinlock_t              lock;
++
++      void __iomem            *regs;
++      int                     irq;
++      struct clk              *clk;
++      struct platform_device  *pdev;
++      unsigned                new_1:1;
++
++      u8                      stopping;
++      struct list_head        queue;
++      struct spi_transfer     *current_transfer;
++      unsigned long           remaining_bytes;
++
++      void                    *buffer;
++      dma_addr_t              buffer_dma;
++};
++
++#define BUFFER_SIZE           PAGE_SIZE
++#define INVALID_DMA_ADDRESS   0xffffffff
++
++/*
++ * Earlier SPI controllers (e.g. on at91rm9200) have a design bug whereby
++ * they assume that spi slave device state will not change on deselect, so
++ * that automagic deselection is OK.  Not so!  Workaround uses nCSx pins
++ * as GPIOs; or newer controllers have CSAAT and friends.
++ *
++ * Since the CSAAT functionality is a bit weird on newer controllers
++ * as well, we use GPIO to control nCSx pins on all controllers.
++ */
++
++static inline void cs_activate(struct spi_device *spi)
++{
++      unsigned gpio = (unsigned) spi->controller_data;
++
++      dev_dbg(&spi->dev, "activate %u\n", gpio);
++      gpio_set_value(gpio, 0);
++}
++
++static inline void cs_deactivate(struct spi_device *spi)
++{
++      unsigned gpio = (unsigned) spi->controller_data;
++
++      dev_dbg(&spi->dev, "DEactivate %u\n", gpio);
++      gpio_set_value(gpio, 1);
++}
++
++/*
++ * Submit next transfer for DMA.
++ * lock is held, spi irq is blocked
++ */
++static void atmel_spi_next_xfer(struct spi_master *master,
++                              struct spi_message *msg)
++{
++      struct atmel_spi        *as = spi_master_get_devdata(master);
++      struct spi_transfer     *xfer;
++      u32                     imr = 0;
++      u32                     len;
++      dma_addr_t              tx_dma, rx_dma;
++
++      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;
++      }
++
++      len = as->remaining_bytes;
++
++      tx_dma = xfer->tx_dma;
++      rx_dma = xfer->rx_dma;
++
++      if (rx_dma == INVALID_DMA_ADDRESS) {
++              rx_dma = as->buffer_dma;
++              if (len > BUFFER_SIZE)
++                      len = BUFFER_SIZE;
++      }
++      if (tx_dma == INVALID_DMA_ADDRESS) {
++              if (xfer->tx_buf) {
++                      tx_dma = as->buffer_dma;
++                      if (len > BUFFER_SIZE)
++                              len = BUFFER_SIZE;
++                      memcpy(as->buffer, xfer->tx_buf, len);
++                      dma_sync_single_for_device(&as->pdev->dev,
++                                                 as->buffer_dma, len,
++                                                 DMA_TO_DEVICE);
++              } else {
++                      /* Send undefined data; rx_dma is handy */
++                      tx_dma = rx_dma;
++              }
++      }
++
++      spi_writel(as, RPR, rx_dma);
++      spi_writel(as, TPR, tx_dma);
++
++      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
++       *
++       * 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
++       * to tell the difference between the ENDRX interrupt we're
++       * actually waiting for and the ENDRX interrupt of the
++       * previous transfer.
++       *
++       * It should be doable, though. Just not now...
++       */
++      spi_writel(as, TNCR, 0);
++      spi_writel(as, RNCR, 0);
++      imr = SPI_BIT(ENDRX);
++
++      dev_dbg(&msg->spi->dev,
++              "start xfer %p: len %u tx %p/%08x rx %p/%08x imr %08x\n",
++              xfer, xfer->len, xfer->tx_buf, xfer->tx_dma,
++              xfer->rx_buf, xfer->rx_dma, imr);
++
++      wmb();
++      spi_writel(as, TCR, len);
++      spi_writel(as, RCR, len);
++      spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN));
++      spi_writel(as, IER, imr);
++}
++
++static void atmel_spi_next_message(struct spi_master *master)
++{
++      struct atmel_spi        *as = spi_master_get_devdata(master);
++      struct spi_message      *msg;
++      u32                     mr;
++
++      BUG_ON(as->current_transfer);
++
++      msg = list_entry(as->queue.next, struct spi_message, queue);
++
++      /* Select the chip */
++      mr = spi_readl(as, MR);
++      mr = SPI_BFINS(PCS, ~(1 << msg->spi->chip_select), mr);
++      spi_writel(as, MR, mr);
++      cs_activate(msg->spi);
++
++      atmel_spi_next_xfer(master, msg);
++}
++
++static void atmel_spi_dma_map_xfer(struct atmel_spi *as,
++                                 struct spi_transfer *xfer)
++{
++      xfer->tx_dma = xfer->rx_dma = INVALID_DMA_ADDRESS;
++      if (!(xfer->len & (L1_CACHE_BYTES - 1))) {
++              if (xfer->tx_buf
++                  && !((unsigned long)xfer->tx_buf & (L1_CACHE_BYTES - 1)))
++                      xfer->tx_dma = dma_map_single(&as->pdev->dev,
++                                                    xfer->tx_buf,
++                                                    xfer->len,
++                                                    DMA_TO_DEVICE);
++              if (xfer->rx_buf
++                  && !((unsigned long)xfer->rx_buf & (L1_CACHE_BYTES - 1)))
++                      xfer->rx_dma = dma_map_single(&as->pdev->dev,
++                                                    xfer->rx_buf,
++                                                    xfer->len,
++                                                    DMA_FROM_DEVICE);
++      }
++}
++
++static irqreturn_t
++atmel_spi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++      struct spi_master       *master = dev_id;
++      struct atmel_spi        *as = spi_master_get_devdata(master);
++      struct spi_message      *msg;
++      struct spi_transfer     *xfer;
++      u32                     status, pending, imr;
++      int                     ret = IRQ_NONE;
++
++      imr = spi_readl(as, IMR);
++      status = spi_readl(as, SR);
++      pending = status & imr;
++pr_debug("spi irq: stat %05x imr %05x pend %05x\n", status, imr, pending);
++
++      if (pending & (SPI_BIT(ENDTX) | SPI_BIT(ENDRX))) {
++              ret = IRQ_HANDLED;
++
++              spi_writel(as, IDR, pending);
++              spin_lock(&as->lock);
++
++              xfer = as->current_transfer;
++              msg = list_entry(as->queue.next, struct spi_message, queue);
++
++              /*
++               * If the rx buffer wasn't aligned, we used a bounce
++               * buffer for the transfer. Copy the data back and
++               * make the bounce buffer ready for re-use.
++               */
++              if (xfer->rx_buf && xfer->rx_dma == INVALID_DMA_ADDRESS) {
++                      unsigned int len = xfer->len;
++                      if (len > BUFFER_SIZE)
++                              len = BUFFER_SIZE;
++
++                      dma_sync_single_for_cpu(&as->pdev->dev, as->buffer_dma,
++                                              len, DMA_FROM_DEVICE);
++                      memcpy((xfer->rx_buf + xfer->len
++                              - len - as->remaining_bytes),
++                             as->buffer, len);
++              }
++
++
++              if (as->remaining_bytes == 0) {
++                      msg->actual_length += xfer->len;
++
++                      if (!msg->is_dma_mapped) {
++                              if (xfer->tx_dma != INVALID_DMA_ADDRESS)
++                                      dma_unmap_single(master->cdev.dev,
++                                                       xfer->tx_dma,
++                                                       xfer->len,
++                                                       DMA_TO_DEVICE);
++                              if (xfer->rx_dma != INVALID_DMA_ADDRESS)
++                                      dma_unmap_single(master->cdev.dev,
++                                                       xfer->rx_dma,
++                                                       xfer->len,
++                                                       DMA_FROM_DEVICE);
++                      }
++
++                      /* REVISIT: udelay in irq is unfriendly */
++                      if (xfer->delay_usecs)
++                              udelay(xfer->delay_usecs);
++
++                      if (msg->transfers.prev == &xfer->transfer_list) {
++
++                              /* report completed message */
++                              cs_deactivate(msg->spi);
++                              list_del(&msg->queue);
++                              msg->status = 0;
++
++                              dev_dbg(master->cdev.dev,
++                                      "xfer complete: %u bytes transferred\n",
++                                      msg->actual_length);
++
++                              spin_unlock(&as->lock);
++                              msg->complete(msg->context);
++                              spin_lock(&as->lock);
++
++                              as->current_transfer = NULL;
++
++                              /* continue; complete() may have queued requests */
++                              if (list_empty(&as->queue) || as->stopping)
++                                      spi_writel(as, PTCR, SPI_BIT(RXTDIS)
++                                                 | SPI_BIT(TXTDIS));
++                              else
++                                      atmel_spi_next_message(master);
++                      } else {
++                              if (xfer->cs_change) {
++                                      cs_deactivate(msg->spi);
++                                      udelay(1);
++                                      cs_activate(msg->spi);
++                              }
++
++                              /*
++                               * Not done yet. Submit the next transfer.
++                               *
++                               * FIXME handle protocol options for xfer
++                               */
++                              atmel_spi_next_xfer(master, msg);
++                      }
++              } else {
++                      /*
++                       * Keep going, we still have data to send in
++                       * the current transfer.
++                       */
++                      atmel_spi_next_xfer(master, msg);
++              }
++              spin_unlock(&as->lock);
++      }
++
++      return ret;
++}
++
++static int atmel_spi_setup(struct spi_device *spi)
++{
++      struct atmel_spi        *as;
++      u32                     scbr, csr;
++      unsigned int            bits = spi->bits_per_word;
++      unsigned long           bus_hz, sck_hz;
++      unsigned int            npcs_pin;
++      int                     ret;
++
++      as = spi_master_get_devdata(spi->master);
++
++      if (as->stopping)
++              return -ESHUTDOWN;
++
++      if (spi->chip_select > spi->master->num_chipselect) {
++              dev_dbg(&spi->dev,
++                              "setup: invalid chipselect %u (%u defined)\n",
++                              spi->chip_select, spi->master->num_chipselect);
++              return -EINVAL;
++      }
++
++      if (bits == 0)
++              bits = 8;
++      if (bits < 8 || bits > 16) {
++              dev_dbg(&spi->dev,
++                              "setup: invalid bits_per_word %u (8 to 16)\n",
++                              bits);
++              return -EINVAL;
++      }
++
++      if (spi->mode & (SPI_CS_HIGH | SPI_LSB_FIRST)) {
++              dev_dbg(&spi->dev, "setup: unsupported mode %u\n", spi->mode);
++              return -EINVAL;
++      }
++
++      /* speed zero convention is used by some upper layers */
++      bus_hz = clk_get_rate(as->clk);
++      if (spi->max_speed_hz) {
++              /* assume div32/fdiv/mbz == 0 */
++              if (!as->new_1)
++                      bus_hz /= 2;
++              scbr = ((bus_hz + spi->max_speed_hz - 1)
++                      / spi->max_speed_hz);
++              if (scbr >= (1 << SPI_SCBR_SIZE)) {
++                      dev_dbg(&spi->dev, "setup: %d Hz too slow, scbr %u\n",
++                                      spi->max_speed_hz, scbr);
++                      return -EINVAL;
++              }
++      } else
++              scbr = 0xff;
++      sck_hz = bus_hz / scbr;
++
++      csr = SPI_BF(SCBR, scbr) | SPI_BF(BITS, bits - 8);
++      if (spi->mode & SPI_CPOL)
++              csr |= SPI_BIT(CPOL);
++      if (!(spi->mode & SPI_CPHA))
++              csr |= SPI_BIT(NCPHA);
++
++      /* TODO: DLYBS and DLYBCT */
++      csr |= SPI_BF(DLYBS, 10);
++      csr |= SPI_BF(DLYBCT, 10);
++
++      npcs_pin = (unsigned int)spi->controller_data;
++      if (!spi->controller_state) {
++              ret = gpio_request(npcs_pin, "spi_npcs");
++              if (ret)
++                      return ret;
++              spi->controller_state = (void *)npcs_pin;
++      }
++
++      gpio_set_value(npcs_pin, 1);
++
++      dev_dbg(&spi->dev,
++              "setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n",
++              sck_hz, bits, spi->mode, spi->chip_select, csr);
++
++      spi_writel(as, CSR0 + 4 * spi->chip_select, csr);
++
++      return 0;
++}
++
++static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
++{
++      struct atmel_spi        *as;
++      struct spi_transfer     *xfer;
++      unsigned long           flags;
++      struct device           *controller = spi->master->cdev.dev;
++
++      as = spi_master_get_devdata(spi->master);
++
++      dev_dbg(controller, "new message %p submitted for %s\n",
++                      msg, spi->dev.bus_id);
++
++      if (unlikely(list_empty(&msg->transfers)
++                      || !spi->max_speed_hz))
++              return -EINVAL;
++
++      if (as->stopping)
++              return -ESHUTDOWN;
++
++      list_for_each_entry(xfer, &msg->transfers, transfer_list) {
++              if (!(xfer->tx_buf || xfer->rx_buf)) {
++                      dev_dbg(&spi->dev, "missing rx or tx buf\n");
++                      return -EINVAL;
++              }
++
++              /* FIXME implement these protocol options!! */
++              if (xfer->bits_per_word || xfer->speed_hz) {
++                      dev_dbg(&spi->dev, "no protocol options yet\n");
++                      return -ENOPROTOOPT;
++              }
++      }
++
++      /* scrub dcache "early" */
++      if (!msg->is_dma_mapped) {
++              list_for_each_entry(xfer, &msg->transfers, transfer_list)
++                      atmel_spi_dma_map_xfer(as, xfer);
++      }
++
++      list_for_each_entry(xfer, &msg->transfers, transfer_list) {
++              dev_dbg(controller,
++                      "  xfer %p: len %u tx %p/%08x rx %p/%08x\n",
++                      xfer, xfer->len,
++                      xfer->tx_buf, xfer->tx_dma,
++                      xfer->rx_buf, xfer->rx_dma);
++      }
++
++      msg->status = -EINPROGRESS;
++      msg->actual_length = 0;
++
++      spin_lock_irqsave(&as->lock, flags);
++      list_add_tail(&msg->queue, &as->queue);
++      if (!as->current_transfer)
++              atmel_spi_next_message(spi->master);
++      spin_unlock_irqrestore(&as->lock, flags);
++
++      return 0;
++}
++
++static void atmel_spi_cleanup(const struct spi_device *spi)
++{
++      if (spi->controller_state)
++              gpio_free((unsigned int)spi->controller_data);
++}
++
++/*-------------------------------------------------------------------------*/
++
++static int __devinit atmel_spi_probe(struct platform_device *pdev)
++{
++      struct resource         *regs;
++      int                     irq;
++      struct clk              *clk;
++      int                     ret;
++      struct spi_master       *master;
++      struct atmel_spi        *as;
++
++      regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!regs)
++              return -ENXIO;
++
++      irq = platform_get_irq(pdev, 0);
++      if (irq < 0)
++              return irq;
++
++      clk = clk_get(&pdev->dev, "pclk");
++      if (IS_ERR(clk))
++              return PTR_ERR(clk);
++
++      /* setup spi core then atmel-specific driver state */
++      ret = -ENOMEM;
++      master = spi_alloc_master(&pdev->dev, sizeof *as);
++      if (!master)
++              goto out_free;
++
++      master->bus_num = pdev->id;
++      master->num_chipselect = 4;
++      master->setup = atmel_spi_setup;
++      master->transfer = atmel_spi_transfer;
++      master->cleanup = atmel_spi_cleanup;
++      platform_set_drvdata(pdev, master);
++
++      as = spi_master_get_devdata(master);
++
++      as->buffer = dma_alloc_coherent(&pdev->dev, BUFFER_SIZE,
++                                      &as->buffer_dma, GFP_KERNEL);
++      if (!as->buffer)
++              goto out_free;
++
++      spin_lock_init(&as->lock);
++      INIT_LIST_HEAD(&as->queue);
++      as->pdev = pdev;
++      as->regs = ioremap(regs->start, (regs->end - regs->start) + 1);
++      if (!as->regs)
++              goto out_free_buffer;
++      as->irq = irq;
++      as->clk = clk;
++#if !defined(CONFIG_ARCH_AT91RM9200)
++      /* if (!cpu_is_at91rm9200()) */
++              as->new_1 = 1;
++#endif
++
++      ret = request_irq(irq, atmel_spi_interrupt, 0,
++                      pdev->dev.bus_id, master);
++      if (ret)
++              goto out_unmap_regs;
++
++      /* Initialize the hardware */
++      clk_enable(clk);
++      spi_writel(as, CR, SPI_BIT(SWRST));
++      spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS));
++      spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
++      spi_writel(as, CR, SPI_BIT(SPIEN));
++
++      /* go! */
++      dev_info(&pdev->dev, "Atmel SPI Controller at 0x%08lx (irq %d)\n",
++                      (unsigned long)regs->start, irq);
++
++      ret = spi_register_master(master);
++      if (ret)
++              goto out_reset_hw;
++
++      return 0;
++
++out_reset_hw:
++      spi_writel(as, CR, SPI_BIT(SWRST));
++      clk_disable(clk);
++      free_irq(irq, master);
++out_unmap_regs:
++      iounmap(as->regs);
++out_free_buffer:
++      dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
++                        as->buffer_dma);
++out_free:
++      clk_put(clk);
++      spi_master_put(master);
++      return ret;
++}
++
++static int __devexit atmel_spi_remove(struct platform_device *pdev)
++{
++      struct spi_master       *master = platform_get_drvdata(pdev);
++      struct atmel_spi        *as = spi_master_get_devdata(master);
++      struct spi_message      *msg;
++
++      /* reset the hardware and block queue progress */
++      spin_lock_irq(&as->lock);
++      as->stopping = 1;
++      spi_writel(as, CR, SPI_BIT(SWRST));
++      spi_readl(as, SR);
++      spin_unlock_irq(&as->lock);
++
++      /* Terminate remaining queued transfers */
++      list_for_each_entry(msg, &as->queue, queue) {
++              /* REVISIT unmapping the dma is sort of a NOP on ARM,
++               * but we shouldn't depend on that...
++               */
++              msg->status = -ESHUTDOWN;
++              msg->complete(msg->context);
++      }
++
++      dma_free_coherent(&pdev->dev, BUFFER_SIZE, as->buffer,
++                        as->buffer_dma);
++
++      clk_disable(as->clk);
++      clk_put(as->clk);
++      free_irq(as->irq, master);
++      iounmap(as->regs);
++
++      spi_unregister_master(master);
++
++      return 0;
++}
++
++#ifdef        CONFIG_PM
++
++static int atmel_spi_suspend(struct platform_device *pdev, pm_message_t mesg)
++{
++      struct spi_master       *master = platform_get_drvdata(pdev);
++      struct atmel_spi        *as = spi_master_get_devdata(master);
++
++      clk_disable(as->clk);
++      return 0;
++}
++
++static int atmel_spi_resume(struct platform_device *pdev)
++{
++      struct spi_master       *master = platform_get_drvdata(pdev);
++      struct atmel_spi        *as = spi_master_get_devdata(master);
++
++      clk_enable(as->clk);
++      return 0;
++}
++
++#else
++#define       atmel_spi_suspend       NULL
++#define       atmel_spi_resume        NULL
++#endif
++
++
++static struct platform_driver atmel_spi_driver = {
++      .driver         = {
++              .name   = "atmel_spi",
++              .owner  = THIS_MODULE,
++      },
++      .probe          = atmel_spi_probe,
++      .suspend        = atmel_spi_suspend,
++      .resume         = atmel_spi_resume,
++      .remove         = __devexit_p(atmel_spi_remove),
++};
++
++static int __init atmel_spi_init(void)
++{
++      return platform_driver_register(&atmel_spi_driver);
++}
++module_init(atmel_spi_init);
++
++static void __exit atmel_spi_exit(void)
++{
++      platform_driver_unregister(&atmel_spi_driver);
++}
++module_exit(atmel_spi_exit);
++
++MODULE_DESCRIPTION("Atmel AT32/AT91 SPI Controller driver");
++MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
++MODULE_LICENSE("GPL");
+Index: linux-2.6.18-avr32/drivers/spi/atmel_spi.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/drivers/spi/atmel_spi.h 2006-11-29 16:55:59.000000000 +0100
+@@ -0,0 +1,167 @@
++/*
++ * Register definitions for Atmel Serial Peripheral Interface (SPI)
++ *
++ * 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 __ATMEL_SPI_H__
++#define __ATMEL_SPI_H__
++
++/* SPI register offsets */
++#define SPI_CR                                        0x0000
++#define SPI_MR                                        0x0004
++#define SPI_RDR                                       0x0008
++#define SPI_TDR                                       0x000c
++#define SPI_SR                                        0x0010
++#define SPI_IER                                       0x0014
++#define SPI_IDR                                       0x0018
++#define SPI_IMR                                       0x001c
++#define SPI_CSR0                              0x0030
++#define SPI_CSR1                              0x0034
++#define SPI_CSR2                              0x0038
++#define SPI_CSR3                              0x003c
++#define SPI_RPR                                       0x0100
++#define SPI_RCR                                       0x0104
++#define SPI_TPR                                       0x0108
++#define SPI_TCR                                       0x010c
++#define SPI_RNPR                              0x0110
++#define SPI_RNCR                              0x0114
++#define SPI_TNPR                              0x0118
++#define SPI_TNCR                              0x011c
++#define SPI_PTCR                              0x0120
++#define SPI_PTSR                              0x0124
++
++/* Bitfields in CR */
++#define SPI_SPIEN_OFFSET                      0
++#define SPI_SPIEN_SIZE                                1
++#define SPI_SPIDIS_OFFSET                     1
++#define SPI_SPIDIS_SIZE                               1
++#define SPI_SWRST_OFFSET                      7
++#define SPI_SWRST_SIZE                                1
++#define SPI_LASTXFER_OFFSET                   24
++#define SPI_LASTXFER_SIZE                     1
++
++/* Bitfields in MR */
++#define SPI_MSTR_OFFSET                               0
++#define SPI_MSTR_SIZE                         1
++#define SPI_PS_OFFSET                         1
++#define SPI_PS_SIZE                           1
++#define SPI_PCSDEC_OFFSET                     2
++#define SPI_PCSDEC_SIZE                               1
++#define SPI_FDIV_OFFSET                               3
++#define SPI_FDIV_SIZE                         1
++#define SPI_MODFDIS_OFFSET                    4
++#define SPI_MODFDIS_SIZE                      1
++#define SPI_LLB_OFFSET                                7
++#define SPI_LLB_SIZE                          1
++#define SPI_PCS_OFFSET                                16
++#define SPI_PCS_SIZE                          4
++#define SPI_DLYBCS_OFFSET                     24
++#define SPI_DLYBCS_SIZE                               8
++
++/* Bitfields in RDR */
++#define SPI_RD_OFFSET                         0
++#define SPI_RD_SIZE                           16
++
++/* Bitfields in TDR */
++#define SPI_TD_OFFSET                         0
++#define SPI_TD_SIZE                           16
++
++/* Bitfields in SR */
++#define SPI_RDRF_OFFSET                               0
++#define SPI_RDRF_SIZE                         1
++#define SPI_TDRE_OFFSET                               1
++#define SPI_TDRE_SIZE                         1
++#define SPI_MODF_OFFSET                               2
++#define SPI_MODF_SIZE                         1
++#define SPI_OVRES_OFFSET                      3
++#define SPI_OVRES_SIZE                                1
++#define SPI_ENDRX_OFFSET                      4
++#define SPI_ENDRX_SIZE                                1
++#define SPI_ENDTX_OFFSET                      5
++#define SPI_ENDTX_SIZE                                1
++#define SPI_RXBUFF_OFFSET                     6
++#define SPI_RXBUFF_SIZE                               1
++#define SPI_TXBUFE_OFFSET                     7
++#define SPI_TXBUFE_SIZE                               1
++#define SPI_NSSR_OFFSET                               8
++#define SPI_NSSR_SIZE                         1
++#define SPI_TXEMPTY_OFFSET                    9
++#define SPI_TXEMPTY_SIZE                      1
++#define SPI_SPIENS_OFFSET                     16
++#define SPI_SPIENS_SIZE                               1
++
++/* Bitfields in CSR0 */
++#define SPI_CPOL_OFFSET                               0
++#define SPI_CPOL_SIZE                         1
++#define SPI_NCPHA_OFFSET                      1
++#define SPI_NCPHA_SIZE                                1
++#define SPI_CSAAT_OFFSET                      3
++#define SPI_CSAAT_SIZE                                1
++#define SPI_BITS_OFFSET                               4
++#define SPI_BITS_SIZE                         4
++#define SPI_SCBR_OFFSET                               8
++#define SPI_SCBR_SIZE                         8
++#define SPI_DLYBS_OFFSET                      16
++#define SPI_DLYBS_SIZE                                8
++#define SPI_DLYBCT_OFFSET                     24
++#define SPI_DLYBCT_SIZE                               8
++
++/* Bitfields in RCR */
++#define SPI_RXCTR_OFFSET                      0
++#define SPI_RXCTR_SIZE                                16
++
++/* Bitfields in TCR */
++#define SPI_TXCTR_OFFSET                      0
++#define SPI_TXCTR_SIZE                                16
++
++/* Bitfields in RNCR */
++#define SPI_RXNCR_OFFSET                      0
++#define SPI_RXNCR_SIZE                                16
++
++/* Bitfields in TNCR */
++#define SPI_TXNCR_OFFSET                      0
++#define SPI_TXNCR_SIZE                                16
++
++/* Bitfields in PTCR */
++#define SPI_RXTEN_OFFSET                      0
++#define SPI_RXTEN_SIZE                                1
++#define SPI_RXTDIS_OFFSET                     1
++#define SPI_RXTDIS_SIZE                               1
++#define SPI_TXTEN_OFFSET                      8
++#define SPI_TXTEN_SIZE                                1
++#define SPI_TXTDIS_OFFSET                     9
++#define SPI_TXTDIS_SIZE                               1
++
++/* Constants for BITS */
++#define SPI_BITS_8_BPT                                0
++#define SPI_BITS_9_BPT                                1
++#define SPI_BITS_10_BPT                               2
++#define SPI_BITS_11_BPT                               3
++#define SPI_BITS_12_BPT                               4
++#define SPI_BITS_13_BPT                               5
++#define SPI_BITS_14_BPT                               6
++#define SPI_BITS_15_BPT                               7
++#define SPI_BITS_16_BPT                               8
++
++/* Bit manipulation macros */
++#define SPI_BIT(name) \
++      (1 << SPI_##name##_OFFSET)
++#define SPI_BF(name,value) \
++      (((value) & ((1 << SPI_##name##_SIZE) - 1)) << SPI_##name##_OFFSET)
++#define SPI_BFEXT(name,value) \
++      (((value) >> SPI_##name##_OFFSET) & ((1 << SPI_##name##_SIZE) - 1))
++#define SPI_BFINS(name,value,old) \
++      ( ((old) & ~(((1 << SPI_##name##_SIZE) - 1) << SPI_##name##_OFFSET)) \
++        | SPI_BF(name,value))
++
++/* Register access macros */
++#define spi_readl(port,reg) \
++      __raw_readl((port)->regs + SPI_##reg)
++#define spi_writel(port,reg,value) \
++      __raw_writel((value), (port)->regs + SPI_##reg)
++
++#endif /* __ATMEL_SPI_H__ */
diff --git a/packages/linux/linux-2.6.18/atmel-twi-driver.patch b/packages/linux/linux-2.6.18/atmel-twi-driver.patch
new file mode 100644 (file)
index 0000000..97ede9b
--- /dev/null
@@ -0,0 +1,521 @@
+rom: Espen Krangnes <ekrangnes at atmel.com>
+
+This patch will add support for Atmel TWI for the AVR32 architecture. Atmel's TWI is compatible with Philips' I2C protocol. It supports Master read and write, and has support for different baudrates that can be set by the user. It uses the Linux I2C framework. The driver is based on the main principles of the TWI driver for the Atmel AT91 series.
+
+Signed-off-by: Espen Krangnes <ekrangnes at atmel.com>
+
+
+diff -Naur linux-2.6.18.orig/drivers/i2c/busses/atmeltwi.h linux-2.6.18/drivers/i2c/busses/atmeltwi.h
+--- linux-2.6.18.orig/drivers/i2c/busses/atmeltwi.h    1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18/drivers/i2c/busses/atmeltwi.h 2006-12-20 12:42:48.000000000 +0100
+@@ -0,0 +1,117 @@
++/*
++ * Register definitions for the Atmel Two-Wire Interface
++ */
++
++#ifndef __ASM_AVR32_TWI_H__
++#define __ASM_AVR32_TWI_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 /* __ASM_AVR32_TWI_H__ */
+diff -Naur linux-2.6.18.orig/drivers/i2c/busses/i2c-atmeltwi.c linux-2.6.18/drivers/i2c/busses/i2c-atmeltwi.c
+--- linux-2.6.18.orig/drivers/i2c/busses/i2c-atmeltwi.c        1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.18/drivers/i2c/busses/i2c-atmeltwi.c     2006-12-20 13:30:49.000000000 +0100
+@@ -0,0 +1,348 @@
++/*
++ * 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>
++ *
++ * 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.
++ */
++
++
++#include <linux/err.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/slab.h>
++#include <linux/types.h>
++#include <linux/delay.h>
++#include <linux/i2c.h>
++#include <linux/init.h>
++#include <linux/clk.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/platform_device.h>
++#include <linux/completion.h>
++#include <asm/io.h>
++#include <linux/time.h>
++#include "atmeltwi.h"
++
++static unsigned int baudrate = CONFIG_I2C_ATMELTWI_BAUDRATE;
++module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
++MODULE_PARM_DESC(baudrate, "The TWI baudrate");
++
++
++struct atmel_twi {
++      void __iomem *regs;
++      struct i2c_adapter adapter;
++      struct clk *pclk;
++      spinlock_t lock;
++      struct completion comp;
++      u32 intmask;
++      u8 *buf;
++      u8 len;
++      u8 acks_left;
++      unsigned int irq;
++
++};
++#define to_atmel_twi(adap) container_of(adap, struct atmel_twi, adapter)
++
++/*
++ * Initialize the TWI hardware registers.
++ */
++static int __devinit twi_hwinit(struct atmel_twi *twi)
++{
++      unsigned long cdiv, ckdiv=0;
++
++      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;
++      }
++
++      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).
++ */
++static short twi_wait_for_completion(struct atmel_twi *twi,
++              u32 mask)
++{
++      int timeout = msecs_to_jiffies(100);
++
++      twi->intmask = mask;
++      init_completion(&twi->comp);
++
++      twi_writel(twi, IER, mask);
++
++      if(!wait_for_completion_timeout(&twi->comp, timeout))
++              return -ETIMEDOUT;
++
++      return 0;
++}
++
++/*
++ * Generic i2c master transfer entrypoint.
++ */
++static int twi_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
++{
++      struct atmel_twi *twi = to_atmel_twi(adap);
++      struct i2c_msg *pmsg;
++      int i;
++
++      /* get first message */
++      pmsg = msgs;
++
++      dev_dbg(&adap->dev, "twi_xfer: processing %d messages:\n", num);
++
++      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: internal addr %d %s byte%s %s 0x%02x\n",
++                      i,pmsg->len, pmsg->flags & I2C_M_RD ? "reading" : "writing",
++                      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) {
++                      twi_writel(twi, CR, TWI_BIT(START));
++                      if ( twi_wait_for_completion(twi,TWI_BIT(RXRDY))==-ETIMEDOUT ) {
++                              dev_dbg(&adap->dev, "RXRDY timeout. Stopped with %d bytes left\n",
++                                      twi->acks_left);
++                              return -ETIMEDOUT;
++                      }
++
++                      /* Send Stop, and Wait until transfer is finished */
++                      if ( twi_wait_for_completion(twi,TWI_BIT(TXCOMP))==-ETIMEDOUT ) {
++                              dev_dbg(&adap->dev, "TXCOMP timeout\n");
++                              return -ETIMEDOUT;
++                      }
++
++              } else {
++                      twi_writel(twi, THR, twi->buf[0]);
++                      if ( twi_wait_for_completion(twi,TWI_BIT(TXRDY))==-ETIMEDOUT ) {
++                              dev_dbg(&adap->dev, "TXRDY timeout. Stopped with %d bytes left\n",
++                              twi->acks_left);
++                              return -ETIMEDOUT;
++                      }
++              }
++
++              /* Disable TWI interface */
++              twi_writel(twi, CR, TWI_BIT(MSDIS));
++
++      } /* end cur msg */
++
++      return i;
++}
++
++
++static irqreturn_t twi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++      struct atmel_twi *twi = dev_id;
++      int status = twi_readl(twi, SR);
++
++      if (twi->intmask & status){
++              if (twi->intmask & TWI_BIT(NACK)) {
++                      goto nack;
++              } else if (twi->intmask & TWI_BIT(RXRDY)){
++                      twi->buf[twi->len - twi->acks_left] = twi_readl(twi,RHR);
++                      if(--twi->acks_left==1)
++                              twi_writel(twi, CR, TWI_BIT(STOP));
++                      if (twi->acks_left==0)
++                              goto complete;
++              } else if (twi->intmask & TWI_BIT(TXRDY)) {
++                      twi->acks_left--;
++                      if (twi->acks_left==0) {
++                              twi->intmask = TWI_BIT(TXCOMP);
++                              twi_writel(twi, IER, TWI_BIT(TXCOMP));
++                      } else
++                              twi_writel(twi, THR, twi->buf[twi->len - twi->acks_left]);
++              } else if (twi->intmask & TWI_BIT(TXCOMP)) {
++                      goto complete;
++              }
++      }
++
++      return IRQ_HANDLED;
++
++nack:
++      printk(KERN_INFO "NACK received!\n");
++
++complete:
++      twi_writel(twi, IDR, ~0UL);
++      complete(&twi->comp);
++
++      return IRQ_HANDLED;
++
++}
++
++
++/*
++ * Return list of supported functionality.
++ */
++static u32 twi_func(struct i2c_adapter *adapter)
++{
++      return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
++}
++
++/* For now, we only handle combined mode (smbus) */
++static struct i2c_algorithm twi_algorithm = {
++      .master_xfer    = twi_xfer,
++      .functionality  = twi_func,
++};
++
++/*
++ * Main initialization routine.
++ */
++static int __devinit 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, "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_err(&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_err(&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_HWMON;
++      adapter->dev.parent = &pdev->dev;
++
++      platform_set_drvdata(pdev, twi);
++
++      rc = i2c_add_adapter(adapter);
++      if (rc) {
++              dev_err(&pdev->dev, "Adapter %s registration failed\n",
++                      adapter->name);
++              goto err_register;
++      }
++
++      dev_info(&pdev->dev, "Atmel TWI i2c bus device (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 __devexit 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 = {
++      .probe          = twi_probe,
++      .remove         = __devexit_p(twi_remove),
++      .driver         = {
++              .name   = "atmel_twi",
++              .owner  = THIS_MODULE,
++      },
++};
++
++static int __init atmel_twi_init(void)
++{
++      return platform_driver_register(&twi_driver);
++}
++
++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");
+diff -Naur linux-2.6.18.orig/drivers/i2c/busses/Kconfig linux-2.6.18/drivers/i2c/busses/Kconfig
+--- linux-2.6.18.orig/drivers/i2c/busses/Kconfig       2006-09-20 05:42:06.000000000 +0200
++++ linux-2.6.18/drivers/i2c/busses/Kconfig    2006-12-18 22:41:58.000000000 +0100
+@@ -5,6 +5,26 @@
+ menu "I2C Hardware Bus support"
+       depends on I2C
++config I2C_ATMELTWI
++      tristate "Atmel TWI/I2C"
++      depends on I2C
++      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. Atmel's TWI is compatible with Philips' I2C
++        protocol. If in doubt, say NO
++
++config I2C_ATMELTWI_BAUDRATE
++      prompt "Atmel TWI baudrate"
++      depends on I2C_ATMELTWI
++      int
++      default 100000
++      help
++        Set the TWI/I2C baudrate. This will alter the default value. A
++        different baudrate can be set by using a module parameter as well. If
++        no parameter is provided when loading, this is the value that will be
++        used.
++
+ config I2C_ALI1535
+       tristate "ALI 1535"
+       depends on I2C && PCI
+diff -Naur linux-2.6.18.orig/drivers/i2c/busses/Makefile linux-2.6.18/drivers/i2c/busses/Makefile
+--- linux-2.6.18.orig/drivers/i2c/busses/Makefile      2006-09-20 05:42:06.000000000 +0200
++++ linux-2.6.18/drivers/i2c/busses/Makefile   2006-12-18 22:42:14.000000000 +0100
+@@ -43,6 +43,7 @@
+ 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
diff --git a/packages/linux/linux-2.6.18/atmel-usart3-driver.patch b/packages/linux/linux-2.6.18/atmel-usart3-driver.patch
new file mode 100644 (file)
index 0000000..2f1b1cf
--- /dev/null
@@ -0,0 +1,1443 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Fri Nov 18 16:31:34 2005 +0100
+Subject: [PATCH] AVR32: USART3 Serial Driver
+
+---
+
+ drivers/serial/Kconfig       |   21 
+ drivers/serial/Makefile      |    1 
+ drivers/serial/atmel_usart.c | 1086 +++++++++++++++++++++++++++++++++++++++++++
+ drivers/serial/atmel_usart.h |  290 +++++++++++
+ 4 files changed, 1398 insertions(+)
+
+Index: linux-2.6.18-avr32/drivers/serial/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/serial/Kconfig     2006-11-02 14:16:07.000000000 +0100
++++ linux-2.6.18-avr32/drivers/serial/Kconfig  2006-11-02 15:54:18.000000000 +0100
+@@ -246,6 +246,27 @@ config SERIAL_8250_AU1X00
+ comment "Non-8250 serial port support"
++config SERIAL_ATMEL
++      tristate "Atmel USART3 serial port support"
++      depends on AVR32
++      select SERIAL_CORE
++      default y
++      help
++        Support for the Atmel USART3 on-chip USART found in most
++        AT32 and AT91 parts from Atmel.
++
++        If unsure, say Y.
++
++config SERIAL_ATMEL_CONSOLE
++      bool "Support for console on Atmel USART3 serial port"
++      depends on SERIAL_ATMEL=y
++      select SERIAL_CORE_CONSOLE
++      help
++        Say Y here if you wish to use an Atmel USART3 serial port as
++        the system console (the system console is the device which
++        receives all kernel messages and warnings and which allows
++        logins in single user mode).
++
+ config SERIAL_AMBA_PL010
+       tristate "ARM AMBA PL010 serial port support"
+       depends on ARM_AMBA && (BROKEN || !ARCH_VERSATILE)
+Index: linux-2.6.18-avr32/drivers/serial/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/serial/Makefile    2006-11-02 14:16:07.000000000 +0100
++++ linux-2.6.18-avr32/drivers/serial/Makefile 2006-11-02 14:17:29.000000000 +0100
+@@ -20,6 +20,7 @@ obj-$(CONFIG_SERIAL_8250_BOCA) += 8250_b
+ obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
+ obj-$(CONFIG_SERIAL_8250_MCA) += 8250_mca.o
+ obj-$(CONFIG_SERIAL_8250_AU1X00) += 8250_au1x00.o
++obj-$(CONFIG_SERIAL_ATMEL) += atmel_usart.o
+ obj-$(CONFIG_SERIAL_AMBA_PL010) += amba-pl010.o
+ obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o
+ obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
+Index: linux-2.6.18-avr32/drivers/serial/atmel_usart.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/drivers/serial/atmel_usart.c    2006-11-02 15:54:18.000000000 +0100
+@@ -0,0 +1,1086 @@
++/*
++ * Driver for Atmel USART3 Serial ports
++ *
++ * Based on AT91RM9200 serial driver by Rick Bronson
++ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
++ * Based on drivers/serial/sa1100.c by Deep Blue Solutions Ltd.
++ *
++ * 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/clk.h>
++#include <linux/console.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/sched.h>
++#include <linux/serial.h>
++#include <linux/tty.h>
++
++#include <asm/io.h>
++#include <asm/irq.h>
++
++#include <asm/arch/board.h>
++
++#if defined(CONFIG_SERIAL_ATMEL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
++#define SUPPORT_SYSRQ
++#include <linux/sysrq.h>
++#endif
++
++#include <linux/serial_core.h>
++
++#include "atmel_usart.h"
++
++/*
++ * TODO: Move this definition into linux/serial_core.h
++ */
++#define PORT_USART3           60
++
++/*
++ * Use the same major/minor numbers as the AT91 USART, which is
++ * actually the same chip
++ */
++#define SERIAL_USART3_MAJOR   TTY_MAJOR
++#define MINOR_START           64
++#define NR_PORTS              4
++
++#define ERROR_FLAGS           (USART3_BIT(CSR_PARE)           \
++                               | USART3_BIT(CSR_FRAME)        \
++                               | USART3_BIT(CSR_OVRE))
++
++/* Must be a power of two, or everything will break */
++#define RX_BUFFER_SIZE                32
++struct usart3_port {
++      void __iomem *regs;
++      int break_active;
++      unsigned int tx_dma_head;
++      int rx_tail;
++      char *rx_buffer;
++      dma_addr_t rx_dma;
++      dma_addr_t tx_dma;
++      struct clk *mck;
++      unsigned long mapsize;
++      struct uart_port uart;
++};
++#define to_usart3_port(port) container_of(port, struct usart3_port, uart)
++
++static void tx_dma_sync(struct uart_port *port)
++{
++      struct usart3_port *up = to_usart3_port(port);
++      struct circ_buf *xmit = &port->info->xmit;
++
++      if (xmit->head < up->tx_dma_head) {
++              dma_sync_single_for_device(port->dev,
++                                         up->tx_dma + up->tx_dma_head,
++                                         UART_XMIT_SIZE - up->tx_dma_head,
++                                         DMA_TO_DEVICE);
++              dma_sync_single_for_device(port->dev, up->tx_dma,
++                                         xmit->head, DMA_TO_DEVICE);
++      } else {
++              dma_sync_single_for_device(port->dev,
++                                         up->tx_dma + up->tx_dma_head,
++                                         xmit->head - up->tx_dma_head,
++                                         DMA_TO_DEVICE);
++      }
++}
++
++static void tx_dma_update_tail(struct uart_port *port)
++{
++      struct usart3_port *up = to_usart3_port(port);
++      struct circ_buf *xmit = &port->info->xmit;
++      unsigned long status, remaining;
++      unsigned int new_tail;
++
++      /* Account for the characters DMA'ed since last update */
++      remaining = usart3_readl(up, TCR);
++
++      if (up->tx_dma_head < xmit->tail) {
++              /*
++               * We have wrapped around, and there's a chunk at the
++               * beginning of the buffer that has been submitted for
++               * DMA.  If the ENDTX bit is set, it means that the
++               * DMA controller also has wrapped around and copied
++               * TNPR/TNCR into TPR/TCR.
++               */
++              status = usart3_readl(up, CSR);
++              BUG_ON((up->tx_dma_head != 0)
++                     && (usart3_readl(up, TNCR) == 0)
++                     && !(status & USART3_BIT(ENDTX)));
++              if (status & USART3_BIT(ENDTX)) {
++                      BUG_ON(usart3_readl(up, TNCR) != 0);
++
++                      /* The ENDTX bit might be set after we read TCR */
++                      remaining = usart3_readl(up, TCR);
++
++                      usart3_writel(up, TNCR, 0);
++                      port->icount.tx += UART_XMIT_SIZE - xmit->tail;
++                      xmit->tail = 0;
++
++                      BUG_ON(remaining > up->tx_dma_head);
++                      new_tail = up->tx_dma_head - remaining;
++              } else {
++                      /*
++                       * The DMA controller hasn't switched yet, so
++                       * TCR indicates the number of bytes left
++                       * until this happens.
++                       */
++                      new_tail = UART_XMIT_SIZE - remaining;
++              }
++      } else {
++              /* No wraparound, move the tail closer to dma_head. */
++              BUG_ON(remaining > up->tx_dma_head);
++              new_tail = up->tx_dma_head - remaining;
++      }
++
++      BUG_ON(new_tail < xmit->tail);
++      port->icount.tx += new_tail - xmit->tail;
++      xmit->tail = new_tail;
++}
++
++static inline void tx_dma_start(struct usart3_port *up)
++{
++      /* Start the PDC and enable interrupts */
++      usart3_writel(up, PTCR, USART3_BIT(TXTEN));
++      usart3_writel(up, IER, USART3_BIT(ENDTX));
++}
++
++static inline void tx_dma_stop(struct usart3_port *up)
++{
++      usart3_writel(up, PTCR, USART3_BIT(TXTDIS));
++      usart3_writel(up, IDR, USART3_BIT(ENDTX));
++}
++
++static inline unsigned int rx_dma_get_head(struct usart3_port *up)
++{
++      unsigned int head;
++      u32 status;
++
++      head = RX_BUFFER_SIZE - usart3_readl(up, RCR);
++      status = usart3_readl(up, CSR);
++      if (status & USART3_BIT(ENDRX))
++              head = RX_BUFFER_SIZE;
++
++      return head;
++}
++
++static inline int rx_dma_update_tail(struct usart3_port *up,
++                                   unsigned int tail)
++{
++      int again = 0;
++
++      if (!(tail & (RX_BUFFER_SIZE - 1))) {
++              u32 rnpr = up->rx_dma;
++
++              tail &= RX_BUFFER_SIZE;
++              if (!tail)
++                      rnpr += RX_BUFFER_SIZE;
++
++              usart3_writel(up, RNPR, rnpr);
++              usart3_writel(up, RNCR, RX_BUFFER_SIZE);
++
++              again = 1;
++      } else
++              BUG_ON(usart3_readl(up, CSR) & USART3_BIT(ENDRX));
++
++      up->rx_tail = tail;
++
++      return again;
++}
++
++static void usart3_stop_tx(struct uart_port *port)
++{
++      struct usart3_port *up = to_usart3_port(port);
++
++      tx_dma_stop(up);
++      tx_dma_update_tail(port);
++}
++
++static void usart3_start_tx(struct uart_port *port)
++{
++      struct usart3_port *up = to_usart3_port(port);
++      struct circ_buf *xmit = &port->info->xmit;
++
++      BUG_ON(!irqs_disabled());
++
++      /*
++       * Stop the DMA engine so that we don't have to worry about race
++       * conditions when updating the various pointers and counters.
++       */
++      tx_dma_stop(up);
++
++      tx_dma_sync(port);
++      tx_dma_update_tail(port);
++
++      if (uart_circ_empty(xmit))
++              return;
++
++      usart3_writel(up, TPR, up->tx_dma + xmit->tail);
++
++      if (xmit->head > xmit->tail) {
++              usart3_writel(up, TCR, xmit->head - xmit->tail);
++      } else {
++              usart3_writel(up, TCR, UART_XMIT_SIZE - xmit->tail);
++              usart3_writel(up, TNPR, up->tx_dma);
++              usart3_writel(up, TNCR, xmit->head);
++      }
++
++      /* Keep track of what we've submitted for DMA */
++      up->tx_dma_head = xmit->head;
++
++      /* Resume operation of DMA engine. */
++      tx_dma_start(up);
++}
++
++static void usart3_stop_rx(struct uart_port *port)
++{
++      struct usart3_port *up = to_usart3_port(port);
++
++      pr_debug("usart3: stop_rx\n");
++
++      usart3_writel(up, PTCR, USART3_BIT(RXTDIS));
++      usart3_writel(up, IDR, (USART3_BIT(TIMEOUT)
++                              | USART3_BIT(ENDRX)
++                              | USART3_BIT(RXBRK)
++                              | USART3_BIT(OVRE)
++                              | USART3_BIT(FRAME)
++                              | USART3_BIT(PARE)));
++}
++
++static void usart3_flush_buffer(struct uart_port *port)
++{
++      struct usart3_port *up = to_usart3_port(port);
++
++      /*
++       * Reset TX DMA state. Note that we must _always_ update TNCR
++       * before TCR, since the value in TNCR will automatically move
++       * to TCR when TCR is 0.
++       */
++      usart3_writel(up, TNCR, 0);
++      usart3_writel(up, TCR, 0);
++      up->tx_dma_head = port->info->xmit.tail;
++}
++
++/*
++ * Enable modem status interrupts
++ */
++static void usart3_enable_ms(struct uart_port *port)
++{
++      struct usart3_port *up = to_usart3_port(port);
++
++      pr_debug("usart3: enable_ms\n");
++      usart3_writel(up, IER, (USART3_BIT(RIIC)
++                              | USART3_BIT(DSRIC)
++                              | USART3_BIT(DCDIC)
++                              | USART3_BIT(CTSIC)));
++}
++
++static inline void handle_rx_error(struct uart_port *port, u32 status)
++{
++      /*
++       * FIXME: Errors should affect the flag buffer, but due to the
++       * PDC, we don't really know which char they belong to...
++       */
++      if (status & USART3_BIT(PARE)) {
++              printk(KERN_NOTICE "usart%u: Parity error\n", port->line);
++              port->icount.parity++;
++      } else if (status & USART3_BIT(FRAME)) {
++              printk(KERN_NOTICE "usart%u: Frame error\n", port->line);
++              port->icount.frame++;
++      }
++      if (status & USART3_BIT(OVRE)) {
++              printk(KERN_NOTICE "usart%u: Overrun\n", port->line);
++              port->icount.overrun++;
++      }
++
++#ifdef SUPPORT_SYSRQ
++      port->sysrq = 0;
++#endif
++}
++
++static inline void handle_pdc_endtx(struct uart_port *port, unsigned long status)
++{
++      struct usart3_port *up = to_usart3_port(port);
++      struct circ_buf *xmit = &port->info->xmit;
++
++      tx_dma_update_tail(port);
++
++      if (uart_tx_stopped(port)) {
++              usart3_stop_tx(port);
++              printk("usart3: stopped\n");
++              return;
++      }
++
++      if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
++              uart_write_wakeup(port);
++
++      if (uart_circ_empty(xmit))
++              usart3_stop_tx(port);
++
++      /*
++       * It could be that xmit is being updated right now. If so,
++       * start_tx() will be called shortly.
++       */
++      if (status & USART3_BIT(TXBUFE))
++              usart3_writel(up, IDR, USART3_BIT(ENDTX));
++}
++
++static void consume_rx_buffer(struct uart_port *port, struct pt_regs *regs)
++{
++      struct usart3_port *up = to_usart3_port(port);
++      struct tty_struct *tty = port->info->tty;
++      unsigned long head, tail;
++      int len;
++      int again;
++
++      do {
++              /*
++               * Re-arm the timeout before we decide how many
++               * characters to read.
++               */
++              usart3_writel(up, CR, USART3_BIT(STTTO));
++
++              head = rx_dma_get_head(up);
++
++              tail = up->rx_tail;
++              if (tail & RX_BUFFER_SIZE)
++                      head += RX_BUFFER_SIZE;
++
++              if (head == tail)
++                      break;
++
++              dma_sync_single_for_cpu(port->dev, up->rx_dma + tail,
++                                      head - tail, DMA_FROM_DEVICE);
++
++              if (uart_handle_sysrq_char(port, up->rx_buffer[tail],
++                                         regs)) {
++                      tail++;
++                      if (head == tail)
++                              goto update_tail;
++              }
++
++              len = tty_insert_flip_string(tty, up->rx_buffer + tail,
++                                           head - tail);
++              port->icount.rx += len;
++              tail += len;
++              if (!(head & (RX_BUFFER_SIZE - 1)) && tail != head) {
++                      /*
++                       * head has wrapped, but there isn't enough
++                       * room in the buffer to handle all the
++                       * characters.  We must recycle this buffer in
++                       * order to clear the interrupt.
++                       */
++                      tty_insert_flip_char(tty, 0, TTY_OVERRUN);
++                      tail = head;
++              }
++
++      update_tail:
++              again = rx_dma_update_tail(up, tail);
++      } while (again);
++
++      tty_flip_buffer_push(tty);
++}
++
++/*
++ * This is the serial driver's interrupt routine
++ */
++static irqreturn_t usart3_interrupt(int irq, void *dev_id,
++                                  struct pt_regs *regs)
++{
++      struct uart_port *port = dev_id;
++      struct usart3_port *up = to_usart3_port(port);
++      u32 status, mask, pending;
++      irqreturn_t ret = IRQ_NONE;
++
++      spin_lock(&port->lock);
++
++      status = usart3_readl(up, CSR);
++      mask = usart3_readl(up, IMR);
++      pending = status & mask;
++      if (unlikely(!pending))
++              goto out;
++
++      ret = IRQ_HANDLED;
++
++      do {
++              /*
++               * Consume the buffer and flip buffers if necessary.
++               */
++              consume_rx_buffer(port, regs);
++
++              /* Clear any break and error flags */
++              usart3_writel(up, CR, USART3_BIT(RSTSTA));
++
++              if (pending & (USART3_BIT(OVRE)
++                             | USART3_BIT(FRAME)
++                             | USART3_BIT(PARE)))
++                      handle_rx_error(port, status);
++
++              if (pending & USART3_BIT(RXBRK)) {
++                      if (up->break_active) {
++                              up->break_active = 0;
++                      } else {
++                              up->break_active = 1;
++                              port->icount.brk++;
++                              uart_handle_break(port);
++                      }
++              }
++
++              if (pending & USART3_BIT(RIIC))
++                      port->icount.rng++;
++              if (pending & USART3_BIT(DSRIC))
++                      port->icount.dsr++;
++              if (pending & USART3_BIT(DCDIC)) {
++                      port->icount.dcd++;
++                      uart_handle_dcd_change
++                              (port, status & USART3_BIT(DCD));
++              }
++              if (pending & USART3_BIT(CTSIC)) {
++                      port->icount.cts++;
++                      uart_handle_cts_change
++                              (port, status & USART3_BIT(CTS));
++              }
++              if (pending & (USART3_BIT(RIIC)
++                             | USART3_BIT(DSRIC)
++                             | USART3_BIT(DCDIC)
++                             | USART3_BIT(CTSIC)))
++                      wake_up_interruptible(&port->info->delta_msr_wait);
++
++              if (pending & USART3_BIT(ENDTX))
++                      handle_pdc_endtx(port, status);
++
++              status = usart3_readl(up, CSR);
++              pending = status & usart3_readl(up, IMR);
++      } while (pending);
++
++out:
++      spin_unlock(&port->lock);
++      return ret;
++}
++
++/*
++ * Return TIOCSER_TEMT when transmitter is not busy
++ */
++static unsigned int usart3_tx_empty(struct uart_port *port)
++{
++      struct usart3_port *up = to_usart3_port(port);
++      unsigned int ret = 0;
++
++      if (usart3_readl(up, CSR) & USART3_BIT(TXEMPTY))
++              ret = TIOCSER_TEMT;
++
++      pr_debug("usart3: tx_empty returned %x\n", ret);
++
++      return ret;
++}
++
++static unsigned int usart3_get_mctrl(struct uart_port *port)
++{
++      struct usart3_port *up = to_usart3_port(port);
++      unsigned int ret = 0;
++      unsigned int status;
++
++      status = usart3_readl(up, CSR);
++      if (status & USART3_BIT(DCD))
++              ret |= TIOCM_CD;
++      if (status & USART3_BIT(CTS))
++              ret |= TIOCM_CTS;
++      if (status & USART3_BIT(DSR))
++              ret |= TIOCM_DSR;
++      if (status & USART3_BIT(RI))
++              ret |= TIOCM_RI;
++
++      pr_debug("usart3: get_mctrl returned %x\n", ret);
++
++      return ret;
++}
++
++static void usart3_set_mctrl(struct uart_port *port, unsigned int mctrl)
++{
++      struct usart3_port *up = to_usart3_port(port);
++      unsigned int control = 0;
++
++      pr_debug("usart3: set_mctrl %x\n", mctrl);
++
++      if (mctrl & TIOCM_RTS)
++              control |= USART3_BIT(RTSEN);
++      else
++              control |= USART3_BIT(RTSDIS);
++
++      if (mctrl & TIOCM_DTR)
++              control |= USART3_BIT(DTREN);
++      else
++              control |= USART3_BIT(DTRDIS);
++
++      usart3_writel(up, CR, control);
++}
++
++static void usart3_break_ctl(struct uart_port *port, int break_state)
++{
++      struct usart3_port *up = to_usart3_port(port);
++
++      pr_debug("usart3: break_ctl %u\n", break_state);
++      if (break_state != 0)
++              usart3_writel(up, CR, USART3_BIT(STTBRK));
++      else
++              usart3_writel(up, CR, USART3_BIT(STPBRK));
++}
++
++static int usart3_startup(struct uart_port *port)
++{
++      struct usart3_port *up = to_usart3_port(port);
++      int ret;
++
++      pr_debug("usart3: startup\n");
++
++      up->break_active = 0;
++
++      /* Set up interrupt handler */
++      ret = request_irq(port->irq, usart3_interrupt, 0,
++                        port->info->tty->name, port);
++      if (ret) {
++              printk(KERN_ERR "usart3: Unable to request irq %d\n",
++                     port->irq);
++              return ret;
++      }
++
++      up->rx_dma = dma_map_single(port->dev, up->rx_buffer,
++                                  2 * RX_BUFFER_SIZE, DMA_FROM_DEVICE);
++      up->tx_dma = dma_map_single(port->dev, port->info->xmit.buf,
++                                  UART_XMIT_SIZE, DMA_TO_DEVICE);
++
++      /* Initialize the PDC for RX (TX is done in start_tx) */
++      up->rx_tail = 0;
++      usart3_writel(up, RPR, up->rx_dma);
++      usart3_writel(up, RCR, RX_BUFFER_SIZE);
++      usart3_writel(up, RNPR, up->rx_dma + RX_BUFFER_SIZE);
++      usart3_writel(up, RNCR, RX_BUFFER_SIZE);
++      usart3_writel(up, PTCR, USART3_BIT(RXTEN));
++
++      /* Reset DMA state */
++      usart3_writel(up, TNCR, 0);
++      usart3_writel(up, TCR, 0);
++      up->tx_dma_head = port->info->xmit.tail;
++
++      /*
++       * Set a suitable timeout. 2000 bit periods corresponds to
++       * about 17 ms at 115200 bps
++       */
++      usart3_writel(up, RTOR, 2000);
++
++      /* Reset and enable receiver and transmitter */
++      usart3_writel(up, CR, (USART3_BIT(RSTRX)
++                                | USART3_BIT(RSTTX)
++                                | USART3_BIT(RSTSTA)));
++      usart3_writel(up, CR, (USART3_BIT(RXEN)
++                                | USART3_BIT(TXEN)));
++
++      /* Enable timeout, end of rx, break and error interrupts */
++      usart3_writel(up, IER, (USART3_BIT(TIMEOUT)
++                                 | USART3_BIT(ENDRX)
++                                 | USART3_BIT(RXBRK)
++                                 | USART3_BIT(OVRE)
++                                 | USART3_BIT(FRAME)
++                                 | USART3_BIT(PARE)));
++
++      /* Arm the timeout counter */
++      usart3_writel(up, CR, USART3_BIT(STTTO));
++
++      return 0;
++}
++
++static void usart3_shutdown(struct uart_port *port)
++{
++      struct usart3_port *up = to_usart3_port(port);
++
++      pr_debug("usart3: shutdown\n");
++
++      /* Disable all interrupts and reset any error flags */
++      usart3_writel(up, IDR, -1L);
++      usart3_writel(up, CR, USART3_BIT(RSTSTA));
++
++      dma_unmap_single(port->dev, up->rx_dma, 2 * RX_BUFFER_SIZE,
++                       DMA_FROM_DEVICE);
++      dma_unmap_single(port->dev, up->tx_dma, UART_XMIT_SIZE,
++                       DMA_TO_DEVICE);
++
++      free_irq(port->irq, port);
++}
++
++static void usart3_set_termios(struct uart_port *port, struct termios *termios,
++                             struct termios *old)
++{
++      struct usart3_port *up = to_usart3_port(port);
++      unsigned int baud, quot, mode = 0;
++      unsigned int imr, flags;
++
++      pr_debug("usart3: set_termios\n");
++
++      switch (termios->c_cflag & CSIZE) {
++      case CS5:
++              mode |= USART3_BF(CHRL, USART3_CHRL_5);
++              break;
++      case CS6:
++              mode |= USART3_BF(CHRL, USART3_CHRL_6);
++              break;
++      case CS7:
++              mode |= USART3_BF(CHRL, USART3_CHRL_7);
++              break;
++      default:
++              mode |= USART3_BF(CHRL, USART3_CHRL_8);
++              break;
++      }
++
++      if (termios->c_cflag & CSTOPB)
++              mode |= USART3_BF(NBSTOP, USART3_NBSTOP_2);
++
++      if (termios->c_cflag & PARENB) {
++               if (termios->c_cflag & PARODD)
++                       mode |= USART3_BF(PAR, USART3_PAR_ODD);
++               else
++                       mode |= USART3_BF(PAR, USART3_PAR_EVEN);
++      } else {
++              mode |= USART3_BF(PAR, USART3_PAR_NONE);
++      }
++
++      /*
++       * Ask the core to calculate the divisor for us.
++       */
++      baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
++      quot = uart_get_divisor(port, baud);
++
++      /* Bits to ignore, timeout, etc. TBD */
++
++      /*
++       * Save and disable interrupts
++       */
++      spin_lock_irqsave(&port->lock, flags);
++      imr = usart3_readl(up, IMR);
++      usart3_writel(up, IDR, -1L);
++      spin_unlock_irqrestore(&port->lock, flags);
++
++      /*
++       * Make sure transmitter is empty. If BRGR == 0, it is safest
++       * to do a reset, since waiting for the transmitter to be
++       * empty will take forever.
++       */
++      if (usart3_readl(up, BRGR) != 0) {
++              while (!(usart3_readl(up, CSR) & USART3_BIT(TXRDY)))
++                      barrier();
++      } else {
++              usart3_writel(up, CR, (USART3_BIT(RSTTX)
++                                        | USART3_BIT(RSTRX)));
++      }
++
++      pr_debug("usart3: Setting BRGR to %u (baud rate %u)...\n", quot, baud);
++
++      /* Disable receiver and transmitter */
++      usart3_writel(up, CR, (USART3_BIT(TXDIS)
++                                | USART3_BIT(RXDIS)));
++
++      /* Set the parity, stop bits and data size */
++      usart3_writel(up, MR, mode);
++
++      /* Set the baud rate and enable receiver and transmitter */
++      usart3_writel(up, BRGR, quot);
++      usart3_writel(up, CR, (USART3_BIT(TXEN)
++                                | USART3_BIT(RXEN)));
++
++      /* Restore interrupts */
++      usart3_writel(up, IER, imr);
++}
++
++static const char *usart3_type(struct uart_port *port)
++{
++      return "USART3";
++}
++
++static void usart3_release_port(struct uart_port *port)
++{
++      pr_debug("usart3: release_port\n");
++      iounmap(port->membase);
++      port->flags |= UPF_IOREMAP;
++}
++
++static int usart3_request_port(struct uart_port *port)
++{
++      struct usart3_port *up = to_usart3_port(port);
++
++      /* TODO: remove this */
++      pr_debug("usart3: request_port\n");
++      if (port->flags & UPF_IOREMAP) {
++              port->membase = ioremap(port->mapbase, up->mapsize);
++              up->regs = port->membase;
++              port->flags &= ~UPF_IOREMAP;
++      }
++      return 0;
++}
++
++static void usart3_config_port(struct uart_port *port, int flags)
++{
++      pr_debug("usart3: config_port\n");
++      if (flags & UART_CONFIG_TYPE) {
++              if (usart3_request_port(port) == 0)
++                      port->type = PORT_USART3;
++      }
++}
++
++static int usart3_verify_port(struct uart_port *port, struct serial_struct *ser)
++{
++      int ret = 0;
++
++      if (ser->type != PORT_UNKNOWN && ser->type != PORT_USART3)
++              ret = -EINVAL;
++      if (port->irq != ser->irq)
++              ret = -EINVAL;
++      if (ser->io_type != SERIAL_IO_MEM)
++              ret = -EINVAL;
++      if (port->uartclk / 16 != ser->baud_base)
++              ret = -EINVAL;
++      if ((void *)port->mapbase != ser->iomem_base)
++              ret = -EINVAL;
++      if (ser->hub6 != 0)
++              ret = -EINVAL;
++
++      pr_debug("usart3_verify_port returned %d\n", ret);
++
++      return ret;
++}
++
++static struct uart_ops usart3_pops = {
++      .tx_empty       = usart3_tx_empty,
++      .set_mctrl      = usart3_set_mctrl,
++      .get_mctrl      = usart3_get_mctrl,
++      .stop_tx        = usart3_stop_tx,
++      .start_tx       = usart3_start_tx,
++      .stop_rx        = usart3_stop_rx,
++      .enable_ms      = usart3_enable_ms,
++      .break_ctl      = usart3_break_ctl,
++      .startup        = usart3_startup,
++      .shutdown       = usart3_shutdown,
++      .flush_buffer   = usart3_flush_buffer,
++      .set_termios    = usart3_set_termios,
++      .type           = usart3_type,
++      .release_port   = usart3_release_port,
++      .request_port   = usart3_request_port,
++      .config_port    = usart3_config_port,
++      .verify_port    = usart3_verify_port,
++};
++
++static int __devinit initialize_port(struct usart3_port *up,
++                                    struct platform_device *pdev)
++{
++      struct uart_port *port = &up->uart;
++      struct resource *regs;
++
++      regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!regs)
++              return -ENXIO;
++
++      spin_lock_init(&port->lock);
++
++      up->mck = clk_get(&pdev->dev, "usart");
++      if (IS_ERR(up->mck))
++              return PTR_ERR(up->mck);
++      clk_enable(up->mck);
++
++      port->mapbase = regs->start;
++      up->mapsize = regs->end - regs->start + 1;
++      port->irq = platform_get_irq(pdev, 0);
++
++      port->uartclk = clk_get_rate(up->mck);
++      port->iotype = SERIAL_IO_MEM;
++      port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
++      port->ops = &usart3_pops;
++      port->line = pdev->id;
++      port->dev = &pdev->dev;
++
++      return 0;
++}
++
++static struct usart3_port usart3_ports[NR_PORTS];
++
++#ifdef CONFIG_SERIAL_ATMEL_CONSOLE
++
++static void usart3_console_write(struct console *console, const char *string,
++                               unsigned int len)
++{
++      struct usart3_port *up = &usart3_ports[console->index];
++      unsigned int imr, i;
++      unsigned long flags, ptsr;
++
++      /*
++       * Save IMR, then disable interrupts
++       */
++      local_irq_save(flags);
++      imr = usart3_readl(up, IMR);
++      usart3_writel(up, IDR, ~0UL);
++      local_irq_restore(flags);
++
++      /*
++       * Save PDC state and disable PDC transmission
++       */
++      ptsr = usart3_readl(up, PTSR);
++      usart3_writel(up, PTCR, USART3_BIT(TXTDIS));
++
++      /*
++       * Now, do each character
++       */
++      for (i = 0; i < len; i++, string++) {
++              char c = *string;
++
++              /*
++               * If we're sending LF, send CR first...
++               */
++              if (c == '\n') {
++                      while (!(usart3_readl(up, CSR)
++                               & USART3_BIT(TXRDY)))
++                              ;
++                      usart3_writel(up, THR, '\r');
++              }
++              while (!(usart3_readl(up, CSR) & USART3_BIT(TXRDY)))
++                      ;
++              usart3_writel(up, THR, c);
++      }
++
++      /*
++       * Wait for transmitter to become empty and restore the IMR
++       * and PDC state.
++       */
++      while (!(usart3_readl(up, CSR) & USART3_BIT(TXRDY)))
++              ;
++
++      usart3_writel(up, PTCR, ptsr & USART3_BIT(TXTEN));
++      usart3_writel(up, IER, imr);
++}
++
++static int __init usart3_console_setup(struct console *console,
++                                     char *options)
++{
++      struct platform_device *pdev;
++      struct usart3_port *up;
++      struct uart_port *port;
++      int baud = 115200;
++      int bits = 8;
++      int parity = 'n';
++      int flow = 'n';
++      int ret;
++
++      if (console->index >= NR_PORTS) {
++              printk(KERN_ERR
++                     "Can't use USART%u for console: index >= NR_PORTS\n",
++                     console->index);
++              return -ENODEV;
++      }
++
++      pdev = at91_default_console_device;
++      if (!pdev)
++              return -ENXIO;
++
++      up = &usart3_ports[console->index];
++      port = &up->uart;
++
++      ret = initialize_port(up, pdev);
++      if (ret)
++              return ret;
++
++      port->membase = ioremap(port->mapbase, up->mapsize);
++      ret = -ENOMEM;
++      if (!port->membase)
++              goto out_disable_clk;
++
++      up->regs = port->membase;
++
++      /* Set a fixed baud rate for now */
++      usart3_writel(up, BRGR, 2);
++
++      /* Make sure all interrupts are disabled and reset/enable the USART */
++      usart3_writel(up, IDR, -1L);
++      usart3_writel(up, CR, (USART3_BIT(RSTRX)
++                                | USART3_BIT(RSTTX)
++                                | USART3_BIT(RSTSTA)));
++      usart3_writel(up, CR, (USART3_BIT(RXEN)
++                                | USART3_BIT(TXEN)));
++
++      if (options)
++              uart_parse_options(options, &baud, &parity, &bits, &flow);
++
++      return uart_set_options(port, console, baud, parity, bits, flow);
++
++out_disable_clk:
++      clk_disable(up->mck);
++      clk_put(up->mck);
++      return ret;
++}
++
++static struct uart_driver usart3_reg;
++static struct console usart3_console = {
++      .name           = "ttyUS",
++      .write          = usart3_console_write,
++      .device         = uart_console_device,
++      .setup          = usart3_console_setup,
++      .flags          = CON_PRINTBUFFER,
++      .index          = -1,
++      .data           = &usart3_reg,
++};
++
++static int __init usart3_console_init(void)
++{
++      register_console(&usart3_console);
++      return 0;
++}
++console_initcall(usart3_console_init);
++
++#define USART3_CONSOLE &usart3_console
++
++#else
++#define USART3_CONSOLE NULL
++#endif
++
++static struct uart_driver usart3_reg = {
++      .owner          = THIS_MODULE,
++      .driver_name    = "serial",
++      .dev_name       = "ttyUS",
++      .major          = SERIAL_USART3_MAJOR,
++      .minor          = MINOR_START,
++      .nr             = NR_PORTS,
++      .cons           = USART3_CONSOLE,
++};
++
++static int usart3_serial_suspend(struct platform_device *pdev,
++                               pm_message_t state)
++{
++      struct usart3_port *port = platform_get_drvdata(pdev);
++      int retval = 0;
++
++      if (port)
++              retval = uart_suspend_port(&usart3_reg, &port->uart);
++
++      return retval;
++}
++
++static int usart3_serial_resume(struct platform_device *pdev)
++{
++      struct usart3_port *port = platform_get_drvdata(pdev);
++      int retval = 0;
++
++      if (port)
++              retval = uart_resume_port(&usart3_reg, &port->uart);
++
++      return retval;
++}
++
++static int __devinit usart3_serial_probe(struct platform_device *pdev)
++{
++      struct usart3_port *up;
++      int ret;
++
++      if (pdev->id >= NR_PORTS) {
++              printk(KERN_WARNING
++                     "Ignoring USART%u, as NR_PORTS is only %u\n",
++                     pdev->id, NR_PORTS);
++              return -ENOMEM;
++      }
++
++      up = &usart3_ports[pdev->id];
++
++      /*
++       * If the port has already been set up as a console, we
++       * shouldn't enable it again.
++       */
++      if (!up->uart.uartclk) {
++              ret = initialize_port(up, pdev);
++              if (ret)
++                      goto out;
++      }
++
++      /*
++       * The RX buffer must be cacheline aligned. If it's not,
++       * invalidating the cache could be disastrous...
++       *
++       * Fortunately, kmalloc() always returns cache-aligned memory.
++       */
++      ret = -ENOMEM;
++      up->rx_buffer = kmalloc(2 * RX_BUFFER_SIZE, GFP_KERNEL);
++      if (!up->rx_buffer)
++              goto out_disable_clk;
++
++      ret = uart_add_one_port(&usart3_reg, &up->uart);
++      if (ret)
++              goto out_free_rx_buffer;
++
++      platform_set_drvdata(pdev, up);
++
++      return 0;
++
++out_free_rx_buffer:
++      kfree(up->rx_buffer);
++out_disable_clk:
++      clk_disable(up->mck);
++      clk_put(up->mck);
++out:
++      return ret;
++}
++
++static int __devexit usart3_serial_remove(struct platform_device *pdev)
++{
++      struct usart3_port *port = platform_get_drvdata(pdev);
++      int retval = 0;
++
++      platform_set_drvdata(pdev, NULL);
++
++      if (port) {
++              retval = uart_remove_one_port(&usart3_reg, &port->uart);
++              clk_disable(port->mck);
++              clk_put(port->mck);
++              kfree(port->rx_buffer);
++              kfree(port);
++      }
++
++      return retval;
++}
++
++static struct platform_driver usart3_serial_driver = {
++      .probe          = usart3_serial_probe,
++      .remove         = __devexit_p(usart3_serial_remove),
++      .suspend        = usart3_serial_suspend,
++      .resume         = usart3_serial_resume,
++      .driver         = {
++              .name   = "usart",
++      },
++};
++
++static int __init usart3_init(void)
++{
++      int ret;
++
++      printk(KERN_INFO "Serial: Atmel USART3 driver\n");
++
++      ret = uart_register_driver(&usart3_reg);
++      if (ret)
++              return ret;
++
++      ret = platform_driver_register(&usart3_serial_driver);
++      if (ret)
++              uart_unregister_driver(&usart3_reg);
++
++      return ret;
++}
++
++static void __exit usart3_exit(void)
++{
++      platform_driver_unregister(&usart3_serial_driver);
++      uart_unregister_driver(&usart3_reg);
++}
++
++module_init(usart3_init);
++module_exit(usart3_exit);
++
++MODULE_LICENSE("GPL");
++MODULE_DESCRIPTION("Atmel USART3 serial driver");
++MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
+Index: linux-2.6.18-avr32/drivers/serial/atmel_usart.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/drivers/serial/atmel_usart.h    2006-11-02 16:37:02.000000000 +0100
+@@ -0,0 +1,290 @@
++/*
++ * Register definitions for USART3
++ *
++ * 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_USART3_H__
++#define __ASM_AVR32_USART3_H__
++
++/* USART3 register offsets */
++#define USART3_CR                             0x0000
++#define USART3_MR                             0x0004
++#define USART3_IER                            0x0008
++#define USART3_IDR                            0x000c
++#define USART3_IMR                            0x0010
++#define USART3_CSR                            0x0014
++#define USART3_RHR                            0x0018
++#define USART3_THR                            0x001c
++#define USART3_BRGR                           0x0020
++#define USART3_RTOR                           0x0024
++#define USART3_TTGR                           0x0028
++#define USART3_FIDI                           0x0040
++#define USART3_NER                            0x0044
++#define USART3_XXR                            0x0048
++#define USART3_IFR                            0x004c
++
++/* PDC register offsets */
++#define USART3_RPR                            0x100
++#define USART3_RCR                            0x104
++#define USART3_TPR                            0x108
++#define USART3_TCR                            0x10c
++#define USART3_RNPR                           0x110
++#define USART3_RNCR                           0x114
++#define USART3_TNPR                           0x118
++#define USART3_TNCR                           0x11c
++#define USART3_PTCR                           0x120
++#define USART3_PTSR                           0x124
++
++/* Bitfields in CR */
++#define USART3_RSTRX_OFFSET                   2
++#define USART3_RSTRX_SIZE                     1
++#define USART3_RSTTX_OFFSET                   3
++#define USART3_RSTTX_SIZE                     1
++#define USART3_RXEN_OFFSET                    4
++#define USART3_RXEN_SIZE                      1
++#define USART3_RXDIS_OFFSET                   5
++#define USART3_RXDIS_SIZE                     1
++#define USART3_TXEN_OFFSET                    6
++#define USART3_TXEN_SIZE                      1
++#define USART3_TXDIS_OFFSET                   7
++#define USART3_TXDIS_SIZE                     1
++#define USART3_RSTSTA_OFFSET                  8
++#define USART3_RSTSTA_SIZE                    1
++#define USART3_STTBRK_OFFSET                  9
++#define USART3_STTBRK_SIZE                    1
++#define USART3_STPBRK_OFFSET                  10
++#define USART3_STPBRK_SIZE                    1
++#define USART3_STTTO_OFFSET                   11
++#define USART3_STTTO_SIZE                     1
++#define USART3_SENDA_OFFSET                   12
++#define USART3_SENDA_SIZE                     1
++#define USART3_RSTIT_OFFSET                   13
++#define USART3_RSTIT_SIZE                     1
++#define USART3_RSTNACK_OFFSET                 14
++#define USART3_RSTNACK_SIZE                   1
++#define USART3_RETTO_OFFSET                   15
++#define USART3_RETTO_SIZE                     1
++#define USART3_DTREN_OFFSET                   16
++#define USART3_DTREN_SIZE                     1
++#define USART3_DTRDIS_OFFSET                  17
++#define USART3_DTRDIS_SIZE                    1
++#define USART3_RTSEN_OFFSET                   18
++#define USART3_RTSEN_SIZE                     1
++#define USART3_RTSDIS_OFFSET                  19
++#define USART3_RTSDIS_SIZE                    1
++#define USART3_COMM_TX_OFFSET                 30
++#define USART3_COMM_TX_SIZE                   1
++#define USART3_COMM_RX_OFFSET                 31
++#define USART3_COMM_RX_SIZE                   1
++
++/* Bitfields in MR */
++#define USART3_USART_MODE_OFFSET              0
++#define USART3_USART_MODE_SIZE                        4
++#define USART3_USCLKS_OFFSET                  4
++#define USART3_USCLKS_SIZE                    2
++#define USART3_CHRL_OFFSET                    6
++#define USART3_CHRL_SIZE                      2
++#define USART3_SYNC_OFFSET                    8
++#define USART3_SYNC_SIZE                      1
++#define USART3_PAR_OFFSET                     9
++#define USART3_PAR_SIZE                               3
++#define USART3_NBSTOP_OFFSET                  12
++#define USART3_NBSTOP_SIZE                    2
++#define USART3_CHMODE_OFFSET                  14
++#define USART3_CHMODE_SIZE                    2
++#define USART3_MSBF_OFFSET                    16
++#define USART3_MSBF_SIZE                      1
++#define USART3_MODE9_OFFSET                   17
++#define USART3_MODE9_SIZE                     1
++#define USART3_CLKO_OFFSET                    18
++#define USART3_CLKO_SIZE                      1
++#define USART3_OVER_OFFSET                    19
++#define USART3_OVER_SIZE                      1
++#define USART3_INACK_OFFSET                   20
++#define USART3_INACK_SIZE                     1
++#define USART3_DSNACK_OFFSET                  21
++#define USART3_DSNACK_SIZE                    1
++#define USART3_MAX_ITERATION_OFFSET           24
++#define USART3_MAX_ITERATION_SIZE             3
++#define USART3_FILTER_OFFSET                  28
++#define USART3_FILTER_SIZE                    1
++
++/* Bitfields in CSR */
++#define USART3_RXRDY_OFFSET                   0
++#define USART3_RXRDY_SIZE                     1
++#define USART3_TXRDY_OFFSET                   1
++#define USART3_TXRDY_SIZE                     1
++#define USART3_RXBRK_OFFSET                   2
++#define USART3_RXBRK_SIZE                     1
++#define USART3_ENDRX_OFFSET                   3
++#define USART3_ENDRX_SIZE                     1
++#define USART3_ENDTX_OFFSET                   4
++#define USART3_ENDTX_SIZE                     1
++#define USART3_OVRE_OFFSET                    5
++#define USART3_OVRE_SIZE                      1
++#define USART3_FRAME_OFFSET                   6
++#define USART3_FRAME_SIZE                     1
++#define USART3_PARE_OFFSET                    7
++#define USART3_PARE_SIZE                      1
++#define USART3_TIMEOUT_OFFSET                 8
++#define USART3_TIMEOUT_SIZE                   1
++#define USART3_TXEMPTY_OFFSET                 9
++#define USART3_TXEMPTY_SIZE                   1
++#define USART3_ITERATION_OFFSET                       10
++#define USART3_ITERATION_SIZE                 1
++#define USART3_TXBUFE_OFFSET                  11
++#define USART3_TXBUFE_SIZE                    1
++#define USART3_RXBUFF_OFFSET                  12
++#define USART3_RXBUFF_SIZE                    1
++#define USART3_NACK_OFFSET                    13
++#define USART3_NACK_SIZE                      1
++#define USART3_RIIC_OFFSET                    16
++#define USART3_RIIC_SIZE                      1
++#define USART3_DSRIC_OFFSET                   17
++#define USART3_DSRIC_SIZE                     1
++#define USART3_DCDIC_OFFSET                   18
++#define USART3_DCDIC_SIZE                     1
++#define USART3_CTSIC_OFFSET                   19
++#define USART3_CTSIC_SIZE                     1
++#define USART3_RI_OFFSET                      20
++#define USART3_RI_SIZE                                1
++#define USART3_DSR_OFFSET                     21
++#define USART3_DSR_SIZE                               1
++#define USART3_DCD_OFFSET                     22
++#define USART3_DCD_SIZE                               1
++#define USART3_CTS_OFFSET                     23
++#define USART3_CTS_SIZE                               1
++
++/* Bitfields in RHR */
++#define USART3_RXCHR_OFFSET                   0
++#define USART3_RXCHR_SIZE                     9
++
++/* Bitfields in THR */
++#define USART3_TXCHR_OFFSET                   0
++#define USART3_TXCHR_SIZE                     9
++
++/* Bitfields in BRGR */
++#define USART3_CD_OFFSET                      0
++#define USART3_CD_SIZE                                16
++
++/* Bitfields in RTOR */
++#define USART3_TO_OFFSET                      0
++#define USART3_TO_SIZE                                16
++
++/* Bitfields in TTGR */
++#define USART3_TG_OFFSET                      0
++#define USART3_TG_SIZE                                8
++
++/* Bitfields in FIDI */
++#define USART3_FI_DI_RATIO_OFFSET             0
++#define USART3_FI_DI_RATIO_SIZE                       11
++
++/* Bitfields in NER */
++#define USART3_NB_ERRORS_OFFSET                       0
++#define USART3_NB_ERRORS_SIZE                 8
++
++/* Bitfields in XXR */
++#define USART3_XOFF_OFFSET                    0
++#define USART3_XOFF_SIZE                      8
++#define USART3_XON_OFFSET                     8
++#define USART3_XON_SIZE                               8
++
++/* Bitfields in IFR */
++#define USART3_IRDA_FILTER_OFFSET             0
++#define USART3_IRDA_FILTER_SIZE                       8
++
++/* Bitfields in PTCR/PTSR (PDC) */
++#define USART3_RXTEN_OFFSET                   0
++#define USART3_RXTEN_SIZE                     1
++#define USART3_RXTDIS_OFFSET                  1
++#define USART3_RXTDIS_SIZE                    1
++#define USART3_TXTEN_OFFSET                   8
++#define USART3_TXTEN_SIZE                     1
++#define USART3_TXTDIS_OFFSET                  9
++#define USART3_TXTDIS_SIZE                    1
++
++/* Constants for USART_MODE */
++#define USART3_USART_MODE_NORMAL              0
++#define USART3_USART_MODE_RS485                       1
++#define USART3_USART_MODE_HARDWARE            2
++#define USART3_USART_MODE_MODEM                       3
++#define USART3_USART_MODE_ISO7816_T0          4
++#define USART3_USART_MODE_ISO7816_T1          6
++#define USART3_USART_MODE_IRDA                        8
++
++/* Constants for USCLKS */
++#define USART3_USCLKS_MCK                     0
++#define USART3_USCLKS_MCK_DIV                 1
++#define USART3_USCLKS_SCK                     3
++
++/* Constants for CHRL */
++#define USART3_CHRL_5                         0
++#define USART3_CHRL_6                         1
++#define USART3_CHRL_7                         2
++#define USART3_CHRL_8                         3
++
++/* Constants for PAR */
++#define USART3_PAR_EVEN                               0
++#define USART3_PAR_ODD                                1
++#define USART3_PAR_SPACE                      2
++#define USART3_PAR_MARK                               3
++#define USART3_PAR_NONE                               4
++#define USART3_PAR_MULTI                      6
++
++/* Constants for NBSTOP */
++#define USART3_NBSTOP_1                               0
++#define USART3_NBSTOP_1_5                     1
++#define USART3_NBSTOP_2                               2
++
++/* Constants for CHMODE */
++#define USART3_CHMODE_NORMAL                  0
++#define USART3_CHMODE_ECHO                    1
++#define USART3_CHMODE_LOCAL_LOOP              2
++#define USART3_CHMODE_REMOTE_LOOP             3
++
++/* Constants for MSBF */
++#define USART3_MSBF_LSBF                      0
++#define USART3_MSBF_MSBF                      1
++
++/* Constants for OVER */
++#define USART3_OVER_X16                               0
++#define USART3_OVER_X8                                1
++
++/* Constants for CD */
++#define USART3_CD_DISABLE                     0
++#define USART3_CD_BYPASS                      1
++
++/* Constants for TO */
++#define USART3_TO_DISABLE                     0
++
++/* Constants for TG */
++#define USART3_TG_DISABLE                     0
++
++/* Constants for FI_DI_RATIO */
++#define USART3_FI_DI_RATIO_DISABLE            0
++
++/* Bit manipulation macros */
++#define USART3_BIT(name)                              \
++      (1 << USART3_##name##_OFFSET)
++#define USART3_BF(name,value)                         \
++      (((value) & ((1 << USART3_##name##_SIZE) - 1))  \
++       << USART3_##name##_OFFSET)
++#define USART3_BFEXT(name,value)                      \
++      (((value) >> USART3_##name##_OFFSET)            \
++       & ((1 << USART3_##name##_SIZE) - 1))
++#define USART3_BFINS(name,value,old)                  \
++      (((old) & ~(((1 << USART3_##name##_SIZE) - 1)   \
++                  << USART3_##name##_OFFSET))         \
++       | USART3_BF(name,value))
++
++/* Register access macros */
++#define usart3_readl(port,reg)                                \
++      __raw_readl((port)->regs + USART3_##reg)
++#define usart3_writel(port,reg,value)                 \
++      __raw_writel((value), (port)->regs + USART3_##reg)
++
++#endif /* __ASM_AVR32_USART3_H__ */
diff --git a/packages/linux/linux-2.6.18/atmel-version.patch b/packages/linux/linux-2.6.18/atmel-version.patch
new file mode 100644 (file)
index 0000000..e72ff55
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ Makefile |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux-2.6.18-avr32/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/Makefile   2006-09-20 05:42:06.000000000 +0200
++++ linux-2.6.18-avr32/Makefile        2006-09-20 13:30:33.000000000 +0200
+@@ -1,7 +1,7 @@
+ VERSION = 2
+ PATCHLEVEL = 6
+ SUBLEVEL = 18
+-EXTRAVERSION =
++EXTRAVERSION = -at0
+ NAME=Avast! A bilge rat!
+ # *DOCUMENTATION*
diff --git a/packages/linux/linux-2.6.18/atmel_spi-handle-rx-overrun.patch b/packages/linux/linux-2.6.18/atmel_spi-handle-rx-overrun.patch
new file mode 100644 (file)
index 0000000..3bfbbee
--- /dev/null
@@ -0,0 +1,200 @@
+---
+ drivers/spi/atmel_spi.c |  140 ++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 100 insertions(+), 40 deletions(-)
+
+Index: linux-2.6.18-avr32/drivers/spi/atmel_spi.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/spi/atmel_spi.c    2007-01-15 15:35:38.000000000 +0100
++++ linux-2.6.18-avr32/drivers/spi/atmel_spi.c 2007-01-16 13:26:32.000000000 +0100
+@@ -156,7 +156,7 @@ static void atmel_spi_next_xfer(struct s
+        */
+       spi_writel(as, TNCR, 0);
+       spi_writel(as, RNCR, 0);
+-      imr = SPI_BIT(ENDRX);
++      imr = SPI_BIT(ENDRX) | SPI_BIT(OVRES);
+       dev_dbg(&msg->spi->dev,
+               "start xfer %p: len %u tx %p/%08x rx %p/%08x imr %08x\n",
+@@ -209,6 +209,43 @@ static void atmel_spi_dma_map_xfer(struc
+       }
+ }
++static void atmel_spi_dma_unmap_xfer(struct spi_master *master,
++                                   struct spi_transfer *xfer)
++{
++      if (xfer->tx_dma != INVALID_DMA_ADDRESS)
++              dma_unmap_single(master->cdev.dev, xfer->tx_dma,
++                               xfer->len, DMA_TO_DEVICE);
++      if (xfer->rx_dma != INVALID_DMA_ADDRESS)
++              dma_unmap_single(master->cdev.dev, xfer->rx_dma,
++                               xfer->len, DMA_FROM_DEVICE);
++}
++
++static void atmel_spi_msg_done(struct spi_master *master,
++                             struct atmel_spi *as,
++                             struct spi_message *msg,
++                             int status)
++{
++      cs_deactivate(msg->spi);
++      list_del(&msg->queue);
++      msg->status = status;
++
++      dev_dbg(master->cdev.dev,
++              "xfer complete: %u bytes transferred\n",
++              msg->actual_length);
++
++      spin_unlock(&as->lock);
++      msg->complete(msg->context);
++      spin_lock(&as->lock);
++
++      as->current_transfer = NULL;
++
++      /* continue; complete() may have queued requests */
++      if (list_empty(&as->queue) || as->stopping)
++              spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
++      else
++              atmel_spi_next_message(master);
++}
++
+ static irqreturn_t
+ atmel_spi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+ {
+@@ -219,19 +256,71 @@ atmel_spi_interrupt(int irq, void *dev_i
+       u32                     status, pending, imr;
+       int                     ret = IRQ_NONE;
++      spin_lock(&as->lock);
++
++      xfer = as->current_transfer;
++      msg = list_entry(as->queue.next, struct spi_message, queue);
++
+       imr = spi_readl(as, IMR);
+       status = spi_readl(as, SR);
+       pending = status & imr;
+ pr_debug("spi irq: stat %05x imr %05x pend %05x\n", status, imr, pending);
+-      if (pending & (SPI_BIT(ENDTX) | SPI_BIT(ENDRX))) {
++      if (pending & SPI_BIT(OVRES)) {
++              int timeout;
++
+               ret = IRQ_HANDLED;
+-              spi_writel(as, IDR, pending);
+-              spin_lock(&as->lock);
++              spi_writel(as, IDR, (SPI_BIT(ENDTX) | SPI_BIT(ENDRX)
++                                   | SPI_BIT(OVRES)));
++
++              /*
++               * When we get an overrun, we disregard the current
++               * transfer. Data will not be copied back from any
++               * bounce buffer and msg->actual_len will not be
++               * updated with the last xfer.
++               *
++               * We will also not process any remaning transfers in
++               * the message.
++               *
++               * First, stop the transfer and unmap the DMA buffers.
++               */
++              spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS));
++              if (!msg->is_dma_mapped)
++                      atmel_spi_dma_unmap_xfer(master, xfer);
++
++              /* REVISIT: udelay in irq is unfriendly */
++              if (xfer->delay_usecs)
++                      udelay(xfer->delay_usecs);
+-              xfer = as->current_transfer;
+-              msg = list_entry(as->queue.next, struct spi_message, queue);
++              dev_warn(master->cdev.dev, "fifo overrun (%u/%u remaining)\n",
++                       spi_readl(as, TCR), spi_readl(as, RCR));
++
++              /*
++               * Clean up DMA registers and make sure the data
++               * registers are empty.
++               */
++              spi_writel(as, RNCR, 0);
++              spi_writel(as, TNCR, 0);
++              spi_writel(as, RCR, 0);
++              spi_writel(as, TCR, 0);
++              for (timeout = 1000; timeout; timeout--)
++                      if (spi_readl(as, SR) & SPI_BIT(TXEMPTY))
++                              break;
++              if (!timeout)
++                      dev_warn(master->cdev.dev,
++                               "timeout waiting for TXEMPTY");
++              while (spi_readl(as, SR) & SPI_BIT(RDRF))
++                      spi_readl(as, RDR);
++
++              /* Clear any overrun happening while cleaning up */
++              spi_readl(as, SR);
++
++              atmel_spi_msg_done(master, as, msg, -EIO);
++      } else if (pending & (SPI_BIT(ENDTX) | SPI_BIT(ENDRX))) {
++              ret = IRQ_HANDLED;
++
++              spi_writel(as, IDR, pending);
+               /*
+                * If the rx buffer wasn't aligned, we used a bounce
+@@ -254,46 +343,16 @@ pr_debug("spi irq: stat %05x imr %05x pe
+               if (as->remaining_bytes == 0) {
+                       msg->actual_length += xfer->len;
+-                      if (!msg->is_dma_mapped) {
+-                              if (xfer->tx_dma != INVALID_DMA_ADDRESS)
+-                                      dma_unmap_single(master->cdev.dev,
+-                                                       xfer->tx_dma,
+-                                                       xfer->len,
+-                                                       DMA_TO_DEVICE);
+-                              if (xfer->rx_dma != INVALID_DMA_ADDRESS)
+-                                      dma_unmap_single(master->cdev.dev,
+-                                                       xfer->rx_dma,
+-                                                       xfer->len,
+-                                                       DMA_FROM_DEVICE);
+-                      }
++                      if (!msg->is_dma_mapped)
++                              atmel_spi_dma_unmap_xfer(master, xfer);
+                       /* REVISIT: udelay in irq is unfriendly */
+                       if (xfer->delay_usecs)
+                               udelay(xfer->delay_usecs);
+                       if (msg->transfers.prev == &xfer->transfer_list) {
+-
+                               /* report completed message */
+-                              cs_deactivate(msg->spi);
+-                              list_del(&msg->queue);
+-                              msg->status = 0;
+-
+-                              dev_dbg(master->cdev.dev,
+-                                      "xfer complete: %u bytes transferred\n",
+-                                      msg->actual_length);
+-
+-                              spin_unlock(&as->lock);
+-                              msg->complete(msg->context);
+-                              spin_lock(&as->lock);
+-
+-                              as->current_transfer = NULL;
+-
+-                              /* continue; complete() may have queued requests */
+-                              if (list_empty(&as->queue) || as->stopping)
+-                                      spi_writel(as, PTCR, SPI_BIT(RXTDIS)
+-                                                 | SPI_BIT(TXTDIS));
+-                              else
+-                                      atmel_spi_next_message(master);
++                              atmel_spi_msg_done(master, as, msg, 0);
+                       } else {
+                               if (xfer->cs_change) {
+                                       cs_deactivate(msg->spi);
+@@ -315,9 +374,10 @@ pr_debug("spi irq: stat %05x imr %05x pe
+                        */
+                       atmel_spi_next_xfer(master, msg);
+               }
+-              spin_unlock(&as->lock);
+       }
++      spin_unlock(&as->lock);
++
+       return ret;
+ }
diff --git a/packages/linux/linux-2.6.18/atmel_spi-send-zeroes-when-tx_buf-is-not-set.patch b/packages/linux/linux-2.6.18/atmel_spi-send-zeroes-when-tx_buf-is-not-set.patch
new file mode 100644 (file)
index 0000000..0cf703d
--- /dev/null
@@ -0,0 +1,48 @@
+From e9bce56d6d8913505049cde45d800bb69943f166 Mon Sep 17 00:00:00 2001
+From: Nicolas Ferre <nicolas.ferre@rfo.atmel.com>
+Date: Tue, 16 Jan 2007 15:15:36 +0100
+Subject: [ATMEL SPI] Send zeroes when tx_buf is not set
+
+send zeros when tx_buf is not set (according to the new spi
+specification by D.Brownell) cf.
+  http://lkml.org/lkml/2006/12/22/171
+  http://kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=4b1badf5d9ddfc46ad075ca5bfc465972c85cc7c
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+---
+ drivers/spi/atmel_spi.c |   21 ++++++++++-----------
+ 1 file changed, 10 insertions(+), 11 deletions(-)
+
+Index: linux-2.6.18-avr32/drivers/spi/atmel_spi.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/spi/atmel_spi.c    2007-01-16 18:20:06.000000000 +0100
++++ linux-2.6.18-avr32/drivers/spi/atmel_spi.c 2007-01-16 18:20:57.000000000 +0100
+@@ -120,18 +120,17 @@ static void atmel_spi_next_xfer(struct s
+                       len = BUFFER_SIZE;
+       }
+       if (tx_dma == INVALID_DMA_ADDRESS) {
+-              if (xfer->tx_buf) {
+-                      tx_dma = as->buffer_dma;
+-                      if (len > BUFFER_SIZE)
+-                              len = BUFFER_SIZE;
++              tx_dma = as->buffer_dma;
++              if (len > BUFFER_SIZE)
++                      len = BUFFER_SIZE;
++              if (xfer->tx_buf)
+                       memcpy(as->buffer, xfer->tx_buf, len);
+-                      dma_sync_single_for_device(&as->pdev->dev,
+-                                                 as->buffer_dma, len,
+-                                                 DMA_TO_DEVICE);
+-              } else {
+-                      /* Send undefined data; rx_dma is handy */
+-                      tx_dma = rx_dma;
+-              }
++              else
++                      /* no tx data: send zeros */
++                      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);
diff --git a/packages/linux/linux-2.6.18/atngw100/.mtn2git_empty b/packages/linux/linux-2.6.18/atngw100/.mtn2git_empty
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/packages/linux/linux-2.6.18/atngw100/defconfig b/packages/linux/linux-2.6.18/atngw100/defconfig
new file mode 100644 (file)
index 0000000..b70408b
--- /dev/null
@@ -0,0 +1,970 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.18-at0
+# Wed Jan 10 10:13:31 2007
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL=y
+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_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=1
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+
+#
+# Block layer
+#
+# CONFIG_BLK_DEV_IO_TRACE 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"
+
+#
+# System Type and features
+#
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP7000=y
+# CONFIG_BOARD_ATSTK1000 is not set
+CONFIG_BOARD_ATNGW=y
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+CONFIG_PIO_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_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_OWNERSHIP_TRACE is not set
+CONFIG_DW_DMAC=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_CMDLINE=""
+
+#
+# Bus options
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# 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_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE 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
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_BIC=y
+
+#
+# IP: Virtual Server Configuration
+#
+# CONFIG_IP_VS is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK is not set
+CONFIG_NETFILTER_XTABLES=y
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_IP_NF_CONNTRACK=y
+# CONFIG_IP_NF_CT_ACCT is not set
+# CONFIG_IP_NF_CONNTRACK_MARK is not set
+# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
+# CONFIG_IP_NF_CT_PROTO_SCTP is not set
+# CONFIG_IP_NF_FTP is not set
+# CONFIG_IP_NF_IRC is not set
+# CONFIG_IP_NF_NETBIOS_NS is not set
+# CONFIG_IP_NF_TFTP is not set
+# CONFIG_IP_NF_AMANDA is not set
+# CONFIG_IP_NF_PPTP is not set
+# CONFIG_IP_NF_H323 is not set
+# CONFIG_IP_NF_SIP is not set
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=y
+# CONFIG_IP_NF_MATCH_IPRANGE is not set
+# CONFIG_IP_NF_MATCH_TOS is not set
+# CONFIG_IP_NF_MATCH_RECENT is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_DSCP is not set
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+# CONFIG_IP_NF_MATCH_OWNER is not set
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_LOG=y
+# CONFIG_IP_NF_TARGET_ULOG is not set
+# CONFIG_IP_NF_TARGET_TCPMSS is not set
+CONFIG_IP_NF_NAT=y
+CONFIG_IP_NF_NAT_NEEDED=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+# CONFIG_IP_NF_TARGET_NETMAP is not set
+# CONFIG_IP_NF_TARGET_SAME is not set
+# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
+# CONFIG_IP_NF_MANGLE is not set
+# CONFIG_IP_NF_RAW is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# 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
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+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 is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=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
+
+#
+# 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
+# CONFIG_MTD_OBSOLETE_CHIPS is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x80000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+CONFIG_MTD_DATAFLASH=y
+# CONFIG_MTD_M25P80 is not set
+# 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# 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_RAM_BLOCKSIZE=1024
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT 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_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+# CONFIG_TELCLOCK is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=m
+CONFIG_I2C_CHARDEV=m
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# 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_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA 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=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
+#
+
+#
+# Dallas's 1-wire bus
+#
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Misc devices
+#
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_V4L2=y
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# 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'
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# 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_HUSB2DEV=y
+CONFIG_USB_HUSB2DEV=m
+# 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 is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_G_SERIAL is not set
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=m
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_ATMELMCI=m
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# 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_JBD=y
+# CONFIG_JBD_DEBUG is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS 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=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=850
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+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_JFFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# 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_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 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_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 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
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# 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=y
+# 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=y
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB 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_RWSEMS 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_FS is not set
+# CONFIG_DEBUG_VM is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_KPROBES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Hardware crypto devices
+#
+
+#
+# Library routines
+#
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
diff --git a/packages/linux/linux-2.6.18/atstk1000-add-platform-data-for-mmc.patch b/packages/linux/linux-2.6.18/atstk1000-add-platform-data-for-mmc.patch
new file mode 100644 (file)
index 0000000..ed9e0f6
--- /dev/null
@@ -0,0 +1,25 @@
+Index: linux-2.6.18/arch/avr32/boards/atstk1000/atstk1002.c
+===================================================================
+--- linux-2.6.18.orig/arch/avr32/boards/atstk1000/atstk1002.c  2006-12-20 12:25:25.000000000 +0100
++++ linux-2.6.18/arch/avr32/boards/atstk1000/atstk1002.c       2006-12-20 12:26:09.000000000 +0100
+@@ -33,6 +33,11 @@
+       },
+ };
++static struct mmci_platform_data __initdata mmci0_data = {
++              .detect_pin     = GPIO_PIO_NONE,
++              .wp_pin         = GPIO_PIO_NONE,
++};
++
+ static int __init parse_tag_ethernet(struct tag *tag)
+ {
+       int i;
+@@ -72,7 +77,7 @@
+       spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+-      at32_add_device_mmci(0);
++      at32_add_device_mmci(0, &mmci0_data);
+       at32_add_device_spi(0);
+       at32_add_device_twi(0);
+       at32_add_device_usb(0);
diff --git a/packages/linux/linux-2.6.18/atstk1000-board-fix-fbmem-setup.patch b/packages/linux/linux-2.6.18/atstk1000-board-fix-fbmem-setup.patch
new file mode 100644 (file)
index 0000000..185f7de
--- /dev/null
@@ -0,0 +1,14 @@
+Index: linux-2.6.18/arch/avr32/boards/atstk1000/setup.c
+===================================================================
+--- linux-2.6.18.orig/arch/avr32/boards/atstk1000/setup.c      2007-01-11 11:30:42.000000000 +0100
++++ linux-2.6.18/arch/avr32/boards/atstk1000/setup.c   2007-01-11 13:27:00.000000000 +0100
+@@ -37,7 +37,8 @@
+               for_each_online_pgdat(pgdat) {
+                       if (fbmem_start >= pgdat->bdata->node_boot_start
+-                          && fbmem_start <= pgdat->bdata->node_low_pfn)
++                          && fbmem_start <= (pgdat->bdata->node_low_pfn
++                                  * PAGE_SIZE))
+                               reserve_bootmem_node(pgdat, fbmem_start,
+                                                    fbmem_size);
+               }
diff --git a/packages/linux/linux-2.6.18/atstk1000-instantiate-devices.patch b/packages/linux/linux-2.6.18/atstk1000-instantiate-devices.patch
new file mode 100644 (file)
index 0000000..9de779b
--- /dev/null
@@ -0,0 +1,103 @@
+---
+ arch/avr32/boards/atstk1000/Makefile    |    2 +-
+ arch/avr32/boards/atstk1000/atstk1002.c |   24 +++++++++++++++++++++++-
+ arch/avr32/boards/atstk1000/spi.c       |   27 ---------------------------
+ 3 files changed, 24 insertions(+), 29 deletions(-)
+
+Index: linux-2.6.18-avr32/arch/avr32/boards/atstk1000/atstk1002.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/boards/atstk1000/atstk1002.c    2006-11-29 16:31:03.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/boards/atstk1000/atstk1002.c 2006-11-29 16:45:43.000000000 +0100
+@@ -7,12 +7,15 @@
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  */
++#include <linux/device.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/string.h>
+ #include <linux/types.h>
++#include <linux/spi/spi.h>
+ #include <asm/setup.h>
++#include <asm/arch/at32ap7000.h>
+ #include <asm/arch/board.h>
+ #include <asm/arch/init.h>
+@@ -20,6 +23,16 @@ static struct eth_platform_data __initda
+ extern struct lcdc_platform_data atstk1000_fb0_data;
++static struct spi_board_info spi_board_info[] __initdata = {
++      {
++              .modalias       = "ltv350qv",
++              .controller_data = (void *)GPIO_PIN_PA(4),
++              .max_speed_hz   = 16000000,
++              .bus_num        = 0,
++              .chip_select    = 1,
++      },
++};
++
+ static int __init parse_tag_ethernet(struct tag *tag)
+ {
+       int i;
+@@ -54,9 +67,18 @@ static int __init atstk1002_init(void)
+       at32_add_device_usart(2);       /* /dev/ttyS1 */
+       at32_add_device_usart(3);       /* /dev/ttyS2 */
+-      at32_add_device_eth(0, &eth0_data);
++      if (eth_data[0].valid)
++              at32_add_device_eth(0, &eth_data[0]);
++
++      spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
++
++      at32_add_device_mmci(0);
+       at32_add_device_spi(0);
++      at32_add_device_twi(0);
++      at32_add_device_usb(0);
+       at32_add_device_lcdc(0, &atstk1000_fb0_data);
++      at32_add_device_dac(0);
++      at32_add_device_at73c213(0);
+       return 0;
+ }
+Index: linux-2.6.18-avr32/arch/avr32/boards/atstk1000/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/boards/atstk1000/Makefile       2006-11-29 16:21:05.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/boards/atstk1000/Makefile    2006-11-29 16:45:07.000000000 +0100
+@@ -1,2 +1,2 @@
+-obj-y                         += setup.o spi.o flash.o
++obj-y                         += setup.o flash.o
+ obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o
+Index: linux-2.6.18-avr32/arch/avr32/boards/atstk1000/spi.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/boards/atstk1000/spi.c  2006-11-29 16:21:05.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,27 +0,0 @@
+-/*
+- * ATSTK1000 SPI devices
+- *
+- * Copyright (C) 2005 Atmel Norway
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License version 2 as
+- * published by the Free Software Foundation.
+- */
+-#include <linux/device.h>
+-#include <linux/spi/spi.h>
+-
+-static struct spi_board_info spi_board_info[] __initdata = {
+-      {
+-              .modalias       = "ltv350qv",
+-              .max_speed_hz   = 16000000,
+-              .bus_num        = 0,
+-              .chip_select    = 1,
+-      },
+-};
+-
+-static int board_init_spi(void)
+-{
+-      spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+-      return 0;
+-}
+-arch_initcall(board_init_spi);
diff --git a/packages/linux/linux-2.6.18/avr32-arch-neutral-gpio-api.patch b/packages/linux/linux-2.6.18/avr32-arch-neutral-gpio-api.patch
new file mode 100644 (file)
index 0000000..049d5e3
--- /dev/null
@@ -0,0 +1,598 @@
+From 05ac6cbfecf9e9b0ab46ba5f30eec8ea91b2987c Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Mon, 13 Nov 2006 10:23:15 +0100
+Subject: [AVR32] Implement arch-neutral GPIO API
+
+AVR32 implementation of the arch-neutral GPIO API described by
+Documentation/gpio.txt.
+
+This also contains a few related changes to the irq handling and
+pin configuration code, to make this actually usable.
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+---
+ arch/avr32/mach-at32ap/at32ap7000.c        |  144 ++++++++++------------
+ arch/avr32/mach-at32ap/pio.c               |  186 +++++++++++++++++++++++++++--
+ include/asm-avr32/arch-at32ap/at32ap7000.h |   26 ++++
+ include/asm-avr32/arch-at32ap/gpio.h       |   39 ++++++
+ include/asm-avr32/arch-at32ap/irq.h        |   11 +
+ include/asm-avr32/arch-at32ap/portmux.h    |   16 --
+ include/asm-avr32/gpio.h                   |    6 
+ include/asm-avr32/irq.h                    |    8 -
+ 8 files changed, 333 insertions(+), 103 deletions(-)
+
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap7000.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/at32ap7000.c        2006-11-29 16:21:12.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap7000.c     2006-11-29 16:22:14.000000000 +0100
+@@ -11,8 +11,9 @@
+ #include <asm/io.h>
++#include <asm/arch/at32ap7000.h>
+ #include <asm/arch/board.h>
+-#include <asm/arch/portmux.h>
++#include <asm/arch/gpio.h>
+ #include <asm/arch/sm.h>
+ #include "clock.h"
+@@ -67,17 +68,8 @@ static struct clk devname##_##_name = {     
+       .index          = _index,                               \
+ }
+-enum {
+-      PIOA,
+-      PIOB,
+-      PIOC,
+-      PIOD,
+-};
+-
+-enum {
+-      FUNC_A,
+-      FUNC_B,
+-};
++#define select_peripheral(pin, periph, pullup)                                \
++      at32_select_periph(GPIO_PIN_##pin, GPIO_##periph, pullup)
+ unsigned long at32ap7000_osc_rates[3] = {
+       [0] = 32768,
+@@ -553,26 +545,26 @@ DEV_CLK(usart, usart3, pba, 6);
+ static inline void configure_usart0_pins(void)
+ {
+-      portmux_set_func(PIOA,  8, FUNC_B);     /* RXD  */
+-      portmux_set_func(PIOA,  9, FUNC_B);     /* TXD  */
++      select_peripheral(PA(8), PERIPH_B, 0);  /* RXD  */
++      select_peripheral(PA(9), PERIPH_B, 0);  /* TXD  */
+ }
+ static inline void configure_usart1_pins(void)
+ {
+-      portmux_set_func(PIOA, 17, FUNC_A);     /* RXD  */
+-      portmux_set_func(PIOA, 18, FUNC_A);     /* TXD  */
++      select_peripheral(PA(17), PERIPH_A, 0); /* RXD  */
++      select_peripheral(PA(18), PERIPH_A, 0); /* TXD  */
+ }
+ static inline void configure_usart2_pins(void)
+ {
+-      portmux_set_func(PIOB, 26, FUNC_B);     /* RXD  */
+-      portmux_set_func(PIOB, 27, FUNC_B);     /* TXD  */
++      select_peripheral(PB(26), PERIPH_B, 0); /* RXD  */
++      select_peripheral(PB(27), PERIPH_B, 0); /* TXD  */
+ }
+ static inline void configure_usart3_pins(void)
+ {
+-      portmux_set_func(PIOB, 18, FUNC_B);     /* RXD  */
+-      portmux_set_func(PIOB, 17, FUNC_B);     /* TXD  */
++      select_peripheral(PB(18), PERIPH_B, 0); /* RXD  */
++      select_peripheral(PB(17), PERIPH_B, 0); /* TXD  */
+ }
+ static struct platform_device *setup_usart(unsigned int id)
+@@ -644,27 +636,27 @@ at32_add_device_eth(unsigned int id, str
+       case 0:
+               pdev = &macb0_device;
+-              portmux_set_func(PIOC,  3, FUNC_A);     /* TXD0 */
+-              portmux_set_func(PIOC,  4, FUNC_A);     /* TXD1 */
+-              portmux_set_func(PIOC,  7, FUNC_A);     /* TXEN */
+-              portmux_set_func(PIOC,  8, FUNC_A);     /* TXCK */
+-              portmux_set_func(PIOC,  9, FUNC_A);     /* RXD0 */
+-              portmux_set_func(PIOC, 10, FUNC_A);     /* RXD1 */
+-              portmux_set_func(PIOC, 13, FUNC_A);     /* RXER */
+-              portmux_set_func(PIOC, 15, FUNC_A);     /* RXDV */
+-              portmux_set_func(PIOC, 16, FUNC_A);     /* MDC  */
+-              portmux_set_func(PIOC, 17, FUNC_A);     /* MDIO */
++              select_peripheral(PC(3), PERIPH_A, 0);          /* TXD0 */
++              select_peripheral(PC(4), PERIPH_A, 0);          /* TXD1 */
++              select_peripheral(PC(7), PERIPH_A, 0);          /* TXEN */
++              select_peripheral(PC(8), PERIPH_A, 0);          /* TXCK */
++              select_peripheral(PC(9), PERIPH_A, 0);          /* RXD0 */
++              select_peripheral(PC(10), PERIPH_A, 0);         /* RXD1 */
++              select_peripheral(PC(13), PERIPH_A, 0);         /* RXER */
++              select_peripheral(PC(15), PERIPH_A, 0);         /* RXDV */
++              select_peripheral(PC(16), PERIPH_A, 0);         /* MDC  */
++              select_peripheral(PC(17), PERIPH_A, 0);         /* MDIO */
+               if (!data->is_rmii) {
+-                      portmux_set_func(PIOC,  0, FUNC_A);     /* COL  */
+-                      portmux_set_func(PIOC,  1, FUNC_A);     /* CRS  */
+-                      portmux_set_func(PIOC,  2, FUNC_A);     /* TXER */
+-                      portmux_set_func(PIOC,  5, FUNC_A);     /* TXD2 */
+-                      portmux_set_func(PIOC,  6, FUNC_A);     /* TXD3 */
+-                      portmux_set_func(PIOC, 11, FUNC_A);     /* RXD2 */
+-                      portmux_set_func(PIOC, 12, FUNC_A);     /* RXD3 */
+-                      portmux_set_func(PIOC, 14, FUNC_A);     /* RXCK */
+-                      portmux_set_func(PIOC, 18, FUNC_A);     /* SPD  */
++                      select_peripheral(PC(0), PERIPH_A, 0);  /* COL  */
++                      select_peripheral(PC(1), PERIPH_A, 0);  /* CRS  */
++                      select_peripheral(PC(2), PERIPH_A, 0);  /* TXER */
++                      select_peripheral(PC(5), PERIPH_A, 0);  /* TXD2 */
++                      select_peripheral(PC(6), PERIPH_A, 0);  /* TXD3 */
++                      select_peripheral(PC(11), PERIPH_A, 0); /* RXD2 */
++                      select_peripheral(PC(12), PERIPH_A, 0); /* RXD3 */
++                      select_peripheral(PC(14), PERIPH_A, 0); /* RXCK */
++                      select_peripheral(PC(18), PERIPH_A, 0); /* SPD  */
+               }
+               break;
+@@ -695,12 +687,12 @@ struct platform_device *__init at32_add_
+       switch (id) {
+       case 0:
+               pdev = &spi0_device;
+-              portmux_set_func(PIOA,  0, FUNC_A);     /* MISO  */
+-              portmux_set_func(PIOA,  1, FUNC_A);     /* MOSI  */
+-              portmux_set_func(PIOA,  2, FUNC_A);     /* SCK   */
+-              portmux_set_func(PIOA,  3, FUNC_A);     /* NPCS0 */
+-              portmux_set_func(PIOA,  4, FUNC_A);     /* NPCS1 */
+-              portmux_set_func(PIOA,  5, FUNC_A);     /* NPCS2 */
++              select_peripheral(PA(0), PERIPH_A, 0);  /* MISO  */
++              select_peripheral(PA(1), PERIPH_A, 0);  /* MOSI  */
++              select_peripheral(PA(2), PERIPH_A, 0);  /* SCK   */
++              select_peripheral(PA(3), PERIPH_A, 0);  /* NPCS0 */
++              select_peripheral(PA(4), PERIPH_A, 0);  /* NPCS1 */
++              select_peripheral(PA(5), PERIPH_A, 0);  /* NPCS2 */
+               break;
+       default:
+@@ -743,37 +735,37 @@ at32_add_device_lcdc(unsigned int id, st
+       switch (id) {
+       case 0:
+               pdev = &lcdc0_device;
+-              portmux_set_func(PIOC, 19, FUNC_A);     /* CC     */
+-              portmux_set_func(PIOC, 20, FUNC_A);     /* HSYNC  */
+-              portmux_set_func(PIOC, 21, FUNC_A);     /* PCLK   */
+-              portmux_set_func(PIOC, 22, FUNC_A);     /* VSYNC  */
+-              portmux_set_func(PIOC, 23, FUNC_A);     /* DVAL   */
+-              portmux_set_func(PIOC, 24, FUNC_A);     /* MODE   */
+-              portmux_set_func(PIOC, 25, FUNC_A);     /* PWR    */
+-              portmux_set_func(PIOC, 26, FUNC_A);     /* DATA0  */
+-              portmux_set_func(PIOC, 27, FUNC_A);     /* DATA1  */
+-              portmux_set_func(PIOC, 28, FUNC_A);     /* DATA2  */
+-              portmux_set_func(PIOC, 29, FUNC_A);     /* DATA3  */
+-              portmux_set_func(PIOC, 30, FUNC_A);     /* DATA4  */
+-              portmux_set_func(PIOC, 31, FUNC_A);     /* DATA5  */
+-              portmux_set_func(PIOD,  0, FUNC_A);     /* DATA6  */
+-              portmux_set_func(PIOD,  1, FUNC_A);     /* DATA7  */
+-              portmux_set_func(PIOD,  2, FUNC_A);     /* DATA8  */
+-              portmux_set_func(PIOD,  3, FUNC_A);     /* DATA9  */
+-              portmux_set_func(PIOD,  4, FUNC_A);     /* DATA10 */
+-              portmux_set_func(PIOD,  5, FUNC_A);     /* DATA11 */
+-              portmux_set_func(PIOD,  6, FUNC_A);     /* DATA12 */
+-              portmux_set_func(PIOD,  7, FUNC_A);     /* DATA13 */
+-              portmux_set_func(PIOD,  8, FUNC_A);     /* DATA14 */
+-              portmux_set_func(PIOD,  9, FUNC_A);     /* DATA15 */
+-              portmux_set_func(PIOD, 10, FUNC_A);     /* DATA16 */
+-              portmux_set_func(PIOD, 11, FUNC_A);     /* DATA17 */
+-              portmux_set_func(PIOD, 12, FUNC_A);     /* DATA18 */
+-              portmux_set_func(PIOD, 13, FUNC_A);     /* DATA19 */
+-              portmux_set_func(PIOD, 14, FUNC_A);     /* DATA20 */
+-              portmux_set_func(PIOD, 15, FUNC_A);     /* DATA21 */
+-              portmux_set_func(PIOD, 16, FUNC_A);     /* DATA22 */
+-              portmux_set_func(PIOD, 17, FUNC_A);     /* DATA23 */
++              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 */
+               clk_set_parent(&lcdc0_pixclk, &pll0);
+               clk_set_rate(&lcdc0_pixclk, clk_get_rate(&pll0));
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/pio.c       2006-11-29 16:21:12.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c    2006-11-29 16:22:14.000000000 +0100
+@@ -13,10 +13,9 @@
+ #include <linux/fs.h>
+ #include <linux/platform_device.h>
++#include <asm/gpio.h>
+ #include <asm/io.h>
+-#include <asm/arch/portmux.h>
+-
+ #include "pio.h"
+ #define MAX_NR_PIO_DEVICES            8
+@@ -25,28 +24,191 @@ struct pio_device {
+       void __iomem *regs;
+       const struct platform_device *pdev;
+       struct clk *clk;
+-      u32 alloc_mask;
++      u32 pinmux_mask;
++      u32 gpio_mask;
+       char name[32];
+ };
+ static struct pio_device pio_dev[MAX_NR_PIO_DEVICES];
+-void portmux_set_func(unsigned int portmux_id, unsigned int pin_id,
+-                    unsigned int function_id)
++static struct pio_device *gpio_to_pio(unsigned int gpio)
+ {
+       struct pio_device *pio;
+-      u32 mask = 1 << pin_id;
++      unsigned int index;
++
++      index = gpio >> 5;
++      if (index >= MAX_NR_PIO_DEVICES)
++              return NULL;
++      pio = &pio_dev[index];
++      if (!pio->regs)
++              return NULL;
++
++      return pio;
++}
++
++/* Pin multiplexing API */
+-      BUG_ON(portmux_id >= MAX_NR_PIO_DEVICES);
++void __init at32_select_periph(unsigned int pin, unsigned int periph,
++                             int use_pullup)
++{
++      struct pio_device *pio;
++      unsigned int pin_index = pin & 0x1f;
++      u32 mask = 1 << pin_index;
++
++      pio = gpio_to_pio(pin);
++      if (unlikely(!pio)) {
++              printk("pio: invalid pin %u\n", pin);
++              goto fail;
++      }
+-      pio = &pio_dev[portmux_id];
++      if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) {
++              printk("%s: pin %u is busy\n", pio->name, pin_index);
++              goto fail;
++      }
+-      if (function_id)
++      pio_writel(pio, PUER, mask);
++      if (periph)
+               pio_writel(pio, BSR, mask);
+       else
+               pio_writel(pio, ASR, mask);
++
+       pio_writel(pio, PDR, mask);
++      if (!use_pullup)
++              pio_writel(pio, PUDR, mask);
++
++      return;
++
++fail:
++      dump_stack();
++}
++
++void __init at32_select_gpio(unsigned int pin, int enable_output,
++                           int use_pullup)
++{
++      struct pio_device *pio;
++      unsigned int pin_index = pin & 0x1f;
++      u32 mask = 1 << pin_index;
++
++      pio = gpio_to_pio(pin);
++      if (unlikely(!pio)) {
++              printk("pio: invalid pin %u\n", pin);
++              goto fail;
++      }
++
++      if (unlikely(test_and_set_bit(pin_index, &pio->pinmux_mask))) {
++              printk("%s: pin %u is busy\n", pio->name, pin_index);
++              goto fail;
++      }
++
++      pio_writel(pio, PUER, mask);
++      if (enable_output)
++              pio_writel(pio, OER, mask);
++      else
++              pio_writel(pio, ODR, mask);
++
++      pio_writel(pio, PER, mask);
++      if (!use_pullup)
++              pio_writel(pio, PUDR, mask);
++
++      /* It's now allowed to use request_gpio on this pin */
++      clear_bit(pin_index, &pio->gpio_mask);
++
++      return;
++
++fail:
++      dump_stack();
++}
++
++/* GPIO API */
++
++int gpio_request(unsigned int gpio, const char *label)
++{
++      struct pio_device *pio;
++      unsigned int pin;
++
++      pio = gpio_to_pio(gpio);
++      if (!pio)
++              return -ENODEV;
++
++      pin = gpio & 0x1f;
++      if (test_and_set_bit(pin, &pio->gpio_mask))
++              return -EBUSY;
++
++      return 0;
+ }
++EXPORT_SYMBOL(gpio_request);
++
++void gpio_free(unsigned int gpio)
++{
++      struct pio_device *pio;
++      unsigned int pin;
++
++      pio = gpio_to_pio(gpio);
++      if (!pio) {
++              printk(KERN_ERR
++                     "gpio: attempted to free invalid pin %u\n", gpio);
++              return;
++      }
++
++      pin = gpio & 0x1f;
++      if (!test_and_clear_bit(pin, &pio->gpio_mask))
++              printk(KERN_ERR "gpio: freeing already-free pin %s[%u]\n",
++                     pio->name, pin);
++}
++EXPORT_SYMBOL(gpio_free);
++
++int gpio_direction_input(unsigned int gpio)
++{
++      struct pio_device *pio;
++      unsigned int pin;
++
++      pio = gpio_to_pio(gpio);
++      if (!pio)
++              return -ENODEV;
++
++      pin = gpio & 0x1f;
++      pio_writel(pio, ODR, 1 << pin);
++
++      return 0;
++}
++EXPORT_SYMBOL(gpio_direction_input);
++
++int gpio_direction_output(unsigned int gpio)
++{
++      struct pio_device *pio;
++      unsigned int pin;
++
++      pio = gpio_to_pio(gpio);
++      if (!pio)
++              return -ENODEV;
++
++      pin = gpio & 0x1f;
++      pio_writel(pio, OER, 1 << pin);
++
++      return 0;
++}
++EXPORT_SYMBOL(gpio_direction_output);
++
++int gpio_get_value(unsigned int gpio)
++{
++      struct pio_device *pio = &pio_dev[gpio >> 5];
++
++      return (pio_readl(pio, PDSR) >> (gpio & 0x1f)) & 1;
++}
++EXPORT_SYMBOL(gpio_get_value);
++
++void gpio_set_value(unsigned int gpio, int value)
++{
++      struct pio_device *pio = &pio_dev[gpio >> 5];
++      u32 mask;
++
++      mask = 1 << (gpio & 0x1f);
++      if (value)
++              pio_writel(pio, SODR, mask);
++      else
++              pio_writel(pio, CODR, mask);
++}
++EXPORT_SYMBOL(gpio_set_value);
+ static int __init pio_probe(struct platform_device *pdev)
+ {
+@@ -113,6 +275,12 @@ void __init at32_init_pio(struct platfor
+       pio->pdev = pdev;
+       pio->regs = ioremap(regs->start, regs->end - regs->start + 1);
++      /*
++       * request_gpio() is only valid for pins that have been
++       * configured as GPIO.
++       */
++      pio->gpio_mask = ~0UL;
++
+       pio_writel(pio, ODR, ~0UL);
+       pio_writel(pio, PER, ~0UL);
+ }
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/at32ap7000.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/at32ap7000.h      2006-11-29 16:22:14.000000000 +0100
+@@ -0,0 +1,26 @@
++#ifndef __ASM_ARCH_AT32AP7000_H
++#define __ASM_ARCH_AT32AP7000_H
++
++#define GPIO_PERIPH_A 0
++#define GPIO_PERIPH_B 1
++
++#define NR_GPIO_CONTROLLERS   4
++
++/*
++ * Pin numbers identifying specific GPIO pins on the chip. They can
++ * also be converted to IRQ numbers by passing them through
++ * gpio_to_irq().
++ */
++#define GPIO_PIOA_BASE        (0)
++#define GPIO_PIOB_BASE        (GPIO_PIOA_BASE + 32)
++#define GPIO_PIOC_BASE        (GPIO_PIOB_BASE + 32)
++#define GPIO_PIOD_BASE        (GPIO_PIOC_BASE + 32)
++#define GPIO_PIOE_BASE        (GPIO_PIOD_BASE + 32)
++
++#define GPIO_PIN_PA(N)        (GPIO_PIOA_BASE + (N))
++#define GPIO_PIN_PB(N)        (GPIO_PIOB_BASE + (N))
++#define GPIO_PIN_PC(N)        (GPIO_PIOC_BASE + (N))
++#define GPIO_PIN_PD(N)        (GPIO_PIOD_BASE + (N))
++#define GPIO_PIN_PE(N)        (GPIO_PIOE_BASE + (N))
++
++#endif /* __ASM_ARCH_AT32AP7000_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/gpio.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/gpio.h    2006-11-29 16:22:14.000000000 +0100
+@@ -0,0 +1,39 @@
++#ifndef __ASM_AVR32_GPIO_H
++#define __ASM_AVR32_GPIO_H
++
++#include <linux/compiler.h>
++#include <asm/irq.h>
++
++/*
++ * Set up pin multiplexing, called from board init only.
++ *
++ * The following flags determine the initial state of the pin.
++ */
++#define AT32_GPIOF_PULLUP     0x00000001      /* Enable pull-up */
++#define AT32_GPIOF_OUTPUT     0x00000002      /* Enable output driver */
++#define AT32_GPIOF_HIGH               0x00000004      /* Set output high */
++
++void at32_select_periph(unsigned int pin, unsigned int periph,
++                      unsigned long flags);
++void at32_select_gpio(unsigned int pin, unsigned long flags);
++
++/* Arch-neutral GPIO API */
++int __must_check gpio_request(unsigned int gpio, const char *label);
++void gpio_free(unsigned int gpio);
++
++int gpio_direction_input(unsigned int gpio);
++int gpio_direction_output(unsigned int gpio);
++int gpio_get_value(unsigned int gpio);
++void gpio_set_value(unsigned int gpio, int value);
++
++static inline int gpio_to_irq(unsigned int gpio)
++{
++      return gpio + GPIO_IRQ_BASE;
++}
++
++static inline int irq_to_gpio(unsigned int irq)
++{
++      return irq - GPIO_IRQ_BASE;
++}
++
++#endif /* __ASM_AVR32_GPIO_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/irq.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/irq.h     2006-11-29 16:22:14.000000000 +0100
+@@ -0,0 +1,11 @@
++#ifndef __ASM_AVR32_ARCH_IRQ_H
++#define __ASM_AVR32_ARCH_IRQ_H
++
++#define EIM_IRQ_BASE  NR_INTERNAL_IRQS
++#define NR_EIM_IRQS   32
++#define GPIO_IRQ_BASE (EIM_IRQ_BASE + NR_EIM_IRQS)
++#define NR_GPIO_IRQS  (4 * 32)
++
++#define NR_IRQS               (GPIO_IRQ_BASE + NR_GPIO_IRQS)
++
++#endif /* __ASM_AVR32_ARCH_IRQ_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/portmux.h
+===================================================================
+--- linux-2.6.18-avr32.orig/include/asm-avr32/arch-at32ap/portmux.h    2006-11-29 16:21:12.000000000 +0100
++++ /dev/null  1970-01-01 00:00:00.000000000 +0000
+@@ -1,16 +0,0 @@
+-/*
+- * AT32 portmux interface.
+- *
+- * 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 __ASM_AVR32_AT32_PORTMUX_H__
+-#define __ASM_AVR32_AT32_PORTMUX_H__
+-
+-void portmux_set_func(unsigned int portmux_id, unsigned int pin_id,
+-                    unsigned int function_id);
+-
+-#endif /* __ASM_AVR32_AT32_PORTMUX_H__ */
+Index: linux-2.6.18-avr32/include/asm-avr32/gpio.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/gpio.h        2006-11-29 16:22:14.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_GPIO_H
++#define __ASM_AVR32_GPIO_H
++
++#include <asm/arch/gpio.h>
++
++#endif /* __ASM_AVR32_GPIO_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/irq.h
+===================================================================
+--- linux-2.6.18-avr32.orig/include/asm-avr32/irq.h    2006-11-29 16:21:12.000000000 +0100
++++ linux-2.6.18-avr32/include/asm-avr32/irq.h 2006-11-29 16:22:14.000000000 +0100
+@@ -2,8 +2,12 @@
+ #define __ASM_AVR32_IRQ_H
+ #define NR_INTERNAL_IRQS      64
+-#define NR_EXTERNAL_IRQS      64
+-#define NR_IRQS                       (NR_INTERNAL_IRQS + NR_EXTERNAL_IRQS)
++
++#include <asm/arch/irq.h>
++
++#ifndef NR_IRQS
++#define NR_IRQS                       (NR_INTERNAL_IRQS)
++#endif
+ #define irq_canonicalize(i)   (i)
diff --git a/packages/linux/linux-2.6.18/avr32-arch.patch b/packages/linux/linux-2.6.18/avr32-arch.patch
new file mode 100644 (file)
index 0000000..76e2b9f
--- /dev/null
@@ -0,0 +1,19628 @@
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+
+This adds support for the Atmel AVR32 architecture as well as the AT32AP7000
+CPU and the AT32STK1000 development board.
+
+AVR32 is a new high-performance 32-bit RISC microprocessor core, designed for
+cost-sensitive embedded applications, with particular emphasis on low power
+consumption and high code density.  The AVR32 architecture is not binary
+compatible with earlier 8-bit AVR architectures.
+
+The AVR32 architecture, including the instruction set, is described by the
+AVR32 Architecture Manual, available from
+
+http://www.atmel.com/dyn/resources/prod_documents/doc32000.pdf
+
+The Atmel AT32AP7000 is the first CPU implementing the AVR32 architecture.  It
+features a 7-stage pipeline, 16KB instruction and data caches and a full
+Memory Management Unit.  It also comes with a large set of integrated
+peripherals, many of which are shared with the AT91 ARM-based controllers from
+Atmel.
+
+Full data sheet is available from
+
+http://www.atmel.com/dyn/resources/prod_documents/doc32003.pdf
+
+while the CPU core implementation including caches and MMU is documented by
+the AVR32 AP Technical Reference, available from
+
+http://www.atmel.com/dyn/resources/prod_documents/doc32001.pdf
+
+Information about the AT32STK1000 development board can be found at
+
+http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3918
+
+including a BSP CD image with an earlier version of this patch, development
+tools (binaries and source/patches) and a root filesystem image suitable for
+booting from SD card.
+
+Alternatively, there's a preliminary "getting started" guide available at
+http://avr32linux.org/twiki/bin/view/Main/GettingStarted which provides links
+to the sources and patches you will need in order to set up a cross-compiling
+environment for avr32-linux.
+
+This patch, as well as the other patches included with the BSP and the
+toolchain patches, is actively supported by Atmel Corporation.
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+---
+
+ MAINTAINERS                                      |   17 
+ arch/avr32/Kconfig                               |  199 +++++
+ arch/avr32/Kconfig.debug                         |   19 
+ arch/avr32/Makefile                              |   89 ++
+ arch/avr32/boards/atstk1000/Makefile             |    2 
+ arch/avr32/boards/atstk1000/atstk1002.c          |   37 
+ arch/avr32/boards/atstk1000/flash.c              |   95 ++
+ arch/avr32/boards/atstk1000/setup.c              |   50 +
+ arch/avr32/boards/atstk1000/spi.c                |   27 
+ arch/avr32/boot/images/Makefile                  |   60 +
+ arch/avr32/boot/u-boot/Makefile                  |    3 
+ arch/avr32/boot/u-boot/empty.S                   |    1 
+ arch/avr32/boot/u-boot/head.S                    |   60 +
+ arch/avr32/configs/atstk1002_defconfig           |  754 +++++++++++++++++++
+ arch/avr32/kernel/Makefile                       |   18 
+ arch/avr32/kernel/asm-offsets.c                  |   25 
+ arch/avr32/kernel/avr32_ksyms.c                  |   64 +
+ arch/avr32/kernel/cpu.c                          |  327 ++++++++
+ arch/avr32/kernel/entry-avr32b.S                 |  678 +++++++++++++++++
+ arch/avr32/kernel/head.S                         |   42 +
+ arch/avr32/kernel/init_task.c                    |   38 
+ arch/avr32/kernel/irq.c                          |   71 +
+ arch/avr32/kernel/kprobes.c                      |  270 +++++++
+ arch/avr32/kernel/module.c                       |  324 ++++++++
+ arch/avr32/kernel/process.c                      |  283 +++++++
+ arch/avr32/kernel/ptrace.c                       |  371 +++++++++
+ arch/avr32/kernel/semaphore.c                    |  148 +++
+ arch/avr32/kernel/setup.c                        |  335 ++++++++
+ arch/avr32/kernel/signal.c                       |  328 ++++++++
+ arch/avr32/kernel/switch_to.S                    |   35 
+ arch/avr32/kernel/sys_avr32.c                    |   51 +
+ arch/avr32/kernel/syscall-stubs.S                |  102 ++
+ arch/avr32/kernel/syscall_table.S                |  289 +++++++
+ arch/avr32/kernel/time.c                         |  238 ++++++
+ arch/avr32/kernel/traps.c                        |  425 +++++++++++
+ arch/avr32/kernel/vmlinux.lds.c                  |  139 +++
+ arch/avr32/lib/Makefile                          |   11 
+ arch/avr32/lib/__avr32_asr64.S                   |   31 
+ arch/avr32/lib/__avr32_lsl64.S                   |   31 
+ arch/avr32/lib/__avr32_lsr64.S                   |   31 
+ arch/avr32/lib/clear_user.S                      |   76 +
+ arch/avr32/lib/copy_user.S                       |  119 +++
+ arch/avr32/lib/csum_partial.S                    |   47 +
+ arch/avr32/lib/csum_partial_copy_generic.S       |   99 ++
+ arch/avr32/lib/delay.c                           |   55 +
+ arch/avr32/lib/findbit.S                         |  155 ++++
+ arch/avr32/lib/io-readsb.S                       |   49 +
+ arch/avr32/lib/io-readsl.S                       |   24 
+ arch/avr32/lib/io-readsw.S                       |   43 +
+ arch/avr32/lib/io-writesb.S                      |   52 +
+ arch/avr32/lib/io-writesl.S                      |   20 
+ arch/avr32/lib/io-writesw.S                      |   38 
+ arch/avr32/lib/libgcc.h                          |   33 
+ arch/avr32/lib/longlong.h                        |   98 ++
+ arch/avr32/lib/memcpy.S                          |   62 +
+ arch/avr32/lib/memset.S                          |   72 +
+ arch/avr32/lib/strncpy_from_user.S               |   60 +
+ arch/avr32/lib/strnlen_user.S                    |   67 +
+ arch/avr32/mach-at32ap/Makefile                  |    2 
+ arch/avr32/mach-at32ap/at32ap.c                  |   90 ++
+ arch/avr32/mach-at32ap/at32ap7000.c              |  876 +++++++++++++++++++++++
+ arch/avr32/mach-at32ap/clock.c                   |  148 +++
+ arch/avr32/mach-at32ap/clock.h                   |   30 
+ arch/avr32/mach-at32ap/extint.c                  |  189 ++++
+ arch/avr32/mach-at32ap/hsmc.c                    |  164 ++++
+ arch/avr32/mach-at32ap/hsmc.h                    |  127 +++
+ arch/avr32/mach-at32ap/intc.c                    |  133 +++
+ arch/avr32/mach-at32ap/intc.h                    |  329 ++++++++
+ arch/avr32/mach-at32ap/pio.c                     |  118 +++
+ arch/avr32/mach-at32ap/pio.h                     |  180 ++++
+ arch/avr32/mach-at32ap/sm.h                      |  242 ++++++
+ arch/avr32/mm/Makefile                           |    6 
+ arch/avr32/mm/cache.c                            |  150 +++
+ arch/avr32/mm/clear_page.S                       |   25 
+ arch/avr32/mm/copy_page.S                        |   28 
+ arch/avr32/mm/dma-coherent.c                     |  139 +++
+ arch/avr32/mm/fault.c                            |  315 ++++++++
+ arch/avr32/mm/init.c                             |  481 ++++++++++++
+ arch/avr32/mm/ioremap.c                          |  199 +++++
+ arch/avr32/mm/tlb.c                              |  378 +++++++++
+ include/asm-avr32/Kbuild                         |    3 
+ include/asm-avr32/a.out.h                        |   26 
+ include/asm-avr32/addrspace.h                    |   43 +
+ include/asm-avr32/arch-at32ap/at91rm9200_pdc.h   |   36 
+ include/asm-avr32/arch-at32ap/at91rm9200_usart.h |  123 +++
+ include/asm-avr32/arch-at32ap/board.h            |   35 
+ include/asm-avr32/arch-at32ap/init.h             |   21 
+ include/asm-avr32/arch-at32ap/portmux.h          |   16 
+ include/asm-avr32/arch-at32ap/sm.h               |   27 
+ include/asm-avr32/arch-at32ap/smc.h              |   60 +
+ include/asm-avr32/asm.h                          |  102 ++
+ include/asm-avr32/atomic.h                       |  201 +++++
+ include/asm-avr32/auxvec.h                       |    4 
+ include/asm-avr32/bitops.h                       |  296 +++++++
+ include/asm-avr32/bug.h                          |   47 +
+ include/asm-avr32/bugs.h                         |   15 
+ include/asm-avr32/byteorder.h                    |   25 
+ include/asm-avr32/cache.h                        |   29 
+ include/asm-avr32/cachectl.h                     |   11 
+ include/asm-avr32/cacheflush.h                   |  129 +++
+ include/asm-avr32/checksum.h                     |  156 ++++
+ include/asm-avr32/cputime.h                      |    6 
+ include/asm-avr32/current.h                      |   15 
+ include/asm-avr32/delay.h                        |   26 
+ include/asm-avr32/div64.h                        |    6 
+ include/asm-avr32/dma-mapping.h                  |  320 ++++++++
+ include/asm-avr32/dma.h                          |    8 
+ include/asm-avr32/elf.h                          |  110 ++
+ include/asm-avr32/emergency-restart.h            |    6 
+ include/asm-avr32/errno.h                        |    6 
+ include/asm-avr32/fcntl.h                        |    6 
+ include/asm-avr32/futex.h                        |    6 
+ include/asm-avr32/hardirq.h                      |   34 
+ include/asm-avr32/hw_irq.h                       |    9 
+ include/asm-avr32/intc.h                         |  128 +++
+ include/asm-avr32/io.h                           |  286 +++++++
+ include/asm-avr32/ioctl.h                        |    6 
+ include/asm-avr32/ioctls.h                       |   83 ++
+ include/asm-avr32/ipcbuf.h                       |   29 
+ include/asm-avr32/irq.h                          |   10 
+ include/asm-avr32/irqflags.h                     |   68 +
+ include/asm-avr32/kdebug.h                       |   38 
+ include/asm-avr32/kmap_types.h                   |   30 
+ include/asm-avr32/kprobes.h                      |   34 
+ include/asm-avr32/linkage.h                      |    7 
+ include/asm-avr32/local.h                        |    6 
+ include/asm-avr32/mach/serial_at91.h             |   33 
+ include/asm-avr32/mman.h                         |   17 
+ include/asm-avr32/mmu.h                          |   10 
+ include/asm-avr32/mmu_context.h                  |  148 +++
+ include/asm-avr32/module.h                       |   28 
+ include/asm-avr32/msgbuf.h                       |   31 
+ include/asm-avr32/mutex.h                        |    9 
+ include/asm-avr32/namei.h                        |    7 
+ include/asm-avr32/numnodes.h                     |    7 
+ include/asm-avr32/ocd.h                          |   78 ++
+ include/asm-avr32/page.h                         |  112 ++
+ include/asm-avr32/param.h                        |   23 
+ include/asm-avr32/pci.h                          |    8 
+ include/asm-avr32/percpu.h                       |    6 
+ include/asm-avr32/pgalloc.h                      |   96 ++
+ include/asm-avr32/pgtable-2level.h               |   47 +
+ include/asm-avr32/pgtable.h                      |  408 ++++++++++
+ include/asm-avr32/poll.h                         |   27 
+ include/asm-avr32/posix_types.h                  |  129 +++
+ include/asm-avr32/processor.h                    |  147 +++
+ include/asm-avr32/ptrace.h                       |  154 ++++
+ include/asm-avr32/resource.h                     |    6 
+ include/asm-avr32/scatterlist.h                  |   21 
+ include/asm-avr32/sections.h                     |    6 
+ include/asm-avr32/semaphore.h                    |  109 ++
+ include/asm-avr32/sembuf.h                       |   25 
+ include/asm-avr32/setup.h                        |  141 +++
+ include/asm-avr32/shmbuf.h                       |   42 +
+ include/asm-avr32/shmparam.h                     |    6 
+ include/asm-avr32/sigcontext.h                   |   34 
+ include/asm-avr32/siginfo.h                      |    6 
+ include/asm-avr32/signal.h                       |  168 ++++
+ include/asm-avr32/socket.h                       |   53 +
+ include/asm-avr32/sockios.h                      |   12 
+ include/asm-avr32/stat.h                         |   79 ++
+ include/asm-avr32/statfs.h                       |    6 
+ include/asm-avr32/string.h                       |   17 
+ include/asm-avr32/sysreg.h                       |  332 ++++++++
+ include/asm-avr32/system.h                       |  155 ++++
+ include/asm-avr32/termbits.h                     |  173 ++++
+ include/asm-avr32/termios.h                      |   80 ++
+ include/asm-avr32/thread_info.h                  |  106 ++
+ include/asm-avr32/timex.h                        |   40 +
+ include/asm-avr32/tlb.h                          |   32 
+ include/asm-avr32/tlbflush.h                     |   40 +
+ include/asm-avr32/topology.h                     |    6 
+ include/asm-avr32/traps.h                        |   23 
+ include/asm-avr32/types.h                        |   70 +
+ include/asm-avr32/uaccess.h                      |  335 ++++++++
+ include/asm-avr32/ucontext.h                     |   12 
+ include/asm-avr32/unaligned.h                    |   25 
+ include/asm-avr32/unistd.h                       |  387 ++++++++++
+ include/asm-avr32/user.h                         |   64 +
+ include/linux/elf-em.h                           |    1 
+ lib/Kconfig.debug                                |    4 
+ 181 files changed, 18463 insertions(+), 2 deletions(-)
+
+Index: linux-2.6.18-avr32/MAINTAINERS
+===================================================================
+--- linux-2.6.18-avr32.orig/MAINTAINERS        2006-12-04 09:32:57.000000000 +0100
++++ linux-2.6.18-avr32/MAINTAINERS     2006-12-04 09:33:12.000000000 +0100
+@@ -435,6 +435,23 @@ W:        http://people.redhat.com/sgrubb/audit
+ T:    git kernel.org:/pub/scm/linux/kernel/git/dwmw2/audit-2.6.git
+ S:    Maintained
++AVR32 ARCHITECTURE
++P:    Atmel AVR32 Support Team
++M:    avr32@atmel.com
++P:    Haavard Skinnemoen
++M:    hskinnemoen@atmel.com
++W:    http://www.atmel.com/products/AVR32/
++W:    http://avr32linux.org/
++W:    http://avrfreaks.net/
++S:    Supported
++
++AVR32/AT32AP MACHINE SUPPORT
++P:    Atmel AVR32 Support Team
++M:    avr32@atmel.com
++P:    Haavard Skinnemoen
++M:    hskinnemoen@atmel.com
++S:    Supported
++
+ AX.25 NETWORK LAYER
+ P:    Ralf Baechle
+ M:    ralf@linux-mips.org
+Index: linux-2.6.18-avr32/arch/avr32/Kconfig
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/Kconfig      2006-12-04 11:50:25.000000000 +0100
+@@ -0,0 +1,199 @@
++#
++# For a description of the syntax of this configuration file,
++# see Documentation/kbuild/kconfig-language.txt.
++#
++
++mainmenu "Linux Kernel Configuration"
++
++config AVR32
++      bool
++      default y
++      # With EMBEDDED=n, we get lots of stuff automatically selected
++      # that we usually don't need on AVR32.
++      select EMBEDDED
++      help
++        AVR32 is a high-performance 32-bit RISC microprocessor core,
++        designed for cost-sensitive embedded applications, with particular
++        emphasis on low power consumption and high code density.
++
++        There is an AVR32 Linux project with a web page at
++        http://avr32linux.org/.
++
++config UID16
++      bool
++
++config GENERIC_HARDIRQS
++      bool
++      default y
++
++config HARDIRQS_SW_RESEND
++      bool
++      default y
++
++config GENERIC_IRQ_PROBE
++      bool
++      default y
++
++config RWSEM_GENERIC_SPINLOCK
++      bool
++      default y
++
++config GENERIC_TIME
++      bool
++      default y
++
++config RWSEM_XCHGADD_ALGORITHM
++      bool
++
++config GENERIC_BUST_SPINLOCK
++      bool
++
++config GENERIC_ISA_DMA
++      bool
++
++config GENERIC_HWEIGHT
++      bool
++      default y
++
++config GENERIC_CALIBRATE_DELAY
++      bool
++      default y
++
++source "init/Kconfig"
++
++menu "System Type and features"
++
++config SUBARCH_AVR32B
++      bool
++config MMU
++      bool
++config PERFORMANCE_COUNTERS
++      bool
++
++config PLATFORM_AT32AP
++      bool
++      select SUBARCH_AVR32B
++      select MMU
++      select PERFORMANCE_COUNTERS
++
++choice
++      prompt "AVR32 CPU type"
++      default CPU_AT32AP7000
++
++config CPU_AT32AP7000
++      bool "AT32AP7000"
++      select PLATFORM_AT32AP
++endchoice
++
++#
++# CPU Daughterboards for ATSTK1000
++config BOARD_ATSTK1002
++      bool
++
++choice
++      prompt "AVR32 board type"
++      default BOARD_ATSTK1000
++
++config BOARD_ATSTK1000
++      bool "ATSTK1000 evaluation board"
++      select BOARD_ATSTK1002 if CPU_AT32AP7000
++endchoice
++
++choice
++      prompt "Boot loader type"
++      default LOADER_U_BOOT
++
++config        LOADER_U_BOOT
++      bool "U-Boot (or similar) bootloader"
++endchoice
++
++config LOAD_ADDRESS
++      hex
++      default 0x10000000 if LOADER_U_BOOT=y && CPU_AT32AP7000=y
++
++config ENTRY_ADDRESS
++      hex
++      default 0x90000000 if LOADER_U_BOOT=y && CPU_AT32AP7000=y
++
++config PHYS_OFFSET
++      hex
++      default 0x10000000 if CPU_AT32AP7000=y
++
++source "kernel/Kconfig.preempt"
++
++config HAVE_ARCH_BOOTMEM_NODE
++      bool
++      default n
++
++config ARCH_HAVE_MEMORY_PRESENT
++      bool
++      default n
++
++config NEED_NODE_MEMMAP_SIZE
++      bool
++      default n
++
++config ARCH_FLATMEM_ENABLE
++      bool
++      default y
++
++config ARCH_DISCONTIGMEM_ENABLE
++      bool
++      default n
++
++config ARCH_SPARSEMEM_ENABLE
++      bool
++      default n
++
++source "mm/Kconfig"
++
++config OWNERSHIP_TRACE
++      bool "Ownership trace support"
++      default y
++      help
++        Say Y to generate an Ownership Trace message on every context switch,
++        enabling Nexus-compliant debuggers to keep track of the PID of the
++        currently executing task.
++
++# FPU emulation goes here
++
++source "kernel/Kconfig.hz"
++
++config CMDLINE
++      string "Default kernel command line"
++      default ""
++      help
++        If you don't have a boot loader capable of passing a command line string
++        to the kernel, you may specify one here. As a minimum, you should specify
++        the memory size and the root device (e.g., mem=8M, root=/dev/nfs).
++
++endmenu
++
++menu "Bus options"
++
++config PCI
++      bool
++
++source "drivers/pci/Kconfig"
++
++source "drivers/pcmcia/Kconfig"
++
++endmenu
++
++menu "Executable file formats"
++source "fs/Kconfig.binfmt"
++endmenu
++
++source "net/Kconfig"
++
++source "drivers/Kconfig"
++
++source "fs/Kconfig"
++
++source "arch/avr32/Kconfig.debug"
++
++source "security/Kconfig"
++
++source "crypto/Kconfig"
++
++source "lib/Kconfig"
+Index: linux-2.6.18-avr32/arch/avr32/Kconfig.debug
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/Kconfig.debug        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,19 @@
++menu "Kernel hacking"
++
++config TRACE_IRQFLAGS_SUPPORT
++      bool
++      default y
++
++source "lib/Kconfig.debug"
++
++config KPROBES
++      bool "Kprobes"
++      depends on DEBUG_KERNEL
++      help
++        Kprobes allows you to trap at almost any kernel address and
++          execute a callback function.  register_kprobe() establishes
++          a probepoint and specifies the callback.  Kprobes is useful
++          for kernel debugging, non-intrusive instrumentation and testing.
++          If in doubt, say "N".
++
++endmenu
+Index: linux-2.6.18-avr32/arch/avr32/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/Makefile     2006-12-04 11:50:25.000000000 +0100
+@@ -0,0 +1,89 @@
++#
++# This file is subject to the terms and conditions of the GNU General Public
++# License.  See the file "COPYING" in the main directory of this archive
++# for more details.
++#
++# Copyright (C) 2004-2006 Atmel Corporation.
++
++# Default target when executing plain make
++.PHONY: all
++all: uImage vmlinux.elf
++
++KBUILD_DEFCONFIG      := atstk1002_defconfig
++
++CFLAGS                += -pipe -fno-builtin -mno-pic
++AFLAGS                += -mrelax -mno-pic
++CFLAGS_MODULE += -mno-relax
++LDFLAGS_vmlinux       += --relax
++
++cpuflags-$(CONFIG_CPU_AP7000) += -mcpu=ap7000
++
++CFLAGS                += $(cpuflags-y)
++AFLAGS                += $(cpuflags-y)
++
++CHECKFLAGS    += -D__avr32__ -D__BIG_ENDIAN
++
++head-$(CONFIG_LOADER_U_BOOT)          += arch/avr32/boot/u-boot/head.o
++head-y                                        += arch/avr32/kernel/head.o
++core-$(CONFIG_PLATFORM_AT32AP)                += arch/avr32/mach-at32ap/
++core-$(CONFIG_BOARD_ATSTK1000)                += arch/avr32/boards/atstk1000/
++core-$(CONFIG_LOADER_U_BOOT)          += arch/avr32/boot/u-boot/
++core-y                                        += arch/avr32/kernel/
++core-y                                        += arch/avr32/mm/
++libs-y                                        += arch/avr32/lib/
++
++archincdir-$(CONFIG_PLATFORM_AT32AP)  := arch-at32ap
++
++include/asm-avr32/.arch: $(wildcard include/config/platform/*.h) include/config/auto.conf
++      @echo '  SYMLINK include/asm-avr32/arch -> include/asm-avr32/$(archincdir-y)'
++ifneq ($(KBUILD_SRC),)
++      $(Q)mkdir -p include/asm-avr32
++      $(Q)ln -fsn $(srctree)/include/asm-avr32/$(archincdir-y) include/asm-avr32/arch
++else
++      $(Q)ln -fsn $(archincdir-y) include/asm-avr32/arch
++endif
++      @touch $@
++
++archprepare: include/asm-avr32/.arch
++
++CLEAN_FILES += include/asm-avr32/.arch include/asm-avr32/arch
++
++BOOT_TARGETS := vmlinux.elf vmlinux.bin uImage uImage.srec
++
++.PHONY: $(BOOT_TARGETS) install
++
++boot := arch/$(ARCH)/boot/images
++
++             KBUILD_IMAGE := $(boot)/uImage
++vmlinux.elf: KBUILD_IMAGE := $(boot)/vmlinux.elf
++vmlinux.cso: KBUILD_IMAGE := $(boot)/vmlinux.cso
++uImage.srec: KBUILD_IMAGE := $(boot)/uImage.srec
++uImage:      KBUILD_IMAGE := $(boot)/uImage
++
++quiet_cmd_listing = LST     $@
++      cmd_listing = avr32-linux-objdump $(OBJDUMPFLAGS) -lS $< > $@
++quiet_cmd_disasm  = DIS     $@
++      cmd_disasm  = avr32-linux-objdump $(OBJDUMPFLAGS) -d $< > $@
++
++vmlinux.elf vmlinux.bin uImage.srec uImage vmlinux.cso: vmlinux
++      $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
++
++install: vmlinux
++      $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
++
++vmlinux.s: vmlinux
++      $(call if_changed,disasm)
++
++vmlinux.lst: vmlinux
++      $(call if_changed,listing)
++
++CLEAN_FILES += vmlinux.s vmlinux.lst
++
++archclean:
++      $(Q)$(MAKE) $(clean)=$(boot)
++
++define archhelp
++  @echo '* vmlinux.elf                - ELF image with load address 0'
++  @echo '  vmlinux.cso                - PathFinder CSO image'
++  @echo '* uImage             - Create a bootable image for U-Boot'
++endef
+Index: linux-2.6.18-avr32/arch/avr32/boot/images/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/boot/images/Makefile 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,60 @@
++#
++# Copyright (C) 2004-2006 Atmel Corporation
++#
++# This file is subject to the terms and conditions of the GNU General Public
++# License.  See the file "COPYING" in the main directory of this archive
++# for more details.
++#
++
++MKIMAGE               := $(srctree)/scripts/mkuboot.sh
++
++extra-y               := vmlinux.bin vmlinux.gz
++
++OBJCOPYFLAGS_vmlinux.bin := -O binary
++$(obj)/vmlinux.bin: vmlinux FORCE
++      $(call if_changed,objcopy)
++
++$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
++      $(call if_changed,gzip)
++
++quiet_cmd_uimage = UIMAGE $@
++      cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A avr32 -O linux -T kernel     \
++              -C gzip -a $(CONFIG_LOAD_ADDRESS) -e $(CONFIG_ENTRY_ADDRESS)    \
++              -n 'Linux-$(KERNELRELEASE)' -d $< $@
++
++targets += uImage uImage.srec
++$(obj)/uImage: $(obj)/vmlinux.gz
++      $(call if_changed,uimage)
++      @echo '  Image $@ is ready'
++
++OBJCOPYFLAGS_uImage.srec := -I binary -O srec
++$(obj)/uImage.srec: $(obj)/uImage
++      $(call if_changed,objcopy)
++
++OBJCOPYFLAGS_vmlinux.elf := --change-section-lma .text-0x80000000 \
++                          --change-section-lma __ex_table-0x80000000 \
++                          --change-section-lma .rodata-0x80000000 \
++                          --change-section-lma .data-0x80000000 \
++                          --change-section-lma .init-0x80000000 \
++                          --change-section-lma .bss-0x80000000 \
++                          --change-section-lma __param-0x80000000 \
++                          --change-section-lma __ksymtab-0x80000000 \
++                          --change-section-lma __ksymtab_gpl-0x80000000 \
++                          --change-section-lma __kcrctab-0x80000000 \
++                          --change-section-lma __kcrctab_gpl-0x80000000 \
++                          --change-section-lma __ksymtab_strings-0x80000000 \
++                          --set-start 0xa0000000
++$(obj)/vmlinux.elf: vmlinux FORCE
++      $(call if_changed,objcopy)
++
++quiet_cmd_sfdwarf = SFDWARF $@
++      cmd_sfdwarf = sfdwarf $< TO $@ GNUAVR IW $(SFDWARF_FLAGS) > $(obj)/sfdwarf.log
++
++$(obj)/vmlinux.cso: $(obj)/vmlinux.elf FORCE
++      $(call if_changed,sfdwarf)
++
++install: $(BOOTIMAGE)
++      sh $(srctree)/install-kernel.sh $<
++
++# Generated files to be removed upon make clean
++clean-files   := vmlinux.elf vmlinux.bin vmlinux.gz uImage uImage.srec
+Index: linux-2.6.18-avr32/arch/avr32/boot/u-boot/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/boot/u-boot/Makefile 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,3 @@
++extra-y               := head.o
++
++obj-y         := empty.o
+Index: linux-2.6.18-avr32/arch/avr32/boot/u-boot/empty.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/boot/u-boot/empty.S  2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1 @@
++/* Empty file */
+Index: linux-2.6.18-avr32/arch/avr32/boot/u-boot/head.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/boot/u-boot/head.S   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,60 @@
++/*
++ * Startup code for use with the u-boot bootloader.
++ *
++ * 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 <asm/setup.h>
++
++      /*
++       * The kernel is loaded where we want it to be and all caches
++       * have just been flushed. We get two parameters from u-boot:
++       *
++       * r12 contains a magic number (ATAG_MAGIC)
++       * r11 points to a tag table providing information about
++       *     the system.
++       */
++      .section .init.text,"ax"
++      .global _start
++_start:
++      /* Check if the boot loader actually provided a tag table */
++      lddpc   r0, magic_number
++      cp.w    r12, r0
++      brne    no_tag_table
++
++      /* Initialize .bss */
++      lddpc   r2, bss_start_addr
++      lddpc   r3, end_addr
++      mov     r0, 0
++      mov     r1, 0
++1:      st.d    r2++, r0
++      cp      r2, r3
++      brlo    1b
++
++      /*
++       * Save the tag table address for later use. This must be done
++       * _after_ .bss has been initialized...
++       */
++      lddpc   r0, tag_table_addr
++      st.w    r0[0], r11
++
++      /* Jump to loader-independent setup code */
++      rjmp    kernel_entry
++
++      .align  2
++magic_number:
++      .long   ATAG_MAGIC
++tag_table_addr:
++      .long   bootloader_tags
++bss_start_addr:
++      .long   __bss_start
++end_addr:
++      .long   _end
++
++no_tag_table:
++      sub     r12, pc, (. - 2f)
++      bral    panic
++2:    .asciz  "Boot loader didn't provide correct magic number\n"
+Index: linux-2.6.18-avr32/arch/avr32/kernel/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/Makefile      2006-12-04 11:50:25.000000000 +0100
+@@ -0,0 +1,18 @@
++#
++# Makefile for the Linux/AVR32 kernel.
++#
++
++extra-y                               := head.o vmlinux.lds
++
++obj-$(CONFIG_SUBARCH_AVR32B)  += entry-avr32b.o
++obj-y                         += syscall_table.o syscall-stubs.o irq.o
++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-$(CONFIG_MODULES)         += module.o avr32_ksyms.o
++obj-$(CONFIG_KPROBES)         += kprobes.o
++
++USE_STANDARD_AS_RULE          := true
++
++%.lds: %.lds.c FORCE
++      $(call if_changed_dep,cpp_lds_S)
+Index: linux-2.6.18-avr32/arch/avr32/kernel/asm-offsets.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/asm-offsets.c 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,25 @@
++/*
++ * Generate definitions needed by assembly language modules.
++ * This code generates raw asm output which is post-processed
++ * to extract and format the required data.
++ */
++
++#include <linux/thread_info.h>
++
++#define DEFINE(sym, val) \
++        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
++
++#define BLANK() asm volatile("\n->" : : )
++
++#define OFFSET(sym, str, mem) \
++        DEFINE(sym, offsetof(struct str, mem));
++
++void foo(void)
++{
++      OFFSET(TI_task, thread_info, task);
++      OFFSET(TI_exec_domain, thread_info, exec_domain);
++      OFFSET(TI_flags, thread_info, flags);
++      OFFSET(TI_cpu, thread_info, cpu);
++      OFFSET(TI_preempt_count, thread_info, preempt_count);
++      OFFSET(TI_restart_block, thread_info, restart_block);
++}
+Index: linux-2.6.18-avr32/arch/avr32/kernel/avr32_ksyms.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/avr32_ksyms.c 2006-12-04 11:50:25.000000000 +0100
+@@ -0,0 +1,64 @@
++/*
++ * Export AVR32-specific functions for loadable modules.
++ *
++ * 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/io.h>
++#include <linux/module.h>
++
++#include <asm/checksum.h>
++#include <asm/uaccess.h>
++#include <asm/delay.h>
++
++/*
++ * GCC functions
++ */
++extern unsigned long long __avr32_lsl64(unsigned long long u, unsigned long b);
++extern unsigned long long __avr32_lsr64(unsigned long long u, unsigned long b);
++extern unsigned long long __avr32_asr64(unsigned long long u, unsigned long b);
++EXPORT_SYMBOL(__avr32_lsl64);
++EXPORT_SYMBOL(__avr32_lsr64);
++EXPORT_SYMBOL(__avr32_asr64);
++
++/*
++ * String functions
++ */
++EXPORT_SYMBOL(memset);
++EXPORT_SYMBOL(memcpy);
++
++/*
++ * Userspace access stuff.
++ */
++EXPORT_SYMBOL(copy_from_user);
++EXPORT_SYMBOL(copy_to_user);
++EXPORT_SYMBOL(__copy_user);
++EXPORT_SYMBOL(strncpy_from_user);
++EXPORT_SYMBOL(__strncpy_from_user);
++EXPORT_SYMBOL(clear_user);
++EXPORT_SYMBOL(__clear_user);
++EXPORT_SYMBOL(csum_partial);
++EXPORT_SYMBOL(csum_partial_copy_generic);
++
++/* Delay loops (lib/delay.S) */
++EXPORT_SYMBOL(__ndelay);
++EXPORT_SYMBOL(__udelay);
++EXPORT_SYMBOL(__const_udelay);
++
++/* Bit operations (lib/findbit.S) */
++EXPORT_SYMBOL(find_first_zero_bit);
++EXPORT_SYMBOL(find_next_zero_bit);
++EXPORT_SYMBOL(find_first_bit);
++EXPORT_SYMBOL(find_next_bit);
++EXPORT_SYMBOL(generic_find_next_zero_le_bit);
++
++/* I/O primitives (lib/io-*.S) */
++EXPORT_SYMBOL(__raw_readsb);
++EXPORT_SYMBOL(__raw_readsw);
++EXPORT_SYMBOL(__raw_readsl);
++EXPORT_SYMBOL(__raw_writesb);
++EXPORT_SYMBOL(__raw_writesw);
++EXPORT_SYMBOL(__raw_writesl);
+Index: linux-2.6.18-avr32/arch/avr32/kernel/cpu.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/cpu.c 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,327 @@
++/*
++ * 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/init.h>
++#include <linux/sysdev.h>
++#include <linux/seq_file.h>
++#include <linux/cpu.h>
++#include <linux/percpu.h>
++#include <linux/param.h>
++#include <linux/errno.h>
++
++#include <asm/setup.h>
++#include <asm/sysreg.h>
++
++static DEFINE_PER_CPU(struct cpu, cpu_devices);
++
++#ifdef CONFIG_PERFORMANCE_COUNTERS
++
++/*
++ * XXX: If/when a SMP-capable implementation of AVR32 will ever be
++ * made, we must make sure that the code executes on the correct CPU.
++ */
++static ssize_t show_pc0event(struct sys_device *dev, char *buf)
++{
++      unsigned long pccr;
++
++      pccr = sysreg_read(PCCR);
++      return sprintf(buf, "0x%lx\n", (pccr >> 12) & 0x3f);
++}
++static ssize_t store_pc0event(struct sys_device *dev, const char *buf,
++                            size_t count)
++{
++      unsigned long val;
++      char *endp;
++
++      val = simple_strtoul(buf, &endp, 0);
++      if (endp == buf || val > 0x3f)
++              return -EINVAL;
++      val = (val << 12) | (sysreg_read(PCCR) & 0xfffc0fff);
++      sysreg_write(PCCR, val);
++      return count;
++}
++static ssize_t show_pc0count(struct sys_device *dev, char *buf)
++{
++      unsigned long pcnt0;
++
++      pcnt0 = sysreg_read(PCNT0);
++      return sprintf(buf, "%lu\n", pcnt0);
++}
++static ssize_t store_pc0count(struct sys_device *dev, const char *buf,
++                            size_t count)
++{
++      unsigned long val;
++      char *endp;
++
++      val = simple_strtoul(buf, &endp, 0);
++      if (endp == buf)
++              return -EINVAL;
++      sysreg_write(PCNT0, val);
++
++      return count;
++}
++
++static ssize_t show_pc1event(struct sys_device *dev, char *buf)
++{
++      unsigned long pccr;
++
++      pccr = sysreg_read(PCCR);
++      return sprintf(buf, "0x%lx\n", (pccr >> 18) & 0x3f);
++}
++static ssize_t store_pc1event(struct sys_device *dev, const char *buf,
++                            size_t count)
++{
++      unsigned long val;
++      char *endp;
++
++      val = simple_strtoul(buf, &endp, 0);
++      if (endp == buf || val > 0x3f)
++              return -EINVAL;
++      val = (val << 18) | (sysreg_read(PCCR) & 0xff03ffff);
++      sysreg_write(PCCR, val);
++      return count;
++}
++static ssize_t show_pc1count(struct sys_device *dev, char *buf)
++{
++      unsigned long pcnt1;
++
++      pcnt1 = sysreg_read(PCNT1);
++      return sprintf(buf, "%lu\n", pcnt1);
++}
++static ssize_t store_pc1count(struct sys_device *dev, const char *buf,
++                            size_t count)
++{
++      unsigned long val;
++      char *endp;
++
++      val = simple_strtoul(buf, &endp, 0);
++      if (endp == buf)
++              return -EINVAL;
++      sysreg_write(PCNT1, val);
++
++      return count;
++}
++
++static ssize_t show_pccycles(struct sys_device *dev, char *buf)
++{
++      unsigned long pccnt;
++
++      pccnt = sysreg_read(PCCNT);
++      return sprintf(buf, "%lu\n", pccnt);
++}
++static ssize_t store_pccycles(struct sys_device *dev, const char *buf,
++                            size_t count)
++{
++      unsigned long val;
++      char *endp;
++
++      val = simple_strtoul(buf, &endp, 0);
++      if (endp == buf)
++              return -EINVAL;
++      sysreg_write(PCCNT, val);
++
++      return count;
++}
++
++static ssize_t show_pcenable(struct sys_device *dev, char *buf)
++{
++      unsigned long pccr;
++
++      pccr = sysreg_read(PCCR);
++      return sprintf(buf, "%c\n", (pccr & 1)?'1':'0');
++}
++static ssize_t store_pcenable(struct sys_device *dev, const char *buf,
++                            size_t count)
++{
++      unsigned long pccr, val;
++      char *endp;
++
++      val = simple_strtoul(buf, &endp, 0);
++      if (endp == buf)
++              return -EINVAL;
++      if (val)
++              val = 1;
++
++      pccr = sysreg_read(PCCR);
++      pccr = (pccr & ~1UL) | val;
++      sysreg_write(PCCR, pccr);
++
++      return count;
++}
++
++static SYSDEV_ATTR(pc0event, 0600, show_pc0event, store_pc0event);
++static SYSDEV_ATTR(pc0count, 0600, show_pc0count, store_pc0count);
++static SYSDEV_ATTR(pc1event, 0600, show_pc1event, store_pc1event);
++static SYSDEV_ATTR(pc1count, 0600, show_pc1count, store_pc1count);
++static SYSDEV_ATTR(pccycles, 0600, show_pccycles, store_pccycles);
++static SYSDEV_ATTR(pcenable, 0600, show_pcenable, store_pcenable);
++
++#endif /* CONFIG_PERFORMANCE_COUNTERS */
++
++static int __init topology_init(void)
++{
++      int cpu;
++
++      for_each_possible_cpu(cpu) {
++              struct cpu *c = &per_cpu(cpu_devices, cpu);
++
++              register_cpu(c, cpu);
++
++#ifdef CONFIG_PERFORMANCE_COUNTERS
++              sysdev_create_file(&c->sysdev, &attr_pc0event);
++              sysdev_create_file(&c->sysdev, &attr_pc0count);
++              sysdev_create_file(&c->sysdev, &attr_pc1event);
++              sysdev_create_file(&c->sysdev, &attr_pc1count);
++              sysdev_create_file(&c->sysdev, &attr_pccycles);
++              sysdev_create_file(&c->sysdev, &attr_pcenable);
++#endif
++      }
++
++      return 0;
++}
++
++subsys_initcall(topology_init);
++
++static const char *cpu_names[] = {
++      "Morgan",
++      "AP7000",
++};
++#define NR_CPU_NAMES ARRAY_SIZE(cpu_names)
++
++static const char *arch_names[] = {
++      "AVR32A",
++      "AVR32B",
++};
++#define NR_ARCH_NAMES ARRAY_SIZE(arch_names)
++
++static const char *mmu_types[] = {
++      "No MMU",
++      "ITLB and DTLB",
++      "Shared TLB",
++      "MPU"
++};
++
++void __init setup_processor(void)
++{
++      unsigned long config0, config1;
++      unsigned cpu_id, cpu_rev, arch_id, arch_rev, mmu_type;
++      unsigned tmp;
++
++      config0 = sysreg_read(CONFIG0); /* 0x0000013e; */
++      config1 = sysreg_read(CONFIG1); /* 0x01f689a2; */
++      cpu_id = config0 >> 24;
++      cpu_rev = (config0 >> 16) & 0xff;
++      arch_id = (config0 >> 13) & 0x07;
++      arch_rev = (config0 >> 10) & 0x07;
++      mmu_type = (config0 >> 7) & 0x03;
++
++      boot_cpu_data.arch_type = arch_id;
++      boot_cpu_data.cpu_type = cpu_id;
++      boot_cpu_data.arch_revision = arch_rev;
++      boot_cpu_data.cpu_revision = cpu_rev;
++      boot_cpu_data.tlb_config = mmu_type;
++
++      tmp = (config1 >> 13) & 0x07;
++      if (tmp) {
++              boot_cpu_data.icache.ways = 1 << ((config1 >> 10) & 0x07);
++              boot_cpu_data.icache.sets = 1 << ((config1 >> 16) & 0x0f);
++              boot_cpu_data.icache.linesz = 1 << (tmp + 1);
++      }
++      tmp = (config1 >> 3) & 0x07;
++      if (tmp) {
++              boot_cpu_data.dcache.ways = 1 << (config1 & 0x07);
++              boot_cpu_data.dcache.sets = 1 << ((config1 >> 6) & 0x0f);
++              boot_cpu_data.dcache.linesz = 1 << (tmp + 1);
++      }
++
++      if ((cpu_id >= NR_CPU_NAMES) || (arch_id >= NR_ARCH_NAMES)) {
++              printk ("Unknown CPU configuration (ID %02x, arch %02x), "
++                      "continuing anyway...\n",
++                      cpu_id, arch_id);
++              return;
++      }
++
++      printk ("CPU: %s [%02x] revision %d (%s revision %d)\n",
++              cpu_names[cpu_id], cpu_id, cpu_rev,
++              arch_names[arch_id], arch_rev);
++      printk ("CPU: MMU configuration: %s\n", mmu_types[mmu_type]);
++      printk ("CPU: features:");
++      if (config0 & (1 << 6))
++              printk(" fpu");
++      if (config0 & (1 << 5))
++              printk(" java");
++      if (config0 & (1 << 4))
++              printk(" perfctr");
++      if (config0 & (1 << 3))
++              printk(" ocd");
++      printk("\n");
++}
++
++#ifdef CONFIG_PROC_FS
++static int c_show(struct seq_file *m, void *v)
++{
++      unsigned int icache_size, dcache_size;
++      unsigned int cpu = smp_processor_id();
++
++      icache_size = boot_cpu_data.icache.ways *
++              boot_cpu_data.icache.sets *
++              boot_cpu_data.icache.linesz;
++      dcache_size = boot_cpu_data.dcache.ways *
++              boot_cpu_data.dcache.sets *
++              boot_cpu_data.dcache.linesz;
++
++      seq_printf(m, "processor\t: %d\n", cpu);
++
++      if (boot_cpu_data.arch_type < NR_ARCH_NAMES)
++              seq_printf(m, "cpu family\t: %s revision %d\n",
++                         arch_names[boot_cpu_data.arch_type],
++                         boot_cpu_data.arch_revision);
++      if (boot_cpu_data.cpu_type < NR_CPU_NAMES)
++              seq_printf(m, "cpu type\t: %s revision %d\n",
++                         cpu_names[boot_cpu_data.cpu_type],
++                         boot_cpu_data.cpu_revision);
++
++      seq_printf(m, "i-cache\t\t: %dK (%u ways x %u sets x %u)\n",
++                 icache_size >> 10,
++                 boot_cpu_data.icache.ways,
++                 boot_cpu_data.icache.sets,
++                 boot_cpu_data.icache.linesz);
++      seq_printf(m, "d-cache\t\t: %dK (%u ways x %u sets x %u)\n",
++                 dcache_size >> 10,
++                 boot_cpu_data.dcache.ways,
++                 boot_cpu_data.dcache.sets,
++                 boot_cpu_data.dcache.linesz);
++      seq_printf(m, "bogomips\t: %lu.%02lu\n",
++                 boot_cpu_data.loops_per_jiffy / (500000/HZ),
++                 (boot_cpu_data.loops_per_jiffy / (5000/HZ)) % 100);
++
++      return 0;
++}
++
++static void *c_start(struct seq_file *m, loff_t *pos)
++{
++      return *pos < 1 ? (void *)1 : NULL;
++}
++
++static void *c_next(struct seq_file *m, void *v, loff_t *pos)
++{
++      ++*pos;
++      return NULL;
++}
++
++static void c_stop(struct seq_file *m, void *v)
++{
++
++}
++
++struct seq_operations cpuinfo_op = {
++      .start  = c_start,
++      .next   = c_next,
++      .stop   = c_stop,
++      .show   = c_show
++};
++#endif /* CONFIG_PROC_FS */
+Index: linux-2.6.18-avr32/arch/avr32/kernel/entry-avr32b.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/entry-avr32b.S        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,678 @@
++/*
++ * 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.
++ */
++
++/*
++ * This file contains the low-level entry-points into the kernel, that is,
++ * exception handlers, debug trap handlers, interrupt handlers and the
++ * system call handler.
++ */
++#include <linux/errno.h>
++
++#include <asm/asm.h>
++#include <asm/hardirq.h>
++#include <asm/irq.h>
++#include <asm/ocd.h>
++#include <asm/page.h>
++#include <asm/pgtable.h>
++#include <asm/ptrace.h>
++#include <asm/sysreg.h>
++#include <asm/thread_info.h>
++#include <asm/unistd.h>
++
++#ifdef CONFIG_PREEMPT
++# define preempt_stop         mask_interrupts
++#else
++# define preempt_stop
++# define fault_resume_kernel  fault_restore_all
++#endif
++
++#define __MASK(x)     ((1 << (x)) - 1)
++#define IRQ_MASK      ((__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) | \
++                       (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT))
++
++      .section .ex.text,"ax",@progbits
++      .align  2
++exception_vectors:
++      bral    handle_critical
++      .align  2
++      bral    handle_critical
++      .align  2
++      bral    do_bus_error_write
++      .align  2
++      bral    do_bus_error_read
++      .align  2
++      bral    do_nmi_ll
++      .align  2
++      bral    handle_address_fault
++      .align  2
++      bral    handle_protection_fault
++      .align  2
++      bral    handle_debug
++      .align  2
++      bral    do_illegal_opcode_ll
++      .align  2
++      bral    do_illegal_opcode_ll
++      .align  2
++      bral    do_illegal_opcode_ll
++      .align  2
++      bral    do_fpe_ll
++      .align  2
++      bral    do_illegal_opcode_ll
++      .align  2
++      bral    handle_address_fault
++      .align  2
++      bral    handle_address_fault
++      .align  2
++      bral    handle_protection_fault
++      .align  2
++      bral    handle_protection_fault
++      .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
++      .global itlb_miss
++itlb_miss:
++      tlbmiss_save
++      rjmp    tlb_miss_common
++
++      .section .tlbr.ex.text,"ax",@progbits
++dtlb_miss_read:
++      tlbmiss_save
++      rjmp    tlb_miss_common
++
++      .section .tlbw.ex.text,"ax",@progbits
++dtlb_miss_write:
++      tlbmiss_save
++
++      .global tlb_miss_common
++tlb_miss_common:
++      mfsr    r0, SYSREG_PTBR
++      mfsr    r1, SYSREG_TLBEAR
++
++      /* Is it the vmalloc space? */
++      bld     r1, 31
++      brcs    handle_vmalloc_miss
++
++      /* First level lookup */
++pgtbl_lookup:
++      lsr     r2, r1, PGDIR_SHIFT
++      ld.w    r0, r0[r2 << 2]
++      bld     r0, _PAGE_BIT_PRESENT
++      brcc    page_table_not_present
++
++      /* TODO: Check access rights on page table if necessary */
++
++      /* Translate to virtual address in P1. */
++      andl    r0, 0xf000
++      sbr     r0, 31
++
++      /* Second level lookup */
++      lsl     r1, (32 - PGDIR_SHIFT)
++      lsr     r1, (32 - PGDIR_SHIFT) + PAGE_SHIFT
++      add     r2, r0, r1 << 2
++      ld.w    r1, r2[0]
++      bld     r1, _PAGE_BIT_PRESENT
++      brcc    page_not_present
++
++      /* Mark the page as accessed */
++      sbr     r1, _PAGE_BIT_ACCESSED
++      st.w    r2[0], r1
++
++      /* Drop software flags */
++      andl    r1, _PAGE_FLAGS_HARDWARE_MASK & 0xffff
++      mtsr    SYSREG_TLBELO, r1
++
++      /* Figure out which entry we want to replace */
++      mfsr    r0, SYSREG_TLBARLO
++      clz     r2, r0
++      brcc    1f
++      mov     r1, -1                  /* All entries have been accessed, */
++      mtsr    SYSREG_TLBARLO, r1      /* so reset TLBAR */
++      mov     r2, 0                   /* and start at 0 */
++1:    mfsr    r1, SYSREG_MMUCR
++      lsl     r2, 14
++      andl    r1, 0x3fff, COH
++      or      r1, r2
++      mtsr    SYSREG_MMUCR, r1
++
++      tlbw
++
++      tlbmiss_restore
++      rete
++
++handle_vmalloc_miss:
++      /* Simply do the lookup in init's page table */
++      mov     r0, lo(swapper_pg_dir)
++      orh     r0, hi(swapper_pg_dir)
++      rjmp    pgtbl_lookup
++
++
++      /* ---                    System Call                    --- */
++
++      .section .scall.text,"ax",@progbits
++system_call:
++      pushm   r12             /* r12_orig */
++      stmts   --sp, r0-lr
++      zero_fp
++      mfsr    r0, SYSREG_RAR_SUP
++      mfsr    r1, SYSREG_RSR_SUP
++      stm     --sp, r0-r1
++
++      /* check for syscall tracing */
++      get_thread_info r0
++      ld.w    r1, r0[TI_flags]
++      bld     r1, TIF_SYSCALL_TRACE
++      brcs    syscall_trace_enter
++
++syscall_trace_cont:
++      cp.w    r8, NR_syscalls
++      brhs    syscall_badsys
++
++      lddpc   lr, syscall_table_addr
++      ld.w    lr, lr[r8 << 2]
++      mov     r8, r5          /* 5th argument (6th is pushed by stub) */
++      icall   lr
++
++      .global syscall_return
++syscall_return:
++      get_thread_info r0
++      mask_interrupts         /* make sure we don't miss an interrupt
++                                 setting need_resched or sigpending
++                                 between sampling and the rets */
++
++      /* Store the return value so that the correct value is loaded below */
++      stdsp   sp[REG_R12], r12
++
++      ld.w    r1, r0[TI_flags]
++      andl    r1, _TIF_ALLWORK_MASK, COH
++      brne    syscall_exit_work
++
++syscall_exit_cont:
++      popm    r8-r9
++      mtsr    SYSREG_RAR_SUP, r8
++      mtsr    SYSREG_RSR_SUP, r9
++      ldmts   sp++, r0-lr
++      sub     sp, -4          /* r12_orig */
++      rets
++
++      .align  2
++syscall_table_addr:
++      .long   sys_call_table
++
++syscall_badsys:
++      mov     r12, -ENOSYS
++      rjmp    syscall_return
++
++      .global ret_from_fork
++ret_from_fork:
++      rcall   schedule_tail
++
++      /* check for syscall tracing */
++      get_thread_info r0
++      ld.w    r1, r0[TI_flags]
++      andl    r1, _TIF_ALLWORK_MASK, COH
++      brne    syscall_exit_work
++      rjmp    syscall_exit_cont
++
++syscall_trace_enter:
++      pushm   r8-r12
++      rcall   syscall_trace
++      popm    r8-r12
++      rjmp    syscall_trace_cont
++
++syscall_exit_work:
++      bld     r1, TIF_SYSCALL_TRACE
++      brcc    1f
++      unmask_interrupts
++      rcall   syscall_trace
++      mask_interrupts
++      ld.w    r1, r0[TI_flags]
++
++1:    bld     r1, TIF_NEED_RESCHED
++      brcc    2f
++      unmask_interrupts
++      rcall   schedule
++      mask_interrupts
++      ld.w    r1, r0[TI_flags]
++      rjmp    1b
++
++2:    mov     r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
++      tst     r1, r2
++      breq    3f
++      unmask_interrupts
++      mov     r12, sp
++      mov     r11, r0
++      rcall   do_notify_resume
++      mask_interrupts
++      ld.w    r1, r0[TI_flags]
++      rjmp    1b
++
++3:    bld     r1, TIF_BREAKPOINT
++      brcc    syscall_exit_cont
++      mfsr    r3, SYSREG_TLBEHI
++      lddsp   r2, sp[REG_PC]
++      andl    r3, 0xff, COH
++      lsl     r3, 1
++      sbr     r3, 30
++      sbr     r3, 0
++      mtdr    DBGREG_BWA2A, r2
++      mtdr    DBGREG_BWC2A, r3
++      rjmp    syscall_exit_cont
++
++
++      /* 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 */
++save_full_context_ex:
++      mfsr    r8, SYSREG_RSR_EX
++      mov     r12, r8
++      andh    r8, (MODE_MASK >> 16), COH
++      mfsr    r11, SYSREG_RAR_EX
++      brne    2f
++
++1:    pushm   r11, r12        /* PC and SR */
++      unmask_exceptions
++      ret     r12
++
++2:    sub     r10, sp, -(FRAME_SIZE_FULL - REG_LR)
++      stdsp   sp[4], r10      /* replace saved SP */
++      rjmp    1b
++
++      /* Low-level exception handlers */
++handle_critical:
++      pushm   r12
++      pushm   r0-r12
++      rcall   save_full_context_ex
++      mfsr    r12, SYSREG_ECR
++      mov     r11, sp
++      rcall   do_critical_exception
++
++      /* We should never get here... */
++bad_return:
++      sub     r12, pc, (. - 1f)
++      bral    panic
++      .align  2
++1:    .asciz  "Return from critical exception!"
++
++      .align  1
++do_bus_error_write:
++      sub     sp, 4
++      stmts   --sp, r0-lr
++      rcall   save_full_context_ex
++      mov     r11, 1
++      rjmp    1f
++
++do_bus_error_read:
++      sub     sp, 4
++      stmts   --sp, r0-lr
++      rcall   save_full_context_ex
++      mov     r11, 0
++1:    mfsr    r12, SYSREG_BEAR
++      mov     r10, sp
++      rcall   do_bus_error
++      rjmp    ret_from_exception
++
++      .align  1
++do_nmi_ll:
++      sub     sp, 4
++      stmts   --sp, r0-lr
++      /* FIXME: Make sure RAR_NMI and RSR_NMI are pushed instead of *_EX */
++      rcall   save_full_context_ex
++      mfsr    r12, SYSREG_ECR
++      mov     r11, sp
++      rcall   do_nmi
++      rjmp    bad_return
++
++handle_address_fault:
++      sub     sp, 4
++      stmts   --sp, r0-lr
++      rcall   save_full_context_ex
++      mfsr    r12, SYSREG_ECR
++      mov     r11, sp
++      rcall   do_address_exception
++      rjmp    ret_from_exception
++
++handle_protection_fault:
++      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  1
++do_illegal_opcode_ll:
++      sub     sp, 4
++      stmts   --sp, r0-lr
++      rcall   save_full_context_ex
++      mfsr    r12, SYSREG_ECR
++      mov     r11, sp
++      rcall   do_illegal_opcode
++      rjmp    ret_from_exception
++
++do_dtlb_modified:
++      pushm   r0-r3
++      mfsr    r1, SYSREG_TLBEAR
++      mfsr    r0, SYSREG_PTBR
++      lsr     r2, r1, PGDIR_SHIFT
++      ld.w    r0, r0[r2 << 2]
++      lsl     r1, (32 - PGDIR_SHIFT)
++      lsr     r1, (32 - PGDIR_SHIFT) + PAGE_SHIFT
++
++      /* Translate to virtual address in P1 */
++      andl    r0, 0xf000
++      sbr     r0, 31
++      add     r2, r0, r1 << 2
++      ld.w    r3, r2[0]
++      sbr     r3, _PAGE_BIT_DIRTY
++      mov     r0, r3
++      st.w    r2[0], r3
++
++      /* The page table is up-to-date. Update the TLB entry as well */
++      andl    r0, lo(_PAGE_FLAGS_HARDWARE_MASK)
++      mtsr    SYSREG_TLBELO, r0
++
++      /* MMUCR[DRP] is updated automatically, so let's go... */
++      tlbw
++
++      popm    r0-r3
++      rete
++
++do_fpe_ll:
++      sub     sp, 4
++      stmts   --sp, r0-lr
++      rcall   save_full_context_ex
++      unmask_interrupts
++      mov     r12, 26
++      mov     r11, sp
++      rcall   do_fpe
++      rjmp    ret_from_exception
++
++ret_from_exception:
++      mask_interrupts
++      lddsp   r4, sp[REG_SR]
++      andh    r4, (MODE_MASK >> 16), COH
++      brne    fault_resume_kernel
++
++      get_thread_info r0
++      ld.w    r1, r0[TI_flags]
++      andl    r1, _TIF_WORK_MASK, COH
++      brne    fault_exit_work
++
++fault_resume_user:
++      popm    r8-r9
++      mask_exceptions
++      mtsr    SYSREG_RAR_EX, r8
++      mtsr    SYSREG_RSR_EX, r9
++      ldmts   sp++, r0-lr
++      sub     sp, -4
++      rete
++
++fault_resume_kernel:
++#ifdef CONFIG_PREEMPT
++      get_thread_info r0
++      ld.w    r2, r0[TI_preempt_count]
++      cp.w    r2, 0
++      brne    1f
++      ld.w    r1, r0[TI_flags]
++      bld     r1, TIF_NEED_RESCHED
++      brcc    1f
++      lddsp   r4, sp[REG_SR]
++      bld     r4, SYSREG_GM_OFFSET
++      brcs    1f
++      rcall   preempt_schedule_irq
++1:
++#endif
++
++      popm    r8-r9
++      mask_exceptions
++      mfsr    r1, SYSREG_SR
++      mtsr    SYSREG_RAR_EX, r8
++      mtsr    SYSREG_RSR_EX, r9
++      popm    lr
++      sub     sp, -4          /* ignore SP */
++      popm    r0-r12
++      sub     sp, -4          /* ignore r12_orig */
++      rete
++
++irq_exit_work:
++      /* Switch to exception mode so that we can share the same code. */
++      mfsr    r8, SYSREG_SR
++      cbr     r8, SYSREG_M0_OFFSET
++      orh     r8, hi(SYSREG_BIT(M1) | SYSREG_BIT(M2))
++      mtsr    SYSREG_SR, r8
++      sub     pc, -2
++      get_thread_info r0
++      ld.w    r1, r0[TI_flags]
++
++fault_exit_work:
++      bld     r1, TIF_NEED_RESCHED
++      brcc    1f
++      unmask_interrupts
++      rcall   schedule
++      mask_interrupts
++      ld.w    r1, r0[TI_flags]
++      rjmp    fault_exit_work
++
++1:    mov     r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
++      tst     r1, r2
++      breq    2f
++      unmask_interrupts
++      mov     r12, sp
++      mov     r11, r0
++      rcall   do_notify_resume
++      mask_interrupts
++      ld.w    r1, r0[TI_flags]
++      rjmp    fault_exit_work
++
++2:    bld     r1, TIF_BREAKPOINT
++      brcc    fault_resume_user
++      mfsr    r3, SYSREG_TLBEHI
++      lddsp   r2, sp[REG_PC]
++      andl    r3, 0xff, COH
++      lsl     r3, 1
++      sbr     r3, 30
++      sbr     r3, 0
++      mtdr    DBGREG_BWA2A, r2
++      mtdr    DBGREG_BWC2A, r3
++      rjmp    fault_resume_user
++
++      /* If we get a debug trap from privileged context we end up here */
++handle_debug_priv:
++      /* Fix up LR and SP in regs. r11 contains the mode we came from */
++      mfsr    r8, SYSREG_SR
++      mov     r9, r8
++      andh    r8, hi(~MODE_MASK)
++      or      r8, r11
++      mtsr    SYSREG_SR, r8
++      sub     pc, -2
++      stdsp   sp[REG_LR], lr
++      mtsr    SYSREG_SR, r9
++      sub     pc, -2
++      sub     r10, sp, -FRAME_SIZE_FULL
++      stdsp   sp[REG_SP], r10
++      mov     r12, sp
++      rcall   do_debug_priv
++
++      /* Now, put everything back */
++      ssrf    SR_EM_BIT
++      popm    r10, r11
++      mtsr    SYSREG_RAR_DBG, r10
++      mtsr    SYSREG_RSR_DBG, r11
++      mfsr    r8, SYSREG_SR
++      mov     r9, r8
++      andh    r8, hi(~MODE_MASK)
++      andh    r11, hi(MODE_MASK)
++      or      r8, r11
++      mtsr    SYSREG_SR, r8
++      sub     pc, -2
++      popm    lr
++      mtsr    SYSREG_SR, r9
++      sub     pc, -2
++      sub     sp, -4          /* skip SP */
++      popm    r0-r12
++      sub     sp, -4
++      retd
++
++      /*
++       * At this point, everything is masked, that is, interrupts,
++       * exceptions and debugging traps. We might get called from
++       * interrupt or exception context in some rare cases, but this
++       * will be taken care of by do_debug(), so we're not going to
++       * do a 100% correct context save here.
++       */
++handle_debug:
++      sub     sp, 4           /* r12_orig */
++      stmts   --sp, r0-lr
++      mfsr    r10, SYSREG_RAR_DBG
++      mfsr    r11, SYSREG_RSR_DBG
++      unmask_exceptions
++      pushm   r10,r11
++      andh    r11, (MODE_MASK >> 16), COH
++      brne    handle_debug_priv
++
++      mov     r12, sp
++      rcall   do_debug
++
++      lddsp   r10, sp[REG_SR]
++      andh    r10, (MODE_MASK >> 16), COH
++      breq    debug_resume_user
++
++debug_restore_all:
++      popm    r10,r11
++      mask_exceptions
++      mtsr    SYSREG_RSR_DBG, r11
++      mtsr    SYSREG_RAR_DBG, r10
++      ldmts   sp++, r0-lr
++      sub     sp, -4
++      retd
++
++debug_resume_user:
++      get_thread_info r0
++      mask_interrupts
++
++      ld.w    r1, r0[TI_flags]
++      andl    r1, _TIF_DBGWORK_MASK, COH
++      breq    debug_restore_all
++
++1:    bld     r1, TIF_NEED_RESCHED
++      brcc    2f
++      unmask_interrupts
++      rcall   schedule
++      mask_interrupts
++      ld.w    r1, r0[TI_flags]
++      rjmp    1b
++
++2:    mov     r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK
++      tst     r1, r2
++      breq    3f
++      unmask_interrupts
++      mov     r12, sp
++      mov     r11, r0
++      rcall   do_notify_resume
++      mask_interrupts
++      ld.w    r1, r0[TI_flags]
++      rjmp    1b
++
++3:    bld     r1, TIF_SINGLE_STEP
++      brcc    debug_restore_all
++      mfdr    r2, DBGREG_DC
++      sbr     r2, DC_SS_BIT
++      mtdr    DBGREG_DC, r2
++      rjmp    debug_restore_all
++
++      .set    rsr_int0,       SYSREG_RSR_INT0
++      .set    rsr_int1,       SYSREG_RSR_INT1
++      .set    rsr_int2,       SYSREG_RSR_INT2
++      .set    rsr_int3,       SYSREG_RSR_INT3
++      .set    rar_int0,       SYSREG_RAR_INT0
++      .set    rar_int1,       SYSREG_RAR_INT1
++      .set    rar_int2,       SYSREG_RAR_INT2
++      .set    rar_int3,       SYSREG_RAR_INT3
++
++      .macro  IRQ_LEVEL level
++      .type   irq_level\level, @function
++irq_level\level:
++      sub     sp, 4           /* r12_orig */
++      stmts   --sp,r0-lr
++      mfsr    r8, rar_int\level
++      mfsr    r9, rsr_int\level
++      pushm   r8-r9
++
++      mov     r11, sp
++      mov     r12, \level
++
++      rcall   do_IRQ
++
++      lddsp   r4, sp[REG_SR]
++      andh    r4, (MODE_MASK >> 16), COH
++#ifdef CONFIG_PREEMPT
++      brne    2f
++#else
++      brne    1f
++#endif
++
++      get_thread_info r0
++      ld.w    r1, r0[TI_flags]
++      andl    r1, _TIF_WORK_MASK, COH
++      brne    irq_exit_work
++
++1:    popm    r8-r9
++      mtsr    rar_int\level, r8
++      mtsr    rsr_int\level, r9
++      ldmts   sp++,r0-lr
++      sub     sp, -4          /* ignore r12_orig */
++      rete
++
++#ifdef CONFIG_PREEMPT
++2:
++      get_thread_info r0
++      ld.w    r2, r0[TI_preempt_count]
++      cp.w    r2, 0
++      brne    1b
++      ld.w    r1, r0[TI_flags]
++      bld     r1, TIF_NEED_RESCHED
++      brcc    1b
++      lddsp   r4, sp[REG_SR]
++      bld     r4, SYSREG_GM_OFFSET
++      brcs    1b
++      rcall   preempt_schedule_irq
++      rjmp    1b
++#endif
++      .endm
++
++      .section .irq.text,"ax",@progbits
++
++      .global irq_level0
++      .global irq_level1
++      .global irq_level2
++      .global irq_level3
++      IRQ_LEVEL 0
++      IRQ_LEVEL 1
++      IRQ_LEVEL 2
++      IRQ_LEVEL 3
+Index: linux-2.6.18-avr32/arch/avr32/kernel/head.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/head.S        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,42 @@
++/*
++ * Non-board-specific low-level startup code
++ *
++ * 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/linkage.h>
++
++#include <asm/page.h>
++#include <asm/thread_info.h>
++#include <asm/sysreg.h>
++
++      .section .init.text,"ax"
++      .global kernel_entry
++kernel_entry:
++      /* Initialize status register */
++      lddpc   r0, init_sr
++      mtsr    SYSREG_SR, r0
++
++      /* Set initial stack pointer */
++      lddpc   sp, stack_addr
++      sub     sp, -THREAD_SIZE
++
++#ifdef CONFIG_FRAME_POINTER
++      /* Mark last stack frame */
++      mov     lr, 0
++      mov     r7, 0
++#endif
++
++      /* Start the show */
++      lddpc   pc, kernel_start_addr
++
++      .align  2
++init_sr:
++      .long   0x007f0000      /* Supervisor mode, everything masked */
++stack_addr:
++      .long   init_thread_union
++kernel_start_addr:
++      .long   start_kernel
+Index: linux-2.6.18-avr32/arch/avr32/kernel/init_task.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/init_task.c   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,38 @@
++/*
++ * 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/module.h>
++#include <linux/fs.h>
++#include <linux/sched.h>
++#include <linux/init_task.h>
++#include <linux/mqueue.h>
++
++#include <asm/pgtable.h>
++
++static struct fs_struct init_fs = INIT_FS;
++static struct files_struct init_files = INIT_FILES;
++static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
++static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
++struct mm_struct init_mm = INIT_MM(init_mm);
++
++EXPORT_SYMBOL(init_mm);
++
++/*
++ * Initial thread structure. Must be aligned on an 8192-byte boundary.
++ */
++union thread_union init_thread_union
++      __attribute__((__section__(".data.init_task"))) =
++              { INIT_THREAD_INFO(init_task) };
++
++/*
++ * Initial task structure.
++ *
++ * All other task structs will be allocated on slabs in fork.c
++ */
++struct task_struct init_task = INIT_TASK(init_task);
++
++EXPORT_SYMBOL(init_task);
+Index: linux-2.6.18-avr32/arch/avr32/kernel/irq.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/irq.c 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,71 @@
++/*
++ * Copyright (C) 2004-2006 Atmel Corporation
++ *
++ * Based on arch/i386/kernel/irq.c
++ *   Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
++ *
++ * 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.
++ *
++ * This file contains the code used by various IRQ handling routines:
++ * asking for different IRQ's should be done through these routines
++ * instead of just grabbing them. Thus setups with different IRQ numbers
++ * shouldn't result in any weird surprises, and installing new handlers
++ * should be easier.
++ *
++ * IRQ's are in fact implemented a bit like signal handlers for the kernel.
++ * Naturally it's not a 1:1 relation, but there are similarities.
++ */
++
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/kernel_stat.h>
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
++#include <linux/sysdev.h>
++
++/*
++ * 'what should we do if we get a hw irq event on an illegal vector'.
++ * each architecture has to answer this themselves.
++ */
++void ack_bad_irq(unsigned int irq)
++{
++      printk("unexpected IRQ %u\n", irq);
++}
++
++#ifdef CONFIG_PROC_FS
++int show_interrupts(struct seq_file *p, void *v)
++{
++      int i = *(loff_t *)v, cpu;
++      struct irqaction *action;
++      unsigned long flags;
++
++      if (i == 0) {
++              seq_puts(p, "           ");
++              for_each_online_cpu(cpu)
++                      seq_printf(p, "CPU%d       ", cpu);
++              seq_putc(p, '\n');
++      }
++
++      if (i < NR_IRQS) {
++              spin_lock_irqsave(&irq_desc[i].lock, flags);
++              action = irq_desc[i].action;
++              if (!action)
++                      goto unlock;
++
++              seq_printf(p, "%3d: ", i);
++              for_each_online_cpu(cpu)
++                      seq_printf(p, "%10u ", kstat_cpu(cpu).irqs[i]);
++              seq_printf(p, "  %s", action->name);
++              for (action = action->next; action; action = action->next)
++                      seq_printf(p, ", %s", action->name);
++
++              seq_putc(p, '\n');
++      unlock:
++              spin_unlock_irqrestore(&irq_desc[i].lock, flags);
++      }
++
++      return 0;
++}
++#endif
+Index: linux-2.6.18-avr32/arch/avr32/kernel/kprobes.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/kprobes.c     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,270 @@
++/*
++ *  Kernel Probes (KProbes)
++ *
++ * Copyright (C) 2005-2006 Atmel Corporation
++ *
++ * Based on arch/ppc64/kernel/kprobes.c
++ *  Copyright (C) IBM Corporation, 2002, 2004
++ *
++ * 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/kprobes.h>
++#include <linux/ptrace.h>
++
++#include <asm/cacheflush.h>
++#include <asm/kdebug.h>
++#include <asm/ocd.h>
++
++DEFINE_PER_CPU(struct kprobe *, current_kprobe);
++static unsigned long kprobe_status;
++static struct pt_regs jprobe_saved_regs;
++
++int __kprobes arch_prepare_kprobe(struct kprobe *p)
++{
++      int ret = 0;
++
++      if ((unsigned long)p->addr & 0x01) {
++              printk("Attempt to register kprobe at an unaligned address\n");
++              ret = -EINVAL;
++      }
++
++      /* XXX: Might be a good idea to check if p->addr is a valid
++       * kernel address as well... */
++
++      if (!ret) {
++              pr_debug("copy kprobe at %p\n", p->addr);
++              memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
++              p->opcode = *p->addr;
++      }
++
++      return ret;
++}
++
++void __kprobes arch_arm_kprobe(struct kprobe *p)
++{
++      pr_debug("arming kprobe at %p\n", p->addr);
++      *p->addr = BREAKPOINT_INSTRUCTION;
++      flush_icache_range((unsigned long)p->addr,
++                         (unsigned long)p->addr + sizeof(kprobe_opcode_t));
++}
++
++void __kprobes arch_disarm_kprobe(struct kprobe *p)
++{
++      pr_debug("disarming kprobe at %p\n", p->addr);
++      *p->addr = p->opcode;
++      flush_icache_range((unsigned long)p->addr,
++                         (unsigned long)p->addr + sizeof(kprobe_opcode_t));
++}
++
++static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
++{
++      unsigned long dc;
++
++      pr_debug("preparing to singlestep over %p (PC=%08lx)\n",
++               p->addr, regs->pc);
++
++      BUG_ON(!(sysreg_read(SR) & SYSREG_BIT(SR_D)));
++
++      dc = __mfdr(DBGREG_DC);
++      dc |= DC_SS;
++      __mtdr(DBGREG_DC, dc);
++
++      /*
++       * We must run the instruction from its original location
++       * since it may actually reference PC.
++       *
++       * TODO: Do the instruction replacement directly in icache.
++       */
++      *p->addr = p->opcode;
++      flush_icache_range((unsigned long)p->addr,
++                         (unsigned long)p->addr + sizeof(kprobe_opcode_t));
++}
++
++static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
++{
++      unsigned long dc;
++
++      pr_debug("resuming execution at PC=%08lx\n", regs->pc);
++
++      dc = __mfdr(DBGREG_DC);
++      dc &= ~DC_SS;
++      __mtdr(DBGREG_DC, dc);
++
++      *p->addr = BREAKPOINT_INSTRUCTION;
++      flush_icache_range((unsigned long)p->addr,
++                         (unsigned long)p->addr + sizeof(kprobe_opcode_t));
++}
++
++static void __kprobes set_current_kprobe(struct kprobe *p)
++{
++      __get_cpu_var(current_kprobe) = p;
++}
++
++static int __kprobes kprobe_handler(struct pt_regs *regs)
++{
++      struct kprobe *p;
++      void *addr = (void *)regs->pc;
++      int ret = 0;
++
++      pr_debug("kprobe_handler: kprobe_running=%p\n",
++               kprobe_running());
++
++      /*
++       * We don't want to be preempted for the entire
++       * duration of kprobe processing
++       */
++      preempt_disable();
++
++      /* Check that we're not recursing */
++      if (kprobe_running()) {
++              p = get_kprobe(addr);
++              if (p) {
++                      if (kprobe_status == KPROBE_HIT_SS) {
++                              printk("FIXME: kprobe hit while single-stepping!\n");
++                              goto no_kprobe;
++                      }
++
++                      printk("FIXME: kprobe hit while handling another kprobe\n");
++                      goto no_kprobe;
++              } else {
++                      p = kprobe_running();
++                      if (p->break_handler && p->break_handler(p, regs))
++                              goto ss_probe;
++              }
++              /* If it's not ours, can't be delete race, (we hold lock). */
++              goto no_kprobe;
++      }
++
++      p = get_kprobe(addr);
++      if (!p)
++              goto no_kprobe;
++
++      kprobe_status = KPROBE_HIT_ACTIVE;
++      set_current_kprobe(p);
++      if (p->pre_handler && p->pre_handler(p, regs))
++              /* handler has already set things up, so skip ss setup */
++              return 1;
++
++ss_probe:
++      prepare_singlestep(p, regs);
++      kprobe_status = KPROBE_HIT_SS;
++      return 1;
++
++no_kprobe:
++      return ret;
++}
++
++static int __kprobes post_kprobe_handler(struct pt_regs *regs)
++{
++      struct kprobe *cur = kprobe_running();
++
++      pr_debug("post_kprobe_handler, cur=%p\n", cur);
++
++      if (!cur)
++              return 0;
++
++      if (cur->post_handler) {
++              kprobe_status = KPROBE_HIT_SSDONE;
++              cur->post_handler(cur, regs, 0);
++      }
++
++      resume_execution(cur, regs);
++      reset_current_kprobe();
++      preempt_enable_no_resched();
++
++      return 1;
++}
++
++static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
++{
++      struct kprobe *cur = kprobe_running();
++
++      pr_debug("kprobe_fault_handler: trapnr=%d\n", trapnr);
++
++      if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
++              return 1;
++
++      if (kprobe_status & KPROBE_HIT_SS) {
++              resume_execution(cur, regs);
++              preempt_enable_no_resched();
++      }
++      return 0;
++}
++
++/*
++ * Wrapper routine to for handling exceptions.
++ */
++int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
++                                     unsigned long val, void *data)
++{
++      struct die_args *args = (struct die_args *)data;
++      int ret = NOTIFY_DONE;
++
++      pr_debug("kprobe_exceptions_notify: val=%lu, data=%p\n",
++               val, data);
++
++      switch (val) {
++      case DIE_BREAKPOINT:
++              if (kprobe_handler(args->regs))
++                      ret = NOTIFY_STOP;
++              break;
++      case DIE_SSTEP:
++              if (post_kprobe_handler(args->regs))
++                      ret = NOTIFY_STOP;
++              break;
++      case DIE_FAULT:
++              if (kprobe_running()
++                  && kprobe_fault_handler(args->regs, args->trapnr))
++                      ret = NOTIFY_STOP;
++              break;
++      default:
++              break;
++      }
++
++      return ret;
++}
++
++int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
++{
++      struct jprobe *jp = container_of(p, struct jprobe, kp);
++
++      memcpy(&jprobe_saved_regs, regs, sizeof(struct pt_regs));
++
++      /*
++       * TODO: We should probably save some of the stack here as
++       * well, since gcc may pass arguments on the stack for certain
++       * functions (lots of arguments, large aggregates, varargs)
++       */
++
++      /* setup return addr to the jprobe handler routine */
++      regs->pc = (unsigned long)jp->entry;
++      return 1;
++}
++
++void __kprobes jprobe_return(void)
++{
++      asm volatile("breakpoint" ::: "memory");
++}
++
++int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
++{
++      /*
++       * FIXME - we should ideally be validating that we got here 'cos
++       * of the "trap" in jprobe_return() above, before restoring the
++       * saved regs...
++       */
++      memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs));
++      return 1;
++}
++
++int __init arch_init_kprobes(void)
++{
++      printk("KPROBES: Enabling monitor mode (MM|DBE)...\n");
++      __mtdr(DBGREG_DC, DC_MM | DC_DBE);
++
++      /* TODO: Register kretprobe trampoline */
++      return 0;
++}
+Index: linux-2.6.18-avr32/arch/avr32/kernel/module.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/module.c      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,324 @@
++/*
++ * AVR32-specific kernel module loader
++ *
++ * Copyright (C) 2005-2006 Atmel Corporation
++ *
++ * GOT initialization parts are based on the s390 version
++ *   Copyright (C) 2002, 2003 IBM Deutschland Entwicklung GmbH,
++ *                            IBM 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/moduleloader.h>
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/elf.h>
++#include <linux/vmalloc.h>
++
++void *module_alloc(unsigned long size)
++{
++      if (size == 0)
++              return NULL;
++      return vmalloc(size);
++}
++
++void module_free(struct module *mod, void *module_region)
++{
++      vfree(mod->arch.syminfo);
++      mod->arch.syminfo = NULL;
++
++      vfree(module_region);
++      /* FIXME: if module_region == mod->init_region, trim exception
++       * table entries. */
++}
++
++static inline int check_rela(Elf32_Rela *rela, struct module *module,
++                           char *strings, Elf32_Sym *symbols)
++{
++      struct mod_arch_syminfo *info;
++
++      info = module->arch.syminfo + ELF32_R_SYM(rela->r_info);
++      switch (ELF32_R_TYPE(rela->r_info)) {
++      case R_AVR32_GOT32:
++      case R_AVR32_GOT16:
++      case R_AVR32_GOT8:
++      case R_AVR32_GOT21S:
++      case R_AVR32_GOT18SW:   /* mcall */
++      case R_AVR32_GOT16S:    /* ld.w */
++              if (rela->r_addend != 0) {
++                      printk(KERN_ERR
++                             "GOT relocation against %s at offset %u with addend\n",
++                             strings + symbols[ELF32_R_SYM(rela->r_info)].st_name,
++                             rela->r_offset);
++                      return -ENOEXEC;
++              }
++              if (info->got_offset == -1UL) {
++                      info->got_offset = module->arch.got_size;
++                      module->arch.got_size += sizeof(void *);
++              }
++              pr_debug("GOT[%3lu] %s\n", info->got_offset,
++                       strings + symbols[ELF32_R_SYM(rela->r_info)].st_name);
++              break;
++      }
++
++      return 0;
++}
++
++int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
++                            char *secstrings, struct module *module)
++{
++      Elf32_Shdr *symtab;
++      Elf32_Sym *symbols;
++      Elf32_Rela *rela;
++      char *strings;
++      int nrela, i, j;
++      int ret;
++
++      /* Find the symbol table */
++      symtab = NULL;
++      for (i = 0; i < hdr->e_shnum; i++)
++              switch (sechdrs[i].sh_type) {
++              case SHT_SYMTAB:
++                      symtab = &sechdrs[i];
++                      break;
++              }
++      if (!symtab) {
++              printk(KERN_ERR "module %s: no symbol table\n", module->name);
++              return -ENOEXEC;
++      }
++
++      /* Allocate room for one syminfo structure per symbol. */
++      module->arch.nsyms = symtab->sh_size / sizeof(Elf_Sym);
++      module->arch.syminfo = vmalloc(module->arch.nsyms
++                                 * sizeof(struct mod_arch_syminfo));
++      if (!module->arch.syminfo)
++              return -ENOMEM;
++
++      symbols = (void *)hdr + symtab->sh_offset;
++      strings = (void *)hdr + sechdrs[symtab->sh_link].sh_offset;
++      for (i = 0; i < module->arch.nsyms; i++) {
++              if (symbols[i].st_shndx == SHN_UNDEF &&
++                  strcmp(strings + symbols[i].st_name,
++                         "_GLOBAL_OFFSET_TABLE_") == 0)
++                      /* "Define" it as absolute. */
++                      symbols[i].st_shndx = SHN_ABS;
++              module->arch.syminfo[i].got_offset = -1UL;
++              module->arch.syminfo[i].got_initialized = 0;
++      }
++
++      /* Allocate GOT entries for symbols that need it. */
++      module->arch.got_size = 0;
++      for (i = 0; i < hdr->e_shnum; i++) {
++              if (sechdrs[i].sh_type != SHT_RELA)
++                      continue;
++              nrela = sechdrs[i].sh_size / sizeof(Elf32_Rela);
++              rela = (void *)hdr + sechdrs[i].sh_offset;
++              for (j = 0; j < nrela; j++) {
++                      ret = check_rela(rela + j, module,
++                                       strings, symbols);
++                      if (ret)
++                              goto out_free_syminfo;
++              }
++      }
++
++      /*
++       * Increase core size to make room for GOT and set start
++       * offset for GOT.
++       */
++      module->core_size = ALIGN(module->core_size, 4);
++      module->arch.got_offset = module->core_size;
++      module->core_size += module->arch.got_size;
++
++      return 0;
++
++out_free_syminfo:
++      vfree(module->arch.syminfo);
++      module->arch.syminfo = NULL;
++
++      return ret;
++}
++
++static inline int reloc_overflow(struct module *module, const char *reloc_name,
++                               Elf32_Addr relocation)
++{
++      printk(KERN_ERR "module %s: Value %lx does not fit relocation %s\n",
++             module->name, (unsigned long)relocation, reloc_name);
++      return -ENOEXEC;
++}
++
++#define get_u16(loc)          (*((uint16_t *)loc))
++#define put_u16(loc, val)     (*((uint16_t *)loc) = (val))
++
++int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
++                     unsigned int symindex, unsigned int relindex,
++                     struct module *module)
++{
++      Elf32_Shdr *symsec = sechdrs + symindex;
++      Elf32_Shdr *relsec = sechdrs + relindex;
++      Elf32_Shdr *dstsec = sechdrs + relsec->sh_info;
++      Elf32_Rela *rel = (void *)relsec->sh_addr;
++      unsigned int i;
++      int ret = 0;
++
++      for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rela); i++, rel++) {
++              struct mod_arch_syminfo *info;
++              Elf32_Sym *sym;
++              Elf32_Addr relocation;
++              uint32_t *location;
++              uint32_t value;
++
++              location = (void *)dstsec->sh_addr + rel->r_offset;
++              sym = (Elf32_Sym *)symsec->sh_addr + ELF32_R_SYM(rel->r_info);
++              relocation = sym->st_value + rel->r_addend;
++
++              info = module->arch.syminfo + ELF32_R_SYM(rel->r_info);
++
++              /* Initialize GOT entry if necessary */
++              switch (ELF32_R_TYPE(rel->r_info)) {
++              case R_AVR32_GOT32:
++              case R_AVR32_GOT16:
++              case R_AVR32_GOT8:
++              case R_AVR32_GOT21S:
++              case R_AVR32_GOT18SW:
++              case R_AVR32_GOT16S:
++                      if (!info->got_initialized) {
++                              Elf32_Addr *gotent;
++
++                              gotent = (module->module_core
++                                        + module->arch.got_offset
++                                        + info->got_offset);
++                              *gotent = relocation;
++                              info->got_initialized = 1;
++                      }
++
++                      relocation = info->got_offset;
++                      break;
++              }
++
++              switch (ELF32_R_TYPE(rel->r_info)) {
++              case R_AVR32_32:
++              case R_AVR32_32_CPENT:
++                      *location = relocation;
++                      break;
++              case R_AVR32_22H_PCREL:
++                      relocation -= (Elf32_Addr)location;
++                      if ((relocation & 0xffe00001) != 0
++                          && (relocation & 0xffc00001) != 0xffc00000)
++                              return reloc_overflow(module,
++                                                    "R_AVR32_22H_PCREL",
++                                                    relocation);
++                      relocation >>= 1;
++
++                      value = *location;
++                      value = ((value & 0xe1ef0000)
++                               | (relocation & 0xffff)
++                               | ((relocation & 0x10000) << 4)
++                               | ((relocation & 0x1e0000) << 8));
++                      *location = value;
++                      break;
++              case R_AVR32_11H_PCREL:
++                      relocation -= (Elf32_Addr)location;
++                      if ((relocation & 0xfffffc01) != 0
++                          && (relocation & 0xfffff801) != 0xfffff800)
++                              return reloc_overflow(module,
++                                                    "R_AVR32_11H_PCREL",
++                                                    relocation);
++                      value = get_u16(location);
++                      value = ((value & 0xf00c)
++                               | ((relocation & 0x1fe) << 3)
++                               | ((relocation & 0x600) >> 9));
++                      put_u16(location, value);
++                      break;
++              case R_AVR32_9H_PCREL:
++                      relocation -= (Elf32_Addr)location;
++                      if ((relocation & 0xffffff01) != 0
++                          && (relocation & 0xfffffe01) != 0xfffffe00)
++                              return reloc_overflow(module,
++                                                    "R_AVR32_9H_PCREL",
++                                                    relocation);
++                      value = get_u16(location);
++                      value = ((value & 0xf00f)
++                               | ((relocation & 0x1fe) << 3));
++                      put_u16(location, value);
++                      break;
++              case R_AVR32_9UW_PCREL:
++                      relocation -= ((Elf32_Addr)location) & 0xfffffffc;
++                      if ((relocation & 0xfffffc03) != 0)
++                              return reloc_overflow(module,
++                                                    "R_AVR32_9UW_PCREL",
++                                                    relocation);
++                      value = get_u16(location);
++                      value = ((value & 0xf80f)
++                               | ((relocation & 0x1fc) << 2));
++                      put_u16(location, value);
++                      break;
++              case R_AVR32_GOTPC:
++                      /*
++                       * R6 = PC - (PC - GOT)
++                       *
++                       * At this point, relocation contains the
++                       * value of PC.  Just subtract the value of
++                       * GOT, and we're done.
++                       */
++                      pr_debug("GOTPC: PC=0x%x, got_offset=0x%lx, core=0x%p\n",
++                               relocation, module->arch.got_offset,
++                               module->module_core);
++                      relocation -= ((unsigned long)module->module_core
++                                     + module->arch.got_offset);
++                      *location = relocation;
++                      break;
++              case R_AVR32_GOT18SW:
++                      if ((relocation & 0xfffe0003) != 0
++                          && (relocation & 0xfffc0003) != 0xffff0000)
++                              return reloc_overflow(module, "R_AVR32_GOT18SW",
++                                                   relocation);
++                      relocation >>= 2;
++                      /* fall through */
++              case R_AVR32_GOT16S:
++                      if ((relocation & 0xffff8000) != 0
++                          && (relocation & 0xffff0000) != 0xffff0000)
++                              return reloc_overflow(module, "R_AVR32_GOT16S",
++                                                    relocation);
++                      pr_debug("GOT reloc @ 0x%x -> %u\n",
++                               rel->r_offset, relocation);
++                      value = *location;
++                      value = ((value & 0xffff0000)
++                               | (relocation & 0xffff));
++                      *location = value;
++                      break;
++
++              default:
++                      printk(KERN_ERR "module %s: Unknown relocation: %u\n",
++                             module->name, ELF32_R_TYPE(rel->r_info));
++                      return -ENOEXEC;
++              }
++      }
++
++      return ret;
++}
++
++int apply_relocate(Elf32_Shdr *sechdrs, const char *strtab,
++                 unsigned int symindex, unsigned int relindex,
++                 struct module *module)
++{
++      printk(KERN_ERR "module %s: REL relocations are not supported\n",
++              module->name);
++      return -ENOEXEC;
++}
++
++int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
++                  struct module *module)
++{
++      vfree(module->arch.syminfo);
++      module->arch.syminfo = NULL;
++
++      return 0;
++}
++
++void module_arch_cleanup(struct module *module)
++{
++
++}
+Index: linux-2.6.18-avr32/arch/avr32/kernel/process.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/process.c     2006-12-04 12:05:20.000000000 +0100
+@@ -0,0 +1,283 @@
++/*
++ * 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/sched.h>
++#include <linux/module.h>
++#include <linux/kallsyms.h>
++#include <linux/fs.h>
++#include <linux/ptrace.h>
++#include <linux/reboot.h>
++#include <linux/unistd.h>
++
++#include <asm/sysreg.h>
++#include <asm/ocd.h>
++
++void (*pm_power_off)(void) = NULL;
++EXPORT_SYMBOL(pm_power_off);
++
++/*
++ * This file handles the architecture-dependent parts of process handling..
++ */
++
++void cpu_idle(void)
++{
++      /* endless idle loop with no priority at all */
++      while (1) {
++              /* TODO: Enter sleep mode */
++              while (!need_resched())
++                      cpu_relax();
++              preempt_enable_no_resched();
++              schedule();
++              preempt_disable();
++      }
++}
++
++void machine_halt(void)
++{
++      /*
++       * Enter Stop mode. The 32 kHz oscillator will keep running so
++       * the RTC will keep the time properly and the system will
++       * boot quickly.
++       */
++      asm volatile("sleep 3\n\t"
++                   "sub pc, -2");
++}
++
++void machine_power_off(void)
++{
++}
++
++void machine_restart(char *cmd)
++{
++      __mtdr(DBGREG_DC, DC_DBE);
++      __mtdr(DBGREG_DC, DC_RES);
++      while (1) ;
++}
++
++/*
++ * PC is actually discarded when returning from a system call -- the
++ * return address must be stored in LR. This function will make sure
++ * LR points to do_exit before starting the thread.
++ *
++ * Also, when returning from fork(), r12 is 0, so we must copy the
++ * argument as well.
++ *
++ *  r0 : The argument to the main thread function
++ *  r1 : The address of do_exit
++ *  r2 : The address of the main thread function
++ */
++asmlinkage extern void kernel_thread_helper(void);
++__asm__("     .type   kernel_thread_helper, @function\n"
++      "kernel_thread_helper:\n"
++      "       mov     r12, r0\n"
++      "       mov     lr, r2\n"
++      "       mov     pc, r1\n"
++      "       .size   kernel_thread_helper, . - kernel_thread_helper");
++
++int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
++{
++      struct pt_regs regs;
++
++      memset(&regs, 0, sizeof(regs));
++
++      regs.r0 = (unsigned long)arg;
++      regs.r1 = (unsigned long)fn;
++      regs.r2 = (unsigned long)do_exit;
++      regs.lr = (unsigned long)kernel_thread_helper;
++      regs.pc = (unsigned long)kernel_thread_helper;
++      regs.sr = MODE_SUPERVISOR;
++
++      return do_fork(flags | CLONE_VM | CLONE_UNTRACED,
++                     0, &regs, 0, NULL, NULL);
++}
++EXPORT_SYMBOL(kernel_thread);
++
++/*
++ * Free current thread data structures etc
++ */
++void exit_thread(void)
++{
++      /* nothing to do */
++}
++
++void flush_thread(void)
++{
++      /* nothing to do */
++}
++
++void release_thread(struct task_struct *dead_task)
++{
++      /* do nothing */
++}
++
++static const char *cpu_modes[] = {
++      "Application", "Supervisor", "Interrupt level 0", "Interrupt level 1",
++      "Interrupt level 2", "Interrupt level 3", "Exception", "NMI"
++};
++
++void show_regs(struct pt_regs *regs)
++{
++      unsigned long sp = regs->sp;
++      unsigned long lr = regs->lr;
++      unsigned long mode = (regs->sr & MODE_MASK) >> MODE_SHIFT;
++
++      if (!user_mode(regs))
++              sp = (unsigned long)regs + FRAME_SIZE_FULL;
++
++      print_symbol("PC is at %s\n", instruction_pointer(regs));
++      print_symbol("LR is at %s\n", lr);
++      printk("pc : [<%08lx>]    lr : [<%08lx>]    %s\n"
++             "sp : %08lx  r12: %08lx  r11: %08lx\n",
++             instruction_pointer(regs),
++             lr, print_tainted(), sp, regs->r12, regs->r11);
++      printk("r10: %08lx  r9 : %08lx  r8 : %08lx\n",
++             regs->r10, regs->r9, regs->r8);
++      printk("r7 : %08lx  r6 : %08lx  r5 : %08lx  r4 : %08lx\n",
++             regs->r7, regs->r6, regs->r5, regs->r4);
++      printk("r3 : %08lx  r2 : %08lx  r1 : %08lx  r0 : %08lx\n",
++             regs->r3, regs->r2, regs->r1, regs->r0);
++      printk("Flags: %c%c%c%c%c\n",
++             regs->sr & SR_Q ? 'Q' : 'q',
++             regs->sr & SR_V ? 'V' : 'v',
++             regs->sr & SR_N ? 'N' : 'n',
++             regs->sr & SR_Z ? 'Z' : 'z',
++             regs->sr & SR_C ? 'C' : 'c');
++      printk("Mode bits: %c%c%c%c%c%c%c%c%c\n",
++             regs->sr & SR_H ? 'H' : 'h',
++             regs->sr & SR_R ? 'R' : 'r',
++             regs->sr & SR_J ? 'J' : 'j',
++             regs->sr & SR_EM ? 'E' : 'e',
++             regs->sr & SR_I3M ? '3' : '.',
++             regs->sr & SR_I2M ? '2' : '.',
++             regs->sr & SR_I1M ? '1' : '.',
++             regs->sr & SR_I0M ? '0' : '.',
++             regs->sr & SR_GM ? 'G' : 'g');
++      printk("CPU Mode: %s\n", cpu_modes[mode]);
++
++      show_trace(NULL, (unsigned long *)sp, regs);
++}
++EXPORT_SYMBOL(show_regs);
++
++/* Fill in the fpu structure for a core dump. This is easy -- we don't have any */
++int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
++{
++      /* Not valid */
++      return 0;
++}
++
++asmlinkage void ret_from_fork(void);
++
++int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
++              unsigned long unused,
++              struct task_struct *p, struct pt_regs *regs)
++{
++      struct pt_regs *childregs;
++
++      childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long)p->thread_info)) - 1;
++      *childregs = *regs;
++
++      if (user_mode(regs))
++              childregs->sp = usp;
++      else
++              childregs->sp = (unsigned long)p->thread_info + THREAD_SIZE;
++
++      childregs->r12 = 0; /* Set return value for child */
++
++      p->thread.cpu_context.sr = MODE_SUPERVISOR | SR_GM;
++      p->thread.cpu_context.ksp = (unsigned long)childregs;
++      p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
++
++      return 0;
++}
++
++/* r12-r8 are dummy parameters to force the compiler to use the stack */
++asmlinkage int sys_fork(struct pt_regs *regs)
++{
++      return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
++}
++
++asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
++                       unsigned long parent_tidptr,
++                       unsigned long child_tidptr, struct pt_regs *regs)
++{
++      if (!newsp)
++              newsp = regs->sp;
++      return do_fork(clone_flags, newsp, regs, 0,
++                     (int __user *)parent_tidptr,
++                     (int __user *)child_tidptr);
++}
++
++asmlinkage int sys_vfork(struct pt_regs *regs)
++{
++      return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs,
++                     0, NULL, NULL);
++}
++
++asmlinkage int sys_execve(char __user *ufilename, char __user *__user *uargv,
++                        char __user *__user *uenvp, struct pt_regs *regs)
++{
++      int error;
++      char *filename;
++
++      filename = getname(ufilename);
++      error = PTR_ERR(filename);
++      if (IS_ERR(filename))
++              goto out;
++
++      error = do_execve(filename, uargv, uenvp, regs);
++      if (error == 0)
++              current->ptrace &= ~PT_DTRACE;
++      putname(filename);
++
++out:
++      return error;
++}
++
++
++/*
++ * This function is supposed to answer the question "who called
++ * schedule()?"
++ */
++unsigned long get_wchan(struct task_struct *p)
++{
++      unsigned long pc;
++      unsigned long stack_page;
++
++      if (!p || p == current || p->state == TASK_RUNNING)
++              return 0;
++
++      stack_page = (unsigned long)p->thread_info;
++      BUG_ON(!stack_page);
++
++      /*
++       * The stored value of PC is either the address right after
++       * the call to __switch_to() or ret_from_fork.
++       */
++      pc = thread_saved_pc(p);
++      if (in_sched_functions(pc)) {
++#ifdef CONFIG_FRAME_POINTER
++              unsigned long fp = p->thread.cpu_context.r7;
++              BUG_ON(fp < stack_page || fp > (THREAD_SIZE + stack_page));
++              pc = *(unsigned long *)fp;
++#else
++              /*
++               * We depend on the frame size of schedule here, which
++               * is actually quite ugly. It might be possible to
++               * determine the frame size automatically at build
++               * time by doing this:
++               *   - compile sched.c
++               *   - disassemble the resulting sched.o
++               *   - look for 'sub sp,??' shortly after '<schedule>:'
++               */
++              unsigned long sp = p->thread.cpu_context.ksp + 16;
++              BUG_ON(sp < stack_page || sp > (THREAD_SIZE + stack_page));
++              pc = *(unsigned long *)sp;
++#endif
++      }
++
++      return pc;
++}
+Index: linux-2.6.18-avr32/arch/avr32/kernel/ptrace.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/ptrace.c      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,371 @@
++/*
++ * 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.
++ */
++#undef DEBUG
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/mm.h>
++#include <linux/smp_lock.h>
++#include <linux/ptrace.h>
++#include <linux/errno.h>
++#include <linux/user.h>
++#include <linux/security.h>
++#include <linux/unistd.h>
++#include <linux/notifier.h>
++
++#include <asm/traps.h>
++#include <asm/uaccess.h>
++#include <asm/ocd.h>
++#include <asm/mmu_context.h>
++#include <asm/kdebug.h>
++
++static struct pt_regs *get_user_regs(struct task_struct *tsk)
++{
++      return (struct pt_regs *)((unsigned long) tsk->thread_info +
++                                THREAD_SIZE - sizeof(struct pt_regs));
++}
++
++static void ptrace_single_step(struct task_struct *tsk)
++{
++      pr_debug("ptrace_single_step: pid=%u, SR=0x%08lx\n",
++               tsk->pid, tsk->thread.cpu_context.sr);
++      if (!(tsk->thread.cpu_context.sr & SR_D)) {
++              /*
++               * Set a breakpoint at the current pc to force the
++               * process into debug mode.  The syscall/exception
++               * exit code will set a breakpoint at the return
++               * address when this flag is set.
++               */
++              pr_debug("ptrace_single_step: Setting TIF_BREAKPOINT\n");
++              set_tsk_thread_flag(tsk, TIF_BREAKPOINT);
++      }
++
++      /* The monitor code will do the actual step for us */
++      set_tsk_thread_flag(tsk, TIF_SINGLE_STEP);
++}
++
++/*
++ * Called by kernel/ptrace.c when detaching
++ *
++ * Make sure any single step bits, etc. are not set
++ */
++void ptrace_disable(struct task_struct *child)
++{
++      clear_tsk_thread_flag(child, TIF_SINGLE_STEP);
++}
++
++/*
++ * Handle hitting a breakpoint
++ */
++static void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
++{
++      siginfo_t info;
++
++      info.si_signo = SIGTRAP;
++      info.si_errno = 0;
++      info.si_code  = TRAP_BRKPT;
++      info.si_addr  = (void __user *)instruction_pointer(regs);
++
++      pr_debug("ptrace_break: Sending SIGTRAP to PID %u (pc = 0x%p)\n",
++               tsk->pid, info.si_addr);
++      force_sig_info(SIGTRAP, &info, tsk);
++}
++
++/*
++ * Read the word at offset "offset" into the task's "struct user". We
++ * actually access the pt_regs struct stored on the kernel stack.
++ */
++static int ptrace_read_user(struct task_struct *tsk, unsigned long offset,
++                          unsigned long __user *data)
++{
++      unsigned long *regs;
++      unsigned long value;
++
++      pr_debug("ptrace_read_user(%p, %#lx, %p)\n",
++               tsk, offset, data);
++
++      if (offset & 3 || offset >= sizeof(struct user)) {
++              printk("ptrace_read_user: invalid offset 0x%08lx\n", offset);
++              return -EIO;
++      }
++
++      regs = (unsigned long *)get_user_regs(tsk);
++
++      value = 0;
++      if (offset < sizeof(struct pt_regs))
++              value = regs[offset / sizeof(regs[0])];
++
++      return put_user(value, data);
++}
++
++/*
++ * Write the word "value" to offset "offset" into the task's "struct
++ * user". We actually access the pt_regs struct stored on the kernel
++ * stack.
++ */
++static int ptrace_write_user(struct task_struct *tsk, unsigned long offset,
++                           unsigned long value)
++{
++      unsigned long *regs;
++
++      if (offset & 3 || offset >= sizeof(struct user)) {
++              printk("ptrace_write_user: invalid offset 0x%08lx\n", offset);
++              return -EIO;
++      }
++
++      if (offset >= sizeof(struct pt_regs))
++              return 0;
++
++      regs = (unsigned long *)get_user_regs(tsk);
++      regs[offset / sizeof(regs[0])] = value;
++
++      return 0;
++}
++
++static int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
++{
++      struct pt_regs *regs = get_user_regs(tsk);
++
++      return copy_to_user(uregs, regs, sizeof(*regs)) ? -EFAULT : 0;
++}
++
++static int ptrace_setregs(struct task_struct *tsk, const void __user *uregs)
++{
++      struct pt_regs newregs;
++      int ret;
++
++      ret = -EFAULT;
++      if (copy_from_user(&newregs, uregs, sizeof(newregs)) == 0) {
++              struct pt_regs *regs = get_user_regs(tsk);
++
++              ret = -EINVAL;
++              if (valid_user_regs(&newregs)) {
++                      *regs = newregs;
++                      ret = 0;
++              }
++      }
++
++      return ret;
++}
++
++long arch_ptrace(struct task_struct *child, long request, long addr, long data)
++{
++      unsigned long tmp;
++      int ret;
++
++      pr_debug("arch_ptrace(%ld, %d, %#lx, %#lx)\n",
++               request, child->pid, addr, data);
++
++      pr_debug("ptrace: Enabling monitor mode...\n");
++      __mtdr(DBGREG_DC, __mfdr(DBGREG_DC) | DC_MM | DC_DBE);
++
++      switch (request) {
++      /* Read the word at location addr in the child process */
++      case PTRACE_PEEKTEXT:
++      case PTRACE_PEEKDATA:
++              ret = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
++              if (ret == sizeof(tmp))
++                      ret = put_user(tmp, (unsigned long __user *)data);
++              else
++                      ret = -EIO;
++              break;
++
++      case PTRACE_PEEKUSR:
++              ret = ptrace_read_user(child, addr,
++                                     (unsigned long __user *)data);
++              break;
++
++      /* Write the word in data at location addr */
++      case PTRACE_POKETEXT:
++      case PTRACE_POKEDATA:
++              ret = access_process_vm(child, addr, &data, sizeof(data), 1);
++              if (ret == sizeof(data))
++                      ret = 0;
++              else
++                      ret = -EIO;
++              break;
++
++      case PTRACE_POKEUSR:
++              ret = ptrace_write_user(child, addr, data);
++              break;
++
++      /* continue and stop at next (return from) syscall */
++      case PTRACE_SYSCALL:
++      /* restart after signal */
++      case PTRACE_CONT:
++              ret = -EIO;
++              if (!valid_signal(data))
++                      break;
++              if (request == PTRACE_SYSCALL)
++                      set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
++              else
++                      clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
++              child->exit_code = data;
++              /* XXX: Are we sure no breakpoints are active here? */
++              wake_up_process(child);
++              ret = 0;
++              break;
++
++      /*
++       * Make the child exit. Best I can do is send it a
++       * SIGKILL. Perhaps it should be put in the status that it
++       * wants to exit.
++       */
++      case PTRACE_KILL:
++              ret = 0;
++              if (child->exit_state == EXIT_ZOMBIE)
++                      break;
++              child->exit_code = SIGKILL;
++              wake_up_process(child);
++              break;
++
++      /*
++       * execute single instruction.
++       */
++      case PTRACE_SINGLESTEP:
++              ret = -EIO;
++              if (!valid_signal(data))
++                      break;
++              clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
++              ptrace_single_step(child);
++              child->exit_code = data;
++              wake_up_process(child);
++              ret = 0;
++              break;
++
++      /* Detach a process that was attached */
++      case PTRACE_DETACH:
++              ret = ptrace_detach(child, data);
++              break;
++
++      case PTRACE_GETREGS:
++              ret = ptrace_getregs(child, (void __user *)data);
++              break;
++
++      case PTRACE_SETREGS:
++              ret = ptrace_setregs(child, (const void __user *)data);
++              break;
++
++      default:
++              ret = ptrace_request(child, request, addr, data);
++              break;
++      }
++
++      pr_debug("sys_ptrace returning %d (DC = 0x%08lx)\n", ret, __mfdr(DBGREG_DC));
++      return ret;
++}
++
++asmlinkage void syscall_trace(void)
++{
++      pr_debug("syscall_trace called\n");
++      if (!test_thread_flag(TIF_SYSCALL_TRACE))
++              return;
++      if (!(current->ptrace & PT_PTRACED))
++              return;
++
++      pr_debug("syscall_trace: notifying parent\n");
++      /* The 0x80 provides a way for the tracing parent to
++       * distinguish between a syscall stop and SIGTRAP delivery */
++      ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
++                               ? 0x80 : 0));
++
++      /*
++       * this isn't the same as continuing with a signal, but it
++       * will do for normal use.  strace only continues with a
++       * signal if the stopping signal is not SIGTRAP.  -brl
++       */
++      if (current->exit_code) {
++              pr_debug("syscall_trace: sending signal %d to PID %u\n",
++                       current->exit_code, current->pid);
++              send_sig(current->exit_code, current, 1);
++              current->exit_code = 0;
++      }
++}
++
++asmlinkage void do_debug_priv(struct pt_regs *regs)
++{
++      unsigned long dc, ds;
++      unsigned long die_val;
++
++      ds = __mfdr(DBGREG_DS);
++
++      pr_debug("do_debug_priv: pc = %08lx, ds = %08lx\n", regs->pc, ds);
++
++      if (ds & DS_SSS)
++              die_val = DIE_SSTEP;
++      else
++              die_val = DIE_BREAKPOINT;
++
++      if (notify_die(die_val, regs, 0, SIGTRAP) == NOTIFY_STOP)
++              return;
++
++      if (likely(ds & DS_SSS)) {
++              extern void itlb_miss(void);
++              extern void tlb_miss_common(void);
++              struct thread_info *ti;
++
++              dc = __mfdr(DBGREG_DC);
++              dc &= ~DC_SS;
++              __mtdr(DBGREG_DC, dc);
++
++              ti = current_thread_info();
++              ti->flags |= _TIF_BREAKPOINT;
++
++              /* The TLB miss handlers don't check thread flags */
++              if ((regs->pc >= (unsigned long)&itlb_miss)
++                  && (regs->pc <= (unsigned long)&tlb_miss_common)) {
++                      __mtdr(DBGREG_BWA2A, sysreg_read(RAR_EX));
++                      __mtdr(DBGREG_BWC2A, 0x40000001 | (get_asid() << 1));
++              }
++
++              /*
++               * If we're running in supervisor mode, the breakpoint
++               * will take us where we want directly, no need to
++               * single step.
++               */
++              if ((regs->sr & MODE_MASK) != MODE_SUPERVISOR)
++                      ti->flags |= TIF_SINGLE_STEP;
++      } else {
++              panic("Unable to handle debug trap at pc = %08lx\n",
++                    regs->pc);
++      }
++}
++
++/*
++ * Handle breakpoints, single steps and other debuggy things. To keep
++ * things simple initially, we run with interrupts and exceptions
++ * disabled all the time.
++ */
++asmlinkage void do_debug(struct pt_regs *regs)
++{
++      unsigned long dc, ds;
++
++      ds = __mfdr(DBGREG_DS);
++      pr_debug("do_debug: pc = %08lx, ds = %08lx\n", regs->pc, ds);
++
++      if (test_thread_flag(TIF_BREAKPOINT)) {
++              pr_debug("TIF_BREAKPOINT set\n");
++              /* We're taking care of it */
++              clear_thread_flag(TIF_BREAKPOINT);
++              __mtdr(DBGREG_BWC2A, 0);
++      }
++
++      if (test_thread_flag(TIF_SINGLE_STEP)) {
++              pr_debug("TIF_SINGLE_STEP set, ds = 0x%08lx\n", ds);
++              if (ds & DS_SSS) {
++                      dc = __mfdr(DBGREG_DC);
++                      dc &= ~DC_SS;
++                      __mtdr(DBGREG_DC, dc);
++
++                      clear_thread_flag(TIF_SINGLE_STEP);
++                      ptrace_break(current, regs);
++              }
++      } else {
++              /* regular breakpoint */
++              ptrace_break(current, regs);
++      }
++}
+Index: linux-2.6.18-avr32/arch/avr32/kernel/semaphore.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/semaphore.c   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,148 @@
++/*
++ * AVR32 sempahore implementation.
++ *
++ * Copyright (C) 2004-2006 Atmel Corporation
++ *
++ * Based on linux/arch/i386/kernel/semaphore.c
++ *  Copyright (C) 1999 Linus Torvalds
++ *
++ * 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/sched.h>
++#include <linux/errno.h>
++#include <linux/module.h>
++
++#include <asm/semaphore.h>
++#include <asm/atomic.h>
++
++/*
++ * Semaphores are implemented using a two-way counter:
++ * The "count" variable is decremented for each process
++ * that tries to acquire the semaphore, while the "sleeping"
++ * variable is a count of such acquires.
++ *
++ * Notably, the inline "up()" and "down()" functions can
++ * efficiently test if they need to do any extra work (up
++ * needs to do something only if count was negative before
++ * the increment operation.
++ *
++ * "sleeping" and the contention routine ordering is protected
++ * by the spinlock in the semaphore's waitqueue head.
++ *
++ * Note that these functions are only called when there is
++ * contention on the lock, and as such all this is the
++ * "non-critical" part of the whole semaphore business. The
++ * critical part is the inline stuff in <asm/semaphore.h>
++ * where we want to avoid any extra jumps and calls.
++ */
++
++/*
++ * Logic:
++ *  - only on a boundary condition do we need to care. When we go
++ *    from a negative count to a non-negative, we wake people up.
++ *  - when we go from a non-negative count to a negative do we
++ *    (a) synchronize with the "sleeper" count and (b) make sure
++ *    that we're on the wakeup list before we synchronize so that
++ *    we cannot lose wakeup events.
++ */
++
++void __up(struct semaphore *sem)
++{
++      wake_up(&sem->wait);
++}
++EXPORT_SYMBOL(__up);
++
++void __sched __down(struct semaphore *sem)
++{
++      struct task_struct *tsk = current;
++        DECLARE_WAITQUEUE(wait, tsk);
++        unsigned long flags;
++
++        tsk->state = TASK_UNINTERRUPTIBLE;
++        spin_lock_irqsave(&sem->wait.lock, flags);
++        add_wait_queue_exclusive_locked(&sem->wait, &wait);
++
++        sem->sleepers++;
++        for (;;) {
++                int sleepers = sem->sleepers;
++
++                /*
++                 * Add "everybody else" into it. They aren't
++                 * playing, because we own the spinlock in
++                 * the wait_queue_head.
++                 */
++                if (atomic_add_return(sleepers - 1, &sem->count) >= 0) {
++                        sem->sleepers = 0;
++                        break;
++                }
++                sem->sleepers = 1;      /* us - see -1 above */
++                spin_unlock_irqrestore(&sem->wait.lock, flags);
++
++                schedule();
++
++                spin_lock_irqsave(&sem->wait.lock, flags);
++                tsk->state = TASK_UNINTERRUPTIBLE;
++        }
++        remove_wait_queue_locked(&sem->wait, &wait);
++        wake_up_locked(&sem->wait);
++        spin_unlock_irqrestore(&sem->wait.lock, flags);
++        tsk->state = TASK_RUNNING;
++}
++EXPORT_SYMBOL(__down);
++
++int __sched __down_interruptible(struct semaphore *sem)
++{
++      int retval = 0;
++      struct task_struct *tsk = current;
++        DECLARE_WAITQUEUE(wait, tsk);
++        unsigned long flags;
++
++        tsk->state = TASK_INTERRUPTIBLE;
++        spin_lock_irqsave(&sem->wait.lock, flags);
++        add_wait_queue_exclusive_locked(&sem->wait, &wait);
++
++        sem->sleepers++;
++        for (;;) {
++                int sleepers = sem->sleepers;
++
++              /*
++               * With signals pending, this turns into the trylock
++               * failure case - we won't be sleeping, and we can't
++               * get the lock as it has contention. Just correct the
++               * count and exit.
++               */
++              if (signal_pending(current)) {
++                      retval = -EINTR;
++                      sem->sleepers = 0;
++                      atomic_add(sleepers, &sem->count);
++                      break;
++              }
++
++                /*
++                 * Add "everybody else" into it. They aren't
++                 * playing, because we own the spinlock in
++                 * the wait_queue_head.
++                 */
++                if (atomic_add_return(sleepers - 1, &sem->count) >= 0) {
++                        sem->sleepers = 0;
++                        break;
++                }
++                sem->sleepers = 1;      /* us - see -1 above */
++                spin_unlock_irqrestore(&sem->wait.lock, flags);
++
++                schedule();
++
++                spin_lock_irqsave(&sem->wait.lock, flags);
++                tsk->state = TASK_INTERRUPTIBLE;
++        }
++        remove_wait_queue_locked(&sem->wait, &wait);
++        wake_up_locked(&sem->wait);
++        spin_unlock_irqrestore(&sem->wait.lock, flags);
++
++        tsk->state = TASK_RUNNING;
++      return retval;
++}
++EXPORT_SYMBOL(__down_interruptible);
+Index: linux-2.6.18-avr32/arch/avr32/kernel/setup.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/setup.c       2006-12-04 11:50:25.000000000 +0100
+@@ -0,0 +1,335 @@
++/*
++ * 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/clk.h>
++#include <linux/init.h>
++#include <linux/sched.h>
++#include <linux/console.h>
++#include <linux/ioport.h>
++#include <linux/bootmem.h>
++#include <linux/fs.h>
++#include <linux/module.h>
++#include <linux/root_dev.h>
++#include <linux/cpu.h>
++
++#include <asm/sections.h>
++#include <asm/processor.h>
++#include <asm/pgtable.h>
++#include <asm/setup.h>
++#include <asm/sysreg.h>
++
++#include <asm/arch/board.h>
++#include <asm/arch/init.h>
++
++extern int root_mountflags;
++
++/*
++ * Bootloader-provided information about physical memory
++ */
++struct tag_mem_range *mem_phys;
++struct tag_mem_range *mem_reserved;
++struct tag_mem_range *mem_ramdisk;
++
++/*
++ * Initialize loops_per_jiffy as 5000000 (500MIPS).
++ * Better make it too large than too small...
++ */
++struct avr32_cpuinfo boot_cpu_data = {
++      .loops_per_jiffy = 5000000
++};
++EXPORT_SYMBOL(boot_cpu_data);
++
++static char command_line[COMMAND_LINE_SIZE];
++
++/*
++ * Should be more than enough, but if you have a _really_ complex
++ * setup, you might need to increase the size of this...
++ */
++static struct tag_mem_range __initdata mem_range_cache[32];
++static unsigned mem_range_next_free;
++
++/*
++ * Standard memory resources
++ */
++static struct resource mem_res[] = {
++      {
++              .name   = "Kernel code",
++              .start  = 0,
++              .end    = 0,
++              .flags  = IORESOURCE_MEM
++      },
++      {
++              .name   = "Kernel data",
++              .start  = 0,
++              .end    = 0,
++              .flags  = IORESOURCE_MEM,
++      },
++};
++
++#define kernel_code   mem_res[0]
++#define kernel_data   mem_res[1]
++
++/*
++ * Early framebuffer allocation. Works as follows:
++ *   - If fbmem_size is zero, nothing will be allocated or reserved.
++ *   - If fbmem_start is zero when setup_bootmem() is called,
++ *     fbmem_size bytes will be allocated from the bootmem allocator.
++ *   - If fbmem_start is nonzero, an area of size fbmem_size will be
++ *     reserved at the physical address fbmem_start if necessary. If
++ *     the area isn't in a memory region known to the kernel, it will
++ *     be left alone.
++ *
++ * Board-specific code may use these variables to set up platform data
++ * for the framebuffer driver if fbmem_size is nonzero.
++ */
++static unsigned long __initdata fbmem_start;
++static unsigned long __initdata fbmem_size;
++
++/*
++ * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for
++ * use as framebuffer.
++ *
++ * "fbmem=xxx[kKmM]@yyy[kKmM]" defines a memory region of size xxx and
++ * starting at yyy to be reserved for use as framebuffer.
++ *
++ * The kernel won't verify that the memory region starting at yyy
++ * actually contains usable RAM.
++ */
++static int __init early_parse_fbmem(char *p)
++{
++      fbmem_size = memparse(p, &p);
++      if (*p == '@')
++              fbmem_start = memparse(p, &p);
++      return 0;
++}
++early_param("fbmem", early_parse_fbmem);
++
++static inline void __init resource_init(void)
++{
++      struct tag_mem_range *region;
++
++      kernel_code.start = __pa(init_mm.start_code);
++      kernel_code.end = __pa(init_mm.end_code - 1);
++      kernel_data.start = __pa(init_mm.end_code);
++      kernel_data.end = __pa(init_mm.brk - 1);
++
++      for (region = mem_phys; region; region = region->next) {
++              struct resource *res;
++              unsigned long phys_start, phys_end;
++
++              if (region->size == 0)
++                      continue;
++
++              phys_start = region->addr;
++              phys_end = phys_start + region->size - 1;
++
++              res = alloc_bootmem_low(sizeof(*res));
++              res->name = "System RAM";
++              res->start = phys_start;
++              res->end = phys_end;
++              res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
++
++              request_resource (&iomem_resource, res);
++
++              if (kernel_code.start >= res->start &&
++                  kernel_code.end <= res->end)
++                      request_resource (res, &kernel_code);
++              if (kernel_data.start >= res->start &&
++                  kernel_data.end <= res->end)
++                      request_resource (res, &kernel_data);
++      }
++}
++
++static int __init parse_tag_core(struct tag *tag)
++{
++      if (tag->hdr.size > 2) {
++              if ((tag->u.core.flags & 1) == 0)
++                      root_mountflags &= ~MS_RDONLY;
++              ROOT_DEV = new_decode_dev(tag->u.core.rootdev);
++      }
++      return 0;
++}
++__tagtable(ATAG_CORE, parse_tag_core);
++
++static int __init parse_tag_mem_range(struct tag *tag,
++                                    struct tag_mem_range **root)
++{
++      struct tag_mem_range *cur, **pprev;
++      struct tag_mem_range *new;
++
++      /*
++       * Ignore zero-sized entries. If we're running standalone, the
++       * SDRAM code may emit such entries if something goes
++       * wrong...
++       */
++      if (tag->u.mem_range.size == 0)
++              return 0;
++
++      /*
++       * Copy the data so the bootmem init code doesn't need to care
++       * about it.
++       */
++      if (mem_range_next_free >=
++          (sizeof(mem_range_cache) / sizeof(mem_range_cache[0])))
++              panic("Physical memory map too complex!\n");
++
++      new = &mem_range_cache[mem_range_next_free++];
++      *new = tag->u.mem_range;
++
++      pprev = root;
++      cur = *root;
++      while (cur) {
++              pprev = &cur->next;
++              cur = cur->next;
++      }
++
++      *pprev = new;
++      new->next = NULL;
++
++      return 0;
++}
++
++static int __init parse_tag_mem(struct tag *tag)
++{
++      return parse_tag_mem_range(tag, &mem_phys);
++}
++__tagtable(ATAG_MEM, parse_tag_mem);
++
++static int __init parse_tag_cmdline(struct tag *tag)
++{
++      strlcpy(saved_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
++      return 0;
++}
++__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
++
++static int __init parse_tag_rdimg(struct tag *tag)
++{
++      return parse_tag_mem_range(tag, &mem_ramdisk);
++}
++__tagtable(ATAG_RDIMG, parse_tag_rdimg);
++
++static int __init parse_tag_clock(struct tag *tag)
++{
++      /*
++       * We'll figure out the clocks by peeking at the system
++       * manager regs directly.
++       */
++      return 0;
++}
++__tagtable(ATAG_CLOCK, parse_tag_clock);
++
++static int __init parse_tag_rsvd_mem(struct tag *tag)
++{
++      return parse_tag_mem_range(tag, &mem_reserved);
++}
++__tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem);
++
++static int __init parse_tag_ethernet(struct tag *tag)
++{
++#if 0
++      const struct platform_device *pdev;
++
++      /*
++       * We really need a bus type that supports "classes"...this
++       * will do for now (until we must handle other kinds of
++       * ethernet controllers)
++       */
++      pdev = platform_get_device("macb", tag->u.ethernet.mac_index);
++      if (pdev && pdev->dev.platform_data) {
++              struct eth_platform_data *data = pdev->dev.platform_data;
++
++              data->valid = 1;
++              data->mii_phy_addr = tag->u.ethernet.mii_phy_addr;
++              memcpy(data->hw_addr, tag->u.ethernet.hw_address,
++                     sizeof(data->hw_addr));
++      }
++#endif
++      return 0;
++}
++__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
++
++/*
++ * Scan the tag table for this tag, and call its parse function. The
++ * tag table is built by the linker from all the __tagtable
++ * declarations.
++ */
++static int __init parse_tag(struct tag *tag)
++{
++      extern struct tagtable __tagtable_begin, __tagtable_end;
++      struct tagtable *t;
++
++      for (t = &__tagtable_begin; t < &__tagtable_end; t++)
++              if (tag->hdr.tag == t->tag) {
++                      t->parse(tag);
++                      break;
++              }
++
++      return t < &__tagtable_end;
++}
++
++/*
++ * Parse all tags in the list we got from the boot loader
++ */
++static void __init parse_tags(struct tag *t)
++{
++      for (; t->hdr.tag != ATAG_NONE; t = tag_next(t))
++              if (!parse_tag(t))
++                      printk(KERN_WARNING
++                             "Ignoring unrecognised tag 0x%08x\n",
++                             t->hdr.tag);
++}
++
++void __init setup_arch (char **cmdline_p)
++{
++      struct clk *cpu_clk;
++
++      parse_tags(bootloader_tags);
++
++      setup_processor();
++      setup_platform();
++
++      cpu_clk = clk_get(NULL, "cpu");
++      if (IS_ERR(cpu_clk)) {
++              printk(KERN_WARNING "Warning: Unable to get CPU clock\n");
++      } else {
++              unsigned long cpu_hz = clk_get_rate(cpu_clk);
++
++              /*
++               * Well, duh, but it's probably a good idea to
++               * increment the use count.
++               */
++              clk_enable(cpu_clk);
++
++              boot_cpu_data.clk = cpu_clk;
++              boot_cpu_data.loops_per_jiffy = cpu_hz * 4;
++              printk("CPU: Running at %lu.%03lu MHz\n",
++                     ((cpu_hz + 500) / 1000) / 1000,
++                     ((cpu_hz + 500) / 1000) % 1000);
++      }
++
++      init_mm.start_code = (unsigned long) &_text;
++      init_mm.end_code = (unsigned long) &_etext;
++      init_mm.end_data = (unsigned long) &_edata;
++      init_mm.brk = (unsigned long) &_end;
++
++      strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE);
++      *cmdline_p = command_line;
++      parse_early_param();
++
++      setup_bootmem();
++
++      board_setup_fbmem(fbmem_start, fbmem_size);
++
++#ifdef CONFIG_VT
++      conswitchp = &dummy_con;
++#endif
++
++      paging_init();
++
++      resource_init();
++}
+Index: linux-2.6.18-avr32/arch/avr32/kernel/signal.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/signal.c      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,328 @@
++/*
++ * Copyright (C) 2004-2006 Atmel Corporation
++ *
++ * Based on linux/arch/sh/kernel/signal.c
++ *  Copyright (C) 1999, 2000  Niibe Yutaka & Kaz Kojima
++ *  Copyright (C) 1991, 1992  Linus Torvalds
++ *
++ * 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/sched.h>
++#include <linux/mm.h>
++#include <linux/errno.h>
++#include <linux/ptrace.h>
++#include <linux/unistd.h>
++#include <linux/suspend.h>
++
++#include <asm/uaccess.h>
++#include <asm/ucontext.h>
++
++#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
++
++asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
++                             struct pt_regs *regs)
++{
++      return do_sigaltstack(uss, uoss, regs->sp);
++}
++
++struct rt_sigframe
++{
++      struct siginfo info;
++      struct ucontext uc;
++      unsigned long retcode;
++};
++
++static int
++restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
++{
++      int err = 0;
++
++#define COPY(x)               err |= __get_user(regs->x, &sc->x)
++      COPY(sr);
++      COPY(pc);
++      COPY(lr);
++      COPY(sp);
++      COPY(r12);
++      COPY(r11);
++      COPY(r10);
++      COPY(r9);
++      COPY(r8);
++      COPY(r7);
++      COPY(r6);
++      COPY(r5);
++      COPY(r4);
++      COPY(r3);
++      COPY(r2);
++      COPY(r1);
++      COPY(r0);
++#undef        COPY
++
++      /*
++       * Don't allow anyone to pretend they're running in supervisor
++       * mode or something...
++       */
++      err |= !valid_user_regs(regs);
++
++      return err;
++}
++
++
++asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
++{
++      struct rt_sigframe __user *frame;
++      sigset_t set;
++
++      frame = (struct rt_sigframe __user *)regs->sp;
++      pr_debug("SIG return: frame = %p\n", frame);
++
++      if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
++              goto badframe;
++
++      if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
++              goto badframe;
++
++      sigdelsetmask(&set, ~_BLOCKABLE);
++      spin_lock_irq(&current->sighand->siglock);
++      current->blocked = set;
++      recalc_sigpending();
++      spin_unlock_irq(&current->sighand->siglock);
++
++      if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
++              goto badframe;
++
++      pr_debug("Context restored: pc = %08lx, lr = %08lx, sp = %08lx\n",
++               regs->pc, regs->lr, regs->sp);
++
++      return regs->r12;
++
++badframe:
++      force_sig(SIGSEGV, current);
++      return 0;
++}
++
++static int
++setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
++{
++      int err = 0;
++
++#define COPY(x)               err |= __put_user(regs->x, &sc->x)
++      COPY(sr);
++      COPY(pc);
++      COPY(lr);
++      COPY(sp);
++      COPY(r12);
++      COPY(r11);
++      COPY(r10);
++      COPY(r9);
++      COPY(r8);
++      COPY(r7);
++      COPY(r6);
++      COPY(r5);
++      COPY(r4);
++      COPY(r3);
++      COPY(r2);
++      COPY(r1);
++      COPY(r0);
++#undef        COPY
++
++      return err;
++}
++
++static inline void __user *
++get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize)
++{
++      unsigned long sp = regs->sp;
++
++      if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))
++              sp = current->sas_ss_sp + current->sas_ss_size;
++
++      return (void __user *)((sp - framesize) & ~3);
++}
++
++static int
++setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
++             sigset_t *set, struct pt_regs *regs)
++{
++      struct rt_sigframe __user *frame;
++      int err = 0;
++
++      frame = get_sigframe(ka, regs, sizeof(*frame));
++      err = -EFAULT;
++      if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
++              goto out;
++
++      /*
++       * Set up the return code:
++       *
++       *      mov     r8, __NR_rt_sigreturn
++       *      scall
++       *
++       * Note: This will blow up since we're using a non-executable
++       * stack. Better use SA_RESTORER.
++       */
++#if __NR_rt_sigreturn > 127
++# error __NR_rt_sigreturn must be < 127 to fit in a short mov
++#endif
++      err = __put_user(0x3008d733 | (__NR_rt_sigreturn << 20),
++                       &frame->retcode);
++
++      err |= copy_siginfo_to_user(&frame->info, info);
++
++      /* Set up the ucontext */
++      err |= __put_user(0, &frame->uc.uc_flags);
++      err |= __put_user(NULL, &frame->uc.uc_link);
++      err |= __put_user((void __user *)current->sas_ss_sp,
++                        &frame->uc.uc_stack.ss_sp);
++      err |= __put_user(sas_ss_flags(regs->sp),
++                        &frame->uc.uc_stack.ss_flags);
++      err |= __put_user(current->sas_ss_size,
++                        &frame->uc.uc_stack.ss_size);
++      err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
++      err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
++
++      if (err)
++              goto out;
++
++      regs->r12 = sig;
++      regs->r11 = (unsigned long) &frame->info;
++      regs->r10 = (unsigned long) &frame->uc;
++      regs->sp = (unsigned long) frame;
++      if (ka->sa.sa_flags & SA_RESTORER)
++              regs->lr = (unsigned long)ka->sa.sa_restorer;
++      else {
++              printk(KERN_NOTICE "[%s:%d] did not set SA_RESTORER\n",
++                     current->comm, current->pid);
++              regs->lr = (unsigned long) &frame->retcode;
++      }
++
++      pr_debug("SIG deliver [%s:%d]: sig=%d sp=0x%lx pc=0x%lx->0x%p lr=0x%lx\n",
++               current->comm, current->pid, sig, regs->sp,
++               regs->pc, ka->sa.sa_handler, regs->lr);
++
++      regs->pc = (unsigned long) ka->sa.sa_handler;
++
++out:
++      return err;
++}
++
++static inline void restart_syscall(struct pt_regs *regs)
++{
++      if (regs->r12 == -ERESTART_RESTARTBLOCK)
++              regs->r8 = __NR_restart_syscall;
++      else
++              regs->r12 = regs->r12_orig;
++      regs->pc -= 2;
++}
++
++static inline void
++handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
++            sigset_t *oldset, struct pt_regs *regs, int syscall)
++{
++      int ret;
++
++      /*
++       * Set up the stack frame
++       */
++      ret = setup_rt_frame(sig, ka, info, oldset, regs);
++
++      /*
++       * Check that the resulting registers are sane
++       */
++      ret |= !valid_user_regs(regs);
++
++      /*
++       * Block the signal if we were unsuccessful.
++       */
++      if (ret != 0 || !(ka->sa.sa_flags & SA_NODEFER)) {
++              spin_lock_irq(&current->sighand->siglock);
++              sigorsets(&current->blocked, &current->blocked,
++                        &ka->sa.sa_mask);
++              sigaddset(&current->blocked, sig);
++              recalc_sigpending();
++              spin_unlock_irq(&current->sighand->siglock);
++      }
++
++      if (ret == 0)
++              return;
++
++      force_sigsegv(sig, current);
++}
++
++/*
++ * Note that 'init' is a special process: it doesn't get signals it
++ * doesn't want to handle. Thus you cannot kill init even with a
++ * SIGKILL even by mistake.
++ */
++int do_signal(struct pt_regs *regs, sigset_t *oldset, int syscall)
++{
++      siginfo_t info;
++      int signr;
++      struct k_sigaction ka;
++
++      /*
++       * We want the common case to go fast, which is why we may in
++       * certain cases get here from kernel mode. Just return
++       * without doing anything if so.
++       */
++      if (!user_mode(regs))
++              return 0;
++
++      if (try_to_freeze()) {
++              signr = 0;
++              if (!signal_pending(current))
++                      goto no_signal;
++      }
++
++      if (test_thread_flag(TIF_RESTORE_SIGMASK))
++              oldset = &current->saved_sigmask;
++      else if (!oldset)
++              oldset = &current->blocked;
++
++      signr = get_signal_to_deliver(&info, &ka, regs, NULL);
++no_signal:
++      if (syscall) {
++              switch (regs->r12) {
++              case -ERESTART_RESTARTBLOCK:
++              case -ERESTARTNOHAND:
++                      if (signr > 0) {
++                              regs->r12 = -EINTR;
++                              break;
++                      }
++                      /* fall through */
++              case -ERESTARTSYS:
++                      if (signr > 0 && !(ka.sa.sa_flags & SA_RESTART)) {
++                              regs->r12 = -EINTR;
++                              break;
++                      }
++                      /* fall through */
++              case -ERESTARTNOINTR:
++                      restart_syscall(regs);
++              }
++      }
++
++      if (signr == 0) {
++              /* No signal to deliver -- put the saved sigmask back */
++              if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
++                      clear_thread_flag(TIF_RESTORE_SIGMASK);
++                      sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
++              }
++              return 0;
++      }
++
++      handle_signal(signr, &ka, &info, oldset, regs, syscall);
++      return 1;
++}
++
++asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti)
++{
++      int syscall = 0;
++
++      if ((sysreg_read(SR) & MODE_MASK) == MODE_SUPERVISOR)
++              syscall = 1;
++
++      if (ti->flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
++              do_signal(regs, &current->blocked, syscall);
++}
+Index: linux-2.6.18-avr32/arch/avr32/kernel/switch_to.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/switch_to.S   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,35 @@
++/*
++ * 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 <asm/sysreg.h>
++
++      .text
++      .global __switch_to
++      .type   __switch_to, @function
++
++      /* Switch thread context from "prev" to "next", returning "last"
++       *   r12 :      prev
++       *   r11 :      &prev->thread + 1
++       *   r10 :      &next->thread
++       */
++__switch_to:
++      stm     --r11, r0,r1,r2,r3,r4,r5,r6,r7,sp,lr
++      mfsr    r9, SYSREG_SR
++      st.w    --r11, r9
++      ld.w    r8, r10++
++      /*
++       * schedule() may have been called from a mode with a different
++       * set of registers. Make sure we don't lose anything here.
++       */
++      pushm   r10,r12
++      mtsr    SYSREG_SR, r8
++      frs                     /* flush the return stack */
++      sub     pc, -2          /* flush the pipeline */
++      popm    r10,r12
++      ldm     r10++, r0,r1,r2,r3,r4,r5,r6,r7,sp,pc
++      .size   __switch_to, . - __switch_to
+Index: linux-2.6.18-avr32/arch/avr32/kernel/sys_avr32.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/sys_avr32.c   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,51 @@
++/*
++ * 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/errno.h>
++#include <linux/fs.h>
++#include <linux/file.h>
++#include <linux/mm.h>
++#include <linux/unistd.h>
++
++#include <asm/mman.h>
++#include <asm/uaccess.h>
++
++asmlinkage int sys_pipe(unsigned long __user *filedes)
++{
++      int fd[2];
++      int error;
++
++      error = do_pipe(fd);
++      if (!error) {
++              if (copy_to_user(filedes, fd, sizeof(fd)))
++                      error = -EFAULT;
++      }
++      return error;
++}
++
++asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
++                        unsigned long prot, unsigned long flags,
++                        unsigned long fd, off_t offset)
++{
++      int error = -EBADF;
++      struct file *file = NULL;
++
++      flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
++      if (!(flags & MAP_ANONYMOUS)) {
++              file = fget(fd);
++              if (!file)
++                      return error;
++      }
++
++      down_write(&current->mm->mmap_sem);
++      error = do_mmap_pgoff(file, addr, len, prot, flags, offset);
++      up_write(&current->mm->mmap_sem);
++
++      if (file)
++              fput(file);
++      return error;
++}
+Index: linux-2.6.18-avr32/arch/avr32/kernel/syscall-stubs.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/syscall-stubs.S       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,102 @@
++/*
++ * 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.
++ */
++
++/*
++ * Stubs for syscalls that require access to pt_regs or that take more
++ * than five parameters.
++ */
++
++#define ARG6  r3
++
++      .text
++      .global __sys_rt_sigsuspend
++      .type   __sys_rt_sigsuspend,@function
++__sys_rt_sigsuspend:
++      mov     r10, sp
++      rjmp    sys_rt_sigsuspend
++
++      .global __sys_sigaltstack
++      .type   __sys_sigaltstack,@function
++__sys_sigaltstack:
++      mov     r10, sp
++      rjmp    sys_sigaltstack
++
++      .global __sys_rt_sigreturn
++      .type   __sys_rt_sigreturn,@function
++__sys_rt_sigreturn:
++      mov     r12, sp
++      rjmp    sys_rt_sigreturn
++
++      .global __sys_fork
++      .type   __sys_fork,@function
++__sys_fork:
++      mov     r12, sp
++      rjmp    sys_fork
++
++      .global __sys_clone
++      .type   __sys_clone,@function
++__sys_clone:
++      mov     r8, sp
++      rjmp    sys_clone
++
++      .global __sys_vfork
++      .type   __sys_vfork,@function
++__sys_vfork:
++      mov     r12, sp
++      rjmp    sys_vfork
++
++      .global __sys_execve
++      .type   __sys_execve,@function
++__sys_execve:
++      mov     r9, sp
++      rjmp    sys_execve
++
++      .global __sys_mmap2
++      .type   __sys_mmap2,@function
++__sys_mmap2:
++      pushm   lr
++      st.w    --sp, ARG6
++      rcall   sys_mmap2
++      sub     sp, -4
++      popm    pc
++
++      .global __sys_sendto
++      .type   __sys_sendto,@function
++__sys_sendto:
++      pushm   lr
++      st.w    --sp, ARG6
++      rcall   sys_sendto
++      sub     sp, -4
++      popm    pc
++
++      .global __sys_recvfrom
++      .type   __sys_recvfrom,@function
++__sys_recvfrom:
++      pushm   lr
++      st.w    --sp, ARG6
++      rcall   sys_recvfrom
++      sub     sp, -4
++      popm    pc
++
++      .global __sys_pselect6
++      .type   __sys_pselect6,@function
++__sys_pselect6:
++      pushm   lr
++      st.w    --sp, ARG6
++      rcall   sys_pselect6
++      sub     sp, -4
++      popm    pc
++
++      .global __sys_splice
++      .type   __sys_splice,@function
++__sys_splice:
++      pushm   lr
++      st.w    --sp, ARG6
++      rcall   sys_splice
++      sub     sp, -4
++      popm    pc
+Index: linux-2.6.18-avr32/arch/avr32/kernel/syscall_table.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/syscall_table.S       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,289 @@
++/*
++ * AVR32 system call table
++ *
++ * 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.
++ */
++
++#if !defined(CONFIG_NFSD) && !defined(CONFIG_NFSD_MODULE)
++#define sys_nfsservctl sys_ni_syscall
++#endif
++
++#if !defined(CONFIG_SYSV_IPC)
++# define sys_ipc      sys_ni_syscall
++#endif
++
++      .section .rodata,"a",@progbits
++      .type   sys_call_table,@object
++      .global sys_call_table
++      .align  2
++sys_call_table:
++      .long   sys_restart_syscall
++      .long   sys_exit
++      .long   __sys_fork
++      .long   sys_read
++      .long   sys_write
++      .long   sys_open                /* 5 */
++      .long   sys_close
++      .long   sys_umask
++      .long   sys_creat
++      .long   sys_link
++      .long   sys_unlink              /* 10 */
++      .long   __sys_execve
++      .long   sys_chdir
++      .long   sys_time
++      .long   sys_mknod
++      .long   sys_chmod               /* 15 */
++      .long   sys_chown
++      .long   sys_lchown
++      .long   sys_lseek
++      .long   sys_llseek
++      .long   sys_getpid              /* 20 */
++      .long   sys_mount
++      .long   sys_umount
++      .long   sys_setuid
++      .long   sys_getuid
++      .long   sys_stime               /* 25 */
++      .long   sys_ptrace
++      .long   sys_alarm
++      .long   sys_pause
++      .long   sys_utime
++      .long   sys_newstat             /* 30 */
++      .long   sys_newfstat
++      .long   sys_newlstat
++      .long   sys_access
++      .long   sys_chroot
++      .long   sys_sync                /* 35 */
++      .long   sys_fsync
++      .long   sys_kill
++      .long   sys_rename
++      .long   sys_mkdir
++      .long   sys_rmdir               /* 40 */
++      .long   sys_dup
++      .long   sys_pipe
++      .long   sys_times
++      .long   __sys_clone
++      .long   sys_brk                 /* 45 */
++      .long   sys_setgid
++      .long   sys_getgid
++      .long   sys_getcwd
++      .long   sys_geteuid
++      .long   sys_getegid             /* 50 */
++      .long   sys_acct
++      .long   sys_setfsuid
++      .long   sys_setfsgid
++      .long   sys_ioctl
++      .long   sys_fcntl               /* 55 */
++      .long   sys_setpgid
++      .long   sys_mremap
++      .long   sys_setresuid
++      .long   sys_getresuid
++      .long   sys_setreuid            /* 60 */
++      .long   sys_setregid
++      .long   sys_ustat
++      .long   sys_dup2
++      .long   sys_getppid
++      .long   sys_getpgrp             /* 65 */
++      .long   sys_setsid
++      .long   sys_rt_sigaction
++      .long   __sys_rt_sigreturn
++      .long   sys_rt_sigprocmask
++      .long   sys_rt_sigpending       /* 70 */
++      .long   sys_rt_sigtimedwait
++      .long   sys_rt_sigqueueinfo
++      .long   __sys_rt_sigsuspend
++      .long   sys_sethostname
++      .long   sys_setrlimit           /* 75 */
++      .long   sys_getrlimit
++      .long   sys_getrusage
++      .long   sys_gettimeofday
++      .long   sys_settimeofday
++      .long   sys_getgroups           /* 80 */
++      .long   sys_setgroups
++      .long   sys_select
++      .long   sys_symlink
++      .long   sys_fchdir
++      .long   sys_readlink            /* 85 */
++      .long   sys_pread64
++      .long   sys_pwrite64
++      .long   sys_swapon
++      .long   sys_reboot
++      .long   __sys_mmap2             /* 90 */
++      .long   sys_munmap
++      .long   sys_truncate
++      .long   sys_ftruncate
++      .long   sys_fchmod
++      .long   sys_fchown              /* 95 */
++      .long   sys_getpriority
++      .long   sys_setpriority
++      .long   sys_wait4
++      .long   sys_statfs
++      .long   sys_fstatfs             /* 100 */
++      .long   sys_vhangup
++      .long   __sys_sigaltstack
++      .long   sys_syslog
++      .long   sys_setitimer
++      .long   sys_getitimer           /* 105 */
++      .long   sys_swapoff
++      .long   sys_sysinfo
++      .long   sys_ipc
++      .long   sys_sendfile
++      .long   sys_setdomainname       /* 110 */
++      .long   sys_newuname
++      .long   sys_adjtimex
++      .long   sys_mprotect
++      .long   __sys_vfork
++      .long   sys_init_module         /* 115 */
++      .long   sys_delete_module
++      .long   sys_quotactl
++      .long   sys_getpgid
++      .long   sys_bdflush
++      .long   sys_sysfs               /* 120 */
++      .long   sys_personality
++      .long   sys_ni_syscall          /* reserved for afs_syscall */
++      .long   sys_getdents
++      .long   sys_flock
++      .long   sys_msync               /* 125 */
++      .long   sys_readv
++      .long   sys_writev
++      .long   sys_getsid
++      .long   sys_fdatasync
++      .long   sys_sysctl              /* 130 */
++      .long   sys_mlock
++      .long   sys_munlock
++      .long   sys_mlockall
++      .long   sys_munlockall
++      .long   sys_sched_setparam              /* 135 */
++      .long   sys_sched_getparam
++      .long   sys_sched_setscheduler
++      .long   sys_sched_getscheduler
++      .long   sys_sched_yield
++      .long   sys_sched_get_priority_max      /* 140 */
++      .long   sys_sched_get_priority_min
++      .long   sys_sched_rr_get_interval
++      .long   sys_nanosleep
++      .long   sys_poll
++      .long   sys_nfsservctl          /* 145 */
++      .long   sys_setresgid
++      .long   sys_getresgid
++      .long   sys_prctl
++      .long   sys_socket
++      .long   sys_bind                /* 150 */
++      .long   sys_connect
++      .long   sys_listen
++      .long   sys_accept
++      .long   sys_getsockname
++      .long   sys_getpeername         /* 155 */
++      .long   sys_socketpair
++      .long   sys_send
++      .long   sys_recv
++      .long   __sys_sendto
++      .long   __sys_recvfrom          /* 160 */
++      .long   sys_shutdown
++      .long   sys_setsockopt
++      .long   sys_getsockopt
++      .long   sys_sendmsg
++      .long   sys_recvmsg             /* 165 */
++      .long   sys_truncate64
++      .long   sys_ftruncate64
++      .long   sys_stat64
++      .long   sys_lstat64
++      .long   sys_fstat64             /* 170 */
++      .long   sys_pivot_root
++      .long   sys_mincore
++      .long   sys_madvise
++      .long   sys_getdents64
++      .long   sys_fcntl64             /* 175 */
++      .long   sys_gettid
++      .long   sys_readahead
++      .long   sys_setxattr
++      .long   sys_lsetxattr
++      .long   sys_fsetxattr           /* 180 */
++      .long   sys_getxattr
++      .long   sys_lgetxattr
++      .long   sys_fgetxattr
++      .long   sys_listxattr
++      .long   sys_llistxattr          /* 185 */
++      .long   sys_flistxattr
++      .long   sys_removexattr
++      .long   sys_lremovexattr
++      .long   sys_fremovexattr
++      .long   sys_tkill               /* 190 */
++      .long   sys_sendfile64
++      .long   sys_futex
++      .long   sys_sched_setaffinity
++      .long   sys_sched_getaffinity
++      .long   sys_capget              /* 195 */
++      .long   sys_capset
++      .long   sys_io_setup
++      .long   sys_io_destroy
++      .long   sys_io_getevents
++      .long   sys_io_submit           /* 200 */
++      .long   sys_io_cancel
++      .long   sys_fadvise64
++      .long   sys_exit_group
++      .long   sys_lookup_dcookie
++      .long   sys_epoll_create        /* 205 */
++      .long   sys_epoll_ctl
++      .long   sys_epoll_wait
++      .long   sys_remap_file_pages
++      .long   sys_set_tid_address
++      .long   sys_timer_create        /* 210 */
++      .long   sys_timer_settime
++      .long   sys_timer_gettime
++      .long   sys_timer_getoverrun
++      .long   sys_timer_delete
++      .long   sys_clock_settime       /* 215 */
++      .long   sys_clock_gettime
++      .long   sys_clock_getres
++      .long   sys_clock_nanosleep
++      .long   sys_statfs64
++      .long   sys_fstatfs64           /* 220 */
++      .long   sys_tgkill
++      .long   sys_ni_syscall          /* reserved for TUX */
++      .long   sys_utimes
++      .long   sys_fadvise64_64
++      .long   sys_cacheflush          /* 225 */
++      .long   sys_ni_syscall          /* sys_vserver */
++      .long   sys_mq_open
++      .long   sys_mq_unlink
++      .long   sys_mq_timedsend
++      .long   sys_mq_timedreceive     /* 230 */
++      .long   sys_mq_notify
++      .long   sys_mq_getsetattr
++      .long   sys_kexec_load
++      .long   sys_waitid
++      .long   sys_add_key             /* 235 */
++      .long   sys_request_key
++      .long   sys_keyctl
++      .long   sys_ioprio_set
++      .long   sys_ioprio_get
++      .long   sys_inotify_init        /* 240 */
++      .long   sys_inotify_add_watch
++      .long   sys_inotify_rm_watch
++      .long   sys_openat
++      .long   sys_mkdirat
++      .long   sys_mknodat             /* 245 */
++      .long   sys_fchownat
++      .long   sys_futimesat
++      .long   sys_fstatat64
++      .long   sys_unlinkat
++      .long   sys_renameat            /* 250 */
++      .long   sys_linkat
++      .long   sys_symlinkat
++      .long   sys_readlinkat
++      .long   sys_fchmodat
++      .long   sys_faccessat           /* 255 */
++      .long   __sys_pselect6
++      .long   sys_ppoll
++      .long   sys_unshare
++      .long   sys_set_robust_list
++      .long   sys_get_robust_list     /* 260 */
++      .long   __sys_splice
++      .long   sys_sync_file_range
++      .long   sys_tee
++      .long   sys_vmsplice
++      .long   sys_ni_syscall          /* r8 is saturated at nr_syscalls */
+Index: linux-2.6.18-avr32/arch/avr32/kernel/time.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/time.c        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,238 @@
++/*
++ * Copyright (C) 2004-2006 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 <asm/div64.h>
++#include <asm/sysreg.h>
++#include <asm/io.h>
++#include <asm/sections.h>
++
++static cycle_t read_cycle_count(void)
++{
++      return (cycle_t)sysreg_read(COUNT);
++}
++
++static struct clocksource clocksource_avr32 = {
++      .name           = "avr32",
++      .rating         = 350,
++      .read           = read_cycle_count,
++      .mask           = CLOCKSOURCE_MASK(32),
++      .shift          = 16,
++      .is_continuous  = 1,
++};
++
++/*
++ * By default we provide the null RTC ops
++ */
++static unsigned long null_rtc_get_time(void)
++{
++      return mktime(2004, 1, 1, 0, 0, 0);
++}
++
++static int null_rtc_set_time(unsigned long sec)
++{
++      return 0;
++}
++
++static unsigned long (*rtc_get_time)(void) = null_rtc_get_time;
++static int (*rtc_set_time)(unsigned long) = null_rtc_set_time;
++
++/* how many counter cycles in a jiffy? */
++static unsigned long cycles_per_jiffy;
++
++/* cycle counter value at the previous timer interrupt */
++static unsigned int timerhi, timerlo;
++
++/* the count value for the next timer interrupt */
++static unsigned int expirelo;
++
++static void avr32_timer_ack(void)
++{
++      unsigned int count;
++
++      /* Ack this timer interrupt and set the next one */
++      expirelo += cycles_per_jiffy;
++      if (expirelo == 0) {
++              printk(KERN_DEBUG "expirelo == 0\n");
++              sysreg_write(COMPARE, expirelo + 1);
++      } else {
++              sysreg_write(COMPARE, expirelo);
++      }
++
++      /* 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);
++      }
++}
++
++static unsigned int avr32_hpt_read(void)
++{
++      return sysreg_read(COUNT);
++}
++
++/*
++ * Taken from MIPS c0_hpt_timer_init().
++ *
++ * Why is it so complicated, and what is "count"?  My assumption is
++ * that `count' specifies the "reference cycle", i.e. the cycle since
++ * reset that should mean "zero". 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.
++ */
++static void avr32_hpt_init(unsigned int count)
++{
++      count = sysreg_read(COUNT) - 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);
++}
++
++/*
++ * Scheduler clock - returns current time in nanosec units.
++ */
++unsigned long long sched_clock(void)
++{
++      /* There must be better ways...? */
++      return (unsigned long long)jiffies * (1000000000 / HZ);
++}
++
++/*
++ * local_timer_interrupt() does profiling and process accounting on a
++ * per-CPU basis.
++ *
++ * In UP mode, it is invoked from the (global) timer_interrupt.
++ */
++static void local_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++      if (current->pid)
++              profile_tick(CPU_PROFILING, regs);
++      update_process_times(user_mode(regs));
++}
++
++static irqreturn_t
++timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++{
++      unsigned int count;
++
++      /* ack timer interrupt and try to set next interrupt */
++      count = avr32_hpt_read();
++      avr32_timer_ack();
++
++      /* Update timerhi/timerlo for intra-jiffy calibration */
++      timerhi += count < timerlo;     /* Wrap around */
++      timerlo = count;
++
++      /*
++       * Call the generic timer interrupt handler
++       */
++      write_seqlock(&xtime_lock);
++      do_timer(regs);
++      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, regs);
++
++      return IRQ_HANDLED;
++}
++
++static struct irqaction timer_irqaction = {
++      .handler        = timer_interrupt,
++      .flags          = IRQF_DISABLED,
++      .name           = "timer",
++};
++
++void __init time_init(void)
++{
++      unsigned long mult, shift, count_hz;
++      int ret;
++
++      xtime.tv_sec = rtc_get_time();
++      xtime.tv_nsec = 0;
++
++      set_normalized_timespec(&wall_to_monotonic,
++                              -xtime.tv_sec, -xtime.tv_nsec);
++
++      printk("Before time_init: count=%08lx, compare=%08lx\n",
++             (unsigned long)sysreg_read(COUNT),
++             (unsigned long)sysreg_read(COMPARE));
++
++      count_hz = clk_get_rate(boot_cpu_data.clk);
++      shift = clocksource_avr32.shift;
++      mult = clocksource_hz2mult(count_hz, shift);
++      clocksource_avr32.mult = mult;
++
++      printk("Cycle counter: mult=%lu, shift=%lu\n", mult, shift);
++
++      {
++              u64 tmp;
++
++              tmp = TICK_NSEC;
++              tmp <<= shift;
++              tmp += mult / 2;
++              do_div(tmp, mult);
++
++              cycles_per_jiffy = tmp;
++      }
++
++      /* This sets up the high precision timer for the first interrupt. */
++      avr32_hpt_init(avr32_hpt_read());
++
++      printk("After time_init: count=%08lx, compare=%08lx\n",
++             (unsigned long)sysreg_read(COUNT),
++             (unsigned long)sysreg_read(COMPARE));
++
++      ret = clocksource_register(&clocksource_avr32);
++      if (ret)
++              printk(KERN_ERR
++                     "timer: could not register clocksource: %d\n", ret);
++
++      ret = setup_irq(0, &timer_irqaction);
++      if (ret)
++              printk("timer: could not request IRQ 0: %d\n", ret);
++}
++
++static struct sysdev_class timer_class = {
++      set_kset_name("timer"),
++};
++
++static struct sys_device timer_device = {
++      .id     = 0,
++      .cls    = &timer_class,
++};
++
++static int __init init_timer_sysfs(void)
++{
++      int err = sysdev_class_register(&timer_class);
++      if (!err)
++              err = sysdev_register(&timer_device);
++      return err;
++}
++
++device_initcall(init_timer_sysfs);
+Index: linux-2.6.18-avr32/arch/avr32/kernel/traps.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/traps.c       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,425 @@
++/*
++ * 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.
++ */
++#undef DEBUG
++#include <linux/sched.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/kallsyms.h>
++#include <linux/notifier.h>
++
++#include <asm/traps.h>
++#include <asm/sysreg.h>
++#include <asm/addrspace.h>
++#include <asm/ocd.h>
++#include <asm/mmu_context.h>
++#include <asm/uaccess.h>
++
++static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
++{
++      unsigned long p;
++      int i;
++
++      printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top);
++
++      for (p = bottom & ~31; p < top; ) {
++              printk("%04lx: ", p & 0xffff);
++
++              for (i = 0; i < 8; i++, p += 4) {
++                      unsigned int val;
++
++                      if (p < bottom || p >= top)
++                              printk("         ");
++                      else {
++                              if (__get_user(val, (unsigned int __user *)p)) {
++                                      printk("\n");
++                                      goto out;
++                              }
++                              printk("%08x ", val);
++                      }
++              }
++              printk("\n");
++      }
++
++out:
++      return;
++}
++
++#ifdef CONFIG_FRAME_POINTER
++static inline void __show_trace(struct task_struct *tsk, unsigned long *sp,
++                              struct pt_regs *regs)
++{
++      unsigned long __user *fp;
++      unsigned long __user *last_fp = NULL;
++
++      if (regs) {
++              fp = (unsigned long __user *)regs->r7;
++      } else if (tsk == current) {
++              register unsigned long __user *real_fp __asm__("r7");
++              fp = real_fp;
++      } else {
++              fp = (unsigned long __user *)tsk->thread.cpu_context.r7;
++      }
++
++      /*
++       * Walk the stack until (a) we get an exception, (b) the frame
++       * pointer becomes zero, or (c) the frame pointer gets stuck
++       * at the same value.
++       */
++      while (fp && fp != last_fp) {
++              unsigned long lr, new_fp = 0;
++
++              last_fp = fp;
++              if (__get_user(lr, fp))
++                      break;
++              if (fp && __get_user(new_fp, fp + 1))
++                      break;
++              fp = (unsigned long __user *)new_fp;
++
++              printk(" [<%08lx>] ", lr);
++              print_symbol("%s\n", lr);
++      }
++      printk("\n");
++}
++#else
++static inline void __show_trace(struct task_struct *tsk, unsigned long *sp,
++                              struct pt_regs *regs)
++{
++      unsigned long addr;
++
++      while (!kstack_end(sp)) {
++              addr = *sp++;
++              if (kernel_text_address(addr)) {
++                      printk(" [<%08lx>] ", addr);
++                      print_symbol("%s\n", addr);
++              }
++      }
++}
++#endif
++
++void show_trace(struct task_struct *tsk, unsigned long *sp,
++                     struct pt_regs *regs)
++{
++      if (regs &&
++          (((regs->sr & MODE_MASK) == MODE_EXCEPTION) ||
++           ((regs->sr & MODE_MASK) == MODE_USER)))
++              return;
++
++      printk ("Call trace:");
++#ifdef CONFIG_KALLSYMS
++      printk("\n");
++#endif
++
++      __show_trace(tsk, sp, regs);
++      printk("\n");
++}
++
++void show_stack(struct task_struct *tsk, unsigned long *sp)
++{
++      unsigned long stack;
++
++      if (!tsk)
++              tsk = current;
++      if (sp == 0) {
++              if (tsk == current) {
++                      register unsigned long *real_sp __asm__("sp");
++                      sp = real_sp;
++              } else {
++                      sp = (unsigned long *)tsk->thread.cpu_context.ksp;
++              }
++      }
++
++      stack = (unsigned long)sp;
++      dump_mem("Stack: ", stack,
++               THREAD_SIZE + (unsigned long)tsk->thread_info);
++      show_trace(tsk, sp, NULL);
++}
++
++void dump_stack(void)
++{
++      show_stack(NULL, NULL);
++}
++EXPORT_SYMBOL(dump_stack);
++
++ATOMIC_NOTIFIER_HEAD(avr32_die_chain);
++
++int register_die_notifier(struct notifier_block *nb)
++{
++      pr_debug("register_die_notifier: %p\n", nb);
++
++      return atomic_notifier_chain_register(&avr32_die_chain, nb);
++}
++EXPORT_SYMBOL(register_die_notifier);
++
++int unregister_die_notifier(struct notifier_block *nb)
++{
++      return atomic_notifier_chain_unregister(&avr32_die_chain, nb);
++}
++EXPORT_SYMBOL(unregister_die_notifier);
++
++static DEFINE_SPINLOCK(die_lock);
++
++void __die(const char *str, struct pt_regs *regs, unsigned long err,
++         const char *file, const char *func, unsigned long line)
++{
++      struct task_struct *tsk = current;
++      static int die_counter;
++
++      console_verbose();
++      spin_lock_irq(&die_lock);
++      bust_spinlocks(1);
++
++      printk(KERN_ALERT "%s", str);
++      if (file && func)
++              printk(" in %s:%s, line %ld", file, func, line);
++      printk("[#%d]:\n", ++die_counter);
++      print_modules();
++      show_regs(regs);
++      printk("Process %s (pid: %d, stack limit = 0x%p)\n",
++             tsk->comm, tsk->pid, tsk->thread_info + 1);
++
++      if (!user_mode(regs) || in_interrupt()) {
++              dump_mem("Stack: ", regs->sp,
++                       THREAD_SIZE + (unsigned long)tsk->thread_info);
++      }
++
++      bust_spinlocks(0);
++      spin_unlock_irq(&die_lock);
++      do_exit(SIGSEGV);
++}
++
++void __die_if_kernel(const char *str, struct pt_regs *regs, unsigned long err,
++                   const char *file, const char *func, unsigned long line)
++{
++      if (!user_mode(regs))
++              __die(str, regs, err, file, func, line);
++}
++
++asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs)
++{
++#ifdef CONFIG_SUBARCH_AVR32B
++      /*
++       * The exception entry always saves RSR_EX. For NMI, this is
++       * wrong; it should be RSR_NMI
++       */
++      regs->sr = sysreg_read(RSR_NMI);
++#endif
++
++      printk("NMI taken!!!!\n");
++      die("NMI", regs, ecr);
++      BUG();
++}
++
++asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs)
++{
++      printk("Unable to handle critical exception %lu at pc = %08lx!\n",
++             ecr, regs->pc);
++      die("Oops", regs, ecr);
++      BUG();
++}
++
++asmlinkage void do_address_exception(unsigned long ecr, struct pt_regs *regs)
++{
++      siginfo_t info;
++
++      die_if_kernel("Oops: Address exception in kernel mode", regs, ecr);
++
++#ifdef DEBUG
++      if (ecr == ECR_ADDR_ALIGN_X)
++              pr_debug("Instruction Address Exception at pc = %08lx\n",
++                       regs->pc);
++      else if (ecr == ECR_ADDR_ALIGN_R)
++              pr_debug("Data Address Exception (Read) at pc = %08lx\n",
++                       regs->pc);
++      else if (ecr == ECR_ADDR_ALIGN_W)
++              pr_debug("Data Address Exception (Write) at pc = %08lx\n",
++                       regs->pc);
++      else
++              BUG();
++
++      show_regs(regs);
++#endif
++
++      info.si_signo = SIGBUS;
++      info.si_errno = 0;
++      info.si_code = BUS_ADRALN;
++      info.si_addr = (void __user *)regs->pc;
++
++      force_sig_info(SIGBUS, &info, current);
++}
++
++/* This way of handling undefined instructions is stolen from ARM */
++static LIST_HEAD(undef_hook);
++static spinlock_t undef_lock = SPIN_LOCK_UNLOCKED;
++
++void register_undef_hook(struct undef_hook *hook)
++{
++      spin_lock_irq(&undef_lock);
++      list_add(&hook->node, &undef_hook);
++      spin_unlock_irq(&undef_lock);
++}
++
++void unregister_undef_hook(struct undef_hook *hook)
++{
++      spin_lock_irq(&undef_lock);
++      list_del(&hook->node);
++      spin_unlock_irq(&undef_lock);
++}
++
++static int do_cop_absent(u32 insn)
++{
++      int cop_nr;
++      u32 cpucr;
++      if ( (insn & 0xfdf00000) == 0xf1900000 )
++              /* LDC0 */
++              cop_nr = 0;
++      else
++              cop_nr = (insn >> 13) & 0x7;
++
++      /* Try enabling the coprocessor */
++      cpucr = sysreg_read(CPUCR);
++      cpucr |= (1 << (24 + cop_nr));
++      sysreg_write(CPUCR, cpucr);
++
++      cpucr = sysreg_read(CPUCR);
++      if ( !(cpucr & (1 << (24 + cop_nr))) ){
++              printk("Coprocessor #%i not found!\n", cop_nr);
++              return -1;
++      }
++
++      return 0;
++}
++
++#ifdef CONFIG_BUG
++#ifdef CONFIG_DEBUG_BUGVERBOSE
++static inline void do_bug_verbose(struct pt_regs *regs, u32 insn)
++{
++      char *file;
++      u16 line;
++      char c;
++
++      if (__get_user(line, (u16 __user *)(regs->pc + 2)))
++              return;
++      if (__get_user(file, (char * __user *)(regs->pc + 4))
++          || (unsigned long)file < PAGE_OFFSET
++          || __get_user(c, file))
++              file = "<bad filename>";
++
++      printk(KERN_ALERT "kernel BUG at %s:%d!\n", file, line);
++}
++#else
++static inline void do_bug_verbose(struct pt_regs *regs, u32 insn)
++{
++
++}
++#endif
++#endif
++
++asmlinkage void do_illegal_opcode(unsigned long ecr, struct pt_regs *regs)
++{
++      u32 insn;
++      struct undef_hook *hook;
++      siginfo_t info;
++      void __user *pc;
++
++      if (!user_mode(regs))
++              goto kernel_trap;
++
++      local_irq_enable();
++
++      pc = (void __user *)instruction_pointer(regs);
++      if (__get_user(insn, (u32 __user *)pc))
++              goto invalid_area;
++
++        if (ecr == ECR_COPROC_ABSENT) {
++              if (do_cop_absent(insn) == 0)
++                      return;
++        }
++
++      spin_lock_irq(&undef_lock);
++      list_for_each_entry(hook, &undef_hook, node) {
++              if ((insn & hook->insn_mask) == hook->insn_val) {
++                      if (hook->fn(regs, insn) == 0) {
++                              spin_unlock_irq(&undef_lock);
++                              return;
++                      }
++              }
++      }
++      spin_unlock_irq(&undef_lock);
++
++invalid_area:
++
++#ifdef DEBUG
++      printk("Illegal instruction at pc = %08lx\n", regs->pc);
++      if (regs->pc < TASK_SIZE) {
++              unsigned long ptbr, pgd, pte, *p;
++
++              ptbr = sysreg_read(PTBR);
++              p = (unsigned long *)ptbr;
++              pgd = p[regs->pc >> 22];
++              p = (unsigned long *)((pgd & 0x1ffff000) | 0x80000000);
++              pte = p[(regs->pc >> 12) & 0x3ff];
++              printk("page table: 0x%08lx -> 0x%08lx -> 0x%08lx\n", ptbr, pgd, pte);
++      }
++#endif
++
++      info.si_signo = SIGILL;
++      info.si_errno = 0;
++      info.si_addr = (void __user *)regs->pc;
++      switch (ecr) {
++      case ECR_ILLEGAL_OPCODE:
++      case ECR_UNIMPL_INSTRUCTION:
++              info.si_code = ILL_ILLOPC;
++              break;
++      case ECR_PRIVILEGE_VIOLATION:
++              info.si_code = ILL_PRVOPC;
++              break;
++      case ECR_COPROC_ABSENT:
++              info.si_code = ILL_COPROC;
++              break;
++      default:
++              BUG();
++      }
++
++      force_sig_info(SIGILL, &info, current);
++      return;
++
++kernel_trap:
++#ifdef CONFIG_BUG
++      if (__kernel_text_address(instruction_pointer(regs))) {
++              insn = *(u16 *)instruction_pointer(regs);
++              if (insn == AVR32_BUG_OPCODE) {
++                      do_bug_verbose(regs, insn);
++                      die("Kernel BUG", regs, 0);
++                      return;
++              }
++      }
++#endif
++
++      die("Oops: Illegal instruction in kernel code", regs, ecr);
++}
++
++asmlinkage void do_fpe(unsigned long ecr, struct pt_regs *regs)
++{
++      siginfo_t info;
++
++      printk("Floating-point exception at pc = %08lx\n", regs->pc);
++
++      /* We have no FPU... */
++      info.si_signo = SIGILL;
++      info.si_errno = 0;
++      info.si_addr = (void __user *)regs->pc;
++      info.si_code = ILL_COPROC;
++
++      force_sig_info(SIGILL, &info, current);
++}
++
++
++void __init trap_init(void)
++{
++
++}
+Index: linux-2.6.18-avr32/arch/avr32/kernel/vmlinux.lds.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/kernel/vmlinux.lds.c 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,139 @@
++/*
++ * AVR32 linker script for the Linux kernel
++ *
++ * 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.
++ */
++#define LOAD_OFFSET 0x00000000
++#include <asm-generic/vmlinux.lds.h>
++
++OUTPUT_FORMAT("elf32-avr32", "elf32-avr32", "elf32-avr32")
++OUTPUT_ARCH(avr32)
++ENTRY(_start)
++
++/* Big endian */
++jiffies = jiffies_64 + 4;
++
++SECTIONS
++{
++      . = CONFIG_ENTRY_ADDRESS;
++      .init           : AT(ADDR(.init) - LOAD_OFFSET) {
++              _stext = .;
++              __init_begin = .;
++                      _sinittext = .;
++                      *(.text.reset)
++                      *(.init.text)
++                      _einittext = .;
++              . = ALIGN(4);
++              __tagtable_begin = .;
++                      *(.taglist)
++              __tagtable_end = .;
++                      *(.init.data)
++              . = ALIGN(16);
++              __setup_start = .;
++                      *(.init.setup)
++              __setup_end = .;
++              . = ALIGN(4);
++              __initcall_start = .;
++                      *(.initcall1.init)
++                      *(.initcall2.init)
++                      *(.initcall3.init)
++                      *(.initcall4.init)
++                      *(.initcall5.init)
++                      *(.initcall6.init)
++                      *(.initcall7.init)
++              __initcall_end = .;
++              __con_initcall_start = .;
++                      *(.con_initcall.init)
++              __con_initcall_end = .;
++              __security_initcall_start = .;
++                      *(.security_initcall.init)
++              __security_initcall_end = .;
++              . = ALIGN(32);
++              __initramfs_start = .;
++                      *(.init.ramfs)
++              __initramfs_end = .;
++              . = ALIGN(4096);
++              __init_end = .;
++      }
++
++      . = ALIGN(8192);
++      .text           : AT(ADDR(.text) - LOAD_OFFSET) {
++              _evba = .;
++              _text = .;
++              *(.ex.text)
++              . = 0x50;
++              *(.tlbx.ex.text)
++              . = 0x60;
++              *(.tlbr.ex.text)
++              . = 0x70;
++              *(.tlbw.ex.text)
++              . = 0x100;
++              *(.scall.text)
++              *(.irq.text)
++              *(.text)
++              SCHED_TEXT
++              LOCK_TEXT
++              KPROBES_TEXT
++              *(.fixup)
++              *(.gnu.warning)
++              _etext = .;
++      } = 0xd703d703
++
++      . = ALIGN(4);
++      __ex_table      : AT(ADDR(__ex_table) - LOAD_OFFSET) {
++              __start___ex_table = .;
++              *(__ex_table)
++              __stop___ex_table = .;
++      }
++
++      RODATA
++
++      . = ALIGN(8192);
++
++      .data           : AT(ADDR(.data) - LOAD_OFFSET) {
++              _data = .;
++              _sdata = .;
++              /*
++               * First, the init task union, aligned to an 8K boundary.
++               */
++              *(.data.init_task)
++
++              /* Then, the cacheline aligned data */
++              . = ALIGN(32);
++              *(.data.cacheline_aligned)
++
++              /* And the rest... */
++              *(.data.rel*)
++              *(.data)
++              CONSTRUCTORS
++
++              _edata = .;
++      }
++
++
++      . = ALIGN(8);
++      .bss            : AT(ADDR(.bss) - LOAD_OFFSET) {
++              __bss_start = .;
++              *(.bss)
++              *(COMMON)
++              . = ALIGN(8);
++              __bss_stop = .;
++              _end = .;
++      }
++
++      /* When something in the kernel is NOT compiled as a module, the module
++       * cleanup code and data are put into these segments. Both can then be
++       * thrown away, as cleanup code is never called unless it's a module.
++       */
++      /DISCARD/               : {
++              *(.exit.text)
++              *(.exit.data)
++              *(.exitcall.exit)
++      }
++
++      DWARF_DEBUG
++}
+Index: linux-2.6.18-avr32/arch/avr32/lib/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/Makefile 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,11 @@
++#
++# Makefile for AVR32-specific library files
++#
++
++lib-y := copy_user.o clear_user.o
++lib-y += strncpy_from_user.o strnlen_user.o
++lib-y += delay.o memset.o memcpy.o findbit.o
++lib-y += csum_partial.o csum_partial_copy_generic.o
++lib-y += io-readsw.o io-readsl.o io-writesw.o io-writesl.o
++lib-y += io-readsb.o io-writesb.o
++lib-y += __avr32_lsl64.o __avr32_lsr64.o __avr32_asr64.o
+Index: linux-2.6.18-avr32/arch/avr32/lib/__avr32_asr64.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/__avr32_asr64.S  2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,31 @@
++/*
++ * 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.
++ */
++
++      /*
++       * DWtype __avr32_asr64(DWtype u, word_type b)
++       */
++      .text
++      .global __avr32_asr64
++      .type   __avr32_asr64,@function
++__avr32_asr64:
++      cp.w    r12, 0
++      reteq   r12
++
++      rsub    r9, r12, 32
++      brle    1f
++
++      lsl     r8, r11, r9
++      lsr     r10, r10, r12
++      asr     r11, r11, r12
++      or      r10, r8
++      retal   r12
++
++1:    neg     r9
++      asr     r10, r11, r9
++      asr     r11, 31
++      retal   r12
+Index: linux-2.6.18-avr32/arch/avr32/lib/__avr32_lsl64.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/__avr32_lsl64.S  2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,31 @@
++/*
++ * 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.
++ */
++
++      /*
++       * DWtype __avr32_lsl64(DWtype u, word_type b)
++       */
++      .text
++      .global __avr32_lsl64
++      .type   __avr32_lsl64,@function
++__avr32_lsl64:
++      cp.w    r12, 0
++      reteq   r12
++
++      rsub    r9, r12, 32
++      brle    1f
++
++      lsr     r8, r10, r9
++      lsl     r10, r10, r12
++      lsl     r11, r11, r12
++      or      r11, r8
++      retal   r12
++
++1:    neg     r9
++      lsl     r11, r10, r9
++      mov     r10, 0
++      retal   r12
+Index: linux-2.6.18-avr32/arch/avr32/lib/__avr32_lsr64.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/__avr32_lsr64.S  2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,31 @@
++/*
++ * 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.
++ */
++
++      /*
++       * DWtype __avr32_lsr64(DWtype u, word_type b)
++       */
++      .text
++      .global __avr32_lsr64
++      .type   __avr32_lsr64,@function
++__avr32_lsr64:
++      cp.w    r12, 0
++      reteq   r12
++
++      rsub    r9, r12, 32
++      brle    1f
++
++      lsl     r8, r11, r9
++      lsr     r11, r11, r12
++      lsr     r10, r10, r12
++      or      r10, r8
++      retal   r12
++
++1:    neg     r9
++      lsr     r10, r11, r9
++      mov     r11, 0
++      retal   r12
+Index: linux-2.6.18-avr32/arch/avr32/lib/clear_user.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/clear_user.S     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,76 @@
++/*
++ * Copyright 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 <asm/page.h>
++#include <asm/thread_info.h>
++#include <asm/asm.h>
++
++      .text
++      .align  1
++      .global clear_user
++      .type   clear_user, "function"
++clear_user:
++      branch_if_kernel r8, __clear_user
++      ret_if_privileged r8, r12, r11, r11
++
++      .global __clear_user
++      .type   __clear_user, "function"
++__clear_user:
++      mov     r9, r12
++      mov     r8, 0
++      andl    r9, 3, COH
++      brne    5f
++
++1:    sub     r11, 4
++      brlt    2f
++
++10:   st.w    r12++, r8
++      sub     r11, 4
++      brge    10b
++
++2:    sub     r11, -4
++      reteq   0
++
++      /* Unaligned count or address */
++      bld     r11, 1
++      brcc    12f
++11:   st.h    r12++, r8
++      sub     r11, 2
++      reteq   0
++12:   st.b    r12++, r8
++      retal   0
++
++      /* Unaligned address */
++5:    cp.w    r11, 4
++      brlt    2b
++
++      lsl     r9, 2
++      add     pc, pc, r9
++13:   st.b    r12++, r8
++      sub     r11, 1
++14:   st.b    r12++, r8
++      sub     r11, 1
++15:   st.b    r12++, r8
++      sub     r11, 1
++      rjmp    1b
++
++      .size   clear_user, . - clear_user
++      .size   __clear_user, . - __clear_user
++
++      .section .fixup, "ax"
++      .align  1
++18:   sub     r11, -4
++19:   retal   r11
++
++      .section __ex_table, "a"
++      .align  2
++      .long   10b, 18b
++      .long   11b, 19b
++      .long   12b, 19b
++      .long   13b, 19b
++      .long   14b, 19b
++      .long   15b, 19b
+Index: linux-2.6.18-avr32/arch/avr32/lib/copy_user.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/copy_user.S      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,119 @@
++/*
++ * Copy to/from userspace with optional address space checking.
++ *
++ * Copyright 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 <asm/page.h>
++#include <asm/thread_info.h>
++#include <asm/asm.h>
++
++      /*
++       * __kernel_size_t
++       * __copy_user(void *to, const void *from, __kernel_size_t n)
++       *
++       * Returns the number of bytes not copied. Might be off by
++       * max 3 bytes if we get a fault in the main loop.
++       *
++       * The address-space checking functions simply fall through to
++       * the non-checking version.
++       */
++      .text
++      .align  1
++      .global copy_from_user
++      .type   copy_from_user, @function
++copy_from_user:
++      branch_if_kernel r8, __copy_user
++      ret_if_privileged r8, r11, r10, r10
++      rjmp    __copy_user
++      .size   copy_from_user, . - copy_from_user
++
++      .global copy_to_user
++      .type   copy_to_user, @function
++copy_to_user:
++      branch_if_kernel r8, __copy_user
++      ret_if_privileged r8, r12, r10, r10
++      .size   copy_to_user, . - copy_to_user
++
++      .global __copy_user
++      .type   __copy_user, @function
++__copy_user:
++      mov     r9, r11
++      andl    r9, 3, COH
++      brne    6f
++
++      /* At this point, from is word-aligned */
++1:    sub     r10, 4
++      brlt    3f
++
++2:
++10:   ld.w    r8, r11++
++11:   st.w    r12++, r8
++      sub     r10, 4
++      brge    2b
++
++3:    sub     r10, -4
++      reteq   0
++
++      /*
++       * Handle unaligned count. Need to be careful with r10 here so
++       * that we return the correct value even if we get a fault
++       */
++4:
++20:   ld.ub   r8, r11++
++21:   st.b    r12++, r8
++      sub     r10, 1
++      reteq   0
++22:   ld.ub   r8, r11++
++23:   st.b    r12++, r8
++      sub     r10, 1
++      reteq   0
++24:   ld.ub   r8, r11++
++25:   st.b    r12++, r8
++      retal   0
++
++      /* Handle unaligned from-pointer */
++6:    cp.w    r10, 4
++      brlt    4b
++      rsub    r9, r9, 4
++
++30:   ld.ub   r8, r11++
++31:   st.b    r12++, r8
++      sub     r10, 1
++      sub     r9, 1
++      breq    1b
++32:   ld.ub   r8, r11++
++33:   st.b    r12++, r8
++      sub     r10, 1
++      sub     r9, 1
++      breq    1b
++34:   ld.ub   r8, r11++
++35:   st.b    r12++, r8
++      sub     r10, 1
++      rjmp    1b
++      .size   __copy_user, . - __copy_user
++
++      .section .fixup,"ax"
++      .align  1
++19:   sub     r10, -4
++29:   retal   r10
++
++      .section __ex_table,"a"
++      .align  2
++      .long   10b, 19b
++      .long   11b, 19b
++      .long   20b, 29b
++      .long   21b, 29b
++      .long   22b, 29b
++      .long   23b, 29b
++      .long   24b, 29b
++      .long   25b, 29b
++      .long   30b, 29b
++      .long   31b, 29b
++      .long   32b, 29b
++      .long   33b, 29b
++      .long   34b, 29b
++      .long   35b, 29b
+Index: linux-2.6.18-avr32/arch/avr32/lib/csum_partial.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/csum_partial.S   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,47 @@
++/*
++ * 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.
++ */
++
++      /*
++       * unsigned int csum_partial(const unsigned char *buff,
++       *                           int len, unsigned int sum)
++       */
++      .text
++      .global csum_partial
++      .type   csum_partial,"function"
++      .align  1
++csum_partial:
++      /* checksum complete words, aligned or not */
++3:    sub     r11, 4
++      brlt    5f
++4:    ld.w    r9, r12++
++      add     r10, r9
++      acr     r10
++      sub     r11, 4
++      brge    4b
++
++      /* return if we had a whole number of words */
++5:    sub     r11, -4
++      reteq   r10
++
++      /* checksum any remaining bytes at the end */
++      mov     r9, 0
++      mov     r8, 0
++      cp      r11, 2
++      brlt    6f
++      ld.uh   r9, r12++
++      sub     r11, 2
++      breq    7f
++      lsl     r9, 16
++6:    ld.ub   r8, r12++
++      lsl     r8, 8
++7:    or      r9, r8
++      add     r10, r9
++      acr     r10
++
++      retal   r10
++      .size   csum_partial, . - csum_partial
+Index: linux-2.6.18-avr32/arch/avr32/lib/csum_partial_copy_generic.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/csum_partial_copy_generic.S      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,99 @@
++/*
++ * 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 <asm/errno.h>
++#include <asm/asm.h>
++
++      /*
++       * unsigned int csum_partial_copy_generic(const char *src, char *dst, int len
++       *                                        int sum, int *src_err_ptr,
++       *                                        int *dst_err_ptr)
++       *
++       * Copy src to dst while checksumming, otherwise like csum_partial.
++       */
++
++      .macro ld_src size, reg, ptr
++9999: ld.\size \reg, \ptr
++      .section __ex_table, "a"
++      .long   9999b, fixup_ld_src
++      .previous
++      .endm
++
++      .macro st_dst size, ptr, reg
++9999: st.\size \ptr, \reg
++      .section __ex_table, "a"
++      .long   9999b, fixup_st_dst
++      .previous
++      .endm
++
++      .text
++      .global csum_partial_copy_generic
++      .type   csum_partial_copy_generic,"function"
++      .align  1
++csum_partial_copy_generic:
++      pushm   r4-r7,lr
++
++      /* The inner loop */
++1:    sub     r10, 4
++      brlt    5f
++2:    ld_src  w, r5, r12++
++      st_dst  w, r11++, r5
++      add     r9, r5
++      acr     r9
++      sub     r10, 4
++      brge    2b
++
++      /* return if we had a whole number of words */
++5:    sub     r10, -4
++      brne    7f
++
++6:    mov     r12, r9
++      popm    r4-r7,pc
++
++      /* handle additional bytes at the tail */
++7:    mov     r5, 0
++      mov     r4, 32
++8:    ld_src  ub, r6, r12++
++      st_dst  b, r11++, r6
++      lsl     r5, 8
++      sub     r4, 8
++      bfins   r5, r6, 0, 8
++      sub     r10, 1
++      brne    8b
++
++      lsl     r5, r5, r4
++      add     r9, r5
++      acr     r9
++      rjmp    6b
++
++      /* Exception handler */
++      .section .fixup,"ax"
++      .align  1
++fixup_ld_src:
++      mov     r9, -EFAULT
++      cp.w    r8, 0
++      breq    1f
++      st.w    r8[0], r9
++
++1:    /*
++       * TODO: zero the complete destination - computing the rest
++       * is too much work
++       */
++
++      mov     r9, 0
++      rjmp    6b
++
++fixup_st_dst:
++      mov     r9, -EFAULT
++      lddsp   r8, sp[20]
++      cp.w    r8, 0
++      breq    1f
++      st.w    r8[0], r9
++1:    mov     r9, 0
++      rjmp    6b
++
++      .previous
+Index: linux-2.6.18-avr32/arch/avr32/lib/delay.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/delay.c  2006-12-04 11:50:25.000000000 +0100
+@@ -0,0 +1,55 @@
++/*
++ *      Precise Delay Loops for avr32
++ *
++ *      Copyright (C) 1993 Linus Torvalds
++ *      Copyright (C) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
++ *    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/delay.h>
++#include <linux/module.h>
++#include <linux/types.h>
++
++#include <asm/delay.h>
++#include <asm/processor.h>
++#include <asm/sysreg.h>
++
++int read_current_timer(unsigned long *timer_value)
++{
++      *timer_value = sysreg_read(COUNT);
++      return 0;
++}
++
++void __delay(unsigned long loops)
++{
++      unsigned bclock, now;
++
++      bclock = sysreg_read(COUNT);
++      do {
++              now = sysreg_read(COUNT);
++      } while ((now - bclock) < loops);
++}
++
++inline void __const_udelay(unsigned long xloops)
++{
++      unsigned long long loops;
++
++      asm("mulu.d %0, %1, %2"
++          : "=r"(loops)
++          : "r"(current_cpu_data.loops_per_jiffy * HZ), "r"(xloops));
++      __delay(loops >> 32);
++}
++
++void __udelay(unsigned long usecs)
++{
++      __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */
++}
++
++void __ndelay(unsigned long nsecs)
++{
++      __const_udelay(nsecs * 0x00005); /* 2**32 / 1000000000 (rounded up) */
++}
+Index: linux-2.6.18-avr32/arch/avr32/lib/findbit.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/findbit.S        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,155 @@
++/*
++ * 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/linkage.h>
++
++      .text
++      /*
++       * unsigned long find_first_zero_bit(const unsigned long *addr,
++       *                                   unsigned long size)
++       */
++ENTRY(find_first_zero_bit)
++      cp.w    r11, 0
++      reteq   r11
++      mov     r9, r11
++1:    ld.w    r8, r12[0]
++      com     r8
++      brne    .L_found
++      sub     r12, -4
++      sub     r9, 32
++      brgt    1b
++      retal   r11
++
++      /*
++       * unsigned long find_next_zero_bit(const unsigned long *addr,
++       *                                  unsigned long size,
++       *                                  unsigned long offset)
++       */
++ENTRY(find_next_zero_bit)
++      lsr     r8, r10, 5
++      sub     r9, r11, r10
++      retle   r11
++
++      lsl     r8, 2
++      add     r12, r8
++      andl    r10, 31, COH
++      breq    1f
++
++      /* offset is not word-aligned. Handle the first (32 - r10) bits */
++      ld.w    r8, r12[0]
++      com     r8
++      sub     r12, -4
++      lsr     r8, r8, r10
++      brne    .L_found
++
++      /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
++      add     r9, r10
++      sub     r9, 32
++      retle   r11
++
++      /* Main loop. offset must be word-aligned */
++1:    ld.w    r8, r12[0]
++      com     r8
++      brne    .L_found
++      sub     r12, -4
++      sub     r9, 32
++      brgt    1b
++      retal   r11
++
++      /* Common return path for when a bit is actually found. */
++.L_found:
++      brev    r8
++      clz     r10, r8
++      rsub    r9, r11
++      add     r10, r9
++
++      /* XXX: If we don't have to return exactly "size" when the bit
++         is not found, we may drop this "min" thing */
++      min     r12, r11, r10
++      retal   r12
++
++      /*
++       * unsigned long find_first_bit(const unsigned long *addr,
++       *                              unsigned long size)
++       */
++ENTRY(find_first_bit)
++      cp.w    r11, 0
++      reteq   r11
++      mov     r9, r11
++1:    ld.w    r8, r12[0]
++      cp.w    r8, 0
++      brne    .L_found
++      sub     r12, -4
++      sub     r9, 32
++      brgt    1b
++      retal   r11
++
++      /*
++       * unsigned long find_next_bit(const unsigned long *addr,
++       *                             unsigned long size,
++       *                             unsigned long offset)
++       */
++ENTRY(find_next_bit)
++      lsr     r8, r10, 5
++      sub     r9, r11, r10
++      retle   r11
++
++      lsl     r8, 2
++      add     r12, r8
++      andl    r10, 31, COH
++      breq    1f
++
++      /* offset is not word-aligned. Handle the first (32 - r10) bits */
++      ld.w    r8, r12[0]
++      sub     r12, -4
++      lsr     r8, r8, r10
++      brne    .L_found
++
++      /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
++      add     r9, r10
++      sub     r9, 32
++      retle   r11
++
++      /* Main loop. offset must be word-aligned */
++1:    ld.w    r8, r12[0]
++      cp.w    r8, 0
++      brne    .L_found
++      sub     r12, -4
++      sub     r9, 32
++      brgt    1b
++      retal   r11
++
++ENTRY(generic_find_next_zero_le_bit)
++      lsr     r8, r10, 5
++      sub     r9, r11, r10
++      retle   r11
++
++      lsl     r8, 2
++      add     r12, r8
++      andl    r10, 31, COH
++      breq    1f
++
++      /* offset is not word-aligned. Handle the first (32 - r10) bits */
++      ldswp.w r8, r12[0]
++      sub     r12, -4
++      com     r8
++      lsr     r8, r8, r10
++      brne    .L_found
++
++      /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
++      add     r9, r10
++      sub     r9, 32
++      retle   r11
++
++      /* Main loop. offset must be word-aligned */
++1:    ldswp.w r8, r12[0]
++      com     r8
++      brne    .L_found
++      sub     r12, -4
++      sub     r9, 32
++      brgt    1b
++      retal   r11
+Index: linux-2.6.18-avr32/arch/avr32/lib/io-readsl.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/io-readsl.S      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,24 @@
++/*
++ * 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.
++ */
++
++      .global __raw_readsl
++      .type   __raw_readsl,@function
++__raw_readsl:
++      cp.w    r10, 0
++      reteq   r12
++
++      /*
++       * If r11 isn't properly aligned, we might get an exception on
++       * some implementations. But there's not much we can do about it.
++       */
++1:    ld.w    r8, r12[0]
++      sub     r10, 1
++      st.w    r11++, r8
++      brne    1b
++
++      retal   r12
+Index: linux-2.6.18-avr32/arch/avr32/lib/io-readsw.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/io-readsw.S      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,43 @@
++/*
++ * 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.
++ */
++
++.Lnot_word_aligned:
++      /*
++       * Bad alignment will cause a hardware exception, which is as
++       * good as anything. No need for us to check for proper alignment.
++       */
++      ld.uh   r8, r12[0]
++      sub     r10, 1
++      st.h    r11++, r8
++
++      /* fall through */
++
++      .global __raw_readsw
++      .type   __raw_readsw,@function
++__raw_readsw:
++      cp.w    r10, 0
++      reteq   r12
++      mov     r9, 3
++      tst     r11, r9
++      brne    .Lnot_word_aligned
++
++      sub     r10, 2
++      brlt    2f
++
++1:    ldins.h r8:t, r12[0]
++      ldins.h r8:b, r12[0]
++      st.w    r11++, r8
++      sub     r10, 2
++      brge    1b
++
++2:    sub     r10, -2
++      reteq   r12
++
++      ld.uh   r8, r12[0]
++      st.h    r11++, r8
++      retal   r12
+Index: linux-2.6.18-avr32/arch/avr32/lib/io-writesl.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/io-writesl.S     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,20 @@
++/*
++ * 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.
++ */
++
++      .global __raw_writesl
++      .type   __raw_writesl,@function
++__raw_writesl:
++      cp.w    r10, 0
++      reteq   r12
++
++1:    ld.w    r8, r11++
++      sub     r10, 1
++      st.w    r12[0], r8
++      brne    1b
++
++      retal   r12
+Index: linux-2.6.18-avr32/arch/avr32/lib/io-writesw.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/io-writesw.S     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,38 @@
++/*
++ * 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.
++ */
++
++.Lnot_word_aligned:
++      ld.uh   r8, r11++
++      sub     r10, 1
++      st.h    r12[0], r8
++
++      .global __raw_writesw
++      .type   __raw_writesw,@function
++__raw_writesw:
++      cp.w    r10, 0
++      mov     r9, 3
++      reteq   r12
++      tst     r11, r9
++      brne    .Lnot_word_aligned
++
++      sub     r10, 2
++      brlt    2f
++
++1:    ld.w    r8, r11++
++      bfextu  r9, r8, 16, 16
++      st.h    r12[0], r9
++      st.h    r12[0], r8
++      sub     r10, 2
++      brge    1b
++
++2:    sub     r10, -2
++      reteq   r12
++
++      ld.uh   r8, r11++
++      st.h    r12[0], r8
++      retal   r12
+Index: linux-2.6.18-avr32/arch/avr32/lib/libgcc.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/libgcc.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,33 @@
++/* Definitions for various functions 'borrowed' from gcc-3.4.3 */
++
++#define BITS_PER_UNIT 8
++
++typedef                int QItype     __attribute__ ((mode (QI)));
++typedef unsigned int UQItype  __attribute__ ((mode (QI)));
++typedef                int HItype     __attribute__ ((mode (HI)));
++typedef unsigned int UHItype  __attribute__ ((mode (HI)));
++typedef        int SItype     __attribute__ ((mode (SI)));
++typedef unsigned int USItype  __attribute__ ((mode (SI)));
++typedef                int DItype     __attribute__ ((mode (DI)));
++typedef unsigned int UDItype  __attribute__ ((mode (DI)));
++typedef       float SFtype    __attribute__ ((mode (SF)));
++typedef               float DFtype    __attribute__ ((mode (DF)));
++typedef int word_type __attribute__ ((mode (__word__)));
++
++#define W_TYPE_SIZE (4 * BITS_PER_UNIT)
++#define Wtype SItype
++#define UWtype        USItype
++#define HWtype        SItype
++#define UHWtype       USItype
++#define DWtype        DItype
++#define UDWtype       UDItype
++#define __NW(a,b)     __ ## a ## si ## b
++#define __NDW(a,b)    __ ## a ## di ## b
++
++struct DWstruct {Wtype high, low;};
++
++typedef union
++{
++  struct DWstruct s;
++  DWtype ll;
++} DWunion;
+Index: linux-2.6.18-avr32/arch/avr32/lib/longlong.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/longlong.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,98 @@
++/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
++   Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000
++   Free Software Foundation, Inc.
++
++   This definition file 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, or (at your option) any later version.
++
++   This definition file 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.  */
++
++/* Borrowed from gcc-3.4.3 */
++
++#define __BITS4 (W_TYPE_SIZE / 4)
++#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
++#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
++#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
++
++#define count_leading_zeros(count, x) ((count) = __builtin_clz(x))
++
++#define __udiv_qrnnd_c(q, r, n1, n0, d) \
++  do {                                                                        \
++    UWtype __d1, __d0, __q1, __q0;                                    \
++    UWtype __r1, __r0, __m;                                           \
++    __d1 = __ll_highpart (d);                                         \
++    __d0 = __ll_lowpart (d);                                          \
++                                                                      \
++    __r1 = (n1) % __d1;                                                       \
++    __q1 = (n1) / __d1;                                                       \
++    __m = (UWtype) __q1 * __d0;                                               \
++    __r1 = __r1 * __ll_B | __ll_highpart (n0);                                \
++    if (__r1 < __m)                                                   \
++      {                                                                       \
++      __q1--, __r1 += (d);                                            \
++      if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
++        if (__r1 < __m)                                               \
++          __q1--, __r1 += (d);                                        \
++      }                                                                       \
++    __r1 -= __m;                                                      \
++                                                                      \
++    __r0 = __r1 % __d1;                                                       \
++    __q0 = __r1 / __d1;                                                       \
++    __m = (UWtype) __q0 * __d0;                                               \
++    __r0 = __r0 * __ll_B | __ll_lowpart (n0);                         \
++    if (__r0 < __m)                                                   \
++      {                                                                       \
++      __q0--, __r0 += (d);                                            \
++      if (__r0 >= (d))                                                \
++        if (__r0 < __m)                                               \
++          __q0--, __r0 += (d);                                        \
++      }                                                                       \
++    __r0 -= __m;                                                      \
++                                                                      \
++    (q) = (UWtype) __q1 * __ll_B | __q0;                              \
++    (r) = __r0;                                                               \
++  } while (0)
++
++#define udiv_qrnnd __udiv_qrnnd_c
++
++#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
++  do {                                                                        \
++    UWtype __x;                                                               \
++    __x = (al) - (bl);                                                        \
++    (sh) = (ah) - (bh) - (__x > (al));                                        \
++    (sl) = __x;                                                               \
++  } while (0)
++
++#define umul_ppmm(w1, w0, u, v)                                               \
++  do {                                                                        \
++    UWtype __x0, __x1, __x2, __x3;                                    \
++    UHWtype __ul, __vl, __uh, __vh;                                   \
++                                                                      \
++    __ul = __ll_lowpart (u);                                          \
++    __uh = __ll_highpart (u);                                         \
++    __vl = __ll_lowpart (v);                                          \
++    __vh = __ll_highpart (v);                                         \
++                                                                      \
++    __x0 = (UWtype) __ul * __vl;                                      \
++    __x1 = (UWtype) __ul * __vh;                                      \
++    __x2 = (UWtype) __uh * __vl;                                      \
++    __x3 = (UWtype) __uh * __vh;                                      \
++                                                                      \
++    __x1 += __ll_highpart (__x0);/* this can't give carry */          \
++    __x1 += __x2;             /* but this indeed can */               \
++    if (__x1 < __x2)          /* did we get it? */                    \
++      __x3 += __ll_B;         /* yes, add it in the proper pos.  */   \
++                                                                      \
++    (w1) = __x3 + __ll_highpart (__x1);                                       \
++    (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);                \
++  } while (0)
+Index: linux-2.6.18-avr32/arch/avr32/lib/memcpy.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/memcpy.S 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,62 @@
++/*
++ * 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.
++ */
++
++      /*
++       * void *memcpy(void *to, const void *from, unsigned long n)
++       *
++       * This implementation does word-aligned loads in the main loop,
++       * possibly sacrificing alignment of stores.
++       *
++       * Hopefully, in most cases, both "to" and "from" will be
++       * word-aligned to begin with.
++       */
++      .text
++      .global memcpy
++      .type   memcpy, @function
++memcpy:
++      mov     r9, r11
++      andl    r9, 3, COH
++      brne    1f
++
++      /* At this point, "from" is word-aligned */
++2:    sub     r10, 4
++      mov     r9, r12
++      brlt    4f
++
++3:    ld.w    r8, r11++
++      sub     r10, 4
++      st.w    r12++, r8
++      brge    3b
++
++4:    neg     r10
++      reteq   r9
++
++      /* Handle unaligned count */
++      lsl     r10, 2
++      add     pc, pc, r10
++      ld.ub   r8, r11++
++      st.b    r12++, r8
++      ld.ub   r8, r11++
++      st.b    r12++, r8
++      ld.ub   r8, r11++
++      st.b    r12++, r8
++      retal   r9
++
++      /* Handle unaligned "from" pointer */
++1:    sub     r10, 4
++      brlt    4b
++      add     r10, r9
++      lsl     r9, 2
++      add     pc, pc, r9
++      ld.ub   r8, r11++
++      st.b    r12++, r8
++      ld.ub   r8, r11++
++      st.b    r12++, r8
++      ld.ub   r8, r11++
++      st.b    r12++, r8
++      rjmp    2b
+Index: linux-2.6.18-avr32/arch/avr32/lib/memset.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/memset.S 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,72 @@
++/*
++ * Copyright (C) 2004-2006 Atmel Corporation
++ *
++ * Based on linux/arch/arm/lib/memset.S
++ *   Copyright (C) 1995-2000 Russell King
++ *
++ * 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.
++ *
++ * ASM optimised string functions
++ */
++#include <asm/asm.h>
++
++      /*
++       * r12: void *b
++       * r11: int c
++       * r10: size_t len
++       *
++       * Returns b in r12
++       */
++      .text
++      .global memset
++      .type   memset, @function
++      .align  5
++memset:
++      mov     r9, r12
++      mov     r8, r12
++      or      r11, r11, r11 << 8
++      andl    r9, 3, COH
++      brne    1f
++
++2:    or      r11, r11, r11 << 16
++      sub     r10, 4
++      brlt    5f
++
++      /* Let's do some real work */
++4:    st.w    r8++, r11
++      sub     r10, 4
++      brge    4b
++
++      /*
++       * When we get here, we've got less than 4 bytes to set. r10
++       * might be negative.
++       */
++5:    sub     r10, -4
++      reteq   r12
++
++      /* Fastpath ends here, exactly 32 bytes from memset */
++
++      /* Handle unaligned count or pointer */
++      bld     r10, 1
++      brcc    6f
++      st.b    r8++, r11
++      st.b    r8++, r11
++      bld     r10, 0
++      retcc   r12
++6:    st.b    r8++, r11
++      retal   r12
++
++      /* Handle unaligned pointer */
++1:    sub     r10, 4
++      brlt    5b
++      add     r10, r9
++      lsl     r9, 1
++      add     pc, r9
++      st.b    r8++, r11
++      st.b    r8++, r11
++      st.b    r8++, r11
++      rjmp    2b
++
++      .size   memset, . - memset
+Index: linux-2.6.18-avr32/arch/avr32/lib/strncpy_from_user.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/strncpy_from_user.S      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,60 @@
++/*
++ * Copy to/from userspace with optional address space checking.
++ *
++ * Copyright 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/errno.h>
++
++#include <asm/page.h>
++#include <asm/thread_info.h>
++#include <asm/asm.h>
++
++      /*
++       * long strncpy_from_user(char *dst, const char *src, long count)
++       *
++       * On success, returns the length of the string, not including
++       * the terminating NUL.
++       *
++       * If the string is longer than count, returns count
++       *
++       * If userspace access fails, returns -EFAULT
++       */
++      .text
++      .align  1
++      .global strncpy_from_user
++      .type   strncpy_from_user, "function"
++strncpy_from_user:
++      mov     r9, -EFAULT
++      branch_if_kernel r8, __strncpy_from_user
++      ret_if_privileged r8, r11, r10, r9
++
++      .global __strncpy_from_user
++      .type   __strncpy_from_user, "function"
++__strncpy_from_user:
++      cp.w    r10, 0
++      reteq   0
++
++      mov     r9, r10
++
++1:    ld.ub   r8, r11++
++      st.b    r12++, r8
++      cp.w    r8, 0
++      breq    2f
++      sub     r9, 1
++      brne    1b
++
++2:    sub     r10, r9
++      retal   r10
++
++      .section .fixup, "ax"
++      .align  1
++3:    mov     r12, -EFAULT
++      retal   r12
++
++      .section __ex_table, "a"
++      .align  2
++      .long   1b, 3b
+Index: linux-2.6.18-avr32/arch/avr32/lib/strnlen_user.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/strnlen_user.S   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,67 @@
++/*
++ * Copy to/from userspace with optional address space checking.
++ *
++ * Copyright 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 <asm/page.h>
++#include <asm/thread_info.h>
++#include <asm/processor.h>
++#include <asm/asm.h>
++
++      .text
++      .align  1
++      .global strnlen_user
++      .type   strnlen_user, "function"
++strnlen_user:
++      branch_if_kernel r8, __strnlen_user
++      sub     r8, r11, 1
++      add     r8, r12
++      retcs   0
++      brmi    adjust_length   /* do a closer inspection */
++
++      .global __strnlen_user
++      .type   __strnlen_user, "function"
++__strnlen_user:
++      mov     r10, r12
++
++10:   ld.ub   r8, r12++
++      cp.w    r8, 0
++      breq    2f
++      sub     r11, 1
++      brne    10b
++
++      sub     r12, -1
++2:    sub     r12, r10
++      retal   r12
++
++
++      .type   adjust_length, "function"
++adjust_length:
++      cp.w    r12, 0          /* addr must always be < TASK_SIZE */
++      retmi   0
++
++      pushm   lr
++      lddpc   lr, _task_size
++      sub     r11, lr, r12
++      mov     r9, r11
++      rcall   __strnlen_user
++      cp.w    r12, r9
++      brgt    1f
++      popm    pc
++1:    popm    pc, r12=0
++
++      .align  2
++_task_size:
++      .long   TASK_SIZE
++
++      .section .fixup, "ax"
++      .align  1
++19:   retal   0
++
++      .section __ex_table, "a"
++      .align  2
++      .long   10b, 19b
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/Makefile 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,2 @@
++obj-y                         += at32ap.o clock.o pio.o intc.o extint.o hsmc.o
++obj-$(CONFIG_CPU_AT32AP7000)  += at32ap7000.o
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap.c 2006-12-04 11:50:22.000000000 +0100
+@@ -0,0 +1,90 @@
++/*
++ * 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/io.h>
++
++#include <asm/arch/init.h>
++#include <asm/arch/sm.h>
++
++struct at32_sm system_manager;
++
++static int __init at32_sm_init(void)
++{
++      struct resource *regs;
++      struct at32_sm *sm = &system_manager;
++      int ret = -ENXIO;
++
++      regs = platform_get_resource(&at32_sm_device, IORESOURCE_MEM, 0);
++      if (!regs)
++              goto fail;
++
++      spin_lock_init(&sm->lock);
++      sm->pdev = &at32_sm_device;
++
++      ret = -ENOMEM;
++      sm->regs = ioremap(regs->start, regs->end - regs->start + 1);
++      if (!sm->regs)
++              goto fail;
++
++      return 0;
++
++fail:
++      printk(KERN_ERR "Failed to initialize System Manager: %d\n", ret);
++      return ret;
++}
++
++void __init setup_platform(void)
++{
++      at32_sm_init();
++      at32_clock_init();
++      at32_portmux_init();
++
++      /* FIXME: This doesn't belong here */
++      at32_setup_serial_console(1);
++}
++
++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);
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap7000.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap7000.c     2006-12-04 11:50:25.000000000 +0100
+@@ -0,0 +1,876 @@
++/*
++ * 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/init.h>
++#include <linux/platform_device.h>
++
++#include <asm/io.h>
++
++#include <asm/arch/board.h>
++#include <asm/arch/portmux.h>
++#include <asm/arch/sm.h>
++
++#include "clock.h"
++#include "pio.h"
++#include "sm.h"
++
++#define PBMEM(base)                                   \
++      {                                               \
++              .start          = base,                 \
++              .end            = base + 0x3ff,         \
++              .flags          = IORESOURCE_MEM,       \
++      }
++#define IRQ(num)                                      \
++      {                                               \
++              .start          = num,                  \
++              .end            = num,                  \
++              .flags          = IORESOURCE_IRQ,       \
++      }
++#define NAMED_IRQ(num, _name)                         \
++      {                                               \
++              .start          = num,                  \
++              .end            = num,                  \
++              .name           = _name,                \
++              .flags          = IORESOURCE_IRQ,       \
++      }
++
++#define DEFINE_DEV(_name, _id)                                        \
++static struct platform_device _name##_id##_device = {         \
++      .name           = #_name,                               \
++      .id             = _id,                                  \
++      .resource       = _name##_id##_resource,                \
++      .num_resources  = ARRAY_SIZE(_name##_id##_resource),    \
++}
++#define DEFINE_DEV_DATA(_name, _id)                           \
++static struct platform_device _name##_id##_device = {         \
++      .name           = #_name,                               \
++      .id             = _id,                                  \
++      .dev            = {                                     \
++              .platform_data  = &_name##_id##_data,           \
++      },                                                      \
++      .resource       = _name##_id##_resource,                \
++      .num_resources  = ARRAY_SIZE(_name##_id##_resource),    \
++}
++
++#define DEV_CLK(_name, devname, bus, _index)                  \
++static struct clk devname##_##_name = {                               \
++      .name           = #_name,                               \
++      .dev            = &devname##_device.dev,                \
++      .parent         = &bus##_clk,                           \
++      .mode           = bus##_clk_mode,                       \
++      .get_rate       = bus##_clk_get_rate,                   \
++      .index          = _index,                               \
++}
++
++enum {
++      PIOA,
++      PIOB,
++      PIOC,
++      PIOD,
++};
++
++enum {
++      FUNC_A,
++      FUNC_B,
++};
++
++unsigned long at32ap7000_osc_rates[3] = {
++      [0] = 32768,
++      /* FIXME: these are ATSTK1002-specific */
++      [1] = 20000000,
++      [2] = 12000000,
++};
++
++static unsigned long osc_get_rate(struct clk *clk)
++{
++      return at32ap7000_osc_rates[clk->index];
++}
++
++static unsigned long pll_get_rate(struct clk *clk, unsigned long control)
++{
++      unsigned long div, mul, rate;
++
++      if (!(control & SM_BIT(PLLEN)))
++              return 0;
++
++      div = SM_BFEXT(PLLDIV, control) + 1;
++      mul = SM_BFEXT(PLLMUL, control) + 1;
++
++      rate = clk->parent->get_rate(clk->parent);
++      rate = (rate + div / 2) / div;
++      rate *= mul;
++
++      return rate;
++}
++
++static unsigned long pll0_get_rate(struct clk *clk)
++{
++      u32 control;
++
++      control = sm_readl(&system_manager, PM_PLL0);
++
++      return pll_get_rate(clk, control);
++}
++
++static unsigned long pll1_get_rate(struct clk *clk)
++{
++      u32 control;
++
++      control = sm_readl(&system_manager, PM_PLL1);
++
++      return pll_get_rate(clk, control);
++}
++
++/*
++ * The AT32AP7000 has five primary clock sources: One 32kHz
++ * oscillator, two crystal oscillators and two PLLs.
++ */
++static struct clk osc32k = {
++      .name           = "osc32k",
++      .get_rate       = osc_get_rate,
++      .users          = 1,
++      .index          = 0,
++};
++static struct clk osc0 = {
++      .name           = "osc0",
++      .get_rate       = osc_get_rate,
++      .users          = 1,
++      .index          = 1,
++};
++static struct clk osc1 = {
++      .name           = "osc1",
++      .get_rate       = osc_get_rate,
++      .index          = 2,
++};
++static struct clk pll0 = {
++      .name           = "pll0",
++      .get_rate       = pll0_get_rate,
++      .parent         = &osc0,
++};
++static struct clk pll1 = {
++      .name           = "pll1",
++      .get_rate       = pll1_get_rate,
++      .parent         = &osc0,
++};
++
++/*
++ * The main clock can be either osc0 or pll0.  The boot loader may
++ * have chosen one for us, so we don't really know which one until we
++ * have a look at the SM.
++ */
++static struct clk *main_clock;
++
++/*
++ * Synchronous clocks are generated from the main clock. The clocks
++ * must satisfy the constraint
++ *   fCPU >= fHSB >= fPB
++ * i.e. each clock must not be faster than its parent.
++ */
++static unsigned long bus_clk_get_rate(struct clk *clk, unsigned int shift)
++{
++      return main_clock->get_rate(main_clock) >> shift;
++};
++
++static void cpu_clk_mode(struct clk *clk, int enabled)
++{
++      struct at32_sm *sm = &system_manager;
++      unsigned long flags;
++      u32 mask;
++
++      spin_lock_irqsave(&sm->lock, flags);
++      mask = sm_readl(sm, PM_CPU_MASK);
++      if (enabled)
++              mask |= 1 << clk->index;
++      else
++              mask &= ~(1 << clk->index);
++      sm_writel(sm, PM_CPU_MASK, mask);
++      spin_unlock_irqrestore(&sm->lock, flags);
++}
++
++static unsigned long cpu_clk_get_rate(struct clk *clk)
++{
++      unsigned long cksel, shift = 0;
++
++      cksel = sm_readl(&system_manager, PM_CKSEL);
++      if (cksel & SM_BIT(CPUDIV))
++              shift = SM_BFEXT(CPUSEL, cksel) + 1;
++
++      return bus_clk_get_rate(clk, shift);
++}
++
++static void hsb_clk_mode(struct clk *clk, int enabled)
++{
++      struct at32_sm *sm = &system_manager;
++      unsigned long flags;
++      u32 mask;
++
++      spin_lock_irqsave(&sm->lock, flags);
++      mask = sm_readl(sm, PM_HSB_MASK);
++      if (enabled)
++              mask |= 1 << clk->index;
++      else
++              mask &= ~(1 << clk->index);
++      sm_writel(sm, PM_HSB_MASK, mask);
++      spin_unlock_irqrestore(&sm->lock, flags);
++}
++
++static unsigned long hsb_clk_get_rate(struct clk *clk)
++{
++      unsigned long cksel, shift = 0;
++
++      cksel = sm_readl(&system_manager, PM_CKSEL);
++      if (cksel & SM_BIT(HSBDIV))
++              shift = SM_BFEXT(HSBSEL, cksel) + 1;
++
++      return bus_clk_get_rate(clk, shift);
++}
++
++static void pba_clk_mode(struct clk *clk, int enabled)
++{
++      struct at32_sm *sm = &system_manager;
++      unsigned long flags;
++      u32 mask;
++
++      spin_lock_irqsave(&sm->lock, flags);
++      mask = sm_readl(sm, PM_PBA_MASK);
++      if (enabled)
++              mask |= 1 << clk->index;
++      else
++              mask &= ~(1 << clk->index);
++      sm_writel(sm, PM_PBA_MASK, mask);
++      spin_unlock_irqrestore(&sm->lock, flags);
++}
++
++static unsigned long pba_clk_get_rate(struct clk *clk)
++{
++      unsigned long cksel, shift = 0;
++
++      cksel = sm_readl(&system_manager, PM_CKSEL);
++      if (cksel & SM_BIT(PBADIV))
++              shift = SM_BFEXT(PBASEL, cksel) + 1;
++
++      return bus_clk_get_rate(clk, shift);
++}
++
++static void pbb_clk_mode(struct clk *clk, int enabled)
++{
++      struct at32_sm *sm = &system_manager;
++      unsigned long flags;
++      u32 mask;
++
++      spin_lock_irqsave(&sm->lock, flags);
++      mask = sm_readl(sm, PM_PBB_MASK);
++      if (enabled)
++              mask |= 1 << clk->index;
++      else
++              mask &= ~(1 << clk->index);
++      sm_writel(sm, PM_PBB_MASK, mask);
++      spin_unlock_irqrestore(&sm->lock, flags);
++}
++
++static unsigned long pbb_clk_get_rate(struct clk *clk)
++{
++      unsigned long cksel, shift = 0;
++
++      cksel = sm_readl(&system_manager, PM_CKSEL);
++      if (cksel & SM_BIT(PBBDIV))
++              shift = SM_BFEXT(PBBSEL, cksel) + 1;
++
++      return bus_clk_get_rate(clk, shift);
++}
++
++static struct clk cpu_clk = {
++      .name           = "cpu",
++      .get_rate       = cpu_clk_get_rate,
++      .users          = 1,
++};
++static struct clk hsb_clk = {
++      .name           = "hsb",
++      .parent         = &cpu_clk,
++      .get_rate       = hsb_clk_get_rate,
++};
++static struct clk pba_clk = {
++      .name           = "pba",
++      .parent         = &hsb_clk,
++      .mode           = hsb_clk_mode,
++      .get_rate       = pba_clk_get_rate,
++      .index          = 1,
++};
++static struct clk pbb_clk = {
++      .name           = "pbb",
++      .parent         = &hsb_clk,
++      .mode           = hsb_clk_mode,
++      .get_rate       = pbb_clk_get_rate,
++      .users          = 1,
++      .index          = 2,
++};
++
++/* --------------------------------------------------------------------
++ *  Generic Clock operations
++ * -------------------------------------------------------------------- */
++
++static void genclk_mode(struct clk *clk, int enabled)
++{
++      u32 control;
++
++      BUG_ON(clk->index > 7);
++
++      control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
++      if (enabled)
++              control |= SM_BIT(CEN);
++      else
++              control &= ~SM_BIT(CEN);
++      sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index, control);
++}
++
++static unsigned long genclk_get_rate(struct clk *clk)
++{
++      u32 control;
++      unsigned long div = 1;
++
++      BUG_ON(clk->index > 7);
++
++      if (!clk->parent)
++              return 0;
++
++      control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
++      if (control & SM_BIT(DIVEN))
++              div = 2 * (SM_BFEXT(DIV, control) + 1);
++
++      return clk->parent->get_rate(clk->parent) / div;
++}
++
++static long genclk_set_rate(struct clk *clk, unsigned long rate, int apply)
++{
++      u32 control;
++      unsigned long parent_rate, actual_rate, div;
++
++      BUG_ON(clk->index > 7);
++
++      if (!clk->parent)
++              return 0;
++
++      parent_rate = clk->parent->get_rate(clk->parent);
++      control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
++
++      if (rate > 3 * parent_rate / 4) {
++              actual_rate = parent_rate;
++              control &= ~SM_BIT(DIVEN);
++      } else {
++              div = (parent_rate + rate) / (2 * rate) - 1;
++              control = SM_BFINS(DIV, div, control) | SM_BIT(DIVEN);
++              actual_rate = parent_rate / (2 * (div + 1));
++      }
++
++      printk("clk %s: new rate %lu (actual rate %lu)\n",
++             clk->name, rate, actual_rate);
++
++      if (apply)
++              sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index,
++                        control);
++
++      return actual_rate;
++}
++
++int genclk_set_parent(struct clk *clk, struct clk *parent)
++{
++      u32 control;
++
++      BUG_ON(clk->index > 7);
++
++      printk("clk %s: new parent %s (was %s)\n",
++             clk->name, parent->name,
++             clk->parent ? clk->parent->name : "(null)");
++
++      control = sm_readl(&system_manager, PM_GCCTRL + 4 * clk->index);
++
++      if (parent == &osc1 || parent == &pll1)
++              control |= SM_BIT(OSCSEL);
++      else if (parent == &osc0 || parent == &pll0)
++              control &= ~SM_BIT(OSCSEL);
++      else
++              return -EINVAL;
++
++      if (parent == &pll0 || parent == &pll1)
++              control |= SM_BIT(PLLSEL);
++      else
++              control &= ~SM_BIT(PLLSEL);
++
++      sm_writel(&system_manager, PM_GCCTRL + 4 * clk->index, control);
++      clk->parent = parent;
++
++      return 0;
++}
++
++/* --------------------------------------------------------------------
++ *  System peripherals
++ * -------------------------------------------------------------------- */
++static struct resource sm_resource[] = {
++      PBMEM(0xfff00000),
++      NAMED_IRQ(19, "eim"),
++      NAMED_IRQ(20, "pm"),
++      NAMED_IRQ(21, "rtc"),
++};
++struct platform_device at32_sm_device = {
++      .name           = "sm",
++      .id             = 0,
++      .resource       = sm_resource,
++      .num_resources  = ARRAY_SIZE(sm_resource),
++};
++DEV_CLK(pclk, at32_sm, pbb, 0);
++
++static struct resource intc0_resource[] = {
++      PBMEM(0xfff00400),
++};
++struct platform_device at32_intc0_device = {
++      .name           = "intc",
++      .id             = 0,
++      .resource       = intc0_resource,
++      .num_resources  = ARRAY_SIZE(intc0_resource),
++};
++DEV_CLK(pclk, at32_intc0, pbb, 1);
++
++static struct clk ebi_clk = {
++      .name           = "ebi",
++      .parent         = &hsb_clk,
++      .mode           = hsb_clk_mode,
++      .get_rate       = hsb_clk_get_rate,
++      .users          = 1,
++};
++static struct clk hramc_clk = {
++      .name           = "hramc",
++      .parent         = &hsb_clk,
++      .mode           = hsb_clk_mode,
++      .get_rate       = hsb_clk_get_rate,
++      .users          = 1,
++};
++
++static struct resource smc0_resource[] = {
++      PBMEM(0xfff03400),
++};
++DEFINE_DEV(smc, 0);
++DEV_CLK(pclk, smc0, pbb, 13);
++DEV_CLK(mck, smc0, hsb, 0);
++
++static struct platform_device pdc_device = {
++      .name           = "pdc",
++      .id             = 0,
++};
++DEV_CLK(hclk, pdc, hsb, 4);
++DEV_CLK(pclk, pdc, pba, 16);
++
++static struct clk pico_clk = {
++      .name           = "pico",
++      .parent         = &cpu_clk,
++      .mode           = cpu_clk_mode,
++      .get_rate       = cpu_clk_get_rate,
++      .users          = 1,
++};
++
++/* --------------------------------------------------------------------
++ *  PIO
++ * -------------------------------------------------------------------- */
++
++static struct resource pio0_resource[] = {
++      PBMEM(0xffe02800),
++      IRQ(13),
++};
++DEFINE_DEV(pio, 0);
++DEV_CLK(mck, pio0, pba, 10);
++
++static struct resource pio1_resource[] = {
++      PBMEM(0xffe02c00),
++      IRQ(14),
++};
++DEFINE_DEV(pio, 1);
++DEV_CLK(mck, pio1, pba, 11);
++
++static struct resource pio2_resource[] = {
++      PBMEM(0xffe03000),
++      IRQ(15),
++};
++DEFINE_DEV(pio, 2);
++DEV_CLK(mck, pio2, pba, 12);
++
++static struct resource pio3_resource[] = {
++      PBMEM(0xffe03400),
++      IRQ(16),
++};
++DEFINE_DEV(pio, 3);
++DEV_CLK(mck, pio3, pba, 13);
++
++void __init at32_add_system_devices(void)
++{
++      system_manager.eim_first_irq = NR_INTERNAL_IRQS;
++
++      platform_device_register(&at32_sm_device);
++      platform_device_register(&at32_intc0_device);
++      platform_device_register(&smc0_device);
++      platform_device_register(&pdc_device);
++
++      platform_device_register(&pio0_device);
++      platform_device_register(&pio1_device);
++      platform_device_register(&pio2_device);
++      platform_device_register(&pio3_device);
++}
++
++/* --------------------------------------------------------------------
++ *  USART
++ * -------------------------------------------------------------------- */
++
++static struct resource usart0_resource[] = {
++      PBMEM(0xffe00c00),
++      IRQ(7),
++};
++DEFINE_DEV(usart, 0);
++DEV_CLK(usart, usart0, pba, 4);
++
++static struct resource usart1_resource[] = {
++      PBMEM(0xffe01000),
++      IRQ(7),
++};
++DEFINE_DEV(usart, 1);
++DEV_CLK(usart, usart1, pba, 4);
++
++static struct resource usart2_resource[] = {
++      PBMEM(0xffe01400),
++      IRQ(8),
++};
++DEFINE_DEV(usart, 2);
++DEV_CLK(usart, usart2, pba, 5);
++
++static struct resource usart3_resource[] = {
++      PBMEM(0xffe01800),
++      IRQ(9),
++};
++DEFINE_DEV(usart, 3);
++DEV_CLK(usart, usart3, pba, 6);
++
++static inline void configure_usart0_pins(void)
++{
++      portmux_set_func(PIOA,  8, FUNC_B);     /* RXD  */
++      portmux_set_func(PIOA,  9, FUNC_B);     /* TXD  */
++}
++
++static inline void configure_usart1_pins(void)
++{
++      portmux_set_func(PIOA, 17, FUNC_A);     /* RXD  */
++      portmux_set_func(PIOA, 18, FUNC_A);     /* TXD  */
++}
++
++static inline void configure_usart2_pins(void)
++{
++      portmux_set_func(PIOB, 26, FUNC_B);     /* RXD  */
++      portmux_set_func(PIOB, 27, FUNC_B);     /* TXD  */
++}
++
++static inline void configure_usart3_pins(void)
++{
++      portmux_set_func(PIOB, 18, FUNC_B);     /* RXD  */
++      portmux_set_func(PIOB, 17, FUNC_B);     /* TXD  */
++}
++
++static struct platform_device *setup_usart(unsigned int id)
++{
++      struct platform_device *pdev;
++
++      switch (id) {
++      case 0:
++              pdev = &usart0_device;
++              configure_usart0_pins();
++              break;
++      case 1:
++              pdev = &usart1_device;
++              configure_usart1_pins();
++              break;
++      case 2:
++              pdev = &usart2_device;
++              configure_usart2_pins();
++              break;
++      case 3:
++              pdev = &usart3_device;
++              configure_usart3_pins();
++              break;
++      default:
++              pdev = NULL;
++              break;
++      }
++
++      return pdev;
++}
++
++struct platform_device *__init at32_add_device_usart(unsigned int id)
++{
++      struct platform_device *pdev;
++
++      pdev = setup_usart(id);
++      if (pdev)
++              platform_device_register(pdev);
++
++      return pdev;
++}
++
++struct platform_device *at91_default_console_device;
++
++void __init at32_setup_serial_console(unsigned int usart_id)
++{
++      at91_default_console_device = setup_usart(usart_id);
++}
++
++/* --------------------------------------------------------------------
++ *  Ethernet
++ * -------------------------------------------------------------------- */
++
++static struct eth_platform_data macb0_data;
++static struct resource macb0_resource[] = {
++      PBMEM(0xfff01800),
++      IRQ(25),
++};
++DEFINE_DEV_DATA(macb, 0);
++DEV_CLK(hclk, macb0, hsb, 8);
++DEV_CLK(pclk, macb0, pbb, 6);
++
++struct platform_device *__init
++at32_add_device_eth(unsigned int id, struct eth_platform_data *data)
++{
++      struct platform_device *pdev;
++
++      switch (id) {
++      case 0:
++              pdev = &macb0_device;
++
++              portmux_set_func(PIOC,  3, FUNC_A);     /* TXD0 */
++              portmux_set_func(PIOC,  4, FUNC_A);     /* TXD1 */
++              portmux_set_func(PIOC,  7, FUNC_A);     /* TXEN */
++              portmux_set_func(PIOC,  8, FUNC_A);     /* TXCK */
++              portmux_set_func(PIOC,  9, FUNC_A);     /* RXD0 */
++              portmux_set_func(PIOC, 10, FUNC_A);     /* RXD1 */
++              portmux_set_func(PIOC, 13, FUNC_A);     /* RXER */
++              portmux_set_func(PIOC, 15, FUNC_A);     /* RXDV */
++              portmux_set_func(PIOC, 16, FUNC_A);     /* MDC  */
++              portmux_set_func(PIOC, 17, FUNC_A);     /* MDIO */
++
++              if (!data->is_rmii) {
++                      portmux_set_func(PIOC,  0, FUNC_A);     /* COL  */
++                      portmux_set_func(PIOC,  1, FUNC_A);     /* CRS  */
++                      portmux_set_func(PIOC,  2, FUNC_A);     /* TXER */
++                      portmux_set_func(PIOC,  5, FUNC_A);     /* TXD2 */
++                      portmux_set_func(PIOC,  6, FUNC_A);     /* TXD3 */
++                      portmux_set_func(PIOC, 11, FUNC_A);     /* RXD2 */
++                      portmux_set_func(PIOC, 12, FUNC_A);     /* RXD3 */
++                      portmux_set_func(PIOC, 14, FUNC_A);     /* RXCK */
++                      portmux_set_func(PIOC, 18, FUNC_A);     /* SPD  */
++              }
++              break;
++
++      default:
++              return NULL;
++      }
++
++      memcpy(pdev->dev.platform_data, data, sizeof(struct eth_platform_data));
++      platform_device_register(pdev);
++
++      return pdev;
++}
++
++/* --------------------------------------------------------------------
++ *  SPI
++ * -------------------------------------------------------------------- */
++static struct resource spi0_resource[] = {
++      PBMEM(0xffe00000),
++      IRQ(3),
++};
++DEFINE_DEV(spi, 0);
++DEV_CLK(mck, spi0, pba, 0);
++
++struct platform_device *__init at32_add_device_spi(unsigned int id)
++{
++      struct platform_device *pdev;
++
++      switch (id) {
++      case 0:
++              pdev = &spi0_device;
++              portmux_set_func(PIOA,  0, FUNC_A);     /* MISO  */
++              portmux_set_func(PIOA,  1, FUNC_A);     /* MOSI  */
++              portmux_set_func(PIOA,  2, FUNC_A);     /* SCK   */
++              portmux_set_func(PIOA,  3, FUNC_A);     /* NPCS0 */
++              portmux_set_func(PIOA,  4, FUNC_A);     /* NPCS1 */
++              portmux_set_func(PIOA,  5, FUNC_A);     /* NPCS2 */
++              break;
++
++      default:
++              return NULL;
++      }
++
++      platform_device_register(pdev);
++      return pdev;
++}
++
++/* --------------------------------------------------------------------
++ *  LCDC
++ * -------------------------------------------------------------------- */
++static struct lcdc_platform_data lcdc0_data;
++static struct resource lcdc0_resource[] = {
++      {
++              .start          = 0xff000000,
++              .end            = 0xff000fff,
++              .flags          = IORESOURCE_MEM,
++      },
++      IRQ(1),
++};
++DEFINE_DEV_DATA(lcdc, 0);
++DEV_CLK(hclk, lcdc0, hsb, 7);
++static struct clk lcdc0_pixclk = {
++      .name           = "pixclk",
++      .dev            = &lcdc0_device.dev,
++      .mode           = genclk_mode,
++      .get_rate       = genclk_get_rate,
++      .set_rate       = genclk_set_rate,
++      .set_parent     = genclk_set_parent,
++      .index          = 7,
++};
++
++struct platform_device *__init
++at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data)
++{
++      struct platform_device *pdev;
++
++      switch (id) {
++      case 0:
++              pdev = &lcdc0_device;
++              portmux_set_func(PIOC, 19, FUNC_A);     /* CC     */
++              portmux_set_func(PIOC, 20, FUNC_A);     /* HSYNC  */
++              portmux_set_func(PIOC, 21, FUNC_A);     /* PCLK   */
++              portmux_set_func(PIOC, 22, FUNC_A);     /* VSYNC  */
++              portmux_set_func(PIOC, 23, FUNC_A);     /* DVAL   */
++              portmux_set_func(PIOC, 24, FUNC_A);     /* MODE   */
++              portmux_set_func(PIOC, 25, FUNC_A);     /* PWR    */
++              portmux_set_func(PIOC, 26, FUNC_A);     /* DATA0  */
++              portmux_set_func(PIOC, 27, FUNC_A);     /* DATA1  */
++              portmux_set_func(PIOC, 28, FUNC_A);     /* DATA2  */
++              portmux_set_func(PIOC, 29, FUNC_A);     /* DATA3  */
++              portmux_set_func(PIOC, 30, FUNC_A);     /* DATA4  */
++              portmux_set_func(PIOC, 31, FUNC_A);     /* DATA5  */
++              portmux_set_func(PIOD,  0, FUNC_A);     /* DATA6  */
++              portmux_set_func(PIOD,  1, FUNC_A);     /* DATA7  */
++              portmux_set_func(PIOD,  2, FUNC_A);     /* DATA8  */
++              portmux_set_func(PIOD,  3, FUNC_A);     /* DATA9  */
++              portmux_set_func(PIOD,  4, FUNC_A);     /* DATA10 */
++              portmux_set_func(PIOD,  5, FUNC_A);     /* DATA11 */
++              portmux_set_func(PIOD,  6, FUNC_A);     /* DATA12 */
++              portmux_set_func(PIOD,  7, FUNC_A);     /* DATA13 */
++              portmux_set_func(PIOD,  8, FUNC_A);     /* DATA14 */
++              portmux_set_func(PIOD,  9, FUNC_A);     /* DATA15 */
++              portmux_set_func(PIOD, 10, FUNC_A);     /* DATA16 */
++              portmux_set_func(PIOD, 11, FUNC_A);     /* DATA17 */
++              portmux_set_func(PIOD, 12, FUNC_A);     /* DATA18 */
++              portmux_set_func(PIOD, 13, FUNC_A);     /* DATA19 */
++              portmux_set_func(PIOD, 14, FUNC_A);     /* DATA20 */
++              portmux_set_func(PIOD, 15, FUNC_A);     /* DATA21 */
++              portmux_set_func(PIOD, 16, FUNC_A);     /* DATA22 */
++              portmux_set_func(PIOD, 17, FUNC_A);     /* DATA23 */
++
++              clk_set_parent(&lcdc0_pixclk, &pll0);
++              clk_set_rate(&lcdc0_pixclk, clk_get_rate(&pll0));
++              break;
++
++      default:
++              return NULL;
++      }
++
++      memcpy(pdev->dev.platform_data, data,
++             sizeof(struct lcdc_platform_data));
++
++      platform_device_register(pdev);
++      return pdev;
++}
++
++struct clk *at32_clock_list[] = {
++      &osc32k,
++      &osc0,
++      &osc1,
++      &pll0,
++      &pll1,
++      &cpu_clk,
++      &hsb_clk,
++      &pba_clk,
++      &pbb_clk,
++      &at32_sm_pclk,
++      &at32_intc0_pclk,
++      &ebi_clk,
++      &hramc_clk,
++      &smc0_pclk,
++      &smc0_mck,
++      &pdc_hclk,
++      &pdc_pclk,
++      &pico_clk,
++      &pio0_mck,
++      &pio1_mck,
++      &pio2_mck,
++      &pio3_mck,
++      &usart0_usart,
++      &usart1_usart,
++      &usart2_usart,
++      &usart3_usart,
++      &macb0_hclk,
++      &macb0_pclk,
++      &spi0_mck,
++      &lcdc0_hclk,
++      &lcdc0_pixclk,
++};
++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);
++}
++
++void __init at32_clock_init(void)
++{
++      struct at32_sm *sm = &system_manager;
++      u32 cpu_mask = 0, hsb_mask = 0, pba_mask = 0, pbb_mask = 0;
++      int i;
++
++      if (sm_readl(sm, PM_MCCTRL) & SM_BIT(PLLSEL))
++              main_clock = &pll0;
++      else
++              main_clock = &osc0;
++
++      if (sm_readl(sm, PM_PLL0) & SM_BIT(PLLOSC))
++              pll0.parent = &osc1;
++      if (sm_readl(sm, PM_PLL1) & SM_BIT(PLLOSC))
++              pll1.parent = &osc1;
++
++      /*
++       * Turn on all clocks that have at least one user already, and
++       * turn off everything else. We only do this for module
++       * clocks, and even though it isn't particularly pretty to
++       * check the address of the mode function, it should do the
++       * trick...
++       */
++      for (i = 0; i < ARRAY_SIZE(at32_clock_list); i++) {
++              struct clk *clk = at32_clock_list[i];
++
++              if (clk->mode == &cpu_clk_mode)
++                      cpu_mask |= 1 << clk->index;
++              else if (clk->mode == &hsb_clk_mode)
++                      hsb_mask |= 1 << clk->index;
++              else if (clk->mode == &pba_clk_mode)
++                      pba_mask |= 1 << clk->index;
++              else if (clk->mode == &pbb_clk_mode)
++                      pbb_mask |= 1 << clk->index;
++      }
++
++      sm_writel(sm, PM_CPU_MASK, cpu_mask);
++      sm_writel(sm, PM_HSB_MASK, hsb_mask);
++      sm_writel(sm, PM_PBA_MASK, pba_mask);
++      sm_writel(sm, PM_PBB_MASK, pbb_mask);
++}
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/clock.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/clock.c  2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,148 @@
++/*
++ * Clock management for AT32AP CPUs
++ *
++ * Copyright (C) 2006 Atmel Corporation
++ *
++ * Based on arch/arm/mach-at91rm9200/clock.c
++ *   Copyright (C) 2005 David Brownell
++ *   Copyright (C) 2005 Ivan Kokshaysky
++ *
++ * 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/device.h>
++#include <linux/string.h>
++
++#include "clock.h"
++
++static spinlock_t clk_lock = SPIN_LOCK_UNLOCKED;
++
++struct clk *clk_get(struct device *dev, const char *id)
++{
++      int i;
++
++      for (i = 0; i < at32_nr_clocks; i++) {
++              struct clk *clk = at32_clock_list[i];
++
++              if (clk->dev == dev && strcmp(id, clk->name) == 0)
++                      return clk;
++      }
++
++      return ERR_PTR(-ENOENT);
++}
++EXPORT_SYMBOL(clk_get);
++
++void clk_put(struct clk *clk)
++{
++      /* clocks are static for now, we can't free them */
++}
++EXPORT_SYMBOL(clk_put);
++
++static void __clk_enable(struct clk *clk)
++{
++      if (clk->parent)
++              __clk_enable(clk->parent);
++      if (clk->users++ == 0 && clk->mode)
++              clk->mode(clk, 1);
++}
++
++int clk_enable(struct clk *clk)
++{
++      unsigned long flags;
++
++      spin_lock_irqsave(&clk_lock, flags);
++      __clk_enable(clk);
++      spin_unlock_irqrestore(&clk_lock, flags);
++
++      return 0;
++}
++EXPORT_SYMBOL(clk_enable);
++
++static void __clk_disable(struct clk *clk)
++{
++      BUG_ON(clk->users == 0);
++
++      if (--clk->users == 0 && clk->mode)
++              clk->mode(clk, 0);
++      if (clk->parent)
++              __clk_disable(clk->parent);
++}
++
++void clk_disable(struct clk *clk)
++{
++      unsigned long flags;
++
++      spin_lock_irqsave(&clk_lock, flags);
++      __clk_disable(clk);
++      spin_unlock_irqrestore(&clk_lock, flags);
++}
++EXPORT_SYMBOL(clk_disable);
++
++unsigned long clk_get_rate(struct clk *clk)
++{
++      unsigned long flags;
++      unsigned long rate;
++
++      spin_lock_irqsave(&clk_lock, flags);
++      rate = clk->get_rate(clk);
++      spin_unlock_irqrestore(&clk_lock, flags);
++
++      return rate;
++}
++EXPORT_SYMBOL(clk_get_rate);
++
++long clk_round_rate(struct clk *clk, unsigned long rate)
++{
++      unsigned long flags, actual_rate;
++
++      if (!clk->set_rate)
++              return -ENOSYS;
++
++      spin_lock_irqsave(&clk_lock, flags);
++      actual_rate = clk->set_rate(clk, rate, 0);
++      spin_unlock_irqrestore(&clk_lock, flags);
++
++      return actual_rate;
++}
++EXPORT_SYMBOL(clk_round_rate);
++
++int clk_set_rate(struct clk *clk, unsigned long rate)
++{
++      unsigned long flags;
++      long ret;
++
++      if (!clk->set_rate)
++              return -ENOSYS;
++
++      spin_lock_irqsave(&clk_lock, flags);
++      ret = clk->set_rate(clk, rate, 1);
++      spin_unlock_irqrestore(&clk_lock, flags);
++
++      return (ret < 0) ? ret : 0;
++}
++EXPORT_SYMBOL(clk_set_rate);
++
++int clk_set_parent(struct clk *clk, struct clk *parent)
++{
++      unsigned long flags;
++      int ret;
++
++      if (!clk->set_parent)
++              return -ENOSYS;
++
++      spin_lock_irqsave(&clk_lock, flags);
++      ret = clk->set_parent(clk, parent);
++      spin_unlock_irqrestore(&clk_lock, flags);
++
++      return ret;
++}
++EXPORT_SYMBOL(clk_set_parent);
++
++struct clk *clk_get_parent(struct clk *clk)
++{
++      return clk->parent;
++}
++EXPORT_SYMBOL(clk_get_parent);
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/clock.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/clock.h  2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,30 @@
++/*
++ * Clock management for AT32AP CPUs
++ *
++ * Copyright (C) 2006 Atmel Corporation
++ *
++ * Based on arch/arm/mach-at91rm9200/clock.c
++ *   Copyright (C) 2005 David Brownell
++ *   Copyright (C) 2005 Ivan Kokshaysky
++ *
++ * 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>
++
++struct clk {
++      const char      *name;          /* Clock name/function */
++      struct device   *dev;           /* Device the clock is used by */
++      struct clk      *parent;        /* Parent clock, if any */
++      void            (*mode)(struct clk *clk, int enabled);
++      unsigned long   (*get_rate)(struct clk *clk);
++      long            (*set_rate)(struct clk *clk, unsigned long rate,
++                                  int apply);
++      int             (*set_parent)(struct clk *clk, struct clk *parent);
++      u16             users;          /* Enabled if non-zero */
++      u16             index;          /* Sibling index */
++};
++
++extern struct clk *at32_clock_list[];
++extern unsigned int at32_nr_clocks;
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/extint.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/extint.c 2006-12-04 12:00:24.000000000 +0100
+@@ -0,0 +1,189 @@
++/*
++ * External interrupt handling for AT32AP CPUs
++ *
++ * 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/errno.h>
++#include <linux/init.h>
++#include <linux/interrupt.h>
++#include <linux/irq.h>
++#include <linux/platform_device.h>
++#include <linux/random.h>
++
++#include <asm/io.h>
++
++#include <asm/arch/sm.h>
++
++#include "sm.h"
++
++static void eim_ack_irq(unsigned int irq)
++{
++      struct at32_sm *sm = get_irq_chip_data(irq);
++      sm_writel(sm, EIM_ICR, 1 << (irq - sm->eim_first_irq));
++}
++
++static void eim_mask_irq(unsigned int irq)
++{
++      struct at32_sm *sm = get_irq_chip_data(irq);
++      sm_writel(sm, EIM_IDR, 1 << (irq - sm->eim_first_irq));
++}
++
++static void eim_mask_ack_irq(unsigned int irq)
++{
++      struct at32_sm *sm = get_irq_chip_data(irq);
++      sm_writel(sm, EIM_ICR, 1 << (irq - sm->eim_first_irq));
++      sm_writel(sm, EIM_IDR, 1 << (irq - sm->eim_first_irq));
++}
++
++static void eim_unmask_irq(unsigned int irq)
++{
++      struct at32_sm *sm = get_irq_chip_data(irq);
++      sm_writel(sm, EIM_IER, 1 << (irq - sm->eim_first_irq));
++}
++
++static int eim_set_irq_type(unsigned int irq, unsigned int flow_type)
++{
++      struct at32_sm *sm = get_irq_chip_data(irq);
++      struct irq_desc *desc;
++      unsigned int i = irq - sm->eim_first_irq;
++      u32 mode, edge, level;
++      unsigned long flags;
++      int ret = 0;
++
++      if (flow_type == IRQ_TYPE_NONE)
++              flow_type = IRQ_TYPE_LEVEL_LOW;
++
++      desc = &irq_desc[irq];
++      desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
++      desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
++
++      if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) {
++              desc->status |= IRQ_LEVEL;
++              set_irq_handler(irq, handle_level_irq);
++      } else {
++              set_irq_handler(irq, handle_edge_irq);
++      }
++
++      spin_lock_irqsave(&sm->lock, flags);
++
++      mode = sm_readl(sm, EIM_MODE);
++      edge = sm_readl(sm, EIM_EDGE);
++      level = sm_readl(sm, EIM_LEVEL);
++
++      switch (flow_type) {
++      case IRQ_TYPE_LEVEL_LOW:
++              mode |= 1 << i;
++              level &= ~(1 << i);
++              break;
++      case IRQ_TYPE_LEVEL_HIGH:
++              mode |= 1 << i;
++              level |= 1 << i;
++              break;
++      case IRQ_TYPE_EDGE_RISING:
++              mode &= ~(1 << i);
++              edge |= 1 << i;
++              break;
++      case IRQ_TYPE_EDGE_FALLING:
++              mode &= ~(1 << i);
++              edge &= ~(1 << i);
++              break;
++      default:
++              ret = -EINVAL;
++              break;
++      }
++
++      sm_writel(sm, EIM_MODE, mode);
++      sm_writel(sm, EIM_EDGE, edge);
++      sm_writel(sm, EIM_LEVEL, level);
++
++      spin_unlock_irqrestore(&sm->lock, flags);
++
++      return ret;
++}
++
++struct irq_chip eim_chip = {
++      .name           = "eim",
++      .ack            = eim_ack_irq,
++      .mask           = eim_mask_irq,
++      .mask_ack       = eim_mask_ack_irq,
++      .unmask         = eim_unmask_irq,
++      .set_type       = eim_set_irq_type,
++};
++
++static void demux_eim_irq(unsigned int irq, struct irq_desc *desc,
++                        struct pt_regs *regs)
++{
++      struct at32_sm *sm = desc->handler_data;
++      struct irq_desc *ext_desc;
++      unsigned long status, pending;
++      unsigned int i, ext_irq;
++
++      spin_lock(&sm->lock);
++
++      status = sm_readl(sm, EIM_ISR);
++      pending = status & sm_readl(sm, EIM_IMR);
++
++      while (pending) {
++              i = fls(pending) - 1;
++              pending &= ~(1 << i);
++
++              ext_irq = i + sm->eim_first_irq;
++              ext_desc = irq_desc + ext_irq;
++              ext_desc->handle_irq(ext_irq, ext_desc, regs);
++      }
++
++      spin_unlock(&sm->lock);
++}
++
++static int __init eim_init(void)
++{
++      struct at32_sm *sm = &system_manager;
++      unsigned int i;
++      unsigned int nr_irqs;
++      unsigned int int_irq;
++      u32 pattern;
++
++      /*
++       * The EIM is really the same module as SM, so register
++       * mapping, etc. has been taken care of already.
++       */
++
++      /*
++       * Find out how many interrupt lines that are actually
++       * implemented in hardware.
++       */
++      sm_writel(sm, EIM_IDR, ~0UL);
++      sm_writel(sm, EIM_MODE, ~0UL);
++      pattern = sm_readl(sm, EIM_MODE);
++      nr_irqs = fls(pattern);
++
++      /* Trigger on falling edge unless overridden by driver */
++      sm_writel(sm, EIM_MODE, 0UL);
++      sm_writel(sm, EIM_EDGE, 0UL);
++
++      sm->eim_chip = &eim_chip;
++
++      for (i = 0; i < nr_irqs; i++) {
++              set_irq_chip_and_handler(sm->eim_first_irq + i, &eim_chip,
++                                       handle_edge_irq);
++              set_irq_chip_data(sm->eim_first_irq + i, sm);
++      }
++
++      int_irq = platform_get_irq_byname(sm->pdev, "eim");
++
++      set_irq_chained_handler(int_irq, demux_eim_irq);
++      set_irq_data(int_irq, sm);
++
++      printk("EIM: External Interrupt Module at 0x%p, IRQ %u\n",
++             sm->regs, int_irq);
++      printk("EIM: Handling %u external IRQs, starting with IRQ %u\n",
++             nr_irqs, sm->eim_first_irq);
++
++      return 0;
++}
++arch_initcall(eim_init);
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/intc.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/intc.c   2006-12-04 11:50:22.000000000 +0100
+@@ -0,0 +1,133 @@
++/*
++ * 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/interrupt.h>
++#include <linux/irq.h>
++#include <linux/platform_device.h>
++
++#include <asm/io.h>
++
++#include "intc.h"
++
++struct intc {
++      void __iomem    *regs;
++      struct irq_chip chip;
++};
++
++extern struct platform_device at32_intc0_device;
++
++/*
++ * TODO: We may be able to implement mask/unmask by setting IxM flags
++ * in the status register.
++ */
++static void intc_mask_irq(unsigned int irq)
++{
++
++}
++
++static void intc_unmask_irq(unsigned int irq)
++{
++
++}
++
++static struct intc intc0 = {
++      .chip = {
++              .name           = "intc",
++              .mask           = intc_mask_irq,
++              .unmask         = intc_unmask_irq,
++      },
++};
++
++/*
++ * All interrupts go via intc at some point.
++ */
++asmlinkage void do_IRQ(int level, struct pt_regs *regs)
++{
++      struct irq_desc *desc;
++      unsigned int irq;
++      unsigned long status_reg;
++
++      local_irq_disable();
++
++      irq_enter();
++
++      irq = intc_readl(&intc0, INTCAUSE0 - 4 * level);
++      desc = irq_desc + irq;
++      desc->handle_irq(irq, desc, regs);
++
++      /*
++       * Clear all interrupt level masks so that we may handle
++       * interrupts during softirq processing.  If this is a nested
++       * interrupt, interrupts must stay globally disabled until we
++       * return.
++       */
++      status_reg = sysreg_read(SR);
++      status_reg &= ~(SYSREG_BIT(I0M) | SYSREG_BIT(I1M)
++                      | SYSREG_BIT(I2M) | SYSREG_BIT(I3M));
++      sysreg_write(SR, status_reg);
++
++      irq_exit();
++}
++
++void __init init_IRQ(void)
++{
++      extern void _evba(void);
++      extern void irq_level0(void);
++      struct resource *regs;
++      struct clk *pclk;
++      unsigned int i;
++      u32 offset, readback;
++
++      regs = platform_get_resource(&at32_intc0_device, IORESOURCE_MEM, 0);
++      if (!regs) {
++              printk(KERN_EMERG "intc: no mmio resource defined\n");
++              goto fail;
++      }
++      pclk = clk_get(&at32_intc0_device.dev, "pclk");
++      if (IS_ERR(pclk)) {
++              printk(KERN_EMERG "intc: no clock defined\n");
++              goto fail;
++      }
++
++      clk_enable(pclk);
++
++      intc0.regs = ioremap(regs->start, regs->end - regs->start + 1);
++      if (!intc0.regs) {
++              printk(KERN_EMERG "intc: failed to map registers (0x%08lx)\n",
++                     (unsigned long)regs->start);
++              goto fail;
++      }
++
++      /*
++       * Initialize all interrupts to level 0 (lowest priority). The
++       * priority level may be changed by calling
++       * irq_set_priority().
++       *
++       */
++      offset = (unsigned long)&irq_level0 - (unsigned long)&_evba;
++      for (i = 0; i < NR_INTERNAL_IRQS; i++) {
++              intc_writel(&intc0, INTPR0 + 4 * i, offset);
++              readback = intc_readl(&intc0, INTPR0 + 4 * i);
++              if (readback == offset)
++                      set_irq_chip_and_handler(i, &intc0.chip,
++                                               handle_simple_irq);
++      }
++
++      /* Unmask all interrupt levels */
++      sysreg_write(SR, (sysreg_read(SR)
++                        & ~(SR_I3M | SR_I2M | SR_I1M | SR_I0M)));
++
++      return;
++
++fail:
++      panic("Interrupt controller initialization failed!\n");
++}
++
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/intc.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/intc.h   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,329 @@
++/*
++ * Automatically generated by gen-header.xsl
++ */
++#ifndef __ASM_AVR32_PERIHP_INTC_H__
++#define __ASM_AVR32_PERIHP_INTC_H__
++
++#define INTC_NUM_INT_GRPS            33
++
++#define INTC_INTPR0                  0x0
++# define INTC_INTPR0_INTLEV_OFFSET   30
++# define INTC_INTPR0_INTLEV_SIZE     2
++# define INTC_INTPR0_OFFSET_OFFSET   0
++# define INTC_INTPR0_OFFSET_SIZE     24
++#define INTC_INTREQ0                 0x100
++# define INTC_INTREQ0_IREQUEST0_OFFSET 0
++# define INTC_INTREQ0_IREQUEST0_SIZE 1
++# define INTC_INTREQ0_IREQUEST1_OFFSET 1
++# define INTC_INTREQ0_IREQUEST1_SIZE 1
++#define INTC_INTPR1                  0x4
++# define INTC_INTPR1_INTLEV_OFFSET   30
++# define INTC_INTPR1_INTLEV_SIZE     2
++# define INTC_INTPR1_OFFSET_OFFSET   0
++# define INTC_INTPR1_OFFSET_SIZE     24
++#define INTC_INTREQ1                 0x104
++# define INTC_INTREQ1_IREQUEST32_OFFSET 0
++# define INTC_INTREQ1_IREQUEST32_SIZE 1
++# define INTC_INTREQ1_IREQUEST33_OFFSET 1
++# define INTC_INTREQ1_IREQUEST33_SIZE 1
++# define INTC_INTREQ1_IREQUEST34_OFFSET 2
++# define INTC_INTREQ1_IREQUEST34_SIZE 1
++# define INTC_INTREQ1_IREQUEST35_OFFSET 3
++# define INTC_INTREQ1_IREQUEST35_SIZE 1
++# define INTC_INTREQ1_IREQUEST36_OFFSET 4
++# define INTC_INTREQ1_IREQUEST36_SIZE 1
++# define INTC_INTREQ1_IREQUEST37_OFFSET 5
++# define INTC_INTREQ1_IREQUEST37_SIZE 1
++#define INTC_INTPR2                  0x8
++# define INTC_INTPR2_INTLEV_OFFSET   30
++# define INTC_INTPR2_INTLEV_SIZE     2
++# define INTC_INTPR2_OFFSET_OFFSET   0
++# define INTC_INTPR2_OFFSET_SIZE     24
++#define INTC_INTREQ2                 0x108
++# define INTC_INTREQ2_IREQUEST64_OFFSET 0
++# define INTC_INTREQ2_IREQUEST64_SIZE 1
++# define INTC_INTREQ2_IREQUEST65_OFFSET 1
++# define INTC_INTREQ2_IREQUEST65_SIZE 1
++# define INTC_INTREQ2_IREQUEST66_OFFSET 2
++# define INTC_INTREQ2_IREQUEST66_SIZE 1
++# define INTC_INTREQ2_IREQUEST67_OFFSET 3
++# define INTC_INTREQ2_IREQUEST67_SIZE 1
++# define INTC_INTREQ2_IREQUEST68_OFFSET 4
++# define INTC_INTREQ2_IREQUEST68_SIZE 1
++#define INTC_INTPR3                  0xc
++# define INTC_INTPR3_INTLEV_OFFSET   30
++# define INTC_INTPR3_INTLEV_SIZE     2
++# define INTC_INTPR3_OFFSET_OFFSET   0
++# define INTC_INTPR3_OFFSET_SIZE     24
++#define INTC_INTREQ3                 0x10c
++# define INTC_INTREQ3_IREQUEST96_OFFSET 0
++# define INTC_INTREQ3_IREQUEST96_SIZE 1
++#define INTC_INTPR4                  0x10
++# define INTC_INTPR4_INTLEV_OFFSET   30
++# define INTC_INTPR4_INTLEV_SIZE     2
++# define INTC_INTPR4_OFFSET_OFFSET   0
++# define INTC_INTPR4_OFFSET_SIZE     24
++#define INTC_INTREQ4                 0x110
++# define INTC_INTREQ4_IREQUEST128_OFFSET 0
++# define INTC_INTREQ4_IREQUEST128_SIZE 1
++#define INTC_INTPR5                  0x14
++# define INTC_INTPR5_INTLEV_OFFSET   30
++# define INTC_INTPR5_INTLEV_SIZE     2
++# define INTC_INTPR5_OFFSET_OFFSET   0
++# define INTC_INTPR5_OFFSET_SIZE     24
++#define INTC_INTREQ5                 0x114
++# define INTC_INTREQ5_IREQUEST160_OFFSET 0
++# define INTC_INTREQ5_IREQUEST160_SIZE 1
++#define INTC_INTPR6                  0x18
++# define INTC_INTPR6_INTLEV_OFFSET   30
++# define INTC_INTPR6_INTLEV_SIZE     2
++# define INTC_INTPR6_OFFSET_OFFSET   0
++# define INTC_INTPR6_OFFSET_SIZE     24
++#define INTC_INTREQ6                 0x118
++# define INTC_INTREQ6_IREQUEST192_OFFSET 0
++# define INTC_INTREQ6_IREQUEST192_SIZE 1
++#define INTC_INTPR7                  0x1c
++# define INTC_INTPR7_INTLEV_OFFSET   30
++# define INTC_INTPR7_INTLEV_SIZE     2
++# define INTC_INTPR7_OFFSET_OFFSET   0
++# define INTC_INTPR7_OFFSET_SIZE     24
++#define INTC_INTREQ7                 0x11c
++# define INTC_INTREQ7_IREQUEST224_OFFSET 0
++# define INTC_INTREQ7_IREQUEST224_SIZE 1
++#define INTC_INTPR8                  0x20
++# define INTC_INTPR8_INTLEV_OFFSET   30
++# define INTC_INTPR8_INTLEV_SIZE     2
++# define INTC_INTPR8_OFFSET_OFFSET   0
++# define INTC_INTPR8_OFFSET_SIZE     24
++#define INTC_INTREQ8                 0x120
++# define INTC_INTREQ8_IREQUEST256_OFFSET 0
++# define INTC_INTREQ8_IREQUEST256_SIZE 1
++#define INTC_INTPR9                  0x24
++# define INTC_INTPR9_INTLEV_OFFSET   30
++# define INTC_INTPR9_INTLEV_SIZE     2
++# define INTC_INTPR9_OFFSET_OFFSET   0
++# define INTC_INTPR9_OFFSET_SIZE     24
++#define INTC_INTREQ9                 0x124
++# define INTC_INTREQ9_IREQUEST288_OFFSET 0
++# define INTC_INTREQ9_IREQUEST288_SIZE 1
++#define INTC_INTPR10                 0x28
++# define INTC_INTPR10_INTLEV_OFFSET  30
++# define INTC_INTPR10_INTLEV_SIZE    2
++# define INTC_INTPR10_OFFSET_OFFSET  0
++# define INTC_INTPR10_OFFSET_SIZE    24
++#define INTC_INTREQ10                0x128
++# define INTC_INTREQ10_IREQUEST320_OFFSET 0
++# define INTC_INTREQ10_IREQUEST320_SIZE 1
++#define INTC_INTPR11                 0x2c
++# define INTC_INTPR11_INTLEV_OFFSET  30
++# define INTC_INTPR11_INTLEV_SIZE    2
++# define INTC_INTPR11_OFFSET_OFFSET  0
++# define INTC_INTPR11_OFFSET_SIZE    24
++#define INTC_INTREQ11                0x12c
++# define INTC_INTREQ11_IREQUEST352_OFFSET 0
++# define INTC_INTREQ11_IREQUEST352_SIZE 1
++#define INTC_INTPR12                 0x30
++# define INTC_INTPR12_INTLEV_OFFSET  30
++# define INTC_INTPR12_INTLEV_SIZE    2
++# define INTC_INTPR12_OFFSET_OFFSET  0
++# define INTC_INTPR12_OFFSET_SIZE    24
++#define INTC_INTREQ12                0x130
++# define INTC_INTREQ12_IREQUEST384_OFFSET 0
++# define INTC_INTREQ12_IREQUEST384_SIZE 1
++#define INTC_INTPR13                 0x34
++# define INTC_INTPR13_INTLEV_OFFSET  30
++# define INTC_INTPR13_INTLEV_SIZE    2
++# define INTC_INTPR13_OFFSET_OFFSET  0
++# define INTC_INTPR13_OFFSET_SIZE    24
++#define INTC_INTREQ13                0x134
++# define INTC_INTREQ13_IREQUEST416_OFFSET 0
++# define INTC_INTREQ13_IREQUEST416_SIZE 1
++#define INTC_INTPR14                 0x38
++# define INTC_INTPR14_INTLEV_OFFSET  30
++# define INTC_INTPR14_INTLEV_SIZE    2
++# define INTC_INTPR14_OFFSET_OFFSET  0
++# define INTC_INTPR14_OFFSET_SIZE    24
++#define INTC_INTREQ14                0x138
++# define INTC_INTREQ14_IREQUEST448_OFFSET 0
++# define INTC_INTREQ14_IREQUEST448_SIZE 1
++#define INTC_INTPR15                 0x3c
++# define INTC_INTPR15_INTLEV_OFFSET  30
++# define INTC_INTPR15_INTLEV_SIZE    2
++# define INTC_INTPR15_OFFSET_OFFSET  0
++# define INTC_INTPR15_OFFSET_SIZE    24
++#define INTC_INTREQ15                0x13c
++# define INTC_INTREQ15_IREQUEST480_OFFSET 0
++# define INTC_INTREQ15_IREQUEST480_SIZE 1
++#define INTC_INTPR16                 0x40
++# define INTC_INTPR16_INTLEV_OFFSET  30
++# define INTC_INTPR16_INTLEV_SIZE    2
++# define INTC_INTPR16_OFFSET_OFFSET  0
++# define INTC_INTPR16_OFFSET_SIZE    24
++#define INTC_INTREQ16                0x140
++# define INTC_INTREQ16_IREQUEST512_OFFSET 0
++# define INTC_INTREQ16_IREQUEST512_SIZE 1
++#define INTC_INTPR17                 0x44
++# define INTC_INTPR17_INTLEV_OFFSET  30
++# define INTC_INTPR17_INTLEV_SIZE    2
++# define INTC_INTPR17_OFFSET_OFFSET  0
++# define INTC_INTPR17_OFFSET_SIZE    24
++#define INTC_INTREQ17                0x144
++# define INTC_INTREQ17_IREQUEST544_OFFSET 0
++# define INTC_INTREQ17_IREQUEST544_SIZE 1
++#define INTC_INTPR18                 0x48
++# define INTC_INTPR18_INTLEV_OFFSET  30
++# define INTC_INTPR18_INTLEV_SIZE    2
++# define INTC_INTPR18_OFFSET_OFFSET  0
++# define INTC_INTPR18_OFFSET_SIZE    24
++#define INTC_INTREQ18                0x148
++# define INTC_INTREQ18_IREQUEST576_OFFSET 0
++# define INTC_INTREQ18_IREQUEST576_SIZE 1
++#define INTC_INTPR19                 0x4c
++# define INTC_INTPR19_INTLEV_OFFSET  30
++# define INTC_INTPR19_INTLEV_SIZE    2
++# define INTC_INTPR19_OFFSET_OFFSET  0
++# define INTC_INTPR19_OFFSET_SIZE    24
++#define INTC_INTREQ19                0x14c
++# define INTC_INTREQ19_IREQUEST608_OFFSET 0
++# define INTC_INTREQ19_IREQUEST608_SIZE 1
++# define INTC_INTREQ19_IREQUEST609_OFFSET 1
++# define INTC_INTREQ19_IREQUEST609_SIZE 1
++# define INTC_INTREQ19_IREQUEST610_OFFSET 2
++# define INTC_INTREQ19_IREQUEST610_SIZE 1
++# define INTC_INTREQ19_IREQUEST611_OFFSET 3
++# define INTC_INTREQ19_IREQUEST611_SIZE 1
++#define INTC_INTPR20                 0x50
++# define INTC_INTPR20_INTLEV_OFFSET  30
++# define INTC_INTPR20_INTLEV_SIZE    2
++# define INTC_INTPR20_OFFSET_OFFSET  0
++# define INTC_INTPR20_OFFSET_SIZE    24
++#define INTC_INTREQ20                0x150
++# define INTC_INTREQ20_IREQUEST640_OFFSET 0
++# define INTC_INTREQ20_IREQUEST640_SIZE 1
++#define INTC_INTPR21                 0x54
++# define INTC_INTPR21_INTLEV_OFFSET  30
++# define INTC_INTPR21_INTLEV_SIZE    2
++# define INTC_INTPR21_OFFSET_OFFSET  0
++# define INTC_INTPR21_OFFSET_SIZE    24
++#define INTC_INTREQ21                0x154
++# define INTC_INTREQ21_IREQUEST672_OFFSET 0
++# define INTC_INTREQ21_IREQUEST672_SIZE 1
++#define INTC_INTPR22                 0x58
++# define INTC_INTPR22_INTLEV_OFFSET  30
++# define INTC_INTPR22_INTLEV_SIZE    2
++# define INTC_INTPR22_OFFSET_OFFSET  0
++# define INTC_INTPR22_OFFSET_SIZE    24
++#define INTC_INTREQ22                0x158
++# define INTC_INTREQ22_IREQUEST704_OFFSET 0
++# define INTC_INTREQ22_IREQUEST704_SIZE 1
++# define INTC_INTREQ22_IREQUEST705_OFFSET 1
++# define INTC_INTREQ22_IREQUEST705_SIZE 1
++# define INTC_INTREQ22_IREQUEST706_OFFSET 2
++# define INTC_INTREQ22_IREQUEST706_SIZE 1
++#define INTC_INTPR23                 0x5c
++# define INTC_INTPR23_INTLEV_OFFSET  30
++# define INTC_INTPR23_INTLEV_SIZE    2
++# define INTC_INTPR23_OFFSET_OFFSET  0
++# define INTC_INTPR23_OFFSET_SIZE    24
++#define INTC_INTREQ23                0x15c
++# define INTC_INTREQ23_IREQUEST736_OFFSET 0
++# define INTC_INTREQ23_IREQUEST736_SIZE 1
++# define INTC_INTREQ23_IREQUEST737_OFFSET 1
++# define INTC_INTREQ23_IREQUEST737_SIZE 1
++# define INTC_INTREQ23_IREQUEST738_OFFSET 2
++# define INTC_INTREQ23_IREQUEST738_SIZE 1
++#define INTC_INTPR24                 0x60
++# define INTC_INTPR24_INTLEV_OFFSET  30
++# define INTC_INTPR24_INTLEV_SIZE    2
++# define INTC_INTPR24_OFFSET_OFFSET  0
++# define INTC_INTPR24_OFFSET_SIZE    24
++#define INTC_INTREQ24                0x160
++# define INTC_INTREQ24_IREQUEST768_OFFSET 0
++# define INTC_INTREQ24_IREQUEST768_SIZE 1
++#define INTC_INTPR25                 0x64
++# define INTC_INTPR25_INTLEV_OFFSET  30
++# define INTC_INTPR25_INTLEV_SIZE    2
++# define INTC_INTPR25_OFFSET_OFFSET  0
++# define INTC_INTPR25_OFFSET_SIZE    24
++#define INTC_INTREQ25                0x164
++# define INTC_INTREQ25_IREQUEST800_OFFSET 0
++# define INTC_INTREQ25_IREQUEST800_SIZE 1
++#define INTC_INTPR26                 0x68
++# define INTC_INTPR26_INTLEV_OFFSET  30
++# define INTC_INTPR26_INTLEV_SIZE    2
++# define INTC_INTPR26_OFFSET_OFFSET  0
++# define INTC_INTPR26_OFFSET_SIZE    24
++#define INTC_INTREQ26                0x168
++# define INTC_INTREQ26_IREQUEST832_OFFSET 0
++# define INTC_INTREQ26_IREQUEST832_SIZE 1
++#define INTC_INTPR27                 0x6c
++# define INTC_INTPR27_INTLEV_OFFSET  30
++# define INTC_INTPR27_INTLEV_SIZE    2
++# define INTC_INTPR27_OFFSET_OFFSET  0
++# define INTC_INTPR27_OFFSET_SIZE    24
++#define INTC_INTREQ27                0x16c
++# define INTC_INTREQ27_IREQUEST864_OFFSET 0
++# define INTC_INTREQ27_IREQUEST864_SIZE 1
++#define INTC_INTPR28                 0x70
++# define INTC_INTPR28_INTLEV_OFFSET  30
++# define INTC_INTPR28_INTLEV_SIZE    2
++# define INTC_INTPR28_OFFSET_OFFSET  0
++# define INTC_INTPR28_OFFSET_SIZE    24
++#define INTC_INTREQ28                0x170
++# define INTC_INTREQ28_IREQUEST896_OFFSET 0
++# define INTC_INTREQ28_IREQUEST896_SIZE 1
++#define INTC_INTPR29                 0x74
++# define INTC_INTPR29_INTLEV_OFFSET  30
++# define INTC_INTPR29_INTLEV_SIZE    2
++# define INTC_INTPR29_OFFSET_OFFSET  0
++# define INTC_INTPR29_OFFSET_SIZE    24
++#define INTC_INTREQ29                0x174
++# define INTC_INTREQ29_IREQUEST928_OFFSET 0
++# define INTC_INTREQ29_IREQUEST928_SIZE 1
++#define INTC_INTPR30                 0x78
++# define INTC_INTPR30_INTLEV_OFFSET  30
++# define INTC_INTPR30_INTLEV_SIZE    2
++# define INTC_INTPR30_OFFSET_OFFSET  0
++# define INTC_INTPR30_OFFSET_SIZE    24
++#define INTC_INTREQ30                0x178
++# define INTC_INTREQ30_IREQUEST960_OFFSET 0
++# define INTC_INTREQ30_IREQUEST960_SIZE 1
++#define INTC_INTPR31                 0x7c
++# define INTC_INTPR31_INTLEV_OFFSET  30
++# define INTC_INTPR31_INTLEV_SIZE    2
++# define INTC_INTPR31_OFFSET_OFFSET  0
++# define INTC_INTPR31_OFFSET_SIZE    24
++#define INTC_INTREQ31                0x17c
++# define INTC_INTREQ31_IREQUEST992_OFFSET 0
++# define INTC_INTREQ31_IREQUEST992_SIZE 1
++#define INTC_INTPR32                 0x80
++# define INTC_INTPR32_INTLEV_OFFSET  30
++# define INTC_INTPR32_INTLEV_SIZE    2
++# define INTC_INTPR32_OFFSET_OFFSET  0
++# define INTC_INTPR32_OFFSET_SIZE    24
++#define INTC_INTREQ32                0x180
++# define INTC_INTREQ32_IREQUEST1024_OFFSET 0
++# define INTC_INTREQ32_IREQUEST1024_SIZE 1
++#define INTC_INTCAUSE0               0x20c
++# define INTC_INTCAUSE0_CAUSEGRP_OFFSET 0
++# define INTC_INTCAUSE0_CAUSEGRP_SIZE 6
++#define INTC_INTCAUSE1               0x208
++# define INTC_INTCAUSE1_CAUSEGRP_OFFSET 0
++# define INTC_INTCAUSE1_CAUSEGRP_SIZE 6
++#define INTC_INTCAUSE2               0x204
++# define INTC_INTCAUSE2_CAUSEGRP_OFFSET 0
++# define INTC_INTCAUSE2_CAUSEGRP_SIZE 6
++#define INTC_INTCAUSE3               0x200
++# define INTC_INTCAUSE3_CAUSEGRP_OFFSET 0
++# define INTC_INTCAUSE3_CAUSEGRP_SIZE 6
++
++#define INTC_BIT(name)               (1 << INTC_##name##_OFFSET)
++#define INTC_MKBF(name, value)       (((value) & ((1 << INTC_##name##_SIZE) - 1)) << INTC_##name##_OFFSET)
++#define INTC_GETBF(name, value)      (((value) >> INTC_##name##_OFFSET) & ((1 << INTC_##name##_SIZE) - 1))
++
++#define intc_readl(port,reg)                                  \
++      __raw_readl((port)->regs + INTC_##reg)
++#define intc_writel(port,reg,value)                           \
++      __raw_writel((value), (port)->regs + INTC_##reg)
++
++#endif /* __ASM_AVR32_PERIHP_INTC_H__ */
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c    2006-12-04 11:50:25.000000000 +0100
+@@ -0,0 +1,118 @@
++/*
++ * Atmel PIO2 Port Multiplexer support
++ *
++ * 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/clk.h>
++#include <linux/debugfs.h>
++#include <linux/fs.h>
++#include <linux/platform_device.h>
++
++#include <asm/io.h>
++
++#include <asm/arch/portmux.h>
++
++#include "pio.h"
++
++#define MAX_NR_PIO_DEVICES            8
++
++struct pio_device {
++      void __iomem *regs;
++      const struct platform_device *pdev;
++      struct clk *clk;
++      u32 alloc_mask;
++      char name[32];
++};
++
++static struct pio_device pio_dev[MAX_NR_PIO_DEVICES];
++
++void portmux_set_func(unsigned int portmux_id, unsigned int pin_id,
++                    unsigned int function_id)
++{
++      struct pio_device *pio;
++      u32 mask = 1 << pin_id;
++
++      BUG_ON(portmux_id >= MAX_NR_PIO_DEVICES);
++
++      pio = &pio_dev[portmux_id];
++
++      if (function_id)
++              pio_writel(pio, BSR, mask);
++      else
++              pio_writel(pio, ASR, mask);
++      pio_writel(pio, PDR, mask);
++}
++
++static int __init pio_probe(struct platform_device *pdev)
++{
++      struct pio_device *pio = NULL;
++
++      BUG_ON(pdev->id >= MAX_NR_PIO_DEVICES);
++      pio = &pio_dev[pdev->id];
++      BUG_ON(!pio->regs);
++
++      /* TODO: Interrupts */
++
++      platform_set_drvdata(pdev, pio);
++
++      printk(KERN_INFO "%s: Atmel Port Multiplexer at 0x%p (irq %d)\n",
++             pio->name, pio->regs, platform_get_irq(pdev, 0));
++
++      return 0;
++}
++
++static struct platform_driver pio_driver = {
++      .probe          = pio_probe,
++      .driver         = {
++              .name           = "pio",
++      },
++};
++
++static int __init pio_init(void)
++{
++      return platform_driver_register(&pio_driver);
++}
++subsys_initcall(pio_init);
++
++void __init at32_init_pio(struct platform_device *pdev)
++{
++      struct resource *regs;
++      struct pio_device *pio;
++
++      if (pdev->id > MAX_NR_PIO_DEVICES) {
++              dev_err(&pdev->dev, "only %d PIO devices supported\n",
++                      MAX_NR_PIO_DEVICES);
++              return;
++      }
++
++      pio = &pio_dev[pdev->id];
++      snprintf(pio->name, sizeof(pio->name), "pio%d", pdev->id);
++
++      regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!regs) {
++              dev_err(&pdev->dev, "no mmio resource defined\n");
++              return;
++      }
++
++      pio->clk = clk_get(&pdev->dev, "mck");
++      if (IS_ERR(pio->clk))
++              /*
++               * This is a fatal error, but if we continue we might
++               * be so lucky that we manage to initialize the
++               * console and display this message...
++               */
++              dev_err(&pdev->dev, "no mck clock defined\n");
++      else
++              clk_enable(pio->clk);
++
++      pio->pdev = pdev;
++      pio->regs = ioremap(regs->start, regs->end - regs->start + 1);
++
++      pio_writel(pio, ODR, ~0UL);
++      pio_writel(pio, PER, ~0UL);
++}
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.h    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,180 @@
++/*
++ * Atmel PIO2 Port Multiplexer support
++ *
++ * 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 __ARCH_AVR32_AT32AP_PIO_H__
++#define __ARCH_AVR32_AT32AP_PIO_H__
++
++/* PIO register offsets */
++#define PIO_PER                                0x0000
++#define PIO_PDR                                0x0004
++#define PIO_PSR                                0x0008
++#define PIO_OER                                0x0010
++#define PIO_ODR                                0x0014
++#define PIO_OSR                                0x0018
++#define PIO_IFER                               0x0020
++#define PIO_IFDR                               0x0024
++#define PIO_ISFR                               0x0028
++#define PIO_SODR                               0x0030
++#define PIO_CODR                               0x0034
++#define PIO_ODSR                               0x0038
++#define PIO_PDSR                               0x003c
++#define PIO_IER                                0x0040
++#define PIO_IDR                                0x0044
++#define PIO_IMR                                0x0048
++#define PIO_ISR                                0x004c
++#define PIO_MDER                               0x0050
++#define PIO_MDDR                               0x0054
++#define PIO_MDSR                               0x0058
++#define PIO_PUDR                               0x0060
++#define PIO_PUER                               0x0064
++#define PIO_PUSR                               0x0068
++#define PIO_ASR                                0x0070
++#define PIO_BSR                                0x0074
++#define PIO_ABSR                               0x0078
++#define PIO_OWER                               0x00a0
++#define PIO_OWDR                               0x00a4
++#define PIO_OWSR                               0x00a8
++
++/* Bitfields in PER */
++
++/* Bitfields in PDR */
++
++/* Bitfields in PSR */
++
++/* Bitfields in OER */
++
++/* Bitfields in ODR */
++
++/* Bitfields in OSR */
++
++/* Bitfields in IFER */
++
++/* Bitfields in IFDR */
++
++/* Bitfields in ISFR */
++
++/* Bitfields in SODR */
++
++/* Bitfields in CODR */
++
++/* Bitfields in ODSR */
++
++/* Bitfields in PDSR */
++
++/* Bitfields in IER */
++
++/* Bitfields in IDR */
++
++/* Bitfields in IMR */
++
++/* Bitfields in ISR */
++
++/* Bitfields in MDER */
++
++/* Bitfields in MDDR */
++
++/* Bitfields in MDSR */
++
++/* Bitfields in PUDR */
++
++/* Bitfields in PUER */
++
++/* Bitfields in PUSR */
++
++/* Bitfields in ASR */
++
++/* Bitfields in BSR */
++
++/* Bitfields in ABSR */
++#define PIO_P0_OFFSET                          0
++#define PIO_P0_SIZE                            1
++#define PIO_P1_OFFSET                          1
++#define PIO_P1_SIZE                            1
++#define PIO_P2_OFFSET                          2
++#define PIO_P2_SIZE                            1
++#define PIO_P3_OFFSET                          3
++#define PIO_P3_SIZE                            1
++#define PIO_P4_OFFSET                          4
++#define PIO_P4_SIZE                            1
++#define PIO_P5_OFFSET                          5
++#define PIO_P5_SIZE                            1
++#define PIO_P6_OFFSET                          6
++#define PIO_P6_SIZE                            1
++#define PIO_P7_OFFSET                          7
++#define PIO_P7_SIZE                            1
++#define PIO_P8_OFFSET                          8
++#define PIO_P8_SIZE                            1
++#define PIO_P9_OFFSET                          9
++#define PIO_P9_SIZE                            1
++#define PIO_P10_OFFSET                         10
++#define PIO_P10_SIZE                           1
++#define PIO_P11_OFFSET                         11
++#define PIO_P11_SIZE                           1
++#define PIO_P12_OFFSET                         12
++#define PIO_P12_SIZE                           1
++#define PIO_P13_OFFSET                         13
++#define PIO_P13_SIZE                           1
++#define PIO_P14_OFFSET                         14
++#define PIO_P14_SIZE                           1
++#define PIO_P15_OFFSET                         15
++#define PIO_P15_SIZE                           1
++#define PIO_P16_OFFSET                         16
++#define PIO_P16_SIZE                           1
++#define PIO_P17_OFFSET                         17
++#define PIO_P17_SIZE                           1
++#define PIO_P18_OFFSET                         18
++#define PIO_P18_SIZE                           1
++#define PIO_P19_OFFSET                         19
++#define PIO_P19_SIZE                           1
++#define PIO_P20_OFFSET                         20
++#define PIO_P20_SIZE                           1
++#define PIO_P21_OFFSET                         21
++#define PIO_P21_SIZE                           1
++#define PIO_P22_OFFSET                         22
++#define PIO_P22_SIZE                           1
++#define PIO_P23_OFFSET                         23
++#define PIO_P23_SIZE                           1
++#define PIO_P24_OFFSET                         24
++#define PIO_P24_SIZE                           1
++#define PIO_P25_OFFSET                         25
++#define PIO_P25_SIZE                           1
++#define PIO_P26_OFFSET                         26
++#define PIO_P26_SIZE                           1
++#define PIO_P27_OFFSET                         27
++#define PIO_P27_SIZE                           1
++#define PIO_P28_OFFSET                         28
++#define PIO_P28_SIZE                           1
++#define PIO_P29_OFFSET                         29
++#define PIO_P29_SIZE                           1
++#define PIO_P30_OFFSET                         30
++#define PIO_P30_SIZE                           1
++#define PIO_P31_OFFSET                         31
++#define PIO_P31_SIZE                           1
++
++/* Bitfields in OWER */
++
++/* Bitfields in OWDR */
++
++/* Bitfields in OWSR */
++
++/* Bit manipulation macros */
++#define PIO_BIT(name)                          (1 << PIO_##name##_OFFSET)
++#define PIO_BF(name,value)                     (((value) & ((1 << PIO_##name##_SIZE) - 1)) << PIO_##name##_OFFSET)
++#define PIO_BFEXT(name,value)                  (((value) >> PIO_##name##_OFFSET) & ((1 << PIO_##name##_SIZE) - 1))
++#define PIO_BFINS(name,value,old)              (((old) & ~(((1 << PIO_##name##_SIZE) - 1) << PIO_##name##_OFFSET)) | PIO_BF(name,value))
++
++/* Register access macros */
++#define pio_readl(port,reg)                                   \
++      __raw_readl((port)->regs + PIO_##reg)
++#define pio_writel(port,reg,value)                            \
++      __raw_writel((value), (port)->regs + PIO_##reg)
++
++void at32_init_pio(struct platform_device *pdev);
++
++#endif /* __ARCH_AVR32_AT32AP_PIO_H__ */
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/sm.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/sm.h     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,242 @@
++/*
++ * Register definitions for SM
++ *
++ * System Manager
++ */
++#ifndef __ASM_AVR32_SM_H__
++#define __ASM_AVR32_SM_H__
++
++/* SM register offsets */
++#define SM_PM_MCCTRL                            0x0000
++#define SM_PM_CKSEL                             0x0004
++#define SM_PM_CPU_MASK                          0x0008
++#define SM_PM_HSB_MASK                          0x000c
++#define SM_PM_PBA_MASK                         0x0010
++#define SM_PM_PBB_MASK                         0x0014
++#define SM_PM_PLL0                              0x0020
++#define SM_PM_PLL1                              0x0024
++#define SM_PM_VCTRL                             0x0030
++#define SM_PM_VMREF                             0x0034
++#define SM_PM_VMV                               0x0038
++#define SM_PM_IER                               0x0040
++#define SM_PM_IDR                               0x0044
++#define SM_PM_IMR                               0x0048
++#define SM_PM_ISR                               0x004c
++#define SM_PM_ICR                               0x0050
++#define SM_PM_GCCTRL                            0x0060
++#define SM_RTC_CTRL                             0x0080
++#define SM_RTC_VAL                              0x0084
++#define SM_RTC_TOP                              0x0088
++#define SM_RTC_IER                              0x0090
++#define SM_RTC_IDR                              0x0094
++#define SM_RTC_IMR                              0x0098
++#define SM_RTC_ISR                              0x009c
++#define SM_RTC_ICR                              0x00a0
++#define SM_WDT_CTRL                             0x00b0
++#define SM_WDT_CLR                              0x00b4
++#define SM_WDT_EXT                              0x00b8
++#define SM_RC_RCAUSE                            0x00c0
++#define SM_EIM_IER                              0x0100
++#define SM_EIM_IDR                              0x0104
++#define SM_EIM_IMR                              0x0108
++#define SM_EIM_ISR                              0x010c
++#define SM_EIM_ICR                              0x0110
++#define SM_EIM_MODE                             0x0114
++#define SM_EIM_EDGE                             0x0118
++#define SM_EIM_LEVEL                            0x011c
++#define SM_EIM_TEST                             0x0120
++#define SM_EIM_NMIC                             0x0124
++
++/* Bitfields in PM_MCCTRL */
++
++/* Bitfields in PM_CKSEL */
++#define SM_CPUSEL_OFFSET                        0
++#define SM_CPUSEL_SIZE                          3
++#define SM_CPUDIV_OFFSET                        7
++#define SM_CPUDIV_SIZE                          1
++#define SM_HSBSEL_OFFSET                        8
++#define SM_HSBSEL_SIZE                          3
++#define SM_HSBDIV_OFFSET                        15
++#define SM_HSBDIV_SIZE                          1
++#define SM_PBASEL_OFFSET                       16
++#define SM_PBASEL_SIZE                         3
++#define SM_PBADIV_OFFSET                       23
++#define SM_PBADIV_SIZE                         1
++#define SM_PBBSEL_OFFSET                       24
++#define SM_PBBSEL_SIZE                         3
++#define SM_PBBDIV_OFFSET                       31
++#define SM_PBBDIV_SIZE                         1
++
++/* Bitfields in PM_CPU_MASK */
++
++/* Bitfields in PM_HSB_MASK */
++
++/* Bitfields in PM_PBA_MASK */
++
++/* Bitfields in PM_PBB_MASK */
++
++/* Bitfields in PM_PLL0 */
++#define SM_PLLEN_OFFSET                         0
++#define SM_PLLEN_SIZE                           1
++#define SM_PLLOSC_OFFSET                        1
++#define SM_PLLOSC_SIZE                          1
++#define SM_PLLOPT_OFFSET                        2
++#define SM_PLLOPT_SIZE                          3
++#define SM_PLLDIV_OFFSET                        8
++#define SM_PLLDIV_SIZE                          8
++#define SM_PLLMUL_OFFSET                        16
++#define SM_PLLMUL_SIZE                          8
++#define SM_PLLCOUNT_OFFSET                      24
++#define SM_PLLCOUNT_SIZE                        6
++#define SM_PLLTEST_OFFSET                       31
++#define SM_PLLTEST_SIZE                         1
++
++/* Bitfields in PM_PLL1 */
++
++/* Bitfields in PM_VCTRL */
++#define SM_VAUTO_OFFSET                         0
++#define SM_VAUTO_SIZE                           1
++#define SM_PM_VCTRL_VAL_OFFSET                  8
++#define SM_PM_VCTRL_VAL_SIZE                    7
++
++/* Bitfields in PM_VMREF */
++#define SM_REFSEL_OFFSET                        0
++#define SM_REFSEL_SIZE                          4
++
++/* Bitfields in PM_VMV */
++#define SM_PM_VMV_VAL_OFFSET                    0
++#define SM_PM_VMV_VAL_SIZE                      8
++
++/* Bitfields in PM_IER */
++
++/* Bitfields in PM_IDR */
++
++/* Bitfields in PM_IMR */
++
++/* Bitfields in PM_ISR */
++
++/* Bitfields in PM_ICR */
++#define SM_LOCK0_OFFSET                         0
++#define SM_LOCK0_SIZE                           1
++#define SM_LOCK1_OFFSET                         1
++#define SM_LOCK1_SIZE                           1
++#define SM_WAKE_OFFSET                          2
++#define SM_WAKE_SIZE                            1
++#define SM_VOK_OFFSET                           3
++#define SM_VOK_SIZE                             1
++#define SM_VMRDY_OFFSET                         4
++#define SM_VMRDY_SIZE                           1
++#define SM_CKRDY_OFFSET                         5
++#define SM_CKRDY_SIZE                           1
++
++/* Bitfields in PM_GCCTRL */
++#define SM_OSCSEL_OFFSET                        0
++#define SM_OSCSEL_SIZE                          1
++#define SM_PLLSEL_OFFSET                        1
++#define SM_PLLSEL_SIZE                          1
++#define SM_CEN_OFFSET                           2
++#define SM_CEN_SIZE                             1
++#define SM_CPC_OFFSET                           3
++#define SM_CPC_SIZE                             1
++#define SM_DIVEN_OFFSET                         4
++#define SM_DIVEN_SIZE                           1
++#define SM_DIV_OFFSET                           8
++#define SM_DIV_SIZE                             8
++
++/* Bitfields in RTC_CTRL */
++#define SM_PCLR_OFFSET                          1
++#define SM_PCLR_SIZE                            1
++#define SM_TOPEN_OFFSET                         2
++#define SM_TOPEN_SIZE                           1
++#define SM_CLKEN_OFFSET                         3
++#define SM_CLKEN_SIZE                           1
++#define SM_PSEL_OFFSET                          8
++#define SM_PSEL_SIZE                            16
++
++/* Bitfields in RTC_VAL */
++#define SM_RTC_VAL_VAL_OFFSET                   0
++#define SM_RTC_VAL_VAL_SIZE                     31
++
++/* Bitfields in RTC_TOP */
++#define SM_RTC_TOP_VAL_OFFSET                   0
++#define SM_RTC_TOP_VAL_SIZE                     32
++
++/* Bitfields in RTC_IER */
++
++/* Bitfields in RTC_IDR */
++
++/* Bitfields in RTC_IMR */
++
++/* Bitfields in RTC_ISR */
++
++/* Bitfields in RTC_ICR */
++#define SM_TOPI_OFFSET                          0
++#define SM_TOPI_SIZE                            1
++
++/* Bitfields in WDT_CTRL */
++#define SM_KEY_OFFSET                           24
++#define SM_KEY_SIZE                             8
++
++/* Bitfields in WDT_CLR */
++
++/* Bitfields in WDT_EXT */
++
++/* Bitfields in RC_RCAUSE */
++#define SM_POR_OFFSET                           0
++#define SM_POR_SIZE                             1
++#define SM_BOD_OFFSET                           1
++#define SM_BOD_SIZE                             1
++#define SM_EXT_OFFSET                           2
++#define SM_EXT_SIZE                             1
++#define SM_WDT_OFFSET                           3
++#define SM_WDT_SIZE                             1
++#define SM_NTAE_OFFSET                          4
++#define SM_NTAE_SIZE                            1
++#define SM_SERP_OFFSET                          5
++#define SM_SERP_SIZE                            1
++
++/* Bitfields in EIM_IER */
++
++/* Bitfields in EIM_IDR */
++
++/* Bitfields in EIM_IMR */
++
++/* Bitfields in EIM_ISR */
++
++/* Bitfields in EIM_ICR */
++
++/* Bitfields in EIM_MODE */
++
++/* Bitfields in EIM_EDGE */
++#define SM_INT0_OFFSET                          0
++#define SM_INT0_SIZE                            1
++#define SM_INT1_OFFSET                          1
++#define SM_INT1_SIZE                            1
++#define SM_INT2_OFFSET                          2
++#define SM_INT2_SIZE                            1
++#define SM_INT3_OFFSET                          3
++#define SM_INT3_SIZE                            1
++
++/* Bitfields in EIM_LEVEL */
++
++/* Bitfields in EIM_TEST */
++#define SM_TESTEN_OFFSET                        31
++#define SM_TESTEN_SIZE                          1
++
++/* Bitfields in EIM_NMIC */
++#define SM_EN_OFFSET                            0
++#define SM_EN_SIZE                              1
++
++/* Bit manipulation macros */
++#define SM_BIT(name)                            (1 << SM_##name##_OFFSET)
++#define SM_BF(name,value)                       (((value) & ((1 << SM_##name##_SIZE) - 1)) << SM_##name##_OFFSET)
++#define SM_BFEXT(name,value)                    (((value) >> SM_##name##_OFFSET) & ((1 << SM_##name##_SIZE) - 1))
++#define SM_BFINS(name,value,old)                (((old) & ~(((1 << SM_##name##_SIZE) - 1) << SM_##name##_OFFSET)) | SM_BF(name,value))
++
++/* Register access macros */
++#define sm_readl(port,reg)                                    \
++      __raw_readl((port)->regs + SM_##reg)
++#define sm_writel(port,reg,value)                             \
++      __raw_writel((value), (port)->regs + SM_##reg)
++
++#endif /* __ASM_AVR32_SM_H__ */
+Index: linux-2.6.18-avr32/arch/avr32/mm/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mm/Makefile  2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#
++# Makefile for the Linux/AVR32 kernel.
++#
++
++obj-y                         += init.o clear_page.o copy_page.o dma-coherent.o
++obj-y                         += ioremap.o cache.o fault.o tlb.o
+Index: linux-2.6.18-avr32/arch/avr32/mm/cache.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mm/cache.c   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,150 @@
++/*
++ * 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/highmem.h>
++#include <linux/unistd.h>
++
++#include <asm/cacheflush.h>
++#include <asm/cachectl.h>
++#include <asm/processor.h>
++#include <asm/uaccess.h>
++
++/*
++ * If you attempt to flush anything more than this, you need superuser
++ * privileges.  The value is completely arbitrary.
++ */
++#define CACHEFLUSH_MAX_LEN    1024
++
++void invalidate_dcache_region(void *start, size_t size)
++{
++      unsigned long v, begin, end, linesz;
++
++      linesz = boot_cpu_data.dcache.linesz;
++
++      //printk("invalidate dcache: %p + %u\n", start, size);
++
++      /* You asked for it, you got it */
++      begin = (unsigned long)start & ~(linesz - 1);
++      end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
++
++      for (v = begin; v < end; v += linesz)
++              invalidate_dcache_line((void *)v);
++}
++
++void clean_dcache_region(void *start, size_t size)
++{
++      unsigned long v, begin, end, linesz;
++
++      linesz = boot_cpu_data.dcache.linesz;
++      begin = (unsigned long)start & ~(linesz - 1);
++      end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
++
++      for (v = begin; v < end; v += linesz)
++              clean_dcache_line((void *)v);
++      flush_write_buffer();
++}
++
++void flush_dcache_region(void *start, size_t size)
++{
++      unsigned long v, begin, end, linesz;
++
++      linesz = boot_cpu_data.dcache.linesz;
++      begin = (unsigned long)start & ~(linesz - 1);
++      end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
++
++      for (v = begin; v < end; v += linesz)
++              flush_dcache_line((void *)v);
++      flush_write_buffer();
++}
++
++void invalidate_icache_region(void *start, size_t size)
++{
++      unsigned long v, begin, end, linesz;
++
++      linesz = boot_cpu_data.icache.linesz;
++      begin = (unsigned long)start & ~(linesz - 1);
++      end = ((unsigned long)start + size + linesz - 1) & ~(linesz - 1);
++
++      for (v = begin; v < end; v += linesz)
++              invalidate_icache_line((void *)v);
++}
++
++static inline void __flush_icache_range(unsigned long start, unsigned long end)
++{
++      unsigned long v, linesz;
++
++      linesz = boot_cpu_data.dcache.linesz;
++      for (v = start; v < end; v += linesz) {
++              clean_dcache_line((void *)v);
++              invalidate_icache_line((void *)v);
++      }
++
++      flush_write_buffer();
++}
++
++/*
++ * This one is called after a module has been loaded.
++ */
++void flush_icache_range(unsigned long start, unsigned long end)
++{
++      unsigned long linesz;
++
++      linesz = boot_cpu_data.dcache.linesz;
++      __flush_icache_range(start & ~(linesz - 1),
++                           (end + linesz - 1) & ~(linesz - 1));
++}
++
++/*
++ * This one is called from do_no_page(), do_swap_page() and install_page().
++ */
++void flush_icache_page(struct vm_area_struct *vma, struct page *page)
++{
++      if (vma->vm_flags & VM_EXEC) {
++              void *v = kmap(page);
++              __flush_icache_range((unsigned long)v, (unsigned long)v + PAGE_SIZE);
++              kunmap(v);
++      }
++}
++
++/*
++ * This one is used by copy_to_user_page()
++ */
++void flush_icache_user_range(struct vm_area_struct *vma, struct page *page,
++                           unsigned long addr, int len)
++{
++      if (vma->vm_flags & VM_EXEC)
++              flush_icache_range(addr, addr + len);
++}
++
++asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len)
++{
++      int ret;
++
++      if (len > CACHEFLUSH_MAX_LEN) {
++              ret = -EPERM;
++              if (!capable(CAP_SYS_ADMIN))
++                      goto out;
++      }
++
++      ret = -EFAULT;
++      if (!access_ok(VERIFY_WRITE, addr, len))
++              goto out;
++
++      switch (operation) {
++      case CACHE_IFLUSH:
++              flush_icache_range((unsigned long)addr,
++                                 (unsigned long)addr + len);
++              ret = 0;
++              break;
++      default:
++              ret = -EINVAL;
++      }
++
++out:
++      return ret;
++}
+Index: linux-2.6.18-avr32/arch/avr32/mm/clear_page.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mm/clear_page.S      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,25 @@
++/*
++ * 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/linkage.h>
++#include <asm/page.h>
++
++/*
++ * clear_page
++ * r12: P1 address (to)
++ */
++      .text
++      .global clear_page
++clear_page:
++      sub     r9, r12, -PAGE_SIZE
++      mov     r10, 0
++      mov     r11, 0
++0:      st.d    r12++, r10
++      cp      r12, r9
++      brne    0b
++      mov     pc, lr
+Index: linux-2.6.18-avr32/arch/avr32/mm/copy_page.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mm/copy_page.S       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,28 @@
++/*
++ * 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/linkage.h>
++#include <asm/page.h>
++
++/*
++ * copy_page
++ *
++ * r12                to (P1 address)
++ * r11                from (P1 address)
++ * r8-r10     scratch
++ */
++      .text
++      .global copy_page
++copy_page:
++      sub     r10, r11, -(1 << PAGE_SHIFT)
++      /* pref r11[0] */
++1:    /* pref r11[8] */
++      ld.d    r8, r11++
++      st.d    r12++, r8
++      cp      r11, r10
++      brlo    1b
++      mov     pc, lr
+Index: linux-2.6.18-avr32/arch/avr32/mm/dma-coherent.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mm/dma-coherent.c    2006-12-04 11:50:25.000000000 +0100
+@@ -0,0 +1,139 @@
++/*
++ *  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/dma-mapping.h>
++
++#include <asm/addrspace.h>
++#include <asm/cacheflush.h>
++
++void dma_cache_sync(void *vaddr, size_t size, int direction)
++{
++      /*
++       * No need to sync an uncached area
++       */
++      if (PXSEG(vaddr) == P2SEG)
++              return;
++
++      switch (direction) {
++      case DMA_FROM_DEVICE:           /* invalidate only */
++              dma_cache_inv(vaddr, size);
++              break;
++      case DMA_TO_DEVICE:             /* writeback only */
++              dma_cache_wback(vaddr, size);
++              break;
++      case DMA_BIDIRECTIONAL:         /* writeback and invalidate */
++              dma_cache_wback_inv(vaddr, size);
++              break;
++      default:
++              BUG();
++      }
++}
++EXPORT_SYMBOL(dma_cache_sync);
++
++static struct page *__dma_alloc(struct device *dev, size_t size,
++                              dma_addr_t *handle, gfp_t gfp)
++{
++      struct page *page, *free, *end;
++      int order;
++
++      size = PAGE_ALIGN(size);
++      order = get_order(size);
++
++      page = alloc_pages(gfp, order);
++      if (!page)
++              return NULL;
++      split_page(page, order);
++
++      /*
++       * When accessing physical memory with valid cache data, we
++       * get a cache hit even if the virtual memory region is marked
++       * as uncached.
++       *
++       * Since the memory is newly allocated, there is no point in
++       * doing a writeback. If the previous owner cares, he should
++       * have flushed the cache before releasing the memory.
++       */
++      invalidate_dcache_region(phys_to_virt(page_to_phys(page)), size);
++
++      *handle = page_to_bus(page);
++      free = page + (size >> PAGE_SHIFT);
++      end = page + (1 << order);
++
++      /*
++       * Free any unused pages
++       */
++      while (free < end) {
++              __free_page(free);
++              free++;
++      }
++
++      return page;
++}
++
++static void __dma_free(struct device *dev, size_t size,
++                     struct page *page, dma_addr_t handle)
++{
++      struct page *end = page + (PAGE_ALIGN(size) >> PAGE_SHIFT);
++
++      while (page < end)
++              __free_page(page++);
++}
++
++void *dma_alloc_coherent(struct device *dev, size_t size,
++                       dma_addr_t *handle, gfp_t gfp)
++{
++      struct page *page;
++      void *ret = NULL;
++
++      page = __dma_alloc(dev, size, handle, gfp);
++      if (page)
++              ret = phys_to_uncached(page_to_phys(page));
++
++      return ret;
++}
++EXPORT_SYMBOL(dma_alloc_coherent);
++
++void dma_free_coherent(struct device *dev, size_t size,
++                     void *cpu_addr, dma_addr_t handle)
++{
++      void *addr = phys_to_cached(uncached_to_phys(cpu_addr));
++      struct page *page;
++
++      pr_debug("dma_free_coherent addr %p (phys %08lx) size %u\n",
++               cpu_addr, (unsigned long)handle, (unsigned)size);
++      BUG_ON(!virt_addr_valid(addr));
++      page = virt_to_page(addr);
++      __dma_free(dev, size, page, handle);
++}
++EXPORT_SYMBOL(dma_free_coherent);
++
++#if 0
++void *dma_alloc_writecombine(struct device *dev, size_t size,
++                           dma_addr_t *handle, gfp_t gfp)
++{
++      struct page *page;
++
++      page = __dma_alloc(dev, size, handle, gfp);
++
++      /* Now, map the page into P3 with write-combining turned on */
++      return __ioremap(page_to_phys(page), size, _PAGE_BUFFER);
++}
++EXPORT_SYMBOL(dma_alloc_writecombine);
++
++void dma_free_writecombine(struct device *dev, size_t size,
++                         void *cpu_addr, dma_addr_t handle)
++{
++      struct page *page;
++
++      iounmap(cpu_addr);
++
++      page = bus_to_page(handle);
++      __dma_free(dev, size, page, handle);
++}
++EXPORT_SYMBOL(dma_free_writecombine);
++#endif
+Index: linux-2.6.18-avr32/arch/avr32/mm/fault.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mm/fault.c   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,315 @@
++/*
++ * Copyright (C) 2004-2006 Atmel Corporation
++ *
++ * Based on linux/arch/sh/mm/fault.c:
++ *   Copyright (C) 1999  Niibe Yutaka
++ *
++ * 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/mm.h>
++#include <linux/module.h>
++#include <linux/pagemap.h>
++
++#include <asm/kdebug.h>
++#include <asm/mmu_context.h>
++#include <asm/sysreg.h>
++#include <asm/uaccess.h>
++#include <asm/tlb.h>
++
++#ifdef DEBUG
++static void dump_code(unsigned long pc)
++{
++      char *p = (char *)pc;
++      char val;
++      int i;
++
++
++      printk(KERN_DEBUG "Code:");
++      for (i = 0; i < 16; i++) {
++              if (__get_user(val, p + i))
++                      break;
++              printk(" %02x", val);
++      }
++      printk("\n");
++}
++#endif
++
++#ifdef CONFIG_KPROBES
++ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
++
++/* Hook to register for page fault notifications */
++int register_page_fault_notifier(struct notifier_block *nb)
++{
++      return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
++}
++
++int unregister_page_fault_notifier(struct notifier_block *nb)
++{
++      return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
++}
++
++static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
++                                  int trap, int sig)
++{
++      struct die_args args = {
++              .regs = regs,
++              .trapnr = trap,
++      };
++      return atomic_notifier_call_chain(&notify_page_fault_chain, val, &args);
++}
++#else
++static inline int notify_page_fault(enum die_val val, struct pt_regs *regs,
++                                  int trap, int sig)
++{
++      return NOTIFY_DONE;
++}
++#endif
++
++/*
++ * This routine handles page faults. It determines the address and the
++ * problem, and then passes it off to one of the appropriate routines.
++ *
++ * ecr is the Exception Cause Register. Possible values are:
++ *   5:  Page not found (instruction access)
++ *   6:  Protection fault (instruction access)
++ *   12: Page not found (read access)
++ *   13: Page not found (write access)
++ *   14: Protection fault (read access)
++ *   15: Protection fault (write access)
++ */
++asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
++{
++      struct task_struct *tsk;
++      struct mm_struct *mm;
++      struct vm_area_struct *vma;
++      const struct exception_table_entry *fixup;
++      unsigned long address;
++      unsigned long page;
++      int writeaccess = 0;
++
++      if (notify_page_fault(DIE_PAGE_FAULT, regs,
++                            ecr, SIGSEGV) == NOTIFY_STOP)
++              return;
++
++      address = sysreg_read(TLBEAR);
++
++      tsk = current;
++      mm = tsk->mm;
++
++      /*
++       * If we're in an interrupt or have no user context, we must
++       * not take the fault...
++       */
++      if (in_atomic() || !mm || regs->sr & SYSREG_BIT(GM))
++              goto no_context;
++
++      local_irq_enable();
++
++      down_read(&mm->mmap_sem);
++
++      vma = find_vma(mm, address);
++      if (!vma)
++              goto bad_area;
++      if (vma->vm_start <= address)
++              goto good_area;
++      if (!(vma->vm_flags & VM_GROWSDOWN))
++              goto bad_area;
++      if (expand_stack(vma, address))
++              goto bad_area;
++
++      /*
++       * Ok, we have a good vm_area for this memory access, so we
++       * can handle it...
++       */
++good_area:
++      //pr_debug("good area: vm_flags = 0x%lx\n", vma->vm_flags);
++      switch (ecr) {
++      case ECR_PROTECTION_X:
++      case ECR_TLB_MISS_X:
++              if (!(vma->vm_flags & VM_EXEC))
++                      goto bad_area;
++              break;
++      case ECR_PROTECTION_R:
++      case ECR_TLB_MISS_R:
++              if (!(vma->vm_flags & (VM_READ | VM_WRITE | VM_EXEC)))
++                      goto bad_area;
++              break;
++      case ECR_PROTECTION_W:
++      case ECR_TLB_MISS_W:
++              if (!(vma->vm_flags & VM_WRITE))
++                      goto bad_area;
++              writeaccess = 1;
++              break;
++      default:
++              panic("Unhandled case %lu in do_page_fault!", ecr);
++      }
++
++      /*
++       * If for any reason at all we couldn't handle the fault, make
++       * sure we exit gracefully rather than endlessly redo the
++       * fault.
++       */
++survive:
++      switch (handle_mm_fault(mm, vma, address, writeaccess)) {
++      case VM_FAULT_MINOR:
++              tsk->min_flt++;
++              break;
++      case VM_FAULT_MAJOR:
++              tsk->maj_flt++;
++              break;
++      case VM_FAULT_SIGBUS:
++              goto do_sigbus;
++      case VM_FAULT_OOM:
++              goto out_of_memory;
++      default:
++              BUG();
++      }
++
++      up_read(&mm->mmap_sem);
++      return;
++
++      /*
++       * Something tried to access memory that isn't in our memory
++       * map. Fix it, but check if it's kernel or user first...
++       */
++bad_area:
++      pr_debug("Bad area [%s:%u]: addr %08lx, ecr %lu\n",
++               tsk->comm, tsk->pid, address, ecr);
++
++      up_read(&mm->mmap_sem);
++
++      if (user_mode(regs)) {
++              /* Hmm...we have to pass address and ecr somehow... */
++              /* tsk->thread.address = address;
++                 tsk->thread.error_code = ecr; */
++#ifdef DEBUG
++              show_regs(regs);
++              dump_code(regs->pc);
++
++              page = sysreg_read(PTBR);
++              printk("ptbr = %08lx", page);
++              if (page) {
++                      page = ((unsigned long *)page)[address >> 22];
++                      printk(" pgd = %08lx", page);
++                      if (page & _PAGE_PRESENT) {
++                              page &= PAGE_MASK;
++                              address &= 0x003ff000;
++                              page = ((unsigned long *)__va(page))[address >> PAGE_SHIFT];
++                              printk(" pte = %08lx\n", page);
++                      }
++              }
++#endif
++              pr_debug("Sending SIGSEGV to PID %d...\n",
++                      tsk->pid);
++              force_sig(SIGSEGV, tsk);
++              return;
++      }
++
++no_context:
++      pr_debug("No context\n");
++
++      /* Are we prepared to handle this kernel fault? */
++      fixup = search_exception_tables(regs->pc);
++      if (fixup) {
++              regs->pc = fixup->fixup;
++              pr_debug("Found fixup at %08lx\n", fixup->fixup);
++              return;
++      }
++
++      /*
++       * Oops. The kernel tried to access some bad page. We'll have
++       * to terminate things with extreme prejudice.
++       */
++      if (address < PAGE_SIZE)
++              printk(KERN_ALERT
++                     "Unable to handle kernel NULL pointer dereference");
++      else
++              printk(KERN_ALERT
++                     "Unable to handle kernel paging request");
++      printk(" at virtual address %08lx\n", address);
++      printk(KERN_ALERT "pc = %08lx\n", regs->pc);
++
++      page = sysreg_read(PTBR);
++      printk(KERN_ALERT "ptbr = %08lx", page);
++      if (page) {
++              page = ((unsigned long *)page)[address >> 22];
++              printk(" pgd = %08lx", page);
++              if (page & _PAGE_PRESENT) {
++                      page &= PAGE_MASK;
++                      address &= 0x003ff000;
++                      page = ((unsigned long *)__va(page))[address >> PAGE_SHIFT];
++                      printk(" pte = %08lx\n", page);
++              }
++      }
++      die("\nOops", regs, ecr);
++      do_exit(SIGKILL);
++
++      /*
++       * We ran out of memory, or some other thing happened to us
++       * that made us unable to handle the page fault gracefully.
++       */
++out_of_memory:
++      printk("Out of memory\n");
++      up_read(&mm->mmap_sem);
++      if (current->pid == 1) {
++              yield();
++              down_read(&mm->mmap_sem);
++              goto survive;
++      }
++      printk("VM: Killing process %s\n", tsk->comm);
++      if (user_mode(regs))
++              do_exit(SIGKILL);
++      goto no_context;
++
++do_sigbus:
++      up_read(&mm->mmap_sem);
++
++      /*
++       * Send a sigbus, regardless of whether we were in kernel or
++       * user mode.
++       */
++      /* address, error_code, trap_no, ... */
++#ifdef DEBUG
++      show_regs(regs);
++      dump_code(regs->pc);
++#endif
++      pr_debug("Sending SIGBUS to PID %d...\n", tsk->pid);
++      force_sig(SIGBUS, tsk);
++
++      /* Kernel mode? Handle exceptions or die */
++      if (!user_mode(regs))
++              goto no_context;
++}
++
++asmlinkage void do_bus_error(unsigned long addr, int write_access,
++                           struct pt_regs *regs)
++{
++      printk(KERN_ALERT
++             "Bus error at physical address 0x%08lx (%s access)\n",
++             addr, write_access ? "write" : "read");
++      printk(KERN_INFO "DTLB dump:\n");
++      dump_dtlb();
++      die("Bus Error", regs, write_access);
++      do_exit(SIGKILL);
++}
++
++/*
++ * This functionality is currently not possible to implement because
++ * we're using segmentation to ensure a fixed mapping of the kernel
++ * virtual address space.
++ *
++ * It would be possible to implement this, but it would require us to
++ * disable segmentation at startup and load the kernel mappings into
++ * the TLB like any other pages. There will be lots of trickery to
++ * avoid recursive invocation of the TLB miss handler, though...
++ */
++#ifdef CONFIG_DEBUG_PAGEALLOC
++void kernel_map_pages(struct page *page, int numpages, int enable)
++{
++
++}
++EXPORT_SYMBOL(kernel_map_pages);
++#endif
+Index: linux-2.6.18-avr32/arch/avr32/mm/init.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mm/init.c    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,481 @@
++/*
++ * 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/kernel.h>
++#include <linux/mm.h>
++#include <linux/swap.h>
++#include <linux/init.h>
++#include <linux/initrd.h>
++#include <linux/mmzone.h>
++#include <linux/bootmem.h>
++#include <linux/pagemap.h>
++#include <linux/pfn.h>
++#include <linux/nodemask.h>
++
++#include <asm/page.h>
++#include <asm/mmu_context.h>
++#include <asm/tlb.h>
++#include <asm/io.h>
++#include <asm/dma.h>
++#include <asm/setup.h>
++#include <asm/sections.h>
++
++DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
++
++pgd_t swapper_pg_dir[PTRS_PER_PGD];
++
++struct page *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;
++      int slab = 0, free = 0, shared = 0;
++      pg_data_t *pgdat;
++
++      printk("Mem-info:\n");
++      show_free_areas();
++
++      for_each_online_pgdat(pgdat) {
++              struct page *page, *end;
++
++              page = pgdat->node_mem_map;
++              end = page + pgdat->node_spanned_pages;
++
++              do {
++                      total++;
++                      if (PageReserved(page))
++                              reserved++;
++                      else if (PageSwapCache(page))
++                              cached++;
++                      else if (PageSlab(page))
++                              slab++;
++                      else if (!page_count(page))
++                              free++;
++                      else
++                              shared += page_count(page) - 1;
++                      page++;
++              } while (page < end);
++      }
++
++      printk ("%d pages of RAM\n", total);
++      printk ("%d free pages\n", free);
++      printk ("%d reserved pages\n", reserved);
++      printk ("%d slab pages\n", slab);
++      printk ("%d pages shared\n", shared);
++      printk ("%d pages swap cached\n", cached);
++}
++
++static void __init print_memory_map(const char *what,
++                                  struct tag_mem_range *mem)
++{
++      printk ("%s:\n", what);
++      for (; mem; mem = mem->next) {
++              printk ("  %08lx - %08lx\n",
++                      (unsigned long)mem->addr,
++                      (unsigned long)(mem->addr + mem->size));
++      }
++}
++
++#define MAX_LOWMEM    HIGHMEM_START
++#define MAX_LOWMEM_PFN        PFN_DOWN(MAX_LOWMEM)
++
++/*
++ * Sort a list of memory regions in-place by ascending address.
++ *
++ * We're using bubble sort because we only have singly linked lists
++ * with few elements.
++ */
++static void __init sort_mem_list(struct tag_mem_range **pmem)
++{
++      int done;
++      struct tag_mem_range **a, **b;
++
++      if (!*pmem)
++              return;
++
++      do {
++              done = 1;
++              a = pmem, b = &(*pmem)->next;
++              while (*b) {
++                      if ((*a)->addr > (*b)->addr) {
++                              struct tag_mem_range *tmp;
++                              tmp = (*b)->next;
++                              (*b)->next = *a;
++                              *a = *b;
++                              *b = tmp;
++                              done = 0;
++                      }
++                      a = &(*a)->next;
++                      b = &(*a)->next;
++              }
++      } while (!done);
++}
++
++/*
++ * Find a free memory region large enough for storing the
++ * bootmem bitmap.
++ */
++static unsigned long __init
++find_bootmap_pfn(const struct tag_mem_range *mem)
++{
++      unsigned long bootmap_pages, bootmap_len;
++      unsigned long node_pages = PFN_UP(mem->size);
++      unsigned long bootmap_addr = mem->addr;
++      struct tag_mem_range *reserved = mem_reserved;
++      struct tag_mem_range *ramdisk = mem_ramdisk;
++      unsigned long kern_start = virt_to_phys(_stext);
++      unsigned long kern_end = virt_to_phys(_end);
++
++      bootmap_pages = bootmem_bootmap_pages(node_pages);
++      bootmap_len = bootmap_pages << PAGE_SHIFT;
++
++      /*
++       * Find a large enough region without reserved pages for
++       * storing the bootmem bitmap. We can take advantage of the
++       * fact that all lists have been sorted.
++       *
++       * We have to check explicitly reserved regions as well as the
++       * kernel image and any RAMDISK images...
++       *
++       * Oh, and we have to make sure we don't overwrite the taglist
++       * since we're going to use it until the bootmem allocator is
++       * fully up and running.
++       */
++      while (1) {
++              if ((bootmap_addr < kern_end) &&
++                  ((bootmap_addr + bootmap_len) > kern_start))
++                      bootmap_addr = kern_end;
++
++              while (reserved &&
++                     (bootmap_addr >= (reserved->addr + reserved->size)))
++                      reserved = reserved->next;
++
++              if (reserved &&
++                  ((bootmap_addr + bootmap_len) >= reserved->addr)) {
++                      bootmap_addr = reserved->addr + reserved->size;
++                      continue;
++              }
++
++              while (ramdisk &&
++                     (bootmap_addr >= (ramdisk->addr + ramdisk->size)))
++                      ramdisk = ramdisk->next;
++
++              if (!ramdisk ||
++                  ((bootmap_addr + bootmap_len) < ramdisk->addr))
++                      break;
++
++              bootmap_addr = ramdisk->addr + ramdisk->size;
++      }
++
++      if ((PFN_UP(bootmap_addr) + bootmap_len) >= (mem->addr + mem->size))
++              return ~0UL;
++
++      return PFN_UP(bootmap_addr);
++}
++
++void __init setup_bootmem(void)
++{
++      unsigned bootmap_size;
++      unsigned long first_pfn, bootmap_pfn, pages;
++      unsigned long max_pfn, max_low_pfn;
++      unsigned long kern_start = virt_to_phys(_stext);
++      unsigned long kern_end = virt_to_phys(_end);
++      unsigned node = 0;
++      struct tag_mem_range *bank, *res;
++
++      sort_mem_list(&mem_phys);
++      sort_mem_list(&mem_reserved);
++
++      print_memory_map("Physical memory", mem_phys);
++      print_memory_map("Reserved memory", mem_reserved);
++
++      nodes_clear(node_online_map);
++
++      if (mem_ramdisk) {
++#ifdef CONFIG_BLK_DEV_INITRD
++              initrd_start = (unsigned long)__va(mem_ramdisk->addr);
++              initrd_end = initrd_start + mem_ramdisk->size;
++
++              print_memory_map("RAMDISK images", mem_ramdisk);
++              if (mem_ramdisk->next)
++                      printk(KERN_WARNING
++                             "Warning: Only the first RAMDISK image "
++                             "will be used\n");
++              sort_mem_list(&mem_ramdisk);
++#else
++              printk(KERN_WARNING "RAM disk image present, but "
++                     "no initrd support in kernel!\n");
++#endif
++      }
++
++      if (mem_phys->next)
++              printk(KERN_WARNING "Only using first memory bank\n");
++
++      for (bank = mem_phys; bank; bank = NULL) {
++              first_pfn = PFN_UP(bank->addr);
++              max_low_pfn = max_pfn = PFN_DOWN(bank->addr + bank->size);
++              bootmap_pfn = find_bootmap_pfn(bank);
++              if (bootmap_pfn > max_pfn)
++                      panic("No space for bootmem bitmap!\n");
++
++              if (max_low_pfn > MAX_LOWMEM_PFN) {
++                      max_low_pfn = MAX_LOWMEM_PFN;
++#ifndef CONFIG_HIGHMEM
++                      /*
++                       * Lowmem is memory that can be addressed
++                       * directly through P1/P2
++                       */
++                      printk(KERN_WARNING
++                             "Node %u: Only %ld MiB of memory will be used.\n",
++                             node, MAX_LOWMEM >> 20);
++                      printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
++#else
++#error HIGHMEM is not supported by AVR32 yet
++#endif
++              }
++
++              /* Initialize the boot-time allocator with low memory only. */
++              bootmap_size = init_bootmem_node(NODE_DATA(node), bootmap_pfn,
++                                               first_pfn, max_low_pfn);
++
++              printk("Node %u: bdata = %p, bdata->node_bootmem_map = %p\n",
++                     node, NODE_DATA(node)->bdata,
++                     NODE_DATA(node)->bdata->node_bootmem_map);
++
++              /*
++               * Register fully available RAM pages with the bootmem
++               * allocator.
++               */
++              pages = max_low_pfn - first_pfn;
++              free_bootmem_node (NODE_DATA(node), PFN_PHYS(first_pfn),
++                                 PFN_PHYS(pages));
++
++              /*
++               * Reserve space for the kernel image (if present in
++               * this node)...
++               */
++              if ((kern_start >= PFN_PHYS(first_pfn)) &&
++                  (kern_start < PFN_PHYS(max_pfn))) {
++                      printk("Node %u: Kernel image %08lx - %08lx\n",
++                             node, kern_start, kern_end);
++                      reserve_bootmem_node(NODE_DATA(node), kern_start,
++                                           kern_end - kern_start);
++              }
++
++              /* ...the bootmem bitmap... */
++              reserve_bootmem_node(NODE_DATA(node),
++                                   PFN_PHYS(bootmap_pfn),
++                                   bootmap_size);
++
++              /* ...any RAMDISK images... */
++              for (res = mem_ramdisk; res; res = res->next) {
++                      if (res->addr > PFN_PHYS(max_pfn))
++                              break;
++
++                      if (res->addr >= PFN_PHYS(first_pfn)) {
++                              printk("Node %u: RAMDISK %08lx - %08lx\n",
++                                     node,
++                                     (unsigned long)res->addr,
++                                     (unsigned long)(res->addr + res->size));
++                              reserve_bootmem_node(NODE_DATA(node),
++                                                   res->addr, res->size);
++                      }
++              }
++
++              /* ...and any other reserved regions. */
++              for (res = mem_reserved; res; res = res->next) {
++                      if (res->addr > PFN_PHYS(max_pfn))
++                              break;
++
++                      if (res->addr >= PFN_PHYS(first_pfn)) {
++                              printk("Node %u: Reserved %08lx - %08lx\n",
++                                     node,
++                                     (unsigned long)res->addr,
++                                     (unsigned long)(res->addr + res->size));
++                              reserve_bootmem_node(NODE_DATA(node),
++                                                   res->addr, res->size);
++                      }
++              }
++
++              node_set_online(node);
++      }
++}
++
++/*
++ * paging_init() sets up the page tables
++ *
++ * This routine also unmaps the page at virtual kernel address 0, so
++ * that we can trap those pesky NULL-reference errors in the kernel.
++ */
++void __init paging_init(void)
++{
++      extern unsigned long _evba;
++      void *zero_page;
++      int nid;
++
++      /*
++       * Make sure we can handle exceptions before enabling
++       * paging. Not that we should ever _get_ any exceptions this
++       * early, but you never know...
++       */
++      printk("Exception vectors start at %p\n", &_evba);
++      sysreg_write(EVBA, (unsigned long)&_evba);
++
++      /*
++       * Since we are ready to handle exceptions now, we should let
++       * the CPU generate them...
++       */
++      __asm__ __volatile__ ("csrf %0" : : "i"(SR_EM_BIT));
++
++      /*
++       * Allocate the zero page. The allocator will panic if it
++       * can't satisfy the request, so no need to check.
++       */
++      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");
++      }
++
++      for_each_online_node(nid) {
++              pg_data_t *pgdat = NODE_DATA(nid);
++              unsigned long zones_size[MAX_NR_ZONES];
++              unsigned long low, start_pfn;
++
++              start_pfn = pgdat->bdata->node_boot_start;
++              start_pfn >>= PAGE_SHIFT;
++              low = pgdat->bdata->node_low_pfn;
++
++              /* All memory is DMA-able */
++              memset(zones_size, 0, sizeof(zones_size));
++              zones_size[ZONE_DMA] = low - start_pfn;
++
++              printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n",
++                     nid, start_pfn, low);
++
++              free_area_init_node(nid, pgdat, zones_size, start_pfn, NULL);
++
++              printk("Node %u: mem_map starts at %p\n",
++                     pgdat->node_id, pgdat->node_mem_map);
++      }
++
++      mem_map = NODE_DATA(0)->node_mem_map;
++
++      memset(zero_page, 0, PAGE_SIZE);
++      empty_zero_page = virt_to_page(zero_page);
++      flush_dcache_page(empty_zero_page);
++}
++
++void __init mem_init(void)
++{
++      int codesize, reservedpages, datasize, initsize;
++      int nid, i;
++
++      reservedpages = 0;
++      high_memory = NULL;
++
++      /* this will put all low memory onto the freelists */
++      for_each_online_node(nid) {
++              pg_data_t *pgdat = NODE_DATA(nid);
++              unsigned long node_pages = 0;
++              void *node_high_memory;
++
++              num_physpages += pgdat->node_present_pages;
++
++              if (pgdat->node_spanned_pages != 0)
++                      node_pages = free_all_bootmem_node(pgdat);
++
++              totalram_pages += node_pages;
++
++              for (i = 0; i < node_pages; i++)
++                      if (PageReserved(pgdat->node_mem_map + i))
++                              reservedpages++;
++
++              node_high_memory = (void *)((pgdat->node_start_pfn
++                                           + pgdat->node_spanned_pages)
++                                          << PAGE_SHIFT);
++              if (node_high_memory > high_memory)
++                      high_memory = node_high_memory;
++      }
++
++      max_mapnr = MAP_NR(high_memory);
++
++      codesize = (unsigned long)_etext - (unsigned long)_text;
++      datasize = (unsigned long)_edata - (unsigned long)_data;
++      initsize = (unsigned long)__init_end - (unsigned long)__init_begin;
++
++      printk ("Memory: %luk/%luk available (%dk kernel code, "
++              "%dk reserved, %dk data, %dk init)\n",
++              (unsigned long)nr_free_pages() << (PAGE_SHIFT - 10),
++              totalram_pages << (PAGE_SHIFT - 10),
++              codesize >> 10,
++              reservedpages << (PAGE_SHIFT - 10),
++              datasize >> 10,
++              initsize >> 10);
++}
++
++static inline void free_area(unsigned long addr, unsigned long end, char *s)
++{
++      unsigned int size = (end - addr) >> 10;
++
++      for (; addr < end; addr += PAGE_SIZE) {
++              struct page *page = virt_to_page(addr);
++              ClearPageReserved(page);
++              init_page_count(page);
++              free_page(addr);
++              totalram_pages++;
++      }
++
++      if (size && s)
++              printk(KERN_INFO "Freeing %s memory: %dK (%lx - %lx)\n",
++                     s, size, end - (size << 10), end);
++}
++
++void free_initmem(void)
++{
++      free_area((unsigned long)__init_begin, (unsigned long)__init_end,
++                "init");
++}
++
++#ifdef CONFIG_BLK_DEV_INITRD
++
++static int keep_initrd;
++
++void free_initrd_mem(unsigned long start, unsigned long end)
++{
++      if (!keep_initrd)
++              free_area(start, end, "initrd");
++}
++
++static int __init keepinitrd_setup(char *__unused)
++{
++      keep_initrd = 1;
++      return 1;
++}
++
++__setup("keepinitrd", keepinitrd_setup);
++#endif
+Index: linux-2.6.18-avr32/arch/avr32/mm/ioremap.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mm/ioremap.c 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,199 @@
++/*
++ * 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/vmalloc.h>
++#include <linux/module.h>
++
++#include <asm/io.h>
++#include <asm/pgtable.h>
++#include <asm/cacheflush.h>
++#include <asm/tlbflush.h>
++#include <asm/addrspace.h>
++
++static inline int remap_area_pte(pte_t *pte, unsigned long address,
++                                unsigned long end, unsigned long phys_addr,
++                                pgprot_t prot)
++{
++      unsigned long pfn;
++
++      pfn = phys_addr >> PAGE_SHIFT;
++      do {
++              WARN_ON(!pte_none(*pte));
++
++              set_pte(pte, pfn_pte(pfn, prot));
++              address += PAGE_SIZE;
++              pfn++;
++              pte++;
++      } while (address && (address < end));
++
++      return 0;
++}
++
++static inline int remap_area_pmd(pmd_t *pmd, unsigned long address,
++                               unsigned long end, unsigned long phys_addr,
++                               pgprot_t prot)
++{
++      unsigned long next;
++
++      phys_addr -= address;
++
++      do {
++              pte_t *pte = pte_alloc_kernel(pmd, address);
++              if (!pte)
++                      return -ENOMEM;
++
++              next = (address + PMD_SIZE) & PMD_MASK;
++              if (remap_area_pte(pte, address, next,
++                                 address + phys_addr, prot))
++                      return -ENOMEM;
++
++              address = next;
++              pmd++;
++      } while (address && (address < end));
++      return 0;
++}
++
++static int remap_area_pud(pud_t *pud, unsigned long address,
++                        unsigned long end, unsigned long phys_addr,
++                        pgprot_t prot)
++{
++      unsigned long next;
++
++      phys_addr -= address;
++
++      do {
++              pmd_t *pmd = pmd_alloc(&init_mm, pud, address);
++              if (!pmd)
++                      return -ENOMEM;
++              next = (address + PUD_SIZE) & PUD_MASK;
++              if (remap_area_pmd(pmd, address, next,
++                                 phys_addr + address, prot))
++                      return -ENOMEM;
++
++              address = next;
++              pud++;
++      } while (address && address < end);
++
++      return 0;
++}
++
++static int remap_area_pages(unsigned long address, unsigned long phys_addr,
++                          size_t size, pgprot_t prot)
++{
++      unsigned long end = address + size;
++      unsigned long next;
++      pgd_t *pgd;
++      int err = 0;
++
++      phys_addr -= address;
++
++      pgd = pgd_offset_k(address);
++      flush_cache_all();
++      BUG_ON(address >= end);
++
++      spin_lock(&init_mm.page_table_lock);
++      do {
++              pud_t *pud = pud_alloc(&init_mm, pgd, address);
++
++              err = -ENOMEM;
++              if (!pud)
++                      break;
++
++              next = (address + PGDIR_SIZE) & PGDIR_MASK;
++              if (next < address || next > end)
++                      next = end;
++              err = remap_area_pud(pud, address, next,
++                                   phys_addr + address, prot);
++              if (err)
++                      break;
++
++              address = next;
++              pgd++;
++      } while (address && (address < end));
++
++      spin_unlock(&init_mm.page_table_lock);
++      flush_tlb_all();
++      return err;
++}
++
++/*
++ * Re-map an arbitrary physical address space into the kernel virtual
++ * address space. Needed when the kernel wants to access physical
++ * memory directly.
++ */
++void __iomem *__ioremap(unsigned long phys_addr, size_t size,
++                      unsigned long flags)
++{
++      void *addr;
++      struct vm_struct *area;
++      unsigned long offset, last_addr;
++      pgprot_t prot;
++
++      /*
++       * Check if we can simply use the P4 segment. This area is
++       * uncacheable, so if caching/buffering is requested, we can't
++       * use it.
++       */
++      if ((phys_addr >= P4SEG) && (flags == 0))
++              return (void __iomem *)phys_addr;
++
++      /* Don't allow wraparound or zero size */
++      last_addr = phys_addr + size - 1;
++      if (!size || last_addr < phys_addr)
++              return NULL;
++
++      /*
++       * XXX: When mapping regular RAM, we'd better make damn sure
++       * it's never used for anything else.  But this is really the
++       * caller's responsibility...
++       */
++      if (PHYSADDR(P2SEGADDR(phys_addr)) == phys_addr)
++              return (void __iomem *)P2SEGADDR(phys_addr);
++
++      /* Mappings have to be page-aligned */
++      offset = phys_addr & ~PAGE_MASK;
++      phys_addr &= PAGE_MASK;
++      size = PAGE_ALIGN(last_addr + 1) - phys_addr;
++
++      prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY
++                      | _PAGE_ACCESSED | _PAGE_TYPE_SMALL | flags);
++
++      /*
++       * Ok, go for it..
++       */
++      area = get_vm_area(size, VM_IOREMAP);
++      if (!area)
++              return NULL;
++      area->phys_addr = phys_addr;
++      addr = area->addr;
++      if (remap_area_pages((unsigned long)addr, phys_addr, size, prot)) {
++              vunmap(addr);
++              return NULL;
++      }
++
++      return (void __iomem *)(offset + (char *)addr);
++}
++EXPORT_SYMBOL(__ioremap);
++
++void __iounmap(void __iomem *addr)
++{
++      struct vm_struct *p;
++
++      if ((unsigned long)addr >= P4SEG)
++              return;
++      if (PXSEG(addr) == P2SEG)
++              return;
++
++      p = remove_vm_area((void *)(PAGE_MASK & (unsigned long __force)addr));
++      if (unlikely(!p)) {
++              printk (KERN_ERR "iounmap: bad address %p\n", addr);
++              return;
++      }
++
++      kfree (p);
++}
++EXPORT_SYMBOL(__iounmap);
+Index: linux-2.6.18-avr32/arch/avr32/mm/tlb.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mm/tlb.c     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,378 @@
++/*
++ * AVR32 TLB operations
++ *
++ * 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/mm.h>
++
++#include <asm/mmu_context.h>
++
++#define _TLBEHI_I     0x100
++
++void show_dtlb_entry(unsigned int index)
++{
++      unsigned int tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save, flags;
++
++      local_irq_save(flags);
++      mmucr_save = sysreg_read(MMUCR);
++      tlbehi_save = sysreg_read(TLBEHI);
++      mmucr = mmucr_save & 0x13;
++      mmucr |= index << 14;
++      sysreg_write(MMUCR, mmucr);
++
++      asm volatile("tlbr" : : : "memory");
++      cpu_sync_pipeline();
++
++      tlbehi = sysreg_read(TLBEHI);
++      tlbelo = sysreg_read(TLBELO);
++
++      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_write(MMUCR, mmucr_save);
++      sysreg_write(TLBEHI, tlbehi_save);
++      cpu_sync_pipeline();
++      local_irq_restore(flags);
++}
++
++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++)
++              show_dtlb_entry(i);
++}
++
++static unsigned long last_mmucr;
++
++static inline void set_replacement_pointer(unsigned shift)
++{
++      unsigned long mmucr, mmucr_save;
++
++      mmucr = mmucr_save = sysreg_read(MMUCR);
++
++      /* Does this mapping already exist? */
++      __asm__ __volatile__(
++              "       tlbs\n"
++              "       mfsr %0, %1"
++              : "=r"(mmucr)
++              : "i"(SYSREG_MMUCR));
++
++      if (mmucr & SYSREG_BIT(MMUCR_N)) {
++              /* Not found -- pick a not-recently-accessed entry */
++              unsigned long rp;
++              unsigned long tlbar = sysreg_read(TLBARLO);
++
++              rp = 32 - fls(tlbar);
++              if (rp == 32) {
++                      rp = 0;
++                      sysreg_write(TLBARLO, -1L);
++              }
++
++              mmucr &= 0x13;
++              mmucr |= (rp << shift);
++
++              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();
++}
++
++void update_mmu_cache(struct vm_area_struct *vma,
++                    unsigned long address, pte_t pte)
++{
++      unsigned long flags;
++
++      /* ptrace may call this routine */
++      if (vma && current->active_mm != vma->vm_mm)
++              return;
++
++      local_irq_save(flags);
++      update_dtlb(address, pte, get_asid());
++      local_irq_restore(flags);
++}
++
++void __flush_tlb_page(unsigned long asid, unsigned long page)
++{
++      unsigned long mmucr, tlbehi;
++
++      page |= asid;
++      sysreg_write(TLBEHI, page);
++      cpu_sync_pipeline();
++      asm volatile("tlbs");
++      mmucr = sysreg_read(MMUCR);
++
++      if (!(mmucr & SYSREG_BIT(MMUCR_N))) {
++              unsigned long tlbarlo;
++              unsigned long entry;
++
++              /* 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;
++              tlbarlo = sysreg_read(TLBARLO);
++              tlbarlo |= (0x80000000 >> entry);
++              sysreg_write(TLBARLO, tlbarlo);
++
++              /* update the entry with valid bit clear */
++              asm volatile("tlbw");
++              cpu_sync_pipeline();
++      }
++}
++
++void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
++{
++      if (vma->vm_mm && vma->vm_mm->context != NO_CONTEXT) {
++              unsigned long flags, asid;
++              unsigned long saved_asid = MMU_NO_ASID;
++
++              asid = vma->vm_mm->context & MMU_CONTEXT_ASID_MASK;
++              page &= PAGE_MASK;
++
++              local_irq_save(flags);
++              if (vma->vm_mm != current->mm) {
++                      saved_asid = get_asid();
++                      set_asid(asid);
++              }
++
++              __flush_tlb_page(asid, page);
++
++              if (saved_asid != MMU_NO_ASID)
++                      set_asid(saved_asid);
++              local_irq_restore(flags);
++      }
++}
++
++void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
++                   unsigned long end)
++{
++      struct mm_struct *mm = vma->vm_mm;
++
++      if (mm->context != NO_CONTEXT) {
++              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 */
++                      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;
++
++                      start &= PAGE_MASK;
++                      end += (PAGE_SIZE - 1);
++                      end &= PAGE_MASK;
++                      if (mm != current->mm) {
++                              saved_asid = get_asid();
++                              set_asid(asid);
++                      }
++
++                      while (start < end) {
++                              __flush_tlb_page(asid, start);
++                              start += PAGE_SIZE;
++                      }
++                      if (saved_asid != MMU_NO_ASID)
++                              set_asid(saved_asid);
++              }
++              local_irq_restore(flags);
++      }
++}
++
++/*
++ * TODO: If this is only called for addresses > TASK_SIZE, we can probably
++ * skip the ASID stuff and just use the Global bit...
++ */
++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();
++
++              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);
++}
++
++void flush_tlb_mm(struct mm_struct *mm)
++{
++      /* Invalidate all TLB entries of this process by getting a new ASID */
++      if (mm->context != NO_CONTEXT) {
++              unsigned long flags;
++
++              local_irq_save(flags);
++              mm->context = NO_CONTEXT;
++              if (mm == current->mm)
++                      activate_context(mm);
++              local_irq_restore(flags);
++      }
++}
++
++void flush_tlb_all(void)
++{
++      unsigned long flags;
++
++      local_irq_save(flags);
++      sysreg_write(MMUCR, sysreg_read(MMUCR) | SYSREG_BIT(MMUCR_I));
++      local_irq_restore(flags);
++}
++
++#ifdef CONFIG_PROC_FS
++
++#include <linux/seq_file.h>
++#include <linux/proc_fs.h>
++#include <linux/init.h>
++
++static void *tlb_start(struct seq_file *tlb, loff_t *pos)
++{
++      static unsigned long tlb_index;
++
++      if (*pos >= 32)
++              return NULL;
++
++      tlb_index = 0;
++      return &tlb_index;
++}
++
++static void *tlb_next(struct seq_file *tlb, void *v, loff_t *pos)
++{
++      unsigned long *index = v;
++
++      if (*index >= 31)
++              return NULL;
++
++      ++*pos;
++      ++*index;
++      return index;
++}
++
++static void tlb_stop(struct seq_file *tlb, void *v)
++{
++
++}
++
++static int tlb_show(struct seq_file *tlb, void *v)
++{
++      unsigned int tlbehi, tlbehi_save, tlbelo, mmucr, mmucr_save, flags;
++      unsigned long *index = v;
++
++      if (*index == 0)
++              seq_puts(tlb, "ID  V G ASID VPN   PFN   AP SZ C B W D\n");
++
++      BUG_ON(*index >= 32);
++
++      local_irq_save(flags);
++      mmucr_save = sysreg_read(MMUCR);
++      tlbehi_save = sysreg_read(TLBEHI);
++      mmucr = mmucr_save & 0x13;
++      mmucr |= *index << 14;
++      sysreg_write(MMUCR, mmucr);
++
++      asm volatile("tlbr" : : : "memory");
++      cpu_sync_pipeline();
++
++      tlbehi = sysreg_read(TLBEHI);
++      tlbelo = sysreg_read(TLBELO);
++
++      sysreg_write(MMUCR, mmucr_save);
++      sysreg_write(TLBEHI, tlbehi_save);
++      cpu_sync_pipeline();
++      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');
++
++      return 0;
++}
++
++static struct seq_operations tlb_ops = {
++      .start          = tlb_start,
++      .next           = tlb_next,
++      .stop           = tlb_stop,
++      .show           = tlb_show,
++};
++
++static int tlb_open(struct inode *inode, struct file *file)
++{
++      return seq_open(file, &tlb_ops);
++}
++
++static struct file_operations proc_tlb_operations = {
++      .open           = tlb_open,
++      .read           = seq_read,
++      .llseek         = seq_lseek,
++      .release        = seq_release,
++};
++
++static int __init proctlb_init(void)
++{
++      struct proc_dir_entry *entry;
++
++      entry = create_proc_entry("tlb", 0, NULL);
++      if (entry)
++              entry->proc_fops = &proc_tlb_operations;
++      return 0;
++}
++late_initcall(proctlb_init);
++#endif /* CONFIG_PROC_FS */
+Index: linux-2.6.18-avr32/include/asm-avr32/Kbuild
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/Kbuild        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,3 @@
++include include/asm-generic/Kbuild.asm
++
++header-y      += cachectl.h
+Index: linux-2.6.18-avr32/include/asm-avr32/a.out.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/a.out.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,26 @@
++#ifndef __ASM_AVR32_A_OUT_H
++#define __ASM_AVR32_A_OUT_H
++
++struct exec
++{
++  unsigned long a_info;               /* Use macros N_MAGIC, etc for access */
++  unsigned a_text;            /* length of text, in bytes */
++  unsigned a_data;            /* length of data, in bytes */
++  unsigned a_bss;             /* length of uninitialized data area for file, in bytes */
++  unsigned a_syms;            /* length of symbol table data in file, in bytes */
++  unsigned a_entry;           /* start address */
++  unsigned a_trsize;          /* length of relocation info for text, in bytes */
++  unsigned a_drsize;          /* length of relocation info for data, in bytes */
++};
++
++#define N_TRSIZE(a)   ((a).a_trsize)
++#define N_DRSIZE(a)   ((a).a_drsize)
++#define N_SYMSIZE(a)  ((a).a_syms)
++
++#ifdef __KERNEL__
++
++#define STACK_TOP     TASK_SIZE
++
++#endif
++
++#endif /* __ASM_AVR32_A_OUT_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/addrspace.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/addrspace.h   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,43 @@
++/*
++ * Defitions for the address spaces of the AVR32 CPUs. Heavily based on
++ * include/asm-sh/addrspace.h
++ *
++ * 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 __ASM_AVR32_ADDRSPACE_H
++#define __ASM_AVR32_ADDRSPACE_H
++
++#ifdef CONFIG_MMU
++
++/* Memory segments when segmentation is enabled */
++#define P0SEG         0x00000000
++#define P1SEG         0x80000000
++#define P2SEG         0xa0000000
++#define P3SEG         0xc0000000
++#define P4SEG         0xe0000000
++
++/* Returns the privileged segment base of a given address */
++#define PXSEG(a)      (((unsigned long)(a)) & 0xe0000000)
++
++/* Returns the physical address of a PnSEG (n=1,2) address */
++#define PHYSADDR(a)   (((unsigned long)(a)) & 0x1fffffff)
++
++/*
++ * Map an address to a certain privileged segment
++ */
++#define P1SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) \
++                                    | P1SEG))
++#define P2SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) \
++                                    | P2SEG))
++#define P3SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) \
++                                    | P3SEG))
++#define P4SEGADDR(a) ((__typeof__(a))(((unsigned long)(a) & 0x1fffffff) \
++                                    | P4SEG))
++
++#endif /* CONFIG_MMU */
++
++#endif /* __ASM_AVR32_ADDRSPACE_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/at91rm9200_pdc.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/at91rm9200_pdc.h  2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,36 @@
++/*
++ * include/asm-arm/arch-at91rm9200/at91rm9200_pdc.h
++ *
++ * Copyright (C) 2005 Ivan Kokshaysky
++ * Copyright (C) SAN People
++ *
++ * Peripheral Data Controller (PDC) registers.
++ * Based on AT91RM9200 datasheet revision E.
++ *
++ * 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 AT91RM9200_PDC_H
++#define AT91RM9200_PDC_H
++
++#define AT91_PDC_RPR          0x100   /* Receive Pointer Register */
++#define AT91_PDC_RCR          0x104   /* Receive Counter Register */
++#define AT91_PDC_TPR          0x108   /* Transmit Pointer Register */
++#define AT91_PDC_TCR          0x10c   /* Transmit Counter Register */
++#define AT91_PDC_RNPR         0x110   /* Receive Next Pointer Register */
++#define AT91_PDC_RNCR         0x114   /* Receive Next Counter Register */
++#define AT91_PDC_TNPR         0x118   /* Transmit Next Pointer Register */
++#define AT91_PDC_TNCR         0x11c   /* Transmit Next Counter Register */
++
++#define AT91_PDC_PTCR         0x120   /* Transfer Control Register */
++#define               AT91_PDC_RXTEN          (1 << 0)        /* Receiver Transfer Enable */
++#define               AT91_PDC_RXTDIS         (1 << 1)        /* Receiver Transfer Disable */
++#define               AT91_PDC_TXTEN          (1 << 8)        /* Transmitter Transfer Enable */
++#define               AT91_PDC_TXTDIS         (1 << 9)        /* Transmitter Transfer Disable */
++
++#define AT91_PDC_PTSR         0x124   /* Transfer Status Register */
++
++#endif
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/at91rm9200_usart.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/at91rm9200_usart.h        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,123 @@
++/*
++ * include/asm-arm/arch-at91rm9200/at91rm9200_usart.h
++ *
++ * Copyright (C) 2005 Ivan Kokshaysky
++ * Copyright (C) SAN People
++ *
++ * USART registers.
++ * Based on AT91RM9200 datasheet revision E.
++ *
++ * 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 AT91RM9200_USART_H
++#define AT91RM9200_USART_H
++
++#define AT91_US_CR            0x00                    /* Control Register */
++#define               AT91_US_RSTRX           (1 <<  2)               /* Reset Receiver */
++#define               AT91_US_RSTTX           (1 <<  3)               /* Reset Transmitter */
++#define               AT91_US_RXEN            (1 <<  4)               /* Receiver Enable */
++#define               AT91_US_RXDIS           (1 <<  5)               /* Receiver Disable */
++#define               AT91_US_TXEN            (1 <<  6)               /* Transmitter Enable */
++#define               AT91_US_TXDIS           (1 <<  7)               /* Transmitter Disable */
++#define               AT91_US_RSTSTA          (1 <<  8)               /* Reset Status Bits */
++#define               AT91_US_STTBRK          (1 <<  9)               /* Start Break */
++#define               AT91_US_STPBRK          (1 << 10)               /* Stop Break */
++#define               AT91_US_STTTO           (1 << 11)               /* Start Time-out */
++#define               AT91_US_SENDA           (1 << 12)               /* Send Address */
++#define               AT91_US_RSTIT           (1 << 13)               /* Reset Iterations */
++#define               AT91_US_RSTNACK         (1 << 14)               /* Reset Non Acknowledge */
++#define               AT91_US_RETTO           (1 << 15)               /* Rearm Time-out */
++#define               AT91_US_DTREN           (1 << 16)               /* Data Terminal Ready Enable */
++#define               AT91_US_DTRDIS          (1 << 17)               /* Data Terminal Ready Disable */
++#define               AT91_US_RTSEN           (1 << 18)               /* Request To Send Enable */
++#define               AT91_US_RTSDIS          (1 << 19)               /* Request To Send Disable */
++
++#define AT91_US_MR            0x04                    /* Mode Register */
++#define               AT91_US_USMODE          (0xf <<  0)             /* Mode of the USART */
++#define                       AT91_US_USMODE_NORMAL           0
++#define                       AT91_US_USMODE_RS485            1
++#define                       AT91_US_USMODE_HWHS             2
++#define                       AT91_US_USMODE_MODEM            3
++#define                       AT91_US_USMODE_ISO7816_T0       4
++#define                       AT91_US_USMODE_ISO7816_T1       6
++#define                       AT91_US_USMODE_IRDA             8
++#define               AT91_US_USCLKS          (3   <<  4)             /* Clock Selection */
++#define               AT91_US_CHRL            (3   <<  6)             /* Character Length */
++#define                       AT91_US_CHRL_5                  (0 <<  6)
++#define                       AT91_US_CHRL_6                  (1 <<  6)
++#define                       AT91_US_CHRL_7                  (2 <<  6)
++#define                       AT91_US_CHRL_8                  (3 <<  6)
++#define               AT91_US_SYNC            (1 <<  8)               /* Synchronous Mode Select */
++#define               AT91_US_PAR             (7 <<  9)               /* Parity Type */
++#define                       AT91_US_PAR_EVEN                (0 <<  9)
++#define                       AT91_US_PAR_ODD                 (1 <<  9)
++#define                       AT91_US_PAR_SPACE               (2 <<  9)
++#define                       AT91_US_PAR_MARK                (3 <<  9)
++#define                       AT91_US_PAR_NONE                (4 <<  9)
++#define                       AT91_US_PAR_MULTI_DROP          (6 <<  9)
++#define               AT91_US_NBSTOP          (3 << 12)               /* Number of Stop Bits */
++#define                       AT91_US_NBSTOP_1                (0 << 12)
++#define                       AT91_US_NBSTOP_1_5              (1 << 12)
++#define                       AT91_US_NBSTOP_2                (2 << 12)
++#define               AT91_US_CHMODE          (3 << 14)               /* Channel Mode */
++#define                       AT91_US_CHMODE_NORMAL           (0 << 14)
++#define                       AT91_US_CHMODE_ECHO             (1 << 14)
++#define                       AT91_US_CHMODE_LOC_LOOP         (2 << 14)
++#define                       AT91_US_CHMODE_REM_LOOP         (3 << 14)
++#define               AT91_US_MSBF            (1 << 16)               /* Bit Order */
++#define               AT91_US_MODE9           (1 << 17)               /* 9-bit Character Length */
++#define               AT91_US_CLKO            (1 << 18)               /* Clock Output Select */
++#define               AT91_US_OVER            (1 << 19)               /* Oversampling Mode */
++#define               AT91_US_INACK           (1 << 20)               /* Inhibit Non Acknowledge */
++#define               AT91_US_DSNACK          (1 << 21)               /* Disable Successive NACK */
++#define               AT91_US_MAX_ITER        (7 << 24)               /* Max Iterations */
++#define               AT91_US_FILTER          (1 << 28)               /* Infrared Receive Line Filter */
++
++#define AT91_US_IER           0x08                    /* Interrupt Enable Register */
++#define               AT91_US_RXRDY           (1 <<  0)               /* Receiver Ready */
++#define               AT91_US_TXRDY           (1 <<  1)               /* Transmitter Ready */
++#define               AT91_US_RXBRK           (1 <<  2)               /* Break Received / End of Break */
++#define               AT91_US_ENDRX           (1 <<  3)               /* End of Receiver Transfer */
++#define               AT91_US_ENDTX           (1 <<  4)               /* End of Transmitter Transfer */
++#define               AT91_US_OVRE            (1 <<  5)               /* Overrun Error */
++#define               AT91_US_FRAME           (1 <<  6)               /* Framing Error */
++#define               AT91_US_PARE            (1 <<  7)               /* Parity Error */
++#define               AT91_US_TIMEOUT         (1 <<  8)               /* Receiver Time-out */
++#define               AT91_US_TXEMPTY         (1 <<  9)               /* Transmitter Empty */
++#define               AT91_US_ITERATION       (1 << 10)               /* Max number of Repetitions Reached */
++#define               AT91_US_TXBUFE          (1 << 11)               /* Transmission Buffer Empty */
++#define               AT91_US_RXBUFF          (1 << 12)               /* Reception Buffer Full */
++#define               AT91_US_NACK            (1 << 13)               /* Non Acknowledge */
++#define               AT91_US_RIIC            (1 << 16)               /* Ring Indicator Input Change */
++#define               AT91_US_DSRIC           (1 << 17)               /* Data Set Ready Input Change */
++#define               AT91_US_DCDIC           (1 << 18)               /* Data Carrier Detect Input Change */
++#define               AT91_US_CTSIC           (1 << 19)               /* Clear to Send Input Change */
++#define               AT91_US_RI              (1 << 20)               /* RI */
++#define               AT91_US_DSR             (1 << 21)               /* DSR */
++#define               AT91_US_DCD             (1 << 22)               /* DCD */
++#define               AT91_US_CTS             (1 << 23)               /* CTS */
++
++#define AT91_US_IDR           0x0c                    /* Interrupt Disable Register */
++#define AT91_US_IMR           0x10                    /* Interrupt Mask Register */
++#define AT91_US_CSR           0x14                    /* Channel Status Register */
++#define AT91_US_RHR           0x18                    /* Receiver Holding Register */
++#define AT91_US_THR           0x1c                    /* Transmitter Holding Register */
++
++#define AT91_US_BRGR          0x20                    /* Baud Rate Generator Register */
++#define               AT91_US_CD              (0xffff << 0)           /* Clock Divider */
++
++#define AT91_US_RTOR          0x24                    /* Receiver Time-out Register */
++#define               AT91_US_TO              (0xffff << 0)           /* Time-out Value */
++
++#define AT91_US_TTGR          0x28                    /* Transmitter Timeguard Register */
++#define               AT91_US_TG              (0xff << 0)             /* Timeguard Value */
++
++#define AT91_US_FIDI          0x40                    /* FI DI Ratio Register */
++#define AT91_US_NER           0x44                    /* Number of Errors Register */
++#define AT91_US_IF            0x4c                    /* IrDA Filter Register */
++
++#endif
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/board.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/board.h   2006-12-04 11:50:22.000000000 +0100
+@@ -0,0 +1,35 @@
++/*
++ * Platform data definitions.
++ */
++#ifndef __ASM_ARCH_BOARD_H
++#define __ASM_ARCH_BOARD_H
++
++#include <linux/types.h>
++
++/* Add basic devices: system manager, interrupt controller, portmuxes, etc. */
++void at32_add_system_devices(void);
++
++#define AT91_NR_UART  4
++extern struct platform_device *at91_default_console_device;
++
++struct platform_device *at32_add_device_usart(unsigned int id);
++
++struct eth_platform_data {
++      u8      valid;
++      u8      mii_phy_addr;
++      u8      is_rmii;
++      u8      hw_addr[6];
++};
++struct platform_device *
++at32_add_device_eth(unsigned int id, struct eth_platform_data *data);
++
++struct platform_device *at32_add_device_spi(unsigned int id);
++
++struct lcdc_platform_data {
++      unsigned long fbmem_start;
++      unsigned long fbmem_size;
++};
++struct platform_device *
++at32_add_device_lcdc(unsigned int id, struct lcdc_platform_data *data);
++
++#endif /* __ASM_ARCH_BOARD_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/init.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/init.h    2006-12-04 11:50:22.000000000 +0100
+@@ -0,0 +1,21 @@
++/*
++ * AT32AP platform initialization calls.
++ *
++ * 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 __ASM_AVR32_AT32AP_INIT_H__
++#define __ASM_AVR32_AT32AP_INIT_H__
++
++void setup_platform(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__ */
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/portmux.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/portmux.h 2006-12-04 11:50:25.000000000 +0100
+@@ -0,0 +1,16 @@
++/*
++ * AT32 portmux interface.
++ *
++ * 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 __ASM_AVR32_AT32_PORTMUX_H__
++#define __ASM_AVR32_AT32_PORTMUX_H__
++
++void portmux_set_func(unsigned int portmux_id, unsigned int pin_id,
++                    unsigned int function_id);
++
++#endif /* __ASM_AVR32_AT32_PORTMUX_H__ */
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/sm.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/sm.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,27 @@
++/*
++ * AT32 System Manager interface.
++ *
++ * 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 __ASM_AVR32_AT32_SM_H__
++#define __ASM_AVR32_AT32_SM_H__
++
++struct irq_chip;
++struct platform_device;
++
++struct at32_sm {
++      spinlock_t lock;
++      void __iomem *regs;
++      struct irq_chip *eim_chip;
++      unsigned int eim_first_irq;
++      struct platform_device *pdev;
++};
++
++extern struct platform_device at32_sm_device;
++extern struct at32_sm system_manager;
++
++#endif /* __ASM_AVR32_AT32_SM_H__ */
+Index: linux-2.6.18-avr32/include/asm-avr32/asm.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/asm.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,102 @@
++/*
++ * 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 __ASM_AVR32_ASM_H__
++#define __ASM_AVR32_ASM_H__
++
++#include <asm/sysreg.h>
++#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
++
++#ifdef CONFIG_FRAME_POINTER
++      .macro  save_fp
++      st.w    --sp, r7
++      .endm
++      .macro  restore_fp
++      ld.w    r7, sp++
++      .endm
++      .macro  zero_fp
++      mov     r7, 0
++      .endm
++#else
++      .macro  save_fp
++      .endm
++      .macro  restore_fp
++      .endm
++      .macro  zero_fp
++      .endm
++#endif
++      .macro  get_thread_info reg
++      mov     \reg, sp
++      andl    \reg, ~(THREAD_SIZE - 1) & 0xffff
++      .endm
++
++      /* Save and restore registers */
++      .macro  save_min sr, tmp=lr
++      pushm   lr
++      mfsr    \tmp, \sr
++      zero_fp
++      st.w    --sp, \tmp
++      .endm
++
++      .macro  restore_min sr, tmp=lr
++      ld.w    \tmp, sp++
++      mtsr    \sr, \tmp
++      popm    lr
++      .endm
++
++      .macro  save_half sr, tmp=lr
++      save_fp
++      pushm   r8-r9,r10,r11,r12,lr
++      zero_fp
++      mfsr    \tmp, \sr
++      st.w    --sp, \tmp
++      .endm
++
++      .macro  restore_half sr, tmp=lr
++      ld.w    \tmp, sp++
++      mtsr    \sr, \tmp
++      popm    r8-r9,r10,r11,r12,lr
++      restore_fp
++      .endm
++
++      .macro  save_full_user sr, tmp=lr
++      stmts   --sp, r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,sp,lr
++      st.w    --sp, lr
++      zero_fp
++      mfsr    \tmp, \sr
++      st.w    --sp, \tmp
++      .endm
++
++      .macro  restore_full_user sr, tmp=lr
++      ld.w    \tmp, sp++
++      mtsr    \sr, \tmp
++      ld.w    lr, sp++
++      ldmts   sp++, r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,sp,lr
++      .endm
++
++      /* uaccess macros */
++      .macro branch_if_kernel scratch, label
++      get_thread_info \scratch
++      ld.w    \scratch, \scratch[TI_flags]
++      bld     \scratch, TIF_USERSPACE
++      brcc    \label
++      .endm
++
++      .macro ret_if_privileged scratch, addr, size, ret
++      sub     \scratch, \size, 1
++      add     \scratch, \addr
++      retcs   \ret
++      retmi   \ret
++      .endm
++
++#endif /* __ASM_AVR32_ASM_H__ */
+Index: linux-2.6.18-avr32/include/asm-avr32/atomic.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/atomic.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,201 @@
++/*
++ * Atomic operations that C can't guarantee us.  Useful for
++ * resource counting etc.
++ *
++ * But use these as seldom as possible since they are slower than
++ * regular operations.
++ *
++ * 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 __ASM_AVR32_ATOMIC_H
++#define __ASM_AVR32_ATOMIC_H
++
++#include <asm/system.h>
++
++typedef struct { volatile int counter; } atomic_t;
++#define ATOMIC_INIT(i)  { (i) }
++
++#define atomic_read(v)                ((v)->counter)
++#define atomic_set(v, i)      (((v)->counter) = i)
++
++/*
++ * atomic_sub_return - subtract the atomic variable
++ * @i: integer value to subtract
++ * @v: pointer of type atomic_t
++ *
++ * Atomically subtracts @i from @v. Returns the resulting value.
++ */
++static inline int atomic_sub_return(int i, atomic_t *v)
++{
++      int result;
++
++      asm volatile(
++              "/* atomic_sub_return */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %2\n"
++              "       sub     %0, %3\n"
++              "       stcond  %1, %0\n"
++              "       brne    1b"
++              : "=&r"(result), "=o"(v->counter)
++              : "m"(v->counter), "rKs21"(i)
++              : "cc");
++
++      return result;
++}
++
++/*
++ * atomic_add_return - add integer to atomic variable
++ * @i: integer value to add
++ * @v: pointer of type atomic_t
++ *
++ * Atomically adds @i to @v. Returns the resulting value.
++ */
++static inline int atomic_add_return(int i, atomic_t *v)
++{
++      int result;
++
++      if (__builtin_constant_p(i) && (i >= -1048575) && (i <= 1048576))
++              result = atomic_sub_return(-i, v);
++      else
++              asm volatile(
++                      "/* atomic_add_return */\n"
++                      "1:     ssrf    5\n"
++                      "       ld.w    %0, %1\n"
++                      "       add     %0, %3\n"
++                      "       stcond  %2, %0\n"
++                      "       brne    1b"
++                      : "=&r"(result), "=o"(v->counter)
++                      : "m"(v->counter), "r"(i)
++                      : "cc", "memory");
++
++      return result;
++}
++
++/*
++ * atomic_sub_unless - sub unless the number is a given value
++ * @v: pointer of type atomic_t
++ * @a: the amount to add to v...
++ * @u: ...unless v is equal to u.
++ *
++ * If the atomic value v is not equal to u, this function subtracts a
++ * from v, and returns non zero. If v is equal to u then it returns
++ * zero. This is done as an atomic operation.
++*/
++static inline int atomic_sub_unless(atomic_t *v, int a, int u)
++{
++      int tmp, result = 0;
++
++      asm volatile(
++              "/* atomic_sub_unless */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %3\n"
++              "       cp.w    %0, %5\n"
++              "       breq    1f\n"
++              "       sub     %0, %4\n"
++              "       stcond  %2, %0\n"
++              "       brne    1b\n"
++              "       mov     %1, 1\n"
++              "1:"
++              : "=&r"(tmp), "=&r"(result), "=o"(v->counter)
++              : "m"(v->counter), "rKs21"(a), "rKs21"(u)
++              : "cc", "memory");
++
++      return result;
++}
++
++/*
++ * atomic_add_unless - add unless the number is a given value
++ * @v: pointer of type atomic_t
++ * @a: the amount to add to v...
++ * @u: ...unless v is equal to u.
++ *
++ * If the atomic value v is not equal to u, this function adds a to v,
++ * and returns non zero. If v is equal to u then it returns zero. This
++ * is done as an atomic operation.
++*/
++static inline int atomic_add_unless(atomic_t *v, int a, int u)
++{
++      int tmp, result;
++
++      if (__builtin_constant_p(a) && (a >= -1048575) && (a <= 1048576))
++              result = atomic_sub_unless(v, -a, u);
++      else {
++              result = 0;
++              asm volatile(
++                      "/* atomic_add_unless */\n"
++                      "1:     ssrf    5\n"
++                      "       ld.w    %0, %3\n"
++                      "       cp.w    %0, %5\n"
++                      "       breq    1f\n"
++                      "       add     %0, %4\n"
++                      "       stcond  %2, %0\n"
++                      "       brne    1b\n"
++                      "       mov     %1, 1\n"
++                      "1:"
++                      : "=&r"(tmp), "=&r"(result), "=o"(v->counter)
++                      : "m"(v->counter), "r"(a), "ir"(u)
++                      : "cc", "memory");
++      }
++
++      return result;
++}
++
++/*
++ * atomic_sub_if_positive - conditionally subtract integer from atomic variable
++ * @i: integer value to subtract
++ * @v: pointer of type atomic_t
++ *
++ * Atomically test @v and subtract @i if @v is greater or equal than @i.
++ * The function returns the old value of @v minus @i.
++ */
++static inline int atomic_sub_if_positive(int i, atomic_t *v)
++{
++      int result;
++
++      asm volatile(
++              "/* atomic_sub_if_positive */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %2\n"
++              "       sub     %0, %3\n"
++              "       brlt    1f\n"
++              "       stcond  %1, %0\n"
++              "       brne    1b\n"
++              "1:"
++              : "=&r"(result), "=o"(v->counter)
++              : "m"(v->counter), "ir"(i)
++              : "cc", "memory");
++
++      return result;
++}
++
++#define atomic_xchg(v, new)   (xchg(&((v)->counter), new))
++#define atomic_cmpxchg(v, o, n)       ((int)cmpxchg(&((v)->counter), (o), (n)))
++
++#define atomic_sub(i, v)      (void)atomic_sub_return(i, v)
++#define atomic_add(i, v)      (void)atomic_add_return(i, v)
++#define atomic_dec(v)         atomic_sub(1, (v))
++#define atomic_inc(v)         atomic_add(1, (v))
++
++#define atomic_dec_return(v)  atomic_sub_return(1, v)
++#define atomic_inc_return(v)  atomic_add_return(1, v)
++
++#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
++#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0)
++#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0)
++#define atomic_add_negative(i, v) (atomic_add_return(i, v) < 0)
++
++#define atomic_inc_not_zero(v)        atomic_add_unless(v, 1, 0)
++#define atomic_dec_if_positive(v) atomic_sub_if_positive(1, v)
++
++#define smp_mb__before_atomic_dec()   barrier()
++#define smp_mb__after_atomic_dec()    barrier()
++#define smp_mb__before_atomic_inc()   barrier()
++#define smp_mb__after_atomic_inc()    barrier()
++
++#include <asm-generic/atomic.h>
++
++#endif /*  __ASM_AVR32_ATOMIC_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/auxvec.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/auxvec.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,4 @@
++#ifndef __ASM_AVR32_AUXVEC_H
++#define __ASM_AVR32_AUXVEC_H
++
++#endif /* __ASM_AVR32_AUXVEC_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/bitops.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/bitops.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,296 @@
++/*
++ * 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 __ASM_AVR32_BITOPS_H
++#define __ASM_AVR32_BITOPS_H
++
++#include <asm/byteorder.h>
++#include <asm/system.h>
++
++/*
++ * clear_bit() doesn't provide any barrier for the compiler
++ */
++#define smp_mb__before_clear_bit()    barrier()
++#define smp_mb__after_clear_bit()     barrier()
++
++/*
++ * set_bit - Atomically set a bit in memory
++ * @nr: the bit to set
++ * @addr: the address to start counting from
++ *
++ * This function is atomic and may not be reordered.  See __set_bit()
++ * if you do not require the atomic guarantees.
++ *
++ * Note that @nr may be almost arbitrarily large; this function is not
++ * restricted to acting on a single-word quantity.
++ */
++static inline void set_bit(int nr, volatile void * addr)
++{
++      unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG;
++      unsigned long tmp;
++
++      if (__builtin_constant_p(nr)) {
++              asm volatile(
++                      "1:     ssrf    5\n"
++                      "       ld.w    %0, %2\n"
++                      "       sbr     %0, %3\n"
++                      "       stcond  %1, %0\n"
++                      "       brne    1b"
++                      : "=&r"(tmp), "=o"(*p)
++                      : "m"(*p), "i"(nr)
++                      : "cc");
++      } else {
++              unsigned long mask = 1UL << (nr % BITS_PER_LONG);
++              asm volatile(
++                      "1:     ssrf    5\n"
++                      "       ld.w    %0, %2\n"
++                      "       or      %0, %3\n"
++                      "       stcond  %1, %0\n"
++                      "       brne    1b"
++                      : "=&r"(tmp), "=o"(*p)
++                      : "m"(*p), "r"(mask)
++                      : "cc");
++      }
++}
++
++/*
++ * clear_bit - Clears a bit in memory
++ * @nr: Bit to clear
++ * @addr: Address to start counting from
++ *
++ * clear_bit() is atomic and may not be reordered.  However, it does
++ * not contain a memory barrier, so if it is used for locking purposes,
++ * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
++ * in order to ensure changes are visible on other processors.
++ */
++static inline void clear_bit(int nr, volatile void * addr)
++{
++      unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG;
++      unsigned long tmp;
++
++      if (__builtin_constant_p(nr)) {
++              asm volatile(
++                      "1:     ssrf    5\n"
++                      "       ld.w    %0, %2\n"
++                      "       cbr     %0, %3\n"
++                      "       stcond  %1, %0\n"
++                      "       brne    1b"
++                      : "=&r"(tmp), "=o"(*p)
++                      : "m"(*p), "i"(nr)
++                      : "cc");
++      } else {
++              unsigned long mask = 1UL << (nr % BITS_PER_LONG);
++              asm volatile(
++                      "1:     ssrf    5\n"
++                      "       ld.w    %0, %2\n"
++                      "       andn    %0, %3\n"
++                      "       stcond  %1, %0\n"
++                      "       brne    1b"
++                      : "=&r"(tmp), "=o"(*p)
++                      : "m"(*p), "r"(mask)
++                      : "cc");
++      }
++}
++
++/*
++ * change_bit - Toggle a bit in memory
++ * @nr: Bit to change
++ * @addr: Address to start counting from
++ *
++ * change_bit() is atomic and may not be reordered.
++ * Note that @nr may be almost arbitrarily large; this function is not
++ * restricted to acting on a single-word quantity.
++ */
++static inline void change_bit(int nr, volatile void * addr)
++{
++      unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG;
++      unsigned long mask = 1UL << (nr % BITS_PER_LONG);
++      unsigned long tmp;
++
++      asm volatile(
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %2\n"
++              "       eor     %0, %3\n"
++              "       stcond  %1, %0\n"
++              "       brne    1b"
++              : "=&r"(tmp), "=o"(*p)
++              : "m"(*p), "r"(mask)
++              : "cc");
++}
++
++/*
++ * test_and_set_bit - Set a bit and return its old value
++ * @nr: Bit to set
++ * @addr: Address to count from
++ *
++ * This operation is atomic and cannot be reordered.
++ * It also implies a memory barrier.
++ */
++static inline int test_and_set_bit(int nr, volatile void * addr)
++{
++      unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG;
++      unsigned long mask = 1UL << (nr % BITS_PER_LONG);
++      unsigned long tmp, old;
++
++      if (__builtin_constant_p(nr)) {
++              asm volatile(
++                      "1:     ssrf    5\n"
++                      "       ld.w    %0, %3\n"
++                      "       mov     %2, %0\n"
++                      "       sbr     %0, %4\n"
++                      "       stcond  %1, %0\n"
++                      "       brne    1b"
++                      : "=&r"(tmp), "=o"(*p), "=&r"(old)
++                      : "m"(*p), "i"(nr)
++                      : "memory", "cc");
++      } else {
++              asm volatile(
++                      "1:     ssrf    5\n"
++                      "       ld.w    %2, %3\n"
++                      "       or      %0, %2, %4\n"
++                      "       stcond  %1, %0\n"
++                      "       brne    1b"
++                      : "=&r"(tmp), "=o"(*p), "=&r"(old)
++                      : "m"(*p), "r"(mask)
++                      : "memory", "cc");
++      }
++
++      return (old & mask) != 0;
++}
++
++/*
++ * test_and_clear_bit - Clear a bit and return its old value
++ * @nr: Bit to clear
++ * @addr: Address to count from
++ *
++ * This operation is atomic and cannot be reordered.
++ * It also implies a memory barrier.
++ */
++static inline int test_and_clear_bit(int nr, volatile void * addr)
++{
++      unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG;
++      unsigned long mask = 1UL << (nr % BITS_PER_LONG);
++      unsigned long tmp, old;
++
++      if (__builtin_constant_p(nr)) {
++              asm volatile(
++                      "1:     ssrf    5\n"
++                      "       ld.w    %0, %3\n"
++                      "       mov     %2, %0\n"
++                      "       cbr     %0, %4\n"
++                      "       stcond  %1, %0\n"
++                      "       brne    1b"
++                      : "=&r"(tmp), "=o"(*p), "=&r"(old)
++                      : "m"(*p), "i"(nr)
++                      : "memory", "cc");
++      } else {
++              asm volatile(
++                      "1:     ssrf    5\n"
++                      "       ld.w    %0, %3\n"
++                      "       mov     %2, %0\n"
++                      "       andn    %0, %4\n"
++                      "       stcond  %1, %0\n"
++                      "       brne    1b"
++                      : "=&r"(tmp), "=o"(*p), "=&r"(old)
++                      : "m"(*p), "r"(mask)
++                      : "memory", "cc");
++      }
++
++      return (old & mask) != 0;
++}
++
++/*
++ * test_and_change_bit - Change a bit and return its old value
++ * @nr: Bit to change
++ * @addr: Address to count from
++ *
++ * This operation is atomic and cannot be reordered.
++ * It also implies a memory barrier.
++ */
++static inline int test_and_change_bit(int nr, volatile void * addr)
++{
++      unsigned long *p = ((unsigned long *)addr) + nr / BITS_PER_LONG;
++      unsigned long mask = 1UL << (nr % BITS_PER_LONG);
++      unsigned long tmp, old;
++
++      asm volatile(
++              "1:     ssrf    5\n"
++              "       ld.w    %2, %3\n"
++              "       eor     %0, %2, %4\n"
++              "       stcond  %1, %0\n"
++              "       brne    1b"
++              : "=&r"(tmp), "=o"(*p), "=&r"(old)
++              : "m"(*p), "r"(mask)
++              : "memory", "cc");
++
++      return (old & mask) != 0;
++}
++
++#include <asm-generic/bitops/non-atomic.h>
++
++/* Find First bit Set */
++static inline unsigned long __ffs(unsigned long word)
++{
++      unsigned long result;
++
++      asm("brev %1\n\t"
++          "clz %0,%1"
++          : "=r"(result), "=&r"(word)
++          : "1"(word));
++      return result;
++}
++
++/* Find First Zero */
++static inline unsigned long ffz(unsigned long word)
++{
++      return __ffs(~word);
++}
++
++/* Find Last bit Set */
++static inline int fls(unsigned long word)
++{
++      unsigned long result;
++
++      asm("clz %0,%1" : "=r"(result) : "r"(word));
++      return 32 - result;
++}
++
++unsigned long find_first_zero_bit(const unsigned long *addr,
++                                unsigned long size);
++unsigned long find_next_zero_bit(const unsigned long *addr,
++                               unsigned long size,
++                               unsigned long offset);
++unsigned long find_first_bit(const unsigned long *addr,
++                           unsigned long size);
++unsigned long find_next_bit(const unsigned long *addr,
++                               unsigned long size,
++                               unsigned long offset);
++
++/*
++ * ffs: find first bit set. This is defined the same way as
++ * the libc and compiler builtin ffs routines, therefore
++ * differs in spirit from the above ffz (man ffs).
++ *
++ * The difference is that bit numbering starts at 1, and if no bit is set,
++ * the function returns 0.
++ */
++static inline int ffs(unsigned long word)
++{
++      if(word == 0)
++              return 0;
++      return __ffs(word) + 1;
++}
++
++#include <asm-generic/bitops/fls64.h>
++#include <asm-generic/bitops/sched.h>
++#include <asm-generic/bitops/hweight.h>
++
++#include <asm-generic/bitops/ext2-non-atomic.h>
++#include <asm-generic/bitops/ext2-atomic.h>
++#include <asm-generic/bitops/minix-le.h>
++
++#endif /* __ASM_AVR32_BITOPS_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/bug.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/bug.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,47 @@
++/*
++ * 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 __ASM_AVR32_BUG_H
++#define __ASM_AVR32_BUG_H
++
++#ifdef CONFIG_BUG
++
++/*
++ * According to our Chief Architect, this compact opcode is very
++ * unlikely to ever be implemented.
++ */
++#define AVR32_BUG_OPCODE      0x5df0
++
++#ifdef CONFIG_DEBUG_BUGVERBOSE
++
++#define BUG()                                                         \
++      do {                                                            \
++              asm volatile(".hword    %0\n\t"                         \
++                           ".hword    %1\n\t"                         \
++                           ".long     %2"                             \
++                           :                                          \
++                           : "n"(AVR32_BUG_OPCODE),                   \
++                             "i"(__LINE__), "X"(__FILE__));           \
++      } while (0)
++
++#else
++
++#define BUG()                                                         \
++      do {                                                            \
++              asm volatile(".hword    %0\n\t"                         \
++                           : : "n"(AVR32_BUG_OPCODE));                \
++      } while (0)
++
++#endif /* CONFIG_DEBUG_BUGVERBOSE */
++
++#define HAVE_ARCH_BUG
++
++#endif /* CONFIG_BUG */
++
++#include <asm-generic/bug.h>
++
++#endif /* __ASM_AVR32_BUG_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/bugs.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/bugs.h        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,15 @@
++/*
++ * This is included by init/main.c to check for architecture-dependent bugs.
++ *
++ * Needs:
++ *      void check_bugs(void);
++ */
++#ifndef __ASM_AVR32_BUGS_H
++#define __ASM_AVR32_BUGS_H
++
++static void __init check_bugs(void)
++{
++      cpu_data->loops_per_jiffy = loops_per_jiffy;
++}
++
++#endif /* __ASM_AVR32_BUGS_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/byteorder.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/byteorder.h   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,25 @@
++/*
++ * AVR32 endian-conversion functions.
++ */
++#ifndef __ASM_AVR32_BYTEORDER_H
++#define __ASM_AVR32_BYTEORDER_H
++
++#include <asm/types.h>
++#include <linux/compiler.h>
++
++#ifdef __CHECKER__
++extern unsigned long __builtin_bswap_32(unsigned long x);
++extern unsigned short __builtin_bswap_16(unsigned short x);
++#endif
++
++#define __arch__swab32(x) __builtin_bswap_32(x)
++#define __arch__swab16(x) __builtin_bswap_16(x)
++
++#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
++# define __BYTEORDER_HAS_U64__
++# define __SWAB_64_THRU_32__
++#endif
++
++#include <linux/byteorder/big_endian.h>
++
++#endif /* __ASM_AVR32_BYTEORDER_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/cache.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/cache.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,29 @@
++#ifndef __ASM_AVR32_CACHE_H
++#define __ASM_AVR32_CACHE_H
++
++#define L1_CACHE_SHIFT 5
++#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
++
++#ifndef __ASSEMBLER__
++struct cache_info {
++      unsigned int ways;
++      unsigned int sets;
++      unsigned int linesz;
++};
++#endif /* __ASSEMBLER */
++
++/* Cache operation constants */
++#define ICACHE_FLUSH          0x00
++#define ICACHE_INVALIDATE     0x01
++#define ICACHE_LOCK           0x02
++#define ICACHE_UNLOCK         0x03
++#define ICACHE_PREFETCH               0x04
++
++#define DCACHE_FLUSH          0x08
++#define DCACHE_LOCK           0x09
++#define DCACHE_UNLOCK         0x0a
++#define DCACHE_INVALIDATE     0x0b
++#define DCACHE_CLEAN          0x0c
++#define DCACHE_CLEAN_INVAL    0x0d
++
++#endif /* __ASM_AVR32_CACHE_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/cachectl.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/cachectl.h    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,11 @@
++#ifndef __ASM_AVR32_CACHECTL_H
++#define __ASM_AVR32_CACHECTL_H
++
++/*
++ * Operations that can be performed through the cacheflush system call
++ */
++
++/* Clean the data cache, then invalidate the icache */
++#define CACHE_IFLUSH  0
++
++#endif /* __ASM_AVR32_CACHECTL_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/cacheflush.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/cacheflush.h  2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,129 @@
++/*
++ * 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 __ASM_AVR32_CACHEFLUSH_H
++#define __ASM_AVR32_CACHEFLUSH_H
++
++/* Keep includes the same across arches.  */
++#include <linux/mm.h>
++
++#define CACHE_OP_ICACHE_INVALIDATE    0x01
++#define CACHE_OP_DCACHE_INVALIDATE    0x0b
++#define CACHE_OP_DCACHE_CLEAN         0x0c
++#define CACHE_OP_DCACHE_CLEAN_INVAL   0x0d
++
++/*
++ * Invalidate any cacheline containing virtual address vaddr without
++ * writing anything back to memory.
++ *
++ * Note that this function may corrupt unrelated data structures when
++ * applied on buffers that are not cacheline aligned in both ends.
++ */
++static inline void invalidate_dcache_line(void *vaddr)
++{
++      asm volatile("cache %0[0], %1"
++                   :
++                   : "r"(vaddr), "n"(CACHE_OP_DCACHE_INVALIDATE)
++                   : "memory");
++}
++
++/*
++ * Make sure any cacheline containing virtual address vaddr is written
++ * to memory.
++ */
++static inline void clean_dcache_line(void *vaddr)
++{
++      asm volatile("cache %0[0], %1"
++                   :
++                   : "r"(vaddr), "n"(CACHE_OP_DCACHE_CLEAN)
++                   : "memory");
++}
++
++/*
++ * Make sure any cacheline containing virtual address vaddr is written
++ * to memory and then invalidate it.
++ */
++static inline void flush_dcache_line(void *vaddr)
++{
++      asm volatile("cache %0[0], %1"
++                   :
++                   : "r"(vaddr), "n"(CACHE_OP_DCACHE_CLEAN_INVAL)
++                   : "memory");
++}
++
++/*
++ * Invalidate any instruction cacheline containing virtual address
++ * vaddr.
++ */
++static inline void invalidate_icache_line(void *vaddr)
++{
++      asm volatile("cache %0[0], %1"
++                   :
++                   : "r"(vaddr), "n"(CACHE_OP_ICACHE_INVALIDATE)
++                   : "memory");
++}
++
++/*
++ * Applies the above functions on all lines that are touched by the
++ * specified virtual address range.
++ */
++void invalidate_dcache_region(void *start, size_t len);
++void clean_dcache_region(void *start, size_t len);
++void flush_dcache_region(void *start, size_t len);
++void invalidate_icache_region(void *start, size_t len);
++
++/*
++ * Make sure any pending writes are completed before continuing.
++ */
++#define flush_write_buffer() asm volatile("sync 0" : : : "memory")
++
++/*
++ * The following functions are called when a virtual mapping changes.
++ * We do not need to flush anything in this case.
++ */
++#define flush_cache_all()                     do { } while (0)
++#define flush_cache_mm(mm)                    do { } while (0)
++#define flush_cache_range(vma, start, end)    do { } while (0)
++#define flush_cache_page(vma, vmaddr, pfn)    do { } while (0)
++#define flush_cache_vmap(start, end)          do { } while (0)
++#define flush_cache_vunmap(start, end)                do { } while (0)
++
++/*
++ * I think we need to implement this one to be able to reliably
++ * execute pages from RAMDISK. However, if we implement the
++ * flush_dcache_*() functions, it might not be needed anymore.
++ *
++ * #define flush_icache_page(vma, page)               do { } while (0)
++ */
++extern void flush_icache_page(struct vm_area_struct *vma, struct page *page);
++
++/*
++ * These are (I think) related to D-cache aliasing.  We might need to
++ * do something here, but only for certain configurations.  No such
++ * configurations exist at this time.
++ */
++#define flush_dcache_page(page)                       do { } while (0)
++#define flush_dcache_mmap_lock(page)          do { } while (0)
++#define flush_dcache_mmap_unlock(page)                do { } while (0)
++
++/*
++ * These are for I/D cache coherency. In this case, we do need to
++ * flush with all configurations.
++ */
++extern void flush_icache_range(unsigned long start, unsigned long end);
++extern void flush_icache_user_range(struct vm_area_struct *vma,
++                                  struct page *page,
++                                  unsigned long addr, int len);
++
++#define copy_to_user_page(vma, page, vaddr, dst, src, len) do {       \
++      memcpy(dst, src, len);                                  \
++      flush_icache_user_range(vma, page, vaddr, len);         \
++} while(0)
++#define copy_from_user_page(vma, page, vaddr, dst, src, len)  \
++      memcpy(dst, src, len)
++
++#endif /* __ASM_AVR32_CACHEFLUSH_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/checksum.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/checksum.h    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,156 @@
++/*
++ * 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 __ASM_AVR32_CHECKSUM_H
++#define __ASM_AVR32_CHECKSUM_H
++
++/*
++ * computes the checksum of a memory block at buff, length len,
++ * and adds in "sum" (32-bit)
++ *
++ * returns a 32-bit number suitable for feeding into itself
++ * or csum_tcpudp_magic
++ *
++ * this function must be called with even lengths, except
++ * for the last fragment, which may be odd
++ *
++ * it's best to have buff aligned on a 32-bit boundary
++ */
++unsigned int csum_partial(const unsigned char * buff, int len,
++                        unsigned int sum);
++
++/*
++ * the same as csum_partial, but copies from src while it
++ * checksums, and handles user-space pointer exceptions correctly, when needed.
++ *
++ * here even more important to align src and dst on a 32-bit (or even
++ * better 64-bit) boundary
++ */
++unsigned int csum_partial_copy_generic(const char *src, char *dst, int len,
++                                     int sum, int *src_err_ptr,
++                                     int *dst_err_ptr);
++
++/*
++ *    Note: when you get a NULL pointer exception here this means someone
++ *    passed in an incorrect kernel address to one of these functions.
++ *
++ *    If you use these functions directly please don't forget the
++ *    verify_area().
++ */
++static inline
++unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
++                                     int len, int sum)
++{
++      return csum_partial_copy_generic(src, dst, len, sum, NULL, NULL);
++}
++
++static inline
++unsigned int csum_partial_copy_from_user (const char __user *src, char *dst,
++                                        int len, int sum, int *err_ptr)
++{
++      return csum_partial_copy_generic((const char __force *)src, dst, len,
++                                       sum, err_ptr, NULL);
++}
++
++/*
++ *    This is a version of ip_compute_csum() optimized for IP headers,
++ *    which always checksum on 4 octet boundaries.
++ */
++static inline unsigned short ip_fast_csum(unsigned char *iph,
++                                        unsigned int ihl)
++{
++      unsigned int sum, tmp;
++
++      __asm__ __volatile__(
++              "       ld.w    %0, %1++\n"
++              "       ld.w    %3, %1++\n"
++              "       sub     %2, 4\n"
++              "       add     %0, %3\n"
++              "       ld.w    %3, %1++\n"
++              "       adc     %0, %0, %3\n"
++              "       ld.w    %3, %1++\n"
++              "       adc     %0, %0, %3\n"
++              "       acr     %0\n"
++              "1:     ld.w    %3, %1++\n"
++              "       add     %0, %3\n"
++              "       acr     %0\n"
++              "       sub     %2, 1\n"
++              "       brne    1b\n"
++              "       lsl     %3, %0, 16\n"
++              "       andl    %0, 0\n"
++              "       mov     %2, 0xffff\n"
++              "       add     %0, %3\n"
++              "       adc     %0, %0, %2\n"
++              "       com     %0\n"
++              "       lsr     %0, 16\n"
++              : "=r"(sum), "=r"(iph), "=r"(ihl), "=r"(tmp)
++              : "1"(iph), "2"(ihl)
++              : "memory", "cc");
++      return sum;
++}
++
++/*
++ *    Fold a partial checksum
++ */
++
++static inline unsigned int csum_fold(unsigned int sum)
++{
++      unsigned int tmp;
++
++      asm("   bfextu  %1, %0, 0, 16\n"
++          "   lsr     %0, 16\n"
++          "   add     %0, %1\n"
++          "   bfextu  %1, %0, 16, 16\n"
++          "   add     %0, %1"
++          : "=&r"(sum), "=&r"(tmp)
++          : "0"(sum));
++
++      return ~sum;
++}
++
++static inline unsigned long csum_tcpudp_nofold(unsigned long saddr,
++                                             unsigned long daddr,
++                                             unsigned short len,
++                                             unsigned short proto,
++                                             unsigned int sum)
++{
++      asm("   add     %0, %1\n"
++          "   adc     %0, %0, %2\n"
++          "   adc     %0, %0, %3\n"
++          "   acr     %0"
++          : "=r"(sum)
++          : "r"(daddr), "r"(saddr), "r"(ntohs(len) | (proto << 16)),
++            "0"(sum)
++          : "cc");
++
++      return sum;
++}
++
++/*
++ * computes the checksum of the TCP/UDP pseudo-header
++ * returns a 16-bit checksum, already complemented
++ */
++static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
++                                                 unsigned long daddr,
++                                                 unsigned short len,
++                                                 unsigned short proto,
++                                                 unsigned int sum)
++{
++      return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
++}
++
++/*
++ * this routine is used for miscellaneous IP-like checksums, mainly
++ * in icmp.c
++ */
++
++static inline unsigned short ip_compute_csum(unsigned char * buff, int len)
++{
++    return csum_fold(csum_partial(buff, len, 0));
++}
++
++#endif /* __ASM_AVR32_CHECKSUM_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/cputime.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/cputime.h     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_CPUTIME_H
++#define __ASM_AVR32_CPUTIME_H
++
++#include <asm-generic/cputime.h>
++
++#endif /* __ASM_AVR32_CPUTIME_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/current.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/current.h     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,15 @@
++#ifndef __ASM_AVR32_CURRENT_H
++#define __ASM_AVR32_CURRENT_H
++
++#include <linux/thread_info.h>
++
++struct task_struct;
++
++inline static struct task_struct * get_current(void)
++{
++      return current_thread_info()->task;
++}
++
++#define current get_current()
++
++#endif /* __ASM_AVR32_CURRENT_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/delay.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/delay.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,26 @@
++#ifndef __ASM_AVR32_DELAY_H
++#define __ASM_AVR32_DELAY_H
++
++/*
++ * Copyright (C) 1993 Linus Torvalds
++ *
++ * Delay routines calling functions in arch/avr32/lib/delay.c
++ */
++
++extern void __bad_udelay(void);
++extern void __bad_ndelay(void);
++
++extern void __udelay(unsigned long usecs);
++extern void __ndelay(unsigned long nsecs);
++extern void __const_udelay(unsigned long usecs);
++extern void __delay(unsigned long loops);
++
++#define udelay(n) (__builtin_constant_p(n) ? \
++      ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c6ul)) : \
++      __udelay(n))
++
++#define ndelay(n) (__builtin_constant_p(n) ? \
++      ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \
++      __ndelay(n))
++
++#endif /* __ASM_AVR32_DELAY_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/div64.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/div64.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_DIV64_H
++#define __ASM_AVR32_DIV64_H
++
++#include <asm-generic/div64.h>
++
++#endif /* __ASM_AVR32_DIV64_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/dma-mapping.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/dma-mapping.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,320 @@
++#ifndef __ASM_AVR32_DMA_MAPPING_H
++#define __ASM_AVR32_DMA_MAPPING_H
++
++#include <linux/mm.h>
++#include <linux/device.h>
++#include <asm/scatterlist.h>
++#include <asm/processor.h>
++#include <asm/cacheflush.h>
++#include <asm/io.h>
++
++extern void dma_cache_sync(void *vaddr, size_t size, int direction);
++
++/*
++ * Return whether the given device DMA address mask can be supported
++ * properly.  For example, if your device can only drive the low 24-bits
++ * during bus mastering, then you would pass 0x00ffffff as the mask
++ * to this function.
++ */
++static inline int dma_supported(struct device *dev, u64 mask)
++{
++      /* Fix when needed. I really don't know of any limitations */
++      return 1;
++}
++
++static inline int dma_set_mask(struct device *dev, u64 dma_mask)
++{
++      if (!dev->dma_mask || !dma_supported(dev, dma_mask))
++              return -EIO;
++
++      *dev->dma_mask = dma_mask;
++      return 0;
++}
++
++/**
++ * dma_alloc_coherent - allocate consistent memory for DMA
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @size: required memory size
++ * @handle: bus-specific DMA address
++ *
++ * Allocate some uncached, unbuffered memory for a device for
++ * performing DMA.  This function allocates pages, and will
++ * return the CPU-viewed address, and sets @handle to be the
++ * device-viewed address.
++ */
++extern void *dma_alloc_coherent(struct device *dev, size_t size,
++                              dma_addr_t *handle, gfp_t gfp);
++
++/**
++ * dma_free_coherent - free memory allocated by dma_alloc_coherent
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @size: size of memory originally requested in dma_alloc_coherent
++ * @cpu_addr: CPU-view address returned from dma_alloc_coherent
++ * @handle: device-view address returned from dma_alloc_coherent
++ *
++ * Free (and unmap) a DMA buffer previously allocated by
++ * dma_alloc_coherent().
++ *
++ * References to memory and mappings associated with cpu_addr/handle
++ * during and after this call executing are illegal.
++ */
++extern void dma_free_coherent(struct device *dev, size_t size,
++                            void *cpu_addr, dma_addr_t handle);
++
++/**
++ * dma_alloc_writecombine - allocate write-combining memory for DMA
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @size: required memory size
++ * @handle: bus-specific DMA address
++ *
++ * Allocate some uncached, buffered memory for a device for
++ * performing DMA.  This function allocates pages, and will
++ * return the CPU-viewed address, and sets @handle to be the
++ * device-viewed address.
++ */
++extern void *dma_alloc_writecombine(struct device *dev, size_t size,
++                                  dma_addr_t *handle, gfp_t gfp);
++
++/**
++ * dma_free_coherent - free memory allocated by dma_alloc_writecombine
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @size: size of memory originally requested in dma_alloc_writecombine
++ * @cpu_addr: CPU-view address returned from dma_alloc_writecombine
++ * @handle: device-view address returned from dma_alloc_writecombine
++ *
++ * Free (and unmap) a DMA buffer previously allocated by
++ * dma_alloc_writecombine().
++ *
++ * References to memory and mappings associated with cpu_addr/handle
++ * during and after this call executing are illegal.
++ */
++extern void dma_free_writecombine(struct device *dev, size_t size,
++                                void *cpu_addr, dma_addr_t handle);
++
++/**
++ * dma_map_single - map a single buffer for streaming DMA
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @cpu_addr: CPU direct mapped address of buffer
++ * @size: size of buffer to map
++ * @dir: DMA transfer direction
++ *
++ * Ensure that any data held in the cache is appropriately discarded
++ * or written back.
++ *
++ * The device owns this memory once this call has completed.  The CPU
++ * can regain ownership by calling dma_unmap_single() or dma_sync_single().
++ */
++static inline dma_addr_t
++dma_map_single(struct device *dev, void *cpu_addr, size_t size,
++             enum dma_data_direction direction)
++{
++      dma_cache_sync(cpu_addr, size, direction);
++      return virt_to_bus(cpu_addr);
++}
++
++/**
++ * dma_unmap_single - unmap a single buffer previously mapped
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @handle: DMA address of buffer
++ * @size: size of buffer to map
++ * @dir: DMA transfer direction
++ *
++ * Unmap a single streaming mode DMA translation.  The handle and size
++ * must match what was provided in the previous dma_map_single() call.
++ * All other usages are undefined.
++ *
++ * After this call, reads by the CPU to the buffer are guaranteed to see
++ * whatever the device wrote there.
++ */
++static inline void
++dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
++               enum dma_data_direction direction)
++{
++
++}
++
++/**
++ * dma_map_page - map a portion of a page for streaming DMA
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @page: page that buffer resides in
++ * @offset: offset into page for start of buffer
++ * @size: size of buffer to map
++ * @dir: DMA transfer direction
++ *
++ * Ensure that any data held in the cache is appropriately discarded
++ * or written back.
++ *
++ * The device owns this memory once this call has completed.  The CPU
++ * can regain ownership by calling dma_unmap_page() or dma_sync_single().
++ */
++static inline dma_addr_t
++dma_map_page(struct device *dev, struct page *page,
++           unsigned long offset, size_t size,
++           enum dma_data_direction direction)
++{
++      return dma_map_single(dev, page_address(page) + offset,
++                            size, direction);
++}
++
++/**
++ * dma_unmap_page - unmap a buffer previously mapped through dma_map_page()
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @handle: DMA address of buffer
++ * @size: size of buffer to map
++ * @dir: DMA transfer direction
++ *
++ * Unmap a single streaming mode DMA translation.  The handle and size
++ * must match what was provided in the previous dma_map_single() call.
++ * All other usages are undefined.
++ *
++ * After this call, reads by the CPU to the buffer are guaranteed to see
++ * whatever the device wrote there.
++ */
++static inline void
++dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
++             enum dma_data_direction direction)
++{
++      dma_unmap_single(dev, dma_address, size, direction);
++}
++
++/**
++ * dma_map_sg - map a set of SG buffers for streaming mode DMA
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @sg: list of buffers
++ * @nents: number of buffers to map
++ * @dir: DMA transfer direction
++ *
++ * Map a set of buffers described by scatterlist in streaming
++ * mode for DMA.  This is the scatter-gather version of the
++ * above pci_map_single interface.  Here the scatter gather list
++ * elements are each tagged with the appropriate dma address
++ * and length.  They are obtained via sg_dma_{address,length}(SG).
++ *
++ * NOTE: An implementation may be able to use a smaller number of
++ *       DMA address/length pairs than there are SG table elements.
++ *       (for example via virtual mapping capabilities)
++ *       The routine returns the number of addr/length pairs actually
++ *       used, at most nents.
++ *
++ * Device ownership issues as mentioned above for pci_map_single are
++ * the same here.
++ */
++static inline int
++dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
++         enum dma_data_direction direction)
++{
++      int i;
++
++      for (i = 0; i < nents; i++) {
++              char *virt;
++
++              sg[i].dma_address = page_to_bus(sg[i].page) + sg[i].offset;
++              virt = page_address(sg[i].page) + sg[i].offset;
++              dma_cache_sync(virt, sg[i].length, direction);
++      }
++
++      return nents;
++}
++
++/**
++ * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @sg: list of buffers
++ * @nents: number of buffers to map
++ * @dir: DMA transfer direction
++ *
++ * Unmap a set of streaming mode DMA translations.
++ * Again, CPU read rules concerning calls here are the same as for
++ * pci_unmap_single() above.
++ */
++static inline void
++dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
++           enum dma_data_direction direction)
++{
++
++}
++
++/**
++ * dma_sync_single_for_cpu
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @handle: DMA address of buffer
++ * @size: size of buffer to map
++ * @dir: DMA transfer direction
++ *
++ * Make physical memory consistent for a single streaming mode DMA
++ * translation after a transfer.
++ *
++ * If you perform a dma_map_single() but wish to interrogate the
++ * buffer using the cpu, yet do not wish to teardown the DMA mapping,
++ * you must call this function before doing so.  At the next point you
++ * give the DMA address back to the card, you must first perform a
++ * dma_sync_single_for_device, and then the device again owns the
++ * buffer.
++ */
++static inline void
++dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
++                      size_t size, enum dma_data_direction direction)
++{
++      dma_cache_sync(bus_to_virt(dma_handle), size, direction);
++}
++
++static inline void
++dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
++                         size_t size, enum dma_data_direction direction)
++{
++      dma_cache_sync(bus_to_virt(dma_handle), size, direction);
++}
++
++/**
++ * dma_sync_sg_for_cpu
++ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
++ * @sg: list of buffers
++ * @nents: number of buffers to map
++ * @dir: DMA transfer direction
++ *
++ * Make physical memory consistent for a set of streaming
++ * mode DMA translations after a transfer.
++ *
++ * The same as dma_sync_single_for_* but for a scatter-gather list,
++ * same rules and usage.
++ */
++static inline void
++dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
++                  int nents, enum dma_data_direction direction)
++{
++      int i;
++
++      for (i = 0; i < nents; i++) {
++              dma_cache_sync(page_address(sg[i].page) + sg[i].offset,
++                             sg[i].length, direction);
++      }
++}
++
++static inline void
++dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
++                     int nents, enum dma_data_direction direction)
++{
++      int i;
++
++      for (i = 0; i < nents; i++) {
++              dma_cache_sync(page_address(sg[i].page) + sg[i].offset,
++                             sg[i].length, direction);
++      }
++}
++
++/* Now for the API extensions over the pci_ one */
++
++#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
++#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
++
++static inline int dma_is_consistent(dma_addr_t dma_addr)
++{
++      return 1;
++}
++
++static inline int dma_get_cache_alignment(void)
++{
++      return boot_cpu_data.dcache.linesz;
++}
++
++#endif /* __ASM_AVR32_DMA_MAPPING_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/dma.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/dma.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,8 @@
++#ifndef __ASM_AVR32_DMA_H
++#define __ASM_AVR32_DMA_H
++
++/* The maximum address that we can perform a DMA transfer to on this platform.
++ * Not really applicable to AVR32, but some functions need it. */
++#define MAX_DMA_ADDRESS               0xffffffff
++
++#endif /* __ASM_AVR32_DMA_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/elf.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/elf.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,110 @@
++#ifndef __ASM_AVR32_ELF_H
++#define __ASM_AVR32_ELF_H
++
++/* AVR32 relocation numbers */
++#define R_AVR32_NONE          0
++#define R_AVR32_32            1
++#define R_AVR32_16            2
++#define R_AVR32_8             3
++#define R_AVR32_32_PCREL      4
++#define R_AVR32_16_PCREL      5
++#define R_AVR32_8_PCREL               6
++#define R_AVR32_DIFF32                7
++#define R_AVR32_DIFF16                8
++#define R_AVR32_DIFF8         9
++#define R_AVR32_GOT32         10
++#define R_AVR32_GOT16         11
++#define R_AVR32_GOT8          12
++#define R_AVR32_21S           13
++#define R_AVR32_16U           14
++#define R_AVR32_16S           15
++#define R_AVR32_8S            16
++#define R_AVR32_8S_EXT                17
++#define R_AVR32_22H_PCREL     18
++#define R_AVR32_18W_PCREL     19
++#define R_AVR32_16B_PCREL     20
++#define R_AVR32_16N_PCREL     21
++#define R_AVR32_14UW_PCREL    22
++#define R_AVR32_11H_PCREL     23
++#define R_AVR32_10UW_PCREL    24
++#define R_AVR32_9H_PCREL      25
++#define R_AVR32_9UW_PCREL     26
++#define R_AVR32_HI16          27
++#define R_AVR32_LO16          28
++#define R_AVR32_GOTPC         29
++#define R_AVR32_GOTCALL               30
++#define R_AVR32_LDA_GOT               31
++#define R_AVR32_GOT21S                32
++#define R_AVR32_GOT18SW               33
++#define R_AVR32_GOT16S                34
++#define R_AVR32_GOT7UW                35
++#define R_AVR32_32_CPENT      36
++#define R_AVR32_CPCALL                37
++#define R_AVR32_16_CP         38
++#define R_AVR32_9W_CP         39
++#define R_AVR32_RELATIVE      40
++#define R_AVR32_GLOB_DAT      41
++#define R_AVR32_JMP_SLOT      42
++#define R_AVR32_ALIGN         43
++
++/*
++ * ELF register definitions..
++ */
++
++#include <asm/ptrace.h>
++#include <asm/user.h>
++
++typedef unsigned long elf_greg_t;
++
++#define ELF_NGREG (sizeof (struct pt_regs) / sizeof (elf_greg_t))
++typedef elf_greg_t elf_gregset_t[ELF_NGREG];
++
++typedef struct user_fpu_struct elf_fpregset_t;
++
++/*
++ * This is used to ensure we don't load something for the wrong architecture.
++ */
++#define elf_check_arch(x) ( (x)->e_machine == EM_AVR32 )
++
++/*
++ * These are used to set parameters in the core dumps.
++ */
++#define ELF_CLASS     ELFCLASS32
++#ifdef __LITTLE_ENDIAN__
++#define ELF_DATA      ELFDATA2LSB
++#else
++#define ELF_DATA      ELFDATA2MSB
++#endif
++#define ELF_ARCH      EM_AVR32
++
++#define USE_ELF_CORE_DUMP
++#define ELF_EXEC_PAGESIZE     4096
++
++/* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
++   use of this is to invoke "./ld.so someprog" to test out a new version of
++   the loader.  We need to make sure that it is out of the way of the program
++   that it will "exec", and that there is sufficient room for the brk.  */
++
++#define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
++
++
++/* This yields a mask that user programs can use to figure out what
++   instruction set this CPU supports.  This could be done in user space,
++   but it's not easy, and we've already done it here.  */
++
++#define ELF_HWCAP     (0)
++
++/* This yields a string that ld.so will use to load implementation
++   specific libraries for optimization.  This is more specific in
++   intent than poking at uname or /proc/cpuinfo.
++
++   For the moment, we have only optimizations for the Intel generations,
++   but that could change... */
++
++#define ELF_PLATFORM  (NULL)
++
++#ifdef __KERNEL__
++#define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
++#endif
++
++#endif /* __ASM_AVR32_ELF_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/emergency-restart.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/emergency-restart.h   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_EMERGENCY_RESTART_H
++#define __ASM_AVR32_EMERGENCY_RESTART_H
++
++#include <asm-generic/emergency-restart.h>
++
++#endif /* __ASM_AVR32_EMERGENCY_RESTART_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/errno.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/errno.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_ERRNO_H
++#define __ASM_AVR32_ERRNO_H
++
++#include <asm-generic/errno.h>
++
++#endif /* __ASM_AVR32_ERRNO_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/fcntl.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/fcntl.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_FCNTL_H
++#define __ASM_AVR32_FCNTL_H
++
++#include <asm-generic/fcntl.h>
++
++#endif /* __ASM_AVR32_FCNTL_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/futex.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/futex.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_FUTEX_H
++#define __ASM_AVR32_FUTEX_H
++
++#include <asm-generic/futex.h>
++
++#endif /* __ASM_AVR32_FUTEX_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/hardirq.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/hardirq.h     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,34 @@
++#ifndef __ASM_AVR32_HARDIRQ_H
++#define __ASM_AVR32_HARDIRQ_H
++
++#include <linux/threads.h>
++#include <asm/irq.h>
++
++#ifndef __ASSEMBLY__
++
++#include <linux/cache.h>
++
++/* entry.S is sensitive to the offsets of these fields */
++typedef struct {
++      unsigned int __softirq_pending;
++} ____cacheline_aligned irq_cpustat_t;
++
++void ack_bad_irq(unsigned int irq);
++
++/* Standard mappings for irq_cpustat_t above */
++#include <linux/irq_cpustat.h>
++
++#endif /* __ASSEMBLY__ */
++
++#define HARDIRQ_BITS  12
++
++/*
++ * The hardirq mask has to be large enough to have
++ * space for potentially all IRQ sources in the system
++ * nesting on a single CPU:
++ */
++#if (1 << HARDIRQ_BITS) < NR_IRQS
++# error HARDIRQ_BITS is too low!
++#endif
++
++#endif /* __ASM_AVR32_HARDIRQ_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/hw_irq.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/hw_irq.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,9 @@
++#ifndef __ASM_AVR32_HW_IRQ_H
++#define __ASM_AVR32_HW_IRQ_H
++
++static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
++{
++      /* Nothing to do */
++}
++
++#endif /* __ASM_AVR32_HW_IRQ_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/intc.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/intc.h        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,128 @@
++#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 */
+Index: linux-2.6.18-avr32/include/asm-avr32/io.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/io.h  2006-12-04 11:50:22.000000000 +0100
+@@ -0,0 +1,286 @@
++#ifndef __ASM_AVR32_IO_H
++#define __ASM_AVR32_IO_H
++
++#include <linux/string.h>
++
++#ifdef __KERNEL__
++
++#include <asm/addrspace.h>
++#include <asm/byteorder.h>
++
++/* virt_to_phys will only work when address is in P1 or P2 */
++static __inline__ unsigned long virt_to_phys(volatile void *address)
++{
++      return PHYSADDR(address);
++}
++
++static __inline__ void * phys_to_virt(unsigned long address)
++{
++      return (void *)P1SEGADDR(address);
++}
++
++#define cached_to_phys(addr)  ((unsigned long)PHYSADDR(addr))
++#define uncached_to_phys(addr)        ((unsigned long)PHYSADDR(addr))
++#define phys_to_cached(addr)  ((void *)P1SEGADDR(addr))
++#define phys_to_uncached(addr)        ((void *)P2SEGADDR(addr))
++
++/*
++ * Generic IO read/write.  These perform native-endian accesses.  Note
++ * that some architectures will want to re-define __raw_{read,write}w.
++ */
++extern void __raw_writesb(unsigned int addr, const void *data, int bytelen);
++extern void __raw_writesw(unsigned int addr, const void *data, int wordlen);
++extern void __raw_writesl(unsigned int addr, const void *data, int longlen);
++
++extern void __raw_readsb(unsigned int addr, void *data, int bytelen);
++extern void __raw_readsw(unsigned int addr, void *data, int wordlen);
++extern void __raw_readsl(unsigned int addr, void *data, int longlen);
++
++static inline void writeb(unsigned char b, volatile void __iomem *addr)
++{
++      *(volatile unsigned char __force *)addr = b;
++}
++static inline void writew(unsigned short b, volatile void __iomem *addr)
++{
++      *(volatile unsigned short __force *)addr = b;
++}
++static inline void writel(unsigned int b, volatile void __iomem *addr)
++{
++      *(volatile unsigned int __force *)addr = b;
++}
++#define __raw_writeb writeb
++#define __raw_writew writew
++#define __raw_writel writel
++
++static inline unsigned char readb(const volatile void __iomem *addr)
++{
++      return *(const volatile unsigned char __force *)addr;
++}
++static inline unsigned short readw(const volatile void __iomem *addr)
++{
++      return *(const volatile unsigned short __force *)addr;
++}
++static inline unsigned int readl(const volatile void __iomem *addr)
++{
++      return *(const volatile unsigned int __force *)addr;
++}
++#define __raw_readb readb
++#define __raw_readw readw
++#define __raw_readl readl
++
++#define writesb(p, d, l)      __raw_writesb((unsigned int)p, d, l)
++#define writesw(p, d, l)      __raw_writesw((unsigned int)p, d, l)
++#define writesl(p, d, l)      __raw_writesl((unsigned int)p, d, l)
++
++#define readsb(p, d, l)               __raw_readsb((unsigned int)p, d, l)
++#define readsw(p, d, l)               __raw_readsw((unsigned int)p, d, l)
++#define readsl(p, d, l)               __raw_readsl((unsigned int)p, d, l)
++
++
++/*
++ * io{read,write}{8,16,32} macros in both le (for PCI style consumers) and native be
++ */
++#ifndef ioread8
++
++#define ioread8(p)    ({ unsigned int __v = __raw_readb(p); __v; })
++
++#define ioread16(p)   ({ unsigned int __v = le16_to_cpu(__raw_readw(p)); __v; })
++#define ioread16be(p) ({ unsigned int __v = be16_to_cpu(__raw_readw(p)); __v; })
++
++#define ioread32(p)   ({ unsigned int __v = le32_to_cpu(__raw_readl(p)); __v; })
++#define ioread32be(p) ({ unsigned int __v = be32_to_cpu(__raw_readl(p)); __v; })
++
++#define iowrite8(v,p) __raw_writeb(v, p)
++
++#define iowrite16(v,p)        __raw_writew(cpu_to_le16(v), p)
++#define iowrite16be(v,p)      __raw_writew(cpu_to_be16(v), p)
++
++#define iowrite32(v,p)        __raw_writel(cpu_to_le32(v), p)
++#define iowrite32be(v,p)      __raw_writel(cpu_to_be32(v), p)
++
++#define ioread8_rep(p,d,c)    __raw_readsb(p,d,c)
++#define ioread16_rep(p,d,c)   __raw_readsw(p,d,c)
++#define ioread32_rep(p,d,c)   __raw_readsl(p,d,c)
++
++#define iowrite8_rep(p,s,c)   __raw_writesb(p,s,c)
++#define iowrite16_rep(p,s,c)  __raw_writesw(p,s,c)
++#define iowrite32_rep(p,s,c)  __raw_writesl(p,s,c)
++
++#endif
++
++
++/*
++ * These two are only here because ALSA _thinks_ it needs them...
++ */
++static inline void memcpy_fromio(void * to, const volatile void __iomem *from,
++                               unsigned long count)
++{
++      char *p = to;
++      while (count) {
++              count--;
++              *p = readb(from);
++              p++;
++              from++;
++      }
++}
++
++static inline void  memcpy_toio(volatile void __iomem *to, const void * from,
++                              unsigned long count)
++{
++      const char *p = from;
++      while (count) {
++              count--;
++              writeb(*p, to);
++              p++;
++              to++;
++      }
++}
++
++static inline void memset_io(volatile void __iomem *addr, unsigned char val,
++                           unsigned long count)
++{
++      memset((void __force *)addr, val, count);
++}
++
++/*
++ * Bad read/write accesses...
++ */
++extern void __readwrite_bug(const char *fn);
++
++#define IO_SPACE_LIMIT        0xffffffff
++
++/* Convert I/O port address to virtual address */
++#define __io(p)               ((void __iomem *)phys_to_uncached(p))
++
++/*
++ *  IO port access primitives
++ *  -------------------------
++ *
++ * The AVR32 doesn't have special IO access instructions; all IO is memory
++ * mapped. Note that these are defined to perform little endian accesses
++ * only. Their primary purpose is to access PCI and ISA peripherals.
++ *
++ * Note that for a big endian machine, this implies that the following
++ * big endian mode connectivity is in place.
++ *
++ * The machine specific io.h include defines __io to translate an "IO"
++ * address to a memory address.
++ *
++ * Note that we prevent GCC re-ordering or caching values in expressions
++ * by introducing sequence points into the in*() definitions.  Note that
++ * __raw_* do not guarantee this behaviour.
++ *
++ * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
++ */
++#define outb(v, p)            __raw_writeb(v, __io(p))
++#define outw(v, p)            __raw_writew(cpu_to_le16(v), __io(p))
++#define outl(v, p)            __raw_writel(cpu_to_le32(v), __io(p))
++
++#define inb(p)                        __raw_readb(__io(p))
++#define inw(p)                        le16_to_cpu(__raw_readw(__io(p)))
++#define inl(p)                        le32_to_cpu(__raw_readl(__io(p)))
++
++static inline void __outsb(unsigned long port, void *addr, unsigned int count)
++{
++      while (count--) {
++              outb(*(u8 *)addr, port);
++              addr++;
++      }
++}
++
++static inline void __insb(unsigned long port, void *addr, unsigned int count)
++{
++      while (count--) {
++              *(u8 *)addr = inb(port);
++              addr++;
++      }
++}
++
++static inline void __outsw(unsigned long port, void *addr, unsigned int count)
++{
++      while (count--) {
++              outw(*(u16 *)addr, port);
++              addr += 2;
++      }
++}
++
++static inline void __insw(unsigned long port, void *addr, unsigned int count)
++{
++      while (count--) {
++              *(u16 *)addr = inw(port);
++              addr += 2;
++      }
++}
++
++static inline void __outsl(unsigned long port, void *addr, unsigned int count)
++{
++      while (count--) {
++              outl(*(u32 *)addr, port);
++              addr += 4;
++      }
++}
++
++static inline void __insl(unsigned long port, void *addr, unsigned int count)
++{
++      while (count--) {
++              *(u32 *)addr = inl(port);
++              addr += 4;
++      }
++}
++
++#define outsb(port, addr, count)      __outsb(port, addr, count)
++#define insb(port, addr, count)               __insb(port, addr, count)
++#define outsw(port, addr, count)      __outsw(port, addr, count)
++#define insw(port, addr, count)               __insw(port, addr, count)
++#define outsl(port, addr, count)      __outsl(port, addr, count)
++#define insl(port, addr, count)               __insl(port, addr, count)
++
++extern void __iomem *__ioremap(unsigned long offset, size_t size,
++                             unsigned long flags);
++extern void __iounmap(void __iomem *addr);
++
++/*
++ * ioremap    -   map bus memory into CPU space
++ * @offset    bus address of the memory
++ * @size      size of the resource to map
++ *
++ * ioremap performs a platform specific sequence of operations to make
++ * bus memory CPU accessible via the readb/.../writel functions and
++ * the other mmio helpers. The returned address is not guaranteed to
++ * be usable directly as a virtual address.
++ */
++#define ioremap(offset, size)                 \
++      __ioremap((offset), (size), 0)
++
++#define iounmap(addr)                         \
++      __iounmap(addr)
++
++#define cached(addr) P1SEGADDR(addr)
++#define uncached(addr) P2SEGADDR(addr)
++
++#define virt_to_bus virt_to_phys
++#define bus_to_virt phys_to_virt
++#define page_to_bus page_to_phys
++#define bus_to_page phys_to_page
++
++#define dma_cache_wback_inv(_start, _size)    \
++      flush_dcache_region(_start, _size)
++#define dma_cache_inv(_start, _size)          \
++      invalidate_dcache_region(_start, _size)
++#define dma_cache_wback(_start, _size)                \
++      clean_dcache_region(_start, _size)
++
++/*
++ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
++ * access
++ */
++#define xlate_dev_mem_ptr(p)    __va(p)
++
++/*
++ * Convert a virtual cached pointer to an uncached pointer
++ */
++#define xlate_dev_kmem_ptr(p)   p
++
++#endif /* __KERNEL__ */
++
++#endif /* __ASM_AVR32_IO_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/ioctl.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/ioctl.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_IOCTL_H
++#define __ASM_AVR32_IOCTL_H
++
++#include <asm-generic/ioctl.h>
++
++#endif /* __ASM_AVR32_IOCTL_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/ioctls.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/ioctls.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,83 @@
++#ifndef __ASM_AVR32_IOCTLS_H
++#define __ASM_AVR32_IOCTLS_H
++
++#include <asm/ioctl.h>
++
++/* 0x54 is just a magic number to make these relatively unique ('T') */
++
++#define TCGETS                0x5401
++#define TCSETS                0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
++#define TCSETSW               0x5403
++#define TCSETSF               0x5404
++#define TCGETA                0x5405
++#define TCSETA                0x5406
++#define TCSETAW               0x5407
++#define TCSETAF               0x5408
++#define TCSBRK                0x5409
++#define TCXONC                0x540A
++#define TCFLSH                0x540B
++#define TIOCEXCL      0x540C
++#define TIOCNXCL      0x540D
++#define TIOCSCTTY     0x540E
++#define TIOCGPGRP     0x540F
++#define TIOCSPGRP     0x5410
++#define TIOCOUTQ      0x5411
++#define TIOCSTI               0x5412
++#define TIOCGWINSZ    0x5413
++#define TIOCSWINSZ    0x5414
++#define TIOCMGET      0x5415
++#define TIOCMBIS      0x5416
++#define TIOCMBIC      0x5417
++#define TIOCMSET      0x5418
++#define TIOCGSOFTCAR  0x5419
++#define TIOCSSOFTCAR  0x541A
++#define FIONREAD      0x541B
++#define TIOCINQ               FIONREAD
++#define TIOCLINUX     0x541C
++#define TIOCCONS      0x541D
++#define TIOCGSERIAL   0x541E
++#define TIOCSSERIAL   0x541F
++#define TIOCPKT               0x5420
++#define FIONBIO               0x5421
++#define TIOCNOTTY     0x5422
++#define TIOCSETD      0x5423
++#define TIOCGETD      0x5424
++#define TCSBRKP               0x5425  /* Needed for POSIX tcsendbreak() */
++/* #define TIOCTTYGSTRUCT 0x5426 - Former debugging-only ioctl */
++#define TIOCSBRK      0x5427  /* BSD compatibility */
++#define TIOCCBRK      0x5428  /* BSD compatibility */
++#define TIOCGSID      0x5429  /* Return the session ID of FD */
++#define TIOCGPTN      _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
++#define TIOCSPTLCK    _IOW('T',0x31, int)  /* Lock/unlock Pty */
++
++#define FIONCLEX      0x5450
++#define FIOCLEX               0x5451
++#define FIOASYNC      0x5452
++#define TIOCSERCONFIG 0x5453
++#define TIOCSERGWILD  0x5454
++#define TIOCSERSWILD  0x5455
++#define TIOCGLCKTRMIOS        0x5456
++#define TIOCSLCKTRMIOS        0x5457
++#define TIOCSERGSTRUCT        0x5458 /* For debugging only */
++#define TIOCSERGETLSR   0x5459 /* Get line status register */
++#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
++#define TIOCSERSETMULTI 0x545B /* Set multiport config */
++
++#define TIOCMIWAIT    0x545C  /* wait for a change on serial input line(s) */
++#define TIOCGICOUNT   0x545D  /* read serial port inline interrupt counts */
++#define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
++#define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
++#define FIOQSIZE      0x5460
++
++/* Used for packet mode */
++#define TIOCPKT_DATA           0
++#define TIOCPKT_FLUSHREAD      1
++#define TIOCPKT_FLUSHWRITE     2
++#define TIOCPKT_STOP           4
++#define TIOCPKT_START          8
++#define TIOCPKT_NOSTOP                16
++#define TIOCPKT_DOSTOP                32
++
++#define TIOCSER_TEMT    0x01  /* Transmitter physically empty */
++
++#endif /* __ASM_AVR32_IOCTLS_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/ipcbuf.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/ipcbuf.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,29 @@
++#ifndef __ASM_AVR32_IPCBUF_H
++#define __ASM_AVR32_IPCBUF_H
++
++/*
++* The user_ipc_perm structure for AVR32 architecture.
++* Note extra padding because this structure is passed back and forth
++* between kernel and user space.
++*
++* Pad space is left for:
++* - 32-bit mode_t and seq
++* - 2 miscellaneous 32-bit values
++*/
++
++struct ipc64_perm
++{
++        __kernel_key_t          key;
++        __kernel_uid32_t        uid;
++        __kernel_gid32_t        gid;
++        __kernel_uid32_t        cuid;
++        __kernel_gid32_t        cgid;
++        __kernel_mode_t         mode;
++        unsigned short          __pad1;
++        unsigned short          seq;
++        unsigned short          __pad2;
++        unsigned long           __unused1;
++        unsigned long           __unused2;
++};
++
++#endif /* __ASM_AVR32_IPCBUF_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/irq.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/irq.h 2006-12-04 11:50:25.000000000 +0100
+@@ -0,0 +1,10 @@
++#ifndef __ASM_AVR32_IRQ_H
++#define __ASM_AVR32_IRQ_H
++
++#define NR_INTERNAL_IRQS      64
++#define NR_EXTERNAL_IRQS      64
++#define NR_IRQS                       (NR_INTERNAL_IRQS + NR_EXTERNAL_IRQS)
++
++#define irq_canonicalize(i)   (i)
++
++#endif /* __ASM_AVR32_IOCTLS_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/kdebug.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/kdebug.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,38 @@
++#ifndef __ASM_AVR32_KDEBUG_H
++#define __ASM_AVR32_KDEBUG_H
++
++#include <linux/notifier.h>
++
++struct pt_regs;
++
++struct die_args {
++      struct pt_regs *regs;
++      int trapnr;
++};
++
++int register_die_notifier(struct notifier_block *nb);
++int unregister_die_notifier(struct notifier_block *nb);
++int register_page_fault_notifier(struct notifier_block *nb);
++int unregister_page_fault_notifier(struct notifier_block *nb);
++extern struct atomic_notifier_head avr32_die_chain;
++
++/* Grossly misnamed. */
++enum die_val {
++      DIE_FAULT,
++      DIE_BREAKPOINT,
++      DIE_SSTEP,
++      DIE_PAGE_FAULT,
++};
++
++static inline int notify_die(enum die_val val, struct pt_regs *regs,
++                           int trap, int sig)
++{
++      struct die_args args = {
++              .regs = regs,
++              .trapnr = trap,
++      };
++
++      return atomic_notifier_call_chain(&avr32_die_chain, val, &args);
++}
++
++#endif /* __ASM_AVR32_KDEBUG_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/kmap_types.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/kmap_types.h  2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,30 @@
++#ifndef __ASM_AVR32_KMAP_TYPES_H
++#define __ASM_AVR32_KMAP_TYPES_H
++
++#ifdef CONFIG_DEBUG_HIGHMEM
++# define D(n) __KM_FENCE_##n ,
++#else
++# define D(n)
++#endif
++
++enum km_type {
++D(0)  KM_BOUNCE_READ,
++D(1)  KM_SKB_SUNRPC_DATA,
++D(2)  KM_SKB_DATA_SOFTIRQ,
++D(3)  KM_USER0,
++D(4)  KM_USER1,
++D(5)  KM_BIO_SRC_IRQ,
++D(6)  KM_BIO_DST_IRQ,
++D(7)  KM_PTE0,
++D(8)  KM_PTE1,
++D(9)  KM_PTE2,
++D(10) KM_IRQ0,
++D(11) KM_IRQ1,
++D(12) KM_SOFTIRQ0,
++D(13) KM_SOFTIRQ1,
++D(14) KM_TYPE_NR
++};
++
++#undef D
++
++#endif /* __ASM_AVR32_KMAP_TYPES_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/kprobes.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/kprobes.h     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,34 @@
++/*
++ * Kernel Probes (KProbes)
++ *
++ * Copyright (C) 2005-2006 Atmel Corporation
++ * Copyright (C) IBM Corporation, 2002, 2004
++ *
++ * 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_KPROBES_H
++#define __ASM_AVR32_KPROBES_H
++
++#include <linux/types.h>
++
++typedef u16   kprobe_opcode_t;
++#define BREAKPOINT_INSTRUCTION        0xd673  /* breakpoint */
++#define MAX_INSN_SIZE         2
++
++#define ARCH_INACTIVE_KPROBE_COUNT 1
++
++#define arch_remove_kprobe(p) do { } while (0)
++
++/* Architecture specific copy of original instruction */
++struct arch_specific_insn {
++      kprobe_opcode_t insn[MAX_INSN_SIZE];
++};
++
++extern int kprobe_exceptions_notify(struct notifier_block *self,
++                                  unsigned long val, void *data);
++
++#define flush_insn_slot(p)    do { } while (0)
++
++#endif /* __ASM_AVR32_KPROBES_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/linkage.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/linkage.h     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,7 @@
++#ifndef __ASM_LINKAGE_H
++#define __ASM_LINKAGE_H
++
++#define __ALIGN .balign 2
++#define __ALIGN_STR ".balign 2"
++
++#endif /* __ASM_LINKAGE_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/local.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/local.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_LOCAL_H
++#define __ASM_AVR32_LOCAL_H
++
++#include <asm-generic/local.h>
++
++#endif /* __ASM_AVR32_LOCAL_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/mach/serial_at91.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/mach/serial_at91.h    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,33 @@
++/*
++ *  linux/include/asm-arm/mach/serial_at91.h
++ *
++ *  Based on serial_sa1100.h  by Nicolas Pitre
++ *
++ *  Copyright (C) 2002 ATMEL Rousset
++ *
++ *  Low level machine dependent UART functions.
++ */
++
++struct uart_port;
++
++/*
++ * This is a temporary structure for registering these
++ * functions; it is intended to be discarded after boot.
++ */
++struct at91_port_fns {
++      void    (*set_mctrl)(struct uart_port *, u_int);
++      u_int   (*get_mctrl)(struct uart_port *);
++      void    (*enable_ms)(struct uart_port *);
++      void    (*pm)(struct uart_port *, u_int, u_int);
++      int     (*set_wake)(struct uart_port *, u_int);
++      int     (*open)(struct uart_port *);
++      void    (*close)(struct uart_port *);
++};
++
++#if defined(CONFIG_SERIAL_AT91)
++void at91_register_uart_fns(struct at91_port_fns *fns);
++#else
++#define at91_register_uart_fns(fns) do { } while (0)
++#endif
++
++
+Index: linux-2.6.18-avr32/include/asm-avr32/mman.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/mman.h        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,17 @@
++#ifndef __ASM_AVR32_MMAN_H__
++#define __ASM_AVR32_MMAN_H__
++
++#include <asm-generic/mman.h>
++
++#define MAP_GROWSDOWN 0x0100          /* stack-like segment */
++#define MAP_DENYWRITE 0x0800          /* ETXTBSY */
++#define MAP_EXECUTABLE        0x1000          /* mark it as an executable */
++#define MAP_LOCKED    0x2000          /* pages are locked */
++#define MAP_NORESERVE 0x4000          /* don't check for reservations */
++#define MAP_POPULATE  0x8000          /* populate (prefault) page tables */
++#define MAP_NONBLOCK  0x10000         /* do not block on IO */
++
++#define MCL_CURRENT   1               /* lock all current mappings */
++#define MCL_FUTURE    2               /* lock all future mappings */
++
++#endif /* __ASM_AVR32_MMAN_H__ */
+Index: linux-2.6.18-avr32/include/asm-avr32/mmu.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/mmu.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,10 @@
++#ifndef __ASM_AVR32_MMU_H
++#define __ASM_AVR32_MMU_H
++
++/* Default "unsigned long" context */
++typedef unsigned long mm_context_t;
++
++#define MMU_ITLB_ENTRIES      64
++#define MMU_DTLB_ENTRIES      64
++
++#endif /* __ASM_AVR32_MMU_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/mmu_context.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/mmu_context.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,148 @@
++/*
++ * Copyright (C) 2004-2006 Atmel Corporation
++ *
++ * ASID handling taken from SH implementation.
++ *   Copyright (C) 1999 Niibe Yutaka
++ *   Copyright (C) 2003 Paul Mundt
++ *
++ * 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_MMU_CONTEXT_H
++#define __ASM_AVR32_MMU_CONTEXT_H
++
++#include <asm/tlbflush.h>
++#include <asm/pgalloc.h>
++#include <asm/sysreg.h>
++
++/*
++ * The MMU "context" consists of two things:
++ *    (a) TLB cache version
++ *    (b) ASID (Address Space IDentifier)
++ */
++#define MMU_CONTEXT_ASID_MASK         0x000000ff
++#define MMU_CONTEXT_VERSION_MASK      0xffffff00
++#define MMU_CONTEXT_FIRST_VERSION       0x00000100
++#define NO_CONTEXT                    0
++
++#define MMU_NO_ASID                   0x100
++
++/* Virtual Page Number mask */
++#define MMU_VPN_MASK  0xfffff000
++
++/* Cache of MMU context last used */
++extern unsigned long mmu_context_cache;
++
++/*
++ * Get MMU context if needed
++ */
++static inline void
++get_mmu_context(struct mm_struct *mm)
++{
++      unsigned long mc = mmu_context_cache;
++
++      if (((mm->context ^ mc) & MMU_CONTEXT_VERSION_MASK) == 0)
++              /* It's up to date, do nothing */
++              return;
++
++      /* It's old, we need to get new context with new version */
++      mc = ++mmu_context_cache;
++      if (!(mc & MMU_CONTEXT_ASID_MASK)) {
++              /*
++               * We have exhausted all ASIDs of this version.
++               * Flush the TLB and start new cycle.
++               */
++              flush_tlb_all();
++              /*
++               * Fix version. Note that we avoid version #0
++               * to distinguish NO_CONTEXT.
++               */
++              if (!mc)
++                      mmu_context_cache = mc = MMU_CONTEXT_FIRST_VERSION;
++      }
++      mm->context = mc;
++}
++
++/*
++ * Initialize the context related info for a new mm_struct
++ * instance.
++ */
++static inline int init_new_context(struct task_struct *tsk,
++                                     struct mm_struct *mm)
++{
++      mm->context = NO_CONTEXT;
++      return 0;
++}
++
++/*
++ * Destroy context related info for an mm_struct that is about
++ * to be put to rest.
++ */
++static inline void destroy_context(struct mm_struct *mm)
++{
++      /* Do nothing */
++}
++
++static inline void set_asid(unsigned long asid)
++{
++      /* XXX: We're destroying TLBEHI[8:31] */
++      sysreg_write(TLBEHI, asid & MMU_CONTEXT_ASID_MASK);
++      cpu_sync_pipeline();
++}
++
++static inline unsigned long get_asid(void)
++{
++      unsigned long asid;
++
++      asid = sysreg_read(TLBEHI);
++      return asid & MMU_CONTEXT_ASID_MASK;
++}
++
++static inline void activate_context(struct mm_struct *mm)
++{
++      get_mmu_context(mm);
++      set_asid(mm->context & MMU_CONTEXT_ASID_MASK);
++}
++
++static inline void switch_mm(struct mm_struct *prev,
++                               struct mm_struct *next,
++                               struct task_struct *tsk)
++{
++      if (likely(prev != next)) {
++              unsigned long __pgdir = (unsigned long)next->pgd;
++
++              sysreg_write(PTBR, __pgdir);
++              activate_context(next);
++      }
++}
++
++#define deactivate_mm(tsk,mm) do { } while(0)
++
++#define activate_mm(prev, next) switch_mm((prev), (next), NULL)
++
++static inline void
++enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
++{
++}
++
++
++static inline void enable_mmu(void)
++{
++      sysreg_write(MMUCR, (SYSREG_BIT(MMUCR_S)
++                           | SYSREG_BIT(E)
++                           | SYSREG_BIT(MMUCR_I)));
++      nop(); nop(); nop(); nop(); nop(); nop(); nop(); nop();
++
++      if (mmu_context_cache == NO_CONTEXT)
++              mmu_context_cache = MMU_CONTEXT_FIRST_VERSION;
++
++      set_asid(mmu_context_cache & MMU_CONTEXT_ASID_MASK);
++}
++
++static inline void disable_mmu(void)
++{
++      sysreg_write(MMUCR, SYSREG_BIT(MMUCR_S));
++}
++
++#endif /* __ASM_AVR32_MMU_CONTEXT_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/module.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/module.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,28 @@
++#ifndef __ASM_AVR32_MODULE_H
++#define __ASM_AVR32_MODULE_H
++
++struct mod_arch_syminfo {
++      unsigned long got_offset;
++      int got_initialized;
++};
++
++struct mod_arch_specific {
++      /* Starting offset of got in the module core memory. */
++      unsigned long got_offset;
++      /* Size of the got. */
++      unsigned long got_size;
++      /* Number of symbols in syminfo. */
++      int nsyms;
++      /* Additional symbol information (got offsets). */
++      struct mod_arch_syminfo *syminfo;
++};
++
++#define Elf_Shdr              Elf32_Shdr
++#define Elf_Sym                       Elf32_Sym
++#define Elf_Ehdr              Elf32_Ehdr
++
++#define MODULE_PROC_FAMILY "AVR32v1"
++
++#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY
++
++#endif /* __ASM_AVR32_MODULE_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/msgbuf.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/msgbuf.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,31 @@
++#ifndef __ASM_AVR32_MSGBUF_H
++#define __ASM_AVR32_MSGBUF_H
++
++/*
++ * The msqid64_ds structure for i386 architecture.
++ * Note extra padding because this structure is passed back and forth
++ * between kernel and user space.
++ *
++ * Pad space is left for:
++ * - 64-bit time_t to solve y2038 problem
++ * - 2 miscellaneous 32-bit values
++ */
++
++struct msqid64_ds {
++      struct ipc64_perm msg_perm;
++      __kernel_time_t msg_stime;      /* last msgsnd time */
++      unsigned long   __unused1;
++      __kernel_time_t msg_rtime;      /* last msgrcv time */
++      unsigned long   __unused2;
++      __kernel_time_t msg_ctime;      /* last change time */
++      unsigned long   __unused3;
++      unsigned long  msg_cbytes;      /* current number of bytes on queue */
++      unsigned long  msg_qnum;        /* number of messages in queue */
++      unsigned long  msg_qbytes;      /* max number of bytes on queue */
++      __kernel_pid_t msg_lspid;       /* pid of last msgsnd */
++      __kernel_pid_t msg_lrpid;       /* last receive pid */
++      unsigned long  __unused4;
++      unsigned long  __unused5;
++};
++
++#endif /* __ASM_AVR32_MSGBUF_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/mutex.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/mutex.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,9 @@
++/*
++ * Pull in the generic implementation for the mutex fastpath.
++ *
++ * TODO: implement optimized primitives instead, or leave the generic
++ * implementation in place, or pick the atomic_xchg() based generic
++ * implementation. (see asm-generic/mutex-xchg.h for details)
++ */
++
++#include <asm-generic/mutex-dec.h>
+Index: linux-2.6.18-avr32/include/asm-avr32/namei.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/namei.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,7 @@
++#ifndef __ASM_AVR32_NAMEI_H
++#define __ASM_AVR32_NAMEI_H
++
++/* This dummy routine may be changed to something useful */
++#define __emul_prefix() NULL
++
++#endif /* __ASM_AVR32_NAMEI_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/numnodes.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/numnodes.h    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,7 @@
++#ifndef __ASM_AVR32_NUMNODES_H
++#define __ASM_AVR32_NUMNODES_H
++
++/* Max 4 nodes */
++#define NODES_SHIFT   2
++
++#endif /* __ASM_AVR32_NUMNODES_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/ocd.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/ocd.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,78 @@
++/*
++ * AVR32 OCD Registers
++ *
++ * 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 __ASM_AVR32_OCD_H
++#define __ASM_AVR32_OCD_H
++
++/* Debug Registers */
++#define DBGREG_DID              0
++#define DBGREG_DC               8
++#define DBGREG_DS              16
++#define DBGREG_RWCS            28
++#define DBGREG_RWA             36
++#define DBGREG_RWD             40
++#define DBGREG_WT              44
++#define DBGREG_DTC             52
++#define DBGREG_DTSA0           56
++#define DBGREG_DTSA1           60
++#define DBGREG_DTEA0           72
++#define DBGREG_DTEA1           76
++#define DBGREG_BWC0A           88
++#define DBGREG_BWC0B           92
++#define DBGREG_BWC1A           96
++#define DBGREG_BWC1B          100
++#define DBGREG_BWC2A          104
++#define DBGREG_BWC2B          108
++#define DBGREG_BWC3A          112
++#define DBGREG_BWC3B          116
++#define DBGREG_BWA0A          120
++#define DBGREG_BWA0B          124
++#define DBGREG_BWA1A          128
++#define DBGREG_BWA1B          132
++#define DBGREG_BWA2A          136
++#define DBGREG_BWA2B          140
++#define DBGREG_BWA3A          144
++#define DBGREG_BWA3B          148
++#define DBGREG_BWD3A          153
++#define DBGREG_BWD3B          156
++
++#define DBGREG_PID            284
++
++#define SABAH_OCD             0x01
++#define SABAH_ICACHE          0x02
++#define SABAH_MEM_CACHED      0x04
++#define SABAH_MEM_UNCACHED    0x05
++
++/* Fields in the Development Control register */
++#define DC_SS_BIT             8
++
++#define DC_SS                 (1 <<  DC_SS_BIT)
++#define DC_DBE                        (1 << 13)
++#define DC_RID                        (1 << 27)
++#define DC_ORP                        (1 << 28)
++#define DC_MM                 (1 << 29)
++#define DC_RES                        (1 << 30)
++
++/* Fields in the Development Status register */
++#define DS_SSS                        (1 <<  0)
++#define DS_SWB                        (1 <<  1)
++#define DS_HWB                        (1 <<  2)
++#define DS_BP_SHIFT           8
++#define DS_BP_MASK            (0xff << DS_BP_SHIFT)
++
++#define __mfdr(addr)                                                  \
++({                                                                    \
++      register unsigned long value;                                   \
++      asm volatile("mfdr      %0, %1" : "=r"(value) : "i"(addr));     \
++      value;                                                          \
++})
++#define __mtdr(addr, value)                                           \
++      asm volatile("mtdr      %0, %1" : : "i"(addr), "r"(value))
++
++#endif /* __ASM_AVR32_OCD_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/page.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/page.h        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,112 @@
++/*
++ * 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 __ASM_AVR32_PAGE_H
++#define __ASM_AVR32_PAGE_H
++
++#ifdef __KERNEL__
++
++/* 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_MASK     (~(PAGE_SIZE-1))
++#define PTE_MASK      PAGE_MASK
++
++#ifndef __ASSEMBLY__
++
++#include <asm/addrspace.h>
++
++extern void clear_page(void *to);
++extern void copy_page(void *to, void *from);
++
++#define clear_user_page(page, vaddr, pg)      clear_page(page)
++#define copy_user_page(to, from, vaddr, pg)   copy_page(to, from)
++
++/*
++ * These are used to make use of C type-checking..
++ */
++typedef struct { unsigned long pte; } pte_t;
++typedef struct { unsigned long pgd; } pgd_t;
++typedef struct { unsigned long pgprot; } pgprot_t;
++
++#define pte_val(x)            ((x).pte)
++#define pgd_val(x)            ((x).pgd)
++#define pgprot_val(x)         ((x).pgprot)
++
++#define __pte(x)              ((pte_t) { (x) })
++#define __pgd(x)              ((pgd_t) { (x) })
++#define __pgprot(x)           ((pgprot_t) { (x) })
++
++/* FIXME: These should be removed soon */
++extern unsigned long memory_start, memory_end;
++
++/* Pure 2^n version of get_order */
++static inline int get_order(unsigned long size)
++{
++      unsigned lz;
++
++      size = (size - 1) >> PAGE_SHIFT;
++      asm("clz %0, %1" : "=r"(lz) : "r"(size));
++      return 32 - lz;
++}
++
++#endif /* !__ASSEMBLY__ */
++
++/* Align the pointer to the (next) page boundary */
++#define PAGE_ALIGN(addr)      (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
++
++/*
++ * The hardware maps the virtual addresses 0x80000000 -> 0x9fffffff
++ * permanently to the physical addresses 0x00000000 -> 0x1fffffff when
++ * segmentation is enabled. We want to make use of this in order to
++ * minimize TLB pressure.
++ */
++#define PAGE_OFFSET           (0x80000000UL)
++
++/*
++ * ALSA uses virt_to_page() on DMA pages, which I'm not entirely sure
++ * is a good idea. Anyway, we can't simply subtract PAGE_OFFSET here
++ * in that case, so we'll have to mask out the three most significant
++ * bits of the address instead...
++ *
++ * What's the difference between __pa() and virt_to_phys() anyway?
++ */
++#define __pa(x)               PHYSADDR(x)
++#define __va(x)               ((void *)(P1SEGADDR(x)))
++
++#define MAP_NR(addr)  (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT)
++
++#define phys_to_page(phys)    (pfn_to_page(phys >> PAGE_SHIFT))
++#define page_to_phys(page)    (page_to_pfn(page) << PAGE_SHIFT)
++
++#ifndef CONFIG_NEED_MULTIPLE_NODES
++
++#define PHYS_PFN_OFFSET               (CONFIG_PHYS_OFFSET >> PAGE_SHIFT)
++
++#define pfn_to_page(pfn)      (mem_map + ((pfn) - PHYS_PFN_OFFSET))
++#define page_to_pfn(page)     ((unsigned long)((page) - mem_map) + PHYS_PFN_OFFSET)
++#define pfn_valid(pfn)                ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
++#endif /* CONFIG_NEED_MULTIPLE_NODES */
++
++#define virt_to_page(kaddr)   pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
++#define virt_addr_valid(kaddr)        pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
++
++#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE |   \
++                               VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
++
++/*
++ * Memory above this physical address will be considered highmem.
++ */
++#define HIGHMEM_START         0x20000000UL
++
++#endif /* __KERNEL__ */
++
++#endif /* __ASM_AVR32_PAGE_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/param.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/param.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,23 @@
++#ifndef __ASM_AVR32_PARAM_H
++#define __ASM_AVR32_PARAM_H
++
++#ifdef __KERNEL__
++# define HZ           CONFIG_HZ
++# define USER_HZ      100             /* User interfaces are in "ticks" */
++# define CLOCKS_PER_SEC       (USER_HZ)       /* frequency at which times() counts */
++#endif
++
++#ifndef HZ
++# define HZ           100
++#endif
++
++/* TODO: Should be configurable */
++#define EXEC_PAGESIZE 4096
++
++#ifndef NOGROUP
++# define NOGROUP      (-1)
++#endif
++
++#define MAXHOSTNAMELEN        64
++
++#endif /* __ASM_AVR32_PARAM_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/pci.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/pci.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,8 @@
++#ifndef __ASM_AVR32_PCI_H__
++#define __ASM_AVR32_PCI_H__
++
++/* We don't support PCI yet, but some drivers require this file anyway */
++
++#define PCI_DMA_BUS_IS_PHYS   (1)
++
++#endif /* __ASM_AVR32_PCI_H__ */
+Index: linux-2.6.18-avr32/include/asm-avr32/percpu.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/percpu.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_PERCPU_H
++#define __ASM_AVR32_PERCPU_H
++
++#include <asm-generic/percpu.h>
++
++#endif /* __ASM_AVR32_PERCPU_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/pgalloc.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/pgalloc.h     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,96 @@
++/*
++ * 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 __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>
++
++#define pmd_populate_kernel(mm, pmd, pte) \
++      set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
++
++static __inline__ void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
++                                  struct page *pte)
++{
++      set_pmd(pmd, __pmd(_PAGE_TABLE + page_to_phys(pte)));
++}
++
++/*
++ * Allocate and free page tables
++ */
++static __inline__ pgd_t *pgd_alloc(struct mm_struct *mm)
++{
++      unsigned int pgd_size = (USER_PTRS_PER_PGD * sizeof(pgd_t));
++      pgd_t *pgd = (pgd_t *)kmalloc(pgd_size, GFP_KERNEL);
++
++      if (pgd)
++              memset(pgd, 0, pgd_size);
++
++      return pgd;
++}
++
++static inline void pgd_free(pgd_t *pgd)
++{
++      kfree(pgd);
++}
++
++static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
++                                        unsigned long address)
++{
++      int count = 0;
++      pte_t *pte;
++
++      do {
++              pte = (pte_t *) __get_free_page(GFP_KERNEL | __GFP_REPEAT);
++              if (pte)
++                      clear_page(pte);
++              else {
++                      current->state = TASK_UNINTERRUPTIBLE;
++                      schedule_timeout(HZ);
++              }
++      } while (!pte && (count++ < 10));
++
++      return pte;
++}
++
++static inline struct page *pte_alloc_one(struct mm_struct *mm,
++                                       unsigned long address)
++{
++      int count = 0;
++      struct page *pte;
++
++      do {
++              pte = alloc_pages(GFP_KERNEL, 0);
++              if (pte)
++                      clear_page(page_address(pte));
++              else {
++                      current->state = TASK_UNINTERRUPTIBLE;
++                      schedule_timeout(HZ);
++              }
++      } while (!pte && (count++ < 10));
++
++      return pte;
++}
++
++static inline void pte_free_kernel(pte_t *pte)
++{
++      free_page((unsigned long)pte);
++}
++
++static inline void pte_free(struct page *pte)
++{
++      __free_page(pte);
++}
++
++#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
++
++#define check_pgt_cache() do { } while(0)
++
++#endif /* __ASM_AVR32_PGALLOC_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/pgtable-2level.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/pgtable-2level.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,47 @@
++/*
++ * 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 __ASM_AVR32_PGTABLE_2LEVEL_H
++#define __ASM_AVR32_PGTABLE_2LEVEL_H
++
++#include <asm-generic/pgtable-nopmd.h>
++
++/*
++ * Traditional 2-level paging structure
++ */
++#define PGDIR_SHIFT   22
++#define PTRS_PER_PGD  1024
++
++#define PTRS_PER_PTE  1024
++
++#ifndef __ASSEMBLY__
++#define pte_ERROR(e) \
++      printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e))
++#define pgd_ERROR(e) \
++      printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
++
++/*
++ * Certain architectures need to do special things when PTEs
++ * within a page table are directly modified.  Thus, the following
++ * hook is made available.
++ */
++#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
++#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep, pteval)
++
++/*
++ * (pmds are folded into pgds so this doesn't get actually called,
++ * but the define is needed for a generic inline function.)
++ */
++#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval)
++
++#define pte_pfn(x)            ((unsigned long)(((x).pte >> PAGE_SHIFT)))
++#define pfn_pte(pfn, prot)    __pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
++#define pfn_pmd(pfn, prot)    __pmd(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
++
++#endif /* !__ASSEMBLY__ */
++
++#endif /* __ASM_AVR32_PGTABLE_2LEVEL_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/pgtable.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/pgtable.h     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,408 @@
++/*
++ * 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 __ASM_AVR32_PGTABLE_H
++#define __ASM_AVR32_PGTABLE_H
++
++#include <asm/addrspace.h>
++
++#ifndef __ASSEMBLY__
++#include <linux/sched.h>
++
++#endif /* !__ASSEMBLY__ */
++
++/*
++ * Use two-level page tables just as the i386 (without PAE)
++ */
++#include <asm/pgtable-2level.h>
++
++/*
++ * The following code might need some cleanup when the values are
++ * final...
++ */
++#define PMD_SIZE      (1UL << PMD_SHIFT)
++#define PMD_MASK      (~(PMD_SIZE-1))
++#define PGDIR_SIZE    (1UL << PGDIR_SHIFT)
++#define PGDIR_MASK    (~(PGDIR_SIZE-1))
++
++#define USER_PTRS_PER_PGD     (TASK_SIZE / PGDIR_SIZE)
++#define FIRST_USER_ADDRESS    0
++
++#define PTE_PHYS_MASK 0x1ffff000
++
++#ifndef __ASSEMBLY__
++extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
++extern void paging_init(void);
++
++/*
++ * ZERO_PAGE is a global shared page that is always zero: used for
++ * zero-mapped memory areas etc.
++ */
++extern struct page *empty_zero_page;
++#define ZERO_PAGE(vaddr) (empty_zero_page)
++
++/*
++ * Just any arbitrary offset to the start of the vmalloc VM area: the
++ * current 8 MiB value just means that there will be a 8 MiB "hole"
++ * after the uncached physical memory (P2 segment) until the vmalloc
++ * area starts. That means that any out-of-bounds memory accesses will
++ * hopefully be caught; we don't know if the end of the P1/P2 segments
++ * are actually used for anything, but it is anyway safer to let the
++ * MMU catch these kinds of errors than to rely on the memory bus.
++ *
++ * A "hole" of the same size is added to the end of the P3 segment as
++ * well. It might seem wasteful to use 16 MiB of virtual address space
++ * on this, but we do have 512 MiB of it...
++ *
++ * The vmalloc() routines leave a hole of 4 KiB between each vmalloced
++ * area for the same reason.
++ */
++#define VMALLOC_OFFSET        (8 * 1024 * 1024)
++#define VMALLOC_START (P3SEG + VMALLOC_OFFSET)
++#define VMALLOC_END   (P4SEG - VMALLOC_OFFSET)
++#endif /* !__ASSEMBLY__ */
++
++/*
++ * Page flags. Some of these flags are not directly supported by
++ * hardware, so we have to emulate them.
++ */
++#define _TLBEHI_BIT_VALID     9
++#define _TLBEHI_VALID         (1 << _TLBEHI_BIT_VALID)
++
++#define _PAGE_BIT_WT          0  /* W-bit   : write-through */
++#define _PAGE_BIT_DIRTY               1  /* D-bit   : page changed */
++#define _PAGE_BIT_SZ0         2  /* SZ0-bit : Size of page */
++#define _PAGE_BIT_SZ1         3  /* SZ1-bit : Size of page */
++#define _PAGE_BIT_EXECUTE     4  /* X-bit   : execute access allowed */
++#define _PAGE_BIT_RW          5  /* AP0-bit : write access allowed */
++#define _PAGE_BIT_USER                6  /* AP1-bit : user space access allowed */
++#define _PAGE_BIT_BUFFER      7  /* B-bit   : bufferable */
++#define _PAGE_BIT_GLOBAL      8  /* G-bit   : global (ignore ASID) */
++#define _PAGE_BIT_CACHABLE    9  /* C-bit   : cachable */
++
++/* If we drop support for 1K pages, we get two extra bits */
++#define _PAGE_BIT_PRESENT     10
++#define _PAGE_BIT_ACCESSED    11 /* software: page was accessed */
++
++/* The following flags are only valid when !PRESENT */
++#define _PAGE_BIT_FILE                0 /* software: pagecache or swap? */
++
++#define _PAGE_WT              (1 << _PAGE_BIT_WT)
++#define _PAGE_DIRTY           (1 << _PAGE_BIT_DIRTY)
++#define _PAGE_EXECUTE         (1 << _PAGE_BIT_EXECUTE)
++#define _PAGE_RW              (1 << _PAGE_BIT_RW)
++#define _PAGE_USER            (1 << _PAGE_BIT_USER)
++#define _PAGE_BUFFER          (1 << _PAGE_BIT_BUFFER)
++#define _PAGE_GLOBAL          (1 << _PAGE_BIT_GLOBAL)
++#define _PAGE_CACHABLE                (1 << _PAGE_BIT_CACHABLE)
++
++/* Software flags */
++#define _PAGE_ACCESSED                (1 << _PAGE_BIT_ACCESSED)
++#define _PAGE_PRESENT         (1 << _PAGE_BIT_PRESENT)
++#define _PAGE_FILE            (1 << _PAGE_BIT_FILE)
++
++/*
++ * Page types, i.e. sizes. _PAGE_TYPE_NONE corresponds to what is
++ * usually called _PAGE_PROTNONE on other architectures.
++ *
++ * XXX: Find out if _PAGE_PROTNONE is equivalent with !_PAGE_USER. If
++ * so, we can encode all possible page sizes (although we can't really
++ * support 1K pages anyway due to the _PAGE_PRESENT and _PAGE_ACCESSED
++ * bits)
++ *
++ */
++#define _PAGE_TYPE_MASK               ((1 << _PAGE_BIT_SZ0) | (1 << _PAGE_BIT_SZ1))
++#define _PAGE_TYPE_NONE               (0 << _PAGE_BIT_SZ0)
++#define _PAGE_TYPE_SMALL      (1 << _PAGE_BIT_SZ0)
++#define _PAGE_TYPE_MEDIUM     (2 << _PAGE_BIT_SZ0)
++#define _PAGE_TYPE_LARGE      (3 << _PAGE_BIT_SZ0)
++
++/*
++ * Mask which drop software flags. We currently can't handle more than
++ * 512 MiB of physical memory, so we can use bits 29-31 for other
++ * stuff.  With a fixed 4K page size, we can use bits 10-11 as well as
++ * bits 2-3 (SZ)
++ */
++#define _PAGE_FLAGS_HARDWARE_MASK     0xfffff3ff
++
++#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)
++
++#define _PAGE_FLAGS_READ      (_PAGE_CACHABLE | _PAGE_BUFFER)
++#define _PAGE_FLAGS_WRITE     (_PAGE_FLAGS_READ | _PAGE_RW | _PAGE_DIRTY)
++
++#define _PAGE_NORMAL(x)       __pgprot((x) | _PAGE_PRESENT | _PAGE_TYPE_SMALL \
++                               | _PAGE_ACCESSED)
++
++#define PAGE_NONE     (_PAGE_ACCESSED | _PAGE_TYPE_NONE)
++#define PAGE_READ     (_PAGE_FLAGS_READ | _PAGE_USER)
++#define PAGE_EXEC     (_PAGE_FLAGS_READ | _PAGE_EXECUTE | _PAGE_USER)
++#define PAGE_WRITE    (_PAGE_FLAGS_WRITE | _PAGE_USER)
++#define PAGE_KERNEL   _PAGE_NORMAL(_PAGE_FLAGS_WRITE | _PAGE_EXECUTE | _PAGE_GLOBAL)
++#define PAGE_KERNEL_RO        _PAGE_NORMAL(_PAGE_FLAGS_READ | _PAGE_EXECUTE | _PAGE_GLOBAL)
++
++#define _PAGE_P(x)    _PAGE_NORMAL((x) & ~(_PAGE_RW | _PAGE_DIRTY))
++#define _PAGE_S(x)    _PAGE_NORMAL(x)
++
++#define PAGE_COPY     _PAGE_P(PAGE_WRITE | PAGE_READ)
++
++#ifndef __ASSEMBLY__
++/*
++ * The hardware supports flags for write- and execute access. Read is
++ * always allowed if the page is loaded into the TLB, so the "-w-",
++ * "--x" and "-wx" mappings are implemented as "rw-", "r-x" and "rwx",
++ * respectively.
++ *
++ * The "---" case is handled by software; the page will simply not be
++ * loaded into the TLB if the page type is _PAGE_TYPE_NONE.
++ */
++
++#define __P000        __pgprot(PAGE_NONE)
++#define __P001        _PAGE_P(PAGE_READ)
++#define __P010        _PAGE_P(PAGE_WRITE)
++#define __P011        _PAGE_P(PAGE_WRITE | PAGE_READ)
++#define __P100        _PAGE_P(PAGE_EXEC)
++#define __P101        _PAGE_P(PAGE_EXEC | PAGE_READ)
++#define __P110        _PAGE_P(PAGE_EXEC | PAGE_WRITE)
++#define __P111        _PAGE_P(PAGE_EXEC | PAGE_WRITE | PAGE_READ)
++
++#define __S000        __pgprot(PAGE_NONE)
++#define __S001        _PAGE_S(PAGE_READ)
++#define __S010        _PAGE_S(PAGE_WRITE)
++#define __S011        _PAGE_S(PAGE_WRITE | PAGE_READ)
++#define __S100        _PAGE_S(PAGE_EXEC)
++#define __S101        _PAGE_S(PAGE_EXEC | PAGE_READ)
++#define __S110        _PAGE_S(PAGE_EXEC | PAGE_WRITE)
++#define __S111        _PAGE_S(PAGE_EXEC | PAGE_WRITE | PAGE_READ)
++
++#define pte_none(x)   (!pte_val(x))
++#define pte_present(x)        (pte_val(x) & _PAGE_PRESENT)
++
++#define pte_clear(mm,addr,xp)                                 \
++      do {                                                    \
++              set_pte_at(mm, addr, xp, __pte(0));             \
++      } while (0)
++
++/*
++ * The following only work if pte_present() is true.
++ * Undefined behaviour if not..
++ */
++static inline int pte_read(pte_t pte)
++{
++      return pte_val(pte) & _PAGE_USER;
++}
++static inline int pte_write(pte_t pte)
++{
++      return pte_val(pte) & _PAGE_RW;
++}
++static inline int pte_exec(pte_t pte)
++{
++      return pte_val(pte) & _PAGE_EXECUTE;
++}
++static inline int pte_dirty(pte_t pte)
++{
++      return pte_val(pte) & _PAGE_DIRTY;
++}
++static inline int pte_young(pte_t pte)
++{
++      return pte_val(pte) & _PAGE_ACCESSED;
++}
++
++/*
++ * The following only work if pte_present() is not true.
++ */
++static inline int pte_file(pte_t pte)
++{
++      return pte_val(pte) & _PAGE_FILE;
++}
++
++/* Mutator functions for PTE bits */
++static inline pte_t pte_rdprotect(pte_t pte)
++{
++      set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
++      return pte;
++}
++static inline pte_t pte_wrprotect(pte_t pte)
++{
++      set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW));
++      return pte;
++}
++static inline pte_t pte_exprotect(pte_t pte)
++{
++      set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_EXECUTE));
++      return pte;
++}
++static inline pte_t pte_mkclean(pte_t pte)
++{
++      set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY));
++      return pte;
++}
++static inline pte_t pte_mkold(pte_t pte)
++{
++      set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED));
++      return pte;
++}
++static inline pte_t pte_mkread(pte_t pte)
++{
++      set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
++      return pte;
++}
++static inline pte_t pte_mkwrite(pte_t pte)
++{
++      set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW));
++      return pte;
++}
++static inline pte_t pte_mkexec(pte_t pte)
++{
++      set_pte(&pte, __pte(pte_val(pte) | _PAGE_EXECUTE));
++      return pte;
++}
++static inline pte_t pte_mkdirty(pte_t pte)
++{
++      set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY));
++      return pte;
++}
++static inline pte_t pte_mkyoung(pte_t pte)
++{
++      set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED));
++      return pte;
++}
++
++#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)
++
++/*
++ * Permanent address of a page. We don't support highmem, so this is
++ * trivial.
++ */
++#define pages_to_mb(x)        ((x) >> (20-PAGE_SHIFT))
++#define pte_page(x)   phys_to_page(pte_val(x) & PTE_PHYS_MASK)
++
++/*
++ * Mark the prot value as uncacheable and unbufferable
++ */
++#define pgprot_noncached(prot)                                                \
++      __pgprot(pgprot_val(prot) & ~(_PAGE_BUFFER | _PAGE_CACHABLE))
++
++/*
++ * Mark the prot value as uncacheable but bufferable
++ */
++#define pgprot_writecombine(prot)                                     \
++      __pgprot((pgprot_val(prot) & ~_PAGE_CACHABLE) | _PAGE_BUFFER)
++
++/*
++ * Conversion functions: convert a page and protection to a page entry,
++ * and a page entry and page directory to the page they refer to.
++ *
++ * extern pte_t mk_pte(struct page *page, pgprot_t pgprot)
++ */
++#define mk_pte(page, pgprot)  pfn_pte(page_to_pfn(page), (pgprot))
++
++static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
++{
++      set_pte(&pte, __pte((pte_val(pte) & _PAGE_CHG_MASK)
++                          | pgprot_val(newprot)));
++      return pte;
++}
++
++#define page_pte(page)        page_pte_prot(page, __pgprot(0))
++
++#define pmd_page_kernel(pmd)                                  \
++      ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
++
++#define pmd_page(pmd) (phys_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))
++
++/* to find an entry in a kernel page-table-directory */
++#define pgd_offset_k(address) pgd_offset(&init_mm, address)
++
++/* Find an entry in the third-level page table.. */
++#define pte_index(address)                            \
++      ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
++#define pte_offset(dir, address)                                      \
++      ((pte_t *) pmd_page_kernel(*(dir)) + pte_index(address))
++#define pte_offset_kernel(dir, address)                                       \
++      ((pte_t *) pmd_page_kernel(*(dir)) + pte_index(address))
++#define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
++#define pte_offset_map_nested(dir, address) pte_offset_kernel(dir, address)
++#define pte_unmap(pte)                do { } while (0)
++#define pte_unmap_nested(pte) do { } while (0)
++
++struct vm_area_struct;
++extern void update_mmu_cache(struct vm_area_struct * vma,
++                           unsigned long address, pte_t pte);
++
++/*
++ * Encode and decode a swap entry
++ *
++ * Constraints:
++ *   _PAGE_FILE at bit 0
++ *   _PAGE_TYPE_* at bits 2-3 (for emulating _PAGE_PROTNONE)
++ *   _PAGE_PRESENT at bit 10
++ *
++ * We encode the type into bits 4-9 and offset into bits 11-31. This
++ * gives us a 21 bits offset, or 2**21 * 4K = 8G usable swap space per
++ * device, and 64 possible types.
++ *
++ * NOTE: We should set ZEROs at the position of _PAGE_PRESENT
++ *       and _PAGE_PROTNONE bits
++ */
++#define __swp_type(x)         (((x).val >> 4) & 0x3f)
++#define __swp_offset(x)               ((x).val >> 11)
++#define __swp_entry(type, offset) ((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
++#define __pte_to_swp_entry(pte)       ((swp_entry_t) { pte_val(pte) })
++#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
++
++/*
++ * Encode and decode a nonlinear file mapping entry. We have to
++ * preserve _PAGE_FILE and _PAGE_PRESENT here. _PAGE_TYPE_* isn't
++ * necessary, since _PAGE_FILE implies !_PAGE_PROTNONE (?)
++ */
++#define PTE_FILE_MAX_BITS     30
++#define pte_to_pgoff(pte)     (((pte_val(pte) >> 1) & 0x1ff)          \
++                               | ((pte_val(pte) >> 11) << 9))
++#define pgoff_to_pte(off)     ((pte_t) { ((((off) & 0x1ff) << 1)      \
++                                          | (((off) >> 9) << 11)      \
++                                          | _PAGE_FILE) })
++
++typedef pte_t *pte_addr_t;
++
++#define kern_addr_valid(addr) (1)
++
++#define io_remap_pfn_range(vma, vaddr, pfn, size, prot)       \
++      remap_pfn_range(vma, vaddr, pfn, size, prot)
++
++#define MK_IOSPACE_PFN(space, pfn)    (pfn)
++#define GET_IOSPACE(pfn)              0
++#define GET_PFN(pfn)                  (pfn)
++
++/* No page table caches to initialize (?) */
++#define pgtable_cache_init()  do { } while(0)
++
++#include <asm-generic/pgtable.h>
++
++#endif /* !__ASSEMBLY__ */
++
++#endif /* __ASM_AVR32_PGTABLE_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/poll.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/poll.h        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,27 @@
++#ifndef __ASM_AVR32_POLL_H
++#define __ASM_AVR32_POLL_H
++
++/* These are specified by iBCS2 */
++#define POLLIN                0x0001
++#define POLLPRI               0x0002
++#define POLLOUT               0x0004
++#define POLLERR               0x0008
++#define POLLHUP               0x0010
++#define POLLNVAL      0x0020
++
++/* The rest seem to be more-or-less nonstandard. Check them! */
++#define POLLRDNORM    0x0040
++#define POLLRDBAND    0x0080
++#define POLLWRNORM    0x0100
++#define POLLWRBAND    0x0200
++#define POLLMSG               0x0400
++#define POLLREMOVE    0x1000
++#define POLLRDHUP     0x2000
++
++struct pollfd {
++      int fd;
++      short events;
++      short revents;
++};
++
++#endif /* __ASM_AVR32_POLL_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/posix_types.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/posix_types.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,129 @@
++/*
++ * 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 __ASM_AVR32_POSIX_TYPES_H
++#define __ASM_AVR32_POSIX_TYPES_H
++
++/*
++ * This file is generally used by user-level software, so you need to
++ * be a little careful about namespace pollution etc.  Also, we cannot
++ * assume GCC is being used.
++ */
++
++typedef unsigned long   __kernel_ino_t;
++typedef unsigned short  __kernel_mode_t;
++typedef unsigned short  __kernel_nlink_t;
++typedef long            __kernel_off_t;
++typedef int             __kernel_pid_t;
++typedef unsigned short  __kernel_ipc_pid_t;
++typedef unsigned int  __kernel_uid_t;
++typedef unsigned int  __kernel_gid_t;
++typedef unsigned long __kernel_size_t;
++typedef int             __kernel_ssize_t;
++typedef int             __kernel_ptrdiff_t;
++typedef long            __kernel_time_t;
++typedef long            __kernel_suseconds_t;
++typedef long            __kernel_clock_t;
++typedef int             __kernel_timer_t;
++typedef int             __kernel_clockid_t;
++typedef int             __kernel_daddr_t;
++typedef char *          __kernel_caddr_t;
++typedef unsigned short  __kernel_uid16_t;
++typedef unsigned short  __kernel_gid16_t;
++typedef unsigned int    __kernel_uid32_t;
++typedef unsigned int    __kernel_gid32_t;
++
++typedef unsigned short  __kernel_old_uid_t;
++typedef unsigned short  __kernel_old_gid_t;
++typedef unsigned short  __kernel_old_dev_t;
++
++#ifdef __GNUC__
++typedef long long       __kernel_loff_t;
++#endif
++
++typedef struct {
++#if defined(__KERNEL__) || defined(__USE_ALL)
++    int     val[2];
++#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
++    int     __val[2];
++#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
++} __kernel_fsid_t;
++
++#if defined(__KERNEL__)
++
++#undef  __FD_SET
++static __inline__ void __FD_SET(unsigned long __fd, __kernel_fd_set *__fdsetp)
++{
++    unsigned long __tmp = __fd / __NFDBITS;
++    unsigned long __rem = __fd % __NFDBITS;
++    __fdsetp->fds_bits[__tmp] |= (1UL<<__rem);
++}
++
++#undef  __FD_CLR
++static __inline__ void __FD_CLR(unsigned long __fd, __kernel_fd_set *__fdsetp)
++{
++    unsigned long __tmp = __fd / __NFDBITS;
++    unsigned long __rem = __fd % __NFDBITS;
++    __fdsetp->fds_bits[__tmp] &= ~(1UL<<__rem);
++}
++
++
++#undef  __FD_ISSET
++static __inline__ int __FD_ISSET(unsigned long __fd, const __kernel_fd_set *__p)
++{
++    unsigned long __tmp = __fd / __NFDBITS;
++    unsigned long __rem = __fd % __NFDBITS;
++    return (__p->fds_bits[__tmp] & (1UL<<__rem)) != 0;
++}
++
++/*
++ * This will unroll the loop for the normal constant case (8 ints,
++ * for a 256-bit fd_set)
++ */
++#undef  __FD_ZERO
++static __inline__ void __FD_ZERO(__kernel_fd_set *__p)
++{
++    unsigned long *__tmp = __p->fds_bits;
++    int __i;
++
++    if (__builtin_constant_p(__FDSET_LONGS)) {
++        switch (__FDSET_LONGS) {
++            case 16:
++                __tmp[ 0] = 0; __tmp[ 1] = 0;
++                __tmp[ 2] = 0; __tmp[ 3] = 0;
++                __tmp[ 4] = 0; __tmp[ 5] = 0;
++                __tmp[ 6] = 0; __tmp[ 7] = 0;
++                __tmp[ 8] = 0; __tmp[ 9] = 0;
++                __tmp[10] = 0; __tmp[11] = 0;
++                __tmp[12] = 0; __tmp[13] = 0;
++                __tmp[14] = 0; __tmp[15] = 0;
++                return;
++
++            case 8:
++                __tmp[ 0] = 0; __tmp[ 1] = 0;
++                __tmp[ 2] = 0; __tmp[ 3] = 0;
++                __tmp[ 4] = 0; __tmp[ 5] = 0;
++                __tmp[ 6] = 0; __tmp[ 7] = 0;
++                return;
++
++            case 4:
++                __tmp[ 0] = 0; __tmp[ 1] = 0;
++                __tmp[ 2] = 0; __tmp[ 3] = 0;
++                return;
++        }
++    }
++    __i = __FDSET_LONGS;
++    while (__i) {
++        __i--;
++        *__tmp = 0;
++        __tmp++;
++    }
++}
++
++#endif /* defined(__KERNEL__) */
++
++#endif /* __ASM_AVR32_POSIX_TYPES_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/processor.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/processor.h   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,147 @@
++/*
++ * 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 __ASM_AVR32_PROCESSOR_H
++#define __ASM_AVR32_PROCESSOR_H
++
++#include <asm/page.h>
++#include <asm/cache.h>
++
++#define TASK_SIZE     0x80000000
++
++#ifndef __ASSEMBLY__
++
++static inline void *current_text_addr(void)
++{
++      register void *pc asm("pc");
++      return pc;
++}
++
++enum arch_type {
++      ARCH_AVR32A,
++      ARCH_AVR32B,
++      ARCH_MAX
++};
++
++enum cpu_type {
++      CPU_MORGAN,
++      CPU_AT32AP,
++      CPU_MAX
++};
++
++enum tlb_config {
++      TLB_NONE,
++      TLB_SPLIT,
++      TLB_UNIFIED,
++      TLB_INVALID
++};
++
++struct avr32_cpuinfo {
++      struct clk *clk;
++      unsigned long loops_per_jiffy;
++      enum arch_type arch_type;
++      enum cpu_type cpu_type;
++      unsigned short arch_revision;
++      unsigned short cpu_revision;
++      enum tlb_config tlb_config;
++
++      struct cache_info icache;
++      struct cache_info dcache;
++};
++
++extern struct avr32_cpuinfo boot_cpu_data;
++
++#ifdef CONFIG_SMP
++extern struct avr32_cpuinfo cpu_data[];
++#define current_cpu_data cpu_data[smp_processor_id()]
++#else
++#define cpu_data (&boot_cpu_data)
++#define current_cpu_data boot_cpu_data
++#endif
++
++/* This decides where the kernel will search for a free chunk of vm
++ * space during mmap's
++ */
++#define TASK_UNMAPPED_BASE    (PAGE_ALIGN(TASK_SIZE / 3))
++
++#define cpu_relax()           barrier()
++#define cpu_sync_pipeline()   asm volatile("sub pc, -2" : : : "memory")
++
++struct cpu_context {
++      unsigned long sr;
++      unsigned long pc;
++      unsigned long ksp;      /* Kernel stack pointer */
++      unsigned long r7;
++      unsigned long r6;
++      unsigned long r5;
++      unsigned long r4;
++      unsigned long r3;
++      unsigned long r2;
++      unsigned long r1;
++      unsigned long r0;
++};
++
++/* This struct contains the CPU context as stored by switch_to() */
++struct thread_struct {
++      struct cpu_context cpu_context;
++      unsigned long single_step_addr;
++      u16 single_step_insn;
++};
++
++#define INIT_THREAD {                                         \
++      .cpu_context = {                                        \
++              .ksp = sizeof(init_stack) + (long)&init_stack,  \
++      },                                                      \
++}
++
++/*
++ * Do necessary setup to start up a newly executed thread.
++ */
++#define start_thread(regs, new_pc, new_sp)     \
++      do {                                     \
++              set_fs(USER_DS);                 \
++              memset(regs, 0, sizeof(*regs));  \
++              regs->sr = MODE_USER;            \
++              regs->pc = new_pc & ~1;          \
++              regs->sp = new_sp;               \
++      } while(0)
++
++struct task_struct;
++
++/* Free all resources held by a thread */
++extern void release_thread(struct task_struct *);
++
++/* Create a kernel thread without removing it from tasklists */
++extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
++
++/* Prepare to copy thread state - unlazy all lazy status */
++#define prepare_to_copy(tsk) do { } while(0)
++
++/* Return saved PC of a blocked thread */
++#define thread_saved_pc(tsk)    ((tsk)->thread.cpu_context.pc)
++
++struct pt_regs;
++void show_trace(struct task_struct *task, unsigned long *stack,
++              struct pt_regs *regs);
++
++extern unsigned long get_wchan(struct task_struct *p);
++
++#define KSTK_EIP(tsk) ((tsk)->thread.cpu_context.pc)
++#define KSTK_ESP(tsk) ((tsk)->thread.cpu_context.ksp)
++
++#define ARCH_HAS_PREFETCH
++
++static inline void prefetch(const void *x)
++{
++      const char *c = x;
++      asm volatile("pref %0" : : "r"(c));
++}
++#define PREFETCH_STRIDE       L1_CACHE_BYTES
++
++#endif /* __ASSEMBLY__ */
++
++#endif /* __ASM_AVR32_PROCESSOR_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/ptrace.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/ptrace.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,154 @@
++/*
++ * 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 __ASM_AVR32_PTRACE_H
++#define __ASM_AVR32_PTRACE_H
++
++#define PTRACE_GETREGS                12
++#define PTRACE_SETREGS                13
++
++/*
++ * Status Register bits
++ */
++#define SR_H          0x40000000
++#define SR_R          0x20000000
++#define SR_J          0x10000000
++#define SR_DM         0x08000000
++#define SR_D          0x04000000
++#define MODE_NMI      0x01c00000
++#define MODE_EXCEPTION        0x01800000
++#define MODE_INT3     0x01400000
++#define MODE_INT2     0x01000000
++#define MODE_INT1     0x00c00000
++#define MODE_INT0     0x00800000
++#define MODE_SUPERVISOR       0x00400000
++#define MODE_USER     0x00000000
++#define MODE_MASK     0x01c00000
++#define SR_EM         0x00200000
++#define SR_I3M                0x00100000
++#define SR_I2M                0x00080000
++#define SR_I1M                0x00040000
++#define SR_I0M                0x00020000
++#define SR_GM         0x00010000
++
++#define SR_H_BIT      30
++#define SR_R_BIT      29
++#define SR_J_BIT      28
++#define SR_DM_BIT     27
++#define SR_D_BIT      26
++#define MODE_SHIFT    22
++#define SR_EM_BIT     21
++#define SR_I3M_BIT    20
++#define SR_I2M_BIT    19
++#define SR_I1M_BIT    18
++#define SR_I0M_BIT    17
++#define SR_GM_BIT     16
++
++/* The user-visible part */
++#define SR_L          0x00000020
++#define SR_Q          0x00000010
++#define SR_V          0x00000008
++#define SR_N          0x00000004
++#define SR_Z          0x00000002
++#define SR_C          0x00000001
++
++#define SR_L_BIT      5
++#define SR_Q_BIT      4
++#define SR_V_BIT      3
++#define SR_N_BIT      2
++#define SR_Z_BIT      1
++#define SR_C_BIT      0
++
++/*
++ * The order is defined by the stmts instruction. r0 is stored first,
++ * so it gets the highest address.
++ *
++ * Registers 0-12 are general-purpose registers (r12 is normally used for
++ * the function return value).
++ * Register 13 is the stack pointer
++ * Register 14 is the link register
++ * Register 15 is the program counter (retrieved from the RAR sysreg)
++ */
++#define FRAME_SIZE_FULL 72
++#define REG_R12_ORIG  68
++#define REG_R0                64
++#define REG_R1                60
++#define REG_R2                56
++#define REG_R3                52
++#define REG_R4                48
++#define REG_R5                44
++#define REG_R6                40
++#define REG_R7                36
++#define REG_R8                32
++#define REG_R9                28
++#define REG_R10               24
++#define REG_R11               20
++#define REG_R12               16
++#define REG_SP                12
++#define REG_LR                 8
++
++#define FRAME_SIZE_MIN         8
++#define REG_PC                 4
++#define REG_SR                 0
++
++#ifndef __ASSEMBLY__
++struct pt_regs {
++      /* These are always saved */
++      unsigned long sr;
++      unsigned long pc;
++
++      /* These are sometimes saved */
++      unsigned long lr;
++      unsigned long sp;
++      unsigned long r12;
++      unsigned long r11;
++      unsigned long r10;
++      unsigned long r9;
++      unsigned long r8;
++      unsigned long r7;
++      unsigned long r6;
++      unsigned long r5;
++      unsigned long r4;
++      unsigned long r3;
++      unsigned long r2;
++      unsigned long r1;
++      unsigned long r0;
++
++      /* Only saved on system call */
++      unsigned long r12_orig;
++};
++
++#ifdef __KERNEL__
++# define user_mode(regs) (((regs)->sr & MODE_MASK) == MODE_USER)
++extern void show_regs (struct pt_regs *);
++
++static __inline__ int valid_user_regs(struct pt_regs *regs)
++{
++      /*
++       * Some of the Java bits might be acceptable if/when we
++       * implement some support for that stuff...
++       */
++      if ((regs->sr & 0xffff0000) == 0)
++              return 1;
++
++      /*
++       * Force status register flags to be sane and report this
++       * illegal behaviour...
++       */
++      regs->sr &= 0x0000ffff;
++      return 0;
++}
++
++#define instruction_pointer(regs) ((regs)->pc)
++
++#define profile_pc(regs) instruction_pointer(regs)
++
++#endif /* __KERNEL__ */
++
++#endif /* ! __ASSEMBLY__ */
++
++#endif /* __ASM_AVR32_PTRACE_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/resource.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/resource.h    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_RESOURCE_H
++#define __ASM_AVR32_RESOURCE_H
++
++#include <asm-generic/resource.h>
++
++#endif /* __ASM_AVR32_RESOURCE_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/scatterlist.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/scatterlist.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,21 @@
++#ifndef __ASM_AVR32_SCATTERLIST_H
++#define __ASM_AVR32_SCATTERLIST_H
++
++struct scatterlist {
++    struct page               *page;
++    unsigned int      offset;
++    dma_addr_t                dma_address;
++    unsigned int      length;
++};
++
++/* These macros should be used after a pci_map_sg call has been done
++ * to get bus addresses of each of the SG entries and their lengths.
++ * You should only work with the number of sg entries pci_map_sg
++ * returns.
++ */
++#define sg_dma_address(sg)    ((sg)->dma_address)
++#define sg_dma_len(sg)                ((sg)->length)
++
++#define ISA_DMA_THRESHOLD (0xffffffff)
++
++#endif /* __ASM_AVR32_SCATTERLIST_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/sections.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/sections.h    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_SECTIONS_H
++#define __ASM_AVR32_SECTIONS_H
++
++#include <asm-generic/sections.h>
++
++#endif /* __ASM_AVR32_SECTIONS_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/semaphore.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/semaphore.h   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,109 @@
++/*
++ * SMP- and interrupt-safe semaphores.
++ *
++ * Copyright (C) 2006 Atmel Corporation
++ *
++ * Based on include/asm-i386/semaphore.h
++ *   Copyright (C) 1996 Linus Torvalds
++ *
++ * 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_SEMAPHORE_H
++#define __ASM_AVR32_SEMAPHORE_H
++
++#include <linux/linkage.h>
++
++#include <asm/system.h>
++#include <asm/atomic.h>
++#include <linux/wait.h>
++#include <linux/rwsem.h>
++
++struct semaphore {
++      atomic_t count;
++      int sleepers;
++      wait_queue_head_t wait;
++};
++
++#define __SEMAPHORE_INITIALIZER(name, n)                              \
++{                                                                     \
++      .count          = ATOMIC_INIT(n),                               \
++      .wait           = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait)    \
++}
++
++#define __DECLARE_SEMAPHORE_GENERIC(name,count) \
++      struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
++
++#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
++#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
++
++static inline void sema_init (struct semaphore *sem, int val)
++{
++      atomic_set(&sem->count, val);
++      sem->sleepers = 0;
++      init_waitqueue_head(&sem->wait);
++}
++
++static inline void init_MUTEX (struct semaphore *sem)
++{
++      sema_init(sem, 1);
++}
++
++static inline void init_MUTEX_LOCKED (struct semaphore *sem)
++{
++      sema_init(sem, 0);
++}
++
++void __down(struct semaphore * sem);
++int  __down_interruptible(struct semaphore * sem);
++void __up(struct semaphore * sem);
++
++/*
++ * This is ugly, but we want the default case to fall through.
++ * "__down_failed" is a special asm handler that calls the C
++ * routine that actually waits. See arch/i386/kernel/semaphore.c
++ */
++static inline void down(struct semaphore * sem)
++{
++      might_sleep();
++      if (unlikely(atomic_dec_return (&sem->count) < 0))
++              __down (sem);
++}
++
++/*
++ * Interruptible try to acquire a semaphore.  If we obtained
++ * it, return zero.  If we were interrupted, returns -EINTR
++ */
++static inline int down_interruptible(struct semaphore * sem)
++{
++      int ret = 0;
++
++      might_sleep();
++      if (unlikely(atomic_dec_return (&sem->count) < 0))
++              ret = __down_interruptible (sem);
++      return ret;
++}
++
++/*
++ * Non-blockingly attempt to down() a semaphore.
++ * Returns zero if we acquired it
++ */
++static inline int down_trylock(struct semaphore * sem)
++{
++      return atomic_dec_if_positive(&sem->count) < 0;
++}
++
++/*
++ * Note! This is subtle. We jump to wake people up only if
++ * the semaphore was negative (== somebody was waiting on it).
++ * The default case (no contention) will result in NO
++ * jumps for both down() and up().
++ */
++static inline void up(struct semaphore * sem)
++{
++      if (unlikely(atomic_inc_return (&sem->count) <= 0))
++              __up (sem);
++}
++
++#endif /*__ASM_AVR32_SEMAPHORE_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/sembuf.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/sembuf.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,25 @@
++#ifndef __ASM_AVR32_SEMBUF_H
++#define __ASM_AVR32_SEMBUF_H
++
++/*
++* The semid64_ds structure for AVR32 architecture.
++ * Note extra padding because this structure is passed back and forth
++ * between kernel and user space.
++ *
++ * Pad space is left for:
++ * - 64-bit time_t to solve y2038 problem
++ * - 2 miscellaneous 32-bit values
++ */
++
++struct semid64_ds {
++        struct ipc64_perm sem_perm;             /* permissions .. see ipc.h */
++        __kernel_time_t sem_otime;              /* last semop time */
++        unsigned long   __unused1;
++        __kernel_time_t sem_ctime;              /* last change time */
++        unsigned long   __unused2;
++        unsigned long   sem_nsems;              /* no. of semaphores in array */
++        unsigned long   __unused3;
++        unsigned long   __unused4;
++};
++
++#endif /* __ASM_AVR32_SEMBUF_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/setup.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/setup.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,141 @@
++/*
++ * Copyright (C) 2004-2006 Atmel Corporation
++ *
++ * Based on linux/include/asm-arm/setup.h
++ *   Copyright (C) 1997-1999 Russel King
++ *
++ * 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_SETUP_H__
++#define __ASM_AVR32_SETUP_H__
++
++#define COMMAND_LINE_SIZE 256
++
++/* Magic number indicating that a tag table is present */
++#define ATAG_MAGIC    0xa2a25441
++
++#ifndef __ASSEMBLY__
++
++/*
++ * Generic memory range, used by several tags.
++ *
++ *   addr is always physical.
++ *   size is measured in bytes.
++ *   next is for use by the OS, e.g. for grouping regions into
++ *        linked lists.
++ */
++struct tag_mem_range {
++      u32                     addr;
++      u32                     size;
++      struct tag_mem_range *  next;
++};
++
++/* The list ends with an ATAG_NONE node. */
++#define ATAG_NONE     0x00000000
++
++struct tag_header {
++      u32 size;
++      u32 tag;
++};
++
++/* The list must start with an ATAG_CORE node */
++#define ATAG_CORE     0x54410001
++
++struct tag_core {
++      u32 flags;
++      u32 pagesize;
++      u32 rootdev;
++};
++
++/* it is allowed to have multiple ATAG_MEM nodes */
++#define ATAG_MEM      0x54410002
++/* ATAG_MEM uses tag_mem_range */
++
++/* command line: \0 terminated string */
++#define ATAG_CMDLINE  0x54410003
++
++struct tag_cmdline {
++      char    cmdline[1];     /* this is the minimum size */
++};
++
++/* Ramdisk image (may be compressed) */
++#define ATAG_RDIMG    0x54410004
++/* ATAG_RDIMG uses tag_mem_range */
++
++/* Information about various clocks present in the system */
++#define ATAG_CLOCK    0x54410005
++
++struct tag_clock {
++      u32     clock_id;       /* Which clock are we talking about? */
++      u32     clock_flags;    /* Special features */
++      u64     clock_hz;       /* Clock speed in Hz */
++};
++
++/* The clock types we know about */
++#define CLOCK_BOOTCPU 0
++
++/* Memory reserved for the system (e.g. the bootloader) */
++#define ATAG_RSVD_MEM 0x54410006
++/* ATAG_RSVD_MEM uses tag_mem_range */
++
++/* Ethernet information */
++
++#define ATAG_ETHERNET 0x54410007
++
++struct tag_ethernet {
++      u8      mac_index;
++      u8      mii_phy_addr;
++      u8      hw_address[6];
++};
++
++#define ETH_INVALID_PHY       0xff
++
++struct tag {
++      struct tag_header hdr;
++      union {
++              struct tag_core core;
++              struct tag_mem_range mem_range;
++              struct tag_cmdline cmdline;
++              struct tag_clock clock;
++              struct tag_ethernet ethernet;
++      } u;
++};
++
++struct tagtable {
++      u32     tag;
++      int     (*parse)(struct tag *);
++};
++
++#define __tag __attribute_used__ __attribute__((__section__(".taglist")))
++#define __tagtable(tag, fn)                                           \
++      static struct tagtable __tagtable_##fn __tag = { tag, fn }
++
++#define tag_member_present(tag,member)                                        \
++      ((unsigned long)(&((struct tag *)0L)->member + 1)               \
++       <= (tag)->hdr.size * 4)
++
++#define tag_next(t)   ((struct tag *)((u32 *)(t) + (t)->hdr.size))
++#define tag_size(type)        ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
++
++#define for_each_tag(t,base)                                          \
++      for (t = base; t->hdr.size; t = tag_next(t))
++
++extern struct tag_mem_range *mem_phys;
++extern struct tag_mem_range *mem_reserved;
++extern struct tag_mem_range *mem_ramdisk;
++
++extern struct tag *bootloader_tags;
++
++extern void setup_bootmem(void);
++extern void setup_processor(void);
++extern void board_setup_fbmem(unsigned long fbmem_start,
++                            unsigned long fbmem_size);
++
++/* Chip-specific hook to enable the use of SDRAM */
++void chip_enable_sdram(void);
++
++#endif /* !__ASSEMBLY__ */
++
++#endif /* __ASM_AVR32_SETUP_H__ */
+Index: linux-2.6.18-avr32/include/asm-avr32/shmbuf.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/shmbuf.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,42 @@
++#ifndef __ASM_AVR32_SHMBUF_H
++#define __ASM_AVR32_SHMBUF_H
++
++/*
++ * The shmid64_ds structure for i386 architecture.
++ * Note extra padding because this structure is passed back and forth
++ * between kernel and user space.
++ *
++ * Pad space is left for:
++ * - 64-bit time_t to solve y2038 problem
++ * - 2 miscellaneous 32-bit values
++ */
++
++struct shmid64_ds {
++      struct ipc64_perm       shm_perm;       /* operation perms */
++      size_t                  shm_segsz;      /* size of segment (bytes) */
++      __kernel_time_t         shm_atime;      /* last attach time */
++      unsigned long           __unused1;
++      __kernel_time_t         shm_dtime;      /* last detach time */
++      unsigned long           __unused2;
++      __kernel_time_t         shm_ctime;      /* last change time */
++      unsigned long           __unused3;
++      __kernel_pid_t          shm_cpid;       /* pid of creator */
++      __kernel_pid_t          shm_lpid;       /* pid of last operator */
++      unsigned long           shm_nattch;     /* no. of current attaches */
++      unsigned long           __unused4;
++      unsigned long           __unused5;
++};
++
++struct shminfo64 {
++      unsigned long   shmmax;
++      unsigned long   shmmin;
++      unsigned long   shmmni;
++      unsigned long   shmseg;
++      unsigned long   shmall;
++      unsigned long   __unused1;
++      unsigned long   __unused2;
++      unsigned long   __unused3;
++      unsigned long   __unused4;
++};
++
++#endif /* __ASM_AVR32_SHMBUF_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/shmparam.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/shmparam.h    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_SHMPARAM_H
++#define __ASM_AVR32_SHMPARAM_H
++
++#define SHMLBA PAGE_SIZE      /* attach addr a multiple of this */
++
++#endif /* __ASM_AVR32_SHMPARAM_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/sigcontext.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/sigcontext.h  2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,34 @@
++/*
++ * 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 __ASM_AVR32_SIGCONTEXT_H
++#define __ASM_AVR32_SIGCONTEXT_H
++
++struct sigcontext {
++      unsigned long   oldmask;
++
++      /* CPU registers */
++      unsigned long   sr;
++      unsigned long   pc;
++      unsigned long   lr;
++      unsigned long   sp;
++      unsigned long   r12;
++      unsigned long   r11;
++      unsigned long   r10;
++      unsigned long   r9;
++      unsigned long   r8;
++      unsigned long   r7;
++      unsigned long   r6;
++      unsigned long   r5;
++      unsigned long   r4;
++      unsigned long   r3;
++      unsigned long   r2;
++      unsigned long   r1;
++      unsigned long   r0;
++};
++
++#endif /* __ASM_AVR32_SIGCONTEXT_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/siginfo.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/siginfo.h     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef _AVR32_SIGINFO_H
++#define _AVR32_SIGINFO_H
++
++#include <asm-generic/siginfo.h>
++
++#endif
+Index: linux-2.6.18-avr32/include/asm-avr32/signal.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/signal.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,168 @@
++/*
++ * 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 __ASM_AVR32_SIGNAL_H
++#define __ASM_AVR32_SIGNAL_H
++
++#include <linux/types.h>
++
++/* Avoid too many header ordering problems.  */
++struct siginfo;
++
++#ifdef __KERNEL__
++/* Most things should be clean enough to redefine this at will, if care
++   is taken to make libc match.  */
++
++#define _NSIG         64
++#define _NSIG_BPW     32
++#define _NSIG_WORDS   (_NSIG / _NSIG_BPW)
++
++typedef unsigned long old_sigset_t;           /* at least 32 bits */
++
++typedef struct {
++      unsigned long sig[_NSIG_WORDS];
++} sigset_t;
++
++#else
++/* Here we must cater to libcs that poke about in kernel headers.  */
++
++#define NSIG          32
++typedef unsigned long sigset_t;
++
++#endif /* __KERNEL__ */
++
++#define SIGHUP                 1
++#define SIGINT                 2
++#define SIGQUIT                3
++#define SIGILL                 4
++#define SIGTRAP                5
++#define SIGABRT                6
++#define SIGIOT                 6
++#define SIGBUS                 7
++#define SIGFPE                 8
++#define SIGKILL                9
++#define SIGUSR1               10
++#define SIGSEGV               11
++#define SIGUSR2               12
++#define SIGPIPE               13
++#define SIGALRM               14
++#define SIGTERM               15
++#define SIGSTKFLT     16
++#define SIGCHLD               17
++#define SIGCONT               18
++#define SIGSTOP               19
++#define SIGTSTP               20
++#define SIGTTIN               21
++#define SIGTTOU               22
++#define SIGURG                23
++#define SIGXCPU               24
++#define SIGXFSZ               25
++#define SIGVTALRM     26
++#define SIGPROF               27
++#define SIGWINCH      28
++#define SIGIO         29
++#define SIGPOLL               SIGIO
++/*
++#define SIGLOST               29
++*/
++#define SIGPWR                30
++#define SIGSYS                31
++#define       SIGUNUSED       31
++
++/* These should not be considered constants from userland.  */
++#define SIGRTMIN      32
++#define SIGRTMAX      (_NSIG-1)
++
++/*
++ * SA_FLAGS values:
++ *
++ * SA_NOCLDSTOP               flag to turn off SIGCHLD when children stop.
++ * SA_NOCLDWAIT               flag on SIGCHLD to inhibit zombies.
++ * SA_SIGINFO         deliver the signal with SIGINFO structs
++ * SA_ONSTACK         indicates that a registered stack_t will be used.
++ * SA_RESTART         flag to get restarting signals (which were the default long ago)
++ * SA_NODEFER         prevents the current signal from being masked in the handler.
++ * SA_RESETHAND               clears the handler when the signal is delivered.
++ *
++ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
++ * Unix names RESETHAND and NODEFER respectively.
++ */
++#define SA_NOCLDSTOP  0x00000001
++#define SA_NOCLDWAIT  0x00000002
++#define SA_SIGINFO    0x00000004
++#define SA_RESTORER   0x04000000
++#define SA_ONSTACK    0x08000000
++#define SA_RESTART    0x10000000
++#define SA_NODEFER    0x40000000
++#define SA_RESETHAND  0x80000000
++
++#define SA_NOMASK     SA_NODEFER
++#define SA_ONESHOT    SA_RESETHAND
++
++/*
++ * sigaltstack controls
++ */
++#define SS_ONSTACK    1
++#define SS_DISABLE    2
++
++#define MINSIGSTKSZ   2048
++#define SIGSTKSZ      8192
++
++#include <asm-generic/signal.h>
++
++#ifdef __KERNEL__
++struct old_sigaction {
++      __sighandler_t sa_handler;
++      old_sigset_t sa_mask;
++      unsigned long sa_flags;
++      __sigrestore_t sa_restorer;
++};
++
++struct sigaction {
++      __sighandler_t sa_handler;
++      unsigned long sa_flags;
++      __sigrestore_t sa_restorer;
++      sigset_t sa_mask;               /* mask last for extensibility */
++};
++
++struct k_sigaction {
++      struct sigaction sa;
++};
++#else
++/* Here we must cater to libcs that poke about in kernel headers.  */
++
++struct sigaction {
++      union {
++              __sighandler_t _sa_handler;
++              void (*_sa_sigaction)(int, struct siginfo *, void *);
++      } _u;
++      sigset_t sa_mask;
++      unsigned long sa_flags;
++      void (*sa_restorer)(void);
++};
++
++#define sa_handler    _u._sa_handler
++#define sa_sigaction  _u._sa_sigaction
++
++#endif /* __KERNEL__ */
++
++typedef struct sigaltstack {
++      void __user *ss_sp;
++      int ss_flags;
++      size_t ss_size;
++} stack_t;
++
++#ifdef __KERNEL__
++
++#include <asm/sigcontext.h>
++#undef __HAVE_ARCH_SIG_BITOPS
++
++#define ptrace_signal_deliver(regs, cookie) do { } while (0)
++
++#endif /* __KERNEL__ */
++
++#endif
+Index: linux-2.6.18-avr32/include/asm-avr32/socket.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/socket.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,53 @@
++#ifndef __ASM_AVR32_SOCKET_H
++#define __ASM_AVR32_SOCKET_H
++
++#include <asm/sockios.h>
++
++/* For setsockopt(2) */
++#define SOL_SOCKET    1
++
++#define SO_DEBUG      1
++#define SO_REUSEADDR  2
++#define SO_TYPE               3
++#define SO_ERROR      4
++#define SO_DONTROUTE  5
++#define SO_BROADCAST  6
++#define SO_SNDBUF     7
++#define SO_RCVBUF     8
++#define SO_SNDBUFFORCE        32
++#define SO_RCVBUFFORCE        33
++#define SO_KEEPALIVE  9
++#define SO_OOBINLINE  10
++#define SO_NO_CHECK   11
++#define SO_PRIORITY   12
++#define SO_LINGER     13
++#define SO_BSDCOMPAT  14
++/* To add :#define SO_REUSEPORT 15 */
++#define SO_PASSCRED   16
++#define SO_PEERCRED   17
++#define SO_RCVLOWAT   18
++#define SO_SNDLOWAT   19
++#define SO_RCVTIMEO   20
++#define SO_SNDTIMEO   21
++
++/* Security levels - as per NRL IPv6 - don't actually do anything */
++#define SO_SECURITY_AUTHENTICATION            22
++#define SO_SECURITY_ENCRYPTION_TRANSPORT      23
++#define SO_SECURITY_ENCRYPTION_NETWORK                24
++
++#define SO_BINDTODEVICE       25
++
++/* Socket filtering */
++#define SO_ATTACH_FILTER        26
++#define SO_DETACH_FILTER        27
++
++#define SO_PEERNAME           28
++#define SO_TIMESTAMP          29
++#define SCM_TIMESTAMP         SO_TIMESTAMP
++
++#define SO_ACCEPTCONN         30
++
++#define SO_PEERSEC            31
++#define SO_PASSSEC            34
++
++#endif /* __ASM_AVR32_SOCKET_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/sockios.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/sockios.h     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,12 @@
++#ifndef __ASM_AVR32_SOCKIOS_H
++#define __ASM_AVR32_SOCKIOS_H
++
++/* Socket-level I/O control calls. */
++#define FIOSETOWN     0x8901
++#define SIOCSPGRP     0x8902
++#define FIOGETOWN     0x8903
++#define SIOCGPGRP     0x8904
++#define SIOCATMARK    0x8905
++#define SIOCGSTAMP    0x8906          /* Get stamp */
++
++#endif /* __ASM_AVR32_SOCKIOS_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/stat.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/stat.h        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,79 @@
++/*
++ * 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 __ASM_AVR32_STAT_H
++#define __ASM_AVR32_STAT_H
++
++struct __old_kernel_stat {
++        unsigned short st_dev;
++        unsigned short st_ino;
++        unsigned short st_mode;
++        unsigned short st_nlink;
++        unsigned short st_uid;
++        unsigned short st_gid;
++        unsigned short st_rdev;
++        unsigned long  st_size;
++        unsigned long  st_atime;
++        unsigned long  st_mtime;
++        unsigned long  st_ctime;
++};
++
++struct stat {
++        unsigned long st_dev;
++        unsigned long st_ino;
++        unsigned short st_mode;
++        unsigned short st_nlink;
++        unsigned short st_uid;
++        unsigned short st_gid;
++        unsigned long  st_rdev;
++        unsigned long  st_size;
++        unsigned long  st_blksize;
++        unsigned long  st_blocks;
++        unsigned long  st_atime;
++        unsigned long  st_atime_nsec;
++        unsigned long  st_mtime;
++        unsigned long  st_mtime_nsec;
++        unsigned long  st_ctime;
++        unsigned long  st_ctime_nsec;
++        unsigned long  __unused4;
++        unsigned long  __unused5;
++};
++
++#define STAT_HAVE_NSEC 1
++
++struct stat64 {
++      unsigned long long st_dev;
++
++      unsigned long long st_ino;
++      unsigned int    st_mode;
++      unsigned int    st_nlink;
++
++      unsigned long   st_uid;
++      unsigned long   st_gid;
++
++      unsigned long long st_rdev;
++
++      long long       st_size;
++      unsigned long   __pad1;         /* align 64-bit st_blocks */
++      unsigned long   st_blksize;
++
++      unsigned long long st_blocks;   /* Number 512-byte blocks allocated. */
++
++      unsigned long   st_atime;
++      unsigned long   st_atime_nsec;
++
++      unsigned long   st_mtime;
++      unsigned long   st_mtime_nsec;
++
++      unsigned long   st_ctime;
++      unsigned long   st_ctime_nsec;
++
++      unsigned long   __unused1;
++      unsigned long   __unused2;
++};
++
++#endif /* __ASM_AVR32_STAT_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/statfs.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/statfs.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_STATFS_H
++#define __ASM_AVR32_STATFS_H
++
++#include <asm-generic/statfs.h>
++
++#endif /* __ASM_AVR32_STATFS_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/string.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/string.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,17 @@
++/*
++ * 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 __ASM_AVR32_STRING_H
++#define __ASM_AVR32_STRING_H
++
++#define __HAVE_ARCH_MEMSET
++extern void *memset(void *b, int c, size_t len);
++
++#define __HAVE_ARCH_MEMCPY
++extern void *memcpy(void *to, const void *from, size_t len);
++
++#endif /* __ASM_AVR32_STRING_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/sysreg.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/sysreg.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,332 @@
++/*
++ * AVR32 System Registers
++ *
++ * 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 __ASM_AVR32_SYSREG_H__
++#define __ASM_AVR32_SYSREG_H__
++
++/* sysreg register offsets */
++#define SYSREG_SR                               0x0000
++#define SYSREG_EVBA                             0x0004
++#define SYSREG_ACBA                             0x0008
++#define SYSREG_CPUCR                            0x000c
++#define SYSREG_ECR                              0x0010
++#define SYSREG_RSR_SUP                          0x0014
++#define SYSREG_RSR_INT0                         0x0018
++#define SYSREG_RSR_INT1                         0x001c
++#define SYSREG_RSR_INT2                         0x0020
++#define SYSREG_RSR_INT3                         0x0024
++#define SYSREG_RSR_EX                           0x0028
++#define SYSREG_RSR_NMI                          0x002c
++#define SYSREG_RSR_DBG                          0x0030
++#define SYSREG_RAR_SUP                          0x0034
++#define SYSREG_RAR_INT0                         0x0038
++#define SYSREG_RAR_INT1                         0x003c
++#define SYSREG_RAR_INT2                         0x0040
++#define SYSREG_RAR_INT3                         0x0044
++#define SYSREG_RAR_EX                           0x0048
++#define SYSREG_RAR_NMI                          0x004c
++#define SYSREG_RAR_DBG                          0x0050
++#define SYSREG_JECR                             0x0054
++#define SYSREG_JOSP                             0x0058
++#define SYSREG_JAVA_LV0                         0x005c
++#define SYSREG_JAVA_LV1                         0x0060
++#define SYSREG_JAVA_LV2                         0x0064
++#define SYSREG_JAVA_LV3                         0x0068
++#define SYSREG_JAVA_LV4                         0x006c
++#define SYSREG_JAVA_LV5                         0x0070
++#define SYSREG_JAVA_LV6                         0x0074
++#define SYSREG_JAVA_LV7                         0x0078
++#define SYSREG_JTBA                             0x007c
++#define SYSREG_JBCR                             0x0080
++#define SYSREG_CONFIG0                          0x0100
++#define SYSREG_CONFIG1                          0x0104
++#define SYSREG_COUNT                            0x0108
++#define SYSREG_COMPARE                          0x010c
++#define SYSREG_TLBEHI                           0x0110
++#define SYSREG_TLBELO                           0x0114
++#define SYSREG_PTBR                             0x0118
++#define SYSREG_TLBEAR                           0x011c
++#define SYSREG_MMUCR                            0x0120
++#define SYSREG_TLBARLO                          0x0124
++#define SYSREG_TLBARHI                          0x0128
++#define SYSREG_PCCNT                            0x012c
++#define SYSREG_PCNT0                            0x0130
++#define SYSREG_PCNT1                            0x0134
++#define SYSREG_PCCR                             0x0138
++#define SYSREG_BEAR                             0x013c
++
++/* Bitfields in SR */
++#define SYSREG_SR_C_OFFSET                      0
++#define SYSREG_SR_C_SIZE                        1
++#define SYSREG_Z_OFFSET                         1
++#define SYSREG_Z_SIZE                           1
++#define SYSREG_SR_N_OFFSET                      2
++#define SYSREG_SR_N_SIZE                        1
++#define SYSREG_SR_V_OFFSET                      3
++#define SYSREG_SR_V_SIZE                        1
++#define SYSREG_Q_OFFSET                         4
++#define SYSREG_Q_SIZE                           1
++#define SYSREG_GM_OFFSET                        16
++#define SYSREG_GM_SIZE                          1
++#define SYSREG_I0M_OFFSET                       17
++#define SYSREG_I0M_SIZE                         1
++#define SYSREG_I1M_OFFSET                       18
++#define SYSREG_I1M_SIZE                         1
++#define SYSREG_I2M_OFFSET                       19
++#define SYSREG_I2M_SIZE                         1
++#define SYSREG_I3M_OFFSET                       20
++#define SYSREG_I3M_SIZE                         1
++#define SYSREG_EM_OFFSET                        21
++#define SYSREG_EM_SIZE                          1
++#define SYSREG_M0_OFFSET                        22
++#define SYSREG_M0_SIZE                          1
++#define SYSREG_M1_OFFSET                        23
++#define SYSREG_M1_SIZE                          1
++#define SYSREG_M2_OFFSET                        24
++#define SYSREG_M2_SIZE                          1
++#define SYSREG_SR_D_OFFSET                      26
++#define SYSREG_SR_D_SIZE                        1
++#define SYSREG_DM_OFFSET                        27
++#define SYSREG_DM_SIZE                          1
++#define SYSREG_SR_J_OFFSET                      28
++#define SYSREG_SR_J_SIZE                        1
++#define SYSREG_R_OFFSET                         29
++#define SYSREG_R_SIZE                           1
++#define SYSREG_H_OFFSET                         30
++#define SYSREG_H_SIZE                           1
++
++/* Bitfields in EVBA */
++
++/* Bitfields in ACBA */
++
++/* Bitfields in CPUCR */
++#define SYSREG_BI_OFFSET                        0
++#define SYSREG_BI_SIZE                          1
++#define SYSREG_BE_OFFSET                        1
++#define SYSREG_BE_SIZE                          1
++#define SYSREG_FE_OFFSET                        2
++#define SYSREG_FE_SIZE                          1
++#define SYSREG_RE_OFFSET                        3
++#define SYSREG_RE_SIZE                          1
++#define SYSREG_IBE_OFFSET                       4
++#define SYSREG_IBE_SIZE                         1
++#define SYSREG_IEE_OFFSET                       5
++#define SYSREG_IEE_SIZE                         1
++
++/* Bitfields in ECR */
++#define SYSREG_ECR_OFFSET                       0
++#define SYSREG_ECR_SIZE                         32
++
++/* Bitfields in RSR_SUP */
++
++/* Bitfields in RSR_INT0 */
++
++/* Bitfields in RSR_INT1 */
++
++/* Bitfields in RSR_INT2 */
++
++/* Bitfields in RSR_INT3 */
++
++/* Bitfields in RSR_EX */
++
++/* Bitfields in RSR_NMI */
++
++/* Bitfields in RSR_DBG */
++
++/* Bitfields in RAR_SUP */
++
++/* Bitfields in RAR_INT0 */
++
++/* Bitfields in RAR_INT1 */
++
++/* Bitfields in RAR_INT2 */
++
++/* Bitfields in RAR_INT3 */
++
++/* Bitfields in RAR_EX */
++
++/* Bitfields in RAR_NMI */
++
++/* Bitfields in RAR_DBG */
++
++/* Bitfields in JECR */
++
++/* Bitfields in JOSP */
++
++/* Bitfields in JAVA_LV0 */
++
++/* Bitfields in JAVA_LV1 */
++
++/* Bitfields in JAVA_LV2 */
++
++/* Bitfields in JAVA_LV3 */
++
++/* Bitfields in JAVA_LV4 */
++
++/* Bitfields in JAVA_LV5 */
++
++/* Bitfields in JAVA_LV6 */
++
++/* Bitfields in JAVA_LV7 */
++
++/* Bitfields in JTBA */
++
++/* Bitfields in JBCR */
++
++/* Bitfields in CONFIG0 */
++#define SYSREG_CONFIG0_D_OFFSET                 1
++#define SYSREG_CONFIG0_D_SIZE                   1
++#define SYSREG_CONFIG0_S_OFFSET                 2
++#define SYSREG_CONFIG0_S_SIZE                   1
++#define SYSREG_O_OFFSET                         3
++#define SYSREG_O_SIZE                           1
++#define SYSREG_P_OFFSET                         4
++#define SYSREG_P_SIZE                           1
++#define SYSREG_CONFIG0_J_OFFSET                 5
++#define SYSREG_CONFIG0_J_SIZE                   1
++#define SYSREG_F_OFFSET                         6
++#define SYSREG_F_SIZE                           1
++#define SYSREG_MMUT_OFFSET                      7
++#define SYSREG_MMUT_SIZE                        3
++#define SYSREG_AR_OFFSET                        10
++#define SYSREG_AR_SIZE                          3
++#define SYSREG_AT_OFFSET                        13
++#define SYSREG_AT_SIZE                          3
++#define SYSREG_PROCESSORREVISION_OFFSET         16
++#define SYSREG_PROCESSORREVISION_SIZE           8
++#define SYSREG_PROCESSORID_OFFSET               24
++#define SYSREG_PROCESSORID_SIZE                 8
++
++/* Bitfields in CONFIG1 */
++#define SYSREG_DASS_OFFSET                      0
++#define SYSREG_DASS_SIZE                        3
++#define SYSREG_DLSZ_OFFSET                      3
++#define SYSREG_DLSZ_SIZE                        3
++#define SYSREG_DSET_OFFSET                      6
++#define SYSREG_DSET_SIZE                        4
++#define SYSREG_IASS_OFFSET                      10
++#define SYSREG_IASS_SIZE                        2
++#define SYSREG_ILSZ_OFFSET                      13
++#define SYSREG_ILSZ_SIZE                        3
++#define SYSREG_ISET_OFFSET                      16
++#define SYSREG_ISET_SIZE                        4
++#define SYSREG_DMMUSZ_OFFSET                    20
++#define SYSREG_DMMUSZ_SIZE                      6
++#define SYSREG_IMMUSZ_OFFSET                    26
++#define SYSREG_IMMUSZ_SIZE                      6
++
++/* Bitfields in COUNT */
++
++/* Bitfields in COMPARE */
++
++/* Bitfields in TLBEHI */
++#define SYSREG_ASID_OFFSET                      0
++#define SYSREG_ASID_SIZE                        8
++#define SYSREG_TLBEHI_I_OFFSET                  8
++#define SYSREG_TLBEHI_I_SIZE                    1
++#define SYSREG_TLBEHI_V_OFFSET                  9
++#define SYSREG_TLBEHI_V_SIZE                    1
++#define SYSREG_VPN_OFFSET                       10
++#define SYSREG_VPN_SIZE                         22
++
++/* Bitfields in TLBELO */
++#define SYSREG_W_OFFSET                         0
++#define SYSREG_W_SIZE                           1
++#define SYSREG_TLBELO_D_OFFSET                  1
++#define SYSREG_TLBELO_D_SIZE                    1
++#define SYSREG_SZ_OFFSET                        2
++#define SYSREG_SZ_SIZE                          2
++#define SYSREG_AP_OFFSET                        4
++#define SYSREG_AP_SIZE                          3
++#define SYSREG_B_OFFSET                         7
++#define SYSREG_B_SIZE                           1
++#define SYSREG_G_OFFSET                         8
++#define SYSREG_G_SIZE                           1
++#define SYSREG_TLBELO_C_OFFSET                  9
++#define SYSREG_TLBELO_C_SIZE                    1
++#define SYSREG_PFN_OFFSET                       10
++#define SYSREG_PFN_SIZE                         22
++
++/* Bitfields in PTBR */
++
++/* Bitfields in TLBEAR */
++
++/* Bitfields in MMUCR */
++#define SYSREG_E_OFFSET                         0
++#define SYSREG_E_SIZE                           1
++#define SYSREG_M_OFFSET                         1
++#define SYSREG_M_SIZE                           1
++#define SYSREG_MMUCR_I_OFFSET                   2
++#define SYSREG_MMUCR_I_SIZE                     1
++#define SYSREG_MMUCR_N_OFFSET                   3
++#define SYSREG_MMUCR_N_SIZE                     1
++#define SYSREG_MMUCR_S_OFFSET                   4
++#define SYSREG_MMUCR_S_SIZE                     1
++#define SYSREG_DLA_OFFSET                       8
++#define SYSREG_DLA_SIZE                         6
++#define SYSREG_DRP_OFFSET                       14
++#define SYSREG_DRP_SIZE                         6
++#define SYSREG_ILA_OFFSET                       20
++#define SYSREG_ILA_SIZE                         6
++#define SYSREG_IRP_OFFSET                       26
++#define SYSREG_IRP_SIZE                         6
++
++/* Bitfields in TLBARLO */
++
++/* Bitfields in TLBARHI */
++
++/* Bitfields in PCCNT */
++
++/* Bitfields in PCNT0 */
++
++/* Bitfields in PCNT1 */
++
++/* Bitfields in PCCR */
++
++/* Bitfields in BEAR */
++
++/* Constants for ECR */
++#define ECR_UNRECOVERABLE                       0
++#define ECR_TLB_MULTIPLE                        1
++#define ECR_BUS_ERROR_WRITE                     2
++#define ECR_BUS_ERROR_READ                      3
++#define ECR_NMI                                 4
++#define ECR_ADDR_ALIGN_X                        5
++#define ECR_PROTECTION_X                        6
++#define ECR_DEBUG                               7
++#define ECR_ILLEGAL_OPCODE                      8
++#define ECR_UNIMPL_INSTRUCTION                  9
++#define ECR_PRIVILEGE_VIOLATION                 10
++#define ECR_FPE                                 11
++#define ECR_COPROC_ABSENT                       12
++#define ECR_ADDR_ALIGN_R                        13
++#define ECR_ADDR_ALIGN_W                        14
++#define ECR_PROTECTION_R                        15
++#define ECR_PROTECTION_W                        16
++#define ECR_DTLB_MODIFIED                       17
++#define ECR_TLB_MISS_X                          20
++#define ECR_TLB_MISS_R                          24
++#define ECR_TLB_MISS_W                          28
++
++/* Bit manipulation macros */
++#define SYSREG_BIT(name)                        (1 << SYSREG_##name##_OFFSET)
++#define SYSREG_BF(name,value)                   (((value) & ((1 << SYSREG_##name##_SIZE) - 1)) << SYSREG_##name##_OFFSET)
++#define SYSREG_BFEXT(name,value)                (((value) >> SYSREG_##name##_OFFSET) & ((1 << SYSREG_##name##_SIZE) - 1))
++#define SYSREG_BFINS(name,value,old)            (((old) & ~(((1 << SYSREG_##name##_SIZE) - 1) << SYSREG_##name##_OFFSET)) | SYSREG_BF(name,value))
++
++#ifdef __CHECKER__
++extern unsigned long __builtin_mfsr(unsigned long reg);
++extern void __builtin_mtsr(unsigned long reg, unsigned long value);
++#endif
++
++/* Register access macros */
++#define sysreg_read(reg)                        __builtin_mfsr(SYSREG_##reg)
++#define sysreg_write(reg, value)                __builtin_mtsr(SYSREG_##reg, value)
++
++#endif /* __ASM_AVR32_SYSREG_H__ */
+Index: linux-2.6.18-avr32/include/asm-avr32/system.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/system.h      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,155 @@
++/*
++ * 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 __ASM_AVR32_SYSTEM_H
++#define __ASM_AVR32_SYSTEM_H
++
++#include <linux/compiler.h>
++#include <linux/types.h>
++
++#include <asm/ptrace.h>
++#include <asm/sysreg.h>
++
++#define xchg(ptr,x) \
++      ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
++
++#define nop() asm volatile("nop")
++
++#define mb()                  asm volatile("" : : : "memory")
++#define rmb()                 mb()
++#define wmb()                 asm volatile("sync 0" : : : "memory")
++#define read_barrier_depends()  do { } while(0)
++#define set_mb(var, value)      do { var = value; mb(); } while(0)
++
++/*
++ * Help PathFinder and other Nexus-compliant debuggers keep track of
++ * the current PID by emitting an Ownership Trace Message each time we
++ * switch task.
++ */
++#ifdef CONFIG_OWNERSHIP_TRACE
++#include <asm/ocd.h>
++#define finish_arch_switch(prev)                      \
++      do {                                            \
++              __mtdr(DBGREG_PID, prev->pid);          \
++              __mtdr(DBGREG_PID, current->pid);       \
++      } while(0)
++#endif
++
++/*
++ * switch_to(prev, next, last) should switch from task `prev' to task
++ * `next'. `prev' will never be the same as `next'.
++ *
++ * We just delegate everything to the __switch_to assembly function,
++ * which is implemented in arch/avr32/kernel/switch_to.S
++ *
++ * mb() tells GCC not to cache `current' across this call.
++ */
++struct cpu_context;
++struct task_struct;
++extern struct task_struct *__switch_to(struct task_struct *,
++                                     struct cpu_context *,
++                                     struct cpu_context *);
++#define switch_to(prev, next, last)                                   \
++      do {                                                            \
++              last = __switch_to(prev, &prev->thread.cpu_context + 1, \
++                                 &next->thread.cpu_context);          \
++      } while (0)
++
++#ifdef CONFIG_SMP
++# error "The AVR32 port does not support SMP"
++#else
++# define smp_mb()             barrier()
++# define smp_rmb()            barrier()
++# define smp_wmb()            barrier()
++# define smp_read_barrier_depends() do { } while(0)
++#endif
++
++#include <linux/irqflags.h>
++
++extern void __xchg_called_with_bad_pointer(void);
++
++#ifdef __CHECKER__
++extern unsigned long __builtin_xchg(void *ptr, unsigned long x);
++#endif
++
++#define xchg_u32(val, m) __builtin_xchg((void *)m, val)
++
++static inline unsigned long __xchg(unsigned long x,
++                                     volatile void *ptr,
++                                     int size)
++{
++      switch(size) {
++      case 4:
++              return xchg_u32(x, ptr);
++      default:
++              __xchg_called_with_bad_pointer();
++              return x;
++      }
++}
++
++static inline unsigned long __cmpxchg_u32(volatile int *m, unsigned long old,
++                                        unsigned long new)
++{
++      __u32 ret;
++
++      asm volatile(
++              "1:     ssrf    5\n"
++              "       ld.w    %[ret], %[m]\n"
++              "       cp.w    %[ret], %[old]\n"
++              "       brne    2f\n"
++              "       stcond  %[m], %[new]\n"
++              "       brne    1b\n"
++              "2:\n"
++              : [ret] "=&r"(ret), [m] "=m"(*m)
++              : "m"(m), [old] "ir"(old), [new] "r"(new)
++              : "memory", "cc");
++      return ret;
++}
++
++extern unsigned long __cmpxchg_u64_unsupported_on_32bit_kernels(
++        volatile int * m, unsigned long old, unsigned long new);
++#define __cmpxchg_u64 __cmpxchg_u64_unsupported_on_32bit_kernels
++
++/* This function doesn't exist, so you'll get a linker error
++   if something tries to do an invalid cmpxchg().  */
++extern void __cmpxchg_called_with_bad_pointer(void);
++
++#define __HAVE_ARCH_CMPXCHG 1
++
++static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
++                                    unsigned long new, int size)
++{
++      switch (size) {
++      case 4:
++              return __cmpxchg_u32(ptr, old, new);
++      case 8:
++              return __cmpxchg_u64(ptr, old, new);
++      }
++
++      __cmpxchg_called_with_bad_pointer();
++      return old;
++}
++
++#define cmpxchg(ptr, old, new)                                        \
++      ((typeof(*(ptr)))__cmpxchg((ptr), (unsigned long)(old), \
++                                 (unsigned long)(new),        \
++                                 sizeof(*(ptr))))
++
++struct pt_regs;
++extern void __die(const char *, struct pt_regs *, unsigned long,
++                const char *, const char *, unsigned long);
++extern void __die_if_kernel(const char *, struct pt_regs *, unsigned long,
++                          const char *, const char *, unsigned long);
++
++#define die(msg, regs, err)                                   \
++      __die(msg, regs, err, __FILE__ ":", __FUNCTION__, __LINE__)
++#define die_if_kernel(msg, regs, err)                                 \
++      __die_if_kernel(msg, regs, err, __FILE__ ":", __FUNCTION__, __LINE__)
++
++#define arch_align_stack(x)   (x)
++
++#endif /* __ASM_AVR32_SYSTEM_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/termbits.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/termbits.h    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,173 @@
++#ifndef __ASM_AVR32_TERMBITS_H
++#define __ASM_AVR32_TERMBITS_H
++
++#include <linux/posix_types.h>
++
++typedef unsigned char cc_t;
++typedef unsigned int  speed_t;
++typedef unsigned int  tcflag_t;
++
++#define NCCS 19
++struct termios {
++      tcflag_t c_iflag;               /* input mode flags */
++      tcflag_t c_oflag;               /* output mode flags */
++      tcflag_t c_cflag;               /* control mode flags */
++      tcflag_t c_lflag;               /* local mode flags */
++      cc_t c_line;                    /* line discipline */
++      cc_t c_cc[NCCS];                /* control characters */
++};
++
++/* c_cc characters */
++#define VINTR 0
++#define VQUIT 1
++#define VERASE 2
++#define VKILL 3
++#define VEOF 4
++#define VTIME 5
++#define VMIN 6
++#define VSWTC 7
++#define VSTART 8
++#define VSTOP 9
++#define VSUSP 10
++#define VEOL 11
++#define VREPRINT 12
++#define VDISCARD 13
++#define VWERASE 14
++#define VLNEXT 15
++#define VEOL2 16
++
++/* c_iflag bits */
++#define IGNBRK        0000001
++#define BRKINT        0000002
++#define IGNPAR        0000004
++#define PARMRK        0000010
++#define INPCK 0000020
++#define ISTRIP        0000040
++#define INLCR 0000100
++#define IGNCR 0000200
++#define ICRNL 0000400
++#define IUCLC 0001000
++#define IXON  0002000
++#define IXANY 0004000
++#define IXOFF 0010000
++#define IMAXBEL       0020000
++#define IUTF8 0040000
++
++/* c_oflag bits */
++#define OPOST 0000001
++#define OLCUC 0000002
++#define ONLCR 0000004
++#define OCRNL 0000010
++#define ONOCR 0000020
++#define ONLRET        0000040
++#define OFILL 0000100
++#define OFDEL 0000200
++#define NLDLY 0000400
++#define   NL0 0000000
++#define   NL1 0000400
++#define CRDLY 0003000
++#define   CR0 0000000
++#define   CR1 0001000
++#define   CR2 0002000
++#define   CR3 0003000
++#define TABDLY        0014000
++#define   TAB0        0000000
++#define   TAB1        0004000
++#define   TAB2        0010000
++#define   TAB3        0014000
++#define   XTABS       0014000
++#define BSDLY 0020000
++#define   BS0 0000000
++#define   BS1 0020000
++#define VTDLY 0040000
++#define   VT0 0000000
++#define   VT1 0040000
++#define FFDLY 0100000
++#define   FF0 0000000
++#define   FF1 0100000
++
++/* c_cflag bit meaning */
++#define CBAUD 0010017
++#define  B0   0000000         /* hang up */
++#define  B50  0000001
++#define  B75  0000002
++#define  B110 0000003
++#define  B134 0000004
++#define  B150 0000005
++#define  B200 0000006
++#define  B300 0000007
++#define  B600 0000010
++#define  B1200        0000011
++#define  B1800        0000012
++#define  B2400        0000013
++#define  B4800        0000014
++#define  B9600        0000015
++#define  B19200       0000016
++#define  B38400       0000017
++#define EXTA B19200
++#define EXTB B38400
++#define CSIZE 0000060
++#define   CS5 0000000
++#define   CS6 0000020
++#define   CS7 0000040
++#define   CS8 0000060
++#define CSTOPB        0000100
++#define CREAD 0000200
++#define PARENB        0000400
++#define PARODD        0001000
++#define HUPCL 0002000
++#define CLOCAL        0004000
++#define CBAUDEX 0010000
++#define    B57600 0010001
++#define   B115200 0010002
++#define   B230400 0010003
++#define   B460800 0010004
++#define   B500000 0010005
++#define   B576000 0010006
++#define   B921600 0010007
++#define  B1000000 0010010
++#define  B1152000 0010011
++#define  B1500000 0010012
++#define  B2000000 0010013
++#define  B2500000 0010014
++#define  B3000000 0010015
++#define  B3500000 0010016
++#define  B4000000 0010017
++#define CIBAUD          002003600000  /* input baud rate (not used) */
++#define CMSPAR          010000000000          /* mark or space (stick) parity */
++#define CRTSCTS         020000000000          /* flow control */
++
++/* c_lflag bits */
++#define ISIG  0000001
++#define ICANON        0000002
++#define XCASE 0000004
++#define ECHO  0000010
++#define ECHOE 0000020
++#define ECHOK 0000040
++#define ECHONL        0000100
++#define NOFLSH        0000200
++#define TOSTOP        0000400
++#define ECHOCTL       0001000
++#define ECHOPRT       0002000
++#define ECHOKE        0004000
++#define FLUSHO        0010000
++#define PENDIN        0040000
++#define IEXTEN        0100000
++
++/* tcflow() and TCXONC use these */
++#define       TCOOFF          0
++#define       TCOON           1
++#define       TCIOFF          2
++#define       TCION           3
++
++/* tcflush() and TCFLSH use these */
++#define       TCIFLUSH        0
++#define       TCOFLUSH        1
++#define       TCIOFLUSH       2
++
++/* tcsetattr uses these */
++#define       TCSANOW         0
++#define       TCSADRAIN       1
++#define       TCSAFLUSH       2
++
++#endif /* __ASM_AVR32_TERMBITS_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/termios.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/termios.h     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,80 @@
++/*
++ * 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 __ASM_AVR32_TERMIOS_H
++#define __ASM_AVR32_TERMIOS_H
++
++#include <asm/termbits.h>
++#include <asm/ioctls.h>
++
++struct winsize {
++      unsigned short ws_row;
++      unsigned short ws_col;
++      unsigned short ws_xpixel;
++      unsigned short ws_ypixel;
++};
++
++#define NCC 8
++struct termio {
++      unsigned short c_iflag;         /* input mode flags */
++      unsigned short c_oflag;         /* output mode flags */
++      unsigned short c_cflag;         /* control mode flags */
++      unsigned short c_lflag;         /* local mode flags */
++      unsigned char c_line;           /* line discipline */
++      unsigned char c_cc[NCC];        /* control characters */
++};
++
++/* modem lines */
++#define TIOCM_LE      0x001
++#define TIOCM_DTR     0x002
++#define TIOCM_RTS     0x004
++#define TIOCM_ST      0x008
++#define TIOCM_SR      0x010
++#define TIOCM_CTS     0x020
++#define TIOCM_CAR     0x040
++#define TIOCM_RNG     0x080
++#define TIOCM_DSR     0x100
++#define TIOCM_CD      TIOCM_CAR
++#define TIOCM_RI      TIOCM_RNG
++#define TIOCM_OUT1    0x2000
++#define TIOCM_OUT2    0x4000
++#define TIOCM_LOOP    0x8000
++
++/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
++
++/* line disciplines */
++#define N_TTY         0
++#define N_SLIP                1
++#define N_MOUSE               2
++#define N_PPP         3
++#define N_STRIP               4
++#define N_AX25                5
++#define N_X25         6       /* X.25 async */
++#define N_6PACK               7
++#define N_MASC                8       /* Reserved for Mobitex module <kaz@cafe.net> */
++#define N_R3964               9       /* Reserved for Simatic R3964 module */
++#define N_PROFIBUS_FDL        10      /* Reserved for Profibus <Dave@mvhi.com> */
++#define N_IRDA                11      /* Linux IR - http://irda.sourceforge.net/ */
++#define N_SMSBLOCK    12      /* SMS block mode - for talking to GSM data cards about SMS messages */
++#define N_HDLC                13      /* synchronous HDLC */
++#define N_SYNC_PPP    14      /* synchronous PPP */
++#define N_HCI         15  /* Bluetooth HCI UART */
++
++#ifdef __KERNEL__
++/*    intr=^C         quit=^\         erase=del       kill=^U
++      eof=^D          vtime=\0        vmin=\1         sxtc=\0
++      start=^Q        stop=^S         susp=^Z         eol=\0
++      reprint=^R      discard=^U      werase=^W       lnext=^V
++      eol2=\0
++*/
++#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
++
++#include <asm-generic/termios.h>
++
++#endif        /* __KERNEL__ */
++
++#endif        /* __ASM_AVR32_TERMIOS_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/thread_info.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/thread_info.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,106 @@
++/*
++ * 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 __ASM_AVR32_THREAD_INFO_H
++#define __ASM_AVR32_THREAD_INFO_H
++
++#include <asm/page.h>
++
++#define THREAD_SIZE_ORDER     1
++#define THREAD_SIZE           (PAGE_SIZE << THREAD_SIZE_ORDER)
++
++#ifndef __ASSEMBLY__
++#include <asm/types.h>
++
++struct task_struct;
++struct exec_domain;
++
++struct thread_info {
++      struct task_struct      *task;          /* main task structure */
++      struct exec_domain      *exec_domain;   /* execution domain */
++      unsigned long           flags;          /* low level flags */
++      __u32                   cpu;
++      __s32                   preempt_count;  /* 0 => preemptable, <0 => BUG */
++      struct restart_block    restart_block;
++      __u8                    supervisor_stack[0];
++};
++
++#define INIT_THREAD_INFO(tsk)                                         \
++{                                                                     \
++      .task           = &tsk,                                         \
++      .exec_domain    = &default_exec_domain,                         \
++      .flags          = 0,                                            \
++      .cpu            = 0,                                            \
++      .preempt_count  = 1,                                            \
++      .restart_block  = {                                             \
++              .fn     = do_no_restart_syscall                         \
++      }                                                               \
++}
++
++#define init_thread_info      (init_thread_union.thread_info)
++#define init_stack            (init_thread_union.stack)
++
++/*
++ * Get the thread information struct from C.
++ * We do the usual trick and use the lower end of the stack for this
++ */
++static inline struct thread_info *current_thread_info(void)
++{
++      unsigned long addr = ~(THREAD_SIZE - 1);
++
++      asm("and %0, sp" : "=r"(addr) : "0"(addr));
++      return (struct thread_info *)addr;
++}
++
++/* thread information allocation */
++#define alloc_thread_info(ti) \
++      ((struct thread_info *) __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER))
++#define free_thread_info(ti) free_pages((unsigned long)(ti), 1)
++#define get_thread_info(ti) get_task_struct((ti)->task)
++#define put_thread_info(ti) put_task_struct((ti)->task)
++
++#endif /* !__ASSEMBLY__ */
++
++#define PREEMPT_ACTIVE                0x40000000
++
++/*
++ * Thread information flags
++ * - these are process state flags that various assembly files may need to access
++ * - pending work-to-be-done flags are in LSW
++ * - other flags in MSW
++ */
++#define TIF_SYSCALL_TRACE       0       /* syscall trace active */
++#define TIF_NOTIFY_RESUME       1       /* resumption notification requested */
++#define TIF_SIGPENDING          2       /* signal pending */
++#define TIF_NEED_RESCHED        3       /* rescheduling necessary */
++#define TIF_POLLING_NRFLAG      4       /* true if poll_idle() is polling
++                                         TIF_NEED_RESCHED */
++#define TIF_BREAKPOINT                5       /* true if we should break after return */
++#define TIF_SINGLE_STEP               6       /* single step after next break */
++#define TIF_MEMDIE            7
++#define TIF_RESTORE_SIGMASK   8       /* restore signal mask in do_signal */
++#define TIF_USERSPACE         31      /* true if FS sets userspace */
++
++#define _TIF_SYSCALL_TRACE    (1 << TIF_SYSCALL_TRACE)
++#define _TIF_NOTIFY_RESUME    (1 << TIF_NOTIFY_RESUME)
++#define _TIF_SIGPENDING               (1 << TIF_SIGPENDING)
++#define _TIF_NEED_RESCHED     (1 << TIF_NEED_RESCHED)
++#define _TIF_POLLING_NRFLAG   (1 << TIF_POLLING_NRFLAG)
++#define _TIF_BREAKPOINT               (1 << TIF_BREAKPOINT)
++#define _TIF_SINGLE_STEP      (1 << TIF_SINGLE_STEP)
++#define _TIF_MEMDIE           (1 << TIF_MEMDIE)
++#define _TIF_RESTORE_SIGMASK  (1 << TIF_RESTORE_SIGMASK)
++
++/* XXX: These two masks must never span more than 16 bits! */
++/* work to do on interrupt/exception return */
++#define _TIF_WORK_MASK                0x0000013e
++/* work to do on any return to userspace */
++#define _TIF_ALLWORK_MASK     0x0000013f
++/* work to do on return from debug mode */
++#define _TIF_DBGWORK_MASK     0x0000017e
++
++#endif /* __ASM_AVR32_THREAD_INFO_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/timex.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/timex.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,40 @@
++/*
++ * 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 __ASM_AVR32_TIMEX_H
++#define __ASM_AVR32_TIMEX_H
++
++/*
++ * This is the frequency of the timer used for Linux's timer interrupt.
++ * The value should be defined as accurate as possible or under certain
++ * circumstances Linux timekeeping might become inaccurate or fail.
++ *
++ * For many system the exact clockrate of the timer isn't known but due to
++ * the way this value is used we can get away with a wrong value as long
++ * as this value is:
++ *
++ *  - a multiple of HZ
++ *  - a divisor of the actual rate
++ *
++ * 500000 is a good such cheat value.
++ *
++ * The obscure number 1193182 is the same as used by the original i8254
++ * time in legacy PC hardware; the chip is never found in AVR32 systems.
++ */
++#define CLOCK_TICK_RATE               500000  /* Underlying HZ */
++
++typedef unsigned long cycles_t;
++
++static inline cycles_t get_cycles (void)
++{
++      return 0;
++}
++
++extern int read_current_timer(unsigned long *timer_value);
++#define ARCH_HAS_READ_CURRENT_TIMER   1
++
++#endif /* __ASM_AVR32_TIMEX_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/tlb.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/tlb.h 2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,32 @@
++/*
++ * 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 __ASM_AVR32_TLB_H
++#define __ASM_AVR32_TLB_H
++
++#define tlb_start_vma(tlb, vma) \
++      flush_cache_range(vma, vma->vm_start, vma->vm_end)
++
++#define tlb_end_vma(tlb, vma) \
++      flush_tlb_range(vma, vma->vm_start, vma->vm_end)
++
++#define __tlb_remove_tlb_entry(tlb, pte, address) do { } while(0)
++
++/*
++ * Flush whole TLB for MM
++ */
++#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
++
++#include <asm-generic/tlb.h>
++
++/*
++ * For debugging purposes
++ */
++extern void show_dtlb_entry(unsigned int index);
++extern void dump_dtlb(void);
++
++#endif /* __ASM_AVR32_TLB_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/tlbflush.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/tlbflush.h    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,40 @@
++/*
++ * 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 __ASM_AVR32_TLBFLUSH_H
++#define __ASM_AVR32_TLBFLUSH_H
++
++#include <asm/mmu.h>
++
++/*
++ * TLB flushing:
++ *
++ *  - flush_tlb() flushes the current mm struct TLBs
++ *  - flush_tlb_all() flushes all processes' TLB entries
++ *  - flush_tlb_mm(mm) flushes the specified mm context TLBs
++ *  - flush_tlb_page(vma, vmaddr) flushes one page
++ *  - flush_tlb_range(vma, start, end) flushes a range of pages
++ *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
++ *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
++ */
++extern void flush_tlb(void);
++extern void flush_tlb_all(void);
++extern void flush_tlb_mm(struct mm_struct *mm);
++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);
++
++static inline void flush_tlb_pgtables(struct mm_struct *mm,
++                                    unsigned long start, unsigned long end)
++{
++      /* Nothing to do */
++}
++
++extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
++
++#endif /* __ASM_AVR32_TLBFLUSH_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/topology.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/topology.h    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,6 @@
++#ifndef __ASM_AVR32_TOPOLOGY_H
++#define __ASM_AVR32_TOPOLOGY_H
++
++#include <asm-generic/topology.h>
++
++#endif /* __ASM_AVR32_TOPOLOGY_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/traps.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/traps.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,23 @@
++/*
++ * 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 __ASM_AVR32_TRAPS_H
++#define __ASM_AVR32_TRAPS_H
++
++#include <linux/list.h>
++
++struct undef_hook {
++      struct list_head node;
++      u32 insn_mask;
++      u32 insn_val;
++      int (*fn)(struct pt_regs *regs, u32 insn);
++};
++
++void register_undef_hook(struct undef_hook *hook);
++void unregister_undef_hook(struct undef_hook *hook);
++
++#endif /* __ASM_AVR32_TRAPS_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/types.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/types.h       2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,70 @@
++/*
++ * 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 __ASM_AVR32_TYPES_H
++#define __ASM_AVR32_TYPES_H
++
++#ifndef __ASSEMBLY__
++
++typedef unsigned short umode_t;
++
++/*
++ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
++ * header files exported to user space
++ */
++typedef __signed__ char __s8;
++typedef unsigned char __u8;
++
++typedef __signed__ short __s16;
++typedef unsigned short __u16;
++
++typedef __signed__ int __s32;
++typedef unsigned int __u32;
++
++#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
++typedef __signed__ long long __s64;
++typedef unsigned long long __u64;
++#endif
++
++#endif /* __ASSEMBLY__ */
++
++/*
++ * These aren't exported outside the kernel to avoid name space clashes
++ */
++#ifdef __KERNEL__
++
++#define BITS_PER_LONG 32
++
++#ifndef __ASSEMBLY__
++
++typedef signed char s8;
++typedef unsigned char u8;
++
++typedef signed short s16;
++typedef unsigned short u16;
++
++typedef signed int s32;
++typedef unsigned int u32;
++
++typedef signed long long s64;
++typedef unsigned long long u64;
++
++/* Dma addresses are 32-bits wide.  */
++
++typedef u32 dma_addr_t;
++
++#ifdef CONFIG_LBD
++typedef u64 sector_t;
++#define HAVE_SECTOR_T
++#endif
++
++#endif /* __ASSEMBLY__ */
++
++#endif /* __KERNEL__ */
++
++
++#endif /* __ASM_AVR32_TYPES_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/uaccess.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/uaccess.h     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,335 @@
++/*
++ * 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 __ASM_AVR32_UACCESS_H
++#define __ASM_AVR32_UACCESS_H
++
++#include <linux/errno.h>
++#include <linux/sched.h>
++
++#define VERIFY_READ   0
++#define VERIFY_WRITE  1
++
++typedef struct {
++      unsigned int is_user_space;
++} mm_segment_t;
++
++/*
++ * The fs value determines whether argument validity checking should be
++ * performed or not.  If get_fs() == USER_DS, checking is performed, with
++ * get_fs() == KERNEL_DS, checking is bypassed.
++ *
++ * For historical reasons (Data Segment Register?), these macros are misnamed.
++ */
++#define MAKE_MM_SEG(s)        ((mm_segment_t) { (s) })
++#define segment_eq(a,b)       ((a).is_user_space == (b).is_user_space)
++
++#define USER_ADDR_LIMIT 0x80000000
++
++#define KERNEL_DS     MAKE_MM_SEG(0)
++#define USER_DS               MAKE_MM_SEG(1)
++
++#define get_ds()      (KERNEL_DS)
++
++static inline mm_segment_t get_fs(void)
++{
++      return MAKE_MM_SEG(test_thread_flag(TIF_USERSPACE));
++}
++
++static inline void set_fs(mm_segment_t s)
++{
++      if (s.is_user_space)
++              set_thread_flag(TIF_USERSPACE);
++      else
++              clear_thread_flag(TIF_USERSPACE);
++}
++
++/*
++ * Test whether a block of memory is a valid user space address.
++ * Returns 0 if the range is valid, nonzero otherwise.
++ *
++ * We do the following checks:
++ *   1. Is the access from kernel space?
++ *   2. Does (addr + size) set the carry bit?
++ *   3. Is (addr + size) a negative number (i.e. >= 0x80000000)?
++ *
++ * If yes on the first check, access is granted.
++ * If no on any of the others, access is denied.
++ */
++#define __range_ok(addr, size)                                                \
++      (test_thread_flag(TIF_USERSPACE)                                \
++       && (((unsigned long)(addr) >= 0x80000000)                      \
++           || ((unsigned long)(size) > 0x80000000)                    \
++           || (((unsigned long)(addr) + (unsigned long)(size)) > 0x80000000)))
++
++#define access_ok(type, addr, size) (likely(__range_ok(addr, size) == 0))
++
++static inline int
++verify_area(int type, const void __user *addr, unsigned long size)
++{
++      return access_ok(type, addr, size) ? 0 : -EFAULT;
++}
++
++/* Generic arbitrary sized copy. Return the number of bytes NOT copied */
++extern __kernel_size_t __copy_user(void *to, const void *from,
++                                 __kernel_size_t n);
++
++extern __kernel_size_t copy_to_user(void __user *to, const void *from,
++                                  __kernel_size_t n);
++extern __kernel_size_t copy_from_user(void *to, const void __user *from,
++                                    __kernel_size_t n);
++
++static inline __kernel_size_t __copy_to_user(void __user *to, const void *from,
++                                           __kernel_size_t n)
++{
++      return __copy_user((void __force *)to, from, n);
++}
++static inline __kernel_size_t __copy_from_user(void *to,
++                                             const void __user *from,
++                                             __kernel_size_t n)
++{
++      return __copy_user(to, (const void __force *)from, n);
++}
++
++#define __copy_to_user_inatomic __copy_to_user
++#define __copy_from_user_inatomic __copy_from_user
++
++/*
++ * put_user: - Write a simple value into user space.
++ * @x:   Value to copy to user space.
++ * @ptr: Destination address, in user space.
++ *
++ * Context: User context only.  This function may sleep.
++ *
++ * This macro copies a single simple value from kernel space to user
++ * space.  It supports simple types like char and int, but not larger
++ * data types like structures or arrays.
++ *
++ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
++ * to the result of dereferencing @ptr.
++ *
++ * Returns zero on success, or -EFAULT on error.
++ */
++#define put_user(x,ptr)       \
++      __put_user_check((x),(ptr),sizeof(*(ptr)))
++
++/*
++ * get_user: - Get a simple variable from user space.
++ * @x:   Variable to store result.
++ * @ptr: Source address, in user space.
++ *
++ * Context: User context only.  This function may sleep.
++ *
++ * This macro copies a single simple variable from user space to kernel
++ * space.  It supports simple types like char and int, but not larger
++ * data types like structures or arrays.
++ *
++ * @ptr must have pointer-to-simple-variable type, and the result of
++ * dereferencing @ptr must be assignable to @x without a cast.
++ *
++ * Returns zero on success, or -EFAULT on error.
++ * On error, the variable @x is set to zero.
++ */
++#define get_user(x,ptr) \
++      __get_user_check((x),(ptr),sizeof(*(ptr)))
++
++/*
++ * __put_user: - Write a simple value into user space, with less checking.
++ * @x:   Value to copy to user space.
++ * @ptr: Destination address, in user space.
++ *
++ * Context: User context only.  This function may sleep.
++ *
++ * This macro copies a single simple value from kernel space to user
++ * space.  It supports simple types like char and int, but not larger
++ * data types like structures or arrays.
++ *
++ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
++ * to the result of dereferencing @ptr.
++ *
++ * Caller must check the pointer with access_ok() before calling this
++ * function.
++ *
++ * Returns zero on success, or -EFAULT on error.
++ */
++#define __put_user(x,ptr) \
++      __put_user_nocheck((x),(ptr),sizeof(*(ptr)))
++
++/*
++ * __get_user: - Get a simple variable from user space, with less checking.
++ * @x:   Variable to store result.
++ * @ptr: Source address, in user space.
++ *
++ * Context: User context only.  This function may sleep.
++ *
++ * This macro copies a single simple variable from user space to kernel
++ * space.  It supports simple types like char and int, but not larger
++ * data types like structures or arrays.
++ *
++ * @ptr must have pointer-to-simple-variable type, and the result of
++ * dereferencing @ptr must be assignable to @x without a cast.
++ *
++ * Caller must check the pointer with access_ok() before calling this
++ * function.
++ *
++ * Returns zero on success, or -EFAULT on error.
++ * On error, the variable @x is set to zero.
++ */
++#define __get_user(x,ptr) \
++      __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
++
++extern int __get_user_bad(void);
++extern int __put_user_bad(void);
++
++#define __get_user_nocheck(x, ptr, size)                              \
++({                                                                    \
++      typeof(*(ptr)) __gu_val = (typeof(*(ptr)) __force)0;            \
++      int __gu_err = 0;                                               \
++                                                                      \
++      switch (size) {                                                 \
++      case 1: __get_user_asm("ub", __gu_val, ptr, __gu_err); break;   \
++      case 2: __get_user_asm("uh", __gu_val, ptr, __gu_err); break;   \
++      case 4: __get_user_asm("w", __gu_val, ptr, __gu_err); break;    \
++      case 8: __get_user_asm("d", __gu_val, ptr, __gu_err); break;    \
++      default: __gu_err = __get_user_bad(); break;                    \
++      }                                                               \
++                                                                      \
++      x = __gu_val;                                                   \
++      __gu_err;                                                       \
++})
++
++#define __get_user_check(x, ptr, size)                                        \
++({                                                                    \
++      typeof(*(ptr)) __gu_val = (typeof(*(ptr)) __force)0;            \
++      const typeof(*(ptr)) __user * __gu_addr = (ptr);                \
++      int __gu_err = 0;                                               \
++                                                                      \
++      if (access_ok(VERIFY_READ, __gu_addr, size)) {                  \
++              switch (size) {                                         \
++              case 1:                                                 \
++                      __get_user_asm("ub", __gu_val, __gu_addr,       \
++                                     __gu_err);                       \
++                      break;                                          \
++              case 2:                                                 \
++                      __get_user_asm("uh", __gu_val, __gu_addr,       \
++                                     __gu_err);                       \
++                      break;                                          \
++              case 4:                                                 \
++                      __get_user_asm("w", __gu_val, __gu_addr,        \
++                                     __gu_err);                       \
++                      break;                                          \
++              case 8:                                                 \
++                      __get_user_asm("d", __gu_val, __gu_addr,        \
++                                     __gu_err);                       \
++                      break;                                          \
++              default:                                                \
++                      __gu_err = __get_user_bad();                    \
++                      break;                                          \
++              }                                                       \
++      } else {                                                        \
++              __gu_err = -EFAULT;                                     \
++      }                                                               \
++      x = __gu_val;                                                   \
++      __gu_err;                                                       \
++})
++
++#define __get_user_asm(suffix, __gu_val, ptr, __gu_err)                       \
++      asm volatile(                                                   \
++              "1:     ld." suffix "   %1, %3                  \n"     \
++              "2:                                             \n"     \
++              "       .section .fixup, \"ax\"                 \n"     \
++              "3:     mov     %0, %4                          \n"     \
++              "       rjmp    2b                              \n"     \
++              "       .previous                               \n"     \
++              "       .section __ex_table, \"a\"              \n"     \
++              "       .long   1b, 3b                          \n"     \
++              "       .previous                               \n"     \
++              : "=r"(__gu_err), "=r"(__gu_val)                        \
++              : "0"(__gu_err), "m"(*(ptr)), "i"(-EFAULT))
++
++#define __put_user_nocheck(x, ptr, size)                              \
++({                                                                    \
++      typeof(*(ptr)) __pu_val;                                        \
++      int __pu_err = 0;                                               \
++                                                                      \
++      __pu_val = (x);                                                 \
++      switch (size) {                                                 \
++      case 1: __put_user_asm("b", ptr, __pu_val, __pu_err); break;    \
++      case 2: __put_user_asm("h", ptr, __pu_val, __pu_err); break;    \
++      case 4: __put_user_asm("w", ptr, __pu_val, __pu_err); break;    \
++      case 8: __put_user_asm("d", ptr, __pu_val, __pu_err); break;    \
++      default: __pu_err = __put_user_bad(); break;                    \
++      }                                                               \
++      __pu_err;                                                       \
++})
++
++#define __put_user_check(x, ptr, size)                                        \
++({                                                                    \
++      typeof(*(ptr)) __pu_val;                                        \
++      typeof(*(ptr)) __user *__pu_addr = (ptr);                       \
++      int __pu_err = 0;                                               \
++                                                                      \
++      __pu_val = (x);                                                 \
++      if (access_ok(VERIFY_WRITE, __pu_addr, size)) {                 \
++              switch (size) {                                         \
++              case 1:                                                 \
++                      __put_user_asm("b", __pu_addr, __pu_val,        \
++                                     __pu_err);                       \
++                      break;                                          \
++              case 2:                                                 \
++                      __put_user_asm("h", __pu_addr, __pu_val,        \
++                                     __pu_err);                       \
++                      break;                                          \
++              case 4:                                                 \
++                      __put_user_asm("w", __pu_addr, __pu_val,        \
++                                     __pu_err);                       \
++                      break;                                          \
++              case 8:                                                 \
++                      __put_user_asm("d", __pu_addr, __pu_val,                \
++                                     __pu_err);                       \
++                      break;                                          \
++              default:                                                \
++                      __pu_err = __put_user_bad();                    \
++                      break;                                          \
++              }                                                       \
++      } else {                                                        \
++              __pu_err = -EFAULT;                                     \
++      }                                                               \
++      __pu_err;                                                       \
++})
++
++#define __put_user_asm(suffix, ptr, __pu_val, __gu_err)                       \
++      asm volatile(                                                   \
++              "1:     st." suffix "   %1, %3                  \n"     \
++              "2:                                             \n"     \
++              "       .section .fixup, \"ax\"                 \n"     \
++              "3:     mov     %0, %4                          \n"     \
++              "       rjmp    2b                              \n"     \
++              "       .previous                               \n"     \
++              "       .section __ex_table, \"a\"              \n"     \
++              "       .long   1b, 3b                          \n"     \
++              "       .previous                               \n"     \
++              : "=r"(__gu_err), "=m"(*(ptr))                          \
++              : "0"(__gu_err), "r"(__pu_val), "i"(-EFAULT))
++
++extern __kernel_size_t clear_user(void __user *addr, __kernel_size_t size);
++extern __kernel_size_t __clear_user(void __user *addr, __kernel_size_t size);
++
++extern long strncpy_from_user(char *dst, const char __user *src, long count);
++extern long __strncpy_from_user(char *dst, const char __user *src, long count);
++
++extern long strnlen_user(const char __user *__s, long __n);
++extern long __strnlen_user(const char __user *__s, long __n);
++
++#define strlen_user(s) strnlen_user(s, ~0UL >> 1)
++
++struct exception_table_entry
++{
++      unsigned long insn, fixup;
++};
++
++#endif /* __ASM_AVR32_UACCESS_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/ucontext.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/ucontext.h    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,12 @@
++#ifndef __ASM_AVR32_UCONTEXT_H
++#define __ASM_AVR32_UCONTEXT_H
++
++struct ucontext {
++      unsigned long           uc_flags;
++      struct ucontext *       uc_link;
++      stack_t                 uc_stack;
++      struct sigcontext       uc_mcontext;
++      sigset_t                uc_sigmask;
++};
++
++#endif /* __ASM_AVR32_UCONTEXT_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/unaligned.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/unaligned.h   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,25 @@
++#ifndef __ASM_AVR32_UNALIGNED_H
++#define __ASM_AVR32_UNALIGNED_H
++
++/*
++ * AVR32 can handle some unaligned accesses, depending on the
++ * implementation.  The AVR32 AP implementation can handle unaligned
++ * words, but halfwords must be halfword-aligned, and doublewords must
++ * be word-aligned.
++ *
++ * TODO: Make all this CPU-specific and optimize.
++ */
++
++#include <linux/string.h>
++
++/* Use memmove here, so gcc does not insert a __builtin_memcpy. */
++
++#define get_unaligned(ptr) \
++  ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
++
++#define put_unaligned(val, ptr)                               \
++  ({ __typeof__(*(ptr)) __tmp = (val);                        \
++     memmove((ptr), &__tmp, sizeof(*(ptr)));          \
++     (void)0; })
++
++#endif /* __ASM_AVR32_UNALIGNED_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/unistd.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/unistd.h      2006-12-04 11:50:25.000000000 +0100
+@@ -0,0 +1,387 @@
++/*
++ * 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 __ASM_AVR32_UNISTD_H
++#define __ASM_AVR32_UNISTD_H
++
++/*
++ * This file contains the system call numbers.
++ */
++
++#define __NR_restart_syscall      0
++#define __NR_exit               1
++#define __NR_fork               2
++#define __NR_read               3
++#define __NR_write              4
++#define __NR_open               5
++#define __NR_close              6
++#define __NR_umask              7
++#define __NR_creat              8
++#define __NR_link               9
++#define __NR_unlink            10
++#define __NR_execve            11
++#define __NR_chdir             12
++#define __NR_time              13
++#define __NR_mknod             14
++#define __NR_chmod             15
++#define __NR_chown             16
++#define __NR_lchown            17
++#define __NR_lseek             18
++#define __NR__llseek           19
++#define __NR_getpid            20
++#define __NR_mount             21
++#define __NR_umount2           22
++#define __NR_setuid            23
++#define __NR_getuid            24
++#define __NR_stime             25
++#define __NR_ptrace            26
++#define __NR_alarm             27
++#define __NR_pause             28
++#define __NR_utime             29
++#define __NR_stat              30
++#define __NR_fstat             31
++#define __NR_lstat             32
++#define __NR_access            33
++#define __NR_chroot            34
++#define __NR_sync              35
++#define __NR_fsync             36
++#define __NR_kill              37
++#define __NR_rename            38
++#define __NR_mkdir             39
++#define __NR_rmdir             40
++#define __NR_dup               41
++#define __NR_pipe              42
++#define __NR_times             43
++#define __NR_clone             44
++#define __NR_brk               45
++#define __NR_setgid            46
++#define __NR_getgid            47
++#define __NR_getcwd            48
++#define __NR_geteuid           49
++#define __NR_getegid           50
++#define __NR_acct              51
++#define __NR_setfsuid          52
++#define __NR_setfsgid          53
++#define __NR_ioctl             54
++#define __NR_fcntl             55
++#define __NR_setpgid           56
++#define __NR_mremap            57
++#define __NR_setresuid                 58
++#define __NR_getresuid                 59
++#define __NR_setreuid          60
++#define __NR_setregid          61
++#define __NR_ustat             62
++#define __NR_dup2              63
++#define __NR_getppid           64
++#define __NR_getpgrp           65
++#define __NR_setsid            66
++#define __NR_rt_sigaction      67
++#define __NR_rt_sigreturn      68
++#define __NR_rt_sigprocmask    69
++#define __NR_rt_sigpending     70
++#define __NR_rt_sigtimedwait   71
++#define __NR_rt_sigqueueinfo   72
++#define __NR_rt_sigsuspend     73
++#define __NR_sethostname       74
++#define __NR_setrlimit                 75
++#define __NR_getrlimit                 76     /* SuS compliant getrlimit */
++#define __NR_getrusage                 77
++#define __NR_gettimeofday      78
++#define __NR_settimeofday      79
++#define __NR_getgroups                 80
++#define __NR_setgroups                 81
++#define __NR_select            82
++#define __NR_symlink           83
++#define __NR_fchdir            84
++#define __NR_readlink          85
++#define __NR_pread             86
++#define __NR_pwrite            87
++#define __NR_swapon            88
++#define __NR_reboot            89
++#define __NR_mmap2             90
++#define __NR_munmap            91
++#define __NR_truncate          92
++#define __NR_ftruncate                 93
++#define __NR_fchmod            94
++#define __NR_fchown            95
++#define __NR_getpriority       96
++#define __NR_setpriority       97
++#define __NR_wait4             98
++#define __NR_statfs            99
++#define __NR_fstatfs          100
++#define __NR_vhangup          101
++#define __NR_sigaltstack      102
++#define __NR_syslog           103
++#define __NR_setitimer                104
++#define __NR_getitimer                105
++#define __NR_swapoff          106
++#define __NR_sysinfo          107
++#define __NR_ipc              108
++#define __NR_sendfile         109
++#define __NR_setdomainname    110
++#define __NR_uname            111
++#define __NR_adjtimex         112
++#define __NR_mprotect         113
++#define __NR_vfork            114
++#define __NR_init_module      115
++#define __NR_delete_module    116
++#define __NR_quotactl         117
++#define __NR_getpgid          118
++#define __NR_bdflush          119
++#define __NR_sysfs            120
++#define __NR_personality      121
++#define __NR_afs_syscall      122 /* Syscall for Andrew File System */
++#define __NR_getdents         123
++#define __NR_flock            124
++#define __NR_msync            125
++#define __NR_readv            126
++#define __NR_writev           127
++#define __NR_getsid           128
++#define __NR_fdatasync                129
++#define __NR__sysctl          130
++#define __NR_mlock            131
++#define __NR_munlock          132
++#define __NR_mlockall         133
++#define __NR_munlockall               134
++#define __NR_sched_setparam           135
++#define __NR_sched_getparam           136
++#define __NR_sched_setscheduler               137
++#define __NR_sched_getscheduler               138
++#define __NR_sched_yield              139
++#define __NR_sched_get_priority_max   140
++#define __NR_sched_get_priority_min   141
++#define __NR_sched_rr_get_interval    142
++#define __NR_nanosleep                143
++#define __NR_poll             144
++#define __NR_nfsservctl               145
++#define __NR_setresgid                146
++#define __NR_getresgid                147
++#define __NR_prctl              148
++#define __NR_socket           149
++#define __NR_bind             150
++#define __NR_connect          151
++#define __NR_listen           152
++#define __NR_accept           153
++#define __NR_getsockname      154
++#define __NR_getpeername      155
++#define __NR_socketpair               156
++#define __NR_send             157
++#define __NR_recv             158
++#define __NR_sendto           159
++#define __NR_recvfrom         160
++#define __NR_shutdown         161
++#define __NR_setsockopt               162
++#define __NR_getsockopt               163
++#define __NR_sendmsg          164
++#define __NR_recvmsg          165
++#define __NR_truncate64               166
++#define __NR_ftruncate64      167
++#define __NR_stat64           168
++#define __NR_lstat64          169
++#define __NR_fstat64          170
++#define __NR_pivot_root               171
++#define __NR_mincore          172
++#define __NR_madvise          173
++#define __NR_getdents64               174
++#define __NR_fcntl64          175
++#define __NR_gettid           176
++#define __NR_readahead                177
++#define __NR_setxattr         178
++#define __NR_lsetxattr                179
++#define __NR_fsetxattr                180
++#define __NR_getxattr         181
++#define __NR_lgetxattr                182
++#define __NR_fgetxattr                183
++#define __NR_listxattr                184
++#define __NR_llistxattr               185
++#define __NR_flistxattr               186
++#define __NR_removexattr      187
++#define __NR_lremovexattr     188
++#define __NR_fremovexattr     189
++#define __NR_tkill            190
++#define __NR_sendfile64               191
++#define __NR_futex            192
++#define __NR_sched_setaffinity        193
++#define __NR_sched_getaffinity        194
++#define __NR_capget           195
++#define __NR_capset           196
++#define __NR_io_setup         197
++#define __NR_io_destroy               198
++#define __NR_io_getevents     199
++#define __NR_io_submit                200
++#define __NR_io_cancel                201
++#define __NR_fadvise64                202
++#define __NR_exit_group               203
++#define __NR_lookup_dcookie   204
++#define __NR_epoll_create     205
++#define __NR_epoll_ctl                206
++#define __NR_epoll_wait               207
++#define __NR_remap_file_pages 208
++#define __NR_set_tid_address  209
++
++#define __NR_timer_create     210
++#define __NR_timer_settime    211
++#define __NR_timer_gettime    212
++#define __NR_timer_getoverrun 213
++#define __NR_timer_delete     214
++#define __NR_clock_settime    215
++#define __NR_clock_gettime    216
++#define __NR_clock_getres     217
++#define __NR_clock_nanosleep  218
++#define __NR_statfs64         219
++#define __NR_fstatfs64                220
++#define __NR_tgkill           221
++                              /* 222 reserved for tux */
++#define __NR_utimes           223
++#define __NR_fadvise64_64     224
++
++#define __NR_cacheflush               225
++
++#define __NR_vserver          226
++#define __NR_mq_open          227
++#define __NR_mq_unlink                228
++#define __NR_mq_timedsend     229
++#define __NR_mq_timedreceive  230
++#define __NR_mq_notify                231
++#define __NR_mq_getsetattr    232
++#define __NR_kexec_load               233
++#define __NR_waitid           234
++#define __NR_add_key          235
++#define __NR_request_key      236
++#define __NR_keyctl           237
++#define __NR_ioprio_set               238
++#define __NR_ioprio_get               239
++#define __NR_inotify_init     240
++#define __NR_inotify_add_watch        241
++#define __NR_inotify_rm_watch 242
++#define __NR_openat           243
++#define __NR_mkdirat          244
++#define __NR_mknodat          245
++#define __NR_fchownat         246
++#define __NR_futimesat                247
++#define __NR_fstatat64                248
++#define __NR_unlinkat         249
++#define __NR_renameat         250
++#define __NR_linkat           251
++#define __NR_symlinkat                252
++#define __NR_readlinkat               253
++#define __NR_fchmodat         254
++#define __NR_faccessat                255
++#define __NR_pselect6         256
++#define __NR_ppoll            257
++#define __NR_unshare          258
++#define __NR_set_robust_list  259
++#define __NR_get_robust_list  260
++#define __NR_splice           261
++#define __NR_sync_file_range  262
++#define __NR_tee              263
++#define __NR_vmsplice         264
++
++#define NR_syscalls           265
++
++
++/*
++ * AVR32 calling convention for system calls:
++ *   - System call number in r8
++ *   - Parameters in r12 and downwards to r9 as well as r6 and r5.
++ *   - Return value in r12
++ */
++
++/*
++ * user-visible error numbers are in the range -1 - -124: see
++ * <asm-generic/errno.h>
++ */
++
++#define __syscall_return(type, res) do {                              \
++              if ((unsigned long)(res) >= (unsigned long)(-125)) {    \
++                      errno = -(res);                                 \
++                      res = -1;                                       \
++              }                                                       \
++              return (type) (res);                                    \
++      } while (0)
++
++#ifdef __KERNEL__
++#define __ARCH_WANT_IPC_PARSE_VERSION
++#define __ARCH_WANT_STAT64
++#define __ARCH_WANT_SYS_ALARM
++#define __ARCH_WANT_SYS_GETHOSTNAME
++#define __ARCH_WANT_SYS_PAUSE
++#define __ARCH_WANT_SYS_TIME
++#define __ARCH_WANT_SYS_UTIME
++#define __ARCH_WANT_SYS_WAITPID
++#define __ARCH_WANT_SYS_FADVISE64
++#define __ARCH_WANT_SYS_GETPGRP
++#define __ARCH_WANT_SYS_LLSEEK
++#define __ARCH_WANT_SYS_GETPGRP
++#define __ARCH_WANT_SYS_RT_SIGACTION
++#define __ARCH_WANT_SYS_RT_SIGSUSPEND
++#endif
++
++#if defined(__KERNEL_SYSCALLS__) || defined(__CHECKER__)
++
++#include <linux/types.h>
++#include <linux/linkage.h>
++#include <asm/signal.h>
++
++struct pt_regs;
++
++/*
++ * we need this inline - forking from kernel space will result
++ * in NO COPY ON WRITE (!!!), until an execve is executed. This
++ * is no problem, but for the stack. This is handled by not letting
++ * main() use the stack at all after fork(). Thus, no function
++ * calls - which means inline code for fork too, as otherwise we
++ * would use the stack upon exit from 'fork()'.
++ *
++ * Actually only pause and fork are needed inline, so that there
++ * won't be any messing with the stack from main(), but we define
++ * some others too.
++ */
++static inline int execve(const char *file, char **argv, char **envp)
++{
++      register long scno asm("r8") = __NR_execve;
++      register long sc1 asm("r12") = (long)file;
++      register long sc2 asm("r11") = (long)argv;
++      register long sc3 asm("r10") = (long)envp;
++      int res;
++
++      asm volatile("scall"
++                   : "=r"(sc1)
++                   : "r"(scno), "0"(sc1), "r"(sc2), "r"(sc3)
++                   : "lr", "memory");
++      res = sc1;
++      __syscall_return(int, res);
++}
++
++asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize);
++asmlinkage int sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
++                             struct pt_regs *regs);
++asmlinkage int sys_rt_sigreturn(struct pt_regs *regs);
++asmlinkage int sys_pipe(unsigned long __user *filedes);
++asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
++                        unsigned long prot, unsigned long flags,
++                        unsigned long fd, off_t offset);
++asmlinkage int sys_cacheflush(int operation, void __user *addr, size_t len);
++asmlinkage int sys_fork(struct pt_regs *regs);
++asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
++                       unsigned long parent_tidptr,
++                       unsigned long child_tidptr, struct pt_regs *regs);
++asmlinkage int sys_vfork(struct pt_regs *regs);
++asmlinkage int sys_execve(char __user *ufilename, char __user *__user *uargv,
++                        char __user *__user *uenvp, struct pt_regs *regs);
++
++#endif
++
++/*
++ * "Conditional" syscalls
++ *
++ * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
++ * but it doesn't work on all toolchains, so we just do it by hand
++ */
++#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
++
++#endif /* __ASM_AVR32_UNISTD_H */
+Index: linux-2.6.18-avr32/include/asm-avr32/user.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/user.h        2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,64 @@
++/*
++ * 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.
++ *
++ * Note: We may not need these definitions for AVR32, as we don't
++ * support a.out.
++ */
++#ifndef __ASM_AVR32_USER_H
++#define __ASM_AVR32_USER_H
++
++#include <asm/ptrace.h>
++#include <asm/page.h>
++
++/*
++ * Core file format: The core file is written in such a way that gdb
++ * can understand it and provide useful information to the user (under
++ * linux we use the `trad-core' bfd).  The file contents are as follows:
++ *
++ *  upage: 1 page consisting of a user struct that tells gdb
++ *    what is present in the file.  Directly after this is a
++ *    copy of the task_struct, which is currently not used by gdb,
++ *    but it may come in handy at some point.  All of the registers
++ *    are stored as part of the upage.  The upage should always be
++ *    only one page long.
++ *  data: The data segment follows next.  We use current->end_text to
++ *    current->brk to pick up all of the user variables, plus any memory
++ *    that may have been sbrk'ed.  No attempt is made to determine if a
++ *    page is demand-zero or if a page is totally unused, we just cover
++ *    the entire range.  All of the addresses are rounded in such a way
++ *    that an integral number of pages is written.
++ *  stack: We need the stack information in order to get a meaningful
++ *    backtrace.  We need to write the data from usp to
++ *    current->start_stack, so we round each of these in order to be able
++ *    to write an integer number of pages.
++ */
++
++struct user_fpu_struct {
++      /* We have no FPU (yet) */
++};
++
++struct user {
++      struct pt_regs  regs;                   /* entire machine state */
++      size_t          u_tsize;                /* text size (pages) */
++      size_t          u_dsize;                /* data size (pages) */
++      size_t          u_ssize;                /* stack size (pages) */
++      unsigned long   start_code;             /* text starting address */
++      unsigned long   start_data;             /* data starting address */
++      unsigned long   start_stack;            /* stack starting address */
++      long int        signal;                 /* signal causing core dump */
++      struct regs *   u_ar0;                  /* help gdb find registers */
++      unsigned long   magic;                  /* identifies a core file */
++      char            u_comm[32];             /* user command name */
++};
++
++#define NBPG                  PAGE_SIZE
++#define UPAGES                        1
++#define HOST_TEXT_START_ADDR  (u.start_code)
++#define HOST_DATA_START_ADDR  (u.start_data)
++#define HOST_STACK_END_ADDR   (u.start_stack + u.u_ssize * NBPG)
++
++#endif /* __ASM_AVR32_USER_H */
+Index: linux-2.6.18-avr32/include/linux/elf-em.h
+===================================================================
+--- linux-2.6.18-avr32.orig/include/linux/elf-em.h     2006-12-04 09:32:57.000000000 +0100
++++ linux-2.6.18-avr32/include/linux/elf-em.h  2006-12-04 09:33:12.000000000 +0100
+@@ -31,6 +31,7 @@
+ #define EM_M32R               88      /* Renesas M32R */
+ #define EM_H8_300     46      /* Renesas H8/300,300H,H8S */
+ #define EM_FRV                0x5441  /* Fujitsu FR-V */
++#define EM_AVR32      0x18ad  /* Atmel AVR32 */
+ /*
+  * This is an interim value that we will use until the committee comes
+Index: linux-2.6.18-avr32/include/asm-avr32/irqflags.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/irqflags.h    2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,68 @@
++/*
++ * 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 __ASM_AVR32_IRQFLAGS_H
++#define __ASM_AVR32_IRQFLAGS_H
++
++#include <asm/sysreg.h>
++
++static inline unsigned long __raw_local_save_flags(void)
++{
++      return sysreg_read(SR);
++}
++
++#define raw_local_save_flags(x)                                       \
++      do { (x) = __raw_local_save_flags(); } while (0)
++
++/*
++ * This will restore ALL status register flags, not only the interrupt
++ * mask flag.
++ *
++ * The empty asm statement informs the compiler of this fact while
++ * also serving as a barrier.
++ */
++static inline void raw_local_irq_restore(unsigned long flags)
++{
++      sysreg_write(SR, flags);
++      asm volatile("" : : : "memory", "cc");
++}
++
++static inline void raw_local_irq_disable(void)
++{
++      asm volatile("ssrf %0" : : "n"(SYSREG_GM_OFFSET) : "memory");
++}
++
++static inline void raw_local_irq_enable(void)
++{
++      asm volatile("csrf %0" : : "n"(SYSREG_GM_OFFSET) : "memory");
++}
++
++static inline int raw_irqs_disabled_flags(unsigned long flags)
++{
++      return (flags & SYSREG_BIT(GM)) != 0;
++}
++
++static inline int raw_irqs_disabled(void)
++{
++      unsigned long flags = __raw_local_save_flags();
++
++      return raw_irqs_disabled_flags(flags);
++}
++
++static inline unsigned long __raw_local_irq_save(void)
++{
++      unsigned long flags = __raw_local_save_flags();
++
++      raw_local_irq_disable();
++
++      return flags;
++}
++
++#define raw_local_irq_save(flags)                             \
++      do { (flags) = __raw_local_irq_save(); } while (0)
++
++#endif /* __ASM_AVR32_IRQFLAGS_H */
+Index: linux-2.6.18-avr32/lib/Kconfig.debug
+===================================================================
+--- linux-2.6.18-avr32.orig/lib/Kconfig.debug  2006-12-04 09:32:57.000000000 +0100
++++ linux-2.6.18-avr32/lib/Kconfig.debug       2006-12-04 09:33:12.000000000 +0100
+@@ -277,7 +277,7 @@ config DEBUG_HIGHMEM
+ config DEBUG_BUGVERBOSE
+       bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED
+       depends on BUG
+-      depends on ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64 || X86_32 || FRV
++      depends on ARM || ARM26 || AVR32 || M32R || M68K || SPARC32 || SPARC64 || X86_32 || FRV
+       default !EMBEDDED
+       help
+         Say Y here to make BUG() panics output the file name and line number
+@@ -315,7 +315,7 @@ config DEBUG_VM
+ config FRAME_POINTER
+       bool "Compile the kernel with frame pointers"
+-      depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390)
++      depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML || S390 || AVR32)
+       default y if DEBUG_INFO && UML
+       help
+         If you say Y here the resulting kernel image will be slightly larger
+Index: linux-2.6.18-avr32/arch/avr32/boards/atstk1000/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/boards/atstk1000/Makefile    2006-12-04 11:50:22.000000000 +0100
+@@ -0,0 +1,2 @@
++obj-y                         += setup.o spi.o flash.o
++obj-$(CONFIG_BOARD_ATSTK1002) += atstk1002.o
+Index: linux-2.6.18-avr32/arch/avr32/boards/atstk1000/atstk1002.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/boards/atstk1000/atstk1002.c 2006-12-04 11:50:25.000000000 +0100
+@@ -0,0 +1,37 @@
++/*
++ * ATSTK1002 daughterboard-specific init code
++ *
++ * Copyright (C) 2005-2006 Atmel Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/init.h>
++
++#include <asm/arch/board.h>
++
++struct eth_platform_data __initdata eth0_data = {
++      .valid          = 1,
++      .mii_phy_addr   = 0x10,
++      .is_rmii        = 0,
++      .hw_addr        = { 0x6a, 0x87, 0x71, 0x14, 0xcd, 0xcb },
++};
++
++extern struct lcdc_platform_data atstk1000_fb0_data;
++
++static int __init atstk1002_init(void)
++{
++      at32_add_system_devices();
++
++      at32_add_device_usart(1);       /* /dev/ttyS0 */
++      at32_add_device_usart(2);       /* /dev/ttyS1 */
++      at32_add_device_usart(3);       /* /dev/ttyS2 */
++
++      at32_add_device_eth(0, &eth0_data);
++      at32_add_device_spi(0);
++      at32_add_device_lcdc(0, &atstk1000_fb0_data);
++
++      return 0;
++}
++postcore_initcall(atstk1002_init);
+Index: linux-2.6.18-avr32/arch/avr32/boards/atstk1000/setup.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/boards/atstk1000/setup.c     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,50 @@
++/*
++ * ATSTK1000 board-specific setup code.
++ *
++ * Copyright (C) 2005-2006 Atmel Corporation
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/bootmem.h>
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/linkage.h>
++
++#include <asm/setup.h>
++
++#include <asm/arch/board.h>
++
++/* Initialized by bootloader-specific startup code. */
++struct tag *bootloader_tags __initdata;
++
++struct lcdc_platform_data __initdata atstk1000_fb0_data;
++
++void __init board_setup_fbmem(unsigned long fbmem_start,
++                            unsigned long fbmem_size)
++{
++      if (!fbmem_size)
++              return;
++
++      if (!fbmem_start) {
++              void *fbmem;
++
++              fbmem = alloc_bootmem_low_pages(fbmem_size);
++              fbmem_start = __pa(fbmem);
++      } else {
++              pg_data_t *pgdat;
++
++              for_each_online_pgdat(pgdat) {
++                      if (fbmem_start >= pgdat->bdata->node_boot_start
++                          && fbmem_start <= pgdat->bdata->node_low_pfn)
++                              reserve_bootmem_node(pgdat, fbmem_start,
++                                                   fbmem_size);
++              }
++      }
++
++      printk("%luKiB framebuffer memory at address 0x%08lx\n",
++             fbmem_size >> 10, fbmem_start);
++      atstk1000_fb0_data.fbmem_start = fbmem_start;
++      atstk1000_fb0_data.fbmem_size = fbmem_size;
++}
+Index: linux-2.6.18-avr32/arch/avr32/boards/atstk1000/spi.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/boards/atstk1000/spi.c       2006-12-04 11:50:22.000000000 +0100
+@@ -0,0 +1,27 @@
++/*
++ * ATSTK1000 SPI devices
++ *
++ * Copyright (C) 2005 Atmel Norway
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++#include <linux/device.h>
++#include <linux/spi/spi.h>
++
++static struct spi_board_info spi_board_info[] __initdata = {
++      {
++              .modalias       = "ltv350qv",
++              .max_speed_hz   = 16000000,
++              .bus_num        = 0,
++              .chip_select    = 1,
++      },
++};
++
++static int board_init_spi(void)
++{
++      spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
++      return 0;
++}
++arch_initcall(board_init_spi);
+Index: linux-2.6.18-avr32/arch/avr32/configs/atstk1002_defconfig
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/configs/atstk1002_defconfig  2006-12-04 11:50:21.000000000 +0100
+@@ -0,0 +1,754 @@
++#
++# Automatically generated make config: don't edit
++# Linux kernel version: 2.6.18-rc1
++# Tue Jul 11 12:41:36 2006
++#
++CONFIG_AVR32=y
++CONFIG_GENERIC_HARDIRQS=y
++CONFIG_HARDIRQS_SW_RESEND=y
++CONFIG_GENERIC_IRQ_PROBE=y
++CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_HWEIGHT=y
++CONFIG_GENERIC_CALIBRATE_DELAY=y
++CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
++
++#
++# Code maturity level options
++#
++CONFIG_EXPERIMENTAL=y
++CONFIG_BROKEN_ON_SMP=y
++CONFIG_INIT_ENV_ARG_LIMIT=32
++
++#
++# General setup
++#
++CONFIG_LOCALVERSION=""
++# CONFIG_LOCALVERSION_AUTO is not set
++CONFIG_SWAP=y
++# CONFIG_SYSVIPC is not set
++# CONFIG_POSIX_MQUEUE is not set
++# CONFIG_BSD_PROCESS_ACCT is not set
++CONFIG_SYSCTL=y
++# CONFIG_AUDIT is not set
++# CONFIG_IKCONFIG is not set
++# CONFIG_RELAY is not set
++CONFIG_INITRAMFS_SOURCE=""
++CONFIG_CC_OPTIMIZE_FOR_SIZE=y
++CONFIG_EMBEDDED=y
++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_BASE_FULL is not set
++# CONFIG_FUTEX is not set
++# CONFIG_EPOLL is not set
++CONFIG_SHMEM=y
++# CONFIG_SLAB is not set
++# CONFIG_VM_EVENT_COUNTERS is not set
++# CONFIG_TINY_SHMEM is not set
++CONFIG_BASE_SMALL=1
++CONFIG_SLOB=y
++
++#
++# Loadable module support
++#
++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
++
++#
++# Block layer
++#
++# CONFIG_BLK_DEV_IO_TRACE is not set
++
++#
++# IO Schedulers
++#
++CONFIG_IOSCHED_NOOP=y
++# CONFIG_IOSCHED_AS is not set
++# CONFIG_IOSCHED_DEADLINE is not set
++# CONFIG_IOSCHED_CFQ is not set
++# 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"
++
++#
++# System Type and features
++#
++CONFIG_SUBARCH_AVR32B=y
++CONFIG_MMU=y
++CONFIG_PERFORMANCE_COUNTERS=y
++CONFIG_PLATFORM_AT32AP=y
++CONFIG_CPU_AT32AP7000=y
++CONFIG_BOARD_ATSTK1002=y
++CONFIG_BOARD_ATSTK1000=y
++CONFIG_LOADER_U_BOOT=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_SPLIT_PTLOCK_CPUS=4
++# CONFIG_RESOURCES_64BIT is not set
++# CONFIG_OWNERSHIP_TRACE is not set
++# CONFIG_HZ_100 is not set
++CONFIG_HZ_250=y
++# CONFIG_HZ_1000 is not set
++CONFIG_HZ=250
++CONFIG_CMDLINE=""
++
++#
++# Bus options
++#
++
++#
++# PCCARD (PCMCIA/CardBus) support
++#
++# 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_NETDEBUG is not set
++CONFIG_PACKET=y
++CONFIG_PACKET_MMAP=y
++CONFIG_UNIX=y
++# CONFIG_NET_KEY 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 is not set
++# CONFIG_NET_IPGRE is not set
++# CONFIG_ARPD is not set
++# CONFIG_SYN_COOKIES is not set
++# CONFIG_INET_AH is not set
++# CONFIG_INET_ESP is not set
++# CONFIG_INET_IPCOMP is not set
++# CONFIG_INET_XFRM_TUNNEL is not set
++# CONFIG_INET_TUNNEL is not set
++# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
++# CONFIG_INET_XFRM_MODE_TUNNEL is not set
++CONFIG_INET_DIAG=y
++CONFIG_INET_TCP_DIAG=y
++# CONFIG_TCP_CONG_ADVANCED is not set
++CONFIG_TCP_CONG_BIC=y
++# CONFIG_IPV6 is not set
++# CONFIG_INET6_XFRM_TUNNEL is not set
++# CONFIG_INET6_TUNNEL is not set
++# CONFIG_NETWORK_SECMARK is not set
++# CONFIG_NETFILTER is not set
++
++#
++# DCCP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_DCCP is not set
++
++#
++# SCTP Configuration (EXPERIMENTAL)
++#
++# CONFIG_IP_SCTP is not set
++
++#
++# TIPC Configuration (EXPERIMENTAL)
++#
++# CONFIG_TIPC is not set
++# CONFIG_ATM is not set
++# CONFIG_BRIDGE is not set
++# CONFIG_VLAN_8021Q is not set
++# CONFIG_DECNET is not set
++# 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_NET_DIVERT is not set
++# CONFIG_ECONET is not set
++# CONFIG_WAN_ROUTER is not set
++
++#
++# QoS and/or fair queueing
++#
++# 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_IRDA is not set
++# CONFIG_BT is not set
++# CONFIG_IEEE80211 is not set
++
++#
++# Device Drivers
++#
++
++#
++# Generic Driver Options
++#
++CONFIG_STANDALONE=y
++# CONFIG_PREVENT_FIRMWARE_BUILD is not set
++# CONFIG_FW_LOADER is not set
++# CONFIG_DEBUG_DRIVER is not set
++# CONFIG_SYS_HYPERVISOR is not set
++
++#
++# Connector - unified userspace <-> kernelspace linker
++#
++# CONFIG_CONNECTOR is not set
++
++#
++# Memory Technology Devices (MTD)
++#
++# CONFIG_MTD is not set
++
++#
++# Parallel port support
++#
++# CONFIG_PARPORT is not set
++
++#
++# Plug and Play support
++#
++
++#
++# Block devices
++#
++# 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_INITRD=y
++# CONFIG_CDROM_PKTCDVD is not set
++# CONFIG_ATA_OVER_ETH is not set
++
++#
++# ATA/ATAPI/MFM/RLL support
++#
++# CONFIG_IDE is not set
++
++#
++# SCSI device support
++#
++# CONFIG_RAID_ATTRS is not set
++# CONFIG_SCSI is not set
++
++#
++# Multi-device support (RAID and LVM)
++#
++# CONFIG_MD is not set
++
++#
++# Fusion MPT device support
++#
++# CONFIG_FUSION is not set
++
++#
++# IEEE 1394 (FireWire) support
++#
++
++#
++# I2O device support
++#
++
++#
++# Network device support
++#
++CONFIG_NETDEVICES=y
++CONFIG_DUMMY=y
++# CONFIG_BONDING is not set
++# CONFIG_EQUALIZER is not set
++CONFIG_TUN=m
++
++#
++# PHY device support
++#
++# CONFIG_PHYLIB is not set
++
++#
++# Ethernet (10 or 100Mbit)
++#
++CONFIG_NET_ETHERNET=y
++CONFIG_MII=y
++CONFIG_MACB=y
++
++#
++# Ethernet (1000 Mbit)
++#
++
++#
++# Ethernet (10000 Mbit)
++#
++
++#
++# Token Ring devices
++#
++
++#
++# Wireless LAN (non-hamradio)
++#
++# CONFIG_NET_RADIO is not set
++
++#
++# Wan interfaces
++#
++# 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 is not set
++# CONFIG_PPP_MPPE is not set
++# CONFIG_PPPOE is not set
++# CONFIG_SLIP is not set
++# CONFIG_SHAPER is not set
++# CONFIG_NETCONSOLE is not set
++# CONFIG_NETPOLL is not set
++# CONFIG_NET_POLL_CONTROLLER is not set
++
++#
++# ISDN subsystem
++#
++# CONFIG_ISDN is not set
++
++#
++# Telephony Support
++#
++# CONFIG_PHONE is not set
++
++#
++# Input device support
++#
++# CONFIG_INPUT 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_AT91=y
++CONFIG_SERIAL_AT91_CONSOLE=y
++# CONFIG_SERIAL_AT91_TTYAT is not set
++CONFIG_SERIAL_CORE=y
++CONFIG_SERIAL_CORE_CONSOLE=y
++CONFIG_UNIX98_PTYS=y
++# CONFIG_LEGACY_PTYS is not set
++
++#
++# IPMI
++#
++# CONFIG_IPMI_HANDLER is not set
++
++#
++# Watchdog Cards
++#
++# CONFIG_WATCHDOG is not set
++# CONFIG_HW_RANDOM is not set
++# CONFIG_RTC is not set
++# CONFIG_GEN_RTC is not set
++# CONFIG_DTLK is not set
++# CONFIG_R3964 is not set
++
++#
++# Ftape, the floppy tape device driver
++#
++# CONFIG_RAW_DRIVER is not set
++
++#
++# TPM devices
++#
++# CONFIG_TCG_TPM is not set
++# CONFIG_TELCLOCK is not set
++
++#
++# I2C support
++#
++# CONFIG_I2C 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=m
++# CONFIG_SPI_BITBANG is not set
++
++#
++# SPI Protocol Masters
++#
++
++#
++# Dallas's 1-wire bus
++#
++
++#
++# Hardware Monitoring support
++#
++# CONFIG_HWMON is not set
++# CONFIG_HWMON_VID is not set
++
++#
++# Misc devices
++#
++
++#
++# Multimedia devices
++#
++# CONFIG_VIDEO_DEV is not set
++CONFIG_VIDEO_V4L2=y
++
++#
++# Digital Video Broadcasting Devices
++#
++# CONFIG_DVB is not set
++
++#
++# Graphics support
++#
++# CONFIG_FIRMWARE_EDID is not set
++CONFIG_FB=m
++CONFIG_FB_CFB_FILLRECT=m
++CONFIG_FB_CFB_COPYAREA=m
++CONFIG_FB_CFB_IMAGEBLIT=m
++# 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
++CONFIG_FB_SIDSA=m
++CONFIG_FB_SIDSA_DEFAULT_BPP=24
++# CONFIG_FB_S1D13XXX is not set
++# CONFIG_FB_VIRTUAL is not set
++
++#
++# Logo configuration
++#
++# CONFIG_LOGO is not set
++CONFIG_BACKLIGHT_LCD_SUPPORT=y
++# CONFIG_BACKLIGHT_CLASS_DEVICE is not set
++CONFIG_LCD_CLASS_DEVICE=m
++CONFIG_LCD_DEVICE=y
++CONFIG_LCD_LTV350QV=m
++
++#
++# Sound
++#
++# CONFIG_SOUND is not set
++
++#
++# USB support
++#
++# 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'
++#
++
++#
++# USB Gadget Support
++#
++# CONFIG_USB_GADGET is not set
++
++#
++# MMC/SD Card support
++#
++# CONFIG_MMC is not set
++
++#
++# LED devices
++#
++# CONFIG_NEW_LEDS is not set
++
++#
++# LED drivers
++#
++
++#
++# LED Triggers
++#
++
++#
++# InfiniBand support
++#
++
++#
++# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
++#
++
++#
++# Real Time Clock
++#
++# CONFIG_RTC_CLASS is not set
++
++#
++# DMA Engine support
++#
++# CONFIG_DMA_ENGINE is not set
++
++#
++# DMA Clients
++#
++
++#
++# DMA Devices
++#
++
++#
++# File systems
++#
++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_REISERFS_FS is not set
++# CONFIG_JFS_FS is not set
++# CONFIG_FS_POSIX_ACL is not set
++# CONFIG_XFS_FS is not set
++# CONFIG_OCFS2_FS is not set
++CONFIG_MINIX_FS=m
++CONFIG_ROMFS_FS=m
++# 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
++
++#
++# 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_SYSFS=y
++CONFIG_TMPFS=y
++# CONFIG_HUGETLB_PAGE is not set
++CONFIG_RAMFS=y
++CONFIG_CONFIGFS_FS=m
++
++#
++# 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_CRAMFS is not set
++# CONFIG_VXFS_FS is not set
++# CONFIG_HPFS_FS is not set
++# CONFIG_QNX4FS_FS is not set
++# CONFIG_SYSV_FS is not set
++# CONFIG_UFS_FS is not set
++
++#
++# Network File Systems
++#
++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_RPCSEC_GSS_KRB5 is not set
++# CONFIG_RPCSEC_GSS_SPKM3 is not set
++# CONFIG_SMB_FS 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
++# CONFIG_9P_FS is not set
++
++#
++# Partition Types
++#
++# CONFIG_PARTITION_ADVANCED is not set
++CONFIG_MSDOS_PARTITION=y
++
++#
++# Native Language Support
++#
++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=m
++# 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
++
++#
++# Kernel hacking
++#
++CONFIG_TRACE_IRQFLAGS_SUPPORT=y
++CONFIG_PRINTK_TIME=y
++CONFIG_MAGIC_SYSRQ=y
++# CONFIG_UNUSED_SYMBOLS is not set
++CONFIG_DEBUG_KERNEL=y
++CONFIG_LOG_BUF_SHIFT=14
++CONFIG_DETECT_SOFTLOCKUP=y
++# CONFIG_SCHEDSTATS is not set
++# CONFIG_DEBUG_SPINLOCK is not set
++# CONFIG_DEBUG_MUTEXES is not set
++# CONFIG_DEBUG_RWSEMS 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_FS=y
++# CONFIG_DEBUG_VM is not set
++CONFIG_FRAME_POINTER=y
++# CONFIG_UNWIND_INFO is not set
++CONFIG_FORCED_INLINING=y
++# CONFIG_RCU_TORTURE_TEST is not set
++CONFIG_KPROBES=y
++
++#
++# Security options
++#
++# CONFIG_KEYS is not set
++# CONFIG_SECURITY is not set
++
++#
++# Cryptographic options
++#
++# CONFIG_CRYPTO is not set
++
++#
++# Hardware crypto devices
++#
++
++#
++# Library routines
++#
++CONFIG_CRC_CCITT=m
++# CONFIG_CRC16 is not set
++CONFIG_CRC32=m
++# CONFIG_LIBCRC32C is not set
++CONFIG_ZLIB_INFLATE=m
++CONFIG_ZLIB_DEFLATE=m
+Index: linux-2.6.18-avr32/arch/avr32/lib/io-readsb.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/io-readsb.S      2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,49 @@
++/*
++ * 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.
++ */
++
++      .text
++.Lnot_word_aligned:
++1:    ld.ub   r8, r12[0]
++      sub     r10, 1
++      st.b    r11++, r8
++      reteq   r12
++      tst     r11, r9
++      brne    1b
++
++      /* fall through */
++
++      .global __raw_readsb
++      .type   __raw_readsb,@function
++__raw_readsb:
++      cp.w    r10, 0
++      mov     r9, 3
++      reteq   r12
++
++      tst     r11, r9
++      brne    .Lnot_word_aligned
++
++      sub     r10, 4
++      brlt    2f
++
++1:    ldins.b r8:t, r12[0]
++      ldins.b r8:u, r12[0]
++      ldins.b r8:l, r12[0]
++      ldins.b r8:b, r12[0]
++      st.w    r11++, r8
++      sub     r10, 4
++      brge    1b
++
++2:    sub     r10, -4
++      reteq   r12
++
++3:    ld.uh   r8, r12[0]
++      sub     r10, 1
++      st.b    r11++, r8
++      brne    3b
++
++      retal   r12
+Index: linux-2.6.18-avr32/arch/avr32/lib/io-writesb.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/lib/io-writesb.S     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,52 @@
++/*
++ * 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.
++ */
++
++      .text
++.Lnot_word_aligned:
++1:    ld.ub   r8, r11++
++      sub     r10, 1
++      st.b    r12[0], r8
++      reteq   r12
++      tst     r11, r9
++      brne    1b
++
++      /* fall through */
++
++      .global __raw_writesb
++      .type   __raw_writesb,@function
++__raw_writesb:
++      cp.w    r10, 0
++      mov     r9, 3
++      reteq   r12
++
++      tst     r11, r9
++      brne    .Lnot_word_aligned
++
++      sub     r10, 4
++      brlt    2f
++
++1:    ld.w    r8, r11++
++      bfextu  r9, r8, 24, 8
++      st.b    r12[0], r9
++      bfextu  r9, r8, 16, 8
++      st.b    r12[0], r9
++      bfextu  r9, r8, 8, 8
++      st.b    r12[0], r9
++      st.b    r12[0], r8
++      sub     r10, 4
++      brge    1b
++
++2:    sub     r10, -4
++      reteq   r12
++
++3:    ld.ub   r8, r11++
++      sub     r10, 1
++      st.b    r12[0], r8
++      brne    3b
++
++      retal   r12
+Index: linux-2.6.18-avr32/arch/avr32/boards/atstk1000/flash.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/boards/atstk1000/flash.c     2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,95 @@
++/*
++ * ATSTK1000 board-specific flash initialization
++ *
++ * 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/init.h>
++#include <linux/platform_device.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/mtd/physmap.h>
++
++#include <asm/arch/smc.h>
++
++static struct smc_config flash_config __initdata = {
++      .ncs_read_setup         = 0,
++      .nrd_setup              = 40,
++      .ncs_write_setup        = 0,
++      .nwe_setup              = 10,
++
++      .ncs_read_pulse         = 80,
++      .nrd_pulse              = 40,
++      .ncs_write_pulse        = 65,
++      .nwe_pulse              = 55,
++
++      .read_cycle             = 120,
++      .write_cycle            = 120,
++
++      .bus_width              = 2,
++      .nrd_controlled         = 1,
++      .nwe_controlled         = 1,
++      .byte_write             = 1,
++};
++
++static struct mtd_partition flash_parts[] = {
++      {
++              .name           = "u-boot",
++              .offset         = 0x00000000,
++              .size           = 0x00020000,           /* 128 KiB */
++              .mask_flags     = MTD_WRITEABLE,
++      },
++      {
++              .name           = "root",
++              .offset         = 0x00020000,
++              .size           = 0x007d0000,
++      },
++      {
++              .name           = "env",
++              .offset         = 0x007f0000,
++              .size           = 0x00010000,
++              .mask_flags     = MTD_WRITEABLE,
++      },
++};
++
++static struct physmap_flash_data flash_data = {
++      .width          = 2,
++      .nr_parts       = ARRAY_SIZE(flash_parts),
++      .parts          = flash_parts,
++};
++
++static struct resource flash_resource = {
++      .start          = 0x00000000,
++      .end            = 0x007fffff,
++      .flags          = IORESOURCE_MEM,
++};
++
++static struct platform_device flash_device = {
++      .name           = "physmap-flash",
++      .id             = 0,
++      .resource       = &flash_resource,
++      .num_resources  = 1,
++      .dev            = {
++              .platform_data = &flash_data,
++      },
++};
++
++/* This needs to be called after the SMC has been initialized */
++static int __init atstk1000_flash_init(void)
++{
++      int ret;
++
++      ret = smc_set_configuration(0, &flash_config);
++      if (ret < 0) {
++              printk(KERN_ERR "atstk1000: failed to set NOR flash timing\n");
++              return ret;
++      }
++
++      platform_device_register(&flash_device);
++
++      return 0;
++}
++device_initcall(atstk1000_flash_init);
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/hsmc.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/hsmc.c   2006-12-04 11:50:22.000000000 +0100
+@@ -0,0 +1,164 @@
++/*
++ * Static Memory Controller for AT32 chips
++ *
++ * 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.
++ */
++#define DEBUG
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/init.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include <asm/io.h>
++#include <asm/arch/smc.h>
++
++#include "hsmc.h"
++
++#define NR_CHIP_SELECTS 6
++
++struct hsmc {
++      void __iomem *regs;
++      struct clk *pclk;
++      struct clk *mck;
++};
++
++static struct hsmc *hsmc;
++
++int smc_set_configuration(int cs, const struct smc_config *config)
++{
++      unsigned long mul;
++      unsigned long offset;
++      u32 setup, pulse, cycle, mode;
++
++      if (!hsmc)
++              return -ENODEV;
++      if (cs >= NR_CHIP_SELECTS)
++              return -EINVAL;
++
++      /*
++       * cycles = x / T = x * f
++       *   = ((x * 1000000000) * ((f * 65536) / 1000000000)) / 65536
++       *   = ((x * 1000000000) * (((f / 10000) * 65536) / 100000)) / 65536
++       */
++      mul = (clk_get_rate(hsmc->mck) / 10000) << 16;
++      mul /= 100000;
++
++#define ns2cyc(x) ((((x) * mul) + 65535) >> 16)
++
++      setup = (HSMC_BF(NWE_SETUP, ns2cyc(config->nwe_setup))
++               | HSMC_BF(NCS_WR_SETUP, ns2cyc(config->ncs_write_setup))
++               | HSMC_BF(NRD_SETUP, ns2cyc(config->nrd_setup))
++               | HSMC_BF(NCS_RD_SETUP, ns2cyc(config->ncs_read_setup)));
++      pulse = (HSMC_BF(NWE_PULSE, ns2cyc(config->nwe_pulse))
++               | HSMC_BF(NCS_WR_PULSE, ns2cyc(config->ncs_write_pulse))
++               | HSMC_BF(NRD_PULSE, ns2cyc(config->nrd_pulse))
++               | HSMC_BF(NCS_RD_PULSE, ns2cyc(config->ncs_read_pulse)));
++      cycle = (HSMC_BF(NWE_CYCLE, ns2cyc(config->write_cycle))
++               | HSMC_BF(NRD_CYCLE, ns2cyc(config->read_cycle)));
++
++      switch (config->bus_width) {
++      case 1:
++              mode = HSMC_BF(DBW, HSMC_DBW_8_BITS);
++              break;
++      case 2:
++              mode = HSMC_BF(DBW, HSMC_DBW_16_BITS);
++              break;
++      case 4:
++              mode = HSMC_BF(DBW, HSMC_DBW_32_BITS);
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      if (config->nrd_controlled)
++              mode |= HSMC_BIT(READ_MODE);
++      if (config->nwe_controlled)
++              mode |= HSMC_BIT(WRITE_MODE);
++      if (config->byte_write)
++              mode |= HSMC_BIT(BAT);
++
++      pr_debug("smc cs%d: setup/%08x pulse/%08x cycle/%08x mode/%08x\n",
++               cs, setup, pulse, cycle, mode);
++
++      offset = cs * 0x10;
++      hsmc_writel(hsmc, SETUP0 + offset, setup);
++      hsmc_writel(hsmc, PULSE0 + offset, pulse);
++      hsmc_writel(hsmc, CYCLE0 + offset, cycle);
++      hsmc_writel(hsmc, MODE0 + offset, mode);
++      hsmc_readl(hsmc, MODE0); /* I/O barrier */
++
++      return 0;
++}
++EXPORT_SYMBOL(smc_set_configuration);
++
++static int hsmc_probe(struct platform_device *pdev)
++{
++      struct resource *regs;
++      struct clk *pclk, *mck;
++      int ret;
++
++      if (hsmc)
++              return -EBUSY;
++
++      regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++      if (!regs)
++              return -ENXIO;
++      pclk = clk_get(&pdev->dev, "pclk");
++      if (IS_ERR(pclk))
++              return PTR_ERR(pclk);
++      mck = clk_get(&pdev->dev, "mck");
++      if (IS_ERR(mck)) {
++              ret = PTR_ERR(mck);
++              goto out_put_pclk;
++      }
++
++      ret = -ENOMEM;
++      hsmc = kzalloc(sizeof(struct hsmc), GFP_KERNEL);
++      if (!hsmc)
++              goto out_put_clocks;
++
++      clk_enable(pclk);
++      clk_enable(mck);
++
++      hsmc->pclk = pclk;
++      hsmc->mck = mck;
++      hsmc->regs = ioremap(regs->start, regs->end - regs->start + 1);
++      if (!hsmc->regs)
++              goto out_disable_clocks;
++
++      dev_info(&pdev->dev, "Atmel Static Memory Controller at 0x%08lx\n",
++               (unsigned long)regs->start);
++
++      platform_set_drvdata(pdev, hsmc);
++
++      return 0;
++
++out_disable_clocks:
++      clk_disable(mck);
++      clk_disable(pclk);
++      kfree(hsmc);
++out_put_clocks:
++      clk_put(mck);
++out_put_pclk:
++      clk_put(pclk);
++      hsmc = NULL;
++      return ret;
++}
++
++static struct platform_driver hsmc_driver = {
++      .probe          = hsmc_probe,
++      .driver         = {
++              .name   = "smc",
++      },
++};
++
++static int __init hsmc_init(void)
++{
++      return platform_driver_register(&hsmc_driver);
++}
++arch_initcall(hsmc_init);
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/hsmc.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/hsmc.h   2006-12-04 09:33:12.000000000 +0100
+@@ -0,0 +1,127 @@
++/*
++ * Register definitions for Atmel Static Memory Controller (SMC)
++ *
++ * 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 __ASM_AVR32_HSMC_H__
++#define __ASM_AVR32_HSMC_H__
++
++/* HSMC register offsets */
++#define HSMC_SETUP0                           0x0000
++#define HSMC_PULSE0                           0x0004
++#define HSMC_CYCLE0                           0x0008
++#define HSMC_MODE0                            0x000c
++#define HSMC_SETUP1                           0x0010
++#define HSMC_PULSE1                           0x0014
++#define HSMC_CYCLE1                           0x0018
++#define HSMC_MODE1                            0x001c
++#define HSMC_SETUP2                           0x0020
++#define HSMC_PULSE2                           0x0024
++#define HSMC_CYCLE2                           0x0028
++#define HSMC_MODE2                            0x002c
++#define HSMC_SETUP3                           0x0030
++#define HSMC_PULSE3                           0x0034
++#define HSMC_CYCLE3                           0x0038
++#define HSMC_MODE3                            0x003c
++#define HSMC_SETUP4                           0x0040
++#define HSMC_PULSE4                           0x0044
++#define HSMC_CYCLE4                           0x0048
++#define HSMC_MODE4                            0x004c
++#define HSMC_SETUP5                           0x0050
++#define HSMC_PULSE5                           0x0054
++#define HSMC_CYCLE5                           0x0058
++#define HSMC_MODE5                            0x005c
++
++/* Bitfields in SETUP0 */
++#define HSMC_NWE_SETUP_OFFSET                 0
++#define HSMC_NWE_SETUP_SIZE                   6
++#define HSMC_NCS_WR_SETUP_OFFSET              8
++#define HSMC_NCS_WR_SETUP_SIZE                        6
++#define HSMC_NRD_SETUP_OFFSET                 16
++#define HSMC_NRD_SETUP_SIZE                   6
++#define HSMC_NCS_RD_SETUP_OFFSET              24
++#define HSMC_NCS_RD_SETUP_SIZE                        6
++
++/* Bitfields in PULSE0 */
++#define HSMC_NWE_PULSE_OFFSET                 0
++#define HSMC_NWE_PULSE_SIZE                   7
++#define HSMC_NCS_WR_PULSE_OFFSET              8
++#define HSMC_NCS_WR_PULSE_SIZE                        7
++#define HSMC_NRD_PULSE_OFFSET                 16
++#define HSMC_NRD_PULSE_SIZE                   7
++#define HSMC_NCS_RD_PULSE_OFFSET              24
++#define HSMC_NCS_RD_PULSE_SIZE                        7
++
++/* Bitfields in CYCLE0 */
++#define HSMC_NWE_CYCLE_OFFSET                 0
++#define HSMC_NWE_CYCLE_SIZE                   9
++#define HSMC_NRD_CYCLE_OFFSET                 16
++#define HSMC_NRD_CYCLE_SIZE                   9
++
++/* Bitfields in MODE0 */
++#define HSMC_READ_MODE_OFFSET                 0
++#define HSMC_READ_MODE_SIZE                   1
++#define HSMC_WRITE_MODE_OFFSET                        1
++#define HSMC_WRITE_MODE_SIZE                  1
++#define HSMC_EXNW_MODE_OFFSET                 4
++#define HSMC_EXNW_MODE_SIZE                   2
++#define HSMC_BAT_OFFSET                               8
++#define HSMC_BAT_SIZE                         1
++#define HSMC_DBW_OFFSET                               12
++#define HSMC_DBW_SIZE                         2
++#define HSMC_TDF_CYCLES_OFFSET                        16
++#define HSMC_TDF_CYCLES_SIZE                  4
++#define HSMC_TDF_MODE_OFFSET                  20
++#define HSMC_TDF_MODE_SIZE                    1
++#define HSMC_PMEN_OFFSET                      24
++#define HSMC_PMEN_SIZE                                1
++#define HSMC_PS_OFFSET                                28
++#define HSMC_PS_SIZE                          2
++
++/* Constants for READ_MODE */
++#define HSMC_READ_MODE_NCS_CONTROLLED         0
++#define HSMC_READ_MODE_NRD_CONTROLLED         1
++
++/* Constants for WRITE_MODE */
++#define HSMC_WRITE_MODE_NCS_CONTROLLED                0
++#define HSMC_WRITE_MODE_NWE_CONTROLLED                1
++
++/* Constants for EXNW_MODE */
++#define HSMC_EXNW_MODE_DISABLED                       0
++#define HSMC_EXNW_MODE_RESERVED                       1
++#define HSMC_EXNW_MODE_FROZEN                 2
++#define HSMC_EXNW_MODE_READY                  3
++
++/* Constants for BAT */
++#define HSMC_BAT_BYTE_SELECT                  0
++#define HSMC_BAT_BYTE_WRITE                   1
++
++/* Constants for DBW */
++#define HSMC_DBW_8_BITS                               0
++#define HSMC_DBW_16_BITS                      1
++#define HSMC_DBW_32_BITS                      2
++
++/* Bit manipulation macros */
++#define HSMC_BIT(name)                                                        \
++      (1 << HSMC_##name##_OFFSET)
++#define HSMC_BF(name,value)                                           \
++      (((value) & ((1 << HSMC_##name##_SIZE) - 1))                    \
++       << HSMC_##name##_OFFSET)
++#define HSMC_BFEXT(name,value)                                                \
++      (((value) >> HSMC_##name##_OFFSET)                              \
++       & ((1 << HSMC_##name##_SIZE) - 1))
++#define HSMC_BFINS(name,value,old)                                    \
++      (((old) & ~(((1 << HSMC_##name##_SIZE) - 1)                     \
++                  << HSMC_##name##_OFFSET)) | HSMC_BF(name,value))
++
++/* Register access macros */
++#define hsmc_readl(port,reg)                                          \
++      __raw_readl((port)->regs + HSMC_##reg)
++#define hsmc_writel(port,reg,value)                                   \
++      __raw_writel((value), (port)->regs + HSMC_##reg)
++
++#endif /* __ASM_AVR32_HSMC_H__ */
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/smc.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/smc.h     2006-12-04 11:50:22.000000000 +0100
+@@ -0,0 +1,60 @@
++/*
++ * Static Memory Controller for AT32 chips
++ *
++ * Copyright (C) 2006 Atmel Corporation
++ *
++ * Inspired by the OMAP2 General-Purpose Memory Controller interface
++ *
++ * 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 __ARCH_AT32AP_SMC_H
++#define __ARCH_AT32AP_SMC_H
++
++/*
++ * All timing parameters are in nanoseconds.
++ */
++struct smc_config {
++      /* Delay from address valid to assertion of given strobe */
++      u16             ncs_read_setup;
++      u16             nrd_setup;
++      u16             ncs_write_setup;
++      u16             nwe_setup;
++
++      /* Pulse length of given strobe */
++      u16             ncs_read_pulse;
++      u16             nrd_pulse;
++      u16             ncs_write_pulse;
++      u16             nwe_pulse;
++
++      /* Total cycle length of given operation */
++      u16             read_cycle;
++      u16             write_cycle;
++
++      /* Bus width in bytes */
++      u8              bus_width;
++
++      /*
++       * 0: Data is sampled on rising edge of NCS
++       * 1: Data is sampled on rising edge of NRD
++       */
++      unsigned int    nrd_controlled:1;
++
++      /*
++       * 0: Data is driven on falling edge of NCS
++       * 1: Data is driven on falling edge of NWR
++       */
++      unsigned int    nwe_controlled:1;
++
++      /*
++       * 0: Byte select access type
++       * 1: Byte write access type
++       */
++      unsigned int    byte_write:1;
++};
++
++extern int smc_set_configuration(int cs, const struct smc_config *config);
++extern struct smc_config *smc_get_configuration(int cs);
++
++#endif /* __ARCH_AT32AP_SMC_H */
diff --git a/packages/linux/linux-2.6.18/avr32-checkstack.patch b/packages/linux/linux-2.6.18/avr32-checkstack.patch
new file mode 100644 (file)
index 0000000..31d2434
--- /dev/null
@@ -0,0 +1,35 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Wed Jan 4 16:58:49 2006 +0100
+Subject: [PATCH] AVR32 checkstack port
+
+Add regexes to recognize stack frame adjustments in AVR32 code.
+
+---
+
+ scripts/checkstack.pl |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+Index: linux-2.6.16-avr32/scripts/checkstack.pl
+===================================================================
+--- linux-2.6.16-avr32.orig/scripts/checkstack.pl      2006-03-20 06:53:29.000000000 +0100
++++ linux-2.6.16-avr32/scripts/checkstack.pl   2006-04-03 18:57:19.000000000 +0200
+@@ -12,6 +12,7 @@
+ #     sh64 port by Paul Mundt
+ #     Random bits by Matt Mackall <mpm@selenic.com>
+ #     M68k port by Geert Uytterhoeven and Andreas Schwab
++#     AVR32 port by Haavard Skinnemoen <hskinnemoen@atmel.com>
+ #
+ #     Usage:
+ #     objdump -d vmlinux | stackcheck.pl [arch]
+@@ -37,6 +38,10 @@ my (@stack, $re, $x, $xs);
+       if ($arch eq 'arm') {
+               #c0008ffc:      e24dd064        sub     sp, sp, #100    ; 0x64
+               $re = qr/.*sub.*sp, sp, #(([0-9]{2}|[3-9])[0-9]{2})/o;
++      } elsif ($arch eq 'avr32') {
++              #8000008a:       20 1d           sub sp,4
++              #80000ca8:       fa cd 05 b0     sub sp,sp,1456
++              $re = qr/^.*sub.*sp.*,([0-9]{1,8})/o;
+       } elsif ($arch =~ /^i[3456]86$/) {
+               #c0105234:       81 ec ac 05 00 00       sub    $0x5ac,%esp
+               $re = qr/^.*[as][du][db]    \$(0x$x{1,8}),\%esp$/o;
diff --git a/packages/linux/linux-2.6.18/avr32-dma-controller-framework.patch b/packages/linux/linux-2.6.18/avr32-dma-controller-framework.patch
new file mode 100644 (file)
index 0000000..0f63013
--- /dev/null
@@ -0,0 +1,241 @@
+From 740c72fe92a5536060ac6debbfe0a26c0b9b8770 Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Mon, 11 Sep 2006 17:59:59 +0200
+Subject: [PATCH] AVR32: DMA controller framework
+
+This patch puts the DMA controller framework used in earlier BSPs back.
+It was removed before the AVR32 patches went into -mm, and it should
+be removed here as well as soon as we have an alternative.
+
+---
+ arch/avr32/kernel/Makefile         |    1 
+ arch/avr32/kernel/dma-controller.c |   34 +++++++
+ include/asm-avr32/dma-controller.h |  165 ++++++++++++++++++++++++++++++++++++
+ 3 files changed, 200 insertions(+), 0 deletions(-)
+
+diff --git a/arch/avr32/kernel/Makefile b/arch/avr32/kernel/Makefile
+index 90e5aff..b6afc0c 100644
+--- 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 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 --git a/arch/avr32/kernel/dma-controller.c b/arch/avr32/kernel/dma-controller.c
+new file mode 100644
+index 0000000..fb654b3
+--- /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);
+diff --git a/include/asm-avr32/dma-controller.h b/include/asm-avr32/dma-controller.h
+new file mode 100644
+index 0000000..8c67601
+--- /dev/null
++++ b/include/asm-avr32/dma-controller.h
+@@ -0,0 +1,165 @@
++/*
++ * 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;
++
++      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 */
+-- 
+1.4.1.1
+
diff --git a/packages/linux/linux-2.6.18/avr32-dont-include-asm-delay-h.patch b/packages/linux/linux-2.6.18/avr32-dont-include-asm-delay-h.patch
new file mode 100644 (file)
index 0000000..b9c5f4d
--- /dev/null
@@ -0,0 +1,47 @@
+From 53678aca529d43e8fd0443c0c5f7f0807d5fd850 Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Wed, 10 Jan 2007 19:18:06 +0100
+Subject: [PATCH] [AVR32] Don't include asm/delay.h
+
+Remove a couple of asm/delay.h inclusions and replace with
+linux/delay.h where necessary.
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+---
+ arch/avr32/kernel/avr32_ksyms.c |    2 +-
+ arch/avr32/lib/delay.c          |    1 -
+ 2 files changed, 1 insertions(+), 2 deletions(-)
+
+diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c
+index 372e3f8..7c4c761 100644
+--- a/arch/avr32/kernel/avr32_ksyms.c
++++ b/arch/avr32/kernel/avr32_ksyms.c
+@@ -7,12 +7,12 @@
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  */
++#include <linux/delay.h>
+ #include <linux/io.h>
+ #include <linux/module.h>
+ #include <asm/checksum.h>
+ #include <asm/uaccess.h>
+-#include <asm/delay.h>
+ /*
+  * GCC functions
+diff --git a/arch/avr32/lib/delay.c b/arch/avr32/lib/delay.c
+index 462c830..76a8474 100644
+--- a/arch/avr32/lib/delay.c
++++ b/arch/avr32/lib/delay.c
+@@ -14,7 +14,6 @@
+ #include <linux/module.h>
+ #include <linux/types.h>
+-#include <asm/delay.h>
+ #include <asm/processor.h>
+ #include <asm/sysreg.h>
+-- 
+1.4.4.1
+
diff --git a/packages/linux/linux-2.6.18/avr32-drop-GFP_COMP-for-DMA-memory-allocations.patch b/packages/linux/linux-2.6.18/avr32-drop-GFP_COMP-for-DMA-memory-allocations.patch
new file mode 100644 (file)
index 0000000..eea6902
--- /dev/null
@@ -0,0 +1,27 @@
+Hack for incompatible __GFP_COMP flag making its way into the AVR32\r
+DMA consistent memory allocator.\r
\r
+This is essentially the same patch as the one submitted by\r
+Marc Singer <elf@buici.com> for ARM.\r
+---\r
+ arch/avr32/mm/dma-coherent.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
\r
+Index: linux-2.6.18-avr32/arch/avr32/mm/dma-coherent.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mm/dma-coherent.c       2006-09-11 18:06:00.000000000 +0200
++++ linux-2.6.18-avr32/arch/avr32/mm/dma-coherent.c    2006-09-12 13:38:39.000000000 +0200
+@@ -41,6 +41,13 @@ static struct page *__dma_alloc(struct d
+       struct page *page, *free, *end;
+       int order;
++      /* Following is a work-around (a.k.a. hack) to prevent pages
++       * with __GFP_COMP being passed to split_page() which cannot
++       * handle them.  The real problem is that this flag probably
++       * should be 0 on AVR32 as it is not supported on this
++       * platform--see CONFIG_HUGETLB_PAGE. */
++      gfp &= ~(__GFP_COMP);
++
+       size = PAGE_ALIGN(size);
+       order = get_order(size);
diff --git a/packages/linux/linux-2.6.18/avr32-fix-oprofile-interrupts.patch b/packages/linux/linux-2.6.18/avr32-fix-oprofile-interrupts.patch
new file mode 100644 (file)
index 0000000..93f571d
--- /dev/null
@@ -0,0 +1,109 @@
+--- linux-2.6.18.orig/arch/avr32/oprofile/op_model_avr32.c     2006-11-06 14:36:51.000000000 +0100
++++ linux-2.6.18/arch/avr32/oprofile/op_model_avr32.c  2006-11-07 10:05:46.000000000 +0100
+@@ -7,7 +7,7 @@
+  * it under the terms of the GNU General Public License version 2 as
+  * published by the Free Software Foundation.
+  *
+- * Author: Ronny Pedersen
++ * Authors: Sondre Garsjoe, Ronny Pedersen
+  */
+ #define DEBUG
+@@ -17,6 +17,7 @@
+ #include <linux/sched.h>
+ #include <linux/oprofile.h>
+ #include <linux/interrupt.h>
++#include <asm/intc.h>
+ #include <asm/irq.h>
+ #include <asm/system.h>
+ #include <asm/sysreg.h>
+@@ -49,7 +50,7 @@
+ #define PCNT0_F  (1 << 9)
+ #define PCNT1_F  (1 << 10)
+-#define AVR32_PC_IRQ 1
++#define AVR32_PC_IRQ 0
+ static const u32 int_mask[MAX_COUNTERS] = { PCCNT_IE, PCNT0_IE, PCNT1_IE };
+ static const u32 ovf_mask[MAX_COUNTERS] = { PCCNT_F, PCNT0_F, PCNT1_F };
+@@ -58,38 +59,37 @@
+ static void write_pccr(u32 val)
+ {
+-      __builtin_mtsr(SYSREG_PCCR, val);
++      sysreg_write(PCCR, val);
+ }
+ static u32 read_pccr(void)
+ {
+-      return __builtin_mfsr(SYSREG_PCCR);
++      return sysreg_read(PCCR);
+ }
+ static u32 read_counter(int counter)
+ {
+       switch (counter) {
+       case PCCNT:
+-              return __builtin_mfsr(SYSREG_PCCNT);
++              return sysreg_read(PCCNT);
+       case PCNT0:
+-              return __builtin_mfsr(SYSREG_PCNT0);
++              return sysreg_read(PCNT0);
+       case PCNT1:
+-              return __builtin_mfsr(SYSREG_PCNT0);
++              return sysreg_read(PCNT1);
+       default:
+               return 0;
+       }
+ }
+-
+ static void write_counter(int counter, u32 val)
+ {
+       switch (counter) {
+       case PCCNT:
+-              __builtin_mtsr(SYSREG_PCCNT, val);
++              sysreg_write(PCCNT, val);
+       case PCNT0:
+-              __builtin_mtsr(SYSREG_PCNT0, val);
++              sysreg_write(PCNT0, val);
+       case PCNT1:
+-              __builtin_mtsr(SYSREG_PCNT0, val);
++              sysreg_write(PCNT1, val);
+       default:
+               break;
+       }
+@@ -144,12 +144,15 @@
+       }
+ }
+-
+ static irqreturn_t avr32_pc_interrupt(int irq, void *arg,
+                                     struct pt_regs *regs)
+ {
+       int i;
++      /* Check if this is a performance counter interrupt */
++      if (!(intc_get_pending(irq) & 2))
++              return IRQ_NONE;
++
+       check_ctrs();
+       for (i = PCCNT; i < MAX_COUNTERS; i++) {
+@@ -179,7 +182,7 @@
+       int i, ret;
+       u32 pccr = read_pccr();
+-      ret = request_irq(AVR32_PC_IRQ, avr32_pc_interrupt, SA_INTERRUPT,
++      ret = request_irq(AVR32_PC_IRQ, avr32_pc_interrupt, IRQF_SHARED | IRQF_DISABLED,
+                         "AVR32 Performance Counter", (void *)results);
+       if (ret < 0) {
+@@ -214,6 +217,6 @@
+       .start          = avr32_pc_start,
+       .stop           = avr32_pc_stop,
+       .num_counters   = MAX_COUNTERS,
+-      .name           = "avr32",
++      .name           = "avr32/at32ap7000",
+ };
diff --git a/packages/linux/linux-2.6.18/avr32-gpio-dev.patch b/packages/linux/linux-2.6.18/avr32-gpio-dev.patch
new file mode 100644 (file)
index 0000000..43971cf
--- /dev/null
@@ -0,0 +1,548 @@
+---
+ arch/avr32/mach-at32ap/Kconfig |    8 
+ arch/avr32/mach-at32ap/pio.c   |  499 ++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 506 insertions(+), 1 deletion(-)
+
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/pio.c       2006-11-29 16:22:14.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c    2006-11-29 16:29:20.000000000 +0100
+@@ -22,7 +22,7 @@
+ struct pio_device {
+       void __iomem *regs;
+-      const struct platform_device *pdev;
++      struct platform_device *pdev;
+       struct clk *clk;
+       u32 pinmux_mask;
+       u32 gpio_mask;
+@@ -119,6 +119,34 @@ fail:
+       dump_stack();
+ }
++static unsigned int pio_id(struct pio_device *pio)
++{
++      return pio - pio_dev;
++}
++
++static void __enable_gpio(struct pio_device *pio, u32 mask)
++{
++      pio_writel(pio, PUER, mask);
++      pio_writel(pio, ODR, mask);
++      pio_writel(pio, PER, mask);
++}
++
++static void __disable_gpio(struct pio_device *pio, u32 mask)
++{
++      pio_writel(pio, PUER, mask);
++      pio_writel(pio, ODR, mask);
++}
++
++static void pio_dealloc_mask(struct pio_device *pio, u32 mask)
++{
++      u32 old, new;
++
++      do {
++              old = pio->pinmux_mask;
++              new = old & ~mask;
++      } while (cmpxchg(&pio->pinmux_mask, old, new) != old);
++}
++
+ /* GPIO API */
+ int gpio_request(unsigned int gpio, const char *label)
+@@ -210,6 +238,475 @@ void gpio_set_value(unsigned int gpio, i
+ }
+ EXPORT_SYMBOL(gpio_set_value);
++#ifdef CONFIG_PIO_DEV
++#include <linux/configfs.h>
++#include <linux/cdev.h>
++#include <linux/uaccess.h>
++
++#define GPIO_DEV_MAX                  8
++
++static struct class *gpio_dev_class;
++static dev_t gpio_devt;
++
++struct gpio_item {
++      spinlock_t lock;
++
++      /* Too bad we don't have committable items... */
++      int enabled;
++
++      struct pio_device *pio;
++      u32 pin_mask;
++
++      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 int gpio_dev_open(struct inode *inode, struct file *file)
++{
++      struct gpio_item *gpio = container_of(inode->i_cdev,
++                                            struct gpio_item,
++                                            char_dev);
++
++      config_item_get(&gpio->item);
++      file->private_data = gpio;
++      return 0;
++}
++
++static int gpio_dev_release(struct inode *inode, struct file *file)
++{
++      struct gpio_item *gpio = file->private_data;
++
++      config_item_put(&gpio->item);
++      return 0;
++}
++
++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;
++
++      value = pio_readl(gpio->pio, PDSR) & gpio->pin_mask;
++
++      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;
++
++      pio_writel(gpio->pio, CODR, ~value & mask);
++      pio_writel(gpio->pio, SODR, 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,
++      .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)
++{
++      if (gpio->pio)
++              return sprintf(page, "%u\n", pio_id(gpio->pio));
++      else
++              return sprintf(page, "-1\n");
++}
++
++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 ((id < MAX_NR_PIO_DEVICES) && pio_dev[id].regs) {
++                      gpio->pio = &pio_dev[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)
++{
++      struct pio_device *pio;
++      u32 old_mask, new_mask;
++      u32 old, new;
++      char *p = (char *)page;
++      ssize_t ret = -EINVAL;
++
++      new_mask = simple_strtoul(p, &p, 0);
++      if (!p || (*p && (*p != '\n')))
++              return -EINVAL;
++
++      /*
++       * Must have a PIO before we can start allocating pins, but we
++       * must not be live.
++       */
++      spin_lock(&gpio->lock);
++      pio = gpio->pio;
++      if (!pio || gpio->enabled)
++              goto out;
++
++      ret = -EBUSY;
++      old_mask = gpio->pin_mask;
++      do {
++              old = pio->pinmux_mask;
++              if ((old & ~old_mask) & new_mask)
++                      goto out;
++
++              new = (old & ~old_mask) | new_mask;
++      } while (cmpxchg(&pio->pinmux_mask, old, new) != old);
++
++      gpio->pin_mask = new_mask;
++      __disable_gpio(pio, old_mask);
++      __enable_gpio(pio, new_mask);
++      ret = count;
++
++out:
++      spin_unlock(&gpio->lock);
++      return ret;
++}
++
++static ssize_t gpio_show_oe_mask(struct gpio_item *gpio, char *page)
++{
++      u32 mask = 0;
++
++      spin_lock(&gpio->lock);
++      if (gpio->pio) {
++              mask = pio_readl(gpio->pio, OSR);
++              mask &= gpio->pin_mask;
++      }
++      spin_unlock(&gpio->lock);
++
++      return sprintf(page, "0x%08x\n", 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->pio) {
++              mask &= gpio->pin_mask;
++              pio_writel(gpio->pio, ODR, mask ^ gpio->pin_mask);
++              pio_writel(gpio->pio, OER, 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)
++              /* Already enabled; do nothing. */
++              return count;
++
++      BUG_ON(gpio->id >= GPIO_DEV_MAX);
++
++      if (!enabled) {
++              class_device_unregister(gpio->gpio_dev);
++              cdev_del(&gpio->char_dev);
++      }
++
++      /* Disallow any updates to gpio_id or pin_mask */
++      spin_lock(&gpio->lock);
++      gpio->enabled = enabled;
++      spin_unlock(&gpio->lock);
++
++      if (!enabled)
++              return count;
++
++      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),
++                                           &gpio->pio->pdev->dev,
++                                           "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 (pio%d/0x%08x) as (%d:%d)\n",
++             gpio->id, pio_id(gpio->pio), 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:
++      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);
++
++      return &gpio->item;
++}
++
++static void gpio_drop_item(struct config_group *group,
++                         struct config_item *item)
++{
++      struct gpio_item *gpio = to_gpio_item(item);
++      struct pio_device *pio;
++
++      spin_lock(&gpio->lock);
++      if (gpio->enabled) {
++              class_device_unregister(gpio->gpio_dev);
++              cdev_del(&gpio->char_dev);
++      }
++
++      pio = gpio->pio;
++      if (pio) {
++              __disable_gpio(pio, gpio->pin_mask);
++              pio_dealloc_mask(pio, gpio->pin_mask);
++              gpio->pio = NULL;
++      }
++      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 pio_init_dev(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);
++      init_MUTEX(&gpio_subsys.su_sem);
++      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(pio_init_dev);
++#endif /* CONFIG_PIO_DEV */
++
+ static int __init pio_probe(struct platform_device *pdev)
+ {
+       struct pio_device *pio = NULL;
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/Kconfig     2006-11-29 16:23:31.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/Kconfig  2006-11-29 16:24:35.000000000 +0100
+@@ -2,6 +2,14 @@ if PLATFORM_AT32AP
+ menu "Atmel AVR32 AP options"
++config PIO_DEV
++      bool "PIO /dev interface"
++      select CONFIGFS_FS
++      default y
++      help
++        Say `Y' to enable a /dev interface to the Parallel I/O
++        Controller.
++
+ endmenu
+ endif
diff --git a/packages/linux/linux-2.6.18/avr32-increment-pointer-when-parsing-for-fbmem_start.patch b/packages/linux/linux-2.6.18/avr32-increment-pointer-when-parsing-for-fbmem_start.patch
new file mode 100644 (file)
index 0000000..e755b47
--- /dev/null
@@ -0,0 +1,16 @@
+Index: linux-2.6.18/arch/avr32/kernel/setup.c
+===================================================================
+--- linux-2.6.18.orig/arch/avr32/kernel/setup.c        2006-12-20 12:45:12.000000000 +0100
++++ linux-2.6.18/arch/avr32/kernel/setup.c     2006-12-20 12:45:24.000000000 +0100
+@@ -103,8 +103,10 @@
+ static int __init early_parse_fbmem(char *p)
+ {
+       fbmem_size = memparse(p, &p);
+-      if (*p == '@')
++      if (*p == '@') {
++              p++;
+               fbmem_start = memparse(p, &p);
++      }
+       return 0;
+ }
+ early_param("fbmem", early_parse_fbmem);
diff --git a/packages/linux/linux-2.6.18/avr32-little-endian-read-write-bwl.patch b/packages/linux/linux-2.6.18/avr32-little-endian-read-write-bwl.patch
new file mode 100644 (file)
index 0000000..5e9b752
--- /dev/null
@@ -0,0 +1,128 @@
+---
+ include/asm-avr32/io.h |   73 ++++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 49 insertions(+), 24 deletions(-)
+
+Index: linux-2.6.18-avr32/include/asm-avr32/io.h
+===================================================================
+--- linux-2.6.18-avr32.orig/include/asm-avr32/io.h     2006-11-02 16:40:37.000000000 +0100
++++ linux-2.6.18-avr32/include/asm-avr32/io.h  2006-11-03 17:58:06.000000000 +0100
+@@ -5,6 +5,8 @@
+ #ifdef __KERNEL__
++#include <linux/types.h>
++
+ #include <asm/addrspace.h>
+ #include <asm/byteorder.h>
+@@ -36,37 +38,64 @@ extern void __raw_readsb(unsigned int ad
+ extern void __raw_readsw(unsigned int addr, void *data, int wordlen);
+ extern void __raw_readsl(unsigned int addr, void *data, int longlen);
+-static inline void writeb(unsigned char b, volatile void __iomem *addr)
++static inline void __raw_writeb(u8 v, volatile void __iomem *addr)
++{
++      *(volatile u8 __force *)addr = v;
++}
++static inline void __raw_writew(u16 v, volatile void __iomem *addr)
++{
++      *(volatile u16 __force *)addr = v;
++}
++static inline void __raw_writel(u32 v, volatile void __iomem *addr)
++{
++      *(volatile u32 __force *)addr = v;
++}
++
++static inline u8 __raw_readb(const volatile void __iomem *addr)
+ {
+-      *(volatile unsigned char __force *)addr = b;
++      return *(const volatile u8 __force *)addr;
+ }
+-static inline void writew(unsigned short b, volatile void __iomem *addr)
++static inline u16 __raw_readw(const volatile void __iomem *addr)
+ {
+-      *(volatile unsigned short __force *)addr = b;
++      return *(const volatile u16 __force *)addr;
+ }
+-static inline void writel(unsigned int b, volatile void __iomem *addr)
++static inline u32 __raw_readl(const volatile void __iomem *addr)
+ {
+-      *(volatile unsigned int __force *)addr = b;
++      return *(const volatile u32 __force *)addr;
+ }
+-#define __raw_writeb writeb
+-#define __raw_writew writew
+-#define __raw_writel writel
+-static inline unsigned char readb(const volatile void __iomem *addr)
++#define __swizzle_addr_b(addr)                                        \
++      ((typeof(addr))((unsigned long)(addr) ^ 3UL))
++#define __swizzle_addr_w(addr)                                        \
++      ((typeof(addr))((unsigned long)(addr) ^ 2UL))
++#define __swizzle_addr_l(addr)                                        \
++      (addr)
++
++static inline void writeb(u8 v, volatile void __iomem *addr)
+ {
+-      return *(const volatile unsigned char __force *)addr;
++      __raw_writeb(v, __swizzle_addr_b(addr));
+ }
+-static inline unsigned short readw(const volatile void __iomem *addr)
++static inline void writew(u16 v, volatile void __iomem *addr)
+ {
+-      return *(const volatile unsigned short __force *)addr;
++      __raw_writew(v, __swizzle_addr_w(addr));
+ }
+-static inline unsigned int readl(const volatile void __iomem *addr)
++static inline void writel(u32 v, volatile void __iomem *addr)
+ {
+-      return *(const volatile unsigned int __force *)addr;
++      __raw_writel(v, __swizzle_addr_l(addr));
++}
++
++static inline u8 readb(const volatile void __iomem *addr)
++{
++      return __raw_readb(__swizzle_addr_b(addr));
++}
++static inline u16 readw(const volatile void __iomem *addr)
++{
++      return __raw_readw(__swizzle_addr_w(addr));
++}
++static inline u32 readl(const volatile void __iomem *addr)
++{
++      return __raw_readl(__swizzle_addr_l(addr));
+ }
+-#define __raw_readb readb
+-#define __raw_readw readw
+-#define __raw_readl readl
+ #define writesb(p, d, l)      __raw_writesb((unsigned int)p, d, l)
+ #define writesw(p, d, l)      __raw_writesw((unsigned int)p, d, l)
+@@ -108,17 +137,13 @@ static inline unsigned int readl(const v
+ #endif
+-
+-/*
+- * These two are only here because ALSA _thinks_ it needs them...
+- */
+ static inline void memcpy_fromio(void * to, const volatile void __iomem *from,
+                                unsigned long count)
+ {
+       char *p = to;
+       while (count) {
+               count--;
+-              *p = readb(from);
++              *p = __raw_readb(from);
+               p++;
+               from++;
+       }
+@@ -130,7 +155,7 @@ static inline void  memcpy_toio(volatile
+       const char *p = from;
+       while (count) {
+               count--;
+-              writeb(*p, to);
++              __raw_writeb(*p, to);
+               p++;
+               to++;
+       }
diff --git a/packages/linux/linux-2.6.18/avr32-move-ethernet-tag-parsing-to-board-specific-code.patch b/packages/linux/linux-2.6.18/avr32-move-ethernet-tag-parsing-to-board-specific-code.patch
new file mode 100644 (file)
index 0000000..03e0878
--- /dev/null
@@ -0,0 +1,94 @@
+From 736c9c38e8a681d0ecfc4dafe15fcb955fe66a29 Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Tue, 24 Oct 2006 09:34:48 +0200
+Subject: [PATCH] AVR32: Move ethernet tag parsing to board-specific code
+
+By moving the ethernet tag parsing to the board-specific code we avoid
+the issue of figuring out which device we're supposed to attach the
+information to.  The board specific code knows this because it's
+where the actual devices are instantiated.
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+---
+ arch/avr32/boards/atstk1000/atstk1002.c |   26 ++++++++++++++++++++------
+ arch/avr32/kernel/setup.c               |   24 ------------------------
+ 2 files changed, 20 insertions(+), 30 deletions(-)
+
+Index: linux-2.6.18-avr32/arch/avr32/boards/atstk1000/atstk1002.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/boards/atstk1000/atstk1002.c    2006-11-01 13:26:19.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/boards/atstk1000/atstk1002.c 2006-11-01 13:33:38.000000000 +0100
+@@ -8,18 +8,32 @@
+  * published by the Free Software Foundation.
+  */
+ #include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <asm/setup.h>
+ #include <asm/arch/board.h>
+-struct eth_platform_data __initdata eth0_data = {
+-      .valid          = 1,
+-      .mii_phy_addr   = 0x10,
+-      .is_rmii        = 0,
+-      .hw_addr        = { 0x6a, 0x87, 0x71, 0x14, 0xcd, 0xcb },
+-};
++static struct eth_platform_data __initdata eth_data[2];
+ extern struct lcdc_platform_data atstk1000_fb0_data;
++static int __init parse_tag_ethernet(struct tag *tag)
++{
++      int i;
++
++      i = tag->u.ethernet.mac_index;
++      if (i < ARRAY_SIZE(eth_data)) {
++              eth_data[i].mii_phy_addr = tag->u.ethernet.mii_phy_addr;
++              memcpy(&eth_data[i].hw_addr, tag->u.ethernet.hw_address,
++                     sizeof(eth_data[i].hw_addr));
++              eth_data[i].valid = 1;
++      }
++      return 0;
++}
++__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
++
+ static int __init atstk1002_init(void)
+ {
+       at32_add_system_devices();
+Index: linux-2.6.18-avr32/arch/avr32/kernel/setup.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/kernel/setup.c  2006-11-01 13:26:19.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/kernel/setup.c       2006-11-01 13:31:32.000000000 +0100
+@@ -229,30 +229,6 @@ static int __init parse_tag_rsvd_mem(str
+ }
+ __tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem);
+-static int __init parse_tag_ethernet(struct tag *tag)
+-{
+-#if 0
+-      const struct platform_device *pdev;
+-
+-      /*
+-       * We really need a bus type that supports "classes"...this
+-       * will do for now (until we must handle other kinds of
+-       * ethernet controllers)
+-       */
+-      pdev = platform_get_device("macb", tag->u.ethernet.mac_index);
+-      if (pdev && pdev->dev.platform_data) {
+-              struct eth_platform_data *data = pdev->dev.platform_data;
+-
+-              data->valid = 1;
+-              data->mii_phy_addr = tag->u.ethernet.mii_phy_addr;
+-              memcpy(data->hw_addr, tag->u.ethernet.hw_address,
+-                     sizeof(data->hw_addr));
+-      }
+-#endif
+-      return 0;
+-}
+-__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
+-
+ /*
+  * Scan the tag table for this tag, and call its parse function. The
+  * tag table is built by the linker from all the __tagtable
diff --git a/packages/linux/linux-2.6.18/avr32-network-gateway-support.patch b/packages/linux/linux-2.6.18/avr32-network-gateway-support.patch
new file mode 100644 (file)
index 0000000..420e859
--- /dev/null
@@ -0,0 +1,233 @@
+From 16655aecb1a151c1f1707c64a571cd06e6a194af Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Mon, 30 Oct 2006 09:35:44 +0100
+Subject: [PATCH] Add support for the AVR32 Network Gateway
+---
+ arch/avr32/Kconfig               |    3 +
+ arch/avr32/Makefile              |    1 
+ arch/avr32/boards/atngw/Makefile |    1 
+ arch/avr32/boards/atngw/flash.c  |   95 +++++++++++++++++++++++++++++++++++++++
+ arch/avr32/boards/atngw/setup.c  |   81 +++++++++++++++++++++++++++++++++
+ 5 files changed, 181 insertions(+)
+
+Index: linux-2.6.18/arch/avr32/Kconfig
+===================================================================
+--- linux-2.6.18.orig/arch/avr32/Kconfig       2006-12-13 09:45:34.000000000 +0100
++++ linux-2.6.18/arch/avr32/Kconfig    2006-12-13 09:45:34.000000000 +0100
+@@ -97,6 +97,9 @@
+ config BOARD_ATSTK1000
+       bool "ATSTK1000 evaluation board"
+       select BOARD_ATSTK1002 if CPU_AT32AP7000
++
++config BOARD_ATNGW
++      bool "AVR32 Network Gateway"
+ endchoice
+ choice
+Index: linux-2.6.18/arch/avr32/Makefile
+===================================================================
+--- linux-2.6.18.orig/arch/avr32/Makefile      2006-12-13 09:45:34.000000000 +0100
++++ linux-2.6.18/arch/avr32/Makefile   2006-12-13 09:45:34.000000000 +0100
+@@ -27,6 +27,7 @@
+ head-y                                        += arch/avr32/kernel/head.o
+ core-$(CONFIG_PLATFORM_AT32AP)                += arch/avr32/mach-at32ap/
+ core-$(CONFIG_BOARD_ATSTK1000)                += arch/avr32/boards/atstk1000/
++core-$(CONFIG_BOARD_ATNGW)            += arch/avr32/boards/atngw/
+ core-$(CONFIG_LOADER_U_BOOT)          += arch/avr32/boot/u-boot/
+ core-y                                        += arch/avr32/kernel/
+ core-y                                        += arch/avr32/mm/
+Index: linux-2.6.18/arch/avr32/boards/atngw/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18/arch/avr32/boards/atngw/Makefile      2006-12-13 09:45:34.000000000 +0100
+@@ -0,0 +1 @@
++obj-y                         += setup.o flash.o
+Index: linux-2.6.18/arch/avr32/boards/atngw/flash.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18/arch/avr32/boards/atngw/flash.c       2006-12-13 09:45:34.000000000 +0100
+@@ -0,0 +1,95 @@
++/*
++ * ATNGW board-specific flash initialization
++ *
++ * 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/init.h>
++#include <linux/platform_device.h>
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/partitions.h>
++#include <linux/mtd/physmap.h>
++
++#include <asm/arch/smc.h>
++
++static struct smc_config flash_config __initdata = {
++      .ncs_read_setup         = 0,
++      .nrd_setup              = 40,
++      .ncs_write_setup        = 0,
++      .nwe_setup              = 10,
++
++      .ncs_read_pulse         = 80,
++      .nrd_pulse              = 40,
++      .ncs_write_pulse        = 65,
++      .nwe_pulse              = 55,
++
++      .read_cycle             = 120,
++      .write_cycle            = 120,
++
++      .bus_width              = 2,
++      .nrd_controlled         = 1,
++      .nwe_controlled         = 1,
++      .byte_write             = 1,
++};
++
++static struct mtd_partition flash_parts[] = {
++      {
++              .name           = "u-boot",
++              .offset         = 0x00000000,
++              .size           = 0x00020000,           /* 128 KiB */
++              .mask_flags     = MTD_WRITEABLE,
++      },
++      {
++              .name           = "root",
++              .offset         = 0x00020000,
++              .size           = 0x007d0000,
++      },
++      {
++              .name           = "env",
++              .offset         = 0x007f0000,
++              .size           = 0x00010000,
++              .mask_flags     = MTD_WRITEABLE,
++      },
++};
++
++static struct physmap_flash_data flash_data = {
++      .width          = 2,
++      .nr_parts       = ARRAY_SIZE(flash_parts),
++      .parts          = flash_parts,
++};
++
++static struct resource flash_resource = {
++      .start          = 0x00000000,
++      .end            = 0x007fffff,
++      .flags          = IORESOURCE_MEM,
++};
++
++static struct platform_device flash_device = {
++      .name           = "physmap-flash",
++      .id             = 0,
++      .resource       = &flash_resource,
++      .num_resources  = 1,
++      .dev            = {
++              .platform_data = &flash_data,
++      },
++};
++
++/* This needs to be called after the SMC has been initialized */
++static int __init atngw_flash_init(void)
++{
++      int ret;
++
++      ret = smc_set_configuration(0, &flash_config);
++      if (ret < 0) {
++              printk(KERN_ERR "atngw: failed to set NOR flash timing\n");
++              return ret;
++      }
++
++      platform_device_register(&flash_device);
++
++      return 0;
++}
++device_initcall(atngw_flash_init);
+Index: linux-2.6.18/arch/avr32/boards/atngw/setup.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18/arch/avr32/boards/atngw/setup.c       2006-12-13 09:59:44.000000000 +0100
+@@ -0,0 +1,84 @@
++/*
++ * Board-specific setup code for the Atmel Network Gateway
++ *
++ * 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/bootmem.h>
++#include <linux/device.h>
++#include <linux/init.h>
++#include <linux/types.h>
++#include <linux/linkage.h>
++#include <linux/spi/spi.h>
++
++#include <asm/setup.h>
++
++#include <asm/arch/at32ap7000.h>
++#include <asm/arch/board.h>
++#include <asm/arch/init.h>
++
++/* Initialized by bootloader-specific startup code. */
++struct tag *bootloader_tags __initdata;
++
++static struct eth_platform_data __initdata eth_data[2];
++
++static struct spi_board_info spi_board_info[] __initdata = {
++      {
++              .modalias       = "mtd_dataflash",
++              .controller_data = (void *)GPIO_PIN_PA(3),
++              .max_speed_hz   = 66000000,
++              .bus_num        = 0,
++              .chip_select    = 0,
++      },
++};
++
++static int __init parse_tag_ethernet(struct tag *tag)
++{
++      int i;
++
++      i = tag->u.ethernet.mac_index;
++      if (i < ARRAY_SIZE(eth_data)) {
++              eth_data[i].mii_phy_addr = tag->u.ethernet.mii_phy_addr;
++              memcpy(&eth_data[i].hw_addr, tag->u.ethernet.hw_address,
++                     sizeof(eth_data[i].hw_addr));
++              eth_data[i].valid = 1;
++      }
++      return 0;
++}
++__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
++
++void __init setup_board(void)
++{
++      at32_map_usart(1, 0);   /* /dev/ttyS0 */
++
++      at32_setup_serial_console(0);
++}
++
++static int __init atngw_init(void)
++{
++      at32_add_system_devices();
++
++      at32_add_device_usart(0);
++
++      if (eth_data[0].valid)
++              at32_add_device_eth(0, &eth_data[0]);
++      if (eth_data[1].valid)
++              at32_add_device_eth(1, &eth_data[1]);
++
++      spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
++
++      at32_add_device_spi(0);
++      at32_add_device_mmci(0);
++      at32_add_device_usb(0);
++
++      return 0;
++}
++postcore_initcall(atngw_init);
++
++void board_setup_fbmem(unsigned long fbmem_start, unsigned long fbmem_size)
++{
++
++}
diff --git a/packages/linux/linux-2.6.18/avr32-oprofile.patch b/packages/linux/linux-2.6.18/avr32-oprofile.patch
new file mode 100644 (file)
index 0000000..5fbc985
--- /dev/null
@@ -0,0 +1,610 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Wed Jan 4 17:26:23 2006 +0100
+Subject: [PATCH] AVR32 oprofile implementation
+
+This adds support for oprofile on the AVR32 architecture.
+---
+
+ arch/avr32/Kconfig                   |    2 
+ arch/avr32/Makefile                  |    1 
+ arch/avr32/oprofile/Kconfig          |   23 +++
+ arch/avr32/oprofile/Makefile         |   10 +
+ arch/avr32/oprofile/common.c         |  169 +++++++++++++++++++++++++++
+ arch/avr32/oprofile/init.c           |   29 ++++
+ arch/avr32/oprofile/op_avr32_model.h |   25 +++
+ arch/avr32/oprofile/op_counter.h     |   29 ++++
+ arch/avr32/oprofile/op_model_avr32.c |  219 +++++++++++++++++++++++++++++++++++
+ arch/avr32/oprofile/op_model_avr32.h |   21 +++
+ 10 files changed, 528 insertions(+)
+
+Index: linux-2.6.18-avr32/arch/avr32/oprofile/Kconfig
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/oprofile/Kconfig     2006-10-20 14:08:20.000000000 +0200
+@@ -0,0 +1,23 @@
++
++menu "Profiling support"
++      depends on EXPERIMENTAL
++
++config PROFILING
++      bool "Profiling support (EXPERIMENTAL)"
++      help
++        Say Y here to enable the extended profiling support mechanisms used
++        by profilers such as OProfile.
++
++
++config OPROFILE
++      tristate "OProfile system profiling (EXPERIMENTAL)"
++      depends on PROFILING
++      help
++        OProfile is a profiling system capable of profiling the
++        whole system, including the kernel, kernel modules, libraries,
++        and applications.
++
++        If unsure, say N.
++
++endmenu
++
+Index: linux-2.6.18-avr32/arch/avr32/oprofile/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/oprofile/Makefile    2006-10-20 14:08:20.000000000 +0200
+@@ -0,0 +1,10 @@
++obj-$(CONFIG_OPROFILE) += oprofile.o
++
++DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
++              oprof.o cpu_buffer.o buffer_sync.o \
++              event_buffer.o oprofile_files.o \
++              oprofilefs.o oprofile_stats.o \
++              timer_int.o )
++
++oprofile-y                            := $(DRIVER_OBJS) init.o common.o
++oprofile-y                            += op_model_avr32.o
+Index: linux-2.6.18-avr32/arch/avr32/oprofile/common.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/oprofile/common.c    2006-10-20 14:08:20.000000000 +0200
+@@ -0,0 +1,169 @@
++/*
++ * 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.
++ *
++ * Author: Ronny Pedersen
++ */
++
++#define DEBUG
++#include <linux/init.h>
++#include <linux/oprofile.h>
++#include <linux/errno.h>
++#include <asm/semaphore.h>
++#include <linux/sysdev.h>
++
++#include "op_avr32_model.h"
++#include "op_counter.h"
++
++static struct op_avr32_model_spec *pc_model;
++static int pc_enabled = 0;
++static struct semaphore pc_sem;
++
++
++static int pc_start(void);
++static int pc_setup(void);
++static void pc_stop(void);
++static int pc_create_files(struct super_block *, struct dentry *);
++
++
++struct op_counter_config counter_config[OP_MAX_COUNTER];
++
++static int pc_suspend(struct sys_device *dev, u32 state)
++{
++      if (pc_enabled)
++              pc_stop();
++      return 0;
++}
++
++static int pc_resume(struct sys_device *dev)
++{
++      if (pc_enabled)
++              pc_start();
++      return 0;
++}
++
++static struct sysdev_class oprofile_sysclass = {
++      set_kset_name("oprofile"),
++      .resume         = pc_resume,
++      .suspend        = pc_suspend,
++};
++
++static struct sys_device device_oprofile = {
++      .id             = 0,
++      .cls            = &oprofile_sysclass,
++};
++
++static int __init init_driverfs(void)
++{
++      int ret;
++
++      if (!(ret = sysdev_class_register(&oprofile_sysclass)))
++              ret = sysdev_register(&device_oprofile);
++
++      return ret;
++}
++
++static void  exit_driverfs(void)
++{
++      sysdev_unregister(&device_oprofile);
++      sysdev_class_unregister(&oprofile_sysclass);
++}
++
++static int pc_create_files(struct super_block *sb, struct dentry *root)
++{
++      unsigned int i;
++
++      pr_debug("AVR32 Peformance Counters: create files\n");
++      for (i = 0; i < pc_model->num_counters; i++) {
++              struct dentry *dir;
++              char buf[2];
++
++              snprintf(buf, sizeof buf, "%d", i);
++              dir = oprofilefs_mkdir(sb, root, buf);
++              oprofilefs_create_ulong(sb, dir, "enabled",
++                                      &counter_config[i].enabled);
++              oprofilefs_create_ulong(sb, dir, "event",
++                                      &counter_config[i].event);
++              oprofilefs_create_ulong(sb, dir, "count",
++                                      &counter_config[i].count);
++              oprofilefs_create_ulong(sb, dir, "unit_mask",
++                                      &counter_config[i].unit_mask);
++              oprofilefs_create_ulong(sb, dir, "kernel",
++                                      &counter_config[i].kernel);
++              oprofilefs_create_ulong(sb, dir, "user",
++                                      &counter_config[i].user);
++      }
++
++      return 0;
++}
++
++static int pc_setup(void)
++{
++      int ret;
++
++      spin_lock(&oprofilefs_lock);
++      pr_debug("AVR32 Peformance Counters: setup\n");
++      ret = pc_model->setup_ctrs();
++      spin_unlock(&oprofilefs_lock);
++      return ret;
++}
++
++static int pc_start(void)
++{
++      int ret = -EBUSY;
++
++      down(&pc_sem);
++      if (!pc_enabled) {
++              pr_debug("AVR32 Peformance Counters: start\n");
++              ret = pc_model->start();
++              pc_enabled = !ret;
++      }
++      up(&pc_sem);
++      return ret;
++}
++
++static void pc_stop(void)
++{
++      down(&pc_sem);
++      pr_debug("AVR32 Peformance Counters: stop\n");
++      if (pc_enabled)
++              pc_model->stop();
++      pc_enabled = 0;
++      up(&pc_sem);
++}
++
++int __init pc_init(struct oprofile_operations *ops,
++                 struct op_avr32_model_spec *spec)
++{
++      init_MUTEX(&pc_sem);
++
++      if ( spec->init )
++              if (spec->init() < 0)
++                      return -ENODEV;
++
++      pc_model = spec;
++      init_driverfs();
++      ops->create_files = pc_create_files;
++      ops->setup = pc_setup;
++      ops->shutdown = pc_stop;
++      ops->start = pc_start;
++      ops->stop = pc_stop;
++      ops->cpu_type = pc_model->name;
++      printk(KERN_INFO "oprofile: using %s Performance Counters\n",
++             spec->name);
++      pr_debug("AVR32 Peformance Counters: pc_init\n");
++
++      return 0;
++}
++
++void pc_exit(void)
++{
++      if (pc_model) {
++              pr_debug("AVR32 Peformance Counters: exit\n");
++              exit_driverfs();
++              pc_model = NULL;
++      }
++}
+Index: linux-2.6.18-avr32/arch/avr32/oprofile/init.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/oprofile/init.c      2006-10-20 14:08:20.000000000 +0200
+@@ -0,0 +1,29 @@
++/*
++ * 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.
++ *
++ * Author: Ronny Pedersen
++ */
++
++#include <linux/oprofile.h>
++#include <linux/init.h>
++#include <linux/errno.h>
++#include "op_avr32_model.h"
++#include "op_model_avr32.h"
++
++int __init oprofile_arch_init(struct oprofile_operations *ops)
++{
++      int ret = -ENODEV;
++
++      ret = pc_init(ops, &op_avr32_spec);
++
++      return ret;
++}
++
++void oprofile_arch_exit(void)
++{
++      pc_exit();
++}
+Index: linux-2.6.18-avr32/arch/avr32/oprofile/op_avr32_model.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/oprofile/op_avr32_model.h    2006-10-20 14:08:20.000000000 +0200
+@@ -0,0 +1,25 @@
++/*
++ * interface to AVR32 machine specific operations
++ *
++ * 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.
++ *
++ * Author: Ronny Pedersen
++ */
++
++#ifndef OP_AVR32_MODEL_H
++#define OP_AVR32_MODEL_H
++
++struct op_avr32_model_spec {
++      int (*init)(void);
++      unsigned int num_counters;
++      int (*setup_ctrs)(void);
++      int (*start)(void);
++      void (*stop)(void);
++      char *name;
++};
++
++#endif /* OP_AVR32_MODEL_H */
+Index: linux-2.6.18-avr32/arch/avr32/oprofile/op_counter.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/oprofile/op_counter.h        2006-10-20 14:08:20.000000000 +0200
+@@ -0,0 +1,29 @@
++/*
++ * 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.
++ *
++ * Author: Ronny Pedersen
++ */
++#ifndef OP_COUNTER_H
++#define OP_COUNTER_H
++
++#define OP_MAX_COUNTER 3
++
++/* Per performance monitor configuration as set via
++ * oprofilefs.
++ */
++struct op_counter_config {
++      unsigned long count;
++      unsigned long enabled;
++      unsigned long event;
++      unsigned long unit_mask;
++      unsigned long kernel;
++      unsigned long user;
++};
++
++extern struct op_counter_config counter_config[];
++
++#endif /* OP_COUNTER_H */
+Index: linux-2.6.18-avr32/arch/avr32/oprofile/op_model_avr32.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/oprofile/op_model_avr32.c    2006-10-20 14:08:20.000000000 +0200
+@@ -0,0 +1,219 @@
++/*
++ * AVR32 Performance Counter Driver
++ *
++ * 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.
++ *
++ * Author: Ronny Pedersen
++ */
++
++#define DEBUG
++
++#include <linux/types.h>
++#include <linux/errno.h>
++#include <linux/sched.h>
++#include <linux/oprofile.h>
++#include <linux/interrupt.h>
++#include <asm/irq.h>
++#include <asm/system.h>
++#include <asm/sysreg.h>
++
++#include "op_counter.h"
++#include "op_avr32_model.h"
++
++
++#define       PC_ENABLE       0x001   /* Enable counters */
++#define PCNT_RESET    0x002   /* Reset event counters */
++#define       CCNT_RESET      0x004   /* Reset clock counter */
++#define       PC_RESET        (CCNT_RESET | PCNT_RESET)
++#define PC_CNT64      0x008   /* Make CCNT count every 64th cycle */
++
++
++#define EVT_UNUSED                    0xFF
++
++struct pc_counter {
++      volatile unsigned long ovf;
++      unsigned long reset_counter;
++};
++
++enum { PCCNT, PCNT0, PCNT1, MAX_COUNTERS };
++
++#define PCCNT_IE  (1 << 4)
++#define PCNT0_IE  (1 << 5)
++#define PCNT1_IE  (1 << 6)
++
++#define PCCNT_F  (1 << 8)
++#define PCNT0_F  (1 << 9)
++#define PCNT1_F  (1 << 10)
++
++#define AVR32_PC_IRQ 1
++
++static const u32 int_mask[MAX_COUNTERS] = { PCCNT_IE, PCNT0_IE, PCNT1_IE };
++static const u32 ovf_mask[MAX_COUNTERS] = { PCCNT_F, PCNT0_F, PCNT1_F };
++
++static struct pc_counter results[MAX_COUNTERS];
++
++static void write_pccr(u32 val)
++{
++      __builtin_mtsr(SYSREG_PCCR, val);
++}
++
++static u32 read_pccr(void)
++{
++      return __builtin_mfsr(SYSREG_PCCR);
++}
++
++static u32 read_counter(int counter)
++{
++      switch (counter) {
++      case PCCNT:
++              return __builtin_mfsr(SYSREG_PCCNT);
++      case PCNT0:
++              return __builtin_mfsr(SYSREG_PCNT0);
++      case PCNT1:
++              return __builtin_mfsr(SYSREG_PCNT0);
++      default:
++              return 0;
++      }
++}
++
++
++static void write_counter(int counter, u32 val)
++{
++      switch (counter) {
++      case PCCNT:
++              __builtin_mtsr(SYSREG_PCCNT, val);
++      case PCNT0:
++              __builtin_mtsr(SYSREG_PCNT0, val);
++      case PCNT1:
++              __builtin_mtsr(SYSREG_PCNT0, val);
++      default:
++              break;
++      }
++}
++
++static int avr32_setup_ctrs(void)
++{
++      u32  pccr;
++      int i;
++
++      for (i = PCCNT; i < MAX_COUNTERS; i++) {
++              if (counter_config[i].enabled)
++                      continue;
++
++              counter_config[i].event = EVT_UNUSED;
++      }
++
++      pccr = ((counter_config[PCNT1].event << 18)
++              | (counter_config[PCNT0].event << 12));
++      pr_debug("avr32_setup_ctrs: pccr: %#08x\n", pccr);
++      write_pccr(pccr);
++
++      for (i = PCCNT; i < MAX_COUNTERS; i++) {
++              if (counter_config[i].event == EVT_UNUSED) {
++                      counter_config[i].event = 0;
++                      continue;
++              }
++
++              results[i].reset_counter = counter_config[i].count;
++              write_counter(i, -(u32)counter_config[i].count);
++              pr_debug("avr32_setup_ctrs: counter%d %#08x from %#08lx\n",
++                       i, read_counter(i), counter_config[i].count);
++      }
++
++      return 0;
++}
++
++static void inline check_ctrs(void)
++{
++      int i;
++      u32 pccr = read_pccr();
++
++      /* Writeback clears overflow flag */
++      write_pccr(pccr & ~PC_ENABLE);
++
++      for (i = PCCNT; i < MAX_COUNTERS; i++) {
++              if (!(int_mask[i] & pccr))
++                      continue;
++
++              if (pccr & ovf_mask[i])
++                      results[i].ovf++;
++      }
++}
++
++
++static irqreturn_t avr32_pc_interrupt(int irq, void *arg,
++                                    struct pt_regs *regs)
++{
++      int i;
++
++      check_ctrs();
++
++      for (i = PCCNT; i < MAX_COUNTERS; i++) {
++              if (!results[i].ovf)
++                      continue;
++
++              write_counter(i, -(u32)results[i].reset_counter);
++              oprofile_add_sample(regs, i);
++              results[i].ovf--;
++      }
++
++      /* Enable Performance Counter */
++      write_pccr(read_pccr() | PC_ENABLE);
++
++      return IRQ_HANDLED;
++}
++
++static void avr32_pc_stop(void)
++{
++      write_pccr(read_pccr() & ~PC_ENABLE);
++
++      free_irq(AVR32_PC_IRQ, results);
++}
++
++static int avr32_pc_start(void)
++{
++      int i, ret;
++      u32 pccr = read_pccr();
++
++      ret = request_irq(AVR32_PC_IRQ, avr32_pc_interrupt, SA_INTERRUPT,
++                        "AVR32 Performance Counter", (void *)results);
++
++      if (ret < 0) {
++              printk(KERN_ERR
++                     "oprofile: unable to request IRQ%d for AVR32"
++                     " Performance Counter\n",
++                     AVR32_PC_IRQ);
++              return ret;
++      }
++
++      /* Enable interrupts */
++      for (i = PCCNT; i < MAX_COUNTERS; i++) {
++              if (counter_config[i].enabled)
++                      pccr |= int_mask[i];
++      }
++
++      /* Disable scaler */
++      pccr &= ~PC_CNT64;
++
++      /* Enable Performance Counter */
++      pccr |= PC_ENABLE;
++
++      write_pccr(pccr);
++      pr_debug("avr32_pc_start: pc: %#08x\n", pccr);
++      return 0;
++}
++
++
++struct op_avr32_model_spec op_avr32_spec = {
++      .init           = 0,
++      .setup_ctrs     = avr32_setup_ctrs,
++      .start          = avr32_pc_start,
++      .stop           = avr32_pc_stop,
++      .num_counters   = MAX_COUNTERS,
++      .name           = "avr32",
++};
++
+Index: linux-2.6.18-avr32/arch/avr32/oprofile/op_model_avr32.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/arch/avr32/oprofile/op_model_avr32.h    2006-10-20 14:08:20.000000000 +0200
+@@ -0,0 +1,21 @@
++/**
++ * AVR32 Machine Specific Operations
++ *
++ * 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.
++ *
++ * Author: Ronny Pedersen
++ */
++#ifndef OP_MODEL_AVR32_H
++#define OP_MODEL_AVR32_H
++
++extern struct op_avr32_model_spec op_avr32_spec;
++extern int pc_init(struct oprofile_operations *ops,
++                 struct op_avr32_model_spec *spec);
++extern void pc_exit(void);
++
++
++#endif
+Index: linux-2.6.18-avr32/arch/avr32/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/Kconfig 2006-10-20 14:04:43.000000000 +0200
++++ linux-2.6.18-avr32/arch/avr32/Kconfig      2006-10-20 14:08:20.000000000 +0200
+@@ -190,6 +190,8 @@ source "drivers/Kconfig"
+ source "fs/Kconfig"
++source "arch/avr32/oprofile/Kconfig"
++
+ source "arch/avr32/Kconfig.debug"
+ source "security/Kconfig"
+Index: linux-2.6.18-avr32/arch/avr32/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/Makefile        2006-10-20 14:04:54.000000000 +0200
++++ linux-2.6.18-avr32/arch/avr32/Makefile     2006-10-20 14:09:10.000000000 +0200
+@@ -30,6 +30,7 @@ core-$(CONFIG_BOARD_ATSTK1000)               += arch/
+ core-$(CONFIG_LOADER_U_BOOT)          += arch/avr32/boot/u-boot/
+ core-y                                        += arch/avr32/kernel/
+ core-y                                        += arch/avr32/mm/
++drivers-$(CONFIG_OPROFILE)            += arch/avr32/oprofile/
+ libs-y                                        += arch/avr32/lib/
+ archincdir-$(CONFIG_PLATFORM_AT32AP)  := arch-at32ap
diff --git a/packages/linux/linux-2.6.18/avr32-sound.patch b/packages/linux/linux-2.6.18/avr32-sound.patch
new file mode 100644 (file)
index 0000000..597a44d
--- /dev/null
@@ -0,0 +1,51 @@
+---
+ sound/Kconfig        |    2 ++
+ sound/Makefile       |    1 +
+ sound/avr32/Kconfig  |    6 ++++++
+ sound/avr32/Makefile |    3 +++
+ 4 files changed, 12 insertions(+)
+
+Index: linux-2.6.18-avr32/sound/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/sound/Kconfig      2006-09-12 10:44:15.000000000 +0200
++++ linux-2.6.18-avr32/sound/Kconfig   2006-09-12 10:45:14.000000000 +0200
+@@ -62,6 +62,8 @@ source "sound/aoa/Kconfig"
+ source "sound/arm/Kconfig"
++source "sound/avr32/Kconfig"
++
+ source "sound/mips/Kconfig"
+ # the following will depenend on the order of config.
+Index: linux-2.6.18-avr32/sound/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/sound/Makefile     2006-09-12 10:44:15.000000000 +0200
++++ linux-2.6.18-avr32/sound/Makefile  2006-09-12 10:44:37.000000000 +0200
+@@ -5,6 +5,7 @@ obj-$(CONFIG_SOUND) += soundcore.o
+ obj-$(CONFIG_SOUND_PRIME) += oss/
+ obj-$(CONFIG_DMASOUND) += oss/
+ obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ sparc/ parisc/ pcmcia/ mips/
++obj-$(CONFIG_SND) += avr32/
+ obj-$(CONFIG_SND_AOA) += aoa/
+ ifeq ($(CONFIG_SND),y)
+Index: linux-2.6.18-avr32/sound/avr32/Kconfig
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/sound/avr32/Kconfig     2006-09-12 10:45:52.000000000 +0200
+@@ -0,0 +1,6 @@
++# ALSA AVR32 drivers
++
++menu "ALSA AVR32 devices"
++      depends on SND != n && AVR32
++
++endmenu
+Index: linux-2.6.18-avr32/sound/avr32/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/sound/avr32/Makefile    2006-09-12 10:46:03.000000000 +0200
+@@ -0,0 +1,3 @@
++#
++# Makefile for ALSA
++#
diff --git a/packages/linux/linux-2.6.18/avr32-time-add-shared-interrupts.patch b/packages/linux/linux-2.6.18/avr32-time-add-shared-interrupts.patch
new file mode 100644 (file)
index 0000000..c626016
--- /dev/null
@@ -0,0 +1,30 @@
+--- linux-2.6.18.orig/arch/avr32/kernel/time.c 2006-11-06 14:36:50.000000000 +0100
++++ linux-2.6.18/arch/avr32/kernel/time.c      2006-11-06 14:57:03.000000000 +0100
+@@ -21,6 +21,7 @@
+ #include <linux/profile.h>
+ #include <linux/sysdev.h>
++#include <asm/intc.h>
+ #include <asm/div64.h>
+ #include <asm/sysreg.h>
+ #include <asm/io.h>
+@@ -136,6 +137,10 @@
+ {
+       unsigned int count;
++      /* Check if interrupt is timer or performance counters */
++      if (!(intc_get_pending(irq) & 1))
++              return IRQ_NONE;
++
+       /* ack timer interrupt and try to set next interrupt */
+       count = avr32_hpt_read();
+       avr32_timer_ack();
+@@ -164,7 +169,7 @@
+ static struct irqaction timer_irqaction = {
+       .handler        = timer_interrupt,
+-      .flags          = IRQF_DISABLED,
++      .flags          = IRQF_DISABLED|IRQF_SHARED,
+       .name           = "timer",
+ };
diff --git a/packages/linux/linux-2.6.18/avr32-unistd-h-move-ifdef-kernel.patch b/packages/linux/linux-2.6.18/avr32-unistd-h-move-ifdef-kernel.patch
new file mode 100644 (file)
index 0000000..eb16d80
--- /dev/null
@@ -0,0 +1,39 @@
+---
+ include/asm-avr32/unistd.h |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+Index: linux-2.6.18-avr32/include/asm-avr32/unistd.h
+===================================================================
+--- linux-2.6.18-avr32.orig/include/asm-avr32/unistd.h 2006-11-29 16:49:54.000000000 +0100
++++ linux-2.6.18-avr32/include/asm-avr32/unistd.h      2006-11-29 16:50:32.000000000 +0100
+@@ -281,6 +281,7 @@
+ #define __NR_tee              263
+ #define __NR_vmsplice         264
++#ifdef __KERNEL__
+ #define NR_syscalls           265
+@@ -304,7 +305,6 @@
+               return (type) (res);                                    \
+       } while (0)
+-#ifdef __KERNEL__
+ #define __ARCH_WANT_IPC_PARSE_VERSION
+ #define __ARCH_WANT_STAT64
+ #define __ARCH_WANT_SYS_ALARM
+@@ -319,7 +319,6 @@
+ #define __ARCH_WANT_SYS_GETPGRP
+ #define __ARCH_WANT_SYS_RT_SIGACTION
+ #define __ARCH_WANT_SYS_RT_SIGSUSPEND
+-#endif
+ #if defined(__KERNEL_SYSCALLS__) || defined(__CHECKER__)
+@@ -384,4 +383,6 @@ asmlinkage int sys_execve(char __user *u
+  */
+ #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
++#endif /* __KERNEL__ */
++
+ #endif /* __ASM_AVR32_UNISTD_H */
diff --git a/packages/linux/linux-2.6.18/avr32_defconfig b/packages/linux/linux-2.6.18/avr32_defconfig
new file mode 100644 (file)
index 0000000..bf9615c
--- /dev/null
@@ -0,0 +1,1036 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.20
+# Mon Mar  5 16:48:58 2007
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+# 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_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_UTS_NS is not set
+# CONFIG_AUDIT is not set
+# CONFIG_IKCONFIG is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+# CONFIG_KALLSYMS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=1
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODULE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+# CONFIG_KMOD is not set
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=m
+CONFIG_IOSCHED_DEADLINE=m
+CONFIG_IOSCHED_CFQ=m
+# 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"
+
+#
+# System Type and features
+#
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP7000=y
+CONFIG_BOARD_ATSTK1002=y
+CONFIG_BOARD_ATSTK1000=y
+CONFIG_LOADER_U_BOOT=y
+
+#
+# Atmel AVR32 AP options
+#
+CONFIG_PIO_DEV=y
+# CONFIG_AP7000_32_BIT_SMC is not set
+CONFIG_AP7000_16_BIT_SMC=y
+# CONFIG_AP7000_8_BIT_SMC is not set
+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_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+# 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
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_CMDLINE=""
+
+#
+# Bus options
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+CONFIG_PCCARD=y
+CONFIG_PCMCIA_DEBUG=y
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+# CONFIG_PCMCIA_IOCTL is not set
+
+#
+# PC-card bridges
+#
+CONFIG_AT32_CF=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+# CONFIG_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY 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 is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# 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
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+CONFIG_FW_LOADER=y
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_SYS_HYPERVISOR is not set
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+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
+
+#
+# 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
+# CONFIG_MTD_OBSOLETE_CHIPS 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 is not set
+# CONFIG_MTD_M25P80 is not set
+# 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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+CONFIG_BLK_DEV_NBD=m
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+# CONFIG_TIFM_CORE is not set
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=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=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR 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
+
+#
+# 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_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# PCMCIA SCSI adapter support
+#
+# CONFIG_PCMCIA_AHA152X is not set
+# CONFIG_PCMCIA_FDOMAIN is not set
+# CONFIG_PCMCIA_NINJA_SCSI is not set
+# CONFIG_PCMCIA_QLOGIC is not set
+# CONFIG_PCMCIA_SYM53C500 is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_PATA_PCMCIA=y
+# CONFIG_PATA_PLATFORM is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT 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_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# I2C Algorithms
+#
+# CONFIG_I2C_ALGOBIT is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_ALGOPCA is not set
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_ATMELTWI=y
+CONFIG_I2C_ATMELTWI_BAUDRATE=100000
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_PCA_ISA 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=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
+#
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# 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
+CONFIG_FB_SIDSA=y
+CONFIG_FB_SIDSA_DEFAULT_BPP=16
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+
+#
+# Logo configuration
+#
+# CONFIG_LOGO is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_DEVICE=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_DEVICE=y
+CONFIG_LCD_LTV350QV=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+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=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# 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
+
+#
+# ALSA AVR32 devices
+#
+# CONFIG_SND_ATMEL_AC97 is not set
+CONFIG_SND_AT73C213=y
+# CONFIG_SND_AT73C213_USE_ALSA_MALLOC_CALLS is not set
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+
+#
+# USB support
+#
+# 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'
+#
+
+#
+# USB Gadget Support
+#
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# 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_HUSB2DEV=y
+CONFIG_USB_HUSB2DEV=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
+
+#
+# MMC/SD Card support
+#
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_ATMELMCI=y
+# CONFIG_MMC_TIFM_SD is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+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_EXT4DEV_FS 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_MINIX_FS is not set
+# CONFIG_ROMFS_FS 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 is not set
+
+#
+# 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 is not set
+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 is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_RAMFS=y
+CONFIG_CONFIGFS_FS=y
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+CONFIG_NFS_FS=m
+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_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# 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
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# 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 is not set
+# 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 is not set
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Profiling support
+#
+# CONFIG_PROFILING is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS 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_FRAME_POINTER is not set
+# CONFIG_FORCED_INLINING is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_KPROBES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_IOMAP_COPY=y
diff --git a/packages/linux/linux-2.6.18/dmac-add-explicit-blockcount-to-dma_request_sg.patch b/packages/linux/linux-2.6.18/dmac-add-explicit-blockcount-to-dma_request_sg.patch
new file mode 100644 (file)
index 0000000..54400ae
--- /dev/null
@@ -0,0 +1,66 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Sun, 14 Jan 2007 19:07:06 +0100
+Subject: [DW DMAC] Add nr_blocks field to struct dma_request_sg
+
+Allow drivers to specify how many blocks to transfer in a sg request.
+The number of blocks will no longer be automatically calculated based
+on the scatterlist because this doesn't always correspond with the
+desired amount of data to be transferred.
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+---
+ arch/avr32/drivers/dw-dmac.c       |   13 ++++++-------
+ include/asm-avr32/dma-controller.h |    1 +
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+Index: linux-2.6.18-avr32/include/asm-avr32/dma-controller.h
+===================================================================
+--- linux-2.6.18-avr32.orig/include/asm-avr32/dma-controller.h 2007-01-15 15:34:32.000000000 +0100
++++ linux-2.6.18-avr32/include/asm-avr32/dma-controller.h      2007-01-15 15:34:50.000000000 +0100
+@@ -36,6 +36,7 @@ struct dma_request_sg {
+       int nr_sg;
+       struct scatterlist *sg;
+       unsigned long block_size;
++      unsigned int nr_blocks;
+       dma_addr_t data_reg;
+       unsigned short periph_id;
+Index: linux-2.6.18-avr32/arch/avr32/drivers/dw-dmac.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/drivers/dw-dmac.c       2007-01-15 15:35:00.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/drivers/dw-dmac.c    2007-01-15 15:35:03.000000000 +0100
+@@ -176,7 +176,8 @@ static int dmac_prepare_request_sg(struc
+       struct dw_dma_channel *chan;
+       unsigned long ctlhi, ctllo, cfghi, cfglo;
+       unsigned long block_size;
+-      int ret, i, nr_blocks, direction;
++      unsigned int nr_blocks;
++      int ret, i, direction;
+       unsigned long flags;
+       spin_lock_irqsave(&dmac->lock, flags);
+@@ -215,12 +216,9 @@ static int dmac_prepare_request_sg(struc
+        * Each block will get its own Linked List Item (LLI) below.
+        */
+       block_size = req->block_size;
+-      pr_debug("block_size = %lu, nr_sg = %u\n", block_size, req->nr_sg);
+-      for (i = 0, nr_blocks = 0; i < req->nr_sg; i++) {
+-              pr_debug("sg[i].length = %u\n", req->sg[i].length);
+-              BUG_ON(req->sg[i].length % block_size);
+-              nr_blocks += req->sg[i].length / 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;
+@@ -269,6 +267,7 @@ static int dmac_prepare_request_sg(struc
+               }
+               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;
diff --git a/packages/linux/linux-2.6.18/dmac-stopping-idle-channel-is-not-fatal.patch b/packages/linux/linux-2.6.18/dmac-stopping-idle-channel-is-not-fatal.patch
new file mode 100644 (file)
index 0000000..ed2714d
--- /dev/null
@@ -0,0 +1,93 @@
+---
+ arch/avr32/drivers/dw-dmac.c |   50 ++++++++++++++++++++++++-------------------
+ 1 file changed, 29 insertions(+), 21 deletions(-)
+
+Index: linux-2.6.18-avr32/arch/avr32/drivers/dw-dmac.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/drivers/dw-dmac.c       2007-01-04 09:56:32.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/drivers/dw-dmac.c    2007-01-04 15:38:13.000000000 +0100
+@@ -7,7 +7,6 @@
+  * 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>
+@@ -155,6 +154,21 @@ fail:
+       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)
+ {
+@@ -313,6 +327,7 @@ static int dmac_prepare_request_sg(struc
+                * 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);
+@@ -520,33 +535,26 @@ static dma_addr_t dmac_get_current_pos(s
+ }
+-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_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);
+-      BUG_ON(dmac->channel[channel].state != CH_STATE_BUSY);
+-
+-      clear_channel_bit(dmac, CH_EN, channel);
+-
+-        cleanup_channel(dmac, &dmac->channel[channel]);
++      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;
+ }
diff --git a/packages/linux/linux-2.6.18/dont-include-map-h-from-physmap-h.patch b/packages/linux/linux-2.6.18/dont-include-map-h-from-physmap-h.patch
new file mode 100644 (file)
index 0000000..c7f03f9
--- /dev/null
@@ -0,0 +1,33 @@
+From 00424e00aeeecfd17ee71918b183e50d07641c5e Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Wed, 10 Jan 2007 18:55:18 +0100
+Subject: [PATCH] MTD: Don't include map.h from physmap.h
+
+Replace inclusion of <linux/mtd/map.h> with a forward-declaration of
+struct map_info. This is necessary because physmap.h may be included
+in platform code and map.h will give errors if MTD isn't enabled.
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+---
+ include/linux/mtd/physmap.h |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h
+index 86831e3..0dc07d5 100644
+--- a/include/linux/mtd/physmap.h
++++ b/include/linux/mtd/physmap.h
+@@ -18,9 +18,10 @@
+ #define __LINUX_MTD_PHYSMAP__
+ #include <linux/mtd/mtd.h>
+-#include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
++struct map_info;
++
+ struct physmap_flash_data {
+       unsigned int            width;
+       void                    (*set_vpp)(struct map_info *, int);
+-- 
+1.4.4.1
+
diff --git a/packages/linux/linux-2.6.18/fix-alpha-color-bitfield.patch b/packages/linux/linux-2.6.18/fix-alpha-color-bitfield.patch
new file mode 100644 (file)
index 0000000..f563a50
--- /dev/null
@@ -0,0 +1,21 @@
+---
+ drivers/video/sidsafb.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+Index: linux-2.6.18-avr32/drivers/video/sidsafb.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/video/sidsafb.c    2006-10-11 15:14:06.000000000 +0200
++++ linux-2.6.18-avr32/drivers/video/sidsafb.c 2006-10-18 14:51:31.000000000 +0200
+@@ -300,8 +300,11 @@ static int sidsafb_check_var(struct fb_v
+               var->green.length = 5;
+               var->blue.length = 5;
+               break;
+-      case 24:
+       case 32:
++              var->transp.offset = 24;
++              var->transp.length = 8;
++              /* fall through */
++      case 24:
+               var->red.offset = 16;
+               var->green.offset = 8;
+               var->blue.offset = 0;
diff --git a/packages/linux/linux-2.6.18/fix-gpio-prototypes.patch b/packages/linux/linux-2.6.18/fix-gpio-prototypes.patch
new file mode 100644 (file)
index 0000000..2b5a096
--- /dev/null
@@ -0,0 +1,75 @@
+---
+ arch/avr32/mach-at32ap/pio.c         |   15 +++++++++------
+ include/asm-avr32/arch-at32ap/gpio.h |    6 +++---
+ 2 files changed, 12 insertions(+), 9 deletions(-)
+
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/pio.c       2006-11-29 18:14:54.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c    2006-11-29 18:17:15.000000000 +0100
+@@ -49,7 +49,7 @@ static struct pio_device *gpio_to_pio(un
+ /* Pin multiplexing API */
+ void __init at32_select_periph(unsigned int pin, unsigned int periph,
+-                             int use_pullup)
++                             unsigned long flags)
+ {
+       struct pio_device *pio;
+       unsigned int pin_index = pin & 0x1f;
+@@ -73,7 +73,7 @@ void __init at32_select_periph(unsigned 
+               pio_writel(pio, ASR, mask);
+       pio_writel(pio, PDR, mask);
+-      if (!use_pullup)
++      if (!(flags & AT32_GPIOF_PULLUP))
+               pio_writel(pio, PUDR, mask);
+       return;
+@@ -82,8 +82,7 @@ fail:
+       dump_stack();
+ }
+-void __init at32_select_gpio(unsigned int pin, int enable_output,
+-                           int use_pullup)
++void __init at32_select_gpio(unsigned int pin, unsigned long flags)
+ {
+       struct pio_device *pio;
+       unsigned int pin_index = pin & 0x1f;
+@@ -101,13 +100,17 @@ void __init at32_select_gpio(unsigned in
+       }
+       pio_writel(pio, PUER, mask);
+-      if (enable_output)
++      if (flags & AT32_GPIOF_HIGH)
++              pio_writel(pio, SODR, mask);
++      else
++              pio_writel(pio, CODR, mask);
++      if (flags & AT32_GPIOF_OUTPUT)
+               pio_writel(pio, OER, mask);
+       else
+               pio_writel(pio, ODR, mask);
+       pio_writel(pio, PER, mask);
+-      if (!use_pullup)
++      if (!(flags & AT32_GPIOF_PULLUP))
+               pio_writel(pio, PUDR, mask);
+       /* It's now allowed to use request_gpio on this pin */
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/gpio.h
+===================================================================
+--- linux-2.6.18-avr32.orig/include/asm-avr32/arch-at32ap/gpio.h       2006-11-29 18:14:37.000000000 +0100
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/gpio.h    2006-11-29 18:15:06.000000000 +0100
+@@ -1,5 +1,5 @@
+-#ifndef __ASM_AVR32_GPIO_H
+-#define __ASM_AVR32_GPIO_H
++#ifndef __ASM_AVR32_ARCH_GPIO_H
++#define __ASM_AVR32_ARCH_GPIO_H
+ #include <linux/compiler.h>
+ #include <asm/irq.h>
+@@ -36,4 +36,4 @@ static inline int irq_to_gpio(unsigned i
+       return irq - GPIO_IRQ_BASE;
+ }
+-#endif /* __ASM_AVR32_GPIO_H */
++#endif /* __ASM_AVR32_ARCH_GPIO_H */
diff --git a/packages/linux/linux-2.6.18/fix-lcd-display-off-by-two-problem.patch b/packages/linux/linux-2.6.18/fix-lcd-display-off-by-two-problem.patch
new file mode 100644 (file)
index 0000000..e99619a
--- /dev/null
@@ -0,0 +1,17 @@
+---
+ drivers/video/sidsafb.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux-2.6.18-avr32/drivers/video/sidsafb.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/video/sidsafb.c    2006-11-27 15:47:16.000000000 +0100
++++ linux-2.6.18-avr32/drivers/video/sidsafb.c 2006-11-27 15:47:25.000000000 +0100
+@@ -107,7 +107,7 @@ static struct fb_videomode samsung_modes
+               .pixclock       = 145111,
+               .left_margin    = 17,           .right_margin   = 33,
+-              .upper_margin   = 8,            .lower_margin   = 10,
++              .upper_margin   = 10,           .lower_margin   = 10,
+               .hsync_len      = 16,           .vsync_len      = 1,
+               .sync           = FB_SYNC_PCLK_RISING,
diff --git a/packages/linux/linux-2.6.18/fix-usart3-rx-BUG.patch b/packages/linux/linux-2.6.18/fix-usart3-rx-BUG.patch
new file mode 100644 (file)
index 0000000..1035f9f
--- /dev/null
@@ -0,0 +1,25 @@
+---
+ drivers/serial/atmel_usart.c |   10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+Index: linux-2.6.18-avr32/drivers/serial/atmel_usart.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/serial/atmel_usart.c       2006-11-24 15:59:38.000000000 +0100
++++ linux-2.6.18-avr32/drivers/serial/atmel_usart.c    2006-11-24 15:59:46.000000000 +0100
+@@ -194,8 +194,14 @@ static inline int rx_dma_update_tail(str
+               usart3_writel(up, RNCR, RX_BUFFER_SIZE);
+               again = 1;
+-      } else
+-              BUG_ON(usart3_readl(up, CSR) & USART3_BIT(ENDRX));
++      } else if(usart3_readl(up, CSR) & USART3_BIT(ENDRX)) {
++              /*
++               * The USART hit the end of the buffer after head was
++               * updated.  Let's do another pass so that we can
++               * avoid taking another interrupt immediately.
++               */
++              again = 1;
++      }
+       up->rx_tail = tail;
diff --git a/packages/linux/linux-2.6.18/gpio-define-pio-none.patch b/packages/linux/linux-2.6.18/gpio-define-pio-none.patch
new file mode 100644 (file)
index 0000000..802a535
--- /dev/null
@@ -0,0 +1,11 @@
+Index: linux-2.6.18/include/asm-avr32/arch-at32ap/at32ap7000.h
+===================================================================
+--- linux-2.6.18.orig/include/asm-avr32/arch-at32ap/at32ap7000.h       2006-12-11 14:53:54.000000000 +0100
++++ linux-2.6.18/include/asm-avr32/arch-at32ap/at32ap7000.h    2006-12-11 14:56:54.000000000 +0100
+@@ -23,4 +23,6 @@
+ #define GPIO_PIN_PD(N)        (GPIO_PIOD_BASE + (N))
+ #define GPIO_PIN_PE(N)        (GPIO_PIOE_BASE + (N))
++#define GPIO_PIO_NONE (0xFFFFffff)
++
+ #endif /* __ASM_ARCH_AT32AP7000_H */
diff --git a/packages/linux/linux-2.6.18/gpio-dev-blocking-read.patch b/packages/linux/linux-2.6.18/gpio-dev-blocking-read.patch
new file mode 100644 (file)
index 0000000..9508d9e
--- /dev/null
@@ -0,0 +1,187 @@
+---
+ arch/avr32/mach-at32ap/pio.c |  113 +++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 113 insertions(+)
+
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/pio.c       2006-11-30 13:16:43.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c    2006-11-30 17:15:24.000000000 +0100
+@@ -250,7 +250,11 @@ EXPORT_SYMBOL(gpio_set_value);
+ #ifdef CONFIG_PIO_DEV
+ #include <linux/configfs.h>
+ #include <linux/cdev.h>
++#include <linux/fs.h>
++#include <linux/interrupt.h>
++#include <linux/poll.h>
+ #include <linux/uaccess.h>
++#include <linux/wait.h>
+ #define GPIO_DEV_MAX                  8
+@@ -267,6 +271,13 @@ struct gpio_item {
+       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;
+@@ -279,36 +290,135 @@ struct gpio_attribute {
+       ssize_t (*store)(struct gpio_item *, const char *, size_t);
+ };
++static irqreturn_t gpio_dev_interrupt(int irq, void *dev_id,
++                                    struct pt_regs *regs)
++{
++      struct gpio_item *gpio = dev_id;
++      u32 old_state, new_state;
++
++      old_state = gpio->pin_state;
++      new_state = pio_readl(gpio->pio, PDSR);
++      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 = pio_readl(gpio->pio, PDSR) & gpio->pin_mask;
++      gpio->changed = 1;
++
++      for (i = 0; i < 32; i++) {
++              if (gpio->pin_mask & (1 << i)) {
++                      irq = gpio_to_irq(32 * pio_id(gpio->pio) + 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 * pio_id(gpio->pio) + 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 * pio_id(gpio->pio) + 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 = pio_readl(gpio->pio, PDSR) & 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;
+ }
+@@ -338,6 +448,8 @@ static struct file_operations gpio_dev_f
+       .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,
+ };
+@@ -632,6 +744,7 @@ static struct config_item *gpio_make_ite
+       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;
+ }
diff --git a/packages/linux/linux-2.6.18/gpio-dev-robustness.patch b/packages/linux/linux-2.6.18/gpio-dev-robustness.patch
new file mode 100644 (file)
index 0000000..56ef0eb
--- /dev/null
@@ -0,0 +1,204 @@
+Make the GPIO /dev interface a bit more robust
+
+Instead of allocating gpio resources on-the-fly as the files are
+written, defer it until enable is set to 1 and disallow updates to
+any of the other files while enable=1.
+
+Otherwise, the number of checks in each _store function will rapidly
+approach insanity.
+---
+ arch/avr32/mach-at32ap/pio.c |   99 ++++++++++++++++++-------------------------
+ 1 file changed, 43 insertions(+), 56 deletions(-)
+
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/pio.c       2006-11-29 17:10:54.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c    2006-11-29 18:11:38.000000000 +0100
+@@ -124,13 +124,6 @@ static unsigned int pio_id(struct pio_de
+       return pio - pio_dev;
+ }
+-static void __enable_gpio(struct pio_device *pio, u32 mask)
+-{
+-      pio_writel(pio, PUER, mask);
+-      pio_writel(pio, ODR, mask);
+-      pio_writel(pio, PER, mask);
+-}
+-
+ static void __disable_gpio(struct pio_device *pio, u32 mask)
+ {
+       pio_writel(pio, PUER, mask);
+@@ -251,11 +244,12 @@ static dev_t gpio_devt;
+ struct gpio_item {
+       spinlock_t lock;
+-      /* Too bad we don't have committable items... */
+-      int enabled;
+-
+       struct pio_device *pio;
++
++      int enabled;
++      int pio_id;
+       u32 pin_mask;
++      u32 oe_mask;
+       int id;
+       struct class_device *gpio_dev;
+@@ -339,10 +333,7 @@ static struct gpio_item *to_gpio_item(st
+ static ssize_t gpio_show_gpio_id(struct gpio_item *gpio, char *page)
+ {
+-      if (gpio->pio)
+-              return sprintf(page, "%u\n", pio_id(gpio->pio));
+-      else
+-              return sprintf(page, "-1\n");
++      return sprintf(page, "%d\n", gpio->pio_id);
+ }
+ static ssize_t gpio_store_gpio_id(struct gpio_item *gpio,
+@@ -361,7 +352,7 @@ static ssize_t gpio_store_gpio_id(struct
+       if (!gpio->enabled) {
+               ret = -ENXIO;
+               if ((id < MAX_NR_PIO_DEVICES) && pio_dev[id].regs) {
+-                      gpio->pio = &pio_dev[id];
++                      gpio->pio_id = id;
+                       ret = count;
+               }
+       }
+@@ -378,9 +369,7 @@ static ssize_t gpio_show_pin_mask(struct
+ static ssize_t gpio_store_pin_mask(struct gpio_item *gpio,
+                                  const char *page, size_t count)
+ {
+-      struct pio_device *pio;
+-      u32 old_mask, new_mask;
+-      u32 old, new;
++      u32 new_mask;
+       char *p = (char *)page;
+       ssize_t ret = -EINVAL;
+@@ -388,47 +377,21 @@ static ssize_t gpio_store_pin_mask(struc
+       if (!p || (*p && (*p != '\n')))
+               return -EINVAL;
+-      /*
+-       * Must have a PIO before we can start allocating pins, but we
+-       * must not be live.
+-       */
++      /* Can't update the pin mask while live. */
+       spin_lock(&gpio->lock);
+-      pio = gpio->pio;
+-      if (!pio || gpio->enabled)
+-              goto out;
+-
+-      ret = -EBUSY;
+-      old_mask = gpio->pin_mask;
+-      do {
+-              old = pio->pinmux_mask;
+-              if ((old & ~old_mask) & new_mask)
+-                      goto out;
+-
+-              new = (old & ~old_mask) | new_mask;
+-      } while (cmpxchg(&pio->pinmux_mask, old, new) != old);
+-
+-      gpio->pin_mask = new_mask;
+-      __disable_gpio(pio, old_mask);
+-      __enable_gpio(pio, new_mask);
+-      ret = count;
+-
+-out:
++      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)
+ {
+-      u32 mask = 0;
+-
+-      spin_lock(&gpio->lock);
+-      if (gpio->pio) {
+-              mask = pio_readl(gpio->pio, OSR);
+-              mask &= gpio->pin_mask;
+-      }
+-      spin_unlock(&gpio->lock);
+-
+-      return sprintf(page, "0x%08x\n", mask);
++      return sprintf(page, "0x%08x\n", gpio->oe_mask);
+ }
+ static ssize_t gpio_store_oe_mask(struct gpio_item *gpio,
+@@ -443,10 +406,8 @@ static ssize_t gpio_store_oe_mask(struct
+               return -EINVAL;
+       spin_lock(&gpio->lock);
+-      if (gpio->pio) {
+-              mask &= gpio->pin_mask;
+-              pio_writel(gpio->pio, ODR, mask ^ gpio->pin_mask);
+-              pio_writel(gpio->pio, OER, mask);
++      if (!gpio->enabled) {
++              gpio->oe_mask = mask & gpio->pin_mask;
+               ret = count;
+       }
+       spin_unlock(&gpio->lock);
+@@ -462,6 +423,8 @@ static ssize_t gpio_show_enabled(struct 
+ static ssize_t gpio_store_enabled(struct gpio_item *gpio,
+                                 const char *page, size_t count)
+ {
++      struct pio_device *pio;
++      u32 old, new;
+       char *p = (char *)page;
+       int enabled;
+       int ret;
+@@ -482,6 +445,12 @@ static ssize_t gpio_store_enabled(struct
+       if (!enabled) {
+               class_device_unregister(gpio->gpio_dev);
+               cdev_del(&gpio->char_dev);
++              __disable_gpio(gpio->pio, gpio->pin_mask);
++              pio_dealloc_mask(gpio->pio, gpio->pin_mask);
++              gpio->pio = NULL;
++      } else {
++              if (gpio->pio_id < 0 || !gpio->pin_mask)
++                      return -ENODEV;
+       }
+       /* Disallow any updates to gpio_id or pin_mask */
+@@ -492,6 +461,20 @@ static ssize_t gpio_store_enabled(struct
+       if (!enabled)
+               return count;
++      /* Now, try to allocate the pins */
++      ret = -EBUSY;
++      pio = gpio->pio = &pio_dev[gpio->pio_id];
++      do {
++              old = pio->pinmux_mask;
++              if (old & gpio->pin_mask)
++                      goto err_alloc_pins;
++
++              new = old | gpio->pin_mask;
++      } while (cmpxchg(&pio->pinmux_mask, old, new) != old);
++
++      pio_writel(pio, OER, gpio->oe_mask);
++      pio_writel(pio, PER, gpio->pin_mask);
++
+       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);
+@@ -516,9 +499,13 @@ static ssize_t gpio_store_enabled(struct
+ err_class_dev:
+       cdev_del(&gpio->char_dev);
+ err_cdev_add:
++      __disable_gpio(pio, gpio->pin_mask);
++      pio_dealloc_mask(pio, gpio->pin_mask);
++err_alloc_pins:
+       spin_lock(&gpio->lock);
+       gpio->enabled = 0;
+       spin_unlock(&gpio->lock);
++      gpio->pio = NULL;
+       return ret;
+ }
diff --git a/packages/linux/linux-2.6.18/husb2_udc-test-mode.patch b/packages/linux/linux-2.6.18/husb2_udc-test-mode.patch
new file mode 100644 (file)
index 0000000..f87f71f
--- /dev/null
@@ -0,0 +1,267 @@
+From hskinnemoen@atmel.com Wed Jan 17 10:05:04 2007
+Date: Wed, 17 Jan 2007 10:05:04 +0100
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Subject: [PATCH] Implement USB test modes for husb2_udc
+
+This patch implements the four test modes defined by the USB 2.0
+standard: Test_J, Test_K, Test_SE0_NAK and Test_Packet.
+
+This patch also contains a couple of more or less unrelated bug fixes
+and debug features:
+
+  * Add "state" file to debugfs for control endpoint. This allows us to
+    see which state the control logic got stuck in when things go bad.
+  * REMOTE_WAKEUP requests are ignored instead of stalling the device.
+  * Bad packet length causes warning message + stall instead of BUG().
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+---
+ drivers/usb/gadget/husb2_udc.c |  135 +++++++++++++++++++++++++++++++++++++++--
+ drivers/usb/gadget/husb2_udc.h |    8 +-
+ 2 files changed, 135 insertions(+), 8 deletions(-)
+
+Index: linux-2.6.18-avr32/drivers/usb/gadget/husb2_udc.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/usb/gadget/husb2_udc.c     2007-01-16 15:01:42.000000000 +0100
++++ linux-2.6.18-avr32/drivers/usb/gadget/husb2_udc.c  2007-01-17 09:56:24.000000000 +0100
+@@ -254,9 +254,20 @@ static void husb2_ep_init_debugfs(struct
+               if (!ep->debugfs_dma_status)
+                       goto err_dma_status;
+       }
++      if (ep_is_control(ep)) {
++              ep->debugfs_state
++                      = debugfs_create_u32("state", 0400, ep_root,
++                                           &ep->state);
++              if (!ep->debugfs_state)
++                      goto err_state;
++      }
++
+       return;
++err_state:
++      if (ep_can_dma(ep))
++              debugfs_remove(ep->debugfs_dma_status);
+ err_dma_status:
+       debugfs_remove(ep->debugfs_queue);
+ err_queue:
+@@ -270,6 +281,7 @@ static void husb2_ep_cleanup_debugfs(str
+ {
+       debugfs_remove(ep->debugfs_queue);
+       debugfs_remove(ep->debugfs_dma_status);
++      debugfs_remove(ep->debugfs_state);
+       debugfs_remove(ep->debugfs_dir);
+       ep->debugfs_dma_status = NULL;
+       ep->debugfs_dir = NULL;
+@@ -336,7 +348,7 @@ static inline void husb2_cleanup_debugfs
+ }
+ #endif
+-static void copy_to_fifo(void __iomem *fifo, void *buf, int len)
++static void copy_to_fifo(void __iomem *fifo, const void *buf, int len)
+ {
+       unsigned long tmp;
+@@ -1302,6 +1314,90 @@ static inline void set_address(struct hu
+       husb2_writel(udc, CTRL, regval);
+ }
++static int do_test_mode(struct husb2_udc *udc)
++{
++      static const char test_packet_buffer[] = {
++              /* JKJKJKJK * 9 */
++              0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
++              /* JJKKJJKK * 8 */
++              0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,
++              /* JJKKJJKK * 8 */
++              0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,
++              /* JJJJJJJKKKKKKK * 8 */
++              0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
++              /* JJJJJJJK * 8 */
++              0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,
++              /* {JKKKKKKK * 10}, JK */
++              0xFC,0x7E,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0x7E
++      };
++      struct husb2_ep *ep;
++      int test_mode;
++
++      test_mode = udc->test_mode;
++
++      /* Start from a clean slate */
++      reset_all_endpoints(udc);
++
++      switch (test_mode) {
++      case 0x0100:
++              /* Test_J */
++              husb2_writel(udc, TST, HUSB2_BIT(TST_J_MODE));
++              printk("udc: Entering Test_J mode...\n");
++              break;
++      case 0x0200:
++              /* Test_K */
++              husb2_writel(udc, TST, HUSB2_BIT(TST_K_MODE));
++              printk("udc: Entering Test_K mode...\n");
++              break;
++      case 0x0300:
++              /*
++               * Test_SE0_NAK: Force high-speed mode and set up ep0
++               * for Bulk IN transfers
++               */
++              ep = &husb2_ep[0];
++              husb2_writel(udc, TST,
++                           HUSB2_BF(SPEED_CFG, HUSB2_SPEED_CFG_FORCE_HIGH));
++              husb2_ep_writel(ep, CFG,
++                              HUSB2_BF(EPT_SIZE, HUSB2_EPT_SIZE_64)
++                              | HUSB2_BIT(EPT_DIR)
++                              | HUSB2_BF(EPT_TYPE, HUSB2_EPT_TYPE_BULK)
++                              | HUSB2_BF(BK_NUMBER, 1));
++              if (!(husb2_ep_readl(ep, CFG) & HUSB2_BIT(EPT_MAPPED))) {
++                      set_protocol_stall(udc, ep);
++                      printk("udc: Test_SE0_NAK: ep0 not mapped\n");
++              } else {
++                      husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(EPT_ENABLE));
++                      printk("udc: Entering Test_SE0_NAK mode...\n");
++              }
++              break;
++      case 0x0400:
++              /* Test_Packet */
++              ep = &husb2_ep[0];
++              husb2_ep_writel(ep, CFG,
++                              HUSB2_BF(EPT_SIZE, HUSB2_EPT_SIZE_64)
++                              | HUSB2_BIT(EPT_DIR)
++                              | HUSB2_BF(EPT_TYPE, HUSB2_EPT_TYPE_BULK)
++                              | HUSB2_BF(BK_NUMBER, 1));
++              if (!(husb2_ep_readl(ep, CFG) & HUSB2_BIT(EPT_MAPPED))) {
++                      set_protocol_stall(udc, ep);
++                      printk("udc: Test_Packet: ep0 not mapped\n");
++              } else {
++                      husb2_ep_writel(ep, CTL_ENB, HUSB2_BIT(EPT_ENABLE));
++                      husb2_writel(udc, TST, HUSB2_BIT(TST_PKT_MODE));
++                      copy_to_fifo(ep->fifo, test_packet_buffer,
++                                   sizeof(test_packet_buffer));
++                      husb2_ep_writel(ep, SET_STA, HUSB2_BIT(TX_PK_RDY));
++                      printk("udc: Entering Test_Packet mode...\n");
++              }
++              break;
++      default:
++              printk("udc: Invalid test mode: 0x%04x\n", test_mode);
++              return -EINVAL;
++      }
++
++      return 0;
++}
++
+ static int handle_ep0_setup(struct husb2_udc *udc, struct husb2_ep *ep,
+                           struct usb_ctrlrequest *crq)
+ {
+@@ -1341,8 +1437,13 @@ static int handle_ep0_setup(struct husb2
+       case USB_REQ_CLEAR_FEATURE: {
+               if (crq->bRequestType == USB_RECIP_DEVICE) {
+-                      /* We don't support TEST_MODE */
+-                      goto stall;
++                      if (crq->wValue
++                          == __constant_cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP)) {
++                              /* TODO: Handle REMOTE_WAKEUP */
++                      } else {
++                              /* CLEAR_FEATURE doesn't make sense for TEST_MODE */
++                              goto stall;
++                      }
+               } else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
+                       struct husb2_ep *target;
+@@ -1365,8 +1466,18 @@ static int handle_ep0_setup(struct husb2
+       case USB_REQ_SET_FEATURE: {
+               if (crq->bRequestType == USB_RECIP_DEVICE) {
+-                      /* We don't support TEST_MODE */
+-                      goto stall;
++                      if (crq->wValue
++                          == __constant_cpu_to_le16(USB_DEVICE_TEST_MODE)) {
++                              send_status(udc, ep);
++                              ep->state = STATUS_STAGE_TEST;
++                              udc->test_mode = le16_to_cpu(crq->wIndex);
++                              return 0;
++                      } else if (crq->wValue
++                                 == __constant_cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP)) {
++                              /* TODO: Handle REMOTE_WAKEUP */
++                      } else {
++                              goto stall;
++                      }
+               } else if (crq->bRequestType == USB_RECIP_ENDPOINT) {
+                       struct husb2_ep *target;
+@@ -1476,6 +1587,12 @@ restart:
+                                       HUSB2_BIT(TX_COMPLETE));
+                       ep->state = WAIT_FOR_SETUP;
+                       break;
++              case STATUS_STAGE_TEST:
++                      husb2_ep_writel(ep, CTL_DIS, HUSB2_BIT(TX_COMPLETE));
++                      ep->state = WAIT_FOR_SETUP;
++                      if (do_test_mode(udc))
++                              set_protocol_stall(udc, ep);
++                      break;
+               default:
+                       printk(KERN_ERR
+                              "udc: %s: TXCOMP: Invalid endpoint state %d, "
+@@ -1550,7 +1667,13 @@ restart:
+               pkt_len = HUSB2_BFEXT(BYTE_COUNT, husb2_ep_readl(ep, STA));
+               DBG(DBG_HW, "Packet length: %u\n", pkt_len);
+-              BUG_ON(pkt_len != sizeof(crq));
++              if (pkt_len != sizeof(crq)) {
++                      printk(KERN_WARNING
++                             "udc: Invalid packet length %u (expected %lu)\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));
+Index: linux-2.6.18-avr32/drivers/usb/gadget/husb2_udc.h
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/usb/gadget/husb2_udc.h     2007-01-16 15:01:42.000000000 +0100
++++ linux-2.6.18-avr32/drivers/usb/gadget/husb2_udc.h  2007-01-17 09:54:03.000000000 +0100
+@@ -21,7 +21,7 @@
+ #define HUSB2_TST_CNT_A                               0x00d4
+ #define HUSB2_TST_CNT_B                               0x00d8
+ #define HUSB2_TST_MODE_REG                    0x00dc
+-#define HUSB2_TST                             0x00f0
++#define HUSB2_TST                             0x00e0
+ /* USB endpoint register offsets */
+ #define HUSB2_EPT_CFG                         0x0000
+@@ -113,7 +113,7 @@
+ #define HUSB2_TST_J_MODE_SIZE                 1
+ #define HUSB2_TST_K_MODE_OFFSET                       3
+ #define HUSB2_TST_K_MODE_SIZE                 1
+-#define HUSB2_TST_PKT_MODE_OFFSE              4
++#define HUSB2_TST_PKT_MODE_OFFSET             4
+ #define HUSB2_TST_PKT_MODE_SIZE                       1
+ #define HUSB2_OPMODE2_OFFSET                  5
+ #define HUSB2_OPMODE2_SIZE                    1
+@@ -304,6 +304,7 @@ enum husb2_ctrl_state {
+       STATUS_STAGE_IN,
+       STATUS_STAGE_OUT,
+       STATUS_STAGE_ADDR,
++      STATUS_STAGE_TEST,
+ };
+ /*
+   EP_STATE_IDLE,
+@@ -343,6 +344,7 @@ struct husb2_ep {
+       struct dentry                           *debugfs_dir;
+       struct dentry                           *debugfs_queue;
+       struct dentry                           *debugfs_dma_status;
++      struct dentry                           *debugfs_state;
+ #endif
+ };
+ #define HUSB2_EP_CAP_ISOC     0x0001
+@@ -381,6 +383,8 @@ struct husb2_udc {
+       struct clk *pclk;
+       struct clk *hclk;
++      int test_mode;
++
+ #ifdef CONFIG_DEBUG_FS
+       struct dentry *debugfs_root;
+       struct dentry *debugfs_regs;
diff --git a/packages/linux/linux-2.6.18/jffs2_can_mark_obsolete-should-return-0-for-dataflash.patch b/packages/linux/linux-2.6.18/jffs2_can_mark_obsolete-should-return-0-for-dataflash.patch
new file mode 100644 (file)
index 0000000..8efbd78
--- /dev/null
@@ -0,0 +1,37 @@
+From 686ee9491d8566eff95cf728eb5d6c9921f92bd2 Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Tue, 28 Nov 2006 12:56:51 +0100
+Subject: [PATCH] MTD: jffs2_can_mark_obsolete() should return 0 for dataflash
+
+Attempting to write something to a file on a jffs2 filesystem using
+mtd_dataflash often results in the following BUG:
+
+jffs2_flash_writev(): Non-contiguous write to 00825720
+wbuf was previously 00825300-0082530c
+kernel BUG at /home/hskinnemoen/git/linux-devel/fs/jffs2/wbuf.c:786!
+
+Fix this by returning 0 from jffs2_can_mark_obsolete() when running
+on top of dataflash.
+
+Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
+---
+ fs/jffs2/os-linux.h |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
+index 9f41fc0..a037fa4 100644
+--- a/fs/jffs2/os-linux.h
++++ b/fs/jffs2/os-linux.h
+@@ -106,7 +106,8 @@ static inline void jffs2_init_inode_info
+ #ifdef CONFIG_JFFS2_SUMMARY
+ #define jffs2_can_mark_obsolete(c) (0)
+ #else
+-#define jffs2_can_mark_obsolete(c) (c->mtd->flags & (MTD_BIT_WRITEABLE))
++#define jffs2_can_mark_obsolete(c) (c->mtd->flags & (MTD_BIT_WRITEABLE)       \
++                                  && !jffs2_dataflash(c))
+ #endif
+ #define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
+-- 
+1.4.3.3
+
diff --git a/packages/linux/linux-2.6.18/kbuild-add-unifdef.patch b/packages/linux/linux-2.6.18/kbuild-add-unifdef.patch
new file mode 100644 (file)
index 0000000..78922a9
--- /dev/null
@@ -0,0 +1,1020 @@
+From 01f1c8799ad8b23c190d59cf1c9e28e6fed390a4 Mon Sep 17 00:00:00 2001
+From: Sam Ravnborg <sam@mars.ravnborg.org>
+Date: Sun, 23 Jul 2006 20:39:59 +0200
+Subject: [PATCH] kbuild: add unifdef
+
+This patch contains a raw copy of unifdef.c
+Next patch will modify it and add infrastructure to use it
+Adding unifdef to the kernel is acked by the author.
+
+The reason to add unifdef as part of the kernel source is that it is not
+yet a common utility on most distributions.
+
+Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
+---
+ scripts/unifdef.c |  998 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 998 insertions(+)
+
+Index: linux-2.6.18-avr32/scripts/unifdef.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/scripts/unifdef.c       2006-10-30 15:59:47.000000000 +0100
+@@ -0,0 +1,998 @@
++/*
++ * Copyright (c) 2002 - 2005 Tony Finch <dot@dotat.at>.  All rights reserved.
++ *
++ * This code is derived from software contributed to Berkeley by Dave Yost.
++ * It was rewritten to support ANSI C by Tony Finch. The original version of
++ * unifdef carried the following copyright notice. None of its code remains
++ * in this version (though some of the names remain).
++ *
++ * Copyright (c) 1985, 1993
++ *    The Regents of the University of California.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++#include <sys/cdefs.h>
++
++#ifndef lint
++#if 0
++static const char copyright[] =
++"@(#) Copyright (c) 1985, 1993\n\
++      The Regents of the University of California.  All rights reserved.\n";
++#endif
++#ifdef __IDSTRING
++__IDSTRING(Berkeley, "@(#)unifdef.c   8.1 (Berkeley) 6/6/93");
++__IDSTRING(NetBSD, "$NetBSD: unifdef.c,v 1.8 2000/07/03 02:51:36 matt Exp $");
++__IDSTRING(dotat, "$dotat: things/unifdef.c,v 1.171 2005/03/08 12:38:48 fanf2 Exp $");
++#endif
++#endif /* not lint */
++#ifdef __FBSDID
++__FBSDID("$FreeBSD: /repoman/r/ncvs/src/usr.bin/unifdef/unifdef.c,v 1.20 2005/05/21 09:55:09 ru Exp $");
++#endif
++
++/*
++ * unifdef - remove ifdef'ed lines
++ *
++ *  Wishlist:
++ *      provide an option which will append the name of the
++ *        appropriate symbol after #else's and #endif's
++ *      provide an option which will check symbols after
++ *        #else's and #endif's to see that they match their
++ *        corresponding #ifdef or #ifndef
++ *
++ *   The first two items above require better buffer handling, which would
++ *     also make it possible to handle all "dodgy" directives correctly.
++ */
++
++#include <ctype.h>
++#include <err.h>
++#include <stdarg.h>
++#include <stdbool.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++size_t strlcpy(char *dst, const char *src, size_t siz);
++
++/* types of input lines: */
++typedef enum {
++      LT_TRUEI,               /* a true #if with ignore flag */
++      LT_FALSEI,              /* a false #if with ignore flag */
++      LT_IF,                  /* an unknown #if */
++      LT_TRUE,                /* a true #if */
++      LT_FALSE,               /* a false #if */
++      LT_ELIF,                /* an unknown #elif */
++      LT_ELTRUE,              /* a true #elif */
++      LT_ELFALSE,             /* a false #elif */
++      LT_ELSE,                /* #else */
++      LT_ENDIF,               /* #endif */
++      LT_DODGY,               /* flag: directive is not on one line */
++      LT_DODGY_LAST = LT_DODGY + LT_ENDIF,
++      LT_PLAIN,               /* ordinary line */
++      LT_EOF,                 /* end of file */
++      LT_COUNT
++} Linetype;
++
++static char const * const linetype_name[] = {
++      "TRUEI", "FALSEI", "IF", "TRUE", "FALSE",
++      "ELIF", "ELTRUE", "ELFALSE", "ELSE", "ENDIF",
++      "DODGY TRUEI", "DODGY FALSEI",
++      "DODGY IF", "DODGY TRUE", "DODGY FALSE",
++      "DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE",
++      "DODGY ELSE", "DODGY ENDIF",
++      "PLAIN", "EOF"
++};
++
++/* state of #if processing */
++typedef enum {
++      IS_OUTSIDE,
++      IS_FALSE_PREFIX,        /* false #if followed by false #elifs */
++      IS_TRUE_PREFIX,         /* first non-false #(el)if is true */
++      IS_PASS_MIDDLE,         /* first non-false #(el)if is unknown */
++      IS_FALSE_MIDDLE,        /* a false #elif after a pass state */
++      IS_TRUE_MIDDLE,         /* a true #elif after a pass state */
++      IS_PASS_ELSE,           /* an else after a pass state */
++      IS_FALSE_ELSE,          /* an else after a true state */
++      IS_TRUE_ELSE,           /* an else after only false states */
++      IS_FALSE_TRAILER,       /* #elifs after a true are false */
++      IS_COUNT
++} Ifstate;
++
++static char const * const ifstate_name[] = {
++      "OUTSIDE", "FALSE_PREFIX", "TRUE_PREFIX",
++      "PASS_MIDDLE", "FALSE_MIDDLE", "TRUE_MIDDLE",
++      "PASS_ELSE", "FALSE_ELSE", "TRUE_ELSE",
++      "FALSE_TRAILER"
++};
++
++/* state of comment parser */
++typedef enum {
++      NO_COMMENT = false,     /* outside a comment */
++      C_COMMENT,              /* in a comment like this one */
++      CXX_COMMENT,            /* between // and end of line */
++      STARTING_COMMENT,       /* just after slash-backslash-newline */
++      FINISHING_COMMENT,      /* star-backslash-newline in a C comment */
++      CHAR_LITERAL,           /* inside '' */
++      STRING_LITERAL          /* inside "" */
++} Comment_state;
++
++static char const * const comment_name[] = {
++      "NO", "C", "CXX", "STARTING", "FINISHING", "CHAR", "STRING"
++};
++
++/* state of preprocessor line parser */
++typedef enum {
++      LS_START,               /* only space and comments on this line */
++      LS_HASH,                /* only space, comments, and a hash */
++      LS_DIRTY                /* this line can't be a preprocessor line */
++} Line_state;
++
++static char const * const linestate_name[] = {
++      "START", "HASH", "DIRTY"
++};
++
++/*
++ * Minimum translation limits from ISO/IEC 9899:1999 5.2.4.1
++ */
++#define       MAXDEPTH        64                      /* maximum #if nesting */
++#define       MAXLINE         4096                    /* maximum length of line */
++#define       MAXSYMS         4096                    /* maximum number of symbols */
++
++/*
++ * Sometimes when editing a keyword the replacement text is longer, so
++ * we leave some space at the end of the tline buffer to accommodate this.
++ */
++#define       EDITSLOP        10
++
++/*
++ * Globals.
++ */
++
++static bool             complement;           /* -c: do the complement */
++static bool             debugging;            /* -d: debugging reports */
++static bool             iocccok;              /* -e: fewer IOCCC errors */
++static bool             killconsts;           /* -k: eval constant #ifs */
++static bool             lnblank;              /* -l: blank deleted lines */
++static bool             lnnum;                        /* -n: add #line directives */
++static bool             symlist;              /* -s: output symbol list */
++static bool             text;                 /* -t: this is a text file */
++
++static const char      *symname[MAXSYMS];     /* symbol name */
++static const char      *value[MAXSYMS];               /* -Dsym=value */
++static bool             ignore[MAXSYMS];      /* -iDsym or -iUsym */
++static int              nsyms;                        /* number of symbols */
++
++static FILE            *input;                        /* input file pointer */
++static const char      *filename;             /* input file name */
++static int              linenum;              /* current line number */
++
++static char             tline[MAXLINE+EDITSLOP];/* input buffer plus space */
++static char            *keyword;              /* used for editing #elif's */
++
++static Comment_state    incomment;            /* comment parser state */
++static Line_state       linestate;            /* #if line parser state */
++static Ifstate          ifstate[MAXDEPTH];    /* #if processor state */
++static bool             ignoring[MAXDEPTH];   /* ignore comments state */
++static int              stifline[MAXDEPTH];   /* start of current #if */
++static int              depth;                        /* current #if nesting */
++static int              delcount;             /* count of deleted lines */
++static bool             keepthis;             /* don't delete constant #if */
++
++static int              exitstat;             /* program exit status */
++
++static void             addsym(bool, bool, char *);
++static void             debug(const char *, ...);
++static void             done(void);
++static void             error(const char *);
++static int              findsym(const char *);
++static void             flushline(bool);
++static Linetype         getline(void);
++static Linetype         ifeval(const char **);
++static void             ignoreoff(void);
++static void             ignoreon(void);
++static void             keywordedit(const char *);
++static void             nest(void);
++static void             process(void);
++static const char      *skipcomment(const char *);
++static const char      *skipsym(const char *);
++static void             state(Ifstate);
++static int              strlcmp(const char *, const char *, size_t);
++static void             unnest(void);
++static void             usage(void);
++
++#define endsym(c) (!isalpha((unsigned char)c) && !isdigit((unsigned char)c) && c != '_')
++
++/*
++ * The main program.
++ */
++int
++main(int argc, char *argv[])
++{
++      int opt;
++
++      while ((opt = getopt(argc, argv, "i:D:U:I:cdeklnst")) != -1)
++              switch (opt) {
++              case 'i': /* treat stuff controlled by these symbols as text */
++                      /*
++                       * For strict backwards-compatibility the U or D
++                       * should be immediately after the -i but it doesn't
++                       * matter much if we relax that requirement.
++                       */
++                      opt = *optarg++;
++                      if (opt == 'D')
++                              addsym(true, true, optarg);
++                      else if (opt == 'U')
++                              addsym(true, false, optarg);
++                      else
++                              usage();
++                      break;
++              case 'D': /* define a symbol */
++                      addsym(false, true, optarg);
++                      break;
++              case 'U': /* undef a symbol */
++                      addsym(false, false, optarg);
++                      break;
++              case 'I':
++                      /* no-op for compatibility with cpp */
++                      break;
++              case 'c': /* treat -D as -U and vice versa */
++                      complement = true;
++                      break;
++              case 'd':
++                      debugging = true;
++                      break;
++              case 'e': /* fewer errors from dodgy lines */
++                      iocccok = true;
++                      break;
++              case 'k': /* process constant #ifs */
++                      killconsts = true;
++                      break;
++              case 'l': /* blank deleted lines instead of omitting them */
++                      lnblank = true;
++                      break;
++              case 'n': /* add #line directive after deleted lines */
++                      lnnum = true;
++                      break;
++              case 's': /* only output list of symbols that control #ifs */
++                      symlist = true;
++                      break;
++              case 't': /* don't parse C comments */
++                      text = true;
++                      break;
++              default:
++                      usage();
++              }
++      argc -= optind;
++      argv += optind;
++      if (argc > 1) {
++              errx(2, "can only do one file");
++      } else if (argc == 1 && strcmp(*argv, "-") != 0) {
++              filename = *argv;
++              input = fopen(filename, "r");
++              if (input == NULL)
++                      err(2, "can't open %s", filename);
++      } else {
++              filename = "[stdin]";
++              input = stdin;
++      }
++      process();
++      abort(); /* bug */
++}
++
++static void
++usage(void)
++{
++      fprintf(stderr, "usage: unifdef [-cdeklnst] [-Ipath]"
++          " [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n");
++      exit(2);
++}
++
++/*
++ * A state transition function alters the global #if processing state
++ * in a particular way. The table below is indexed by the current
++ * processing state and the type of the current line.
++ *
++ * Nesting is handled by keeping a stack of states; some transition
++ * functions increase or decrease the depth. They also maintain the
++ * ignore state on a stack. In some complicated cases they have to
++ * alter the preprocessor directive, as follows.
++ *
++ * When we have processed a group that starts off with a known-false
++ * #if/#elif sequence (which has therefore been deleted) followed by a
++ * #elif that we don't understand and therefore must keep, we edit the
++ * latter into a #if to keep the nesting correct.
++ *
++ * When we find a true #elif in a group, the following block will
++ * always be kept and the rest of the sequence after the next #elif or
++ * #else will be discarded. We edit the #elif into a #else and the
++ * following directive to #endif since this has the desired behaviour.
++ *
++ * "Dodgy" directives are split across multiple lines, the most common
++ * example being a multi-line comment hanging off the right of the
++ * directive. We can handle them correctly only if there is no change
++ * from printing to dropping (or vice versa) caused by that directive.
++ * If the directive is the first of a group we have a choice between
++ * failing with an error, or passing it through unchanged instead of
++ * evaluating it. The latter is not the default to avoid questions from
++ * users about unifdef unexpectedly leaving behind preprocessor directives.
++ */
++typedef void state_fn(void);
++
++/* report an error */
++static void Eelif (void) { error("Inappropriate #elif"); }
++static void Eelse (void) { error("Inappropriate #else"); }
++static void Eendif(void) { error("Inappropriate #endif"); }
++static void Eeof  (void) { error("Premature EOF"); }
++static void Eioccc(void) { error("Obfuscated preprocessor control line"); }
++/* plain line handling */
++static void print (void) { flushline(true); }
++static void drop  (void) { flushline(false); }
++/* output lacks group's start line */
++static void Strue (void) { drop();  ignoreoff(); state(IS_TRUE_PREFIX); }
++static void Sfalse(void) { drop();  ignoreoff(); state(IS_FALSE_PREFIX); }
++static void Selse (void) { drop();               state(IS_TRUE_ELSE); }
++/* print/pass this block */
++static void Pelif (void) { print(); ignoreoff(); state(IS_PASS_MIDDLE); }
++static void Pelse (void) { print();              state(IS_PASS_ELSE); }
++static void Pendif(void) { print(); unnest(); }
++/* discard this block */
++static void Dfalse(void) { drop();  ignoreoff(); state(IS_FALSE_TRAILER); }
++static void Delif (void) { drop();  ignoreoff(); state(IS_FALSE_MIDDLE); }
++static void Delse (void) { drop();               state(IS_FALSE_ELSE); }
++static void Dendif(void) { drop();  unnest(); }
++/* first line of group */
++static void Fdrop (void) { nest();  Dfalse(); }
++static void Fpass (void) { nest();  Pelif(); }
++static void Ftrue (void) { nest();  Strue(); }
++static void Ffalse(void) { nest();  Sfalse(); }
++/* variable pedantry for obfuscated lines */
++static void Oiffy (void) { if (!iocccok) Eioccc(); Fpass(); ignoreon(); }
++static void Oif   (void) { if (!iocccok) Eioccc(); Fpass(); }
++static void Oelif (void) { if (!iocccok) Eioccc(); Pelif(); }
++/* ignore comments in this block */
++static void Idrop (void) { Fdrop();  ignoreon(); }
++static void Itrue (void) { Ftrue();  ignoreon(); }
++static void Ifalse(void) { Ffalse(); ignoreon(); }
++/* edit this line */
++static void Mpass (void) { strncpy(keyword, "if  ", 4); Pelif(); }
++static void Mtrue (void) { keywordedit("else\n");  state(IS_TRUE_MIDDLE); }
++static void Melif (void) { keywordedit("endif\n"); state(IS_FALSE_TRAILER); }
++static void Melse (void) { keywordedit("endif\n"); state(IS_FALSE_ELSE); }
++
++static state_fn * const trans_table[IS_COUNT][LT_COUNT] = {
++/* IS_OUTSIDE */
++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif,
++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eelif, Eelif, Eelif, Eelse, Eendif,
++  print, done },
++/* IS_FALSE_PREFIX */
++{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif,
++  Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc,
++  drop,  Eeof },
++/* IS_TRUE_PREFIX */
++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif,
++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
++  print, Eeof },
++/* IS_PASS_MIDDLE */
++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif,
++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Pelif, Oelif, Oelif, Pelse, Pendif,
++  print, Eeof },
++/* IS_FALSE_MIDDLE */
++{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif,
++  Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
++  drop,  Eeof },
++/* IS_TRUE_MIDDLE */
++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif,
++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eioccc,Eioccc,Eioccc,Eioccc,Pendif,
++  print, Eeof },
++/* IS_PASS_ELSE */
++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif,
++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eelif, Eelif, Eelif, Eelse, Pendif,
++  print, Eeof },
++/* IS_FALSE_ELSE */
++{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif,
++  Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc,
++  drop,  Eeof },
++/* IS_TRUE_ELSE */
++{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif,
++  Oiffy, Oiffy, Fpass, Oif,   Oif,   Eelif, Eelif, Eelif, Eelse, Eioccc,
++  print, Eeof },
++/* IS_FALSE_TRAILER */
++{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif,
++  Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc,
++  drop,  Eeof }
++/*TRUEI  FALSEI IF     TRUE   FALSE  ELIF   ELTRUE ELFALSE ELSE  ENDIF
++  TRUEI  FALSEI IF     TRUE   FALSE  ELIF   ELTRUE ELFALSE ELSE  ENDIF (DODGY)
++  PLAIN  EOF */
++};
++
++/*
++ * State machine utility functions
++ */
++static void
++done(void)
++{
++      if (incomment)
++              error("EOF in comment");
++      exit(exitstat);
++}
++static void
++ignoreoff(void)
++{
++      if (depth == 0)
++              abort(); /* bug */
++      ignoring[depth] = ignoring[depth-1];
++}
++static void
++ignoreon(void)
++{
++      ignoring[depth] = true;
++}
++static void
++keywordedit(const char *replacement)
++{
++      strlcpy(keyword, replacement, tline + sizeof(tline) - keyword);
++      print();
++}
++static void
++nest(void)
++{
++      depth += 1;
++      if (depth >= MAXDEPTH)
++              error("Too many levels of nesting");
++      stifline[depth] = linenum;
++}
++static void
++unnest(void)
++{
++      if (depth == 0)
++              abort(); /* bug */
++      depth -= 1;
++}
++static void
++state(Ifstate is)
++{
++      ifstate[depth] = is;
++}
++
++/*
++ * Write a line to the output or not, according to command line options.
++ */
++static void
++flushline(bool keep)
++{
++      if (symlist)
++              return;
++      if (keep ^ complement) {
++              if (lnnum && delcount > 0)
++                      printf("#line %d\n", linenum);
++              fputs(tline, stdout);
++              delcount = 0;
++      } else {
++              if (lnblank)
++                      putc('\n', stdout);
++              exitstat = 1;
++              delcount += 1;
++      }
++}
++
++/*
++ * The driver for the state machine.
++ */
++static void
++process(void)
++{
++      Linetype lineval;
++
++      for (;;) {
++              linenum++;
++              lineval = getline();
++              trans_table[ifstate[depth]][lineval]();
++              debug("process %s -> %s depth %d",
++                  linetype_name[lineval],
++                  ifstate_name[ifstate[depth]], depth);
++      }
++}
++
++/*
++ * Parse a line and determine its type. We keep the preprocessor line
++ * parser state between calls in the global variable linestate, with
++ * help from skipcomment().
++ */
++static Linetype
++getline(void)
++{
++      const char *cp;
++      int cursym;
++      int kwlen;
++      Linetype retval;
++      Comment_state wascomment;
++
++      if (fgets(tline, MAXLINE, input) == NULL)
++              return (LT_EOF);
++      retval = LT_PLAIN;
++      wascomment = incomment;
++      cp = skipcomment(tline);
++      if (linestate == LS_START) {
++              if (*cp == '#') {
++                      linestate = LS_HASH;
++                      cp = skipcomment(cp + 1);
++              } else if (*cp != '\0')
++                      linestate = LS_DIRTY;
++      }
++      if (!incomment && linestate == LS_HASH) {
++              keyword = tline + (cp - tline);
++              cp = skipsym(cp);
++              kwlen = cp - keyword;
++              /* no way can we deal with a continuation inside a keyword */
++              if (strncmp(cp, "\\\n", 2) == 0)
++                      Eioccc();
++              if (strlcmp("ifdef", keyword, kwlen) == 0 ||
++                  strlcmp("ifndef", keyword, kwlen) == 0) {
++                      cp = skipcomment(cp);
++                      if ((cursym = findsym(cp)) < 0)
++                              retval = LT_IF;
++                      else {
++                              retval = (keyword[2] == 'n')
++                                  ? LT_FALSE : LT_TRUE;
++                              if (value[cursym] == NULL)
++                                      retval = (retval == LT_TRUE)
++                                          ? LT_FALSE : LT_TRUE;
++                              if (ignore[cursym])
++                                      retval = (retval == LT_TRUE)
++                                          ? LT_TRUEI : LT_FALSEI;
++                      }
++                      cp = skipsym(cp);
++              } else if (strlcmp("if", keyword, kwlen) == 0)
++                      retval = ifeval(&cp);
++              else if (strlcmp("elif", keyword, kwlen) == 0)
++                      retval = ifeval(&cp) - LT_IF + LT_ELIF;
++              else if (strlcmp("else", keyword, kwlen) == 0)
++                      retval = LT_ELSE;
++              else if (strlcmp("endif", keyword, kwlen) == 0)
++                      retval = LT_ENDIF;
++              else {
++                      linestate = LS_DIRTY;
++                      retval = LT_PLAIN;
++              }
++              cp = skipcomment(cp);
++              if (*cp != '\0') {
++                      linestate = LS_DIRTY;
++                      if (retval == LT_TRUE || retval == LT_FALSE ||
++                          retval == LT_TRUEI || retval == LT_FALSEI)
++                              retval = LT_IF;
++                      if (retval == LT_ELTRUE || retval == LT_ELFALSE)
++                              retval = LT_ELIF;
++              }
++              if (retval != LT_PLAIN && (wascomment || incomment)) {
++                      retval += LT_DODGY;
++                      if (incomment)
++                              linestate = LS_DIRTY;
++              }
++              /* skipcomment should have changed the state */
++              if (linestate == LS_HASH)
++                      abort(); /* bug */
++      }
++      if (linestate == LS_DIRTY) {
++              while (*cp != '\0')
++                      cp = skipcomment(cp + 1);
++      }
++      debug("parser %s comment %s line",
++          comment_name[incomment], linestate_name[linestate]);
++      return (retval);
++}
++
++/*
++ * These are the binary operators that are supported by the expression
++ * evaluator. Note that if support for division is added then we also
++ * need short-circuiting booleans because of divide-by-zero.
++ */
++static int op_lt(int a, int b) { return (a < b); }
++static int op_gt(int a, int b) { return (a > b); }
++static int op_le(int a, int b) { return (a <= b); }
++static int op_ge(int a, int b) { return (a >= b); }
++static int op_eq(int a, int b) { return (a == b); }
++static int op_ne(int a, int b) { return (a != b); }
++static int op_or(int a, int b) { return (a || b); }
++static int op_and(int a, int b) { return (a && b); }
++
++/*
++ * An evaluation function takes three arguments, as follows: (1) a pointer to
++ * an element of the precedence table which lists the operators at the current
++ * level of precedence; (2) a pointer to an integer which will receive the
++ * value of the expression; and (3) a pointer to a char* that points to the
++ * expression to be evaluated and that is updated to the end of the expression
++ * when evaluation is complete. The function returns LT_FALSE if the value of
++ * the expression is zero, LT_TRUE if it is non-zero, or LT_IF if the
++ * expression could not be evaluated.
++ */
++struct ops;
++
++typedef Linetype eval_fn(const struct ops *, int *, const char **);
++
++static eval_fn eval_table, eval_unary;
++
++/*
++ * The precedence table. Expressions involving binary operators are evaluated
++ * in a table-driven way by eval_table. When it evaluates a subexpression it
++ * calls the inner function with its first argument pointing to the next
++ * element of the table. Innermost expressions have special non-table-driven
++ * handling.
++ */
++static const struct ops {
++      eval_fn *inner;
++      struct op {
++              const char *str;
++              int (*fn)(int, int);
++      } op[5];
++} eval_ops[] = {
++      { eval_table, { { "||", op_or } } },
++      { eval_table, { { "&&", op_and } } },
++      { eval_table, { { "==", op_eq },
++                      { "!=", op_ne } } },
++      { eval_unary, { { "<=", op_le },
++                      { ">=", op_ge },
++                      { "<", op_lt },
++                      { ">", op_gt } } }
++};
++
++/*
++ * Function for evaluating the innermost parts of expressions,
++ * viz. !expr (expr) defined(symbol) symbol number
++ * We reset the keepthis flag when we find a non-constant subexpression.
++ */
++static Linetype
++eval_unary(const struct ops *ops, int *valp, const char **cpp)
++{
++      const char *cp;
++      char *ep;
++      int sym;
++
++      cp = skipcomment(*cpp);
++      if (*cp == '!') {
++              debug("eval%d !", ops - eval_ops);
++              cp++;
++              if (eval_unary(ops, valp, &cp) == LT_IF)
++                      return (LT_IF);
++              *valp = !*valp;
++      } else if (*cp == '(') {
++              cp++;
++              debug("eval%d (", ops - eval_ops);
++              if (eval_table(eval_ops, valp, &cp) == LT_IF)
++                      return (LT_IF);
++              cp = skipcomment(cp);
++              if (*cp++ != ')')
++                      return (LT_IF);
++      } else if (isdigit((unsigned char)*cp)) {
++              debug("eval%d number", ops - eval_ops);
++              *valp = strtol(cp, &ep, 0);
++              cp = skipsym(cp);
++      } else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) {
++              cp = skipcomment(cp+7);
++              debug("eval%d defined", ops - eval_ops);
++              if (*cp++ != '(')
++                      return (LT_IF);
++              cp = skipcomment(cp);
++              sym = findsym(cp);
++              if (sym < 0)
++                      return (LT_IF);
++              *valp = (value[sym] != NULL);
++              cp = skipsym(cp);
++              cp = skipcomment(cp);
++              if (*cp++ != ')')
++                      return (LT_IF);
++              keepthis = false;
++      } else if (!endsym(*cp)) {
++              debug("eval%d symbol", ops - eval_ops);
++              sym = findsym(cp);
++              if (sym < 0)
++                      return (LT_IF);
++              if (value[sym] == NULL)
++                      *valp = 0;
++              else {
++                      *valp = strtol(value[sym], &ep, 0);
++                      if (*ep != '\0' || ep == value[sym])
++                              return (LT_IF);
++              }
++              cp = skipsym(cp);
++              keepthis = false;
++      } else {
++              debug("eval%d bad expr", ops - eval_ops);
++              return (LT_IF);
++      }
++
++      *cpp = cp;
++      debug("eval%d = %d", ops - eval_ops, *valp);
++      return (*valp ? LT_TRUE : LT_FALSE);
++}
++
++/*
++ * Table-driven evaluation of binary operators.
++ */
++static Linetype
++eval_table(const struct ops *ops, int *valp, const char **cpp)
++{
++      const struct op *op;
++      const char *cp;
++      int val;
++
++      debug("eval%d", ops - eval_ops);
++      cp = *cpp;
++      if (ops->inner(ops+1, valp, &cp) == LT_IF)
++              return (LT_IF);
++      for (;;) {
++              cp = skipcomment(cp);
++              for (op = ops->op; op->str != NULL; op++)
++                      if (strncmp(cp, op->str, strlen(op->str)) == 0)
++                              break;
++              if (op->str == NULL)
++                      break;
++              cp += strlen(op->str);
++              debug("eval%d %s", ops - eval_ops, op->str);
++              if (ops->inner(ops+1, &val, &cp) == LT_IF)
++                      return (LT_IF);
++              *valp = op->fn(*valp, val);
++      }
++
++      *cpp = cp;
++      debug("eval%d = %d", ops - eval_ops, *valp);
++      return (*valp ? LT_TRUE : LT_FALSE);
++}
++
++/*
++ * Evaluate the expression on a #if or #elif line. If we can work out
++ * the result we return LT_TRUE or LT_FALSE accordingly, otherwise we
++ * return just a generic LT_IF.
++ */
++static Linetype
++ifeval(const char **cpp)
++{
++      int ret;
++      int val;
++
++      debug("eval %s", *cpp);
++      keepthis = killconsts ? false : true;
++      ret = eval_table(eval_ops, &val, cpp);
++      debug("eval = %d", val);
++      return (keepthis ? LT_IF : ret);
++}
++
++/*
++ * Skip over comments, strings, and character literals and stop at the
++ * next character position that is not whitespace. Between calls we keep
++ * the comment state in the global variable incomment, and we also adjust
++ * the global variable linestate when we see a newline.
++ * XXX: doesn't cope with the buffer splitting inside a state transition.
++ */
++static const char *
++skipcomment(const char *cp)
++{
++      if (text || ignoring[depth]) {
++              for (; isspace((unsigned char)*cp); cp++)
++                      if (*cp == '\n')
++                              linestate = LS_START;
++              return (cp);
++      }
++      while (*cp != '\0')
++              /* don't reset to LS_START after a line continuation */
++              if (strncmp(cp, "\\\n", 2) == 0)
++                      cp += 2;
++              else switch (incomment) {
++              case NO_COMMENT:
++                      if (strncmp(cp, "/\\\n", 3) == 0) {
++                              incomment = STARTING_COMMENT;
++                              cp += 3;
++                      } else if (strncmp(cp, "/*", 2) == 0) {
++                              incomment = C_COMMENT;
++                              cp += 2;
++                      } else if (strncmp(cp, "//", 2) == 0) {
++                              incomment = CXX_COMMENT;
++                              cp += 2;
++                      } else if (strncmp(cp, "\'", 1) == 0) {
++                              incomment = CHAR_LITERAL;
++                              linestate = LS_DIRTY;
++                              cp += 1;
++                      } else if (strncmp(cp, "\"", 1) == 0) {
++                              incomment = STRING_LITERAL;
++                              linestate = LS_DIRTY;
++                              cp += 1;
++                      } else if (strncmp(cp, "\n", 1) == 0) {
++                              linestate = LS_START;
++                              cp += 1;
++                      } else if (strchr(" \t", *cp) != NULL) {
++                              cp += 1;
++                      } else
++                              return (cp);
++                      continue;
++              case CXX_COMMENT:
++                      if (strncmp(cp, "\n", 1) == 0) {
++                              incomment = NO_COMMENT;
++                              linestate = LS_START;
++                      }
++                      cp += 1;
++                      continue;
++              case CHAR_LITERAL:
++              case STRING_LITERAL:
++                      if ((incomment == CHAR_LITERAL && cp[0] == '\'') ||
++                          (incomment == STRING_LITERAL && cp[0] == '\"')) {
++                              incomment = NO_COMMENT;
++                              cp += 1;
++                      } else if (cp[0] == '\\') {
++                              if (cp[1] == '\0')
++                                      cp += 1;
++                              else
++                                      cp += 2;
++                      } else if (strncmp(cp, "\n", 1) == 0) {
++                              if (incomment == CHAR_LITERAL)
++                                      error("unterminated char literal");
++                              else
++                                      error("unterminated string literal");
++                      } else
++                              cp += 1;
++                      continue;
++              case C_COMMENT:
++                      if (strncmp(cp, "*\\\n", 3) == 0) {
++                              incomment = FINISHING_COMMENT;
++                              cp += 3;
++                      } else if (strncmp(cp, "*/", 2) == 0) {
++                              incomment = NO_COMMENT;
++                              cp += 2;
++                      } else
++                              cp += 1;
++                      continue;
++              case STARTING_COMMENT:
++                      if (*cp == '*') {
++                              incomment = C_COMMENT;
++                              cp += 1;
++                      } else if (*cp == '/') {
++                              incomment = CXX_COMMENT;
++                              cp += 1;
++                      } else {
++                              incomment = NO_COMMENT;
++                              linestate = LS_DIRTY;
++                      }
++                      continue;
++              case FINISHING_COMMENT:
++                      if (*cp == '/') {
++                              incomment = NO_COMMENT;
++                              cp += 1;
++                      } else
++                              incomment = C_COMMENT;
++                      continue;
++              default:
++                      abort(); /* bug */
++              }
++      return (cp);
++}
++
++/*
++ * Skip over an identifier.
++ */
++static const char *
++skipsym(const char *cp)
++{
++      while (!endsym(*cp))
++              ++cp;
++      return (cp);
++}
++
++/*
++ * Look for the symbol in the symbol table. If is is found, we return
++ * the symbol table index, else we return -1.
++ */
++static int
++findsym(const char *str)
++{
++      const char *cp;
++      int symind;
++
++      cp = skipsym(str);
++      if (cp == str)
++              return (-1);
++      if (symlist) {
++              printf("%.*s\n", (int)(cp-str), str);
++              /* we don't care about the value of the symbol */
++              return (0);
++      }
++      for (symind = 0; symind < nsyms; ++symind) {
++              if (strlcmp(symname[symind], str, cp-str) == 0) {
++                      debug("findsym %s %s", symname[symind],
++                          value[symind] ? value[symind] : "");
++                      return (symind);
++              }
++      }
++      return (-1);
++}
++
++/*
++ * Add a symbol to the symbol table.
++ */
++static void
++addsym(bool ignorethis, bool definethis, char *sym)
++{
++      int symind;
++      char *val;
++
++      symind = findsym(sym);
++      if (symind < 0) {
++              if (nsyms >= MAXSYMS)
++                      errx(2, "too many symbols");
++              symind = nsyms++;
++      }
++      symname[symind] = sym;
++      ignore[symind] = ignorethis;
++      val = sym + (skipsym(sym) - sym);
++      if (definethis) {
++              if (*val == '=') {
++                      value[symind] = val+1;
++                      *val = '\0';
++              } else if (*val == '\0')
++                      value[symind] = "";
++              else
++                      usage();
++      } else {
++              if (*val != '\0')
++                      usage();
++              value[symind] = NULL;
++      }
++}
++
++/*
++ * Compare s with n characters of t.
++ * The same as strncmp() except that it checks that s[n] == '\0'.
++ */
++static int
++strlcmp(const char *s, const char *t, size_t n)
++{
++      while (n-- && *t != '\0')
++              if (*s != *t)
++                      return ((unsigned char)*s - (unsigned char)*t);
++              else
++                      ++s, ++t;
++      return ((unsigned char)*s);
++}
++
++/*
++ * Diagnostics.
++ */
++static void
++debug(const char *msg, ...)
++{
++      va_list ap;
++
++      if (debugging) {
++              va_start(ap, msg);
++              vwarnx(msg, ap);
++              va_end(ap);
++      }
++}
++
++static void
++error(const char *msg)
++{
++      if (depth == 0)
++              warnx("%s: %d: %s", filename, linenum, msg);
++      else
++              warnx("%s: %d: %s (#if line %d depth %d)",
++                  filename, linenum, msg, stifline[depth], depth);
++      errx(2, "output may be truncated");
++}
diff --git a/packages/linux/linux-2.6.18/kbuild-replace-use-of-strlcpy-with-a-dedicated-implmentation-in-unifdef.patch b/packages/linux/linux-2.6.18/kbuild-replace-use-of-strlcpy-with-a-dedicated-implmentation-in-unifdef.patch
new file mode 100644 (file)
index 0000000..a9a67da
--- /dev/null
@@ -0,0 +1,30 @@
+From 14a036d2dc304797f3624c06bd6d2a1e9b59e45a Mon Sep 17 00:00:00 2001
+From: Sam Ravnborg <sam@mars.ravnborg.org>
+Date: Sun, 23 Jul 2006 20:41:30 +0200
+Subject: [PATCH] kbuild: replace use of strlcpy with a dedicated implmentation in unifdef
+
+Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
+---
+ scripts/unifdef.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+Index: linux-2.6.18-avr32/scripts/unifdef.c
+===================================================================
+--- linux-2.6.18-avr32.orig/scripts/unifdef.c  2006-10-30 15:58:53.000000000 +0100
++++ linux-2.6.18-avr32/scripts/unifdef.c       2006-10-30 15:58:59.000000000 +0100
+@@ -450,7 +450,14 @@ ignoreon(void)
+ static void
+ keywordedit(const char *replacement)
+ {
+-      strlcpy(keyword, replacement, tline + sizeof(tline) - keyword);
++      size_t size = tline + sizeof(tline) - keyword;
++      char *dst = keyword;
++      const char *src = replacement;
++      if (size != 0) {
++              while ((--size != 0) && (*src != '\0'))
++                      *dst++ = *src++;
++              *dst = '\0';
++      }
+       print();
+ }
+ static void
diff --git a/packages/linux/linux-2.6.18/kbuild-use-in-kernel-unifdef.patch b/packages/linux/linux-2.6.18/kbuild-use-in-kernel-unifdef.patch
new file mode 100644 (file)
index 0000000..b2c7930
--- /dev/null
@@ -0,0 +1,56 @@
+From 07aea3a71fc6b07744691eec2dfea705a7b30280 Mon Sep 17 00:00:00 2001
+From: Sam Ravnborg <sam@mars.ravnborg.org>
+Date: Sun, 23 Jul 2006 20:47:50 +0200
+Subject: [PATCH] kbuild: use in-kernel unifdef
+
+Let headers_install use in-kernel unifdef
+
+Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
+---
+ Makefile                     |    4 ++--
+ scripts/Makefile             |    3 +++
+ scripts/Makefile.headersinst |    2 +-
+ 3 files changed, 6 insertions(+), 3 deletions(-)
+
+Index: linux-2.6.18-avr32/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/Makefile   2006-10-26 10:20:21.000000000 +0200
++++ linux-2.6.18-avr32/Makefile        2006-10-30 15:59:06.000000000 +0100
+@@ -893,8 +893,8 @@ INSTALL_HDR_PATH=$(objtree)/usr
+ export INSTALL_HDR_PATH
+ PHONY += headers_install
+-headers_install: include/linux/version.h
+-      $(Q)unifdef -Ux /dev/null
++headers_install: include/linux/version.h scripts_basic FORCE
++      $(Q)$(MAKE) $(build)=scripts scripts/unifdef
+       $(Q)rm -rf $(INSTALL_HDR_PATH)/include
+       $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.headersinst obj=include
+Index: linux-2.6.18-avr32/scripts/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/scripts/Makefile   2006-09-20 05:42:06.000000000 +0200
++++ linux-2.6.18-avr32/scripts/Makefile        2006-10-30 15:59:06.000000000 +0100
+@@ -15,6 +15,9 @@ hostprogs-$(CONFIG_IKCONFIG)     += bin2
+ always                := $(hostprogs-y)
++# The following hostprogs-y programs are only build on demand
++hostprogs-y += unifdef
++
+ subdir-$(CONFIG_MODVERSIONS) += genksyms
+ subdir-$(CONFIG_MODULES)     += mod
+Index: linux-2.6.18-avr32/scripts/Makefile.headersinst
+===================================================================
+--- linux-2.6.18-avr32.orig/scripts/Makefile.headersinst       2006-09-20 05:42:06.000000000 +0200
++++ linux-2.6.18-avr32/scripts/Makefile.headersinst    2006-10-30 15:59:06.000000000 +0100
+@@ -7,7 +7,7 @@
+ #
+ # ==========================================================================
+-UNIFDEF := unifdef -U__KERNEL__
++UNIFDEF := scripts/unifdef -U__KERNEL__
+ # Eliminate the contents of (and inclusions of) compiler.h
+ HDRSED  := sed        -e "s/ inline / __inline__ /g" \
diff --git a/packages/linux/linux-2.6.18/lcdc-do-not-clear-mem-if-fbmem_start-is-set.patch b/packages/linux/linux-2.6.18/lcdc-do-not-clear-mem-if-fbmem_start-is-set.patch
new file mode 100644 (file)
index 0000000..b354047
--- /dev/null
@@ -0,0 +1,16 @@
+Index: linux-2.6.18/drivers/video/sidsafb.c
+===================================================================
+--- linux-2.6.18.orig/drivers/video/sidsafb.c  2006-12-20 13:43:17.000000000 +0100
++++ linux-2.6.18/drivers/video/sidsafb.c       2006-12-20 13:46:44.000000000 +0100
+@@ -765,7 +765,10 @@
+       printk("fb%d: Atmel LCDC at 0x%08lx (mapped at %p), irq %lu\n",
+              info->node, info->fix.mmio_start, sinfo->regs, sinfo->irq_base);
+-      memset_io(info->screen_base, 0, info->fix.smem_len);
++      /* Only clear framebuffer if fbmem_start was not declared, assume the
++       * user have filled the framebuffer before the kernel was started. */
++      if (!fb_data->fbmem_start)
++              memset_io(info->screen_base, 0, info->fix.smem_len);
+       info->var.activate |= FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
+       ret = fb_set_var(info, &info->var);
+       if (ret)
diff --git a/packages/linux/linux-2.6.18/lcdc-fix-possible-null-pointer-and-match-guard-time-to-uboot.patch b/packages/linux/linux-2.6.18/lcdc-fix-possible-null-pointer-and-match-guard-time-to-uboot.patch
new file mode 100644 (file)
index 0000000..fea5d6c
--- /dev/null
@@ -0,0 +1,38 @@
+Index: linux-2.6.18/drivers/video/sidsafb.c
+===================================================================
+--- linux-2.6.18.orig/drivers/video/sidsafb.c  2007-01-11 13:35:02.000000000 +0100
++++ linux-2.6.18/drivers/video/sidsafb.c       2007-01-11 14:22:56.000000000 +0100
+@@ -661,6 +661,7 @@
+       struct fb_info *info;
+       struct sidsafb_info *sinfo;
+       const struct resource *mmio_resource;
++      int preinitialized = 0;
+       int ret;
+       pr_debug("sidsafb_probe BEGIN\n");
+@@ -681,7 +682,7 @@
+       sinfo = info->par;
+       sinfo->info = info;
+       sinfo->pdev = pdev;
+-      sinfo->guard_time = 1;
++      sinfo->guard_time = 2;
+       spin_lock_init(&sinfo->lock);
+       sidsafb_set_fbinfo(sinfo);
+@@ -711,6 +712,7 @@
+               info->fix.smem_len = fb_data->fbmem_size;
+               info->screen_base = ioremap(info->fix.smem_start,
+                                           info->fix.smem_len);
++              preinitialized = 1;
+       } else {
+               dma_addr_t paddr;
+@@ -767,7 +769,7 @@
+       /* Only clear framebuffer if fbmem_start was not declared, assume the
+        * user have filled the framebuffer before the kernel was started. */
+-      if (!fb_data->fbmem_start)
++      if (!preinitialized)
+               memset_io(info->screen_base, 0, info->fix.smem_len);
+       info->var.activate |= FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
+       ret = fb_set_var(info, &info->var);
diff --git a/packages/linux/linux-2.6.18/lcdc-wait-for-vsync.patch b/packages/linux/linux-2.6.18/lcdc-wait-for-vsync.patch
new file mode 100644 (file)
index 0000000..7c1cd66
--- /dev/null
@@ -0,0 +1,152 @@
+---
+ drivers/video/sidsafb.c |   68 +++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 61 insertions(+), 7 deletions(-)
+
+Index: linux-2.6.18-rc6-mm1/drivers/video/sidsafb.c
+===================================================================
+--- linux-2.6.18-rc6-mm1.orig/drivers/video/sidsafb.c  2006-09-11 13:03:46.000000000 +0200
++++ linux-2.6.18-rc6-mm1/drivers/video/sidsafb.c       2006-09-11 13:38:52.000000000 +0200
+@@ -11,6 +11,7 @@
+ #include <linux/config.h>
+ #include <linux/clk.h>
++#include <linux/completion.h>
+ #include <linux/kernel.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/interrupt.h>
+@@ -38,7 +39,8 @@ struct sidsafb_info {
+       struct fb_info *        info;
+       void __iomem *          regs;
+       unsigned long           irq_base;
+-      wait_queue_head_t       vsync_wait;
++      int                     wait_for_vsync;
++      struct completion       vsync_complete;
+       unsigned int            guard_time;
+       struct clk              *hclk;
+       struct clk              *pixclk;
+@@ -169,6 +171,38 @@ static struct fb_fix_screeninfo sidsafb_
+       .accel          = FB_ACCEL_NONE,
+ };
++/*
++ * Let the user decide whether FBIOPAN_DISPLAY waits for the next
++ * vsync or not.
++ */
++static ssize_t
++vsync_pan_show(struct device *dev, struct device_attribute *attr, char *buf)
++{
++      struct fb_info *info = dev_get_drvdata(dev);
++      struct sidsafb_info *sinfo = info->par;
++
++      return sprintf(buf, "%d\n", sinfo->wait_for_vsync);
++}
++
++static ssize_t
++vsync_pan_store(struct device *dev, struct device_attribute *attr,
++              const char *buf, size_t count)
++{
++      struct fb_info *info = dev_get_drvdata(dev);
++      struct sidsafb_info *sinfo = info->par;
++      unsigned long val;
++
++      val = simple_strtoul(buf, NULL, 0);
++      if (val)
++              sinfo->wait_for_vsync = 1;
++      else
++              sinfo->wait_for_vsync = 0;
++
++      return count;
++}
++
++static DEVICE_ATTR(vsync_pan, 0644, vsync_pan_show, vsync_pan_store);
++
+ static void sidsafb_update_dma(struct fb_info *info,
+                              struct fb_var_screeninfo *var)
+ {
+@@ -513,10 +547,25 @@ static int sidsafb_setcolreg(unsigned in
+ static int sidsafb_pan_display(struct fb_var_screeninfo *var,
+                              struct fb_info *info)
+ {
++      struct sidsafb_info *sinfo = info->par;
++
+       pr_debug("sidsafb_pan_display\n");
+       sidsafb_update_dma(info, var);
++      if (sinfo->wait_for_vsync) {
++              spin_lock_irq(&sinfo->lock);
++              lcdc_writel(sinfo, LCD_ICR, LCDC_BIT(LCD_ICR_EOFIC));
++              lcdc_writel(sinfo, LCD_IER, LCDC_BIT(LCD_IER_EOFIE));
++              init_completion(&sinfo->vsync_complete);
++              lcdc_readl(sinfo, LCD_IMR);
++              spin_unlock_irq(&sinfo->lock);
++
++              wait_for_completion(&sinfo->vsync_complete);
++
++              lcdc_writel(sinfo, LCD_IDR, LCDC_BIT(LCD_IDR_EOFID));
++      }
++
+       return 0;
+ }
+@@ -545,7 +594,7 @@ static irqreturn_t sidsafb_interrupt(int
+                       lcdc_writel(sinfo, LCD_ICR, LCDC_BIT(LCD_ICR_EOFIC));
+                       status &= ~LCDC_BIT(LCD_ISR_EOFIS);
+-                      wake_up(&sinfo->vsync_wait);
++                      complete(&sinfo->vsync_complete);
+               }
+               if (status) {
+@@ -600,8 +649,6 @@ static int __devinit sidsafb_set_fbinfo(
+       info->fbops             = &sidsafb_ops;
+       info->pseudo_palette    = sinfo->pseudo_palette;
+-      init_waitqueue_head(&sinfo->vsync_wait);
+-
+       return 0;
+ }
+@@ -700,18 +747,21 @@ static int __devinit sidsafb_probe(struc
+               goto unregister_irqs;
+       }
++      platform_set_drvdata(pdev, info);
++      ret = device_create_file(&pdev->dev, &dev_attr_vsync_pan);
++      if (ret)
++              goto free_cmap;
++
+       /*
+        * Tell the world that we're ready to go
+        */
+       ret = register_framebuffer(info);
+       if (ret)
+-              goto free_cmap;
++              goto remove_attrs;
+       printk("fb%d: Atmel LCDC at 0x%08lx (mapped at %p), irq %lu\n",
+              info->node, info->fix.mmio_start, sinfo->regs, sinfo->irq_base);
+-      platform_set_drvdata(pdev, info);
+-
+       memset_io(info->screen_base, 0, info->fix.smem_len);
+       info->var.activate |= FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
+       ret = fb_set_var(info, &info->var);
+@@ -724,6 +774,8 @@ static int __devinit sidsafb_probe(struc
+       return 0;
++remove_attrs:
++      device_remove_file(&pdev->dev, &dev_attr_vsync_pan);
+ free_cmap:
+       fb_dealloc_cmap(&info->cmap);
+ unregister_irqs:
+@@ -761,6 +813,8 @@ static int __devexit sidsafb_remove(stru
+       /* TODO: Restore original state */
+       unregister_framebuffer(info);
++      device_remove_file(&pdev->dev, &dev_attr_vsync_pan);
++
+       fb_dealloc_cmap(&info->cmap);
+       free_irq(sinfo->irq_base, info);
+       iounmap(sinfo->regs);
diff --git a/packages/linux/linux-2.6.18/ltv350qv-add-initial_power_state-param.patch b/packages/linux/linux-2.6.18/ltv350qv-add-initial_power_state-param.patch
new file mode 100644 (file)
index 0000000..a877b0e
--- /dev/null
@@ -0,0 +1,25 @@
+Index: linux-2.6.18/drivers/video/backlight/ltv350qv.c
+===================================================================
+--- linux-2.6.18.orig/drivers/video/backlight/ltv350qv.c       2007-01-11 14:55:39.000000000 +0100
++++ linux-2.6.18/drivers/video/backlight/ltv350qv.c    2007-01-11 14:59:23.000000000 +0100
+@@ -19,6 +19,11 @@
+ #define POWER_IS_ON(pwr)      ((pwr) <= FB_BLANK_NORMAL)
++static int initial_power_state = FB_BLANK_POWERDOWN;
++
++module_param(initial_power_state, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
++MODULE_PARM_DESC(initial_power_state, "Set initial power state of LCD");
++
+ struct ltv350qv {
+       struct spi_device *spi;
+       u8 *buffer;
+@@ -178,7 +183,7 @@
+               return -ENOMEM;
+       lcd->spi = spi;
+-      lcd->power = FB_BLANK_POWERDOWN;
++      lcd->power = initial_power_state;
+       init_MUTEX(&lcd->lock);
+       lcd->buffer = kzalloc(8, GFP_KERNEL);
diff --git a/packages/linux/linux-2.6.18/ltv350qv-lcd-driver.patch b/packages/linux/linux-2.6.18/ltv350qv-lcd-driver.patch
new file mode 100644 (file)
index 0000000..ce0250e
--- /dev/null
@@ -0,0 +1,355 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Wed Dec 21 14:52:09 2005 +0100
+Subject: [PATCH] LTV350QV LCD driver
+
+This patch adds support for powering on and off the Samsung LTV350QV
+LCD panel via SPI. The driver responds to framebuffer power management,
+it powers off the panel on reboot/halt/poweroff, and it can also be
+controlled through sysfs. The panel is powered up when the module is
+loaded and off when the module is unloaded.
+
+---
+ drivers/video/backlight/Kconfig    |   12 +
+ drivers/video/backlight/Makefile   |    1 
+ drivers/video/backlight/ltv350qv.c |  301 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 314 insertions(+)
+
+Index: linux-2.6.18-avr32/drivers/video/backlight/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/video/backlight/Kconfig    2006-09-11 20:30:16.000000000 +0200
++++ linux-2.6.18-avr32/drivers/video/backlight/Kconfig 2006-09-11 20:31:24.000000000 +0200
+@@ -42,6 +42,18 @@ config LCD_DEVICE
+       depends on LCD_CLASS_DEVICE
+       default y
++config LCD_LTV350QV
++      tristate "Samsung LTV350QV LCD Panel"
++      depends on LCD_DEVICE && SPI
++      default n
++      help
++        If you have a Samsung LTV350QV LCD panel, say y to include a
++        power control driver for it.  The panel starts up in power
++        off state, so you need this driver in order to see any
++        output.
++
++        The LTV350QV panel is present on most ATSTK1000 boards.
++
+ config BACKLIGHT_CORGI
+       tristate "Sharp Corgi Backlight Driver (SL Series)"
+       depends on BACKLIGHT_DEVICE && PXA_SHARPSL
+Index: linux-2.6.18-avr32/drivers/video/backlight/Makefile
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/video/backlight/Makefile   2006-09-11 20:30:23.000000000 +0200
++++ linux-2.6.18-avr32/drivers/video/backlight/Makefile        2006-09-11 20:31:24.000000000 +0200
+@@ -5,3 +5,4 @@ obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += 
+ obj-$(CONFIG_BACKLIGHT_CORGI) += corgi_bl.o
+ obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
+ obj-$(CONFIG_BACKLIGHT_LOCOMO)        += locomolcd.o
++obj-$(CONFIG_LCD_LTV350QV)    += ltv350qv.o
+Index: linux-2.6.18-avr32/drivers/video/backlight/ltv350qv.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.18-avr32/drivers/video/backlight/ltv350qv.c      2006-09-11 20:31:24.000000000 +0200
+@@ -0,0 +1,301 @@
++/*
++ * Power control for Samsung LTV350QV Quarter VGA LCD Panel
++ *
++ * 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/config.h>
++#include <linux/delay.h>
++#include <linux/err.h>
++#include <linux/fb.h>
++#include <linux/init.h>
++#include <linux/lcd.h>
++#include <linux/module.h>
++#include <linux/reboot.h>
++#include <linux/spi/spi.h>
++
++#define POWER_IS_ON(pwr)      ((pwr) <= FB_BLANK_NORMAL)
++
++struct ltv350qv {
++      struct spi_device *spi;
++      u8 *buffer;
++      int power;
++      struct semaphore lock;
++      struct lcd_device *ld;
++      struct list_head list;
++      int halt_done;
++};
++
++static LIST_HEAD(lcd_list);
++
++static int ltv350qv_write_reg(struct ltv350qv *lcd, u8 reg, u16 val)
++{
++      struct spi_message msg;
++      struct spi_transfer index_xfer = {
++              .len            = 3,
++              .cs_change      = 1,
++      };
++      struct spi_transfer value_xfer = {
++              .len            = 3,
++              .cs_change      = 1,
++      };
++
++      spi_message_init(&msg);
++
++      /* register index */
++      lcd->buffer[0] = 0x74;
++      lcd->buffer[1] = 0x00;
++      lcd->buffer[2] = reg & 0x7f;
++      index_xfer.tx_buf = lcd->buffer;
++      spi_message_add_tail(&index_xfer, &msg);
++
++      /* register value */
++      lcd->buffer[4] = 0x76;
++      lcd->buffer[5] = val >> 8;
++      lcd->buffer[6] = val;
++      value_xfer.tx_buf = lcd->buffer + 4;
++      spi_message_add_tail(&value_xfer, &msg);
++
++      return spi_sync(lcd->spi, &msg);
++}
++
++#define write_reg(_spi, reg, val)                             \
++      do {                                                    \
++              ret = ltv350qv_write_reg(_spi, reg, val);       \
++              if (ret)                                        \
++                      goto out;                               \
++      } while (0)
++
++static int ltv350qv_power_on(struct ltv350qv *lcd)
++{
++      int ret;
++
++      write_reg(lcd,  9, 0x0000);
++      msleep(15);
++      write_reg(lcd,  9, 0x4000);
++      write_reg(lcd, 10, 0x2000);
++      write_reg(lcd,  9, 0x4055);
++      msleep(55);
++      write_reg(lcd,  1, 0x409d);
++      write_reg(lcd,  2, 0x0204);
++      write_reg(lcd,  3, 0x0100);
++      write_reg(lcd,  4, 0x3000);
++      write_reg(lcd,  5, 0x4003);
++      write_reg(lcd,  6, 0x000a);
++      write_reg(lcd,  7, 0x0021);
++      write_reg(lcd,  8, 0x0c00);
++      write_reg(lcd, 10, 0x0103);
++      write_reg(lcd, 11, 0x0301);
++      write_reg(lcd, 12, 0x1f0f);
++      write_reg(lcd, 13, 0x1f0f);
++      write_reg(lcd, 14, 0x0707);
++      write_reg(lcd, 15, 0x0307);
++      write_reg(lcd, 16, 0x0707);
++      write_reg(lcd, 17, 0x0000);
++      write_reg(lcd, 18, 0x0004);
++      write_reg(lcd, 19, 0x0000);
++
++      msleep(20);
++      write_reg(lcd,  9, 0x4a55);
++      write_reg(lcd,  5, 0x5003);
++
++out:
++      return ret;
++}
++
++static int ltv350qv_power_off(struct ltv350qv *lcd)
++{
++      int ret;
++
++      /* GON -> 0, POC -> 0 */
++      write_reg(lcd,  9, 0x4055);
++      /* DSC -> 0 */
++      write_reg(lcd,  5, 0x4003);
++      /* VCOMG -> 0 */
++      write_reg(lcd, 10, 0x2103);
++
++      msleep(1);
++
++      /* AP[2:0] -> 000 */
++      write_reg(lcd,  9, 0x4050);
++
++out:
++      return ret;
++}
++
++static int ltv350qv_power(struct ltv350qv *lcd, int power)
++{
++      int ret = 0;
++
++      down(&lcd->lock);
++
++      if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
++              ret = ltv350qv_power_on(lcd);
++      else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
++              ret = ltv350qv_power_off(lcd);
++
++      if (!ret)
++              lcd->power = power;
++
++      up(&lcd->lock);
++
++      return ret;
++}
++
++static int ltv350qv_set_power(struct lcd_device *ld, int power)
++{
++      struct ltv350qv *lcd;
++
++      lcd = class_get_devdata(&ld->class_dev);
++      return ltv350qv_power(lcd, power);
++}
++
++static int ltv350qv_get_power(struct lcd_device *ld)
++{
++      struct ltv350qv *lcd;
++
++      lcd = class_get_devdata(&ld->class_dev);
++      return lcd->power;
++}
++
++static struct lcd_properties lcd_properties = {
++      .owner          = THIS_MODULE,
++      .get_power      = ltv350qv_get_power,
++      .set_power      = ltv350qv_set_power,
++};
++
++static int __devinit ltv350qv_probe(struct spi_device *spi)
++{
++      struct ltv350qv *lcd;
++      struct lcd_device *ld;
++      int ret;
++
++      lcd = kzalloc(sizeof(struct ltv350qv), GFP_KERNEL);
++      if (!lcd)
++              return -ENOMEM;
++
++      lcd->spi = spi;
++      lcd->power = FB_BLANK_POWERDOWN;
++      init_MUTEX(&lcd->lock);
++      lcd->buffer = kzalloc(8, GFP_KERNEL);
++
++      spi->mode = SPI_MODE_3;
++      spi->bits_per_word = 8;
++      ret = spi_setup(spi);
++      if (ret)
++              goto out_free_lcd;
++
++      ld = lcd_device_register("ltv350qv", lcd, &lcd_properties);
++      if (IS_ERR(ld)) {
++              ret = PTR_ERR(ld);
++              goto out_free_lcd;
++      }
++      lcd->ld = ld;
++
++      list_add(&lcd->list, &lcd_list);
++
++      ret = ltv350qv_power(lcd, FB_BLANK_UNBLANK);
++      if (ret)
++              goto out_unregister;
++
++      dev_set_drvdata(&spi->dev, lcd);
++
++      return 0;
++
++out_unregister:
++      lcd_device_unregister(ld);
++out_free_lcd:
++      kfree(lcd);
++      return ret;
++}
++
++static int __devexit ltv350qv_remove(struct spi_device *spi)
++{
++      struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
++
++      ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
++      list_del(&lcd->list);
++      lcd_device_unregister(lcd->ld);
++      kfree(lcd);
++
++      return 0;
++}
++
++#ifdef CONFIG_PM
++static int ltv350qv_suspend(struct spi_device *spi,
++                          pm_message_t state, u32 level)
++{
++      struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
++
++      if (level == SUSPEND_POWER_DOWN)
++              return ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
++
++      return 0;
++}
++
++static int ltv350qv_resume(struct spi_device *spi, u32 level)
++{
++      struct ltv350qv *lcd = dev_get_drvdata(&spi->dev);
++
++      if (level == RESUME_POWER_ON)
++              return ltv350qv_power(lcd, FB_BLANK_UNBLANK);
++
++      return 0;
++}
++#else
++#define ltv350qv_suspend      NULL
++#define ltv350qv_resume               NULL
++#endif
++
++/* Power down all displays on reboot, poweroff or halt */
++static int ltv350qv_halt(struct notifier_block *nb, unsigned long event,
++                       void *p)
++{
++      struct ltv350qv *lcd;
++
++      list_for_each_entry(lcd, &lcd_list, list) {
++              if (!lcd->halt_done)
++                      ltv350qv_power(lcd, FB_BLANK_POWERDOWN);
++              lcd->halt_done = 1;
++      }
++
++      return NOTIFY_OK;
++}
++
++static struct spi_driver ltv350qv_driver = {
++      .driver = {
++              .name           = "ltv350qv",
++              .bus            = &spi_bus_type,
++              .owner          = THIS_MODULE,
++      },
++
++      .probe          = ltv350qv_probe,
++      .remove         = __devexit_p(ltv350qv_remove),
++      .suspend        = ltv350qv_suspend,
++      .resume         = ltv350qv_resume,
++};
++
++static struct notifier_block ltv350qv_notifier = {
++      .notifier_call  = ltv350qv_halt,
++};
++
++static int __init ltv350qv_init(void)
++{
++      register_reboot_notifier(&ltv350qv_notifier);
++      return spi_register_driver(&ltv350qv_driver);
++}
++
++static void __exit ltv350qv_exit(void)
++{
++      unregister_reboot_notifier(&ltv350qv_notifier);
++      spi_unregister_driver(&ltv350qv_driver);
++}
++module_init(ltv350qv_init);
++module_exit(ltv350qv_exit);
++
++MODULE_AUTHOR("Atmel Norway");
++MODULE_DESCRIPTION("Samsung LTV350QV LCD Driver");
++MODULE_LICENSE("GPL");
diff --git a/packages/linux/linux-2.6.18/mmc-add-bit-manipulating-macros.patch b/packages/linux/linux-2.6.18/mmc-add-bit-manipulating-macros.patch
new file mode 100644 (file)
index 0000000..544e447
--- /dev/null
@@ -0,0 +1,321 @@
+Index: linux-2.6.18/drivers/mmc/atmel-mci.c
+===================================================================
+--- linux-2.6.18.orig/drivers/mmc/atmel-mci.c  2007-01-15 16:36:59.000000000 +0100
++++ linux-2.6.18/drivers/mmc/atmel-mci.c       2007-01-16 13:18:40.000000000 +0100
+@@ -45,6 +45,7 @@
+       EVENT_STOP_COMPLETE,
+       EVENT_STOP_ERROR,
+       EVENT_DMA_ERROR,
++      EVENT_CARD_DETECT,
+ };
+ struct atmel_mci_dma {
+@@ -572,9 +589,8 @@
+        * Data might complete before command for very short transfers
+        * (like READ_SCR)
+        */
+-      if (test_bit(EVENT_CMD_COMPLETE, &host->completed_events)
+-          && (!data->stop
+-              || test_bit(EVENT_STOP_COMPLETE, &host->completed_events)))
++      if (mci_cmd_is_complete(host)
++                      && (!data->stop || mci_stop_is_complete(host)))
+               atmci_request_end(host->mmc, data->mrq);
+ }
+@@ -604,11 +620,11 @@
+                host->pending_events, host->completed_events,
+                mci_readl(host, IMR));
+-      if (test_and_clear_bit(EVENT_CMD_ERROR, &host->pending_events)) {
++      if (mci_clear_cmd_error_is_pending(host)) {
+               struct mmc_command *cmd;
+-              set_bit(EVENT_CMD_ERROR, &host->completed_events);
+-              clear_bit(EVENT_CMD_COMPLETE, &host->pending_events);
++              mci_set_cmd_error_complete(host);
++              mci_clear_cmd_pending(host);
+               cmd = host->mrq->cmd;
+               if (cmd->data) {
+@@ -620,28 +636,27 @@
+               atmci_command_error(mmc, cmd, host->error_status);
+               atmci_request_end(mmc, cmd->mrq);
+       }
+-      if (test_and_clear_bit(EVENT_STOP_ERROR, &host->pending_events)) {
+-              set_bit(EVENT_STOP_ERROR, &host->completed_events);
+-              clear_bit(EVENT_STOP_COMPLETE, &host->pending_events);
++      if (mci_clear_stop_error_is_pending(host)) {
++              mci_set_stop_error_complete(host);
++              mci_clear_stop_pending(host);
+               atmci_command_error(mmc, host->mrq->stop,
+                                   host->error_status);
+               if (!host->data)
+                       atmci_request_end(mmc, host->mrq);
+       }
+-      if (test_and_clear_bit(EVENT_CMD_COMPLETE, &host->pending_events)) {
+-              set_bit(EVENT_CMD_COMPLETE, &host->completed_events);
+-              if (!mrq->data
+-                  || test_bit(EVENT_DATA_COMPLETE, &host->completed_events))
++      if (mci_clear_cmd_is_pending(host)) {
++              mci_set_cmd_complete(host);
++              if (!mrq->data || mci_data_is_complete(host))
+                       atmci_request_end(mmc, mrq);
+       }
+-      if (test_and_clear_bit(EVENT_STOP_COMPLETE, &host->pending_events)) {
+-              set_bit(EVENT_STOP_COMPLETE, &host->completed_events);
+-              if (test_bit(EVENT_DATA_COMPLETE, &host->completed_events))
++      if (mci_clear_stop_is_pending(host)) {
++              mci_set_stop_complete(host);
++              if (mci_data_is_complete(host))
+                       atmci_request_end(mmc, mrq);
+       }
+-      if (test_and_clear_bit(EVENT_DMA_ERROR, &host->pending_events)) {
+-              set_bit(EVENT_DMA_ERROR, &host->completed_events);
+-              clear_bit(EVENT_DATA_COMPLETE, &host->pending_events);
++      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 = MMC_ERR_INVALID;
+@@ -650,18 +665,17 @@
+                      mmc_hostname(mmc), host->data->bytes_xfered);
+               if (data->stop
+-                  && !test_and_set_bit(EVENT_STOP_SENT,
+-                                       &host->completed_events))
++                  && !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 (test_and_clear_bit(EVENT_DATA_ERROR, &host->pending_events)) {
++      if (mci_clear_data_error_is_pending(host)) {
+               u32 status = host->error_status;
+-              set_bit(EVENT_DATA_ERROR, &host->completed_events);
+-              clear_bit(EVENT_DATA_COMPLETE, &host->pending_events);
++              mci_set_data_error_complete(host);
++              mci_clear_data_pending(host);
+               dma_stop_request(host->dma.req.req.dmac,
+                                host->dma.req.req.channel);
+@@ -686,14 +700,14 @@
+                      mmc_hostname(host->mmc), data->bytes_xfered);
+               if (data->stop
+-                  && !test_and_set_bit(EVENT_STOP_SENT, &host->completed_events))
++                  && !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 (test_and_clear_bit(EVENT_DATA_COMPLETE, &host->pending_events)) {
+-              set_bit(EVENT_DATA_COMPLETE, &host->completed_events);
++      if (mci_clear_data_is_pending(host)) {
++              mci_set_data_complete(host);
+               data->bytes_xfered = data->blocks * data->blksz;
+               atmci_data_complete(host, data);
+       }
+@@ -716,10 +761,10 @@
+       mci_writel(host, IDR, MCI_BIT(CMDRDY) | MCI_CMD_ERROR_FLAGS);
+       host->cmd = NULL;
+-      if (test_bit(EVENT_STOP_SENT, &host->completed_events))
+-              set_bit(EVENT_STOP_COMPLETE, &host->pending_events);
++      if (mci_stop_sent_is_complete(host))
++              mci_set_stop_pending(host);
+       else
+-              set_bit(EVENT_CMD_COMPLETE, &host->pending_events);
++              mci_set_cmd_pending(host);
+       tasklet_schedule(&host->tasklet);
+ }
+@@ -735,13 +780,12 @@
+       host = container_of(dma, struct atmel_mci, dma);
+       data = host->data;
+-      if (data->stop && !test_and_set_bit(EVENT_STOP_SENT,
+-                                          &host->completed_events))
++      if (data->stop && !mci_set_stop_sent_is_completed(host))
+               send_stop_cmd(host->mmc, data, 0);
+       if (data->flags & MMC_DATA_READ) {
+               mci_writel(host, IDR, MCI_DATA_ERROR_FLAGS);
+-              set_bit(EVENT_DATA_COMPLETE, &host->pending_events);
++              mci_set_data_pending(host);
+               tasklet_schedule(&host->tasklet);
+       } else {
+               /*
+@@ -765,7 +809,7 @@
+       mci_writel(host, IDR, (MCI_BIT(NOTBUSY)
+                              | MCI_DATA_ERROR_FLAGS));
+-      set_bit(EVENT_DMA_ERROR, &host->pending_events);
++      mci_set_dma_error_pending(host);
+       tasklet_schedule(&host->tasklet);
+ }
+@@ -790,10 +834,10 @@
+                                              | MCI_DATA_ERROR_FLAGS));
+                       host->error_status = status;
+                       host->cmd = NULL;
+-                      if (test_bit(EVENT_STOP_SENT, &host->completed_events))
+-                              set_bit(EVENT_STOP_ERROR, &host->pending_events);
++                      if (mci_stop_sent_is_complete(host))
++                              mci_set_stop_error_pending(host);
+                       else
+-                              set_bit(EVENT_CMD_ERROR, &host->pending_events);
++                              mci_set_cmd_error_pending(host);
+                       tasklet_schedule(&host->tasklet);
+                       break;
+               }
+@@ -801,7 +845,7 @@
+                       mci_writel(host, IDR, (MCI_BIT(NOTBUSY)
+                                              | MCI_DATA_ERROR_FLAGS));
+                       host->error_status = status;
+-                      set_bit(EVENT_DATA_ERROR, &host->pending_events);
++                      mci_set_data_error_pending(host);
+                       tasklet_schedule(&host->tasklet);
+                       break;
+               }
+@@ -810,7 +854,7 @@
+               if (pending & MCI_BIT(NOTBUSY)) {
+                       mci_writel(host, IDR, (MCI_BIT(NOTBUSY)
+                                              | MCI_DATA_ERROR_FLAGS));
+-                      set_bit(EVENT_DATA_COMPLETE, &host->pending_events);
++                      mci_set_data_pending(host);
+                       tasklet_schedule(&host->tasklet);
+               }
+Index: linux-2.6.18/drivers/mmc/atmel-mci.h
+===================================================================
+--- linux-2.6.18.orig/drivers/mmc/atmel-mci.h  2007-01-16 13:22:59.000000000 +0100
++++ linux-2.6.18/drivers/mmc/atmel-mci.h       2007-01-16 13:24:33.000000000 +0100
+@@ -189,4 +189,124 @@
+ #define mci_writel(port,reg,value)                    \
+       __raw_writel((value), (port)->regs + MCI_##reg)
++/* Test bit macros for completed events */
++#define mci_cmd_is_complete(host)                     \
++      test_bit(EVENT_CMD_COMPLETE, &host->completed_events)
++#define mci_cmd_error_is_complete(host)                       \
++      test_bit(EVENT_CMD_ERROR, &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_stop_error_is_complete(host)              \
++      test_bit(EVENT_STOP_ERROR, &host->completed_events)
++#define mci_dma_error_is_complete(host)                       \
++      test_bit(EVENT_DMA_ERROR, &host->completed_events)
++#define mci_card_detect_is_complete(host)                     \
++      test_bit(EVENT_CARD_DETECT, &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_cmd_error_is_pending(host)          \
++      test_and_clear_bit(EVENT_CMD_ERROR, &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_stop_error_is_pending(host)         \
++      test_and_clear_bit(EVENT_STOP_ERROR, &host->pending_events)
++#define mci_clear_dma_error_is_pending(host)          \
++      test_and_clear_bit(EVENT_DMA_ERROR, &host->pending_events)
++#define mci_clear_card_detect_is_pending(host)                \
++      test_and_clear_bit(EVENT_CARD_DETECT, &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_cmd_error_is_completed(host)          \
++      test_and_set_bit(EVENT_CMD_ERROR, &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_stop_error_is_completed(host)         \
++      test_and_set_bit(EVENT_STOP_ERROR, &host->completed_events)
++#define mci_set_dma_error_is_completed(host)          \
++      test_and_set_bit(EVENT_DMA_ERROR, &host->completed_events)
++#define mci_set_card_detect_is_completed(host)                \
++      test_and_set_bit(EVENT_CARD_DETECT, &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_cmd_error_complete(host)              \
++      set_bit(EVENT_CMD_ERROR, &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_stop_error_complete(host)             \
++      set_bit(EVENT_STOP_ERROR, &host->completed_events)
++#define mci_set_dma_error_complete(host)              \
++      set_bit(EVENT_DMA_ERROR, &host->completed_events)
++#define mci_set_card_detect_complete(host)            \
++      set_bit(EVENT_CARD_DETECT, &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_cmd_error_pending(host)                       \
++      set_bit(EVENT_CMD_ERROR, &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_stop_error_pending(host)              \
++      set_bit(EVENT_STOP_ERROR, &host->pending_events)
++#define mci_set_dma_error_pending(host)                       \
++      set_bit(EVENT_DMA_ERROR, &host->pending_events)
++#define mci_set_card_detect_pending(host)             \
++      set_bit(EVENT_CARD_DETECT, &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_cmd_error_pending(host)             \
++      clear_bit(EVENT_CMD_ERROR, &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_stop_error_pending(host)            \
++      clear_bit(EVENT_STOP_ERROR, &host->pending_events)
++#define mci_clear_dma_error_pending(host)             \
++      clear_bit(EVENT_DMA_ERROR, &host->pending_events)
++#define mci_clear_card_detect_pending(host)           \
++      clear_bit(EVENT_CARD_DETECT, &host->pending_events)
++
+ #endif /* __DRIVERS_MMC_ATMEL_MCI_H__ */
diff --git a/packages/linux/linux-2.6.18/mmc-add-detect-card-and-wp-support.patch b/packages/linux/linux-2.6.18/mmc-add-detect-card-and-wp-support.patch
new file mode 100644 (file)
index 0000000..f91ddc2
--- /dev/null
@@ -0,0 +1,159 @@
+Index: linux-2.6.18/drivers/mmc/atmel-mci.c
+===================================================================
+--- linux-2.6.18.orig/drivers/mmc/atmel-mci.c  2007-01-16 14:01:56.000000000 +0100
++++ linux-2.6.18/drivers/mmc/atmel-mci.c       2007-01-16 14:20:23.000000000 +0100
+@@ -72,7 +72,6 @@
+       u32                     error_status;
+       int                     present;
+-      unsigned int            wp_present:1;
+       unsigned long           bus_hz;
+       unsigned long           mapbase;
+@@ -538,9 +537,26 @@
+       }
+ }
++int atmci_get_ro(struct mmc_host *mmc)
++{
++      int read_only = 0;
++      struct atmel_mci *host = mmc_priv(mmc);
++
++      if (host->board->wp_pin != GPIO_PIO_NONE) {
++              read_only = gpio_get_value(host->board->wp_pin);
++              pr_debug("%s: card is %s\n", mmc_hostname(mmc),
++                              (read_only ? "read-only" : "read-write") );
++      } else {
++              pr_debug("%s: host does not support reading read-only switch."
++                              " Assuming write-enable.\n", mmc_hostname(mmc));
++      }
++      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)
+@@ -695,6 +711,37 @@
+               data->bytes_xfered = data->blocks * data->blksz;
+               atmci_data_complete(host, data);
+       }
++      if (mci_clear_card_detect_is_pending(host)) {
++              /* Reset controller if card is gone */
++              if (!host->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)
++                                      && !mci_cmd_error_is_complete(host)) {
++                              mrq->cmd->error = MMC_ERR_TIMEOUT;
++                      }
++                      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 = MMC_ERR_TIMEOUT;
++                              atmci_data_complete(host, data);
++                      }
++                      if (mrq->stop && !mci_stop_is_complete(host)
++                                      && !mci_stop_error_is_complete(host)) {
++                              mrq->stop->error = MMC_ERR_TIMEOUT;
++                      }
++
++                      host->cmd = NULL;
++                      atmci_request_end(mmc, mrq);
++              }
++              mmc_detect_change(host->mmc, msecs_to_jiffies(100));
++      }
+ }
+ static void atmci_cmd_interrupt(struct mmc_host *mmc, u32 status)
+@@ -821,6 +868,23 @@
+       return IRQ_HANDLED;
+ }
++static irqreturn_t atmci_detect_int(int irq, void *dev_id, struct pt_regs *regs)
++{
++      struct mmc_host *mmc = dev_id;
++      struct atmel_mci *host = mmc_priv(mmc);
++
++      int present = !gpio_get_value(irq_to_gpio(irq));
++
++      if (present != host->present) {
++              pr_debug("%s: card %s\n", mmc_hostname(host->mmc),
++                              present ? "inserted" : "removed");
++              host->present = present;
++              mci_set_card_detect_pending(host);
++              tasklet_schedule(&host->tasklet);
++      }
++      return IRQ_HANDLED;
++}
++
+ static int __devinit atmci_probe(struct platform_device *pdev)
+ {
+       struct atmel_mci *host;
+@@ -887,15 +951,9 @@
+       if (host->board && host->board->wp_pin != GPIO_PIO_NONE) {
+               ret = gpio_request(host->board->wp_pin, "mmc_wp");
+-              if (ret) {
++              if (ret)
+                       printk(KERN_WARNING "%s: no WP pin available (%d)\n",
+                                       mmc_hostname(host->mmc), ret);
+-                      host->wp_present = 0;
+-              } else {
+-                      host->wp_present = 1;
+-              }
+-      } else {
+-              host->wp_present = 0;
+       }
+       /* TODO: Get this information from platform data */
+@@ -928,6 +986,19 @@
+       mmc_add_host(mmc);
++      if (host->present != -1) {
++              ret = request_irq(gpio_to_irq(host->board->detect_pin),
++                              atmci_detect_int,
++                              IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,
++                              "mmci", mmc);
++              if (ret) {
++                      printk(KERN_ERR "%s: could not request IRQ %d "
++                                      "for detect pin\n",
++                                      mmc_hostname(mmc),
++                                      gpio_to_irq(host->board->detect_pin));
++              }
++      }
++
+       printk(KERN_INFO "%s: Atmel MCI controller at 0x%08lx irq %d\n",
+              mmc_hostname(mmc), host->mapbase, irq);
+@@ -936,8 +1007,11 @@
+       return 0;
+ out_free_irq:
+-      if (host->present != -1)
++      if (host->present != -1) {
++              free_irq(gpio_to_irq(host->board->detect_pin), host->mmc);
++              cancel_delayed_work(&host->mmc->detect);
+               gpio_free(host->board->detect_pin);
++      }
+       if (host->board->wp_pin != GPIO_PIO_NONE)
+               gpio_free(host->board->wp_pin);
+       free_irq(irq, mmc);
+@@ -971,6 +1045,7 @@
+                                       host->dma.req.req.channel);
+               if (host->present != -1) {
++                      free_irq(gpio_to_irq(host->board->detect_pin), host->mmc);
+                       cancel_delayed_work(&host->mmc->detect);
+                       gpio_free(host->board->detect_pin);
+               }
diff --git a/packages/linux/linux-2.6.18/mmc-add-platform-data.patch b/packages/linux/linux-2.6.18/mmc-add-platform-data.patch
new file mode 100644 (file)
index 0000000..b0a67b3
--- /dev/null
@@ -0,0 +1,185 @@
+---
+ arch/avr32/boards/atngw/setup.c       |    7 ++++
+ arch/avr32/mach-at32ap/at32ap7000.c   |   13 +++++++--
+ drivers/mmc/atmel-mci.c               |   49 ++++++++++++++++++++++++++++++++++
+ include/asm-avr32/arch-at32ap/board.h |    7 ++++
+ 4 files changed, 72 insertions(+), 4 deletions(-)
+
+Index: linux-2.6.18-avr32/arch/avr32/boards/atngw/setup.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/boards/atngw/setup.c    2007-01-15 10:24:38.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/boards/atngw/setup.c 2007-01-15 10:25:04.000000000 +0100
+@@ -35,6 +35,11 @@ static struct spi_board_info spi_board_i
+       },
+ };
++static struct mmci_platform_data __initdata mmci0_data = {
++              .detect_pin     = GPIO_PIN_PC(25),
++              .wp_pin         = GPIO_PIN_PE(0),
++};
++
+ static int __init parse_tag_ethernet(struct tag *tag)
+ {
+       int i;
+@@ -72,7 +77,7 @@ static int __init atngw_init(void)
+       spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+       at32_add_device_spi(0);
+-      at32_add_device_mmci(0);
++      at32_add_device_mmci(0, &mmci0_data);
+       at32_add_device_usb(0);
+       return 0;
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap7000.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/at32ap7000.c        2007-01-15 10:24:38.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap7000.c     2007-01-15 10:25:04.000000000 +0100
+@@ -749,14 +749,16 @@ at32_add_device_eth(unsigned int id, str
+ /* --------------------------------------------------------------------
+  * MMC
+  * -------------------------------------------------------------------- */
++static struct mmci_platform_data mmci0_data;
+ static struct resource mmci0_resource[] = {
+       PBMEM(0xfff02400),
+       IRQ(28),
+ };
+-DEFINE_DEV(mmci, 0);
++DEFINE_DEV_DATA(mmci, 0);
+ DEV_CLK(mck, mmci0, pbb, 9);
+-struct platform_device *__init at32_add_device_mmci(unsigned int id)
++struct platform_device *__init
++at32_add_device_mmci(unsigned int id, struct mmci_platform_data *data)
+ {
+       struct platform_device *pdev;
+@@ -774,6 +776,13 @@ struct platform_device *__init at32_add_
+               return NULL;
+       }
++      if (data && data->detect_pin != GPIO_PIO_NONE)
++              at32_select_gpio(data->detect_pin, 0);
++      if (data && data->wp_pin != GPIO_PIO_NONE)
++              at32_select_gpio(data->wp_pin, 0);
++
++      memcpy(pdev->dev.platform_data, data,
++                      sizeof(struct mmci_platform_data));
+       platform_device_register(pdev);
+       return pdev;
+ }
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/board.h
+===================================================================
+--- linux-2.6.18-avr32.orig/include/asm-avr32/arch-at32ap/board.h      2007-01-15 10:24:38.000000000 +0100
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/board.h   2007-01-15 10:25:04.000000000 +0100
+@@ -24,7 +24,12 @@ struct eth_platform_data {
+ struct platform_device *
+ at32_add_device_eth(unsigned int id, struct eth_platform_data *data);
+-struct platform_device *at32_add_device_mmci(unsigned int id);
++struct mmci_platform_data {
++      unsigned int detect_pin;
++      unsigned int wp_pin;
++};
++struct platform_device *
++at32_add_device_mmci(unsigned int id, struct mmci_platform_data *data);
+ struct platform_device *at32_add_device_spi(unsigned int id);
+ struct platform_device *at32_add_device_twi(unsigned int id);
+Index: linux-2.6.18-avr32/drivers/mmc/atmel-mci.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/mmc/atmel-mci.c    2007-01-15 10:23:19.000000000 +0100
++++ linux-2.6.18-avr32/drivers/mmc/atmel-mci.c 2007-01-15 10:27:37.000000000 +0100
+@@ -22,6 +22,9 @@
+ #include <asm/dma-controller.h>
+ #include <asm/io.h>
++#include <asm/arch/at32ap7000.h>
++#include <asm/arch/board.h>
++#include <asm/arch/gpio.h>
+ #include "atmel-mci.h"
+@@ -68,9 +71,13 @@ struct atmel_mci {
+       unsigned long           completed_events;
+       u32                     error_status;
++      int                     present;
++      unsigned int            wp_present:1;
++
+       unsigned long           bus_hz;
+       unsigned long           mapbase;
+       struct clk              *mck;
++      struct mmci_platform_data *board;
+       struct platform_device  *pdev;
+ };
+@@ -626,6 +633,7 @@ static int __devinit atmci_probe(struct 
+       if (!host->regs)
+               goto out_disable_clk;
++      host->board = pdev->dev.platform_data;
+       host->bus_hz = clk_get_rate(host->mck);
+       host->mapbase = regs->start;
+@@ -641,6 +649,32 @@ static int __devinit atmci_probe(struct 
+       if (ret)
+               goto out_unmap;
++      if (host->board && host->board->detect_pin != GPIO_PIO_NONE) {
++              ret = gpio_request(host->board->detect_pin, "mmc_detect");
++              if (ret) {
++                      printk(KERN_WARNING "%s: no detect pin available (%d)\n",
++                                      mmc_hostname(host->mmc), ret);
++                      host->present = -1;
++              } else {
++                      host->present = !gpio_get_value(host->board->detect_pin);
++              }
++      } else {
++              host->present = -1;
++      }
++
++      if (host->board && host->board->wp_pin != GPIO_PIO_NONE) {
++              ret = gpio_request(host->board->wp_pin, "mmc_wp");
++              if (ret) {
++                      printk(KERN_WARNING "%s: no WP pin available (%d)\n",
++                                      mmc_hostname(host->mmc), ret);
++                      host->wp_present = 0;
++              } else {
++                      host->wp_present = 1;
++              }
++      } else {
++              host->wp_present = 0;
++      }
++
+       /* TODO: Get this information from platform data */
+       ret = -ENOMEM;
+       host->dma.req.req.dmac = find_dma_controller(0);
+@@ -677,6 +711,10 @@ static int __devinit atmci_probe(struct 
+       return 0;
+ out_free_irq:
++      if (host->present != -1)
++              gpio_free(host->board->detect_pin);
++      if (host->board->wp_pin != GPIO_PIO_NONE)
++              gpio_free(host->board->wp_pin);
+       free_irq(irq, mmc);
+ out_unmap:
+       iounmap(host->regs);
+@@ -701,6 +739,17 @@ static int __devexit atmci_remove(struct
+               mci_writel(host, CR, MCI_BIT(MCIDIS));
+               mci_readl(host, SR);
++              if (host->dma.req.req.channel)
++                      dma_release_channel(host->dma.req.req.dmac,
++                                      host->dma.req.req.channel);
++
++              if (host->present != -1) {
++                      cancel_delayed_work(&host->mmc->detect);
++                      gpio_free(host->board->detect_pin);
++              }
++              if (host->board->wp_pin != GPIO_PIO_NONE)
++                      gpio_free(host->board->wp_pin);
++
+               free_irq(platform_get_irq(pdev, 0), host->mmc);
+               iounmap(host->regs);
diff --git a/packages/linux/linux-2.6.18/mmc-core-dma-fix.patch b/packages/linux/linux-2.6.18/mmc-core-dma-fix.patch
new file mode 100644 (file)
index 0000000..4106970
--- /dev/null
@@ -0,0 +1,33 @@
+Index: linux-2.6.18-avr32/drivers/mmc/mmc.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/mmc/mmc.c  2007-01-04 09:54:56.000000000 +0100
++++ linux-2.6.18-avr32/drivers/mmc/mmc.c       2007-01-04 09:58:08.000000000 +0100
+@@ -961,6 +961,7 @@ static void mmc_read_scrs(struct mmc_hos
+       struct mmc_command cmd;
+       struct mmc_data data;
+       struct scatterlist sg;
++      u32 *buf;
+       list_for_each_entry(card, &host->cards, node) {
+               if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))
+@@ -1008,7 +1009,8 @@ static void mmc_read_scrs(struct mmc_hos
+               mrq.cmd = &cmd;
+               mrq.data = &data;
+-              sg_init_one(&sg, (u8*)card->raw_scr, 8);
++              buf = kmalloc(8, GFP_KERNEL);
++              sg_init_one(&sg, (u8*)buf, 8);
+               mmc_wait_for_req(host, &mrq);
+@@ -1017,8 +1019,8 @@ static void mmc_read_scrs(struct mmc_hos
+                       continue;
+               }
+-              card->raw_scr[0] = ntohl(card->raw_scr[0]);
+-              card->raw_scr[1] = ntohl(card->raw_scr[1]);
++              card->raw_scr[0] = ntohl(buf[0]);
++              card->raw_scr[1] = ntohl(buf[1]);
+               mmc_decode_scr(card);
+       }
diff --git a/packages/linux/linux-2.6.18/mtd-fix-atmel-pri-for-cmdset-0001-and-cmdset-0002.patch b/packages/linux/linux-2.6.18/mtd-fix-atmel-pri-for-cmdset-0001-and-cmdset-0002.patch
new file mode 100644 (file)
index 0000000..4884d8a
--- /dev/null
@@ -0,0 +1,99 @@
+Index: linux-2.6.18/drivers/mtd/chips/cfi_cmdset_0001.c
+===================================================================
+--- linux-2.6.18.orig/drivers/mtd/chips/cfi_cmdset_0001.c      2006-12-13 09:58:34.000000000 +0100
++++ linux-2.6.18/drivers/mtd/chips/cfi_cmdset_0001.c   2006-12-13 10:01:35.000000000 +0100
+@@ -47,6 +47,7 @@
+ #define I82802AC      0x00ac
+ #define MANUFACTURER_ST         0x0020
+ #define M50LPW080       0x002F
++#define AT49BV640D    0x02de
+ static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
+ static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+@@ -153,6 +154,47 @@
+ }
+ #endif
++/* Atmel chips don't use the same PRI format as Intel chips */
++static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param)
++{
++      struct map_info *map = mtd->priv;
++      struct cfi_private *cfi = map->fldrv_priv;
++      struct cfi_pri_intelext *extp = cfi->cmdset_priv;
++      struct cfi_pri_atmel atmel_pri;
++      uint32_t features = 0;
++
++      /* Reverse byteswapping */
++      extp->FeatureSupport = cpu_to_le32(extp->FeatureSupport);
++      extp->BlkStatusRegMask = cpu_to_le16(extp->BlkStatusRegMask);
++      extp->ProtRegAddr = cpu_to_le16(extp->ProtRegAddr);
++
++      memcpy(&atmel_pri, extp, sizeof(atmel_pri));
++      memset((char *)extp + 5, 0, sizeof(*extp) - 5);
++
++      printk(KERN_ERR "atmel Features: %02x\n", atmel_pri.Features);
++
++      if (atmel_pri.Features & 0x01) /* chip erase supported */
++              features |= (1<<0);
++      if (atmel_pri.Features & 0x02) /* erase suspend supported */
++              features |= (1<<1);
++      if (atmel_pri.Features & 0x04) /* program suspend supported */
++              features |= (1<<2);
++      if (atmel_pri.Features & 0x08) /* simultaneous operations supported */
++              features |= (1<<9);
++      if (atmel_pri.Features & 0x20) /* page mode read supported */
++              features |= (1<<7);
++      if (atmel_pri.Features & 0x40) /* queued erase supported */
++              features |= (1<<4);
++      if (atmel_pri.Features & 0x80) /* Protection bits supported */
++              features |= (1<<6);
++
++      extp->FeatureSupport = features;
++
++      /* burst write mode not supported */
++      cfi->cfiq->BufWriteTimeoutTyp = 0;
++      cfi->cfiq->BufWriteTimeoutMax = 0;
++}
++
+ #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
+ /* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
+ static void fixup_intel_strataflash(struct mtd_info *mtd, void* param)
+@@ -221,6 +263,7 @@
+ }
+ static struct cfi_fixup cfi_fixup_table[] = {
++      { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
+ #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
+       { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL },
+ #endif
+Index: linux-2.6.18/drivers/mtd/chips/cfi_cmdset_0002.c
+===================================================================
+--- linux-2.6.18.orig/drivers/mtd/chips/cfi_cmdset_0002.c      2006-12-13 10:01:34.000000000 +0100
++++ linux-2.6.18/drivers/mtd/chips/cfi_cmdset_0002.c   2006-12-15 10:19:22.000000000 +0100
+@@ -184,6 +184,10 @@
+               extp->TopBottom = 2;
+       else
+               extp->TopBottom = 3;
++
++      /* burst write mode not supported */
++      cfi->cfiq->BufWriteTimeoutTyp = 0;
++      cfi->cfiq->BufWriteTimeoutMax = 0;
+ }
+ static void fixup_use_secsi(struct mtd_info *mtd, void *param)
+@@ -216,6 +220,7 @@
+ }
+ static struct cfi_fixup cfi_fixup_table[] = {
++      { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
+ #ifdef AMD_BOOTLOC_BUG
+       { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL },
+ #endif
+@@ -228,7 +233,6 @@
+ #if !FORCE_WORD_WRITE
+       { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
+ #endif
+-      { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
+       { 0, 0, NULL, NULL }
+ };
+ static struct cfi_fixup jedec_fixup_table[] = {
diff --git a/packages/linux/linux-2.6.18/mtd-unlock-nor-flash-automatically-where-necessary.patch b/packages/linux/linux-2.6.18/mtd-unlock-nor-flash-automatically-where-necessary.patch
new file mode 100644 (file)
index 0000000..1cb1f8e
--- /dev/null
@@ -0,0 +1,75 @@
+From 187ef15268e638603dea55a91fdfa29feaed6d13 Mon Sep 17 00:00:00 2001
+From: =?utf-8?q?H=C3=A5vard_Skinnemoen?= <hskinnemoen@atmel.com>
+Date: Fri, 22 Sep 2006 10:07:08 +0100
+Subject: [PATCH] [MTD] Unlock NOR flash automatically where necessary
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Introduce the MTD_STUPID_LOCK flag which indicates that the flash chip is
+always locked after power-up, so all sectors need to be unlocked before it
+is usable.
+
+If this flag is set, and the chip provides an unlock() operation,
+mtd_add_device will unlock the whole MTD device if it's writeable.  This
+means that non-writeable partitions will stay locked.
+
+Set MTD_STUPID_LOCK in fixup_use_atmel_lock() so that these chips will work
+as expected.
+
+Signed-off-by: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: David Woodhouse <dwmw2@infradead.org>
+---
+ drivers/mtd/chips/cfi_cmdset_0002.c |    1 +
+ drivers/mtd/mtdcore.c               |   10 ++++++++++
+ include/mtd/mtd-abi.h               |    1 +
+ 3 files changed, 12 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
+index a482e89..702ae4c 100644
+--- a/drivers/mtd/chips/cfi_cmdset_0002.c
++++ b/drivers/mtd/chips/cfi_cmdset_0002.c
+@@ -212,6 +212,7 @@ static void fixup_use_atmel_lock(struct mtd_info *mtd, void *param)
+ {
+       mtd->lock = cfi_atmel_lock;
+       mtd->unlock = cfi_atmel_unlock;
++      mtd->flags |= MTD_STUPID_LOCK;
+ }
+ static struct cfi_fixup cfi_fixup_table[] = {
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
+index 168d3ba..c4d26de 100644
+--- a/drivers/mtd/mtdcore.c
++++ b/drivers/mtd/mtdcore.c
+@@ -57,6 +57,16 @@ int add_mtd_device(struct mtd_info *mtd)
+                       mtd->index = i;
+                       mtd->usecount = 0;
++                      /* Some chips always power up locked. Unlock them now */
++                      if ((mtd->flags & MTD_WRITEABLE)
++                          && (mtd->flags & MTD_STUPID_LOCK) && mtd->unlock) {
++                              if (mtd->unlock(mtd, 0, mtd->size))
++                                      printk(KERN_WARNING
++                                             "%s: unlock failed, "
++                                             "writes may not work\n",
++                                             mtd->name);
++                      }
++
+                       DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name);
+                       /* No need to get a refcount on the module containing
+                          the notifier, since we hold the mtd_table_mutex */
+diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
+index 1da3f7f..b0a67b7 100644
+--- a/include/mtd/mtd-abi.h
++++ b/include/mtd/mtd-abi.h
+@@ -34,6 +34,7 @@ struct mtd_oob_buf {
+ #define MTD_WRITEABLE         0x400   /* Device is writeable */
+ #define MTD_BIT_WRITEABLE     0x800   /* Single bits can be flipped */
+ #define MTD_NO_ERASE          0x1000  /* No erase necessary */
++#define MTD_STUPID_LOCK               0x2000  /* Always locked after reset */
+ // Some common devices / combinations of capabilities
+ #define MTD_CAP_ROM           0
+-- 
+1.4.4.1
+
diff --git a/packages/linux/linux-2.6.18/ngw-fix-usart-initialization.patch b/packages/linux/linux-2.6.18/ngw-fix-usart-initialization.patch
new file mode 100644 (file)
index 0000000..702b9aa
--- /dev/null
@@ -0,0 +1,32 @@
+---
+ arch/avr32/boards/atngw/setup.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+Index: linux-2.6.18-avr32/arch/avr32/boards/atngw/setup.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/boards/atngw/setup.c    2006-11-02 14:22:05.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/boards/atngw/setup.c 2006-11-02 14:42:53.000000000 +0100
+@@ -50,18 +50,19 @@ static int __init parse_tag_ethernet(str
+ }
+ __tagtable(ATAG_ETHERNET, parse_tag_ethernet);
++struct platform_device *at32_usart_map[1];
++unsigned int at32_nr_usarts = 1;
++
+ void __init setup_board(void)
+ {
+-      at32_map_usart(1, 0);   /* /dev/ttyS0 */
+-
+-      at32_setup_serial_console(0);
++      at32_usart_map[0] = at32_get_usart(1);
+ }
+ static int __init atngw_init(void)
+ {
+       at32_add_system_devices();
+-      at32_add_device_usart(0);
++      at32_add_device_usart(1);
+       if (eth_data[0].valid)
+               at32_add_device_eth(0, &eth_data[0]);
diff --git a/packages/linux/linux-2.6.18/ngw100-change-spi-clock-on-dataflash.patch b/packages/linux/linux-2.6.18/ngw100-change-spi-clock-on-dataflash.patch
new file mode 100644 (file)
index 0000000..af1228f
--- /dev/null
@@ -0,0 +1,13 @@
+Index: linux-2.6.18/arch/avr32/boards/atngw/setup.c
+===================================================================
+--- linux-2.6.18.orig/arch/avr32/boards/atngw/setup.c  2006-12-19 14:15:02.000000000 +0100
++++ linux-2.6.18/arch/avr32/boards/atngw/setup.c       2006-12-19 14:15:11.000000000 +0100
+@@ -29,7 +29,7 @@
+       {
+               .modalias       = "mtd_dataflash",
+               .controller_data = (void *)GPIO_PIN_PA(3),
+-              .max_speed_hz   = 66000000,
++              .max_speed_hz   = 10000000,
+               .bus_num        = 0,
+               .chip_select    = 0,
+       },
diff --git a/packages/linux/linux-2.6.18/pio-deglitch.patch b/packages/linux/linux-2.6.18/pio-deglitch.patch
new file mode 100644 (file)
index 0000000..3fe9231
--- /dev/null
@@ -0,0 +1,40 @@
+---
+ arch/avr32/mach-at32ap/pio.c         |   12 ++++++++++++
+ include/asm-avr32/arch-at32ap/gpio.h |    1 +
+ 2 files changed, 13 insertions(+)
+
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/pio.c       2006-11-30 11:55:02.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c    2006-11-30 11:57:52.000000000 +0100
+@@ -122,6 +122,18 @@ fail:
+       dump_stack();
+ }
++void at32_set_deglitch(unsigned int pin, int enable)
++{
++      struct pio_device *pio;
++      u32 mask = 1 << (pin & 0x1f);
++
++      pio = gpio_to_pio(pin);
++      if (enable)
++              pio_writel(pio, IFER, mask);
++      else
++              pio_writel(pio, IFDR, mask);
++}
++
+ static unsigned int pio_id(struct pio_device *pio)
+ {
+       return pio - pio_dev;
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/gpio.h
+===================================================================
+--- linux-2.6.18-avr32.orig/include/asm-avr32/arch-at32ap/gpio.h       2006-11-30 11:54:56.000000000 +0100
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/gpio.h    2006-11-30 11:55:56.000000000 +0100
+@@ -16,6 +16,7 @@
+ void at32_select_periph(unsigned int pin, unsigned int periph,
+                       unsigned long flags);
+ void at32_select_gpio(unsigned int pin, unsigned long flags);
++void at32_set_deglitch(unsigned int pin, int enable);
+ /* Arch-neutral GPIO API */
+ int __must_check gpio_request(unsigned int gpio, const char *label);
diff --git a/packages/linux/linux-2.6.18/pio-interrupt-controller.patch b/packages/linux/linux-2.6.18/pio-interrupt-controller.patch
new file mode 100644 (file)
index 0000000..b4f15c4
--- /dev/null
@@ -0,0 +1,108 @@
+---
+ arch/avr32/mach-at32ap/pio.c |   73 ++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 72 insertions(+), 1 deletion(-)
+
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/pio.c       2006-11-29 18:17:15.000000000 +0100
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/pio.c    2006-11-30 11:50:27.000000000 +0100
+@@ -11,6 +11,7 @@
+ #include <linux/clk.h>
+ #include <linux/debugfs.h>
+ #include <linux/fs.h>
++#include <linux/irq.h>
+ #include <linux/platform_device.h>
+ #include <asm/gpio.h>
+@@ -709,20 +710,90 @@ err_class_create:
+ late_initcall(pio_init_dev);
+ #endif /* CONFIG_PIO_DEV */
++/* Interrupt controller implementation */
++static void pio_mask_irq(unsigned int irq)
++{
++      struct pio_device *pio = get_irq_chip_data(irq);
++
++      pio_writel(pio, IDR, 1 << (irq & 0x1f));
++}
++
++static void pio_unmask_irq(unsigned int irq)
++{
++      struct pio_device *pio = get_irq_chip_data(irq);
++
++      pio_writel(pio, IER, 1 << (irq & 0x1f));
++}
++
++static int pio_set_irq_type(unsigned int irq, unsigned int flow_type)
++{
++      if (flow_type != IRQ_TYPE_NONE && flow_type != IRQ_TYPE_EDGE_BOTH)
++              return -EINVAL;
++
++      return 0;
++}
++
++static struct irq_chip pio_irq_chip = {
++      .name           = "pio",
++      .mask           = pio_mask_irq,
++      .unmask         = pio_unmask_irq,
++      .set_type       = pio_set_irq_type,
++};
++
++static void demux_pio_irq(unsigned int irq, struct irq_desc *desc,
++                        struct pt_regs *regs)
++{
++      struct pio_device *pio = desc->handler_data;
++      struct irq_desc *ext_desc;
++      u32 status, pending;
++      unsigned int ext_irq;
++      unsigned int i;
++
++      status = pio_readl(pio, ISR);
++      pending = status & pio_readl(pio, IMR);
++
++      while (pending) {
++              i = fls(pending) - 1;
++              pending &= ~(1 << i);
++
++              ext_irq = gpio_to_irq(32 * pio_id(pio) + i);
++              ext_desc = irq_desc + ext_irq;
++              ext_desc->handle_irq(ext_irq, ext_desc, regs);
++      }
++}
++
+ static int __init pio_probe(struct platform_device *pdev)
+ {
+       struct pio_device *pio = NULL;
++      unsigned int i;
++      int int_irq, ext_irq;
+       BUG_ON(pdev->id >= MAX_NR_PIO_DEVICES);
+       pio = &pio_dev[pdev->id];
+       BUG_ON(!pio->regs);
+-      /* TODO: Interrupts */
++      /* Set up interrupts */
++      pio_writel(pio, IDR, ~0UL);
++      pio_readl(pio, ISR);
++
++      ext_irq = gpio_to_irq(32 * pdev->id);
++      for (i = 0; i < 32; i++, ext_irq++) {
++              set_irq_chip_and_handler(ext_irq, &pio_irq_chip,
++                                       handle_simple_irq);
++              set_irq_chip_data(ext_irq, pio);
++      }
++
++      int_irq = platform_get_irq(pdev, 0);
++      set_irq_chained_handler(int_irq, demux_pio_irq);
++      set_irq_data(int_irq, pio);
+       platform_set_drvdata(pdev, pio);
+       printk(KERN_INFO "%s: Atmel Port Multiplexer at 0x%p (irq %d)\n",
+              pio->name, pio->regs, platform_get_irq(pdev, 0));
++      printk(KERN_INFO
++             "%s: Handling 32 external IRQs, starting with IRQ %d\n",
++             pio->name, ext_irq - 32);
+       return 0;
+ }
diff --git a/packages/linux/linux-2.6.18/rename-ttyUS-to-ttyS-or-ttyAT.patch b/packages/linux/linux-2.6.18/rename-ttyUS-to-ttyS-or-ttyAT.patch
new file mode 100644 (file)
index 0000000..b2a020f
--- /dev/null
@@ -0,0 +1,74 @@
+---
+ drivers/serial/Kconfig       |   18 ++++++++++++++++++
+ drivers/serial/atmel_usart.c |   13 +++++++++++--
+ 2 files changed, 29 insertions(+), 2 deletions(-)
+
+Index: linux-2.6.18-avr32/drivers/serial/Kconfig
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/serial/Kconfig     2006-09-14 12:51:15.000000000 +0200
++++ linux-2.6.18-avr32/drivers/serial/Kconfig  2006-09-14 13:07:37.000000000 +0200
+@@ -267,6 +267,24 @@ config SERIAL_ATMEL_CONSOLE
+         receives all kernel messages and warnings and which allows
+         logins in single user mode).
++config SERIAL_ATMEL_TTYAT
++      bool "Install as device ttyAT0-N instead of ttyS0-N"
++      depends on SERIAL_ATMEL=y
++      help
++        Say Y here if you wish to have the internal UARTs appear as
++        /dev/ttyAT0-N (major 204, minor 154-169) instead of the
++        normal /dev/ttyS0-4 (major 4, minor 64-255). This is
++        necessary if you also want other UARTs, such as external
++        8250/16C550 compatible UARTs.
++
++        The ttySn nodes are legally reserved for the 8250 serial driver
++        but are often misused by other serial drivers.
++
++        To use this, you should create suitable ttyATn device nodes in
++        /dev/, and pass "console=ttyATn" to the kernel.
++
++        Say Y if you have an external 8250/16C550 UART.  If unsure, say N.
++
+ config SERIAL_AMBA_PL010
+       tristate "ARM AMBA PL010 serial port support"
+       depends on ARM_AMBA && (BROKEN || !ARCH_VERSATILE)
+Index: linux-2.6.18-avr32/drivers/serial/atmel_usart.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/serial/atmel_usart.c       2006-09-14 12:51:15.000000000 +0200
++++ linux-2.6.18-avr32/drivers/serial/atmel_usart.c    2006-09-14 12:51:16.000000000 +0200
+@@ -46,8 +46,17 @@
+  * Use the same major/minor numbers as the AT91 USART, which is
+  * actually the same chip
+  */
++
++#ifdef CONFIG_SERIAL_ATMEL_TTYAT
++#define SERIAL_USART3_MAJOR   204
++#define MINOR_START           154
++#define DEVICE_NAME           "ttyAT"
++#else
+ #define SERIAL_USART3_MAJOR   TTY_MAJOR
+ #define MINOR_START           64
++#define DEVICE_NAME           "ttyS"
++#endif
++
+ #define NR_PORTS              4
+ #define ERROR_FLAGS           (USART3_BIT(CSR_PARE)           \
+@@ -923,7 +932,7 @@ out_disable_clk:
+ static struct uart_driver usart3_reg;
+ static struct console usart3_console = {
+-      .name           = "ttyUS",
++      .name           = DEVICE_NAME,
+       .write          = usart3_console_write,
+       .device         = uart_console_device,
+       .setup          = usart3_console_setup,
+@@ -948,7 +957,7 @@ console_initcall(usart3_console_init);
+ static struct uart_driver usart3_reg = {
+       .owner          = THIS_MODULE,
+       .driver_name    = "serial",
+-      .dev_name       = "ttyUS",
++      .dev_name       = DEVICE_NAME,
+       .major          = SERIAL_USART3_MAJOR,
+       .minor          = MINOR_START,
+       .nr             = NR_PORTS,
diff --git a/packages/linux/linux-2.6.18/renumber-usart-devices.patch b/packages/linux/linux-2.6.18/renumber-usart-devices.patch
new file mode 100644 (file)
index 0000000..74f5991
--- /dev/null
@@ -0,0 +1,228 @@
+---
+ arch/avr32/boards/atstk1000/atstk1002.c |   12 ++++++++++++
+ arch/avr32/kernel/setup.c               |    1 +
+ arch/avr32/mach-at32ap/at32ap.c         |    3 ---
+ arch/avr32/mach-at32ap/at32ap7000.c     |   31 ++++++++++++++++++++++++-------
+ drivers/serial/atmel_usart.c            |   24 ++++++++++++++++++------
+ include/asm-avr32/arch-at32ap/board.h   |    7 ++++---
+ include/asm-avr32/arch-at32ap/init.h    |    3 +--
+ 7 files changed, 60 insertions(+), 21 deletions(-)
+
+Index: linux-2.6.18-avr32/arch/avr32/boards/atstk1000/atstk1002.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/boards/atstk1000/atstk1002.c    2006-09-13 14:30:31.000000000 +0200
++++ linux-2.6.18-avr32/arch/avr32/boards/atstk1000/atstk1002.c 2006-09-13 14:50:59.000000000 +0200
+@@ -14,6 +14,7 @@
+ #include <asm/setup.h>
+ #include <asm/arch/board.h>
++#include <asm/arch/init.h>
+ static struct eth_platform_data __initdata eth_data[2];
+@@ -34,6 +34,17 @@ struct platform_device flash_device = {
+ }
+ __tagtable(ATAG_ETHERNET, parse_tag_ethernet);
++struct platform_device *at32_usart_map[3];
++unsigned int at32_nr_usarts = 3;
++
++void __init setup_board(void)
++{
++      /* These need to be in place before initializing the console */
++      at32_usart_map[0] = at32_get_usart(1);
++      at32_usart_map[1] = at32_get_usart(2);
++      at32_usart_map[2] = at32_get_usart(3);
++}
++
+ static int __init atstk1002_init(void)
+ {
+       at32_add_system_devices();
+Index: linux-2.6.18-avr32/arch/avr32/kernel/setup.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/kernel/setup.c  2006-09-13 14:42:11.000000000 +0200
++++ linux-2.6.18-avr32/arch/avr32/kernel/setup.c       2006-09-13 14:43:36.000000000 +0200
+@@ -268,6 +268,7 @@ void __init setup_arch (char **cmdline_p
+       setup_processor();
+       setup_platform();
++      setup_board();
+       cpu_clk = clk_get(NULL, "cpu");
+       if (IS_ERR(cpu_clk)) {
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/at32ap.c    2006-09-13 14:38:24.000000000 +0200
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap.c 2006-09-13 14:38:28.000000000 +0200
+@@ -48,9 +48,6 @@ void __init setup_platform(void)
+       at32_sm_init();
+       at32_clock_init();
+       at32_portmux_init();
+-
+-      /* FIXME: This doesn't belong here */
+-      at32_setup_serial_console(1);
+ }
+ static int __init pdc_probe(struct platform_device *pdev)
+Index: linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap7000.c
+===================================================================
+--- linux-2.6.18-avr32.orig/arch/avr32/mach-at32ap/at32ap7000.c        2006-09-13 13:40:02.000000000 +0200
++++ linux-2.6.18-avr32/arch/avr32/mach-at32ap/at32ap7000.c     2006-09-13 14:39:08.000000000 +0200
+@@ -543,6 +543,30 @@ static struct resource usart3_resource[]
+ DEFINE_DEV(usart, 3);
+ DEV_CLK(usart, usart3, pba, 6);
++struct platform_device *at32_get_usart(unsigned int id)
++{
++      struct platform_device *pdev;
++
++      switch (id) {
++      case 0:
++              pdev = &usart0_device;
++              break;
++      case 1:
++              pdev = &usart1_device;
++              break;
++      case 2:
++              pdev = &usart2_device;
++              break;
++      case 3:
++              pdev = &usart3_device;
++              break;
++      default:
++              return NULL;
++      }
++
++      return pdev;
++}
++
+ static inline void configure_usart0_pins(void)
+ {
+       select_peripheral(PA(8), PERIPH_B, 0);  /* RXD  */
+@@ -607,13 +607,6 @@ struct platform_device *__init at32_add_
+       return pdev;
+ }
+-struct platform_device *at91_default_console_device;
+-
+-void __init at32_setup_serial_console(unsigned int usart_id)
+-{
+-      at91_default_console_device = setup_usart(usart_id);
+-}
+-
+ /* --------------------------------------------------------------------
+  *  Ethernet
+  * -------------------------------------------------------------------- */
+Index: linux-2.6.18-avr32/drivers/serial/atmel_usart.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/serial/atmel_usart.c       2006-09-13 14:30:42.000000000 +0200
++++ linux-2.6.18-avr32/drivers/serial/atmel_usart.c    2006-09-13 14:48:47.000000000 +0200
+@@ -773,7 +773,8 @@ static struct uart_ops usart3_pops = {
+ };
+ static int __devinit initialize_port(struct usart3_port *up,
+-                                    struct platform_device *pdev)
++                                   struct platform_device *pdev,
++                                   unsigned int line)
+ {
+       struct uart_port *port = &up->uart;
+       struct resource *regs;
+@@ -797,7 +798,7 @@ static int __devinit initialize_port(str
+       port->iotype = SERIAL_IO_MEM;
+       port->flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP;
+       port->ops = &usart3_pops;
+-      port->line = pdev->id;
++      port->line = line;
+       port->dev = &pdev->dev;
+       return 0;
+@@ -877,15 +878,17 @@ static int __init usart3_console_setup(s
+                      console->index);
+               return -ENODEV;
+       }
++      if (console->index >= at32_nr_usarts)
++              return -ENXIO;
+-      pdev = at91_default_console_device;
++      pdev = at32_usart_map[console->index];
+       if (!pdev)
+               return -ENXIO;
+       up = &usart3_ports[console->index];
+       port = &up->uart;
+-      ret = initialize_port(up, pdev);
++      ret = initialize_port(up, pdev, console->index);
+       if (ret)
+               return ret;
+@@ -978,6 +981,7 @@ static int usart3_serial_resume(struct p
+ static int __devinit usart3_serial_probe(struct platform_device *pdev)
+ {
+       struct usart3_port *up;
++      int line;
+       int ret;
+       if (pdev->id >= NR_PORTS) {
+@@ -987,14 +991,22 @@ static int __devinit usart3_serial_probe
+               return -ENOMEM;
+       }
+-      up = &usart3_ports[pdev->id];
++      for (line = 0; line < at32_nr_usarts; line++) {
++              if (at32_usart_map[line]->id == pdev->id)
++                      break;
++      }
++
++      if (line >= at32_nr_usarts)
++              return -ENXIO;
++
++      up = &usart3_ports[line];
+       /*
+        * If the port has already been set up as a console, we
+        * shouldn't enable it again.
+        */
+       if (!up->uart.uartclk) {
+-              ret = initialize_port(up, pdev);
++              ret = initialize_port(up, pdev, line);
+               if (ret)
+                       goto out;
+       }
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/board.h
+===================================================================
+--- linux-2.6.18-avr32.orig/include/asm-avr32/arch-at32ap/board.h      2006-09-13 14:30:13.000000000 +0200
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/board.h   2006-09-13 15:19:56.000000000 +0200
+@@ -9,11 +9,12 @@ struct flash_platform_data {
+ /* Add basic devices: system manager, interrupt controller, portmuxes, etc. */
+ void at32_add_system_devices(void);
+-#define AT91_NR_UART  4
+-extern struct platform_device *at91_default_console_device;
+-
++struct platform_device *at32_get_usart(unsigned int id);
+ struct platform_device *at32_add_device_usart(unsigned int id);
++extern struct platform_device *at32_usart_map[];
++extern unsigned int at32_nr_usarts;
++
+ struct eth_platform_data {
+       u8      valid;
+       u8      mii_phy_addr;
+Index: linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/init.h
+===================================================================
+--- linux-2.6.18-avr32.orig/include/asm-avr32/arch-at32ap/init.h       2006-09-13 13:43:20.000000000 +0200
++++ linux-2.6.18-avr32/include/asm-avr32/arch-at32ap/init.h    2006-09-13 14:50:26.000000000 +0200
+@@ -11,11 +11,10 @@
+ #define __ASM_AVR32_AT32AP_INIT_H__
+ 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__ */
diff --git a/packages/linux/linux-2.6.18/spi-fix-spi-busnum-to-master-buffer-and-bus_num-0.patch b/packages/linux/linux-2.6.18/spi-fix-spi-busnum-to-master-buffer-and-bus_num-0.patch
new file mode 100644 (file)
index 0000000..e5e040b
--- /dev/null
@@ -0,0 +1,50 @@
+From 4740d387f3cb9e63f48f2488815b38a2c92755c8 Mon Sep 17 00:00:00 2001
+From: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
+Date: Wed, 6 Dec 2006 20:36:17 -0800
+Subject: [PATCH] [PATCH] spi: correct bus_num and buffer bug in spi core
+
+Correct the following in driver/spi/spi.c in function spi_busnum_to_master:
+
+ * must allow bus_num 0, the if is really not needed.
+ * correct the name buffer which is too small for bus_num >= 10000. It
+
+should be 9 bytes big, not 8.
+
+Signed-off-by: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
+Cc: David Brownell <david-b@pacbell.net>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Linus Torvalds <torvalds@osdl.org>
+---
+ drivers/spi/spi.c |   16 +++++++---------
+ 1 files changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index 1a3c963..7d215ea 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -465,15 +465,13 @@ EXPORT_SYMBOL_GPL(spi_unregister_master);
+  */
+ struct spi_master *spi_busnum_to_master(u16 bus_num)
+ {
+-      if (bus_num) {
+-              char                    name[8];
+-              struct kobject          *bus;
+-
+-              snprintf(name, sizeof name, "spi%u", bus_num);
+-              bus = kset_find_obj(&spi_master_class.subsys.kset, name);
+-              if (bus)
+-                      return container_of(bus, struct spi_master, cdev.kobj);
+-      }
++      char                    name[9];
++      struct kobject          *bus;
++
++      snprintf(name, sizeof name, "spi%u", bus_num);
++      bus = kset_find_obj(&spi_master_class.subsys.kset, name);
++      if (bus)
++              return container_of(bus, struct spi_master, cdev.kobj);
+       return NULL;
+ }
+ EXPORT_SYMBOL_GPL(spi_busnum_to_master);
+-- 
+1.4.4.1
+
diff --git a/packages/linux/linux-2.6.18/spi-reduce-dlybs-and-dlybct.patch b/packages/linux/linux-2.6.18/spi-reduce-dlybs-and-dlybct.patch
new file mode 100644 (file)
index 0000000..ca4989f
--- /dev/null
@@ -0,0 +1,19 @@
+---
+ drivers/spi/atmel_spi.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+Index: linux-2.6.18-avr32/drivers/spi/atmel_spi.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/spi/atmel_spi.c    2006-12-18 12:31:32.000000000 +0100
++++ linux-2.6.18-avr32/drivers/spi/atmel_spi.c 2006-12-18 12:31:37.000000000 +0100
+@@ -380,8 +380,8 @@ static int atmel_spi_setup(struct spi_de
+               csr |= SPI_BIT(NCPHA);
+       /* TODO: DLYBS and DLYBCT */
+-      csr |= SPI_BF(DLYBS, 10);
+-      csr |= SPI_BF(DLYBCT, 10);
++      csr |= SPI_BF(DLYBS, 0);
++      csr |= SPI_BF(DLYBCT, 0);
+       npcs_pin = (unsigned int)spi->controller_data;
+       if (!spi->controller_state) {
diff --git a/packages/linux/linux-2.6.18/spi-set-kset-of-master-class-dev-explicitly.patch b/packages/linux/linux-2.6.18/spi-set-kset-of-master-class-dev-explicitly.patch
new file mode 100644 (file)
index 0000000..4a6ed65
--- /dev/null
@@ -0,0 +1,34 @@
+From 3bd0f6943520e459659d10f3282285e43d3990f1 Mon Sep 17 00:00:00 2001
+From: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
+Date: Wed, 6 Dec 2006 20:36:19 -0800
+Subject: [PATCH] [PATCH] spi: set kset of master class dev explicitly
+
+<quote Imre Deak from Thu, 12 Jan 2006 21:18:54 +0200>
+  In order for spi_busnum_to_master to work spi master devices must be linked
+  into the spi_master_class.subsys.kset list.  At the moment the default
+  class_obj_subsys.kset is used and we can't enumerate the master devices.
+</quote>
+
+Signed-off-by: Hans-Christian Egtvedt <hcegtvedt@atmel.com>
+Cc: David Brownell <david-b@pacbell.net>
+Signed-off-by: Andrew Morton <akpm@osdl.org>
+Signed-off-by: Linus Torvalds <torvalds@osdl.org>
+---
+ drivers/spi/spi.c |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index 7d215ea..270e621 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -366,6 +366,7 @@ spi_alloc_master(struct device *dev, unsigned size)
+       class_device_initialize(&master->cdev);
+       master->cdev.class = &spi_master_class;
++      kobj_set_kset_s(&master->cdev, spi_master_class.subsys);
+       master->cdev.dev = get_device(dev);
+       spi_master_set_devdata(master, &master[1]);
+-- 
+1.4.4.1
+
diff --git a/packages/linux/linux-2.6.18/update-atstk1002_defconfig.patch b/packages/linux/linux-2.6.18/update-atstk1002_defconfig.patch
new file mode 100644 (file)
index 0000000..fef3f8b
--- /dev/null
@@ -0,0 +1,563 @@
+---
+ arch/avr32/configs/atstk1002_defconfig |  293 ++++++++++++++++++++++++++++-----
+ 1 file changed, 250 insertions(+), 43 deletions(-)
+
+Index: linux-2.6.18/arch/avr32/configs/atstk1002_defconfig
+===================================================================
+--- linux-2.6.18.orig/arch/avr32/configs/atstk1002_defconfig   2007-01-11 14:30:26.000000000 +0100
++++ linux-2.6.18/arch/avr32/configs/atstk1002_defconfig        2007-01-11 15:44:49.000000000 +0100
+@@ -1,13 +1,14 @@
+ #
+ # Automatically generated make config: don't edit
+-# Linux kernel version: 2.6.18-rc1
+-# Tue Jul 11 12:41:36 2006
++# Linux kernel version: 2.6.18-at0
++# Thu Jan 11 15:37:42 2007
+ #
+ CONFIG_AVR32=y
+ CONFIG_GENERIC_HARDIRQS=y
+ CONFIG_HARDIRQS_SW_RESEND=y
+ CONFIG_GENERIC_IRQ_PROBE=y
+ CONFIG_RWSEM_GENERIC_SPINLOCK=y
++CONFIG_GENERIC_TIME=y
+ CONFIG_GENERIC_HWEIGHT=y
+ CONFIG_GENERIC_CALIBRATE_DELAY=y
+ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+@@ -25,16 +26,18 @@
+ CONFIG_LOCALVERSION=""
+ # CONFIG_LOCALVERSION_AUTO is not set
+ CONFIG_SWAP=y
+-# CONFIG_SYSVIPC is not set
+-# CONFIG_POSIX_MQUEUE is not set
+-# CONFIG_BSD_PROCESS_ACCT is not set
+-CONFIG_SYSCTL=y
++CONFIG_SYSVIPC=y
++CONFIG_POSIX_MQUEUE=y
++CONFIG_BSD_PROCESS_ACCT=y
++CONFIG_BSD_PROCESS_ACCT_V3=y
++# CONFIG_TASKSTATS is not set
+ # CONFIG_AUDIT is not set
+ # CONFIG_IKCONFIG is not set
+ # CONFIG_RELAY is not set
+ CONFIG_INITRAMFS_SOURCE=""
+ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+ CONFIG_EMBEDDED=y
++CONFIG_SYSCTL=y
+ CONFIG_KALLSYMS=y
+ # CONFIG_KALLSYMS_ALL is not set
+ # CONFIG_KALLSYMS_EXTRA_PASS is not set
+@@ -43,14 +46,15 @@
+ CONFIG_BUG=y
+ CONFIG_ELF_CORE=y
+ # CONFIG_BASE_FULL is not set
+-# CONFIG_FUTEX is not set
+-# CONFIG_EPOLL is not set
++CONFIG_FUTEX=y
++CONFIG_EPOLL=y
+ CONFIG_SHMEM=y
+-# CONFIG_SLAB is not set
+-# CONFIG_VM_EVENT_COUNTERS is not set
++CONFIG_SLAB=y
++CONFIG_VM_EVENT_COUNTERS=y
++CONFIG_RT_MUTEXES=y
+ # CONFIG_TINY_SHMEM is not set
+ CONFIG_BASE_SMALL=1
+-CONFIG_SLOB=y
++# CONFIG_SLOB is not set
+ #
+ # Loadable module support
+@@ -60,7 +64,7 @@
+ # 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_KMOD=y
+ #
+ # Block layer
+@@ -90,7 +94,13 @@
+ CONFIG_CPU_AT32AP7000=y
+ CONFIG_BOARD_ATSTK1002=y
+ CONFIG_BOARD_ATSTK1000=y
++# CONFIG_BOARD_ATNGW is not set
+ CONFIG_LOADER_U_BOOT=y
++
++#
++# Atmel AVR32 AP options
++#
++CONFIG_PIO_DEV=y
+ CONFIG_LOAD_ADDRESS=0x10000000
+ CONFIG_ENTRY_ADDRESS=0x90000000
+ CONFIG_PHYS_OFFSET=0x10000000
+@@ -113,6 +123,7 @@
+ CONFIG_SPLIT_PTLOCK_CPUS=4
+ # CONFIG_RESOURCES_64BIT is not set
+ # CONFIG_OWNERSHIP_TRACE is not set
++CONFIG_DW_DMAC=y
+ # CONFIG_HZ_100 is not set
+ CONFIG_HZ_250=y
+ # CONFIG_HZ_1000 is not set
+@@ -199,7 +210,6 @@
+ # CONFIG_ATALK is not set
+ # CONFIG_X25 is not set
+ # CONFIG_LAPB is not set
+-# CONFIG_NET_DIVERT is not set
+ # CONFIG_ECONET is not set
+ # CONFIG_WAN_ROUTER is not set
+@@ -212,7 +222,6 @@
+ # Network testing
+ #
+ # CONFIG_NET_PKTGEN is not set
+-# CONFIG_NET_TCPPROBE is not set
+ # CONFIG_HAMRADIO is not set
+ # CONFIG_IRDA is not set
+ # CONFIG_BT is not set
+@@ -239,7 +248,85 @@
+ #
+ # Memory Technology Devices (MTD)
+ #
+-# CONFIG_MTD 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_BLOCK=y
++# CONFIG_FTL is not set
++# CONFIG_NFTL is not set
++# CONFIG_INFTL is not set
++# CONFIG_RFD_FTL 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
++# CONFIG_MTD_OBSOLETE_CHIPS 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 is not set
++# 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
++
++#
++# NAND Flash Device Drivers
++#
++# CONFIG_MTD_NAND is not set
++
++#
++# OneNAND Flash Device Drivers
++#
++# CONFIG_MTD_ONENAND is not set
+ #
+ # Parallel port support
+@@ -260,6 +347,7 @@
+ 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_INITRD=y
+ # CONFIG_CDROM_PKTCDVD is not set
+ # CONFIG_ATA_OVER_ETH is not set
+@@ -343,7 +431,7 @@
+ CONFIG_PPP_DEFLATE=m
+ # CONFIG_PPP_BSDCOMP is not set
+ # CONFIG_PPP_MPPE is not set
+-# CONFIG_PPPOE is not set
++CONFIG_PPPOE=m
+ # CONFIG_SLIP is not set
+ # CONFIG_SHAPER is not set
+ # CONFIG_NETCONSOLE is not set
+@@ -363,7 +451,25 @@
+ #
+ # Input device support
+ #
+-# CONFIG_INPUT is not set
++CONFIG_INPUT=y
++
++#
++# Userland interfaces
++#
++# CONFIG_INPUT_MOUSEDEV is not set
++# 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 is not set
++# CONFIG_INPUT_MOUSE is not set
++# CONFIG_INPUT_JOYSTICK is not set
++# CONFIG_INPUT_TOUCHSCREEN is not set
++# CONFIG_INPUT_MISC is not set
+ #
+ # Hardware I/O ports
+@@ -374,7 +480,10 @@
+ #
+ # Character devices
+ #
+-# CONFIG_VT is not set
++CONFIG_VT=y
++CONFIG_VT_CONSOLE=y
++CONFIG_HW_CONSOLE=y
++# CONFIG_VT_HW_CONSOLE_BINDING is not set
+ # CONFIG_SERIAL_NONSTANDARD is not set
+ #
+@@ -385,9 +494,9 @@
+ #
+ # Non-8250 serial port support
+ #
+-CONFIG_SERIAL_AT91=y
+-CONFIG_SERIAL_AT91_CONSOLE=y
+-# CONFIG_SERIAL_AT91_TTYAT is not set
++CONFIG_SERIAL_ATMEL=y
++CONFIG_SERIAL_ATMEL_CONSOLE=y
++# CONFIG_SERIAL_ATMEL_TTYAT is not set
+ CONFIG_SERIAL_CORE=y
+ CONFIG_SERIAL_CORE_CONSOLE=y
+ CONFIG_UNIX98_PTYS=y
+@@ -422,7 +531,40 @@
+ #
+ # I2C support
+ #
+-# CONFIG_I2C is not set
++CONFIG_I2C=m
++CONFIG_I2C_CHARDEV=m
++
++#
++# I2C Algorithms
++#
++# CONFIG_I2C_ALGOBIT is not set
++# 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_OCORES is not set
++# CONFIG_I2C_PARPORT_LIGHT is not set
++# CONFIG_I2C_STUB is not set
++# CONFIG_I2C_PCA_ISA is not set
++
++#
++# Miscellaneous I2C Chip support
++#
++# CONFIG_SENSORS_DS1337 is not set
++# CONFIG_SENSORS_DS1374 is not set
++CONFIG_SENSORS_EEPROM=m
++# 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
+@@ -434,7 +576,7 @@
+ #
+ # SPI Master Controller Drivers
+ #
+-CONFIG_SPI_ATMEL=m
++CONFIG_SPI_ATMEL=y
+ # CONFIG_SPI_BITBANG is not set
+ #
+@@ -470,33 +612,85 @@
+ # Graphics support
+ #
+ # CONFIG_FIRMWARE_EDID is not set
+-CONFIG_FB=m
+-CONFIG_FB_CFB_FILLRECT=m
+-CONFIG_FB_CFB_COPYAREA=m
+-CONFIG_FB_CFB_IMAGEBLIT=m
++CONFIG_FB=y
++CONFIG_FB_CFB_FILLRECT=y
++CONFIG_FB_CFB_COPYAREA=y
++CONFIG_FB_CFB_IMAGEBLIT=y
+ # 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
+-CONFIG_FB_SIDSA=m
++CONFIG_FB_SIDSA=y
+ CONFIG_FB_SIDSA_DEFAULT_BPP=24
+ # CONFIG_FB_S1D13XXX is not set
+ # CONFIG_FB_VIRTUAL is not set
+ #
++# Console display driver support
++#
++# CONFIG_VGA_CONSOLE is not set
++CONFIG_DUMMY_CONSOLE=y
++# CONFIG_FRAMEBUFFER_CONSOLE is not set
++
++#
+ # Logo configuration
+ #
+ # CONFIG_LOGO is not set
+ CONFIG_BACKLIGHT_LCD_SUPPORT=y
+ # CONFIG_BACKLIGHT_CLASS_DEVICE is not set
+-CONFIG_LCD_CLASS_DEVICE=m
++CONFIG_LCD_CLASS_DEVICE=y
+ CONFIG_LCD_DEVICE=y
+-CONFIG_LCD_LTV350QV=m
++CONFIG_LCD_LTV350QV=y
+ #
+ # Sound
+ #
+-# CONFIG_SOUND is not set
++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_AC97_BUS=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
++
++#
++# ALSA AVR32 devices
++#
++CONFIG_SND_ATMEL_AC97=m
++# CONFIG_SND_ATMEL_AC97_USE_ALSA_MALLOC_CALLS is not set
++# CONFIG_SND_ATMEL_AC97C_USE_PDC is not set
++CONFIG_SND_AT73C213=m
++# CONFIG_SND_AT73C213_USE_ALSA_MALLOC_CALLS is not set
++
++#
++# Open Sound System
++#
++CONFIG_SOUND_PRIME=m
++# CONFIG_OSS_OBSOLETE_DRIVER is not set
++# CONFIG_SOUND_MSNDCLAS is not set
++# CONFIG_SOUND_MSNDPIN is not set
++CONFIG_SOUND_AT32_DAC=m
+ #
+ # USB support
+@@ -512,12 +706,34 @@
+ #
+ # USB Gadget Support
+ #
+-# CONFIG_USB_GADGET is not set
++CONFIG_USB_GADGET=m
++CONFIG_USB_GADGET_DEBUG_FILES=y
++CONFIG_USB_GADGET_SELECTED=y
++# 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_HUSB2DEV=y
++CONFIG_USB_HUSB2DEV=m
++# 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
+ #
+ # MMC/SD Card support
+ #
+-# CONFIG_MMC is not set
++CONFIG_MMC=y
++# CONFIG_MMC_DEBUG is not set
++CONFIG_MMC_BLOCK=y
++CONFIG_MMC_ATMELMCI=y
+ #
+ # LED devices
+@@ -570,14 +786,14 @@
+ # CONFIG_FS_POSIX_ACL is not set
+ # CONFIG_XFS_FS is not set
+ # CONFIG_OCFS2_FS is not set
+-CONFIG_MINIX_FS=m
+-CONFIG_ROMFS_FS=m
++# CONFIG_MINIX_FS is not set
++CONFIG_ROMFS_FS=y
+ # 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
++CONFIG_FUSE_FS=m
+ #
+ # CD-ROM/DVD Filesystems
+@@ -604,7 +820,7 @@
+ CONFIG_TMPFS=y
+ # CONFIG_HUGETLB_PAGE is not set
+ CONFIG_RAMFS=y
+-CONFIG_CONFIGFS_FS=m
++CONFIG_CONFIGFS_FS=y
+ #
+ # Miscellaneous filesystems
+@@ -616,6 +832,16 @@
+ # CONFIG_BEFS_FS is not set
+ # CONFIG_BFS_FS is not set
+ # CONFIG_EFS_FS is not set
++# CONFIG_JFFS_FS is not set
++CONFIG_JFFS2_FS=y
++CONFIG_JFFS2_FS_DEBUG=0
++CONFIG_JFFS2_FS_WRITEBUFFER=y
++# 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_RTIME=y
++# CONFIG_JFFS2_RUBIN is not set
+ # CONFIG_CRAMFS is not set
+ # CONFIG_VXFS_FS is not set
+ # CONFIG_HPFS_FS is not set
+@@ -639,7 +865,8 @@
+ CONFIG_SUNRPC=y
+ # CONFIG_RPCSEC_GSS_KRB5 is not set
+ # CONFIG_RPCSEC_GSS_SPKM3 is not set
+-# CONFIG_SMB_FS 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
+@@ -702,16 +929,24 @@
+ CONFIG_NLS_UTF8=m
+ #
++# Profiling support
++#
++# CONFIG_PROFILING is not set
++
++#
+ # Kernel hacking
+ #
+ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+-CONFIG_PRINTK_TIME=y
++# CONFIG_PRINTK_TIME is not set
+ CONFIG_MAGIC_SYSRQ=y
+ # CONFIG_UNUSED_SYMBOLS is not set
+ CONFIG_DEBUG_KERNEL=y
+ CONFIG_LOG_BUF_SHIFT=14
+ CONFIG_DETECT_SOFTLOCKUP=y
+ # CONFIG_SCHEDSTATS is not set
++# CONFIG_DEBUG_SLAB 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_RWSEMS is not set
+@@ -720,13 +955,13 @@
+ # CONFIG_DEBUG_KOBJECT is not set
+ CONFIG_DEBUG_BUGVERBOSE=y
+ # CONFIG_DEBUG_INFO is not set
+-CONFIG_DEBUG_FS=y
++# CONFIG_DEBUG_FS is not set
+ # CONFIG_DEBUG_VM is not set
+ CONFIG_FRAME_POINTER=y
+ # CONFIG_UNWIND_INFO is not set
+-CONFIG_FORCED_INLINING=y
++# CONFIG_FORCED_INLINING is not set
+ # CONFIG_RCU_TORTURE_TEST is not set
+-CONFIG_KPROBES=y
++# CONFIG_KPROBES is not set
+ #
+ # Security options
+@@ -748,7 +983,8 @@
+ #
+ CONFIG_CRC_CCITT=m
+ # CONFIG_CRC16 is not set
+-CONFIG_CRC32=m
++CONFIG_CRC32=y
+ # CONFIG_LIBCRC32C is not set
+-CONFIG_ZLIB_INFLATE=m
+-CONFIG_ZLIB_DEFLATE=m
++CONFIG_ZLIB_INFLATE=y
++CONFIG_ZLIB_DEFLATE=y
++CONFIG_PLIST=y
diff --git a/packages/linux/linux-2.6.18/usart-make-rx-timeout-baudrate-independent.patch b/packages/linux/linux-2.6.18/usart-make-rx-timeout-baudrate-independent.patch
new file mode 100644 (file)
index 0000000..9da0667
--- /dev/null
@@ -0,0 +1,83 @@
+---
+ drivers/serial/atmel_usart.c |   33 ++++++++++++++++++++++++++-------
+ 1 file changed, 26 insertions(+), 7 deletions(-)
+
+Index: linux-2.6.18-avr32/drivers/serial/atmel_usart.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/serial/atmel_usart.c       2006-12-18 14:59:00.000000000 +0100
++++ linux-2.6.18-avr32/drivers/serial/atmel_usart.c    2006-12-18 16:51:33.000000000 +0100
+@@ -76,6 +76,14 @@ struct usart3_port {
+       struct clk *mck;
+       unsigned long mapsize;
+       struct uart_port uart;
++
++      /*
++       * If no data is received within rx_timeout_us microseconds or
++       * rx_timeout_cycles cycles, whichever is longest, we get an
++       * interrupt.
++       */
++      unsigned int rx_timeout_us;
++      unsigned int rx_timeout_cycles;
+ };
+ #define to_usart3_port(port) container_of(port, struct usart3_port, uart)
+@@ -582,12 +590,6 @@ static int usart3_startup(struct uart_po
+       usart3_writel(up, TCR, 0);
+       up->tx_dma_head = port->info->xmit.tail;
+-      /*
+-       * Set a suitable timeout. 2000 bit periods corresponds to
+-       * about 17 ms at 115200 bps
+-       */
+-      usart3_writel(up, RTOR, 2000);
+-
+       /* Reset and enable receiver and transmitter */
+       usart3_writel(up, CR, (USART3_BIT(RSTRX)
+                                 | USART3_BIT(RSTTX)
+@@ -633,6 +635,7 @@ static void usart3_set_termios(struct ua
+       struct usart3_port *up = to_usart3_port(port);
+       unsigned int baud, quot, mode = 0;
+       unsigned int imr, flags;
++      unsigned long long timeout_cycles;
+       pr_debug("usart3: set_termios\n");
+@@ -692,6 +695,13 @@ static void usart3_set_termios(struct ua
+                                         | USART3_BIT(RSTRX)));
+       }
++      timeout_cycles = up->rx_timeout_us;
++      timeout_cycles *= baud;
++      do_div(timeout_cycles, 1000000);
++      if (timeout_cycles < up->rx_timeout_cycles)
++              timeout_cycles = up->rx_timeout_cycles;
++
++      pr_debug("usart3: Setting RTOR to %llu...\n", timeout_cycles);
+       pr_debug("usart3: Setting BRGR to %u (baud rate %u)...\n", quot, baud);
+       /* Disable receiver and transmitter */
+@@ -701,7 +711,12 @@ static void usart3_set_termios(struct ua
+       /* Set the parity, stop bits and data size */
+       usart3_writel(up, MR, mode);
+-      /* Set the baud rate and enable receiver and transmitter */
++      /*
++       * Set the baud rate and RX timeout, and enable receiver and
++       * transmitter.
++       */
++      usart3_writel(up, RTOR, timeout_cycles);
++
+       usart3_writel(up, BRGR, quot);
+       usart3_writel(up, CR, (USART3_BIT(TXEN)
+                                 | USART3_BIT(RXEN)));
+@@ -805,6 +820,10 @@ static int __devinit initialize_port(str
+               return PTR_ERR(up->mck);
+       clk_enable(up->mck);
++      /* Default RX timeout after 10 ms, but no less than 10 cycles */
++      up->rx_timeout_us = 10000;
++      up->rx_timeout_cycles = 10;
++
+       port->mapbase = regs->start;
+       up->mapsize = regs->end - regs->start + 1;
+       port->irq = platform_get_irq(pdev, 0);
diff --git a/packages/linux/linux-2.6.18/usb-ethernet-align-all-descriptors-on-a-word-boundary.patch b/packages/linux/linux-2.6.18/usb-ethernet-align-all-descriptors-on-a-word-boundary.patch
new file mode 100644 (file)
index 0000000..65aa9a4
--- /dev/null
@@ -0,0 +1,171 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Tue Feb 28 08:51:18 2006 +0100
+Subject: [PATCH] USB Ethernet: Align all descriptors on a word boundary
+
+Seems like gcc has problems with packed structs, so we'll just align
+them explicitly.
+
+---
+
+ drivers/usb/gadget/ether.c |   35 ++++++++++++++++++-----------------
+ 1 file changed, 18 insertions(+), 17 deletions(-)
+
+Index: linux-2.6.18-avr32/drivers/usb/gadget/ether.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/usb/gadget/ether.c 2006-09-11 14:36:02.000000000 +0200
++++ linux-2.6.18-avr32/drivers/usb/gadget/ether.c      2006-09-12 10:14:19.000000000 +0200
+@@ -428,7 +428,7 @@ static inline int BITRATE(struct usb_gad
+ #define DEV_RNDIS_CONFIG_VALUE        2       /* rndis; optional */
+ static struct usb_device_descriptor
+-device_desc = {
++device_desc __attribute__((aligned(2))) = {
+       .bLength =              sizeof device_desc,
+       .bDescriptorType =      USB_DT_DEVICE,
+@@ -454,7 +454,7 @@ otg_descriptor = {
+ };
+ static struct usb_config_descriptor
+-eth_config = {
++eth_config __attribute__((aligned(2))) = {
+       .bLength =              sizeof eth_config,
+       .bDescriptorType =      USB_DT_CONFIG,
+@@ -468,7 +468,7 @@ eth_config = {
+ #ifdef        CONFIG_USB_ETH_RNDIS
+ static struct usb_config_descriptor
+-rndis_config = {
++rndis_config __attribute__((aligned(2))) = {
+       .bLength =              sizeof rndis_config,
+       .bDescriptorType =      USB_DT_CONFIG,
+@@ -493,7 +493,7 @@ rndis_config = {
+ #ifdef        DEV_CONFIG_CDC
+ static struct usb_interface_descriptor
+-control_intf = {
++control_intf __attribute__((aligned(2))) = {
+       .bLength =              sizeof control_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -509,7 +509,7 @@ control_intf = {
+ #ifdef        CONFIG_USB_ETH_RNDIS
+ static const struct usb_interface_descriptor
+-rndis_control_intf = {
++rndis_control_intf __attribute__((aligned(2))) = {
+       .bLength =              sizeof rndis_control_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -524,7 +524,7 @@ rndis_control_intf = {
+ #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+-static const struct usb_cdc_header_desc header_desc = {
++static const struct usb_cdc_header_desc __attribute__((aligned(2))) header_desc = {
+       .bLength =              sizeof header_desc,
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
+@@ -566,7 +566,8 @@ static const struct usb_cdc_acm_descript
+ #ifdef        DEV_CONFIG_CDC
+-static const struct usb_cdc_ether_desc ether_desc = {
++static const struct usb_cdc_ether_desc
++ether_desc __attribute__((aligned(2))) = {
+       .bLength =              sizeof ether_desc,
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_ETHERNET_TYPE,
+@@ -601,7 +602,7 @@ static const struct usb_cdc_ether_desc e
+ #define STATUS_BYTECOUNT              16      /* 8 byte header + data */
+ static struct usb_endpoint_descriptor
+-fs_status_desc = {
++fs_status_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -632,7 +633,7 @@ data_nop_intf = {
+ /* ... but the "real" data interface has two bulk endpoints */
+ static const struct usb_interface_descriptor
+-data_intf = {
++data_intf __attribute__((aligned(2))) = {
+       .bLength =              sizeof data_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -652,7 +653,7 @@ data_intf = {
+ /* RNDIS doesn't activate by changing to the "real" altsetting */
+ static const struct usb_interface_descriptor
+-rndis_data_intf = {
++rndis_data_intf __attribute__((aligned(2))) = {
+       .bLength =              sizeof rndis_data_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -675,7 +676,7 @@ rndis_data_intf = {
+  */
+ static const struct usb_interface_descriptor
+-subset_data_intf = {
++subset_data_intf __attribute__((aligned(2))) = {
+       .bLength =              sizeof subset_data_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -692,7 +693,7 @@ subset_data_intf = {
+ static struct usb_endpoint_descriptor
+-fs_source_desc = {
++fs_source_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -701,7 +702,7 @@ fs_source_desc = {
+ };
+ static struct usb_endpoint_descriptor
+-fs_sink_desc = {
++fs_sink_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -767,7 +768,7 @@ static const struct usb_descriptor_heade
+ #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS)
+ static struct usb_endpoint_descriptor
+-hs_status_desc = {
++hs_status_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -778,7 +779,7 @@ hs_status_desc = {
+ #endif /* DEV_CONFIG_CDC */
+ static struct usb_endpoint_descriptor
+-hs_source_desc = {
++hs_source_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -787,7 +788,7 @@ hs_source_desc = {
+ };
+ static struct usb_endpoint_descriptor
+-hs_sink_desc = {
++hs_sink_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -796,7 +797,7 @@ hs_sink_desc = {
+ };
+ static struct usb_qualifier_descriptor
+-dev_qualifier = {
++dev_qualifier __attribute__((aligned(2))) = {
+       .bLength =              sizeof dev_qualifier,
+       .bDescriptorType =      USB_DT_DEVICE_QUALIFIER,
diff --git a/packages/linux/linux-2.6.18/usb-ethernet-define-cdc-capability-for-husb2.patch b/packages/linux/linux-2.6.18/usb-ethernet-define-cdc-capability-for-husb2.patch
new file mode 100644 (file)
index 0000000..1e3295e
--- /dev/null
@@ -0,0 +1,27 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Mon Feb 27 18:15:04 2006 +0100
+Subject: [PATCH] USB: Define CDC capability for HUSB2
+
+Define DEV_CONFIG_CDC when compiling for HUSB2DEV.
+
+---
+
+ drivers/usb/gadget/ether.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+Index: linux-2.6.18-avr32/drivers/usb/gadget/ether.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/usb/gadget/ether.c 2006-09-12 10:14:19.000000000 +0200
++++ linux-2.6.18-avr32/drivers/usb/gadget/ether.c      2006-09-12 10:14:40.000000000 +0200
+@@ -266,6 +266,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethern
+ #define DEV_CONFIG_CDC
+ #endif
++#ifdef CONFIG_USB_GADGET_HUSB2DEV
++#define DEV_CONFIG_CDC
++#endif
++
+ /* For CDC-incapable hardware, choose the simple cdc subset.
+  * Anything that talks bulk (without notable bugs) can do this.
diff --git a/packages/linux/linux-2.6.18/usb-file-storage-align-all-descriptors-on-a-word-boundary.patch b/packages/linux/linux-2.6.18/usb-file-storage-align-all-descriptors-on-a-word-boundary.patch
new file mode 100644 (file)
index 0000000..10778d5
--- /dev/null
@@ -0,0 +1,107 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Tue Feb 28 08:51:18 2006 +0100
+Subject: [PATCH] USB File Storage: Align all descriptors on a word boundary
+
+Seems like gcc has problems with packed structs, so we'll just align
+them explicitly.
+
+---
+
+ drivers/usb/gadget/file_storage.c |   20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+Index: linux-2.6.18-avr32/drivers/usb/gadget/file_storage.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/usb/gadget/file_storage.c  2006-09-11 14:36:02.000000000 +0200
++++ linux-2.6.18-avr32/drivers/usb/gadget/file_storage.c       2006-09-12 10:16:30.000000000 +0200
+@@ -853,7 +853,7 @@ static void inline put_be32(u8 *buf, u32
+ #define       CONFIG_VALUE            1
+ static struct usb_device_descriptor
+-device_desc = {
++device_desc __attribute__((aligned(2))) = {
+       .bLength =              sizeof device_desc,
+       .bDescriptorType =      USB_DT_DEVICE,
+@@ -872,7 +872,7 @@ device_desc = {
+ };
+ static struct usb_config_descriptor
+-config_desc = {
++config_desc __attribute__((aligned(2))) = {
+       .bLength =              sizeof config_desc,
+       .bDescriptorType =      USB_DT_CONFIG,
+@@ -895,7 +895,7 @@ otg_desc = {
+ /* There is only one interface. */
+ static struct usb_interface_descriptor
+-intf_desc = {
++intf_desc __attribute__((aligned(2))) = {
+       .bLength =              sizeof intf_desc,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -910,7 +910,7 @@ intf_desc = {
+  * and interrupt-in. */
+ static struct usb_endpoint_descriptor
+-fs_bulk_in_desc = {
++fs_bulk_in_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -920,7 +920,7 @@ fs_bulk_in_desc = {
+ };
+ static struct usb_endpoint_descriptor
+-fs_bulk_out_desc = {
++fs_bulk_out_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -930,7 +930,7 @@ fs_bulk_out_desc = {
+ };
+ static struct usb_endpoint_descriptor
+-fs_intr_in_desc = {
++fs_intr_in_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -962,7 +962,7 @@ static const struct usb_descriptor_heade
+  * for the config descriptor.
+  */
+ static struct usb_qualifier_descriptor
+-dev_qualifier = {
++dev_qualifier __attribute__((aligned(2))) = {
+       .bLength =              sizeof dev_qualifier,
+       .bDescriptorType =      USB_DT_DEVICE_QUALIFIER,
+@@ -973,7 +973,7 @@ dev_qualifier = {
+ };
+ static struct usb_endpoint_descriptor
+-hs_bulk_in_desc = {
++hs_bulk_in_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -983,7 +983,7 @@ hs_bulk_in_desc = {
+ };
+ static struct usb_endpoint_descriptor
+-hs_bulk_out_desc = {
++hs_bulk_out_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -994,7 +994,7 @@ hs_bulk_out_desc = {
+ };
+ static struct usb_endpoint_descriptor
+-hs_intr_in_desc = {
++hs_intr_in_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
diff --git a/packages/linux/linux-2.6.18/usb-serial-align-all-descriptors-on-a-word-boundary.patch b/packages/linux/linux-2.6.18/usb-serial-align-all-descriptors-on-a-word-boundary.patch
new file mode 100644 (file)
index 0000000..f78063c
--- /dev/null
@@ -0,0 +1,140 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Tue Feb 28 08:51:18 2006 +0100
+Subject: [PATCH] USB Serial: Align all descriptors on a word boundary
+
+Seems like gcc has problems with packed structs, so we'll just align
+them explicitly.
+
+---
+
+ drivers/usb/gadget/serial.c |   28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+Index: linux-2.6.18-avr32/drivers/usb/gadget/serial.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/usb/gadget/serial.c        2006-09-11 14:36:02.000000000 +0200
++++ linux-2.6.18-avr32/drivers/usb/gadget/serial.c     2006-09-12 10:17:52.000000000 +0200
+@@ -333,7 +333,7 @@ static struct usb_gadget_strings gs_stri
+       .strings =              gs_strings,
+ };
+-static struct usb_device_descriptor gs_device_desc = {
++static struct usb_device_descriptor __attribute__((aligned(2))) gs_device_desc = {
+       .bLength =              USB_DT_DEVICE_SIZE,
+       .bDescriptorType =      USB_DT_DEVICE,
+       .bcdUSB =               __constant_cpu_to_le16(0x0200),
+@@ -353,7 +353,7 @@ static struct usb_otg_descriptor gs_otg_
+       .bmAttributes =         USB_OTG_SRP,
+ };
+-static struct usb_config_descriptor gs_bulk_config_desc = {
++static struct usb_config_descriptor __attribute__((aligned(2))) gs_bulk_config_desc = {
+       .bLength =              USB_DT_CONFIG_SIZE,
+       .bDescriptorType =      USB_DT_CONFIG,
+       /* .wTotalLength computed dynamically */
+@@ -364,7 +364,7 @@ static struct usb_config_descriptor gs_b
+       .bMaxPower =            1,
+ };
+-static struct usb_config_descriptor gs_acm_config_desc = {
++static struct usb_config_descriptor __attribute__((aligned(2))) gs_acm_config_desc = {
+       .bLength =              USB_DT_CONFIG_SIZE,
+       .bDescriptorType =      USB_DT_CONFIG,
+       /* .wTotalLength computed dynamically */
+@@ -375,7 +375,7 @@ static struct usb_config_descriptor gs_a
+       .bMaxPower =            1,
+ };
+-static const struct usb_interface_descriptor gs_bulk_interface_desc = {
++static const struct usb_interface_descriptor __attribute__((aligned(2))) gs_bulk_interface_desc = {
+       .bLength =              USB_DT_INTERFACE_SIZE,
+       .bDescriptorType =      USB_DT_INTERFACE,
+       .bInterfaceNumber =     GS_BULK_INTERFACE_ID,
+@@ -386,7 +386,7 @@ static const struct usb_interface_descri
+       .iInterface =           GS_DATA_STR_ID,
+ };
+-static const struct usb_interface_descriptor gs_control_interface_desc = {
++static const struct usb_interface_descriptor __attribute__((aligned(2))) gs_control_interface_desc = {
+       .bLength =              USB_DT_INTERFACE_SIZE,
+       .bDescriptorType =      USB_DT_INTERFACE,
+       .bInterfaceNumber =     GS_CONTROL_INTERFACE_ID,
+@@ -397,7 +397,7 @@ static const struct usb_interface_descri
+       .iInterface =           GS_CONTROL_STR_ID,
+ };
+-static const struct usb_interface_descriptor gs_data_interface_desc = {
++static const struct usb_interface_descriptor __attribute__((aligned(2))) gs_data_interface_desc = {
+       .bLength =              USB_DT_INTERFACE_SIZE,
+       .bDescriptorType =      USB_DT_INTERFACE,
+       .bInterfaceNumber =     GS_DATA_INTERFACE_ID,
+@@ -408,7 +408,7 @@ static const struct usb_interface_descri
+       .iInterface =           GS_DATA_STR_ID,
+ };
+-static const struct usb_cdc_header_desc gs_header_desc = {
++static const struct usb_cdc_header_desc __attribute__((aligned(2))) gs_header_desc = {
+       .bLength =              sizeof(gs_header_desc),
+       .bDescriptorType =      USB_DT_CS_INTERFACE,
+       .bDescriptorSubType =   USB_CDC_HEADER_TYPE,
+@@ -438,7 +438,7 @@ static const struct usb_cdc_union_desc g
+       .bSlaveInterface0 =     1,      /* index of data interface */
+ };
+  
+-static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = {
++static struct usb_endpoint_descriptor __attribute__((aligned(2))) gs_fullspeed_notify_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_IN,
+@@ -447,14 +447,14 @@ static struct usb_endpoint_descriptor gs
+       .bInterval =            1 << GS_LOG2_NOTIFY_INTERVAL,
+ };
+-static struct usb_endpoint_descriptor gs_fullspeed_in_desc = {
++static struct usb_endpoint_descriptor __attribute__((aligned(2))) gs_fullspeed_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_IN,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+ };
+-static struct usb_endpoint_descriptor gs_fullspeed_out_desc = {
++static struct usb_endpoint_descriptor __attribute__((aligned(2))) gs_fullspeed_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_OUT,
+@@ -484,7 +484,7 @@ static const struct usb_descriptor_heade
+ };
+ #ifdef CONFIG_USB_GADGET_DUALSPEED
+-static struct usb_endpoint_descriptor gs_highspeed_notify_desc = {
++static struct usb_endpoint_descriptor __attribute__((aligned(2))) gs_highspeed_notify_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bEndpointAddress =     USB_DIR_IN,
+@@ -493,21 +493,21 @@ static struct usb_endpoint_descriptor gs
+       .bInterval =            GS_LOG2_NOTIFY_INTERVAL+4,
+ };
+-static struct usb_endpoint_descriptor gs_highspeed_in_desc = {
++static struct usb_endpoint_descriptor __attribute__((aligned(2))) gs_highspeed_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+ };
+-static struct usb_endpoint_descriptor gs_highspeed_out_desc = {
++static struct usb_endpoint_descriptor __attribute__((aligned(2))) gs_highspeed_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       __constant_cpu_to_le16(512),
+ };
+-static struct usb_qualifier_descriptor gs_qualifier_desc = {
++static struct usb_qualifier_descriptor __attribute__((aligned(2))) gs_qualifier_desc = {
+       .bLength =              sizeof(struct usb_qualifier_descriptor),
+       .bDescriptorType =      USB_DT_DEVICE_QUALIFIER,
+       .bcdUSB =               __constant_cpu_to_le16 (0x0200),
diff --git a/packages/linux/linux-2.6.18/usb-zero-align-all-descriptors-on-a-word-boundary.patch b/packages/linux/linux-2.6.18/usb-zero-align-all-descriptors-on-a-word-boundary.patch
new file mode 100644 (file)
index 0000000..e9143ee
--- /dev/null
@@ -0,0 +1,107 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Tue Feb 28 08:51:18 2006 +0100
+Subject: [PATCH] USB Zero: Align all descriptors on a word boundary
+
+Seems like gcc has problems with packed structs, so we'll just align
+them explicitly.
+
+---
+
+ drivers/usb/gadget/zero.c |   20 ++++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+Index: linux-2.6.18-avr32/drivers/usb/gadget/zero.c
+===================================================================
+--- linux-2.6.18-avr32.orig/drivers/usb/gadget/zero.c  2006-09-11 14:36:02.000000000 +0200
++++ linux-2.6.18-avr32/drivers/usb/gadget/zero.c       2006-09-12 10:19:02.000000000 +0200
+@@ -221,7 +221,7 @@ module_param (loopdefault, bool, S_IRUGO
+ #define       CONFIG_LOOPBACK         2
+ static struct usb_device_descriptor
+-device_desc = {
++device_desc __attribute__((aligned(2))) = {
+       .bLength =              sizeof device_desc,
+       .bDescriptorType =      USB_DT_DEVICE,
+@@ -237,7 +237,7 @@ device_desc = {
+ };
+ static struct usb_config_descriptor
+-source_sink_config = {
++source_sink_config __attribute__((aligned(2))) = {
+       .bLength =              sizeof source_sink_config,
+       .bDescriptorType =      USB_DT_CONFIG,
+@@ -250,7 +250,7 @@ source_sink_config = {
+ };
+ static struct usb_config_descriptor
+-loopback_config = {
++loopback_config __attribute__((aligned(2))) = {
+       .bLength =              sizeof loopback_config,
+       .bDescriptorType =      USB_DT_CONFIG,
+@@ -273,7 +273,7 @@ otg_descriptor = {
+ /* one interface in each configuration */
+ static const struct usb_interface_descriptor
+-source_sink_intf = {
++source_sink_intf __attribute__((aligned(2))) = {
+       .bLength =              sizeof source_sink_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -283,7 +283,7 @@ source_sink_intf = {
+ };
+ static const struct usb_interface_descriptor
+-loopback_intf = {
++loopback_intf __attribute__((aligned(2))) = {
+       .bLength =              sizeof loopback_intf,
+       .bDescriptorType =      USB_DT_INTERFACE,
+@@ -295,7 +295,7 @@ loopback_intf = {
+ /* two full speed bulk endpoints; their use is config-dependent */
+ static struct usb_endpoint_descriptor
+-fs_source_desc = {
++fs_source_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -304,7 +304,7 @@ fs_source_desc = {
+ };
+ static struct usb_endpoint_descriptor
+-fs_sink_desc = {
++fs_sink_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -340,7 +340,7 @@ static const struct usb_descriptor_heade
+  */
+ static struct usb_endpoint_descriptor
+-hs_source_desc = {
++hs_source_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -349,7 +349,7 @@ hs_source_desc = {
+ };
+ static struct usb_endpoint_descriptor
+-hs_sink_desc = {
++hs_sink_desc __attribute__((aligned(2))) = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+@@ -358,7 +358,7 @@ hs_sink_desc = {
+ };
+ static struct usb_qualifier_descriptor
+-dev_qualifier = {
++dev_qualifier __attribute__((aligned(2))) = {
+       .bLength =              sizeof dev_qualifier,
+       .bDescriptorType =      USB_DT_DEVICE_QUALIFIER,
diff --git a/packages/linux/linux/atngw100/.mtn2git_empty b/packages/linux/linux/atngw100/.mtn2git_empty
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/packages/linux/linux/atngw100/defconfig b/packages/linux/linux/atngw100/defconfig
new file mode 100644 (file)
index 0000000..290dce5
--- /dev/null
@@ -0,0 +1,849 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.21
+# Sat Jun  2 10:40:44 2007
+#
+CONFIG_AVR32=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_TIME=y
+# 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_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+
+#
+# General setup
+#
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+# CONFIG_IPC_NS is not set
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+# CONFIG_TASK_XACCT is not set
+# CONFIG_UTS_NS is not set
+CONFIG_AUDIT=y
+# CONFIG_IKCONFIG is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_RELAY=y
+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_BASE_FULL is not set
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SHMEM=y
+CONFIG_SLAB=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=1
+# CONFIG_SLOB is not set
+
+#
+# Loadable module support
+#
+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
+
+#
+# Block layer
+#
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_AS is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# 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"
+
+#
+# System Type and features
+#
+CONFIG_SUBARCH_AVR32B=y
+CONFIG_MMU=y
+CONFIG_PERFORMANCE_COUNTERS=y
+CONFIG_PLATFORM_AT32AP=y
+CONFIG_CPU_AT32AP7000=y
+CONFIG_BOARD_ATSTK1002=y
+CONFIG_BOARD_ATSTK1000=y
+CONFIG_LOADER_U_BOOT=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_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+# CONFIG_OWNERSHIP_TRACE is not set
+# 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_CMDLINE=""
+
+#
+# Bus options
+#
+
+#
+# PCCARD (PCMCIA/CardBus) support
+#
+# 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_NETDEBUG is not set
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY 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 is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+
+#
+# DCCP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_DCCP is not set
+
+#
+# SCTP Configuration (EXPERIMENTAL)
+#
+# CONFIG_IP_SCTP is not set
+
+#
+# TIPC Configuration (EXPERIMENTAL)
+#
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# 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
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_IEEE80211 is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+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
+
+#
+# Connector - unified userspace <-> kernelspace linker
+#
+# CONFIG_CONNECTOR is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+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
+
+#
+# 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
+# CONFIG_MTD_OBSOLETE_CHIPS 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_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
+
+#
+# NAND Flash Device Drivers
+#
+# CONFIG_MTD_NAND is not set
+
+#
+# OneNAND Flash Device Drivers
+#
+# CONFIG_MTD_ONENAND is not set
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Plug and Play support
+#
+# CONFIG_PNPACPI is not set
+
+#
+# Block devices
+#
+# 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_RAM_BLOCKSIZE=1024
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+
+#
+# Misc devices
+#
+
+#
+# ATA/ATAPI/MFM/RLL support
+#
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_NETLINK is not set
+
+#
+# Serial ATA (prod) and Parallel ATA (experimental) drivers
+#
+# CONFIG_ATA is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+
+#
+# Fusion MPT device support
+#
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# I2O device support
+#
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+
+#
+# PHY device support
+#
+# CONFIG_PHYLIB is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+CONFIG_MACB=y
+
+#
+# Ethernet (1000 Mbit)
+#
+
+#
+# Ethernet (10000 Mbit)
+#
+
+#
+# Token Ring devices
+#
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Wan interfaces
+#
+# 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_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
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Telephony Support
+#
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT 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_TTYAT is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_LEGACY_PTYS is not set
+
+#
+# IPMI
+#
+# CONFIG_IPMI_HANDLER is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+# CONFIG_SPI is not set
+# CONFIG_SPI_MASTER is not set
+
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
+#
+# Hardware Monitoring support
+#
+# CONFIG_HWMON is not set
+# CONFIG_HWMON_VID is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Digital Video Broadcasting Devices
+#
+# CONFIG_DVB is not set
+
+#
+# Graphics support
+#
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_FB is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# 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'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
+# InfiniBand support
+#
+
+#
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
+#
+
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
+# DMA Engine support
+#
+# CONFIG_DMA_ENGINE is not set
+
+#
+# DMA Clients
+#
+
+#
+# DMA Devices
+#
+
+#
+# Auxiliary Display support
+#
+
+#
+# Virtualization
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=m
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS 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_MINIX_FS=m
+# CONFIG_ROMFS_FS 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 is not set
+
+#
+# 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_RAMFS=y
+CONFIG_CONFIGFS_FS=m
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD 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
+# CONFIG_9P_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# Native Language Support
+#
+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
+
+#
+# Distributed Lock Manager
+#
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+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_LOG_BUF_SHIFT=14
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_SLAB 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_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_FRAME_POINTER=y
+CONFIG_FORCED_INLINING=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_KPROBES is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+
+#
+# Cryptographic options
+#
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC32=y
+# CONFIG_LIBCRC32C is not set
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
diff --git a/packages/linux/linux_2.6.18.bb b/packages/linux/linux_2.6.18.bb
new file mode 100644 (file)
index 0000000..91a89c3
--- /dev/null
@@ -0,0 +1,108 @@
+# Copyright (C) 2007, Stelios Koroneos - Digital OPSiS, All Rights Reserved
+# Released under the MIT license (see packages/COPYING)
+
+require linux.inc
+
+DEFAULT_PREFERENCE_avr32 = "1"
+
+PR = "r0"
+
+PARALLEL_MAKE=""
+
+SRC_URI = "${KERNELORG_MIRROR}/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2 \
+           file://defconfig \
+           " 
+
+SRC_URI_append_avr32 = " \
+           file://atmel-version.patch;patch=1 \
+           file://add-flush_buffer-operation-to-uart_ops.patch;patch=1 \
+           file://kbuild-add-unifdef.patch;patch=1 \
+           file://kbuild-replace-use-of-strlcpy-with-a-dedicated-implmentation-in-unifdef.patch;patch=1 \
+           file://kbuild-use-in-kernel-unifdef.patch;patch=1 \
+           file://spi-set-kset-of-master-class-dev-explicitly.patch;patch=1 \
+           file://spi-fix-spi-busnum-to-master-buffer-and-bus_num-0.patch;patch=1 \
+           file://usb-ethernet-align-all-descriptors-on-a-word-boundary.patch;patch=1 \
+           file://usb-ethernet-define-cdc-capability-for-husb2.patch;patch=1 \
+           file://usb-file-storage-align-all-descriptors-on-a-word-boundary.patch;patch=1 \
+           file://usb-serial-align-all-descriptors-on-a-word-boundary.patch;patch=1 \
+           file://usb-zero-align-all-descriptors-on-a-word-boundary.patch;patch=1 \
+           file://dont-include-map-h-from-physmap-h.patch;patch=1 \
+           file://mtd-unlock-nor-flash-automatically-where-necessary.patch;patch=1 \
+           file://avr32-arch.patch;patch=1 \
+           file://avr32-dont-include-asm-delay-h.patch;patch=1 \
+           file://avr32-unistd-h-move-ifdef-kernel.patch;patch=1 \
+           file://avr32-checkstack.patch;patch=1 \
+           file://avr32-oprofile.patch;patch=1 \
+           file://avr32-drop-GFP_COMP-for-DMA-memory-allocations.patch;patch=1 \
+           file://avr32-move-ethernet-tag-parsing-to-board-specific-code.patch;patch=1 \
+           file://avr32-dma-controller-framework.patch;patch=1 \
+           file://avr32-arch-neutral-gpio-api.patch;patch=1 \
+           file://add-mach-specific-kconfig.patch;patch=1 \
+           file://avr32-gpio-dev.patch;patch=1 \
+           file://atmel-usart3-driver.patch;patch=1 \
+           file://atmel-macb-ethernet-driver.patch;patch=1 \
+           file://at32ap7000-dmac-driver.patch;patch=1 \
+           file://atmel-mmc-host-driver.patch;patch=1 \
+           file://atmel-spi-master-driver.patch;patch=1 \
+           file://atmel-twi-driver.patch;patch=1 \
+           file://atmel-lcdc-framebuffer-driver.patch;patch=1 \
+           file://lcdc-wait-for-vsync.patch;patch=1 \
+           file://ltv350qv-lcd-driver.patch;patch=1 \
+           file://atmel-husb2-udc-driver.patch;patch=1 \
+           file://avr32-sound.patch;patch=1 \
+           file://atmel-ac97c-alsa-driver.patch;patch=1 \
+           file://at73c213-alsa-driver.patch;patch=1 \
+           file://at32-dac-oss-driver.patch;patch=1 \
+           file://renumber-usart-devices.patch;patch=1 \
+           file://rename-ttyUS-to-ttyS-or-ttyAT.patch;patch=1 \
+           file://at32-dac-oss-driver-clk-fix.patch;patch=1 \
+           file://add-all-parameters-to-smc-driver.patch;patch=1 \
+           file://at32ap7000-platform_device-definitions.patch;patch=1 \
+           file://atstk1000-instantiate-devices.patch;patch=1 \
+           file://add-hmatrix-support.patch;patch=1 \
+           file://add-ide-header.patch;patch=1 \
+           file://avr32-network-gateway-support.patch;patch=1 \
+           file://ngw-fix-usart-initialization.patch;patch=1 \
+           file://avr32-little-endian-read-write-bwl.patch;patch=1 \
+           file://gpio-dev-robustness.patch;patch=1 \
+           file://add-intc_pending_irq-to-intc.patch;patch=1 \
+           file://update-atstk1002_defconfig.patch;patch=1 \
+           file://fix-usart3-rx-BUG.patch;patch=1 \
+           file://fix-lcd-display-off-by-two-problem.patch;patch=1 \
+           file://fix-alpha-color-bitfield.patch;patch=1 \
+           file://jffs2_can_mark_obsolete-should-return-0-for-dataflash.patch;patch=1 \
+           file://mtd-fix-atmel-pri-for-cmdset-0001-and-cmdset-0002.patch;patch=1 \
+           file://fix-gpio-prototypes.patch;patch=1 \
+           file://pio-deglitch.patch;patch=1 \
+           file://pio-interrupt-controller.patch;patch=1 \
+           file://gpio-dev-blocking-read.patch;patch=1 \
+           file://add-default-atngw-defconfig.patch;patch=1 \
+           file://gpio-define-pio-none.patch;patch=1 \
+           file://mmc-add-platform-data.patch;patch=1 \
+           file://ngw100-change-spi-clock-on-dataflash.patch;patch=1 \
+           file://atstk1000-add-platform-data-for-mmc.patch;patch=1 \
+           file://avr32-increment-pointer-when-parsing-for-fbmem_start.patch;patch=1 \
+           file://lcdc-do-not-clear-mem-if-fbmem_start-is-set.patch;patch=1 \
+           file://avr32-fix-oprofile-interrupts.patch;patch=1 \
+           file://avr32-time-add-shared-interrupts.patch;patch=1 \
+           file://usart-make-rx-timeout-baudrate-independent.patch;patch=1 \
+           file://spi-reduce-dlybs-and-dlybct.patch;patch=1 \
+           file://dmac-stopping-idle-channel-is-not-fatal.patch;patch=1 \
+           file://mmc-core-dma-fix.patch;patch=1 \
+           file://atstk1000-board-fix-fbmem-setup.patch;patch=1 \
+           file://lcdc-fix-possible-null-pointer-and-match-guard-time-to-uboot.patch;patch=1 \
+           file://ltv350qv-add-initial_power_state-param.patch;patch=1 \
+           file://atmel-mci-debugfs.patch;patch=1 \
+           file://dmac-add-explicit-blockcount-to-dma_request_sg.patch;patch=1 \
+           file://atmel-mci-init-nr_blocks-in-dma-request.patch;patch=1 \
+           file://mmc-add-bit-manipulating-macros.patch;patch=1 \
+           file://mmc-add-detect-card-and-wp-support.patch;patch=1 \
+           file://atmel_spi-handle-rx-overrun.patch;patch=1 \
+           file://atmel_spi-send-zeroes-when-tx_buf-is-not-set.patch;patch=1 \
+           file://husb2_udc-test-mode.patch;patch=1 \
+           file://0001-AVR32-Fix-compile-error-with-gcc-4.1.patch;patch=1 \
+"
+
+
+S = "${WORKDIR}/linux-${PV}"
+
diff --git a/packages/mplayer/files/mplayer-1.0rc1-atmel.2.patch b/packages/mplayer/files/mplayer-1.0rc1-atmel.2.patch
new file mode 100644 (file)
index 0000000..800f43e
--- /dev/null
@@ -0,0 +1,6444 @@
+ cfg-common.h                     |    4 +
+ cfg-mencoder.h                   |    4 +
+ cfg-mplayer.h                    |    4 +
+ configure                        |   13 +-
+ libaf/af_format.c                |    7 +
+ libavcodec/Makefile              |    7 +
+ libavcodec/avr32/dsputil_avr32.c | 2678 ++++++++++++++++++++++++++++++++++++++
+ libavcodec/avr32/fdct.S          |  541 ++++++++
+ libavcodec/avr32/h264idct.S      |  451 +++++++
+ libavcodec/avr32/idct.S          |  829 ++++++++++++
+ libavcodec/avr32/mc.S            |  434 ++++++
+ libavcodec/avr32/pico.h          |  260 ++++
+ libavcodec/bitstream.h           |   77 +-
+ libavcodec/dsputil.c             |    3 +
+ libavcodec/h264.c                |   15 +
+ libavutil/common.h               |   16 +
+ libavutil/internal.h             |    9 +
+ libfaad2/common.h                |    2 +-
+ libmpcodecs/ad_libmad.c          |    5 +
+ libswscale/pico-avr32.h          |  137 ++
+ libswscale/swscale_internal.h    |    2 +-
+ libswscale/yuv2rgb.c             |   14 +
+ libswscale/yuv2rgb_avr32.c       |  416 ++++++
+ libvo/vo_fbdev2.c                |  101 ++-
+ version.sh                       |    2 +-
+ 25 files changed, 6011 insertions(+), 20 deletions(-)
+ create mode 100644 libavcodec/avr32/dsputil_avr32.c
+ create mode 100644 libavcodec/avr32/fdct.S
+ create mode 100644 libavcodec/avr32/h264idct.S
+ create mode 100644 libavcodec/avr32/idct.S
+ create mode 100644 libavcodec/avr32/mc.S
+ create mode 100644 libavcodec/avr32/pico.h
+ create mode 100644 libswscale/pico-avr32.h
+ create mode 100644 libswscale/yuv2rgb_avr32.c
+
+diff --git a/cfg-common.h b/cfg-common.h
+index 780df38..7d878a8 100644
+--- a/cfg-common.h
++++ b/cfg-common.h
+@@ -235,6 +235,10 @@
+       {"tsprobe", &ts_probe, CONF_TYPE_POSITION, 0, 0, TS_MAX_PROBE_SIZE, NULL},
+       {"tskeepbroken", &ts_keep_broken, CONF_TYPE_FLAG, 0, 0, 1, NULL},
++#ifdef ARCH_AVR32
++        {"use-pico", &avr32_use_pico, CONF_TYPE_FLAG, 0, 0, 1, NULL},
++        {"nouse-pico", &avr32_use_pico, CONF_TYPE_FLAG, 0, 1, 0, NULL},
++#endif
+       // draw by slices or whole frame (useful with libmpeg2/libavcodec)
+       {"slices", &vd_use_slices, CONF_TYPE_FLAG, 0, 0, 1, NULL},
+       {"noslices", &vd_use_slices, CONF_TYPE_FLAG, 0, 1, 0, NULL},
+diff --git a/cfg-mencoder.h b/cfg-mencoder.h
+index 411b748..addf791 100644
+--- a/cfg-mencoder.h
++++ b/cfg-mencoder.h
+@@ -5,6 +5,10 @@
+ #include "cfg-common.h"
++#ifdef ARCH_AVR32
++extern int avr32_use_pico;
++#endif
++
+ #ifdef USE_FAKE_MONO
+ extern int fakemono; // defined in dec_audio.c
+ #endif
+diff --git a/cfg-mplayer.h b/cfg-mplayer.h
+index 62b6eac..31499c2 100644
+--- a/cfg-mplayer.h
++++ b/cfg-mplayer.h
+@@ -4,6 +4,10 @@
+ #include "cfg-common.h"
++#ifdef ARCH_AVR32
++extern int avr32_use_pico;
++#endif
++
+ extern int noconsolecontrols;
+ #if defined(HAVE_FBDEV)||defined(HAVE_VESA)
+diff --git a/configure b/configure
+index 29002c8..56c6fe4 100755
+--- a/configure
++++ b/configure
+@@ -1203,6 +1203,15 @@ EOF
+     _optimizing="$proc"
+     ;;
++  avr32)
++    _def_arch='#define ARCH_AVR32'
++    _target_arch='TARGET_ARCH_AVR32 = yes'
++    iproc='avr32'
++    proc=''
++    _march=''
++    _mcpu=''
++    _optimizing=''
++    ;;
+   arm|armv4l|armv5tel)
+     _def_arch='#define ARCH_ARMV4L 1'
+     _target_arch='TARGET_ARCH_ARMV4L = yes'
+@@ -1533,7 +1542,7 @@ echores $_named_asm_args
+ # Checking for CFLAGS
+ _stripbinaries=yes
+ if test "$_profile" != "" || test "$_debug" != "" ; then
+-  CFLAGS="-W -Wall -O2 $_march $_mcpu $_debug $_profile"
++  CFLAGS="-W -Wall -O4 $_march $_mcpu $_debug $_profile"
+   if test "$_cc_major" -ge "3" ; then
+     CFLAGS=`echo "$CFLAGS" | sed -e 's/\(-Wall\)/\1 -Wno-unused-parameter/'`
+   fi
+@@ -3794,7 +3803,7 @@ fi
+ echocheck "X11 headers presence"
+-  for I in `echo $_inc_extra | sed s/-I//g` /usr/X11/include /usr/X11R6/include /usr/include/X11R6 /usr/include /usr/openwin/include ; do
++  for I in `echo $_inc_extra | sed s/-I//g`; do
+     if test -f "$I/X11/Xlib.h" ; then
+       _inc_x11="-I$I"
+       _x11_headers="yes"
+diff --git a/libaf/af_format.c b/libaf/af_format.c
+index e5b7cc9..5d7ea6d 100644
+--- a/libaf/af_format.c
++++ b/libaf/af_format.c
+@@ -20,7 +20,14 @@
+ // Integer to float conversion through lrintf()
+ #ifdef HAVE_LRINTF
+ #include <math.h>
++
++#ifdef ARCH_AVR32
++#define lrintf(x) rint(x)
++#define llrint(x) (long long)rint(x) 
++#else
+ long int lrintf(float);
++#endif
++
+ #else
+ #define lrintf(x) ((int)(x))
+ #endif
+diff --git a/libavcodec/Makefile b/libavcodec/Makefile
+index 17b6c45..8e1dc96 100644
+--- a/libavcodec/Makefile
++++ b/libavcodec/Makefile
+@@ -360,6 +360,12 @@ OBJS-$(TARGET_ARCH_SPARC)              += sparc/dsputil_vis.o \
+ sparc/dsputil_vis.o: CFLAGS += -mcpu=ultrasparc -mtune=ultrasparc
++# avr32 specific stuff
++ifeq ($(TARGET_ARCH_AVR32),yes)
++ASM_OBJS += avr32/idct.o avr32/fdct.o avr32/mc.o avr32/h264idct.o
++OBJS += avr32/dsputil_avr32.o
++endif
++
+ # sun mediaLib specific stuff
+ OBJS-$(HAVE_MLIB)                      += mlib/dsputil_mlib.o \
+@@ -419,6 +425,7 @@ tests: apiexample $(TESTS)
+ clean::
+       rm -f \
+          i386/*.o i386/*~ \
++         avr32/*.o avr32/*~ \
+          armv4l/*.o armv4l/*~ \
+          mlib/*.o mlib/*~ \
+          alpha/*.o alpha/*~ \
+diff --git a/libavcodec/avr32/dsputil_avr32.c b/libavcodec/avr32/dsputil_avr32.c
+new file mode 100644
+index 0000000..200284d
+--- /dev/null
++++ b/libavcodec/avr32/dsputil_avr32.c
+@@ -0,0 +1,2678 @@
++/*
++ * Copyright (c) 2007 Atmel Corporation. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials provided
++ * with the distribution.
++ *
++ * 3. The name of ATMEL may not be used to endorse or promote products
++ * derived from this software without specific prior written
++ * permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL
++ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
++ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
++ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
++ * DAMAGE.
++ */
++
++#include "../dsputil.h"
++#include "pico.h"
++
++int avr32_use_pico = 1;
++
++//#define CHECK_DSP_FUNCS_AGAINST_C
++
++#ifdef CHECK_DSP_FUNCS_AGAINST_C
++#define DSP_FUNC_NAME(name) test_ ## name
++#else
++#define DSP_FUNC_NAME(name) name
++#endif
++
++union doubleword {
++  int64_t doubleword;
++  struct {
++    int32_t top;
++    int32_t bottom;
++  } words; 
++};
++
++#undef  LD16
++#undef  LD32
++#undef  LD64
++  
++#define LD16(a) (*((uint16_t*)(a)))
++#define LD32(a) (*((uint32_t*)(a)))
++#define LD64(a) (*((uint64_t*)(a)))
++#define LD64_UNALIGNED(a) \
++  ({ union doubleword __tmp__; \
++   __tmp__.words.top = LD32(a); \
++   __tmp__.words.bottom = LD32(a + 4); \
++   __tmp__.doubleword; }) 
++
++#undef  ST32
++#undef  ST16
++
++#define ST16(a, b) *((uint16_t*)(a)) = (b)
++#define ST32(a, b) *((uint32_t*)(a)) = (b)
++
++#undef rnd_avg32
++#define rnd_avg32(a, b) \
++  ({ uint32_t __tmp__;\
++     asm("pavg.ub\t%0, %1, %2" : "=r"(__tmp__) : "r"(a), "r"(b));\
++     __tmp__;})
++
++void idct_avr32(DCTELEM *data);
++void fdct_avr32(DCTELEM *data);
++
++void idct_put_avr32(uint8_t *dest, int line_size, DCTELEM *data);
++void idct_add_avr32(uint8_t *dest, int line_size, DCTELEM *data);
++
++void h264_idct_add_avr32(uint8_t *dest, DCTELEM *data, int stride);
++void h264_idct8_add_avr32(uint8_t *dest, DCTELEM *data, int stride);
++
++#define extern_dspfunc(PFX, NUM) \
++    void PFX ## _pixels ## NUM ## _avr32(uint8_t *dst, const uint8_t *pixels, int line_size, int h );     \
++    void PFX ## _pixels ## NUM ## _h_avr32(uint8_t *dst, const uint8_t *pixels, int line_size, int h );  \
++    void PFX ## _pixels ## NUM ## _v_avr32(uint8_t *dst, const uint8_t *pixels, int line_size, int h );  \
++    void PFX ## _pixels ## NUM ## _hv_avr32(uint8_t *dst, const uint8_t *pixels, int line_size, int h )
++
++extern_dspfunc(put, 8);
++extern_dspfunc(put_no_rnd, 8);
++extern_dspfunc(avg, 8);
++extern_dspfunc(avg_no_rnd, 8);
++#undef extern_dspfunc
++
++#ifdef CHECK_DSP_FUNCS_AGAINST_C
++#define extern_dspfunc(PFX, NUM)                                        \
++  void PFX ## _pixels ## NUM ## _c(uint8_t *dst, const uint8_t *pixels, int line_size, int h ); \
++  void PFX ## _pixels ## NUM ## _x2_c(uint8_t *dst, const uint8_t *pixels, int line_size, int h ); \
++  void PFX ## _pixels ## NUM ## _y2_c(uint8_t *dst, const uint8_t *pixels, int line_size, int h ); \
++  void PFX ## _pixels ## NUM ## _xy2_c(uint8_t *dst, const uint8_t *pixels, int line_size, int h )
++
++extern_dspfunc(put, 4);
++extern_dspfunc(put_no_rnd, 4);
++extern_dspfunc(put, 8);
++extern_dspfunc(put_no_rnd, 8);
++extern_dspfunc(put, 16);
++extern_dspfunc(put_no_rnd, 16);
++extern_dspfunc(avg, 8);
++extern_dspfunc(avg_no_rnd, 8);
++extern_dspfunc(avg, 16);
++extern_dspfunc(avg_no_rnd, 16);
++
++
++#undef extern_dspfunc
++#define extern_dspfunc(PFX, NUM) \
++void PFX ## NUM ## _mc00_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc10_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc20_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc30_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc01_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc11_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc21_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc31_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc02_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc12_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc22_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc32_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc03_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc13_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc23_c(uint8_t *dst, uint8_t *src, int stride);  \
++void PFX ## NUM ## _mc33_c(uint8_t *dst, uint8_t *src, int stride);  \
++
++extern_dspfunc(put_h264_qpel,  16);
++extern_dspfunc(put_h264_qpel,  8);
++extern_dspfunc(put_h264_qpel,  4);
++extern_dspfunc(avg_h264_qpel,  16);
++extern_dspfunc(avg_h264_qpel,  8);
++extern_dspfunc(avg_h264_qpel,  4);
++
++#undef extern_dspfunc
++
++void put_h264_chroma_mc2_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y);
++void put_h264_chroma_mc4_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y);
++void put_h264_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y);
++                         
++void avg_h264_chroma_mc2_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y);
++void avg_h264_chroma_mc4_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y);
++void avg_h264_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y);
++
++
++void dump_block8(uint8_t *block, int line_size, int h);
++void dump_block4(uint8_t *block, int line_size, int h);
++void dump_block(uint8_t *block, int line_size, int h, int w);
++
++void check_block8(uint8_t *test, uint8_t *correct, int line_size_test, int line_size_correct, 
++                  int h, char *name, int max_dev);
++void check_block4(uint8_t *test, uint8_t *correct, int line_size_test, int line_size_correct, 
++                  int h, char *name, int max_dev);
++void check_block(uint8_t *test, uint8_t *correct, int line_size_test, int line_size_correct, 
++                 int h, int width, char *name, int max_dev);
++
++#define PIXOP2( OPNAME, OP ) \
++void OPNAME ## _pixels4_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
++    int i;\
++    for(i=0; i<h; i++){\
++        OP(*((uint32_t*)(block  )), LD32(pixels  ));\
++        pixels+=line_size;\
++        block +=line_size;\
++    }\
++}\
++void OPNAME ## _pixels8_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
++                                                int src_stride1, int src_stride2, int h){\
++    int i;\
++    for(i=0; i<h; i++){\
++        uint32_t a,b;\
++        a= LD32(&src1[i*src_stride1  ]);\
++        b= LD32(&src2[i*src_stride2  ]);\
++        OP(*((uint32_t*)&dst[i*dst_stride  ]), rnd_avg32(a, b));\
++        a= LD32(&src1[i*src_stride1+4]);\
++        b= LD32(&src2[i*src_stride2+4]);\
++        OP(*((uint32_t*)&dst[i*dst_stride+4]), rnd_avg32(a, b));\
++    }\
++}\
++\
++void OPNAME ## _pixels4_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
++                                                int src_stride1, int src_stride2, int h){\
++    int i;\
++    for(i=0; i<h; i++){\
++        uint32_t a,b;\
++        a= LD32(&src1[i*src_stride1  ]);\
++        b= LD32(&src2[i*src_stride2  ]);\
++        OP(*((uint32_t*)&dst[i*dst_stride  ]), rnd_avg32(a, b));\
++    }\
++}\
++\
++void OPNAME ## _pixels16_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
++                                                int src_stride1, int src_stride2, int h){\
++    OPNAME ## _pixels8_l2(dst  , src1  , src2  , dst_stride, src_stride1, src_stride2, h);\
++    OPNAME ## _pixels8_l2(dst+8, src1+8, src2+8, dst_stride, src_stride1, src_stride2, h);\
++}\
++
++#else
++#define PIXOP2( OPNAME, OP ) \
++static void OPNAME ## _pixels4_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
++    int i;\
++    for(i=0; i<h; i++){\
++        OP(*((uint32_t*)(block  )), LD32(pixels  ));\
++        pixels+=line_size;\
++        block +=line_size;\
++    }\
++}\
++static void OPNAME ## _pixels8_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
++    int i;\
++    for(i=0; i<h; i++){\
++        OP(*((uint32_t*)(block  )), LD32(pixels  ));\
++        OP(*((uint32_t*)(block+4)), LD32(pixels+4));\
++        pixels+=line_size;\
++        block +=line_size;\
++    }\
++}\
++static void OPNAME ## _pixels16_c(uint8_t *block, const uint8_t *pixels, int line_size, int h){\
++    int i;\
++    for(i=0; i<h; i++){\
++        OP(*((uint32_t*)(block  )), LD32(pixels  ));\
++        OP(*((uint32_t*)(block+4)), LD32(pixels+4));\
++        OP(*((uint32_t*)(block+8)), LD32(pixels+8));\
++        OP(*((uint32_t*)(block+12)), LD32(pixels+12));\
++        pixels+=line_size;\
++        block +=line_size;\
++    }\
++}\
++static void OPNAME ## _pixels8_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
++                                                int src_stride1, int src_stride2, int h){\
++    int i;\
++    for(i=0; i<h; i++){\
++        uint32_t a,b;\
++        a= LD32(&src1[i*src_stride1  ]);\
++        b= LD32(&src2[i*src_stride2  ]);\
++        OP(*((uint32_t*)&dst[i*dst_stride  ]), rnd_avg32(a, b));\
++        a= LD32(&src1[i*src_stride1+4]);\
++        b= LD32(&src2[i*src_stride2+4]);\
++        OP(*((uint32_t*)&dst[i*dst_stride+4]), rnd_avg32(a, b));\
++    }\
++}\
++\
++static void OPNAME ## _pixels4_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
++                                                int src_stride1, int src_stride2, int h){\
++    int i;\
++    for(i=0; i<h; i++){\
++        uint32_t a,b;\
++        a= LD32(&src1[i*src_stride1  ]);\
++        b= LD32(&src2[i*src_stride2  ]);\
++        OP(*((uint32_t*)&dst[i*dst_stride  ]), rnd_avg32(a, b));\
++    }\
++}\
++\
++static void OPNAME ## _pixels16_l2(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int dst_stride, \
++                                                int src_stride1, int src_stride2, int h){\
++    OPNAME ## _pixels8_l2(dst  , src1  , src2  , dst_stride, src_stride1, src_stride2, h);\
++    OPNAME ## _pixels8_l2(dst+8, src1+8, src2+8, dst_stride, src_stride1, src_stride2, h);\
++}\
++
++#endif
++
++#define op_avg(a, b) a = rnd_avg32(a, b)
++#define op_put(a, b) a = b
++
++PIXOP2(avg, op_avg)
++PIXOP2(put, op_put)
++#undef op_avg
++#undef op_put
++
++
++
++static inline void copy_block4(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h)
++{
++  int i;
++  for(i=0; i<h; i++)
++    {
++      ST32(dst   , LD32(src   ));
++      dst+=dstStride;
++      src+=srcStride;
++    }
++}
++
++static void clear_blocks_avr32(DCTELEM *blocks)
++{
++  int n = 12;
++  uint64_t tmp1, tmp2;
++  blocks += 6*64;  
++  asm volatile ( "mov\t%1, 0\n" 
++                 "mov\t%m1, 0\n" 
++                 "mov\t%2, 0\n" 
++                 "mov\t%m2, 0\n" 
++                 "0:\n" 
++                 "stm\t--%3, %1, %m1, %2, %m2\n"
++                 "stm\t--%3, %1, %m1, %2, %m2\n"
++                 "stm\t--%3, %1, %m1, %2, %m2\n"
++                 "stm\t--%3, %1, %m1, %2, %m2\n"        
++                 "sub\t%0, 1\n"        
++                 "brne\t0b\n"        
++                 : "+r"(n), "=&r"(tmp1), "=&r"(tmp2), 
++                 "+r"(blocks));
++}
++
++
++static inline void copy_block8(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h)
++{
++  int i;
++  for(i=0; i<h; i++)
++    {
++      ST32(dst   , LD32(src   ));
++      ST32(dst+4 , LD32(src+4 ));
++      dst+=dstStride;
++      src+=srcStride;
++    }
++}
++
++static inline void copy_block16(uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int h)
++{
++  int i;
++  for(i=0; i<h; i++)
++    {
++      ST32(dst   , LD32(src   ));
++      ST32(dst+4 , LD32(src+4 ));
++      ST32(dst+8 , LD32(src+8 ));
++      ST32(dst+12, LD32(src+12));
++      dst+=dstStride;
++      src+=srcStride;
++    }
++}
++
++
++static void put_h264_chroma_mc2_pico(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){
++  const int A=(8-x)*(8-y);
++  const int B=(  x)*(8-y);
++  const int C=(8-x)*(  y);
++  const int D=(  x)*(  y);
++  int i;
++  
++  PICO_PUT_W(PICO_COEFF0_A, (A << 16) | (B & 0xFFFF));
++  PICO_PUT_W(PICO_COEFF0_B, 32);
++  PICO_PUT_W(PICO_COEFF1_A, (C << 16) | (D & 0xFFFF));
++  PICO_PUT_W(PICO_COEFF1_B, 0);
++  PICO_PUT_W(PICO_COEFF2_A, 0);
++  PICO_PUT_W(PICO_COEFF2_B, 0);
++  PICO_PUT_W(PICO_CONFIG, 
++             PICO_OUTPUT_MODE(PICO_PLANAR_MODE) 
++             | PICO_INPUT_MODE(PICO_HOR_FILTER_MODE) 
++             | PICO_COEFF_FRAC_BITS(6)
++             | PICO_OFFSET_FRAC_BITS(6));
++  
++  for(i=0; i<h; i++)
++    {
++      
++      int src0 = LD32(src);
++      int src1 = LD32(src + stride);
++
++      PICO_MVRC_W(PICO_INPIX0, src0);
++      PICO_MVRC_W(PICO_INPIX1, src1);
++      PICO_OP(PICO_SINGLE_VECTOR, 2, 0, 4, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 3, 1, 5, 0);
++      src += stride;
++      ST16(dst,(short)PICO_GET_W(PICO_OUTPIX0));
++      dst += stride;
++    }
++}
++
++
++static void put_h264_chroma_mc4_pico(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){
++  const int A=(8-x)*(8-y);\
++  const int B=(  x)*(8-y);
++  const int C=(8-x)*(  y);
++  const int D=(  x)*(  y);
++  int i;
++  
++  PICO_PUT_W(PICO_COEFF0_A, (A << 16) | (B & 0xFFFF));
++  PICO_PUT_W(PICO_COEFF0_B, 32);
++  PICO_PUT_W(PICO_COEFF1_A, (C << 16) | (D & 0xFFFF));
++  PICO_PUT_W(PICO_COEFF1_B, 0);
++  PICO_PUT_W(PICO_COEFF2_A, 0);
++  PICO_PUT_W(PICO_COEFF2_B, 0);
++  PICO_PUT_W(PICO_CONFIG, 
++             PICO_OUTPUT_MODE(PICO_PLANAR_MODE) 
++             | PICO_INPUT_MODE(PICO_HOR_FILTER_MODE) 
++             | PICO_COEFF_FRAC_BITS(6)
++             | PICO_OFFSET_FRAC_BITS(6));
++
++  for(i=0; i<h; i++)
++    {
++      /*
++        OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));
++        OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));
++        OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));
++        OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));
++        dst+= stride;
++        src+= stride;
++      */
++      
++      int src0 = LD32(src);
++      int src1 = (((int)src[4] << 24) | (int)src[stride]);
++      int src2 = LD32(src + stride + 1);
++      
++      PICO_MVRC_W(PICO_INPIX0, src0);
++      PICO_MVRC_W(PICO_INPIX1, src1);
++      PICO_MVRC_W(PICO_INPIX2, src2);
++      PICO_OP(PICO_SINGLE_VECTOR, 0, 0, 7, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 1, 1, 8, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 2, 2, 9, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 3, 3, 10, 0);
++      src += stride;
++      ST32(dst, PICO_GET_W(PICO_OUTPIX0));
++
++      dst += stride;
++    }
++}
++
++static void put_h264_chroma_mc8_pico(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){
++  const int A=(8-x)*(8-y);
++  const int B=(  x)*(8-y);
++  const int C=(8-x)*(  y);
++  const int D=(  x)*(  y);
++  int i;
++  
++  PICO_PUT_W(PICO_COEFF0_A, (A << 16) | (B & 0xFFFF));
++  PICO_PUT_W(PICO_COEFF0_B, 32);
++  PICO_PUT_W(PICO_COEFF1_A, (C << 16) | (D & 0xFFFF));
++  PICO_PUT_W(PICO_COEFF1_B, 0);
++  PICO_PUT_W(PICO_COEFF2_A, 0);
++  PICO_PUT_W(PICO_COEFF2_B, 0);
++  PICO_PUT_W(PICO_CONFIG, 
++             PICO_OUTPUT_MODE(PICO_PLANAR_MODE) 
++             | PICO_INPUT_MODE(PICO_HOR_FILTER_MODE) 
++             | PICO_COEFF_FRAC_BITS(6)
++             | PICO_OFFSET_FRAC_BITS(6));
++
++  for(i=0; i<h; i++)
++    {
++      /*
++        OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));
++        OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));
++        OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));
++        OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));
++        OP(dst[4], (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5]));
++        OP(dst[5], (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6]));
++        OP(dst[6], (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7]));
++        OP(dst[7], (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8]));
++        dst+= stride;
++        src+= stride;
++      */  
++      int src0 = LD32(src);
++      int src1 = (((int)src[4] << 24) | (int)src[stride]);
++      int src2 = LD32(src + stride + 1);
++      
++      PICO_MVRC_W(PICO_INPIX0, src0);
++      PICO_MVRC_W(PICO_INPIX1, src1);
++      PICO_MVRC_W(PICO_INPIX2, src2);
++      PICO_OP(PICO_SINGLE_VECTOR, 0, 0, 7, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 1, 1, 8, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 2, 2, 9, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 3, 3, 10, 0);
++      ST32(dst, PICO_GET_W(PICO_OUTPIX0));
++      
++      src0 = LD32(src + 4);
++      src1 = (src[8] << 24) | src[stride + 4];
++      src2 = LD32(src + stride + 5);
++      
++      PICO_MVRC_W(PICO_INPIX0, src0);
++      PICO_MVRC_W(PICO_INPIX1, src1);
++      PICO_MVRC_W(PICO_INPIX2, src2);
++      PICO_OP(PICO_SINGLE_VECTOR, 0, 0, 7, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 1, 1, 8, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 2, 2, 9, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 3, 3, 10, 0);
++      src += stride;
++      ST32(dst + 4, PICO_GET_W(PICO_OUTPIX0));
++
++      dst += stride;
++    }
++}
++
++
++static void avg_h264_chroma_mc2_pico(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){
++  const int A=(8-x)*(8-y);
++  const int B=(  x)*(8-y);
++  const int C=(8-x)*(  y);
++  const int D=(  x)*(  y);
++  int i;
++  
++  PICO_PUT_W(PICO_COEFF0_A, (A << 16) | (B & 0xFFFF));
++  PICO_PUT_W(PICO_COEFF0_B, 32);
++  PICO_PUT_W(PICO_COEFF1_A, (C << 16) | (D & 0xFFFF));
++  PICO_PUT_W(PICO_COEFF1_B, 0);
++  PICO_PUT_W(PICO_COEFF2_A, 0);
++  PICO_PUT_W(PICO_COEFF2_B, 0);
++  PICO_PUT_W(PICO_CONFIG, 
++             PICO_OUTPUT_MODE(PICO_PLANAR_MODE) 
++             | PICO_INPUT_MODE(PICO_HOR_FILTER_MODE) 
++             | PICO_COEFF_FRAC_BITS(6)
++             | PICO_OFFSET_FRAC_BITS(6));
++  
++  for(i=0; i<h; i++)
++    {
++      int src0 = LD32(src);
++      int src1 = LD32(src + stride);
++      
++      PICO_MVRC_W(PICO_INPIX0, src0);
++      PICO_MVRC_W(PICO_INPIX1, src1);
++      PICO_OP(PICO_SINGLE_VECTOR, 2, 0, 4, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 3, 1, 5, 0);
++      src += stride;
++      ST16(dst, rnd_avg32(LD16(dst), PICO_GET_W(PICO_OUTPIX0)));
++      dst += stride;
++    }
++}
++
++
++static void avg_h264_chroma_mc4_pico(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){
++  const int A=(8-x)*(8-y);\
++  const int B=(  x)*(8-y);
++  const int C=(8-x)*(  y);
++  const int D=(  x)*(  y);
++  int i;
++  
++  PICO_PUT_W(PICO_COEFF0_A, (A << 16) | (B & 0xFFFF));
++  PICO_PUT_W(PICO_COEFF0_B, 32);
++  PICO_PUT_W(PICO_COEFF1_A, (C << 16) | (D & 0xFFFF));
++  PICO_PUT_W(PICO_COEFF1_B, 0);
++  PICO_PUT_W(PICO_COEFF2_A, 0);
++  PICO_PUT_W(PICO_COEFF2_B, 0);
++  PICO_PUT_W(PICO_CONFIG, 
++             PICO_OUTPUT_MODE(PICO_PLANAR_MODE) 
++             | PICO_INPUT_MODE(PICO_HOR_FILTER_MODE) 
++             | PICO_COEFF_FRAC_BITS(6)
++             | PICO_OFFSET_FRAC_BITS(6));
++
++  for(i=0; i<h; i++)
++    {
++      /*
++        OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));
++        OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));
++        OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));
++        OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));
++        dst+= stride;
++        src+= stride;
++      */
++      
++      int src0 = *((int *)src);
++      int src1 = (int)((src[4] << 24) | src[stride]);
++      int src2 = *((int *)(src + stride + 1));
++      
++      PICO_MVRC_W(PICO_INPIX0, src0);
++      PICO_MVRC_W(PICO_INPIX1, src1);
++      PICO_MVRC_W(PICO_INPIX2, src2);
++      PICO_OP(PICO_SINGLE_VECTOR, 0, 0, 7, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 1, 1, 8, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 2, 2, 9, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 3, 3, 10, 0);
++      src += stride;
++      ST32(dst, rnd_avg32(LD32(dst), PICO_GET_W(PICO_OUTPIX0)));
++      dst += stride;
++    }
++}
++
++static void avg_h264_chroma_mc8_pico(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){
++  const int A=(8-x)*(8-y);
++  const int B=(  x)*(8-y);
++  const int C=(8-x)*(  y);
++  const int D=(  x)*(  y);
++  int i;
++  
++  PICO_PUT_W(PICO_COEFF0_A, (A << 16) | (B & 0xFFFF));
++  PICO_PUT_W(PICO_COEFF0_B, 32);
++  PICO_PUT_W(PICO_COEFF1_A, (C << 16) | (D & 0xFFFF));
++  PICO_PUT_W(PICO_COEFF1_B, 0);
++  PICO_PUT_W(PICO_COEFF2_A, 0);
++  PICO_PUT_W(PICO_COEFF2_B, 0);
++  PICO_PUT_W(PICO_CONFIG, 
++             PICO_OUTPUT_MODE(PICO_PLANAR_MODE) 
++             | PICO_INPUT_MODE(PICO_HOR_FILTER_MODE) 
++             | PICO_COEFF_FRAC_BITS(6)
++             | PICO_OFFSET_FRAC_BITS(6));
++
++  for(i=0; i<h; i++)
++    {
++      /*
++        OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1]));
++        OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2]));
++        OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3]));
++        OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4]));
++        OP(dst[4], (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5]));
++        OP(dst[5], (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6]));
++        OP(dst[6], (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7]));
++        OP(dst[7], (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8]));
++        dst+= stride;
++        src+= stride;
++      */  
++      int src0 = *((int *)src);
++      int src1 = (volatile int)((src[4] << 24) | src[stride]);
++      int src2 = *((int *)(src + stride + 1));
++
++      PICO_MVRC_W(PICO_INPIX0, src0);
++      PICO_MVRC_W(PICO_INPIX1, src1);
++      PICO_MVRC_W(PICO_INPIX2, src2);
++      PICO_OP(PICO_SINGLE_VECTOR, 0, 0, 7, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 1, 1, 8, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 2, 2, 9, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 3, 3, 10, 0);
++      ST32(dst, rnd_avg32(LD32(dst), PICO_GET_W(PICO_OUTPIX0)));
++
++      src0 = *((int *)(src + 4));
++      src1 = (int)((src[8] << 24) | src[stride + 4]);
++      src2 = *((int *)(src + stride + 5));
++      
++      PICO_MVRC_W(PICO_INPIX0, src0);
++      PICO_MVRC_W(PICO_INPIX1, src1);
++      PICO_MVRC_W(PICO_INPIX2, src2);
++      PICO_OP(PICO_SINGLE_VECTOR, 0, 0, 7, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 1, 1, 8, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 2, 2, 9, 0);
++      PICO_OP(PICO_SINGLE_VECTOR, 3, 3, 10, 0);
++      src += stride;
++      ST32(dst + 4, rnd_avg32(LD32(dst + 4), PICO_GET_W(PICO_OUTPIX0)));
++      dst += stride;
++    }
++}
++
++static struct pico_config_t h264_qpel4_h_lowpass_config = { 
++  .input_mode = PICO_HOR_FILTER_MODE,
++  .output_mode = PICO_PLANAR_MODE,
++  .coeff_frac_bits = 5,
++  .offset_frac_bits = 5,
++  .coeff0_0 = 1,
++  .coeff0_1 = -5,
++  .coeff0_2 = 20,
++  .coeff0_3 = 16,
++  .coeff1_0 = 20,
++  .coeff1_1 = -5,
++  .coeff1_2 = 1,
++  .coeff1_3 = 0,
++  .coeff2_0 = 0,
++  .coeff2_1 = 0,
++  .coeff2_2 = 0,
++  .coeff2_3 = 0 
++};
++
++
++
++static void put_h264_qpel4_h_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  const int h=4;
++  int i;
++    
++  set_pico_config(&h264_qpel4_h_lowpass_config);
++
++  for(i=0; i<h; i++){
++    
++    /*
++      OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\
++      OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]));\
++      OP(dst[2], (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5]));\
++      OP(dst[3], (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6]));\
++      dst+=dstStride;\
++      src+=srcStride;\ */
++    PICO_MVRC_W(PICO_INPIX0, LD32(src - 2));
++    PICO_MVRC_D(PICO_INPIX2, LD64_UNALIGNED(src + 2));
++    PICO_OP(PICO_SINGLE_VECTOR, 0, 0, 3, 6);
++    PICO_OP(PICO_SINGLE_VECTOR, 1, 1, 4, 7);
++    PICO_OP(PICO_SINGLE_VECTOR, 2, 2, 5, 8);
++    PICO_OP(PICO_SINGLE_VECTOR, 3, 3, 6, 9);
++    src += srcStride;
++    ST32(dst, PICO_GET_W(PICO_OUTPIX0));
++    dst += dstStride;
++  }
++}
++
++static void avg_h264_qpel4_h_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  const int h=4;
++  int i;
++    
++  set_pico_config(&h264_qpel4_h_lowpass_config);
++  
++  for(i=0; i<h; i++){
++    
++    /*
++      OP(dst[0], (src[0]+src[1])*20 - (src[-1]+src[2])*5 + (src[-2]+src[3]));\
++      OP(dst[1], (src[1]+src[2])*20 - (src[0 ]+src[3])*5 + (src[-1]+src[4]));\
++      OP(dst[2], (src[2]+src[3])*20 - (src[1 ]+src[4])*5 + (src[0 ]+src[5]));\
++      OP(dst[3], (src[3]+src[4])*20 - (src[2 ]+src[5])*5 + (src[1 ]+src[6]));\
++      dst+=dstStride;\
++      src+=srcStride;\ */
++        
++    PICO_MVRC_W(PICO_INPIX0, LD32(src - 2));
++    PICO_MVRC_D(PICO_INPIX2, LD64_UNALIGNED(src + 2));
++    PICO_OP(PICO_SINGLE_VECTOR, 0, 0, 3, 6);
++    PICO_OP(PICO_SINGLE_VECTOR, 1, 1, 4, 7);
++    PICO_OP(PICO_SINGLE_VECTOR, 2, 2, 5, 8);
++    PICO_OP(PICO_SINGLE_VECTOR, 3, 3, 6, 9);
++    src += srcStride;
++    ST32(dst, rnd_avg32(LD32(dst), PICO_GET_W(PICO_OUTPIX0)));
++    dst += dstStride;
++  }
++}
++
++static struct pico_config_t h264_qpel4_v_lowpass_config1 = { 
++  .input_mode = PICO_VERT_FILTER_MODE,
++  .output_mode = PICO_PACKED_MODE,
++  .coeff_frac_bits = 5,
++  .offset_frac_bits = 5,
++  .coeff0_0 = 1,
++  .coeff0_1 = -5,
++  .coeff0_2 = 20,
++  .coeff0_3 = 16,
++  .coeff1_0 = 1,
++  .coeff1_1 = -5,
++  .coeff1_2 = 20,
++  .coeff1_3 = 16,
++  .coeff2_0 = 1,
++  .coeff2_1 = -5,
++  .coeff2_2 = 20,
++  .coeff2_3 = 16 
++};
++
++
++
++static struct pico_config_t h264_qpel4_v_lowpass_config2 = { 
++  .input_mode = PICO_VERT_FILTER_MODE,
++  .output_mode = PICO_PLANAR_MODE,
++  .coeff_frac_bits = 5,
++  .offset_frac_bits = 5,
++  .coeff0_0 = 1,
++  .coeff0_1 = -5,
++  .coeff0_2 = 20,
++  .coeff0_3 = 16,
++  .coeff1_0 = 20,
++  .coeff1_1 = -5,
++  .coeff1_2 = 1,
++  .coeff1_3 = 0,
++  .coeff2_0 = 0,
++  .coeff2_1 = 0,
++  .coeff2_2 = 0,
++  .coeff2_3 = 0 
++};
++
++static void put_h264_qpel4_v_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++
++  /*
++    const int w=4;
++    uint8_t *cm = cropTbl + MAX_NEG_CROP;
++    int i;
++    for(i=0; i<w; i++)
++    {
++    const int srcB= src[-2*srcStride];\
++    const int srcA= src[-1*srcStride];\
++    const int src0= src[0 *srcStride];\
++    const int src1= src[1 *srcStride];\
++    const int src2= src[2 *srcStride];\
++    const int src3= src[3 *srcStride];\
++    const int src4= src[4 *srcStride];\
++    const int src5= src[5 *srcStride];\
++    const int src6= src[6 *srcStride];\
++    OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
++    OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
++    OP(dst[2*dstStride], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
++    OP(dst[3*dstStride], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
++    dst++;\
++    src++;\
++  */  
++  
++  set_pico_config(&h264_qpel4_v_lowpass_config1);
++  
++  {
++    int srcB= LD32(src - 2*srcStride);
++    int srcA= LD32(src - 1*srcStride);
++    int src0= LD32(src + 0 *srcStride);
++    int src1= LD32(src + 1 *srcStride);
++    int src2= LD32(src + 2 *srcStride);
++    int src3= LD32(src + 3 *srcStride);
++    int src4= LD32(src + 4 *srcStride);
++    int src5= LD32(src + 5 *srcStride);
++    int src6= LD32(src + 6 *srcStride);
++    
++    /* First compute the leftmost three colums */
++    PICO_MVRC_W(PICO_INPIX0, srcB);
++    PICO_MVRC_W(PICO_INPIX1, srcA);
++    PICO_MVRC_W(PICO_INPIX2, src0);
++    PICO_OP(0, 0, 0, 3, 6);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX0, src3);
++    PICO_OP(PICO_USE_ACC, 0, 0, 3, 6);
++    ST32(dst, PICO_GET_W(PICO_OUTPIX0));
++    dst += dstStride;
++    PICO_MVRC_W(PICO_INPIX0, srcA);
++    PICO_MVRC_W(PICO_INPIX1, src0);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_OP(0, 0, 0, 3, 6);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_MVRC_W(PICO_INPIX1, src3);
++    PICO_MVRC_W(PICO_INPIX0, src4);
++    PICO_OP(PICO_USE_ACC, 0, 0, 3, 6);
++    ST32(dst, PICO_GET_W(PICO_OUTPIX0));
++    dst += dstStride;
++    PICO_MVRC_W(PICO_INPIX0, src0);
++    PICO_MVRC_W(PICO_INPIX1, src1);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_OP(0, 0, 0, 3, 6);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_MVRC_W(PICO_INPIX1, src4);
++    PICO_MVRC_W(PICO_INPIX0, src5);
++    PICO_OP(PICO_USE_ACC, 0, 0, 3, 6);
++    ST32(dst, PICO_GET_W(PICO_OUTPIX0));
++    dst += dstStride;
++    PICO_MVRC_W(PICO_INPIX0, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_OP(0, 0, 0, 3, 6);
++    PICO_MVRC_W(PICO_INPIX2, src4);
++    PICO_MVRC_W(PICO_INPIX1, src5);
++    PICO_MVRC_W(PICO_INPIX0, src6);
++    PICO_OP(PICO_USE_ACC, 0, 0, 3, 6);
++    ST32(dst, PICO_GET_W(PICO_OUTPIX0));
++    /* Now compute the last column */
++ 
++    union wordbytes {
++      int word;
++      struct  {
++        unsigned int t:8;
++        unsigned int u:8;
++        unsigned int l:8;
++        unsigned int b:8; 
++      } bytes; } tmp1, tmp2, tmp3;
++    
++    
++    tmp1.bytes.t = srcB;
++    tmp1.bytes.u = src1;
++    tmp1.bytes.l = src4;
++    
++    tmp2.bytes.t = srcA;
++    tmp2.bytes.u = src2;
++    tmp2.bytes.l = src5;
++
++    tmp3.bytes.t = src0;
++    tmp3.bytes.u = src3;
++    tmp3.bytes.l = src6;
++    
++    PICO_MVRC_W(PICO_INPIX0, tmp1.word);
++    PICO_MVRC_W(PICO_INPIX1, tmp2.word);
++    PICO_MVRC_W(PICO_INPIX2, tmp3.word);
++    set_pico_config(&h264_qpel4_v_lowpass_config2);
++
++    
++    PICO_OP(PICO_SINGLE_VECTOR, 0, 0, 3, 6);
++    PICO_OP(PICO_SINGLE_VECTOR, 1, 1, 4, 7);
++    PICO_OP(PICO_SINGLE_VECTOR, 2, 2, 5, 8);
++    PICO_OP(PICO_SINGLE_VECTOR, 3, 3, 6, 9);
++    
++    PICO_MVCR_W(tmp1.word, PICO_OUTPIX0);
++    dst[3] = (char)(tmp1.bytes.b);
++    dst[3 - dstStride] = (char)(tmp1.bytes.l);
++    dst[3 - 2*dstStride] = (char)(tmp1.bytes.u);
++    dst[3 - 3*dstStride] = (char)(tmp1.bytes.t);
++    
++  }
++    /*}
++    
++
++    }*/
++}
++
++static void avg_h264_qpel4_v_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++
++  /*
++    const int w=4;
++    uint8_t *cm = cropTbl + MAX_NEG_CROP;
++    int i;
++    for(i=0; i<w; i++)
++    {
++    const int srcB= src[-2*srcStride];\
++    const int srcA= src[-1*srcStride];\
++    const int src0= src[0 *srcStride];\
++    const int src1= src[1 *srcStride];\
++    const int src2= src[2 *srcStride];\
++    const int src3= src[3 *srcStride];\
++    const int src4= src[4 *srcStride];\
++    const int src5= src[5 *srcStride];\
++    const int src6= src[6 *srcStride];\
++    OP(dst[0*dstStride], (src0+src1)*20 - (srcA+src2)*5 + (srcB+src3));\
++    OP(dst[1*dstStride], (src1+src2)*20 - (src0+src3)*5 + (srcA+src4));\
++    OP(dst[2*dstStride], (src2+src3)*20 - (src1+src4)*5 + (src0+src5));\
++    OP(dst[3*dstStride], (src3+src4)*20 - (src2+src5)*5 + (src1+src6));\
++    dst++;\
++    src++;\
++  */  
++  uint8_t tmp_block[4*4];
++  
++  set_pico_config(&h264_qpel4_v_lowpass_config1);
++  
++  {
++    int srcB= LD32(src - 2*srcStride);
++    int srcA= LD32(src - 1*srcStride);
++    int src0= LD32(src + 0 *srcStride);
++    int src1= LD32(src + 1 *srcStride);
++    int src2= LD32(src + 2 *srcStride);
++    int src3= LD32(src + 3 *srcStride);
++    int src4= LD32(src + 4 *srcStride);
++    int src5= LD32(src + 5 *srcStride);
++    int src6= LD32(src + 6 *srcStride);
++    
++    /* First compute the leftmost three colums */
++    PICO_MVRC_W(PICO_INPIX0, srcB);
++    PICO_MVRC_W(PICO_INPIX1, srcA);
++    PICO_MVRC_W(PICO_INPIX2, src0);
++    PICO_OP(0, 0, 0, 3, 6);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX0, src3);
++    PICO_OP(PICO_USE_ACC, 0, 0, 3, 6);
++    ST32(tmp_block, PICO_GET_W(PICO_OUTPIX0));
++    PICO_MVRC_W(PICO_INPIX0, srcA);
++    PICO_MVRC_W(PICO_INPIX1, src0);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_OP(0, 0, 0, 3, 6);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_MVRC_W(PICO_INPIX1, src3);
++    PICO_MVRC_W(PICO_INPIX0, src4);
++    PICO_OP(PICO_USE_ACC, 0, 0, 3, 6);
++    ST32(tmp_block + 4, PICO_GET_W(PICO_OUTPIX0));
++    PICO_MVRC_W(PICO_INPIX0, src0);
++    PICO_MVRC_W(PICO_INPIX1, src1);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_OP(0, 0, 0, 3, 6);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_MVRC_W(PICO_INPIX1, src4);
++    PICO_MVRC_W(PICO_INPIX0, src5);
++    PICO_OP(PICO_USE_ACC, 0, 0, 3, 6);
++    ST32(tmp_block + 8, PICO_GET_W(PICO_OUTPIX0));
++    PICO_MVRC_W(PICO_INPIX0, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_OP(0, 0, 0, 3, 6);
++    PICO_MVRC_W(PICO_INPIX2, src4);
++    PICO_MVRC_W(PICO_INPIX1, src5);
++    PICO_MVRC_W(PICO_INPIX0, src6);
++    PICO_OP(PICO_USE_ACC, 0, 0, 3, 6);
++    ST32(tmp_block + 12, PICO_GET_W(PICO_OUTPIX0));
++    /* Now compute the last column */
++ 
++    union wordbytes {
++      int word;
++      struct  {
++        unsigned int t:8;
++        unsigned int u:8;
++        unsigned int l:8;
++        unsigned int b:8; 
++      } bytes; } tmp1, tmp2, tmp3;
++    
++    
++    tmp1.bytes.t = srcB;
++    tmp1.bytes.u = src1;
++    tmp1.bytes.l = src4;
++    
++    tmp2.bytes.t = srcA;
++    tmp2.bytes.u = src2;
++    tmp2.bytes.l = src5;
++
++    tmp3.bytes.t = src0;
++    tmp3.bytes.u = src3;
++    tmp3.bytes.l = src6;
++    
++    PICO_MVRC_W(PICO_INPIX0, tmp1.word);
++    PICO_MVRC_W(PICO_INPIX1, tmp2.word);
++    PICO_MVRC_W(PICO_INPIX2, tmp3.word);
++    set_pico_config(&h264_qpel4_v_lowpass_config2);
++
++    
++    PICO_OP(PICO_SINGLE_VECTOR, 0, 0, 3, 6);
++    PICO_OP(PICO_SINGLE_VECTOR, 1, 1, 4, 7);
++    PICO_OP(PICO_SINGLE_VECTOR, 2, 2, 5, 8);
++    PICO_OP(PICO_SINGLE_VECTOR, 3, 3, 6, 9);
++    
++    PICO_MVCR_W(tmp1.word, PICO_OUTPIX0);
++    tmp_block[3 + 3*4] = (char)(tmp1.bytes.b);
++    tmp_block[3 + 2*4] = (char)(tmp1.bytes.l);
++    tmp_block[3 + 1*4] = (char)(tmp1.bytes.u);
++    tmp_block[3] = (char)(tmp1.bytes.t);
++
++    /* Compute the average */
++    srcB= LD32(dst);
++    srcA= LD32(dst + dstStride);
++    src0= LD32(dst + dstStride*2);
++    src1= LD32(dst + dstStride*3);
++          
++    src2= LD32(tmp_block);
++    src3= LD32(tmp_block + 4);
++    src4= LD32(tmp_block + 8);
++    src5= LD32(tmp_block + 12);
++
++    ST32(dst, rnd_avg32(srcB, src2));
++    ST32(dst + dstStride, rnd_avg32(srcA, src3));
++    ST32(dst + 2*dstStride, rnd_avg32(src0, src4));
++    ST32(dst + 3*dstStride, rnd_avg32(src1, src5));    
++  }
++}
++
++static struct pico_config_t h264_qpel4_hv_lowpass_config = { 
++  .input_mode = PICO_HOR_FILTER_MODE,
++  .output_mode = PICO_PACKED_MODE,
++  .coeff_frac_bits = 10,
++  .offset_frac_bits = 10,
++  .coeff0_0 = 1,
++  .coeff0_1 = -5,
++  .coeff0_2 = 20,
++  .coeff0_3 = 512,
++  .coeff1_0 = -5,
++  .coeff1_1 = 25,
++  .coeff1_2 = -100,
++  .coeff1_3 = 0,
++  .coeff2_0 = 20,
++  .coeff2_1 = -100,
++  .coeff2_2 = 400,
++  .coeff2_3 = 0 
++};
++
++static void put_h264_qpel4_hv_lowpass_pico(uint8_t *dst,  uint8_t *src, int dstStride, int srcStride){
++
++  int32_t tmp_block[48];
++  int32_t *tmp = tmp_block;
++  int i;
++  
++  set_pico_config(&h264_qpel4_hv_lowpass_config);
++
++  src -= 2;
++  for ( i = 0; i < 2; i++ ){ 
++    int srcB= LD32(src - 2*srcStride);
++    int srcA= LD32(src - 1*srcStride);
++    int src0= LD32(src + 0 *srcStride);
++    int src1= LD32(src + 1 *srcStride);
++    int src2= LD32(src + 2 *srcStride);
++    int src3= LD32(src + 3 *srcStride);
++    int src4= LD32(src + 4 *srcStride);
++    int src5= LD32(src + 5 *srcStride);
++    int src6= LD32(src + 6 *srcStride);
++    
++    PICO_MVRC_W(PICO_INPIX0, srcB);
++    PICO_MVRC_W(PICO_INPIX1, srcA);
++    PICO_MVRC_W(PICO_INPIX2, src0);
++    PICO_OP(0, 0, 0, 4, 8);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX0, src3);
++    PICO_OP(PICO_USE_ACC, 0, 0, 4, 8);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++    
++    PICO_OP(0, 0, 1, 5, 9);
++    PICO_MVRC_W(PICO_INPIX0, srcB);
++    PICO_MVRC_W(PICO_INPIX1, srcA);
++    PICO_MVRC_W(PICO_INPIX2, src0);
++    PICO_OP(PICO_USE_ACC, 0, 1, 5, 9);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++    
++    PICO_MVRC_W(PICO_INPIX0, src1);
++    PICO_OP(0, 0, 4, 8, 0);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_MVRC_W(PICO_INPIX1, src3);
++    PICO_MVRC_W(PICO_INPIX0, src4);
++    PICO_OP(PICO_USE_ACC, 0, 0, 4, 8);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++    
++    PICO_OP(0, 0, 1, 5, 9);
++    PICO_MVRC_W(PICO_INPIX0, srcA);
++    PICO_MVRC_W(PICO_INPIX1, src0);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_OP(PICO_USE_ACC, 0, 1, 5, 9);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++    
++    PICO_MVRC_W(PICO_INPIX0, src2);
++    PICO_OP(0, 0, 4, 8, 0);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_MVRC_W(PICO_INPIX1, src4);
++    PICO_MVRC_W(PICO_INPIX0, src5);
++    PICO_OP(PICO_USE_ACC, 0, 0, 4, 8);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++
++    PICO_OP(0, 0, 1, 5, 9);
++    PICO_MVRC_W(PICO_INPIX0, src0);
++    PICO_MVRC_W(PICO_INPIX1, src1);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_OP(PICO_USE_ACC, 0, 1, 5, 9);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++
++    PICO_MVRC_W(PICO_INPIX0, src3);
++    PICO_OP(0, 0, 4, 8, 0);
++    PICO_MVRC_W(PICO_INPIX2, src4);
++    PICO_MVRC_W(PICO_INPIX1, src5);
++    PICO_MVRC_W(PICO_INPIX0, src6);
++    PICO_OP(PICO_USE_ACC, 0, 0, 4, 8); 
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++    
++    PICO_OP(0, 0, 1, 5, 9);
++    PICO_MVRC_W(PICO_INPIX0, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_OP(PICO_USE_ACC, 0, 1, 5, 9);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;    
++    src += 2;
++  }
++
++  src -= 1;
++  tmp -= 48;
++
++  
++  PICO_PUT_W(PICO_CONFIG, 
++             PICO_OUTPUT_MODE(PICO_PLANAR_MODE)  
++             | PICO_INPUT_MODE(PICO_VERT_FILTER_MODE) 
++             | PICO_COEFF_FRAC_BITS(10)
++             | PICO_OFFSET_FRAC_BITS(10));
++
++  for ( i = 0; i < 2; i++ ){ 
++    int srcB= LD32(src - 2*srcStride);
++    int srcA= LD32(src - 1*srcStride);
++    int src0= LD32(src + 0 *srcStride);
++    int src1= LD32(src + 1 *srcStride);
++    int src2= LD32(src + 2 *srcStride);
++    int src3= LD32(src + 3 *srcStride);
++    int src4= LD32(src + 4 *srcStride);
++    int src5= LD32(src + 5 *srcStride);
++    int src6= LD32(src + 6 *srcStride);
++    
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_MVRC_W(PICO_INPIX0, srcB);
++    PICO_MVRC_W(PICO_INPIX1, srcA);
++    PICO_MVRC_W(PICO_INPIX2, src0);
++    PICO_OP(PICO_USE_ACC, 0, 6, 3, 0);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX0, src3);
++    PICO_OP(PICO_USE_ACC | PICO_SINGLE_VECTOR, 0, 6, 3, 0);
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_OP(PICO_USE_ACC, 1, 9, 6, 3);
++    PICO_MVRC_W(PICO_INPIX0, srcB);
++    PICO_MVRC_W(PICO_INPIX1, srcA);
++    PICO_MVRC_W(PICO_INPIX2, src0);
++    PICO_OP(PICO_USE_ACC | PICO_SINGLE_VECTOR, 1, 9, 6, 3);
++    
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_MVRC_W(PICO_INPIX0, srcA);
++    PICO_MVRC_W(PICO_INPIX1, src0);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_OP(PICO_USE_ACC, 2, 6, 3, 0);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_MVRC_W(PICO_INPIX1, src3);
++    PICO_MVRC_W(PICO_INPIX0, src4);
++    PICO_OP(PICO_USE_ACC | PICO_SINGLE_VECTOR, 2, 6, 3, 0);
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_OP(PICO_USE_ACC, 3, 9, 6, 3);
++    PICO_MVRC_W(PICO_INPIX0, srcA);
++    PICO_MVRC_W(PICO_INPIX1, src0);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_OP(PICO_USE_ACC | PICO_SINGLE_VECTOR, 3, 9, 6, 3);
++    
++    ST16(dst + 0*dstStride, (short)(PICO_GET_W(PICO_OUTPIX0) >> 16)); 
++    ST16(dst + 1*dstStride, (short)PICO_GET_W(PICO_OUTPIX0)); 
++    
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_MVRC_W(PICO_INPIX0, src0);
++    PICO_MVRC_W(PICO_INPIX1, src1);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_OP(PICO_USE_ACC, 0, 6, 3, 0);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_MVRC_W(PICO_INPIX1, src4);
++    PICO_MVRC_W(PICO_INPIX0, src5);
++    PICO_OP(PICO_USE_ACC| PICO_SINGLE_VECTOR, 0, 6, 3, 0);
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_OP(PICO_USE_ACC, 1, 9, 6, 3);
++    PICO_MVRC_W(PICO_INPIX0, src0);
++    PICO_MVRC_W(PICO_INPIX1, src1);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_OP(PICO_USE_ACC| PICO_SINGLE_VECTOR, 1, 9, 6, 3);
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_MVRC_W(PICO_INPIX0, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_OP(PICO_USE_ACC, 2, 6, 3, 0);
++    PICO_MVRC_W(PICO_INPIX2, src4);
++    PICO_MVRC_W(PICO_INPIX1, src5);
++    PICO_MVRC_W(PICO_INPIX0, src6);
++    PICO_OP(PICO_USE_ACC| PICO_SINGLE_VECTOR, 2, 6, 3, 0);
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_OP(PICO_USE_ACC, 3, 9, 6, 3);
++    PICO_MVRC_W(PICO_INPIX0, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_OP(PICO_USE_ACC| PICO_SINGLE_VECTOR, 3, 9, 6, 3);
++
++    ST16(dst + 2*dstStride, (short)(PICO_GET_W(PICO_OUTPIX0) >> 16)); 
++    ST16(dst + 3*dstStride, (short)PICO_GET_W(PICO_OUTPIX0)); 
++
++    dst += 2;
++    src += 2;
++  }
++}
++
++
++
++
++static void avg_h264_qpel4_hv_lowpass_pico(uint8_t *dst,  uint8_t *src, int dstStride, int srcStride){
++
++  int32_t tmp_block[48];
++  int32_t *tmp = tmp_block;
++  int i;
++  
++  set_pico_config(&h264_qpel4_hv_lowpass_config);
++
++  src -= 2;
++  for ( i = 0; i < 2; i++ ){ 
++    int srcB= LD32(src - 2*srcStride);
++    int srcA= LD32(src - 1*srcStride);
++    int src0= LD32(src + 0 *srcStride);
++    int src1= LD32(src + 1 *srcStride);
++    int src2= LD32(src + 2 *srcStride);
++    int src3= LD32(src + 3 *srcStride);
++    int src4= LD32(src + 4 *srcStride);
++    int src5= LD32(src + 5 *srcStride);
++    int src6= LD32(src + 6 *srcStride);
++    
++    PICO_MVRC_W(PICO_INPIX0, srcB);
++    PICO_MVRC_W(PICO_INPIX1, srcA);
++    PICO_MVRC_W(PICO_INPIX2, src0);
++    PICO_OP(0, 0, 0, 4, 8);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX0, src3);
++    PICO_OP(PICO_USE_ACC, 0, 0, 4, 8);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++    
++    PICO_OP(0, 0, 1, 5, 9);
++    PICO_MVRC_W(PICO_INPIX0, srcB);
++    PICO_MVRC_W(PICO_INPIX1, srcA);
++    PICO_MVRC_W(PICO_INPIX2, src0);
++    PICO_OP(PICO_USE_ACC, 0, 1, 5, 9);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++    
++    PICO_MVRC_W(PICO_INPIX0, src1);
++    PICO_OP(0, 0, 4, 8, 0);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_MVRC_W(PICO_INPIX1, src3);
++    PICO_MVRC_W(PICO_INPIX0, src4);
++    PICO_OP(PICO_USE_ACC, 0, 0, 4, 8);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++    
++    PICO_OP(0, 0, 1, 5, 9);
++    PICO_MVRC_W(PICO_INPIX0, srcA);
++    PICO_MVRC_W(PICO_INPIX1, src0);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_OP(PICO_USE_ACC, 0, 1, 5, 9);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++    
++    PICO_MVRC_W(PICO_INPIX0, src2);
++    PICO_OP(0, 0, 4, 8, 0);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_MVRC_W(PICO_INPIX1, src4);
++    PICO_MVRC_W(PICO_INPIX0, src5);
++    PICO_OP(PICO_USE_ACC, 0, 0, 4, 8);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++
++    PICO_OP(0, 0, 1, 5, 9);
++    PICO_MVRC_W(PICO_INPIX0, src0);
++    PICO_MVRC_W(PICO_INPIX1, src1);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_OP(PICO_USE_ACC, 0, 1, 5, 9);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++
++    PICO_MVRC_W(PICO_INPIX0, src3);
++    PICO_OP(0, 0, 4, 8, 0);
++    PICO_MVRC_W(PICO_INPIX2, src4);
++    PICO_MVRC_W(PICO_INPIX1, src5);
++    PICO_MVRC_W(PICO_INPIX0, src6);
++    PICO_OP(PICO_USE_ACC, 0, 0, 4, 8); 
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;
++    
++    PICO_OP(0, 0, 1, 5, 9);
++    PICO_MVRC_W(PICO_INPIX0, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_OP(PICO_USE_ACC, 0, 1, 5, 9);
++    PICO_STCM_W(tmp, 
++                PICO_REGVECT_VMU0_OUT, 
++                PICO_REGVECT_VMU1_OUT, 
++                PICO_REGVECT_VMU2_OUT);
++    tmp += 3;    
++    src += 2;
++  }
++
++  src -= 1;
++  tmp -= 48;
++
++  
++  PICO_PUT_W(PICO_CONFIG, 
++             PICO_OUTPUT_MODE(PICO_PLANAR_MODE)  
++             | PICO_INPUT_MODE(PICO_VERT_FILTER_MODE) 
++             | PICO_COEFF_FRAC_BITS(10)
++             | PICO_OFFSET_FRAC_BITS(10));
++
++  for ( i = 0; i < 2; i++ ){ 
++    int srcB= LD32(src - 2*srcStride);
++    int srcA= LD32(src - 1*srcStride);
++    int src0= LD32(src + 0 *srcStride);
++    int src1= LD32(src + 1 *srcStride);
++    int src2= LD32(src + 2 *srcStride);
++    int src3= LD32(src + 3 *srcStride);
++    int src4= LD32(src + 4 *srcStride);
++    int src5= LD32(src + 5 *srcStride);
++    int src6= LD32(src + 6 *srcStride);
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_MVRC_W(PICO_INPIX0, srcB);
++    PICO_MVRC_W(PICO_INPIX1, srcA);
++    PICO_MVRC_W(PICO_INPIX2, src0);
++    PICO_OP(PICO_USE_ACC, 0, 6, 3, 0);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX0, src3);
++    PICO_OP(PICO_USE_ACC | PICO_SINGLE_VECTOR, 0, 6, 3, 0);
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_OP(PICO_USE_ACC, 1, 9, 6, 3);
++    PICO_MVRC_W(PICO_INPIX0, srcB);
++    PICO_MVRC_W(PICO_INPIX1, srcA);
++    PICO_MVRC_W(PICO_INPIX2, src0);
++    PICO_OP(PICO_USE_ACC | PICO_SINGLE_VECTOR, 1, 9, 6, 3);
++    
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_MVRC_W(PICO_INPIX0, srcA);
++    PICO_MVRC_W(PICO_INPIX1, src0);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_OP(PICO_USE_ACC, 2, 6, 3, 0);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_MVRC_W(PICO_INPIX1, src3);
++    PICO_MVRC_W(PICO_INPIX0, src4);
++    PICO_OP(PICO_USE_ACC | PICO_SINGLE_VECTOR, 2, 6, 3, 0);
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_OP(PICO_USE_ACC, 3, 9, 6, 3);
++    PICO_MVRC_W(PICO_INPIX0, srcA);
++    PICO_MVRC_W(PICO_INPIX1, src0);
++    PICO_MVRC_W(PICO_INPIX2, src1);
++    PICO_OP(PICO_USE_ACC | PICO_SINGLE_VECTOR, 3, 9, 6, 3);
++    
++    ST16(dst + 0*dstStride, rnd_avg32(LD16(dst + 0*dstStride), PICO_GET_W(PICO_OUTPIX0) >> 16)); 
++    ST16(dst + 1*dstStride, rnd_avg32(LD16(dst + 1*dstStride), PICO_GET_W(PICO_OUTPIX0))); 
++    
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_MVRC_W(PICO_INPIX0, src0);
++    PICO_MVRC_W(PICO_INPIX1, src1);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_OP(PICO_USE_ACC, 0, 6, 3, 0);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_MVRC_W(PICO_INPIX1, src4);
++    PICO_MVRC_W(PICO_INPIX0, src5);
++    PICO_OP(PICO_USE_ACC| PICO_SINGLE_VECTOR, 0, 6, 3, 0);
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_OP(PICO_USE_ACC, 1, 9, 6, 3);
++    PICO_MVRC_W(PICO_INPIX0, src0);
++    PICO_MVRC_W(PICO_INPIX1, src1);
++    PICO_MVRC_W(PICO_INPIX2, src2);
++    PICO_OP(PICO_USE_ACC| PICO_SINGLE_VECTOR, 1, 9, 6, 3);
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_MVRC_W(PICO_INPIX0, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_OP(PICO_USE_ACC, 2, 6, 3, 0);
++    PICO_MVRC_W(PICO_INPIX2, src4);
++    PICO_MVRC_W(PICO_INPIX1, src5);
++    PICO_MVRC_W(PICO_INPIX0, src6);
++    PICO_OP(PICO_USE_ACC| PICO_SINGLE_VECTOR, 2, 6, 3, 0);
++
++    PICO_LDCM_W_INC(tmp, 
++                    PICO_REGVECT_VMU0_OUT, 
++                    PICO_REGVECT_VMU1_OUT, 
++                    PICO_REGVECT_VMU2_OUT);
++    PICO_OP(PICO_USE_ACC, 3, 9, 6, 3);
++    PICO_MVRC_W(PICO_INPIX0, src1);
++    PICO_MVRC_W(PICO_INPIX1, src2);
++    PICO_MVRC_W(PICO_INPIX2, src3);
++    PICO_OP(PICO_USE_ACC| PICO_SINGLE_VECTOR, 3, 9, 6, 3);
++
++    ST16(dst + 2*dstStride, rnd_avg32(LD16(dst + 2*dstStride), PICO_GET_W(PICO_OUTPIX0) >> 16)); 
++    ST16(dst + 3*dstStride, rnd_avg32(LD16(dst + 3*dstStride), PICO_GET_W(PICO_OUTPIX0))); 
++
++    dst += 2;
++    src += 2;
++  }
++}
++
++
++static void put_h264_qpel8_v_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  put_h264_qpel4_v_lowpass_pico(dst  , src  , dstStride, srcStride);
++  put_h264_qpel4_v_lowpass_pico(dst+4, src+4, dstStride, srcStride);
++  src += 4*srcStride;
++  dst += 4*dstStride;
++  put_h264_qpel4_v_lowpass_pico(dst  , src  , dstStride, srcStride);
++  put_h264_qpel4_v_lowpass_pico(dst+4, src+4, dstStride, srcStride);
++}
++
++static void avg_h264_qpel8_v_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  avg_h264_qpel4_v_lowpass_pico(dst  , src  , dstStride, srcStride);
++  avg_h264_qpel4_v_lowpass_pico(dst+4, src+4, dstStride, srcStride);
++  src += 4*srcStride;
++  dst += 4*dstStride;
++  avg_h264_qpel4_v_lowpass_pico(dst  , src  , dstStride, srcStride);
++  avg_h264_qpel4_v_lowpass_pico(dst+4, src+4, dstStride, srcStride);
++}
++
++static void put_h264_qpel8_h_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  put_h264_qpel4_h_lowpass_pico(dst  , src  , dstStride, srcStride);
++  put_h264_qpel4_h_lowpass_pico(dst+4, src+4, dstStride, srcStride);
++  src += 4*srcStride;
++  dst += 4*dstStride;
++  put_h264_qpel4_h_lowpass_pico(dst  , src  , dstStride, srcStride);
++  put_h264_qpel4_h_lowpass_pico(dst+4, src+4, dstStride, srcStride);
++}
++
++static void avg_h264_qpel8_h_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  avg_h264_qpel4_h_lowpass_pico(dst  , src  , dstStride, srcStride);
++  avg_h264_qpel4_h_lowpass_pico(dst+4, src+4, dstStride, srcStride);
++  src += 4*srcStride;
++  dst += 4*dstStride;
++  avg_h264_qpel4_h_lowpass_pico(dst  , src  , dstStride, srcStride);
++  avg_h264_qpel4_h_lowpass_pico(dst+4, src+4, dstStride, srcStride);
++}
++
++static void put_h264_qpel8_hv_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  put_h264_qpel4_hv_lowpass_pico(dst  , src  , dstStride, srcStride);
++  put_h264_qpel4_hv_lowpass_pico(dst+4, src+4, dstStride, srcStride);
++  src += 4*srcStride;
++  dst += 4*dstStride;
++  put_h264_qpel4_hv_lowpass_pico(dst  , src  , dstStride, srcStride);
++  put_h264_qpel4_hv_lowpass_pico(dst+4, src+4, dstStride, srcStride);
++}
++
++static void avg_h264_qpel8_hv_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  avg_h264_qpel4_hv_lowpass_pico(dst  , src  , dstStride, srcStride);
++  avg_h264_qpel4_hv_lowpass_pico(dst+4, src+4, dstStride, srcStride);
++  src += 4*srcStride;
++  dst += 4*dstStride;
++  avg_h264_qpel4_hv_lowpass_pico(dst  , src  , dstStride, srcStride);
++  avg_h264_qpel4_hv_lowpass_pico(dst+4, src+4, dstStride, srcStride);
++}
++
++static void put_h264_qpel16_v_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  put_h264_qpel8_v_lowpass_pico(dst  , src  , dstStride, srcStride);
++  put_h264_qpel8_v_lowpass_pico(dst+8, src+8, dstStride, srcStride);
++  src += 8*srcStride;
++  dst += 8*dstStride;
++  put_h264_qpel8_v_lowpass_pico(dst  , src  , dstStride, srcStride);
++  put_h264_qpel8_v_lowpass_pico(dst+8, src+8, dstStride, srcStride);
++}
++
++static void avg_h264_qpel16_v_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  avg_h264_qpel8_v_lowpass_pico(dst  , src  , dstStride, srcStride);
++  avg_h264_qpel8_v_lowpass_pico(dst+8, src+8, dstStride, srcStride);
++  src += 8*srcStride;
++  dst += 8*dstStride;
++  avg_h264_qpel8_v_lowpass_pico(dst  , src  , dstStride, srcStride);
++  avg_h264_qpel8_v_lowpass_pico(dst+8, src+8, dstStride, srcStride);
++}
++
++static void put_h264_qpel16_h_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  put_h264_qpel8_h_lowpass_pico(dst  , src  , dstStride, srcStride);
++  put_h264_qpel8_h_lowpass_pico(dst+8, src+8, dstStride, srcStride);
++  src += 8*srcStride;
++  dst += 8*dstStride;
++  put_h264_qpel8_h_lowpass_pico(dst  , src  , dstStride, srcStride);
++  put_h264_qpel8_h_lowpass_pico(dst+8, src+8, dstStride, srcStride);
++}
++
++static void avg_h264_qpel16_h_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  avg_h264_qpel8_h_lowpass_pico(dst  , src  , dstStride, srcStride);
++  avg_h264_qpel8_h_lowpass_pico(dst+8, src+8, dstStride, srcStride);
++  src += 8*srcStride;
++  dst += 8*dstStride;
++  avg_h264_qpel8_h_lowpass_pico(dst  , src  , dstStride, srcStride);
++  avg_h264_qpel8_h_lowpass_pico(dst+8, src+8, dstStride, srcStride);
++}
++
++static void put_h264_qpel16_hv_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  put_h264_qpel8_hv_lowpass_pico(dst  , src  , dstStride, srcStride);
++  put_h264_qpel8_hv_lowpass_pico(dst+8, src+8, dstStride, srcStride);
++  src += 8*srcStride;
++  dst += 8*dstStride;
++  put_h264_qpel8_hv_lowpass_pico(dst  , src  , dstStride, srcStride);
++  put_h264_qpel8_hv_lowpass_pico(dst+8, src+8, dstStride, srcStride);
++}
++
++static void avg_h264_qpel16_hv_lowpass_pico(uint8_t *dst, uint8_t *src, int dstStride, int srcStride){
++  avg_h264_qpel8_hv_lowpass_pico(dst  , src  , dstStride, srcStride);
++  avg_h264_qpel8_hv_lowpass_pico(dst+8, src+8, dstStride, srcStride);
++  src += 8*srcStride;
++  dst += 8*dstStride;
++  avg_h264_qpel8_hv_lowpass_pico(dst  , src  , dstStride, srcStride);
++  avg_h264_qpel8_hv_lowpass_pico(dst+8, src+8, dstStride, srcStride);
++}
++
++
++#define H264_MC(OPNAME, SIZE) \
++static void OPNAME ## h264_qpel ## SIZE ## _mc00_pico (uint8_t *dst, uint8_t *src, int stride){\
++    OPNAME ## pixels ## SIZE ## _c(dst, src, stride, SIZE);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc10_pico(uint8_t *dst, uint8_t *src, int stride){\
++    uint8_t half[SIZE*SIZE];\
++    put_h264_qpel ## SIZE ## _h_lowpass_pico(half, src, SIZE, stride);\
++    OPNAME ## pixels ## SIZE ## _l2(dst, src, half, stride, stride, SIZE, SIZE);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc20_pico(uint8_t *dst, uint8_t *src, int stride){\
++    OPNAME ## h264_qpel ## SIZE ## _h_lowpass_pico(dst, src, stride, stride);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc30_pico(uint8_t *dst, uint8_t *src, int stride){\
++    uint8_t half[SIZE*SIZE];\
++    put_h264_qpel ## SIZE ## _h_lowpass_pico(half, src, SIZE, stride);\
++    OPNAME ## pixels ## SIZE ## _l2(dst, src+1, half, stride, stride, SIZE, SIZE);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc01_pico(uint8_t *dst, uint8_t *src, int stride){\
++    uint8_t full[SIZE*(SIZE+5)];\
++    uint8_t * const full_mid= full + SIZE*2;\
++    uint8_t half[SIZE*SIZE];\
++    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
++    put_h264_qpel ## SIZE ## _v_lowpass_pico(half, full_mid, SIZE, SIZE);\
++    OPNAME ## pixels ## SIZE ## _l2(dst, full_mid, half, stride, SIZE, SIZE, SIZE);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc02_pico(uint8_t *dst, uint8_t *src, int stride){\
++    uint8_t full[SIZE*(SIZE+5)];\
++    uint8_t * const full_mid= full + SIZE*2;\
++    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
++    OPNAME ## h264_qpel ## SIZE ## _v_lowpass_pico(dst, full_mid, stride, SIZE);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc03_pico(uint8_t *dst, uint8_t *src, int stride){\
++    uint8_t full[SIZE*(SIZE+5)];\
++    uint8_t * const full_mid= full + SIZE*2;\
++    uint8_t half[SIZE*SIZE];\
++    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
++    put_h264_qpel ## SIZE ## _v_lowpass_pico(half, full_mid, SIZE, SIZE);\
++    OPNAME ## pixels ## SIZE ## _l2(dst, full_mid+SIZE, half, stride, SIZE, SIZE, SIZE);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc11_pico(uint8_t *dst, uint8_t *src, int stride){\
++    uint8_t full[SIZE*(SIZE+5)];\
++    uint8_t * const full_mid= full + SIZE*2;\
++    uint8_t halfH[SIZE*SIZE];\
++    uint8_t halfV[SIZE*SIZE];\
++    put_h264_qpel ## SIZE ## _h_lowpass_pico(halfH, src, SIZE, stride);\
++    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
++    put_h264_qpel ## SIZE ## _v_lowpass_pico(halfV, full_mid, SIZE, SIZE);\
++    OPNAME ## pixels ## SIZE ## _l2(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc31_pico(uint8_t *dst, uint8_t *src, int stride){\
++    uint8_t full[SIZE*(SIZE+5)];\
++    uint8_t * const full_mid= full + SIZE*2;\
++    uint8_t halfH[SIZE*SIZE];\
++    uint8_t halfV[SIZE*SIZE];\
++    put_h264_qpel ## SIZE ## _h_lowpass_pico(halfH, src, SIZE, stride);\
++    copy_block ## SIZE (full, src - stride*2 + 1, SIZE,  stride, SIZE + 5);\
++    put_h264_qpel ## SIZE ## _v_lowpass_pico(halfV, full_mid, SIZE, SIZE);\
++    OPNAME ## pixels ## SIZE ## _l2(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc13_pico(uint8_t *dst, uint8_t *src, int stride){\
++    uint8_t full[SIZE*(SIZE+5)];\
++    uint8_t * const full_mid= full + SIZE*2;\
++    uint8_t halfH[SIZE*SIZE];\
++    uint8_t halfV[SIZE*SIZE];\
++    put_h264_qpel ## SIZE ## _h_lowpass_pico(halfH, src + stride, SIZE, stride);\
++    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
++    put_h264_qpel ## SIZE ## _v_lowpass_pico(halfV, full_mid, SIZE, SIZE);\
++    OPNAME ## pixels ## SIZE ## _l2(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc33_pico(uint8_t *dst, uint8_t *src, int stride){\
++    uint8_t full[SIZE*(SIZE+5)];\
++    uint8_t * const full_mid= full + SIZE*2;\
++    uint8_t halfH[SIZE*SIZE];\
++    uint8_t halfV[SIZE*SIZE];\
++    put_h264_qpel ## SIZE ## _h_lowpass_pico(halfH, src + stride, SIZE, stride);\
++    copy_block ## SIZE (full, src - stride*2 + 1, SIZE,  stride, SIZE + 5);\
++    put_h264_qpel ## SIZE ## _v_lowpass_pico(halfV, full_mid, SIZE, SIZE);\
++    OPNAME ## pixels ## SIZE ## _l2(dst, halfH, halfV, stride, SIZE, SIZE, SIZE);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc22_pico(uint8_t *dst, uint8_t *src, int stride){\
++    OPNAME ## h264_qpel ## SIZE ## _hv_lowpass_pico(dst, src, stride, stride);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc21_pico(uint8_t *dst, uint8_t *src, int stride){\
++    uint8_t halfH[SIZE*SIZE];\
++    uint8_t halfHV[SIZE*SIZE];\
++    put_h264_qpel ## SIZE ## _h_lowpass_pico(halfH, src, SIZE, stride);\
++    put_h264_qpel ## SIZE ## _hv_lowpass_pico(halfHV, src, SIZE, stride);\
++    OPNAME ## pixels ## SIZE ## _l2(dst, halfH, halfHV, stride, SIZE, SIZE, SIZE);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc23_pico(uint8_t *dst, uint8_t *src, int stride){\
++    uint8_t halfH[SIZE*SIZE];\
++    uint8_t halfHV[SIZE*SIZE];\
++    put_h264_qpel ## SIZE ## _h_lowpass_pico(halfH, src + stride, SIZE, stride);\
++    put_h264_qpel ## SIZE ## _hv_lowpass_pico(halfHV, src, SIZE, stride);\
++    OPNAME ## pixels ## SIZE ## _l2(dst, halfH, halfHV, stride, SIZE, SIZE, SIZE);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc12_pico(uint8_t *dst, uint8_t *src, int stride){\
++    uint8_t full[SIZE*(SIZE+5)];\
++    uint8_t * const full_mid= full + SIZE*2;\
++    uint8_t halfV[SIZE*SIZE];\
++    uint8_t halfHV[SIZE*SIZE];\
++    copy_block ## SIZE (full, src - stride*2, SIZE,  stride, SIZE + 5);\
++    put_h264_qpel ## SIZE ## _v_lowpass_pico(halfV, full_mid, SIZE, SIZE);\
++    put_h264_qpel ## SIZE ## _hv_lowpass_pico(halfHV, src, SIZE, stride);\
++    OPNAME ## pixels ## SIZE ## _l2(dst, halfV, halfHV, stride, SIZE, SIZE, SIZE);\
++}\
++\
++static void OPNAME ## h264_qpel ## SIZE ## _mc32_pico(uint8_t *dst, uint8_t *src, int stride){\
++    uint8_t full[SIZE*(SIZE+5)];\
++    uint8_t * const full_mid= full + SIZE*2;\
++    uint8_t halfV[SIZE*SIZE];\
++    uint8_t halfHV[SIZE*SIZE];\
++    copy_block ## SIZE (full, src - stride*2 + 1, SIZE,  stride, SIZE + 5);\
++    put_h264_qpel ## SIZE ## _v_lowpass_pico(halfV, full_mid, SIZE, SIZE);\
++    put_h264_qpel ## SIZE ## _hv_lowpass_pico(halfHV, src, SIZE, stride);\
++    OPNAME ## pixels ## SIZE ## _l2(dst, halfV, halfHV, stride, SIZE, SIZE, SIZE);\
++}\
++
++H264_MC(put_, 4)
++H264_MC(put_, 8)
++H264_MC(put_, 16)
++H264_MC(avg_, 4)
++H264_MC(avg_, 8)
++H264_MC(avg_, 16)
++
++
++
++#define dspfunc16(PFX) \
++    void PFX ## _pixels16_avr32(uint8_t *dst, const uint8_t *pixels, int line_size, int h ){ \
++          PFX ## _pixels8_avr32(dst, pixels, line_size, h);\
++          PFX ## _pixels8_avr32(dst + 8, pixels + 8, line_size, h);\
++    }\
++    void PFX ## _pixels16_h_avr32(uint8_t *dst, const uint8_t *pixels, int line_size, int h ){ \
++          PFX ## _pixels8_h_avr32(dst, pixels, line_size, h);\
++          PFX ## _pixels8_h_avr32(dst + 8, pixels + 8, line_size, h);\
++    }\
++    void PFX ## _pixels16_v_avr32(uint8_t *dst, const uint8_t *pixels, int line_size, int h ){ \
++          PFX ## _pixels8_v_avr32(dst, pixels, line_size, h);\
++          PFX ## _pixels8_v_avr32(dst + 8, pixels + 8, line_size, h);\
++    }\
++    void PFX ## _pixels16_hv_avr32(uint8_t *dst, const uint8_t *pixels, int line_size, int h ){ \
++          PFX ## _pixels8_hv_avr32(dst, pixels, line_size, h);\
++          PFX ## _pixels8_hv_avr32(dst + 8, pixels + 8, line_size, h);\
++    }\
++
++
++dspfunc16(put)
++dspfunc16(put_no_rnd)
++dspfunc16(avg)
++dspfunc16(avg_no_rnd)
++#undef dspfunc16
++
++static int pix_sum_avr32(uint8_t * pix, int line_size)
++{
++    int s, i;
++
++    s = 0;
++    for (i = 0; i < 16; i++) {
++      int tmp1,tmp2,tmp3,tmp4,tmp5;
++      __asm__ volatile ( "ld.w\t%0, %6[0]\n\t"
++                         "ld.w\t%1, %6[4]\n\t"
++                         "ld.w\t%2, %6[8]\n\t"
++                         "ld.w\t%3, %6[12]\n\t"
++                         "punpckub.h\t%4, %0:t\n\t"
++                         "padd.h\t%5, %5, %4\n\t"
++                         "punpckub.h\t%4, %0:b\n\t"
++                         "padd.h\t%5, %5, %4\n\t"
++                         "punpckub.h\t%4, %1:t\n\t"
++                         "padd.h\t%5, %5, %4\n\t"
++                         "punpckub.h\t%4, %1:b\n\t"
++                         "padd.h\t%5, %5, %4\n\t"
++                         "punpckub.h\t%4, %2:t\n\t"
++                         "padd.h\t%5, %5, %4\n\t"
++                         "punpckub.h\t%4, %2:b\n\t"
++                         "padd.h\t%5, %5, %4\n\t"
++                         "punpckub.h\t%4, %3:t\n\t"
++                         "padd.h\t%5, %5, %4\n\t"
++                         "punpckub.h\t%4, %3:b\n\t"
++                         "padd.h\t%5, %5, %4\n\t"
++                         : "=&r"(tmp1),"=&r"(tmp2),"=&r"(tmp3),"=&r"(tmp4),"=&r"(tmp5),"=&r"(s)
++                         : "r"(pix));
++      pix += line_size;
++    }
++    __asm__ volatile ( "addhh.w\t%0, %0:t, %0:b" : "=&r" (s) );
++
++    return s;
++}
++
++
++//#define op_scale1(x)  block[x] = clip_uint8( (block[x]*weight + offset) >> log2_denom )
++//#define op_scale2(x)  dst[x] = clip_uint8( (src[x]*weights + dst[x]*weightd + offset) >> (log2_denom+1))
++//#define H264_WEIGHT(W,H) \
++//static void weight_h264_pixels ## W ## x ## H ## _c(uint8_t *block, int stride, int log2_denom, int weight, int offset){ \
++//    int attribute_unused x, y; \
++//    offset <<= log2_denom; \
++//    if(log2_denom) offset += 1<<(log2_denom-1); \
++//    for(y=0; y<H; y++, block += stride){ \
++//      uint32_t tmp0, tmp1;
++//      if(W==2) { \
++//        asm volatile ( "ld.ub\t%[tmp0], %[block][0]\n" \
++//                       "ld.ub\t%[tmp1], %[block][1]\n" \
++//                       "mulhh.w\t%[tmp0], %[tmp0]:b, %[weight]:b\n" \
++//                       "mulhh.w\t%[tmp1], %[tmp1]:b, %[weight]:b\n" \
++//                       "asr\t%[tmp0], %[log2_denom]\n" \
++//                       "asr\t%[tmp1], %[log2_denom]\n" \
++//                       "satu\t%[tmp0] >> 0, 8\n" \
++//                       "satu\t%[tmp1] >> 0, 8\n" \
++//                       "st.b\t%[block][0], %[tmp0]\n" \
++//                       "st.b\t%[block][1], %[tmp1]\n" \
++//                       : [tmp0] "=&r"(tmp0), [tmp1] "=&r"(tmp1) \
++//                       : [block] "r"(block), [weight]"r"(weight), [log2_denom]"r"(log2denom) ); \     
++//      } else if ( W==4 ) { \
++//        asm volatile ( "ld.w\t%[tmp0], %[block][0]\n" \
++//                       "punpckub.h\t%[tmp1], %[tmp0]:t\n" \
++//                       "punpckub.h\t%[tmp0], %[tmp0]:b\n" \
++//                       "mulhh.w\t%[tmp2], %[tmp1]:t, %[weight]:b\n" \
++//                       "mulhh.w\t%[tmp1], %[tmp1]:b, %[weight]:b\n" \
++//                       "asr\t%[tmp0], %[log2_denom]\n" \
++//                       "asr\t%[tmp1], %[log2_denom]\n" \
++//                       "satu\t%[tmp0] >> 0, 8\n" \
++//                       "satu\t%[tmp1] >> 0, 8\n" \
++//                       "st.b\t%[block][0], %[tmp0]\n" \
++//                       "st.b\t%[block][1], %[tmp1]\n" \
++//                       : [tmp0] "=&r"(tmp0), [tmp1] "=&r"(tmp1) \
++//                       : [block] "r"(block), [weight]"r"(weight), [log2_denom]"r"(log2denom) ); \     
++//
++//
++//
++//        if(W==4) continue; \
++//        op_scale1(4); \
++//        op_scale1(5); \
++//        op_scale1(6); \
++//        op_scale1(7); \
++//        if(W==8) continue; \
++//        op_scale1(8); \
++//        op_scale1(9); \
++//        op_scale1(10); \
++//        op_scale1(11); \
++//        op_scale1(12); \
++//        op_scale1(13); \
++//        op_scale1(14); \
++//        op_scale1(15); \
++//    } \
++//} \
++//static void biweight_h264_pixels ## W ## x ## H ## _c(uint8_t *dst, uint8_t *src, int stride, int log2_denom, int weightd, int weights, int offsetd, int offsets){ \
++//    int attribute_unused x, y; \
++//    int offset = (offsets + offsetd + 1) >> 1; \
++//    offset = ((offset << 1) + 1) << log2_denom; \
++//    for(y=0; y<H; y++, dst += stride, src += stride){ \
++//        op_scale2(0); \
++//        op_scale2(1); \
++//        if(W==2) continue; \
++//        op_scale2(2); \
++//        op_scale2(3); \
++//        if(W==4) continue; \
++//        op_scale2(4); \
++//        op_scale2(5); \
++//        op_scale2(6); \
++//        op_scale2(7); \
++//        if(W==8) continue; \
++//        op_scale2(8); \
++//        op_scale2(9); \
++//        op_scale2(10); \
++//        op_scale2(11); \
++//        op_scale2(12); \
++//        op_scale2(13); \
++//        op_scale2(14); \
++//        op_scale2(15); \
++//    } \
++//}
++
++
++
++/* Returns zero in each byte where the absolute difference between <a> and <b>
++   is not less than <compare> */
++#define PABS_DIFF_LESS_THAN( a, b, compare) \
++  ({  uint32_t __tmp__, __tmp2__, __mask__; \
++      asm ( \
++      /* Check ABS( a - b ) < compare */  \
++        "psubs.ub\t%[tmp], %[opa], %[opb]\n"  \
++        "psubs.ub\t%[tmp2], %[opb], %[opa]\n" \
++        "or\t%[tmp], %[tmp2]\n" /* ABS ( a - b ) */ \
++        /* This produces 0 for all bytes where the comparison is not true */ \
++        "psubs.ub\t%[mask], %[cmp], %[tmp]\n" \
++        : [tmp] "=&r"(__tmp__), [tmp2] "=&r"(__tmp2__), [mask] "=&r"(__mask__)  \
++        : [opa] "r"(a), [opb] "r"(b), [cmp] "r"(compare)  ); \
++      __mask__; })
++
++/* 
++   Set all bytes containing zero in <value> to 255 and the rest to zero.
++   
++   Add with saturation 254 to all bytes making all bytes different from 
++   zero become 255. Then add one without saturation to make all bytes 
++   originally containing zero 255 and the rest 0. */ 
++#define SET_ALL_BITS_IN_ZERO_BYTES(value) \
++  ({  uint32_t __tmp__; \
++      asm ( \
++        "padds.ub\t%[tmp], %[val], %[max_minus_one]\n"  \
++        "padd.b\t%[tmp], %[tmp], %[all_ones]\n" \
++        : [tmp] "=r"(__tmp__) \
++        : [val] "r"(value), [max_minus_one] "r"(0xFEFEFEFE), [all_ones] "r"(0x01010101) ); \
++      __tmp__; })
++
++#define  PACKW_SH(upper, lower) \
++  ({  uint32_t __tmp__; \
++      asm ( \
++        "packw.sh\t%[tmp], %[u], %[l]\n"  \
++        : [tmp] "=r"(__tmp__) \
++        : [u] "r"(upper), [l] "r"(lower) ); \
++      __tmp__; })
++
++#define  PACKSH_UB(upper, lower) \
++  ({  uint32_t __tmp__; \
++      asm ( \
++        "packsh.sb\t%[tmp], %[u], %[l]\n"  \
++        : [tmp] "=r"(__tmp__) \
++        : [u] "r"(upper), [l] "r"(lower) ); \
++      __tmp__; })
++
++static  void h264_v_loop_filter_luma_avr32(uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0)
++{
++  int i;
++  
++  if ( alpha == 0 )
++    return;
++  
++  alpha = PACKW_SH(alpha, alpha);
++  alpha = PACKSH_UB(alpha, alpha);
++  beta = PACKW_SH(beta, beta);
++  beta = PACKSH_UB(beta, beta);
++
++  for( i = 0; i < 4; i++ ) {
++    uint32_t p0, p1, p2, q0, q1, q2;
++    uint32_t mask, mask2;
++    uint32_t tmp, tmp2, tmp3, tmp4;
++
++    if( tc0[i] < 0 ) {
++      pix += 4;
++      continue;
++    }
++
++/*    for( d = 0; d < 4; d++ ) {
++       const int p0 = pix[-1*stride];
++       const int p1 = pix[-2*stride];
++       const int p2 = pix[-3*stride];
++       const int q0 = pix[0];
++       const int q1 = pix[1*stride];
++       const int q2 = pix[2*stride];
++      
++       if( ABS( p0 - q0 ) < alpha &&
++           ABS( p1 - p0 ) < beta &&
++           ABS( q1 - q0 ) < beta ) { */
++
++    p0 = LD32(pix - stride);
++    p1 = LD32(pix - 2*stride);
++    q0 = LD32(pix);
++    q1 = LD32(pix + stride);
++    
++    /* Check which of the columns should be filtered, if any. */
++    mask = PABS_DIFF_LESS_THAN(p0, q0, alpha);
++    mask |= PABS_DIFF_LESS_THAN(p1, p0, beta);
++    mask |= PABS_DIFF_LESS_THAN(q1, q0, beta);
++        
++    if ( !mask )
++      continue;
++        
++    mask = SET_ALL_BITS_IN_ZERO_BYTES(mask);
++    
++
++    int tc =  PACKW_SH(tc0[i], tc0[i]);
++    int tc0_p = tc;
++    int tc0_m = PACKW_SH(-tc0[i], -tc0[i]);
++
++    /*
++      int i_delta;
++      if( ABS( p2 - p0 ) < beta ) {
++      pix[-2*stride] = p1 + clip( (( p2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - p1, -tc0[i], tc0[i] );
++      tc++;
++      }*/ 
++
++    p2 = LD32(pix - 3*stride);
++    mask2 = PABS_DIFF_LESS_THAN(p2, p0, beta) & ~mask;
++    
++    if ( mask2 ){
++      mask2 = SET_ALL_BITS_IN_ZERO_BYTES(mask2);
++      asm ("pavg.ub\t%[tmp], %[p0], %[q0]\n"
++           "paddh.ub\t%[tmp], %[tmp], %[p2]\n"
++           "punpckub.h\t%[tmp2], %[tmp]:t\n"
++           "punpckub.h\t%[tmp], %[tmp]:b\n"
++           "punpckub.h\t%[tmp3], %[p1]:t\n"
++           "punpckub.h\t%[tmp4], %[p1]:b\n"
++           "psub.h\t%[tmp2], %[tmp2], %[tmp3]\n"
++           "psub.h\t%[tmp], %[tmp], %[tmp4]\n"
++           "pmin.sh\t%[tmp2], %[tmp2], %[tc0_p]\n"
++           "pmin.sh\t%[tmp], %[tmp], %[tc0_p]\n"
++           "pmax.sh\t%[tmp2], %[tmp2], %[tc0_m]\n"
++           "pmax.sh\t%[tmp], %[tmp], %[tc0_m]\n"
++           "padd.h\t%[tmp2], %[tmp2], %[tmp3]\n"
++           "padd.h\t%[tmp], %[tmp], %[tmp4]\n"
++           "packsh.ub\t%[tmp], %[tmp2], %[tmp]\n"
++           "andn\t%[tmp], %[mask2]\n"
++           "and\t%[tmp2], %[q1], %[mask2]\n"
++           "or\t%[tmp], %[tmp2]\n"
++           : [tmp]"=&r"(tmp), [tmp2]"=&r"(tmp2), [tmp3]"=&r"(tmp3),
++           [tmp4]"=&r"(tmp4)
++           : [q0]"r"(q0), [p2]"r"(p2), [p1]"r"(p1), [p0]"r"(p0), [q1]"r"(q1), [tc0_p]"r"(tc0_p),
++           [tc0_m]"r"(tc0_m), [mask2]"r"(mask2));
++      ST32(pix - 2*stride, tmp);      
++      tc += 0x00010001;
++    }
++
++        
++    q2 = LD32(pix + 2*stride);
++
++    /*
++      if( ABS( q2 - q0 ) < beta ) {
++      pix[   stride] = q1 + clip( (( q2 + ( ( p0 + q0 + 1 ) >> 1 ) ) >> 1) - q1, -tc0[i], tc0[i] );
++      tc++;
++      }
++    */
++    mask2 = PABS_DIFF_LESS_THAN(q2, q0, beta) & ~mask;
++
++    if ( mask2 ){
++      mask2 = SET_ALL_BITS_IN_ZERO_BYTES(mask2);
++      asm ("pavg.ub\t%[tmp], %[p0], %[q0]\n"
++           "paddh.ub\t%[tmp], %[tmp], %[q2]\n"
++           "punpckub.h\t%[tmp2], %[tmp]:t\n"
++           "punpckub.h\t%[tmp], %[tmp]:b\n"
++           "punpckub.h\t%[tmp3], %[q1]:t\n"
++           "punpckub.h\t%[tmp4], %[q1]:b\n"
++           "psub.h\t%[tmp2], %[tmp2], %[tmp3]\n"
++           "psub.h\t%[tmp], %[tmp], %[tmp4]\n"
++           "pmin.sh\t%[tmp2], %[tmp2], %[tc0_p]\n"
++           "pmin.sh\t%[tmp], %[tmp], %[tc0_p]\n"
++           "pmax.sh\t%[tmp2], %[tmp2], %[tc0_m]\n"
++           "pmax.sh\t%[tmp], %[tmp], %[tc0_m]\n"
++           "padd.h\t%[tmp2], %[tmp2], %[tmp3]\n"
++           "padd.h\t%[tmp], %[tmp], %[tmp4]\n"
++           "packsh.ub\t%[tmp], %[tmp2], %[tmp]\n"
++           "andn\t%[tmp], %[mask2]\n"
++           "and\t%[tmp2], %[q1], %[mask2]\n"
++           "or\t%[tmp], %[tmp2]\n"
++           : [tmp]"=&r"(tmp), [tmp2]"=&r"(tmp2), [tmp3]"=&r"(tmp3),
++           [tmp4]"=&r"(tmp4)
++           : [q0]"r"(q0), [q2]"r"(q2), [q1]"r"(q1), [p0]"r"(p0), [tc0_p]"r"(tc0_p),
++           [tc0_m]"r"(tc0_m), [mask2]"r"(mask2));
++      ST32(pix + stride, tmp); 
++      tc += 0x00010001;
++    }
++
++    uint32_t old_p0 = p0;
++    uint32_t old_q0 = q0;
++    
++    /* i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc );
++       pix[-stride] = clip_uint8( p0 + i_delta );   
++       pix[0]        = clip_uint8( q0 - i_delta );  */ 
++    
++    asm (
++         /* Check if the two upper pixels should be filtered */
++         "lsr\t%[tmp], %[inv_mask], 16\n"
++         "breq\t0f\n"
++
++         "punpckub.h\t%[tmp], %[p1]:t\n"
++         "punpckub.h\t%[tmp2], %[q1]:t\n"
++         
++         /* p1 - q1 */
++         "psub.h\t%[tmp], %[tmp], %[tmp2]\n"
++
++         "punpckub.h\t%[tmp3], %[q0]:t\n"
++         "punpckub.h\t%[tmp4], %[p0]:t\n"
++
++         /* q0 - p0 */
++         "psub.h\t%[tmp2], %[tmp3], %[tmp4]\n"
++         
++         /* (q0 - p0) << 2 */
++         "plsl.h\t%[tmp2], %[tmp2], 2\n"
++
++         /* ((q0 - p0) << 2) + (p1 - q1) */
++         "padd.h\t%[tmp2], %[tmp2], %[tmp]\n"
++
++         "mov\t%[tmp], 0x00040004\n"
++         /* ((q0 - p0) << 2) + (p1 - q1) + 4*/
++         "padd.h\t%[tmp2], %[tmp2], %[tmp]\n"
++
++         /* (((q0 - p0) << 2) + (p1 - q1) + 4) >> 3*/
++         "pasr.h\t%[tmp2], %[tmp2], 3\n"
++
++         "mov\t%[tmp], 0\n"
++         "psub.h\t%[tmp], %[tmp], %[tc]\n"
++
++         /* i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); */
++         "pmin.sh\t%[tmp2], %[tmp2], %[tc]\n"
++         "pmax.sh\t%[tmp2], %[tmp2], %[tmp]\n"
++
++
++         /* pix[-stride] = clip_uint8( p0 + i_delta ); */
++         "padd.h\t%[tmp4], %[tmp4], %[tmp2]\n"
++
++         
++         /* pix[0]        = clip_uint8( q0 - i_delta ); */
++         "psub.h\t%[tmp3], %[tmp3], %[tmp2]\n"
++
++         /* Check if the two lower pixels should be filtered */
++         "lsl\t%[tmp2], %[inv_mask], 16\n"
++         "breq\t1f\n"
++
++         "0:\n"
++         "punpckub.h\t%[p1], %[p1]:b\n"
++         "punpckub.h\t%[q1], %[q1]:b\n"
++
++         /* p1 - q1 */
++         "psub.h\t%[p1], %[p1], %[q1]\n"
++
++         "punpckub.h\t%[q0], %[q0]:b\n"
++         "punpckub.h\t%[p0], %[p0]:b\n"
++
++         /* q0 - p0 */
++         "psub.h\t%[tmp2], %[q0], %[p0]\n"
++
++         /* (q0 - p0) << 2 */
++         "plsl.h\t%[tmp2], %[tmp2], 2\n"
++
++         /* ((q0 - p0) << 2) + (p1 - q1) */
++         "padd.h\t%[tmp2], %[tmp2], %[p1]\n"
++
++         "mov\t%[q1], 0x00040004\n"
++         /* ((q0 - p0) << 2) + (p1 - q1) + 4*/
++         "padd.h\t%[tmp2], %[tmp2], %[q1]\n"
++
++         /* (((q0 - p0) << 2) + (p1 - q1) + 4) >> 3*/
++         "pasr.h\t%[tmp2], %[tmp2], 3\n"
++ 
++         /* i_delta = clip( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3, -tc, tc ); */
++         "pmin.sh\t%[tmp2], %[tmp2], %[tc]\n"
++         "pmax.sh\t%[tmp2], %[tmp2], %[tmp]\n"
++
++         /* pix[-stride] = clip_uint8( p0 + i_delta ); */
++         "padd.h\t%[p0], %[p0], %[tmp2]\n"
++
++         /* pix[0]        = clip_uint8( q0 - i_delta ); */
++         "psub.h\t%[q0], %[q0], %[tmp2]\n"
++
++         "1:\n"
++         "packsh.ub\t%[p0], %[tmp4], %[p0]\n"
++         "packsh.ub\t%[q0], %[tmp3], %[tmp4]\n"
++
++         : [tmp]"=&r"(tmp), [tmp2]"=&r"(tmp2), [tmp3]"=&r"(tmp3),
++         [tmp4]"=&r"(tmp4), [q0]"=&r"(q0), [q1]"=&r"(q1), [p0]"=&r"(p0), [p1]"=&r"(p1)
++         : [tc]"r"(tc), [inv_mask]"r"(~mask));
++    
++    ST32(pix - stride, (mask & old_p0) | (p0 & ~mask));
++    ST32(pix, (mask & old_q0) | (q0 & ~mask));
++    
++  }
++  pix += 1;
++}
++
++
++
++
++#ifdef CHECK_DSP_FUNCS_AGAINST_C
++
++void dump_block8(uint8_t *block, int line_size, int h){
++  int i, j;
++
++  for ( i = 0; i < h ; i++ ){
++    av_log(NULL, AV_LOG_ERROR, "\t"); 
++    for ( j = 0; j < 8 ; j++ ){
++      av_log(NULL, AV_LOG_ERROR, "%d ", block[j + i*line_size]); 
++    }
++    av_log(NULL, AV_LOG_ERROR, "\n"); 
++  }
++}
++
++void dump_block4(uint8_t *block, int line_size, int h){
++  int i, j;
++
++  for ( i = 0; i < h ; i++ ){
++    av_log(NULL, AV_LOG_ERROR, "\t"); 
++    for ( j = 0; j < 4 ; j++ ){
++      av_log(NULL, AV_LOG_ERROR, "%d ", block[j + i*line_size]); 
++    }
++    av_log(NULL, AV_LOG_ERROR, "\n"); 
++  }
++}
++
++void dump_block(uint8_t *block, int line_size, int h, int w){
++  int i, j;
++
++  for ( i = 0; i < h ; i++ ){
++    av_log(NULL, AV_LOG_ERROR, "\t"); 
++    for ( j = 0; j < w ; j++ ){
++      av_log(NULL, AV_LOG_ERROR, "%d ", block[j + i*line_size]); 
++    }
++    av_log(NULL, AV_LOG_ERROR, "\n"); 
++  }
++}
++
++void check_block8(uint8_t *test, uint8_t *correct, int line_size_test, int line_size_correct, 
++                  int h, char *name, int max_dev){
++  int i,j;
++  for ( i = 0; i < 8 ; i++ ){
++    for ( j = 0; j < h ; j++ ){
++      int diff = test[i + line_size_test*j] - correct[i + line_size_correct*j];
++      diff = diff < 0 ? -diff : diff;
++      if ( diff > max_dev ){
++        av_log(NULL, AV_LOG_ERROR, "Error pixel x=%i, y=%i differs. Is 0x%x should be 0x%x\n", 
++               i, j, test[i + line_size_test*j], correct[i + j*line_size_correct]);        
++        av_log(NULL, AV_LOG_ERROR, "Error resulting block from %s is:\n", name);
++        dump_block8(test, line_size_test, h); 
++        av_log(NULL, AV_LOG_ERROR, "But should be equal to:\n");
++        dump_block8(correct, line_size_correct, h);         
++        exit(1);
++      }
++    }
++  }  
++}
++
++void check_block4(uint8_t *test, uint8_t *correct, int line_size_test, int line_size_correct, 
++                  int h, char *name, int max_dev){
++  int i,j;
++  for ( i = 0; i < 4 ; i++ ){
++    for ( j = 0; j < h ; j++ ){
++      int diff = test[i + line_size_test*j] - correct[i + line_size_correct*j];
++      diff = diff < 0 ? -diff : diff;
++      if ( diff > max_dev ){
++        av_log(NULL, AV_LOG_ERROR, "Error pixel x=%i, y=%i differs. Is 0x%x should be 0x%x\n", 
++               i, j, test[i + line_size_test*j], correct[i + j*line_size_correct]);        
++        av_log(NULL, AV_LOG_ERROR, "Error resulting block from %s is:\n", name);
++        dump_block8(test, line_size_test, h); 
++        av_log(NULL, AV_LOG_ERROR, "But should be equal to:\n");
++        dump_block4(correct, line_size_correct, h);         
++        exit(1);
++      }
++    }
++  }  
++}
++
++void check_block(uint8_t *test, uint8_t *correct, int line_size_test, int line_size_correct, 
++                 int h, int width, char *name, int max_dev){
++  int i,j;
++  for ( i = 0; i < width ; i++ ){
++    for ( j = 0; j < h ; j++ ){
++      int diff = test[i + line_size_test*j] - correct[i + line_size_correct*j];
++      diff = diff < 0 ? -diff : diff;
++      if ( diff > max_dev ){
++        av_log(NULL, AV_LOG_ERROR, "Error pixel x=%i, y=%i differs. Is 0x%x should be 0x%x\n", 
++               i, j, test[i + line_size_test*j], correct[i + j*line_size_correct]);        
++        av_log(NULL, AV_LOG_ERROR, "Error resulting block from %s is:\n", name);
++        dump_block(test, line_size_test, h, width); 
++        av_log(NULL, AV_LOG_ERROR, "But should be equal to:\n");
++        dump_block(correct, line_size_correct, h, width);         
++        exit(1);
++      }
++    }
++  }  
++}
++
++void dump_dct_block(DCTELEM *block){
++  int i, j;
++
++  for ( i = 0; i < 8 ; i++ ){
++    av_log(NULL, AV_LOG_ERROR, "\t"); 
++    for ( j = 0; j < 8 ; j++ ){
++      av_log(NULL, AV_LOG_ERROR, "0x%x ", block[j + i*8]); 
++    }
++    av_log(NULL, AV_LOG_ERROR, "\n"); 
++  }
++}
++
++void test_idct_avr32(DCTELEM *block){
++  DCTELEM testBlock[64];
++  int i, j;
++
++  /* Copy transposed block to testBlock */ 
++  for ( i = 0; i < 8 ; i++ ){
++    for ( j = 0; j < 8 ; j++ ){
++      testBlock[i + 8*j] = block[j + i*8]; 
++    }
++  }
++  
++  idct_avr32(block);
++  simple_idct(&testBlock);
++  
++  for ( i = 0; i < 64 ; i++ ){
++    if ( block[i] != testBlock[i] ){
++      av_log(NULL, AV_LOG_ERROR, "Error resulting block from idct is:\n");
++      dump_dct_block(block); 
++      av_log(NULL, AV_LOG_ERROR, "But should be equal to the transposed of:\n");
++      dump_dct_block(testBlock);         
++      exit(1);
++    }
++  }
++}
++
++void test_idct_put_avr32(uint8_t *dest, int line_size, DCTELEM *block){
++  uint8_t testBlock[64];
++  DCTELEM blockCopy[64];
++  int i, j;
++
++  /* Copy transposed block to blockCopy */ 
++  for ( i = 0; i < 8 ; i++ ){
++    for ( j = 0; j < 8 ; j++ ){
++      blockCopy[i + 8*j] = block[j + i*8]; 
++    }
++  }
++
++  idct_put_avr32(dest, line_size, block);
++  simple_idct_put(&testBlock, 8, blockCopy);
++  
++  check_block8(dest, testBlock, line_size, 8, 8, "idct_put", 1);
++}
++
++
++void test_idct_add_avr32(uint8_t *dest, int line_size, DCTELEM *block){
++  uint8_t testBlock[64];
++  DCTELEM blockCopy[64];
++  int i, j;
++  
++  /* Copy dest to testBlock */ 
++  for ( i = 0; i < 8 ; i++ ){
++    for ( j = 0; j < 8 ; j++ ){
++      testBlock[i + 8*j] = dest[i + j*line_size]; 
++    }
++  }
++
++  /* Copy transposed block to blockCopy */ 
++  for ( i = 0; i < 8 ; i++ ){
++    for ( j = 0; j < 8 ; j++ ){
++      blockCopy[i + 8*j] = block[j + i*8]; 
++    }
++  }
++
++  idct_add_avr32(dest, line_size, block);
++  simple_idct_add(&testBlock, 8, blockCopy);
++  
++  check_block8(dest, testBlock, line_size, 8, 8, "idct_add", 1);
++}
++
++void test_h264_idct_add_avr32(uint8_t *dest, DCTELEM *block, int stride){
++  uint8_t testBlock[16];
++  DCTELEM blockCopy[16];
++  int i, j;
++  
++  /* Copy dest to testBlock */ 
++  for ( i = 0; i < 4 ; i++ ){
++    for ( j = 0; j < 4 ; j++ ){
++      testBlock[i + 4*j] = dest[i + j*stride]; 
++    }
++  }
++
++  /* Copy transposed block to blockCopy */ 
++  for ( i = 0; i < 16 ; i++ ){
++    blockCopy[i] = block[i]; 
++  }
++
++  ff_h264_idct_add_c(dest, block, stride);
++  
++  h264_idct_add_avr32(testBlock, blockCopy, 4);
++  
++  check_block(dest, testBlock, stride, 4, 4, 4, "h264_idct_add", 0);
++}
++
++void test_h264_idct8_add_avr32(uint8_t *dest, DCTELEM *block, int stride){
++  uint8_t testBlock[8*8];
++  DCTELEM blockCopy[8*8];
++  int i, j;
++  
++  /* Copy dest to testBlock */ 
++  for ( i = 0; i < 8 ; i++ ){
++    for ( j = 0; j < 8 ; j++ ){
++      testBlock[i + 8*j] = dest[i + j*stride]; 
++    }
++  }
++
++  /* Copy source block to blockCopy */ 
++  for ( i = 0; i < 8*8 ; i++ ){
++    blockCopy[i] = block[i]; 
++  }
++
++  ff_h264_idct8_add_c(dest, block, stride);
++  h264_idct8_add_avr32(testBlock, blockCopy, 8);
++  
++  check_block(dest, testBlock, stride, 8, 8, 8, "h264_idct8_add", 0);
++}
++
++void test_put_pixels_funcs8(op_pixels_func test, op_pixels_func correct, uint8_t *block, 
++                       const uint8_t *pixels, int line_size, int h, char *name, int in_h_size, int in_v_size){
++  uint8_t *testBlock, *testBlock2;
++  int i, j;
++  int input_v_size = h + in_v_size;
++  int input_h_size = 8 + in_h_size;
++
++  testBlock = alloca(input_h_size*input_v_size);
++  testBlock2 = alloca(input_h_size*input_v_size);
++
++  for ( i = 0; i < input_h_size ; i++ ){
++    for ( j = 0; j < input_v_size ; j++ ){
++      testBlock[i + input_h_size*j] = pixels[i + j*line_size]; 
++    }
++  }
++
++  test(block, pixels, line_size, h);
++  correct(testBlock2, testBlock, input_h_size, h);
++  
++  check_block8(block, testBlock2, line_size, input_h_size, h, name, 0);
++
++} 
++
++void test_h264_chroma_mc_funcs(h264_chroma_mc_func test, h264_chroma_mc_func correct, uint8_t *dst, 
++                               uint8_t *src, int stride, int h, int w, int x, int y, char *name){
++  uint8_t *testBlock, *testBlock2;
++  int i, j;
++  int input_v_size = h + 1;
++  int input_h_size = ((w + 1) + 3) & ~3;
++
++  testBlock = alloca(input_h_size*input_v_size);
++  testBlock2 = alloca(input_h_size*input_v_size);
++
++  for ( i = 0; i < w + 1 ; i++ ){
++    for ( j = 0; j < h + 1 ; j++ ){
++      testBlock[i + input_h_size*j] = src[i + j*stride]; 
++    }
++  }
++
++  for ( i = 0; i < w ; i++ ){
++    for ( j = 0; j < h ; j++ ){
++      testBlock2[i + input_h_size*j] = dst[i + j*stride]; 
++    }
++  }
++
++  test(dst, src, stride, h, x, y);
++  correct(testBlock2, testBlock, input_h_size, h, x, y);
++  
++  check_block(dst, testBlock2, stride, input_h_size, h, w, name, 0);
++
++} 
++
++void test_qpel_mc_funcs(qpel_mc_func test, qpel_mc_func correct, uint8_t *dst, 
++                        uint8_t *src, int stride, int size, char *name){
++  uint8_t *testBlock, *testBlock2;
++  int i, j;
++  int test_stride = size + 8;
++
++  testBlock = alloca(test_stride*(size+8)) + 4 + test_stride*4;
++  testBlock2 = alloca(test_stride*size);
++  
++  for ( i = -4; i < size+4 ; i++ ){
++    for ( j = -4; j < size+4 ; j++ ){
++      testBlock[i + test_stride*j] = src[i + j*stride]; 
++    }
++  }
++  
++  for ( i = 0; i < size ; i++ ){
++    for ( j = 0; j < size ; j++ ){
++      testBlock2[i + test_stride*j] = dst[i + j*stride]; 
++    }
++  }
++
++  correct(dst, src, stride);
++  test(testBlock2, testBlock, test_stride);
++  
++  check_block(testBlock2, dst, test_stride, stride, size, size, name, 0);
++
++} 
++
++
++#define test_pixels_funcs(PFX, NUM ) \
++void test_ ## PFX ## _pixels ## NUM ## _avr32( uint8_t *block, const uint8_t *pixels, int line_size, int h){ \
++  test_put_pixels_funcs8(PFX ## _pixels ## NUM ## _avr32, PFX ## _pixels ## NUM ## _c, \
++                         block, pixels, line_size, h, "test_" #PFX "_pixels", 0, 0); } \
++void test_ ## PFX ## _pixels ## NUM ## _h_avr32( uint8_t *block, const uint8_t *pixels, int line_size, int h){ \
++  test_put_pixels_funcs8(PFX ## _pixels ## NUM ## _h_avr32, PFX ## _pixels ## NUM ## _x2_c, \
++                         block, pixels, line_size, h, "test_" #PFX "_pixels_h", 1, 0); } \
++void test_ ## PFX ## _pixels ## NUM ## _v_avr32( uint8_t *block, const uint8_t *pixels, int line_size, int h){ \
++  test_put_pixels_funcs8(PFX ## _pixels ## NUM ## _v_avr32, PFX ## _pixels ## NUM ## _y2_c, \
++                         block, pixels, line_size, h, "test_" #PFX "_pixels_v", 0, 1); } \
++void test_ ## PFX ## _pixels ## NUM ## _hv_avr32( uint8_t *block, const uint8_t *pixels, int line_size, int h){ \
++  test_put_pixels_funcs8(PFX ## _pixels ## NUM ## _hv_avr32, PFX ## _pixels ## NUM ## _xy2_c, \
++                         block, pixels, line_size, h, "test_" #PFX "_pixels_hv", 1, 1); }
++
++test_pixels_funcs(put, 8);
++test_pixels_funcs(put_no_rnd, 8);
++test_pixels_funcs(put, 16);
++test_pixels_funcs(put_no_rnd, 16);
++
++test_pixels_funcs(avg, 8);
++test_pixels_funcs(avg_no_rnd, 8);
++test_pixels_funcs(avg, 16);
++test_pixels_funcs(avg_no_rnd, 16);
++
++#define test_h264_chroma_mc_funcs(PFX, NUM ) \
++void test_ ## PFX ## _h264_chroma_mc ## NUM ## _pico( uint8_t *dst, uint8_t *src, int stride, int h, int x, int y){ \
++  test_h264_chroma_mc_funcs(PFX ## _h264_chroma_mc ## NUM ## _pico, PFX ## _h264_chroma_mc ## NUM ## _c, \
++                         dst, src, stride, h, NUM, x, y, "test_" #PFX "_h264_chroma_mc" #NUM "_pico"); } \
++
++test_h264_chroma_mc_funcs(put, 2);
++test_h264_chroma_mc_funcs(put, 4);
++test_h264_chroma_mc_funcs(put, 8);
++test_h264_chroma_mc_funcs(avg, 2);
++test_h264_chroma_mc_funcs(avg, 4);
++test_h264_chroma_mc_funcs(avg, 8);
++
++#define test_qpel_mc_funcs_type(PFX, NUM, TYPE ) \
++void test_ ## PFX ## NUM ## _ ## TYPE ## _pico( uint8_t *dst, uint8_t *src, int stride){ \
++  test_qpel_mc_funcs(PFX ## NUM ## _ ## TYPE ## _pico, PFX ## NUM ## _ ## TYPE ## _c, \
++                         dst, src, stride, NUM, "test_" #PFX #NUM "_" #TYPE "_pico"); } 
++
++#define test_qpel_mc_funcs(PFX, NUM) \
++  test_qpel_mc_funcs_type(PFX, NUM, mc00);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc10);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc20);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc30);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc01);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc11);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc21);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc31);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc02);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc12);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc22);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc32);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc03);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc13);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc23);\
++  test_qpel_mc_funcs_type(PFX, NUM, mc33)
++
++test_qpel_mc_funcs(put_h264_qpel, 4);
++test_qpel_mc_funcs(put_h264_qpel, 8);
++test_qpel_mc_funcs(put_h264_qpel, 16);
++test_qpel_mc_funcs(avg_h264_qpel, 4);
++test_qpel_mc_funcs(avg_h264_qpel, 8);
++test_qpel_mc_funcs(avg_h264_qpel, 16);
++
++
++#define dspfunc(PFX, IDX, NUM) \
++    c->PFX ## _pixels_tab[IDX][ 0] = DSP_FUNC_NAME( PFX ## NUM ## _mc00_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 1] = DSP_FUNC_NAME( PFX ## NUM ## _mc10_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 2] = DSP_FUNC_NAME( PFX ## NUM ## _mc20_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 3] = DSP_FUNC_NAME( PFX ## NUM ## _mc30_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 4] = DSP_FUNC_NAME( PFX ## NUM ## _mc01_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 5] = DSP_FUNC_NAME( PFX ## NUM ## _mc11_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 6] = DSP_FUNC_NAME( PFX ## NUM ## _mc21_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 7] = DSP_FUNC_NAME( PFX ## NUM ## _mc31_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 8] = DSP_FUNC_NAME( PFX ## NUM ## _mc02_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 9] = DSP_FUNC_NAME( PFX ## NUM ## _mc12_pico ); \
++    c->PFX ## _pixels_tab[IDX][10] = DSP_FUNC_NAME( PFX ## NUM ## _mc22_pico ); \
++    c->PFX ## _pixels_tab[IDX][11] = DSP_FUNC_NAME( PFX ## NUM ## _mc32_pico ); \
++    c->PFX ## _pixels_tab[IDX][12] = DSP_FUNC_NAME( PFX ## NUM ## _mc03_pico ); \
++    c->PFX ## _pixels_tab[IDX][13] = DSP_FUNC_NAME( PFX ## NUM ## _mc13_pico ); \
++    c->PFX ## _pixels_tab[IDX][14] = DSP_FUNC_NAME( PFX ## NUM ## _mc23_pico ); \
++    c->PFX ## _pixels_tab[IDX][15] = DSP_FUNC_NAME( PFX ## NUM ## _mc33_pico )
++
++#endif
++
++void dsputil_init_avr32(DSPContext* c, AVCodecContext *avctx)
++{
++
++  /* H264 */
++
++  if ( 0 /*avr32_use_pico*/ ){
++    c->put_h264_chroma_pixels_tab[0]= DSP_FUNC_NAME(put_h264_chroma_mc8_pico);
++    c->put_h264_chroma_pixels_tab[1]= DSP_FUNC_NAME(put_h264_chroma_mc4_pico);
++    c->put_h264_chroma_pixels_tab[2]= DSP_FUNC_NAME(put_h264_chroma_mc2_pico);
++    
++    c->avg_h264_chroma_pixels_tab[0]= DSP_FUNC_NAME(avg_h264_chroma_mc8_pico);
++    c->avg_h264_chroma_pixels_tab[1]= DSP_FUNC_NAME(avg_h264_chroma_mc4_pico);
++    c->avg_h264_chroma_pixels_tab[2]= DSP_FUNC_NAME(avg_h264_chroma_mc2_pico);
++  }
++
++#define dspfunc(PFX, IDX, NUM) \
++    c->PFX ## _pixels_tab[IDX][ 0] = DSP_FUNC_NAME( PFX ## NUM ## _mc00_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 1] = DSP_FUNC_NAME( PFX ## NUM ## _mc10_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 2] = DSP_FUNC_NAME( PFX ## NUM ## _mc20_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 3] = DSP_FUNC_NAME( PFX ## NUM ## _mc30_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 4] = DSP_FUNC_NAME( PFX ## NUM ## _mc01_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 5] = DSP_FUNC_NAME( PFX ## NUM ## _mc11_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 6] = DSP_FUNC_NAME( PFX ## NUM ## _mc21_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 7] = DSP_FUNC_NAME( PFX ## NUM ## _mc31_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 8] = DSP_FUNC_NAME( PFX ## NUM ## _mc02_pico ); \
++    c->PFX ## _pixels_tab[IDX][ 9] = DSP_FUNC_NAME( PFX ## NUM ## _mc12_pico ); \
++    c->PFX ## _pixels_tab[IDX][10] = DSP_FUNC_NAME( PFX ## NUM ## _mc22_pico ); \
++    c->PFX ## _pixels_tab[IDX][11] = DSP_FUNC_NAME( PFX ## NUM ## _mc32_pico ); \
++    c->PFX ## _pixels_tab[IDX][12] = DSP_FUNC_NAME( PFX ## NUM ## _mc03_pico ); \
++    c->PFX ## _pixels_tab[IDX][13] = DSP_FUNC_NAME( PFX ## NUM ## _mc13_pico ); \
++    c->PFX ## _pixels_tab[IDX][14] = DSP_FUNC_NAME( PFX ## NUM ## _mc23_pico ); \
++    c->PFX ## _pixels_tab[IDX][15] = DSP_FUNC_NAME( PFX ## NUM ## _mc33_pico )
++
++  if ( avr32_use_pico ){
++    dspfunc(put_h264_qpel, 0, 16);
++    dspfunc(put_h264_qpel, 1, 8);
++    dspfunc(put_h264_qpel, 2, 4);
++    dspfunc(avg_h264_qpel, 0, 16);
++    dspfunc(avg_h264_qpel, 1, 8);
++    dspfunc(avg_h264_qpel, 2, 4);
++  }
++
++  c->idct_put= DSP_FUNC_NAME(idct_put_avr32);
++  c->idct_add= DSP_FUNC_NAME(idct_add_avr32);
++  c->idct    = DSP_FUNC_NAME(idct_avr32);
++  c->h264_idct_add = DSP_FUNC_NAME(h264_idct_add_avr32);
++  c->h264_idct8_add = DSP_FUNC_NAME(h264_idct8_add_avr32);
++
++  /*c->h264_v_loop_filter_luma= h264_v_loop_filter_luma_avr32;*/
++  
++  c->idct_permutation_type= FF_TRANSPOSE_IDCT_PERM;
++  
++  c->fdct = fdct_avr32;
++
++  c->clear_blocks = clear_blocks_avr32;
++  
++#undef dspfunc  
++#define dspfunc(PFX, IDX, NUM) \
++    c->PFX ## _pixels_tab[IDX][0] = DSP_FUNC_NAME( PFX ## _pixels ## NUM ## _avr32 );     \
++    c->PFX ## _pixels_tab[IDX][1] = DSP_FUNC_NAME( PFX ## _pixels ## NUM ## _h_avr32);  \
++    c->PFX ## _pixels_tab[IDX][2] = DSP_FUNC_NAME( PFX ## _pixels ## NUM ## _v_avr32);  \
++    c->PFX ## _pixels_tab[IDX][3] = DSP_FUNC_NAME( PFX ## _pixels ## NUM ## _hv_avr32)
++
++    dspfunc(put, 0, 16);
++    dspfunc(put_no_rnd, 0, 16);
++    dspfunc(put, 1, 8);
++    dspfunc(put_no_rnd, 1, 8);
++
++    dspfunc(avg, 1, 8);
++    dspfunc(avg_no_rnd, 1, 8);
++    dspfunc(avg, 0, 16);
++    dspfunc(avg_no_rnd, 0, 16);
++#undef dspfunc
++
++}
++
++
++
++#if 0
++int main(int argc, char *argv[]){
++  
++
++}
++#endif
++
+diff --git a/libavcodec/avr32/fdct.S b/libavcodec/avr32/fdct.S
+new file mode 100644
+index 0000000..be45b86
+--- /dev/null
++++ b/libavcodec/avr32/fdct.S
+@@ -0,0 +1,541 @@
++/*
++ * Copyright (c) 2007 Atmel Corporation. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials provided
++ * with the distribution.
++ *
++ * 3. The name of ATMEL may not be used to endorse or promote products
++ * derived from this software without specific prior written
++ * permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL
++ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
++ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
++ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
++ * DAMAGE.
++ */
++
++//********************************************************** 
++//* 2-D fDCT, Based on:                                         *
++//* C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical *
++//* Fast 1-D DCT Algorithms with 11 Multiplications",      *
++//* Proc. Int'l. Conf. on Acoustics, Speech, and Signal    *
++//* Processing 1989 (ICASSP '89), pp. 988-991.             *
++//*                                                     *
++//* Fixed point implementation optimized for the AVR-II         *     
++//* instruction set. If a table is used for the                 *
++//* coeffisients we can load two and two of them from      *
++//* This will give a reduction of 
++//*                                                     *
++//*                                                     *
++//**********************************************************
++
++
++/* This routine is a slow-but-accurate integer implementation of the
++ * forward DCT (Discrete Cosine Transform). Taken from the IJG software
++ *
++ * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
++ * on each column.  Direct algorithms are also available, but they are
++ * much more complex and seem not to be any faster when reduced to code.
++ *
++ * This implementation is based on an algorithm described in
++ *   C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
++ *   Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
++ *   Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
++ * The primary algorithm described there uses 11 multiplies and 29 adds.
++ * We use their alternate method with 12 multiplies and 32 adds.
++ * The advantage of this method is that no data path contains more than one
++ * multiplication; this allows a very simple and accurate implementation in
++ * scaled fixed-point arithmetic, with a minimal number of shifts.
++ *
++ * The poop on this scaling stuff is as follows:
++ *
++ * Each 1-D DCT step produces outputs which are a factor of sqrt(N)
++ * larger than the true DCT outputs.  The final outputs are therefore
++ * a factor of N larger than desired; since N=8 this can be cured by
++ * a simple right shift at the end of the algorithm.  The advantage of
++ * this arrangement is that we save two multiplications per 1-D DCT,
++ * because the y0 and y4 outputs need not be divided by sqrt(N).
++ * In the IJG code, this factor of 8 is removed by the quantization step
++ * (in jcdctmgr.c), here it is removed.
++ *
++ * We have to do addition and subtraction of the integer inputs, which
++ * is no problem, and multiplication by fractional constants, which is
++ * a problem to do in integer arithmetic.  We multiply all the constants
++ * by CONST_SCALE and convert them to integer constants (thus retaining
++ * CONST_BITS bits of precision in the constants).  After doing a
++ * multiplication we have to divide the product by CONST_SCALE, with proper
++ * rounding, to produce the correct output.  This division can be done
++ * cheaply as a right shift of CONST_BITS bits.  We postpone shifting
++ * as long as possible so that partial sums can be added together with
++ * full fractional precision.
++ *
++ * The outputs of the first pass are scaled up by PASS1_BITS bits so that
++ * they are represented to better-than-integral precision.  These outputs
++ * require 8 + PASS1_BITS + 3 bits; this fits in a 16-bit word
++ * with the recommended scaling.  (For 12-bit sample data, the intermediate
++ * array is INT32 anyway.)
++ *
++ * To avoid overflow of the 32-bit intermediate results in pass 2, we must
++ * have 8 + CONST_BITS + PASS1_BITS <= 26.  Error analysis
++ * shows that the values given below are the most effective.
++ *
++ * We can gain a little more speed, with a further compromise in accuracy,
++ * by omitting the addition in a descaling shift.  This yields an incorrectly
++ * rounded result half the time...
++ */
++
++      .global         fdct_avr32
++
++
++
++#define CONST_BITS  13
++#define PASS1_BITS  2
++
++#define FIX_0_298631336  2446 /* FIX(0.298631336) */
++#define FIX_0_390180644  3196 /* FIX(0.390180644) */
++#define FIX_0_541196100  4433 /* FIX(0.541196100) */
++#define FIX_0_765366865  6270 /* FIX(0.765366865) */
++#define FIX_0_899976223  7373 /* FIX(0.899976223) */
++#define FIX_1_175875602  9633 /* FIX(1.175875602) */
++#define FIX_1_501321110  12299        /* FIX(1.501321110) */
++#define FIX_1_847759065  15137        /* FIX(1.847759065) */
++#define FIX_1_961570560  16069        /* FIX(1.961570560) */
++#define FIX_2_053119869  16819        /* FIX(2.053119869) */
++#define FIX_2_562915447  20995        /* FIX(2.562915447) */
++#define FIX_3_072711026  25172        /* FIX(3.072711026) */
++
++
++/*
++ * Perform an integer forward DCT on one block of samples.
++ */
++
++//void
++//fdct_int32(short *const block)
++//{
++//    int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
++//    int tmp10, tmp11, tmp12, tmp13;
++//    int z1, z2, z3, z4, z5;
++//    short *blkptr;
++//    int *dataptr;
++//    int data[64];
++//    int i;
++//
++//       /* Pass 1: process rows. */
++//       /* Note results are scaled up by sqrt(8) compared to a true DCT; */
++//       /* furthermore, we scale the results by 2**PASS1_BITS. */
++//
++//    dataptr = data;
++//    blkptr = block;
++
++      .text
++fdct_avr32:
++      pushm           r0-r3, r4-r7, lr
++#define               loop_ctr        r0
++#define               blkptr          r12
++#define               x0              r1
++#define               x1              r2
++#define               x2              r3
++#define               x3              r4
++#define               x4              r5
++#define               x5              r6
++#define               x6              r7
++#define               x7              r8
++#define               tmp0            r5
++#define               tmp7            r2
++#define               tmp1            r3
++#define               tmp6            r4
++#define               tmp2            r9
++#define               tmp5            r8
++#define               tmp3            r7
++#define               tmp4            r6
++
++
++      mov             loop_ctr, 8
++//    for (i = 0; i < 8; i++) {
++ROW_LOOP:
++
++      ldm             blkptr, r1, r2, r3, r4 
++
++//            tmp2 = blkptr[2] + blkptr[5];
++//            tmp3 = blkptr[3] + blkptr[4];
++      paddx.h         r5, r3, r2  
++//            tmp5 = blkptr[2] - blkptr[5];
++//            tmp4 = blkptr[3] - blkptr[4];
++      psubx.h         r6, r3, r2 
++//            tmp0 = blkptr[0] + blkptr[7];
++//            tmp1 = blkptr[1] + blkptr[6];
++      paddx.h         r2, r4, r1
++//            tmp7 = blkptr[0] - blkptr[7];
++//            tmp6 = blkptr[1] - blkptr[6];
++      psubx.h         r3, r4, r1
++
++//            /* Even part per LL&M figure 1 --- note that published figure is faulty;
++//             * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
++//             */
++
++#define               tmp10           r1
++#define               tmp13           r5
++#define               tmp11           r7
++#define               tmp12           r3
++#define               z1              r9
++
++//            tmp10 = tmp0 + tmp3;
++//            tmp13 = tmp0 - tmp3;
++      paddsub.h       r1, r2:t, r5:b  
++//            tmp11 = tmp1 + tmp2;
++//            tmp12 = tmp1 - tmp2;
++      paddsub.h       r4, r2:b, r5:t  
++      
++
++//            dataptr[0] = (tmp10 + tmp11) << PASS1_BITS;
++//            dataptr[4] = (tmp10 - tmp11) << PASS1_BITS;
++      paddsub.h       r7, r1:t, r4:t
++      ld.w            r10, pc[const_table - .] 
++      plsl.h          r7, r7, PASS1_BITS
++      
++//            z1 = (tmp12 + tmp13) * FIX_0_541196100;
++      addhh.w         r8, r4:b, r1:b
++      mulhh.w         r8, r8:b, r10:t         
++      
++//            dataptr[2] =
++//                    DESCALE(z1 + tmp13 * FIX_0_765366865, CONST_BITS - PASS1_BITS);
++//            dataptr[6] =
++//                    DESCALE(z1 + tmp12 * (-FIX_1_847759065), CONST_BITS - PASS1_BITS);
++      mulhh.w         r9, r1:b, r10:b
++      ld.w            r10, pc[const_table - . + 4]    
++      add             r1, r8, r9      
++      satrnds         r1 >> (CONST_BITS - PASS1_BITS), 31     
++
++      mulhh.w         r9, r4:b, r10:t
++      add             r4, r8, r9
++      satrnds         r4 >> (CONST_BITS - PASS1_BITS), 31     
++              
++
++//            /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
++//             * cK represents cos(K*pi/16).
++//             * i0..i3 in the paper are tmp4..tmp7 here.
++//             */
++
++#define               z2              r5
++#define               z3              r6
++#define               z4              r7
++#define               z5              r8
++
++//            z4 = tmp5 + tmp7;
++//            z3 = tmp4 + tmp6;
++      padd.h          r2, r6, r3 
++//            z2 = tmp5 + tmp6;
++//            z1 = tmp4 + tmp7;
++      paddx.h         r5, r6, r3      
++
++      lddpc           r9, pc[const_table - . + 8]
++//            z5 = (z3 + z4) * FIX_1_175875602;       /* sqrt(2) * c3 */
++      addhh.w         r8, r2:t, r2:b
++      mulhh.w         r8, r8:b, r10:b
++      lddpc           r10, pc[const_table - . + 12]
++      
++
++//            tmp4 *= FIX_0_298631336;        /* sqrt(2) * (-c1+c3+c5-c7) */
++      mulhh.w         r11, r6:b, r9:t
++      
++//            tmp5 *= FIX_2_053119869;        /* sqrt(2) * ( c1+c3-c5+c7) */
++      mulhh.w         r6, r6:t, r9:b
++
++//            tmp6 *= FIX_3_072711026;        /* sqrt(2) * ( c1+c3+c5-c7) */
++      lddpc           r9, pc[const_table - . + 20]
++      mulhh.w         lr, r3:b, r10:t
++      
++//            tmp7 *= FIX_1_501321110;        /* sqrt(2) * ( c1+c3-c5-c7) */
++      mulhh.w         r3, r3:t, r10:b
++
++//            z3 *= -FIX_1_961570560; /* sqrt(2) * (-c3-c5) */
++      mulhh.w         r10, r2:b, r9:t
++
++//            z4 *= -FIX_0_390180644; /* sqrt(2) * (c5-c3) */
++      mulhh.w         r2, r2:t, r9:b
++      lddpc           r9, pc[const_table - . + 16]
++//            z3 += z5;
++//            z4 += z5;
++      add             r10, r8
++      add             r2, r8
++      
++//            z1 *= -FIX_0_899976223; /* sqrt(2) * (c7-c3) */
++      mulhh.w         r8, r5:b, r9:t
++
++//            z2 *= -FIX_2_562915447; /* sqrt(2) * (-c1-c3) */
++      mulhh.w         r5, r5:t, r9:b
++      
++//            dataptr[7] = DESCALE(tmp4 + z1 + z3, CONST_BITS - PASS1_BITS);
++      add             r11, r8
++      add             r11, r10
++      satrnds         r11 >> (CONST_BITS - PASS1_BITS), 31    
++      
++//            dataptr[5] = DESCALE(tmp5 + z2 + z4, CONST_BITS - PASS1_BITS);
++      add             r6, r5
++
++      sthh.w          blkptr[6*2], r4:b, r11:b        
++      add             r6, r2
++      satrnds         r6 >> (CONST_BITS - PASS1_BITS), 31     
++
++//            dataptr[3] = DESCALE(tmp6 + z2 + z3, CONST_BITS - PASS1_BITS);
++      add             lr, r5
++      sthh.w          blkptr[4*2], r7:b, r6:b 
++      add             lr, r10
++      satrnds         lr >> (CONST_BITS - PASS1_BITS), 31     
++      
++//            dataptr[1] = DESCALE(tmp7 + z1 + z4, CONST_BITS - PASS1_BITS);
++      add             r3, r8
++      sthh.w          blkptr[2*2], r1:b, lr:b
++      add             r3, r2
++      satrnds         r3 >> (CONST_BITS - PASS1_BITS), 31     
++
++              
++
++//            dataptr += 8;                   /* advance pointer to next row */
++//            blkptr += 8;
++      sthh.w          blkptr[0], r7:t, r3:b   
++      sub             blkptr, -16
++      sub             loop_ctr, 1
++      brne            ROW_LOOP
++
++//    }
++
++      /* Pass 2: process columns.
++       * We remove the PASS1_BITS scaling, but leave the results scaled up
++       * by an overall factor of 8.
++       */
++
++//    dataptr = data;
++      sub             blkptr, 128
++
++      mov             loop_ctr, 4
++//    for (i = 0; i < 8; i++) {
++COLOUMN_LOOP:
++      ld.w            r1, blkptr[0]
++      ld.w            r2, blkptr[1*8*2]
++      ld.w            r3, blkptr[2*8*2]
++      ld.w            r4, blkptr[3*8*2]
++      ld.w            r5, blkptr[4*8*2]
++      ld.w            r6, blkptr[5*8*2]
++      ld.w            r7, blkptr[6*8*2]
++      ld.w            r8, blkptr[7*8*2]
++      
++//            tmp0 = blkptr[0] + blkptr[7*8];
++      padds.sh        r9, r1, r8 
++//            tmp7 = blkptr[0] - blkptr[7*8];
++      psubs.sh        r1, r1, r8 
++//            tmp1 = blkptr[1*8] + blkptr[6*8];
++      padds.sh        r8, r2, r7 
++//            tmp6 = blkptr[1*8] - blkptr[6*8];
++      psubs.sh        r2, r2, r7 
++//            tmp2 = blkptr[2*8] + blkptr[5*8];
++      padds.sh        r7, r3, r6 
++//            tmp5 = blkptr[2*8] - blkptr[5*8];
++      psubs.sh        r3, r3, r6 
++//            tmp3 = blkptr[3*8] + blkptr[4*8];
++      padds.sh        r6, r4, r5 
++//            tmp4 = blkptr[3*8] - blkptr[4*8];
++      psubs.sh        r4, r4, r5 
++
++//            /* even part per ll&m figure 1 --- note that published figure is faulty;
++//             * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
++//             */
++//
++//            tmp10 = tmp0 + tmp3;
++      padds.sh        r5, r9, r6 
++//            tmp13 = tmp0 - tmp3;
++      psubs.sh        r9, r9, r6 
++//            tmp11 = tmp1 + tmp2;
++      padds.sh        r6, r8, r7 
++//            tmp12 = tmp1 - tmp2;
++      psubs.sh        r8, r8, r7 
++
++//            dataptr[0] = DESCALE(tmp10 + tmp11, PASS1_BITS);
++//            dataptr[32] = DESCALE(tmp10 - tmp11, PASS1_BITS);
++//Might get an overflow here
++      padds.sh        r7, r5, r6
++      psubs.sh        r5, r5, r6
++
++      //Rounding      
++      mov             lr,  (1 << (PASS1_BITS + 2))
++      orh             lr, hi(1 << (16 + PASS1_BITS + 2))      
++      padds.sh        r7, r7, lr
++      padds.sh        r5, r5, lr
++      
++      pasr.h          r7, r7, PASS1_BITS + 3
++      pasr.h          r5, r5, PASS1_BITS + 3
++      st.w            r12[0], r7
++      st.w            r12[4*8*2], r5
++                               
++      lddpc           r10, const_table2
++
++
++//            z1 = (tmp12 + tmp13) * FIX_0_541196100;
++      padds.sh        r5, r8, r9
++      mulhh.w         r6, r5:t, r10:t
++      mulhh.w         r7, r5:b, r10:t
++
++//            dataptr[16] =
++//                    DESCALE(z1 + tmp13 * FIX_0_765366865, CONST_BITS + PASS1_BITS);
++      lddpc           r11, const_table2 + 4
++      mulhh.w         lr, r9:t, r10:b
++      mulhh.w         r9, r9:b, r10:b
++      add             lr, r6
++      add             r9, r7
++      satrnds         lr >> (CONST_BITS + PASS1_BITS + 3), 31
++      satrnds         r9 >> (CONST_BITS + PASS1_BITS + 3), 31
++      sthh.w          r12[2*8*2], lr:b, r9:b
++                      
++//            dataptr[48] =
++//                    DESCALE(z1 + tmp12 * (-FIX_1_847759065), CONST_BITS + PASS1_BITS);
++      mulhh.w         lr, r8:t, r11:t
++      mulhh.w         r8, r8:b, r11:t
++      add             lr, r6
++      add             r8, r7
++      satrnds         lr >> (CONST_BITS + PASS1_BITS + 3), 31
++      satrnds         r8 >> (CONST_BITS + PASS1_BITS + 3), 31
++      sthh.w          r12[6*8*2], lr:b, r8:b
++
++//            /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
++//             * cK represents cos(K*pi/16).
++//             * i0..i3 in the paper are tmp4..tmp7 here.
++//             */
++//
++//            z2 = tmp5 + tmp6;
++//            z3 = tmp4 + tmp6;
++//            z4 = tmp5 + tmp7;
++      padds.sh        r5, r3, r2
++      padds.sh        r6, r4, r2
++      padds.sh        r7, r3, r1
++      
++//            z5 = (z3 + z4) * FIX_1_175875602;       /* sqrt(2) * c3 */
++      padds.sh        r8, r6, r7
++      mulhh.w         r9, r8:t, r11:b
++      mulhh.w         r8, r8:b, r11:b
++      
++//            z3 *= -FIX_1_961570560; /* sqrt(2) * (-c3-c5) */
++//            z3 += z5;
++      lddpc           r11, const_table2 + 8
++      mulhh.w         r10, r6:t, r11:t
++      mulhh.w         r6, r6:b, r11:t
++      add             r10, r9
++      add             r6, r8
++      
++//            z4 *= -FIX_0_390180644; /* sqrt(2) * (c5-c3) */
++//            z4 += z5;
++      mulhh.w         lr, r7:t, r11:b
++      mulhh.w         r7, r7:b, r11:b
++      lddpc           r11, const_table2 + 12
++      st.w            --sp,r0
++      add             lr, r9
++      add             r7, r8
++
++//            tmp6 *= FIX_3_072711026;        /* sqrt(2) * ( c1+c3+c5-c7) */
++      mulhh.w         r0, r2:t, r11:t   
++      machh.w         r0, r5:t, r11:b
++      mulhh.w         r2, r2:b, r11:t   
++      machh.w         r2, r5:b, r11:b
++
++//            z2 *= -FIX_2_562915447; /* sqrt(2) * (-c1-c3) */
++//            dataptr[24] = DESCALE(tmp6 + z2 + z3, CONST_BITS + PASS1_BITS);
++      add             r0, r10
++      lddpc           r11, const_table2 + 16
++      add             r2, r6
++      satrnds         r0 >> (CONST_BITS + PASS1_BITS + 3), 31 
++      satrnds         r2 >> (CONST_BITS + PASS1_BITS + 3), 31 
++      sthh.w          r12[3*8*2], r0:b, r2:b          
++//            tmp5 *= FIX_2_053119869;        /* sqrt(2) * ( c1+c3-c5+c7) */
++      mulhh.w         r0, r3:t, r11:t   
++      machh.w         r0, r5:t, r11:b
++      mulhh.w         r2, r3:b, r11:t   
++      machh.w         r2, r5:b, r11:b
++      add             r0, lr
++      lddpc           r11, const_table2 + 20
++      add             r2, r7
++      
++//            dataptr[40] = DESCALE(tmp5 + z2 + z4, CONST_BITS + PASS1_BITS);
++      satrnds         r0 >> (CONST_BITS + PASS1_BITS + 3), 31 
++      satrnds         r2 >> (CONST_BITS + PASS1_BITS + 3), 31 
++      sthh.w          r12[5*8*2], r0:b, r2:b          
++
++
++//            z1 = tmp4 + tmp7;
++      padds.sh        r2, r4, r1
++
++//            tmp4 *= FIX_0_298631336;        /* sqrt(2) * (-c1+c3+c5-c7) */
++      mulhh.w         r3, r4:t, r11:t
++      machh.w         r3, r2:t, r11:b
++      mulhh.w         r4, r4:b, r11:t
++      machh.w         r4, r2:b, r11:b
++      add             r3, r10
++      lddpc           r11, const_table2 + 24
++      add             r4, r6
++      
++//            z1 *= -FIX_0_899976223; /* sqrt(2) * (c7-c3) */
++//            dataptr[56] = DESCALE(tmp4 + z1 + z3, CONST_BITS + PASS1_BITS);
++      satrnds         r3 >> (CONST_BITS + PASS1_BITS + 3), 31 
++      satrnds         r4 >> (CONST_BITS + PASS1_BITS + 3), 31 
++      sthh.w          r12[7*8*2], r3:b, r4:b          
++
++
++//            tmp7 *= FIX_1_501321110;        /* sqrt(2) * ( c1+c3-c5-c7) */
++      mulhh.w         r3, r1:t, r11:t
++      machh.w         r3, r2:t, r11:b
++      mulhh.w         r4, r1:b, r11:t
++      machh.w         r4, r2:b, r11:b
++      add             r3, lr
++      add             r4, r7
++
++//            dataptr[8] = DESCALE(tmp7 + z1 + z4, CONST_BITS + PASS1_BITS);
++      satrnds         r3 >> (CONST_BITS + PASS1_BITS + 3), 31 
++      satrnds         r4 >> (CONST_BITS + PASS1_BITS + 3), 31 
++      sthh.w          r12[1*8*2], r3:b, r4:b          
++      ld.w            r0, sp++ 
++      
++//            dataptr++;                              /* advance pointer to next column */
++      sub             blkptr, -4
++      sub             loop_ctr, 1
++      brne            COLOUMN_LOOP
++
++//    }
++
++      popm            r0-r3, r4-r7, pc
++      
++//    /* descale */
++//    for (i = 0; i < 64; i++)
++//            block[i] = (short int) DESCALE(data[i], 3);
++
++
++//}
++
++
++      .align  2
++const_table:  .short  FIX_0_541196100, FIX_0_765366865, -FIX_1_847759065, FIX_1_175875602
++              .short  FIX_0_298631336, FIX_2_053119869, FIX_3_072711026, FIX_1_501321110
++              .short  -FIX_0_899976223,-FIX_2_562915447, -FIX_1_961570560, -FIX_0_390180644
++      
++const_table2: .short  FIX_0_541196100, FIX_0_765366865, -FIX_1_847759065, FIX_1_175875602
++              .short  -FIX_1_961570560, -FIX_0_390180644, FIX_3_072711026, -FIX_2_562915447
++              .short  FIX_2_053119869, -FIX_2_562915447, FIX_0_298631336,  -FIX_0_899976223 
++              .short  FIX_1_501321110, -FIX_0_899976223
++      
++
++
++
+diff --git a/libavcodec/avr32/h264idct.S b/libavcodec/avr32/h264idct.S
+new file mode 100644
+index 0000000..4b23e2d
+--- /dev/null
++++ b/libavcodec/avr32/h264idct.S
+@@ -0,0 +1,451 @@
++/*
++ * Copyright (c) 2007 Atmel Corporation. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials provided
++ * with the distribution.
++ *
++ * 3. The name of ATMEL may not be used to endorse or promote products
++ * derived from this software without specific prior written
++ * permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL
++ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
++ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
++ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
++ * DAMAGE.
++ */
++
++      .global h264_idct_add_avr32
++
++      /* Macro for performing the 1-D transform on one row line. 
++
++         The register 'w01' should contain the first two pixels,
++         and the register 'w23' should contain the last two pixels
++         in the line. The resulting line is placed in p01 and p23
++         so that { w01, w23 } = { x0, x1, x3, x2 }.
++         'tmp' and 'tmp2' should be scratchpad registers. */ 
++      .macro  transform_row   w01, w23, tmp, tmp2 
++      add             \tmp, \w23, \w01 << 1   /* tmp = { xxxx, 2*w1 + w3 } */
++      sub             \tmp2, \w01, \w23 << 1  /* tmp2 = { xxxx, w1 - 2*w3 } */ 
++      bfins           \tmp2, \tmp, 16, 16     /* tmp2 = { 2*w1 + w3, w1 - 2*w3 } */
++      pasr.h          \tmp2, \tmp2, 1         /* tmp2 = { w1 + w3/2, w1/2 - w3 } */
++      paddsub.h       \tmp, \w01:t, \w23:t    /* tmp =  { w0 + w2, w0 - w2 }  */
++      padd.h          \w01, \tmp, \tmp2       /* w01 =  { w0 + w2 + w1 + w3/2, w0 - w2 + w1/2 - w3 } */
++      psub.h          \w23, \tmp, \tmp2       /* w23 =  { w0 + w2 - w1 - w3/2, w0 - w2 - w1/2 + w3 } */
++      .endm                                   
++
++      /* Macro for performing the 1-D transform on two columns. 
++         
++         The registers w0, w1, w2, w3 should each contain two 
++         packed samples from the two colomns to transform.
++         tmp and tmp2 are scratchpad registers. 
++        
++         The resulting transformed columns are placed in the
++         same positions as the input columns. 
++      */ 
++      .macro  transform_2columns      w0, w1, w2, w3, tmp, tmp2
++      padd.h          \tmp, \w0, \w2  /* tmp = z0 = w0 + w2 */
++      psub.h          \w0, \w0, \w2   /* w0 = z1 = w0 - w2 */
++      pasr.h          \w2, \w1, 1     /* w2 = w1/2 */
++      pasr.h          \tmp2, \w3, 1   /* tmp2 = w3/2 */
++      psub.h          \w3, \w2, \w3   /* w3 = z2 = w1/2 - w3 */
++      padd.h          \tmp2, \w1, \tmp2/* tmp2 = z3 = w1 + w3/2 */
++      padd.h          \w1, \w0, \w3   /* w1 = x1 = z1 + z2 */
++      psub.h          \w2, \w0, \w3   /* w2 = x2 = z1 - z2 */
++      padd.h          \w0, \tmp, \tmp2/* w0 = x0 = z0 + z3 */
++      psub.h          \w3, \tmp, \tmp2/* w3 = x3 = z0 - z3 */
++      /* Scale down result. */
++      pasr.h          \w0, \w0, 6
++      pasr.h          \w1, \w1, 6
++      pasr.h          \w2, \w2, 6
++      pasr.h          \w3, \w3, 6
++      .endm                                   
++      
++/*void h264_idct_add_avr32(uint8_t *dst, DCTELEM *block, int stride)*/
++
++h264_idct_add_avr32:
++              
++      stm     --sp,r0-r3,r4-r7, lr 
++
++      /* Setup rounding factor. */
++      mov     r0, (1 << 5)
++      lsl     r0, 16  
++
++      /* Load block */
++        ldm   r11,r2-r9 
++        /* r9 = { w00, w01 }, 
++           r8 = { w02, w03 }, 
++           r7 = { w10, w11 }, 
++           r6 = { w12, w13 }, 
++           r5 = { w20, w21 }, 
++           r4 = { w22, w23 }, 
++           r3 = { w30, w31 }, 
++           r2 = { w32, w33 } */
++
++      
++      /* Add the rounding factor to w00. */
++      add                     r9, r0
++      
++      /* Transform rows */
++      transform_row           r9, r8, r0, r1
++      transform_row           r7, r6, r0, r1
++      transform_row           r5, r4, r0, r1
++      transform_row           r3, r2, r0, r1
++
++      /* Transform columns */
++      transform_2columns      r9, r7, r5, r3, r0, r1
++      transform_2columns      r8, r6, r4, r2, r0, r1
++
++      /* Load predicted pixels.*/
++      ld.w                    lr, r12[0]
++        ld.w                  r11, r12[r10]
++
++      /* Unpack to halwords. */
++        punpckub.h            r0, lr:t
++        punpckub.h            r1, lr:b
++
++      /* Add with transformed row. */
++        padd.h                        r0, r0, r9
++        paddx.h                       r1, r1, r8
++      /* Pack and saturate back to 8-bit pixels. */
++        packsh.ub             r0, r0, r1
++
++      /* Unpack to halwords. */
++        punpckub.h            lr, r11:t
++        punpckub.h            r11, r11:b
++
++      /* Add with transformed row. */
++        padd.h                        lr, lr, r7
++        paddx.h                       r11, r11, r6
++      /* Pack and saturate back to 8-bit pixels. */
++        packsh.ub             r1, lr, r11
++
++      /* Store back to frame. */
++      st.w                    r12[0], r0
++      st.w                    r12[r10], r1
++
++      add                     r12, r12, r10 << 1
++
++      /* Load predicted pixels.*/
++      ld.w                    lr, r12[0]
++        ld.w                  r11, r12[r10]
++
++      /* Unpack to halwords. */
++        punpckub.h            r0, lr:t
++        punpckub.h            r1, lr:b
++
++      /* Add with transformed row. */
++        padd.h                        r0, r0, r5
++        paddx.h                       r1, r1, r4
++      /* Pack and saturate back to 8-bit pixels. */
++        packsh.ub             r0, r0, r1
++
++      /* Unpack to halwords. */
++        punpckub.h            lr, r11:t
++        punpckub.h            r11, r11:b
++
++      /* Add with transformed row. */
++        padd.h                        lr, lr, r3
++        paddx.h                       r11, r11, r2
++      /* Pack and saturate back to 8-bit pixels. */
++        packsh.ub             r1, lr, r11
++
++      /* Store back to frame. */
++      st.w                    r12[0], r0
++      st.w                    r12[r10], r1
++      
++      ldm                     sp++,r0-r3,r4-r7, pc 
++
++
++      .global h264_idct8_add_avr32
++//void ff_h264_idct8_add_c(uint8_t *dst, DCTELEM *block, int stride){
++
++h264_idct8_add_avr32:         
++      stm         --sp,r0-r3,r4-r7, lr 
++
++      /* Push dst and stride on stack */
++      stm         --sp,r10,r12 
++
++//    int i;
++//    DCTELEM (*src)[8] = (DCTELEM(*)[8])block;
++//    uint8_t *cm = cropTbl + MAX_NEG_CROP;
++
++//    block[0] += 32;
++
++
++//    for( i = 0; i < 8; i++ )
++//    {
++      mov             lr, 4
++0:
++      ld.w            r7, r11[0*(8*2)]
++      ld.w            r6, r11[1*(8*2)]
++      ld.w            r5, r11[2*(8*2)]        
++      ld.w            r4, r11[3*(8*2)]        
++      ld.w            r3, r11[4*(8*2)]        
++      ld.w            r2, r11[5*(8*2)]        
++      ld.w            r1, r11[6*(8*2)]        
++      ld.w            r0, r11[7*(8*2)]        
++      
++/*    
++
++        const int a0 =  src[0][i] + src[4][i];
++        const int a2 =  src[0][i] - src[4][i];
++        const int a4 = (src[2][i]>>1) - src[6][i];
++        const int a6 = (src[6][i]>>1) + src[2][i]; 
++*/
++      padd.h          r8, r7, r3      /* r8 = a0 */   
++      psub.h          r7, r7, r3      /* r7 = a2 */   
++      pasr.h          r3, r5, 1       /* r3 = src[2][i] >> 1 */
++      pasr.h          r9, r1, 1       /* r9 = src[6][i] >> 1 */
++      psub.h          r3, r3, r1      /* r3 = a4 */
++      padd.h          r9, r9, r5      /* r9 = a6 */
++
++/*
++        const int b0 = a0 + a6;
++        const int b2 = a2 + a4;
++        const int b4 = a2 - a4;
++        const int b6 = a0 - a6; 
++*/
++      padd.h          r1, r8, r9      /* r1 = b0 */
++      psub.h          r8, r8, r9      /* r8 = b6 */
++      padd.h          r5, r7, r3      /* r5 = b2 */
++      psub.h          r7, r7, r3      /* r7 = b4 */
++      
++/*    
++        const int a1 = -src[3][i] + src[5][i] - src[7][i] - (src[7][i]>>1);
++        const int a3 =  src[1][i] + src[7][i] - src[3][i] - (src[3][i]>>1);
++        const int a5 = -src[1][i] + src[7][i] + src[5][i] + (src[5][i]>>1);
++        const int a7 =  src[3][i] + src[5][i] + src[1][i] + (src[1][i]>>1);
++*/
++      pasr.h          r3, r0, 1
++      padd.h          r3, r3, r0
++      psub.h          r3, r2, r3
++      psub.h          r3, r3, r4 /* r3 = a1 */
++      
++      pasr.h          r9, r4, 1
++      padd.h          r9, r9, r4
++      psub.h          r9, r0, r9
++      padd.h          r9, r6, r9 /* r9 = a3 */
++      
++      pasr.h          r10, r2, 1
++      padd.h          r10, r10, r2
++      padd.h          r10, r10, r0
++      psub.h          r10, r10, r6 /* r10 = a5 */
++      
++      pasr.h          r0, r6, 1
++      padd.h          r0, r0, r6
++      padd.h          r0, r0, r2
++      padd.h          r0, r0, r4 /* r0 = a7 */
++/*
++        const int b1 = (a7>>2) + a1;
++        const int b3 =  a3 + (a5>>2);
++        const int b5 = (a3>>2) - a5;
++        const int b7 =  a7 - (a1>>2);
++*/
++      pasr.h          r2, r0, 2
++      padd.h          r2, r2, r3 /* r2 = b1 */
++      pasr.h          r3, r3, 2
++      psub.h          r3, r0, r3 /* r3 = b7 */
++
++      pasr.h          r0, r10, 2
++      padd.h          r0, r0, r9 /* r0 = b3 */
++      pasr.h          r9, r9, 2
++      psub.h          r9, r9, r10 /* r9 = b5 */
++      
++      
++/*    
++        src[0][i] = b0 + b7;
++        src[7][i] = b0 - b7;
++        src[1][i] = b2 + b5;
++        src[6][i] = b2 - b5;
++        src[2][i] = b4 + b3;
++        src[5][i] = b4 - b3;
++        src[3][i] = b6 + b1;
++        src[4][i] = b6 - b1; */
++
++      padd.h          r4, r1, r3
++      psub.h          r1, r1, r3
++      st.w            r11[0*(8*2)], r4
++      st.w            r11[7*(8*2)], r1
++              
++      padd.h          r3, r5, r9
++      psub.h          r5, r5, r9
++      st.w            r11[1*(8*2)], r3
++      st.w            r11[6*(8*2)], r5
++      
++      padd.h          r9, r7, r0
++      psub.h          r7, r7, r0
++      st.w            r11[2*(8*2)], r9
++      st.w            r11[5*(8*2)], r7
++
++      padd.h          r0, r8, r2
++      psub.h          r8, r8, r2
++      st.w            r11[3*(8*2)], r0
++      st.w            r11[4*(8*2)], r8
++
++      sub             r11, -4
++      sub             lr, 1
++      brne            0b
++      
++//    }
++
++      lddsp           r12, sp[0]      /* r12 = dst */ 
++      sub             r11, 4*4
++      ldm             r11++, r4-r7
++      mov             lr, 8
++      /* Push dst and stride on stack */
++      
++1:            
++//    for( i = 0; i < 8; i++ )
++//    {
++
++      /* r7 = {src[i][0], src[i][1]}  
++           r6 = {src[i][2], src[i][3]}
++         r5 = {src[i][4], src[i][5]}
++           r4 = {src[i][6], src[i][7]}        */      
++
++/*
++        const int a0 =  src[i][0] + src[i][4];
++        const int a2 =  src[i][0] - src[i][4];
++        const int a4 = (src[i][2]>>1) - src[i][6];
++        const int a6 = (src[i][6]>>1) + src[i][2]; 
++*/
++      pasr.h          r8, r6, 1
++      pasr.h          r9, r4, 1
++      addhh.w         r0, r7:t, r5:t  /* r0 = a0 */
++      subhh.w         r1, r7:t, r5:t  /* r1 = a2 */
++      subhh.w         r2, r8:t, r4:t  /* r2 = a4 */
++      addhh.w         r3, r9:t, r6:t  /* r3 = a6 */           
++              
++/*
++        const int b0 = a0 + a6;
++        const int b2 = a2 + a4;
++        const int b4 = a2 - a4;
++        const int b6 = a0 - a6;       
++*/
++      add             r10, r0, r3     /* r10 = b0 */ 
++      sub             r0, r3          /* r0 = b6 */
++      add             r3, r1, r2      /* r3 = b2 */
++      sub             r1, r2          /* r1 = b4 */           
++/*
++      
++
++          const int a7 =  src[i][5] + src[i][3] + src[i][1] + (src[i][1]>>1);
++          const int a1 =  src[i][5] - src[i][3] - src[i][7] - (src[i][7]>>1);
++          const int a3 =  src[i][7] + src[i][1] - src[i][3] - (src[i][3]>>1);
++          const int a5 =  src[i][7] - src[i][1] + src[i][5] + (src[i][5]>>1); */
++      addhh.w         r8, r8:b, r6:b
++      addhh.w         r2, r4:b, r7:b
++      sub             r2, r8          /* r2 = a3 */   
++
++      addhh.w         r9, r9:b, r4:b
++      subhh.w         r8, r5:b, r6:b
++      sub             r8, r9          /* r8 = a1 */   
++
++      pasr.h          r9, r7, 1
++      addhh.w         r9, r9:b, r7:b
++      addhh.w         r6, r5:b, r6:b
++      add             r6, r9          /* r6 = a7 */   
++              
++      pasr.h          r9, r5, 1
++      addhh.w         r9, r9:b, r5:b
++      subhh.w         r5, r4:b, r7:b
++      add             r5, r9          /* r5 = a5 */   
++                      
++/*        const int b1 = (a7>>2) + a1;
++          const int b3 = (a5>>2) + a3;
++          const int b5 = (a3>>2) - a5;
++          const int b7 = -(a1>>2) + a7  ;  */
++      asr             r4, r6, 2
++      add             r4, r8          /* r4 = b1 */
++      asr             r8, 2
++      rsub            r8, r6          /* r8 = b7 */
++      
++      asr             r6, r5, 2
++      add             r6, r2          /* r6 = b3 */
++      asr             r2, 2
++      sub             r2, r5          /* r2 = b5 */
++      
++/*
++        dst[i*stride + 0] = cm[ dst[i*stride + 0] + ((b0 + b7) >> 6) ];
++        dst[i*stride + 1] = cm[ dst[i*stride + 1] + ((b2 + b5) >> 6) ];
++        dst[i*stride + 2] = cm[ dst[i*stride + 2] + ((b4 + b3) >> 6) ];
++        dst[i*stride + 3] = cm[ dst[i*stride + 3] + ((b6 + b1) >> 6) ];
++        dst[i*stride + 4] = cm[ dst[i*stride + 4] + ((b6 - b1) >> 6) ];
++        dst[i*stride + 5] = cm[ dst[i*stride + 5] + ((b4 - b3) >> 6) ];
++        dst[i*stride + 6] = cm[ dst[i*stride + 6] + ((b2 - b5) >> 6) ];
++        dst[i*stride + 7] = cm[ dst[i*stride + 7] + ((b0 - b7) >> 6) ];
++*/
++      add             r5, r10, r8
++      satrnds         r5 >> 6, 0      /* r5 = (b0 + b7) >> 6 */
++      sub             r10, r8
++      satrnds         r10 >> 6, 0     /* r10 = (b0 - b7) >> 6 */
++      add             r8, r3, r2
++      satrnds         r8 >> 6, 0      /* r8 = (b2 + b5) >> 6 */
++      sub             r3, r2
++      satrnds         r3 >> 6, 0      /* r3 = (b2 - b5) >> 6 */
++      
++      add             r2, r1, r6      
++      satrnds         r2 >> 6, 0      /* r2 = (b4 + b3) >> 6 */
++      sub             r1, r6  
++      satrnds         r1 >> 6, 0      /* r1 = (b4 - b3) >> 6 */
++                              
++      add             r6, r0, r4      
++      satrnds         r6 >> 6, 0      /* r6 = (b6 + b1) >> 6 */
++      sub             r0, r4  
++      satrnds         r0 >> 6, 0      /* r0 = (b6 - b1) >> 6 */
++
++      ld.w            r4, r12[0]
++      
++      packw.sh        r8, r5, r8
++      packw.sh        r7, r2, r6
++      ld.w            r9, r12[4]
++      packw.sh        r6, r0, r1
++      packw.sh        r5, r3, r10
++      
++      punpckub.h      r10, r4:t
++      punpckub.h      r4, r4:b
++      punpckub.h      r3, r9:t
++      punpckub.h      r9, r9:b
++
++      padd.h          r8, r8, r10
++      padd.h          r7, r7, r4
++      padd.h          r6, r6, r3
++      padd.h          r5, r5, r9
++      
++      lddsp           r10, sp[4]      /* r10 = stride */
++      packsh.ub       r0, r8, r7
++      packsh.ub       r1, r6, r5
++
++      st.w            r12[0], r0
++      st.w            r12[4], r1
++      
++      ldm             r11++, r4-r7
++      add             r12, r10        /* dst += stride */
++      
++      sub             lr, 1
++      brne            1b                      
++                      
++      sub             sp, -8
++      ldm             sp++,r0-r3,r4-r7, pc
++
++
++              
++//    }
++//}
+diff --git a/libavcodec/avr32/idct.S b/libavcodec/avr32/idct.S
+new file mode 100644
+index 0000000..e7551ec
+--- /dev/null
++++ b/libavcodec/avr32/idct.S
+@@ -0,0 +1,829 @@
++/*
++ * Copyright (c) 2007 Atmel Corporation. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials provided
++ * with the distribution.
++ *
++ * 3. The name of ATMEL may not be used to endorse or promote products
++ * derived from this software without specific prior written
++ * permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL
++ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
++ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
++ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
++ * DAMAGE.
++ */
++
++      .global idct_add_avr32
++      .global idct_put_avr32
++      .global idct_avr32
++      
++
++#define CONST_BITS  13
++#define PASS1_BITS  2
++
++#define ONE   ((INT32) 1)
++
++#define CONST_SCALE (ONE << CONST_BITS)
++
++#define       LINE_SIZE       32
++
++#define FIX_0_298631336  (2446)       /* FIX(0.298631336) */
++#define FIX_0_390180644  (3196)       /* FIX(0.390180644) */
++#define FIX_0_541196100  (4433)       /* FIX(0.541196100) */
++#define FIX_0_765366865  (6270)       /* FIX(0.765366865) */
++#define FIX_0_899976223  (7373)       /* FIX(0.899976223) */
++#define FIX_1_175875602  (9633)       /* FIX(1.175875602) */
++#define FIX_1_501321110  (12299)/* FIX(1.501321110) */
++#define FIX_1_847759065  (15137)/* FIX(1.847759065) */
++#define FIX_1_961570560  (16069)/* FIX(1.961570560) */
++#define FIX_2_053119869  (16819)/* FIX(2.053119869) */
++#define FIX_2_562915447  (20995)/* FIX(2.562915447) */
++#define FIX_3_072711026  (25172)/* FIX(3.072711026) */
++
++
++#define loop_cnt      r11     
++      
++      .text
++      
++idct_add_avr32:
++      pushm           r0-r3, r4-r7, lr        //Free up registers to use for local variables
++
++      // Give room for some variables on the stack
++      sub             sp, 8
++      stdsp           SP[0], r12 // rfp
++      stdsp           SP[4], r11 // iinc
++              
++      mov             loop_cnt, 8             //Initialize loop counter
++
++FOR_ROW:
++
++      ldm             r10, r0, r1, r2, r3     //Load 8 DCT-coeffisients from the current row in the DCT-block
++      mov             r6, 0
++#ifdef USE_PREFETCH
++      pref            r10[LINE_SIZE]          //Prefetch next line 
++#endif
++      or              r4, r2, r3 << 16 
++      or              r4, r1                  //Check if all DCT-coeffisients except the DC is zero
++      or              r4, r0
++      brne            AC_ROW                  //If there are non-zero AC coeffisients perform row-transform
++
++      paddsub.h       r5, r3:t, r6:b          //Extract the DC-coeff from r5                  
++      plsl.h          r5, r5, PASS1_BITS
++      mov             r4, r5
++      st.d            r10++, r4
++      st.d            r10++, r4
++      
++      sub             loop_cnt, 1             //Decrement loop counter
++      brne            FOR_ROW                 //Perform loop one more time if loop_cnt is not zero 
++
++      bral            COLOUMN_TRANSFORM       //Perform coloumn transform after row transform is computed 
++              
++              
++AC_ROW:       
++
++
++      ld.w            r12, pc[coef_table - .]
++      ld.w            r9, pc[coef_table - . + 4]
++
++      padd.h          r4, r2, r0 // r4:t = dataptr[2] + dataptr[6],r4:b = dataptr[3] + dataptr[7] 
++      mulhh.w         r5, r4:t, r12:t
++      mulhh.w         r6, r0:t, r12:b
++      ld.w            r12, pc[coef_table - . + 8]
++      mulhh.w         r7, r2:t, r9:t
++      add             r6, r5  // tmp2
++      satrnds         r6 >> (CONST_BITS - PASS1_BITS), 31
++      add             r7, r5  // tmp3
++      satrnds         r7 >> (CONST_BITS - PASS1_BITS), 31
++
++      paddsub.h       r5, r3:t, r1:t
++      plsl.h          r5, r5, PASS1_BITS // r5:t = tmp0, r5:b = tmp1
++      
++      paddsub.h       r7, r5:t, r7:b // r7:t = tmp10, r7:b = tmp13
++      paddsub.h       r6, r5:b, r6:b // r6:t = tmp11, r6:b = tmp12
++      
++          
++      addhh.w         lr, r3:b, r1:b // lr = z4       
++      addhh.w         r5, r4:b, lr:b
++      mulhh.w         r5, r5:b, r9:b // r5 = z5
++      
++      ld.w            r9, pc[coef_table - . + 12]
++      mulhh.w         r4, r4:b, r12:t // r4 = z3
++      mulhh.w         lr, lr:b, r12:b // lr = z4
++      
++      add             r4, r5  
++      add             lr, r5  
++      
++      addhh.w         r5, r2:b, r1:b // r5 = z2       
++      addhh.w         r8, r3:b, r0:b // r8 = z1       
++
++          
++      mulhh.w         r0, r0:b, r9:t // r0 = tmp0
++      ld.w            r12, pc[coef_table - . + 16]
++      mulhh.w         r1, r1:b, r9:b // r1 = tmp1
++      ld.w            r9, pc[coef_table - . + 20]
++      mulhh.w         r2, r2:b, r12:t // r2 = tmp2
++      mulhh.w         r3, r3:b, r12:b // r3 = tmp3
++      mulhh.w         r8, r8:b, r9:t // r8 = z1       
++      mulhh.w         r5, r5:b, r9:b // r5 = z2       
++    
++    
++      add             r0, r8
++      add             r0, r4
++      add             r1, r5
++      add             r1, lr
++      add             r2, r5
++      add             r2, r4   
++      add             r3, r8
++      add             r3, lr   
++
++      satrnds         r0 >> (CONST_BITS - PASS1_BITS), 31
++      satrnds         r1 >> (CONST_BITS - PASS1_BITS), 31
++      satrnds         r2 >> (CONST_BITS - PASS1_BITS), 31
++      satrnds         r3 >> (CONST_BITS - PASS1_BITS), 31
++      
++      paddsub.h       r5, r6:t, r2:b // r5:t = dataptr[1], r5:b = dataptr[6]
++      paddsub.h       r4, r7:t, r3:b // r4:t = dataptr[0], r4:b = dataptr[7]
++      paddsub.h       r3, r6:b, r1:b // r3:t = dataptr[2], r3:b = dataptr[5]
++      paddsub.h       r2, r7:b, r0:b // r2:t = dataptr[3], r2:b = dataptr[4]
++
++      sthh.w          r10[0], r4:t, r5:t
++      sthh.w          r10[4], r3:t, r2:t
++      sthh.w          r10[8], r2:b, r3:b
++      sthh.w          r10[12], r5:b, r4:b
++      
++      
++
++      sub             r10, -16 
++      sub             loop_cnt, 1
++      brne            FOR_ROW, e
++
++COLOUMN_TRANSFORM:
++
++      sub             r10, 128        //Set pointer to start of DCT block
++
++
++      mov             loop_cnt, 8
++FOR_COLOUMN:  
++      ldins.h         r3:t,r10[0]    // r3:t = dataptr[0]  
++      ldins.h         r1:t,r10[1*8*2]// r1:t = dataptr[1] 
++      ldins.h         r2:t,r10[2*8*2]// r2:t = dataptr[2] 
++      ldins.h         r0:t,r10[5*8*2]// r0:t = dataptr[5] 
++      ldins.h         r3:b,r10[4*8*2]// r3:b = dataptr[4] 
++      ldins.h         r1:b,r10[3*8*2]// r1:b = dataptr[3] 
++      ldins.h         r2:b,r10[6*8*2]// r2:b = dataptr[6] 
++      ldins.h         r0:b,r10[7*8*2]// r0:b = dataptr[7] 
++              
++      or              r4, r1, r3 << 16
++      or              r4, r2  
++      or              r4, r0
++      brne            AC_COLOUMN                      //If there are non-zero AC coeffisients perform row-transform
++
++      lddsp           r12, SP[0]       // rfp
++      lddsp           r9, SP[4]       // iinc
++      satrnds         r3 >> ( PASS1_BITS + 3 + 16 ), 9        
++      ld.d            r0, r12[0]
++      sub             r10, -2 // Increment the dataptr
++      bfins           r3, r3, 16, 16
++      punpckub.h      r2, r1:t
++      padd.h          r2, r2, r3
++      punpckub.h      r1, r1:b
++      padd.h          r1, r1, r3
++      packsh.ub       r1, r2, r1
++      punpckub.h      r2, r0:t
++      padd.h          r2, r2, r3
++      punpckub.h      r0, r0:b
++      padd.h          r0, r0, r3
++      packsh.ub       r0, r2, r0
++      st.d            r12[0], r0
++      add             r12, r9 // increment rfp
++      stdsp           SP[0], r12              
++                      
++      sub             loop_cnt, 1//Decrement loop counter
++      brne            FOR_COLOUMN//Perform loop one more time if loop_cnt is not zero 
++
++      sub             sp, -8  
++      popm            r0-r3, r4-r7, pc//Pop back registers and PC 
++
++AC_COLOUMN:
++      
++      ld.w            r12, pc[coef_table - .]
++      ld.w            r9, pc[coef_table - . + 4]
++
++      addhh.w         r4, r2:t, r2:b
++      mulhh.w         r4, r4:b, r12:t // r4 = z1
++      mulhh.w         r5, r2:b, r12:b
++      ld.w            r12, pc[coef_table - . + 8]
++      mulhh.w         r6, r2:t, r9:t
++      add             r5, r4  // r5 = tmp2
++      add             r6, r4  // r6 = tmp3
++
++      addhh.w         r7, r3:t, r3:b
++      subhh.w         r8, r3:t, r3:b
++
++      lsl             r7, CONST_BITS
++      lsl             r8, CONST_BITS
++                      
++      add             r2, r7, r6 // r2 = tmp10
++      sub             r3, r7, r6 // r3 = tmp13
++      add             r4, r8, r5 // r4 = tmp11
++      sub             r5, r8, r5 // r5 = tmp12
++         
++      padd.h          r6, r0, r1 // r6:t = z4, r6:b = z3
++      addhh.w         r7, r6:t, r6:b
++      mulhh.w         r7, r7:b, r9:b // r7 = z5
++      
++      ld.w            r9, pc[coef_table - . + 12]
++      mulhh.w         r8, r6:b, r12:t // r8 = z3
++      mulhh.w         r6, r6:t, r12:b // r6 = z4
++      
++      add             r8, r7  
++      add             r6, r7  
++      
++      paddx.h         r7, r0, r1 // r7:t = z2, r7:b = z1
++
++      mulhh.w         r12, r0:b, r9:t // r12 = tmp0
++      mulhh.w         r0, r0:t, r9:b // r0 = tmp1
++      ld.w            r9, pc[coef_table - . + 16]
++      add             r12, r8
++      add             r0, r6
++              
++      ld.w            lr, pc[coef_table - . + 20]
++      machh.w         r8, r1:b, r9:t // r8 = tmp2
++      machh.w         r6, r1:t, r9:b // r6 = tmp3
++      mulhh.w         r9, r7:b, lr:t // r9 = z1       
++      mulhh.w         r7, r7:t, lr:b // r7 = z2       
++    
++    
++      add             r12, r9
++      add             r0, r7
++      add             r8, r7
++      add             r6, r9
++
++      add             r1, r2, r6 // r1 = dataptr[DCTSIZE*0]
++      sub             r2, r2, r6 // r2 = dataptr[DCTSIZE*7]
++      add             r6, r4, r8 // r6 = dataptr[DCTSIZE*1]
++      sub             r4, r4, r8 // r4 = dataptr[DCTSIZE*6]
++      add             r8, r5, r0 // r8 = dataptr[DCTSIZE*2]
++      sub             r5, r5, r0 // r5 = dataptr[DCTSIZE*5]
++      add             r0, r3, r12 // r0 = dataptr[DCTSIZE*3]
++      sub             r3, r3, r12 // r3 = dataptr[DCTSIZE*4]
++      
++      satrnds         r1 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r2 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r6 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r4 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r8 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r5 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r0 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r3 >> (CONST_BITS+PASS1_BITS+3), 9
++
++      packw.sh        r1, r1, r6
++      packw.sh        r8, r8, r0
++      packw.sh        r3, r3, r5
++      packw.sh        r4, r4, r2
++              
++      lddsp           r12, SP[0]       // rfp
++      lddsp           r9, SP[4]       // iinc
++      ld.d            r6, r12[0]
++      sub             r10, -2 // Increment the dataptr
++      punpckub.h      r0, r7:t
++      padd.h          r1, r1, r0
++      punpckub.h      r0, r7:b
++      padd.h          r8, r8, r0
++      packsh.ub       r7, r1, r8
++      punpckub.h      r0, r6:t
++      padd.h          r3, r3, r0
++      punpckub.h      r0, r6:b
++      padd.h          r4, r4, r0
++      packsh.ub       r6, r3, r4
++      st.d            r12[0], r6
++      add             r12, r9 // increment rfp
++      stdsp           SP[0], r12              
++                              
++      sub             loop_cnt, 1             //Decrement loop counter
++      brne            FOR_COLOUMN                     //Perform loop one more time if loop_cnt is not zero 
++      
++      sub             sp, -8  
++      popm            r0-r3, r4-r7, pc        //Pop back registers and PC 
++      
++
++
++//Coeffisient Table:
++      .align  2
++coef_table:   
++      .short  FIX_0_541196100, -FIX_1_847759065, FIX_0_765366865, FIX_1_175875602 
++      .short  - FIX_1_961570560, - FIX_0_390180644, FIX_0_298631336, FIX_2_053119869
++      .short  FIX_3_072711026, FIX_1_501321110, - FIX_0_899976223, - FIX_2_562915447
++
++
++idct_put_avr32:
++      pushm           r0-r3, r4-r7, lr        //Free up registers to use for local variables
++
++              //; Give room for some variables on the stack
++      sub             sp, 8
++      stdsp           SP[0], r12 // rfp
++      stdsp           SP[4], r11 // iinc
++              
++      mov             loop_cnt, 8             //Initialize loop counter
++
++0:
++
++      ldm             r10, r0, r1, r2, r3     //Load 8 DCT-coeffisients from the current row in the DCT-block
++      mov             r6, 0
++#ifdef USE_PREFETCH
++      pref            r10[LINE_SIZE]          //Prefetch next line 
++#endif
++      or              r4, r2, r3 << 16 
++      or              r4, r1                  //Check if all DCT-coeffisients except the DC is zero
++      or              r4, r0
++      brne            1f                      //If there are non-zero AC coeffisients perform row-transform
++
++      paddsub.h       r5, r3:t, r6:b          //Extract the DC-coeff from r5                  
++      plsl.h          r5, r5, PASS1_BITS
++      mov             r4, r5
++      st.d            r10++, r4
++      st.d            r10++, r4
++      
++      sub             loop_cnt, 1             //Decrement loop counter
++      brne            0b                      //Perform loop one more time if loop_cnt is not zero 
++
++      bral            2f                      //Perform coloumn transform after row transform is computed 
++              
++1:    
++
++      ld.w            r12, pc[coef_table_copy - .]
++      ld.w            r9, pc[coef_table_copy - . + 4]
++
++      padd.h          r4, r2, r0 // r4:t = dataptr[2] + dataptr[6],r4:b = dataptr[3] + dataptr[7] 
++      mulhh.w         r5, r4:t, r12:t
++      mulhh.w         r6, r0:t, r12:b
++      ld.w            r12, pc[coef_table_copy - . + 8]
++      mulhh.w         r7, r2:t, r9:t
++      add             r6, r5  // tmp2
++      satrnds         r6 >> (CONST_BITS - PASS1_BITS), 31
++      add             r7, r5  // tmp3
++      satrnds         r7 >> (CONST_BITS - PASS1_BITS), 31
++
++      paddsub.h       r5, r3:t, r1:t
++      plsl.h          r5, r5, PASS1_BITS // r5:t = tmp0, r5:b = tmp1
++      
++      paddsub.h       r7, r5:t, r7:b // r7:t = tmp10, r7:b = tmp13
++      paddsub.h       r6, r5:b, r6:b // r6:t = tmp11, r6:b = tmp12
++      
++          
++
++      addhh.w         lr, r3:b, r1:b // lr = z4       
++      addhh.w         r5, r4:b, lr:b
++      mulhh.w         r5, r5:b, r9:b // r5 = z5
++      
++      ld.w            r9, pc[coef_table_copy - . + 12]
++      mulhh.w         r4, r4:b, r12:t // r4 = z3
++      mulhh.w         lr, lr:b, r12:b // lr = z4
++      
++      add             r4, r5  
++      add             lr, r5  
++      
++      addhh.w         r5, r2:b, r1:b // r5 = z2       
++      addhh.w         r8, r3:b, r0:b // r8 = z1       
++
++          
++      mulhh.w         r0, r0:b, r9:t // r0 = tmp0
++      ld.w            r12, pc[coef_table_copy - . + 16]
++      mulhh.w         r1, r1:b, r9:b // r1 = tmp1
++      ld.w            r9, pc[coef_table_copy - . + 20]
++      mulhh.w         r2, r2:b, r12:t // r2 = tmp2
++      mulhh.w         r3, r3:b, r12:b // r3 = tmp3
++      mulhh.w         r8, r8:b, r9:t // r8 = z1       
++      mulhh.w         r5, r5:b, r9:b // r5 = z2       
++    
++    
++      add             r0, r8
++      add             r0, r4
++      add             r1, r5
++      add             r1, lr
++      add             r2, r5
++      add             r2, r4   
++      add             r3, r8
++      add             r3, lr   
++
++      satrnds         r0 >> (CONST_BITS - PASS1_BITS), 31
++      satrnds         r1 >> (CONST_BITS - PASS1_BITS), 31
++      satrnds         r2 >> (CONST_BITS - PASS1_BITS), 31
++      satrnds         r3 >> (CONST_BITS - PASS1_BITS), 31
++      
++      paddsub.h       r5, r6:t, r2:b // r5:t = dataptr[1], r5:b = dataptr[6]
++      paddsub.h       r4, r7:t, r3:b // r4:t = dataptr[0], r4:b = dataptr[7]
++      paddsub.h       r3, r6:b, r1:b // r3:t = dataptr[2], r3:b = dataptr[5]
++      paddsub.h       r2, r7:b, r0:b // r2:t = dataptr[3], r2:b = dataptr[4]
++
++      sthh.w          r10[0], r4:t, r5:t
++      sthh.w          r10[4], r3:t, r2:t
++      sthh.w          r10[8], r2:b, r3:b
++      sthh.w          r10[12], r5:b, r4:b
++      
++      
++
++      sub             r10, -16 
++      sub             loop_cnt, 1
++      brne            0b
++
++2:
++
++      sub             r10, 128        //Set pointer to start of DCT block
++
++      mov             loop_cnt, 8
++
++0:    
++      ldins.h         r3:t,r10[0]    // r3:t = dataptr[0]  
++      ldins.h         r1:t,r10[1*8*2]// r1:t = dataptr[1] 
++      ldins.h         r2:t,r10[2*8*2]// r2:t = dataptr[2] 
++      ldins.h         r0:t,r10[5*8*2]// r0:t = dataptr[5] 
++      ldins.h         r3:b,r10[4*8*2]// r3:b = dataptr[4] 
++      ldins.h         r1:b,r10[3*8*2]// r1:b = dataptr[3] 
++      ldins.h         r2:b,r10[6*8*2]// r2:b = dataptr[6] 
++      ldins.h         r0:b,r10[7*8*2]// r0:b = dataptr[7] 
++              
++      or              r4, r1, r3 << 16
++      or              r4, r2  
++      or              r4, r0
++      brne            1f                      //If there are non-zero AC coeffisients perform row-transform
++
++      lddsp           r12, SP[0]       // rfp
++      lddsp           r9, SP[4]       // iinc
++      satrnds         r3 >> ( PASS1_BITS + 3 + 16 ), 31       
++      packw.sh        r3, r3, r3
++      packsh.ub       r3, r3, r3
++      mov             r2, r3
++      st.d            r12[0], r2
++      add             r12, r9 // increment rfp
++      sub             r10, -2 // Increment the dataptr
++      stdsp           SP[0], r12              
++                      
++      sub             loop_cnt, 1//Decrement loop counter
++      brne            0b         //Perform loop one more time if loop_cnt is not zero 
++
++      sub             sp, -8  
++      popm            r0-r3, r4-r7, pc//Pop back registers and PC 
++
++1:
++      
++      ld.w            r12, pc[coef_table_copy - .]
++      ld.w            r9, pc[coef_table_copy - . + 4]
++
++      addhh.w         r4, r2:t, r2:b
++      mulhh.w         r4, r4:b, r12:t // r4 = z1
++      mulhh.w         r5, r2:b, r12:b
++      ld.w            r12, pc[coef_table_copy - . + 8]
++      mulhh.w         r6, r2:t, r9:t
++      add             r5, r4  // r5 = tmp2
++      add             r6, r4  // r6 = tmp3
++
++      addhh.w         r7, r3:t, r3:b
++      subhh.w         r8, r3:t, r3:b
++
++      lsl             r7, CONST_BITS
++      lsl             r8, CONST_BITS
++                      
++      add             r2, r7, r6 // r2 = tmp10
++      sub             r3, r7, r6 // r3 = tmp13
++      add             r4, r8, r5 // r4 = tmp11
++      sub             r5, r8, r5 // r5 = tmp12
++         
++
++      padd.h          r6, r0, r1 // r6:t = z4, r6:b = z3
++      addhh.w         r7, r6:t, r6:b
++      mulhh.w         r7, r7:b, r9:b // r7 = z5
++      
++      ld.w            r9, pc[coef_table_copy - . + 12]
++      mulhh.w         r8, r6:b, r12:t // r8 = z3
++      mulhh.w         r6, r6:t, r12:b // r6 = z4
++      
++      add             r8, r7  
++      add             r6, r7  
++      
++      paddx.h         r7, r0, r1 // r7:t = z2, r7:b = z1
++
++      mulhh.w         r12, r0:b, r9:t // r12 = tmp0
++      mulhh.w         r0, r0:t, r9:b // r0 = tmp1
++      ld.w            r9, pc[coef_table_copy - . + 16]
++      add             r12, r8
++      add             r0, r6
++              
++      ld.w            lr, pc[coef_table_copy - . + 20]
++      machh.w         r8, r1:b, r9:t // r8 = tmp2
++      machh.w         r6, r1:t, r9:b // r6 = tmp3
++      mulhh.w         r9, r7:b, lr:t // r9 = z1       
++      mulhh.w         r7, r7:t, lr:b // r7 = z2       
++    
++    
++      add             r12, r9
++      add             r0, r7
++      add             r8, r7
++      add             r6, r9
++
++      add             r1, r2, r6 // r1 = dataptr[DCTSIZE*0]
++      sub             r2, r2, r6 // r2 = dataptr[DCTSIZE*7]
++      add             r6, r4, r8 // r6 = dataptr[DCTSIZE*1]
++      sub             r4, r4, r8 // r4 = dataptr[DCTSIZE*6]
++      add             r8, r5, r0 // r8 = dataptr[DCTSIZE*2]
++      sub             r5, r5, r0 // r5 = dataptr[DCTSIZE*5]
++      add             r0, r3, r12 // r0 = dataptr[DCTSIZE*3]
++      sub             r3, r3, r12 // r3 = dataptr[DCTSIZE*4]
++      
++      satrnds         r1 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r2 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r6 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r4 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r8 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r5 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r0 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r3 >> (CONST_BITS+PASS1_BITS+3), 9
++
++      packw.sh        r1, r1, r6
++      packw.sh        r8, r8, r0
++      packw.sh        r3, r3, r5
++      packw.sh        r4, r4, r2
++
++      packsh.ub       r1, r1, r8
++      packsh.ub       r0, r3, r4              
++      lddsp           r12, SP[0]       // rfp
++      lddsp           r9, SP[4]       // iinc
++      st.d            r12[0], r0
++      sub             r10, -2 // Increment the dataptr
++      add             r12, r9 // increment rfp
++      stdsp           SP[0], r12              
++                              
++      sub             loop_cnt, 1             //Decrement loop counter
++      brne            0b                      //Perform loop one more time if loop_cnt is not zero 
++      
++      sub             sp, -8  
++      popm            r0-r3, r4-r7, pc        //Pop back registers and PC 
++      
++
++
++      .align 2
++coef_table_copy:      
++      .short  FIX_0_541196100, -FIX_1_847759065, FIX_0_765366865, FIX_1_175875602 
++      .short  - FIX_1_961570560, - FIX_0_390180644, FIX_0_298631336, FIX_2_053119869
++      .short  FIX_3_072711026, FIX_1_501321110, - FIX_0_899976223, - FIX_2_562915447
++      
++
++idct_avr32:
++      pushm           r0-r3, r4-r7, lr        //Free up registers to use for local variables
++
++              //; Give room for a temporary block on the stack
++      sub             sp, 8*8*2
++              
++      mov             loop_cnt, 8             //Initialize loop counter
++
++0:
++
++      ldm             r12++, r0, r1, r2, r3   //Load 8 DCT-coeffisients from the current row in the DCT-block
++      mov             r6, 0
++#ifdef USE_PREFETCH
++      pref            r12[LINE_SIZE]          //Prefetch next line 
++#endif
++      or              r4, r2, r3 << 16 
++      or              r4, r1                  //Check if all DCT-coeffisients except the DC is zero
++      or              r4, r0
++      brne            1f                      //If there are non-zero AC coeffisients perform row-transform
++
++      paddsub.h       r5, r3:t, r6:b          //Extract the DC-coeff from r5                  
++      plsl.h          r5, r5, PASS1_BITS
++      mov             r4, r5
++      st.d            sp++, r4
++      st.d            sp++, r4
++      
++      sub             loop_cnt, 1             //Decrement loop counter
++      brne            0b                      //Perform loop one more time if loop_cnt is not zero 
++
++      bral            2f                      //Perform coloumn transform after row transform is computed 
++              
++1:    
++
++      ld.w            r10, pc[coef_table_idct - .]
++      ld.w            r9, pc[coef_table_idct - . + 4]
++
++      padd.h          r4, r2, r0 // r4:t = dataptr[2] + dataptr[6],r4:b = dataptr[3] + dataptr[7] 
++      mulhh.w         r5, r4:t, r10:t
++      mulhh.w         r6, r0:t, r10:b
++      ld.w            r10, pc[coef_table_idct - . + 8]
++      mulhh.w         r7, r2:t, r9:t
++      add             r6, r5  // tmp2
++      satrnds         r6 >> (CONST_BITS - PASS1_BITS), 31
++      add             r7, r5  // tmp3
++      satrnds         r7 >> (CONST_BITS - PASS1_BITS), 31
++
++      paddsub.h       r5, r3:t, r1:t
++      plsl.h          r5, r5, PASS1_BITS // r5:t = tmp0, r5:b = tmp1
++      
++      paddsub.h       r7, r5:t, r7:b // r7:t = tmp10, r7:b = tmp13
++      paddsub.h       r6, r5:b, r6:b // r6:t = tmp11, r6:b = tmp12
++      
++          
++
++      addhh.w         lr, r3:b, r1:b // lr = z4       
++      addhh.w         r5, r4:b, lr:b
++      mulhh.w         r5, r5:b, r9:b // r5 = z5
++      
++      ld.w            r9, pc[coef_table_idct - . + 12]
++      mulhh.w         r4, r4:b, r10:t // r4 = z3
++      mulhh.w         lr, lr:b, r10:b // lr = z4
++      
++      add             r4, r5  
++      add             lr, r5  
++      
++      addhh.w         r5, r2:b, r1:b // r5 = z2       
++      addhh.w         r8, r3:b, r0:b // r8 = z1       
++
++          
++      mulhh.w         r0, r0:b, r9:t // r0 = tmp0
++      ld.w            r10, pc[coef_table_idct - . + 16]
++      mulhh.w         r1, r1:b, r9:b // r1 = tmp1
++      ld.w            r9, pc[coef_table_idct - . + 20]
++      mulhh.w         r2, r2:b, r10:t // r2 = tmp2
++      mulhh.w         r3, r3:b, r10:b // r3 = tmp3
++      mulhh.w         r8, r8:b, r9:t // r8 = z1       
++      mulhh.w         r5, r5:b, r9:b // r5 = z2       
++    
++    
++      add             r0, r8
++      add             r0, r4
++      add             r1, r5
++      add             r1, lr
++      add             r2, r5
++      add             r2, r4   
++      add             r3, r8
++      add             r3, lr   
++
++      satrnds         r0 >> (CONST_BITS - PASS1_BITS), 31
++      satrnds         r1 >> (CONST_BITS - PASS1_BITS), 31
++      satrnds         r2 >> (CONST_BITS - PASS1_BITS), 31
++      satrnds         r3 >> (CONST_BITS - PASS1_BITS), 31
++      
++      paddsub.h       r5, r6:t, r2:b // r5:t = dataptr[1], r5:b = dataptr[6]
++      paddsub.h       r4, r7:t, r3:b // r4:t = dataptr[0], r4:b = dataptr[7]
++      paddsub.h       r3, r6:b, r1:b // r3:t = dataptr[2], r3:b = dataptr[5]
++      paddsub.h       r2, r7:b, r0:b // r2:t = dataptr[3], r2:b = dataptr[4]
++
++      sthh.w          sp[0], r4:t, r5:t
++      sthh.w          sp[4], r3:t, r2:t
++      sthh.w          sp[8], r2:b, r3:b
++      sthh.w          sp[12], r5:b, r4:b
++      
++      
++
++      sub             sp, -16 
++      sub             loop_cnt, 1
++      brne            0b
++
++2:
++
++      sub             sp, 8*8*2       //Set pointer to start of DCT block
++      sub             r12, 8*8*2      //Set pointer to start of DCT block
++
++      mov             loop_cnt, 8
++
++0:    
++      ldins.h         r3:t,sp[0]    // r3:t = dataptr[0]  
++      ldins.h         r1:t,sp[1*8*2]// r1:t = dataptr[1] 
++      ldins.h         r2:t,sp[2*8*2]// r2:t = dataptr[2] 
++      ldins.h         r0:t,sp[5*8*2]// r0:t = dataptr[5] 
++      ldins.h         r3:b,sp[4*8*2]// r3:b = dataptr[4] 
++      ldins.h         r1:b,sp[3*8*2]// r1:b = dataptr[3] 
++      ldins.h         r2:b,sp[6*8*2]// r2:b = dataptr[6] 
++      ldins.h         r0:b,sp[7*8*2]// r0:b = dataptr[7] 
++              
++      or              r4, r1, r3 << 16
++      or              r4, r2  
++      or              r4, r0
++      brne            1f                      //If there are non-zero AC coeffisients perform row-transform
++
++      satrnds         r3 >> ( PASS1_BITS + 3 + 16 ), 31       
++      packw.sh        r3, r3, r3
++      mov             r2, r3
++      st.d            r12++, r2
++      st.d            r12++, r2
++      sub             sp, -2  // Increment the dataptr
++                      
++      sub             loop_cnt, 1//Decrement loop counter
++      brne            0b         //Perform loop one more time if loop_cnt is not zero 
++
++      sub             sp, -(8*8*2 - 8)        
++      popm            r0-r3, r4-r7, pc//Pop back registers and PC 
++
++1:
++      
++      ld.w            r10, pc[coef_table_idct - .]
++      ld.w            r9, pc[coef_table_idct - . + 4]
++
++      addhh.w         r4, r2:t, r2:b
++      mulhh.w         r4, r4:b, r10:t // r4 = z1
++      mulhh.w         r5, r2:b, r10:b
++      ld.w            r10, pc[coef_table_idct - . + 8]
++      mulhh.w         r6, r2:t, r9:t
++      add             r5, r4  // r5 = tmp2
++      add             r6, r4  // r6 = tmp3
++
++      addhh.w         r7, r3:t, r3:b
++      subhh.w         r8, r3:t, r3:b
++
++      lsl             r7, CONST_BITS
++      lsl             r8, CONST_BITS
++                      
++      add             r2, r7, r6 // r2 = tmp10
++      sub             r3, r7, r6 // r3 = tmp13
++      add             r4, r8, r5 // r4 = tmp11
++      sub             r5, r8, r5 // r5 = tmp12
++         
++
++      padd.h          r6, r0, r1 // r6:t = z4, r6:b = z3
++      addhh.w         r7, r6:t, r6:b
++      mulhh.w         r7, r7:b, r9:b // r7 = z5
++      
++      ld.w            r9, pc[coef_table_idct - . + 12]
++      mulhh.w         r8, r6:b, r10:t // r8 = z3
++      mulhh.w         r6, r6:t, r10:b // r6 = z4
++      
++      add             r8, r7  
++      add             r6, r7  
++      
++      paddx.h         r7, r0, r1 // r7:t = z2, r7:b = z1
++
++      mulhh.w         r10, r0:b, r9:t // r10 = tmp0
++      mulhh.w         r0, r0:t, r9:b // r0 = tmp1
++      ld.w            r9, pc[coef_table_idct - . + 16]
++      add             r10, r8
++      add             r0, r6
++              
++      ld.w            lr, pc[coef_table_idct - . + 20]
++      machh.w         r8, r1:b, r9:t // r8 = tmp2
++      machh.w         r6, r1:t, r9:b // r6 = tmp3
++      mulhh.w         r9, r7:b, lr:t // r9 = z1       
++      mulhh.w         r7, r7:t, lr:b // r7 = z2       
++    
++    
++      add             r10, r9
++      add             r0, r7
++      add             r8, r7
++      add             r6, r9
++
++      add             r1, r2, r6 // r1 = dataptr[DCTSIZE*0]
++      sub             r2, r2, r6 // r2 = dataptr[DCTSIZE*7]
++      add             r6, r4, r8 // r6 = dataptr[DCTSIZE*1]
++      sub             r4, r4, r8 // r4 = dataptr[DCTSIZE*6]
++      add             r8, r5, r0 // r8 = dataptr[DCTSIZE*2]
++      sub             r5, r5, r0 // r5 = dataptr[DCTSIZE*5]
++      add             r0, r3, r10 // r0 = dataptr[DCTSIZE*3]
++      sub             r3, r3, r10 // r3 = dataptr[DCTSIZE*4]
++      
++      satrnds         r1 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r2 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r6 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r4 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r8 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r5 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r0 >> (CONST_BITS+PASS1_BITS+3), 9
++      satrnds         r3 >> (CONST_BITS+PASS1_BITS+3), 9
++
++      packw.sh        r7, r1, r6
++      packw.sh        r6, r8, r0
++      packw.sh        r5, r3, r5
++      packw.sh        r4, r4, r2
++
++      stm             r12, r4-r7
++      sub             sp, -2  // Increment the dataptr
++      sub             r12, -16
++                                      
++      sub             loop_cnt, 1             //Decrement loop counter
++      brne            0b                      //Perform loop one more time if loop_cnt is not zero 
++      
++      sub             sp, -(8*8*2 - 8)        
++      popm            r0-r3, r4-r7, pc        //Pop back registers and PC 
++      
++
++
++      .align 2
++coef_table_idct:      
++      .short  FIX_0_541196100, -FIX_1_847759065, FIX_0_765366865, FIX_1_175875602 
++      .short  - FIX_1_961570560, - FIX_0_390180644, FIX_0_298631336, FIX_2_053119869
++      .short  FIX_3_072711026, FIX_1_501321110, - FIX_0_899976223, - FIX_2_562915447
++      
+diff --git a/libavcodec/avr32/mc.S b/libavcodec/avr32/mc.S
+new file mode 100644
+index 0000000..07a002d
+--- /dev/null
++++ b/libavcodec/avr32/mc.S
+@@ -0,0 +1,434 @@
++/*
++ * Copyright (c) 2007 Atmel Corporation. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials provided
++ * with the distribution.
++ *
++ * 3. The name of ATMEL may not be used to endorse or promote products
++ * derived from this software without specific prior written
++ * permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL
++ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
++ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
++ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
++ * DAMAGE.
++ */
++              
++      
++      /* Macro for masking the lowest bit of each byte in a
++         packed word */
++      .macro  packedmask1     reg, round
++      .if     \round
++      and     \reg, \reg, r8 >> 1
++      .else
++      and     \reg, r8
++      .endif
++      .endm           
++
++      /* Macro for 8 pixel wide horizontal and vertical interpolation functions */    
++      .macro  pixels8_hv      round, put              
++
++
++      pushm   r0-r7, lr
++
++      /* R12 = uint8_t *block, R11 = uint8_t pixels, R10 = int line_size, R9 = int h */
++      
++      /* Rounding immediate */
++      .if     \round
++      mov     r8, lo(0x02020202)
++      orh     r8, hi(0x02020202) 
++      .else
++      mov     r8, lo(0x01010101)
++      orh     r8, hi(0x01010101) 
++      .endif
++      mov     r7, 2
++      
++      /* Pixel naming convention :     
++      
++              |-----------------------------------------------------|
++              | s00 | s01 | s02 | s03 | s04 | s05 | s06 | s07 | s08 |
++              |----d00---d01---d02---d03---d04---d05---d06---d07----|
++              | s10 | s11 | s12 | s13 | s14 | s15 | s16 | s17 | s18 |
++              |-----------------------------------------------------|
++      */
++1:    
++      ld.w    r0, r11[0]              // r0 = { s00, s01, s02, s03 } 
++      ld.w    r1, r11[1]              // r1 = { s01, s02, s03, s04 }
++      mov     lr, r9
++      eor     r2, r0, r1              
++      packedmask1     r2, \round                       
++      add     r2, r8
++
++      paddh.ub        r0, r0, r1      // r0 = {(s00+s01)/2,(s01+s02)/2,(s02+s03)/2,(s03+s04)/2}
++      
++      add             r11, r10        // pixels += line_size
++      ld.w    r1, r11[0]              // r1 = { s10, s11, s12, s13 } 
++      ld.w    r3, r11[1]              // r3 = { s11, s12, s13, s14 }
++0:
++      eor     r5, r1, r3              
++      packedmask1     r5, \round                       
++      add     r2, r5
++      
++      paddh.ub        r1, r1, r3      // r1 = {(s10+s11)/2,(s11+s12)/2,(s12+s13)/2,(s13+s14)/2}
++      eor     r6, r0, r1              
++      packedmask1     r6, \round                       
++      add     r2, r2, r6 << 1 
++                                              
++      ld.w    r3, r11[r10]            // r3 = { s00, s01, s02, s03 } 
++      add     r11, r10                // pixels += line_size
++      ld.w    r4, r11[1]              // r4 = { s01, s02, s03, s04 }
++
++      paddh.ub        r0, r0, r1
++      plsr.b          r2, r2, 2
++      padd.b          r0, r0, r2      // r0 = { d00, d01, d02, d03 }
++      
++      /* Next row */
++      .if     \put
++      eor     r2, r3, r4              
++      packedmask1     r2, \round                       
++      add     r2, r8
++      .else
++      ld.w    r6, r12[0]
++      eor     r2, r3, r4              
++      packedmask1     r2, \round                       
++      add     r2, r8
++      pavg.ub r0, r0, r6
++      .endif
++      st.w    r12[0], r0              // Put data into the block
++              
++      add     r5, r2
++      paddh.ub        r0, r3, r4      // r0 = {(s00+s01)/2,(s01+s02)/2,(s02+s03)/2,(s03+s04)/2}
++                              
++      eor     r6, r0, r1              
++      packedmask1     r6, \round                       
++      add     r5, r5, r6 << 1 
++
++      .if     \put
++      paddh.ub        r1, r0, r1
++      plsr.b          r5, r5, 2
++      padd.b          r1, r1, r5      // r1 = { d10, d11, d12, d13 }
++      .else
++      ld.w            r3, r12[r10]
++      paddh.ub        r1, r0, r1
++      plsr.b          r5, r5, 2
++      padd.b          r1, r1, r5      // r1 = { d10, d11, d12, d13 }
++      pavg.ub         r1, r1, r3
++      .endif
++              
++      st.w    r12[r10], r1            // Put data into the block
++      
++      
++      ld.w    r1, r11[r10]            // r1 = { s10, s11, s12, s13 } 
++      add     r11, r10                // pixels += line_size
++      ld.w    r3, r11[1]              // r3 = { s11, s12, s13, s14 }
++      add     r12, r12, r10 << 1      // block += 2*line_size
++      sub     lr, 2
++      brne    0b
++
++      mul     r0, r10, r9             // r0 = line_size * h
++      rsub    r0, r0, 4               // r0 = 4 - (line_size * h)  
++      add     r11, r0
++      sub     r11, r10                // pixels += 4 - (line_size * (h+1))
++      add     r12, r0                 // pixels += 4 - (line_size * (h))
++      sub     r7, 1
++      brne    1b
++      
++      popm    r0-r7, pc
++      .endm
++
++
++      /* Macro for 8 pixel wide vertical interpolation functions */   
++
++      .macro  pixels8_v       round, put              
++      pushm   r4-r7,lr        
++      /* R12 = uint8_t *block, R11 = uint8_t pixels, R10 = int line_size, R9 = int h */
++
++      /* 
++              Pixel Naming Convention :       
++              |-----------------------------------------------|
++              | s00 | s01 | s02 | s03 | s04 | s05 | s06 | s07 |
++              |-d00---d01---d02---d03---d04---d05---d06---d07-|
++              | s10 | s11 | s12 | s13 | s14 | s15 | s16 | s17 |
++              |-----------------------------------------------|
++      */
++      ld.w    r8, r11[r10]            // r8 = { s10, s11, s12, s13 }
++      ld.w    lr, r11++               // lr = { s00, s01, s02, s03 }, src += 4
++      ld.w    r7, r11[0]              // r7 = { s04, s05, s06, s07 }
++      ld.w    r6, r11[r10]            // r6 = { s14, s15, s16, s17 }
++      sub     r10, 4                  // stride -= 4 
++      add     r11, r11, r10 << 1      // src += 2*stride 
++      sub     r11, -4                 // src += 4                               
++      
++0:    
++      .if     \round
++      pavg.ub r5, r8, lr              // r5 = {(s10+s00)/2,(s11+s01)/2,(s12+s02)/2,(s13+s03)/2}
++      pavg.ub r4, r6, r7              // r4 = {(s14+s04)/2,(s15+s05)/2,(s16+s06)/2,(s17+s07)/2}
++      .else
++      paddh.ub r5, r8, lr             // r5 = {(s10+s00)/2,(s11+s01)/2,(s12+s02)/2,(s13+s03)/2}
++      paddh.ub r4, r6, r7             // r4 = {(s14+s04)/2,(s15+s05)/2,(s16+s06)/2,(s17+s07)/2}
++      .endif
++
++      .if     \put
++      st.w    r12++, r5               // *dst++ = { d00, d01, d02, d03 } 
++      ld.w    lr, r11++               // lr = { s10, s11, s12, s13 }, src += 4 
++      st.w    r12[0], r4              // *dst = { d04, d05, d06, d07 }
++      ld.w    r7, r11[0]              // r7 = { s14, s15, s16, s17 }
++      .else
++      ld.w    lr, r12[0]              
++      ld.w    r7, r12[4]      
++      pavg.ub r5, r5, lr       
++      pavg.ub r4, r4, r7       
++      st.w    r12++, r5               // *dst++ = { d00, d01, d02, d03 } 
++      ld.w    lr, r11++               // lr = { s10, s11, s12, s13 }, src += 4 
++      st.w    r12[0], r4              // *dst = { d04, d05, d06, d07 }
++      ld.w    r7, r11[0]              // r7 = { s14, s15, s16, s17 }
++      .endif
++      add     r11, r10                // src += stride                                                        
++#ifdef USE_PREFETCH
++      pref            r11[0]
++#endif                
++      add     r12, r10                // dst += stride
++
++      .if     \round
++      pavg.ub r5, r8, lr              // r5 = {(s10+s00)/2,(s11+s01)/2,(s12+s02)/2,(s13+s03)/2}
++      pavg.ub r4, r6, r7              // r4 = {(s14+s04)/2,(s15+s05)/2,(s16+s06)/2,(s17+s07)/2}
++      .else
++      paddh.ub r5, r8, lr             // r5 = {(s10+s00)/2,(s11+s01)/2,(s12+s02)/2,(s13+s03)/2}
++      paddh.ub r4, r6, r7             // r4 = {(s14+s04)/2,(s15+s05)/2,(s16+s06)/2,(s17+s07)/2}
++      .endif
++      .if     \put
++      st.w    r12++, r5               // *dst++ = { d00, d01, d02, d03 }                       
++      ld.w    r8, r11++               // r8 = { s10, s11, s12, s13 }, src += 4                 
++      st.w    r12[0], r4              // *dst = { d04, d05, d06, d07 }                         
++      ld.w    r6, r11[0]              // r6 = { s14, s15, s16, s17 }                           
++      .else
++      ld.w    r8, r12[0]              
++      ld.w    r6, r12[4]      
++      pavg.ub r5, r5, r8       
++      pavg.ub r4, r4, r6       
++      st.w    r12++, r5               // *dst++ = { d00, d01, d02, d03 }                       
++      ld.w    r8, r11++               // r8 = { s10, s11, s12, s13 }, src += 4                 
++      st.w    r12[0], r4              // *dst = { d04, d05, d06, d07 }                         
++      ld.w    r6, r11[0]              // r6 = { s14, s15, s16, s17 }                           
++      .endif
++      
++      add     r11, r10                // src += stride                                         
++#ifdef USE_PREFETCH
++      pref            r11[0]
++#endif                
++      add     r12, r10                // dst += stride                                         
++      sub     r9, 2
++      brne    0b
++              
++      popm    r4-r7,pc
++      .endm
++
++      /* Macro for 8 pixel wide horizontal interpolation functions */ 
++
++      .macro  pixels8_h       round, put
++      pushm   r4-r7, lr       
++
++      /* R12 = uint8_t *block, R11 = uint8_t pixels, R10 = int line_size, R9 = int h */
++      /*
++               Pixel Naming Convention:       
++              |--------------------------------------------------------------------|
++              | s00 d00 s01 d01 s02 d02 s03 d03 s04 d04 s05 d05 s06 d06 s07 d07 s08|
++              |------|-------|-------|-------|-------|-------|-------|-------|-----|
++              | s10 d10 s11 d11 s12 d12 s13 d13 s14 d14 s15 d15 s16 d16 s17 d17 s18|
++              |--------------------------------------------------------------------|
++      */
++
++      ld.w    lr, r11[0]      // lr = { s00, s01, s02, s03 }
++      ld.w    r8, r11[1]      // r8 = { s01, s02, s03, s04 }
++      ld.w    r7, r11[4]      // r7 = { s04, s05, s06, s07 }
++      ld.w    r6, r11[5]      // r6 = { s05, s06, s07, s08 }
++      add     r11, r10        // src += stride                        
++
++0:    
++      .if     \round
++      pavg.ub lr, r8, lr      // lr = {(s00+s01)/2,(s01+s02)/2,(s02+s03)/2,(s03+s04)/2}
++      pavg.ub r7, r6, r7      // r7 = {(s04+s05)/2,(s05+s06)/2,(s06+s07)/2,(s07+s08)/2}
++      .else
++      paddh.ub lr, r8, lr     // lr = {(s00+s01)/2,(s01+s02)/2,(s02+s03)/2,(s03+s04)/2}
++      paddh.ub r7, r6, r7     // r7 = {(s04+s05)/2,(s05+s06)/2,(s06+s07)/2,(s07+s08)/2}
++      .endif
++      .if     \put
++      ld.w    r5, r11[0]      // r5 = { s00, s01, s02, s03 }
++      ld.w    r4, r11[1]      // r4 = { s01, s02, s03, s04 }
++      .else
++      ld.w    r8, r12[0]
++      ld.w    r6, r12[4]
++      ld.w    r5, r11[0]      // r5 = { s00, s01, s02, s03 }
++      ld.w    r4, r11[1]      // r4 = { s01, s02, s03, s04 }
++      pavg.ub lr, lr, r8
++      pavg.ub r7, r7, r6
++      .endif
++      st.w    r12[0], lr      // dst = { d00, d01, d02, d03 }
++      st.w    r12[4], r7      // dst = { d04, d05, d06, d07 }
++      ld.w    r8, r11[4]      // r8 = { s04, s05, s06, s07 }
++      ld.w    r6, r11[5]      // r6 = { s05, s06, s07, s08 }
++      add     r11, r10        // src += stride                                                
++#ifdef USE_PREFETCH
++      pref            r11[0]
++#endif                
++      add     r12, r10        // dst += stride
++
++      .if     \round
++      pavg.ub r5, r4, r5      // r5 = {(s00+s01)/2,(s01+s02)/2,(s02+s03)/2,(s03+s04)/2}
++      pavg.ub r4, r6, r8      // r4 = {(s04+s05)/2,(s05+s06)/2,(s06+s07)/2,(s07+s08)/2}
++      .else
++      paddh.ub r5, r4, r5     // r5 = {(s00+s01)/2,(s01+s02)/2,(s02+s03)/2,(s03+s04)/2}
++      paddh.ub r4, r6, r8     // r4 = {(s04+s05)/2,(s05+s06)/2,(s06+s07)/2,(s07+s08)/2}
++      .endif
++      .if     \put
++      ld.w    lr, r11[0]      // lr = { s00, s01, s02, s03 }                           
++      ld.w    r8, r11[1]      // r8 = { s01, s02, s03, s04 }                           
++      .else
++      ld.w    r7, r12[0]
++      ld.w    r6, r12[4]
++      ld.w    lr, r11[0]      // lr = { s00, s01, s02, s03 }                           
++      ld.w    r8, r11[1]      // r8 = { s01, s02, s03, s04 }                           
++      pavg.ub r5, r5, r7
++      pavg.ub r4, r4, r6
++      .endif
++      st.w    r12[0], r5      // dst = { d00, d01, d02, d03 }                          
++      st.w    r12[4], r4      // dst = { d04, d05, d06, d07 }                          
++      ld.w    r7, r11[4]      // r7 = { s04, s05, s06, s07 }                           
++      ld.w    r6, r11[5]      // r6 = { s05, s06, s07, s08 }                           
++      add     r11, r10        // src += stride                                                                                         
++#ifdef USE_PREFETCH
++      pref            r11[0]
++#endif                
++      add     r12, r10        // dst += stride                                         
++      sub     r9, 2
++      brne    0b
++              
++      popm    r4-r7, pc
++      .endm
++      
++      /* Macro for 8 pixel wide copy functions */     
++      .macro  pixels8 put
++      stm             --sp, r3-r7,lr
++      /* R12 = uint8_t *block, R11 = uint8_t pixels, R10 = int line_size, R9 = int h */
++      mov             lr, r9
++      sub             r3, r10, 2              // stride2 = stride - 2 
++0:    
++      .if     \put
++      ld.w            r9, r11[r10]            // r9 = { s10, s11, s12, s13 }
++      ld.w            r7, r11++               // r7 = { s00, s01, s02, s03 }, src += 4
++      ld.w            r6, r11[0]              // r6 = { s04, s05, s06, s07 }
++      ld.w            r8, r11[r10]            // r8 = { s14, s15, s16, s17 }
++      .else
++      ld.w            r9, r11[r10]            // r9 = { s10, s11, s12, s13 }
++      ld.d            r4, r12[0]
++      ld.w            r7, r11++               // r7 = { s00, s01, s02, s03 }, src += 4
++      ld.w            r6, r11[0]              // r6 = { s04, s05, s06, s07 }
++      ld.w            r8, r11[r10]            // r8 = { s14, s15, s16, s17 }
++      pavg.ub         r6, r6, r4
++      pavg.ub         r7, r7, r5
++      ld.d            r4, r12[r10]
++      .endif
++      st.d            r12, r6                 // *dst = { s00, s01, s02, s03, s04, s05, s06, s07 }   
++      add             r11, r11, r3 << 1       // src += stride2 * 2
++      .ifeq   \put
++      pavg.ub         r8, r8, r4
++      pavg.ub         r9, r9, r5      
++      .endif  
++      st.d            r12[r10 << 0], r8       // *(dst + stride) = { s10, s11, s12, s13, s14, s15, s16, s17 } 
++      add             r12, r12, r10 << 1      // dst += 2*stride
++      sub             lr, 2
++      brne            0b
++      ldm             sp++, r3-r7,pc
++
++      .endm   
++      
++      .global put_no_rnd_pixels8_hv_avr32
++      .text
++put_no_rnd_pixels8_hv_avr32:
++      pixels8_hv      0, 1    
++
++      .global put_pixels8_hv_avr32
++      .text
++put_pixels8_hv_avr32:
++      pixels8_hv      1, 1    
++
++      .global avg_no_rnd_pixels8_hv_avr32
++      .text
++avg_no_rnd_pixels8_hv_avr32:
++      pixels8_hv      0, 0    
++
++      .global avg_pixels8_hv_avr32
++      .text
++avg_pixels8_hv_avr32:
++      pixels8_hv      1, 0    
++
++      .global put_no_rnd_pixels8_v_avr32
++      .text
++put_no_rnd_pixels8_v_avr32:
++      pixels8_v       0, 1    
++
++      .global put_pixels8_v_avr32
++      .text
++put_pixels8_v_avr32:
++      pixels8_v       1, 1    
++
++      .global avg_no_rnd_pixels8_v_avr32
++      .text
++avg_no_rnd_pixels8_v_avr32:
++      pixels8_v       0, 0    
++
++      .global avg_pixels8_v_avr32
++      .text
++avg_pixels8_v_avr32:
++      pixels8_v       1, 0    
++
++      .global put_no_rnd_pixels8_h_avr32
++      .text
++put_no_rnd_pixels8_h_avr32:
++      pixels8_h       0, 1    
++
++      .global put_pixels8_h_avr32
++      .text
++put_pixels8_h_avr32:
++      pixels8_h       1, 1    
++
++      .global avg_no_rnd_pixels8_h_avr32
++      .text
++avg_no_rnd_pixels8_h_avr32:
++      pixels8_h       0, 0    
++
++      .global avg_pixels8_h_avr32
++      .text
++avg_pixels8_h_avr32:
++      pixels8_h       1, 0    
++
++      .global put_pixels8_avr32
++      .global put_no_rnd_pixels8_avr32
++      .text
++put_pixels8_avr32:
++put_no_rnd_pixels8_avr32:
++      pixels8 1       
++
++      .global avg_no_rnd_pixels8_avr32
++      .global avg_pixels8_avr32
++      .text
++avg_pixels8_avr32:
++avg_no_rnd_pixels8_avr32:
++      pixels8 0       
+diff --git a/libavcodec/avr32/pico.h b/libavcodec/avr32/pico.h
+new file mode 100644
+index 0000000..32201ba
+--- /dev/null
++++ b/libavcodec/avr32/pico.h
+@@ -0,0 +1,260 @@
++/*
++ * Copyright (c) 2007 Atmel Corporation. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials provided
++ * with the distribution.
++ *
++ * 3. The name of ATMEL may not be used to endorse or promote products
++ * derived from this software without specific prior written
++ * permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL
++ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
++ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
++ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
++ * DAMAGE.
++ */
++#ifndef __PICO_H__
++#define __PICO_H__
++
++
++
++/* Coprocessor Number */
++#define PICO_CPNO  1
++
++/* Pixel Coprocessor Register file */
++#define PICO_REGVECT_INPIX2  cr0
++#define PICO_REGVECT_INPIX1  cr1
++#define PICO_REGVECT_INPIX0  cr2
++#define PICO_REGVECT_OUTPIX2 cr3
++#define PICO_REGVECT_OUTPIX1 cr4
++#define PICO_REGVECT_OUTPIX0 cr5
++#define PICO_REGVECT_COEFF0_A cr6
++#define PICO_REGVECT_COEFF0_B cr7
++#define PICO_REGVECT_COEFF1_A cr8
++#define PICO_REGVECT_COEFF1_B cr9
++#define PICO_REGVECT_COEFF2_A cr10
++#define PICO_REGVECT_COEFF2_B cr11
++#define PICO_REGVECT_VMU0_OUT cr12
++#define PICO_REGVECT_VMU1_OUT cr13
++#define PICO_REGVECT_VMU2_OUT cr14
++#define PICO_REGVECT_CONFIG   cr15
++
++#define PICO_INPIX2  0
++#define PICO_INPIX1  1
++#define PICO_INPIX0  2
++#define PICO_OUTPIX2 3
++#define PICO_OUTPIX1 4
++#define PICO_OUTPIX0 5
++#define PICO_COEFF0_A 6
++#define PICO_COEFF0_B 7
++#define PICO_COEFF1_A 8
++#define PICO_COEFF1_B 9
++#define PICO_COEFF2_A 10
++#define PICO_COEFF2_B 11
++#define PICO_VMU0_OUT 12
++#define PICO_VMU1_OUT 13
++#define PICO_VMU2_OUT 14
++#define PICO_CONFIG   15
++
++/* Config Register */
++#define PICO_COEFF_FRAC_BITS_OFFSET  0
++#define PICO_COEFF_FRAC_BITS_SIZE  4
++#define PICO_OFFSET_FRAC_BITS_OFFSET  4
++#define PICO_OFFSET_FRAC_BITS_SIZE  4
++#define PICO_INPUT_MODE_OFFSET  8
++#define PICO_INPUT_MODE_SIZE  2
++#define PICO_OUTPUT_MODE_OFFSET 10
++#define PICO_OUTPUT_MODE_SIZE 1
++
++struct pico_config_t {
++  unsigned int          : 32 - PICO_OUTPUT_MODE_OFFSET - PICO_OUTPUT_MODE_SIZE;
++  unsigned int          output_mode : PICO_OUTPUT_MODE_SIZE;
++  unsigned int          input_mode : PICO_INPUT_MODE_SIZE;
++  unsigned int          offset_frac_bits : PICO_OFFSET_FRAC_BITS_SIZE;
++  unsigned int          coeff_frac_bits : PICO_COEFF_FRAC_BITS_SIZE;
++  int                   vmu2_out;
++  int                   vmu1_out;
++  int                   vmu0_out;
++  short                 coeff2_2;
++  short                 coeff2_3;
++  short                 coeff2_0;
++  short                 coeff2_1;
++  short                 coeff1_2;
++  short                 coeff1_3;
++  short                 coeff1_0;
++  short                 coeff1_1;
++  short                 coeff0_2;
++  short                 coeff0_3;
++  short                 coeff0_0;
++  short                 coeff0_1;
++};
++
++
++#define PICO_COEFF_FRAC_BITS(x) (x << PICO_COEFF_FRAC_BITS_OFFSET)
++#define PICO_OFFSET_FRAC_BITS(x) (x << PICO_OFFSET_FRAC_BITS_OFFSET)
++#define PICO_INPUT_MODE(x) (x << PICO_INPUT_MODE_OFFSET)
++#define PICO_OUTPUT_MODE(x) (x << PICO_OUTPUT_MODE_OFFSET)
++
++#define GET_PICO_COEFF_FRAC_BITS(x) ((x >> PICO_COEFF_FRAC_BITS_OFFSET)&((1 << PICO_COEFF_FRAC_BITS_SIZE)-1))
++#define GET_PICO_OFFSET_FRAC_BITS(x) ((x >> PICO_OFFSET_FRAC_BITS_OFFSET)&((1 << PICO_OFFSET_FRAC_BITS_SIZE)-1))
++#define GET_PICO_INPUT_MODE(x) ((x >> PICO_INPUT_MODE_OFFSET)&((1 << PICO_INPUT_MODE_SIZE)-1))
++#define GET_PICO_OUTPUT_MODE(x) ((x >> PICO_OUTPUT_MODE_OFFSET)&((1 << PICO_OUTPUT_MODE_SIZE)-1))
++
++enum pico_input_mode { PICO_TRANSFORMATION_MODE,
++                       PICO_HOR_FILTER_MODE,
++                       PICO_VERT_FILTER_MODE };
++
++enum pico_output_mode { PICO_PACKED_MODE,
++                        PICO_PLANAR_MODE };
++
++/* Bits in coefficients */
++#define PICO_COEFF_BITS 12
++
++/* Operation bits */
++#define PICO_MATRIX (0)
++#define PICO_USE_ACC (1 << 2)
++#define PICO_SINGLE_VECTOR (1 << 3)
++
++
++#define __str(x...) #x
++#define __xstr(x...) __str(x)
++
++#define PICO_PUT_W(pico_reg, x) \
++  __builtin_mvrc_w(PICO_CPNO, pico_reg, x);
++#define PICO_GET_W(pico_reg) \
++  __builtin_mvcr_w(PICO_CPNO, pico_reg)
++
++#define PICO_MVCR_W(x, pico_reg) \
++  asm ("mvcr.w\tcp" __xstr(PICO_CPNO) ", %0, cr" __xstr(pico_reg) : "=r"(x));
++
++#define PICO_MVRC_W(pico_reg, x) \
++  asm  ("mvrc.w\tcp" __xstr(PICO_CPNO) ", cr" __xstr(pico_reg) ", %0" :: "r"(x));
++
++#define PICO_PUT_D(pico_reg, x) \
++  __builtin_mvrc_d(PICO_CPNO, pico_reg, x);
++#define PICO_GET_D(pico_reg) \
++  __builtin_mvcr_d(PICO_CPNO, pico_reg)
++
++#define PICO_MVCR_D(x, pico_reg) \
++  asm volatile ("mvcr.d\tcp" __xstr(PICO_CPNO) ", %0, cr" __xstr(pico_reg) : "=r"(x));
++#define PICO_MVRC_D(pico_reg, x) \
++  asm volatile ("mvrc.d\tcp" __xstr(PICO_CPNO) ", cr" __xstr(pico_reg) ", %0" :: "r"(x));
++
++#define PICO_STCM_W(ptr, pico_regs...) \
++  asm volatile ("stcm.w\tcp" __xstr(PICO_CPNO) ", %0," __xstr(pico_regs)  :: "r"(ptr)); 
++#define PICO_STCM_D(ptr, pico_regs...) \
++  asm volatile ("stcm.d\tcp" __xstr(PICO_CPNO) ", %0," __xstr(pico_regs)  :: "r"(ptr)); 
++
++#define PICO_STCM_W_DEC(ptr, pico_regs...) \
++  asm volatile ("stcm.w\tcp" __xstr(PICO_CPNO) ", --%0," __xstr(pico_regs)  : "+r"(ptr)); 
++#define PICO_STCM_D_DEC(ptr, pico_regs...) \
++  asm volatile ("stcm.d\tcp" __xstr(PICO_CPNO) ", --%0," __xstr(pico_regs)  : "+r"(ptr)); 
++
++#define PICO_LDCM_W(ptr, pico_regs...) \
++  asm volatile ("ldcm.w\tcp" __xstr(PICO_CPNO) ", %0," __xstr(pico_regs)  :: "r"(ptr)); 
++#define PICO_LDCM_D(ptr, pico_regs...) \
++  asm volatile ("ldcm.d\tcp" __xstr(PICO_CPNO) ", %0," __xstr(pico_regs)  :: "r"(ptr)); 
++
++#define PICO_LDCM_W_INC(ptr, pico_regs...) \
++  asm volatile ("ldcm.w\tcp" __xstr(PICO_CPNO) ", %0++," __xstr(pico_regs)  : "+r"(ptr)); 
++#define PICO_LDCM_D_INC(ptr, pico_regs...) \
++  asm volatile ("ldcm.d\tcp" __xstr(PICO_CPNO) ", %0++," __xstr(pico_regs)  : "+r"(ptr)); 
++
++#define PICO_OP(op, dst_addr, addr0, addr1, addr2) \
++  __builtin_cop(PICO_CPNO, addr0, addr1, addr2, op | dst_addr);
++
++static inline void set_pico_config(struct pico_config_t *config){
++  PICO_LDCM_D(config, 
++              PICO_REGVECT_COEFF0_A, PICO_REGVECT_COEFF0_B, 
++              PICO_REGVECT_COEFF1_A, PICO_REGVECT_COEFF1_B,
++              PICO_REGVECT_COEFF2_A, PICO_REGVECT_COEFF2_B,
++              PICO_REGVECT_VMU0_OUT, PICO_REGVECT_VMU1_OUT,
++              PICO_REGVECT_VMU2_OUT, PICO_REGVECT_CONFIG);              
++}
++
++static inline void get_pico_config(struct pico_config_t *config){
++  PICO_STCM_D(config, 
++              PICO_REGVECT_COEFF0_A, PICO_REGVECT_COEFF0_B, 
++              PICO_REGVECT_COEFF1_A, PICO_REGVECT_COEFF1_B,
++              PICO_REGVECT_COEFF2_A, PICO_REGVECT_COEFF2_B,
++              PICO_REGVECT_VMU0_OUT, PICO_REGVECT_VMU1_OUT,
++              PICO_REGVECT_VMU2_OUT, PICO_REGVECT_CONFIG);              
++}
++
++static inline void dump_pico_config(){
++  struct pico_config_t pico_config;
++  char *input_mode, *output_mode;
++  get_pico_config(&pico_config);
++
++  
++  av_log(NULL, AV_LOG_INFO, "Dumping pico configuration:\n\n"); 
++  av_log(NULL, AV_LOG_INFO, "\tcoeff_frac_bits = %d\n", pico_config.coeff_frac_bits); 
++  av_log(NULL, AV_LOG_INFO, "\toffset_frac_bits = %d\n", pico_config.offset_frac_bits); 
++
++  switch ( pico_config.input_mode ){
++  case PICO_TRANSFORMATION_MODE:
++    input_mode = "Transformation Mode"; 
++    break;
++  case PICO_HOR_FILTER_MODE:
++    input_mode = "Horisontal Filter Mode"; 
++    break;
++  case PICO_VERT_FILTER_MODE:
++    input_mode = "Vertical Filter Mode"; 
++    break;
++  default:
++    input_mode = "Unknown Mode!!"; 
++    break;    
++  }
++  av_log(NULL, AV_LOG_INFO, "\tinput_mode = %s\n", input_mode); 
++
++  switch ( pico_config.output_mode ){
++  case PICO_PLANAR_MODE:
++    output_mode = "Planar Mode"; 
++    break;
++  case PICO_PACKED_MODE:
++    output_mode = "Packed Mode"; 
++    break;
++  default:
++    output_mode = "Unknown Mode!!"; 
++    break;    
++  }
++
++  av_log(NULL, AV_LOG_INFO, "\toutput_mode = %s\n", output_mode); 
++
++  av_log(NULL, AV_LOG_INFO, "\tCoeff0_0 = %f\n", (float)pico_config.coeff0_0/(float)(1 << pico_config.coeff_frac_bits)); 
++  av_log(NULL, AV_LOG_INFO, "\tCoeff0_1 = %f\n", (float)pico_config.coeff0_1/(float)(1 << pico_config.coeff_frac_bits)); 
++  av_log(NULL, AV_LOG_INFO, "\tCoeff0_2 = %f\n", (float)pico_config.coeff0_2/(float)(1 << pico_config.coeff_frac_bits)); 
++  av_log(NULL, AV_LOG_INFO, "\tCoeff0_3 = %f\n", (float)pico_config.coeff0_3/(float)(1 << pico_config.offset_frac_bits)); 
++                                   
++  av_log(NULL, AV_LOG_INFO, "\tCoeff1_0 = %f\n", (float)pico_config.coeff1_0/(float)(1 << pico_config.coeff_frac_bits)); 
++  av_log(NULL, AV_LOG_INFO, "\tCoeff1_1 = %f\n", (float)pico_config.coeff1_1/(float)(1 << pico_config.coeff_frac_bits)); 
++  av_log(NULL, AV_LOG_INFO, "\tCoeff1_2 = %f\n", (float)pico_config.coeff1_2/(float)(1 << pico_config.coeff_frac_bits)); 
++  av_log(NULL, AV_LOG_INFO, "\tCoeff1_3 = %f\n", (float)pico_config.coeff1_3/(float)(1 << pico_config.offset_frac_bits)); 
++                                   
++  av_log(NULL, AV_LOG_INFO, "\tCoeff2_0 = %f\n", (float)pico_config.coeff2_0/(float)(1 << pico_config.coeff_frac_bits)); 
++  av_log(NULL, AV_LOG_INFO, "\tCoeff2_1 = %f\n", (float)pico_config.coeff2_1/(float)(1 << pico_config.coeff_frac_bits)); 
++  av_log(NULL, AV_LOG_INFO, "\tCoeff2_2 = %f\n", (float)pico_config.coeff2_2/(float)(1 << pico_config.coeff_frac_bits)); 
++  av_log(NULL, AV_LOG_INFO, "\tCoeff2_3 = %f\n", (float)pico_config.coeff2_3/(float)(1 << pico_config.offset_frac_bits)); 
++}
++
++
++
++#endif
++
+diff --git a/libavcodec/bitstream.h b/libavcodec/bitstream.h
+index 26b4f8d..1f8fabf 100644
+--- a/libavcodec/bitstream.h
++++ b/libavcodec/bitstream.h
+@@ -171,7 +171,7 @@ typedef struct RL_VLC_ELEM {
+ #endif
+ /* used to avoid missaligned exceptions on some archs (alpha, ...) */
+-#if defined(ARCH_X86) || defined(ARCH_X86_64)
++#if defined(ARCH_X86) || defined(ARCH_X86_64) || defined(ARCH_AVR32)
+ #    define unaligned16(a) (*(const uint16_t*)(a))
+ #    define unaligned32(a) (*(const uint32_t*)(a))
+ #    define unaligned64(a) (*(const uint64_t*)(a))
+@@ -813,6 +813,44 @@ void free_vlc(VLC *vlc);
+  * if the vlc code is invalid and max_depth>1 than the number of bits removed
+  * is undefined
+  */
++
++#if defined(ARCH_AVR32)
++#define GET_VLC(code, name, gb, table, bits, max_depth)\
++{\
++    int n, index, nb_bits;\
++    union { VLC_TYPE vlc[2];\
++            uint32_t u32; } table_elem;\
++\
++    index= SHOW_UBITS(name, gb, bits);\
++    table_elem.u32 = unaligned32(&table[index]); \
++    code = table_elem.vlc[0];\
++    n    = table_elem.vlc[1];\
++\
++    if(max_depth > 1 && n < 0 ){\
++        LAST_SKIP_BITS(name, gb, bits)\
++        UPDATE_CACHE(name, gb)\
++\
++        nb_bits = -n;\
++\
++        index= SHOW_UBITS(name, gb, nb_bits) + code;\
++        table_elem.u32 = unaligned32(&table[index]); \
++        code = table_elem.vlc[0];\
++        n    = table_elem.vlc[1];\
++        if(max_depth > 2 && n < 0){\
++            LAST_SKIP_BITS(name, gb, nb_bits)\
++            UPDATE_CACHE(name, gb)\
++\
++            nb_bits = -n;\
++\
++            index= SHOW_UBITS(name, gb, nb_bits) + code;\
++            code = table[index][0];\
++            n    = table[index][1];\
++        }\
++    }\
++    SKIP_BITS(name, gb, n)\
++}
++
++#else
+ #define GET_VLC(code, name, gb, table, bits, max_depth)\
+ {\
+     int n, index, nb_bits;\
+@@ -821,7 +859,7 @@ void free_vlc(VLC *vlc);
+     code = table[index][0];\
+     n    = table[index][1];\
+ \
+-    if(max_depth > 1 && n < 0){\
++    if(max_depth > 1 && n < 0 ){\
+         LAST_SKIP_BITS(name, gb, bits)\
+         UPDATE_CACHE(name, gb)\
+ \
+@@ -843,7 +881,38 @@ void free_vlc(VLC *vlc);
+     }\
+     SKIP_BITS(name, gb, n)\
+ }
++#endif
++#if defined(ARCH_AVR32)
++#define GET_RL_VLC(level, run, name, gb, table, bits, max_depth, need_update)\
++{\
++    int n, index, nb_bits;\
++    union { RL_VLC_ELEM vlc;\
++            uint32_t u32; } table_elem;\
++\
++    index= SHOW_UBITS(name, gb, bits);\
++    table_elem.u32 = unaligned32(&table[index]); \
++    level = table_elem.vlc.level;\
++    n     = table_elem.vlc.len;\
++\
++    if(max_depth > 1 && n < 0 ){\
++        SKIP_BITS(name, gb, bits)\
++        if(need_update){\
++            UPDATE_CACHE(name, gb)\
++        }\
++\
++        nb_bits = -n;\
++\
++        index= SHOW_UBITS(name, gb, nb_bits) + level;\
++        table_elem.u32 = unaligned32(&table[index]); \
++        level = table_elem.vlc.level;\
++        n     = table_elem.vlc.len;\
++    }\
++    run= table_elem.vlc.run;\
++    SKIP_BITS(name, gb, n)\
++}
++
++#else
+ #define GET_RL_VLC(level, run, name, gb, table, bits, max_depth, need_update)\
+ {\
+     int n, index, nb_bits;\
+@@ -852,7 +921,7 @@ void free_vlc(VLC *vlc);
+     level = table[index].level;\
+     n     = table[index].len;\
+ \
+-    if(max_depth > 1 && n < 0){\
++    if(max_depth > 1 && n < 0 ){\
+         SKIP_BITS(name, gb, bits)\
+         if(need_update){\
+             UPDATE_CACHE(name, gb)\
+@@ -867,7 +936,7 @@ void free_vlc(VLC *vlc);
+     run= table[index].run;\
+     SKIP_BITS(name, gb, n)\
+ }
+-
++#endif
+ /**
+  * parses a vlc code, faster then get_vlc()
+diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c
+index 56c42b9..8fc10c6 100644
+--- a/libavcodec/dsputil.c
++++ b/libavcodec/dsputil.c
+@@ -4197,6 +4197,9 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx)
+ #ifdef ARCH_BFIN
+     dsputil_init_bfin(c,avctx);
+ #endif
++#ifdef ARCH_AVR32
++    dsputil_init_avr32(c,avctx);
++#endif
+     for(i=0; i<64; i++){
+         if(!c->put_2tap_qpel_pixels_tab[0][i])
+diff --git a/libavcodec/h264.c b/libavcodec/h264.c
+index 865e80a..8f7c3f1 100644
+--- a/libavcodec/h264.c
++++ b/libavcodec/h264.c
+@@ -3258,7 +3258,12 @@ static void free_tables(H264Context *h){
+ static void init_dequant8_coeff_table(H264Context *h){
+     int i,q,x;
++#ifdef ARCH_AVR32
++    const int transpose = 0;
++#else
+     const int transpose = (h->s.dsp.h264_idct8_add != ff_h264_idct8_add_c); //FIXME ugly
++#endif
++
+     h->dequant8_coeff[0] = h->dequant8_buffer[0];
+     h->dequant8_coeff[1] = h->dequant8_buffer[1];
+@@ -3281,7 +3286,13 @@ static void init_dequant8_coeff_table(H264Context *h){
+ static void init_dequant4_coeff_table(H264Context *h){
+     int i,j,q,x;
++    // Yes this is ugly as hell....
++#ifdef ARCH_AVR32
++    const int transpose = 0;
++#else
+     const int transpose = (h->s.dsp.h264_idct_add != ff_h264_idct_add_c); //FIXME ugly
++#endif
++
+     for(i=0; i<6; i++ ){
+         h->dequant4_coeff[i] = h->dequant4_buffer[i];
+         for(j=0; j<i; j++){
+@@ -4663,7 +4674,11 @@ static int decode_slice_header(H264Context *h){
+         if (MPV_common_init(s) < 0)
+             return -1;
++#ifdef ARCH_AVR32
++        if ( 1 ){
++#else
+         if(s->dsp.h264_idct_add == ff_h264_idct_add_c){ //FIXME little ugly
++#endif
+             memcpy(h->zigzag_scan, zigzag_scan, 16*sizeof(uint8_t));
+             memcpy(h-> field_scan,  field_scan, 16*sizeof(uint8_t));
+         }else{
+diff --git a/libavutil/common.h b/libavutil/common.h
+index 3ae5971..7e52b90 100644
+--- a/libavutil/common.h
++++ b/libavutil/common.h
+@@ -283,23 +283,39 @@ static inline int mid_pred(int a, int b, int c)
+  * @param amax maximum value of the clip range
+  * @return cliped value
+  */
++#if defined(ARCH_AVR32)
++#define clip(a, amin, amax) \
++  ({ int __tmp__; \
++     asm ("min\t%0, %1, %2\n" \
++          "max\t%0, %0, %3\n" \
++          : "=&r"(__tmp__) : "r"(a), "r"(amax), "r"(amin)); \
++     __tmp__; })
++#else
+ static inline int clip(int a, int amin, int amax)
+ {
+     if (a < amin)      return amin;
+     else if (a > amax) return amax;
+     else               return a;
+ }
++#endif
+ /**
+  * clip a signed integer value into the 0-255 range
+  * @param a value to clip
+  * @return cliped value
+  */
++#if defined(ARCH_AVR32)
++#define clip_uint8(a) \
++  ({ int __tmp__ = a; \
++     asm ("satu\t%0 >> 0, 8" : "+r"(__tmp__)); \
++     __tmp__; })
++#else
+ static inline uint8_t clip_uint8(int a)
+ {
+     if (a&(~255)) return (-a)>>31;
+     else          return a;
+ }
++#endif
+ /* math */
+ int64_t ff_gcd(int64_t a, int64_t b);
+diff --git a/libavutil/internal.h b/libavutil/internal.h
+index 285d304..a8b0718 100644
+--- a/libavutil/internal.h
++++ b/libavutil/internal.h
+@@ -210,6 +210,15 @@ if((y)<(x)){\
+     }\
+ }
++/* XXX: Hack for uclibc which declares lrintf but does not implement it... */
++#ifdef ARCH_AVR32
++#undef HAVE_LRINTF
++#define HAVE_LRINTF 1
++#define lrintf(x) rint(x)
++#define llrint(x) (long long)rint(x) 
++#endif
++ 
++
+ #ifndef HAVE_LRINTF
+ /* XXX: add ISOC specific test to avoid specific BSD testing. */
+ /* better than nothing implementation. */
+diff --git a/libfaad2/common.h b/libfaad2/common.h
+index f809042..6c5fb21 100644
+--- a/libfaad2/common.h
++++ b/libfaad2/common.h
+@@ -67,7 +67,7 @@ extern "C" {
+ /* Use if target platform has address generators with autoincrement */
+ //#define PREFER_POINTERS
+-#if defined(_WIN32_WCE) || defined(__arm__)
++#if defined(_WIN32_WCE) || defined(__arm__) || defined(__avr32__)
+ #define FIXED_POINT
+ #endif
+diff --git a/libmpcodecs/ad_libmad.c b/libmpcodecs/ad_libmad.c
+index 076359a..51b77fe 100644
+--- a/libmpcodecs/ad_libmad.c
++++ b/libmpcodecs/ad_libmad.c
+@@ -86,6 +86,11 @@ static int init(sh_audio_t *sh){
+   sh->channels=(this->frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ? 1 : 2;
+   sh->samplerate=this->frame.header.samplerate;
+   sh->i_bps=this->frame.header.bitrate/8;
++#ifdef WORDS_BIGENDIAN
++  sh->sample_format = AF_FORMAT_S16_BE;
++#else
++  sh->sample_format = AF_FORMAT_S16_LE;
++#endif
+   sh->samplesize=2;
+   
+   return 1;
+diff --git a/libswscale/pico-avr32.h b/libswscale/pico-avr32.h
+new file mode 100644
+index 0000000..7ac6200
+--- /dev/null
++++ b/libswscale/pico-avr32.h
+@@ -0,0 +1,137 @@
++/*
++ * Copyright (c) 2007 Atmel Corporation. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials provided
++ * with the distribution.
++ *
++ * 3. The name of ATMEL may not be used to endorse or promote products
++ * derived from this software without specific prior written
++ * permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL
++ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
++ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
++ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
++ * DAMAGE.
++ */
++#ifndef __PICO_H__
++#define __PICO_H__
++
++/* Coprocessor Number */
++#define PICO_CPNO  1
++
++/* Pixel Coprocessor Register file */
++#define PICO_REGVECT_INPIX2  cr0
++#define PICO_REGVECT_INPIX1  cr1
++#define PICO_REGVECT_INPIX0  cr2
++#define PICO_REGVECT_OUTPIX2 cr3
++#define PICO_REGVECT_OUTPIX1 cr4
++#define PICO_REGVECT_OUTPIX0 cr5
++#define PICO_REGVECT_COEFF0_A cr6
++#define PICO_REGVECT_COEFF0_B cr7
++#define PICO_REGVECT_COEFF1_A cr8
++#define PICO_REGVECT_COEFF1_B cr9
++#define PICO_REGVECT_COEFF2_A cr10
++#define PICO_REGVECT_COEFF2_B cr11
++#define PICO_REGVECT_VMU0_OUT cr12
++#define PICO_REGVECT_VMU1_OUT cr13
++#define PICO_REGVECT_VMU2_OUT cr14
++#define PICO_REGVECT_CONFIG   cr15
++
++#define PICO_INPIX2  0
++#define PICO_INPIX1  1
++#define PICO_INPIX0  2
++#define PICO_OUTPIX2 3
++#define PICO_OUTPIX1 4
++#define PICO_OUTPIX0 5
++#define PICO_COEFF0_A 6
++#define PICO_COEFF0_B 7
++#define PICO_COEFF1_A 8
++#define PICO_COEFF1_B 9
++#define PICO_COEFF2_A 10
++#define PICO_COEFF2_B 11
++#define PICO_VMU0_OUT 12
++#define PICO_VMU1_OUT 13
++#define PICO_VMU2_OUT 14
++#define PICO_CONFIG   15
++
++/* Config Register */
++#define PICO_COEFF_FRAC_BITS  0
++#define PICO_COEFF_FRAC_BITS_WIDTH  4
++#define PICO_OFFSET_FRAC_BITS  4
++#define PICO_OFFSET_FRAC_BITS_WIDTH  4
++#define PICO_INPUT_MODE  8
++#define PICO_INPUT_MODE_WIDTH  2
++#define PICO_OUTPUT_MODE 10
++
++#define PICO_TRANSFORMATION_MODE 0 
++#define PICO_HOR_FILTER_MODE 1 
++#define PICO_VERT_FILTER_MODE 2 
++
++#define PICO_PLANAR_MODE 1
++#define PICO_PACKED_MODE 0
++
++/* Bits in coefficients */
++#define PICO_COEFF_BITS 12
++
++/* Operation bits */
++#define PICO_USE_ACC (1 << 2)
++#define PICO_SINGLE_VECTOR (1 << 3)
++
++
++#define __str(x...) #x
++#define __xstr(x...) __str(x)
++
++#define PICO_PUT_W(pico_reg, x) \
++  __builtin_mvrc_w(PICO_CPNO, pico_reg, x);
++#define PICO_GET_W(pico_reg) \
++  __builtin_mvcr_w(PICO_CPNO, pico_reg)
++
++#define PICO_PUT_D(pico_reg, x) \
++  __builtin_mvrc_d(PICO_CPNO, pico_reg, x);
++#define PICO_GET_D(pico_reg) \
++  __builtin_mvcr_d(PICO_CPNO, pico_reg)
++
++
++#define PICO_STCM_W(ptr, pico_regs...) \
++  asm volatile ("stcm.w\tcp" __xstr(PICO_CPNO) ", %0," __xstr(pico_regs)  :: "r"(ptr)); 
++#define PICO_STCM_D(ptr, pico_regs...) \
++  asm volatile ("stcm.d\tcp" __xstr(PICO_CPNO) ", %0," __xstr(pico_regs)  :: "r"(ptr)); 
++
++#define PICO_STCM_W_DEC(ptr, pico_regs...) \
++  asm volatile ("stcm.w\tcp" __xstr(PICO_CPNO) ", --%0," __xstr(pico_regs)  : "+r"(ptr)); 
++#define PICO_STCM_D_DEC(ptr, pico_regs...) \
++  asm volatile ("stcm.d\tcp" __xstr(PICO_CPNO) ", --%0," __xstr(pico_regs)  : "+r"(ptr)); 
++
++#define PICO_LDCM_W(ptr, pico_regs...) \
++  asm volatile ("ldcm.w\tcp" __xstr(PICO_CPNO) ", %0," __xstr(pico_regs)  :: "r"(ptr)); 
++#define PICO_LDCM_D(ptr, pico_regs...) \
++  asm volatile ("ldcm.d\tcp" __xstr(PICO_CPNO) ", %0," __xstr(pico_regs)  :: "r"(ptr)); 
++
++#define PICO_LDCM_W_INC(ptr, pico_regs...) \
++  asm volatile ("ldcm.w\tcp" __xstr(PICO_CPNO) ", %0++," __xstr(pico_regs)  : "+r"(ptr)); 
++#define PICO_LDCM_D_INC(ptr, pico_regs...) \
++  asm volatile ("ldcm.d\tcp" __xstr(PICO_CPNO) ", %0++," __xstr(pico_regs)  : "+r"(ptr)); 
++
++#define PICO_OP(op, dst_addr, addr0, addr1, addr2) \
++  __builtin_cop(PICO_CPNO, addr0, addr1, addr2, op | dst_addr);
++
++
++#endif
++
+diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
+index ecd28f5..3221d0c 100644
+--- a/libswscale/swscale_internal.h
++++ b/libswscale/swscale_internal.h
+@@ -173,7 +173,7 @@ typedef struct SwsContext{
+ SwsFunc yuv2rgb_get_func_ptr (SwsContext *c);
+ int yuv2rgb_c_init_tables (SwsContext *c, const int inv_table[4], int fullRange, int brightness, int contrast, int saturation);
+-char *sws_format_name(int format);
++char *sws_format_name(enum PixelFormat format);
+ //FIXME replace this with something faster
+ #define isPlanarYUV(x) ((x)==PIX_FMT_YUV410P || (x)==PIX_FMT_YUV420P  \
+diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c
+index 71759bc..fa83985 100644
+--- a/libswscale/yuv2rgb.c
++++ b/libswscale/yuv2rgb.c
+@@ -44,6 +44,10 @@
+ #include "yuv2rgb_mlib.c"
+ #endif
++#ifdef ARCH_AVR32
++#include "yuv2rgb_avr32.c"
++#endif
++
+ #define DITHER1XBPP // only for mmx
+ const uint8_t  __attribute__((aligned(8))) dither_2x2_4[2][8]={
+@@ -601,6 +605,12 @@ SwsFunc yuv2rgb_get_func_ptr (SwsContext *c)
+       if(t) return t;
+     }
+ #endif
++#ifdef ARCH_AVR32
++    {
++      SwsFunc t= yuv2rgb_init_avr32(c);
++      if(t) return t;
++    }
++#endif
+ #ifdef HAVE_ALTIVEC
+     if (c->flags & SWS_CPU_CAPS_ALTIVEC)
+     {
+@@ -678,6 +688,10 @@ int yuv2rgb_c_init_tables (SwsContext *c, const int inv_table[4], int fullRange,
+ //printf("%lld %lld %lld %lld %lld\n", cy, crv, cbu, cgu, cgv);
+     oy -= 256*brightness;
++#ifdef ARCH_AVR32
++    yuv2rgb_c_init_tables_avr32 (c, inv_table, fullRange, brightness, contrast, saturation);
++#endif
++
+     for (i = 0; i < 1024; i++) {
+       int j;
+diff --git a/libswscale/yuv2rgb_avr32.c b/libswscale/yuv2rgb_avr32.c
+new file mode 100644
+index 0000000..4a8341e
+--- /dev/null
++++ b/libswscale/yuv2rgb_avr32.c
+@@ -0,0 +1,416 @@
++/*
++ * Copyright (c) 2007 Atmel Corporation. All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above
++ * copyright notice, this list of conditions and the following
++ * disclaimer in the documentation and/or other materials provided
++ * with the distribution.
++ *
++ * 3. The name of ATMEL may not be used to endorse or promote products
++ * derived from this software without specific prior written
++ * permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY ATMEL ``AS IS'' AND ANY EXPRESS OR
++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
++ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL
++ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
++ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
++ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
++ * DAMAGE.
++ */
++#include "pico-avr32.h"
++
++
++#define RGB(uv_part)  \
++      __asm__ volatile (        \
++                        "ld.w\t%0, %3[%7:" uv_part " << 2]\n\t" /* tmp = c->table_gV[V] */ \
++                        "ld.w\t%1, %4[%8:" uv_part "  << 2]\n\t" /* g = c->table_gU[U] */  \
++                        "ld.w\t%2, %5[%8:" uv_part "  << 2]\n\t" /* b = c->table_bU[U] */  \
++                        "add\t%1, %0\n\t" /* g += tmp */\
++                        "ld.w\t%0, %6[%7:" uv_part "  << 2]" /* r = c->table_rV[V] */ \
++                        : "=&r" (r), "=&r" (g), "=&r" (b) \
++                        : "r" (&c->table_gV[0]), "r" (&c->table_gU[0]),"r" (&c->table_bU[0]), \
++                        "r" (&c->table_rV[0]), "r" (V), "r" (U));
++
++                        
++#undef YUV2RGB1
++#define YUV2RGB1(dst, src, y, idx) \
++  { int tmp2;    __asm__ volatile (      \
++                        "ld.ub\t%0, %3[2*%8]\n\t" /* Y = ((uint32_t*)py_1)[0] */ \
++                        "ld.ub\t%1, %4[%0]\n\t" /* tmp = r[(Y >> 24) & 0xFF] */ \
++                        "ld.ub\t%2, %5[%0]\n\t" /* tmp = g[(Y >> 24) & 0xFF] */ \
++                        "st.b\t%7[6*%8 + 0], %1\n\t"         /* dst_1[2] = tmp; */   \
++                        "st.b\t%7[6*%8 + 1], %2\n\t"         /* dst_1[1] = tmp; */   \
++                        "ld.ub\t%1, %6[%0]\n\t" /* tmp = b[(Y >> 24) & 0xFF] */ \
++                        "ld.ub\t%0, %3[2*%8 + 1]\n\t" /* Y = ((uint32_t*)py_1)[0] */ \
++                        "st.b\t%7[6*%8 + 2], %1\n\t"         /* dst_1[0] = tmp; */   \
++                        "ld.ub\t%1, %4[%0]\n\t" /* tmp = r[(Y >> 16) & 0xFF] */ \
++                        "ld.ub\t%2, %5[%0]\n\t" /* tmp = g[(Y >> 16) & 0xFF] */ \
++                        "st.b\t%7[6*%8 + 3], %1\n\t"         /* dst_1[5] = tmp; */   \
++                        "ld.ub\t%1, %6[%0]\n\t" /* tmp = b[(Y >> 16) & 0xFF] */ \
++                        "st.b\t%7[6*%8 + 4], %2\n\t"         /* dst_1[4] = tmp; */   \
++                        "st.b\t%7[6*%8 + 5], %1"         /* dst_1[3] = tmp; */   \
++                        : "=&r" (y), "=&r" (tmp), "=&r" (tmp2) \
++                        : "r" (src), "r" (r), "r" (g), "r" (b), "r" (dst), "i" (idx)); }
++                        
++#undef YUV2RGB2
++#define YUV2RGB2(dst, src, y, idx) \
++  { int tmp2;    __asm__ volatile (      \
++                        "ld.ub\t%0, %3[2*%8]\n\t" /* Y = ((uint32_t*)py_1)[0] */ \
++                        "ld.ub\t%1, %4[%0]\n\t" /* tmp = r[(Y >> 24) & 0xFF] */ \
++                        "ld.ub\t%2, %5[%0]\n\t" /* tmp = g[(Y >> 24) & 0xFF] */ \
++                        "st.b\t%7[6*%8 + 0], %1\n\t"         /* dst_1[2] = tmp; */   \
++                        "st.b\t%7[6*%8 + 1], %2\n\t"         /* dst_1[1] = tmp; */   \
++                        "ld.ub\t%1, %6[%0]\n\t" /* tmp = b[(Y >> 24) & 0xFF] */ \
++                        "ld.ub\t%0, %3[2*%8 + 1]\n\t" /* Y = ((uint32_t*)py_1)[0] */ \
++                        "st.b\t%7[6*%8 + 2], %1\n\t"         /* dst_1[0] = tmp; */   \
++                        "ld.ub\t%1, %4[%0]\n\t" /* tmp = r[(Y >> 16) & 0xFF] */ \
++                        "ld.ub\t%2, %5[%0]\n\t" /* tmp = g[(Y >> 16) & 0xFF] */ \
++                        "st.b\t%7[6*%8 + 3], %1\n\t"         /* dst_1[5] = tmp; */   \
++                        "ld.ub\t%1, %6[%0]\n\t" /* tmp = b[(Y >> 16) & 0xFF] */ \
++                        "st.b\t%7[6*%8 + 4], %2\n\t"         /* dst_1[4] = tmp; */   \
++                        "st.b\t%7[6*%8 + 5], %1"         /* dst_1[3] = tmp; */   \
++                        : "=&r" (y), "=&r" (tmp), "=&r" (tmp2) \
++                        : "r" (src), "r" (r), "r" (g), "r" (b), "r" (dst), "i" (idx)); }
++
++
++#undef YUV2BGR1
++#define YUV2BGR1(dst, src, y, idx) \
++  { int tmp2;    __asm__ volatile (      \
++                        "ld.ub\t%0, %3[2*%8]\n\t" /* Y = ((uint32_t*)py_1)[0] */ \
++                        "ld.ub\t%1, %4[%0]\n\t" /* tmp = r[(Y >> 24) & 0xFF] */ \
++                        "ld.ub\t%2, %5[%0]\n\t" /* tmp = g[(Y >> 24) & 0xFF] */ \
++                        "st.b\t%7[6*%8 + 2], %1\n\t"         /* dst_1[2] = tmp; */   \
++                        "st.b\t%7[6*%8 + 1], %2\n\t"         /* dst_1[1] = tmp; */   \
++                        "ld.ub\t%1, %6[%0]\n\t" /* tmp = b[(Y >> 24) & 0xFF] */ \
++                        "ld.ub\t%0, %3[2*%8 + 1]\n\t" /* Y = ((uint32_t*)py_1)[0] */ \
++                        "st.b\t%7[6*%8 + 0], %1\n\t"         /* dst_1[0] = tmp; */   \
++                        "ld.ub\t%1, %4[%0]\n\t" /* tmp = r[(Y >> 16) & 0xFF] */ \
++                        "ld.ub\t%2, %5[%0]\n\t" /* tmp = g[(Y >> 16) & 0xFF] */ \
++                        "st.b\t%7[6*%8 + 5], %1\n\t"         /* dst_1[5] = tmp; */   \
++                        "ld.ub\t%1, %6[%0]\n\t" /* tmp = b[(Y >> 16) & 0xFF] */ \
++                        "st.b\t%7[6*%8 + 4], %2\n\t"         /* dst_1[4] = tmp; */   \
++                        "st.b\t%7[6*%8 + 3], %1"         /* dst_1[3] = tmp; */   \
++                        : "=&r" (y), "=&r" (tmp), "=&r" (tmp2) \
++                        : "r" (src), "r" (r), "r" (g), "r" (b), "r" (dst), "i" (idx)); }
++                        
++#undef YUV2BGR2
++#define YUV2BGR2(dst, src, y, idx) \
++  { int tmp2;    __asm__ volatile (      \
++                        "ld.ub\t%0, %3[2*%8]\n\t" /* Y = ((uint32_t*)py_1)[0] */ \
++                        "ld.ub\t%1, %4[%0]\n\t" /* tmp = r[(Y >> 24) & 0xFF] */ \
++                        "ld.ub\t%2, %5[%0]\n\t" /* tmp = g[(Y >> 24) & 0xFF] */ \
++                        "st.b\t%7[6*%8 + 2], %1\n\t"         /* dst_1[2] = tmp; */   \
++                        "st.b\t%7[6*%8 + 1], %2\n\t"         /* dst_1[1] = tmp; */   \
++                        "ld.ub\t%1, %6[%0]\n\t" /* tmp = b[(Y >> 24) & 0xFF] */ \
++                        "ld.ub\t%0, %3[2*%8 + 1]\n\t" /* Y = ((uint32_t*)py_1)[0] */ \
++                        "st.b\t%7[6*%8 + 0], %1\n\t"         /* dst_1[0] = tmp; */   \
++                        "ld.ub\t%1, %4[%0]\n\t" /* tmp = r[(Y >> 16) & 0xFF] */ \
++                        "ld.ub\t%2, %5[%0]\n\t" /* tmp = g[(Y >> 16) & 0xFF] */ \
++                        "st.b\t%7[6*%8 + 5], %1\n\t"         /* dst_1[5] = tmp; */   \
++                        "ld.ub\t%1, %6[%0]\n\t" /* tmp = b[(Y >> 16) & 0xFF] */ \
++                        "st.b\t%7[6*%8 + 4], %2\n\t"         /* dst_1[4] = tmp; */   \
++                        "st.b\t%7[6*%8 + 3], %1"         /* dst_1[3] = tmp; */   \
++                        : "=&r" (y), "=&r" (tmp), "=&r" (tmp2) \
++                        : "r" (src), "r" (r), "r" (g), "r" (b), "r" (dst), "i" (idx)); }
++
++
++
++int yuv2bgr24_avr32(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, 
++                    int srcSliceH, uint8_t* dst[], int dstStride[]){
++  int y;
++  
++  if(c->srcFormat == PIX_FMT_YUV422P){
++    srcStride[1] *= 2;    
++    srcStride[2] *= 2;
++  }
++
++
++  for(y=0; y<srcSliceH; y+=2){
++    uint8_t *dst_1= (uint8_t*)(dst[0] + (y+srcSliceY  )*dstStride[0]);
++    uint8_t *dst_2= (uint8_t*)(dst[0] + (y+srcSliceY+1)*dstStride[0]);
++    uint32_t *r, *g, *b;
++    uint8_t *py_1= src[0] + y*srcStride[0];
++    uint8_t *py_2= py_1 + srcStride[0];
++    uint8_t *pu= src[1] + (y>>1)*srcStride[1];
++    uint8_t *pv= src[2] + (y>>1)*srcStride[2];
++    unsigned int h_size= c->dstW>>3;
++    while (h_size--) {
++      uint32_t U, V, Y1, Y2, tmp;
++      U = ((uint32_t*)pu)[0];
++      V = ((uint32_t*)pv)[0];
++      
++      RGB("t")
++        YUV2BGR1(dst_1, py_1, Y1, 0) 
++        YUV2BGR1(dst_2, py_2, Y2, 0) 
++
++      RGB("u")
++        YUV2BGR2(dst_1, py_1, Y1, 1) 
++        YUV2BGR2(dst_2, py_2, Y2, 1)
++
++      RGB("l")
++        YUV2BGR1(dst_1, py_1, Y1, 2) 
++        YUV2BGR1(dst_2, py_2, Y2, 2)
++
++      RGB("b")
++        YUV2BGR2(dst_1, py_1, Y1, 3) 
++        YUV2BGR2(dst_2, py_2, Y2, 3)
++ 
++                        
++
++      pu += 4;
++      pv += 4;
++      py_1 += 8;
++      py_2 += 8;
++      dst_1 += 24;
++      dst_2 += 24;
++    }
++  }
++  return srcSliceH;
++}
++
++
++
++static int yuv2rgb24_avr32(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, 
++                             int srcSliceH, uint8_t* dst[], int dstStride[]){
++  int y;
++  
++  if(c->srcFormat == PIX_FMT_YUV422P){
++    srcStride[1] *= 2;
++    srcStride[2] *= 2;
++  }
++  for(y=0; y<srcSliceH; y+=2){
++    uint8_t *dst_1= (uint8_t*)(dst[0] + (y+srcSliceY  )*dstStride[0]);
++    uint8_t *dst_2= (uint8_t*)(dst[0] + (y+srcSliceY+1)*dstStride[0]);
++    uint8_t *r, *g, *b;
++    uint8_t *py_1= src[0] + y*srcStride[0];
++    uint8_t *py_2= py_1 + srcStride[0];
++    uint8_t *pu= src[1] + (y>>1)*srcStride[1];
++    uint8_t *pv= src[2] + (y>>1)*srcStride[2];
++    unsigned int h_size= c->dstW>>3;
++    while (h_size--) {
++      uint32_t U, V, Y1, Y2, tmp;
++      U = ((uint32_t*)pu)[0];
++      V = ((uint32_t*)pv)[0];
++      
++      RGB("t")
++        YUV2RGB1(dst_1, py_1, Y1, 0) 
++        YUV2RGB1(dst_2, py_2, Y2, 0) 
++
++      RGB("u")
++        YUV2RGB2(dst_1, py_1, Y1, 1) 
++        YUV2RGB2(dst_2, py_2, Y2, 1)
++
++      RGB("l")
++        YUV2RGB1(dst_1, py_1, Y1, 2) 
++        YUV2RGB1(dst_2, py_2, Y2, 2)
++
++      RGB("b")
++        YUV2RGB2(dst_1, py_1, Y1, 3) 
++        YUV2RGB2(dst_2, py_2, Y2, 3)
++ 
++      pu += 4;
++      pv += 4;
++      py_1 += 8;
++      py_2 += 8;
++      dst_1 += 24;
++      dst_2 += 24;
++    }
++  }
++  return srcSliceH;
++}
++
++#define SCALE(x, bits) (((x) + ( 1 << (bits - 1))) >> bits)
++#define COEFF_FRAC_BITS  9
++#define OFFSET_FRAC_BITS  2
++
++/* Coefficients used in the pico */
++static struct {
++  short coeff2_2;
++  short coeff2_3;
++  short coeff2_0;
++  short coeff2_1;
++  short coeff1_2;
++  short coeff1_3;
++  short coeff1_0;
++  short coeff1_1;
++  short coeff0_2;
++  short coeff0_3;
++  short coeff0_0;
++  short coeff0_1;
++} pico_coeff;
++
++
++static int yuv2bgr24_avr32_pico(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, 
++                                int srcSliceH, uint8_t* dst[], int dstStride[]){
++  int y;
++  static int first_time = 1;
++
++  /* Initialize pico */
++  PICO_LDCM_D(&pico_coeff, 
++              PICO_REGVECT_COEFF0_A, PICO_REGVECT_COEFF0_B, 
++              PICO_REGVECT_COEFF1_A, PICO_REGVECT_COEFF1_B,
++              PICO_REGVECT_COEFF2_A, PICO_REGVECT_COEFF2_B);              
++  
++  PICO_PUT_W(PICO_CONFIG, 
++             (PICO_PACKED_MODE << PICO_OUTPUT_MODE 
++              | PICO_TRANSFORMATION_MODE << PICO_INPUT_MODE 
++              | OFFSET_FRAC_BITS << PICO_OFFSET_FRAC_BITS
++              | COEFF_FRAC_BITS << PICO_COEFF_FRAC_BITS));
++
++
++  if(c->srcFormat == PIX_FMT_YUV422P){
++    srcStride[1] *= 2;
++    srcStride[2] *= 2;
++  }
++
++  for(y=0; y<srcSliceH; y+=2){
++    uint8_t *dst_1= (uint8_t*)(dst[0] + (y+srcSliceY  )*dstStride[0]);
++    uint8_t *dst_2= (uint8_t*)(dst[0] + (y+srcSliceY+1)*dstStride[0]);
++    uint8_t *r, *g, *b;
++    uint8_t *py_1= src[0] + y*srcStride[0];
++    uint8_t *py_2= py_1 + srcStride[0];
++    uint8_t *pu= src[1] + (y>>1)*srcStride[1];
++    uint8_t *pv= src[2] + (y>>1)*srcStride[2];
++    unsigned int h_size= c->dstW>>3;
++    int *py_1_int = (int *)py_1;
++    int *py_2_int = (int *)py_2;
++    int *pu_int = (int *)pu;
++    int *pv_int = (int *)pv;
++    while (h_size--) {
++      PICO_PUT_W(PICO_INPIX0, *py_1_int++);
++      PICO_PUT_W(PICO_INPIX1, *pu_int++);
++      PICO_PUT_W(PICO_INPIX2, *pv_int++);
++      PICO_OP(0, 0, 0, 4, 8);
++      PICO_OP(0, 1, 1, 4, 8);
++      PICO_OP(0, 2, 2, 5, 9);
++      PICO_OP(0, 3, 3, 5, 9);
++      PICO_PUT_W(PICO_INPIX0, *py_1_int++);
++      PICO_STCM_W(dst_1, PICO_REGVECT_OUTPIX2, PICO_REGVECT_OUTPIX1, PICO_REGVECT_OUTPIX0);
++      PICO_OP(0, 0, 0, 6, 10);
++      PICO_OP(0, 1, 1, 6, 10);
++      PICO_OP(0, 2, 2, 7, 11);
++      PICO_OP(0, 3, 3, 7, 11);
++      PICO_PUT_W(PICO_INPIX0, *py_2_int++);
++      PICO_STCM_W(dst_1 + 12, PICO_REGVECT_OUTPIX2, PICO_REGVECT_OUTPIX1, PICO_REGVECT_OUTPIX0);
++      
++      PICO_OP(0, 0, 0, 4, 8);
++      PICO_OP(0, 1, 1, 4, 8);
++      PICO_OP(0, 2, 2, 5, 9);
++      PICO_OP(0, 3, 3, 5, 9);
++      PICO_PUT_W(PICO_INPIX0, *py_2_int++);
++      PICO_STCM_W(dst_2, PICO_REGVECT_OUTPIX2, PICO_REGVECT_OUTPIX1, PICO_REGVECT_OUTPIX0);
++      PICO_OP(0, 0, 0, 6, 10);
++      PICO_OP(0, 1, 1, 6, 10);
++      PICO_OP(0, 2, 2, 7, 11);
++      PICO_OP(0, 3, 3, 7, 11);
++      PICO_STCM_W(dst_2 + 12, PICO_REGVECT_OUTPIX2, PICO_REGVECT_OUTPIX1, PICO_REGVECT_OUTPIX0);
++
++      dst_1 += 24;
++      dst_2 += 24;
++    }
++  }
++  return srcSliceH;
++}
++
++extern int avr32_use_pico;
++
++SwsFunc yuv2rgb_init_avr32 (SwsContext *c){
++  switch(c->dstFormat){
++  case PIX_FMT_BGR24:
++    {
++      if ( avr32_use_pico ){
++        MSG_ERR("AVR32 BGR24: Using PICO for color space conversion\n");
++        return yuv2bgr24_avr32_pico;
++      } else {
++        MSG_ERR("AVR32 BGR24: Using optimized color space conversion\n");
++        return yuv2bgr24_avr32;
++      }
++    }
++    break;
++  case PIX_FMT_RGB24:
++    {      
++      if ( avr32_use_pico ){
++        MSG_ERR("AVR32 RGB24: Using PICO for color space conversion\n");
++        return yuv2bgr24_avr32_pico;
++      } else {
++        MSG_ERR("AVR32 RGB24: Using optimized color space conversion\n");
++        return yuv2rgb24_avr32;
++      }  
++    }
++  }
++  return NULL;
++}
++
++
++int yuv2rgb_c_init_tables_avr32 (SwsContext *c, const int inv_table[4], int fullRange, int brightness, int contrast, int saturation){
++  const int isRgb = (c->dstFormat == PIX_FMT_RGB24);
++ 
++  int64_t crv =  inv_table[0];
++  int64_t cbu =  inv_table[1];
++  int64_t cgu = -inv_table[2];
++  int64_t cgv = -inv_table[3];
++  int64_t cy  = 1<<16;
++  int64_t oy  = 0;
++  
++  if(!fullRange){
++    cy= (cy*255) / 219;
++    oy= 16<<16;
++  }
++  
++  cy = (cy *contrast             )>>16;
++  crv= (crv*contrast * saturation)>>32;
++  cbu= (cbu*contrast * saturation)>>32;
++  cgu= (cgu*contrast * saturation)>>32;
++  cgv= (cgv*contrast * saturation)>>32;
++
++  oy -= 256*brightness;
++  
++  pico_coeff.coeff1_0 = SCALE(cy, 16 - COEFF_FRAC_BITS); /* G <- Y */
++  pico_coeff.coeff1_1 = SCALE(cgu, 16 - COEFF_FRAC_BITS); /* G <- U */
++  pico_coeff.coeff1_2 = SCALE(cgv, 16 - COEFF_FRAC_BITS); /* G <- V */ 
++  pico_coeff.coeff1_3 = (SCALE(-128*cgu - 128*cgv - 16*cy, 16 - OFFSET_FRAC_BITS)
++                         + /*0.5*/(1 << (OFFSET_FRAC_BITS-1))); /* G offset */ 
++  
++  if ( isRgb ){
++    pico_coeff.coeff0_0 = SCALE(cy, 16 - COEFF_FRAC_BITS); /* R <- Y */
++    pico_coeff.coeff0_1 = 0; /* R <- U */
++    pico_coeff.coeff0_2 = SCALE(crv, 16 - COEFF_FRAC_BITS); /* R <- V */ 
++    pico_coeff.coeff0_3 = (SCALE(-128*crv - 16*cy, 16 - OFFSET_FRAC_BITS)
++                           + /*0.5*/(1 << (OFFSET_FRAC_BITS-1))); /* R offset */ 
++    
++    pico_coeff.coeff2_0 = SCALE(cy, 16 - COEFF_FRAC_BITS); /* B <- Y */
++    pico_coeff.coeff2_1 = SCALE(cbu, 16 - COEFF_FRAC_BITS); /* B <- U */
++    pico_coeff.coeff2_2 = 0; /* B <- V */ 
++    pico_coeff.coeff2_3 = (SCALE(-128*cbu - 16*cy, 16 - OFFSET_FRAC_BITS) 
++                           + /*0.5*/(1 << (OFFSET_FRAC_BITS-1)));/* B offset */       
++  } else {
++    pico_coeff.coeff2_0 = SCALE(cy, 16 - COEFF_FRAC_BITS); /* R <- Y */
++    pico_coeff.coeff2_1 = 0; /* R <- U */
++    pico_coeff.coeff2_2 = SCALE(crv, 16 - COEFF_FRAC_BITS); /* R <- V */ 
++    pico_coeff.coeff2_3 = (SCALE(-128*crv - 16*cy, 16 - OFFSET_FRAC_BITS)
++                           + /*0.5*/(1 << (OFFSET_FRAC_BITS-1))); /* R offset */ 
++    
++    pico_coeff.coeff0_0 = SCALE(cy, 16 - COEFF_FRAC_BITS); /* B <- Y */
++    pico_coeff.coeff0_1 = SCALE(cbu, 16 - COEFF_FRAC_BITS); /* B <- U */
++    pico_coeff.coeff0_2 = 0; /* B <- V */ 
++    pico_coeff.coeff0_3 = (SCALE(-128*cbu - 16*cy, 16 - OFFSET_FRAC_BITS)
++                           + /*0.5*/(1 << (OFFSET_FRAC_BITS-1))); /* B offset */       
++  }
++
++}
++
++
++#undef RGB
+diff --git a/libvo/vo_fbdev2.c b/libvo/vo_fbdev2.c
+index 053c193..7017770 100644
+--- a/libvo/vo_fbdev2.c
++++ b/libvo/vo_fbdev2.c
+@@ -22,6 +22,9 @@
+ #include "sub.h"
+ #include "mp_msg.h"
++/* Draw directly to framebuffer */
++#define USE_CONVERT2FB
++
+ static vo_info_t info = {
+       "Framebuffer Device",
+       "fbdev2",
+@@ -178,6 +181,15 @@ static int fb_preinit(int reset)
+       }
+       fb_orig_vinfo = fb_vinfo;
++      /* Reset panning offset */
++      fb_vinfo.yoffset = 0;
++      if (ioctl(fb_dev_fd, FBIOPAN_DISPLAY, &fb_vinfo)) {
++              mp_msg(MSGT_VO, MSGL_ERR,
++                     "[fbdev2] FBIOPAN_DISPLAY failed: %s\n",
++                     strerror(errno));
++              return 0;
++      }
++
+       fb_bpp = fb_vinfo.bits_per_pixel;
+       /* 16 and 15 bpp is reported as 16 bpp */
+@@ -289,6 +301,10 @@ static int config(uint32_t width, uint32_t height, uint32_t d_width,
+               mp_msg(MSGT_VO, MSGL_ERR, "[fbdev2] Can't malloc next_frame: %s\n", strerror(errno));
+               return 1;
+       }
++#else
++      if ((fb_line_len * fb_vinfo.yres) <= (fb_finfo.smem_len / 2)
++          && fb_vinfo.yoffset == 0)
++              center += fb_line_len * fb_vinfo.yres;
+ #endif
+       if (fs) memset(frame_buffer, '\0', fb_line_len * fb_vinfo.yres);
+@@ -299,14 +315,22 @@ static int query_format(uint32_t format)
+ {
+       // open the device, etc.
+       if (fb_preinit(0)) return 0;
+-      if ((format & IMGFMT_BGR_MASK) == IMGFMT_BGR) {
++      if ((format & IMGFMT_RGB_MASK) == IMGFMT_RGB) {
+               int fb_target_bpp = format & 0xff;
+               set_bpp(&fb_vinfo, fb_target_bpp);
+               fb_vinfo.xres_virtual = fb_vinfo.xres;
+-              fb_vinfo.yres_virtual = fb_vinfo.yres;
++              fb_vinfo.yres_virtual = fb_vinfo.yres * 2;
+               if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) {
+-                      mp_msg(MSGT_VO, MSGL_ERR, "[fbdev2] Can't put VSCREENINFO: %s\n", strerror(errno));
+-                      return 0;
++                      mp_msg(MSGT_VO, MSGL_WARN,
++                             "[fbdev2] Can't double virtual y resolution: %s\n",
++                             strerror(errno));
++                      fb_vinfo.yres_virtual = fb_vinfo.yres;
++                      if (ioctl(fb_dev_fd, FBIOPUT_VSCREENINFO, &fb_vinfo)) {
++                              mp_msg(MSGT_VO, MSGL_ERR,
++                                     "[fbdev2] Can't put VSCREENINFO: %s\n",
++                                     strerror(errno));
++                              return -1;
++                      }
+               }
+               fb_pixel_size = fb_vinfo.bits_per_pixel / 8;
+               fb_bpp = fb_vinfo.red.length + fb_vinfo.green.length +
+@@ -367,16 +391,67 @@ static void check_events(void)
+ static void flip_page(void)
+ {
+-#ifndef USE_CONVERT2FB
+       int i, out_offset = 0, in_offset = 0;
+-      for (i = 0; i < in_height; i++) {
+-              memcpy(center + out_offset, next_frame + in_offset,
+-                              in_width * fb_pixel_size);
+-              out_offset += fb_line_len;
+-              in_offset += in_width * fb_pixel_size;
+-      }
++#ifndef USE_CONVERT2FB
++      if (1) {
++#else
++      if (fb_vinfo.yres_virtual == fb_vinfo.yres) {
+ #endif
++              for (i = 0; i < in_height; i++) {
++                      memcpy(center + out_offset, next_frame + in_offset,
++                             in_width * fb_pixel_size);
++                      out_offset += fb_line_len;
++                      in_offset += in_width * fb_pixel_size;
++              }
++      } else {
++              if (fb_vinfo.yoffset == 0) {
++                      fb_vinfo.yoffset += fb_vinfo.yres;
++                      center -= fb_line_len * fb_vinfo.yres;
++              } else {
++                      fb_vinfo.yoffset = 0;
++                      center += fb_line_len * fb_vinfo.yres;
++              }
++
++              if (ioctl(fb_dev_fd, FBIOPAN_DISPLAY, &fb_vinfo)) {
++                      mp_msg(MSGT_VO, MSGL_ERR,
++                             "[fbdev2] Can't FBIOPAN_DISPLAY: %s\n",
++                             strerror(errno));
++              }
++      }
++}
++
++static uint32_t get_image(mp_image_t *mpi)
++{
++      if(mpi->flags&MP_IMGFLAG_READABLE)
++              return VO_FALSE; // slow video ram 
++      if(mpi->type==MP_IMGTYPE_STATIC)
++              return VO_FALSE; // it is not static
++  
++      if (mpi->flags & (MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH)) {
++              // we're lucky or codec accepts stride => ok, let's go!
++
++              //YUY2 and RGB formats
++              mpi->planes[0] = center;
++              mpi->width = in_width;
++              mpi->stride[0] = fb_line_len;
++
++              // center image
++
++              mpi->flags |= MP_IMGFLAG_DIRECT;
++
++              return VO_TRUE;
++      }
++
++      return VO_FALSE;
++}
++
++static uint32_t put_image(mp_image_t *mpi)
++{
++      // already out?
++      if ((mpi->flags & (MP_IMGFLAG_DIRECT | MP_IMGFLAG_DRAW_CALLBACK)))
++              return VO_TRUE;
++      return VO_FALSE;
+ }
+ static void uninit(void)
+@@ -403,6 +478,10 @@ static int control(uint32_t request, void *data, ...)
+   switch (request) {
+   case VOCTRL_QUERY_FORMAT:
+     return query_format(*((uint32_t*)data));
++  case VOCTRL_GET_IMAGE:
++    return get_image(data);
++  case VOCTRL_DRAW_IMAGE:
++    return put_image(data);
+   }
+   return VO_NOTIMPL;
+ }
+diff --git a/version.sh b/version.sh
+index 44b5c5d..cf22a68 100755
+--- a/version.sh
++++ b/version.sh
+@@ -1,2 +1,2 @@
+ #!/bin/sh
+-echo "#define VERSION \"1.0rc1-$1\"" > version.h
++echo "#define VERSION \"1.0rc1.atmel.2-$1\"" > version.h
index 6d9cd75..c0062bd 100644 (file)
@@ -22,7 +22,11 @@ SRC_URI = "http://www1.mplayerhq.hu/MPlayer/releases/MPlayer-1.0rc1.tar.bz2 \
            file://imageon-video_out.patch;patch=1 \
           file://powerpc-is-ppc.diff;patch=1 \
            file://pxa_configure.patch;patch=1 \
-           file://pxa-video_out.patch;patch=1 "
+           file://pxa-video_out.patch;patch=1 \
+          "
+
+SRC_URI_append_avr32 = " file://mplayer-1.0rc1-atmel.2.patch;patch=1 \
+                       "
 
 # This is required for the collie machine only as all stacks in that
 # machine seem to be set to executable by the toolchain. If someone
@@ -34,7 +38,7 @@ PACKAGE_ARCH_mencoder_collie = "collie"
 
 RCONFLICTS_${PN} = "mplayer-atty"
 RREPLACES_${PN} = "mplayer-atty"
-PR = "r14"
+PR = "r15"
 
 PARALLEL_MAKE = ""
 
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/avr32-arch-2.patch b/packages/uclibc/uclibc-0.9.28/avr32/avr32-arch-2.patch
new file mode 100644 (file)
index 0000000..0e8c2a1
--- /dev/null
@@ -0,0 +1,2135 @@
+Subject: [PATCH] AVR32 Architecture support
+
+Add support for the AVR32 architecture in the core libc and build system.
+This also adds AVR32-ELF definitions to elf.h
+
+---
+
+ Rules.mak                                      |    4 
+ extra/Configs/Config.avr32                     |   38 +++++
+ extra/Configs/Config.in                        |    7 +
+ include/elf.h                                  |   51 +++++++
+ libc/sysdeps/linux/avr32/Makefile              |   93 +++++++++++++
+ libc/sysdeps/linux/avr32/__longjmp.S           |   17 ++
+ libc/sysdeps/linux/avr32/_mmap.c               |   33 ++++
+ libc/sysdeps/linux/avr32/bits/atomicity.h      |   86 ++++++++++++
+ libc/sysdeps/linux/avr32/bits/byteswap.h       |   80 +++++++++++
+ libc/sysdeps/linux/avr32/bits/endian.h         |    7 +
+ libc/sysdeps/linux/avr32/bits/fcntl.h          |  167 +++++++++++++++++++++++++
+ libc/sysdeps/linux/avr32/bits/kernel_stat.h    |   63 +++++++++
+ libc/sysdeps/linux/avr32/bits/kernel_types.h   |   56 ++++++++
+ libc/sysdeps/linux/avr32/bits/machine-gmon.h   |   69 ++++++++++
+ libc/sysdeps/linux/avr32/bits/mman.h           |   95 ++++++++++++++
+ libc/sysdeps/linux/avr32/bits/profil-counter.h |   26 +++
+ libc/sysdeps/linux/avr32/bits/setjmp.h         |   21 +++
+ libc/sysdeps/linux/avr32/bits/syscalls.h       |  143 +++++++++++++++++++++
+ libc/sysdeps/linux/avr32/bits/wordsize.h       |    1 
+ libc/sysdeps/linux/avr32/brk.c                 |   23 +++
+ libc/sysdeps/linux/avr32/bsd-_setjmp.S         |   12 +
+ libc/sysdeps/linux/avr32/bsd-setjmp.S          |   12 +
+ libc/sysdeps/linux/avr32/clone.c               |   37 +++++
+ libc/sysdeps/linux/avr32/crt1.S                |   93 +++++++++++++
+ libc/sysdeps/linux/avr32/crti.S                |   17 ++
+ libc/sysdeps/linux/avr32/crtn.S                |   14 ++
+ libc/sysdeps/linux/avr32/mmap.c                |   31 ++++
+ libc/sysdeps/linux/avr32/setjmp.S              |   43 ++++++
+ libc/sysdeps/linux/avr32/sigaction.c           |   49 +++++++
+ libc/sysdeps/linux/avr32/sigrestorer.S         |   11 +
+ libc/sysdeps/linux/avr32/sys/elf.h             |   26 +++
+ libc/sysdeps/linux/avr32/sys/io.h              |   48 +++++++
+ libc/sysdeps/linux/avr32/sys/procfs.h          |  123 ++++++++++++++++++
+ libc/sysdeps/linux/avr32/sys/ucontext.h        |   94 ++++++++++++++
+ libc/sysdeps/linux/avr32/sys/user.h            |   46 ++++++
+ libc/sysdeps/linux/avr32/syscall.S             |   81 ++++++++++++
+ libc/sysdeps/linux/avr32/vfork.S               |   55 ++++++++
+ 37 files changed, 1872 insertions(+)
+
+Index: uClibc-0.9.28/extra/Configs/Config.avr32
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/extra/Configs/Config.avr32   2006-05-05 09:27:17.000000000 +0200
+@@ -0,0 +1,38 @@
++#
++# For a description of the syntax of this configuration file,
++# see extra/config/Kconfig-language.txt
++#
++
++config HAVE_ELF
++      bool
++      default y
++
++config TARGET_ARCH
++      default "avr32"
++
++config ARCH_CFLAGS
++      string
++
++config ARCH_LDFLAGS
++      string
++
++config LIBGCC_CFLAGS
++      string
++
++config ARCH_SUPPORTS_BIG_ENDIAN
++      bool
++      default y
++
++config UCLIBC_COMPLETELY_PIC
++      select FORCE_SHAREABLE_TEXT_SEGMENTS
++      bool
++      default y
++
++choice
++      prompt "Target CPU Type"
++      default CONFIG_AP7000
++
++config CONFIG_AP7000
++      bool "AP7000"
++
++endchoice
+Index: uClibc-0.9.28/extra/Configs/Config.in
+===================================================================
+--- uClibc-0.9.28.orig/extra/Configs/Config.in 2006-04-19 12:47:48.000000000 +0200
++++ uClibc-0.9.28/extra/Configs/Config.in      2006-04-19 12:48:33.000000000 +0200
+@@ -16,6 +16,9 @@ config TARGET_alpha
+ config TARGET_arm
+       bool "arm"
++config TARGET_avr32
++      bool "avr32"
++
+ config TARGET_bfin
+       bool "bfin"
+@@ -83,6 +86,10 @@ if TARGET_arm
+ source "extra/Configs/Config.arm"
+ endif
++if TARGET_avr32
++source "extra/Configs/Config.avr32"
++endif
++
+ if TARGET_bfin
+ source "extra/Configs/Config.bfin"
+ endif
+Index: uClibc-0.9.28/include/elf.h
+===================================================================
+--- uClibc-0.9.28.orig/include/elf.h   2006-04-19 12:47:48.000000000 +0200
++++ uClibc-0.9.28/include/elf.h        2006-05-05 09:28:38.000000000 +0200
+@@ -261,6 +261,8 @@ typedef struct
+ #define EM_NIOS32     0xfebb          /* Altera Nios 32 */
+ #define EM_ALTERA_NIOS2  0x9ee5       /* Altera Nios II */
++#define EM_AVR32      0x18ad
++
+ /* V850 backend magic number.  Written in the absense of an ABI.  */
+ #define EM_CYGNUS_V850 0x9080
+@@ -2687,6 +2689,55 @@ typedef Elf32_Addr Elf32_Conflict;
+ /* Keep this the last entry.  */
+ #define R_V850_NUM            25
++/* Atmel AVR32 relocations.  */
++#define R_AVR32_NONE          0
++#define R_AVR32_32            1
++#define R_AVR32_16            2
++#define R_AVR32_8             3
++#define R_AVR32_32_PCREL      4
++#define R_AVR32_16_PCREL      5
++#define R_AVR32_8_PCREL               6
++#define R_AVR32_DIFF32                7
++#define R_AVR32_DIFF16                8
++#define R_AVR32_DIFF8         9
++#define R_AVR32_GOT32         10
++#define R_AVR32_GOT16         11
++#define R_AVR32_GOT8          12
++#define R_AVR32_21S           13
++#define R_AVR32_16U           14
++#define R_AVR32_16S           15
++#define R_AVR32_8S            16
++#define R_AVR32_8S_EXT                17
++#define R_AVR32_22H_PCREL     18
++#define R_AVR32_18W_PCREL     19
++#define R_AVR32_16B_PCREL     20
++#define R_AVR32_16N_PCREL     21
++#define R_AVR32_14UW_PCREL    22
++#define R_AVR32_11H_PCREL     23
++#define R_AVR32_10UW_PCREL    24
++#define R_AVR32_9H_PCREL      25
++#define R_AVR32_9UW_PCREL     26
++#define R_AVR32_HI16          27
++#define R_AVR32_LO16          28
++#define R_AVR32_GOTPC         29
++#define R_AVR32_GOTCALL               30
++#define R_AVR32_LDA_GOT               31
++#define R_AVR32_GOT21S                32
++#define R_AVR32_GOT18SW               33
++#define R_AVR32_GOT16S                34
++#define R_AVR32_GOT7UW                35
++#define R_AVR32_32_CPENT      36
++#define R_AVR32_CPCALL                37
++#define R_AVR32_16_CP         38
++#define R_AVR32_9W_CP         39
++#define R_AVR32_RELATIVE      40
++#define R_AVR32_GLOB_DAT      41
++#define R_AVR32_JMP_SLOT      42
++#define R_AVR32_ALIGN         43
++#define R_AVR32_NUM           44
++
++/* AVR32 dynamic tags */
++#define DT_AVR32_GOTSZ                0x70000001 /* Total size of GOT in bytes */
+ #define R_H8_NONE       0
+ #define R_H8_DIR32      1
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/Makefile    2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,93 @@
++# Makefile for uClibc
++#
++# Copyright (C) 2000-2003 Erik Andersen <andersen@uclibc.org>
++#
++# This program is free software; you can redistribute it and/or modify it under
++# the terms of the GNU Library 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 Library General Public License for more
++# details.
++#
++# You should have received a copy of the GNU Library 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
++
++TOPDIR=../../../../
++include $(TOPDIR)Rules.mak
++ASFLAGS=$(CFLAGS)
++
++CRT_SRC       = crt1.S
++CRT_OBJ = crt1.o
++SCRT_OBJ = $(patsubst %,S%, $(CRT_OBJ))
++CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
++
++SSRC=__longjmp.S setjmp.S bsd-setjmp.S vfork.S \
++      bsd-_setjmp.S sigrestorer.S syscall.S
++SOBJS=$(patsubst %.S,%.o, $(SSRC))
++
++CSRC=clone.c brk.c sigaction.c mmap.c
++COBJS=$(patsubst %.c,%.o, $(CSRC))
++
++OBJS=$(SOBJS) $(COBJS)
++
++OBJ_LIST=../../../obj.sysdeps.$(TARGET_ARCH)
++
++all: $(OBJ_LIST)
++
++$(OBJ_LIST): $(OBJS) $(CRT_OBJ) $(SCRT_OBJ) $(CTOR_TARGETS)
++      echo $(patsubst %, sysdeps/linux/$(TARGET_ARCH)/%, $(OBJS)) > $(OBJ_LIST)
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp $(CRT_OBJ) $(SCRT_OBJ) $(TOPDIR)lib/
++
++$(CRT_OBJ): $(CRT_SRC)
++      $(CC) $(ASFLAGS) -DL_$* $< -c -o $*.o
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(SCRT_OBJ): $(CRT_SRC)
++      $(CC) $(ASFLAGS) $(PIEFLAG) -DL_$* $< -c -o $*.o
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(SOBJS): %.o : %.S
++      $(CC) $(ASFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(COBJS): %.o : %.c
++      $(CC) $(CFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
++crti.o: crti.S
++      $(CC) $(ASFLAGS) -c crti.S -o crti.o
++
++$(TOPDIR)lib/crti.o: crti.o
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp crti.o $(TOPDIR)lib/
++
++crtn.o: crtn.S
++      $(CC) $(ASFLAGS) -c crtn.S -o crtn.o
++
++$(TOPDIR)lib/crtn.o: crtn.o
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp crtn.o $(TOPDIR)lib/
++else
++$(TOPDIR)lib/crti.o:
++      $(INSTALL) -d $(TOPDIR)lib/
++      $(AR) $(ARFLAGS) $(TOPDIR)lib/crti.o
++$(TOPDIR)lib/crtn.o:
++      $(INSTALL) -d $(TOPDIR)lib/
++      $(AR) $(ARFLAGS) $(TOPDIR)lib/crtn.o
++endif
++
++
++headers:
++#     $(LN) -fs ../libc/sysdeps/linux/avr32/fpu_control.h $(TOPDIR)/include/
++
++clean:
++      $(RM) *.[oa] *~ core
++      $(RM) bits/sysnum.h
++      $(RM) gmon-start.S
++
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/__longjmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/__longjmp.S 2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,17 @@
++/* longjmp for AVR32
++ *
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      .global __longjmp
++      .type   __longjmp,"function"
++      .align  1
++__longjmp:
++      ldm     r12++, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr
++      mov     r12, r11        /* get the return value right */
++      mustr   r8              /* restore status register (lower half) */
++      cp      r12, 0          /* can't return zero */
++      frs
++      moveq   r12, 1
++      mov     pc,lr
++      .size   __longjmp, . - __longjmp
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/_mmap.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/_mmap.c     2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,33 @@
++/* Copyright (C) 2005 Atmel Norway
++
++   This program is free software; you can redistribute it and/or modify it under
++   the terms of the GNU Library 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 Library General Public License for more
++   details.
++
++   You should have received a copy of the GNU Library 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
++
++   Derived in part from the Linux-8086 C library, the GNU C Library, and several
++   other sundry sources.  Files within this library are copyright by their
++   respective copyright holders.
++ */
++
++#include <errno.h>
++#include <sys/mman.h>
++#include <sys/syscall.h>
++
++#define __NR_mmap2 __NR_mmap
++
++static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot, int, flags, int, fd, __off_t, pgoff);
++
++__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
++{
++      return mmap2(addr, len, prot, flags, fd, offset >> 12);
++}
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/atomicity.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/atomicity.h    2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,86 @@
++/* Low-level functions for atomic operations.  AVR32 version.
++   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef _ATOMICITY_H
++#define _ATOMICITY_H 1
++
++#include <inttypes.h>
++
++static inline int
++__attribute__((unused))
++exchange_and_add (volatile uint32_t *mem, int val)
++{
++      int tmp, result;
++
++      __asm__ __volatile__(
++              "/* Inline exchange and add */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %3\n"
++              "       add     %1, %0, %4\n"
++              "       stcond  %2, %1\n"
++              "       brne    1b"
++              : "=&r"(result), "=&r"(tmp), "=m"(*mem)
++              : "m"(*mem), "r"(val)
++              : "cc", "memory");
++
++      return result;
++}
++
++static inline void
++__attribute__((unused))
++atomic_add (volatile uin32_t *mem, int val)
++{
++      int result;
++
++      __asm__ __volatile__(
++              "/* Inline atomic add */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %2\n"
++              "       add     %0, %3\n"
++              "       stcond  %2, %0\n"
++              "       brne    1b"
++              : "=&r"(result), "=m"(*mem)
++              : "m"(*mem), "r"(val)
++              : "cc", "memory");
++}
++
++static inline int
++__attribute__((unused))
++compare_and_swap(volatile long int *p, long int oldval, long int newval)
++{
++      long int result, tmp;
++
++      __asm__ __volatile__(
++              "/* Inline compare and swap */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %1, %3\n"
++              "       cp.w    %1, %5\n"
++              "       sreq    %0\n"
++              "       brne    2f\n"
++              "       stcond  %2, %4\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=&r"(tmp), "=m"(*p)
++              : "m"(*p), "r"(newval), "r"(oldval)
++              : "cc", "memory");
++
++      return result;
++}
++
++#endif /* atomicity.h */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/byteswap.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/byteswap.h     2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,80 @@
++/* Macros to swap the order of bytes in integer values.
++   Copyright (C) 2005 Atmel Norway.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
++# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
++#endif
++
++#ifndef _BITS_BYTESWAP_H
++#define _BITS_BYTESWAP_H 1
++
++/* Swap bytes in 16 bit value.  */
++#if defined __GNUC__
++# define __bswap_16(x) (__extension__ __builtin_bswap_16(x))
++#else
++/* This is better than nothing.  */
++static __inline unsigned short int
++__bswap_16 (unsigned short int __bsx)
++{
++      return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));
++}
++#endif
++
++/* Swap bytes in 32 bit value.  */
++#if defined __GNUC__
++# define __bswap_32(x) (__extension__ __builtin_bswap_32(x))
++#else
++static __inline unsigned int
++__bswap_32 (unsigned int __bsx)
++{
++  return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >>  8) |
++        (((__bsx) & 0x0000ff00) <<  8) | (((__bsx) & 0x000000ff) << 24));
++}
++#endif
++
++#if defined __GNUC__
++/* Swap bytes in 64 bit value.  */
++# define __bswap_constant_64(x)                               \
++      ((((x) & 0xff00000000000000ull) >> 56)          \
++       | (((x) & 0x00ff000000000000ull) >> 40)        \
++       | (((x) & 0x0000ff0000000000ull) >> 24)        \
++       | (((x) & 0x000000ff00000000ull) >> 8)         \
++       | (((x) & 0x00000000ff000000ull) << 8)         \
++       | (((x) & 0x0000000000ff0000ull) << 24)        \
++       | (((x) & 0x000000000000ff00ull) << 40)        \
++       | (((x) & 0x00000000000000ffull) << 56))
++
++# define __bswap_64(x)                                                        \
++      (__extension__                                                  \
++       ({                                                             \
++               union {                                                \
++                       __extension__ unsigned long long int __ll;     \
++                       unsigned int __l[2];                           \
++               } __w, __r;                                            \
++               if (__builtin_constant_p(x))                           \
++                       __r.__ll = __bswap_constant_64(x);             \
++               else {                                                 \
++                       __w.__ll = (x);                                \
++                       __r.__l[0] = __bswap_32(__w.__l[1]);           \
++                       __r.__l[1] = __bswap_32(__w.__l[0]);           \
++               }                                                      \
++               __r.__ll;                                              \
++       }))
++#endif
++
++#endif /* _BITS_BYTESWAP_H */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/endian.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/endian.h       2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,7 @@
++/* AVR32 is big-endian */
++
++#ifndef _ENDIAN_H
++# error "Never use <bits/endian.h> directly; include <endian.h> instead."
++#endif
++
++#define __BYTE_ORDER __BIG_ENDIAN
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/fcntl.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/fcntl.h        2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,167 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ *
++ * This file is part of the Linux kernel
++ */
++#ifndef _FCNTL_H
++# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
++#endif
++
++#include <sys/types.h>
++
++/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
++   located on an ext2 file system */
++#define O_ACCMODE       0003
++#define O_RDONLY          00
++#define O_WRONLY          01
++#define O_RDWR                    02
++#define O_CREAT                 0100  /* not fcntl */
++#define O_EXCL                  0200  /* not fcntl */
++#define O_NOCTTY        0400  /* not fcntl */
++#define O_TRUNC                01000  /* not fcntl */
++#define O_APPEND       02000
++#define O_NONBLOCK     04000
++#define O_NDELAY      O_NONBLOCK
++#define O_SYNC                010000
++#define O_ASYNC               020000
++
++#ifdef __USE_GNU
++# define O_DIRECTORY  040000  /* must be a directory */
++# define O_NOFOLLOW   0100000 /* don't follow links */
++# define O_DIRECT     0200000 /* direct disk access */
++#endif
++
++#ifdef __USE_LARGEFILE64
++# define O_LARGEFILE  0400000
++#endif
++
++/* For now Linux has synchronisity options for data and read operations.
++   We define the symbols here but let them do the same as O_SYNC since
++   this is a superset.        */
++#if defined __USE_POSIX199309 || defined __USE_UNIX98
++# define O_DSYNC      O_SYNC  /* Synchronize data.  */
++# define O_RSYNC      O_SYNC  /* Synchronize read operations.  */
++#endif
++
++#define F_DUPFD               0       /* dup */
++#define F_GETFD               1       /* get close_on_exec */
++#define F_SETFD               2       /* set/clear close_on_exec */
++#define F_GETFL               3       /* get file->f_flags */
++#define F_SETFL               4       /* set file->f_flags */
++
++#ifndef __USE_FILE_OFFSET64
++# define F_GETLK      5
++# define F_SETLK      6
++# define F_SETLKW     7
++#else
++# define F_GETLK      F_GETLK64
++# define F_SETLK      F_SETLK64
++# define F_SETLKW     F_SETLKW64
++#endif
++#define F_GETLK64     12      /*  using 'struct flock64' */
++#define F_SETLK64     13
++#define F_SETLKW64    14
++
++#if defined __USE_BSD || defined __USE_XOPEN2K
++# define F_SETOWN     8       /*  for sockets. */
++# define F_GETOWN     9       /*  for sockets. */
++#endif
++
++#ifdef __USE_GNU
++# define F_SETSIG     10      /*  for sockets. */
++# define F_GETSIG     11      /*  for sockets. */
++#endif
++
++#ifdef __USE_GNU
++# define F_SETLEASE   1024    /* Set a lease.  */
++# define F_GETLEASE   1025    /* Enquire what lease is active.  */
++# define F_NOTIFY     1026    /* Request notfications on a directory.  */
++#endif
++
++/* for F_[GET|SET]FL */
++#define FD_CLOEXEC    1       /* actually anything with low bit set goes */
++
++/* for posix fcntl() and lockf() */
++#define F_RDLCK               0
++#define F_WRLCK               1
++#define F_UNLCK               2
++
++/* for old implementation of bsd flock () */
++#define F_EXLCK               4       /* or 3 */
++#define F_SHLCK               8       /* or 4 */
++
++/* for leases */
++#define F_INPROGRESS  16
++
++#ifdef __USE_BSD
++/* operations for bsd flock(), also used by the kernel implementation */
++# define LOCK_SH      1       /* shared lock */
++# define LOCK_EX      2       /* exclusive lock */
++# define LOCK_NB      4       /* or'd with one of the above to prevent
++                                 blocking */
++# define LOCK_UN      8       /* remove lock */
++#endif
++
++#ifdef __USE_GNU
++# define LOCK_MAND    32      /* This is a mandatory flock */
++# define LOCK_READ    64      /* ... Which allows concurrent
++                                     read operations */
++# define LOCK_WRITE   128     /* ... Which allows concurrent
++                                     write operations */
++# define LOCK_RW      192     /* ... Which allows concurrent
++                                     read & write ops */
++#endif
++
++#ifdef __USE_GNU
++/* Types of directory notifications that may be requested with F_NOTIFY.  */
++# define DN_ACCESS    0x00000001      /* File accessed.  */
++# define DN_MODIFY    0x00000002      /* File modified.  */
++# define DN_CREATE    0x00000004      /* File created.  */
++# define DN_DELETE    0x00000008      /* File removed.  */
++# define DN_RENAME    0x00000010      /* File renamed.  */
++# define DN_ATTRIB    0x00000020      /* File changed attibutes.  */
++# define DN_MULTISHOT 0x80000000      /* Don't remove notifier.  */
++#endif
++
++struct flock {
++      short l_type;
++      short l_whence;
++#ifndef __USE_FILE_OFFSET64
++      __off_t l_start;
++      __off_t l_len;
++#else
++      __off64_t l_start;
++      __off64_t l_len;
++#endif
++      __pid_t l_pid;
++};
++
++#ifdef __USE_LARGEFILE64
++struct flock64 {
++      short  l_type;
++      short  l_whence;
++      __off64_t l_start;
++      __off64_t l_len;
++      __pid_t  l_pid;
++};
++#endif
++
++/* Define some more compatibility macros to be backward compatible with
++ *    BSD systems which did not managed to hide these kernel macros.  */
++#ifdef  __USE_BSD
++# define FAPPEND        O_APPEND
++# define FFSYNC         O_FSYNC
++# define FASYNC         O_ASYNC
++# define FNONBLOCK      O_NONBLOCK
++# define FNDELAY        O_NDELAY
++#endif /* Use BSD.  */
++
++/* Advise to `posix_fadvise'.  */
++#ifdef __USE_XOPEN2K
++# define POSIX_FADV_NORMAL      0 /* No further special treatment.  */
++# define POSIX_FADV_RANDOM      1 /* Expect random page references.  */
++# define POSIX_FADV_SEQUENTIAL  2 /* Expect sequential page references.  */
++# define POSIX_FADV_WILLNEED    3 /* Will need these pages.  */
++# define POSIX_FADV_DONTNEED    4 /* Don't need these pages.  */
++# define POSIX_FADV_NOREUSE     5 /* Data will be accessed once.  */
++#endif
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_stat.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_stat.h  2006-05-05 09:28:32.000000000 +0200
+@@ -0,0 +1,63 @@
++#ifndef _BITS_STAT_STRUCT_H
++#define _BITS_STAT_STRUCT_H
++
++/*
++ * This file provides struct stat, taken from kernel 2.6.4
++ * (include/asm-avr32/stat.h revision 1.1).
++ */
++
++struct kernel_stat {
++        unsigned long st_dev;
++        unsigned long st_ino;
++        unsigned short st_mode;
++        unsigned short st_nlink;
++        unsigned short st_uid;
++        unsigned short st_gid;
++        unsigned long  st_rdev;
++        unsigned long  st_size;
++        unsigned long  st_blksize;
++        unsigned long  st_blocks;
++        unsigned long  st_atime;
++        unsigned long  st_atime_nsec;
++        unsigned long  st_mtime;
++        unsigned long  st_mtime_nsec;
++        unsigned long  st_ctime;
++        unsigned long  st_ctime_nsec;
++        unsigned long  __unused4;
++        unsigned long  __unused5;
++};
++
++#define STAT_HAVE_NSEC 1
++
++struct kernel_stat64 {
++      unsigned long long st_dev;
++
++      unsigned long long st_ino;
++      unsigned int    st_mode;
++      unsigned int    st_nlink;
++
++      unsigned long   st_uid;
++      unsigned long   st_gid;
++
++      unsigned long long st_rdev;
++
++      long long       st_size;
++      unsigned long   __pad1;
++      unsigned long   st_blksize;
++
++      unsigned long long st_blocks;
++
++      unsigned long   st_atime;
++      unsigned long   st_atime_nsec;
++
++      unsigned long   st_mtime;
++      unsigned long   st_mtime_nsec;
++
++      unsigned long   st_ctime;
++      unsigned long   st_ctime_nsec;
++
++      unsigned long   __unused1;
++      unsigned long   __unused2;
++};
++
++#endif /* _BITS_STAT_STRUCT_H */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_types.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_types.h 2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,56 @@
++/* Note that we use the exact same include guard #define names
++ * as asm/posix_types.h.  This will avoid gratuitous conflicts
++ * with the posix_types.h kernel header, and will ensure that
++ * our private content, and not the kernel header, will win.
++ *  -Erik
++ */
++#ifndef __ASM_AVR32_POSIX_TYPES_H
++#define __ASM_AVR32_POSIX_TYPES_H
++
++/*
++ * This file is generally used by user-level software, so you need to
++ * be a little careful about namespace pollution etc.  Also, we cannot
++ * assume GCC is being used.
++ */
++
++typedef unsigned long __kernel_dev_t;
++typedef unsigned long   __kernel_ino_t;
++typedef unsigned short  __kernel_mode_t;
++typedef unsigned short  __kernel_nlink_t;
++typedef long            __kernel_off_t;
++typedef int             __kernel_pid_t;
++typedef unsigned short  __kernel_ipc_pid_t;
++typedef unsigned int  __kernel_uid_t;
++typedef unsigned int  __kernel_gid_t;
++typedef unsigned long __kernel_size_t;
++typedef int             __kernel_ssize_t;
++typedef int             __kernel_ptrdiff_t;
++typedef long            __kernel_time_t;
++typedef long            __kernel_suseconds_t;
++typedef long            __kernel_clock_t;
++typedef int             __kernel_timer_t;
++typedef int             __kernel_clockid_t;
++typedef int             __kernel_daddr_t;
++typedef char *          __kernel_caddr_t;
++typedef unsigned short  __kernel_uid16_t;
++typedef unsigned short  __kernel_gid16_t;
++typedef unsigned int    __kernel_uid32_t;
++typedef unsigned int    __kernel_gid32_t;
++
++typedef unsigned short  __kernel_old_uid_t;
++typedef unsigned short  __kernel_old_gid_t;
++typedef unsigned short  __kernel_old_dev_t;
++
++#ifdef __GNUC__
++typedef long long       __kernel_loff_t;
++#endif
++
++typedef struct {
++#if defined(__USE_ALL)
++    int     val[2];
++#else
++    int     __val[2];
++#endif
++} __kernel_fsid_t;
++
++#endif /* __ASM_AVR32_POSIX_TYPES_H */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/machine-gmon.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/machine-gmon.h 2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,69 @@
++/* Machine-dependent definitions for profiling support.  AVR32 version.
++   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#define mcount_internal __mcount_internal
++
++#define _MCOUNT_DECL(frompc, selfpc) \
++static void __attribute((used)) mcount_internal(unsigned long frompc, unsigned long selfpc)
++
++/*
++ * This mcount implementation expects to get called after the prologue
++ * has been run. It also expects that r7 contains a valid frame
++ * pointer.
++ *
++ * When profiling, the compiler should generate something like this at
++ * each function entry:
++ *
++ *    pushm   r0-r7,lr        // lr mandatory, others optional
++ *    mov     r7, sp
++ *    // rest of prologue goes here
++ *    mcall   pc[.LC1 - .]
++ *      // rest of function goes here
++ * .LC1:
++ *    .long   mcount
++ *
++ * or for PIC:
++ *
++ *    pushm   r0-r7,lr
++ *    mov     r7, sp
++ *    // rest of prologue goes here
++ *    lddpc   r0, .LC1
++ * .L1: rsub  r0, pc
++ *    mcall   r0[mcount@GOT]
++ *    // rest of function goes here
++ * .LC1:
++ *    .long   .L1 - _GLOBAL_OFFSET_TABLE_
++ *
++ * This way, when mcount() is called, r7 points to the calling
++ * function's return address. It is guaranteed that calling mcount
++ * will clobber no registers except LR, which is unavoidable.
++ */
++#define MCOUNT asm(                           \
++      "       .align  4\n"                    \
++      "       .global _mcount\n"              \
++      "       .type   _mcount,@function\n"    \
++      "_mcount:\n"                            \
++      "       pushm   r8-r12,lr\n"            \
++      "       mov     r11, lr\n"              \
++      "       ld.w    r12, r7[0]\n"           \
++      "       rcall   __mcount_internal\n"    \
++      "       popm    r8-r12,pc\n"            \
++      "       .size   _mcount, . - _mcount\n" \
++      "       .weak   mcount\n"               \
++      "       mcount = _mcount");
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/mman.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/mman.h 2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,95 @@
++/* Definitions for POSIX memory map interface.  Linux/AVR32 version.
++   Copyright (C) 1997, 2000 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef _SYS_MMAN_H
++# error "Never include this file directly.  Use <sys/mman.h> instead"
++#endif
++
++/* The following definitions basically come from the kernel headers.
++   But the kernel header is not namespace clean.  */
++
++
++/* Protections are chosen from these bits, OR'd together.  The
++   implementation does not necessarily support PROT_EXEC or PROT_WRITE
++   without PROT_READ.  The only guarantees are that no writing will be
++   allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
++
++#define PROT_READ     0x1             /* Page can be read.  */
++#define PROT_WRITE    0x2             /* Page can be written.  */
++#define PROT_EXEC     0x4             /* Page can be executed.  */
++#define PROT_NONE     0x0             /* Page can not be accessed.  */
++
++/* Sharing types (must choose one and only one of these).  */
++#define MAP_SHARED    0x01            /* Share changes.  */
++#define MAP_PRIVATE   0x02            /* Changes are private.  */
++#ifdef __USE_MISC
++# define MAP_TYPE     0x0f            /* Mask for type of mapping.  */
++#endif
++
++/* Other flags.  */
++#define MAP_FIXED     0x10            /* Interpret addr exactly.  */
++#ifdef __USE_MISC
++# define MAP_FILE     0
++# define MAP_ANONYMOUS        0x20            /* Don't use a file.  */
++# define MAP_ANON     MAP_ANONYMOUS
++#endif
++
++/* These are Linux-specific.  */
++#ifdef __USE_MISC
++# define MAP_GROWSDOWN        0x0100          /* Stack-like segment.  */
++# define MAP_DENYWRITE        0x0800          /* ETXTBSY */
++# define MAP_EXECUTABLE       0x1000          /* Mark it as an executable.  */
++# define MAP_LOCKED   0x2000          /* Lock the mapping.  */
++# define MAP_NORESERVE        0x4000          /* Don't check for reservations.  */
++# define MAP_POPULATE 0x8000          /* populate (prefault) pagetables */
++# define MAP_NONBLOCK 0x10000         /* do not block on IO */
++#endif
++
++/* Flags to `msync'.  */
++#define MS_ASYNC      1               /* Sync memory asynchronously.  */
++#define MS_SYNC               4               /* Synchronous memory sync.  */
++#define MS_INVALIDATE 2               /* Invalidate the caches.  */
++
++/* Flags for `mlockall'.  */
++#define MCL_CURRENT   1               /* Lock all currently mapped pages.  */
++#define MCL_FUTURE    2               /* Lock all additions to address
++                                         space.  */
++
++/* Flags for `mremap'.  */
++#ifdef __USE_GNU
++# define MREMAP_MAYMOVE       1
++#endif
++
++/* Advise to `madvise'.  */
++#ifdef __USE_BSD
++# define MADV_NORMAL   0      /* No further special treatment.  */
++# define MADV_RANDOM   1      /* Expect random page references.  */
++# define MADV_SEQUENTIAL 2    /* Expect sequential page references.  */
++# define MADV_WILLNEED         3      /* Will need these pages.  */
++# define MADV_DONTNEED         4      /* Don't need these pages.  */
++#endif
++
++/* The POSIX people had to invent similar names for the same things.  */
++#ifdef __USE_XOPEN2K
++# define POSIX_MADV_NORMAL    0 /* No further special treatment.  */
++# define POSIX_MADV_RANDOM    1 /* Expect random page references.  */
++# define POSIX_MADV_SEQUENTIAL        2 /* Expect sequential page references.  */
++# define POSIX_MADV_WILLNEED  3 /* Will need these pages.  */
++# define POSIX_MADV_DONTNEED  4 /* Don't need these pages.  */
++#endif
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/profil-counter.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/profil-counter.h       2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,26 @@
++/* Low-level statistical profiling support function.  Linux/AVR32 version.
++   Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <signal.h>
++
++void
++profil_counter(int signo, siginfo_t *si, struct sigcontext *sc)
++{
++      profil_count((void *)sc->pc);
++}
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/setjmp.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/setjmp.h       2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,21 @@
++/*
++ * Copyright (C) 2004-2005 Atmel Norway
++ */
++#ifndef _SETJMP_H
++# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
++#endif
++
++#ifndef _ASM
++/*
++ * The jump buffer contains r0-r7, sr, sp and lr. Other registers are
++ * not saved.
++ */
++typedef int __jmp_buf[11];
++#endif
++
++#define __JMP_BUF_SP  4
++
++/* Test if longjmp to JMPBUF would unwind the frame containing a local
++   variable at ADDRESS.  */
++#define _JMPBUF_UNWINDS(jmpbuf, address) \
++  ((void *)(address) < (void *)(jmpbuf[__JMP_BUF_SP]))
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/syscalls.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/syscalls.h     2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,143 @@
++#ifndef _SYSCALL_H
++# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
++#endif
++
++/*
++ * This includes the `__NR_<name>' syscall numbers taken from the
++ * Linux kernel header files. It also defines the traditional
++ * `SYS_<name>' macros for older programs.
++ */
++#include <bits/sysnum.h>
++
++#ifndef __set_errno
++# define __set_errno(val) (*__errno_location()) = (val)
++#endif
++#ifndef SYS_ify
++# define SYS_ify(syscall_name) (__NR_##syscall_name)
++#endif
++
++#ifndef __ASSEMBLER__
++
++#undef _syscall0
++#define _syscall0(type,name)                          \
++      type name(void)                                 \
++      {                                               \
++              return (type)(INLINE_SYSCALL(name, 0)); \
++      }
++
++#undef _syscall1
++#define _syscall1(type,name,type1,arg1)                               \
++      type name(type1 arg1)                                   \
++      {                                                       \
++              return (type)(INLINE_SYSCALL(name, 1, arg1));   \
++      }
++
++#undef _syscall2
++#define _syscall2(type,name,type1,arg1,type2,arg2)                    \
++      type name(type1 arg1, type2 arg2)                               \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 2, arg1, arg2));     \
++      }
++
++#undef _syscall3
++#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)         \
++      type name(type1 arg1, type2 arg2, type3 arg3)                   \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 3, arg1,             \
++                                           arg2, arg3));              \
++      }
++
++#undef _syscall4
++#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4)                                           \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)       \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 4, arg1, arg2,       \
++                                           arg3, arg4));              \
++      }
++
++#undef _syscall5
++#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4,type5,arg5)                                \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
++                type5 arg5)                                           \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 5, arg1, arg2,       \
++                                           arg3, arg4, arg5));        \
++      }
++
++#undef _syscall6
++#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4,type5,arg5,type6,arg6)                     \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
++                type5 arg5, type6 arg6)                               \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 6, arg1, arg2, arg3, \
++                                           arg4, arg5, arg6));        \
++      }
++
++#undef unlikely
++#define unlikely(x) __builtin_expect((x), 0)
++
++#undef INLINE_SYSCALL
++#define INLINE_SYSCALL(name, nr, args...)                             \
++      ({                                                              \
++              unsigned _sys_result = INTERNAL_SYSCALL(name, , nr, args); \
++              if (unlikely(INTERNAL_SYSCALL_ERROR_P(_sys_result, ))) { \
++                      __set_errno(INTERNAL_SYSCALL_ERRNO(_sys_result, )); \
++                      _sys_result = (unsigned int) -1;                \
++              }                                                       \
++              (int) _sys_result;                                      \
++      })
++
++#undef INTERNAL_SYSCALL_DECL
++#define INTERNAL_SYSCALL_DECL(err) do { } while(0)
++
++#undef INTERNAL_SYSCALL
++#define INTERNAL_SYSCALL(name, err, nr, args...)                      \
++      ({                                                              \
++              register int _a1 asm ("r12");                           \
++              register int _scno asm("r8") = SYS_ify(name);           \
++              LOAD_ARGS_##nr (args);                                  \
++              asm volatile ("scall    /* syscall " #name " */"        \
++                            : "=r" (_a1)                              \
++                            : "r"(_scno) ASM_ARGS_##nr                \
++                            : "lr", "cc", "memory");                  \
++              _a1;                                                    \
++      })
++
++#undef INTERNAL_SYSCALL_ERROR_P
++#define INTERNAL_SYSCALL_ERROR_P(val, err)            \
++      ((unsigned int)(val) >= 0xfffff001U)
++
++#undef INTERNAL_SYSCALL_ERRNO
++#define INTERNAL_SYSCALL_ERRNO(val, errr) (-(val))
++
++#define LOAD_ARGS_0() do { } while(0)
++#define ASM_ARGS_0
++#define LOAD_ARGS_1(a1)                                       \
++      _a1 = (int) (a1);                               \
++      LOAD_ARGS_0()
++#define ASM_ARGS_1    ASM_ARGS_0, "r"(_a1)
++#define LOAD_ARGS_2(a1, a2)                           \
++      register int _a2 asm("r11") = (int)(a2);        \
++      LOAD_ARGS_1(a1)
++#define ASM_ARGS_2    ASM_ARGS_1, "r"(_a2)
++#define LOAD_ARGS_3(a1, a2, a3)                               \
++      register int _a3 asm("r10") = (int)(a3);        \
++      LOAD_ARGS_2(a1, a2)
++#define ASM_ARGS_3    ASM_ARGS_2, "r"(_a3)
++#define LOAD_ARGS_4(a1, a2, a3, a4)                   \
++      register int _a4 asm("r9") = (int)(a4);         \
++      LOAD_ARGS_3(a1, a2, a3)
++#define ASM_ARGS_4    ASM_ARGS_3, "r"(_a4)
++#define LOAD_ARGS_5(a1, a2, a3, a4, a5)                       \
++      register int _a5 asm("r5") = (int)(a5);         \
++      LOAD_ARGS_4(a1, a2, a3, a4)
++#define ASM_ARGS_5    ASM_ARGS_4, "r"(_a5)
++#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)           \
++      register int _a6 asm("r3") = (int)(a6);         \
++      LOAD_ARGS_5(a1, a2, a3, a4, a5)
++#define ASM_ARGS_6    ASM_ARGS_5, "r"(_a6)
++
++#endif /* __ASSEMBLER__ */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/wordsize.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/wordsize.h     2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1 @@
++#define __WORDSIZE    32
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/brk.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/brk.c       2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,23 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <sys/syscall.h>
++
++void *__curbrk = 0;
++
++int brk (void *addr)
++{
++      void *newbrk;
++
++      newbrk = INLINE_SYSCALL(brk, 1, addr);
++
++      __curbrk = newbrk;
++
++      if (newbrk < addr) {
++              __set_errno (ENOMEM);
++              return -1;
++      }
++
++      return 0;
++}
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-_setjmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-_setjmp.S       2006-05-05 09:26:42.000000000 +0200
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      /* This just does a tail-call to __sigsetjmp(env, 0) */
++      .global _setjmp
++      .type   _setjmp,"function"
++      .align  1
++_setjmp:
++      mov     r11, 0
++      bral    __sigsetjmp_internal
++      .size   _setjmp, . - _setjmp
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-setjmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-setjmp.S        2006-05-05 09:26:42.000000000 +0200
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      /* This just does a tail-call to __sigsetjmp(env, 1) */
++      .global setjmp
++      .type   setjmp,"function"
++      .align  1
++setjmp:
++      mov     r11, 1
++      bral    __sigsetjmp_internal
++      .size   setjmp, . - setjmp
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/clone.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/clone.c     2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <sys/syscall.h>
++#include <unistd.h>
++
++/*
++ * I don't know if we can be absolutely certain that the fn and arg
++ * parameters are preserved when returning as the child. If the
++ * compiler stores them in registers (r0-r7), they should be.
++ */
++int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg)
++{
++      register int (*_fn)(void *arg) = fn;
++      register void *_arg = arg;
++      int err;
++
++      /* Sanity check the arguments */
++      err = -EINVAL;
++      if (!fn)
++              goto syscall_error;
++      if (!child_stack)
++              goto syscall_error;
++
++      err = INLINE_SYSCALL(clone, 2, flags, child_stack);
++      if (err < 0)
++              goto syscall_error;
++      else if (err != 0)
++              return err;
++
++      _exit(_fn(_arg));
++
++syscall_error:
++      __set_errno (-err);
++      return -1;
++}
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/crt1.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/crt1.S      2006-05-05 09:28:23.000000000 +0200
+@@ -0,0 +1,93 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ *
++ * When we enter _start, the stack looks like this:
++ *    argc            argument counter
++ *    argv[0]         pointer to program name
++ *    argv[1..argc-1] pointers to program args
++ *    NULL
++ *    env[0..N]       pointers to environment variables
++ *    NULL
++ *
++ * r12 contains a function pointer to be registered with `atexit'.
++ * This is how the dynamic linker arranges to have DT_FINI functions
++ * called for shared libraries that have been loaded before this
++ * code runs.
++ *
++ * We're going to call the following function:
++ * __uClibc_main(int (*main)(int, char **, char **), int argc,
++ *             char **argv, void (*app_init)(void), void (*app_fini)(void),
++ *             void (*rtld_fini)(void), void *stack_end)
++ *
++ * So we need to set up things as follows:
++ *    r12 = address of main
++ *    r11 = argc
++ *    r10 = &argv[0]
++ *    r9  = address of _init
++ *    r8  = address of _fini
++ *    sp[0] = whatever we got passed in r12
++ */
++
++#include <features.h>
++
++      .text
++      .global _start
++      .type   _start, @function
++_start:
++      /* Clear the frame pointer and link register since this is the outermost frame.  */
++      mov     r7, 0
++      mov     lr, 0
++
++      ld.w    r11, sp++               /* argc         */
++      mov     r10, sp                 /* &argv[0]     */
++
++      st.w    --sp, r10               /* stack_end */
++      st.w    --sp, r12               /* rtld_fini */
++
++#ifdef __PIC__
++      lddpc   r6, .L_GOT
++.L_RGOT:
++      rsub    r6, pc
++      lda.w   r9, _init
++      lda.w   r8, _fini
++      lda.w   r12, main
++
++      /* Ok, now run uClibc's main() -- should not return */
++      call    __uClibc_main
++
++      .align  2
++.L_GOT:
++      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
++#else
++      lddpc   r9, __init_addr         /* app_init */
++      lddpc   r8, __fini_addr         /* app_fini */
++      lddpc   r12, __main_addr        /* main */
++
++      /* Ok, now run uClibc's main() -- should not return */
++      lddpc   pc, ___uClibc_main_addr
++
++      .align  2
++__init_addr:
++      .long   _init
++__fini_addr:
++      .long   _fini
++__main_addr:
++      .long   main
++___uClibc_main_addr:
++      .long   __uClibc_main
++#endif
++      .size   _start, . - _start
++
++      /*
++       * The LSB says we need this.
++       */
++      .section ".note.ABI-tag", "a"
++      .align  4
++      .long   2f - 1f         /* namesz */
++      .long   4f - 3f         /* descsz */
++      .long   1               /* type   */
++1:    .asciz  "GNU"           /* name */
++2:    .align  4
++3:    .long   0               /* Linux executable */
++      .long   2,6,0           /* Earliest compatible kernel */
++4:    .align  4
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/crti.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/crti.S      2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,17 @@
++
++      .section .init
++      .align  2
++      .global _init
++      .type   _init, @function
++_init:
++      /* Use a four-byte instruction to avoid NOPs */
++      stm     --sp, r0-r7,lr
++      .align  2
++
++      .section .fini
++      .align  2
++      .global _fini
++      .type   _fini, @function
++_fini:
++      stm     --sp, r0-r7,lr
++      .align  2
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/crtn.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/crtn.S      2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,14 @@
++
++      .section .init
++      .align  2
++      .global _init
++      .type   _init, @function
++      ldm     sp++, r0-r7,pc
++      .size   _init, . - _init
++
++      .section .fini
++      .align  2
++      .global _fini
++      .type   _fini, @function
++      ldm     sp++, r0-r7,pc
++      .size   _fini, . - _fini
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/mmap.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/mmap.c      2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,31 @@
++/* Copyright (C) 2005 Atmel Norway
++
++   This program is free software; you can redistribute it and/or modify it under
++   the terms of the GNU Library 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 Library General Public License for more
++   details.
++
++   You should have received a copy of the GNU Library 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
++
++   Derived in part from the Linux-8086 C library, the GNU C Library, and several
++   other sundry sources.  Files within this library are copyright by their
++   respective copyright holders.
++ */
++
++#include <errno.h>
++#include <sys/mman.h>
++#include <sys/syscall.h>
++
++static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot, int, flags, int, fd, __off_t, pgoff);
++
++__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
++{
++      return mmap2(addr, len, prot, flags, fd, offset >> 12);
++}
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/setjmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/setjmp.S    2006-05-05 09:28:28.000000000 +0200
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#define _SETJMP_H
++#define _ASM
++#include <bits/setjmp.h>
++
++      .text
++
++      .global __sigsetjmp
++      .type   __sigsetjmp,"function"
++
++      /* Create a global, hidden symbol for use by setjmp() and _setjmp().
++         If it's not hidden, the linker will complain about a relative
++         jump to a dynamic symbol when building a shared library.
++
++         Also, if a user overrides the __sigsetjmp function, he might not
++         expect the setjmp() and _setjmp() function to effectively be
++         overridden as well.  */
++      .global __sigsetjmp_internal
++      .hidden __sigsetjmp_internal
++      .type   __sigsetjmp_internal,"function"
++      .align  1
++__sigsetjmp:
++__sigsetjmp_internal:
++      mustr   r8
++      stm     r12, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr
++
++      /* Make a tail call to __sigjmp_save; it takes the same args.  */
++#ifdef __PIC__
++      mov     r9, r6
++      lddpc   r6, .LG
++.L1:  rsub    r6, pc
++      ld.w    r8, r6[__sigjmp_save@got]
++      mov     r6, r9
++      mov     pc, r8
++
++      .align  2
++.LG:  .long   .L1 - _GLOBAL_OFFSET_TABLE_
++#else
++      rjmp    __sigjmp_save
++#endif
++      .size   __sigsetjmp, . - __sigsetjmp
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sigaction.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sigaction.c 2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <signal.h>
++#include <string.h>
++#include <sys/syscall.h>
++#include <bits/kernel_sigaction.h>
++
++#define SA_RESTORER   0x04000000
++extern void __default_rt_sa_restorer(void);
++
++/*
++ * If act is not NULL, change the action for sig to *act.
++ * If oact is not NULL, put the old action for sig in *oact.
++ */
++int __libc_sigaction(int signum, const struct sigaction *act,
++                   struct sigaction *oldact)
++{
++      struct kernel_sigaction kact, koact;
++      int result;
++
++      if (act) {
++              kact.k_sa_handler = act->sa_handler;
++              memcpy(&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
++              kact.sa_flags = act->sa_flags;
++              if (kact.sa_flags & (SA_RESTORER | SA_ONSTACK))
++                      kact.sa_restorer = act->sa_restorer;
++              else
++                      kact.sa_restorer = __default_rt_sa_restorer;
++              kact.sa_flags |= SA_RESTORER;
++      }
++
++      result = __syscall_rt_sigaction(signum, act ? __ptrvalue(&kact) : NULL,
++                                      oldact ? __ptrvalue(&koact) : NULL,
++                                      _NSIG / 8);
++
++      if (oldact && result >= 0) {
++              oldact->sa_handler = koact.k_sa_handler;
++              memcpy(&oldact->sa_mask, &koact.sa_mask,
++                     sizeof(oldact->sa_mask));
++              oldact->sa_flags = koact.sa_flags;
++              oldact->sa_restorer = koact.sa_restorer;
++      }
++
++      return result;
++}
++
++weak_alias(__libc_sigaction, sigaction)
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sigrestorer.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sigrestorer.S       2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,11 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <sys/syscall.h>
++
++      .global __default_rt_sa_restorer
++      .type   __default_rt_sa_restorer,"function"
++      .align  1
++__default_rt_sa_restorer:
++      mov     r8, __NR_rt_sigreturn
++      scall
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/elf.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/elf.h   2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,26 @@
++/* Copyright (C) 1996, 1997, 1999, 2001 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef _SYS_ELF_H
++#define _SYS_ELF_H    1
++
++#warning "This header is obsolete; use <sys/procfs.h> instead."
++
++#include <sys/procfs.h>
++
++#endif        /* sys/elf.h */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/io.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/io.h    2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,48 @@
++/* Copyright (C) 1996, 1998, 1999 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef       _SYS_IO_H
++
++#define       _SYS_IO_H       1
++#include <features.h>
++
++__BEGIN_DECLS
++
++/* If TURN_ON is TRUE, request for permission to do direct i/o on the
++   port numbers in the range [FROM,FROM+NUM-1].  Otherwise, turn I/O
++   permission off for that range.  This call requires root privileges.  */
++extern int ioperm (unsigned long int __from, unsigned long int __num,
++                 int __turn_on) __THROW;
++
++/* Set the I/O privilege level to LEVEL.  If LEVEL is nonzero,
++   permission to access any I/O port is granted.  This call requires
++   root privileges. */
++extern int iopl (int __level) __THROW;
++
++/* The functions that actually perform reads and writes.  */
++extern unsigned char inb (unsigned long int port) __THROW;
++extern unsigned short int inw (unsigned long int port) __THROW;
++extern unsigned long int inl (unsigned long int port) __THROW;
++
++extern void outb (unsigned char value, unsigned long int port) __THROW;
++extern void outw (unsigned short value, unsigned long int port) __THROW;
++extern void outl (unsigned long value, unsigned long int port) __THROW;
++
++__END_DECLS
++
++#endif /* _SYS_IO_H */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/procfs.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/procfs.h        2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,123 @@
++/* Copyright (C) 1996, 1997, 1999, 2001 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef _SYS_PROCFS_H
++#define _SYS_PROCFS_H 1
++
++/* This is somewhat modelled after the file of the same name on SVR4
++   systems.  It provides a definition of the core file format for ELF
++   used on Linux.  It doesn't have anything to do with the /proc file
++   system, even though Linux has one.
++
++   Anyway, the whole purpose of this file is for GDB and GDB only.
++   Don't read too much into it.  Don't use it for anything other than
++   GDB unless you know what you are doing.  */
++
++#include <features.h>
++#include <sys/time.h>
++#include <sys/types.h>
++#include <sys/user.h>
++
++__BEGIN_DECLS
++
++/* Type for a general-purpose register.  */
++typedef unsigned long elf_greg_t;
++
++/* And the whole bunch of them.  We could have used `struct
++   user_regs' directly in the typedef, but tradition says that
++   the register set is an array, which does have some peculiar
++   semantics, so leave it that way.  */
++#define ELF_NGREG (sizeof (struct user_regs) / sizeof(elf_greg_t))
++typedef elf_greg_t elf_gregset_t[ELF_NGREG];
++
++/* Register set for the floating-point registers.  */
++typedef struct user_fpregs elf_fpregset_t;
++
++/* Signal info.  */
++struct elf_siginfo
++  {
++    int si_signo;                     /* Signal number.  */
++    int si_code;                      /* Extra code.  */
++    int si_errno;                     /* Errno.  */
++  };
++
++/* Definitions to generate Intel SVR4-like core files.  These mostly
++   have the same names as the SVR4 types with "elf_" tacked on the
++   front to prevent clashes with Linux definitions, and the typedef
++   forms have been avoided.  This is mostly like the SVR4 structure,
++   but more Linuxy, with things that Linux does not support and which
++   GDB doesn't really use excluded.  */
++
++struct elf_prstatus
++  {
++    struct elf_siginfo pr_info;               /* Info associated with signal.  */
++    short int pr_cursig;              /* Current signal.  */
++    unsigned long int pr_sigpend;     /* Set of pending signals.  */
++    unsigned long int pr_sighold;     /* Set of held signals.  */
++    __pid_t pr_pid;
++    __pid_t pr_ppid;
++    __pid_t pr_pgrp;
++    __pid_t pr_sid;
++    struct timeval pr_utime;          /* User time.  */
++    struct timeval pr_stime;          /* System time.  */
++    struct timeval pr_cutime;         /* Cumulative user time.  */
++    struct timeval pr_cstime;         /* Cumulative system time.  */
++    elf_gregset_t pr_reg;             /* GP registers.  */
++    int pr_fpvalid;                   /* True if math copro being used.  */
++  };
++
++
++#define ELF_PRARGSZ     (80)    /* Number of chars for args.  */
++
++struct elf_prpsinfo
++  {
++    char pr_state;                    /* Numeric process state.  */
++    char pr_sname;                    /* Char for pr_state.  */
++    char pr_zomb;                     /* Zombie.  */
++    char pr_nice;                     /* Nice val.  */
++    unsigned long int pr_flag;                /* Flags.  */
++    unsigned short int pr_uid;
++    unsigned short int pr_gid;
++    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
++    /* Lots missing */
++    char pr_fname[16];                        /* Filename of executable.  */
++    char pr_psargs[ELF_PRARGSZ];      /* Initial part of arg list.  */
++  };
++
++/* The rest of this file provides the types for emulation of the
++   Solaris <proc_service.h> interfaces that should be implemented by
++   users of libthread_db.  */
++
++/* Addresses.  */
++typedef void *psaddr_t;
++
++/* Register sets.  Linux has different names.  */
++typedef elf_gregset_t prgregset_t;
++typedef elf_fpregset_t prfpregset_t;
++
++/* We don't have any differences between processes and threads,
++   therefore have only one PID type.  */
++typedef __pid_t lwpid_t;
++
++/* Process status and info.  In the end we do provide typedefs for them.  */
++typedef struct elf_prstatus prstatus_t;
++typedef struct elf_prpsinfo prpsinfo_t;
++
++__END_DECLS
++
++#endif        /* sys/procfs.h */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/ucontext.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/ucontext.h      2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,94 @@
++/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++/* Linux/AVR32 ABI compliant context switching support.  */
++
++#ifndef _SYS_UCONTEXT_H
++#define _SYS_UCONTEXT_H       1
++
++#include <features.h>
++#include <signal.h>
++#include <sys/procfs.h>
++#include <bits/sigcontext.h>
++
++typedef int greg_t;
++
++/* Number of general registers.  */
++#define NGREG 16
++
++/* Container for all general registers.  */
++typedef elf_gregset_t gregset_t;
++
++/* Number of each register is the `gregset_t' array.  */
++enum
++{
++  R0 = 0,
++#define R0    R0
++  R1 = 1,
++#define R1    R1
++  R2 = 2,
++#define R2    R2
++  R3 = 3,
++#define R3    R3
++  R4 = 4,
++#define R4    R4
++  R5 = 5,
++#define R5    R5
++  R6 = 6,
++#define R6    R6
++  R7 = 7,
++#define R7    R7
++  R8 = 8,
++#define R8    R8
++  R9 = 9,
++#define R9    R9
++  R10 = 10,
++#define R10   R10
++  R11 = 11,
++#define R11   R11
++  R12 = 12,
++#define R12   R12
++  R13 = 13,
++#define R13   R13
++  R14 = 14,
++#define R14   R14
++  R15 = 15
++#define R15   R15
++};
++
++/* Structure to describe FPU registers.  */
++typedef elf_fpregset_t        fpregset_t;
++
++/* Context to describe whole processor state.  */
++typedef struct
++  {
++    gregset_t gregs;
++    fpregset_t fpregs;
++  } mcontext_t;
++
++/* Userlevel context.  */
++typedef struct ucontext
++{
++    unsigned long     uc_flags;
++    struct ucontext  *uc_link;
++    stack_t           uc_stack;
++    struct sigcontext uc_mcontext;
++    sigset_t          uc_sigmask;   /* mask last for extensibility */
++} ucontext_t;
++
++#endif /* sys/ucontext.h */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/user.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/user.h  2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,46 @@
++#ifndef _SYS_USER_H
++#define _SYS_USER_H
++
++struct user_fpregs
++{
++
++};
++
++struct user_regs
++{
++      unsigned long sr;
++      unsigned long pc;
++      unsigned long lr;
++      unsigned long sp;
++      unsigned long r12;
++      unsigned long r11;
++      unsigned long r10;
++      unsigned long r9;
++      unsigned long r8;
++      unsigned long r7;
++      unsigned long r6;
++      unsigned long r5;
++      unsigned long r4;
++      unsigned long r3;
++      unsigned long r2;
++      unsigned long r1;
++      unsigned long r0;
++      unsigned long r12_orig;
++};
++
++struct user
++{
++      struct user_regs        regs;           /* general registers */
++      size_t                  u_tsize;        /* text size (pages) */
++      size_t                  u_dsize;        /* data size (pages) */
++      size_t                  u_ssize;        /* stack size (pages) */
++      unsigned long           start_code;     /* text starting address */
++      unsigned long           start_data;     /* data starting address */
++      unsigned long           start_stack;    /* stack starting address */
++      long int                signal;         /* signal causing core dump */
++      struct user_regs *      u_ar0;          /* help gdb find registers */
++      unsigned long           magic;          /* identifies a core file */
++      char                    u_comm[32];     /* user command name */
++};
++
++#endif /* _SYS_USER_H */
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/syscall.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/syscall.S   2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,81 @@
++/*
++ * syscall for AVR32/uClibc
++ *
++ * Copyright (C) 2004 Atmel Norway
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU Library 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 Library General Public License
++ * for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this program; if not, write to the Free Software Foundation,
++ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#include <features.h>
++
++      .text
++
++      /*
++       * long int syscall(long int sysno, ...)
++       */
++      .global syscall
++      .type   syscall, @function
++      .align  2
++syscall:
++      stm     --sp, r3,r5,lr
++      sub     lr, sp, -12
++      mov     r8, r12
++      ldm     lr, r3,r5,r9-r12
++      scall
++      cp.w    r12, -4095
++      brlo    .Ldone
++
++#ifdef __PIC__
++      lddpc   r5, .Lgot
++.Lgotcalc:
++      rsub    r5, pc
++# ifdef __UCLIBC_HAS_THREADS__
++      mov     r3, r12
++      mcall   r5[__errno_location@got]
++      st.w    r12[0], r3
++# else
++      ld.w    r3, r5[errno@got]
++      st.w    r3[0], r12
++# endif
++#else
++# ifdef __UCLIBC_HAS_THREADS__
++      mov     r3, r12
++      mcall   .Lerrno_location
++      st.w    r12[0], r3
++# else
++      lddpc   r3, .Lerrno
++      st.w    r3[0], r12
++# endif
++#endif
++      mov     r12, -1
++
++.Ldone:
++      ldm     sp++, r3,r5,pc
++
++      .align  2
++#ifdef __PIC__
++.Lgot:
++      .long   .Lgotcalc - _GLOBAL_OFFSET_TABLE_
++#else
++# ifdef __UCLIBC_HAS_THREADS__
++.Lerrno_location:
++      .long   __errno_location
++# else
++.Lerrno:
++      .long   errno
++# endif
++#endif
++
++
++      .size   syscall, . - syscall
+Index: uClibc-0.9.28/libc/sysdeps/linux/avr32/vfork.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libc/sysdeps/linux/avr32/vfork.S     2006-04-19 12:48:33.000000000 +0200
+@@ -0,0 +1,55 @@
++      /*
++       * vfork for uClibc
++       *
++       * Copyright (C) 2005 Atmel Norway
++       */
++
++      /*
++       * Clone the process without copying the address space.  The
++       * calling process is suspended until the child either exits
++       * or calls execve.
++       *
++       * This all means that we cannot rely on the stack to store
++       * away registers, since they will be overwritten by the child
++       * as soon as it makes another function call (e.g. execve()).
++       * Fortunately, the Linux kernel preserves LR across system calls.
++       */
++#include <features.h>
++#include <sys/syscall.h>
++
++      .global __vfork
++      .type   __vfork,@function
++      .align  1
++__vfork:
++      mov     r8, __NR_vfork
++      scall
++      cp.w    r12, -4096
++      retls   r12
++
++      /* vfork failed, so we may use the stack freely */
++      pushm   r4-r7,lr
++#ifdef __PIC__
++      lddpc   r6, .L_GOT
++      rsub    r4, r12, 0
++.L_RGOT:
++      rsub    r6, pc
++      mcall   r6[__errno_location@got]
++#else
++      rsub    r4, r12, 0
++      mcall   .L__errno_location
++#endif
++      st.w    r12[0], r4
++      popm    r4-r7,pc,r12=-1
++
++      .align  2
++#ifdef __PIC__
++.L_GOT:
++      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
++#else
++.L__errno_location:
++      .long   __errno_location
++#endif
++      .size   __vfork, . - __vfork
++
++      .weak   vfork
++      vfork   = __vfork
+Index: uClibc-0.9.28/Rules.mak
+===================================================================
+--- uClibc-0.9.28.orig/Rules.mak       2006-05-05 09:26:01.000000000 +0200
++++ uClibc-0.9.28/Rules.mak    2006-05-05 09:27:17.000000000 +0200
+@@ -231,6 +231,10 @@ ifeq ($(strip $(TARGET_ARCH)),frv)
+       UCLIBC_LDSO=ld.so.1
+ endif
++ifeq ($(strip $(TARGET_ARCH)),avr32)
++      CPU_CFLAGS-$(CONFIG_AP7000)     += -mcpu=ap7000
++endif
++
+ # Keep the check_gcc from being needlessly executed
+ ifndef PIEFLAG
+ ifneq ($(UCLIBC_BUILD_PIE),y)
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/avr32-linkrelax-option.patch b/packages/uclibc/uclibc-0.9.28/avr32/avr32-linkrelax-option.patch
new file mode 100644 (file)
index 0000000..991e344
--- /dev/null
@@ -0,0 +1,40 @@
+From nobody Mon Sep 17 00:00:00 2001
+Subject: [PATCH] Make linkrelax configurable
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: 1133951618 +0100
+
+Add a linkrelax option to the configure system which will give
+appropriate options to the compiler, assembler and linker to enable
+link-time optimizations.
+
+---
+
+ Rules.mak                  |    2 ++
+ extra/Configs/Config.avr32 |    4 ++++
+ 2 files changed, 6 insertions(+)
+
+Index: uClibc-0.9.28/Rules.mak
+===================================================================
+--- uClibc-0.9.28.orig/Rules.mak       2006-02-08 17:58:53.000000000 +0100
++++ uClibc-0.9.28/Rules.mak    2006-02-08 17:59:07.000000000 +0100
+@@ -233,6 +233,8 @@ endif
+ ifeq ($(strip $(TARGET_ARCH)),avr32)
+       CPU_CFLAGS-$(CONFIG_AP7000)     += -mcpu=ap7000
++      CPU_CFLAGS-$(LINKRELAX)         += -masm-addr-pseudos -Wa,--pic,--linkrelax
++      CPU_LDFLAGS-$(LINKRELAX)        += --relax
+ endif
+ # Keep the check_gcc from being needlessly executed
+Index: uClibc-0.9.28/extra/Configs/Config.avr32
+===================================================================
+--- uClibc-0.9.28.orig/extra/Configs/Config.avr32      2006-02-08 17:58:53.000000000 +0100
++++ uClibc-0.9.28/extra/Configs/Config.avr32   2006-02-08 17:59:07.000000000 +0100
+@@ -36,3 +36,7 @@ config CONFIG_AP7000
+       bool "AP7000"
+ endchoice
++
++config LINKRELAX
++      bool "Enable linker optimizations"
++      default n
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/avr32-string-ops.patch b/packages/uclibc/uclibc-0.9.28/avr32/avr32-string-ops.patch
new file mode 100644 (file)
index 0000000..8518ccf
--- /dev/null
@@ -0,0 +1,1139 @@
+Subject: [PATCH] AVR32-optimized string operations
+
+Add hand-optimized AVR32-specific string operations. Some of them
+need a bit more testing, though.
+
+---
+
+ libc/string/avr32/Makefile      |   40 +++++++++++
+ libc/string/avr32/bcopy.S       |   15 ++++
+ libc/string/avr32/bzero.S       |   12 +++
+ libc/string/avr32/memchr.S      |   62 +++++++++++++++++
+ libc/string/avr32/memcmp.S      |   50 +++++++++++++
+ libc/string/avr32/memcpy.S      |  110 ++++++++++++++++++++++++++++++
+ libc/string/avr32/memmove.S     |  114 +++++++++++++++++++++++++++++++
+ libc/string/avr32/memset.S      |   60 ++++++++++++++++
+ libc/string/avr32/strcat.S      |   95 ++++++++++++++++++++++++++
+ libc/string/avr32/strcmp.S      |   80 ++++++++++++++++++++++
+ libc/string/avr32/strcpy.S      |   63 +++++++++++++++++
+ libc/string/avr32/stringtest.c  |  144 ++++++++++++++++++++++++++++++++++++++++
+ libc/string/avr32/strlen.S      |   52 ++++++++++++++
+ libc/string/avr32/strncpy.S     |   77 +++++++++++++++++++++
+ libc/string/avr32/test_memcpy.c |   66 ++++++++++++++++++
+ 15 files changed, 1040 insertions(+)
+
+Index: uClibc-0.9.28-avr32/libc/string/avr32/bcopy.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/bcopy.S      2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,15 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++      .text
++      .global bcopy
++      .type   bcopy, @function
++      .align  1
++bcopy:
++      /* Swap the first two arguments */
++      eor     r11, r12
++      eor     r12, r11
++      eor     r11, r12
++      rjmp    __memmove
++      .size   bcopy, . - bcopy
+Index: uClibc-0.9.28-avr32/libc/string/avr32/bzero.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/bzero.S      2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++      .text
++      .global bzero
++      .type   bzero, @function
++      .align  1
++bzero:
++      mov     r10, r11
++      mov     r11, 0
++      rjmp    __memset
+Index: uClibc-0.9.28-avr32/libc/string/avr32/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/Makefile     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,40 @@
++# Makefile for uClibc
++#
++# Copyright (C) 2000-2003 Erik Andersen <andersen@uclibc.org>
++#
++# This program is free software; you can redistribute it and/or modify it under
++# the terms of the GNU Library 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 Library General Public License for more
++# details.
++#
++# You should have received a copy of the GNU Library 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
++
++TOPDIR=../../../
++include $(TOPDIR)Rules.mak
++
++SSRC  := bcopy.S bzero.S memcmp.S memcpy.S memmove.S
++SSRC  += memset.S strcmp.S strlen.S
++# memchr.S, strcat.S, strcpy.S, strncpy.S is broken
++SOBJS := $(patsubst %.S,%.o, $(SSRC))
++OBJS  := $(SOBJS)
++
++OBJ_LIST:= ../../obj.string.$(TARGET_ARCH)
++
++all: $(OBJ_LIST)
++
++$(OBJ_LIST): $(OBJS)
++      echo $(addprefix string/$(TARGET_ARCH)/, $(OBJS)) > $@
++
++$(SOBJS): %.o: %.S
++      $(CC) $(ASFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $@
++
++clean:
++      $(RM) *.[oa] *~ core
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memchr.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memchr.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define str r12
++#define chr r11
++#define len r10
++
++      .text
++      .global memchr
++      .type   memchr, @function
++memchr:
++      or      chr, chr, chr << 8
++      or      chr, chr, chr << 16
++
++      mov     r9, str
++      andl    r9, 3, COH
++      brne    .Lunaligned_str
++
++1:    sub     len, 4
++      brlt    2f
++      ld.w    r8, str++
++      psub.b  r9, r8, r11
++      tnbz    r9
++      brne    1b
++
++      sub     str, 4
++      bfextu  r9, r8, 24, 8
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      bfextu  r9, r8, 16, 8
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      bfextu  r9, r8, 8, 8
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      retal   str
++
++2:    sub     len, -4
++      reteq   0
++
++3:    ld.ub   r8, str++
++      cp.w    r8, 0
++      reteq   str
++      sub     len, 1
++      brne    3b
++
++      retal   0
++
++.Lunaligned_str:
++1:    sub     len, 1
++      retlt   0
++      ld.ub   r8, str++
++      cp.b    r8, r11
++      reteq   str
++      sub     r9, 1
++      brge    1b
++
++      rjmp    .Laligned_search
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memcmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memcmp.S     2006-10-20 10:42:09.000000000 +0200
+@@ -0,0 +1,50 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s1 r12
++#define s2 r11
++#define len r10
++
++      .text
++      .global memcmp
++      .type   memcmp, @function
++      .align  1
++memcmp:
++      sub     len, 4
++      brlt    .Lless_than_4
++
++1:    ld.w    r8, s1++
++      ld.w    r9, s2++
++      cp.w    r8, r9
++      brne    .Lfound_word
++      sub     len, 4
++      brge    1b
++
++.Lless_than_4:
++      sub     len, -4
++      reteq   0
++
++1:    ld.ub   r8, s1++
++      ld.ub   r9, s2++
++      sub     r8, r9
++      retne   r8
++      sub     len, 1
++      brgt    1b
++
++      retal   0
++
++.Lfound_word:
++      psub.b  r9, r8, r9
++      bfextu  r8, r9, 24, 8
++      retne   r8
++      bfextu  r8, r9, 16, 8
++      retne   r8
++      bfextu  r8, r9, 8, 8
++      retne   r8
++      retal   r9
++
++      .size   memcmp, . - memcmp
++
++      .weak   bcmp
++      bcmp = memcmp
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memcpy.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memcpy.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,110 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++/* Don't use r12 as dst since we must return it unmodified */
++#define dst r9
++#define src r11
++#define len r10
++
++      .text
++      .global memcpy
++      .type   memcpy, @function
++
++      .global __memcpy
++      .hidden __memcpy
++      .type   __memcpy, @function
++memcpy:
++__memcpy:
++      pref    src[0]
++      mov     dst, r12
++
++      /* If we have less than 32 bytes, don't do anything fancy */
++      cp.w    len, 32
++      brge    .Lmore_than_31
++
++      sub     len, 1
++      retlt   r12
++1:    ld.ub   r8, src++
++      st.b    dst++, r8
++      sub     len, 1
++      brge    1b
++      retal   r12
++
++.Lmore_than_31:
++      pushm   r0-r7, lr
++
++      /* Check alignment */
++      mov     r8, src
++      andl    r8, 31, COH
++      brne    .Lunaligned_src
++      mov     r8, dst
++      andl    r8, 3, COH
++      brne    .Lunaligned_dst
++
++.Laligned_copy:
++      sub     len, 32
++      brlt    .Lless_than_32
++
++1:    /* Copy 32 bytes at a time */
++      ldm     src, r0-r7
++      sub     src, -32
++      stm     dst, r0-r7
++      sub     dst, -32
++      sub     len, 32
++      brge    1b
++
++.Lless_than_32:
++      /* Copy 16 more bytes if possible */
++      sub     len, -16
++      brlt    .Lless_than_16
++      ldm     src, r0-r3
++      sub     src, -16
++      sub     len, 16
++      stm     dst, r0-r3
++      sub     dst, -16
++
++.Lless_than_16:
++      /* Do the remaining as byte copies */
++      neg     len
++      add     pc, pc, len << 2
++      .rept   15
++      ld.ub   r0, src++
++      st.b    dst++, r0
++      .endr
++
++      popm    r0-r7, pc
++
++.Lunaligned_src:
++      /* Make src cacheline-aligned. r8 = (src & 31) */
++      rsub    r8, r8, 32
++      sub     len, r8
++1:    ld.ub   r0, src++
++      st.b    dst++, r0
++      sub     r8, 1
++      brne    1b
++
++      /* If dst is word-aligned, we're ready to go */
++      pref    src[0]
++      mov     r8, 3
++      tst     dst, r8
++      breq    .Laligned_copy
++
++.Lunaligned_dst:
++      /* src is aligned, but dst is not. Expect bad performance */
++      sub     len, 4
++      brlt    2f
++1:    ld.w    r0, src++
++      st.w    dst++, r0
++      sub     len, 4
++      brge    1b
++
++2:    neg     len
++      add     pc, pc, len << 2
++      .rept   3
++      ld.ub   r0, src++
++      st.b    dst++, r0
++      .endr
++
++      popm    r0-r7, pc
++      .size   memcpy, . - memcpy
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memmove.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memmove.S    2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,114 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define dst r12
++#define src r11
++#define len r10
++
++      .text
++      .global memmove
++      .type   memmove, @function
++
++      .global __memmove
++      .hidden __memmove
++      .type   __memmove, @function
++memmove:
++__memmove:
++      cp.w    src, dst
++      brge    __memcpy
++
++      add     dst, len
++      add     src, len
++      pref    src[-1]
++
++      /*
++       * The rest is basically the same as in memcpy.S except that
++       * the direction is reversed.
++       */
++      cp.w    len, 32
++      brge    .Lmore_than_31
++
++      sub     len, 1
++      retlt   r12
++1:    ld.ub   r8, --src
++      st.b    --dst, r8
++      sub     len, 1
++      brge    1b
++      retal   r12
++
++.Lmore_than_31:
++      pushm   r0-r7, lr
++
++      /* Check alignment */
++      mov     r8, src
++      andl    r8, 31, COH
++      brne    .Lunaligned_src
++      mov     r8, r12
++      andl    r8, 3, COH
++      brne    .Lunaligned_dst
++
++.Laligned_copy:
++      sub     len, 32
++      brlt    .Lless_than_32
++
++1:    /* Copy 32 bytes at a time */
++      sub     src, 32
++      ldm     src, r0-r7
++      sub     dst, 32
++      sub     len, 32
++      stm     dst, r0-r7
++      brge    1b
++
++.Lless_than_32:
++      /* Copy 16 more bytes if possible */
++      sub     len, -16
++      brlt    .Lless_than_16
++      sub     src, 16
++      ldm     src, r0-r3
++      sub     dst, 16
++      sub     len, 16
++      stm     dst, r0-r3
++
++.Lless_than_16:
++      /* Do the remaining as byte copies */
++      sub     len, -16
++      breq    2f
++1:    ld.ub   r0, --src
++      st.b    --dst, r0
++      sub     len, 1
++      brne    1b
++
++2:    popm    r0-r7, pc
++
++.Lunaligned_src:
++      /* Make src cacheline-aligned. r8 = (src & 31) */
++      sub     len, r8
++1:    ld.ub   r0, --src
++      st.b    --dst, r0
++      sub     r8, 1
++      brne    1b
++
++      /* If dst is word-aligned, we're ready to go */
++      pref    src[-4]
++      mov     r8, 3
++      tst     dst, r8
++      breq    .Laligned_copy
++
++.Lunaligned_dst:
++      /* src is aligned, but dst is not. Expect bad performance */
++      sub     len, 4
++      brlt    2f
++1:    ld.w    r0, --src
++      st.w    --dst, r0
++      sub     len, 4
++      brge    1b
++
++2:    neg     len
++      add     pc, pc, len << 2
++      .rept   3
++      ld.ub   r0, --src
++      st.b    --dst, r0
++      .endr
++
++      popm    r0-r7, pc
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memset.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memset.S     2006-10-20 10:42:15.000000000 +0200
+@@ -0,0 +1,60 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s r12
++#define c r11
++#define n r10
++
++      .text
++      .global memset
++      .type   memset, @function
++
++      .global __memset
++      .hidden __memset
++      .type   __memset, @function
++
++      .align  1
++memset:
++__memset:
++      cp.w    n, 32
++      mov     r9, s
++      brge    .Llarge_memset
++
++      sub     n, 1
++      retlt   s
++1:    st.b    s++, c
++      sub     n, 1
++      brge    1b
++
++      retal   r9
++
++.Llarge_memset:
++      mov     r8, r11
++      mov     r11, 3
++      bfins   r8, r8, 8, 8
++      bfins   r8, r8, 16, 16
++      tst     s, r11
++      breq    2f
++
++1:    st.b    s++, r8
++      sub     n, 1
++      tst     s, r11
++      brne    1b
++
++2:    mov     r11, r9
++      mov     r9, r8
++      sub     n, 8
++
++3:    st.d    s++, r8
++      sub     n, 8
++      brge    3b
++
++      /* If we are done, n == -8 and we'll skip all st.b insns below */
++      neg     n
++      lsl     n, 1
++      add     pc, n
++      .rept   7
++      st.b    s++, r8
++      .endr
++      retal   r11
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strcat.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strcat.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,95 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define s1 r9
++#define s2 r11
++
++      .text
++      .global strcat
++      .type   strcat, @function
++      .align  1
++strcat:
++      mov     s1, r12
++
++      /* Make sure s1 is word-aligned */
++      mov     r10, s1
++      andl    r10, 3, COH
++      breq    2f
++
++      add     pc, pc, r10 << 3
++      sub     r0, r0, 0       /* 4-byte nop */
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    2f
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    3f
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    4f
++
++      /* Find the end of the first string */
++5:    ld.w    r8, s1++
++      tnbz    r8
++      brne    5b
++
++      sub     s1, 4
++
++      bfextu  r10, r8, 24, 8
++      cp.w    r10, 0
++      breq    1f
++      sub     s1, -1
++      bfextu  r10, r8, 16, 8
++      cp.w    r10, 0
++      breq    2f
++      sub     s1, -1
++      bfextu  r10, r8, 8, 8
++      cp.w    r10, 0
++      breq    3f
++      sub     s1, -1
++      rjmp    4f
++
++      /* Now, append s2 */
++1:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++2:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++3:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++4:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++
++      /* Copy one word at a time */
++      ld.w    r8, s2++
++      tnbz    r8
++      breq    2f
++1:    st.w    r8, s2++
++      ld.w    r8, s2++
++      tnbz    r8
++      brne    1b
++
++      /* Copy the remaining bytes */
++      bfextu  r10, r8, 24, 8
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 16, 8
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 8, 8
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      st.b    s1++, r8
++      retal   r12
++      .size   strcat, . - strcat
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strcmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strcmp.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,80 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s1 r12
++#define s2 r11
++#define len r10
++
++      .text
++      .global strcmp
++      .type   strcmp, @function
++      .align  1
++strcmp:
++      mov     r8, 3
++      tst     s1, r8
++      brne    .Lunaligned_s1
++      tst     s2, r8
++      brne    .Lunaligned_s2
++
++1:    ld.w    r8, s1++
++      ld.w    r9, s2++
++      cp.w    r8, r9
++      brne    2f
++      tnbz    r8
++      brne    1b
++      retal   0
++
++2:    bfextu  r12, r8, 24, 8
++      bfextu  r11, r9, 24, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 16, 8
++      bfextu  r11, r9, 16, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 8, 8
++      bfextu  r11, r9, 8, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 0, 8
++      bfextu  r11, r9, 0, 8
++      sub     r12, r11
++      retal   r12
++
++.Lunaligned_s1:
++3:    tst     s1, r8
++      breq    4f
++      ld.ub   r10, s1++
++      ld.ub   r9, s2++
++      sub     r10, r9
++      retne   r10
++      cp.w    r9, 0
++      brne    3b
++      retal   r10
++
++4:    tst     s2, r8
++      breq    1b
++
++.Lunaligned_s2:
++      /*
++       * s1 and s2 can't both be aligned, and unaligned word loads
++       * can trigger spurious exceptions if we cross a page boundary.
++       * Do it the slow way...
++       */
++1:    ld.ub   r8, s1++
++      ld.ub   r9, s2++
++      sub     r8, r9
++      retne   r8
++      cp.w    r9, 0
++      brne    1b
++      retal   0
++
++      .weak   strcoll
++      strcoll = strcmp
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strcpy.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strcpy.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ *
++ * To reduce the size, this one might simply call strncpy with len = -1.
++ */
++
++#define dst r9
++#define src r11
++
++      .text
++      .global strcpy
++      .type   strcpy, @function
++strcpy:
++      mov     dst, r12
++
++      pref    src[0]
++
++      /*
++       * Check alignment. If src is aligned but dst isn't, we can't
++       * do much about it...
++       */
++      mov     r8, src
++      andl    r8, 3 COH
++      brne    .Lunaligned_src
++
++.Laligned_copy:
++1:    ld.w    r8, src++
++      tnbz    r8
++      breq    2f
++      st.w    dst++, r8
++      rjmp    1b
++
++2:    /*
++       * Ok, r8 now contains the terminating '\0'. Copy the
++       * remaining bytes individually.
++       */
++      bfextu  r10, r8, 24, 8
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 16, 8
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 8, 8
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      st.b    dst++, r8
++      retal   r12
++
++.Lunaligned_src:
++      /* Copy bytes until we're aligned */
++      rsub    r8, r8, 4
++      add     pc, pc, r8 << 3
++      nop
++      nop
++      ld.ub   r10, src++
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++
++      rjmp    .Laligned_copy
+Index: uClibc-0.9.28-avr32/libc/string/avr32/stringtest.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/stringtest.c 2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,144 @@
++
++#include <stdio.h>
++#include <string.h>
++#include <time.h>
++#include <sys/mman.h>
++
++#define BUF_SIZE (8 * 1024)
++
++static char *buf1;
++static char *buf1_ref;
++static char *buf2;
++
++extern void *optimized_memcpy(void *dest, void *src, size_t len);
++extern void *optimized_memmove(void *dest, void *src, size_t len);
++extern char *optimized_strcpy(char *dest, char *src);
++extern char *optimized_strncpy(char *dest, char *src, size_t len);
++
++void dump_mismatch(char *buf, char *ref, size_t len)
++{
++      int i, j;
++
++      for (i = 0; i < len; i += 16) {
++              if (memcmp(buf + i, ref + i, 16) == 0)
++                      continue;
++
++              printf("%4x buf:", i);
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", buf[j]);
++              printf("\n     ref:");
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", ref[j]);
++              printf("\n");
++      }
++}
++
++static void test_memcpy(int src_offset, int dst_offset, int len)
++{
++      clock_t start, old, new;
++      int i;
++
++      memset(buf1, 0x55, BUF_SIZE);
++      memset(buf1_ref, 0x55, BUF_SIZE);
++      memset(buf2, 0xaa, BUF_SIZE);
++
++      printf("Testing memcpy with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      start = clock();
++      for (i = 0; i < 8192; i++)
++              optimized_memcpy(buf1 + dst_offset, buf2 + src_offset, len);
++      new = clock() - start;
++      start = clock();
++      for ( i = 0; i < 8192; i++)
++              memcpy(buf1_ref + dst_offset, buf2 + src_offset, len);
++      old = clock() - start;
++
++      if (memcmp(buf1, buf1_ref, BUF_SIZE) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, BUF_SIZE);
++      }
++      printf("CPU time used: %d vs. %d\n", new, old);
++}
++
++static void test_memmove(int src_offset, int dst_offset, int len)
++{
++      clock_t start, old, new;
++
++      memset(buf1, 0x55, BUF_SIZE);
++      memset(buf1_ref, 0x55, BUF_SIZE);
++      memset(buf2, 0xaa, BUF_SIZE);
++
++      printf("Testing memmove with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      start = clock();
++      optimized_memmove(buf1 + dst_offset, buf2 + src_offset, len);
++      new = clock() - start;
++      start = clock();
++      memmove(buf1_ref + dst_offset, buf2 + src_offset, len);
++      old = clock() - start;
++
++      if (memcmp(buf1, buf1_ref, BUF_SIZE) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, BUF_SIZE);
++      }
++      printf("CPU time used: %d vs. %d\n", new, old);
++}
++
++int main(int argc, char *argv[])
++{
++      buf2 = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                  MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf2 == MAP_FAILED) {
++              perror("Failed to allocate memory for buf2");
++              return 1;
++      }
++      buf1 = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                  MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf1 == MAP_FAILED) {
++              perror("Failed to allocate memory for buf1");
++              return 1;
++      }
++      buf1_ref = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                      MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf1_ref == MAP_FAILED) {
++              perror("Failed to allocate memory for buf1_ref");
++              return 1;
++      }
++      printf("\n === MEMCPY ===\n\n");
++
++      test_memcpy(0, 0, BUF_SIZE - 32);
++      test_memcpy(0, 0, 1);
++      test_memcpy(0, 0, 31);
++      test_memcpy(0, 0, 32);
++      test_memcpy(0, 0, 127);
++      test_memcpy(0, 0, 128);
++      test_memcpy(4, 4, BUF_SIZE - 32 - 4);
++      test_memcpy(1, 1, BUF_SIZE - 32 - 1);
++      test_memcpy(1, 1, 126);
++      test_memcpy(0, 3, 128);
++      test_memcpy(1, 4, 128);
++      test_memcpy(0, 0, 0);
++
++      printf("\n === MEMMOVE ===\n\n");
++
++      test_memmove(0, 0, BUF_SIZE - 32);
++      test_memmove(0, 0, 1);
++      test_memmove(0, 0, 31);
++      test_memmove(0, 0, 32);
++      test_memmove(0, 0, BUF_SIZE - 33);
++      test_memmove(0, 0, 128);
++      test_memmove(4, 4, BUF_SIZE - 32 - 4);
++      test_memmove(1, 1, BUF_SIZE - 32 - 1);
++      test_memmove(1, 1, BUF_SIZE - 130);
++      test_memmove(0, 3, BUF_SIZE - 128);
++      test_memmove(1, 4, BUF_SIZE - 128);
++      test_memmove(0, 0, 0);
++
++      return 0;
++}
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strlen.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strlen.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define str r12
++
++      .text
++      .global strlen
++      .type   strlen, @function
++strlen:
++      mov     r11, r12
++
++      mov     r9, str
++      andl    r9, 3, COH
++      brne    .Lunaligned_str
++
++1:    ld.w    r8, str++
++      tnbz    r8
++      brne    1b
++
++      sub     r12, r11
++      bfextu  r9, r8, 24, 8
++      cp.w    r9, 0
++      subeq   r12, 4
++      reteq   r12
++      bfextu  r9, r8, 16, 8
++      cp.w    r9, 0
++      subeq   r12, 3
++      reteq   r12
++      bfextu  r9, r8, 8, 8
++      cp.w    r9, 0
++      subeq   r12, 2
++      reteq   r12
++      sub     r12, 1
++      retal   r12
++
++.Lunaligned_str:
++      add     pc, pc, r9 << 3
++      sub     r0, r0, 0       /* 4-byte nop */
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      breq    1f
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      breq    1f
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      brne    1b
++
++1:    sub     r12, 1
++      sub     r12, r11
++      retal   r12
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strncpy.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strncpy.S    2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define dst r9
++#define src r11
++
++      .text
++      .global strcpy
++      .type   strncpy, @function
++strncpy:
++      mov     dst, r12
++
++      pref    src[0]
++      mov     dst, r12
++
++      /*
++       * Check alignment. If src is aligned but dst isn't, we can't
++       * do much about it...
++       */
++      mov     r8, src
++      andl    r8, 3 COH
++      brne    .Lunaligned_src
++
++.Laligned_copy:
++      sub     r10, 4
++      brlt    3f
++1:    ld.w    r8, src++
++      tnbz    r8
++      breq    2f
++      st.w    dst++, r8
++      sub     r10, 4
++      brne    1b
++
++3:    sub     r10, -4
++      reteq   r12
++
++      /* This is safe as long as src is word-aligned and r10 > 0 */
++      ld.w    r8, src++
++
++2:    /*
++       * Ok, r8 now contains the terminating '\0'. Copy the
++       * remaining bytes individually.
++       */
++      bfextu  r11, r8, 24, 8
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      bfextu  r11, r8, 16, 8
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      bfextu  r11, r8, 8, 8
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      st.b    dst++, r8
++      retal   r12
++
++.Lunaligned_src:
++      /* Copy bytes until we're aligned */
++      min     r8, r8, r10
++      sub     r10, r8
++      sub     r8, 1
++      retlt   r12
++1:    ld.ub   r10, src++
++      st.b    dst++, r10
++      sub     r8, 1
++      brge    1b
++
++      rjmp    .Laligned_copy
+Index: uClibc-0.9.28-avr32/libc/string/avr32/test_memcpy.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/test_memcpy.c        2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,66 @@
++
++#include <stdio.h>
++#include <string.h>
++
++#define BUF_SIZE 32768
++
++static char buf1[BUF_SIZE] __attribute__((aligned(32)));
++static char buf1_ref[BUF_SIZE] __attribute__((aligned(32)));
++static char buf2[BUF_SIZE] __attribute__((aligned(32)));
++
++extern void *new_memcpy(void *dest, void *src, size_t len);
++
++void dump_mismatch(char *buf, char *ref, size_t len)
++{
++      int i, j;
++
++      for (i = 0; i < len; i += 16) {
++              if (memcmp(buf + i, ref + i, 16) == 0)
++                      continue;
++
++              printf("% 4x buf:", i);
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", buf[j]);
++              printf("\n     ref:");
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", ref[j]);
++              printf("\n");
++      }
++}
++
++void test(int src_offset, int dst_offset, int len)
++{
++      memset(buf1, 0x55, sizeof(buf1));
++      memset(buf1_ref, 0x55, sizeof(buf1_ref));
++      memset(buf2, 0xaa, sizeof(buf2));
++
++      printf("Testing with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      new_memcpy(buf1 + dst_offset, buf2 + src_offset, len);
++      memcpy(buf1_ref + dst_offset, buf2 + src_offset, len);
++
++      if (memcmp(buf1, buf1_ref, sizeof(buf1)) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, sizeof(buf1));
++      }
++}
++
++int main(int argc, char *argv[])
++{
++      test(0, 0, BUF_SIZE);
++      test(0, 0, 1);
++      test(0, 0, 31);
++      test(0, 0, 32);
++      test(0, 0, 127);
++      test(0, 0, 128);
++      test(4, 4, BUF_SIZE - 4);
++      test(1, 1, BUF_SIZE - 1);
++      test(1, 1, 126);
++      test(0, 3, 128);
++      test(1, 4, 128);
++
++      return 0;
++}
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/fix-__libc_fcntl64-varargs-prototype.patch b/packages/uclibc/uclibc-0.9.28/avr32/fix-__libc_fcntl64-varargs-prototype.patch
new file mode 100644 (file)
index 0000000..3319f98
--- /dev/null
@@ -0,0 +1,24 @@
+Subject: [PATCH] Fix __libc_fcntl64 prototype in __syscall_fcntl.c
+
+__libc_fcntl64 is a varargs function and should be declared as such.
+Otherwise, the gcc compiler for AVR32, and perhaps other architectures,
+will use the wrong calling convention.
+
+---
+
+ libc/sysdeps/linux/common/__syscall_fcntl.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: uClibc-0.9.28/libc/sysdeps/linux/common/__syscall_fcntl.c
+===================================================================
+--- uClibc-0.9.28.orig/libc/sysdeps/linux/common/__syscall_fcntl.c     2006-02-07 16:48:32.000000000 +0100
++++ uClibc-0.9.28/libc/sysdeps/linux/common/__syscall_fcntl.c  2006-02-07 17:19:09.000000000 +0100
+@@ -12,7 +12,7 @@
+ #include <fcntl.h>
+ #if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64
+-extern int __libc_fcntl64(int fd, int cmd, long arg);
++extern int __libc_fcntl64(int fd, int cmd, ...);
+ #endif
+ #define __NR___syscall_fcntl __NR_fcntl
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/fix-broken-__libc_open-declaration.patch b/packages/uclibc/uclibc-0.9.28/avr32/fix-broken-__libc_open-declaration.patch
new file mode 100644 (file)
index 0000000..aafdc8c
--- /dev/null
@@ -0,0 +1,30 @@
+From nobody Mon Sep 17 00:00:00 2001
+From: HÃ¥vard Skinnemoen <hskinnemoen@atmel.com>
+Date: Fri Apr 7 17:10:32 2006 +0200
+Subject: [PATCH] Fix broken __libc_open declaration in open64.c
+
+__libc_open is a vararg function and should therefore be declared as
+such. Fixes bug #4190.
+
+---
+
+ libc/sysdeps/linux/common/open64.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+70f2c81903327a8a346e370830932b80045ab04e
+diff --git a/libc/sysdeps/linux/common/open64.c b/libc/sysdeps/linux/common/open64.c
+index 543aa13..d9a27a7 100644
+--- a/libc/sysdeps/linux/common/open64.c
++++ b/libc/sysdeps/linux/common/open64.c
+@@ -26,7 +26,7 @@
+ #endif
+ #ifdef __UCLIBC_HAS_LFS__
+-extern int __libc_open (__const char *file, int oflag, mode_t mode);
++extern int __libc_open (__const char *file, int oflag, ...);
+ /* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+    a third argument is the file protection.  */
+-- 
+1.2.4
+
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/fix-getrusage-argument-type.patch b/packages/uclibc/uclibc-0.9.28/avr32/fix-getrusage-argument-type.patch
new file mode 100644 (file)
index 0000000..d68576b
--- /dev/null
@@ -0,0 +1,19 @@
+Subject: [PATCH] Fix getrusage argument type
+
+The first argument to getrusage is of type __rusage_who_t, not int.
+This patch fixes that.
+---
+
+ libc/sysdeps/linux/common/getrusage.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: uClibc-0.9.28/libc/sysdeps/linux/common/getrusage.c
+===================================================================
+--- uClibc-0.9.28.orig/libc/sysdeps/linux/common/getrusage.c   2006-02-07 17:18:22.000000000 +0100
++++ uClibc-0.9.28/libc/sysdeps/linux/common/getrusage.c        2006-02-07 17:18:31.000000000 +0100
+@@ -10,4 +10,4 @@
+ #include "syscalls.h"
+ #include <unistd.h>
+ #include <wait.h>
+-_syscall2(int, getrusage, int, who, struct rusage *, usage);
++_syscall2(int, getrusage, __rusage_who_t, who, struct rusage *, usage);
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/ldd-avr32-support.patch b/packages/uclibc/uclibc-0.9.28/avr32/ldd-avr32-support.patch
new file mode 100644 (file)
index 0000000..dd61f17
--- /dev/null
@@ -0,0 +1,25 @@
+Subject: [PATCH] ldd: AVR32 support
+
+Add AVR32-specific definitions to ldd.
+
+---
+
+ utils/ldd.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+Index: uClibc-0.9.28/utils/ldd.c
+===================================================================
+--- uClibc-0.9.28.orig/utils/ldd.c     2006-02-07 16:48:02.000000000 +0100
++++ uClibc-0.9.28/utils/ldd.c  2006-02-07 17:13:00.000000000 +0100
+@@ -56,6 +56,11 @@
+ #define ELFCLASSM     ELFCLASS32
+ #endif
++#if defined(__avr32__)
++#define MATCH_MACHINE(x) (x == EM_AVR32)
++#define ELFCLASSM     ELFCLASS32
++#endif
++
+ #if defined(__s390__)
+ #define MATCH_MACHINE(x) (x == EM_S390)
+ #define ELFCLASSM     ELFCLASS32
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/ldso-always-inline-_dl_memcpy.patch b/packages/uclibc/uclibc-0.9.28/avr32/ldso-always-inline-_dl_memcpy.patch
new file mode 100644 (file)
index 0000000..cf0e677
--- /dev/null
@@ -0,0 +1,24 @@
+Subject: [PATCH] ldso: Always inline _dl_memcpy()
+
+On some gcc versions, inline is merely a hint. AVR32 depends on this
+function actually getting inlined, so we need to use __always_inline
+instead of just inline.
+
+---
+
+ ldso/include/dl-string.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: uClibc-0.9.28/ldso/include/dl-string.h
+===================================================================
+--- uClibc-0.9.28.orig/ldso/include/dl-string.h        2006-02-07 17:01:28.000000000 +0100
++++ uClibc-0.9.28/ldso/include/dl-string.h     2006-02-07 17:03:02.000000000 +0100
+@@ -134,7 +134,7 @@ static inline char * _dl_strstr(const ch
+     } while (1);
+ }
+-static inline void * _dl_memcpy(void * dst, const void * src, size_t len)
++static __always_inline void * _dl_memcpy(void * dst, const void * src, size_t len)
+ {
+       register char *a = dst-1;
+       register const char *b = src-1;
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/ldso-always-inline-syscalls.patch b/packages/uclibc/uclibc-0.9.28/avr32/ldso-always-inline-syscalls.patch
new file mode 100644 (file)
index 0000000..e6f5c42
--- /dev/null
@@ -0,0 +1,107 @@
+Subject: [PATCH] ldso: Always inline system calls
+
+Some versions of gcc consider inline merely a hint. AVR32 depends on
+the system calls actually being inlined, so we need to use
+__always_inline instead of just inline.
+
+---
+
+ ldso/include/dl-syscall.h |   38 +++++++++++++++++++-------------------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+Index: uClibc-0.9.28/ldso/include/dl-syscall.h
+===================================================================
+--- uClibc-0.9.28.orig/ldso/include/dl-syscall.h       2006-02-07 17:07:06.000000000 +0100
++++ uClibc-0.9.28/ldso/include/dl-syscall.h    2006-02-07 17:08:47.000000000 +0100
+@@ -60,59 +60,59 @@
+    dynamic linking at all, so we cannot return any error codes.
+    We just punt if there is an error. */
+ #define __NR__dl_exit __NR_exit
+-static inline _syscall1(void, _dl_exit, int, status);
++static __always_inline _syscall1(void, _dl_exit, int, status);
+ #define __NR__dl_close __NR_close
+-static inline _syscall1(int, _dl_close, int, fd);
++static __always_inline _syscall1(int, _dl_close, int, fd);
+ #define __NR__dl_open __NR_open
+-static inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode);
++static __always_inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode);
+ #define __NR__dl_write __NR_write
+-static inline _syscall3(unsigned long, _dl_write, int, fd,
++static __always_inline _syscall3(unsigned long, _dl_write, int, fd,
+           const void *, buf, unsigned long, count);
+ #define __NR__dl_read __NR_read
+-static inline _syscall3(unsigned long, _dl_read, int, fd,
++static __always_inline _syscall3(unsigned long, _dl_read, int, fd,
+           const void *, buf, unsigned long, count);
+ #define __NR__dl_mprotect __NR_mprotect
+-static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot);
++static __always_inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot);
+ #define __NR__dl_stat __NR_stat
+-static inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
++static __always_inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
+ #define __NR__dl_munmap __NR_munmap
+-static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
++static __always_inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
+ #define __NR__dl_getuid __NR_getuid
+-static inline _syscall0(uid_t, _dl_getuid);
++static __always_inline _syscall0(uid_t, _dl_getuid);
+ #define __NR__dl_geteuid __NR_geteuid
+-static inline _syscall0(uid_t, _dl_geteuid);
++static __always_inline _syscall0(uid_t, _dl_geteuid);
+ #define __NR__dl_getgid __NR_getgid
+-static inline _syscall0(gid_t, _dl_getgid);
++static __always_inline _syscall0(gid_t, _dl_getgid);
+ #define __NR__dl_getegid __NR_getegid
+-static inline _syscall0(gid_t, _dl_getegid);
++static __always_inline _syscall0(gid_t, _dl_getegid);
+ #define __NR__dl_getpid __NR_getpid
+-static inline _syscall0(gid_t, _dl_getpid);
++static __always_inline _syscall0(gid_t, _dl_getpid);
+ #define __NR__dl_readlink __NR_readlink
+-static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
++static __always_inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
+ #ifdef __NR_mmap
+ #ifdef MMAP_HAS_6_ARGS
+ #define __NR__dl_mmap __NR_mmap
+-static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
++static __always_inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
+               int, prot, int, flags, int, fd, off_t, offset);
+ #else
+ #define __NR__dl_mmap_real __NR_mmap
+-static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
++static __always_inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
+-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
++static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+               int flags, int fd, unsigned long offset)
+ {
+       unsigned long buffer[6];
+@@ -128,12 +128,12 @@ static inline void * _dl_mmap(void * add
+ #endif
+ #elif defined __NR_mmap2
+ #define __NR___syscall_mmap2       __NR_mmap2
+-static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
++static __always_inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
+               size_t, len, int, prot, int, flags, int, fd, off_t, offset);
+ /*always 12, even on architectures where PAGE_SHIFT != 12 */
+ #define MMAP2_PAGE_SHIFT 12
+ #define MAP_FAILED ((void *) -1)
+-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
++static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+               int flags, int fd, unsigned long offset)
+ {
+     if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/ldso-avr32-2.patch b/packages/uclibc/uclibc-0.9.28/avr32/ldso-avr32-2.patch
new file mode 100644 (file)
index 0000000..ddeb84d
--- /dev/null
@@ -0,0 +1,526 @@
+Subject: [PATCH] ldso: AVR32 support
+
+This implements the AVR32-specific parts of the dynamic linker.
+
+---
+
+ ldso/ldso/avr32/dl-debug.h    |   45 +++++++++
+ ldso/ldso/avr32/dl-startup.h  |  110 ++++++++++++++++++++++++
+ ldso/ldso/avr32/dl-syscalls.h |    5 +
+ ldso/ldso/avr32/dl-sysdep.h   |  103 ++++++++++++++++++++++
+ ldso/ldso/avr32/elfinterp.c   |  191 ++++++++++++++++++++++++++++++++++++++++++
+ ldso/ldso/avr32/resolve.S     |   28 ++++++
+ 6 files changed, 482 insertions(+)
+
+Index: uClibc-0.9.28/ldso/ldso/avr32/dl-debug.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/ldso/ldso/avr32/dl-debug.h   2006-05-05 09:30:43.000000000 +0200
+@@ -0,0 +1,45 @@
++/*
++ * AVR32 ELF shared libary loader support
++ *
++ * Copyright (C) 2005 Atmel Norway
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. The name of the above contributors may not be
++ *    used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++static const char *_dl_reltypes_tab[] = {
++    "R_AVR32_NONE",
++    "R_AVR32_32", "R_AVR32_16", "R_AVR32_8",
++    "R_AVR32_32_PCREL", "R_AVR32_16_PCREL", "R_AVR32_8_PCREL",
++    "R_AVR32_DIFF32", "R_AVR32_DIFF16", "R_AVR32_DIFF8",
++    "R_AVR32_GOT32", "R_AVR32_GOT16", "R_AVR32_GOT8",
++    "R_AVR32_21S", "R_AVR32_16U", "R_AVR32_16S", "R_AVR32_8S", "R_AVR32_8S_EXT",
++    "R_AVR32_22H_PCREL", "R_AVR32_18W_PCREL", "R_AVR32_16B_PCREL",
++    "R_AVR32_16N_PCREL", "R_AVR32_14UW_PCREL", "R_AVR32_11H_PCREL",
++    "R_AVR32_10UW_PCREL", "R_AVR32_9H_PCREL", "R_AVR32_9UW_PCREL",
++    "R_AVR32_HI16", "R_AVR32_LO16",
++    "R_AVR32_GOTPC", "R_AVR32_GOTCALL", "R_AVR32_LDA_GOT",
++    "R_AVR32_GOT21S", "R_AVR32_GOT18SW", "R_AVR32_GOT16S", "R_AVR32_GOT7UW",
++    "R_AVR32_32_CPENT", "R_AVR32_CPCALL", "R_AVR32_16_CP", "R_AVR32_9W_CP",
++    "R_AVR32_RELATIVE", "R_AVR32_GLOB_DAT", "R_AVR32_JMP_SLOT",
++    "R_AVR32_ALIGN",
++};
+Index: uClibc-0.9.28/ldso/ldso/avr32/dl-startup.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/ldso/ldso/avr32/dl-startup.h 2006-05-05 09:29:45.000000000 +0200
+@@ -0,0 +1,110 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Architecture specific code used by dl-startup.c
++ * Copyright (C) 2005 Atmel Norway
++ */
++
++/* This is the library loader's main entry point. Let _dl_boot2 do its
++ * initializations and jump to the application's entry point
++ * afterwards. */
++asm(  "       .text\n"
++      "       .global _start\n"
++      "       .type   _start,@function\n"
++      "_start:\n"
++      /* All arguments are on the stack initially */
++      "       mov     r12, sp\n"
++      "       rcall   _dl_start\n"
++      /* Returns user entry point in r12. Save it. */
++      "       mov     r0, r12\n"
++      /* We're PIC, so get the Global Offset Table */
++      "       lddpc   r6, .L_GOT\n"
++      ".L_RGOT:\n"
++      "       rsub    r6, pc\n"
++      /* Adjust argc and argv according to _dl_skip_args */
++      "       ld.w    r1, r6[_dl_skip_args@got]\n"
++      "       ld.w    r1, r1[0]\n"
++      "       ld.w    r2, sp++\n"
++      "       sub     r2, r1\n"
++      "       add     sp, sp, r1 << 2\n"
++      "       st.w    --sp, r2\n"
++      /* Load the finalizer function */
++      "       ld.w    r12, r6[_dl_fini@got]\n"
++      /* Jump to the user's entry point */
++      "       mov     pc, r0\n\n"
++
++      "       .align  2\n"
++      ".L_GOT:"
++      "       .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_\n"
++      "       .size   _start, . - _start\n"
++      "       .previous\n");
++
++/* Get a pointer to the argv array.  On many platforms this can be just
++ * the address if the first argument, on other platforms we need to
++ * do something a little more subtle here. */
++#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *)ARGS + 1)
++
++
++/* We can't call functions before the GOT has been initialized */
++#define NO_FUNCS_BEFORE_BOOTSTRAP
++
++/*
++ * Relocate the GOT during dynamic loader bootstrap.  This will add
++ * the load address to all entries in the GOT, which is necessary
++ * because the linker doesn't generate R_AVR32_RELATIVE relocs for the
++ * GOT.
++ */
++static __always_inline
++void PERFORM_BOOTSTRAP_GOT(struct elf_resolve *tpnt)
++{
++      Elf32_Addr i, nr_got;
++      register Elf32_Addr *__r6 __asm__("r6");
++      Elf32_Addr *got = __r6;
++
++      nr_got = tpnt->dynamic_info[DT_AVR32_GOTSZ_IDX] / sizeof(*got);
++      for (i = 2; i < nr_got; i++)
++              got[i] += tpnt->loadaddr;
++}
++
++#define PERFORM_BOOTSTRAP_GOT(tpnt) PERFORM_BOOTSTRAP_GOT(tpnt)
++
++/* Handle relocation of the symbols in the dynamic loader. */
++static __always_inline
++void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
++                           unsigned long symbol_addr,
++                           unsigned long load_addr, Elf32_Sym *symtab)
++{
++      switch(ELF32_R_TYPE(rpnt->r_info)) {
++      case R_AVR32_NONE:
++              break;
++      case R_AVR32_GLOB_DAT:
++      case R_AVR32_JMP_SLOT:
++              *reloc_addr = symbol_addr;
++              break;
++      case R_AVR32_RELATIVE:
++              SEND_STDERR_DEBUG("Applying RELATIVE relocation: ");
++              SEND_ADDRESS_STDERR_DEBUG(load_addr, 0);
++              SEND_STDERR_DEBUG(" + ");
++              SEND_ADDRESS_STDERR_DEBUG(rpnt->r_addend, 1);
++              *reloc_addr = load_addr + rpnt->r_addend;
++              break;
++      default:
++              SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc_type ");
++              SEND_NUMBER_STDERR(ELF32_R_TYPE(rpnt->r_info), 1);
++              SEND_STDERR("REL, SYMBOL, LOAD: ");
++              SEND_ADDRESS_STDERR(reloc_addr, 0);
++              SEND_STDERR(", ");
++              SEND_ADDRESS_STDERR(symbol_addr, 0);
++              SEND_STDERR(", ");
++              SEND_ADDRESS_STDERR(load_addr, 1);
++              _dl_exit(1);
++      }
++}
++
++/* Transfer control to the user's application, once the dynamic loader
++ * is done. This routine has to exit the current function, then call
++ * the _dl_elf_main function.
++ *
++ * Since our _dl_boot will simply call whatever is returned by
++ * _dl_boot2, we can just return the address we're supposed to
++ * call.  */
++#define START()       return _dl_elf_main;
+Index: uClibc-0.9.28/ldso/ldso/avr32/dl-syscalls.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/ldso/ldso/avr32/dl-syscalls.h        2006-05-05 09:29:25.000000000 +0200
+@@ -0,0 +1,5 @@
++/* We can't use the real errno in ldso, since it has not yet
++ * been dynamicly linked in yet. */
++extern int _dl_errno;
++#define __set_errno(X) {(_dl_errno) = (X);}
++#include "sys/syscall.h"
+Index: uClibc-0.9.28/ldso/ldso/avr32/dl-sysdep.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/ldso/ldso/avr32/dl-sysdep.h  2006-05-05 09:30:43.000000000 +0200
+@@ -0,0 +1,103 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Various assembly language/system dependent hacks that are required
++ * so that we can minimize the amount of platform specific code.
++ * Copyright (C) 2004-2005 Atmel Norway
++ */
++
++/* Define this if the system uses RELOCA. */
++#define ELF_USES_RELOCA
++
++#include <elf.h>
++
++#define ARCH_NUM 1
++#define DT_AVR32_GOTSZ_IDX    (DT_NUM + OS_NUM)
++
++#define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr)                  \
++      do {                                                            \
++              if (dpnt->d_tag == DT_AVR32_GOTSZ)                      \
++                      dynamic[DT_AVR32_GOTSZ_IDX] = dpnt->d_un.d_val; \
++      } while (0)
++
++/* Initialization sequence for the application/library GOT. */
++#define INIT_GOT(GOT_BASE,MODULE)                                     \
++      do {                                                            \
++              unsigned long i, nr_got;                                \
++                                                                      \
++              GOT_BASE[0] = (unsigned long) _dl_linux_resolve;        \
++              GOT_BASE[1] = (unsigned long) MODULE;                   \
++                                                                      \
++              /* Add load address displacement to all GOT entries */  \
++              nr_got = MODULE->dynamic_info[DT_AVR32_GOTSZ_IDX] / 4;  \
++              for (i = 2; i < nr_got; i++)                            \
++                      GOT_BASE[i] += (unsigned long)MODULE->loadaddr; \
++      } while (0)
++
++#define do_rem(result, n, base)       ((result) = (n) % (base))
++
++/* Here we define the magic numbers that this dynamic loader should accept */
++#define MAGIC1 EM_AVR32
++#undef MAGIC2
++
++/* Used for error messages */
++#define ELF_TARGET "AVR32"
++
++unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got);
++
++/* 4096 bytes alignment */
++#define PAGE_ALIGN 0xfffff000
++#define ADDR_ALIGN 0xfff
++#define OFFS_ALIGN 0x7ffff000
++
++#define elf_machine_type_class(type)                          \
++      ((type == R_AVR32_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)
++
++/* AVR32 doesn't need any COPY relocs */
++#define DL_NO_COPY_RELOCS
++
++/* Return the link-time address of _DYNAMIC.  Conveniently, this is the
++   first element of the GOT.  This must be inlined in a function which
++   uses global data.  */
++static inline Elf32_Addr
++elf_machine_dynamic (void)
++{
++      register Elf32_Addr *got asm ("r6");
++      return *got;
++}
++
++/* Return the run-time load address of the shared object.  */
++static inline Elf32_Addr
++elf_machine_load_address (void)
++{
++      extern void __dl_start asm("_dl_start");
++      Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
++      Elf32_Addr pcrel_addr;
++
++      asm   ("        lddpc   %0, 2f\n"
++             "1:      add     %0, pc\n"
++             "        rjmp    3f\n"
++             "        .align  2\n"
++             "2:      .long   _dl_start - 1b\n"
++             "3:\n"
++             : "=r"(pcrel_addr) : : "cc");
++
++      return pcrel_addr - got_addr;
++}
++
++/*
++ * Perform any RELATIVE relocations specified by DT_RELCOUNT.
++ * Currently, we don't use that tag, but we might in the future as
++ * this would reduce the startup time somewhat (although probably not by much).
++ */
++static inline void
++elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
++                    Elf32_Word relative_count)
++{
++      Elf32_Rela *rpnt = (void *)rel_addr;
++
++      do {
++              Elf32_Addr *reloc_addr;
++              reloc_addr = (void *)(load_off + (rpnt++)->r_offset);
++              *reloc_addr = load_off + rpnt->r_addend;
++      } while (--relative_count);
++}
+Index: uClibc-0.9.28/ldso/ldso/avr32/elfinterp.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/ldso/ldso/avr32/elfinterp.c  2006-05-05 09:30:43.000000000 +0200
+@@ -0,0 +1,191 @@
++/*
++ * AVR32 ELF shared library loader suppport
++ *
++ * Copyright (C) 2004-2006 Atmel Corporation
++ *
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. The name of the above contributors may not be
++ *    used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got)
++{
++      struct elf_resolve *tpnt = (struct elf_resolve *)got[1];
++      Elf32_Sym *sym;
++      unsigned long local_gotno;
++      unsigned long gotsym;
++      unsigned long new_addr;
++      char *strtab, *symname;
++      unsigned long *entry;
++      unsigned long sym_index = got_offset / 4;
++
++#if 0
++      local_gotno = tpnt->dynamic_info[DT_AVR32_LOCAL_GOTNO];
++      gotsym = tpnt->dynamic_info[DT_AVR32_GOTSYM];
++
++      sym = ((Elf32_Sym *)(tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr))
++              + sym_index;
++      strtab = (char *)(tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
++      symname = strtab + sym->st_name;
++
++#if 0
++      new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name,
++                                               tpnt->symbol_scope, tpnt,
++                                               resolver);
++#endif
++
++      entry = (unsigned long *)(got + local_gotno + sym_index - gotsym);
++      *entry = new_addr;
++#endif
++
++      return new_addr;
++}
++
++static int
++_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
++        unsigned long rel_addr, unsigned long rel_size,
++        int (*reloc_func)(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                          Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab))
++{
++      Elf32_Sym *symtab;
++      Elf32_Rela *rpnt;
++      char *strtab;
++      int i;
++
++      rpnt = (Elf32_Rela *)rel_addr;
++      rel_size /= sizeof(Elf32_Rela);
++      symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
++      strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
++
++      for (i = 0; i < rel_size; i++, rpnt++) {
++              int symtab_index, res;
++
++              symtab_index = ELF32_R_SYM(rpnt->r_info);
++
++              debug_sym(symtab, strtab, symtab_index);
++              debug_reloc(symtab, strtab, rpnt);
++
++              res = reloc_func(tpnt, scope, rpnt, symtab, strtab);
++
++              if (res == 0)
++                      continue;
++
++              _dl_dprintf(2, "\n%s: ", _dl_progname);
++
++              if (symtab_index)
++                      _dl_dprintf(2, "symbol '%s': ",
++                                  strtab + symtab[symtab_index].st_name);
++
++              if (res < 0) {
++                      int reloc_type = ELF32_R_TYPE(rpnt->r_info);
++#if defined(__SUPPORT_LD_DEBUG__)
++                      _dl_dprintf(2, "can't handle reloc type %s\n",
++                                  _dl_reltypes(reloc_type));
++#else
++                      _dl_dprintf(2, "can't handle reloc type %x\n",
++                                  reloc_type);
++#endif
++                      _dl_exit(-res);
++              } else {
++                      _dl_dprintf(2, "can't resolve symbol\n");
++                      return res;
++              }
++      }
++
++      return 0;
++}
++
++static int _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                      Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab)
++{
++      int reloc_type;
++      int symtab_index;
++      char *symname;
++      unsigned long *reloc_addr;
++      unsigned long symbol_addr;
++#if defined(__SUPPORT_LD_DEBUG__)
++      unsigned long old_val;
++#endif
++
++      reloc_addr = (unsigned long *)(tpnt->loadaddr + rpnt->r_offset);
++      reloc_type = ELF32_R_TYPE(rpnt->r_info);
++      symtab_index = ELF32_R_SYM(rpnt->r_info);
++      symbol_addr = 0;
++      symname = strtab + symtab[symtab_index].st_name;
++
++      if (symtab_index) {
++              symbol_addr = (unsigned long)
++                      _dl_find_hash(strtab + symtab[symtab_index].st_name,
++                                    tpnt->symbol_scope, tpnt,
++                                    elf_machine_type_class(reloc_type));
++
++              /* Allow undefined references to weak symbols */
++              if (!symbol_addr &&
++                  ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) {
++                      _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
++                                  _dl_progname, symname);
++                      return 0;
++              }
++      }
++
++#if defined(__SUPPORT_LD_DEBUG__)
++      old_val = *reloc_addr;
++#endif
++      switch (reloc_type) {
++      case R_AVR32_NONE:
++              break;
++      case R_AVR32_GLOB_DAT:
++      case R_AVR32_JMP_SLOT:
++              *reloc_addr = symbol_addr + rpnt->r_addend;
++              break;
++      case R_AVR32_RELATIVE:
++              *reloc_addr = (unsigned long)tpnt->loadaddr
++                      + rpnt->r_addend;
++              break;
++      default:
++              return -1;
++      }
++
++#if defined(__SUPPORT_LD_DEBUG__)
++      if (_dl_debug_reloc && _dl_debug_detail)
++              _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
++                          old_val, *reloc_addr);
++#endif
++
++      return 0;
++}
++
++void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
++                                         unsigned long rel_addr,
++                                         unsigned long rel_size)
++{
++      /* TODO: Might want to support this in order to get faster
++       * startup times... */
++}
++
++int _dl_parse_relocation_information(struct dyn_elf *rpnt,
++                                   unsigned long rel_addr,
++                                   unsigned long rel_size)
++{
++      return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size,
++                       _dl_do_reloc);
++}
+Index: uClibc-0.9.28/ldso/ldso/avr32/resolve.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/ldso/ldso/avr32/resolve.S    2006-05-05 09:29:25.000000000 +0200
+@@ -0,0 +1,28 @@
++/*
++ * Linux dynamic resolving code for AVR32. Fixes up the GOT entry as
++ * indicated in register r12 and jumps to the resolved address.
++ *
++ * This file is subject to the terms and conditions of the GNU Lesser General
++ * Public License.  See the file "COPYING.LIB" in the main directory of this
++ * archive for more details.
++ *
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define ip r5
++
++      .text
++      .global _dl_linux_resolve
++      .type   _dl_linux_resolve,@function
++_dl_linux_resolve:
++      /* The PLT code pushed r8 for us. It contains the address of this
++         function's GOT entry, that is entry 0. ip contains the address
++         of the GOT entry of the function we wanted to call. */
++      stm     --sp, r9-r12, lr
++      mov     r11, r8
++      sub     r12, ip, r8
++      rcall   _dl_linux_resolver
++      mov     ip, r12
++      popm    r8-r12,lr
++      mov     pc, ip
++      .size   _dl_linux_resolve, . - _dl_linux_resolve
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/ldso-avr32-needs-CONSTANT_STRING_GOT_FIXUP.patch b/packages/uclibc/uclibc-0.9.28/avr32/ldso-avr32-needs-CONSTANT_STRING_GOT_FIXUP.patch
new file mode 100644 (file)
index 0000000..222749f
--- /dev/null
@@ -0,0 +1,23 @@
+Subject: [PATCH] ldso: AVR32 needs CONSTANT_STRING_GOT_FIXUP
+
+Add AVR32 to the list of architectures needing CONSTANT_STRING_GOT_FIXUP.
+
+---
+
+ ldso/include/dl-string.h |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+Index: uClibc-0.9.28/ldso/include/dl-string.h
+===================================================================
+--- uClibc-0.9.28.orig/ldso/include/dl-string.h        2006-02-07 16:58:58.000000000 +0100
++++ uClibc-0.9.28/ldso/include/dl-string.h     2006-02-07 16:59:28.000000000 +0100
+@@ -271,7 +271,8 @@ static __always_inline char * _dl_simple
+ /* On some arches constant strings are referenced through the GOT.
+  * This requires that load_addr must already be defined... */
+ #if defined(mc68000) || defined(__arm__) || defined(__mips__) \
+-                     || defined(__sh__) ||  defined(__powerpc__)
++                     || defined(__sh__) ||  defined(__powerpc__) \
++                   || defined(__avr32__)
+ # define CONSTANT_STRING_GOT_FIXUP(X) \
+       if ((X) < (const char *) load_addr) (X) += load_addr
+ # define NO_EARLY_SEND_STDERR
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/ldso-avr32-startup-hack.patch b/packages/uclibc/uclibc-0.9.28/avr32/ldso-avr32-startup-hack.patch
new file mode 100644 (file)
index 0000000..0cdc2cc
--- /dev/null
@@ -0,0 +1,40 @@
+Subject: [PATCH] ldso: AVR32 startup hack
+
+AVR32 needs to do both PERFORM_BOOTSTRAP_GOT and a full relocation of
+the GOT. I don't quite remember why, but I think it's because some GOT
+entries just need the load address added to them, while the rest need
+the full relocation code.
+
+This patch should be revisited to figure out whether we're processing
+relocations against undefined symbols and whether that's something we
+should be doing...
+
+---
+
+ ldso/ldso/dl-startup.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+Index: uClibc-0.9.28/ldso/ldso/dl-startup.c
+===================================================================
+--- uClibc-0.9.28.orig/ldso/ldso/dl-startup.c  2006-02-07 16:49:27.000000000 +0100
++++ uClibc-0.9.28/ldso/ldso/dl-startup.c       2006-02-07 17:12:09.000000000 +0100
+@@ -217,7 +217,9 @@ static void * __attribute_used__ _dl_sta
+       /* some arches (like MIPS) we have to tweak the GOT before relocations */
+       PERFORM_BOOTSTRAP_GOT(tpnt);
+-#else
++#endif
++
++#if !defined(PERFORM_BOOTSTRAP_GOT) || defined(__avr32__)
+       /* OK, now do the relocations.  We do not do a lazy binding here, so
+          that once we are done, we have considerably more flexibility. */
+@@ -259,7 +261,7 @@ static void * __attribute_used__ _dl_sta
+                               rel_addr += relative_count * sizeof(ELF_RELOC);;
+                       }
+-                      rpnt = (ELF_RELOC *) (rel_addr + load_addr);
++                      rpnt = (ELF_RELOC *) (rel_addr /* + load_addr */);
+                       for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
+                               reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset);
+                               symtab_index = ELF_R_SYM(rpnt->r_info);
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/ldso-define-MAP_FAILED.patch b/packages/uclibc/uclibc-0.9.28/avr32/ldso-define-MAP_FAILED.patch
new file mode 100644 (file)
index 0000000..d2838ef
--- /dev/null
@@ -0,0 +1,23 @@
+Subject: [PATCH] ldso: Define MAP_FAILED for _dl_mmap()
+
+When using mmap2() to emulate mmap(), _dl_mmap() uses MAP_FAILED to
+indicate failure. MAP_FAILED is not defined anywhere, so this patch
+defines it.
+
+---
+
+ ldso/include/dl-syscall.h |    1 +
+ 1 file changed, 1 insertion(+)
+
+Index: uClibc-0.9.28/ldso/include/dl-syscall.h
+===================================================================
+--- uClibc-0.9.28.orig/ldso/include/dl-syscall.h       2006-02-07 16:49:27.000000000 +0100
++++ uClibc-0.9.28/ldso/include/dl-syscall.h    2006-02-07 17:07:06.000000000 +0100
+@@ -132,6 +132,7 @@ static inline _syscall6(__ptr_t, __sysca
+               size_t, len, int, prot, int, flags, int, fd, off_t, offset);
+ /*always 12, even on architectures where PAGE_SHIFT != 12 */
+ #define MMAP2_PAGE_SHIFT 12
++#define MAP_FAILED ((void *) -1)
+ static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+               int flags, int fd, unsigned long offset)
+ {
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/let-optimized-stringops-override-default-ones.patch b/packages/uclibc/uclibc-0.9.28/avr32/let-optimized-stringops-override-default-ones.patch
new file mode 100644 (file)
index 0000000..a383a6e
--- /dev/null
@@ -0,0 +1,28 @@
+From 7b2f125425cf777e7937b533217588e27952b87d Mon Sep 17 00:00:00 2001
+From: Haavard Skinnemoen <hskinnemoen@atmel.com>
+Date: Mon, 7 Aug 2006 11:12:50 +0200
+Subject: [PATCH] Let optimized stringops override default ones
+
+The default, slow stringops must be archived _before_ the optimized
+stringops if there is to be any point doing the optimizations in the
+first place.
+---
+ libc/Makefile |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/libc/Makefile b/libc/Makefile
+index 31e4bab..687eac5 100644
+--- a/libc/Makefile
++++ b/libc/Makefile
+@@ -59,7 +59,7 @@ # will evaluate to no files :(.
+       $(AR) dN 2 $(LIBNAME) $$objs && \
+       $(AR) dN 2 $(LIBNAME) $$objs
+       @for objfile in obj.signal \
+-                      obj.string.generic obj.string.$(TARGET_ARCH) obj.string \
++                      obj.string obj.string.generic obj.string.$(TARGET_ARCH) \
+                       obj.sysdeps.common obj.sysdeps.$(TARGET_ARCH) ; do \
+               if [ -e $$objfile ] ; then \
+                       if [ "$(MAKE_IS_SILENT)" = "n" ] ; then \
+-- 
+1.4.1.1
+
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/libpthread-avr32.patch b/packages/uclibc/uclibc-0.9.28/avr32/libpthread-avr32.patch
new file mode 100644 (file)
index 0000000..5277677
--- /dev/null
@@ -0,0 +1,105 @@
+Subject: [PATCH] libpthread: AVR32 support
+
+Implement pt-machine.h for AVR32.
+---
+
+ libpthread/linuxthreads/sysdeps/avr32/pt-machine.h |   92 +++++++++++++++++++++
+ 1 file changed, 92 insertions(+)
+
+Index: uClibc-0.9.28/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h   2006-02-07 17:14:47.000000000 +0100
+@@ -0,0 +1,92 @@
++/* Machine-dependent pthreads configuration and inline functions.
++
++   Copyright (C) 2005 Atmel Norway
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public License as
++   published by the Free Software Foundation; either version 2.1 of the
++   License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; see the file COPYING.LIB.  If not,
++   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++   Boston, MA 02111-1307, USA.  */
++
++#ifndef _PT_MACHINE_H
++#define _PT_MACHINE_H   1
++
++#include <features.h>
++
++static inline int
++_test_and_set (int *p, int v) __THROW
++{
++      int result;
++
++      __asm__ __volatile__(
++              "/* Inline test and set */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %2\n"
++              "       tst     %0, %3\n"
++              "       breq    2f\n"
++              "       stcond  %1, %3\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=m"(*p)
++              : "m"(*p), "r"(v)
++              : "memory", "cc");
++
++      return result;
++}
++
++#ifndef PT_EI
++# define PT_EI extern inline
++#endif
++
++extern long int testandset (int *spinlock);
++extern int __compare_and_swap (long int *p, long int oldval, long int newval);
++
++/* Spinlock implementation; required.  */
++PT_EI long int
++testandset (int *spinlock)
++{
++      return _test_and_set(spinlock, 1);
++}
++
++
++/* Get some notion of the current stack.  Need not be exactly the top
++   of the stack, just something somewhere in the current frame.  */
++#define CURRENT_STACK_FRAME  stack_pointer
++register char * stack_pointer __asm__ ("sp");
++
++/* Compare-and-swap for semaphores. */
++
++#define HAS_COMPARE_AND_SWAP
++PT_EI int
++__compare_and_swap(long int *p, long int oldval, long int newval)
++{
++      long int result, tmp;
++
++      __asm__ __volatile__(
++              "/* Inline compare and swap */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %1, %3\n"
++              "       cp.w    %1, %5\n"
++              "       sreq    %0\n"
++              "       brne    2f\n"
++              "       stcond  %2, %4\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=&r"(tmp), "=m"(*p)
++              : "m"(*p), "r"(newval), "r"(oldval)
++              : "cc", "memory");
++
++      return result;
++}
++
++#endif /* pt-machine.h */
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/no-create_module-on-avr32.patch b/packages/uclibc/uclibc-0.9.28/avr32/no-create_module-on-avr32.patch
new file mode 100644 (file)
index 0000000..9bfdc53
--- /dev/null
@@ -0,0 +1,27 @@
+Subject: [PATCH] Don't include create_module() for AVR32
+
+The create_module() system call is obsolete in Linux 2.6, so the
+AVR32 kernel doesn't even have it.
+
+Come to think about it, this should be completely unnecessary as the
+create_module function is only a stub when __NR_create_module is
+undefined.
+---
+
+ libc/sysdeps/linux/common/create_module.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+Index: uClibc-0.9.28/libc/sysdeps/linux/common/create_module.c
+===================================================================
+--- uClibc-0.9.28.orig/libc/sysdeps/linux/common/create_module.c       2006-02-07 16:48:38.000000000 +0100
++++ uClibc-0.9.28/libc/sysdeps/linux/common/create_module.c    2006-02-07 17:17:14.000000000 +0100
+@@ -61,7 +61,8 @@ unsigned long create_module(const char *
+ {
+   return __create_module(name, size, 0, 0);
+ }
+-#else
++/* create_module is obsolete in Linux 2.6, so AVR32 doesn't have it */
++#elif !defined(__avr32__)
+ /* Sparc, MIPS, etc don't mistake return values for errors. */ 
+ _syscall2(unsigned long, create_module, const char *, name, size_t, size);
+ #endif
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/remove-bogus-version-hack-and-just-use-asm-generic-if-it-exists.patch b/packages/uclibc/uclibc-0.9.28/avr32/remove-bogus-version-hack-and-just-use-asm-generic-if-it-exists.patch
new file mode 100644 (file)
index 0000000..9f27f68
--- /dev/null
@@ -0,0 +1,48 @@
+--- a/extra/scripts/fix_includes.sh    2005-08-18 00:49:41.000000000 +0200
++++ b/extra/scripts/fix_includes.sh    2006-09-27 13:23:12.000000000 +0200
+@@ -78,36 +78,6 @@ if [ ! -d "$KERNEL_SOURCE" ]; then
+     exit 1;
+ fi;
+-if [ -f "$KERNEL_SOURCE/Makefile" ] ; then
+-# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
+-eval `sed -n -e 's/^\([A-Z]*\) = \([0-9]*\)$/\1=\2/p' -e 's/^\([A-Z]*\) = \(-[-a-z0-9]*\)$/\1=\2/p' $KERNEL_SOURCE/Makefile`
+-else
+-ver=`grep UTS_RELEASE $KERNEL_SOURCE/include/linux/version.h | cut -d '"' -f 2`
+-VERSION=`echo "$ver" | cut -d '.' -f 1`
+-PATCHLEVEL=`echo "$ver" | cut -d '.' -f 2`
+-if echo "$ver" | grep -q '-' ; then
+-SUBLEVEL=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.//" | cut -d '-' -f 1`
+-EXTRAVERSION=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}-//"`
+-else
+-SUBLEVEL=`echo "$ver" | cut -d '.' -f 3`
+-#EXTRAVERSION=
+-fi
+-fi
+-if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ]
+-then
+-    echo "Unable to determine version for kernel headers"
+-    echo -e "\tprovided in directory $KERNEL_SOURCE"
+-    exit 1
+-fi
+-
+-if [ "$MAKE_IS_SILENT" != "y" ]; then
+-echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION}"
+-echo -e "\n"
+-echo "Using kernel headers from $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} for architecture '$TARGET_ARCH'"
+-echo -e "\tprovided in directory $KERNEL_SOURCE"
+-echo -e "\n"
+-fi
+-
+ # Create a symlink to include/asm
+ rm -f include/asm*
+@@ -172,7 +142,7 @@ fi;
+ # Annoyingly, 2.6.x kernel headers also need an include/asm-generic/ directory
+-if [ $VERSION -eq 2 ] && [ $PATCHLEVEL -ge 6 ] ; then
++if [ -d $KERNEL_SOURCE/include/asm-generic ] ; then
+     ln -fs $KERNEL_SOURCE/include/asm-generic include/asm-generic
+ fi;
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/sync-fcntl-h-with-linux-kernel.patch b/packages/uclibc/uclibc-0.9.28/avr32/sync-fcntl-h-with-linux-kernel.patch
new file mode 100644 (file)
index 0000000..ae6de2b
--- /dev/null
@@ -0,0 +1,54 @@
+---
+ libc/sysdeps/linux/avr32/bits/fcntl.h |   33 +++++++++++++++++----------------
+ 1 file changed, 17 insertions(+), 16 deletions(-)
+
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/fcntl.h
+===================================================================
+--- uClibc-0.9.28-avr32.orig/libc/sysdeps/linux/avr32/bits/fcntl.h     2006-11-23 17:38:30.000000000 +0100
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/fcntl.h  2006-11-23 17:52:15.000000000 +0100
+@@ -11,28 +11,29 @@
+ /* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+    located on an ext2 file system */
+-#define O_ACCMODE       0003
+-#define O_RDONLY          00
+-#define O_WRONLY          01
+-#define O_RDWR                    02
+-#define O_CREAT                 0100  /* not fcntl */
+-#define O_EXCL                  0200  /* not fcntl */
+-#define O_NOCTTY        0400  /* not fcntl */
+-#define O_TRUNC                01000  /* not fcntl */
+-#define O_APPEND       02000
+-#define O_NONBLOCK     04000
++#define O_ACCMODE     00000003
++#define O_RDONLY      00000000
++#define O_WRONLY      00000001
++#define O_RDWR                00000002
++#define O_CREAT               00000100        /* not fcntl */
++#define O_EXCL                00000200        /* not fcntl */
++#define O_NOCTTY      00000400        /* not fcntl */
++#define O_TRUNC               00001000        /* not fcntl */
++#define O_APPEND      00002000
++#define O_NONBLOCK    00004000
+ #define O_NDELAY      O_NONBLOCK
+-#define O_SYNC                010000
+-#define O_ASYNC               020000
++#define O_SYNC                00010000
++#define O_ASYNC               00020000
+ #ifdef __USE_GNU
+-# define O_DIRECTORY  040000  /* must be a directory */
+-# define O_NOFOLLOW   0100000 /* don't follow links */
+-# define O_DIRECT     0200000 /* direct disk access */
++# define O_DIRECT     00040000        /* must be a directory */
++# define O_DIRECTORY  00200000        /* direct disk access */
++# define O_NOFOLLOW   00400000        /* don't follow links */
++# define O_NOATIME    01000000        /* don't set atime */
+ #endif
+ #ifdef __USE_LARGEFILE64
+-# define O_LARGEFILE  0400000
++# define O_LARGEFILE  00100000
+ #endif
+ /* For now Linux has synchronisity options for data and read operations.
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/uClibc-0.9.28-avr32-20060621.patch b/packages/uclibc/uclibc-0.9.28/avr32/uClibc-0.9.28-avr32-20060621.patch
new file mode 100644 (file)
index 0000000..430b54c
--- /dev/null
@@ -0,0 +1,4322 @@
+diff -Nur uClibc-0.9.28/extra/Configs/Config.avr32 uClibc-0.9.28-avr32-20060621/extra/Configs/Config.avr32
+--- uClibc-0.9.28/extra/Configs/Config.avr32   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/extra/Configs/Config.avr32    2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,38 @@
++#
++# For a description of the syntax of this configuration file,
++# see extra/config/Kconfig-language.txt
++#
++
++config HAVE_ELF
++      bool
++      default y
++
++config TARGET_ARCH
++      default "avr32"
++
++config ARCH_CFLAGS
++      string
++
++config ARCH_LDFLAGS
++      string
++
++config LIBGCC_CFLAGS
++      string
++
++config ARCH_SUPPORTS_BIG_ENDIAN
++      bool
++      default y
++
++config UCLIBC_COMPLETELY_PIC
++      select FORCE_SHAREABLE_TEXT_SEGMENTS
++      bool
++      default y
++
++choice
++      prompt "Target CPU Type"
++      default CONFIG_AP7000
++
++config CONFIG_AP7000
++      bool "AP7000"
++
++endchoice
+diff -Nur uClibc-0.9.28/extra/Configs/Config.in uClibc-0.9.28-avr32-20060621/extra/Configs/Config.in
+--- uClibc-0.9.28/extra/Configs/Config.in      2005-08-18 00:49:41.000000000 +0200
++++ uClibc-0.9.28-avr32-20060621/extra/Configs/Config.in       2006-06-21 11:35:56.000000000 +0200
+@@ -16,6 +16,9 @@
+ config TARGET_arm
+       bool "arm"
++config TARGET_avr32
++      bool "avr32"
++
+ config TARGET_bfin
+       bool "bfin"
+@@ -83,6 +86,10 @@
+ source "extra/Configs/Config.arm"
+ endif
++if TARGET_avr32
++source "extra/Configs/Config.avr32"
++endif
++
+ if TARGET_bfin
+ source "extra/Configs/Config.bfin"
+ endif
+diff -Nur uClibc-0.9.28/include/elf.h uClibc-0.9.28-avr32-20060621/include/elf.h
+--- uClibc-0.9.28/include/elf.h        2005-08-18 00:49:41.000000000 +0200
++++ uClibc-0.9.28-avr32-20060621/include/elf.h 2006-06-21 11:35:56.000000000 +0200
+@@ -261,6 +261,8 @@
+ #define EM_NIOS32     0xfebb          /* Altera Nios 32 */
+ #define EM_ALTERA_NIOS2  0x9ee5       /* Altera Nios II */
++#define EM_AVR32      0x18ad
++
+ /* V850 backend magic number.  Written in the absense of an ABI.  */
+ #define EM_CYGNUS_V850 0x9080
+@@ -2687,6 +2689,55 @@
+ /* Keep this the last entry.  */
+ #define R_V850_NUM            25
++/* Atmel AVR32 relocations.  */
++#define R_AVR32_NONE          0
++#define R_AVR32_32            1
++#define R_AVR32_16            2
++#define R_AVR32_8             3
++#define R_AVR32_32_PCREL      4
++#define R_AVR32_16_PCREL      5
++#define R_AVR32_8_PCREL               6
++#define R_AVR32_DIFF32                7
++#define R_AVR32_DIFF16                8
++#define R_AVR32_DIFF8         9
++#define R_AVR32_GOT32         10
++#define R_AVR32_GOT16         11
++#define R_AVR32_GOT8          12
++#define R_AVR32_21S           13
++#define R_AVR32_16U           14
++#define R_AVR32_16S           15
++#define R_AVR32_8S            16
++#define R_AVR32_8S_EXT                17
++#define R_AVR32_22H_PCREL     18
++#define R_AVR32_18W_PCREL     19
++#define R_AVR32_16B_PCREL     20
++#define R_AVR32_16N_PCREL     21
++#define R_AVR32_14UW_PCREL    22
++#define R_AVR32_11H_PCREL     23
++#define R_AVR32_10UW_PCREL    24
++#define R_AVR32_9H_PCREL      25
++#define R_AVR32_9UW_PCREL     26
++#define R_AVR32_HI16          27
++#define R_AVR32_LO16          28
++#define R_AVR32_GOTPC         29
++#define R_AVR32_GOTCALL               30
++#define R_AVR32_LDA_GOT               31
++#define R_AVR32_GOT21S                32
++#define R_AVR32_GOT18SW               33
++#define R_AVR32_GOT16S                34
++#define R_AVR32_GOT7UW                35
++#define R_AVR32_32_CPENT      36
++#define R_AVR32_CPCALL                37
++#define R_AVR32_16_CP         38
++#define R_AVR32_9W_CP         39
++#define R_AVR32_RELATIVE      40
++#define R_AVR32_GLOB_DAT      41
++#define R_AVR32_JMP_SLOT      42
++#define R_AVR32_ALIGN         43
++#define R_AVR32_NUM           44
++
++/* AVR32 dynamic tags */
++#define DT_AVR32_GOTSZ                0x70000001 /* Total size of GOT in bytes */
+ #define R_H8_NONE       0
+ #define R_H8_DIR32      1
+diff -Nur uClibc-0.9.28/ldso/include/dl-string.h uClibc-0.9.28-avr32-20060621/ldso/include/dl-string.h
+--- uClibc-0.9.28/ldso/include/dl-string.h     2005-08-18 00:49:41.000000000 +0200
++++ uClibc-0.9.28-avr32-20060621/ldso/include/dl-string.h      2006-06-21 11:35:57.000000000 +0200
+@@ -134,7 +134,7 @@
+     } while (1);
+ }
+-static inline void * _dl_memcpy(void * dst, const void * src, size_t len)
++static __always_inline void * _dl_memcpy(void * dst, const void * src, size_t len)
+ {
+       register char *a = dst-1;
+       register const char *b = src-1;
+@@ -271,7 +271,8 @@
+ /* On some arches constant strings are referenced through the GOT.
+  * This requires that load_addr must already be defined... */
+ #if defined(mc68000) || defined(__arm__) || defined(__mips__) \
+-                     || defined(__sh__) ||  defined(__powerpc__)
++                     || defined(__sh__) ||  defined(__powerpc__) \
++                   || defined(__avr32__)
+ # define CONSTANT_STRING_GOT_FIXUP(X) \
+       if ((X) < (const char *) load_addr) (X) += load_addr
+ # define NO_EARLY_SEND_STDERR
+diff -Nur uClibc-0.9.28/ldso/include/dl-syscall.h uClibc-0.9.28-avr32-20060621/ldso/include/dl-syscall.h
+--- uClibc-0.9.28/ldso/include/dl-syscall.h    2005-08-18 00:49:41.000000000 +0200
++++ uClibc-0.9.28-avr32-20060621/ldso/include/dl-syscall.h     2006-06-21 11:35:57.000000000 +0200
+@@ -60,59 +60,59 @@
+    dynamic linking at all, so we cannot return any error codes.
+    We just punt if there is an error. */
+ #define __NR__dl_exit __NR_exit
+-static inline _syscall1(void, _dl_exit, int, status);
++static __always_inline _syscall1(void, _dl_exit, int, status);
+ #define __NR__dl_close __NR_close
+-static inline _syscall1(int, _dl_close, int, fd);
++static __always_inline _syscall1(int, _dl_close, int, fd);
+ #define __NR__dl_open __NR_open
+-static inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode);
++static __always_inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode);
+ #define __NR__dl_write __NR_write
+-static inline _syscall3(unsigned long, _dl_write, int, fd,
++static __always_inline _syscall3(unsigned long, _dl_write, int, fd,
+           const void *, buf, unsigned long, count);
+ #define __NR__dl_read __NR_read
+-static inline _syscall3(unsigned long, _dl_read, int, fd,
++static __always_inline _syscall3(unsigned long, _dl_read, int, fd,
+           const void *, buf, unsigned long, count);
+ #define __NR__dl_mprotect __NR_mprotect
+-static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot);
++static __always_inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot);
+ #define __NR__dl_stat __NR_stat
+-static inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
++static __always_inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
+ #define __NR__dl_munmap __NR_munmap
+-static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
++static __always_inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
+ #define __NR__dl_getuid __NR_getuid
+-static inline _syscall0(uid_t, _dl_getuid);
++static __always_inline _syscall0(uid_t, _dl_getuid);
+ #define __NR__dl_geteuid __NR_geteuid
+-static inline _syscall0(uid_t, _dl_geteuid);
++static __always_inline _syscall0(uid_t, _dl_geteuid);
+ #define __NR__dl_getgid __NR_getgid
+-static inline _syscall0(gid_t, _dl_getgid);
++static __always_inline _syscall0(gid_t, _dl_getgid);
+ #define __NR__dl_getegid __NR_getegid
+-static inline _syscall0(gid_t, _dl_getegid);
++static __always_inline _syscall0(gid_t, _dl_getegid);
+ #define __NR__dl_getpid __NR_getpid
+-static inline _syscall0(gid_t, _dl_getpid);
++static __always_inline _syscall0(gid_t, _dl_getpid);
+ #define __NR__dl_readlink __NR_readlink
+-static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
++static __always_inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
+ #ifdef __NR_mmap
+ #ifdef MMAP_HAS_6_ARGS
+ #define __NR__dl_mmap __NR_mmap
+-static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
++static __always_inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
+               int, prot, int, flags, int, fd, off_t, offset);
+ #else
+ #define __NR__dl_mmap_real __NR_mmap
+-static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
++static __always_inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
+-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
++static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+               int flags, int fd, unsigned long offset)
+ {
+       unsigned long buffer[6];
+@@ -128,11 +128,12 @@
+ #endif
+ #elif defined __NR_mmap2
+ #define __NR___syscall_mmap2       __NR_mmap2
+-static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
++static __always_inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
+               size_t, len, int, prot, int, flags, int, fd, off_t, offset);
+ /*always 12, even on architectures where PAGE_SHIFT != 12 */
+ #define MMAP2_PAGE_SHIFT 12
+-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
++#define MAP_FAILED ((void *) -1)
++static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+               int flags, int fd, unsigned long offset)
+ {
+     if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
+diff -Nur uClibc-0.9.28/ldso/ldso/avr32/dl-debug.h uClibc-0.9.28-avr32-20060621/ldso/ldso/avr32/dl-debug.h
+--- uClibc-0.9.28/ldso/ldso/avr32/dl-debug.h   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/ldso/ldso/avr32/dl-debug.h    2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,45 @@
++/*
++ * AVR32 ELF shared libary loader support
++ *
++ * Copyright (C) 2005 Atmel Norway
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. The name of the above contributors may not be
++ *    used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++static const char *_dl_reltypes_tab[] = {
++    "R_AVR32_NONE",
++    "R_AVR32_32", "R_AVR32_16", "R_AVR32_8",
++    "R_AVR32_32_PCREL", "R_AVR32_16_PCREL", "R_AVR32_8_PCREL",
++    "R_AVR32_DIFF32", "R_AVR32_DIFF16", "R_AVR32_DIFF8",
++    "R_AVR32_GOT32", "R_AVR32_GOT16", "R_AVR32_GOT8",
++    "R_AVR32_21S", "R_AVR32_16U", "R_AVR32_16S", "R_AVR32_8S", "R_AVR32_8S_EXT",
++    "R_AVR32_22H_PCREL", "R_AVR32_18W_PCREL", "R_AVR32_16B_PCREL",
++    "R_AVR32_16N_PCREL", "R_AVR32_14UW_PCREL", "R_AVR32_11H_PCREL",
++    "R_AVR32_10UW_PCREL", "R_AVR32_9H_PCREL", "R_AVR32_9UW_PCREL",
++    "R_AVR32_HI16", "R_AVR32_LO16",
++    "R_AVR32_GOTPC", "R_AVR32_GOTCALL", "R_AVR32_LDA_GOT",
++    "R_AVR32_GOT21S", "R_AVR32_GOT18SW", "R_AVR32_GOT16S", "R_AVR32_GOT7UW",
++    "R_AVR32_32_CPENT", "R_AVR32_CPCALL", "R_AVR32_16_CP", "R_AVR32_9W_CP",
++    "R_AVR32_RELATIVE", "R_AVR32_GLOB_DAT", "R_AVR32_JMP_SLOT",
++    "R_AVR32_ALIGN",
++};
+diff -Nur uClibc-0.9.28/ldso/ldso/avr32/dl-startup.h uClibc-0.9.28-avr32-20060621/ldso/ldso/avr32/dl-startup.h
+--- uClibc-0.9.28/ldso/ldso/avr32/dl-startup.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/ldso/ldso/avr32/dl-startup.h  2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,110 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Architecture specific code used by dl-startup.c
++ * Copyright (C) 2005 Atmel Norway
++ */
++
++/* This is the library loader's main entry point. Let _dl_boot2 do its
++ * initializations and jump to the application's entry point
++ * afterwards. */
++asm(  "       .text\n"
++      "       .global _start\n"
++      "       .type   _start,@function\n"
++      "_start:\n"
++      /* All arguments are on the stack initially */
++      "       mov     r12, sp\n"
++      "       rcall   _dl_start\n"
++      /* Returns user entry point in r12. Save it. */
++      "       mov     r0, r12\n"
++      /* We're PIC, so get the Global Offset Table */
++      "       lddpc   r6, .L_GOT\n"
++      ".L_RGOT:\n"
++      "       rsub    r6, pc\n"
++      /* Adjust argc and argv according to _dl_skip_args */
++      "       ld.w    r1, r6[_dl_skip_args@got]\n"
++      "       ld.w    r1, r1[0]\n"
++      "       ld.w    r2, sp++\n"
++      "       sub     r2, r1\n"
++      "       add     sp, sp, r1 << 2\n"
++      "       st.w    --sp, r2\n"
++      /* Load the finalizer function */
++      "       ld.w    r12, r6[_dl_fini@got]\n"
++      /* Jump to the user's entry point */
++      "       mov     pc, r0\n\n"
++
++      "       .align  2\n"
++      ".L_GOT:"
++      "       .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_\n"
++      "       .size   _start, . - _start\n"
++      "       .previous\n");
++
++/* Get a pointer to the argv array.  On many platforms this can be just
++ * the address if the first argument, on other platforms we need to
++ * do something a little more subtle here. */
++#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *)ARGS + 1)
++
++
++/* We can't call functions before the GOT has been initialized */
++#define NO_FUNCS_BEFORE_BOOTSTRAP
++
++/*
++ * Relocate the GOT during dynamic loader bootstrap.  This will add
++ * the load address to all entries in the GOT, which is necessary
++ * because the linker doesn't generate R_AVR32_RELATIVE relocs for the
++ * GOT.
++ */
++static __always_inline
++void PERFORM_BOOTSTRAP_GOT(struct elf_resolve *tpnt)
++{
++      Elf32_Addr i, nr_got;
++      register Elf32_Addr *__r6 __asm__("r6");
++      Elf32_Addr *got = __r6;
++
++      nr_got = tpnt->dynamic_info[DT_AVR32_GOTSZ_IDX] / sizeof(*got);
++      for (i = 2; i < nr_got; i++)
++              got[i] += tpnt->loadaddr;
++}
++
++#define PERFORM_BOOTSTRAP_GOT(tpnt) PERFORM_BOOTSTRAP_GOT(tpnt)
++
++/* Handle relocation of the symbols in the dynamic loader. */
++static __always_inline
++void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
++                           unsigned long symbol_addr,
++                           unsigned long load_addr, Elf32_Sym *symtab)
++{
++      switch(ELF32_R_TYPE(rpnt->r_info)) {
++      case R_AVR32_NONE:
++              break;
++      case R_AVR32_GLOB_DAT:
++      case R_AVR32_JMP_SLOT:
++              *reloc_addr = symbol_addr;
++              break;
++      case R_AVR32_RELATIVE:
++              SEND_STDERR_DEBUG("Applying RELATIVE relocation: ");
++              SEND_ADDRESS_STDERR_DEBUG(load_addr, 0);
++              SEND_STDERR_DEBUG(" + ");
++              SEND_ADDRESS_STDERR_DEBUG(rpnt->r_addend, 1);
++              *reloc_addr = load_addr + rpnt->r_addend;
++              break;
++      default:
++              SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc_type ");
++              SEND_NUMBER_STDERR(ELF32_R_TYPE(rpnt->r_info), 1);
++              SEND_STDERR("REL, SYMBOL, LOAD: ");
++              SEND_ADDRESS_STDERR(reloc_addr, 0);
++              SEND_STDERR(", ");
++              SEND_ADDRESS_STDERR(symbol_addr, 0);
++              SEND_STDERR(", ");
++              SEND_ADDRESS_STDERR(load_addr, 1);
++              _dl_exit(1);
++      }
++}
++
++/* Transfer control to the user's application, once the dynamic loader
++ * is done. This routine has to exit the current function, then call
++ * the _dl_elf_main function.
++ *
++ * Since our _dl_boot will simply call whatever is returned by
++ * _dl_boot2, we can just return the address we're supposed to
++ * call.  */
++#define START()       return _dl_elf_main;
+diff -Nur uClibc-0.9.28/ldso/ldso/avr32/dl-syscalls.h uClibc-0.9.28-avr32-20060621/ldso/ldso/avr32/dl-syscalls.h
+--- uClibc-0.9.28/ldso/ldso/avr32/dl-syscalls.h        1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/ldso/ldso/avr32/dl-syscalls.h 2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,5 @@
++/* We can't use the real errno in ldso, since it has not yet
++ * been dynamicly linked in yet. */
++extern int _dl_errno;
++#define __set_errno(X) {(_dl_errno) = (X);}
++#include "sys/syscall.h"
+diff -Nur uClibc-0.9.28/ldso/ldso/avr32/dl-sysdep.h uClibc-0.9.28-avr32-20060621/ldso/ldso/avr32/dl-sysdep.h
+--- uClibc-0.9.28/ldso/ldso/avr32/dl-sysdep.h  1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/ldso/ldso/avr32/dl-sysdep.h   2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,103 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Various assembly language/system dependent hacks that are required
++ * so that we can minimize the amount of platform specific code.
++ * Copyright (C) 2004-2005 Atmel Norway
++ */
++
++/* Define this if the system uses RELOCA. */
++#define ELF_USES_RELOCA
++
++#include <elf.h>
++
++#define ARCH_NUM 1
++#define DT_AVR32_GOTSZ_IDX    (DT_NUM + OS_NUM)
++
++#define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr)                  \
++      do {                                                            \
++              if (dpnt->d_tag == DT_AVR32_GOTSZ)                      \
++                      dynamic[DT_AVR32_GOTSZ_IDX] = dpnt->d_un.d_val; \
++      } while (0)
++
++/* Initialization sequence for the application/library GOT. */
++#define INIT_GOT(GOT_BASE,MODULE)                                     \
++      do {                                                            \
++              unsigned long i, nr_got;                                \
++                                                                      \
++              GOT_BASE[0] = (unsigned long) _dl_linux_resolve;        \
++              GOT_BASE[1] = (unsigned long) MODULE;                   \
++                                                                      \
++              /* Add load address displacement to all GOT entries */  \
++              nr_got = MODULE->dynamic_info[DT_AVR32_GOTSZ_IDX] / 4;  \
++              for (i = 2; i < nr_got; i++)                            \
++                      GOT_BASE[i] += (unsigned long)MODULE->loadaddr; \
++      } while (0)
++
++#define do_rem(result, n, base)       ((result) = (n) % (base))
++
++/* Here we define the magic numbers that this dynamic loader should accept */
++#define MAGIC1 EM_AVR32
++#undef MAGIC2
++
++/* Used for error messages */
++#define ELF_TARGET "AVR32"
++
++unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got);
++
++/* 4096 bytes alignment */
++#define PAGE_ALIGN 0xfffff000
++#define ADDR_ALIGN 0xfff
++#define OFFS_ALIGN 0x7ffff000
++
++#define elf_machine_type_class(type)                          \
++      ((type == R_AVR32_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)
++
++/* AVR32 doesn't need any COPY relocs */
++#define DL_NO_COPY_RELOCS
++
++/* Return the link-time address of _DYNAMIC.  Conveniently, this is the
++   first element of the GOT.  This must be inlined in a function which
++   uses global data.  */
++static inline Elf32_Addr
++elf_machine_dynamic (void)
++{
++      register Elf32_Addr *got asm ("r6");
++      return *got;
++}
++
++/* Return the run-time load address of the shared object.  */
++static inline Elf32_Addr
++elf_machine_load_address (void)
++{
++      extern void __dl_start asm("_dl_start");
++      Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
++      Elf32_Addr pcrel_addr;
++
++      asm   ("        lddpc   %0, 2f\n"
++             "1:      add     %0, pc\n"
++             "        rjmp    3f\n"
++             "        .align  2\n"
++             "2:      .long   _dl_start - 1b\n"
++             "3:\n"
++             : "=r"(pcrel_addr) : : "cc");
++
++      return pcrel_addr - got_addr;
++}
++
++/*
++ * Perform any RELATIVE relocations specified by DT_RELCOUNT.
++ * Currently, we don't use that tag, but we might in the future as
++ * this would reduce the startup time somewhat (although probably not by much).
++ */
++static inline void
++elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
++                    Elf32_Word relative_count)
++{
++      Elf32_Rela *rpnt = (void *)rel_addr;
++
++      do {
++              Elf32_Addr *reloc_addr;
++              reloc_addr = (void *)(load_off + (rpnt++)->r_offset);
++              *reloc_addr = load_off + rpnt->r_addend;
++      } while (--relative_count);
++}
+diff -Nur uClibc-0.9.28/ldso/ldso/avr32/elfinterp.c uClibc-0.9.28-avr32-20060621/ldso/ldso/avr32/elfinterp.c
+--- uClibc-0.9.28/ldso/ldso/avr32/elfinterp.c  1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/ldso/ldso/avr32/elfinterp.c   2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,191 @@
++/*
++ * AVR32 ELF shared library loader suppport
++ *
++ * Copyright (C) 2004-2006 Atmel Corporation
++ *
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. The name of the above contributors may not be
++ *    used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got)
++{
++      struct elf_resolve *tpnt = (struct elf_resolve *)got[1];
++      Elf32_Sym *sym;
++      unsigned long local_gotno;
++      unsigned long gotsym;
++      unsigned long new_addr;
++      char *strtab, *symname;
++      unsigned long *entry;
++      unsigned long sym_index = got_offset / 4;
++
++#if 0
++      local_gotno = tpnt->dynamic_info[DT_AVR32_LOCAL_GOTNO];
++      gotsym = tpnt->dynamic_info[DT_AVR32_GOTSYM];
++
++      sym = ((Elf32_Sym *)(tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr))
++              + sym_index;
++      strtab = (char *)(tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
++      symname = strtab + sym->st_name;
++
++#if 0
++      new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name,
++                                               tpnt->symbol_scope, tpnt,
++                                               resolver);
++#endif
++
++      entry = (unsigned long *)(got + local_gotno + sym_index - gotsym);
++      *entry = new_addr;
++#endif
++
++      return new_addr;
++}
++
++static int
++_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
++        unsigned long rel_addr, unsigned long rel_size,
++        int (*reloc_func)(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                          Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab))
++{
++      Elf32_Sym *symtab;
++      Elf32_Rela *rpnt;
++      char *strtab;
++      int i;
++
++      rpnt = (Elf32_Rela *)rel_addr;
++      rel_size /= sizeof(Elf32_Rela);
++      symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
++      strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
++
++      for (i = 0; i < rel_size; i++, rpnt++) {
++              int symtab_index, res;
++
++              symtab_index = ELF32_R_SYM(rpnt->r_info);
++
++              debug_sym(symtab, strtab, symtab_index);
++              debug_reloc(symtab, strtab, rpnt);
++
++              res = reloc_func(tpnt, scope, rpnt, symtab, strtab);
++
++              if (res == 0)
++                      continue;
++
++              _dl_dprintf(2, "\n%s: ", _dl_progname);
++
++              if (symtab_index)
++                      _dl_dprintf(2, "symbol '%s': ",
++                                  strtab + symtab[symtab_index].st_name);
++
++              if (res < 0) {
++                      int reloc_type = ELF32_R_TYPE(rpnt->r_info);
++#if defined(__SUPPORT_LD_DEBUG__)
++                      _dl_dprintf(2, "can't handle reloc type %s\n",
++                                  _dl_reltypes(reloc_type));
++#else
++                      _dl_dprintf(2, "can't handle reloc type %x\n",
++                                  reloc_type);
++#endif
++                      _dl_exit(-res);
++              } else {
++                      _dl_dprintf(2, "can't resolve symbol\n");
++                      return res;
++              }
++      }
++
++      return 0;
++}
++
++static int _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                      Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab)
++{
++      int reloc_type;
++      int symtab_index;
++      char *symname;
++      unsigned long *reloc_addr;
++      unsigned long symbol_addr;
++#if defined(__SUPPORT_LD_DEBUG__)
++      unsigned long old_val;
++#endif
++
++      reloc_addr = (unsigned long *)(tpnt->loadaddr + rpnt->r_offset);
++      reloc_type = ELF32_R_TYPE(rpnt->r_info);
++      symtab_index = ELF32_R_SYM(rpnt->r_info);
++      symbol_addr = 0;
++      symname = strtab + symtab[symtab_index].st_name;
++
++      if (symtab_index) {
++              symbol_addr = (unsigned long)
++                      _dl_find_hash(strtab + symtab[symtab_index].st_name,
++                                    tpnt->symbol_scope, tpnt,
++                                    elf_machine_type_class(reloc_type));
++
++              /* Allow undefined references to weak symbols */
++              if (!symbol_addr &&
++                  ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) {
++                      _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
++                                  _dl_progname, symname);
++                      return 0;
++              }
++      }
++
++#if defined(__SUPPORT_LD_DEBUG__)
++      old_val = *reloc_addr;
++#endif
++      switch (reloc_type) {
++      case R_AVR32_NONE:
++              break;
++      case R_AVR32_GLOB_DAT:
++      case R_AVR32_JMP_SLOT:
++              *reloc_addr = symbol_addr + rpnt->r_addend;
++              break;
++      case R_AVR32_RELATIVE:
++              *reloc_addr = (unsigned long)tpnt->loadaddr
++                      + rpnt->r_addend;
++              break;
++      default:
++              return -1;
++      }
++
++#if defined(__SUPPORT_LD_DEBUG__)
++      if (_dl_debug_reloc && _dl_debug_detail)
++              _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
++                          old_val, *reloc_addr);
++#endif
++
++      return 0;
++}
++
++void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
++                                         unsigned long rel_addr,
++                                         unsigned long rel_size)
++{
++      /* TODO: Might want to support this in order to get faster
++       * startup times... */
++}
++
++int _dl_parse_relocation_information(struct dyn_elf *rpnt,
++                                   unsigned long rel_addr,
++                                   unsigned long rel_size)
++{
++      return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size,
++                       _dl_do_reloc);
++}
+diff -Nur uClibc-0.9.28/ldso/ldso/avr32/resolve.S uClibc-0.9.28-avr32-20060621/ldso/ldso/avr32/resolve.S
+--- uClibc-0.9.28/ldso/ldso/avr32/resolve.S    1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/ldso/ldso/avr32/resolve.S     2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,28 @@
++/*
++ * Linux dynamic resolving code for AVR32. Fixes up the GOT entry as
++ * indicated in register r12 and jumps to the resolved address.
++ *
++ * This file is subject to the terms and conditions of the GNU Lesser General
++ * Public License.  See the file "COPYING.LIB" in the main directory of this
++ * archive for more details.
++ *
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define ip r5
++
++      .text
++      .global _dl_linux_resolve
++      .type   _dl_linux_resolve,@function
++_dl_linux_resolve:
++      /* The PLT code pushed r8 for us. It contains the address of this
++         function's GOT entry, that is entry 0. ip contains the address
++         of the GOT entry of the function we wanted to call. */
++      stm     --sp, r9-r12, lr
++      mov     r11, r8
++      sub     r12, ip, r8
++      rcall   _dl_linux_resolver
++      mov     ip, r12
++      popm    r8-r12,lr
++      mov     pc, ip
++      .size   _dl_linux_resolve, . - _dl_linux_resolve
+diff -Nur uClibc-0.9.28/ldso/ldso/dl-startup.c uClibc-0.9.28-avr32-20060621/ldso/ldso/dl-startup.c
+--- uClibc-0.9.28/ldso/ldso/dl-startup.c       2005-08-18 00:49:41.000000000 +0200
++++ uClibc-0.9.28-avr32-20060621/ldso/ldso/dl-startup.c        2006-06-21 11:35:57.000000000 +0200
+@@ -217,7 +217,9 @@
+       /* some arches (like MIPS) we have to tweak the GOT before relocations */
+       PERFORM_BOOTSTRAP_GOT(tpnt);
+-#else
++#endif
++
++#if !defined(PERFORM_BOOTSTRAP_GOT) || defined(__avr32__)
+       /* OK, now do the relocations.  We do not do a lazy binding here, so
+          that once we are done, we have considerably more flexibility. */
+@@ -259,7 +261,7 @@
+                               rel_addr += relative_count * sizeof(ELF_RELOC);;
+                       }
+-                      rpnt = (ELF_RELOC *) (rel_addr + load_addr);
++                      rpnt = (ELF_RELOC *) (rel_addr /* + load_addr */);
+                       for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
+                               reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset);
+                               symtab_index = ELF_R_SYM(rpnt->r_info);
+diff -Nur uClibc-0.9.28/libc/string/avr32/bcopy.S uClibc-0.9.28-avr32-20060621/libc/string/avr32/bcopy.S
+--- uClibc-0.9.28/libc/string/avr32/bcopy.S    1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/bcopy.S     2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,15 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++      .text
++      .global bcopy
++      .type   bcopy, @function
++      .align  1
++bcopy:
++      /* Swap the first two arguments */
++      eor     r11, r12
++      eor     r12, r11
++      eor     r11, r12
++      rjmp    memmove
++      .size   bcopy, . - bcopy
+diff -Nur uClibc-0.9.28/libc/string/avr32/bzero.S uClibc-0.9.28-avr32-20060621/libc/string/avr32/bzero.S
+--- uClibc-0.9.28/libc/string/avr32/bzero.S    1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/bzero.S     2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++      .text
++      .global bzero
++      .type   bzero, @function
++      .align  1
++bzero:
++      mov     r10, r11
++      mov     r11, 0
++      rjmp    memset
+diff -Nur uClibc-0.9.28/libc/string/avr32/Makefile uClibc-0.9.28-avr32-20060621/libc/string/avr32/Makefile
+--- uClibc-0.9.28/libc/string/avr32/Makefile   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/Makefile    2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,45 @@
++# Makefile for uClibc
++#
++# Copyright (C) 2000-2003 Erik Andersen <andersen@uclibc.org>
++#
++# This program is free software; you can redistribute it and/or modify it under
++# the terms of the GNU Library 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 Library General Public License for more
++# details.
++#
++# You should have received a copy of the GNU Library 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
++
++TOPDIR=../../../
++include $(TOPDIR)Rules.mak
++
++SSRC  := bcopy.S bzero.S memcmp.S memcpy.S memmove.S
++SSRC  += memset.S strcmp.S strlen.S
++# memchr.S, strcat.S, strcpy.S, strncpy.S is broken
++SOBJS := $(addprefix __avr32_,$(addsuffix .o,$(basename $(SSRC))))
++
++all: $(SOBJS) $(LIBC)
++
++$(LIBC): ar-target
++
++ar-target: $(SOBJS)
++      $(AR) $(ARFLAGS) $(LIBC) $(SOBJS)
++
++$(SOBJS): __avr32_%.o: %.S
++      $(CC) $(ASFLAGS) -D$*=__avr32_$* -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $@
++
++clean:
++      $(RM) *.[oa] *~ core
++
++stringtest.o: stringtest.c
++      $(CC) $(CFLAGS) -c $< -o $@
++
++stringtest: stringtest.o $(SOBJS)
++      $(CC) -static -o $@ $^
+diff -Nur uClibc-0.9.28/libc/string/avr32/memchr.S uClibc-0.9.28-avr32-20060621/libc/string/avr32/memchr.S
+--- uClibc-0.9.28/libc/string/avr32/memchr.S   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/memchr.S    2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define str r12
++#define chr r11
++#define len r10
++
++      .text
++      .global memchr
++      .type   memchr, @function
++memchr:
++      insert.b chr:l, chr
++      insert.h chr:t, chr
++
++      mov     r9, str
++      andl    r9, 3, COH
++      brne    .Lunaligned_str
++
++1:    sub     len, 4
++      brlt    2f
++      ld.w    r8, str++
++      psub.b  r9, r8, r11
++      tnbz    r9
++      brne    1b
++
++      sub     str, 4
++      extract.b r9, r8:t
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      extract.b r9, r8:u
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      extract.b r9, r8:l
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      retal   str
++
++2:    sub     len, -4
++      reteq   0
++
++3:    ld.ub   r8, str++
++      cp.w    r8, 0
++      reteq   str
++      sub     len, 1
++      brne    3b
++
++      retal   0
++
++.Lunaligned_str:
++1:    sub     len, 1
++      retlt   0
++      ld.ub   r8, str++
++      cp.b    r8, r11
++      reteq   str
++      sub     r9, 1
++      brge    1b
++
++      rjmp    .Laligned_search
+diff -Nur uClibc-0.9.28/libc/string/avr32/memcmp.S uClibc-0.9.28-avr32-20060621/libc/string/avr32/memcmp.S
+--- uClibc-0.9.28/libc/string/avr32/memcmp.S   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/memcmp.S    2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,26 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s1 r12
++#define s2 r11
++#define len r10
++
++      .text
++      .global memcmp
++      .type   memcmp, @function
++      .align  1
++memcmp:
++      cp.w    len, 1
++      retlt   0
++1:    ld.ub   r8, s1++
++      ld.ub   r9, s2++
++      sub     r8, r9
++      subfne  len, 1
++      brne    1b
++
++      retal   r8
++      .size   memcmp, . - memcmp
++
++      .weak   bcmp
++      bcmp = memcmp
+diff -Nur uClibc-0.9.28/libc/string/avr32/memcpy.S uClibc-0.9.28-avr32-20060621/libc/string/avr32/memcpy.S
+--- uClibc-0.9.28/libc/string/avr32/memcpy.S   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/memcpy.S    2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,106 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++/* Don't use r12 as dst since we must return it unmodified */
++#define dst r9
++#define src r11
++#define len r10
++
++      .text
++      .global memcpy
++      .type   memcpy, @function
++memcpy:
++      pref    src[0]
++      mov     dst, r12
++
++      /* If we have less than 32 bytes, don't do anything fancy */
++      cp.w    len, 32
++      brge    .Lmore_than_31
++
++      sub     len, 1
++      retlt   r12
++1:    ld.ub   r8, src++
++      st.b    dst++, r8
++      sub     len, 1
++      brge    1b
++      retal   r12
++
++.Lmore_than_31:
++      pushm   r0-r7, lr
++
++      /* Check alignment */
++      mov     r8, src
++      andl    r8, 31, COH
++      brne    .Lunaligned_src
++      mov     r8, dst
++      andl    r8, 3, COH
++      brne    .Lunaligned_dst
++
++.Laligned_copy:
++      sub     len, 32
++      brlt    .Lless_than_32
++
++1:    /* Copy 32 bytes at a time */
++      pref    src[32]
++      ldm     src, r0-r7
++      sub     src, -32
++      stm     dst, r0-r7
++      sub     dst, -32
++      sub     len, 32
++      brge    1b
++
++.Lless_than_32:
++      /* Copy 16 more bytes if possible */
++      sub     len, -16
++      brlt    .Lless_than_16
++      ldm     src, r0-r3
++      sub     src, -16
++      sub     len, 16
++      stm     dst, r0-r3
++      sub     dst, -16
++
++.Lless_than_16:
++      /* Do the remaining as byte copies */
++      neg     len
++      add     pc, pc, len << 2
++      .rept   15
++      ld.ub   r0, src++
++      st.b    dst++, r0
++      .endr
++
++      popm    r0-r7, pc
++
++.Lunaligned_src:
++      /* Make src cacheline-aligned. r8 = (src & 31) */
++      rsub    r8, r8, 32
++      sub     len, r8
++1:    ld.ub   r0, src++
++      st.b    dst++, r0
++      sub     r8, 1
++      brne    1b
++
++      /* If dst is word-aligned, we're ready to go */
++      pref    src[0]
++      mov     r8, 3
++      tst     dst, r8
++      breq    .Laligned_copy
++
++.Lunaligned_dst:
++      /* src is aligned, but dst is not. Expect bad performance */
++      sub     len, 4
++      brlt    2f
++1:    ld.w    r0, src++
++      st.w    dst++, r0
++      sub     len, 4
++      brge    1b
++
++2:    neg     len
++      add     pc, pc, len << 2
++      .rept   3
++      ld.ub   r0, src++
++      st.b    dst++, r0
++      .endr
++
++      popm    r0-r7, pc
++      .size   memcpy, . - memcpy
+diff -Nur uClibc-0.9.28/libc/string/avr32/memmove.S uClibc-0.9.28-avr32-20060621/libc/string/avr32/memmove.S
+--- uClibc-0.9.28/libc/string/avr32/memmove.S  1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/memmove.S   2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,124 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define dst r12
++#define src r11
++#define len r10
++
++      .text
++      .global memmove
++      .type   memmove, @function
++memmove:
++      cp.w    src, dst
++#ifdef memmove
++      brge    optimized_memcpy
++#else
++      brge    memcpy
++#endif
++
++      add     dst, len
++      add     src, len
++      pref    src[-1]
++
++      /*
++       * The rest is basically the same as in memcpy.S except that
++       * the direction is reversed.
++       */
++      cp.w    len, 32
++      brge    .Lmore_than_31
++
++      sub     len, 1
++      retlt   r12
++1:    ld.ub   r8, --src
++      st.b    --dst, r8
++      sub     len, 1
++      brge    1b
++      retal   r12
++
++.Lmore_than_31:
++      pushm   r0-r7, lr
++
++      /* Check alignment */
++      mov     r8, src
++      andl    r8, 31, COH
++      brne    .Lunaligned_src
++      mov     r8, r12
++      andl    r8, 3, COH
++      brne    .Lunaligned_dst
++
++.Laligned_copy:
++      sub     len, 32
++      brlt    .Lless_than_32
++
++1:    /* Copy 32 bytes at a time */
++      pref    src[-36]
++      sub     src, 32
++      ldm     src, r0-r7
++      sub     dst, 32
++      sub     len, 32
++      stm     dst, r0-r7
++      brge    1b
++
++.Lless_than_32:
++      /* Copy 16 more bytes if possible */
++      sub     len, -16
++      brlt    .Lless_than_16
++      sub     src, 16
++      ldm     src, r0-r3
++      sub     dst, 16
++      sub     len, 16
++      stm     dst, r0-r3
++
++.Lless_than_16:
++      /* Do the remaining as byte copies */
++#if 1
++      sub     len, -16
++      breq    2f
++1:    ld.ub   r0, --src
++      st.b    --dst, r0
++      sub     len, 1
++      brne    1b
++#else
++      neg     len
++      add     pc, pc, len << 2
++      .rept   15
++      ld.ub   r0, --src
++      st.b    --dst, r0
++      .endr
++#endif
++
++2:    popm    r0-r7, pc
++
++.Lunaligned_src:
++      /* Make src cacheline-aligned. r8 = (src & 31) */
++      rsub    r8, r8, 32
++      sub     len, r8
++1:    ld.ub   r0, --src
++      st.b    --dst, r0
++      sub     r8, 1
++      brne    1b
++
++      /* If dst is word-aligned, we're ready to go */
++      pref    src[-4]
++      mov     r8, 3
++      tst     dst, r8
++      breq    .Laligned_copy
++
++.Lunaligned_dst:
++      /* src is aligned, but dst is not. Expect bad performance */
++      sub     len, 4
++      brlt    2f
++1:    ld.w    r0, --src
++      st.w    --dst, r0
++      sub     len, 4
++      brge    1b
++
++2:    neg     len
++      add     pc, pc, len << 2
++      .rept   3
++      ld.ub   r0, --src
++      st.b    --dst, r0
++      .endr
++
++      popm    r0-r7, pc
+diff -Nur uClibc-0.9.28/libc/string/avr32/memset.S uClibc-0.9.28-avr32-20060621/libc/string/avr32/memset.S
+--- uClibc-0.9.28/libc/string/avr32/memset.S   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/memset.S    2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,54 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s r12
++#define c r11
++#define n r10
++
++      .text
++      .global memset
++      .type   memset, @function
++      .align  1
++memset:
++      cp.w    n, 32
++      mov     r9, s
++      brge    .Llarge_memset
++
++      sub     n, 1
++      retlt   s
++1:    st.b    s++, c
++      sub     n, 1
++      brge    1b
++
++      retal   r9
++
++.Llarge_memset:
++      mov     r8, r11
++      mov     r11, 3
++      insert.b r8:l, r8
++      tst     s, r11
++      insert.h r8:t, r8
++      breq    2f
++
++1:    st.b    s++, r8
++      sub     n, 1
++      tst     s, r11
++      brne    1b
++
++2:    mov     r11, r9
++      mov     r9, r8
++      sub     n, 8
++
++3:    st.d    s++, r8
++      sub     n, 8
++      brge    3b
++
++      /* If we are done, n == -8 and we'll skip all st.b insns below */
++      neg     n
++      lsl     n, 1
++      add     pc, n
++      .rept   7
++      st.b    s++, r8
++      .endr
++      retal   r11
+diff -Nur uClibc-0.9.28/libc/string/avr32/strcat.S uClibc-0.9.28-avr32-20060621/libc/string/avr32/strcat.S
+--- uClibc-0.9.28/libc/string/avr32/strcat.S   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/strcat.S    2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,96 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define s1 r9
++#define s2 r11
++
++      .text
++      .global strcat
++      .type   strcat, @function
++      .align  1
++strcat:
++      mov     s1, r12
++
++      /* Make sure s1 is word-aligned */
++      mov     r10, s1
++      andl    r10, 3, COH
++      breq    2f
++
++      add     pc, pc, r10 << 3
++      sub     r0, r0, 0       /* 4-byte nop */
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    2f
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    3f
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    4f
++
++      /* Find the end of the first string */
++5:    ld.w    r8, s1++
++      tnbz    r8
++      brne    5b
++
++      sub     s1, 4
++
++      extract.b r10, r8:t
++      cp.w    r10, 0
++      breq    1f
++      sub     s1, -1
++      extract.b r10, r8:u
++      cp.w    r10, 0
++      breq    2f
++      sub     s1, -1
++      extract.b r10, r8:l
++      cp.w    r10, 0
++      breq    3f
++      sub     s1, -1
++      rjmp    4f
++
++      /* Now, append s2 */
++1:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++2:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++3:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++4:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++
++      /* Copy one word at a time */
++      ld.w    r8, s2++
++      tnbz    r8
++      breq    2f
++1:    st.w    r8, s2++
++      ld.w    r8, s2++
++      tnbz    r8
++      brne    1b
++
++      /* Copy the remaining bytes */
++      extract.b r10, r8:t
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      extract.b r10, r8:u
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      extract.b r10, r8:l
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      extract.b r10, r8:b
++      st.b    s1++, r10
++      retal   r12
++      .size   strcat, . - strcat
+diff -Nur uClibc-0.9.28/libc/string/avr32/strcmp.S uClibc-0.9.28-avr32-20060621/libc/string/avr32/strcmp.S
+--- uClibc-0.9.28/libc/string/avr32/strcmp.S   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/strcmp.S    2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s1 r12
++#define s2 r11
++#define len r10
++
++      .text
++      .global strcmp
++      .type   strcmp, @function
++      .align  1
++strcmp:
++      mov     r8, 3
++      tst     s1, r8
++      brne    .Lunaligned_s1
++      tst     s2, r8
++      brne    .Lunaligned_s2
++
++1:    ld.w    r8, s1++
++      ld.w    r9, s2++
++      cp.w    r8, r9
++      brne    2f
++      tnbz    r8
++      brne    1b
++      retal   0
++
++2:    extract.b r12, r8:t
++      extract.b r11, r9:t
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      extract.b r12, r8:u
++      extract.b r11, r9:u
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      extract.b r12, r8:l
++      extract.b r11, r9:l
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      extract.b r12, r8:b
++      extract.b r11, r9:b
++      sub     r12, r11
++      retal   r12
++
++.Lunaligned_s1:
++3:    tst     s1, r8
++      breq    4f
++      ld.ub   r10, s1++
++      ld.ub   r9, s2++
++      sub     r10, r9
++      retne   r10
++      cp.w    r9, 0
++      brne    3b
++      retal   r10
++
++4:    tst     s2, r8
++      breq    1b
++
++.Lunaligned_s2:
++      /*
++       * s1 and s2 can't both be aligned, and unaligned word loads
++       * can trigger spurious exceptions if we cross a page boundary.
++       * Do it the slow way...
++       */
++1:    ld.ub   r8, s1++
++      ld.ub   r9, s2++
++      sub     r8, r9
++      retne   r8
++      cp.w    r9, 0
++      brne    1b
++      retal   0
+diff -Nur uClibc-0.9.28/libc/string/avr32/strcpy.S uClibc-0.9.28-avr32-20060621/libc/string/avr32/strcpy.S
+--- uClibc-0.9.28/libc/string/avr32/strcpy.S   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/strcpy.S    2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,64 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ *
++ * To reduce the size, this one might simply call strncpy with len = -1.
++ */
++
++#define dst r9
++#define src r11
++
++      .text
++      .global strcpy
++      .type   strcpy, @function
++strcpy:
++      mov     dst, r12
++
++      pref    src[0]
++
++      /*
++       * Check alignment. If src is aligned but dst isn't, we can't
++       * do much about it...
++       */
++      mov     r8, src
++      andl    r8, 3 COH
++      brne    .Lunaligned_src
++
++.Laligned_copy:
++1:    ld.w    r8, src++
++      tnbz    r8
++      breq    2f
++      st.w    dst++, r8
++      rjmp    1b
++
++2:    /*
++       * Ok, r8 now contains the terminating '\0'. Copy the
++       * remaining bytes individually.
++       */
++      extract.b r10, r8:t
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      extract.b r10, r8:u
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      extract.b r10, r8:l
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      extract.b r10, r8:b
++      st.b    dst++, r10
++      retal   r12
++
++.Lunaligned_src:
++      /* Copy bytes until we're aligned */
++      rsub    r8, r8, 4
++      add     pc, pc, r8 << 3
++      nop
++      nop
++      ld.ub   r10, src++
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++
++      rjmp    .Laligned_copy
+diff -Nur uClibc-0.9.28/libc/string/avr32/stringtest.c uClibc-0.9.28-avr32-20060621/libc/string/avr32/stringtest.c
+--- uClibc-0.9.28/libc/string/avr32/stringtest.c       1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/stringtest.c        2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,144 @@
++
++#include <stdio.h>
++#include <string.h>
++#include <time.h>
++#include <sys/mman.h>
++
++#define BUF_SIZE (8 * 1024)
++
++static char *buf1;
++static char *buf1_ref;
++static char *buf2;
++
++extern void *optimized_memcpy(void *dest, void *src, size_t len);
++extern void *optimized_memmove(void *dest, void *src, size_t len);
++extern char *optimized_strcpy(char *dest, char *src);
++extern char *optimized_strncpy(char *dest, char *src, size_t len);
++
++void dump_mismatch(char *buf, char *ref, size_t len)
++{
++      int i, j;
++
++      for (i = 0; i < len; i += 16) {
++              if (memcmp(buf + i, ref + i, 16) == 0)
++                      continue;
++
++              printf("%4x buf:", i);
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", buf[j]);
++              printf("\n     ref:");
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", ref[j]);
++              printf("\n");
++      }
++}
++
++static void test_memcpy(int src_offset, int dst_offset, int len)
++{
++      clock_t start, old, new;
++      int i;
++
++      memset(buf1, 0x55, BUF_SIZE);
++      memset(buf1_ref, 0x55, BUF_SIZE);
++      memset(buf2, 0xaa, BUF_SIZE);
++
++      printf("Testing memcpy with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      start = clock();
++      for (i = 0; i < 8192; i++)
++              optimized_memcpy(buf1 + dst_offset, buf2 + src_offset, len);
++      new = clock() - start;
++      start = clock();
++      for ( i = 0; i < 8192; i++)
++              memcpy(buf1_ref + dst_offset, buf2 + src_offset, len);
++      old = clock() - start;
++
++      if (memcmp(buf1, buf1_ref, BUF_SIZE) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, BUF_SIZE);
++      }
++      printf("CPU time used: %d vs. %d\n", new, old);
++}
++
++static void test_memmove(int src_offset, int dst_offset, int len)
++{
++      clock_t start, old, new;
++
++      memset(buf1, 0x55, BUF_SIZE);
++      memset(buf1_ref, 0x55, BUF_SIZE);
++      memset(buf2, 0xaa, BUF_SIZE);
++
++      printf("Testing memmove with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      start = clock();
++      optimized_memmove(buf1 + dst_offset, buf2 + src_offset, len);
++      new = clock() - start;
++      start = clock();
++      memmove(buf1_ref + dst_offset, buf2 + src_offset, len);
++      old = clock() - start;
++
++      if (memcmp(buf1, buf1_ref, BUF_SIZE) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, BUF_SIZE);
++      }
++      printf("CPU time used: %d vs. %d\n", new, old);
++}
++
++int main(int argc, char *argv[])
++{
++      buf2 = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                  MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf2 == MAP_FAILED) {
++              perror("Failed to allocate memory for buf2");
++              return 1;
++      }
++      buf1 = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                  MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf1 == MAP_FAILED) {
++              perror("Failed to allocate memory for buf1");
++              return 1;
++      }
++      buf1_ref = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                      MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf1_ref == MAP_FAILED) {
++              perror("Failed to allocate memory for buf1_ref");
++              return 1;
++      }
++      printf("\n === MEMCPY ===\n\n");
++
++      test_memcpy(0, 0, BUF_SIZE - 32);
++      test_memcpy(0, 0, 1);
++      test_memcpy(0, 0, 31);
++      test_memcpy(0, 0, 32);
++      test_memcpy(0, 0, 127);
++      test_memcpy(0, 0, 128);
++      test_memcpy(4, 4, BUF_SIZE - 32 - 4);
++      test_memcpy(1, 1, BUF_SIZE - 32 - 1);
++      test_memcpy(1, 1, 126);
++      test_memcpy(0, 3, 128);
++      test_memcpy(1, 4, 128);
++      test_memcpy(0, 0, 0);
++
++      printf("\n === MEMMOVE ===\n\n");
++
++      test_memmove(0, 0, BUF_SIZE - 32);
++      test_memmove(0, 0, 1);
++      test_memmove(0, 0, 31);
++      test_memmove(0, 0, 32);
++      test_memmove(0, 0, BUF_SIZE - 33);
++      test_memmove(0, 0, 128);
++      test_memmove(4, 4, BUF_SIZE - 32 - 4);
++      test_memmove(1, 1, BUF_SIZE - 32 - 1);
++      test_memmove(1, 1, BUF_SIZE - 130);
++      test_memmove(0, 3, BUF_SIZE - 128);
++      test_memmove(1, 4, BUF_SIZE - 128);
++      test_memmove(0, 0, 0);
++
++      return 0;
++}
+diff -Nur uClibc-0.9.28/libc/string/avr32/strlen.S uClibc-0.9.28-avr32-20060621/libc/string/avr32/strlen.S
+--- uClibc-0.9.28/libc/string/avr32/strlen.S   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/strlen.S    2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define str r12
++
++      .text
++      .global strlen
++      .type   strlen, @function
++strlen:
++      mov     r11, r12
++
++      mov     r9, str
++      andl    r9, 3, COH
++      brne    .Lunaligned_str
++
++1:    ld.w    r8, str++
++      tnbz    r8
++      brne    1b
++
++      sub     r12, r11
++      extract.b r9, r8:t
++      cp.w    r9, 0
++      subeq   r12, 4
++      reteq   r12
++      extract.b r9, r8:u
++      cp.w    r9, 0
++      subeq   r12, 3
++      reteq   r12
++      extract.b r9, r8:l
++      cp.w    r9, 0
++      subeq   r12, 2
++      reteq   r12
++      sub     r12, 1
++      retal   r12
++
++.Lunaligned_str:
++      add     pc, pc, r9 << 3
++      sub     r0, r0, 0       /* 4-byte nop */
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      breq    1f
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      breq    1f
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      brne    1b
++
++1:    sub     r12, 1
++      sub     r12, r11
++      retal   r12
+diff -Nur uClibc-0.9.28/libc/string/avr32/strncpy.S uClibc-0.9.28-avr32-20060621/libc/string/avr32/strncpy.S
+--- uClibc-0.9.28/libc/string/avr32/strncpy.S  1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/strncpy.S   2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,78 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define dst r9
++#define src r11
++
++      .text
++      .global strcpy
++      .type   strncpy, @function
++strncpy:
++      mov     dst, r12
++
++      pref    src[0]
++      mov     dst, r12
++
++      /*
++       * Check alignment. If src is aligned but dst isn't, we can't
++       * do much about it...
++       */
++      mov     r8, src
++      andl    r8, 3 COH
++      brne    .Lunaligned_src
++
++.Laligned_copy:
++      sub     r10, 4
++      brlt    3f
++1:    ld.w    r8, src++
++      tnbz    r8
++      breq    2f
++      st.w    dst++, r8
++      sub     r10, 4
++      brne    1b
++
++3:    sub     r10, -4
++      reteq   r12
++
++      /* This is safe as long as src is word-aligned and r10 > 0 */
++      ld.w    r8, src++
++
++2:    /*
++       * Ok, r8 now contains the terminating '\0'. Copy the
++       * remaining bytes individually.
++       */
++      extract.b r11, r8:t
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      extract.b r11, r8:u
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      extract.b r11, r8:l
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      extract.b r10, r8:b
++      st.b    dst++, r10
++      retal   r12
++
++.Lunaligned_src:
++      /* Copy bytes until we're aligned */
++      min     r8, r8, r10
++      sub     r10, r8
++      sub     r8, 1
++      retlt   r12
++1:    ld.ub   r10, src++
++      st.b    dst++, r10
++      sub     r8, 1
++      brge    1b
++
++      rjmp    .Laligned_copy
+diff -Nur uClibc-0.9.28/libc/string/avr32/test_memcpy.c uClibc-0.9.28-avr32-20060621/libc/string/avr32/test_memcpy.c
+--- uClibc-0.9.28/libc/string/avr32/test_memcpy.c      1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/string/avr32/test_memcpy.c       2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,66 @@
++
++#include <stdio.h>
++#include <string.h>
++
++#define BUF_SIZE 32768
++
++static char buf1[BUF_SIZE] __attribute__((aligned(32)));
++static char buf1_ref[BUF_SIZE] __attribute__((aligned(32)));
++static char buf2[BUF_SIZE] __attribute__((aligned(32)));
++
++extern void *new_memcpy(void *dest, void *src, size_t len);
++
++void dump_mismatch(char *buf, char *ref, size_t len)
++{
++      int i, j;
++
++      for (i = 0; i < len; i += 16) {
++              if (memcmp(buf + i, ref + i, 16) == 0)
++                      continue;
++
++              printf("% 4x buf:", i);
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", buf[j]);
++              printf("\n     ref:");
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", ref[j]);
++              printf("\n");
++      }
++}
++
++void test(int src_offset, int dst_offset, int len)
++{
++      memset(buf1, 0x55, sizeof(buf1));
++      memset(buf1_ref, 0x55, sizeof(buf1_ref));
++      memset(buf2, 0xaa, sizeof(buf2));
++
++      printf("Testing with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      new_memcpy(buf1 + dst_offset, buf2 + src_offset, len);
++      memcpy(buf1_ref + dst_offset, buf2 + src_offset, len);
++
++      if (memcmp(buf1, buf1_ref, sizeof(buf1)) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, sizeof(buf1));
++      }
++}
++
++int main(int argc, char *argv[])
++{
++      test(0, 0, BUF_SIZE);
++      test(0, 0, 1);
++      test(0, 0, 31);
++      test(0, 0, 32);
++      test(0, 0, 127);
++      test(0, 0, 128);
++      test(4, 4, BUF_SIZE - 4);
++      test(1, 1, BUF_SIZE - 1);
++      test(1, 1, 126);
++      test(0, 3, 128);
++      test(1, 4, 128);
++
++      return 0;
++}
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/atomicity.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/atomicity.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/atomicity.h    1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/atomicity.h     2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,86 @@
++/* Low-level functions for atomic operations.  AVR32 version.
++   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef _ATOMICITY_H
++#define _ATOMICITY_H 1
++
++#include <inttypes.h>
++
++static inline int
++__attribute__((unused))
++exchange_and_add (volatile uint32_t *mem, int val)
++{
++      int tmp, result;
++
++      __asm__ __volatile__(
++              "/* Inline exchange and add */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %3\n"
++              "       add     %1, %0, %4\n"
++              "       stcond  %2, %1\n"
++              "       brne    1b"
++              : "=&r"(result), "=&r"(tmp), "=m"(*mem)
++              : "m"(*mem), "r"(val)
++              : "cc", "memory");
++
++      return result;
++}
++
++static inline void
++__attribute__((unused))
++atomic_add (volatile uin32_t *mem, int val)
++{
++      int result;
++
++      __asm__ __volatile__(
++              "/* Inline atomic add */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %2\n"
++              "       add     %0, %3\n"
++              "       stcond  %2, %0\n"
++              "       brne    1b"
++              : "=&r"(result), "=m"(*mem)
++              : "m"(*mem), "r"(val)
++              : "cc", "memory");
++}
++
++static inline int
++__attribute__((unused))
++compare_and_swap(volatile long int *p, long int oldval, long int newval)
++{
++      long int result, tmp;
++
++      __asm__ __volatile__(
++              "/* Inline compare and swap */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %1, %3\n"
++              "       cp.w    %1, %5\n"
++              "       sreq    %0\n"
++              "       brne    2f\n"
++              "       stcond  %2, %4\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=&r"(tmp), "=m"(*p)
++              : "m"(*p), "r"(newval), "r"(oldval)
++              : "cc", "memory");
++
++      return result;
++}
++
++#endif /* atomicity.h */
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/byteswap.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/byteswap.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/byteswap.h     1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/byteswap.h      2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,80 @@
++/* Macros to swap the order of bytes in integer values.
++   Copyright (C) 2005 Atmel Norway.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
++# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
++#endif
++
++#ifndef _BITS_BYTESWAP_H
++#define _BITS_BYTESWAP_H 1
++
++/* Swap bytes in 16 bit value.  */
++#if defined __GNUC__
++# define __bswap_16(x) (__extension__ __builtin_bswap_16(x))
++#else
++/* This is better than nothing.  */
++static __inline unsigned short int
++__bswap_16 (unsigned short int __bsx)
++{
++      return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));
++}
++#endif
++
++/* Swap bytes in 32 bit value.  */
++#if defined __GNUC__
++# define __bswap_32(x) (__extension__ __builtin_bswap_32(x))
++#else
++static __inline unsigned int
++__bswap_32 (unsigned int __bsx)
++{
++  return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >>  8) |
++        (((__bsx) & 0x0000ff00) <<  8) | (((__bsx) & 0x000000ff) << 24));
++}
++#endif
++
++#if defined __GNUC__
++/* Swap bytes in 64 bit value.  */
++# define __bswap_constant_64(x)                               \
++      ((((x) & 0xff00000000000000ull) >> 56)          \
++       | (((x) & 0x00ff000000000000ull) >> 40)        \
++       | (((x) & 0x0000ff0000000000ull) >> 24)        \
++       | (((x) & 0x000000ff00000000ull) >> 8)         \
++       | (((x) & 0x00000000ff000000ull) << 8)         \
++       | (((x) & 0x0000000000ff0000ull) << 24)        \
++       | (((x) & 0x000000000000ff00ull) << 40)        \
++       | (((x) & 0x00000000000000ffull) << 56))
++
++# define __bswap_64(x)                                                        \
++      (__extension__                                                  \
++       ({                                                             \
++               union {                                                \
++                       __extension__ unsigned long long int __ll;     \
++                       unsigned int __l[2];                           \
++               } __w, __r;                                            \
++               if (__builtin_constant_p(x))                           \
++                       __r.__ll = __bswap_constant_64(x);             \
++               else {                                                 \
++                       __w.__ll = (x);                                \
++                       __r.__l[0] = __bswap_32(__w.__l[1]);           \
++                       __r.__l[1] = __bswap_32(__w.__l[0]);           \
++               }                                                      \
++               __r.__ll;                                              \
++       }))
++#endif
++
++#endif /* _BITS_BYTESWAP_H */
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/endian.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/endian.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/endian.h       1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/endian.h        2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,7 @@
++/* AVR32 is big-endian */
++
++#ifndef _ENDIAN_H
++# error "Never use <bits/endian.h> directly; include <endian.h> instead."
++#endif
++
++#define __BYTE_ORDER __BIG_ENDIAN
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/fcntl.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/fcntl.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/fcntl.h        1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/fcntl.h 2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,167 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ *
++ * This file is part of the Linux kernel
++ */
++#ifndef _FCNTL_H
++# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
++#endif
++
++#include <sys/types.h>
++
++/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
++   located on an ext2 file system */
++#define O_ACCMODE       0003
++#define O_RDONLY          00
++#define O_WRONLY          01
++#define O_RDWR                    02
++#define O_CREAT                 0100  /* not fcntl */
++#define O_EXCL                  0200  /* not fcntl */
++#define O_NOCTTY        0400  /* not fcntl */
++#define O_TRUNC                01000  /* not fcntl */
++#define O_APPEND       02000
++#define O_NONBLOCK     04000
++#define O_NDELAY      O_NONBLOCK
++#define O_SYNC                010000
++#define O_ASYNC               020000
++
++#ifdef __USE_GNU
++# define O_DIRECTORY  040000  /* must be a directory */
++# define O_NOFOLLOW   0100000 /* don't follow links */
++# define O_DIRECT     0200000 /* direct disk access */
++#endif
++
++#ifdef __USE_LARGEFILE64
++# define O_LARGEFILE  0400000
++#endif
++
++/* For now Linux has synchronisity options for data and read operations.
++   We define the symbols here but let them do the same as O_SYNC since
++   this is a superset.        */
++#if defined __USE_POSIX199309 || defined __USE_UNIX98
++# define O_DSYNC      O_SYNC  /* Synchronize data.  */
++# define O_RSYNC      O_SYNC  /* Synchronize read operations.  */
++#endif
++
++#define F_DUPFD               0       /* dup */
++#define F_GETFD               1       /* get close_on_exec */
++#define F_SETFD               2       /* set/clear close_on_exec */
++#define F_GETFL               3       /* get file->f_flags */
++#define F_SETFL               4       /* set file->f_flags */
++
++#ifndef __USE_FILE_OFFSET64
++# define F_GETLK      5
++# define F_SETLK      6
++# define F_SETLKW     7
++#else
++# define F_GETLK      F_GETLK64
++# define F_SETLK      F_SETLK64
++# define F_SETLKW     F_SETLKW64
++#endif
++#define F_GETLK64     12      /*  using 'struct flock64' */
++#define F_SETLK64     13
++#define F_SETLKW64    14
++
++#if defined __USE_BSD || defined __USE_XOPEN2K
++# define F_SETOWN     8       /*  for sockets. */
++# define F_GETOWN     9       /*  for sockets. */
++#endif
++
++#ifdef __USE_GNU
++# define F_SETSIG     10      /*  for sockets. */
++# define F_GETSIG     11      /*  for sockets. */
++#endif
++
++#ifdef __USE_GNU
++# define F_SETLEASE   1024    /* Set a lease.  */
++# define F_GETLEASE   1025    /* Enquire what lease is active.  */
++# define F_NOTIFY     1026    /* Request notfications on a directory.  */
++#endif
++
++/* for F_[GET|SET]FL */
++#define FD_CLOEXEC    1       /* actually anything with low bit set goes */
++
++/* for posix fcntl() and lockf() */
++#define F_RDLCK               0
++#define F_WRLCK               1
++#define F_UNLCK               2
++
++/* for old implementation of bsd flock () */
++#define F_EXLCK               4       /* or 3 */
++#define F_SHLCK               8       /* or 4 */
++
++/* for leases */
++#define F_INPROGRESS  16
++
++#ifdef __USE_BSD
++/* operations for bsd flock(), also used by the kernel implementation */
++# define LOCK_SH      1       /* shared lock */
++# define LOCK_EX      2       /* exclusive lock */
++# define LOCK_NB      4       /* or'd with one of the above to prevent
++                                 blocking */
++# define LOCK_UN      8       /* remove lock */
++#endif
++
++#ifdef __USE_GNU
++# define LOCK_MAND    32      /* This is a mandatory flock */
++# define LOCK_READ    64      /* ... Which allows concurrent
++                                     read operations */
++# define LOCK_WRITE   128     /* ... Which allows concurrent
++                                     write operations */
++# define LOCK_RW      192     /* ... Which allows concurrent
++                                     read & write ops */
++#endif
++
++#ifdef __USE_GNU
++/* Types of directory notifications that may be requested with F_NOTIFY.  */
++# define DN_ACCESS    0x00000001      /* File accessed.  */
++# define DN_MODIFY    0x00000002      /* File modified.  */
++# define DN_CREATE    0x00000004      /* File created.  */
++# define DN_DELETE    0x00000008      /* File removed.  */
++# define DN_RENAME    0x00000010      /* File renamed.  */
++# define DN_ATTRIB    0x00000020      /* File changed attibutes.  */
++# define DN_MULTISHOT 0x80000000      /* Don't remove notifier.  */
++#endif
++
++struct flock {
++      short l_type;
++      short l_whence;
++#ifndef __USE_FILE_OFFSET64
++      __off_t l_start;
++      __off_t l_len;
++#else
++      __off64_t l_start;
++      __off64_t l_len;
++#endif
++      __pid_t l_pid;
++};
++
++#ifdef __USE_LARGEFILE64
++struct flock64 {
++      short  l_type;
++      short  l_whence;
++      __off64_t l_start;
++      __off64_t l_len;
++      __pid_t  l_pid;
++};
++#endif
++
++/* Define some more compatibility macros to be backward compatible with
++ *    BSD systems which did not managed to hide these kernel macros.  */
++#ifdef  __USE_BSD
++# define FAPPEND        O_APPEND
++# define FFSYNC         O_FSYNC
++# define FASYNC         O_ASYNC
++# define FNONBLOCK      O_NONBLOCK
++# define FNDELAY        O_NDELAY
++#endif /* Use BSD.  */
++
++/* Advise to `posix_fadvise'.  */
++#ifdef __USE_XOPEN2K
++# define POSIX_FADV_NORMAL      0 /* No further special treatment.  */
++# define POSIX_FADV_RANDOM      1 /* Expect random page references.  */
++# define POSIX_FADV_SEQUENTIAL  2 /* Expect sequential page references.  */
++# define POSIX_FADV_WILLNEED    3 /* Will need these pages.  */
++# define POSIX_FADV_DONTNEED    4 /* Don't need these pages.  */
++# define POSIX_FADV_NOREUSE     5 /* Data will be accessed once.  */
++#endif
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_stat.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/kernel_stat.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_stat.h  1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/kernel_stat.h   2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,63 @@
++#ifndef _BITS_STAT_STRUCT_H
++#define _BITS_STAT_STRUCT_H
++
++/*
++ * This file provides struct stat, taken from kernel 2.6.4
++ * (include/asm-avr32/stat.h revision 1.1).
++ */
++
++struct kernel_stat {
++        unsigned long st_dev;
++        unsigned long st_ino;
++        unsigned short st_mode;
++        unsigned short st_nlink;
++        unsigned short st_uid;
++        unsigned short st_gid;
++        unsigned long  st_rdev;
++        unsigned long  st_size;
++        unsigned long  st_blksize;
++        unsigned long  st_blocks;
++        unsigned long  st_atime;
++        unsigned long  st_atime_nsec;
++        unsigned long  st_mtime;
++        unsigned long  st_mtime_nsec;
++        unsigned long  st_ctime;
++        unsigned long  st_ctime_nsec;
++        unsigned long  __unused4;
++        unsigned long  __unused5;
++};
++
++#define STAT_HAVE_NSEC 1
++
++struct kernel_stat64 {
++      unsigned long long st_dev;
++
++      unsigned long long st_ino;
++      unsigned int    st_mode;
++      unsigned int    st_nlink;
++
++      unsigned long   st_uid;
++      unsigned long   st_gid;
++
++      unsigned long long st_rdev;
++
++      long long       st_size;
++      unsigned long   __pad1;
++      unsigned long   st_blksize;
++
++      unsigned long long st_blocks;
++
++      unsigned long   st_atime;
++      unsigned long   st_atime_nsec;
++
++      unsigned long   st_mtime;
++      unsigned long   st_mtime_nsec;
++
++      unsigned long   st_ctime;
++      unsigned long   st_ctime_nsec;
++
++      unsigned long   __unused1;
++      unsigned long   __unused2;
++};
++
++#endif /* _BITS_STAT_STRUCT_H */
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_types.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/kernel_types.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/kernel_types.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/kernel_types.h  2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,56 @@
++/* Note that we use the exact same include guard #define names
++ * as asm/posix_types.h.  This will avoid gratuitous conflicts
++ * with the posix_types.h kernel header, and will ensure that
++ * our private content, and not the kernel header, will win.
++ *  -Erik
++ */
++#ifndef __ASM_AVR32_POSIX_TYPES_H
++#define __ASM_AVR32_POSIX_TYPES_H
++
++/*
++ * This file is generally used by user-level software, so you need to
++ * be a little careful about namespace pollution etc.  Also, we cannot
++ * assume GCC is being used.
++ */
++
++typedef unsigned long __kernel_dev_t;
++typedef unsigned long   __kernel_ino_t;
++typedef unsigned short  __kernel_mode_t;
++typedef unsigned short  __kernel_nlink_t;
++typedef long            __kernel_off_t;
++typedef int             __kernel_pid_t;
++typedef unsigned short  __kernel_ipc_pid_t;
++typedef unsigned int  __kernel_uid_t;
++typedef unsigned int  __kernel_gid_t;
++typedef unsigned long __kernel_size_t;
++typedef int             __kernel_ssize_t;
++typedef int             __kernel_ptrdiff_t;
++typedef long            __kernel_time_t;
++typedef long            __kernel_suseconds_t;
++typedef long            __kernel_clock_t;
++typedef int             __kernel_timer_t;
++typedef int             __kernel_clockid_t;
++typedef int             __kernel_daddr_t;
++typedef char *          __kernel_caddr_t;
++typedef unsigned short  __kernel_uid16_t;
++typedef unsigned short  __kernel_gid16_t;
++typedef unsigned int    __kernel_uid32_t;
++typedef unsigned int    __kernel_gid32_t;
++
++typedef unsigned short  __kernel_old_uid_t;
++typedef unsigned short  __kernel_old_gid_t;
++typedef unsigned short  __kernel_old_dev_t;
++
++#ifdef __GNUC__
++typedef long long       __kernel_loff_t;
++#endif
++
++typedef struct {
++#if defined(__USE_ALL)
++    int     val[2];
++#else
++    int     __val[2];
++#endif
++} __kernel_fsid_t;
++
++#endif /* __ASM_AVR32_POSIX_TYPES_H */
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/machine-gmon.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/machine-gmon.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/machine-gmon.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/machine-gmon.h  2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,69 @@
++/* Machine-dependent definitions for profiling support.  AVR32 version.
++   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#define mcount_internal __mcount_internal
++
++#define _MCOUNT_DECL(frompc, selfpc) \
++static void __attribute((used)) mcount_internal(unsigned long frompc, unsigned long selfpc)
++
++/*
++ * This mcount implementation expects to get called after the prologue
++ * has been run. It also expects that r7 contains a valid frame
++ * pointer.
++ *
++ * When profiling, the compiler should generate something like this at
++ * each function entry:
++ *
++ *    pushm   r0-r7,lr        // lr mandatory, others optional
++ *    mov     r7, sp
++ *    // rest of prologue goes here
++ *    mcall   pc[.LC1 - .]
++ *      // rest of function goes here
++ * .LC1:
++ *    .long   mcount
++ *
++ * or for PIC:
++ *
++ *    pushm   r0-r7,lr
++ *    mov     r7, sp
++ *    // rest of prologue goes here
++ *    lddpc   r0, .LC1
++ * .L1: rsub  r0, pc
++ *    mcall   r0[mcount@GOT]
++ *    // rest of function goes here
++ * .LC1:
++ *    .long   .L1 - _GLOBAL_OFFSET_TABLE_
++ *
++ * This way, when mcount() is called, r7 points to the calling
++ * function's return address. It is guaranteed that calling mcount
++ * will clobber no registers except LR, which is unavoidable.
++ */
++#define MCOUNT asm(                           \
++      "       .align  4\n"                    \
++      "       .global _mcount\n"              \
++      "       .type   _mcount,@function\n"    \
++      "_mcount:\n"                            \
++      "       pushm   r8-r12,lr\n"            \
++      "       mov     r11, lr\n"              \
++      "       ld.w    r12, r7[0]\n"           \
++      "       rcall   __mcount_internal\n"    \
++      "       popm    r8-r12,pc\n"            \
++      "       .size   _mcount, . - _mcount\n" \
++      "       .weak   mcount\n"               \
++      "       mcount = _mcount");
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/mman.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/mman.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/mman.h 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/mman.h  2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,95 @@
++/* Definitions for POSIX memory map interface.  Linux/AVR32 version.
++   Copyright (C) 1997, 2000 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef _SYS_MMAN_H
++# error "Never include this file directly.  Use <sys/mman.h> instead"
++#endif
++
++/* The following definitions basically come from the kernel headers.
++   But the kernel header is not namespace clean.  */
++
++
++/* Protections are chosen from these bits, OR'd together.  The
++   implementation does not necessarily support PROT_EXEC or PROT_WRITE
++   without PROT_READ.  The only guarantees are that no writing will be
++   allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
++
++#define PROT_READ     0x1             /* Page can be read.  */
++#define PROT_WRITE    0x2             /* Page can be written.  */
++#define PROT_EXEC     0x4             /* Page can be executed.  */
++#define PROT_NONE     0x0             /* Page can not be accessed.  */
++
++/* Sharing types (must choose one and only one of these).  */
++#define MAP_SHARED    0x01            /* Share changes.  */
++#define MAP_PRIVATE   0x02            /* Changes are private.  */
++#ifdef __USE_MISC
++# define MAP_TYPE     0x0f            /* Mask for type of mapping.  */
++#endif
++
++/* Other flags.  */
++#define MAP_FIXED     0x10            /* Interpret addr exactly.  */
++#ifdef __USE_MISC
++# define MAP_FILE     0
++# define MAP_ANONYMOUS        0x20            /* Don't use a file.  */
++# define MAP_ANON     MAP_ANONYMOUS
++#endif
++
++/* These are Linux-specific.  */
++#ifdef __USE_MISC
++# define MAP_GROWSDOWN        0x0100          /* Stack-like segment.  */
++# define MAP_DENYWRITE        0x0800          /* ETXTBSY */
++# define MAP_EXECUTABLE       0x1000          /* Mark it as an executable.  */
++# define MAP_LOCKED   0x2000          /* Lock the mapping.  */
++# define MAP_NORESERVE        0x4000          /* Don't check for reservations.  */
++# define MAP_POPULATE 0x8000          /* populate (prefault) pagetables */
++# define MAP_NONBLOCK 0x10000         /* do not block on IO */
++#endif
++
++/* Flags to `msync'.  */
++#define MS_ASYNC      1               /* Sync memory asynchronously.  */
++#define MS_SYNC               4               /* Synchronous memory sync.  */
++#define MS_INVALIDATE 2               /* Invalidate the caches.  */
++
++/* Flags for `mlockall'.  */
++#define MCL_CURRENT   1               /* Lock all currently mapped pages.  */
++#define MCL_FUTURE    2               /* Lock all additions to address
++                                         space.  */
++
++/* Flags for `mremap'.  */
++#ifdef __USE_GNU
++# define MREMAP_MAYMOVE       1
++#endif
++
++/* Advise to `madvise'.  */
++#ifdef __USE_BSD
++# define MADV_NORMAL   0      /* No further special treatment.  */
++# define MADV_RANDOM   1      /* Expect random page references.  */
++# define MADV_SEQUENTIAL 2    /* Expect sequential page references.  */
++# define MADV_WILLNEED         3      /* Will need these pages.  */
++# define MADV_DONTNEED         4      /* Don't need these pages.  */
++#endif
++
++/* The POSIX people had to invent similar names for the same things.  */
++#ifdef __USE_XOPEN2K
++# define POSIX_MADV_NORMAL    0 /* No further special treatment.  */
++# define POSIX_MADV_RANDOM    1 /* Expect random page references.  */
++# define POSIX_MADV_SEQUENTIAL        2 /* Expect sequential page references.  */
++# define POSIX_MADV_WILLNEED  3 /* Will need these pages.  */
++# define POSIX_MADV_DONTNEED  4 /* Don't need these pages.  */
++#endif
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/profil-counter.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/profil-counter.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/profil-counter.h       1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/profil-counter.h        2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,26 @@
++/* Low-level statistical profiling support function.  Linux/AVR32 version.
++   Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <signal.h>
++
++void
++profil_counter(int signo, siginfo_t *si, struct sigcontext *sc)
++{
++      profil_count((void *)sc->pc);
++}
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/setjmp.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/setjmp.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/setjmp.h       1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/setjmp.h        2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,21 @@
++/*
++ * Copyright (C) 2004-2005 Atmel Norway
++ */
++#ifndef _SETJMP_H
++# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
++#endif
++
++#ifndef _ASM
++/*
++ * The jump buffer contains r0-r7, sr, sp and lr. Other registers are
++ * not saved.
++ */
++typedef int __jmp_buf[11];
++#endif
++
++#define __JMP_BUF_SP  4
++
++/* Test if longjmp to JMPBUF would unwind the frame containing a local
++   variable at ADDRESS.  */
++#define _JMPBUF_UNWINDS(jmpbuf, address) \
++  ((void *)(address) < (void *)(jmpbuf[__JMP_BUF_SP]))
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/syscalls.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/syscalls.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/syscalls.h     1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/syscalls.h      2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,143 @@
++#ifndef _SYSCALL_H
++# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
++#endif
++
++/*
++ * This includes the `__NR_<name>' syscall numbers taken from the
++ * Linux kernel header files. It also defines the traditional
++ * `SYS_<name>' macros for older programs.
++ */
++#include <bits/sysnum.h>
++
++#ifndef __set_errno
++# define __set_errno(val) (*__errno_location()) = (val)
++#endif
++#ifndef SYS_ify
++# define SYS_ify(syscall_name) (__NR_##syscall_name)
++#endif
++
++#ifndef __ASSEMBLER__
++
++#undef _syscall0
++#define _syscall0(type,name)                          \
++      type name(void)                                 \
++      {                                               \
++              return (type)(INLINE_SYSCALL(name, 0)); \
++      }
++
++#undef _syscall1
++#define _syscall1(type,name,type1,arg1)                               \
++      type name(type1 arg1)                                   \
++      {                                                       \
++              return (type)(INLINE_SYSCALL(name, 1, arg1));   \
++      }
++
++#undef _syscall2
++#define _syscall2(type,name,type1,arg1,type2,arg2)                    \
++      type name(type1 arg1, type2 arg2)                               \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 2, arg1, arg2));     \
++      }
++
++#undef _syscall3
++#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)         \
++      type name(type1 arg1, type2 arg2, type3 arg3)                   \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 3, arg1,             \
++                                           arg2, arg3));              \
++      }
++
++#undef _syscall4
++#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4)                                           \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)       \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 4, arg1, arg2,       \
++                                           arg3, arg4));              \
++      }
++
++#undef _syscall5
++#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4,type5,arg5)                                \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
++                type5 arg5)                                           \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 5, arg1, arg2,       \
++                                           arg3, arg4, arg5));        \
++      }
++
++#undef _syscall6
++#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4,type5,arg5,type6,arg6)                     \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
++                type5 arg5, type6 arg6)                               \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 6, arg1, arg2, arg3, \
++                                           arg4, arg5, arg6));        \
++      }
++
++#undef unlikely
++#define unlikely(x) __builtin_expect((x), 0)
++
++#undef INLINE_SYSCALL
++#define INLINE_SYSCALL(name, nr, args...)                             \
++      ({                                                              \
++              unsigned _sys_result = INTERNAL_SYSCALL(name, , nr, args); \
++              if (unlikely(INTERNAL_SYSCALL_ERROR_P(_sys_result, ))) { \
++                      __set_errno(INTERNAL_SYSCALL_ERRNO(_sys_result, )); \
++                      _sys_result = (unsigned int) -1;                \
++              }                                                       \
++              (int) _sys_result;                                      \
++      })
++
++#undef INTERNAL_SYSCALL_DECL
++#define INTERNAL_SYSCALL_DECL(err) do { } while(0)
++
++#undef INTERNAL_SYSCALL
++#define INTERNAL_SYSCALL(name, err, nr, args...)                      \
++      ({                                                              \
++              register int _a1 asm ("r12");                           \
++              register int _scno asm("r8") = SYS_ify(name);           \
++              LOAD_ARGS_##nr (args);                                  \
++              asm volatile ("scall    /* syscall " #name " */"        \
++                            : "=r" (_a1)                              \
++                            : "r"(_scno) ASM_ARGS_##nr                \
++                            : "lr", "cc", "memory");                  \
++              _a1;                                                    \
++      })
++
++#undef INTERNAL_SYSCALL_ERROR_P
++#define INTERNAL_SYSCALL_ERROR_P(val, err)            \
++      ((unsigned int)(val) >= 0xfffff001U)
++
++#undef INTERNAL_SYSCALL_ERRNO
++#define INTERNAL_SYSCALL_ERRNO(val, errr) (-(val))
++
++#define LOAD_ARGS_0() do { } while(0)
++#define ASM_ARGS_0
++#define LOAD_ARGS_1(a1)                                       \
++      _a1 = (int) (a1);                               \
++      LOAD_ARGS_0()
++#define ASM_ARGS_1    ASM_ARGS_0, "r"(_a1)
++#define LOAD_ARGS_2(a1, a2)                           \
++      register int _a2 asm("r11") = (int)(a2);        \
++      LOAD_ARGS_1(a1)
++#define ASM_ARGS_2    ASM_ARGS_1, "r"(_a2)
++#define LOAD_ARGS_3(a1, a2, a3)                               \
++      register int _a3 asm("r10") = (int)(a3);        \
++      LOAD_ARGS_2(a1, a2)
++#define ASM_ARGS_3    ASM_ARGS_2, "r"(_a3)
++#define LOAD_ARGS_4(a1, a2, a3, a4)                   \
++      register int _a4 asm("r9") = (int)(a4);         \
++      LOAD_ARGS_3(a1, a2, a3)
++#define ASM_ARGS_4    ASM_ARGS_3, "r"(_a4)
++#define LOAD_ARGS_5(a1, a2, a3, a4, a5)                       \
++      register int _a5 asm("r5") = (int)(a5);         \
++      LOAD_ARGS_4(a1, a2, a3, a4)
++#define ASM_ARGS_5    ASM_ARGS_4, "r"(_a5)
++#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)           \
++      register int _a6 asm("r3") = (int)(a6);         \
++      LOAD_ARGS_5(a1, a2, a3, a4, a5)
++#define ASM_ARGS_6    ASM_ARGS_5, "r"(_a6)
++
++#endif /* __ASSEMBLER__ */
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/wordsize.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/wordsize.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bits/wordsize.h     1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bits/wordsize.h      2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1 @@
++#define __WORDSIZE    32
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/brk.c uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/brk.c
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/brk.c       1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/brk.c        2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,23 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <sys/syscall.h>
++
++void *__curbrk = 0;
++
++int brk (void *addr)
++{
++      void *newbrk;
++
++      newbrk = INLINE_SYSCALL(brk, 1, addr);
++
++      __curbrk = newbrk;
++
++      if (newbrk < addr) {
++              __set_errno (ENOMEM);
++              return -1;
++      }
++
++      return 0;
++}
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-_setjmp.S uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bsd-_setjmp.S
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-_setjmp.S       1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bsd-_setjmp.S        2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      /* This just does a tail-call to __sigsetjmp(env, 0) */
++      .global _setjmp
++      .type   _setjmp,"function"
++      .align  1
++_setjmp:
++      mov     r11, 0
++      bral    __sigsetjmp_internal
++      .size   _setjmp, . - _setjmp
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-setjmp.S uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bsd-setjmp.S
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/bsd-setjmp.S        1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/bsd-setjmp.S 2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      /* This just does a tail-call to __sigsetjmp(env, 1) */
++      .global setjmp
++      .type   setjmp,"function"
++      .align  1
++setjmp:
++      mov     r11, 1
++      bral    __sigsetjmp_internal
++      .size   setjmp, . - setjmp
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/clone.c uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/clone.c
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/clone.c     1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/clone.c      2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <sys/syscall.h>
++#include <unistd.h>
++
++/*
++ * I don't know if we can be absolutely certain that the fn and arg
++ * parameters are preserved when returning as the child. If the
++ * compiler stores them in registers (r0-r7), they should be.
++ */
++int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg)
++{
++      register int (*_fn)(void *arg) = fn;
++      register void *_arg = arg;
++      int err;
++
++      /* Sanity check the arguments */
++      err = -EINVAL;
++      if (!fn)
++              goto syscall_error;
++      if (!child_stack)
++              goto syscall_error;
++
++      err = INLINE_SYSCALL(clone, 2, flags, child_stack);
++      if (err < 0)
++              goto syscall_error;
++      else if (err != 0)
++              return err;
++
++      _exit(_fn(_arg));
++
++syscall_error:
++      __set_errno (-err);
++      return -1;
++}
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/crt1.S uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/crt1.S
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/crt1.S      1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/crt1.S       2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,93 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ *
++ * When we enter _start, the stack looks like this:
++ *    argc            argument counter
++ *    argv[0]         pointer to program name
++ *    argv[1..argc-1] pointers to program args
++ *    NULL
++ *    env[0..N]       pointers to environment variables
++ *    NULL
++ *
++ * r12 contains a function pointer to be registered with `atexit'.
++ * This is how the dynamic linker arranges to have DT_FINI functions
++ * called for shared libraries that have been loaded before this
++ * code runs.
++ *
++ * We're going to call the following function:
++ * __uClibc_main(int (*main)(int, char **, char **), int argc,
++ *             char **argv, void (*app_init)(void), void (*app_fini)(void),
++ *             void (*rtld_fini)(void), void *stack_end)
++ *
++ * So we need to set up things as follows:
++ *    r12 = address of main
++ *    r11 = argc
++ *    r10 = &argv[0]
++ *    r9  = address of _init
++ *    r8  = address of _fini
++ *    sp[0] = whatever we got passed in r12
++ */
++
++#include <features.h>
++
++      .text
++      .global _start
++      .type   _start, @function
++_start:
++      /* Clear the frame pointer and link register since this is the outermost frame.  */
++      mov     r7, 0
++      mov     lr, 0
++
++      ld.w    r11, sp++               /* argc         */
++      mov     r10, sp                 /* &argv[0]     */
++
++      st.w    --sp, r10               /* stack_end */
++      st.w    --sp, r12               /* rtld_fini */
++
++#ifdef __PIC__
++      lddpc   r6, .L_GOT
++.L_RGOT:
++      rsub    r6, pc
++      lda.w   r9, _init
++      lda.w   r8, _fini
++      lda.w   r12, main
++
++      /* Ok, now run uClibc's main() -- should not return */
++      call    __uClibc_main
++
++      .align  2
++.L_GOT:
++      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
++#else
++      lddpc   r9, __init_addr         /* app_init */
++      lddpc   r8, __fini_addr         /* app_fini */
++      lddpc   r12, __main_addr        /* main */
++
++      /* Ok, now run uClibc's main() -- should not return */
++      lddpc   pc, ___uClibc_main_addr
++
++      .align  2
++__init_addr:
++      .long   _init
++__fini_addr:
++      .long   _fini
++__main_addr:
++      .long   main
++___uClibc_main_addr:
++      .long   __uClibc_main
++#endif
++      .size   _start, . - _start
++
++      /*
++       * The LSB says we need this.
++       */
++      .section ".note.ABI-tag", "a"
++      .align  4
++      .long   2f - 1f         /* namesz */
++      .long   4f - 3f         /* descsz */
++      .long   1               /* type   */
++1:    .asciz  "GNU"           /* name */
++2:    .align  4
++3:    .long   0               /* Linux executable */
++      .long   2,6,0           /* Earliest compatible kernel */
++4:    .align  4
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/crti.S uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/crti.S
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/crti.S      1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/crti.S       2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,17 @@
++
++      .section .init
++      .align  2
++      .global _init
++      .type   _init, @function
++_init:
++      /* Use a four-byte instruction to avoid NOPs */
++      stm     --sp, r0-r7,lr
++      .align  2
++
++      .section .fini
++      .align  2
++      .global _fini
++      .type   _fini, @function
++_fini:
++      stm     --sp, r0-r7,lr
++      .align  2
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/crtn.S uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/crtn.S
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/crtn.S      1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/crtn.S       2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,14 @@
++
++      .section .init
++      .align  2
++      .global _init
++      .type   _init, @function
++      ldm     sp++, r0-r7,pc
++      .size   _init, . - _init
++
++      .section .fini
++      .align  2
++      .global _fini
++      .type   _fini, @function
++      ldm     sp++, r0-r7,pc
++      .size   _fini, . - _fini
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/__longjmp.S uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/__longjmp.S
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/__longjmp.S 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/__longjmp.S  2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,17 @@
++/* longjmp for AVR32
++ *
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      .global __longjmp
++      .type   __longjmp,"function"
++      .align  1
++__longjmp:
++      ldm     r12++, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr
++      mov     r12, r11        /* get the return value right */
++      mustr   r8              /* restore status register (lower half) */
++      cp      r12, 0          /* can't return zero */
++      frs
++      moveq   r12, 1
++      mov     pc,lr
++      .size   __longjmp, . - __longjmp
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/Makefile uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/Makefile
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/Makefile    1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/Makefile     2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,93 @@
++# Makefile for uClibc
++#
++# Copyright (C) 2000-2003 Erik Andersen <andersen@uclibc.org>
++#
++# This program is free software; you can redistribute it and/or modify it under
++# the terms of the GNU Library 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 Library General Public License for more
++# details.
++#
++# You should have received a copy of the GNU Library 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
++
++TOPDIR=../../../../
++include $(TOPDIR)Rules.mak
++ASFLAGS=$(CFLAGS)
++
++CRT_SRC       = crt1.S
++CRT_OBJ = crt1.o
++SCRT_OBJ = $(patsubst %,S%, $(CRT_OBJ))
++CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
++
++SSRC=__longjmp.S setjmp.S bsd-setjmp.S vfork.S \
++      bsd-_setjmp.S sigrestorer.S syscall.S
++SOBJS=$(patsubst %.S,%.o, $(SSRC))
++
++CSRC=clone.c brk.c sigaction.c mmap.c
++COBJS=$(patsubst %.c,%.o, $(CSRC))
++
++OBJS=$(SOBJS) $(COBJS)
++
++OBJ_LIST=../../../obj.sysdeps.$(TARGET_ARCH)
++
++all: $(OBJ_LIST)
++
++$(OBJ_LIST): $(OBJS) $(CRT_OBJ) $(SCRT_OBJ) $(CTOR_TARGETS)
++      echo $(patsubst %, sysdeps/linux/$(TARGET_ARCH)/%, $(OBJS)) > $(OBJ_LIST)
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp $(CRT_OBJ) $(SCRT_OBJ) $(TOPDIR)lib/
++
++$(CRT_OBJ): $(CRT_SRC)
++      $(CC) $(ASFLAGS) -DL_$* $< -c -o $*.o
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(SCRT_OBJ): $(CRT_SRC)
++      $(CC) $(ASFLAGS) $(PIEFLAG) -DL_$* $< -c -o $*.o
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(SOBJS): %.o : %.S
++      $(CC) $(ASFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(COBJS): %.o : %.c
++      $(CC) $(CFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
++crti.o: crti.S
++      $(CC) $(ASFLAGS) -c crti.S -o crti.o
++
++$(TOPDIR)lib/crti.o: crti.o
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp crti.o $(TOPDIR)lib/
++
++crtn.o: crtn.S
++      $(CC) $(ASFLAGS) -c crtn.S -o crtn.o
++
++$(TOPDIR)lib/crtn.o: crtn.o
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp crtn.o $(TOPDIR)lib/
++else
++$(TOPDIR)lib/crti.o:
++      $(INSTALL) -d $(TOPDIR)lib/
++      $(AR) $(ARFLAGS) $(TOPDIR)lib/crti.o
++$(TOPDIR)lib/crtn.o:
++      $(INSTALL) -d $(TOPDIR)lib/
++      $(AR) $(ARFLAGS) $(TOPDIR)lib/crtn.o
++endif
++
++
++headers:
++#     $(LN) -fs ../libc/sysdeps/linux/avr32/fpu_control.h $(TOPDIR)/include/
++
++clean:
++      $(RM) *.[oa] *~ core
++      $(RM) bits/sysnum.h
++      $(RM) gmon-start.S
++
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/_mmap.c uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/_mmap.c
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/_mmap.c     1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/_mmap.c      2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,33 @@
++/* Copyright (C) 2005 Atmel Norway
++
++   This program is free software; you can redistribute it and/or modify it under
++   the terms of the GNU Library 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 Library General Public License for more
++   details.
++
++   You should have received a copy of the GNU Library 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
++
++   Derived in part from the Linux-8086 C library, the GNU C Library, and several
++   other sundry sources.  Files within this library are copyright by their
++   respective copyright holders.
++ */
++
++#include <errno.h>
++#include <sys/mman.h>
++#include <sys/syscall.h>
++
++#define __NR_mmap2 __NR_mmap
++
++static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot, int, flags, int, fd, __off_t, pgoff);
++
++__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
++{
++      return mmap2(addr, len, prot, flags, fd, offset >> 12);
++}
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/mmap.c uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/mmap.c
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/mmap.c      1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/mmap.c       2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,31 @@
++/* Copyright (C) 2005 Atmel Norway
++
++   This program is free software; you can redistribute it and/or modify it under
++   the terms of the GNU Library 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 Library General Public License for more
++   details.
++
++   You should have received a copy of the GNU Library 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
++
++   Derived in part from the Linux-8086 C library, the GNU C Library, and several
++   other sundry sources.  Files within this library are copyright by their
++   respective copyright holders.
++ */
++
++#include <errno.h>
++#include <sys/mman.h>
++#include <sys/syscall.h>
++
++static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot, int, flags, int, fd, __off_t, pgoff);
++
++__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
++{
++      return mmap2(addr, len, prot, flags, fd, offset >> 12);
++}
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/setjmp.S uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/setjmp.S
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/setjmp.S    1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/setjmp.S     2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#define _SETJMP_H
++#define _ASM
++#include <bits/setjmp.h>
++
++      .text
++
++      .global __sigsetjmp
++      .type   __sigsetjmp,"function"
++
++      /* Create a global, hidden symbol for use by setjmp() and _setjmp().
++         If it's not hidden, the linker will complain about a relative
++         jump to a dynamic symbol when building a shared library.
++
++         Also, if a user overrides the __sigsetjmp function, he might not
++         expect the setjmp() and _setjmp() function to effectively be
++         overridden as well.  */
++      .global __sigsetjmp_internal
++      .hidden __sigsetjmp_internal
++      .type   __sigsetjmp_internal,"function"
++      .align  1
++__sigsetjmp:
++__sigsetjmp_internal:
++      mustr   r8
++      stm     r12, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr
++
++      /* Make a tail call to __sigjmp_save; it takes the same args.  */
++#ifdef __PIC__
++      mov     r9, r6
++      lddpc   r6, .LG
++.L1:  rsub    r6, pc
++      ld.w    r8, r6[__sigjmp_save@got]
++      mov     r6, r9
++      mov     pc, r8
++
++      .align  2
++.LG:  .long   .L1 - _GLOBAL_OFFSET_TABLE_
++#else
++      rjmp    __sigjmp_save
++#endif
++      .size   __sigsetjmp, . - __sigsetjmp
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/sigaction.c uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sigaction.c
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/sigaction.c 1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sigaction.c  2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <signal.h>
++#include <string.h>
++#include <sys/syscall.h>
++#include <bits/kernel_sigaction.h>
++
++#define SA_RESTORER   0x04000000
++extern void __default_rt_sa_restorer(void);
++
++/*
++ * If act is not NULL, change the action for sig to *act.
++ * If oact is not NULL, put the old action for sig in *oact.
++ */
++int __libc_sigaction(int signum, const struct sigaction *act,
++                   struct sigaction *oldact)
++{
++      struct kernel_sigaction kact, koact;
++      int result;
++
++      if (act) {
++              kact.k_sa_handler = act->sa_handler;
++              memcpy(&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
++              kact.sa_flags = act->sa_flags;
++              if (kact.sa_flags & (SA_RESTORER | SA_ONSTACK))
++                      kact.sa_restorer = act->sa_restorer;
++              else
++                      kact.sa_restorer = __default_rt_sa_restorer;
++              kact.sa_flags |= SA_RESTORER;
++      }
++
++      result = __syscall_rt_sigaction(signum, act ? __ptrvalue(&kact) : NULL,
++                                      oldact ? __ptrvalue(&koact) : NULL,
++                                      _NSIG / 8);
++
++      if (oldact && result >= 0) {
++              oldact->sa_handler = koact.k_sa_handler;
++              memcpy(&oldact->sa_mask, &koact.sa_mask,
++                     sizeof(oldact->sa_mask));
++              oldact->sa_flags = koact.sa_flags;
++              oldact->sa_restorer = koact.sa_restorer;
++      }
++
++      return result;
++}
++
++weak_alias(__libc_sigaction, sigaction)
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/sigrestorer.S uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sigrestorer.S
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/sigrestorer.S       1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sigrestorer.S        2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,11 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <sys/syscall.h>
++
++      .global __default_rt_sa_restorer
++      .type   __default_rt_sa_restorer,"function"
++      .align  1
++__default_rt_sa_restorer:
++      mov     r8, __NR_rt_sigreturn
++      scall
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/elf.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sys/elf.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/elf.h   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sys/elf.h    2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,26 @@
++/* Copyright (C) 1996, 1997, 1999, 2001 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef _SYS_ELF_H
++#define _SYS_ELF_H    1
++
++#warning "This header is obsolete; use <sys/procfs.h> instead."
++
++#include <sys/procfs.h>
++
++#endif        /* sys/elf.h */
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/io.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sys/io.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/io.h    1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sys/io.h     2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,48 @@
++/* Copyright (C) 1996, 1998, 1999 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef       _SYS_IO_H
++
++#define       _SYS_IO_H       1
++#include <features.h>
++
++__BEGIN_DECLS
++
++/* If TURN_ON is TRUE, request for permission to do direct i/o on the
++   port numbers in the range [FROM,FROM+NUM-1].  Otherwise, turn I/O
++   permission off for that range.  This call requires root privileges.  */
++extern int ioperm (unsigned long int __from, unsigned long int __num,
++                 int __turn_on) __THROW;
++
++/* Set the I/O privilege level to LEVEL.  If LEVEL is nonzero,
++   permission to access any I/O port is granted.  This call requires
++   root privileges. */
++extern int iopl (int __level) __THROW;
++
++/* The functions that actually perform reads and writes.  */
++extern unsigned char inb (unsigned long int port) __THROW;
++extern unsigned short int inw (unsigned long int port) __THROW;
++extern unsigned long int inl (unsigned long int port) __THROW;
++
++extern void outb (unsigned char value, unsigned long int port) __THROW;
++extern void outw (unsigned short value, unsigned long int port) __THROW;
++extern void outl (unsigned long value, unsigned long int port) __THROW;
++
++__END_DECLS
++
++#endif /* _SYS_IO_H */
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/procfs.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sys/procfs.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/procfs.h        1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sys/procfs.h 2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,123 @@
++/* Copyright (C) 1996, 1997, 1999, 2001 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef _SYS_PROCFS_H
++#define _SYS_PROCFS_H 1
++
++/* This is somewhat modelled after the file of the same name on SVR4
++   systems.  It provides a definition of the core file format for ELF
++   used on Linux.  It doesn't have anything to do with the /proc file
++   system, even though Linux has one.
++
++   Anyway, the whole purpose of this file is for GDB and GDB only.
++   Don't read too much into it.  Don't use it for anything other than
++   GDB unless you know what you are doing.  */
++
++#include <features.h>
++#include <sys/time.h>
++#include <sys/types.h>
++#include <sys/user.h>
++
++__BEGIN_DECLS
++
++/* Type for a general-purpose register.  */
++typedef unsigned long elf_greg_t;
++
++/* And the whole bunch of them.  We could have used `struct
++   user_regs' directly in the typedef, but tradition says that
++   the register set is an array, which does have some peculiar
++   semantics, so leave it that way.  */
++#define ELF_NGREG (sizeof (struct user_regs) / sizeof(elf_greg_t))
++typedef elf_greg_t elf_gregset_t[ELF_NGREG];
++
++/* Register set for the floating-point registers.  */
++typedef struct user_fpregs elf_fpregset_t;
++
++/* Signal info.  */
++struct elf_siginfo
++  {
++    int si_signo;                     /* Signal number.  */
++    int si_code;                      /* Extra code.  */
++    int si_errno;                     /* Errno.  */
++  };
++
++/* Definitions to generate Intel SVR4-like core files.  These mostly
++   have the same names as the SVR4 types with "elf_" tacked on the
++   front to prevent clashes with Linux definitions, and the typedef
++   forms have been avoided.  This is mostly like the SVR4 structure,
++   but more Linuxy, with things that Linux does not support and which
++   GDB doesn't really use excluded.  */
++
++struct elf_prstatus
++  {
++    struct elf_siginfo pr_info;               /* Info associated with signal.  */
++    short int pr_cursig;              /* Current signal.  */
++    unsigned long int pr_sigpend;     /* Set of pending signals.  */
++    unsigned long int pr_sighold;     /* Set of held signals.  */
++    __pid_t pr_pid;
++    __pid_t pr_ppid;
++    __pid_t pr_pgrp;
++    __pid_t pr_sid;
++    struct timeval pr_utime;          /* User time.  */
++    struct timeval pr_stime;          /* System time.  */
++    struct timeval pr_cutime;         /* Cumulative user time.  */
++    struct timeval pr_cstime;         /* Cumulative system time.  */
++    elf_gregset_t pr_reg;             /* GP registers.  */
++    int pr_fpvalid;                   /* True if math copro being used.  */
++  };
++
++
++#define ELF_PRARGSZ     (80)    /* Number of chars for args.  */
++
++struct elf_prpsinfo
++  {
++    char pr_state;                    /* Numeric process state.  */
++    char pr_sname;                    /* Char for pr_state.  */
++    char pr_zomb;                     /* Zombie.  */
++    char pr_nice;                     /* Nice val.  */
++    unsigned long int pr_flag;                /* Flags.  */
++    unsigned short int pr_uid;
++    unsigned short int pr_gid;
++    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
++    /* Lots missing */
++    char pr_fname[16];                        /* Filename of executable.  */
++    char pr_psargs[ELF_PRARGSZ];      /* Initial part of arg list.  */
++  };
++
++/* The rest of this file provides the types for emulation of the
++   Solaris <proc_service.h> interfaces that should be implemented by
++   users of libthread_db.  */
++
++/* Addresses.  */
++typedef void *psaddr_t;
++
++/* Register sets.  Linux has different names.  */
++typedef elf_gregset_t prgregset_t;
++typedef elf_fpregset_t prfpregset_t;
++
++/* We don't have any differences between processes and threads,
++   therefore have only one PID type.  */
++typedef __pid_t lwpid_t;
++
++/* Process status and info.  In the end we do provide typedefs for them.  */
++typedef struct elf_prstatus prstatus_t;
++typedef struct elf_prpsinfo prpsinfo_t;
++
++__END_DECLS
++
++#endif        /* sys/procfs.h */
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/ucontext.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sys/ucontext.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/ucontext.h      1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sys/ucontext.h       2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,94 @@
++/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++/* Linux/AVR32 ABI compliant context switching support.  */
++
++#ifndef _SYS_UCONTEXT_H
++#define _SYS_UCONTEXT_H       1
++
++#include <features.h>
++#include <signal.h>
++#include <sys/procfs.h>
++#include <bits/sigcontext.h>
++
++typedef int greg_t;
++
++/* Number of general registers.  */
++#define NGREG 16
++
++/* Container for all general registers.  */
++typedef elf_gregset_t gregset_t;
++
++/* Number of each register is the `gregset_t' array.  */
++enum
++{
++  R0 = 0,
++#define R0    R0
++  R1 = 1,
++#define R1    R1
++  R2 = 2,
++#define R2    R2
++  R3 = 3,
++#define R3    R3
++  R4 = 4,
++#define R4    R4
++  R5 = 5,
++#define R5    R5
++  R6 = 6,
++#define R6    R6
++  R7 = 7,
++#define R7    R7
++  R8 = 8,
++#define R8    R8
++  R9 = 9,
++#define R9    R9
++  R10 = 10,
++#define R10   R10
++  R11 = 11,
++#define R11   R11
++  R12 = 12,
++#define R12   R12
++  R13 = 13,
++#define R13   R13
++  R14 = 14,
++#define R14   R14
++  R15 = 15
++#define R15   R15
++};
++
++/* Structure to describe FPU registers.  */
++typedef elf_fpregset_t        fpregset_t;
++
++/* Context to describe whole processor state.  */
++typedef struct
++  {
++    gregset_t gregs;
++    fpregset_t fpregs;
++  } mcontext_t;
++
++/* Userlevel context.  */
++typedef struct ucontext
++{
++    unsigned long     uc_flags;
++    struct ucontext  *uc_link;
++    stack_t           uc_stack;
++    struct sigcontext uc_mcontext;
++    sigset_t          uc_sigmask;   /* mask last for extensibility */
++} ucontext_t;
++
++#endif /* sys/ucontext.h */
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/user.h uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sys/user.h
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/sys/user.h  1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/sys/user.h   2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,46 @@
++#ifndef _SYS_USER_H
++#define _SYS_USER_H
++
++struct user_fpregs
++{
++
++};
++
++struct user_regs
++{
++      unsigned long sr;
++      unsigned long pc;
++      unsigned long lr;
++      unsigned long sp;
++      unsigned long r12;
++      unsigned long r11;
++      unsigned long r10;
++      unsigned long r9;
++      unsigned long r8;
++      unsigned long r7;
++      unsigned long r6;
++      unsigned long r5;
++      unsigned long r4;
++      unsigned long r3;
++      unsigned long r2;
++      unsigned long r1;
++      unsigned long r0;
++      unsigned long r12_orig;
++};
++
++struct user
++{
++      struct user_regs        regs;           /* general registers */
++      size_t                  u_tsize;        /* text size (pages) */
++      size_t                  u_dsize;        /* data size (pages) */
++      size_t                  u_ssize;        /* stack size (pages) */
++      unsigned long           start_code;     /* text starting address */
++      unsigned long           start_data;     /* data starting address */
++      unsigned long           start_stack;    /* stack starting address */
++      long int                signal;         /* signal causing core dump */
++      struct user_regs *      u_ar0;          /* help gdb find registers */
++      unsigned long           magic;          /* identifies a core file */
++      char                    u_comm[32];     /* user command name */
++};
++
++#endif /* _SYS_USER_H */
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/syscall.S uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/syscall.S
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/syscall.S   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/syscall.S    2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,81 @@
++/*
++ * syscall for AVR32/uClibc
++ *
++ * Copyright (C) 2004 Atmel Norway
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU Library 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 Library General Public License
++ * for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this program; if not, write to the Free Software Foundation,
++ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#include <features.h>
++
++      .text
++
++      /*
++       * long int syscall(long int sysno, ...)
++       */
++      .global syscall
++      .type   syscall, @function
++      .align  2
++syscall:
++      stm     --sp, r3,r5,lr
++      sub     lr, sp, -12
++      mov     r8, r12
++      ldm     lr, r3,r5,r9-r12
++      scall
++      cp.w    r12, -4095
++      brlo    .Ldone
++
++#ifdef __PIC__
++      lddpc   r5, .Lgot
++.Lgotcalc:
++      rsub    r5, pc
++# ifdef __UCLIBC_HAS_THREADS__
++      mov     r3, r12
++      mcall   r5[__errno_location@got]
++      st.w    r12[0], r3
++# else
++      ld.w    r3, r5[errno@got]
++      st.w    r3[0], r12
++# endif
++#else
++# ifdef __UCLIBC_HAS_THREADS__
++      mov     r3, r12
++      mcall   .Lerrno_location
++      st.w    r12[0], r3
++# else
++      lddpc   r3, .Lerrno
++      st.w    r3[0], r12
++# endif
++#endif
++      mov     r12, -1
++
++.Ldone:
++      ldm     sp++, r3,r5,pc
++
++      .align  2
++#ifdef __PIC__
++.Lgot:
++      .long   .Lgotcalc - _GLOBAL_OFFSET_TABLE_
++#else
++# ifdef __UCLIBC_HAS_THREADS__
++.Lerrno_location:
++      .long   __errno_location
++# else
++.Lerrno:
++      .long   errno
++# endif
++#endif
++
++
++      .size   syscall, . - syscall
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/avr32/vfork.S uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/vfork.S
+--- uClibc-0.9.28/libc/sysdeps/linux/avr32/vfork.S     1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/avr32/vfork.S      2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,55 @@
++      /*
++       * vfork for uClibc
++       *
++       * Copyright (C) 2005 Atmel Norway
++       */
++
++      /*
++       * Clone the process without copying the address space.  The
++       * calling process is suspended until the child either exits
++       * or calls execve.
++       *
++       * This all means that we cannot rely on the stack to store
++       * away registers, since they will be overwritten by the child
++       * as soon as it makes another function call (e.g. execve()).
++       * Fortunately, the Linux kernel preserves LR across system calls.
++       */
++#include <features.h>
++#include <sys/syscall.h>
++
++      .global __vfork
++      .type   __vfork,@function
++      .align  1
++__vfork:
++      mov     r8, __NR_vfork
++      scall
++      cp.w    r12, -4096
++      retls   r12
++
++      /* vfork failed, so we may use the stack freely */
++      pushm   r4-r7,lr
++#ifdef __PIC__
++      lddpc   r6, .L_GOT
++      rsub    r4, r12, 0
++.L_RGOT:
++      rsub    r6, pc
++      mcall   r6[__errno_location@got]
++#else
++      rsub    r4, r12, 0
++      mcall   .L__errno_location
++#endif
++      st.w    r12[0], r4
++      popm    r4-r7,pc,r12=-1
++
++      .align  2
++#ifdef __PIC__
++.L_GOT:
++      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
++#else
++.L__errno_location:
++      .long   __errno_location
++#endif
++      .size   __vfork, . - __vfork
++
++      .weak   vfork
++      vfork   = __vfork
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/common/create_module.c uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/common/create_module.c
+--- uClibc-0.9.28/libc/sysdeps/linux/common/create_module.c    2005-08-18 00:49:42.000000000 +0200
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/common/create_module.c     2006-06-21 11:35:57.000000000 +0200
+@@ -61,7 +61,8 @@
+ {
+   return __create_module(name, size, 0, 0);
+ }
+-#else
++/* create_module is obsolete in Linux 2.6, so AVR32 doesn't have it */
++#elif !defined(__avr32__)
+ /* Sparc, MIPS, etc don't mistake return values for errors. */ 
+ _syscall2(unsigned long, create_module, const char *, name, size_t, size);
+ #endif
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/common/getrusage.c uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/common/getrusage.c
+--- uClibc-0.9.28/libc/sysdeps/linux/common/getrusage.c        2005-08-18 00:49:42.000000000 +0200
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/common/getrusage.c 2006-06-21 11:35:56.000000000 +0200
+@@ -10,4 +10,4 @@
+ #include "syscalls.h"
+ #include <unistd.h>
+ #include <wait.h>
+-_syscall2(int, getrusage, int, who, struct rusage *, usage);
++_syscall2(int, getrusage, __rusage_who_t, who, struct rusage *, usage);
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/common/open64.c uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/common/open64.c
+--- uClibc-0.9.28/libc/sysdeps/linux/common/open64.c   2005-08-18 00:49:42.000000000 +0200
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/common/open64.c    2006-06-21 11:35:56.000000000 +0200
+@@ -26,7 +26,7 @@
+ #endif
+ #ifdef __UCLIBC_HAS_LFS__
+-extern int __libc_open (__const char *file, int oflag, mode_t mode);
++extern int __libc_open (__const char *file, int oflag, ...);
+ /* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+    a third argument is the file protection.  */
+diff -Nur uClibc-0.9.28/libc/sysdeps/linux/common/__syscall_fcntl.c uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/common/__syscall_fcntl.c
+--- uClibc-0.9.28/libc/sysdeps/linux/common/__syscall_fcntl.c  2005-08-18 00:49:42.000000000 +0200
++++ uClibc-0.9.28-avr32-20060621/libc/sysdeps/linux/common/__syscall_fcntl.c   2006-06-21 11:35:56.000000000 +0200
+@@ -12,7 +12,7 @@
+ #include <fcntl.h>
+ #if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64
+-extern int __libc_fcntl64(int fd, int cmd, long arg);
++extern int __libc_fcntl64(int fd, int cmd, ...);
+ #endif
+ #define __NR___syscall_fcntl __NR_fcntl
+diff -Nur uClibc-0.9.28/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h uClibc-0.9.28-avr32-20060621/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h
+--- uClibc-0.9.28/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h   1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h    2006-06-21 11:35:57.000000000 +0200
+@@ -0,0 +1,92 @@
++/* Machine-dependent pthreads configuration and inline functions.
++
++   Copyright (C) 2005 Atmel Norway
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public License as
++   published by the Free Software Foundation; either version 2.1 of the
++   License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; see the file COPYING.LIB.  If not,
++   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++   Boston, MA 02111-1307, USA.  */
++
++#ifndef _PT_MACHINE_H
++#define _PT_MACHINE_H   1
++
++#include <features.h>
++
++static inline int
++_test_and_set (int *p, int v) __THROW
++{
++      int result;
++
++      __asm__ __volatile__(
++              "/* Inline test and set */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %2\n"
++              "       tst     %0, %3\n"
++              "       breq    2f\n"
++              "       stcond  %1, %3\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=m"(*p)
++              : "m"(*p), "r"(v)
++              : "memory", "cc");
++
++      return result;
++}
++
++#ifndef PT_EI
++# define PT_EI extern inline
++#endif
++
++extern long int testandset (int *spinlock);
++extern int __compare_and_swap (long int *p, long int oldval, long int newval);
++
++/* Spinlock implementation; required.  */
++PT_EI long int
++testandset (int *spinlock)
++{
++      return _test_and_set(spinlock, 1);
++}
++
++
++/* Get some notion of the current stack.  Need not be exactly the top
++   of the stack, just something somewhere in the current frame.  */
++#define CURRENT_STACK_FRAME  stack_pointer
++register char * stack_pointer __asm__ ("sp");
++
++/* Compare-and-swap for semaphores. */
++
++#define HAS_COMPARE_AND_SWAP
++PT_EI int
++__compare_and_swap(long int *p, long int oldval, long int newval)
++{
++      long int result, tmp;
++
++      __asm__ __volatile__(
++              "/* Inline compare and swap */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %1, %3\n"
++              "       cp.w    %1, %5\n"
++              "       sreq    %0\n"
++              "       brne    2f\n"
++              "       stcond  %2, %4\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=&r"(tmp), "=m"(*p)
++              : "m"(*p), "r"(newval), "r"(oldval)
++              : "cc", "memory");
++
++      return result;
++}
++
++#endif /* pt-machine.h */
+diff -Nur uClibc-0.9.28/Makefile uClibc-0.9.28-avr32-20060621/Makefile
+--- uClibc-0.9.28/Makefile     2005-08-18 00:49:49.000000000 +0200
++++ uClibc-0.9.28-avr32-20060621/Makefile      2006-06-21 11:35:57.000000000 +0200
+@@ -163,7 +163,7 @@
+       else \
+               extra_exclude="" ; \
+       fi ; \
+-      tar -chf - include --exclude .svn --exclude CVS $$extra_exclude \
++      tar -chf - --exclude .svn --exclude CVS $$extra_exclude include \
+               | tar -xf - -C $(PREFIX)$(DEVEL_PREFIX)
+ ifneq ($(strip $(UCLIBC_HAS_FLOATS)),y)
+       # Remove floating point related headers since float support is disabled.
+diff -Nur uClibc-0.9.28/Rules.mak uClibc-0.9.28-avr32-20060621/Rules.mak
+--- uClibc-0.9.28/Rules.mak    2005-08-18 00:49:49.000000000 +0200
++++ uClibc-0.9.28-avr32-20060621/Rules.mak     2006-06-21 11:35:57.000000000 +0200
+@@ -231,6 +231,10 @@
+       UCLIBC_LDSO=ld.so.1
+ endif
++ifeq ($(strip $(TARGET_ARCH)),avr32)
++      CPU_CFLAGS-$(CONFIG_AP7000)     += -mcpu=ap7000
++endif
++
+ # Keep the check_gcc from being needlessly executed
+ ifndef PIEFLAG
+ ifneq ($(UCLIBC_BUILD_PIE),y)
+@@ -266,7 +270,11 @@
+ # If -msoft-float isn't supported, we want an error anyway.
+ # Hmm... might need to revisit this for arm since it has 2 different
+ # soft float encodings.
++ifeq ($(strip $(TARGET_ARCH)),avr32)
++# GCC on avr32 doesn't support -msoft-float, it's the default.
++else
+     CPU_CFLAGS += -msoft-float
++endif
+ ifeq ($(strip $(TARGET_ARCH)),arm)
+ # No longer needed with current toolchains, but leave it here for now.
+ # If anyone is actually still using gcc 2.95 (say), they can uncomment it.
+diff -Nur uClibc-0.9.28/Rules.mak.orig uClibc-0.9.28-avr32-20060621/Rules.mak.orig
+--- uClibc-0.9.28/Rules.mak.orig       1970-01-01 01:00:00.000000000 +0100
++++ uClibc-0.9.28-avr32-20060621/Rules.mak.orig        2006-06-21 11:35:56.000000000 +0200
+@@ -0,0 +1,358 @@
++# Rules.make for uClibc
++#
++# Copyright (C) 2000 by Lineo, inc.
++# Copyright (C) 2000-2002 Erik Andersen <andersen@uclibc.org>
++#
++# This program is free software; you can redistribute it and/or modify it under
++# the terms of the GNU Library 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 Library General Public License for more
++# details.
++#
++# You should have received a copy of the GNU Library 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
++
++
++#-----------------------------------------------------------
++# This file contains rules which are shared between multiple
++# Makefiles.  All normal configuration options live in the 
++# file named ".config".  Don't mess with this file unless 
++# you know what you are doing.
++
++
++#-----------------------------------------------------------
++# If you are running a cross compiler, you will want to set 
++# 'CROSS' to something more interesting ...  Target 
++# architecture is determined by asking the CC compiler what 
++# arch it compiles things for, so unless your compiler is 
++# broken, you should not need to specify TARGET_ARCH.
++#
++# Most people will set this stuff on the command line, i.e.
++#        make CROSS=arm-linux-
++# will build uClibc for 'arm'.
++
++ifndef CROSS
++CROSS=
++endif
++CC         = $(CROSS)gcc
++AR         = $(CROSS)ar
++LD         = $(CROSS)ld
++NM         = $(CROSS)nm
++RANLIB     = $(CROSS)ranlib
++STRIPTOOL  = $(CROSS)strip
++
++INSTALL    = install
++LN         = ln
++RM         = rm -f
++
++# Select the compiler needed to build binaries for your development system
++HOSTCC     = gcc
++HOSTCFLAGS = -O2 -Wall
++
++
++#---------------------------------------------------------
++# Nothing beyond this point should ever be touched by mere
++# mortals.  Unless you hang out with the gods, you should
++# probably leave all this stuff alone.
++MAJOR_VERSION := 0
++MINOR_VERSION := 9
++SUBLEVEL      := 28
++VERSION       := $(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL)
++# Ensure consistent sort order, 'gcc -print-search-dirs' behavior, etc.
++LC_ALL := C
++export MAJOR_VERSION MINOR_VERSION SUBLEVEL VERSION LC_ALL
++
++SHARED_FULLNAME:=libuClibc-$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL).so
++SHARED_MAJORNAME:=libc.so.$(MAJOR_VERSION)
++UCLIBC_LDSO:=ld-uClibc.so.$(MAJOR_VERSION)
++LIBNAME:=libc.a
++LIBC:=$(TOPDIR)libc/$(LIBNAME)
++
++# Make sure DESTDIR and PREFIX can be used to install
++# PREFIX is a uClibcism while DESTDIR is a common GNUism
++ifndef PREFIX
++PREFIX = $(DESTDIR)
++endif
++
++# Pull in the user's uClibc configuration
++ifeq ($(filter $(noconfig_targets),$(MAKECMDGOALS)),)
++-include $(TOPDIR).config
++endif
++
++ifndef CROSS
++CROSS=$(subst ",, $(strip $(CROSS_COMPILER_PREFIX)))
++endif
++
++# A nifty macro to make testing gcc features easier
++check_gcc=$(shell \
++      if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; \
++      then echo "$(1)"; else echo "$(2)"; fi)
++check_as=$(shell \
++      if $(CC) -Wa,$(1) -Wa,-Z -c -o /dev/null -xassembler /dev/null > /dev/null 2>&1; \
++      then echo "-Wa,$(1)"; fi)
++
++# Setup some shortcuts so that silent mode is silent like it should be
++ifeq ($(subst s,,$(MAKEFLAGS)),$(MAKEFLAGS))
++export MAKE_IS_SILENT=n
++SECHO=@echo
++SHELL_SET_X=set -x
++else
++export MAKE_IS_SILENT=y
++SECHO=-@false
++SHELL_SET_X=set +x
++endif
++
++# Make certain these contain a final "/", but no "//"s.
++TARGET_ARCH:=$(shell grep -s ^TARGET_ARCH $(TOPDIR)/.config | sed -e 's/^TARGET_ARCH=//' -e 's/"//g')
++RUNTIME_PREFIX:=$(strip $(subst //,/, $(subst ,/, $(subst ",, $(strip $(RUNTIME_PREFIX))))))
++DEVEL_PREFIX:=$(strip $(subst //,/, $(subst ,/, $(subst ",, $(strip $(DEVEL_PREFIX))))))
++export RUNTIME_PREFIX DEVEL_PREFIX
++
++ARFLAGS:=cr
++
++OPTIMIZATION:=
++PICFLAG:=-fPIC
++PIEFLAG_NAME:=-fPIE
++
++# Some nice CPU specific optimizations
++ifeq ($(strip $(TARGET_ARCH)),i386)
++      OPTIMIZATION+=$(call check_gcc,-mpreferred-stack-boundary=2,)
++      OPTIMIZATION+=$(call check_gcc,-falign-jumps=0 -falign-loops=0,-malign-jumps=0 -malign-loops=0)
++      CPU_CFLAGS-$(CONFIG_386)+=-march=i386
++      CPU_CFLAGS-$(CONFIG_486)+=-march=i486
++      CPU_CFLAGS-$(CONFIG_ELAN)+=-march=i486
++      CPU_CFLAGS-$(CONFIG_586)+=-march=i586
++      CPU_CFLAGS-$(CONFIG_586MMX)+=$(call check_gcc,-march=pentium-mmx,-march=i586)
++      CPU_CFLAGS-$(CONFIG_686)+=-march=i686
++      CPU_CFLAGS-$(CONFIG_PENTIUMII)+=$(call check_gcc,-march=pentium2,-march=i686)
++      CPU_CFLAGS-$(CONFIG_PENTIUMIII)+=$(call check_gcc,-march=pentium3,-march=i686)
++      CPU_CFLAGS-$(CONFIG_PENTIUM4)+=$(call check_gcc,-march=pentium4,-march=i686)
++      CPU_CFLAGS-$(CONFIG_K6)+=$(call check_gcc,-march=k6,-march=i586)
++      CPU_CFLAGS-$(CONFIG_K7)+=$(call check_gcc,-march=athlon,-malign-functions=4 -march=i686)
++      CPU_CFLAGS-$(CONFIG_CRUSOE)+=-march=i686 -malign-functions=0 -malign-jumps=0 -malign-loops=0
++      CPU_CFLAGS-$(CONFIG_WINCHIPC6)+=$(call check_gcc,-march=winchip-c6,-march=i586)
++      CPU_CFLAGS-$(CONFIG_WINCHIP2)+=$(call check_gcc,-march=winchip2,-march=i586)
++      CPU_CFLAGS-$(CONFIG_CYRIXIII)+=$(call check_gcc,-march=c3,-march=i486) -malign-functions=0 -malign-jumps=0 -malign-loops=0
++      CPU_CFLAGS-$(CONFIG_NEHEMIAH)+=$(call check_gcc,-march=c3-2,-march=i686)
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),arm)
++      OPTIMIZATION+=-fstrict-aliasing
++      CPU_LDFLAGS-$(ARCH_LITTLE_ENDIAN)+=-EL
++      CPU_LDFLAGS-$(ARCH_BIG_ENDIAN)+=-EB
++      CPU_CFLAGS-$(ARCH_LITTLE_ENDIAN)+=-mlittle-endian
++      CPU_CFLAGS-$(ARCH_BIG_ENDIAN)+=-mbig-endian
++      CPU_CFLAGS-$(CONFIG_GENERIC_ARM)+=
++      CPU_CFLAGS-$(CONFIG_ARM610)+=-mtune=arm610 -march=armv3
++      CPU_CFLAGS-$(CONFIG_ARM710)+=-mtune=arm710 -march=armv3
++      CPU_CFLAGS-$(CONFIG_ARM720T)+=-mtune=arm7tdmi -march=armv4
++      CPU_CFLAGS-$(CONFIG_ARM920T)+=-mtune=arm9tdmi -march=armv4
++      CPU_CFLAGS-$(CONFIG_ARM922T)+=-mtune=arm9tdmi -march=armv4
++      CPU_CFLAGS-$(CONFIG_ARM926T)+=-mtune=arm9tdmi -march=armv5
++      CPU_CFLAGS-$(CONFIG_ARM1136JF_S)+=-mtune=arm1136jf-s -march=armv6
++      CPU_CFLAGS-$(CONFIG_ARM_SA110)+=-mtune=strongarm110 -march=armv4
++      CPU_CFLAGS-$(CONFIG_ARM_SA1100)+=-mtune=strongarm1100 -march=armv4
++      CPU_CFLAGS-$(CONFIG_ARM_XSCALE)+=$(call check_gcc,-mtune=xscale,-mtune=strongarm110)
++      CPU_CFLAGS-$(CONFIG_ARM_XSCALE)+=-march=armv4 -Wa,-mcpu=xscale
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),mips)
++      CPU_CFLAGS-$(CONFIG_MIPS_ISA_1)+=-mips1
++      CPU_CFLAGS-$(CONFIG_MIPS_ISA_2)+=-mips2 -mtune=mips2
++      CPU_CFLAGS-$(CONFIG_MIPS_ISA_3)+=-mips3 -mtune=mips3
++      CPU_CFLAGS-$(CONFIG_MIPS_ISA_4)+=-mips4 -mtune=mips4
++      CPU_CFLAGS-$(CONFIG_MIPS_ISA_MIPS32)+=-mips32 -mtune=mips32
++      CPU_CFLAGS-$(CONFIG_MIPS_ISA_MIPS64)+=-mips64 -mtune=mips32
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),sh)
++      OPTIMIZATION+=-fstrict-aliasing
++      OPTIMIZATION+= $(call check_gcc,-mprefergot,)
++      CPU_LDFLAGS-$(ARCH_LITTLE_ENDIAN)+=-EL
++      CPU_LDFLAGS-$(ARCH_BIG_ENDIAN)+=-EB
++      CPU_CFLAGS-$(ARCH_LITTLE_ENDIAN)+=-ml
++      CPU_CFLAGS-$(ARCH_BIG_ENDIAN)+=-mb
++      CPU_CFLAGS-$(CONFIG_SH2)+=-m2
++      CPU_CFLAGS-$(CONFIG_SH3)+=-m3
++ifeq ($(strip $(UCLIBC_HAS_FLOATS)),y)
++      CPU_CFLAGS-$(CONFIG_SH2A)+=-m2a
++      CPU_CFLAGS-$(CONFIG_SH4)+=-m4
++else
++      CPU_CFLAGS-$(CONFIG_SH2A)+=-m2a-nofpu
++      CPU_CFLAGS-$(CONFIG_SH4)+=-m4-nofpu
++endif
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),sh64)
++      OPTIMIZATION+=-fstrict-aliasing
++      CPU_LDFLAGS-$(ARCH_LITTLE_ENDIAN):=-EL
++      CPU_LDFLAGS-$(ARCH_BIG_ENDIAN):=-EB
++      CPU_CFLAGS-$(ARCH_LITTLE_ENDIAN):=-ml
++      CPU_CFLAGS-$(ARCH_BIG_ENDIAN):=-mb
++      CPU_CFLAGS-$(CONFIG_SH5)+=-m5-32media
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),h8300)
++      CPU_LDFLAGS-$(CONFIG_H8300H)+= -ms8300h
++      CPU_LDFLAGS-$(CONFIG_H8S)   += -ms8300s
++      CPU_CFLAGS-$(CONFIG_H8300H) += -mh -mint32 -fsigned-char
++      CPU_CFLAGS-$(CONFIG_H8S)    += -ms -mint32 -fsigned-char
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),cris)
++      CPU_LDFLAGS-$(CONFIG_CRIS)+=-mcrislinux
++      CPU_CFLAGS-$(CONFIG_CRIS)+=-mlinux
++      PICFLAG:=-fpic
++      PIEFLAG_NAME:=-fpie
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),powerpc)
++# PowerPC can hold 8192 entries in its GOT with -fpic which is more than
++# enough. Therefore use -fpic which will reduce code size and generates
++# faster code.
++      PICFLAG:=-fpic
++      PIEFLAG_NAME:=-fpie
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),frv)
++      CPU_LDFLAGS-$(CONFIG_FRV)+=-melf32frvfd
++      CPU_CFLAGS-$(CONFIG_FRV)+=-mfdpic
++      # Using -pie causes the program to have an interpreter, which is
++      # forbidden, so we must make do with -shared.  Unfortunately,
++      # -shared by itself would get us global function descriptors
++      # and calls through PLTs, dynamic resolution of symbols, etc,
++      # which would break as well, but -Bsymbolic comes to the rescue.
++      export LDPIEFLAG:=-shared -Bsymbolic
++      UCLIBC_LDSO=ld.so.1
++endif
++
++ifeq ($(strip $(TARGET_ARCH)),avr32)
++      CPU_CFLAGS-$(CONFIG_AP7000)     += -mcpu=ap7000
++endif
++
++# Keep the check_gcc from being needlessly executed
++ifndef PIEFLAG
++ifneq ($(UCLIBC_BUILD_PIE),y)
++export PIEFLAG:=
++else
++export PIEFLAG:=$(call check_gcc,$(PIEFLAG_NAME),$(PICFLAG))
++endif
++endif
++# We need to keep track of both the CC PIE flag (above) as 
++# well as the LD PIE flag (below) because we can't rely on 
++# gcc passing -pie if we used -fPIE
++ifndef LDPIEFLAG
++ifneq ($(UCLIBC_BUILD_PIE),y)
++export LDPIEFLAG:=
++else
++export LDPIEFLAG:=$(shell $(LD) --help | grep -q pie && echo "-Wl,-pie")
++endif
++endif
++
++# Use '-Os' optimization if available, else use -O2, allow Config to override
++OPTIMIZATION+=$(call check_gcc,-Os,-O2)
++# Use the gcc 3.4 -funit-at-a-time optimization when available
++OPTIMIZATION+=$(call check_gcc,-funit-at-a-time,)
++
++# Add a bunch of extra pedantic annoyingly strict checks
++XWARNINGS=$(subst ",, $(strip $(WARNINGS))) -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing
++XARCH_CFLAGS=$(subst ",, $(strip $(ARCH_CFLAGS)))
++CPU_CFLAGS=$(subst ",, $(strip $(CPU_CFLAGS-y)))
++
++LDADD_LIBFLOAT=
++ifeq ($(strip $(UCLIBC_HAS_SOFT_FLOAT)),y)
++# Add -msoft-float to the CPU_FLAGS since ldso and libdl ignore CFLAGS.
++# If -msoft-float isn't supported, we want an error anyway.
++# Hmm... might need to revisit this for arm since it has 2 different
++# soft float encodings.
++    CPU_CFLAGS += -msoft-float
++ifeq ($(strip $(TARGET_ARCH)),arm)
++# No longer needed with current toolchains, but leave it here for now.
++# If anyone is actually still using gcc 2.95 (say), they can uncomment it.
++#    LDADD_LIBFLOAT=-lfloat
++endif
++endif
++
++SSP_DISABLE_FLAGS:=$(call check_gcc,-fno-stack-protector,)
++ifeq ($(UCLIBC_BUILD_SSP),y)
++SSP_CFLAGS:=$(call check_gcc,-fno-stack-protector-all,)
++SSP_CFLAGS+=$(call check_gcc,-fstack-protector,)
++SSP_ALL_CFLAGS:=$(call check_gcc,-fstack-protector-all,)
++else
++SSP_CFLAGS:=$(SSP_DISABLE_FLAGS)
++endif
++
++# Some nice CFLAGS to work with
++CFLAGS:=$(XWARNINGS) $(CPU_CFLAGS) $(SSP_CFLAGS) \
++      -fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)include -I.
++LDFLAGS_NOSTRIP:=$(CPU_LDFLAGS-y) -shared --warn-common --warn-once -z combreloc -z defs
++
++ifeq ($(DODEBUG),y)
++    #CFLAGS += -g3
++    CFLAGS += -O0 -g3
++    LDFLAGS := $(LDFLAGS_NOSTRIP)
++    STRIPTOOL:= true -Since_we_are_debugging
++else
++    CFLAGS += $(OPTIMIZATION) $(XARCH_CFLAGS)
++    LDFLAGS := $(LDFLAGS_NOSTRIP) -s
++endif
++
++ifeq ($(UCLIBC_BUILD_RELRO),y)
++LDFLAGS+=-z relro
++endif
++
++ifeq ($(UCLIBC_BUILD_NOW),y)
++LDFLAGS+=-z now
++endif
++
++# Sigh, some stupid versions of gcc can't seem to cope with '-iwithprefix include'
++#CFLAGS+=-iwithprefix include
++CFLAGS+=-isystem $(shell $(CC) -print-file-name=include)
++
++ifneq ($(DOASSERTS),y)
++    CFLAGS += -DNDEBUG
++endif
++
++CFLAGS_NOPIC:=$(CFLAGS)
++ifeq ($(DOPIC),y)
++    CFLAGS += $(PICFLAG)
++endif
++
++ifeq ($(DL_FINI_CRT_COMPAT),y)
++CFLAGS += -D_DL_FINI_CRT_COMPAT
++endif
++
++# Keep the check_as from being needlessly executed
++ASFLAGS = $(CFLAGS)
++ifndef ASFLAGS_NOEXEC
++ifeq ($(UCLIBC_BUILD_NOEXECSTACK),y)
++export ASFLAGS_NOEXEC := $(call check_as,--noexecstack)
++else
++export ASFLAGS_NOEXEC :=
++endif
++endif
++ASFLAGS += $(ASFLAGS_NOEXEC)
++
++LIBGCC_CFLAGS ?= $(CFLAGS) $(CPU_CFLAGS-y)
++LIBGCC:=$(shell $(CC) $(LIBGCC_CFLAGS) -print-libgcc-file-name)
++LIBGCC_DIR:=$(dir $(LIBGCC))
++
++########################################
++#
++# uClinux shared lib support
++#
++
++ifeq ($(CONFIG_BINFMT_SHARED_FLAT),y)
++  # For the shared version of this, we specify no stack and its library ID
++  FLTFLAGS += -s 0
++  LIBID=1
++  export LIBID FLTFLAGS
++  SHARED_TARGET = lib/libc
++endif
++
++TARGET_ARCH:=$(strip $(subst ",, $(strip $(TARGET_ARCH))))
+diff -Nur uClibc-0.9.28/utils/ldd.c uClibc-0.9.28-avr32-20060621/utils/ldd.c
+--- uClibc-0.9.28/utils/ldd.c  2005-08-18 00:49:41.000000000 +0200
++++ uClibc-0.9.28-avr32-20060621/utils/ldd.c   2006-06-21 11:35:57.000000000 +0200
+@@ -56,6 +56,11 @@
+ #define ELFCLASSM     ELFCLASS32
+ #endif
++#if defined(__avr32__)
++#define MATCH_MACHINE(x) (x == EM_AVR32)
++#define ELFCLASSM     ELFCLASS32
++#endif
++
+ #if defined(__s390__)
+ #define MATCH_MACHINE(x) (x == EM_S390)
+ #define ELFCLASSM     ELFCLASS32
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/uClibc-0.9.28-avr32-20061019.patch b/packages/uclibc/uclibc-0.9.28/avr32/uClibc-0.9.28-avr32-20061019.patch
new file mode 100644 (file)
index 0000000..6608b4d
--- /dev/null
@@ -0,0 +1,4080 @@
+Index: uClibc-0.9.28-avr32/Makefile
+===================================================================
+--- uClibc-0.9.28-avr32.orig/Makefile  2006-10-19 15:05:49.000000000 +0200
++++ uClibc-0.9.28-avr32/Makefile       2006-10-19 15:05:52.000000000 +0200
+@@ -163,7 +163,7 @@ install_dev:
+       else \
+               extra_exclude="" ; \
+       fi ; \
+-      tar -chf - include --exclude .svn --exclude CVS $$extra_exclude \
++      tar -chf - --exclude .svn --exclude CVS $$extra_exclude include \
+               | tar -xf - -C $(PREFIX)$(DEVEL_PREFIX)
+ ifneq ($(strip $(UCLIBC_HAS_FLOATS)),y)
+       # Remove floating point related headers since float support is disabled.
+Index: uClibc-0.9.28-avr32/extra/scripts/fix_includes.sh
+===================================================================
+--- uClibc-0.9.28-avr32.orig/extra/scripts/fix_includes.sh     2006-10-19 15:05:49.000000000 +0200
++++ uClibc-0.9.28-avr32/extra/scripts/fix_includes.sh  2006-10-19 15:05:52.000000000 +0200
+@@ -78,36 +78,6 @@ if [ ! -d "$KERNEL_SOURCE" ]; then
+     exit 1;
+ fi;
+-if [ -f "$KERNEL_SOURCE/Makefile" ] ; then
+-# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
+-eval `sed -n -e 's/^\([A-Z]*\) = \([0-9]*\)$/\1=\2/p' -e 's/^\([A-Z]*\) = \(-[-a-z0-9]*\)$/\1=\2/p' $KERNEL_SOURCE/Makefile`
+-else
+-ver=`grep UTS_RELEASE $KERNEL_SOURCE/include/linux/version.h | cut -d '"' -f 2`
+-VERSION=`echo "$ver" | cut -d '.' -f 1`
+-PATCHLEVEL=`echo "$ver" | cut -d '.' -f 2`
+-if echo "$ver" | grep -q '-' ; then
+-SUBLEVEL=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.//" | cut -d '-' -f 1`
+-EXTRAVERSION=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}-//"`
+-else
+-SUBLEVEL=`echo "$ver" | cut -d '.' -f 3`
+-#EXTRAVERSION=
+-fi
+-fi
+-if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ]
+-then
+-    echo "Unable to determine version for kernel headers"
+-    echo -e "\tprovided in directory $KERNEL_SOURCE"
+-    exit 1
+-fi
+-
+-if [ "$MAKE_IS_SILENT" != "y" ]; then
+-echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION}"
+-echo -e "\n"
+-echo "Using kernel headers from $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} for architecture '$TARGET_ARCH'"
+-echo -e "\tprovided in directory $KERNEL_SOURCE"
+-echo -e "\n"
+-fi
+-
+ # Create a symlink to include/asm
+ rm -f include/asm*
+@@ -172,7 +142,7 @@ fi;
+ # Annoyingly, 2.6.x kernel headers also need an include/asm-generic/ directory
+-if [ $VERSION -eq 2 ] && [ $PATCHLEVEL -ge 6 ] ; then
++if [ -d $KERNEL_SOURCE/include/asm-generic ] ; then
+     ln -fs $KERNEL_SOURCE/include/asm-generic include/asm-generic
+ fi;
+Index: uClibc-0.9.28-avr32/libc/Makefile
+===================================================================
+--- uClibc-0.9.28-avr32.orig/libc/Makefile     2006-10-19 15:05:49.000000000 +0200
++++ uClibc-0.9.28-avr32/libc/Makefile  2006-10-19 15:05:52.000000000 +0200
+@@ -59,7 +59,7 @@ $(LIBNAME) shared_$(LIBNAME) ar-target: 
+       $(AR) dN 2 $(LIBNAME) $$objs && \
+       $(AR) dN 2 $(LIBNAME) $$objs
+       @for objfile in obj.signal \
+-                      obj.string.generic obj.string.$(TARGET_ARCH) obj.string \
++                      obj.string obj.string.generic obj.string.$(TARGET_ARCH) \
+                       obj.sysdeps.common obj.sysdeps.$(TARGET_ARCH) ; do \
+               if [ -e $$objfile ] ; then \
+                       if [ "$(MAKE_IS_SILENT)" = "n" ] ; then \
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/common/getrusage.c
+===================================================================
+--- uClibc-0.9.28-avr32.orig/libc/sysdeps/linux/common/getrusage.c     2006-10-19 15:05:49.000000000 +0200
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/common/getrusage.c  2006-10-19 15:05:52.000000000 +0200
+@@ -10,4 +10,4 @@
+ #include "syscalls.h"
+ #include <unistd.h>
+ #include <wait.h>
+-_syscall2(int, getrusage, int, who, struct rusage *, usage);
++_syscall2(int, getrusage, __rusage_who_t, who, struct rusage *, usage);
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/common/__syscall_fcntl.c
+===================================================================
+--- uClibc-0.9.28-avr32.orig/libc/sysdeps/linux/common/__syscall_fcntl.c       2006-10-19 15:05:49.000000000 +0200
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/common/__syscall_fcntl.c    2006-10-19 15:05:52.000000000 +0200
+@@ -12,7 +12,7 @@
+ #include <fcntl.h>
+ #if defined __UCLIBC_HAS_LFS__ && defined __NR_fcntl64
+-extern int __libc_fcntl64(int fd, int cmd, long arg);
++extern int __libc_fcntl64(int fd, int cmd, ...);
+ #endif
+ #define __NR___syscall_fcntl __NR_fcntl
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/common/open64.c
+===================================================================
+--- uClibc-0.9.28-avr32.orig/libc/sysdeps/linux/common/open64.c        2006-10-19 15:05:49.000000000 +0200
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/common/open64.c     2006-10-19 15:05:52.000000000 +0200
+@@ -26,7 +26,7 @@
+ #endif
+ #ifdef __UCLIBC_HAS_LFS__
+-extern int __libc_open (__const char *file, int oflag, mode_t mode);
++extern int __libc_open (__const char *file, int oflag, ...);
+ /* Open FILE with access OFLAG.  If OFLAG includes O_CREAT,
+    a third argument is the file protection.  */
+Index: uClibc-0.9.28-avr32/extra/Configs/Config.avr32
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/extra/Configs/Config.avr32     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,42 @@
++#
++# For a description of the syntax of this configuration file,
++# see extra/config/Kconfig-language.txt
++#
++
++config HAVE_ELF
++      bool
++      default y
++
++config TARGET_ARCH
++      default "avr32"
++
++config ARCH_CFLAGS
++      string
++
++config ARCH_LDFLAGS
++      string
++
++config LIBGCC_CFLAGS
++      string
++
++config ARCH_SUPPORTS_BIG_ENDIAN
++      bool
++      default y
++
++config UCLIBC_COMPLETELY_PIC
++      select FORCE_SHAREABLE_TEXT_SEGMENTS
++      bool
++      default y
++
++choice
++      prompt "Target CPU Type"
++      default CONFIG_AP7000
++
++config CONFIG_AP7000
++      bool "AP7000"
++
++endchoice
++
++config LINKRELAX
++      bool "Enable linker optimizations"
++      default n
+Index: uClibc-0.9.28-avr32/extra/Configs/Config.in
+===================================================================
+--- uClibc-0.9.28-avr32.orig/extra/Configs/Config.in   2006-10-19 15:05:49.000000000 +0200
++++ uClibc-0.9.28-avr32/extra/Configs/Config.in        2006-10-19 15:05:52.000000000 +0200
+@@ -16,6 +16,9 @@ config TARGET_alpha
+ config TARGET_arm
+       bool "arm"
++config TARGET_avr32
++      bool "avr32"
++
+ config TARGET_bfin
+       bool "bfin"
+@@ -83,6 +86,10 @@ if TARGET_arm
+ source "extra/Configs/Config.arm"
+ endif
++if TARGET_avr32
++source "extra/Configs/Config.avr32"
++endif
++
+ if TARGET_bfin
+ source "extra/Configs/Config.bfin"
+ endif
+Index: uClibc-0.9.28-avr32/include/elf.h
+===================================================================
+--- uClibc-0.9.28-avr32.orig/include/elf.h     2006-10-19 15:05:49.000000000 +0200
++++ uClibc-0.9.28-avr32/include/elf.h  2006-10-19 15:05:52.000000000 +0200
+@@ -261,6 +261,8 @@ typedef struct
+ #define EM_NIOS32     0xfebb          /* Altera Nios 32 */
+ #define EM_ALTERA_NIOS2  0x9ee5       /* Altera Nios II */
++#define EM_AVR32      0x18ad
++
+ /* V850 backend magic number.  Written in the absense of an ABI.  */
+ #define EM_CYGNUS_V850 0x9080
+@@ -2687,6 +2689,55 @@ typedef Elf32_Addr Elf32_Conflict;
+ /* Keep this the last entry.  */
+ #define R_V850_NUM            25
++/* Atmel AVR32 relocations.  */
++#define R_AVR32_NONE          0
++#define R_AVR32_32            1
++#define R_AVR32_16            2
++#define R_AVR32_8             3
++#define R_AVR32_32_PCREL      4
++#define R_AVR32_16_PCREL      5
++#define R_AVR32_8_PCREL               6
++#define R_AVR32_DIFF32                7
++#define R_AVR32_DIFF16                8
++#define R_AVR32_DIFF8         9
++#define R_AVR32_GOT32         10
++#define R_AVR32_GOT16         11
++#define R_AVR32_GOT8          12
++#define R_AVR32_21S           13
++#define R_AVR32_16U           14
++#define R_AVR32_16S           15
++#define R_AVR32_8S            16
++#define R_AVR32_8S_EXT                17
++#define R_AVR32_22H_PCREL     18
++#define R_AVR32_18W_PCREL     19
++#define R_AVR32_16B_PCREL     20
++#define R_AVR32_16N_PCREL     21
++#define R_AVR32_14UW_PCREL    22
++#define R_AVR32_11H_PCREL     23
++#define R_AVR32_10UW_PCREL    24
++#define R_AVR32_9H_PCREL      25
++#define R_AVR32_9UW_PCREL     26
++#define R_AVR32_HI16          27
++#define R_AVR32_LO16          28
++#define R_AVR32_GOTPC         29
++#define R_AVR32_GOTCALL               30
++#define R_AVR32_LDA_GOT               31
++#define R_AVR32_GOT21S                32
++#define R_AVR32_GOT18SW               33
++#define R_AVR32_GOT16S                34
++#define R_AVR32_GOT7UW                35
++#define R_AVR32_32_CPENT      36
++#define R_AVR32_CPCALL                37
++#define R_AVR32_16_CP         38
++#define R_AVR32_9W_CP         39
++#define R_AVR32_RELATIVE      40
++#define R_AVR32_GLOB_DAT      41
++#define R_AVR32_JMP_SLOT      42
++#define R_AVR32_ALIGN         43
++#define R_AVR32_NUM           44
++
++/* AVR32 dynamic tags */
++#define DT_AVR32_GOTSZ                0x70000001 /* Total size of GOT in bytes */
+ #define R_H8_NONE       0
+ #define R_H8_DIR32      1
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/Makefile      2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,93 @@
++# Makefile for uClibc
++#
++# Copyright (C) 2000-2003 Erik Andersen <andersen@uclibc.org>
++#
++# This program is free software; you can redistribute it and/or modify it under
++# the terms of the GNU Library 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 Library General Public License for more
++# details.
++#
++# You should have received a copy of the GNU Library 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
++
++TOPDIR=../../../../
++include $(TOPDIR)Rules.mak
++ASFLAGS=$(CFLAGS)
++
++CRT_SRC       = crt1.S
++CRT_OBJ = crt1.o
++SCRT_OBJ = $(patsubst %,S%, $(CRT_OBJ))
++CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
++
++SSRC=__longjmp.S setjmp.S bsd-setjmp.S vfork.S \
++      bsd-_setjmp.S sigrestorer.S syscall.S
++SOBJS=$(patsubst %.S,%.o, $(SSRC))
++
++CSRC=clone.c brk.c sigaction.c mmap.c
++COBJS=$(patsubst %.c,%.o, $(CSRC))
++
++OBJS=$(SOBJS) $(COBJS)
++
++OBJ_LIST=../../../obj.sysdeps.$(TARGET_ARCH)
++
++all: $(OBJ_LIST)
++
++$(OBJ_LIST): $(OBJS) $(CRT_OBJ) $(SCRT_OBJ) $(CTOR_TARGETS)
++      echo $(patsubst %, sysdeps/linux/$(TARGET_ARCH)/%, $(OBJS)) > $(OBJ_LIST)
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp $(CRT_OBJ) $(SCRT_OBJ) $(TOPDIR)lib/
++
++$(CRT_OBJ): $(CRT_SRC)
++      $(CC) $(ASFLAGS) -DL_$* $< -c -o $*.o
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(SCRT_OBJ): $(CRT_SRC)
++      $(CC) $(ASFLAGS) $(PIEFLAG) -DL_$* $< -c -o $*.o
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(SOBJS): %.o : %.S
++      $(CC) $(ASFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++$(COBJS): %.o : %.c
++      $(CC) $(CFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $*.o
++
++ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
++crti.o: crti.S
++      $(CC) $(ASFLAGS) -c crti.S -o crti.o
++
++$(TOPDIR)lib/crti.o: crti.o
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp crti.o $(TOPDIR)lib/
++
++crtn.o: crtn.S
++      $(CC) $(ASFLAGS) -c crtn.S -o crtn.o
++
++$(TOPDIR)lib/crtn.o: crtn.o
++      $(INSTALL) -d $(TOPDIR)lib/
++      cp crtn.o $(TOPDIR)lib/
++else
++$(TOPDIR)lib/crti.o:
++      $(INSTALL) -d $(TOPDIR)lib/
++      $(AR) $(ARFLAGS) $(TOPDIR)lib/crti.o
++$(TOPDIR)lib/crtn.o:
++      $(INSTALL) -d $(TOPDIR)lib/
++      $(AR) $(ARFLAGS) $(TOPDIR)lib/crtn.o
++endif
++
++
++headers:
++#     $(LN) -fs ../libc/sysdeps/linux/avr32/fpu_control.h $(TOPDIR)/include/
++
++clean:
++      $(RM) *.[oa] *~ core
++      $(RM) bits/sysnum.h
++      $(RM) gmon-start.S
++
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/__longjmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/__longjmp.S   2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,17 @@
++/* longjmp for AVR32
++ *
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      .global __longjmp
++      .type   __longjmp,"function"
++      .align  1
++__longjmp:
++      ldm     r12++, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr
++      mov     r12, r11        /* get the return value right */
++      mustr   r8              /* restore status register (lower half) */
++      cp      r12, 0          /* can't return zero */
++      frs
++      moveq   r12, 1
++      mov     pc,lr
++      .size   __longjmp, . - __longjmp
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/_mmap.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/_mmap.c       2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,33 @@
++/* Copyright (C) 2005 Atmel Norway
++
++   This program is free software; you can redistribute it and/or modify it under
++   the terms of the GNU Library 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 Library General Public License for more
++   details.
++
++   You should have received a copy of the GNU Library 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
++
++   Derived in part from the Linux-8086 C library, the GNU C Library, and several
++   other sundry sources.  Files within this library are copyright by their
++   respective copyright holders.
++ */
++
++#include <errno.h>
++#include <sys/mman.h>
++#include <sys/syscall.h>
++
++#define __NR_mmap2 __NR_mmap
++
++static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot, int, flags, int, fd, __off_t, pgoff);
++
++__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
++{
++      return mmap2(addr, len, prot, flags, fd, offset >> 12);
++}
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/atomicity.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/atomicity.h      2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,86 @@
++/* Low-level functions for atomic operations.  AVR32 version.
++   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef _ATOMICITY_H
++#define _ATOMICITY_H 1
++
++#include <inttypes.h>
++
++static inline int
++__attribute__((unused))
++exchange_and_add (volatile uint32_t *mem, int val)
++{
++      int tmp, result;
++
++      __asm__ __volatile__(
++              "/* Inline exchange and add */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %3\n"
++              "       add     %1, %0, %4\n"
++              "       stcond  %2, %1\n"
++              "       brne    1b"
++              : "=&r"(result), "=&r"(tmp), "=m"(*mem)
++              : "m"(*mem), "r"(val)
++              : "cc", "memory");
++
++      return result;
++}
++
++static inline void
++__attribute__((unused))
++atomic_add (volatile uin32_t *mem, int val)
++{
++      int result;
++
++      __asm__ __volatile__(
++              "/* Inline atomic add */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %2\n"
++              "       add     %0, %3\n"
++              "       stcond  %2, %0\n"
++              "       brne    1b"
++              : "=&r"(result), "=m"(*mem)
++              : "m"(*mem), "r"(val)
++              : "cc", "memory");
++}
++
++static inline int
++__attribute__((unused))
++compare_and_swap(volatile long int *p, long int oldval, long int newval)
++{
++      long int result, tmp;
++
++      __asm__ __volatile__(
++              "/* Inline compare and swap */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %1, %3\n"
++              "       cp.w    %1, %5\n"
++              "       sreq    %0\n"
++              "       brne    2f\n"
++              "       stcond  %2, %4\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=&r"(tmp), "=m"(*p)
++              : "m"(*p), "r"(newval), "r"(oldval)
++              : "cc", "memory");
++
++      return result;
++}
++
++#endif /* atomicity.h */
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/byteswap.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/byteswap.h       2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,80 @@
++/* Macros to swap the order of bytes in integer values.
++   Copyright (C) 2005 Atmel Norway.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
++# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
++#endif
++
++#ifndef _BITS_BYTESWAP_H
++#define _BITS_BYTESWAP_H 1
++
++/* Swap bytes in 16 bit value.  */
++#if defined __GNUC__
++# define __bswap_16(x) (__extension__ __builtin_bswap_16(x))
++#else
++/* This is better than nothing.  */
++static __inline unsigned short int
++__bswap_16 (unsigned short int __bsx)
++{
++      return ((((__bsx) >> 8) & 0xff) | (((__bsx) & 0xff) << 8));
++}
++#endif
++
++/* Swap bytes in 32 bit value.  */
++#if defined __GNUC__
++# define __bswap_32(x) (__extension__ __builtin_bswap_32(x))
++#else
++static __inline unsigned int
++__bswap_32 (unsigned int __bsx)
++{
++  return ((((__bsx) & 0xff000000) >> 24) | (((__bsx) & 0x00ff0000) >>  8) |
++        (((__bsx) & 0x0000ff00) <<  8) | (((__bsx) & 0x000000ff) << 24));
++}
++#endif
++
++#if defined __GNUC__
++/* Swap bytes in 64 bit value.  */
++# define __bswap_constant_64(x)                               \
++      ((((x) & 0xff00000000000000ull) >> 56)          \
++       | (((x) & 0x00ff000000000000ull) >> 40)        \
++       | (((x) & 0x0000ff0000000000ull) >> 24)        \
++       | (((x) & 0x000000ff00000000ull) >> 8)         \
++       | (((x) & 0x00000000ff000000ull) << 8)         \
++       | (((x) & 0x0000000000ff0000ull) << 24)        \
++       | (((x) & 0x000000000000ff00ull) << 40)        \
++       | (((x) & 0x00000000000000ffull) << 56))
++
++# define __bswap_64(x)                                                        \
++      (__extension__                                                  \
++       ({                                                             \
++               union {                                                \
++                       __extension__ unsigned long long int __ll;     \
++                       unsigned int __l[2];                           \
++               } __w, __r;                                            \
++               if (__builtin_constant_p(x))                           \
++                       __r.__ll = __bswap_constant_64(x);             \
++               else {                                                 \
++                       __w.__ll = (x);                                \
++                       __r.__l[0] = __bswap_32(__w.__l[1]);           \
++                       __r.__l[1] = __bswap_32(__w.__l[0]);           \
++               }                                                      \
++               __r.__ll;                                              \
++       }))
++#endif
++
++#endif /* _BITS_BYTESWAP_H */
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/endian.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/endian.h 2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,7 @@
++/* AVR32 is big-endian */
++
++#ifndef _ENDIAN_H
++# error "Never use <bits/endian.h> directly; include <endian.h> instead."
++#endif
++
++#define __BYTE_ORDER __BIG_ENDIAN
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/fcntl.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/fcntl.h  2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,167 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ *
++ * This file is part of the Linux kernel
++ */
++#ifndef _FCNTL_H
++# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
++#endif
++
++#include <sys/types.h>
++
++/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
++   located on an ext2 file system */
++#define O_ACCMODE       0003
++#define O_RDONLY          00
++#define O_WRONLY          01
++#define O_RDWR                    02
++#define O_CREAT                 0100  /* not fcntl */
++#define O_EXCL                  0200  /* not fcntl */
++#define O_NOCTTY        0400  /* not fcntl */
++#define O_TRUNC                01000  /* not fcntl */
++#define O_APPEND       02000
++#define O_NONBLOCK     04000
++#define O_NDELAY      O_NONBLOCK
++#define O_SYNC                010000
++#define O_ASYNC               020000
++
++#ifdef __USE_GNU
++# define O_DIRECTORY  040000  /* must be a directory */
++# define O_NOFOLLOW   0100000 /* don't follow links */
++# define O_DIRECT     0200000 /* direct disk access */
++#endif
++
++#ifdef __USE_LARGEFILE64
++# define O_LARGEFILE  0400000
++#endif
++
++/* For now Linux has synchronisity options for data and read operations.
++   We define the symbols here but let them do the same as O_SYNC since
++   this is a superset.        */
++#if defined __USE_POSIX199309 || defined __USE_UNIX98
++# define O_DSYNC      O_SYNC  /* Synchronize data.  */
++# define O_RSYNC      O_SYNC  /* Synchronize read operations.  */
++#endif
++
++#define F_DUPFD               0       /* dup */
++#define F_GETFD               1       /* get close_on_exec */
++#define F_SETFD               2       /* set/clear close_on_exec */
++#define F_GETFL               3       /* get file->f_flags */
++#define F_SETFL               4       /* set file->f_flags */
++
++#ifndef __USE_FILE_OFFSET64
++# define F_GETLK      5
++# define F_SETLK      6
++# define F_SETLKW     7
++#else
++# define F_GETLK      F_GETLK64
++# define F_SETLK      F_SETLK64
++# define F_SETLKW     F_SETLKW64
++#endif
++#define F_GETLK64     12      /*  using 'struct flock64' */
++#define F_SETLK64     13
++#define F_SETLKW64    14
++
++#if defined __USE_BSD || defined __USE_XOPEN2K
++# define F_SETOWN     8       /*  for sockets. */
++# define F_GETOWN     9       /*  for sockets. */
++#endif
++
++#ifdef __USE_GNU
++# define F_SETSIG     10      /*  for sockets. */
++# define F_GETSIG     11      /*  for sockets. */
++#endif
++
++#ifdef __USE_GNU
++# define F_SETLEASE   1024    /* Set a lease.  */
++# define F_GETLEASE   1025    /* Enquire what lease is active.  */
++# define F_NOTIFY     1026    /* Request notfications on a directory.  */
++#endif
++
++/* for F_[GET|SET]FL */
++#define FD_CLOEXEC    1       /* actually anything with low bit set goes */
++
++/* for posix fcntl() and lockf() */
++#define F_RDLCK               0
++#define F_WRLCK               1
++#define F_UNLCK               2
++
++/* for old implementation of bsd flock () */
++#define F_EXLCK               4       /* or 3 */
++#define F_SHLCK               8       /* or 4 */
++
++/* for leases */
++#define F_INPROGRESS  16
++
++#ifdef __USE_BSD
++/* operations for bsd flock(), also used by the kernel implementation */
++# define LOCK_SH      1       /* shared lock */
++# define LOCK_EX      2       /* exclusive lock */
++# define LOCK_NB      4       /* or'd with one of the above to prevent
++                                 blocking */
++# define LOCK_UN      8       /* remove lock */
++#endif
++
++#ifdef __USE_GNU
++# define LOCK_MAND    32      /* This is a mandatory flock */
++# define LOCK_READ    64      /* ... Which allows concurrent
++                                     read operations */
++# define LOCK_WRITE   128     /* ... Which allows concurrent
++                                     write operations */
++# define LOCK_RW      192     /* ... Which allows concurrent
++                                     read & write ops */
++#endif
++
++#ifdef __USE_GNU
++/* Types of directory notifications that may be requested with F_NOTIFY.  */
++# define DN_ACCESS    0x00000001      /* File accessed.  */
++# define DN_MODIFY    0x00000002      /* File modified.  */
++# define DN_CREATE    0x00000004      /* File created.  */
++# define DN_DELETE    0x00000008      /* File removed.  */
++# define DN_RENAME    0x00000010      /* File renamed.  */
++# define DN_ATTRIB    0x00000020      /* File changed attibutes.  */
++# define DN_MULTISHOT 0x80000000      /* Don't remove notifier.  */
++#endif
++
++struct flock {
++      short l_type;
++      short l_whence;
++#ifndef __USE_FILE_OFFSET64
++      __off_t l_start;
++      __off_t l_len;
++#else
++      __off64_t l_start;
++      __off64_t l_len;
++#endif
++      __pid_t l_pid;
++};
++
++#ifdef __USE_LARGEFILE64
++struct flock64 {
++      short  l_type;
++      short  l_whence;
++      __off64_t l_start;
++      __off64_t l_len;
++      __pid_t  l_pid;
++};
++#endif
++
++/* Define some more compatibility macros to be backward compatible with
++ *    BSD systems which did not managed to hide these kernel macros.  */
++#ifdef  __USE_BSD
++# define FAPPEND        O_APPEND
++# define FFSYNC         O_FSYNC
++# define FASYNC         O_ASYNC
++# define FNONBLOCK      O_NONBLOCK
++# define FNDELAY        O_NDELAY
++#endif /* Use BSD.  */
++
++/* Advise to `posix_fadvise'.  */
++#ifdef __USE_XOPEN2K
++# define POSIX_FADV_NORMAL      0 /* No further special treatment.  */
++# define POSIX_FADV_RANDOM      1 /* Expect random page references.  */
++# define POSIX_FADV_SEQUENTIAL  2 /* Expect sequential page references.  */
++# define POSIX_FADV_WILLNEED    3 /* Will need these pages.  */
++# define POSIX_FADV_DONTNEED    4 /* Don't need these pages.  */
++# define POSIX_FADV_NOREUSE     5 /* Data will be accessed once.  */
++#endif
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/kernel_stat.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/kernel_stat.h    2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,63 @@
++#ifndef _BITS_STAT_STRUCT_H
++#define _BITS_STAT_STRUCT_H
++
++/*
++ * This file provides struct stat, taken from kernel 2.6.4
++ * (include/asm-avr32/stat.h revision 1.1).
++ */
++
++struct kernel_stat {
++        unsigned long st_dev;
++        unsigned long st_ino;
++        unsigned short st_mode;
++        unsigned short st_nlink;
++        unsigned short st_uid;
++        unsigned short st_gid;
++        unsigned long  st_rdev;
++        unsigned long  st_size;
++        unsigned long  st_blksize;
++        unsigned long  st_blocks;
++        unsigned long  st_atime;
++        unsigned long  st_atime_nsec;
++        unsigned long  st_mtime;
++        unsigned long  st_mtime_nsec;
++        unsigned long  st_ctime;
++        unsigned long  st_ctime_nsec;
++        unsigned long  __unused4;
++        unsigned long  __unused5;
++};
++
++#define STAT_HAVE_NSEC 1
++
++struct kernel_stat64 {
++      unsigned long long st_dev;
++
++      unsigned long long st_ino;
++      unsigned int    st_mode;
++      unsigned int    st_nlink;
++
++      unsigned long   st_uid;
++      unsigned long   st_gid;
++
++      unsigned long long st_rdev;
++
++      long long       st_size;
++      unsigned long   __pad1;
++      unsigned long   st_blksize;
++
++      unsigned long long st_blocks;
++
++      unsigned long   st_atime;
++      unsigned long   st_atime_nsec;
++
++      unsigned long   st_mtime;
++      unsigned long   st_mtime_nsec;
++
++      unsigned long   st_ctime;
++      unsigned long   st_ctime_nsec;
++
++      unsigned long   __unused1;
++      unsigned long   __unused2;
++};
++
++#endif /* _BITS_STAT_STRUCT_H */
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/kernel_types.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/kernel_types.h   2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,56 @@
++/* Note that we use the exact same include guard #define names
++ * as asm/posix_types.h.  This will avoid gratuitous conflicts
++ * with the posix_types.h kernel header, and will ensure that
++ * our private content, and not the kernel header, will win.
++ *  -Erik
++ */
++#ifndef __ASM_AVR32_POSIX_TYPES_H
++#define __ASM_AVR32_POSIX_TYPES_H
++
++/*
++ * This file is generally used by user-level software, so you need to
++ * be a little careful about namespace pollution etc.  Also, we cannot
++ * assume GCC is being used.
++ */
++
++typedef unsigned long __kernel_dev_t;
++typedef unsigned long   __kernel_ino_t;
++typedef unsigned short  __kernel_mode_t;
++typedef unsigned short  __kernel_nlink_t;
++typedef long            __kernel_off_t;
++typedef int             __kernel_pid_t;
++typedef unsigned short  __kernel_ipc_pid_t;
++typedef unsigned int  __kernel_uid_t;
++typedef unsigned int  __kernel_gid_t;
++typedef unsigned long __kernel_size_t;
++typedef int             __kernel_ssize_t;
++typedef int             __kernel_ptrdiff_t;
++typedef long            __kernel_time_t;
++typedef long            __kernel_suseconds_t;
++typedef long            __kernel_clock_t;
++typedef int             __kernel_timer_t;
++typedef int             __kernel_clockid_t;
++typedef int             __kernel_daddr_t;
++typedef char *          __kernel_caddr_t;
++typedef unsigned short  __kernel_uid16_t;
++typedef unsigned short  __kernel_gid16_t;
++typedef unsigned int    __kernel_uid32_t;
++typedef unsigned int    __kernel_gid32_t;
++
++typedef unsigned short  __kernel_old_uid_t;
++typedef unsigned short  __kernel_old_gid_t;
++typedef unsigned short  __kernel_old_dev_t;
++
++#ifdef __GNUC__
++typedef long long       __kernel_loff_t;
++#endif
++
++typedef struct {
++#if defined(__USE_ALL)
++    int     val[2];
++#else
++    int     __val[2];
++#endif
++} __kernel_fsid_t;
++
++#endif /* __ASM_AVR32_POSIX_TYPES_H */
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/machine-gmon.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/machine-gmon.h   2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,69 @@
++/* Machine-dependent definitions for profiling support.  AVR32 version.
++   Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#define mcount_internal __mcount_internal
++
++#define _MCOUNT_DECL(frompc, selfpc) \
++static void __attribute((used)) mcount_internal(unsigned long frompc, unsigned long selfpc)
++
++/*
++ * This mcount implementation expects to get called after the prologue
++ * has been run. It also expects that r7 contains a valid frame
++ * pointer.
++ *
++ * When profiling, the compiler should generate something like this at
++ * each function entry:
++ *
++ *    pushm   r0-r7,lr        // lr mandatory, others optional
++ *    mov     r7, sp
++ *    // rest of prologue goes here
++ *    mcall   pc[.LC1 - .]
++ *      // rest of function goes here
++ * .LC1:
++ *    .long   mcount
++ *
++ * or for PIC:
++ *
++ *    pushm   r0-r7,lr
++ *    mov     r7, sp
++ *    // rest of prologue goes here
++ *    lddpc   r0, .LC1
++ * .L1: rsub  r0, pc
++ *    mcall   r0[mcount@GOT]
++ *    // rest of function goes here
++ * .LC1:
++ *    .long   .L1 - _GLOBAL_OFFSET_TABLE_
++ *
++ * This way, when mcount() is called, r7 points to the calling
++ * function's return address. It is guaranteed that calling mcount
++ * will clobber no registers except LR, which is unavoidable.
++ */
++#define MCOUNT asm(                           \
++      "       .align  4\n"                    \
++      "       .global _mcount\n"              \
++      "       .type   _mcount,@function\n"    \
++      "_mcount:\n"                            \
++      "       pushm   r8-r12,lr\n"            \
++      "       mov     r11, lr\n"              \
++      "       ld.w    r12, r7[0]\n"           \
++      "       rcall   __mcount_internal\n"    \
++      "       popm    r8-r12,pc\n"            \
++      "       .size   _mcount, . - _mcount\n" \
++      "       .weak   mcount\n"               \
++      "       mcount = _mcount");
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/mman.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/mman.h   2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,95 @@
++/* Definitions for POSIX memory map interface.  Linux/AVR32 version.
++   Copyright (C) 1997, 2000 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef _SYS_MMAN_H
++# error "Never include this file directly.  Use <sys/mman.h> instead"
++#endif
++
++/* The following definitions basically come from the kernel headers.
++   But the kernel header is not namespace clean.  */
++
++
++/* Protections are chosen from these bits, OR'd together.  The
++   implementation does not necessarily support PROT_EXEC or PROT_WRITE
++   without PROT_READ.  The only guarantees are that no writing will be
++   allowed without PROT_WRITE and no access will be allowed for PROT_NONE. */
++
++#define PROT_READ     0x1             /* Page can be read.  */
++#define PROT_WRITE    0x2             /* Page can be written.  */
++#define PROT_EXEC     0x4             /* Page can be executed.  */
++#define PROT_NONE     0x0             /* Page can not be accessed.  */
++
++/* Sharing types (must choose one and only one of these).  */
++#define MAP_SHARED    0x01            /* Share changes.  */
++#define MAP_PRIVATE   0x02            /* Changes are private.  */
++#ifdef __USE_MISC
++# define MAP_TYPE     0x0f            /* Mask for type of mapping.  */
++#endif
++
++/* Other flags.  */
++#define MAP_FIXED     0x10            /* Interpret addr exactly.  */
++#ifdef __USE_MISC
++# define MAP_FILE     0
++# define MAP_ANONYMOUS        0x20            /* Don't use a file.  */
++# define MAP_ANON     MAP_ANONYMOUS
++#endif
++
++/* These are Linux-specific.  */
++#ifdef __USE_MISC
++# define MAP_GROWSDOWN        0x0100          /* Stack-like segment.  */
++# define MAP_DENYWRITE        0x0800          /* ETXTBSY */
++# define MAP_EXECUTABLE       0x1000          /* Mark it as an executable.  */
++# define MAP_LOCKED   0x2000          /* Lock the mapping.  */
++# define MAP_NORESERVE        0x4000          /* Don't check for reservations.  */
++# define MAP_POPULATE 0x8000          /* populate (prefault) pagetables */
++# define MAP_NONBLOCK 0x10000         /* do not block on IO */
++#endif
++
++/* Flags to `msync'.  */
++#define MS_ASYNC      1               /* Sync memory asynchronously.  */
++#define MS_SYNC               4               /* Synchronous memory sync.  */
++#define MS_INVALIDATE 2               /* Invalidate the caches.  */
++
++/* Flags for `mlockall'.  */
++#define MCL_CURRENT   1               /* Lock all currently mapped pages.  */
++#define MCL_FUTURE    2               /* Lock all additions to address
++                                         space.  */
++
++/* Flags for `mremap'.  */
++#ifdef __USE_GNU
++# define MREMAP_MAYMOVE       1
++#endif
++
++/* Advise to `madvise'.  */
++#ifdef __USE_BSD
++# define MADV_NORMAL   0      /* No further special treatment.  */
++# define MADV_RANDOM   1      /* Expect random page references.  */
++# define MADV_SEQUENTIAL 2    /* Expect sequential page references.  */
++# define MADV_WILLNEED         3      /* Will need these pages.  */
++# define MADV_DONTNEED         4      /* Don't need these pages.  */
++#endif
++
++/* The POSIX people had to invent similar names for the same things.  */
++#ifdef __USE_XOPEN2K
++# define POSIX_MADV_NORMAL    0 /* No further special treatment.  */
++# define POSIX_MADV_RANDOM    1 /* Expect random page references.  */
++# define POSIX_MADV_SEQUENTIAL        2 /* Expect sequential page references.  */
++# define POSIX_MADV_WILLNEED  3 /* Will need these pages.  */
++# define POSIX_MADV_DONTNEED  4 /* Don't need these pages.  */
++#endif
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/profil-counter.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/profil-counter.h 2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,26 @@
++/* Low-level statistical profiling support function.  Linux/AVR32 version.
++   Copyright (C) 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#include <signal.h>
++
++void
++profil_counter(int signo, siginfo_t *si, struct sigcontext *sc)
++{
++      profil_count((void *)sc->pc);
++}
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/setjmp.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/setjmp.h 2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,21 @@
++/*
++ * Copyright (C) 2004-2005 Atmel Norway
++ */
++#ifndef _SETJMP_H
++# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
++#endif
++
++#ifndef _ASM
++/*
++ * The jump buffer contains r0-r7, sr, sp and lr. Other registers are
++ * not saved.
++ */
++typedef int __jmp_buf[11];
++#endif
++
++#define __JMP_BUF_SP  4
++
++/* Test if longjmp to JMPBUF would unwind the frame containing a local
++   variable at ADDRESS.  */
++#define _JMPBUF_UNWINDS(jmpbuf, address) \
++  ((void *)(address) < (void *)(jmpbuf[__JMP_BUF_SP]))
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/syscalls.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/syscalls.h       2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,143 @@
++#ifndef _SYSCALL_H
++# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
++#endif
++
++/*
++ * This includes the `__NR_<name>' syscall numbers taken from the
++ * Linux kernel header files. It also defines the traditional
++ * `SYS_<name>' macros for older programs.
++ */
++#include <bits/sysnum.h>
++
++#ifndef __set_errno
++# define __set_errno(val) (*__errno_location()) = (val)
++#endif
++#ifndef SYS_ify
++# define SYS_ify(syscall_name) (__NR_##syscall_name)
++#endif
++
++#ifndef __ASSEMBLER__
++
++#undef _syscall0
++#define _syscall0(type,name)                          \
++      type name(void)                                 \
++      {                                               \
++              return (type)(INLINE_SYSCALL(name, 0)); \
++      }
++
++#undef _syscall1
++#define _syscall1(type,name,type1,arg1)                               \
++      type name(type1 arg1)                                   \
++      {                                                       \
++              return (type)(INLINE_SYSCALL(name, 1, arg1));   \
++      }
++
++#undef _syscall2
++#define _syscall2(type,name,type1,arg1,type2,arg2)                    \
++      type name(type1 arg1, type2 arg2)                               \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 2, arg1, arg2));     \
++      }
++
++#undef _syscall3
++#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)         \
++      type name(type1 arg1, type2 arg2, type3 arg3)                   \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 3, arg1,             \
++                                           arg2, arg3));              \
++      }
++
++#undef _syscall4
++#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4)                                           \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4)       \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 4, arg1, arg2,       \
++                                           arg3, arg4));              \
++      }
++
++#undef _syscall5
++#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4,type5,arg5)                                \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
++                type5 arg5)                                           \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 5, arg1, arg2,       \
++                                           arg3, arg4, arg5));        \
++      }
++
++#undef _syscall6
++#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,         \
++                type4,arg4,type5,arg5,type6,arg6)                     \
++      type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4,       \
++                type5 arg5, type6 arg6)                               \
++      {                                                               \
++              return (type)(INLINE_SYSCALL(name, 6, arg1, arg2, arg3, \
++                                           arg4, arg5, arg6));        \
++      }
++
++#undef unlikely
++#define unlikely(x) __builtin_expect((x), 0)
++
++#undef INLINE_SYSCALL
++#define INLINE_SYSCALL(name, nr, args...)                             \
++      ({                                                              \
++              unsigned _sys_result = INTERNAL_SYSCALL(name, , nr, args); \
++              if (unlikely(INTERNAL_SYSCALL_ERROR_P(_sys_result, ))) { \
++                      __set_errno(INTERNAL_SYSCALL_ERRNO(_sys_result, )); \
++                      _sys_result = (unsigned int) -1;                \
++              }                                                       \
++              (int) _sys_result;                                      \
++      })
++
++#undef INTERNAL_SYSCALL_DECL
++#define INTERNAL_SYSCALL_DECL(err) do { } while(0)
++
++#undef INTERNAL_SYSCALL
++#define INTERNAL_SYSCALL(name, err, nr, args...)                      \
++      ({                                                              \
++              register int _a1 asm ("r12");                           \
++              register int _scno asm("r8") = SYS_ify(name);           \
++              LOAD_ARGS_##nr (args);                                  \
++              asm volatile ("scall    /* syscall " #name " */"        \
++                            : "=r" (_a1)                              \
++                            : "r"(_scno) ASM_ARGS_##nr                \
++                            : "lr", "cc", "memory");                  \
++              _a1;                                                    \
++      })
++
++#undef INTERNAL_SYSCALL_ERROR_P
++#define INTERNAL_SYSCALL_ERROR_P(val, err)            \
++      ((unsigned int)(val) >= 0xfffff001U)
++
++#undef INTERNAL_SYSCALL_ERRNO
++#define INTERNAL_SYSCALL_ERRNO(val, errr) (-(val))
++
++#define LOAD_ARGS_0() do { } while(0)
++#define ASM_ARGS_0
++#define LOAD_ARGS_1(a1)                                       \
++      _a1 = (int) (a1);                               \
++      LOAD_ARGS_0()
++#define ASM_ARGS_1    ASM_ARGS_0, "r"(_a1)
++#define LOAD_ARGS_2(a1, a2)                           \
++      register int _a2 asm("r11") = (int)(a2);        \
++      LOAD_ARGS_1(a1)
++#define ASM_ARGS_2    ASM_ARGS_1, "r"(_a2)
++#define LOAD_ARGS_3(a1, a2, a3)                               \
++      register int _a3 asm("r10") = (int)(a3);        \
++      LOAD_ARGS_2(a1, a2)
++#define ASM_ARGS_3    ASM_ARGS_2, "r"(_a3)
++#define LOAD_ARGS_4(a1, a2, a3, a4)                   \
++      register int _a4 asm("r9") = (int)(a4);         \
++      LOAD_ARGS_3(a1, a2, a3)
++#define ASM_ARGS_4    ASM_ARGS_3, "r"(_a4)
++#define LOAD_ARGS_5(a1, a2, a3, a4, a5)                       \
++      register int _a5 asm("r5") = (int)(a5);         \
++      LOAD_ARGS_4(a1, a2, a3, a4)
++#define ASM_ARGS_5    ASM_ARGS_4, "r"(_a5)
++#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)           \
++      register int _a6 asm("r3") = (int)(a6);         \
++      LOAD_ARGS_5(a1, a2, a3, a4, a5)
++#define ASM_ARGS_6    ASM_ARGS_5, "r"(_a6)
++
++#endif /* __ASSEMBLER__ */
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/wordsize.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bits/wordsize.h       2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1 @@
++#define __WORDSIZE    32
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/brk.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/brk.c 2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,23 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <sys/syscall.h>
++
++void *__curbrk = 0;
++
++int brk (void *addr)
++{
++      void *newbrk;
++
++      newbrk = INLINE_SYSCALL(brk, 1, addr);
++
++      __curbrk = newbrk;
++
++      if (newbrk < addr) {
++              __set_errno (ENOMEM);
++              return -1;
++      }
++
++      return 0;
++}
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bsd-_setjmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bsd-_setjmp.S 2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      /* This just does a tail-call to __sigsetjmp(env, 0) */
++      .global _setjmp
++      .type   _setjmp,"function"
++      .align  1
++_setjmp:
++      mov     r11, 0
++      bral    __sigsetjmp_internal
++      .size   _setjmp, . - _setjmp
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bsd-setjmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/bsd-setjmp.S  2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++
++      /* This just does a tail-call to __sigsetjmp(env, 1) */
++      .global setjmp
++      .type   setjmp,"function"
++      .align  1
++setjmp:
++      mov     r11, 1
++      bral    __sigsetjmp_internal
++      .size   setjmp, . - setjmp
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/clone.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/clone.c       2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,37 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <sys/syscall.h>
++#include <unistd.h>
++
++/*
++ * I don't know if we can be absolutely certain that the fn and arg
++ * parameters are preserved when returning as the child. If the
++ * compiler stores them in registers (r0-r7), they should be.
++ */
++int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg)
++{
++      register int (*_fn)(void *arg) = fn;
++      register void *_arg = arg;
++      int err;
++
++      /* Sanity check the arguments */
++      err = -EINVAL;
++      if (!fn)
++              goto syscall_error;
++      if (!child_stack)
++              goto syscall_error;
++
++      err = INLINE_SYSCALL(clone, 2, flags, child_stack);
++      if (err < 0)
++              goto syscall_error;
++      else if (err != 0)
++              return err;
++
++      _exit(_fn(_arg));
++
++syscall_error:
++      __set_errno (-err);
++      return -1;
++}
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/crt1.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/crt1.S        2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,93 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ *
++ * When we enter _start, the stack looks like this:
++ *    argc            argument counter
++ *    argv[0]         pointer to program name
++ *    argv[1..argc-1] pointers to program args
++ *    NULL
++ *    env[0..N]       pointers to environment variables
++ *    NULL
++ *
++ * r12 contains a function pointer to be registered with `atexit'.
++ * This is how the dynamic linker arranges to have DT_FINI functions
++ * called for shared libraries that have been loaded before this
++ * code runs.
++ *
++ * We're going to call the following function:
++ * __uClibc_main(int (*main)(int, char **, char **), int argc,
++ *             char **argv, void (*app_init)(void), void (*app_fini)(void),
++ *             void (*rtld_fini)(void), void *stack_end)
++ *
++ * So we need to set up things as follows:
++ *    r12 = address of main
++ *    r11 = argc
++ *    r10 = &argv[0]
++ *    r9  = address of _init
++ *    r8  = address of _fini
++ *    sp[0] = whatever we got passed in r12
++ */
++
++#include <features.h>
++
++      .text
++      .global _start
++      .type   _start, @function
++_start:
++      /* Clear the frame pointer and link register since this is the outermost frame.  */
++      mov     r7, 0
++      mov     lr, 0
++
++      ld.w    r11, sp++               /* argc         */
++      mov     r10, sp                 /* &argv[0]     */
++
++      st.w    --sp, r10               /* stack_end */
++      st.w    --sp, r12               /* rtld_fini */
++
++#ifdef __PIC__
++      lddpc   r6, .L_GOT
++.L_RGOT:
++      rsub    r6, pc
++      lda.w   r9, _init
++      lda.w   r8, _fini
++      lda.w   r12, main
++
++      /* Ok, now run uClibc's main() -- should not return */
++      call    __uClibc_main
++
++      .align  2
++.L_GOT:
++      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
++#else
++      lddpc   r9, __init_addr         /* app_init */
++      lddpc   r8, __fini_addr         /* app_fini */
++      lddpc   r12, __main_addr        /* main */
++
++      /* Ok, now run uClibc's main() -- should not return */
++      lddpc   pc, ___uClibc_main_addr
++
++      .align  2
++__init_addr:
++      .long   _init
++__fini_addr:
++      .long   _fini
++__main_addr:
++      .long   main
++___uClibc_main_addr:
++      .long   __uClibc_main
++#endif
++      .size   _start, . - _start
++
++      /*
++       * The LSB says we need this.
++       */
++      .section ".note.ABI-tag", "a"
++      .align  4
++      .long   2f - 1f         /* namesz */
++      .long   4f - 3f         /* descsz */
++      .long   1               /* type   */
++1:    .asciz  "GNU"           /* name */
++2:    .align  4
++3:    .long   0               /* Linux executable */
++      .long   2,6,0           /* Earliest compatible kernel */
++4:    .align  4
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/crti.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/crti.S        2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,17 @@
++
++      .section .init
++      .align  2
++      .global _init
++      .type   _init, @function
++_init:
++      /* Use a four-byte instruction to avoid NOPs */
++      stm     --sp, r0-r7,lr
++      .align  2
++
++      .section .fini
++      .align  2
++      .global _fini
++      .type   _fini, @function
++_fini:
++      stm     --sp, r0-r7,lr
++      .align  2
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/crtn.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/crtn.S        2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,14 @@
++
++      .section .init
++      .align  2
++      .global _init
++      .type   _init, @function
++      ldm     sp++, r0-r7,pc
++      .size   _init, . - _init
++
++      .section .fini
++      .align  2
++      .global _fini
++      .type   _fini, @function
++      ldm     sp++, r0-r7,pc
++      .size   _fini, . - _fini
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/mmap.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/mmap.c        2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,31 @@
++/* Copyright (C) 2005 Atmel Norway
++
++   This program is free software; you can redistribute it and/or modify it under
++   the terms of the GNU Library 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 Library General Public License for more
++   details.
++
++   You should have received a copy of the GNU Library 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
++
++   Derived in part from the Linux-8086 C library, the GNU C Library, and several
++   other sundry sources.  Files within this library are copyright by their
++   respective copyright holders.
++ */
++
++#include <errno.h>
++#include <sys/mman.h>
++#include <sys/syscall.h>
++
++static _syscall6(__ptr_t, mmap2, __ptr_t, addr, size_t, len, int, prot, int, flags, int, fd, __off_t, pgoff);
++
++__ptr_t mmap(__ptr_t addr, size_t len, int prot, int flags, int fd, __off_t offset)
++{
++      return mmap2(addr, len, prot, flags, fd, offset >> 12);
++}
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/setjmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/setjmp.S      2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,43 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#define _SETJMP_H
++#define _ASM
++#include <bits/setjmp.h>
++
++      .text
++
++      .global __sigsetjmp
++      .type   __sigsetjmp,"function"
++
++      /* Create a global, hidden symbol for use by setjmp() and _setjmp().
++         If it's not hidden, the linker will complain about a relative
++         jump to a dynamic symbol when building a shared library.
++
++         Also, if a user overrides the __sigsetjmp function, he might not
++         expect the setjmp() and _setjmp() function to effectively be
++         overridden as well.  */
++      .global __sigsetjmp_internal
++      .hidden __sigsetjmp_internal
++      .type   __sigsetjmp_internal,"function"
++      .align  1
++__sigsetjmp:
++__sigsetjmp_internal:
++      mustr   r8
++      stm     r12, r0,r1,r2,r3,r4,r5,r6,r7,r8,sp,lr
++
++      /* Make a tail call to __sigjmp_save; it takes the same args.  */
++#ifdef __PIC__
++      mov     r9, r6
++      lddpc   r6, .LG
++.L1:  rsub    r6, pc
++      ld.w    r8, r6[__sigjmp_save@got]
++      mov     r6, r9
++      mov     pc, r8
++
++      .align  2
++.LG:  .long   .L1 - _GLOBAL_OFFSET_TABLE_
++#else
++      rjmp    __sigjmp_save
++#endif
++      .size   __sigsetjmp, . - __sigsetjmp
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sigaction.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sigaction.c   2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,49 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <errno.h>
++#include <signal.h>
++#include <string.h>
++#include <sys/syscall.h>
++#include <bits/kernel_sigaction.h>
++
++#define SA_RESTORER   0x04000000
++extern void __default_rt_sa_restorer(void);
++
++/*
++ * If act is not NULL, change the action for sig to *act.
++ * If oact is not NULL, put the old action for sig in *oact.
++ */
++int __libc_sigaction(int signum, const struct sigaction *act,
++                   struct sigaction *oldact)
++{
++      struct kernel_sigaction kact, koact;
++      int result;
++
++      if (act) {
++              kact.k_sa_handler = act->sa_handler;
++              memcpy(&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
++              kact.sa_flags = act->sa_flags;
++              if (kact.sa_flags & (SA_RESTORER | SA_ONSTACK))
++                      kact.sa_restorer = act->sa_restorer;
++              else
++                      kact.sa_restorer = __default_rt_sa_restorer;
++              kact.sa_flags |= SA_RESTORER;
++      }
++
++      result = __syscall_rt_sigaction(signum, act ? __ptrvalue(&kact) : NULL,
++                                      oldact ? __ptrvalue(&koact) : NULL,
++                                      _NSIG / 8);
++
++      if (oldact && result >= 0) {
++              oldact->sa_handler = koact.k_sa_handler;
++              memcpy(&oldact->sa_mask, &koact.sa_mask,
++                     sizeof(oldact->sa_mask));
++              oldact->sa_flags = koact.sa_flags;
++              oldact->sa_restorer = koact.sa_restorer;
++      }
++
++      return result;
++}
++
++weak_alias(__libc_sigaction, sigaction)
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sigrestorer.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sigrestorer.S 2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,11 @@
++/*
++ * Copyright (C) 2004 Atmel Norway AS
++ */
++#include <sys/syscall.h>
++
++      .global __default_rt_sa_restorer
++      .type   __default_rt_sa_restorer,"function"
++      .align  1
++__default_rt_sa_restorer:
++      mov     r8, __NR_rt_sigreturn
++      scall
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sys/elf.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sys/elf.h     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,26 @@
++/* Copyright (C) 1996, 1997, 1999, 2001 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef _SYS_ELF_H
++#define _SYS_ELF_H    1
++
++#warning "This header is obsolete; use <sys/procfs.h> instead."
++
++#include <sys/procfs.h>
++
++#endif        /* sys/elf.h */
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sys/io.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sys/io.h      2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,48 @@
++/* Copyright (C) 1996, 1998, 1999 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef       _SYS_IO_H
++
++#define       _SYS_IO_H       1
++#include <features.h>
++
++__BEGIN_DECLS
++
++/* If TURN_ON is TRUE, request for permission to do direct i/o on the
++   port numbers in the range [FROM,FROM+NUM-1].  Otherwise, turn I/O
++   permission off for that range.  This call requires root privileges.  */
++extern int ioperm (unsigned long int __from, unsigned long int __num,
++                 int __turn_on) __THROW;
++
++/* Set the I/O privilege level to LEVEL.  If LEVEL is nonzero,
++   permission to access any I/O port is granted.  This call requires
++   root privileges. */
++extern int iopl (int __level) __THROW;
++
++/* The functions that actually perform reads and writes.  */
++extern unsigned char inb (unsigned long int port) __THROW;
++extern unsigned short int inw (unsigned long int port) __THROW;
++extern unsigned long int inl (unsigned long int port) __THROW;
++
++extern void outb (unsigned char value, unsigned long int port) __THROW;
++extern void outw (unsigned short value, unsigned long int port) __THROW;
++extern void outl (unsigned long value, unsigned long int port) __THROW;
++
++__END_DECLS
++
++#endif /* _SYS_IO_H */
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sys/procfs.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sys/procfs.h  2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,123 @@
++/* Copyright (C) 1996, 1997, 1999, 2001 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++#ifndef _SYS_PROCFS_H
++#define _SYS_PROCFS_H 1
++
++/* This is somewhat modelled after the file of the same name on SVR4
++   systems.  It provides a definition of the core file format for ELF
++   used on Linux.  It doesn't have anything to do with the /proc file
++   system, even though Linux has one.
++
++   Anyway, the whole purpose of this file is for GDB and GDB only.
++   Don't read too much into it.  Don't use it for anything other than
++   GDB unless you know what you are doing.  */
++
++#include <features.h>
++#include <sys/time.h>
++#include <sys/types.h>
++#include <sys/user.h>
++
++__BEGIN_DECLS
++
++/* Type for a general-purpose register.  */
++typedef unsigned long elf_greg_t;
++
++/* And the whole bunch of them.  We could have used `struct
++   user_regs' directly in the typedef, but tradition says that
++   the register set is an array, which does have some peculiar
++   semantics, so leave it that way.  */
++#define ELF_NGREG (sizeof (struct user_regs) / sizeof(elf_greg_t))
++typedef elf_greg_t elf_gregset_t[ELF_NGREG];
++
++/* Register set for the floating-point registers.  */
++typedef struct user_fpregs elf_fpregset_t;
++
++/* Signal info.  */
++struct elf_siginfo
++  {
++    int si_signo;                     /* Signal number.  */
++    int si_code;                      /* Extra code.  */
++    int si_errno;                     /* Errno.  */
++  };
++
++/* Definitions to generate Intel SVR4-like core files.  These mostly
++   have the same names as the SVR4 types with "elf_" tacked on the
++   front to prevent clashes with Linux definitions, and the typedef
++   forms have been avoided.  This is mostly like the SVR4 structure,
++   but more Linuxy, with things that Linux does not support and which
++   GDB doesn't really use excluded.  */
++
++struct elf_prstatus
++  {
++    struct elf_siginfo pr_info;               /* Info associated with signal.  */
++    short int pr_cursig;              /* Current signal.  */
++    unsigned long int pr_sigpend;     /* Set of pending signals.  */
++    unsigned long int pr_sighold;     /* Set of held signals.  */
++    __pid_t pr_pid;
++    __pid_t pr_ppid;
++    __pid_t pr_pgrp;
++    __pid_t pr_sid;
++    struct timeval pr_utime;          /* User time.  */
++    struct timeval pr_stime;          /* System time.  */
++    struct timeval pr_cutime;         /* Cumulative user time.  */
++    struct timeval pr_cstime;         /* Cumulative system time.  */
++    elf_gregset_t pr_reg;             /* GP registers.  */
++    int pr_fpvalid;                   /* True if math copro being used.  */
++  };
++
++
++#define ELF_PRARGSZ     (80)    /* Number of chars for args.  */
++
++struct elf_prpsinfo
++  {
++    char pr_state;                    /* Numeric process state.  */
++    char pr_sname;                    /* Char for pr_state.  */
++    char pr_zomb;                     /* Zombie.  */
++    char pr_nice;                     /* Nice val.  */
++    unsigned long int pr_flag;                /* Flags.  */
++    unsigned short int pr_uid;
++    unsigned short int pr_gid;
++    int pr_pid, pr_ppid, pr_pgrp, pr_sid;
++    /* Lots missing */
++    char pr_fname[16];                        /* Filename of executable.  */
++    char pr_psargs[ELF_PRARGSZ];      /* Initial part of arg list.  */
++  };
++
++/* The rest of this file provides the types for emulation of the
++   Solaris <proc_service.h> interfaces that should be implemented by
++   users of libthread_db.  */
++
++/* Addresses.  */
++typedef void *psaddr_t;
++
++/* Register sets.  Linux has different names.  */
++typedef elf_gregset_t prgregset_t;
++typedef elf_fpregset_t prfpregset_t;
++
++/* We don't have any differences between processes and threads,
++   therefore have only one PID type.  */
++typedef __pid_t lwpid_t;
++
++/* Process status and info.  In the end we do provide typedefs for them.  */
++typedef struct elf_prstatus prstatus_t;
++typedef struct elf_prpsinfo prpsinfo_t;
++
++__END_DECLS
++
++#endif        /* sys/procfs.h */
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sys/ucontext.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sys/ucontext.h        2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,94 @@
++/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++/* Linux/AVR32 ABI compliant context switching support.  */
++
++#ifndef _SYS_UCONTEXT_H
++#define _SYS_UCONTEXT_H       1
++
++#include <features.h>
++#include <signal.h>
++#include <sys/procfs.h>
++#include <bits/sigcontext.h>
++
++typedef int greg_t;
++
++/* Number of general registers.  */
++#define NGREG 16
++
++/* Container for all general registers.  */
++typedef elf_gregset_t gregset_t;
++
++/* Number of each register is the `gregset_t' array.  */
++enum
++{
++  R0 = 0,
++#define R0    R0
++  R1 = 1,
++#define R1    R1
++  R2 = 2,
++#define R2    R2
++  R3 = 3,
++#define R3    R3
++  R4 = 4,
++#define R4    R4
++  R5 = 5,
++#define R5    R5
++  R6 = 6,
++#define R6    R6
++  R7 = 7,
++#define R7    R7
++  R8 = 8,
++#define R8    R8
++  R9 = 9,
++#define R9    R9
++  R10 = 10,
++#define R10   R10
++  R11 = 11,
++#define R11   R11
++  R12 = 12,
++#define R12   R12
++  R13 = 13,
++#define R13   R13
++  R14 = 14,
++#define R14   R14
++  R15 = 15
++#define R15   R15
++};
++
++/* Structure to describe FPU registers.  */
++typedef elf_fpregset_t        fpregset_t;
++
++/* Context to describe whole processor state.  */
++typedef struct
++  {
++    gregset_t gregs;
++    fpregset_t fpregs;
++  } mcontext_t;
++
++/* Userlevel context.  */
++typedef struct ucontext
++{
++    unsigned long     uc_flags;
++    struct ucontext  *uc_link;
++    stack_t           uc_stack;
++    struct sigcontext uc_mcontext;
++    sigset_t          uc_sigmask;   /* mask last for extensibility */
++} ucontext_t;
++
++#endif /* sys/ucontext.h */
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sys/user.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/sys/user.h    2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,46 @@
++#ifndef _SYS_USER_H
++#define _SYS_USER_H
++
++struct user_fpregs
++{
++
++};
++
++struct user_regs
++{
++      unsigned long sr;
++      unsigned long pc;
++      unsigned long lr;
++      unsigned long sp;
++      unsigned long r12;
++      unsigned long r11;
++      unsigned long r10;
++      unsigned long r9;
++      unsigned long r8;
++      unsigned long r7;
++      unsigned long r6;
++      unsigned long r5;
++      unsigned long r4;
++      unsigned long r3;
++      unsigned long r2;
++      unsigned long r1;
++      unsigned long r0;
++      unsigned long r12_orig;
++};
++
++struct user
++{
++      struct user_regs        regs;           /* general registers */
++      size_t                  u_tsize;        /* text size (pages) */
++      size_t                  u_dsize;        /* data size (pages) */
++      size_t                  u_ssize;        /* stack size (pages) */
++      unsigned long           start_code;     /* text starting address */
++      unsigned long           start_data;     /* data starting address */
++      unsigned long           start_stack;    /* stack starting address */
++      long int                signal;         /* signal causing core dump */
++      struct user_regs *      u_ar0;          /* help gdb find registers */
++      unsigned long           magic;          /* identifies a core file */
++      char                    u_comm[32];     /* user command name */
++};
++
++#endif /* _SYS_USER_H */
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/syscall.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/syscall.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,81 @@
++/*
++ * syscall for AVR32/uClibc
++ *
++ * Copyright (C) 2004 Atmel Norway
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU Library 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 Library General Public License
++ * for more details.
++ *
++ * You should have received a copy of the GNU Library General Public License
++ * along with this program; if not, write to the Free Software Foundation,
++ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#include <features.h>
++
++      .text
++
++      /*
++       * long int syscall(long int sysno, ...)
++       */
++      .global syscall
++      .type   syscall, @function
++      .align  2
++syscall:
++      stm     --sp, r3,r5,lr
++      sub     lr, sp, -12
++      mov     r8, r12
++      ldm     lr, r3,r5,r9-r12
++      scall
++      cp.w    r12, -4095
++      brlo    .Ldone
++
++#ifdef __PIC__
++      lddpc   r5, .Lgot
++.Lgotcalc:
++      rsub    r5, pc
++# ifdef __UCLIBC_HAS_THREADS__
++      mov     r3, r12
++      mcall   r5[__errno_location@got]
++      st.w    r12[0], r3
++# else
++      ld.w    r3, r5[errno@got]
++      st.w    r3[0], r12
++# endif
++#else
++# ifdef __UCLIBC_HAS_THREADS__
++      mov     r3, r12
++      mcall   .Lerrno_location
++      st.w    r12[0], r3
++# else
++      lddpc   r3, .Lerrno
++      st.w    r3[0], r12
++# endif
++#endif
++      mov     r12, -1
++
++.Ldone:
++      ldm     sp++, r3,r5,pc
++
++      .align  2
++#ifdef __PIC__
++.Lgot:
++      .long   .Lgotcalc - _GLOBAL_OFFSET_TABLE_
++#else
++# ifdef __UCLIBC_HAS_THREADS__
++.Lerrno_location:
++      .long   __errno_location
++# else
++.Lerrno:
++      .long   errno
++# endif
++#endif
++
++
++      .size   syscall, . - syscall
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/vfork.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/avr32/vfork.S       2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,55 @@
++      /*
++       * vfork for uClibc
++       *
++       * Copyright (C) 2005 Atmel Norway
++       */
++
++      /*
++       * Clone the process without copying the address space.  The
++       * calling process is suspended until the child either exits
++       * or calls execve.
++       *
++       * This all means that we cannot rely on the stack to store
++       * away registers, since they will be overwritten by the child
++       * as soon as it makes another function call (e.g. execve()).
++       * Fortunately, the Linux kernel preserves LR across system calls.
++       */
++#include <features.h>
++#include <sys/syscall.h>
++
++      .global __vfork
++      .type   __vfork,@function
++      .align  1
++__vfork:
++      mov     r8, __NR_vfork
++      scall
++      cp.w    r12, -4096
++      retls   r12
++
++      /* vfork failed, so we may use the stack freely */
++      pushm   r4-r7,lr
++#ifdef __PIC__
++      lddpc   r6, .L_GOT
++      rsub    r4, r12, 0
++.L_RGOT:
++      rsub    r6, pc
++      mcall   r6[__errno_location@got]
++#else
++      rsub    r4, r12, 0
++      mcall   .L__errno_location
++#endif
++      st.w    r12[0], r4
++      popm    r4-r7,pc,r12=-1
++
++      .align  2
++#ifdef __PIC__
++.L_GOT:
++      .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_
++#else
++.L__errno_location:
++      .long   __errno_location
++#endif
++      .size   __vfork, . - __vfork
++
++      .weak   vfork
++      vfork   = __vfork
+Index: uClibc-0.9.28-avr32/Rules.mak
+===================================================================
+--- uClibc-0.9.28-avr32.orig/Rules.mak 2006-10-19 15:05:49.000000000 +0200
++++ uClibc-0.9.28-avr32/Rules.mak      2006-10-19 15:05:52.000000000 +0200
+@@ -231,6 +231,12 @@ ifeq ($(strip $(TARGET_ARCH)),frv)
+       UCLIBC_LDSO=ld.so.1
+ endif
++ifeq ($(strip $(TARGET_ARCH)),avr32)
++      CPU_CFLAGS-$(CONFIG_AP7000)     += -mcpu=ap7000
++      CPU_CFLAGS-$(LINKRELAX)         += -masm-addr-pseudos -Wa,--pic,--linkrelax
++      CPU_LDFLAGS-$(LINKRELAX)        += --relax
++endif
++
+ # Keep the check_gcc from being needlessly executed
+ ifndef PIEFLAG
+ ifneq ($(UCLIBC_BUILD_PIE),y)
+Index: uClibc-0.9.28-avr32/libc/string/avr32/bcopy.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/bcopy.S      2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,15 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++      .text
++      .global bcopy
++      .type   bcopy, @function
++      .align  1
++bcopy:
++      /* Swap the first two arguments */
++      eor     r11, r12
++      eor     r12, r11
++      eor     r11, r12
++      rjmp    __memmove
++      .size   bcopy, . - bcopy
+Index: uClibc-0.9.28-avr32/libc/string/avr32/bzero.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/bzero.S      2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,12 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++      .text
++      .global bzero
++      .type   bzero, @function
++      .align  1
++bzero:
++      mov     r10, r11
++      mov     r11, 0
++      rjmp    __memset
+Index: uClibc-0.9.28-avr32/libc/string/avr32/Makefile
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/Makefile     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,40 @@
++# Makefile for uClibc
++#
++# Copyright (C) 2000-2003 Erik Andersen <andersen@uclibc.org>
++#
++# This program is free software; you can redistribute it and/or modify it under
++# the terms of the GNU Library 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 Library General Public License for more
++# details.
++#
++# You should have received a copy of the GNU Library 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
++
++TOPDIR=../../../
++include $(TOPDIR)Rules.mak
++
++SSRC  := bcopy.S bzero.S memcmp.S memcpy.S memmove.S
++SSRC  += memset.S strcmp.S strlen.S
++# memchr.S, strcat.S, strcpy.S, strncpy.S is broken
++SOBJS := $(patsubst %.S,%.o, $(SSRC))
++OBJS  := $(SOBJS)
++
++OBJ_LIST:= ../../obj.string.$(TARGET_ARCH)
++
++all: $(OBJ_LIST)
++
++$(OBJ_LIST): $(OBJS)
++      echo $(addprefix string/$(TARGET_ARCH)/, $(OBJS)) > $@
++
++$(SOBJS): %.o: %.S
++      $(CC) $(ASFLAGS) -c $< -o $@
++      $(STRIPTOOL) -x -R .note -R .comment $@
++
++clean:
++      $(RM) *.[oa] *~ core
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memchr.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memchr.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,62 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define str r12
++#define chr r11
++#define len r10
++
++      .text
++      .global memchr
++      .type   memchr, @function
++memchr:
++      or      chr, chr, chr << 8
++      or      chr, chr, chr << 16
++
++      mov     r9, str
++      andl    r9, 3, COH
++      brne    .Lunaligned_str
++
++1:    sub     len, 4
++      brlt    2f
++      ld.w    r8, str++
++      psub.b  r9, r8, r11
++      tnbz    r9
++      brne    1b
++
++      sub     str, 4
++      bfextu  r9, r8, 24, 8
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      bfextu  r9, r8, 16, 8
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      bfextu  r9, r8, 8, 8
++      cp.b    r9, r11
++      reteq   str
++      sub     str, -1
++      retal   str
++
++2:    sub     len, -4
++      reteq   0
++
++3:    ld.ub   r8, str++
++      cp.w    r8, 0
++      reteq   str
++      sub     len, 1
++      brne    3b
++
++      retal   0
++
++.Lunaligned_str:
++1:    sub     len, 1
++      retlt   0
++      ld.ub   r8, str++
++      cp.b    r8, r11
++      reteq   str
++      sub     r9, 1
++      brge    1b
++
++      rjmp    .Laligned_search
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memcmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memcmp.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,26 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s1 r12
++#define s2 r11
++#define len r10
++
++      .text
++      .global memcmp
++      .type   memcmp, @function
++      .align  1
++memcmp:
++      cp.w    len, 1
++      retlt   0
++1:    ld.ub   r8, s1++
++      ld.ub   r9, s2++
++      sub     r8, r9
++      subfne  len, 1
++      brne    1b
++
++      retal   r8
++      .size   memcmp, . - memcmp
++
++      .weak   bcmp
++      bcmp = memcmp
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memcpy.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memcpy.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,110 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++/* Don't use r12 as dst since we must return it unmodified */
++#define dst r9
++#define src r11
++#define len r10
++
++      .text
++      .global memcpy
++      .type   memcpy, @function
++
++      .global __memcpy
++      .hidden __memcpy
++      .type   __memcpy, @function
++memcpy:
++__memcpy:
++      pref    src[0]
++      mov     dst, r12
++
++      /* If we have less than 32 bytes, don't do anything fancy */
++      cp.w    len, 32
++      brge    .Lmore_than_31
++
++      sub     len, 1
++      retlt   r12
++1:    ld.ub   r8, src++
++      st.b    dst++, r8
++      sub     len, 1
++      brge    1b
++      retal   r12
++
++.Lmore_than_31:
++      pushm   r0-r7, lr
++
++      /* Check alignment */
++      mov     r8, src
++      andl    r8, 31, COH
++      brne    .Lunaligned_src
++      mov     r8, dst
++      andl    r8, 3, COH
++      brne    .Lunaligned_dst
++
++.Laligned_copy:
++      sub     len, 32
++      brlt    .Lless_than_32
++
++1:    /* Copy 32 bytes at a time */
++      ldm     src, r0-r7
++      sub     src, -32
++      stm     dst, r0-r7
++      sub     dst, -32
++      sub     len, 32
++      brge    1b
++
++.Lless_than_32:
++      /* Copy 16 more bytes if possible */
++      sub     len, -16
++      brlt    .Lless_than_16
++      ldm     src, r0-r3
++      sub     src, -16
++      sub     len, 16
++      stm     dst, r0-r3
++      sub     dst, -16
++
++.Lless_than_16:
++      /* Do the remaining as byte copies */
++      neg     len
++      add     pc, pc, len << 2
++      .rept   15
++      ld.ub   r0, src++
++      st.b    dst++, r0
++      .endr
++
++      popm    r0-r7, pc
++
++.Lunaligned_src:
++      /* Make src cacheline-aligned. r8 = (src & 31) */
++      rsub    r8, r8, 32
++      sub     len, r8
++1:    ld.ub   r0, src++
++      st.b    dst++, r0
++      sub     r8, 1
++      brne    1b
++
++      /* If dst is word-aligned, we're ready to go */
++      pref    src[0]
++      mov     r8, 3
++      tst     dst, r8
++      breq    .Laligned_copy
++
++.Lunaligned_dst:
++      /* src is aligned, but dst is not. Expect bad performance */
++      sub     len, 4
++      brlt    2f
++1:    ld.w    r0, src++
++      st.w    dst++, r0
++      sub     len, 4
++      brge    1b
++
++2:    neg     len
++      add     pc, pc, len << 2
++      .rept   3
++      ld.ub   r0, src++
++      st.b    dst++, r0
++      .endr
++
++      popm    r0-r7, pc
++      .size   memcpy, . - memcpy
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memmove.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memmove.S    2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,114 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define dst r12
++#define src r11
++#define len r10
++
++      .text
++      .global memmove
++      .type   memmove, @function
++
++      .global __memmove
++      .hidden __memmove
++      .type   __memmove, @function
++memmove:
++__memmove:
++      cp.w    src, dst
++      brge    __memcpy
++
++      add     dst, len
++      add     src, len
++      pref    src[-1]
++
++      /*
++       * The rest is basically the same as in memcpy.S except that
++       * the direction is reversed.
++       */
++      cp.w    len, 32
++      brge    .Lmore_than_31
++
++      sub     len, 1
++      retlt   r12
++1:    ld.ub   r8, --src
++      st.b    --dst, r8
++      sub     len, 1
++      brge    1b
++      retal   r12
++
++.Lmore_than_31:
++      pushm   r0-r7, lr
++
++      /* Check alignment */
++      mov     r8, src
++      andl    r8, 31, COH
++      brne    .Lunaligned_src
++      mov     r8, r12
++      andl    r8, 3, COH
++      brne    .Lunaligned_dst
++
++.Laligned_copy:
++      sub     len, 32
++      brlt    .Lless_than_32
++
++1:    /* Copy 32 bytes at a time */
++      sub     src, 32
++      ldm     src, r0-r7
++      sub     dst, 32
++      sub     len, 32
++      stm     dst, r0-r7
++      brge    1b
++
++.Lless_than_32:
++      /* Copy 16 more bytes if possible */
++      sub     len, -16
++      brlt    .Lless_than_16
++      sub     src, 16
++      ldm     src, r0-r3
++      sub     dst, 16
++      sub     len, 16
++      stm     dst, r0-r3
++
++.Lless_than_16:
++      /* Do the remaining as byte copies */
++      sub     len, -16
++      breq    2f
++1:    ld.ub   r0, --src
++      st.b    --dst, r0
++      sub     len, 1
++      brne    1b
++
++2:    popm    r0-r7, pc
++
++.Lunaligned_src:
++      /* Make src cacheline-aligned. r8 = (src & 31) */
++      sub     len, r8
++1:    ld.ub   r0, --src
++      st.b    --dst, r0
++      sub     r8, 1
++      brne    1b
++
++      /* If dst is word-aligned, we're ready to go */
++      pref    src[-4]
++      mov     r8, 3
++      tst     dst, r8
++      breq    .Laligned_copy
++
++.Lunaligned_dst:
++      /* src is aligned, but dst is not. Expect bad performance */
++      sub     len, 4
++      brlt    2f
++1:    ld.w    r0, --src
++      st.w    --dst, r0
++      sub     len, 4
++      brge    1b
++
++2:    neg     len
++      add     pc, pc, len << 2
++      .rept   3
++      ld.ub   r0, --src
++      st.b    --dst, r0
++      .endr
++
++      popm    r0-r7, pc
+Index: uClibc-0.9.28-avr32/libc/string/avr32/memset.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/memset.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,60 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s r12
++#define c r11
++#define n r10
++
++      .text
++      .global memset
++      .type   memset, @function
++
++      .global __memset
++      .hidden __memset
++      .type   __memset, @function
++
++      .align  1
++memset:
++__memset:
++      cp.w    n, 32
++      mov     r9, s
++      brge    .Llarge_memset
++
++      sub     n, 1
++      retlt   s
++1:    st.b    s++, c
++      sub     n, 1
++      brge    1b
++
++      retal   r9
++
++.Llarge_memset:
++      mov     r8, r11
++      mov     r11, 3
++      or      r8, r8, r8 << 8
++      or      r8, r8, r8 << 16
++      tst     s, r11
++      breq    2f
++
++1:    st.b    s++, r8
++      sub     n, 1
++      tst     s, r11
++      brne    1b
++
++2:    mov     r11, r9
++      mov     r9, r8
++      sub     n, 8
++
++3:    st.d    s++, r8
++      sub     n, 8
++      brge    3b
++
++      /* If we are done, n == -8 and we'll skip all st.b insns below */
++      neg     n
++      lsl     n, 1
++      add     pc, n
++      .rept   7
++      st.b    s++, r8
++      .endr
++      retal   r11
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strcat.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strcat.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,95 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define s1 r9
++#define s2 r11
++
++      .text
++      .global strcat
++      .type   strcat, @function
++      .align  1
++strcat:
++      mov     s1, r12
++
++      /* Make sure s1 is word-aligned */
++      mov     r10, s1
++      andl    r10, 3, COH
++      breq    2f
++
++      add     pc, pc, r10 << 3
++      sub     r0, r0, 0       /* 4-byte nop */
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    2f
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    3f
++      ld.ub   r8, s1++
++      sub     r8, r8, 0
++      breq    4f
++
++      /* Find the end of the first string */
++5:    ld.w    r8, s1++
++      tnbz    r8
++      brne    5b
++
++      sub     s1, 4
++
++      bfextu  r10, r8, 24, 8
++      cp.w    r10, 0
++      breq    1f
++      sub     s1, -1
++      bfextu  r10, r8, 16, 8
++      cp.w    r10, 0
++      breq    2f
++      sub     s1, -1
++      bfextu  r10, r8, 8, 8
++      cp.w    r10, 0
++      breq    3f
++      sub     s1, -1
++      rjmp    4f
++
++      /* Now, append s2 */
++1:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++2:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++3:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++4:    ld.ub   r8, s2++
++      st.b    s1++, r8
++      cp.w    r8, 0
++      reteq   r12
++
++      /* Copy one word at a time */
++      ld.w    r8, s2++
++      tnbz    r8
++      breq    2f
++1:    st.w    r8, s2++
++      ld.w    r8, s2++
++      tnbz    r8
++      brne    1b
++
++      /* Copy the remaining bytes */
++      bfextu  r10, r8, 24, 8
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 16, 8
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 8, 8
++      st.b    s1++, r10
++      cp.w    r10, 0
++      reteq   r12
++      st.b    s1++, r8
++      retal   r12
++      .size   strcat, . - strcat
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strcmp.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strcmp.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,80 @@
++/*
++ * Copyright (C) 2004 Atmel Norway.
++ */
++
++#define s1 r12
++#define s2 r11
++#define len r10
++
++      .text
++      .global strcmp
++      .type   strcmp, @function
++      .align  1
++strcmp:
++      mov     r8, 3
++      tst     s1, r8
++      brne    .Lunaligned_s1
++      tst     s2, r8
++      brne    .Lunaligned_s2
++
++1:    ld.w    r8, s1++
++      ld.w    r9, s2++
++      cp.w    r8, r9
++      brne    2f
++      tnbz    r8
++      brne    1b
++      retal   0
++
++2:    bfextu  r12, r8, 24, 8
++      bfextu  r11, r9, 24, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 16, 8
++      bfextu  r11, r9, 16, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 8, 8
++      bfextu  r11, r9, 8, 8
++      sub     r12, r11
++      retne   r12
++      cp.w    r11, 0
++      reteq   0
++      bfextu  r12, r8, 0, 8
++      bfextu  r11, r9, 0, 8
++      sub     r12, r11
++      retal   r12
++
++.Lunaligned_s1:
++3:    tst     s1, r8
++      breq    4f
++      ld.ub   r10, s1++
++      ld.ub   r9, s2++
++      sub     r10, r9
++      retne   r10
++      cp.w    r9, 0
++      brne    3b
++      retal   r10
++
++4:    tst     s2, r8
++      breq    1b
++
++.Lunaligned_s2:
++      /*
++       * s1 and s2 can't both be aligned, and unaligned word loads
++       * can trigger spurious exceptions if we cross a page boundary.
++       * Do it the slow way...
++       */
++1:    ld.ub   r8, s1++
++      ld.ub   r9, s2++
++      sub     r8, r9
++      retne   r8
++      cp.w    r9, 0
++      brne    1b
++      retal   0
++
++      .weak   strcoll
++      strcoll = strcmp
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strcpy.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strcpy.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ *
++ * To reduce the size, this one might simply call strncpy with len = -1.
++ */
++
++#define dst r9
++#define src r11
++
++      .text
++      .global strcpy
++      .type   strcpy, @function
++strcpy:
++      mov     dst, r12
++
++      pref    src[0]
++
++      /*
++       * Check alignment. If src is aligned but dst isn't, we can't
++       * do much about it...
++       */
++      mov     r8, src
++      andl    r8, 3 COH
++      brne    .Lunaligned_src
++
++.Laligned_copy:
++1:    ld.w    r8, src++
++      tnbz    r8
++      breq    2f
++      st.w    dst++, r8
++      rjmp    1b
++
++2:    /*
++       * Ok, r8 now contains the terminating '\0'. Copy the
++       * remaining bytes individually.
++       */
++      bfextu  r10, r8, 24, 8
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 16, 8
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      bfextu  r10, r8, 8, 8
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++      st.b    dst++, r8
++      retal   r12
++
++.Lunaligned_src:
++      /* Copy bytes until we're aligned */
++      rsub    r8, r8, 4
++      add     pc, pc, r8 << 3
++      nop
++      nop
++      ld.ub   r10, src++
++      st.b    dst++, r10
++      cp.w    r10, 0
++      reteq   r12
++
++      rjmp    .Laligned_copy
+Index: uClibc-0.9.28-avr32/libc/string/avr32/stringtest.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/stringtest.c 2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,144 @@
++
++#include <stdio.h>
++#include <string.h>
++#include <time.h>
++#include <sys/mman.h>
++
++#define BUF_SIZE (8 * 1024)
++
++static char *buf1;
++static char *buf1_ref;
++static char *buf2;
++
++extern void *optimized_memcpy(void *dest, void *src, size_t len);
++extern void *optimized_memmove(void *dest, void *src, size_t len);
++extern char *optimized_strcpy(char *dest, char *src);
++extern char *optimized_strncpy(char *dest, char *src, size_t len);
++
++void dump_mismatch(char *buf, char *ref, size_t len)
++{
++      int i, j;
++
++      for (i = 0; i < len; i += 16) {
++              if (memcmp(buf + i, ref + i, 16) == 0)
++                      continue;
++
++              printf("%4x buf:", i);
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", buf[j]);
++              printf("\n     ref:");
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", ref[j]);
++              printf("\n");
++      }
++}
++
++static void test_memcpy(int src_offset, int dst_offset, int len)
++{
++      clock_t start, old, new;
++      int i;
++
++      memset(buf1, 0x55, BUF_SIZE);
++      memset(buf1_ref, 0x55, BUF_SIZE);
++      memset(buf2, 0xaa, BUF_SIZE);
++
++      printf("Testing memcpy with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      start = clock();
++      for (i = 0; i < 8192; i++)
++              optimized_memcpy(buf1 + dst_offset, buf2 + src_offset, len);
++      new = clock() - start;
++      start = clock();
++      for ( i = 0; i < 8192; i++)
++              memcpy(buf1_ref + dst_offset, buf2 + src_offset, len);
++      old = clock() - start;
++
++      if (memcmp(buf1, buf1_ref, BUF_SIZE) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, BUF_SIZE);
++      }
++      printf("CPU time used: %d vs. %d\n", new, old);
++}
++
++static void test_memmove(int src_offset, int dst_offset, int len)
++{
++      clock_t start, old, new;
++
++      memset(buf1, 0x55, BUF_SIZE);
++      memset(buf1_ref, 0x55, BUF_SIZE);
++      memset(buf2, 0xaa, BUF_SIZE);
++
++      printf("Testing memmove with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      start = clock();
++      optimized_memmove(buf1 + dst_offset, buf2 + src_offset, len);
++      new = clock() - start;
++      start = clock();
++      memmove(buf1_ref + dst_offset, buf2 + src_offset, len);
++      old = clock() - start;
++
++      if (memcmp(buf1, buf1_ref, BUF_SIZE) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, BUF_SIZE);
++      }
++      printf("CPU time used: %d vs. %d\n", new, old);
++}
++
++int main(int argc, char *argv[])
++{
++      buf2 = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                  MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf2 == MAP_FAILED) {
++              perror("Failed to allocate memory for buf2");
++              return 1;
++      }
++      buf1 = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                  MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf1 == MAP_FAILED) {
++              perror("Failed to allocate memory for buf1");
++              return 1;
++      }
++      buf1_ref = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
++                      MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
++      if (buf1_ref == MAP_FAILED) {
++              perror("Failed to allocate memory for buf1_ref");
++              return 1;
++      }
++      printf("\n === MEMCPY ===\n\n");
++
++      test_memcpy(0, 0, BUF_SIZE - 32);
++      test_memcpy(0, 0, 1);
++      test_memcpy(0, 0, 31);
++      test_memcpy(0, 0, 32);
++      test_memcpy(0, 0, 127);
++      test_memcpy(0, 0, 128);
++      test_memcpy(4, 4, BUF_SIZE - 32 - 4);
++      test_memcpy(1, 1, BUF_SIZE - 32 - 1);
++      test_memcpy(1, 1, 126);
++      test_memcpy(0, 3, 128);
++      test_memcpy(1, 4, 128);
++      test_memcpy(0, 0, 0);
++
++      printf("\n === MEMMOVE ===\n\n");
++
++      test_memmove(0, 0, BUF_SIZE - 32);
++      test_memmove(0, 0, 1);
++      test_memmove(0, 0, 31);
++      test_memmove(0, 0, 32);
++      test_memmove(0, 0, BUF_SIZE - 33);
++      test_memmove(0, 0, 128);
++      test_memmove(4, 4, BUF_SIZE - 32 - 4);
++      test_memmove(1, 1, BUF_SIZE - 32 - 1);
++      test_memmove(1, 1, BUF_SIZE - 130);
++      test_memmove(0, 3, BUF_SIZE - 128);
++      test_memmove(1, 4, BUF_SIZE - 128);
++      test_memmove(0, 0, 0);
++
++      return 0;
++}
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strlen.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strlen.S     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,52 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define str r12
++
++      .text
++      .global strlen
++      .type   strlen, @function
++strlen:
++      mov     r11, r12
++
++      mov     r9, str
++      andl    r9, 3, COH
++      brne    .Lunaligned_str
++
++1:    ld.w    r8, str++
++      tnbz    r8
++      brne    1b
++
++      sub     r12, r11
++      bfextu  r9, r8, 24, 8
++      cp.w    r9, 0
++      subeq   r12, 4
++      reteq   r12
++      bfextu  r9, r8, 16, 8
++      cp.w    r9, 0
++      subeq   r12, 3
++      reteq   r12
++      bfextu  r9, r8, 8, 8
++      cp.w    r9, 0
++      subeq   r12, 2
++      reteq   r12
++      sub     r12, 1
++      retal   r12
++
++.Lunaligned_str:
++      add     pc, pc, r9 << 3
++      sub     r0, r0, 0       /* 4-byte nop */
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      breq    1f
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      breq    1f
++      ld.ub   r8, str++
++      sub     r8, r8, 0
++      brne    1b
++
++1:    sub     r12, 1
++      sub     r12, r11
++      retal   r12
+Index: uClibc-0.9.28-avr32/libc/string/avr32/strncpy.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/strncpy.S    2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define dst r9
++#define src r11
++
++      .text
++      .global strcpy
++      .type   strncpy, @function
++strncpy:
++      mov     dst, r12
++
++      pref    src[0]
++      mov     dst, r12
++
++      /*
++       * Check alignment. If src is aligned but dst isn't, we can't
++       * do much about it...
++       */
++      mov     r8, src
++      andl    r8, 3 COH
++      brne    .Lunaligned_src
++
++.Laligned_copy:
++      sub     r10, 4
++      brlt    3f
++1:    ld.w    r8, src++
++      tnbz    r8
++      breq    2f
++      st.w    dst++, r8
++      sub     r10, 4
++      brne    1b
++
++3:    sub     r10, -4
++      reteq   r12
++
++      /* This is safe as long as src is word-aligned and r10 > 0 */
++      ld.w    r8, src++
++
++2:    /*
++       * Ok, r8 now contains the terminating '\0'. Copy the
++       * remaining bytes individually.
++       */
++      bfextu  r11, r8, 24, 8
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      bfextu  r11, r8, 16, 8
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      bfextu  r11, r8, 8, 8
++      st.b    dst++, r11
++      cp.w    r11, 0
++      reteq   r12
++      sub     r10, 1
++      reteq   r12
++      st.b    dst++, r8
++      retal   r12
++
++.Lunaligned_src:
++      /* Copy bytes until we're aligned */
++      min     r8, r8, r10
++      sub     r10, r8
++      sub     r8, 1
++      retlt   r12
++1:    ld.ub   r10, src++
++      st.b    dst++, r10
++      sub     r8, 1
++      brge    1b
++
++      rjmp    .Laligned_copy
+Index: uClibc-0.9.28-avr32/libc/string/avr32/test_memcpy.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libc/string/avr32/test_memcpy.c        2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,66 @@
++
++#include <stdio.h>
++#include <string.h>
++
++#define BUF_SIZE 32768
++
++static char buf1[BUF_SIZE] __attribute__((aligned(32)));
++static char buf1_ref[BUF_SIZE] __attribute__((aligned(32)));
++static char buf2[BUF_SIZE] __attribute__((aligned(32)));
++
++extern void *new_memcpy(void *dest, void *src, size_t len);
++
++void dump_mismatch(char *buf, char *ref, size_t len)
++{
++      int i, j;
++
++      for (i = 0; i < len; i += 16) {
++              if (memcmp(buf + i, ref + i, 16) == 0)
++                      continue;
++
++              printf("% 4x buf:", i);
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", buf[j]);
++              printf("\n     ref:");
++              for (j = i; j < (i + 16); j++)
++                      printf(" %02x", ref[j]);
++              printf("\n");
++      }
++}
++
++void test(int src_offset, int dst_offset, int len)
++{
++      memset(buf1, 0x55, sizeof(buf1));
++      memset(buf1_ref, 0x55, sizeof(buf1_ref));
++      memset(buf2, 0xaa, sizeof(buf2));
++
++      printf("Testing with offsets %d => %d and len %d...",
++             src_offset, dst_offset, len);
++
++      new_memcpy(buf1 + dst_offset, buf2 + src_offset, len);
++      memcpy(buf1_ref + dst_offset, buf2 + src_offset, len);
++
++      if (memcmp(buf1, buf1_ref, sizeof(buf1)) == 0)
++              printf("OK\n");
++      else {
++              printf("FAILED\n");
++              dump_mismatch(buf1, buf1_ref, sizeof(buf1));
++      }
++}
++
++int main(int argc, char *argv[])
++{
++      test(0, 0, BUF_SIZE);
++      test(0, 0, 1);
++      test(0, 0, 31);
++      test(0, 0, 32);
++      test(0, 0, 127);
++      test(0, 0, 128);
++      test(4, 4, BUF_SIZE - 4);
++      test(1, 1, BUF_SIZE - 1);
++      test(1, 1, 126);
++      test(0, 3, 128);
++      test(1, 4, 128);
++
++      return 0;
++}
+Index: uClibc-0.9.28-avr32/libc/sysdeps/linux/common/create_module.c
+===================================================================
+--- uClibc-0.9.28-avr32.orig/libc/sysdeps/linux/common/create_module.c 2006-10-19 15:05:48.000000000 +0200
++++ uClibc-0.9.28-avr32/libc/sysdeps/linux/common/create_module.c      2006-10-19 15:05:52.000000000 +0200
+@@ -61,7 +61,8 @@ unsigned long create_module(const char *
+ {
+   return __create_module(name, size, 0, 0);
+ }
+-#else
++/* create_module is obsolete in Linux 2.6, so AVR32 doesn't have it */
++#elif !defined(__avr32__)
+ /* Sparc, MIPS, etc don't mistake return values for errors. */ 
+ _syscall2(unsigned long, create_module, const char *, name, size_t, size);
+ #endif
+Index: uClibc-0.9.28-avr32/ldso/include/dl-string.h
+===================================================================
+--- uClibc-0.9.28-avr32.orig/ldso/include/dl-string.h  2006-10-19 15:05:48.000000000 +0200
++++ uClibc-0.9.28-avr32/ldso/include/dl-string.h       2006-10-19 15:05:52.000000000 +0200
+@@ -134,7 +134,7 @@ static inline char * _dl_strstr(const ch
+     } while (1);
+ }
+-static inline void * _dl_memcpy(void * dst, const void * src, size_t len)
++static __always_inline void * _dl_memcpy(void * dst, const void * src, size_t len)
+ {
+       register char *a = dst-1;
+       register const char *b = src-1;
+@@ -271,7 +271,8 @@ static __always_inline char * _dl_simple
+ /* On some arches constant strings are referenced through the GOT.
+  * This requires that load_addr must already be defined... */
+ #if defined(mc68000) || defined(__arm__) || defined(__mips__) \
+-                     || defined(__sh__) ||  defined(__powerpc__)
++                     || defined(__sh__) ||  defined(__powerpc__) \
++                   || defined(__avr32__)
+ # define CONSTANT_STRING_GOT_FIXUP(X) \
+       if ((X) < (const char *) load_addr) (X) += load_addr
+ # define NO_EARLY_SEND_STDERR
+Index: uClibc-0.9.28-avr32/ldso/include/dl-syscall.h
+===================================================================
+--- uClibc-0.9.28-avr32.orig/ldso/include/dl-syscall.h 2006-10-19 15:05:48.000000000 +0200
++++ uClibc-0.9.28-avr32/ldso/include/dl-syscall.h      2006-10-19 15:05:52.000000000 +0200
+@@ -60,59 +60,59 @@
+    dynamic linking at all, so we cannot return any error codes.
+    We just punt if there is an error. */
+ #define __NR__dl_exit __NR_exit
+-static inline _syscall1(void, _dl_exit, int, status);
++static __always_inline _syscall1(void, _dl_exit, int, status);
+ #define __NR__dl_close __NR_close
+-static inline _syscall1(int, _dl_close, int, fd);
++static __always_inline _syscall1(int, _dl_close, int, fd);
+ #define __NR__dl_open __NR_open
+-static inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode);
++static __always_inline _syscall3(int, _dl_open, const char *, fn, int, flags, __kernel_mode_t, mode);
+ #define __NR__dl_write __NR_write
+-static inline _syscall3(unsigned long, _dl_write, int, fd,
++static __always_inline _syscall3(unsigned long, _dl_write, int, fd,
+           const void *, buf, unsigned long, count);
+ #define __NR__dl_read __NR_read
+-static inline _syscall3(unsigned long, _dl_read, int, fd,
++static __always_inline _syscall3(unsigned long, _dl_read, int, fd,
+           const void *, buf, unsigned long, count);
+ #define __NR__dl_mprotect __NR_mprotect
+-static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot);
++static __always_inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, len, int, prot);
+ #define __NR__dl_stat __NR_stat
+-static inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
++static __always_inline _syscall2(int, _dl_stat, const char *, file_name, struct stat *, buf);
+ #define __NR__dl_munmap __NR_munmap
+-static inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
++static __always_inline _syscall2(int, _dl_munmap, void *, start, unsigned long, length);
+ #define __NR__dl_getuid __NR_getuid
+-static inline _syscall0(uid_t, _dl_getuid);
++static __always_inline _syscall0(uid_t, _dl_getuid);
+ #define __NR__dl_geteuid __NR_geteuid
+-static inline _syscall0(uid_t, _dl_geteuid);
++static __always_inline _syscall0(uid_t, _dl_geteuid);
+ #define __NR__dl_getgid __NR_getgid
+-static inline _syscall0(gid_t, _dl_getgid);
++static __always_inline _syscall0(gid_t, _dl_getgid);
+ #define __NR__dl_getegid __NR_getegid
+-static inline _syscall0(gid_t, _dl_getegid);
++static __always_inline _syscall0(gid_t, _dl_getegid);
+ #define __NR__dl_getpid __NR_getpid
+-static inline _syscall0(gid_t, _dl_getpid);
++static __always_inline _syscall0(gid_t, _dl_getpid);
+ #define __NR__dl_readlink __NR_readlink
+-static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
++static __always_inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
+ #ifdef __NR_mmap
+ #ifdef MMAP_HAS_6_ARGS
+ #define __NR__dl_mmap __NR_mmap
+-static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
++static __always_inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
+               int, prot, int, flags, int, fd, off_t, offset);
+ #else
+ #define __NR__dl_mmap_real __NR_mmap
+-static inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
++static __always_inline _syscall1(void *, _dl_mmap_real, unsigned long *, buffer);
+-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
++static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+               int flags, int fd, unsigned long offset)
+ {
+       unsigned long buffer[6];
+@@ -128,11 +128,12 @@ static inline void * _dl_mmap(void * add
+ #endif
+ #elif defined __NR_mmap2
+ #define __NR___syscall_mmap2       __NR_mmap2
+-static inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
++static __always_inline _syscall6(__ptr_t, __syscall_mmap2, __ptr_t, addr,
+               size_t, len, int, prot, int, flags, int, fd, off_t, offset);
+ /*always 12, even on architectures where PAGE_SHIFT != 12 */
+ #define MMAP2_PAGE_SHIFT 12
+-static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
++#define MAP_FAILED ((void *) -1)
++static __always_inline void * _dl_mmap(void * addr, unsigned long size, int prot,
+               int flags, int fd, unsigned long offset)
+ {
+     if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1))
+Index: uClibc-0.9.28-avr32/ldso/ldso/avr32/dl-debug.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/ldso/ldso/avr32/dl-debug.h     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,45 @@
++/*
++ * AVR32 ELF shared libary loader support
++ *
++ * Copyright (C) 2005 Atmel Norway
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. The name of the above contributors may not be
++ *    used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++static const char *_dl_reltypes_tab[] = {
++    "R_AVR32_NONE",
++    "R_AVR32_32", "R_AVR32_16", "R_AVR32_8",
++    "R_AVR32_32_PCREL", "R_AVR32_16_PCREL", "R_AVR32_8_PCREL",
++    "R_AVR32_DIFF32", "R_AVR32_DIFF16", "R_AVR32_DIFF8",
++    "R_AVR32_GOT32", "R_AVR32_GOT16", "R_AVR32_GOT8",
++    "R_AVR32_21S", "R_AVR32_16U", "R_AVR32_16S", "R_AVR32_8S", "R_AVR32_8S_EXT",
++    "R_AVR32_22H_PCREL", "R_AVR32_18W_PCREL", "R_AVR32_16B_PCREL",
++    "R_AVR32_16N_PCREL", "R_AVR32_14UW_PCREL", "R_AVR32_11H_PCREL",
++    "R_AVR32_10UW_PCREL", "R_AVR32_9H_PCREL", "R_AVR32_9UW_PCREL",
++    "R_AVR32_HI16", "R_AVR32_LO16",
++    "R_AVR32_GOTPC", "R_AVR32_GOTCALL", "R_AVR32_LDA_GOT",
++    "R_AVR32_GOT21S", "R_AVR32_GOT18SW", "R_AVR32_GOT16S", "R_AVR32_GOT7UW",
++    "R_AVR32_32_CPENT", "R_AVR32_CPCALL", "R_AVR32_16_CP", "R_AVR32_9W_CP",
++    "R_AVR32_RELATIVE", "R_AVR32_GLOB_DAT", "R_AVR32_JMP_SLOT",
++    "R_AVR32_ALIGN",
++};
+Index: uClibc-0.9.28-avr32/ldso/ldso/avr32/dl-startup.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/ldso/ldso/avr32/dl-startup.h   2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,110 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Architecture specific code used by dl-startup.c
++ * Copyright (C) 2005 Atmel Norway
++ */
++
++/* This is the library loader's main entry point. Let _dl_boot2 do its
++ * initializations and jump to the application's entry point
++ * afterwards. */
++asm(  "       .text\n"
++      "       .global _start\n"
++      "       .type   _start,@function\n"
++      "_start:\n"
++      /* All arguments are on the stack initially */
++      "       mov     r12, sp\n"
++      "       rcall   _dl_start\n"
++      /* Returns user entry point in r12. Save it. */
++      "       mov     r0, r12\n"
++      /* We're PIC, so get the Global Offset Table */
++      "       lddpc   r6, .L_GOT\n"
++      ".L_RGOT:\n"
++      "       rsub    r6, pc\n"
++      /* Adjust argc and argv according to _dl_skip_args */
++      "       ld.w    r1, r6[_dl_skip_args@got]\n"
++      "       ld.w    r1, r1[0]\n"
++      "       ld.w    r2, sp++\n"
++      "       sub     r2, r1\n"
++      "       add     sp, sp, r1 << 2\n"
++      "       st.w    --sp, r2\n"
++      /* Load the finalizer function */
++      "       ld.w    r12, r6[_dl_fini@got]\n"
++      /* Jump to the user's entry point */
++      "       mov     pc, r0\n\n"
++
++      "       .align  2\n"
++      ".L_GOT:"
++      "       .long   .L_RGOT - _GLOBAL_OFFSET_TABLE_\n"
++      "       .size   _start, . - _start\n"
++      "       .previous\n");
++
++/* Get a pointer to the argv array.  On many platforms this can be just
++ * the address if the first argument, on other platforms we need to
++ * do something a little more subtle here. */
++#define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long *)ARGS + 1)
++
++
++/* We can't call functions before the GOT has been initialized */
++#define NO_FUNCS_BEFORE_BOOTSTRAP
++
++/*
++ * Relocate the GOT during dynamic loader bootstrap.  This will add
++ * the load address to all entries in the GOT, which is necessary
++ * because the linker doesn't generate R_AVR32_RELATIVE relocs for the
++ * GOT.
++ */
++static __always_inline
++void PERFORM_BOOTSTRAP_GOT(struct elf_resolve *tpnt)
++{
++      Elf32_Addr i, nr_got;
++      register Elf32_Addr *__r6 __asm__("r6");
++      Elf32_Addr *got = __r6;
++
++      nr_got = tpnt->dynamic_info[DT_AVR32_GOTSZ_IDX] / sizeof(*got);
++      for (i = 2; i < nr_got; i++)
++              got[i] += tpnt->loadaddr;
++}
++
++#define PERFORM_BOOTSTRAP_GOT(tpnt) PERFORM_BOOTSTRAP_GOT(tpnt)
++
++/* Handle relocation of the symbols in the dynamic loader. */
++static __always_inline
++void PERFORM_BOOTSTRAP_RELOC(ELF_RELOC *rpnt, unsigned long *reloc_addr,
++                           unsigned long symbol_addr,
++                           unsigned long load_addr, Elf32_Sym *symtab)
++{
++      switch(ELF32_R_TYPE(rpnt->r_info)) {
++      case R_AVR32_NONE:
++              break;
++      case R_AVR32_GLOB_DAT:
++      case R_AVR32_JMP_SLOT:
++              *reloc_addr = symbol_addr;
++              break;
++      case R_AVR32_RELATIVE:
++              SEND_STDERR_DEBUG("Applying RELATIVE relocation: ");
++              SEND_ADDRESS_STDERR_DEBUG(load_addr, 0);
++              SEND_STDERR_DEBUG(" + ");
++              SEND_ADDRESS_STDERR_DEBUG(rpnt->r_addend, 1);
++              *reloc_addr = load_addr + rpnt->r_addend;
++              break;
++      default:
++              SEND_STDERR("BOOTSTRAP_RELOC: unhandled reloc_type ");
++              SEND_NUMBER_STDERR(ELF32_R_TYPE(rpnt->r_info), 1);
++              SEND_STDERR("REL, SYMBOL, LOAD: ");
++              SEND_ADDRESS_STDERR(reloc_addr, 0);
++              SEND_STDERR(", ");
++              SEND_ADDRESS_STDERR(symbol_addr, 0);
++              SEND_STDERR(", ");
++              SEND_ADDRESS_STDERR(load_addr, 1);
++              _dl_exit(1);
++      }
++}
++
++/* Transfer control to the user's application, once the dynamic loader
++ * is done. This routine has to exit the current function, then call
++ * the _dl_elf_main function.
++ *
++ * Since our _dl_boot will simply call whatever is returned by
++ * _dl_boot2, we can just return the address we're supposed to
++ * call.  */
++#define START()       return _dl_elf_main;
+Index: uClibc-0.9.28-avr32/ldso/ldso/avr32/dl-syscalls.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/ldso/ldso/avr32/dl-syscalls.h  2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,5 @@
++/* We can't use the real errno in ldso, since it has not yet
++ * been dynamicly linked in yet. */
++extern int _dl_errno;
++#define __set_errno(X) {(_dl_errno) = (X);}
++#include "sys/syscall.h"
+Index: uClibc-0.9.28-avr32/ldso/ldso/avr32/dl-sysdep.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/ldso/ldso/avr32/dl-sysdep.h    2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,103 @@
++/* vi: set sw=4 ts=4: */
++/*
++ * Various assembly language/system dependent hacks that are required
++ * so that we can minimize the amount of platform specific code.
++ * Copyright (C) 2004-2005 Atmel Norway
++ */
++
++/* Define this if the system uses RELOCA. */
++#define ELF_USES_RELOCA
++
++#include <elf.h>
++
++#define ARCH_NUM 1
++#define DT_AVR32_GOTSZ_IDX    (DT_NUM + OS_NUM)
++
++#define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr)                  \
++      do {                                                            \
++              if (dpnt->d_tag == DT_AVR32_GOTSZ)                      \
++                      dynamic[DT_AVR32_GOTSZ_IDX] = dpnt->d_un.d_val; \
++      } while (0)
++
++/* Initialization sequence for the application/library GOT. */
++#define INIT_GOT(GOT_BASE,MODULE)                                     \
++      do {                                                            \
++              unsigned long i, nr_got;                                \
++                                                                      \
++              GOT_BASE[0] = (unsigned long) _dl_linux_resolve;        \
++              GOT_BASE[1] = (unsigned long) MODULE;                   \
++                                                                      \
++              /* Add load address displacement to all GOT entries */  \
++              nr_got = MODULE->dynamic_info[DT_AVR32_GOTSZ_IDX] / 4;  \
++              for (i = 2; i < nr_got; i++)                            \
++                      GOT_BASE[i] += (unsigned long)MODULE->loadaddr; \
++      } while (0)
++
++#define do_rem(result, n, base)       ((result) = (n) % (base))
++
++/* Here we define the magic numbers that this dynamic loader should accept */
++#define MAGIC1 EM_AVR32
++#undef MAGIC2
++
++/* Used for error messages */
++#define ELF_TARGET "AVR32"
++
++unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got);
++
++/* 4096 bytes alignment */
++#define PAGE_ALIGN 0xfffff000
++#define ADDR_ALIGN 0xfff
++#define OFFS_ALIGN 0x7ffff000
++
++#define elf_machine_type_class(type)                          \
++      ((type == R_AVR32_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)
++
++/* AVR32 doesn't need any COPY relocs */
++#define DL_NO_COPY_RELOCS
++
++/* Return the link-time address of _DYNAMIC.  Conveniently, this is the
++   first element of the GOT.  This must be inlined in a function which
++   uses global data.  */
++static inline Elf32_Addr
++elf_machine_dynamic (void)
++{
++      register Elf32_Addr *got asm ("r6");
++      return *got;
++}
++
++/* Return the run-time load address of the shared object.  */
++static inline Elf32_Addr
++elf_machine_load_address (void)
++{
++      extern void __dl_start asm("_dl_start");
++      Elf32_Addr got_addr = (Elf32_Addr) &__dl_start;
++      Elf32_Addr pcrel_addr;
++
++      asm   ("        lddpc   %0, 2f\n"
++             "1:      add     %0, pc\n"
++             "        rjmp    3f\n"
++             "        .align  2\n"
++             "2:      .long   _dl_start - 1b\n"
++             "3:\n"
++             : "=r"(pcrel_addr) : : "cc");
++
++      return pcrel_addr - got_addr;
++}
++
++/*
++ * Perform any RELATIVE relocations specified by DT_RELCOUNT.
++ * Currently, we don't use that tag, but we might in the future as
++ * this would reduce the startup time somewhat (although probably not by much).
++ */
++static inline void
++elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
++                    Elf32_Word relative_count)
++{
++      Elf32_Rela *rpnt = (void *)rel_addr;
++
++      do {
++              Elf32_Addr *reloc_addr;
++              reloc_addr = (void *)(load_off + (rpnt++)->r_offset);
++              *reloc_addr = load_off + rpnt->r_addend;
++      } while (--relative_count);
++}
+Index: uClibc-0.9.28-avr32/ldso/ldso/avr32/elfinterp.c
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/ldso/ldso/avr32/elfinterp.c    2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,191 @@
++/*
++ * AVR32 ELF shared library loader suppport
++ *
++ * Copyright (C) 2004-2006 Atmel Corporation
++ *
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. The name of the above contributors may not be
++ *    used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got)
++{
++      struct elf_resolve *tpnt = (struct elf_resolve *)got[1];
++      Elf32_Sym *sym;
++      unsigned long local_gotno;
++      unsigned long gotsym;
++      unsigned long new_addr;
++      char *strtab, *symname;
++      unsigned long *entry;
++      unsigned long sym_index = got_offset / 4;
++
++#if 0
++      local_gotno = tpnt->dynamic_info[DT_AVR32_LOCAL_GOTNO];
++      gotsym = tpnt->dynamic_info[DT_AVR32_GOTSYM];
++
++      sym = ((Elf32_Sym *)(tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr))
++              + sym_index;
++      strtab = (char *)(tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
++      symname = strtab + sym->st_name;
++
++#if 0
++      new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name,
++                                               tpnt->symbol_scope, tpnt,
++                                               resolver);
++#endif
++
++      entry = (unsigned long *)(got + local_gotno + sym_index - gotsym);
++      *entry = new_addr;
++#endif
++
++      return new_addr;
++}
++
++static int
++_dl_parse(struct elf_resolve *tpnt, struct dyn_elf *scope,
++        unsigned long rel_addr, unsigned long rel_size,
++        int (*reloc_func)(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                          Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab))
++{
++      Elf32_Sym *symtab;
++      Elf32_Rela *rpnt;
++      char *strtab;
++      int i;
++
++      rpnt = (Elf32_Rela *)rel_addr;
++      rel_size /= sizeof(Elf32_Rela);
++      symtab = (Elf32_Sym *)tpnt->dynamic_info[DT_SYMTAB];
++      strtab = (char *)tpnt->dynamic_info[DT_STRTAB];
++
++      for (i = 0; i < rel_size; i++, rpnt++) {
++              int symtab_index, res;
++
++              symtab_index = ELF32_R_SYM(rpnt->r_info);
++
++              debug_sym(symtab, strtab, symtab_index);
++              debug_reloc(symtab, strtab, rpnt);
++
++              res = reloc_func(tpnt, scope, rpnt, symtab, strtab);
++
++              if (res == 0)
++                      continue;
++
++              _dl_dprintf(2, "\n%s: ", _dl_progname);
++
++              if (symtab_index)
++                      _dl_dprintf(2, "symbol '%s': ",
++                                  strtab + symtab[symtab_index].st_name);
++
++              if (res < 0) {
++                      int reloc_type = ELF32_R_TYPE(rpnt->r_info);
++#if defined(__SUPPORT_LD_DEBUG__)
++                      _dl_dprintf(2, "can't handle reloc type %s\n",
++                                  _dl_reltypes(reloc_type));
++#else
++                      _dl_dprintf(2, "can't handle reloc type %x\n",
++                                  reloc_type);
++#endif
++                      _dl_exit(-res);
++              } else {
++                      _dl_dprintf(2, "can't resolve symbol\n");
++                      return res;
++              }
++      }
++
++      return 0;
++}
++
++static int _dl_do_reloc(struct elf_resolve *tpnt, struct dyn_elf *scope,
++                      Elf32_Rela *rpnt, Elf32_Sym *symtab, char *strtab)
++{
++      int reloc_type;
++      int symtab_index;
++      char *symname;
++      unsigned long *reloc_addr;
++      unsigned long symbol_addr;
++#if defined(__SUPPORT_LD_DEBUG__)
++      unsigned long old_val;
++#endif
++
++      reloc_addr = (unsigned long *)(tpnt->loadaddr + rpnt->r_offset);
++      reloc_type = ELF32_R_TYPE(rpnt->r_info);
++      symtab_index = ELF32_R_SYM(rpnt->r_info);
++      symbol_addr = 0;
++      symname = strtab + symtab[symtab_index].st_name;
++
++      if (symtab_index) {
++              symbol_addr = (unsigned long)
++                      _dl_find_hash(strtab + symtab[symtab_index].st_name,
++                                    tpnt->symbol_scope, tpnt,
++                                    elf_machine_type_class(reloc_type));
++
++              /* Allow undefined references to weak symbols */
++              if (!symbol_addr &&
++                  ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) {
++                      _dl_dprintf(2, "%s: can't resolve symbol '%s'\n",
++                                  _dl_progname, symname);
++                      return 0;
++              }
++      }
++
++#if defined(__SUPPORT_LD_DEBUG__)
++      old_val = *reloc_addr;
++#endif
++      switch (reloc_type) {
++      case R_AVR32_NONE:
++              break;
++      case R_AVR32_GLOB_DAT:
++      case R_AVR32_JMP_SLOT:
++              *reloc_addr = symbol_addr + rpnt->r_addend;
++              break;
++      case R_AVR32_RELATIVE:
++              *reloc_addr = (unsigned long)tpnt->loadaddr
++                      + rpnt->r_addend;
++              break;
++      default:
++              return -1;
++      }
++
++#if defined(__SUPPORT_LD_DEBUG__)
++      if (_dl_debug_reloc && _dl_debug_detail)
++              _dl_dprintf(_dl_debug_file, "\tpatched: %x ==> %x @ %x\n",
++                          old_val, *reloc_addr);
++#endif
++
++      return 0;
++}
++
++void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
++                                         unsigned long rel_addr,
++                                         unsigned long rel_size)
++{
++      /* TODO: Might want to support this in order to get faster
++       * startup times... */
++}
++
++int _dl_parse_relocation_information(struct dyn_elf *rpnt,
++                                   unsigned long rel_addr,
++                                   unsigned long rel_size)
++{
++      return _dl_parse(rpnt->dyn, rpnt->dyn->symbol_scope, rel_addr, rel_size,
++                       _dl_do_reloc);
++}
+Index: uClibc-0.9.28-avr32/ldso/ldso/avr32/resolve.S
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/ldso/ldso/avr32/resolve.S      2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,28 @@
++/*
++ * Linux dynamic resolving code for AVR32. Fixes up the GOT entry as
++ * indicated in register r12 and jumps to the resolved address.
++ *
++ * This file is subject to the terms and conditions of the GNU Lesser General
++ * Public License.  See the file "COPYING.LIB" in the main directory of this
++ * archive for more details.
++ *
++ * Copyright (C) 2004 Atmel Norway
++ */
++
++#define ip r5
++
++      .text
++      .global _dl_linux_resolve
++      .type   _dl_linux_resolve,@function
++_dl_linux_resolve:
++      /* The PLT code pushed r8 for us. It contains the address of this
++         function's GOT entry, that is entry 0. ip contains the address
++         of the GOT entry of the function we wanted to call. */
++      stm     --sp, r9-r12, lr
++      mov     r11, r8
++      sub     r12, ip, r8
++      rcall   _dl_linux_resolver
++      mov     ip, r12
++      popm    r8-r12,lr
++      mov     pc, ip
++      .size   _dl_linux_resolve, . - _dl_linux_resolve
+Index: uClibc-0.9.28-avr32/ldso/ldso/dl-startup.c
+===================================================================
+--- uClibc-0.9.28-avr32.orig/ldso/ldso/dl-startup.c    2006-10-19 15:05:48.000000000 +0200
++++ uClibc-0.9.28-avr32/ldso/ldso/dl-startup.c 2006-10-19 15:05:52.000000000 +0200
+@@ -217,7 +217,9 @@ static void * __attribute_used__ _dl_sta
+       /* some arches (like MIPS) we have to tweak the GOT before relocations */
+       PERFORM_BOOTSTRAP_GOT(tpnt);
+-#else
++#endif
++
++#if !defined(PERFORM_BOOTSTRAP_GOT) || defined(__avr32__)
+       /* OK, now do the relocations.  We do not do a lazy binding here, so
+          that once we are done, we have considerably more flexibility. */
+@@ -259,7 +261,7 @@ static void * __attribute_used__ _dl_sta
+                               rel_addr += relative_count * sizeof(ELF_RELOC);;
+                       }
+-                      rpnt = (ELF_RELOC *) (rel_addr + load_addr);
++                      rpnt = (ELF_RELOC *) (rel_addr /* + load_addr */);
+                       for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
+                               reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset);
+                               symtab_index = ELF_R_SYM(rpnt->r_info);
+Index: uClibc-0.9.28-avr32/utils/ldd.c
+===================================================================
+--- uClibc-0.9.28-avr32.orig/utils/ldd.c       2006-10-19 15:05:48.000000000 +0200
++++ uClibc-0.9.28-avr32/utils/ldd.c    2006-10-19 15:05:52.000000000 +0200
+@@ -56,6 +56,11 @@
+ #define ELFCLASSM     ELFCLASS32
+ #endif
++#if defined(__avr32__)
++#define MATCH_MACHINE(x) (x == EM_AVR32)
++#define ELFCLASSM     ELFCLASS32
++#endif
++
+ #if defined(__s390__)
+ #define MATCH_MACHINE(x) (x == EM_S390)
+ #define ELFCLASSM     ELFCLASS32
+Index: uClibc-0.9.28-avr32/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h
+===================================================================
+--- /dev/null  1970-01-01 00:00:00.000000000 +0000
++++ uClibc-0.9.28-avr32/libpthread/linuxthreads/sysdeps/avr32/pt-machine.h     2006-10-19 15:05:52.000000000 +0200
+@@ -0,0 +1,92 @@
++/* Machine-dependent pthreads configuration and inline functions.
++
++   Copyright (C) 2005 Atmel Norway
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public License as
++   published by the Free Software Foundation; either version 2.1 of the
++   License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; see the file COPYING.LIB.  If not,
++   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++   Boston, MA 02111-1307, USA.  */
++
++#ifndef _PT_MACHINE_H
++#define _PT_MACHINE_H   1
++
++#include <features.h>
++
++static inline int
++_test_and_set (int *p, int v) __THROW
++{
++      int result;
++
++      __asm__ __volatile__(
++              "/* Inline test and set */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %0, %2\n"
++              "       tst     %0, %3\n"
++              "       breq    2f\n"
++              "       stcond  %1, %3\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=m"(*p)
++              : "m"(*p), "r"(v)
++              : "memory", "cc");
++
++      return result;
++}
++
++#ifndef PT_EI
++# define PT_EI extern inline
++#endif
++
++extern long int testandset (int *spinlock);
++extern int __compare_and_swap (long int *p, long int oldval, long int newval);
++
++/* Spinlock implementation; required.  */
++PT_EI long int
++testandset (int *spinlock)
++{
++      return _test_and_set(spinlock, 1);
++}
++
++
++/* Get some notion of the current stack.  Need not be exactly the top
++   of the stack, just something somewhere in the current frame.  */
++#define CURRENT_STACK_FRAME  stack_pointer
++register char * stack_pointer __asm__ ("sp");
++
++/* Compare-and-swap for semaphores. */
++
++#define HAS_COMPARE_AND_SWAP
++PT_EI int
++__compare_and_swap(long int *p, long int oldval, long int newval)
++{
++      long int result, tmp;
++
++      __asm__ __volatile__(
++              "/* Inline compare and swap */\n"
++              "1:     ssrf    5\n"
++              "       ld.w    %1, %3\n"
++              "       cp.w    %1, %5\n"
++              "       sreq    %0\n"
++              "       brne    2f\n"
++              "       stcond  %2, %4\n"
++              "       brne    1b\n"
++              "2:"
++              : "=&r"(result), "=&r"(tmp), "=m"(*p)
++              : "m"(*p), "r"(newval), "r"(oldval)
++              : "cc", "memory");
++
++      return result;
++}
++
++#endif /* pt-machine.h */
index c59defd..478c713 100644 (file)
@@ -32,23 +32,6 @@ ARCH_SUPPORTS_BIG_ENDIAN=y
 UCLIBC_COMPLETELY_PIC=y
 CONFIG_AP7000=y
 LINKRELAX=y
-# CONFIG_GENERIC_386 is not set
-# CONFIG_386 is not set
-# CONFIG_486 is not set
-# CONFIG_586 is not set
-# CONFIG_586MMX is not set
-# CONFIG_686 is not set
-# CONFIG_PENTIUMII is not set
-# CONFIG_PENTIUMIII is not set
-# CONFIG_PENTIUM4 is not set
-# CONFIG_K6 is not set
-# CONFIG_K7 is not set
-# CONFIG_ELAN is not set
-# CONFIG_CRUSOE is not set
-# CONFIG_WINCHIPC6 is not set
-# CONFIG_WINCHIP2 is not set
-# CONFIG_CYRIXIII is not set
-# CONFIG_NEHEMIAH is not set
 # ARCH_LITTLE_ENDIAN is not set
 ARCH_BIG_ENDIAN=y
 # ARCH_HAS_NO_MMU is not set
@@ -57,7 +40,7 @@ UCLIBC_HAS_FLOATS=y
 # HAS_FPU is not set
 UCLIBC_HAS_SOFT_FLOAT=y
 DO_C99_MATH=y
-KERNEL_SOURCE="/usr/src/linux"
+KERNEL_SOURCE="/media/hda4/OE/build/tmp-new/angstrom/cross/avr32-angstrom-linux-uclibc"
 C_SYMBOL_PREFIX=""
 HAVE_DOT_CONFIG=y
 
@@ -86,7 +69,7 @@ UCLIBC_STATIC_LDCONFIG=y
 # MALLOC is not set
 # MALLOC_SIMPLE is not set
 MALLOC_STANDARD=y
-# MALLOC_GLIBC_COMPAT is not set
+MALLOC_GLIBC_COMPAT=y
 UCLIBC_DYNAMIC_ATEXIT=y
 HAS_SHADOW=y
 UNIX98PTY_ONLY=y
@@ -102,6 +85,7 @@ UCLIBC_TZ_FILE_PATH="/etc/TZ"
 #
 UCLIBC_HAS_IPV6=y
 UCLIBC_HAS_RPC=y
+UCLIBC_HAS_FULL_RPC=y
 
 #
 # String and Stdio Support
@@ -113,11 +97,10 @@ UCLIBC_HAS_CTYPE_SIGNED=y
 UCLIBC_HAS_CTYPE_UNSAFE=y
 # UCLIBC_HAS_CTYPE_CHECKED is not set
 # UCLIBC_HAS_CTYPE_ENFORCED is not set
-# UCLIBC_HAS_WCHAR is not set
+UCLIBC_HAS_WCHAR=y
 # UCLIBC_HAS_LOCALE is not set
 # UCLIBC_HAS_HEXADECIMAL_FLOATS is not set
 # UCLIBC_HAS_GLIBC_CUSTOM_PRINTF is not set
-# USE_OLD_VFPRINTF is not set
 UCLIBC_PRINTF_SCANF_POSITIONAL_ARGS=9
 # UCLIBC_HAS_SCANF_GLIBC_A_FLAG is not set
 # UCLIBC_HAS_STDIO_BUFSIZ_NONE is not set
@@ -155,9 +138,9 @@ UCLIBC_HAS_GLOB=y
 #
 # Library Installation Options
 #
-SHARED_LIB_LOADER_PREFIX="$(DEVEL_PREFIX)/lib"
-RUNTIME_PREFIX="/usr/$(TARGET_ARCH)-linux-uclibc/"
-DEVEL_PREFIX="/usr/$(TARGET_ARCH)-linux-uclibc/usr/"
+SHARED_LIB_LOADER_PREFIX="/lib"
+RUNTIME_PREFIX="/"
+DEVEL_PREFIX="//usr"
 
 #
 # uClibc security related options
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/uclibc-avr32-kernheaders.spec b/packages/uclibc/uclibc-0.9.28/avr32/uclibc-avr32-kernheaders.spec
new file mode 100644 (file)
index 0000000..7d5541c
--- /dev/null
@@ -0,0 +1,41 @@
+Name: uclibc-avr32-kernheaders
+Version: 2.6
+Release: 9
+License: GPL
+Group: Development/System
+Summary: AVR32 header files from the Linux kernel for use by uClibc
+BuildRoot: %{_tmppath}/uclibc-kernheaders-root
+Source: linux-2.6.16.tar.bz2
+Source1: linux-dot-config
+Patch0: linux-2.6.16.11.patch
+Patch1: linux-2.6.16.11-avr32-20060626.patch
+
+%description
+uclibc-avr32-kernheaders contain C header files from the Linux kernel
+which are necessary for building the uClibc library. These header
+files are also necessary for developing programs which use the standard
+C libraries.
+
+If you are developing programs which wil use the standard C libraries,
+you should install uclibc-avr32-kernheaders.
+
+%prep
+%setup -q -n linux-2.6.16
+%patch0 -p1
+%patch1 -p1
+cp %{SOURCE1} .config
+
+%build
+make prepare-all ARCH=avr32 CROSS_COMPILE=avr32-linux-
+
+%install
+mkdir -p %{buildroot}/usr/avr32-linux/include
+cp -a include/{linux,asm,asm-avr32,asm-generic} %{buildroot}/usr/avr32-linux/include
+
+
+%clean
+rm -rf %{buildroot}
+
+%files
+%defattr(-,root,root)
+/usr/avr32-linux/include
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/uclibc-avr32-no-msoft-float.patch b/packages/uclibc/uclibc-0.9.28/avr32/uclibc-avr32-no-msoft-float.patch
new file mode 100644 (file)
index 0000000..0813c45
--- /dev/null
@@ -0,0 +1,14 @@
+--- uClibc-0.9.28/Rules.mak.orig       2006-03-30 10:23:05.000000000 +0200
++++ uClibc-0.9.28/Rules.mak    2006-03-30 10:23:07.000000000 +0200
+@@ -272,7 +272,11 @@
+ # If -msoft-float isn't supported, we want an error anyway.
+ # Hmm... might need to revisit this for arm since it has 2 different
+ # soft float encodings.
++ifeq ($(strip $(TARGET_ARCH)),avr32)
++# GCC on avr32 doesn't support -msoft-float, it's the default.
++else
+     CPU_CFLAGS += -msoft-float
++endif
+ ifeq ($(strip $(TARGET_ARCH)),arm)
+ # No longer needed with current toolchains, but leave it here for now.
+ # If anyone is actually still using gcc 2.95 (say), they can uncomment it.
diff --git a/packages/uclibc/uclibc-0.9.28/avr32/uclibc-makefile.patch b/packages/uclibc/uclibc-0.9.28/avr32/uclibc-makefile.patch
new file mode 100644 (file)
index 0000000..97ed734
--- /dev/null
@@ -0,0 +1,16 @@
+Index: uclibc/Makefile
+===================================================================
+RCS file: /disk1/ic_group/design/I9980/REPOSITORY/I7413/source/uclibc/Makefile,v
+retrieving revision 1.1.1.3
+diff -u -r1.1.1.3 Makefile
+--- uclibc/Makefile    31 Aug 2005 13:08:25 -0000      1.1.1.3
++++ uclibc/Makefile    7 Dec 2005 06:38:39 -0000
+@@ -163,7 +163,7 @@
+       else \
+               extra_exclude="" ; \
+       fi ; \
+-      tar -chf - include --exclude .svn --exclude CVS $$extra_exclude \
++      tar -chf - --exclude .svn --exclude CVS $$extra_exclude include \
+               | tar -xf - -C $(PREFIX)$(DEVEL_PREFIX)
+ ifneq ($(strip $(UCLIBC_HAS_FLOATS)),y)
+       # Remove floating point related headers since float support is disabled.
index 7fb8e5c..e57ef17 100644 (file)
@@ -141,7 +141,7 @@ do_configure() {
                echo "# CONFIG_ARM_EABI is not set"     >> ${S}/.config
        fi
 
-       oe_runmake oldconfig
+       yes '' | oe_runmake oldconfig
 }
 
 do_stage() {
@@ -151,7 +151,6 @@ do_stage() {
                RUNTIME_PREFIX=${UCLIBC_PREFIX}/ \
                install_dev install_runtime
 
-       oe_runmake utils
        oe_runmake PREFIX= DEVEL_PREFIX=${UCLIBC_PREFIX}/ \
                RUNTIME_PREFIX=${UCLIBC_PREFIX}/ \
                install_utils
@@ -189,8 +188,14 @@ do_stage() {
 }
 
 do_install() {
+        # Install into the cross dir (this MUST be done first because we
+        # will install crt1.o in the install_dev stage and gcc needs it)
+        oe_runmake PREFIX= DEVEL_PREFIX=${UCLIBC_PREFIX}/ \
+                RUNTIME_PREFIX=${UCLIBC_PREFIX}/ \
+                install_dev install_runtime
+
        oe_runmake PREFIX=${D} DEVEL_PREFIX=${prefix}/ RUNTIME_PREFIX=/ \
-               install_dev install_runtime install_utils
+               install_dev install_runtime 
 
        # We don't really need this in ${includedir}
        rm -f ${D}${prefix}/include/.cvsignore
@@ -216,5 +221,9 @@ do_install() {
                mv ${D}/usr/bin/* ${D}${bindir}/
                rmdir ${D}/usr/bin
        fi
+
+        oe_runmake utils
+        oe_runmake PREFIX=${D} DEVEL_PREFIX=${prefix}/ RUNTIME_PREFIX=/ \
+                install_utils
 }
 
diff --git a/packages/uclibc/uclibc/.mtn2git_empty b/packages/uclibc/uclibc/.mtn2git_empty
new file mode 100644 (file)
index 0000000..e69de29
index 2c557ec..d5d1bae 100644 (file)
@@ -1,5 +1,5 @@
 DEFAULT_PREFERENCE = "1"
-PR = "r9"
+PR = "r10"
 
 require uclibc.inc
 
@@ -47,6 +47,30 @@ SRC_URI += " ${THUMB_INTERWORK_RESOLVE_PATCH}"
 
 
 DEFAULT_PREFERENCE_avr32 = "6000"
-SRC_URI_append_avr32 = " http://avr32linux.org/twiki/pub/Main/MicroClibcPatches/uClibc-0.9.28-avr1.patch.bz2;patch=1 "
-
+SRC_URI_append_avr32 = " \
+                        file://uclibc-makefile.patch;patch=1 \
+                        file://remove-bogus-version-hack-and-just-use-asm-generic-if-it-exists.patch;patch=1 \
+                        file://let-optimized-stringops-override-default-ones.patch;patch=1 \
+                        file://fix-getrusage-argument-type.patch;patch=1 \
+                        file://fix-__libc_fcntl64-varargs-prototype.patch;patch=1 \
+                        file://fix-broken-__libc_open-declaration.patch;patch=1 \
+                        file://avr32-arch-2.patch;patch=1 \
+                        file://avr32-linkrelax-option.patch;patch=1 \
+                        file://avr32-string-ops.patch;patch=1 \
+                        file://no-create_module-on-avr32.patch;patch=1 \
+                        file://ldso-always-inline-_dl_memcpy.patch;patch=1 \
+                        file://ldso-define-MAP_FAILED.patch;patch=1 \
+                        file://ldso-always-inline-syscalls.patch;patch=1 \
+                        file://ldso-avr32-2.patch;patch=1 \
+                        file://ldso-avr32-needs-CONSTANT_STRING_GOT_FIXUP.patch;patch=1 \
+                        file://ldso-avr32-startup-hack.patch;patch=1 \
+                        file://ldd-avr32-support.patch;patch=1 \
+                        file://libpthread-avr32.patch;patch=1 \
+                        file://sync-fcntl-h-with-linux-kernel.patch;patch=1 \
+                       "
+#file://uClibc-0.9.28-avr32-20060621.patch;patch=1 \
+#file://uClibc-0.9.28-avr32-20061019.patch;patch=1 \
+#file://uclibc-avr32-no-msoft-float.patch;patch=1 \
 
diff --git a/packages/util-linux/files/fdiskbsdlabel-avr32.patch b/packages/util-linux/files/fdiskbsdlabel-avr32.patch
new file mode 100644 (file)
index 0000000..4a7d8f4
--- /dev/null
@@ -0,0 +1,11 @@
+--- /tmp/fdiskbsdlabel.h       2007-09-14 08:52:56.188364759 +0200
++++ util-linux-2.12r/fdisk/fdiskbsdlabel.h     2007-09-14 08:53:31.279986639 +0200
+@@ -43,7 +43,7 @@
+ #define BSD_LINUX_BOOTDIR "/usr/ucb/mdec"
+-#if defined (i386) || defined (__sparc__) || defined (__arm__) || defined (__mips__) || defined (__s390__) || defined (__sh__) || defined(__x86_64__)
++#if defined (i386) || defined (__sparc__) || defined (__arm__) || defined (__mips__) || defined (__s390__) || defined (__sh__) || defined(__x86_64__) || defined(__avr32__)
+ #define BSD_LABELSECTOR   1
+ #define BSD_LABELOFFSET   0
+ #elif defined (__alpha__) || defined (__powerpc__) || defined (__ia64__) || defined (__hppa__)
index 9d4b59c..7f8c3dd 100644 (file)
@@ -3,5 +3,6 @@ require util-linux.inc
 SRC_URI += "file://util-linux_2.12r-12.diff.gz;patch=1"
 SRC_URI += "file://glibc-fix.patch;patch=1"
 SRC_URI += "file://glibc-umount2.patch;patch=1"
+SRC_URI += "file://fdiskbsdlabel-avr32.patch;patch=1" 
 
-PR = "r12"
+PR = "r13"
diff --git a/packages/xorg-xserver/files/.mtn2git_empty b/packages/xorg-xserver/files/.mtn2git_empty
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/packages/xorg-xserver/files/xorg-avr32-support.diff b/packages/xorg-xserver/files/xorg-avr32-support.diff
new file mode 100644 (file)
index 0000000..dd7d379
--- /dev/null
@@ -0,0 +1,19 @@
+--- /tmp/servermd.h    2007-09-30 17:27:22.310911628 +0200
++++ xorg-server-1.4/include/servermd.h 2007-09-30 17:28:25.297799199 +0200
+@@ -130,6 +130,16 @@
+ #endif /* vax */
++#ifdef __avr32__
++
++#define IMAGE_BYTE_ORDER        MSBFirst
++#define BITMAP_BIT_ORDER        MSBFirst
++#define GLYPHPADBYTES           4
++#define GETLEFTBITS_ALIGNMENT   1
++#define AVOID_MEMORY_READ
++
++#endif /* __avr32__ */ 
++
+ #ifdef __arm32__
+ #define IMAGE_BYTE_ORDER        LSBFirst
index 3cc6707..7822e40 100644 (file)
@@ -19,8 +19,9 @@ SRC_URI = "${XORG_MIRROR}/individual/xserver/xorg-server-${PV}.tar.bz2 \
        file://w100.patch;patch=1 \
        file://w100-autofoo.patch;patch=1 \
        file://w100-fix-offscreen-bmp.patch;patch=1 \
-        file://kdrive-1.3-18bpp.patch;patch=1 \
-        file://gumstix-kmode.patch;patch=1 \
+    file://xorg-avr32-support.diff;patch=1 \
+    file://kdrive-1.3-18bpp.patch;patch=1 \
+    file://gumstix-kmode.patch;patch=1 \
 "
 
 S = "${WORKDIR}/xorg-server-${PV}"
index 87880c9..8d91e3b 100644 (file)
@@ -3,6 +3,7 @@ require xserver-kdrive-common.inc
 DEPENDS += "libxkbfile libxcalibrate pixman"
 
 PE = "1"
+PR = "r1"
 
 SRC_URI = "${XORG_MIRROR}/individual/xserver/xorg-server-${PV}.tar.bz2 \
        ${KDRIVE_COMMON_PATCHES} \
@@ -18,7 +19,8 @@ SRC_URI = "${XORG_MIRROR}/individual/xserver/xorg-server-${PV}.tar.bz2 \
        file://xcalibrate-new-input-world-order.patch;patch=1 \
        file://tslib-default-device.patch;patch=1 \
        file://fbdev-evdev.patch;patch=1 \
-       "
+       file://xorg-avr32-support.diff;patch=1 \
+        "
 
 S = "${WORKDIR}/xorg-server-${PV}"
 
index 5bce901..b5b176c 100644 (file)
@@ -1,3 +1,25 @@
 glib_cv_stack_grows=${glib_cv_stack_grows=no}
 ac_cv_func_posix_getpwuid_r=${ac_cv_func_posix_getpwuid_r=yes}
 glib_cv_uscore=${glib_cv_uscore=no}
+ac_cv_func_setpgrp_void=${ac_cv_func_setpgrp_void=yes}
+
+#dbus-glib
+ac_cv_func_posix_getpwnam_r=${ac_cv_func_posix_getpwnam_r=yes}
+
+# set MALLOC_GLIBC_COMPAT=y in your uclibc .config for this
+ac_cv_func_malloc_0_nonnull=${ac_cv_func_malloc_0_nonnull=yes}
+
+#gstreamer
+as_cv_unaligned_access=${as_cv_unaligned_access=no}
+
+#readline
+bash_cv_have_mbstate_t=${bash_cv_have_mbstate_t=yes}
+
+#libpcap
+ac_cv_linux_vers=${ac_cv_linux_vers=2}
+
+#startup notification
+ac_cv_func_realloc_works=${ac_cv_func_realloc_works=yes}
+ac_cv_func_realloc_0_nonnull=${ac_cv_func_realloc_0_nonnull=yes}
+lf_cv_sane_realloc=yes
+