aboutsummaryrefslogtreecommitdiffstats
path: root/packages/linux/linux-2.6.18/avr32-arch.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/linux/linux-2.6.18/avr32-arch.patch')
-rw-r--r--packages/linux/linux-2.6.18/avr32-arch.patch19628
1 files changed, 19628 insertions, 0 deletions
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
index 0000000000..76e2b9f492
--- /dev/null
+++ b/packages/linux/linux-2.6.18/avr32-arch.patch
@@ -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 */