summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>2012-10-08 15:03:32 +0200
committerUwe Kleine-König <u.kleine-koenig@pengutronix.de>2012-10-08 15:03:32 +0200
commit771037416ed13636bfcbe6d16ce3c3d516c85dc4 (patch)
tree1622d0f2cac83f128dc99242bb0256b8b19b323e
downloadOSELAS.BSP-EnergyMicro-Gecko-771037416ed13636bfcbe6d16ce3c3d516c85dc4.tar.gz
OSELAS.BSP-EnergyMicro-Gecko-771037416ed13636bfcbe6d16ce3c3d516c85dc4.tar.xz
platform-energymicro-efm32gg-dk3750: initial code drop
-rw-r--r--.gitignore1
-rw-r--r--kernelconfig-3.6922
-rw-r--r--patches/energyAwareTools_25052012/fix-for-ptxdist.patch12
-rw-r--r--patches/energyAwareTools_25052012/series1
-rw-r--r--patches/linux-3.6/0001-hwmon-efm32-adc-new-driver.patch347
-rw-r--r--patches/linux-3.6/0002-spi-new-controller-driver-for-efm32-SoCs.patch505
-rw-r--r--patches/linux-3.6/0003-ARM-make-cr_alignment-read-only-ifndef-CONFIG_CPU_CP.patch131
-rw-r--r--patches/linux-3.6/0004-Cortex-M3-Add-base-support-for-Cortex-M3.patch665
-rw-r--r--patches/linux-3.6/0005-Cortex-M3-Add-support-for-exception-handling.patch402
-rw-r--r--patches/linux-3.6/0006-Cortex-M3-Add-NVIC-support.patch192
-rw-r--r--patches/linux-3.6/0007-Cortex-M3-Allow-the-building-of-Cortex-M3-kernel-por.patch151
-rw-r--r--patches/linux-3.6/0008-HACK-ARM-no-we-don-t-enter-in-ARM.patch39
-rw-r--r--patches/linux-3.6/0009-mtd-maps-uclinux-fix-sparse-warnings-and-codingstyle.patch162
-rw-r--r--patches/linux-3.6/0010-mtd-maps-uclinux-add-support-for-romfs-in-RAM-or-ROM.patch175
-rw-r--r--patches/linux-3.6/0011-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch616
-rw-r--r--patches/linux-3.6/0012-ARM-efm32-add-support-for-non-dt-builds-and-add-more.patch845
-rw-r--r--patches/linux-3.6/0013-pinctrl-add-a-driver-for-Energy-Micro-s-efm32-SoCs.patch516
-rw-r--r--patches/linux-3.6/0014-HACK-ARM-allow-a-bootloader-to-be-embedded-and-do-it.patch322
-rw-r--r--patches/linux-3.6/0015-HACK-don-t-reserve-memory-for-device-tree-if-it-s-be.patch31
-rw-r--r--patches/linux-3.6/0016-HACK-make-stack-dumps-provoked-by-BUG-a-bit-more-hel.patch35
-rw-r--r--patches/linux-3.6/0017-ARM-v7m-add-trivial-suspend-support.patch95
-rw-r--r--patches/linux-3.6/0018-ARM-efm32-add-trivial-suspend-support.patch71
-rw-r--r--patches/linux-3.6/0019-HACK-ARM-increase-TASK_SIZE-for-MMU.patch34
-rw-r--r--patches/linux-3.6/series22
-rw-r--r--platformconfig194
25 files changed, 6486 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a8415dd
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/platformconfig.old
diff --git a/kernelconfig-3.6 b/kernelconfig-3.6
new file mode 100644
index 0000000..8dd8102
--- /dev/null
+++ b/kernelconfig-3.6
@@ -0,0 +1,922 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Linux/arm 3.6.0 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_NO_IOPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0x00000000
+CONFIG_PHYS_OFFSET=0x88000000
+CONFIG_GENERIC_BUG=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_XZ=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_XZ is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
+# CONFIG_SYSVIPC is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_FHANDLE is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# Timers subsystem
+#
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=12
+# CONFIG_CHECKPOINT_RESTORE is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+# CONFIG_UID16 is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_HOTPLUG is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+CONFIG_TIMERFD=y
+# CONFIG_EVENTFD is not set
+# CONFIG_AIO is not set
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SLUB_DEBUG is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_GENERIC_SMP_IDLE_THREAD=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
+
+#
+# GCOV-based kernel profiling
+#
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_BASE_SMALL=1
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_BSGLIB is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+# CONFIG_MMU is not set
+# CONFIG_ARCH_SOCFPGA is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_HIGHBANK is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_PRIMA2 is not set
+# CONFIG_ARCH_EBSA110 is not set
+CONFIG_ARCH_EFM32=y
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_MXS is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_MVEBU is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_PICOXCELL is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C24XX is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_PLAT_SPEAR is not set
+# CONFIG_ARCH_VT8500 is not set
+# CONFIG_ARCH_ZYNQ is not set
+CONFIG_MACH_EFM32GG_DK3750=y
+# CONFIG_EFM32GG_DK3750_FPGA is not set
+
+#
+# Processor Type
+#
+# CONFIG_CPU_ARM7TDMI is not set
+# CONFIG_CPU_ARM9TDMI is not set
+CONFIG_CPU_V7M=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7M=y
+CONFIG_CPU_ABRT_NOMMU=y
+CONFIG_CPU_PABRT_LEGACY=y
+CONFIG_CPU_CACHE_V7M=y
+CONFIG_CPU_CACHE_VIPT=y
+
+#
+# Processor Features
+#
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_ARM_THUMB=y
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_NR_BANKS=8
+# CONFIG_SET_MEM_PARAM is not set
+CONFIG_DRAM_BASE=0x88000000
+CONFIG_DRAM_SIZE=0x00400000
+CONFIG_FLASH_MEM_BASE=0x00000000
+CONFIG_FLASH_SIZE=0x00100000
+CONFIG_ARM_NVIC=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+
+#
+# Kernel Features
+#
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_ARCH_NR_GPIO=0
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+CONFIG_THUMB2_KERNEL=y
+CONFIG_ARM_ASM_UNIFIED=y
+CONFIG_AEABI=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+CONFIG_FORCE_MAX_ZONEORDER=9
+# CONFIG_SECCOMP is not set
+# CONFIG_CC_STACKPROTECTOR is not set
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+CONFIG_XIP_KERNEL=y
+CONFIG_XIP_PHYS_ADDR=0x00000000
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+
+#
+# Userspace binary formats
+#
+CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
+CONFIG_BINFMT_FLAT=y
+# CONFIG_BINFMT_ZFLAT is not set
+CONFIG_BINFMT_SHARED_FLAT=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_PM_SLEEP=y
+# CONFIG_PM_AUTOSLEEP is not set
+# CONFIG_PM_WAKELOCKS is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+CONFIG_PM_CLK=y
+CONFIG_CPU_PM=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_ARM_CPU_SUSPEND=y
+# CONFIG_NET is not set
+CONFIG_HAVE_BPF_JIT=y
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_GENERIC_CPU_DEVICES is not set
+# CONFIG_DMA_SHARED_BUFFER is not set
+CONFIG_MTD=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+# CONFIG_MTD_BLOCK is not set
+CONFIG_MTD_BLOCK_RO=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+CONFIG_MTD_ROM=y
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_UCLINUX=y
+# CONFIG_MTD_UCLINUX_EBSS is not set
+CONFIG_MTD_UCLINUX_ADDRESS=0x8c000000
+CONFIG_MTD_UCLINUX_ROM=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SST25L is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOCG3 is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+# CONFIG_BLK_DEV is not set
+
+#
+# Misc devices
+#
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_ATMEL_PWM is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_BMP085_SPI is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT25 is not set
+CONFIG_EEPROM_93CX6=y
+# CONFIG_EEPROM_93XX46 is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+
+#
+# Altera FPGA firmware download module
+#
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD 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_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_N_HDLC is not set
+# CONFIG_TRACE_SINK is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_IFX6X60 is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+CONFIG_SERIAL_EFM32_UART=y
+CONFIG_SERIAL_EFM32_UART_CONSOLE=y
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_EFM32=y
+# CONFIG_SPI_GPIO is not set
+# CONFIG_SPI_OC_TINY is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+# CONFIG_SPI_XILINX is not set
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_HSI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+
+#
+# Enable Device Drivers -> PPS to see the PTP clock options.
+#
+CONFIG_PINCTRL=y
+
+#
+# Pin controllers
+#
+CONFIG_PINMUX=y
+CONFIG_PINCONF=y
+# CONFIG_DEBUG_PINCTRL is not set
+CONFIG_PINCTRL_EFM32=y
+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO drivers:
+#
+# CONFIG_GPIO_GENERIC_PLATFORM is not set
+# CONFIG_GPIO_EM is not set
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_GPIO_MAX7301 is not set
+# CONFIG_GPIO_MCP23S08 is not set
+# CONFIG_GPIO_MC33880 is not set
+# CONFIG_GPIO_74X164 is not set
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_POWER_AVS is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7314 is not set
+# CONFIG_SENSORS_ADCXX is not set
+CONFIG_SENSORS_EFM32_ADC=y
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_NTC_THERMISTOR is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH56XX_COMMON is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TPS65912_SPI is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_MFD_DA9052_SPI is not set
+# CONFIG_MFD_ARIZONA_SPI is not set
+# CONFIG_MFD_WM831X_SPI is not set
+# CONFIG_MFD_MC13XXX_SPI is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_EZX_PCAP is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_EXYNOS_VIDEO is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB_ARCH_HAS_XHCI is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# Virtio drivers
+#
+# CONFIG_VIRTIO_BALLOON is not set
+# CONFIG_VIRTIO_MMIO is not set
+
+#
+# Microsoft Hyper-V guest support
+#
+# CONFIG_STAGING is not set
+
+#
+# Hardware Spinlock drivers
+#
+CONFIG_CLKSRC_MMIO=y
+# CONFIG_IOMMU_SUPPORT is not set
+
+#
+# Remoteproc drivers (EXPERIMENTAL)
+#
+
+#
+# Rpmsg drivers (EXPERIMENTAL)
+#
+# CONFIG_VIRT_DRIVERS is not set
+# CONFIG_PM_DEVFREQ is not set
+# CONFIG_EXTCON is not set
+# CONFIG_MEMORY is not set
+# CONFIG_IIO is not set
+# CONFIG_PWM is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_FSNOTIFY is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+# CONFIG_PROC_FS is not set
+CONFIG_SYSFS=y
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX6FS_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_ROMFS_BACKED_BY_BLOCK is not set
+CONFIG_ROMFS_BACKED_BY_MTD=y
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+CONFIG_ROMFS_ON_MTD=y
+# CONFIG_PSTORE is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_READABLE_ASM is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_PANIC_ON_OOPS is not set
+CONFIG_PANIC_ON_OOPS_VALUE=0
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO_REDUCED is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_NOMMU_REGIONS is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_TEST_KSTRTOX is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_LL is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_STRNCPY_FROM_USER=y
+CONFIG_GENERIC_STRNLEN_USER=y
+CONFIG_GENERIC_PCI_IOMAP=y
+CONFIG_GENERIC_IO=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC32_SELFTEST is not set
+CONFIG_CRC32_SLICEBY8=y
+# CONFIG_CRC32_SLICEBY4 is not set
+# CONFIG_CRC32_SARWATE is not set
+# CONFIG_CRC32_BIT is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+# CONFIG_CRC8 is not set
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
+CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
+# CONFIG_AVERAGE is not set
+# CONFIG_CORDIC is not set
+# CONFIG_DDR is not set
diff --git a/patches/energyAwareTools_25052012/fix-for-ptxdist.patch b/patches/energyAwareTools_25052012/fix-for-ptxdist.patch
new file mode 100644
index 0000000..a0bb4b1
--- /dev/null
+++ b/patches/energyAwareTools_25052012/fix-for-ptxdist.patch
@@ -0,0 +1,12 @@
+Index: energyAwareTools_25052012/eACommander.sh
+===================================================================
+--- energyAwareTools_25052012.orig/eACommander.sh 2012-05-21 13:27:41.000000000 +0200
++++ energyAwareTools_25052012/eACommander.sh 2012-07-26 09:12:26.370360327 +0200
+@@ -4,5 +4,5 @@
+ # Run Commander
+ #
+ DIR="$( cd "$( dirname "$0" )" && pwd )"
+-export LD_LIBRARY_PATH="${DIR}/lib":/usr/lib32/gio/modules:$LD_LIBRARY_PATH
+-"${DIR}/bin/eACommander" "$@"
++export LD_LIBRARY_PATH="${DIR}/../lib/energyAwareTools":/usr/lib32/gio/modules
++"${DIR}/../lib/energyAwareTools/eACommander" --flashloader "${DIR}/../lib/energyAwareTools/nandflashloader.bin" "$@"
diff --git a/patches/energyAwareTools_25052012/series b/patches/energyAwareTools_25052012/series
new file mode 100644
index 0000000..64fb196
--- /dev/null
+++ b/patches/energyAwareTools_25052012/series
@@ -0,0 +1 @@
+fix-for-ptxdist.patch
diff --git a/patches/linux-3.6/0001-hwmon-efm32-adc-new-driver.patch b/patches/linux-3.6/0001-hwmon-efm32-adc-new-driver.patch
new file mode 100644
index 0000000..56e38db
--- /dev/null
+++ b/patches/linux-3.6/0001-hwmon-efm32-adc-new-driver.patch
@@ -0,0 +1,347 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Thu, 9 Feb 2012 22:35:24 +0100
+Subject: [PATCH] hwmon/efm32-adc: new driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ drivers/hwmon/Kconfig | 10 ++
+ drivers/hwmon/Makefile | 1 +
+ drivers/hwmon/efm32-adc.c | 293 +++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 304 insertions(+)
+ create mode 100644 drivers/hwmon/efm32-adc.c
+
+diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
+index b0a2e4c..2286e68 100644
+--- a/drivers/hwmon/Kconfig
++++ b/drivers/hwmon/Kconfig
+@@ -324,6 +324,16 @@ config SENSORS_DA9052_ADC
+ This driver can also be built as module. If so, the module
+ will be called da9052-hwmon.
+
++config SENSORS_EFM32_ADC
++ tristate "Energy Micro EFM32 ADC"
++ depends on ARCH_EFM32
++ help
++ If you say yes here you get support for Energy Micro's ADC
++ build into their EFM32 SoCs
++
++ This driver can also be built as a module. If so, the module
++ will be called efm32-adc.
++
+ config SENSORS_EXYNOS4_TMU
+ tristate "Temperature sensor on Samsung EXYNOS4"
+ depends on ARCH_EXYNOS4
+diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
+index 7aa9811..dc14fc4 100644
+--- a/drivers/hwmon/Makefile
++++ b/drivers/hwmon/Makefile
+@@ -46,6 +46,7 @@ obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o
+ obj-$(CONFIG_SENSORS_DME1737) += dme1737.o
+ obj-$(CONFIG_SENSORS_DS620) += ds620.o
+ obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
++obj-$(CONFIG_SENSORS_EFM32_ADC) += efm32-adc.o
+ obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o
+ obj-$(CONFIG_SENSORS_EMC2103) += emc2103.o
+ obj-$(CONFIG_SENSORS_EMC6W201) += emc6w201.o
+diff --git a/drivers/hwmon/efm32-adc.c b/drivers/hwmon/efm32-adc.c
+new file mode 100644
+index 0000000..cc9c3d8
+--- /dev/null
++++ b/drivers/hwmon/efm32-adc.c
+@@ -0,0 +1,293 @@
++/*
++ * Energy Micro EFM32 adc
++ *
++ * Copyright (C) 2012 Uwe Kleine-Koenig for Pengutronix
++ *
++ * This program is free software; you can 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/platform_device.h>
++#include <linux/hwmon-sysfs.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/hwmon.h>
++#include <linux/io.h>
++#include <linux/slab.h>
++#include <linux/interrupt.h>
++#include <linux/clk.h>
++#include <linux/init.h>
++#include <linux/err.h>
++
++#define DRIVER_NAME "efm32-adc"
++
++#define ADC_CTRL 0x000
++
++#define ADC_CMD 0x004
++#define ADC_CMD_SINGLESTART 0x00000001
++#define ADC_CMD_SINGLESTOP 0x00000002
++#define ADC_CMD_SCANSTART 0x00000004
++#define ADC_CMD_SCANSTOP 0x00000008
++
++#define ADC_STATUS 0x008
++#define ADC_STATUS_SINGLEDV 0x00010000
++#define ADC_SINGLECTRL 0x00c
++#define ADC_SINGLEDATA 0x024
++
++#define ADC_IEN 0x014
++#define ADC_IF 0x018
++#define ADC_IFC 0x020
++#define ADC_IF_SINGLE 0x00000001
++
++struct efm32_adc_ddata {
++ struct device *hwmondev;
++ void __iomem *base;
++ struct clk *clk;
++ unsigned int irq;
++ spinlock_t lock;
++ unsigned int busy;
++};
++
++static void efm32_adc_write32(struct efm32_adc_ddata *ddata,
++ u32 value, unsigned offset)
++{
++ writel_relaxed(value, ddata->base + offset);
++}
++
++static u32 efm32_adc_read32(struct efm32_adc_ddata *ddata, unsigned offset)
++{
++ return readl_relaxed(ddata->base + offset);
++}
++
++static ssize_t efm32_adc_show_name(struct device *dev,
++ struct device_attribute *devattr, char *buf)
++{
++ return sprintf(buf, "efm32\n");
++}
++
++struct efm32_adc_irqdata {
++ struct efm32_adc_ddata *ddata;
++ struct completion done;
++};
++
++static irqreturn_t efm32_adc_irq(int irq, void *data)
++{
++ struct efm32_adc_irqdata *irqdata = data;
++ u32 iflag = efm32_adc_read32(irqdata->ddata, ADC_IF);
++
++ if (iflag & ADC_IF_SINGLE) {
++ efm32_adc_write32(irqdata->ddata, ADC_IF_SINGLE, ADC_IFC);
++ complete(&irqdata->done);
++ return IRQ_HANDLED;
++ }
++
++ return IRQ_NONE;
++}
++
++static int efm32_adc_read_single(struct device *dev,
++ struct device_attribute *devattr, unsigned int *val)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct efm32_adc_ddata *ddata = platform_get_drvdata(pdev);
++ int ret;
++ struct efm32_adc_irqdata irqdata = { .ddata = ddata, };
++ u32 status;
++ unsigned long freq = clk_get_rate(ddata->clk);
++
++ init_completion(&irqdata.done);
++
++ spin_lock_irq(&ddata->lock);
++ if (ddata->busy) {
++ ret = -EBUSY;
++ goto out_unlock;
++ }
++
++ /* XXX: this depends on CMU_HFPERCLKEN0.ADC being on. */
++ efm32_adc_write32(ddata,
++ ADC_CMD_SINGLESTOP | ADC_CMD_SCANSTOP, ADC_CMD);
++ efm32_adc_write32(ddata, ((freq - 1) / 1000000) << 16 |
++ ((freq / 400000) - 1) << 8, ADC_CTRL);
++ efm32_adc_write32(ddata, 0x800, ADC_SINGLECTRL);
++ efm32_adc_write32(ddata, ADC_IF_SINGLE, ADC_IFC);
++ efm32_adc_write32(ddata, ADC_CMD_SINGLESTART, ADC_CMD);
++
++ ret = request_irq(ddata->irq, efm32_adc_irq, 0, DRIVER_NAME, &irqdata);
++ if (ret) {
++ efm32_adc_write32(ddata, ADC_CMD_SINGLESTOP, ADC_CMD);
++ goto out_unlock;
++ }
++
++ efm32_adc_write32(ddata, ADC_IF_SINGLE, ADC_IEN);
++
++ ddata->busy = 1;
++
++ spin_unlock_irq(&ddata->lock);
++
++ ret = wait_for_completion_interruptible_timeout(&irqdata.done, 2 * HZ);
++
++ spin_lock_irq(&ddata->lock);
++
++ efm32_adc_write32(ddata, 0, ADC_IEN);
++ free_irq(ddata->irq, &irqdata);
++
++ if (ret < 0)
++ goto done_out_unlock;
++
++ status = efm32_adc_read32(ddata, ADC_STATUS);
++ if (status & ADC_STATUS_SINGLEDV) {
++ *val = efm32_adc_read32(ddata, ADC_SINGLEDATA);
++ ret = 0;
++ } else
++ ret = -ETIMEDOUT;
++
++done_out_unlock:
++ ddata->busy = 0;
++out_unlock:
++ spin_unlock_irq(&ddata->lock);
++
++ return ret;
++}
++
++static ssize_t efm32_adc_read_chan(struct device *dev,
++ struct device_attribute *devattr, char *buf)
++{
++ unsigned int val;
++ int ret = efm32_adc_read_single(dev, devattr, &val);
++
++ if (ret)
++ return ret;
++
++ return sprintf(buf, "%u\n", val);
++}
++
++static ssize_t efm32_adc_read_temp(struct device *dev,
++ struct device_attribute *devattr, char *buf)
++{
++ unsigned int val;
++ int ret = efm32_adc_read_single(dev, devattr, &val);
++ /*
++ * XXX: get these via pdata or read them from the device information
++ * registers
++ */
++ unsigned temp0 = 0x19 * 1000;
++ unsigned adc0 = 0x910;
++
++ if (ret)
++ return ret;
++
++ val = temp0 + DIV_ROUND_CLOSEST((adc0 - val) * 10000, 63);
++
++ return sprintf(buf, "%u\n", val);
++}
++
++static DEVICE_ATTR(name, S_IRUGO, efm32_adc_show_name, NULL);
++static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, efm32_adc_read_chan, NULL, 8);
++static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, efm32_adc_read_temp, NULL, 8);
++
++static struct attribute *efm32_adc_attr[] = {
++ &dev_attr_name.attr,
++ &sensor_dev_attr_in8_input.dev_attr.attr,
++ &sensor_dev_attr_temp1_input.dev_attr.attr,
++ NULL
++};
++
++static const struct attribute_group efm32_adc_group = {
++ .attrs = efm32_adc_attr,
++};
++
++static int __devinit efm32_adc_probe(struct platform_device *pdev)
++{
++ struct efm32_adc_ddata *ddata;
++ struct resource *res;
++ int ret;
++
++ ddata = kzalloc(sizeof(*ddata), GFP_KERNEL);
++ if (!ddata)
++ return -ENOMEM;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ ret = -ENXIO;
++ dev_dbg(&pdev->dev, "failed to determine base address\n");
++ goto err_get_base;
++ }
++
++ ret = platform_get_irq(pdev, 0);
++ if (ret <= 0) {
++ ret = -ENXIO;
++ dev_dbg(&pdev->dev, "failed to determine irq\n");
++ goto err_get_irq;
++ }
++ ddata->irq = ret;
++
++ ddata->base = ioremap(res->start, resource_size(res));
++ if (!ddata->base) {
++ ret = -ENOMEM;
++ dev_dbg(&pdev->dev, "failed to remap\n");
++ goto err_ioremap;
++ }
++
++ ddata->clk = clk_get(&pdev->dev, NULL);
++ if (IS_ERR(ddata->clk)) {
++ ret = PTR_ERR(ddata->clk);
++ dev_dbg(&pdev->dev, "failed to get clock\n");
++ goto err_clk_get;
++ }
++
++ platform_set_drvdata(pdev, ddata);
++ spin_lock_init(&ddata->lock);
++
++ ret = sysfs_create_group(&pdev->dev.kobj, &efm32_adc_group);
++ if (ret)
++ goto err_create_group;
++
++ ddata->hwmondev = hwmon_device_register(&pdev->dev);
++ if (IS_ERR(ddata->hwmondev)) {
++ ret = PTR_ERR(ddata->hwmondev);
++
++ sysfs_remove_group(&pdev->dev.kobj, &efm32_adc_group);
++err_create_group:
++
++ platform_set_drvdata(pdev, NULL);
++
++ clk_put(ddata->clk);
++err_clk_get:
++
++ iounmap(ddata->base);
++err_ioremap:
++err_get_irq:
++err_get_base:
++ kfree(ddata);
++ }
++
++ return ret;
++}
++
++static int __devexit efm32_adc_remove(struct platform_device *pdev)
++{
++ struct efm32_adc_ddata *ddata = platform_get_drvdata(pdev);
++
++ hwmon_device_unregister(ddata->hwmondev);
++ sysfs_remove_group(&pdev->dev.kobj, &efm32_adc_group);
++ platform_set_drvdata(pdev, NULL);
++ clk_put(ddata->clk);
++ iounmap(ddata->base);
++ kfree(ddata);
++
++ return 0;
++}
++
++static struct platform_driver efm32_adc_driver = {
++ .probe = efm32_adc_probe,
++ .remove = __devexit_p(efm32_adc_remove),
++ .driver = {
++ .name = DRIVER_NAME,
++ .owner = THIS_MODULE,
++ },
++};
++module_platform_driver(efm32_adc_driver);
++
++MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
++MODULE_DESCRIPTION("EFM32 ADC driver");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/patches/linux-3.6/0002-spi-new-controller-driver-for-efm32-SoCs.patch b/patches/linux-3.6/0002-spi-new-controller-driver-for-efm32-SoCs.patch
new file mode 100644
index 0000000..bf85cf7
--- /dev/null
+++ b/patches/linux-3.6/0002-spi-new-controller-driver-for-efm32-SoCs.patch
@@ -0,0 +1,505 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Thu, 23 Feb 2012 10:44:35 +0100
+Subject: [PATCH] spi: new controller driver for efm32 SoCs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ drivers/spi/Kconfig | 5 +
+ drivers/spi/Makefile | 1 +
+ drivers/spi/spi-efm32.c | 456 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 462 insertions(+)
+ create mode 100644 drivers/spi/spi-efm32.c
+
+diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
+index 5f84b55..053ee60 100644
+--- a/drivers/spi/Kconfig
++++ b/drivers/spi/Kconfig
+@@ -137,6 +137,11 @@ config SPI_DAVINCI
+ help
+ SPI master controller for DaVinci/DA8x/OMAP-L/AM1x SPI modules.
+
++config SPI_EFM32
++ tristate "EFM32 SPI controller"
++ depends on ARCH_EFM32
++ select SPI_BITBANG
++
+ config SPI_EP93XX
+ tristate "Cirrus Logic EP93xx SPI controller"
+ depends on ARCH_EP93XX
+diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
+index 3920dcf..da1243e 100644
+--- a/drivers/spi/Makefile
++++ b/drivers/spi/Makefile
+@@ -25,6 +25,7 @@ obj-$(CONFIG_SPI_DESIGNWARE) += spi-dw.o
+ obj-$(CONFIG_SPI_DW_MMIO) += spi-dw-mmio.o
+ obj-$(CONFIG_SPI_DW_PCI) += spi-dw-midpci.o
+ spi-dw-midpci-objs := spi-dw-pci.o spi-dw-mid.o
++obj-$(CONFIG_SPI_EFM32) += spi-efm32.o
+ obj-$(CONFIG_SPI_EP93XX) += spi-ep93xx.o
+ obj-$(CONFIG_SPI_FALCON) += spi-falcon.o
+ obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-lib.o
+diff --git a/drivers/spi/spi-efm32.c b/drivers/spi/spi-efm32.c
+new file mode 100644
+index 0000000..85b252a
+--- /dev/null
++++ b/drivers/spi/spi-efm32.c
+@@ -0,0 +1,456 @@
++/*
++ * Copyright (C) 2012 Uwe Kleine-Koenig for Pengutronix
++ *
++ * This program is free software; you can 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/io.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/spi_bitbang.h>
++#include <linux/gpio.h>
++#include <linux/interrupt.h>
++#include <linux/platform_device.h>
++#include <linux/clk.h>
++#include <linux/err.h>
++#include <linux/module.h>
++
++#define DRIVER_NAME "efm32-spi"
++
++#define REG_CTRL 0x00
++#define REG_CTRL_SYNC 0x0001
++#define REG_CTRL_CLKPOL 0x0100
++#define REG_CTRL_CLKPHA 0x0200
++#define REG_CTRL_MSBF 0x0400
++#define REG_CTRL_TXBIL 0x1000
++
++#define REG_FRAME 0x04
++#define REG_FRAME_DATABITS__MASK 0x000f
++#define REG_FRAME_DATABITS(n) ((n) - 3)
++
++#define REG_CMD 0x0c
++#define REG_CMD_RXEN 0x0001
++#define REG_CMD_RXDIS 0x0002
++#define REG_CMD_TXEN 0x0004
++#define REG_CMD_TXDIS 0x0008
++#define REG_CMD_MASTEREN 0x0010
++
++#define REG_STATUS 0x10
++#define REG_STATUS_TXENS 0x0002
++#define REG_STATUS_TXC 0x0020
++#define REG_STATUS_TXBL 0x0040
++#define REG_STATUS_RXDATAV 0x0080
++
++#define REG_CLKDIV 0x14
++
++#define REG_RXDATAX 0x18
++#define REG_RXDATAX_RXDATA__MASK 0x01ff
++#define REG_RXDATAX_PERR 0x4000
++#define REG_RXDATAX_FERR 0x8000
++
++#define REG_TXDATA 0x34
++
++#define REG_IF 0x40
++#define REG_IF_TXBL 0x0002
++#define REG_IF_RXDATAV 0x0004
++
++#define REG_IFS 0x44
++#define REG_IFC 0x48
++#define REG_IEN 0x4c
++
++#define REG_ROUTE 0x54
++#define REG_ROUTE_RXPEN 0x0001
++#define REG_ROUTE_TXPEN 0x0002
++#define REG_ROUTE_CLKPEN 0x0008
++#define REG_ROUTE_LOCATION__MASK 0x0700
++#define REG_ROUTE_LOCATION(n) (((n) << 8) & REG_ROUTE_LOCATION__MASK)
++
++
++
++struct efm32_spi_ddata {
++ /* bitbang must be the first member */
++ struct spi_bitbang bitbang;
++
++ spinlock_t lock;
++
++ struct clk *clk;
++ void __iomem *base;
++ unsigned int rxirq, txirq;
++
++ /* irq data */
++ struct completion done;
++ const void *tx_buf;
++ void *rx_buf;
++ unsigned tx_len, rx_len;
++};
++
++static void efm32_spi_write32(struct efm32_spi_ddata *ddata,
++ u32 value, unsigned offset)
++{
++ writel_relaxed(value, ddata->base + offset);
++}
++
++static u32 efm32_spi_read32(struct efm32_spi_ddata *ddata, unsigned offset)
++{
++ return readl_relaxed(ddata->base + offset);
++}
++
++static const struct gpio usart1_gpios[] = {
++ {
++ .gpio = 48,
++ .flags = GPIOF_OUT_INIT_LOW,
++ .label = DRIVER_NAME,
++ }, {
++ .gpio = 49,
++ .flags = GPIOF_IN,
++ .label = DRIVER_NAME,
++ }, {
++ .gpio = 50,
++ .flags = GPIOF_OUT_INIT_LOW,
++ .label = DRIVER_NAME,
++ }, {
++ .gpio = 51,
++ .flags = GPIOF_OUT_INIT_HIGH,
++ .label = DRIVER_NAME,
++ },
++};
++
++static int efm32_spi_setup(struct spi_device *spi)
++{
++ pr_debug("%s\n", __func__);
++
++ return gpio_request_array(usart1_gpios, ARRAY_SIZE(usart1_gpios));
++
++}
++
++static void efm32_spi_cleanup(struct spi_device *spi)
++{
++ pr_debug("%s\n", __func__);
++}
++
++static void efm32_spi_chipselect(struct spi_device *spi, int is_on)
++{
++ int gpio = /* XXX */51;
++ int value = !(spi->mode & SPI_CS_HIGH) == !(is_on == BITBANG_CS_ACTIVE);
++
++ gpio_set_value(gpio, value);
++}
++
++static int efm32_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
++{
++ struct efm32_spi_ddata *ddata = spi_master_get_devdata(spi->master);
++
++ unsigned bpw = t && t->bits_per_word ?
++ t->bits_per_word : spi->bits_per_word;
++ unsigned speed = t && t->speed_hz ? t->speed_hz : spi->max_speed_hz;
++ unsigned long clkfreq = clk_get_rate(ddata->clk);
++ u32 clkdiv;
++
++ efm32_spi_write32(ddata, REG_CTRL_SYNC | REG_CTRL_MSBF |
++ (spi->mode & SPI_CPHA ? REG_CTRL_CLKPHA : 0) |
++ (spi->mode & SPI_CPOL ? REG_CTRL_CLKPOL : 0), REG_CTRL);
++
++ efm32_spi_write32(ddata,
++ REG_FRAME_DATABITS(bpw), REG_FRAME);
++ /* XXX */
++ if (2 * speed >= clkfreq)
++ clkdiv = 0;
++ else
++ clkdiv = 64 * (DIV_ROUND_UP(2 * clkfreq, speed) - 4);
++
++ if (clkdiv > (1U << 21))
++ return -EINVAL;
++
++ efm32_spi_write32(ddata, clkdiv, REG_CLKDIV);
++ efm32_spi_write32(ddata, REG_CMD_MASTEREN, REG_CMD);
++ efm32_spi_write32(ddata, REG_CMD_RXEN | REG_CMD_TXEN, REG_CMD);
++
++ return 0;
++}
++
++#define DEFINE_EFM32_SPI_XFER(type) \
++static void efm32_spi_tx_ ## type(struct efm32_spi_ddata *ddata) \
++{ \
++ type val = 0; \
++ \
++ if (ddata->tx_len >= sizeof(type)) { \
++ if (ddata->tx_buf) { \
++ val = *(type *)ddata->tx_buf; \
++ ddata->tx_buf += sizeof(type); \
++ } \
++ \
++ ddata->tx_len -= sizeof(type); \
++ efm32_spi_write32(ddata, val, REG_TXDATA); \
++ pr_debug("%s: tx 0x%x\n", __func__, val); \
++ } \
++} \
++ \
++static void efm32_spi_rx_ ## type(struct efm32_spi_ddata *ddata) \
++{ \
++ if (ddata->rx_len >= sizeof(type)) { \
++ u32 rxdata = efm32_spi_read32(ddata, REG_RXDATAX); \
++ pr_debug("%s: rx 0x%x\n", __func__, rxdata); \
++ \
++ if (ddata->rx_buf) { \
++ *(type *)ddata->rx_buf = rxdata; \
++ ddata->rx_buf += sizeof(type); \
++ } \
++ \
++ ddata->rx_len -= sizeof(type); \
++ } \
++}
++
++DEFINE_EFM32_SPI_XFER(u8)
++
++static void efm32_spi_filltx(struct efm32_spi_ddata *ddata)
++{
++ while (ddata->tx_len &&
++ ddata->tx_len + 2 /* XXX * bpw */ > ddata->rx_len &&
++ efm32_spi_read32(ddata, REG_STATUS) & REG_STATUS_TXBL) {
++ efm32_spi_tx_u8(ddata);
++ }
++}
++
++static int efm32_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
++{
++ struct efm32_spi_ddata *ddata = spi_master_get_devdata(spi->master);
++ int ret = -EBUSY;
++
++ spin_lock_irq(&ddata->lock);
++
++ if (ddata->tx_buf || ddata->rx_buf)
++ goto out_unlock;
++
++ ddata->tx_buf = t->tx_buf;
++ ddata->rx_buf = t->rx_buf;
++ ddata->tx_len = ddata->rx_len = t->len;
++
++ efm32_spi_filltx(ddata);
++
++ init_completion(&ddata->done);
++
++ efm32_spi_write32(ddata, REG_IF_TXBL | REG_IF_RXDATAV, REG_IEN);
++
++ spin_unlock_irq(&ddata->lock);
++
++ wait_for_completion(&ddata->done);
++
++ spin_lock_irq(&ddata->lock);
++
++ ret = t->len - max(ddata->tx_len, ddata->rx_len);
++
++ efm32_spi_write32(ddata, 0, REG_IEN);
++ ddata->tx_buf = ddata->rx_buf = NULL;
++
++out_unlock:
++ spin_unlock_irq(&ddata->lock);
++
++ return ret;
++}
++
++static irqreturn_t efm32_spi_rxirq(int irq, void *data)
++{
++ struct efm32_spi_ddata *ddata = data;
++ irqreturn_t ret = IRQ_NONE;
++
++ spin_lock(&ddata->lock);
++
++ while (ddata->rx_len > 0 &&
++ efm32_spi_read32(ddata, REG_STATUS) &
++ REG_STATUS_RXDATAV) {
++ efm32_spi_rx_u8(ddata);
++
++ ret = IRQ_HANDLED;
++ }
++
++ if (!ddata->rx_len) {
++ u32 ien = efm32_spi_read32(ddata, REG_IEN);
++
++ ien &= ~REG_IF_RXDATAV;
++
++ efm32_spi_write32(ddata, ien, REG_IEN);
++
++ complete(&ddata->done);
++ }
++
++ spin_unlock(&ddata->lock);
++
++ return ret;
++}
++
++static irqreturn_t efm32_spi_txirq(int irq, void *data)
++{
++ struct efm32_spi_ddata *ddata = data;
++
++ pr_debug("%s: txlen = %u, rxlen = %u, if=0x%08x, status=0x%08x\n",
++ __func__, ddata->tx_len, ddata->rx_len,
++ efm32_spi_read32(ddata, REG_IF),
++ efm32_spi_read32(ddata, REG_STATUS));
++
++ spin_lock(&ddata->lock);
++
++ efm32_spi_filltx(ddata);
++
++ pr_debug("%s: txlen = %u, rxlen = %u\n", __func__,
++ ddata->tx_len, ddata->rx_len);
++
++ if (!ddata->tx_len) {
++ u32 ien = efm32_spi_read32(ddata, REG_IEN);
++
++ ien &= ~REG_IF_TXBL;
++
++ efm32_spi_write32(ddata, ien, REG_IEN);
++ pr_debug("disable TXBL\n");
++ }
++
++ spin_unlock(&ddata->lock);
++
++ return IRQ_HANDLED;
++}
++
++static int __devinit efm32_spi_probe(struct platform_device *pdev)
++{
++ struct efm32_spi_ddata *ddata;
++ struct resource *res;
++ int ret;
++ struct spi_master *master;
++
++ pr_debug("%s %d\n", __func__, sizeof(struct efm32_spi_ddata));
++
++ master = spi_alloc_master(&pdev->dev, sizeof(*ddata));
++ if (!master) {
++ dev_dbg(&pdev->dev,
++ "failed to allocate spi master controller\n");
++ return -ENOMEM;
++ }
++ platform_set_drvdata(pdev, master);
++
++ master->bus_num = pdev->id;
++ master->num_chipselect = 1;
++ master->setup = efm32_spi_setup;
++ master->cleanup = efm32_spi_cleanup;
++ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
++
++ ddata = spi_master_get_devdata(master);
++
++ ddata->bitbang.master = spi_master_get(master);
++ ddata->bitbang.chipselect = efm32_spi_chipselect;
++ ddata->bitbang.setup_transfer = efm32_spi_setup_transfer;
++ ddata->bitbang.txrx_bufs = efm32_spi_txrx_bufs;
++
++ spin_lock_init(&ddata->lock);
++
++ ddata->clk = clk_get(&pdev->dev, NULL);
++ if (IS_ERR(ddata->clk)) {
++ ret = PTR_ERR(ddata->clk);
++ dev_dbg(&pdev->dev, "failed to get clock: %d\n", ret);
++ goto err_clk_get;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ ret = -ENODEV;
++ dev_dbg(&pdev->dev, "failed to determine base address\n");
++ goto err_get_base;
++ }
++
++ if (resource_size(res) < 60) {
++ ret = -EINVAL;
++ dev_dbg(&pdev->dev, "memory resource too small\n");
++ goto err_too_small;
++ }
++
++ /* XXX: request_mem_region? */
++
++ ddata->base = ioremap(res->start, resource_size(res));
++ if (!ddata->base) {
++ ret = -ENOMEM;
++ dev_dbg(&pdev->dev, "failed to remap memory\n");
++ goto err_ioremap;
++ }
++
++ ret = platform_get_irq(pdev, 0);
++ if (ret <= 0) {
++ dev_dbg(&pdev->dev, "failed to get rx irq\n");
++ goto err_get_rxirq;
++ }
++
++ ddata->rxirq = ret;
++
++ ret = platform_get_irq(pdev, 1);
++ if (ret <= 0)
++ ret = ddata->rxirq + 1;
++
++ ddata->txirq = ret;
++
++ efm32_spi_write32(ddata, 0, REG_IEN);
++ efm32_spi_write32(ddata, REG_ROUTE_TXPEN | REG_ROUTE_RXPEN |
++ REG_ROUTE_CLKPEN | REG_ROUTE_LOCATION(1), REG_ROUTE);
++
++ ret = request_irq(ddata->rxirq, efm32_spi_rxirq, 0, DRIVER_NAME, ddata);
++ if (ret) {
++ dev_dbg(&pdev->dev, "failed to register rxirq (%d)\n", ret);
++ goto err_request_rxirq;
++ }
++
++ ret = request_irq(ddata->txirq, efm32_spi_txirq, 0, DRIVER_NAME, ddata);
++ if (ret) {
++ dev_dbg(&pdev->dev, "failed to register txirq (%d)\n", ret);
++ goto err_request_txirq;
++ }
++
++ ret = spi_bitbang_start(&ddata->bitbang);
++ if (ret) {
++ dev_dbg(&pdev->dev, "spi_bitbang_start failed: %d\n", ret);
++
++ free_irq(ddata->txirq, ddata);
++err_request_txirq:
++
++ free_irq(ddata->rxirq, ddata);
++err_request_rxirq:
++err_get_rxirq:
++ iounmap(ddata->base);
++err_ioremap:
++err_too_small:
++err_get_base:
++ clk_put(ddata->clk);
++err_clk_get:
++ platform_set_drvdata(pdev, NULL);
++ spi_master_put(master);
++ kfree(master);
++ }
++
++ pr_debug("%s returns %d\n", __func__, ret);
++ return ret;
++}
++
++static void __devexit efm32_spi_remove(struct platform_device *pdev)
++{
++ struct spi_master *master = platform_get_drvdata(pdev);
++ struct efm32_spi_ddata *ddata = spi_master_get_devdata(master);
++
++ free_irq(ddata->txirq, ddata);
++ free_irq(ddata->rxirq, ddata);
++ iounmap(ddata->base);
++ clk_put(ddata->clk);
++ platform_set_drvdata(pdev, NULL);
++ spi_master_put(master);
++ kfree(master);
++}
++
++static struct platform_driver efm32_spi_driver = {
++ .probe = efm32_spi_probe,
++ .remove = __devexit_p(efm32_spi_remove),
++
++ .driver = {
++ .name = DRIVER_NAME,
++ .owner = THIS_MODULE,
++ },
++};
++module_platform_driver(efm32_spi_driver);
++
++MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
++MODULE_DESCRIPTION("EFM32 SPI driver");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/patches/linux-3.6/0003-ARM-make-cr_alignment-read-only-ifndef-CONFIG_CPU_CP.patch b/patches/linux-3.6/0003-ARM-make-cr_alignment-read-only-ifndef-CONFIG_CPU_CP.patch
new file mode 100644
index 0000000..33f3731
--- /dev/null
+++ b/patches/linux-3.6/0003-ARM-make-cr_alignment-read-only-ifndef-CONFIG_CPU_CP.patch
@@ -0,0 +1,131 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Mon, 16 Jan 2012 10:34:31 +0100
+Subject: [PATCH] ARM: make cr_alignment read-only #ifndef CONFIG_CPU_CP15
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This makes cr_alignment a constant 0 to break code that tries to modify
+the value as it's likely that it's built on wrong assumption when
+CONFIG_CPU_CP15 isn't defined. For code that is only reading the value 0
+is more or less a fine value to report.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Forwarded: id:1333573807-23709-1-git-send-email-u.kleine-koenig@pengutronix.de
+---
+ arch/arm/include/asm/cp15.h | 11 ++++++++++-
+ arch/arm/kernel/head-common.S | 9 +++++++--
+ arch/arm/mm/alignment.c | 2 ++
+ arch/arm/mm/mmu.c | 17 +++++++++++++++++
+ 4 files changed, 36 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h
+index 5ef4d80..d814435 100644
+--- a/arch/arm/include/asm/cp15.h
++++ b/arch/arm/include/asm/cp15.h
+@@ -42,6 +42,8 @@
+ #define vectors_high() (0)
+ #endif
+
++#ifdef CONFIG_CPU_CP15
++
+ extern unsigned long cr_no_alignment; /* defined in entry-armv.S */
+ extern unsigned long cr_alignment; /* defined in entry-armv.S */
+
+@@ -82,6 +84,13 @@ static inline void set_copro_access(unsigned int val)
+ isb();
+ }
+
+-#endif
++#else /* ifdef CONFIG_CPU_CP15 */
++
++#define cr_no_alignment UL(0)
++#define cr_alignment UL(0)
++
++#endif /* ifdef CONFIG_CPU_CP15 / else */
++
++#endif /* ifndef __ASSEMBLY__ */
+
+ #endif
+diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
+index 854bd22..2f560c5 100644
+--- a/arch/arm/kernel/head-common.S
++++ b/arch/arm/kernel/head-common.S
+@@ -98,8 +98,9 @@ __mmap_switched:
+ str r9, [r4] @ Save processor ID
+ str r1, [r5] @ Save machine type
+ str r2, [r6] @ Save atags pointer
+- bic r4, r0, #CR_A @ Clear 'A' bit
+- stmia r7, {r0, r4} @ Save control register values
++ cmp r7, #0
++ bicne r4, r0, #CR_A @ Clear 'A' bit
++ stmneia r7, {r0, r4} @ Save control register values
+ b start_kernel
+ ENDPROC(__mmap_switched)
+
+@@ -113,7 +114,11 @@ __mmap_switched_data:
+ .long processor_id @ r4
+ .long __machine_arch_type @ r5
+ .long __atags_pointer @ r6
++#ifdef CONFIG_CPU_CP15
+ .long cr_alignment @ r7
++#else
++ .long 0
++#endif
+ .long init_thread_union + THREAD_START_SP @ sp
+ .size __mmap_switched_data, . - __mmap_switched_data
+
+diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
+index 9107231..7df07d1 100644
+--- a/arch/arm/mm/alignment.c
++++ b/arch/arm/mm/alignment.c
+@@ -962,12 +962,14 @@ static int __init alignment_init(void)
+ return -ENOMEM;
+ #endif
+
++#ifdef CONFIG_CPU_CP15
+ if (cpu_is_v6_unaligned()) {
+ cr_alignment &= ~CR_A;
+ cr_no_alignment &= ~CR_A;
+ set_cr(cr_alignment);
+ ai_usermode = safe_usermode(ai_usermode, false);
+ }
++#endif
+
+ hook_fault_code(FAULT_CODE_ALIGNMENT, do_alignment, SIGBUS, BUS_ADRALN,
+ "alignment exception");
+diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
+index c2fa21d..07d19a6 100644
+--- a/arch/arm/mm/mmu.c
++++ b/arch/arm/mm/mmu.c
+@@ -96,6 +96,7 @@ static struct cachepolicy cache_policies[] __initdata = {
+ }
+ };
+
++#ifdef CONFIG_CPU_CP15
+ /*
+ * These are useful for identifying cache coherency
+ * problems by allowing the cache or the cache and
+@@ -194,6 +195,22 @@ void adjust_cr(unsigned long mask, unsigned long set)
+ }
+ #endif
+
++#else
++
++static int __init early_cachepolicy(char *p)
++{
++ pr_warning("cachepolicy kernel parameter not supported without cp15\n");
++}
++early_param("cachepolicy", early_cachepolicy);
++
++static int __init noalign_setup(char *__unused)
++{
++ pr_warning("noalign kernel parameter not supported without cp15\n");
++}
++__setup("noalign", noalign_setup);
++
++#endif
++
+ #define PROT_PTE_DEVICE L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
+ #define PROT_SECT_DEVICE PMD_TYPE_SECT|PMD_SECT_AP_WRITE
+
diff --git a/patches/linux-3.6/0004-Cortex-M3-Add-base-support-for-Cortex-M3.patch b/patches/linux-3.6/0004-Cortex-M3-Add-base-support-for-Cortex-M3.patch
new file mode 100644
index 0000000..0dbb461
--- /dev/null
+++ b/patches/linux-3.6/0004-Cortex-M3-Add-base-support-for-Cortex-M3.patch
@@ -0,0 +1,665 @@
+From: Catalin Marinas <catalin.marinas@arm.com>
+Date: Fri, 21 May 2010 18:06:41 +0100
+Subject: [PATCH] Cortex-M3: Add base support for Cortex-M3
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch adds the base support for the Cortex-M3 processor (ARMv7-M
+architecture). It consists of the corresponding arch/arm/mm/ files and
+various #ifdef's around the kernel. Exception handling is implemented by
+a subsequent patch.
+
+[ukleinek: squash in some changes originating from commit
+
+b5717ba (Cortex-M3: Add support for the Microcontroller Prototyping System)
+
+from the v2.6.33-arm1 patch stack, port to post 3.4, drop zImage
+support, drop reorganisation of pt_regs, assert CONFIG_V7M doesn't leak
+into installed headers and a few cosmetic changes]
+
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+Changes since v4, id:1333573807-23709-2-git-send-email-u.kleine-koenig@pengutronix.de
+ - simplify irq enable/disable ops as suggested by Russell
+ - don't leak kernel config symbols into userspace headers and add some
+ comments
+---
+ arch/arm/include/asm/assembler.h | 13 ++-
+ arch/arm/include/asm/cputype.h | 3 +
+ arch/arm/include/asm/glue-cache.h | 24 ++++++
+ arch/arm/include/asm/glue-df.h | 8 ++
+ arch/arm/include/asm/glue-proc.h | 9 ++
+ arch/arm/include/asm/irqflags.h | 22 +++--
+ arch/arm/include/asm/processor.h | 7 ++
+ arch/arm/include/asm/ptrace.h | 44 ++++++++--
+ arch/arm/include/asm/system_info.h | 1 +
+ arch/arm/kernel/asm-offsets.c | 3 +
+ arch/arm/kernel/head-nommu.S | 9 +-
+ arch/arm/kernel/setup.c | 13 ++-
+ arch/arm/kernel/traps.c | 2 +
+ arch/arm/mm/nommu.c | 2 +
+ arch/arm/mm/proc-v7m.S | 161 ++++++++++++++++++++++++++++++++++++
+ 15 files changed, 302 insertions(+), 19 deletions(-)
+ create mode 100644 arch/arm/mm/proc-v7m.S
+
+diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
+index 5c8b3bf..6ce005b 100644
+--- a/arch/arm/include/asm/assembler.h
++++ b/arch/arm/include/asm/assembler.h
+@@ -135,7 +135,11 @@
+ * assumes FIQs are enabled, and that the processor is in SVC mode.
+ */
+ .macro save_and_disable_irqs, oldcpsr
++#ifdef CONFIG_CPU_V7M
++ mrs \oldcpsr, primask
++#else
+ mrs \oldcpsr, cpsr
++#endif
+ disable_irq
+ .endm
+
+@@ -149,7 +153,11 @@
+ * guarantee that this will preserve the flags.
+ */
+ .macro restore_irqs_notrace, oldcpsr
++#ifdef CONFIG_CPU_V7M
++ msr primask, \oldcpsr
++#else
+ msr cpsr_c, \oldcpsr
++#endif
+ .endm
+
+ .macro restore_irqs, oldcpsr
+@@ -228,7 +236,10 @@
+ #endif
+ .endm
+
+-#ifdef CONFIG_THUMB2_KERNEL
++#if defined(CONFIG_CPU_V7M)
++ .macro setmode, mode, reg
++ .endm
++#elif defined(CONFIG_THUMB2_KERNEL)
+ .macro setmode, mode, reg
+ mov \reg, #\mode
+ msr cpsr_c, \reg
+diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
+index cb47d28..5bd8cb6 100644
+--- a/arch/arm/include/asm/cputype.h
++++ b/arch/arm/include/asm/cputype.h
+@@ -46,6 +46,9 @@ extern unsigned int processor_id;
+ : "cc"); \
+ __val; \
+ })
++#elif defined(CONFIG_CPU_V7M)
++#define read_cpuid(reg) (*(unsigned int *)0xe000ed00)
++#define read_cpuid_ext(reg) 0
+ #else
+ #define read_cpuid(reg) (processor_id)
+ #define read_cpuid_ext(reg) 0
+diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h
+index 7e30874..a02fd01 100644
+--- a/arch/arm/include/asm/glue-cache.h
++++ b/arch/arm/include/asm/glue-cache.h
+@@ -125,10 +125,34 @@
+ //# endif
+ #endif
+
++#if defined(CONFIG_CPU_V7M)
++# ifdef _CACHE
++# error "Multi-cache not supported on ARMv7-M"
++# else
++# define _CACHE nop
++# endif
++#endif
++
+ #if !defined(_CACHE) && !defined(MULTI_CACHE)
+ #error Unknown cache maintenance model
+ #endif
+
++#ifndef __ASSEMBLER__
++static inline void nop_flush_icache_all(void) { }
++static inline void nop_flush_kern_cache_all(void) { }
++static inline void nop_flush_user_cache_all(void) { }
++static inline void nop_flush_user_cache_range(unsigned long a, unsigned long b, unsigned int c) { }
++
++static inline void nop_coherent_kern_range(unsigned long a, unsigned long b) { }
++static inline int nop_coherent_user_range(unsigned long a, unsigned long b) { return 0; }
++static inline void nop_flush_kern_dcache_area(void *a, size_t s) { }
++
++static inline void nop_dma_flush_range(const void *a, const void *b) { }
++
++static inline void nop_dma_map_area(const void *s, size_t l, int f) { }
++static inline void nop_dma_unmap_area(const void *s, size_t l, int f) { }
++#endif
++
+ #ifndef MULTI_CACHE
+ #define __cpuc_flush_icache_all __glue(_CACHE,_flush_icache_all)
+ #define __cpuc_flush_kern_all __glue(_CACHE,_flush_kern_cache_all)
+diff --git a/arch/arm/include/asm/glue-df.h b/arch/arm/include/asm/glue-df.h
+index 8cacbcd..1f2339c 100644
+--- a/arch/arm/include/asm/glue-df.h
++++ b/arch/arm/include/asm/glue-df.h
+@@ -95,6 +95,14 @@
+ # endif
+ #endif
+
++#ifdef CONFIG_CPU_ABRT_NOMMU
++# ifdef CPU_DABORT_HANDLER
++# define MULTI_DABORT 1
++# else
++# define CPU_DABORT_HANDLER nommu_early_abort
++# endif
++#endif
++
+ #ifndef CPU_DABORT_HANDLER
+ #error Unknown data abort handler type
+ #endif
+diff --git a/arch/arm/include/asm/glue-proc.h b/arch/arm/include/asm/glue-proc.h
+index ac1dd54..f2f39bc 100644
+--- a/arch/arm/include/asm/glue-proc.h
++++ b/arch/arm/include/asm/glue-proc.h
+@@ -230,6 +230,15 @@
+ # endif
+ #endif
+
++#ifdef CONFIG_CPU_V7M
++# ifdef CPU_NAME
++# undef MULTI_CPU
++# define MULTI_CPU
++# else
++# define CPU_NAME cpu_v7m
++# endif
++#endif
++
+ #ifndef MULTI_CPU
+ #define cpu_proc_init __glue(CPU_NAME,_proc_init)
+ #define cpu_proc_fin __glue(CPU_NAME,_proc_fin)
+diff --git a/arch/arm/include/asm/irqflags.h b/arch/arm/include/asm/irqflags.h
+index 1e6cca5..3b763d6 100644
+--- a/arch/arm/include/asm/irqflags.h
++++ b/arch/arm/include/asm/irqflags.h
+@@ -8,6 +8,16 @@
+ /*
+ * CPU interrupt mask handling.
+ */
++#ifdef CONFIG_CPU_V7M
++#define IRQMASK_REG_NAME_R "primask"
++#define IRQMASK_REG_NAME_W "primask"
++#define IRQMASK_I_BIT 1
++#else
++#define IRQMASK_REG_NAME_R "cpsr"
++#define IRQMASK_REG_NAME_W "cpsr_c"
++#define IRQMASK_I_BIT PSR_I_BIT
++#endif
++
+ #if __LINUX_ARM_ARCH__ >= 6
+
+ static inline unsigned long arch_local_irq_save(void)
+@@ -15,7 +25,7 @@ static inline unsigned long arch_local_irq_save(void)
+ unsigned long flags;
+
+ asm volatile(
+- " mrs %0, cpsr @ arch_local_irq_save\n"
++ " mrs %0, " IRQMASK_REG_NAME_R " @ arch_local_irq_save\n"
+ " cpsid i"
+ : "=r" (flags) : : "memory", "cc");
+ return flags;
+@@ -129,7 +139,7 @@ static inline unsigned long arch_local_save_flags(void)
+ {
+ unsigned long flags;
+ asm volatile(
+- " mrs %0, cpsr @ local_save_flags"
++ " mrs %0, " IRQMASK_REG_NAME_R " @ local_save_flags"
+ : "=r" (flags) : : "memory", "cc");
+ return flags;
+ }
+@@ -140,7 +150,7 @@ static inline unsigned long arch_local_save_flags(void)
+ static inline void arch_local_irq_restore(unsigned long flags)
+ {
+ asm volatile(
+- " msr cpsr_c, %0 @ local_irq_restore"
++ " msr " IRQMASK_REG_NAME_W ", %0 @ local_irq_restore"
+ :
+ : "r" (flags)
+ : "memory", "cc");
+@@ -148,8 +158,8 @@ static inline void arch_local_irq_restore(unsigned long flags)
+
+ static inline int arch_irqs_disabled_flags(unsigned long flags)
+ {
+- return flags & PSR_I_BIT;
++ return flags & IRQMASK_I_BIT;
+ }
+
+-#endif
+-#endif
++#endif /* ifdef __KERNEL__ */
++#endif /* ifndef __ASM_ARM_IRQFLAGS_H */
+diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
+index 99afa74..dc82aa0 100644
+--- a/arch/arm/include/asm/processor.h
++++ b/arch/arm/include/asm/processor.h
+@@ -49,7 +49,14 @@ struct thread_struct {
+ #ifdef CONFIG_MMU
+ #define nommu_start_thread(regs) do { } while (0)
+ #else
++#ifndef CONFIG_CPU_V7M
+ #define nommu_start_thread(regs) regs->ARM_r10 = current->mm->start_data
++#else
++#define nommu_start_thread(regs) do { \
++ regs->ARM_r10 = current->mm->start_data; \
++ regs->ARM_EXC_RET = 0xfffffffdL; \
++} while (0)
++#endif
+ #endif
+
+ #define start_thread(regs,pc,sp) \
+diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
+index 355ece5..090fea7 100644
+--- a/arch/arm/include/asm/ptrace.h
++++ b/arch/arm/include/asm/ptrace.h
+@@ -34,27 +34,46 @@
+
+ /*
+ * PSR bits
++ * Note on V7M there is no mode contained in the PSR
+ */
+ #define USR26_MODE 0x00000000
+ #define FIQ26_MODE 0x00000001
+ #define IRQ26_MODE 0x00000002
+ #define SVC26_MODE 0x00000003
++#if defined(__KERNEL__) && defined(CONFIG_CPU_V7M)
++/*
++ * Use 0 here to get code right that creates a userspace
++ * or kernel space thread
++ */
++#define USR_MODE 0x00000000
++#define SVC_MODE 0x00000000
++#else
+ #define USR_MODE 0x00000010
++#define SVC_MODE 0x00000013
++#endif
+ #define FIQ_MODE 0x00000011
+ #define IRQ_MODE 0x00000012
+-#define SVC_MODE 0x00000013
+ #define ABT_MODE 0x00000017
+ #define UND_MODE 0x0000001b
+ #define SYSTEM_MODE 0x0000001f
+ #define MODE32_BIT 0x00000010
+ #define MODE_MASK 0x0000001f
+-#define PSR_T_BIT 0x00000020
+-#define PSR_F_BIT 0x00000040
+-#define PSR_I_BIT 0x00000080
+-#define PSR_A_BIT 0x00000100
+-#define PSR_E_BIT 0x00000200
+-#define PSR_J_BIT 0x01000000
+-#define PSR_Q_BIT 0x08000000
++
++#define V4_PSR_T_BIT 0x00000020 /* >= V4T, but not V7M */
++#define V7M_PSR_T_BIT 0x01000000
++#if defined(__KERNEL__) && defined(CONFIG_CPU_V7M)
++#define PSR_T_BIT V7M_PSR_T_BIT
++#else
++/* for compatibility */
++#define PSR_T_BIT V4_PSR_T_BIT
++#endif
++
++#define PSR_F_BIT 0x00000040 /* >= V4, but not V7M */
++#define PSR_I_BIT 0x00000080 /* >= V4, but not V7M */
++#define PSR_A_BIT 0x00000100 /* >= V6, but not V7M */
++#define PSR_E_BIT 0x00000200 /* >= V6, but not V7M */
++#define PSR_J_BIT 0x01000000 /* >= V5J, but not V7M */
++#define PSR_Q_BIT 0x08000000 /* >= V5E, including V7M */
+ #define PSR_V_BIT 0x10000000
+ #define PSR_C_BIT 0x20000000
+ #define PSR_Z_BIT 0x40000000
+@@ -106,7 +125,11 @@ struct pt_regs {
+ };
+ #else /* __KERNEL__ */
+ struct pt_regs {
++#ifdef CONFIG_CPU_V7M
++ unsigned long uregs[20];
++#else
+ unsigned long uregs[18];
++#endif
+ };
+ #endif /* __KERNEL__ */
+
+@@ -128,6 +151,7 @@ struct pt_regs {
+ #define ARM_r1 uregs[1]
+ #define ARM_r0 uregs[0]
+ #define ARM_ORIG_r0 uregs[17]
++#define ARM_EXC_RET uregs[18]
+
+ /*
+ * The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
+@@ -165,6 +189,7 @@ struct pt_regs {
+ */
+ static inline int valid_user_regs(struct pt_regs *regs)
+ {
++#ifndef CONFIG_CPU_V7M
+ unsigned long mode = regs->ARM_cpsr & MODE_MASK;
+
+ /*
+@@ -187,6 +212,9 @@ static inline int valid_user_regs(struct pt_regs *regs)
+ regs->ARM_cpsr |= USR_MODE;
+
+ return 0;
++#else /* ifndef CONFIG_CPU_V7M */
++ return 1;
++#endif
+ }
+
+ static inline long regs_return_value(struct pt_regs *regs)
+diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h
+index dfd386d..720ea03 100644
+--- a/arch/arm/include/asm/system_info.h
++++ b/arch/arm/include/asm/system_info.h
+@@ -11,6 +11,7 @@
+ #define CPU_ARCH_ARMv5TEJ 7
+ #define CPU_ARCH_ARMv6 8
+ #define CPU_ARCH_ARMv7 9
++#define CPU_ARCH_ARMv7M 10
+
+ #ifndef __ASSEMBLY__
+
+diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
+index 1429d89..6f6b5b6 100644
+--- a/arch/arm/kernel/asm-offsets.c
++++ b/arch/arm/kernel/asm-offsets.c
+@@ -91,6 +91,9 @@ int main(void)
+ DEFINE(S_PC, offsetof(struct pt_regs, ARM_pc));
+ DEFINE(S_PSR, offsetof(struct pt_regs, ARM_cpsr));
+ DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0));
++#ifdef CONFIG_CPU_V7M
++ DEFINE(S_EXC_RET, offsetof(struct pt_regs, ARM_EXC_RET));
++#endif
+ DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
+ BLANK();
+ #ifdef CONFIG_CACHE_L2X0
+diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
+index 278cfc1..c391c05 100644
+--- a/arch/arm/kernel/head-nommu.S
++++ b/arch/arm/kernel/head-nommu.S
+@@ -44,10 +44,13 @@ ENTRY(stext)
+
+ setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
+ @ and irqs disabled
+-#ifndef CONFIG_CPU_CP15
+- ldr r9, =CONFIG_PROCESSOR_ID
+-#else
++#if defined(CONFIG_CPU_CP15)
+ mrc p15, 0, r9, c0, c0 @ get processor id
++#elif defined(CONFIG_CPU_V7M)
++ ldr r9, =0xe000ed00 @ CPUID register address
++ ldr r9, [r9]
++#else
++ ldr r9, =CONFIG_PROCESSOR_ID
+ #endif
+ bl __lookup_processor_type @ r5=procinfo r9=cpuid
+ movs r10, r5 @ invalid processor (r5=0)?
+diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
+index a81dcec..4dda5ca 100644
+--- a/arch/arm/kernel/setup.c
++++ b/arch/arm/kernel/setup.c
+@@ -135,7 +135,9 @@ struct stack {
+ u32 und[3];
+ } ____cacheline_aligned;
+
++#ifndef CONFIG_CPU_V7M
+ static struct stack stacks[NR_CPUS];
++#endif
+
+ char elf_platform[ELF_PLATFORM_SIZE];
+ EXPORT_SYMBOL(elf_platform);
+@@ -215,7 +217,7 @@ static const char *proc_arch[] = {
+ "5TEJ",
+ "6TEJ",
+ "7",
+- "?(11)",
++ "7M",
+ "?(12)",
+ "?(13)",
+ "?(14)",
+@@ -224,6 +226,12 @@ static const char *proc_arch[] = {
+ "?(17)",
+ };
+
++#ifdef CONFIG_CPU_V7M
++static int __get_cpu_architecture(void)
++{
++ return CPU_ARCH_ARMv7M;
++}
++#else
+ static int __get_cpu_architecture(void)
+ {
+ int cpu_arch;
+@@ -256,6 +264,7 @@ static int __get_cpu_architecture(void)
+
+ return cpu_arch;
+ }
++#endif
+
+ int __pure cpu_architecture(void)
+ {
+@@ -383,6 +392,7 @@ static void __init feat_v6_fixup(void)
+ */
+ void cpu_init(void)
+ {
++#ifndef CONFIG_CPU_V7M
+ unsigned int cpu = smp_processor_id();
+ struct stack *stk = &stacks[cpu];
+
+@@ -427,6 +437,7 @@ void cpu_init(void)
+ "I" (offsetof(struct stack, und[0])),
+ PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
+ : "r14");
++#endif
+ }
+
+ int __cpu_logical_map[NR_CPUS];
+diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
+index b0179b8..12d976b 100644
+--- a/arch/arm/kernel/traps.c
++++ b/arch/arm/kernel/traps.c
+@@ -819,6 +819,7 @@ static void __init kuser_get_tls_init(unsigned long vectors)
+
+ void __init early_trap_init(void *vectors_base)
+ {
++#ifndef CONFIG_CPU_V7M
+ unsigned long vectors = (unsigned long)vectors_base;
+ extern char __stubs_start[], __stubs_end[];
+ extern char __vectors_start[], __vectors_end[];
+@@ -850,4 +851,5 @@ void __init early_trap_init(void *vectors_base)
+
+ flush_icache_range(vectors, vectors + PAGE_SIZE);
+ modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
++#endif
+ }
+diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
+index d51225f..4bc8ae5 100644
+--- a/arch/arm/mm/nommu.c
++++ b/arch/arm/mm/nommu.c
+@@ -20,12 +20,14 @@
+
+ void __init arm_mm_memblock_reserve(void)
+ {
++#ifndef CONFIG_CPU_V7M
+ /*
+ * Register the exception vector page.
+ * some architectures which the DRAM is the exception vector to trap,
+ * alloc_page breaks with error, although it is not NULL, but "0."
+ */
+ memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
++#endif
+ }
+
+ void __init sanity_check_meminfo(void)
+diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S
+new file mode 100644
+index 0000000..2b8eb97
+--- /dev/null
++++ b/arch/arm/mm/proc-v7m.S
+@@ -0,0 +1,161 @@
++/*
++ * linux/arch/arm/mm/proc-v7m.S
++ *
++ * Copyright (C) 2008 ARM Ltd.
++ * Copyright (C) 2001 Deep Blue Solutions Ltd.
++ *
++ * This program is free software; you can 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 is the "shell" of the ARMv7-M processor support.
++ */
++#include <linux/linkage.h>
++#include <asm/assembler.h>
++
++ENTRY(cpu_v7m_proc_init)
++ mov pc, lr
++ENDPROC(cpu_v7m_proc_init)
++
++ENTRY(cpu_v7m_proc_fin)
++ mov pc, lr
++ENDPROC(cpu_v7m_proc_fin)
++
++/*
++ * cpu_v7m_reset(loc)
++ *
++ * Perform a soft reset of the system. Put the CPU into the
++ * same state as it would be if it had been reset, and branch
++ * to what would be the reset vector.
++ *
++ * - loc - location to jump to for soft reset
++ */
++ .align 5
++ENTRY(cpu_v7m_reset)
++ mov pc, r0
++ENDPROC(cpu_v7m_reset)
++
++/*
++ * cpu_v7m_do_idle()
++ *
++ * Idle the processor (eg, wait for interrupt).
++ *
++ * IRQs are already disabled.
++ */
++ENTRY(cpu_v7m_do_idle)
++ wfi
++ mov pc, lr
++ENDPROC(cpu_v7m_do_idle)
++
++ENTRY(cpu_v7m_dcache_clean_area)
++ mov pc, lr
++ENDPROC(cpu_v7m_dcache_clean_area)
++
++/*
++ * There is no MMU, so here is nothing to do.
++ */
++ENTRY(cpu_v7m_switch_mm)
++ mov pc, lr
++ENDPROC(cpu_v7m_switch_mm)
++
++cpu_v7m_name:
++ .ascii "ARMv7-M Processor"
++ .align
++
++ .section ".text.init", #alloc, #execinstr
++
++/*
++ * __v7m_setup
++ *
++ * This should be able to cover all ARMv7-M cores.
++ */
++__v7m_setup:
++ @ Configure the vector table base address
++ ldr r0, =0xe000ed08 @ vector table base address
++ ldr r12, =vector_table
++ str r12, [r0]
++
++ @ Lower the priority of the SVC and PendSV exceptions
++ ldr r0, =0xe000ed1c
++ mov r5, #0x80000000
++ str r5, [r0] @ set SVC priority
++ ldr r0, =0xe000ed20
++ mov r5, #0x00800000
++ str r5, [r0] @ set PendSV priority
++
++ @ SVC to run the kernel in this mode
++ adr r0, BSYM(1f)
++ ldr r5, [r12, #11 * 4] @ read the SVC vector entry
++ str r0, [r12, #11 * 4] @ write the temporary SVC vector entry
++ mov r6, lr @ save LR
++ mov r7, sp @ save SP
++ ldr sp, =__v7m_setup_stack_top
++ cpsie i
++ svc #0
++1: cpsid i
++ str r5, [r12, #11 * 4] @ restore the original SVC vector entry
++ mov lr, r6 @ restore LR
++ mov sp, r7 @ restore SP
++
++ @ Special-purpose control register
++ mov r0, #1
++ msr control, r0 @ Thread mode has unpriviledged access
++
++ @ Configure the System Control Register
++ ldr r0, =0xe000ed14 @ system control register
++ ldr r12, [r0]
++ orr r12, #1 << 9 @ STKALIGN
++ str r12, [r0]
++ mov pc, lr
++ENDPROC(__v7m_setup)
++
++ .align 2
++ .type v7m_processor_functions, #object
++ENTRY(v7m_processor_functions)
++ .word nommu_early_abort
++ .word cpu_v7m_proc_init
++ .word cpu_v7m_proc_fin
++ .word cpu_v7m_reset
++ .word cpu_v7m_do_idle
++ .word cpu_v7m_dcache_clean_area
++ .word cpu_v7m_switch_mm
++ .word 0 @ cpu_v7m_set_pte_ext
++ .word legacy_pabort
++ .size v7m_processor_functions, . - v7m_processor_functions
++
++ .type cpu_arch_name, #object
++cpu_arch_name:
++ .asciz "armv7m"
++ .size cpu_arch_name, . - cpu_arch_name
++
++ .type cpu_elf_name, #object
++cpu_elf_name:
++ .asciz "v7m"
++ .size cpu_elf_name, . - cpu_elf_name
++ .align
++
++ .section ".proc.info.init", #alloc, #execinstr
++
++ /*
++ * Match any ARMv7-M processor core.
++ */
++ .type __v7m_proc_info, #object
++__v7m_proc_info:
++ .long 0x000f0000 @ Required ID value
++ .long 0x000f0000 @ Mask for ID
++ .long 0 @ proc_info_list.__cpu_mm_mmu_flags
++ .long 0 @ proc_info_list.__cpu_io_mmu_flags
++ b __v7m_setup @ proc_info_list.__cpu_flush
++ .long cpu_arch_name
++ .long cpu_elf_name
++ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
++ .long cpu_v7m_name
++ .long v7m_processor_functions @ proc_info_list.proc
++ .long 0 @ proc_info_list.tlb
++ .long 0 @ proc_info_list.user
++ .long 0 @ proc_info_list.cache
++ .size __v7m_proc_info, . - __v7m_proc_info
++
++__v7m_setup_stack:
++ .space 4 * 8 @ 8 registers
++__v7m_setup_stack_top:
diff --git a/patches/linux-3.6/0005-Cortex-M3-Add-support-for-exception-handling.patch b/patches/linux-3.6/0005-Cortex-M3-Add-support-for-exception-handling.patch
new file mode 100644
index 0000000..1394799
--- /dev/null
+++ b/patches/linux-3.6/0005-Cortex-M3-Add-support-for-exception-handling.patch
@@ -0,0 +1,402 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Fri, 21 May 2010 18:06:42 +0100
+Subject: [PATCH] Cortex-M3: Add support for exception handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch implements the exception handling for the ARMv7-M
+architecture (pretty different from the A or R profiles).
+
+It bases on work done earlier by Catalin for 2.6.33 but was nearly
+completely rewritten to use a pt_regs layout compatible to the A
+profile.
+
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Forwarded: id:1333573807-23709-3-git-send-email-u.kleine-koenig@pengutronix.de
+---
+ arch/arm/kernel/entry-common.S | 4 ++
+ arch/arm/kernel/entry-header.S | 148 ++++++++++++++++++++++++++++++++++++++++
+ arch/arm/kernel/entry-v7m.S | 134 ++++++++++++++++++++++++++++++++++++
+ arch/arm/kernel/process.c | 8 +++
+ arch/arm/kernel/ptrace.c | 3 +
+ 5 files changed, 297 insertions(+)
+ create mode 100644 arch/arm/kernel/entry-v7m.S
+
+diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
+index 978eac5..a93eed3 100644
+--- a/arch/arm/kernel/entry-common.S
++++ b/arch/arm/kernel/entry-common.S
+@@ -327,6 +327,9 @@ ENDPROC(ftrace_stub)
+
+ .align 5
+ ENTRY(vector_swi)
++#ifdef CONFIG_CPU_V7M
++ v7m_exception_entry
++#else
+ sub sp, sp, #S_FRAME_SIZE
+ stmia sp, {r0 - r12} @ Calling r0 - r12
+ ARM( add r8, sp, #S_PC )
+@@ -337,6 +340,7 @@ ENTRY(vector_swi)
+ str lr, [sp, #S_PC] @ Save calling PC
+ str r8, [sp, #S_PSR] @ Save CPSR
+ str r0, [sp, #S_OLD_R0] @ Save OLD_R0
++#endif
+ zero_fp
+
+ /*
+diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
+index 9a8531e..33d9900 100644
+--- a/arch/arm/kernel/entry-header.S
++++ b/arch/arm/kernel/entry-header.S
+@@ -44,6 +44,145 @@
+ #endif
+ .endm
+
++#ifdef CONFIG_CPU_V7M
++/*
++ * ARMv7-M exception entry/exit macros.
++ *
++ * xPSR, ReturnAddress(), LR (R14), R12, R3, R2, R1, and R0 are
++ * automatically saved on the current stack (32 words) before
++ * switching to the exception stack (SP_main).
++ *
++ * If exception is taken while in user mode, SP_main is
++ * empty. Otherwise, SP_main is aligned to 64 bit automatically
++ * (CCR.STKALIGN set).
++ *
++ * Linux assumes that the interrupts are disabled when entering an
++ * exception handler and it may BUG if this is not the case. Interrupts
++ * are disabled during entry and reenabled in the exit macro.
++ *
++ * v7m_exception_fast_exit is used when returning from interrupts.
++ *
++ * v7m_exception_slow_exit is used when returning from SVC or PendSV.
++ * When returning to kernel mode, we don't return from exception.
++ */
++ .macro v7m_exception_entry
++ @ determine the location of the registers saved by the core during
++ @ exception entry. Depending on the mode the cpu was in when the
++ @ exception happend that is either on the main or the process stack.
++ @ Bit 2 of EXC_RETURN stored in the lr register specifies which stack
++ @ was used.
++ tst lr, #0x4
++ mrsne r12, psp
++ moveq r12, sp
++
++ @ we cannot rely on r0-r3 and r12 matching the value saved in the
++ @ exception frame because of tail-chaining. So these have to be
++ @ reloaded.
++ ldmia r12!, {r0-r3}
++
++ @ Linux expects to have irqs off. Do it here before taking stack space
++ cpsid i
++
++ sub sp, #S_FRAME_SIZE-S_IP
++ stmdb sp!, {r0-r11}
++
++ @ load saved r12, lr, return address and xPSR.
++ @ r0-r7 are used for signals and never touched from now on. Clobbering
++ @ r8-r12 is OK.
++ mov r9, r12
++ ldmia r9!, {r8, r10-r12}
++
++ @ calculate the original stack pointer value.
++ @ r9 currently points to the memory location just above the auto saved
++ @ xPSR. If the FP extension is implemented and bit 4 of EXC_RETURN is 0
++ @ then space was allocated for FP state. That is space for 18 32-bit
++ @ values. (If FP extension is unimplemented, bit 4 is 1.)
++ @ Additionally the cpu might automatically 8-byte align the stack. Bit 9
++ @ of the saved xPSR specifies if stack aligning took place. In this case
++ @ another 32-bit value is included in the stack.
++
++ tst lr, #0x10
++ addeq r9, r9, #576
++
++ tst r12, 0x100
++ addne r9, r9, #4
++
++ @ store saved r12 using str to have a register to hold the base for stm
++ str r8, [sp, #S_IP]
++ add r8, sp, #S_SP
++ @ store r13-r15, xPSR
++ stmia r8!, {r9-r12}
++ @ store r0 once more and EXC_RETURN
++ stmia r8, {r0, lr}
++ .endm
++
++ .macro v7m_exception_fast_exit
++ @ registers r0-r3 and r12 are automatically restored on exception
++ @ return. r4-r7 were not clobbered in v7m_exception_entry so for
++ @ correctness they don't need to be restored. So only r8-r11 must be
++ @ restored here. The easiest way to do so is to restore r0-r7, too.
++ ldmia sp!, {r0-r11}
++ add sp, #S_FRAME_SIZE-S_IP
++ cpsie i
++ bx lr
++ .endm
++
++ .macro v7m_exception_slow_exit ret_r0
++ cpsid i
++ ldr lr, [sp, #S_EXC_RET] @ read exception LR
++ tst lr, #0x8
++ bne 1f @ go to thread mode using exception return
++
++ /*
++ * return to kernel thread
++ * sp is already set up (and might be unset in pt_regs), so only
++ * restore r0-r12 and pc
++ */
++ ldmia sp, {r0-r12}
++ ldr lr, [sp, #S_PC]
++ add sp, sp, #S_FRAME_SIZE
++ cpsie i
++ bx lr
++
++1: /*
++ * return to userspace
++ */
++
++ @ read original r12, sp, lr, pc and xPSR
++ add r12, sp, #S_IP
++ ldmia r12, {r1-r5}
++
++ @ handle stack aligning
++ tst r5, #0x100
++ subne r2, r2, #4
++
++ @ skip over stack space for fp saving
++ tst lr, #0x10
++ subeq r2, r2, #576
++
++ @ write basic exception frame
++ stmdb r2!, {r1, r3-r5}
++ ldmia sp, {r1, r3-r5}
++ .if \ret_r0
++ stmdb r2!, {r0, r3-r5}
++ .else
++ stmdb r2!, {r1, r3-r5}
++ .endif
++
++ @ restore process sp
++ msr psp, r2
++
++ @ restore original r4-r11
++ ldmia sp!, {r0-r11}
++
++ @ restore main sp
++ add sp, sp, #S_FRAME_SIZE-S_IP
++
++ cpsie i
++ bx lr
++ .endm
++#endif /* CONFIG_CPU_V7M */
++
+ @
+ @ Store/load the USER SP and LR registers by switching to the SYS
+ @ mode. Useful in Thumb-2 mode where "stm/ldm rd, {sp, lr}^" is not
+@@ -131,6 +270,14 @@
+ rfeia sp!
+ .endm
+
++#ifdef CONFIG_CPU_V7M
++ .macro restore_user_regs, fast = 0, offset = 0
++ .if \offset
++ add sp, #\offset
++ .endif
++ v7m_exception_slow_exit ret_r0 = \fast
++ .endm
++#else /* !CONFIG_CPU_V7M */
+ .macro restore_user_regs, fast = 0, offset = 0
+ clrex @ clear the exclusive monitor
+ mov r2, sp
+@@ -147,6 +294,7 @@
+ add sp, sp, #S_FRAME_SIZE - S_SP
+ movs pc, lr @ return & move spsr_svc into cpsr
+ .endm
++#endif /* CONFIG_CPU_V7M */
+
+ .macro get_thread_info, rd
+ mov \rd, sp
+diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
+new file mode 100644
+index 0000000..a0991dc
+--- /dev/null
++++ b/arch/arm/kernel/entry-v7m.S
+@@ -0,0 +1,134 @@
++/*
++ * linux/arch/arm/kernel/entry-v7m.S
++ *
++ * Copyright (C) 2008 ARM Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * Low-level vector interface routines for the ARMv7-M architecture
++ */
++#include <asm/memory.h>
++#include <asm/glue.h>
++#include <asm/thread_notify.h>
++
++#include <mach/entry-macro.S>
++
++#include "entry-header.S"
++
++#ifdef CONFIG_PREEMPT
++#error "CONFIG_PREEMPT not supported on the current ARMv7M implementation"
++#endif
++#ifdef CONFIG_TRACE_IRQFLAGS
++#error "CONFIG_TRACE_IRQFLAGS not supported on the current ARMv7M implementation"
++#endif
++
++__invalid_entry:
++ v7m_exception_entry
++ adr r0, strerr
++ mrs r1, ipsr
++ mov r2, lr
++ bl printk
++ mov r0, sp
++ bl show_regs
++1: b 1b
++ENDPROC(__invalid_entry)
++
++strerr: .asciz "\nUnhandled exception: IPSR = %08lx LR = %08lx\n"
++
++ .align 2
++__irq_entry:
++ v7m_exception_entry
++
++ @
++ @ Invoke the IRQ handler
++ @
++ mrs r0, ipsr
++ and r0, #0xff
++ sub r0, #16 @ IRQ number
++ mov r1, sp
++ @ routine called with r0 = irq number, r1 = struct pt_regs *
++ bl asm_do_IRQ
++
++ @
++ @ Check for any pending work if returning to user
++ @
++ ldr lr, [sp, #S_EXC_RET]
++ tst lr, #0x8 @ check the return stack
++ beq 2f @ returning to handler mode
++ get_thread_info tsk
++ ldr r1, [tsk, #TI_FLAGS]
++ tst r1, #_TIF_WORK_MASK
++ beq 2f @ no work pending
++ ldr r1, =0xe000ed04 @ ICSR
++ mov r0, #1 << 28 @ ICSR.PENDSVSET
++ str r0, [r1] @ raise PendSV
++
++2:
++ v7m_exception_fast_exit
++ENDPROC(__irq_entry)
++
++__pendsv_entry:
++ v7m_exception_entry
++
++ ldr r1, =0xe000ed04 @ ICSR
++ mov r0, #1 << 27 @ ICSR.PENDSVCLR
++ str r0, [r1] @ clear PendSV
++
++ @ execute the pending work, including reschedule
++ get_thread_info tsk
++ mov why, #0
++ b ret_to_user
++ENDPROC(__pendsv_entry)
++
++/*
++ * Register switch for ARMv7-M processors.
++ * r0 = previous task_struct, r1 = previous thread_info, r2 = next thread_info
++ * previous and next are guaranteed not to be the same.
++ */
++ENTRY(__switch_to)
++ .fnstart
++ .cantunwind
++ add ip, r1, #TI_CPU_SAVE
++ stmia ip!, {r4 - r11} @ Store most regs on stack
++ str sp, [ip], #4
++ str lr, [ip], #4
++ mov r5, r0
++ add r4, r2, #TI_CPU_SAVE
++ ldr r0, =thread_notify_head
++ mov r1, #THREAD_NOTIFY_SWITCH
++ bl atomic_notifier_call_chain
++ mov ip, r4
++ mov r0, r5
++ ldmia ip!, {r4 - r11} @ Load all regs saved previously
++ ldr sp, [ip], #4
++ ldr pc, [ip]
++ .fnend
++ENDPROC(__switch_to)
++
++ .data
++ .align 8
++/*
++ * Vector table (64 words => 256 bytes natural alignment)
++ */
++ENTRY(vector_table)
++ .long 0 @ 0 - Reset stack pointer
++ .long __invalid_entry @ 1 - Reset
++ .long __invalid_entry @ 2 - NMI
++ .long __invalid_entry @ 3 - HardFault
++ .long __invalid_entry @ 4 - MemManage
++ .long __invalid_entry @ 5 - BusFault
++ .long __invalid_entry @ 6 - UsageFault
++ .long __invalid_entry @ 7 - Reserved
++ .long __invalid_entry @ 8 - Reserved
++ .long __invalid_entry @ 9 - Reserved
++ .long __invalid_entry @ 10 - Reserved
++ .long vector_swi @ 11 - SVCall
++ .long __invalid_entry @ 12 - Debug Monitor
++ .long __invalid_entry @ 13 - Reserved
++ .long __pendsv_entry @ 14 - PendSV
++ .long __invalid_entry @ 15 - SysTick
++ .rept 64 - 16
++ .long __irq_entry @ 16..64 - External Interrupts
++ .endr
+diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
+index 693b744..c45099a 100644
+--- a/arch/arm/kernel/process.c
++++ b/arch/arm/kernel/process.c
+@@ -436,7 +436,11 @@ asm( ".pushsection .text\n"
+ #ifdef CONFIG_TRACE_IRQFLAGS
+ " bl trace_hardirqs_on\n"
+ #endif
++#ifdef CONFIG_CPU_V7M
++" msr primask, r7\n"
++#else
+ " msr cpsr_c, r7\n"
++#endif
+ " mov r0, r4\n"
+ " mov lr, r6\n"
+ " mov pc, r5\n"
+@@ -475,6 +479,10 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
+ regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
+ regs.ARM_pc = (unsigned long)kernel_thread_helper;
+ regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;
++#if defined CONFIG_CPU_V7M
++ /* Return to Handler mode */
++ regs.ARM_EXC_RET = 0xfffffff1L;
++#endif
+
+ return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
+ }
+diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
+index 3e0fc5f..43f7afe 100644
+--- a/arch/arm/kernel/ptrace.c
++++ b/arch/arm/kernel/ptrace.c
+@@ -84,6 +84,9 @@ static const struct pt_regs_offset regoffset_table[] = {
+ REG_OFFSET_NAME(pc),
+ REG_OFFSET_NAME(cpsr),
+ REG_OFFSET_NAME(ORIG_r0),
++#ifdef CONFIG_CPU_V7M
++ REG_OFFSET_NAME(EXC_RET),
++#endif
+ REG_OFFSET_END,
+ };
+
diff --git a/patches/linux-3.6/0006-Cortex-M3-Add-NVIC-support.patch b/patches/linux-3.6/0006-Cortex-M3-Add-NVIC-support.patch
new file mode 100644
index 0000000..d4f0912
--- /dev/null
+++ b/patches/linux-3.6/0006-Cortex-M3-Add-NVIC-support.patch
@@ -0,0 +1,192 @@
+From: Catalin Marinas <catalin.marinas@arm.com>
+Date: Fri, 21 May 2010 18:06:43 +0100
+Subject: [PATCH] Cortex-M3: Add NVIC support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch implements the NVIC (interrupt controller) support for
+Cortex-M3.
+
+[ukleinek: use a raw spinlock]
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ arch/arm/common/Kconfig | 3 ++
+ arch/arm/common/Makefile | 1 +
+ arch/arm/common/nvic.c | 98 ++++++++++++++++++++++++++++++++++
+ arch/arm/include/asm/hardware/nvic.h | 34 ++++++++++++
+ 4 files changed, 136 insertions(+)
+ create mode 100644 arch/arm/common/nvic.c
+ create mode 100644 arch/arm/include/asm/hardware/nvic.h
+
+diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig
+index 283fa1d..58a142f 100644
+--- a/arch/arm/common/Kconfig
++++ b/arch/arm/common/Kconfig
+@@ -21,6 +21,9 @@ config ARM_VIC_NR
+ The maximum number of VICs available in the system, for
+ power management.
+
++config ARM_NVIC
++ bool
++
+ config ICST
+ bool
+
+diff --git a/arch/arm/common/Makefile b/arch/arm/common/Makefile
+index e8a4e58..68031d0 100644
+--- a/arch/arm/common/Makefile
++++ b/arch/arm/common/Makefile
+@@ -4,6 +4,7 @@
+
+ obj-$(CONFIG_ARM_GIC) += gic.o
+ obj-$(CONFIG_ARM_VIC) += vic.o
++obj-$(CONFIG_ARM_NVIC) += nvic.o
+ obj-$(CONFIG_ICST) += icst.o
+ obj-$(CONFIG_SA1111) += sa1111.o
+ obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
+diff --git a/arch/arm/common/nvic.c b/arch/arm/common/nvic.c
+new file mode 100644
+index 0000000..a0d76f4
+--- /dev/null
++++ b/arch/arm/common/nvic.c
+@@ -0,0 +1,98 @@
++/*
++ * linux/arch/arm/common/nvic.c
++ *
++ * Copyright (C) 2008 ARM Limited, All Rights Reserved.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ * Support for the Nested Vectored Interrupt Controller found on the
++ * ARMv7-M CPUs (Cortex-M3)
++ */
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/smp.h>
++
++#include <asm/irq.h>
++#include <asm/io.h>
++#include <asm/mach/irq.h>
++#include <asm/hardware/nvic.h>
++
++static DEFINE_RAW_SPINLOCK(irq_controller_lock);
++
++/*
++ * Routines to acknowledge, disable and enable interrupts
++ *
++ * Linux assumes that when we're done with an interrupt we need to
++ * unmask it, in the same way we need to unmask an interrupt when
++ * we first enable it.
++ *
++ * The NVIC has a separate notion of "end of interrupt" to re-enable
++ * an interrupt after handling, in order to support hardware
++ * prioritisation.
++ *
++ * We can make the NVIC behave in the way that Linux expects by making
++ * our "acknowledge" routine disable the interrupt, then mark it as
++ * complete.
++ */
++static void nvic_ack_irq(struct irq_data *d)
++{
++ u32 mask = 1 << (d->irq % 32);
++
++ raw_spin_lock(&irq_controller_lock);
++ writel(mask, NVIC_CLEAR_ENABLE + d->irq / 32 * 4);
++ raw_spin_unlock(&irq_controller_lock);
++}
++
++static void nvic_mask_irq(struct irq_data *d)
++{
++ u32 mask = 1 << (d->irq % 32);
++
++ raw_spin_lock(&irq_controller_lock);
++ writel(mask, NVIC_CLEAR_ENABLE + d->irq / 32 * 4);
++ raw_spin_unlock(&irq_controller_lock);
++}
++
++static void nvic_unmask_irq(struct irq_data *d)
++{
++ u32 mask = 1 << (d->irq % 32);
++
++ raw_spin_lock(&irq_controller_lock);
++ writel(mask, NVIC_SET_ENABLE + d->irq / 32 * 4);
++ raw_spin_unlock(&irq_controller_lock);
++}
++
++static struct irq_chip nvic_chip = {
++ .name = "NVIC",
++ .irq_ack = nvic_ack_irq,
++ .irq_mask = nvic_mask_irq,
++ .irq_unmask = nvic_unmask_irq,
++};
++
++void __init nvic_init(void)
++{
++ unsigned int max_irq, i;
++
++ max_irq = ((readl(NVIC_INTR_CTRL) & 0x1f) + 1) * 32;
++
++ /*
++ * Disable all interrupts
++ */
++ for (i = 0; i < max_irq / 32; i++)
++ writel(~0, NVIC_CLEAR_ENABLE + i * 4);
++
++ /*
++ * Set priority on all interrupts.
++ */
++ for (i = 0; i < max_irq; i += 4)
++ writel(0, NVIC_PRIORITY + i);
++
++ /*
++ * Setup the Linux IRQ subsystem.
++ */
++ for (i = 0; i < NR_IRQS; i++) {
++ irq_set_chip_and_handler(i, &nvic_chip, handle_level_irq);
++ set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
++ }
++}
+diff --git a/arch/arm/include/asm/hardware/nvic.h b/arch/arm/include/asm/hardware/nvic.h
+new file mode 100644
+index 0000000..b7f8026
+--- /dev/null
++++ b/arch/arm/include/asm/hardware/nvic.h
+@@ -0,0 +1,34 @@
++/*
++ * linux/include/asm-arm/hardware/nvic.h
++ *
++ * Copyright (C) 2008 ARM Limited, All Rights Reserved.
++ *
++ * This program is free software; you can 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_ARM_HARDWARE_NVIC_H
++#define __ASM_ARM_HARDWARE_NVIC_H
++
++#include <linux/compiler.h>
++
++#define V7M_SCS 0xe000e000
++#define NVIC_INTR_CTRL (V7M_SCS + 0x004)
++#define NVIC_SYSTICK_CTRL (V7M_SCS + 0x010)
++#define NVIC_SYSTICK_RELOAD (V7M_SCS + 0x014)
++#define NVIC_SYSTICK_CURRENT (V7M_SCS + 0x018)
++#define NVIC_SYSTICK_CALIBRATION (V7M_SCS + 0x01c)
++#define NVIC_SET_ENABLE (V7M_SCS + 0x100)
++#define NVIC_CLEAR_ENABLE (V7M_SCS + 0x180)
++#define NVIC_SET_PENDING (V7M_SCS + 0x200)
++#define NVIC_CLEAR_PENDING (V7M_SCS + 0x280)
++#define NVIC_ACTIVE_BIT (V7M_SCS + 0x300)
++#define NVIC_PRIORITY (V7M_SCS + 0x400)
++#define NVIC_INTR_CTRL_STATE (V7M_SCS + 0xd04)
++#define NVIC_SOFTWARE_INTR (V7M_SCS + 0xf00)
++
++#ifndef __ASSEMBLY__
++void nvic_init(void);
++#endif
++
++#endif
diff --git a/patches/linux-3.6/0007-Cortex-M3-Allow-the-building-of-Cortex-M3-kernel-por.patch b/patches/linux-3.6/0007-Cortex-M3-Allow-the-building-of-Cortex-M3-kernel-por.patch
new file mode 100644
index 0000000..c5aadf4
--- /dev/null
+++ b/patches/linux-3.6/0007-Cortex-M3-Allow-the-building-of-Cortex-M3-kernel-por.patch
@@ -0,0 +1,151 @@
+From: Catalin Marinas <catalin.marinas@arm.com>
+Date: Fri, 21 May 2010 18:06:44 +0100
+Subject: [PATCH] Cortex-M3: Allow the building of Cortex-M3 kernel port
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch modifies the required Kconfig and Makefile files to allow the
+building of kernel for Cortex-M3.
+
+[ukleinek: don't make CPU_V7M user visible]
+
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ arch/arm/Kconfig | 2 +-
+ arch/arm/Kconfig-nommu | 2 +-
+ arch/arm/Makefile | 1 +
+ arch/arm/kernel/Makefile | 8 +++++++-
+ arch/arm/mm/Kconfig | 24 +++++++++++++++++++++++-
+ arch/arm/mm/Makefile | 1 +
+ 6 files changed, 34 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 2f88d8d..84a8e47 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1642,7 +1642,7 @@ config HZ
+
+ config THUMB2_KERNEL
+ bool "Compile the kernel in Thumb-2 mode (EXPERIMENTAL)"
+- depends on CPU_V7 && !CPU_V6 && !CPU_V6K && EXPERIMENTAL
++ depends on (CPU_V7 || CPU_V7M) && !CPU_V6 && !CPU_V6K && EXPERIMENTAL
+ select AEABI
+ select ARM_ASM_UNIFIED
+ select ARM_UNWIND
+diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu
+index 2cef8e1..c859495 100644
+--- a/arch/arm/Kconfig-nommu
++++ b/arch/arm/Kconfig-nommu
+@@ -28,7 +28,7 @@ config FLASH_SIZE
+ config PROCESSOR_ID
+ hex 'Hard wire the processor ID'
+ default 0x00007700
+- depends on !CPU_CP15
++ depends on !(CPU_CP15 || CPU_V7M)
+ help
+ If processor has no CP15 register, this processor ID is
+ used instead of the auto-probing which utilizes the register.
+diff --git a/arch/arm/Makefile b/arch/arm/Makefile
+index a051dfb..a86ca69 100644
+--- a/arch/arm/Makefile
++++ b/arch/arm/Makefile
+@@ -60,6 +60,7 @@ comma = ,
+ # Note that GCC does not numerically define an architecture version
+ # macro, but instead defines a whole series of macros which makes
+ # testing for a specific architecture or later rather impossible.
++arch-$(CONFIG_CPU_32v7M) :=-D__LINUX_ARM_ARCH__=7 -march=armv7-m -Wa,-march=armv7-m
+ arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
+ arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
+ # Only override the compiler option if ARMv6. The ARMv6K extensions are
+diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
+index 7ad2d5c..f9b7231 100644
+--- a/arch/arm/kernel/Makefile
++++ b/arch/arm/kernel/Makefile
+@@ -15,10 +15,16 @@ CFLAGS_REMOVE_return_address.o = -pg
+
+ # Object file lists.
+
+-obj-y := elf.o entry-armv.o entry-common.o irq.o opcodes.o \
++obj-y := elf.o entry-common.o irq.o opcodes.o \
+ process.o ptrace.o return_address.o sched_clock.o \
+ setup.o signal.o stacktrace.o sys_arm.o time.o traps.o
+
++ifeq ($(CONFIG_CPU_V7M),y)
++obj-y += entry-v7m.o
++else
++obj-y += entry-armv.o
++endif
++
+ obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o
+
+ obj-$(CONFIG_LEDS) += leds.o
+diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
+index 101b968..66e76fb 100644
+--- a/arch/arm/mm/Kconfig
++++ b/arch/arm/mm/Kconfig
+@@ -393,6 +393,18 @@ config CPU_V7
+ select CPU_COPY_V6 if MMU
+ select CPU_TLB_V7 if MMU
+
++# ARMv7
++config CPU_V7M
++ bool
++ select THUMB2_KERNEL
++ select ARM_THUMB
++ select CPU_32v7M
++ select CPU_32v6K
++ select CPU_ABRT_NOMMU
++ select CPU_PABRT_LEGACY
++ select CPU_CACHE_V7M
++ select CPU_CACHE_VIPT
++
+ # Figure out what processor architecture version we should be using.
+ # This defines the compiler instruction set which depends on the machine type.
+ config CPU_32v3
+@@ -430,6 +442,9 @@ config CPU_32v6K
+ config CPU_32v7
+ bool
+
++config CPU_32v7M
++ bool
++
+ # The abort model
+ config CPU_ABRT_NOMMU
+ bool
+@@ -483,6 +498,9 @@ config CPU_CACHE_V6
+ config CPU_CACHE_V7
+ bool
+
++config CPU_CACHE_V7M
++ bool
++
+ config CPU_CACHE_VIVT
+ bool
+
+@@ -605,7 +623,11 @@ config ARCH_DMA_ADDR_T_64BIT
+
+ config ARM_THUMB
+ bool "Support Thumb user binaries"
+- depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || CPU_V7 || CPU_FEROCEON
++ depends on CPU_ARM720T || CPU_ARM740T || CPU_ARM920T || CPU_ARM922T || \
++ CPU_ARM925T || CPU_ARM926T || CPU_ARM940T || CPU_ARM946E || \
++ CPU_ARM1020 || CPU_ARM1020E || CPU_ARM1022 || CPU_ARM1026 || \
++ CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_V6 || CPU_V6K || CPU_V7 || \
++ CPU_FEROCEON || CPU_V7M
+ default y
+ help
+ Say Y if you want to include kernel support for running user space
+diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
+index 8a9c4cb..02ac462 100644
+--- a/arch/arm/mm/Makefile
++++ b/arch/arm/mm/Makefile
+@@ -88,6 +88,7 @@ obj-$(CONFIG_CPU_FEROCEON) += proc-feroceon.o
+ obj-$(CONFIG_CPU_V6) += proc-v6.o
+ obj-$(CONFIG_CPU_V6K) += proc-v6.o
+ obj-$(CONFIG_CPU_V7) += proc-v7.o
++obj-$(CONFIG_CPU_V7M) += proc-v7m.o
+
+ AFLAGS_proc-v6.o :=-Wa,-march=armv6
+ AFLAGS_proc-v7.o :=-Wa,-march=armv7-a
diff --git a/patches/linux-3.6/0008-HACK-ARM-no-we-don-t-enter-in-ARM.patch b/patches/linux-3.6/0008-HACK-ARM-no-we-don-t-enter-in-ARM.patch
new file mode 100644
index 0000000..428dc04
--- /dev/null
+++ b/patches/linux-3.6/0008-HACK-ARM-no-we-don-t-enter-in-ARM.patch
@@ -0,0 +1,39 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Fri, 9 Dec 2011 20:52:10 +0100
+Subject: [PATCH] HACK! ARM: no, we don't enter in ARM
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+... as a Cortex-M3 can only do Thumb-2 ...
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+This probably needs a new Kconfig symbol as THUMB2_KERNEL doesn't have
+the right meaning. Something like "CPU_THUMB_ONLY"?
+---
+ arch/arm/kernel/head-nommu.S | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
+index c391c05..b27af61 100644
+--- a/arch/arm/kernel/head-nommu.S
++++ b/arch/arm/kernel/head-nommu.S
+@@ -32,13 +32,14 @@
+ * numbers for r1.
+ *
+ */
+- .arm
++
++ @.arm
+
+ __HEAD
+ ENTRY(stext)
+
+- THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM.
+- THUMB( bx r9 ) @ If this is a Thumb-2 kernel,
++ @THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM.
++ @THUMB( bx r9 ) @ If this is a Thumb-2 kernel,
+ THUMB( .thumb ) @ switch to Thumb now.
+ THUMB(1: )
+
diff --git a/patches/linux-3.6/0009-mtd-maps-uclinux-fix-sparse-warnings-and-codingstyle.patch b/patches/linux-3.6/0009-mtd-maps-uclinux-fix-sparse-warnings-and-codingstyle.patch
new file mode 100644
index 0000000..1728d74
--- /dev/null
+++ b/patches/linux-3.6/0009-mtd-maps-uclinux-fix-sparse-warnings-and-codingstyle.patch
@@ -0,0 +1,162 @@
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Mon, 7 Nov 2011 09:39:32 +0100
+Subject: [PATCH] mtd/maps: uclinux: fix sparse warnings and codingstyle
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ drivers/mtd/maps/uclinux.c | 73 ++++++++++++++++++--------------------------
+ 1 file changed, 29 insertions(+), 44 deletions(-)
+
+diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
+index c3bb304..3e39318 100644
+--- a/drivers/mtd/maps/uclinux.c
++++ b/drivers/mtd/maps/uclinux.c
+@@ -1,12 +1,15 @@
+-/****************************************************************************/
+-
+ /*
+- * uclinux.c -- generic memory mapped MTD driver for uclinux
++ * uclinux.c -- generic memory mapped MTD driver for uclinux
++ *
++ * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License version
++ * 2 as published by the Free Software Foundation.
+ *
+- * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
+ */
+
+-/****************************************************************************/
++#define pr_fmt(fmt) "uclinux[mtd]: " fmt
+
+ #include <linux/module.h>
+ #include <linux/types.h>
+@@ -18,69 +21,57 @@
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
+-#include <asm/io.h>
++#include <linux/io.h>
+ #include <asm/sections.h>
+
+-/****************************************************************************/
+-
+-struct map_info uclinux_ram_map = {
++static struct map_info uclinux_ram_map = {
+ .name = "RAM",
+- .phys = (unsigned long)__bss_stop,
+- .size = 0,
++ .phys = (resource_size_t)__bss_stop,
++ .bankwidth = 4,
+ };
+
+ static struct mtd_info *uclinux_ram_mtdinfo;
+
+-/****************************************************************************/
+-
+ static struct mtd_partition uclinux_romfs[] = {
+ { .name = "ROMfs" }
+ };
+
+-#define NUM_PARTITIONS ARRAY_SIZE(uclinux_romfs)
+-
+-/****************************************************************************/
+-
+ static int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len,
+- size_t *retlen, void **virt, resource_size_t *phys)
++ size_t *retlen, void **virt, resource_size_t *phys)
+ {
+ struct map_info *map = mtd->priv;
+- *virt = map->virt + from;
++ *virt = (__force void *)(map->virt + from);
+ if (phys)
+ *phys = map->phys + from;
+ *retlen = len;
+- return(0);
++ return 0;
+ }
+
+-/****************************************************************************/
+-
+ static int __init uclinux_mtd_init(void)
+ {
+ struct mtd_info *mtd;
+- struct map_info *mapp;
++ struct map_info *mapp = &uclinux_ram_map;
+
+- mapp = &uclinux_ram_map;
+ if (!mapp->size)
+- mapp->size = PAGE_ALIGN(ntohl(*((unsigned long *)(mapp->phys + 8))));
+- mapp->bankwidth = 4;
++ mapp->size =
++ PAGE_ALIGN(be32_to_cpup((__be32 *)(mapp->phys + 8)));
+
+- printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
+- (int) mapp->phys, (int) mapp->size);
++ pr_info("RAM probe address=0x%x size=0x%x\n",
++ (int) mapp->phys, (int) mapp->size);
+
+ mapp->virt = ioremap_nocache(mapp->phys, mapp->size);
+-
+- if (mapp->virt == 0) {
+- printk("uclinux[mtd]: ioremap_nocache() failed\n");
+- return(-EIO);
++ if (!mapp->virt) {
++ pr_err("ioremap_nocache() failed\n");
++ return -EIO;
+ }
+
+ simple_map_init(mapp);
+
+ mtd = do_map_probe("map_ram", mapp);
+ if (!mtd) {
+- printk("uclinux[mtd]: failed to find a mapping?\n");
++ pr_err("failed to find a mapping?\n");
+ iounmap(mapp->virt);
+- return(-ENXIO);
++ return -ENXIO;
+ }
+
+ mtd->owner = THIS_MODULE;
+@@ -88,13 +79,11 @@ static int __init uclinux_mtd_init(void)
+ mtd->priv = mapp;
+
+ uclinux_ram_mtdinfo = mtd;
+- mtd_device_register(mtd, uclinux_romfs, NUM_PARTITIONS);
++ mtd_device_register(mtd, uclinux_romfs, ARRAY_SIZE(uclinux_romfs));
+
+- return(0);
++ return 0;
+ }
+
+-/****************************************************************************/
+-
+ static void __exit uclinux_mtd_cleanup(void)
+ {
+ if (uclinux_ram_mtdinfo) {
+@@ -103,18 +92,14 @@ static void __exit uclinux_mtd_cleanup(void)
+ uclinux_ram_mtdinfo = NULL;
+ }
+ if (uclinux_ram_map.virt) {
+- iounmap((void *) uclinux_ram_map.virt);
+- uclinux_ram_map.virt = 0;
++ iounmap(uclinux_ram_map.virt);
++ uclinux_ram_map.virt = NULL;
+ }
+ }
+
+-/****************************************************************************/
+-
+ module_init(uclinux_mtd_init);
+ module_exit(uclinux_mtd_cleanup);
+
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
+ MODULE_DESCRIPTION("Generic RAM based MTD for uClinux");
+-
+-/****************************************************************************/
diff --git a/patches/linux-3.6/0010-mtd-maps-uclinux-add-support-for-romfs-in-RAM-or-ROM.patch b/patches/linux-3.6/0010-mtd-maps-uclinux-add-support-for-romfs-in-RAM-or-ROM.patch
new file mode 100644
index 0000000..b32ef23
--- /dev/null
+++ b/patches/linux-3.6/0010-mtd-maps-uclinux-add-support-for-romfs-in-RAM-or-ROM.patch
@@ -0,0 +1,175 @@
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+Date: Mon, 7 Nov 2011 11:01:32 +0100
+Subject: [PATCH] mtd/maps: uclinux: add support for romfs in RAM or ROM
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+based on patch from uClinux_on_stm32
+
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ drivers/mtd/maps/Kconfig | 33 ++++++++++++++++++++++++-
+ drivers/mtd/maps/uclinux.c | 58 +++++++++++++++++++++++++++++---------------
+ 2 files changed, 71 insertions(+), 20 deletions(-)
+
+diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
+index 5ba2458..27d22f5 100644
+--- a/drivers/mtd/maps/Kconfig
++++ b/drivers/mtd/maps/Kconfig
+@@ -443,10 +443,41 @@ config MTD_GPIO_ADDR
+
+ config MTD_UCLINUX
+ bool "Generic uClinux RAM/ROM filesystem support"
+- depends on MTD_RAM=y && !MMU
++ depends on (MTD_RAM=y || MTD_ROM=y) && !MMU
+ help
+ Map driver to support image based filesystems for uClinux.
+
++if MTD_UCLINUX
++
++config MTD_UCLINUX_EBSS
++ bool "uClinux RAM/ROM filesystem is located at ebss"
++ default y
++ help
++ The filesystem is located directly after the kernel in memory.
++
++config MTD_UCLINUX_ADDRESS
++ hex "uClinux RAM/ROM filesystem address"
++ default 0x1400000
++ depends on !MTD_UCLINUX_EBSS
++ help
++ The filesystem is located at the given address.
++
++choice
++ prompt "uClinux RAM/ROM is located in ROM/RAM"
++ depends on !MTD_UCLINUX_EBSS
++
++config MTD_UCLINUX_RAM
++ bool "RAM"
++ depends on MTD_RAM
++
++config MTD_UCLINUX_ROM
++ bool "ROM"
++ depends on MTD_ROM
++
++endchoice
++
++endif
++
+ config MTD_WRSBC8260
+ tristate "Map driver for WindRiver PowerQUICC II MPC82xx board"
+ depends on (SBC82xx || SBC8560)
+diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c
+index 3e39318..b287cfc 100644
+--- a/drivers/mtd/maps/uclinux.c
++++ b/drivers/mtd/maps/uclinux.c
+@@ -18,22 +18,36 @@
+ #include <linux/fs.h>
+ #include <linux/mm.h>
+ #include <linux/major.h>
++#include <linux/root_dev.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/mtd/map.h>
+ #include <linux/mtd/partitions.h>
+ #include <linux/io.h>
+ #include <asm/sections.h>
+
+-static struct map_info uclinux_ram_map = {
+- .name = "RAM",
+- .phys = (resource_size_t)__bss_stop,
++#ifdef CONFIG_MTD_UCLINUX_EBSS
++#define MAP_TYPE "map_ram"
++#define MAP_NAME "RAM"
++#define CONFIG_MTD_UCLINUX_ADDRESS __bss_stop
++#elif defined CONFIG_MTD_UCLINUX_RAM
++#define MAP_TYPE "map_ram"
++#define MAP_NAME "RAM"
++#elif defined CONFIG_MTD_UCLINUX_ROM
++#define MAP_TYPE "map_rom"
++#define MAP_NAME "ROM"
++#else
++#error "Unknown uClinux map type"
++#endif
++
++static struct map_info uclinux_map = {
++ .name = MAP_NAME,
+ .bankwidth = 4,
+ };
+
+-static struct mtd_info *uclinux_ram_mtdinfo;
++static struct mtd_info *uclinux_mtdinfo;
+
+-static struct mtd_partition uclinux_romfs[] = {
+- { .name = "ROMfs" }
++static struct mtd_partition uclinux_fs[] = {
++ { .name = MAP_NAME }
+ };
+
+ static int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len,
+@@ -50,14 +64,16 @@ static int uclinux_point(struct mtd_info *mtd, loff_t from, size_t len,
+ static int __init uclinux_mtd_init(void)
+ {
+ struct mtd_info *mtd;
+- struct map_info *mapp = &uclinux_ram_map;
++ struct map_info *mapp = &uclinux_map;
+
++ if (!mapp->phys)
++ mapp->phys = (resource_size_t)CONFIG_MTD_UCLINUX_ADDRESS;
+ if (!mapp->size)
+ mapp->size =
+ PAGE_ALIGN(be32_to_cpup((__be32 *)(mapp->phys + 8)));
+
+- pr_info("RAM probe address=0x%x size=0x%x\n",
+- (int) mapp->phys, (int) mapp->size);
++ pr_info("%s probe address=0x%x size=0x%x\n",
++ MAP_TYPE, (int)mapp->phys, (int)mapp->size);
+
+ mapp->virt = ioremap_nocache(mapp->phys, mapp->size);
+ if (!mapp->virt) {
+@@ -67,7 +83,7 @@ static int __init uclinux_mtd_init(void)
+
+ simple_map_init(mapp);
+
+- mtd = do_map_probe("map_ram", mapp);
++ mtd = do_map_probe(MAP_TYPE, mapp);
+ if (!mtd) {
+ pr_err("failed to find a mapping?\n");
+ iounmap(mapp->virt);
+@@ -78,22 +94,26 @@ static int __init uclinux_mtd_init(void)
+ mtd->_point = uclinux_point;
+ mtd->priv = mapp;
+
+- uclinux_ram_mtdinfo = mtd;
+- mtd_device_register(mtd, uclinux_romfs, ARRAY_SIZE(uclinux_romfs));
++ uclinux_mtdinfo = mtd;
++ mtd_device_register(mtd, uclinux_fs, ARRAY_SIZE(uclinux_fs));
++
++ pr_info("set %s to be root filesystem\n",
++ uclinux_fs[0].name);
++ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 0);
+
+ return 0;
+ }
+
+ static void __exit uclinux_mtd_cleanup(void)
+ {
+- if (uclinux_ram_mtdinfo) {
+- mtd_device_unregister(uclinux_ram_mtdinfo);
+- map_destroy(uclinux_ram_mtdinfo);
+- uclinux_ram_mtdinfo = NULL;
++ if (uclinux_mtdinfo) {
++ mtd_device_unregister(uclinux_mtdinfo);
++ map_destroy(uclinux_mtdinfo);
++ uclinux_mtdinfo = NULL;
+ }
+- if (uclinux_ram_map.virt) {
+- iounmap(uclinux_ram_map.virt);
+- uclinux_ram_map.virt = NULL;
++ if (uclinux_map.virt) {
++ iounmap(uclinux_map.virt);
++ uclinux_map.virt = NULL;
+ }
+ }
+
diff --git a/patches/linux-3.6/0011-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch b/patches/linux-3.6/0011-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch
new file mode 100644
index 0000000..4f1ad9f
--- /dev/null
+++ b/patches/linux-3.6/0011-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch
@@ -0,0 +1,616 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Thu, 17 Nov 2011 14:36:23 +0100
+Subject: [PATCH] ARM: new platform for Energy Micro's EFM32 Cortex-M3 SoCs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+changes since
+id:1324480428-13344-1-git-send-email-u.kleine-koenig@pengutronix.de:
+
+ - select NO_IOPORT + don't provide __io()
+ - fix debug-macro stuff to do proper fifo handling, fix register
+ names and enable TX as the driver disables it occasionally
+ - add DEBUG_EFM32_UART1
+ - $SUBJECT ~= s/architecture/platform/
+ - a timekeeping fix
+ - #include "common.h" instead of <common.h> in time.c
+---
+ arch/arm/Kconfig | 13 +-
+ arch/arm/Kconfig.debug | 16 +++
+ arch/arm/Makefile | 1 +
+ arch/arm/boot/dts/efm32gg-dk3750.dts | 41 ++++++
+ arch/arm/mach-efm32/Makefile | 3 +
+ arch/arm/mach-efm32/Makefile.boot | 1 +
+ arch/arm/mach-efm32/clk.c | 38 ++++++
+ arch/arm/mach-efm32/cmu.h | 11 ++
+ arch/arm/mach-efm32/common.h | 1 +
+ arch/arm/mach-efm32/dtmachine.c | 47 +++++++
+ arch/arm/mach-efm32/include/mach/debug-macro.S | 48 +++++++
+ arch/arm/mach-efm32/include/mach/entry-macro.S | 12 ++
+ arch/arm/mach-efm32/include/mach/io.h | 6 +
+ arch/arm/mach-efm32/include/mach/irqs.h | 6 +
+ arch/arm/mach-efm32/include/mach/system.h | 18 +++
+ arch/arm/mach-efm32/include/mach/timex.h | 7 +
+ arch/arm/mach-efm32/time.c | 170 ++++++++++++++++++++++++
+ 17 files changed, 438 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/boot/dts/efm32gg-dk3750.dts
+ create mode 100644 arch/arm/mach-efm32/Makefile
+ create mode 100644 arch/arm/mach-efm32/Makefile.boot
+ create mode 100644 arch/arm/mach-efm32/clk.c
+ create mode 100644 arch/arm/mach-efm32/cmu.h
+ create mode 100644 arch/arm/mach-efm32/common.h
+ create mode 100644 arch/arm/mach-efm32/dtmachine.c
+ create mode 100644 arch/arm/mach-efm32/include/mach/debug-macro.S
+ create mode 100644 arch/arm/mach-efm32/include/mach/entry-macro.S
+ create mode 100644 arch/arm/mach-efm32/include/mach/io.h
+ create mode 100644 arch/arm/mach-efm32/include/mach/irqs.h
+ create mode 100644 arch/arm/mach-efm32/include/mach/system.h
+ create mode 100644 arch/arm/mach-efm32/include/mach/timex.h
+ create mode 100644 arch/arm/mach-efm32/time.c
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 84a8e47..4831437 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -437,6 +437,17 @@ config ARCH_EBSA110
+ Ethernet interface, two PCMCIA sockets, two serial ports and a
+ parallel port.
+
++config ARCH_EFM32
++ bool "EnergyMicro Cortex M3 Platform"
++ depends on !MMU
++ select ARM_NVIC
++ select CLKSRC_MMIO
++ select CPU_V7M
++ select GENERIC_CLOCKEVENTS
++ select HAVE_CLK
++ select NO_DMA
++ select NO_IOPORT
++
+ config ARCH_EP93XX
+ bool "EP93xx-based"
+ select CPU_ARM920T
+@@ -1768,7 +1779,7 @@ source "mm/Kconfig"
+ config FORCE_MAX_ZONEORDER
+ int "Maximum zone order" if ARCH_SHMOBILE
+ range 11 64 if ARCH_SHMOBILE
+- default "9" if SA1111
++ default "9" if SA1111 || ARCH_EFM32
+ default "11"
+ help
+ The kernel memory allocator divides physically contiguous memory
+diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
+index e968a52..93aaae2 100644
+--- a/arch/arm/Kconfig.debug
++++ b/arch/arm/Kconfig.debug
+@@ -139,6 +139,22 @@ choice
+ Say Y here if you want the debug print routines to direct
+ their output to the serial port in the DC21285 (Footbridge).
+
++ config DEBUG_EFM32_USART1
++ bool "Kernel low-level debugging messages via USART1"
++ depends on ARCH_EFM32
++ help
++ Say Y here if you want the debug print routines to direct
++ their output to the second USART port on efm32 based
++ machines.
++
++ config DEBUG_EFM32_UART1
++ bool "Kernel low-level debugging messages via UART1"
++ depends on ARCH_EFM32
++ help
++ Say Y here if you want the debug print routines to direct
++ their output to the second UART port on efm32 based
++ machines.
++
+ config DEBUG_FOOTBRIDGE_COM1
+ bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1"
+ depends on FOOTBRIDGE
+diff --git a/arch/arm/Makefile b/arch/arm/Makefile
+index a86ca69..f4e4d42 100644
+--- a/arch/arm/Makefile
++++ b/arch/arm/Makefile
+@@ -143,6 +143,7 @@ machine-$(CONFIG_ARCH_CNS3XXX) := cns3xxx
+ machine-$(CONFIG_ARCH_DAVINCI) := davinci
+ machine-$(CONFIG_ARCH_DOVE) := dove
+ machine-$(CONFIG_ARCH_EBSA110) := ebsa110
++machine-$(CONFIG_ARCH_EFM32) := efm32
+ machine-$(CONFIG_ARCH_EP93XX) := ep93xx
+ machine-$(CONFIG_ARCH_GEMINI) := gemini
+ machine-$(CONFIG_ARCH_H720X) := h720x
+diff --git a/arch/arm/boot/dts/efm32gg-dk3750.dts b/arch/arm/boot/dts/efm32gg-dk3750.dts
+new file mode 100644
+index 0000000..2a28b0f
+--- /dev/null
++++ b/arch/arm/boot/dts/efm32gg-dk3750.dts
+@@ -0,0 +1,41 @@
++/dts-v1/;
++/include/ "skeleton.dtsi"
++
++/ {
++ model = "Energy Micro Giant Gecko Development Kit";
++ compatible = "efm32,dk3750";
++
++ aliases {
++ serial1 = &uart1;
++ };
++
++ nvic: nv-interrupt-controller@0xe0000000 {
++ compatible = "arm,cortex-m3-nvic";
++ interrupt-controller;
++ #interrupt-cells = <1>;
++ reg = <0xe0000000 0x4000>;
++ };
++
++ chosen {
++ bootargs = "console=ttyefm1,115200 init=/linuxrc ignore_loglevel ihash_entries=64 dhash_entries=64";
++ };
++
++ memory {
++ reg = <0x80000000 0x100000>;
++ };
++
++ soc {
++ #address-cells = <1>;
++ #size-cells = <1>;
++ compatible = "simple-bus";
++ interrupt-parent = <&nvic>;
++ ranges;
++
++ uart1: uart@0x4000c400 { /* USART1 */
++ compatible = "efm32,uart";
++ reg = <0x4000c400 0x400>;
++ interrupts = <15>;
++ status = "ok";
++ };
++ };
++};
+diff --git a/arch/arm/mach-efm32/Makefile b/arch/arm/mach-efm32/Makefile
+new file mode 100644
+index 0000000..10a3426
+--- /dev/null
++++ b/arch/arm/mach-efm32/Makefile
+@@ -0,0 +1,3 @@
++obj-y += clk.o time.o
++
++obj-$(CONFIG_OF) += dtmachine.o
+diff --git a/arch/arm/mach-efm32/Makefile.boot b/arch/arm/mach-efm32/Makefile.boot
+new file mode 100644
+index 0000000..385e93a
+--- /dev/null
++++ b/arch/arm/mach-efm32/Makefile.boot
+@@ -0,0 +1 @@
++dtb-$(CONFIG_MACH_EFM32GG_DK3750) += efm32gg-dk3750.dtb
+diff --git a/arch/arm/mach-efm32/clk.c b/arch/arm/mach-efm32/clk.c
+new file mode 100644
+index 0000000..5b158ab
+--- /dev/null
++++ b/arch/arm/mach-efm32/clk.c
+@@ -0,0 +1,38 @@
++#include <linux/clk.h>
++#include <linux/export.h>
++#include <linux/io.h>
++
++#include "cmu.h"
++
++struct clk *clk_get(struct device *dev, const char *id)
++{
++ return NULL;
++}
++EXPORT_SYMBOL(clk_get);
++
++int clk_enable(struct clk *clk)
++{
++ return 0;
++}
++EXPORT_SYMBOL(clk_enable);
++
++void clk_disable(struct clk *clk)
++{
++}
++EXPORT_SYMBOL(clk_disable);
++
++unsigned long clk_get_rate(struct clk *clk)
++{
++ u32 cmu_status = __raw_readl(CMU_STATUS);
++
++ if (cmu_status & CMU_STATUS_HFRCOSEL)
++ return 14000000;
++ else
++ return 48000000;
++}
++EXPORT_SYMBOL(clk_get_rate);
++
++void clk_put(struct clk *clk)
++{
++}
++EXPORT_SYMBOL(clk_put);
+diff --git a/arch/arm/mach-efm32/cmu.h b/arch/arm/mach-efm32/cmu.h
+new file mode 100644
+index 0000000..05ef676
+--- /dev/null
++++ b/arch/arm/mach-efm32/cmu.h
+@@ -0,0 +1,11 @@
++#include "common.h"
++
++#define CMU_OSCENCMD IOMEM(0x400c8020)
++#define CMU_OSCENCMD_HFXOEN 0x00000004
++
++#define CMU_CMD IOMEM(0x400C8024)
++#define CMU_CMD_HFCLKSEL_HFXO 0x00000002
++
++#define CMU_STATUS IOMEM(0x400c802c)
++#define CMU_STATUS_HFRCOSEL 0x00000400
++#define CMU_STATUS_HFXOSEL 0x00000800
+diff --git a/arch/arm/mach-efm32/common.h b/arch/arm/mach-efm32/common.h
+new file mode 100644
+index 0000000..d2ff797
+--- /dev/null
++++ b/arch/arm/mach-efm32/common.h
+@@ -0,0 +1 @@
++extern struct sys_timer efm32_timer;
+diff --git a/arch/arm/mach-efm32/dtmachine.c b/arch/arm/mach-efm32/dtmachine.c
+new file mode 100644
+index 0000000..42d091c
+--- /dev/null
++++ b/arch/arm/mach-efm32/dtmachine.c
+@@ -0,0 +1,47 @@
++#include <linux/kernel.h>
++#include <linux/pinctrl/machine.h>
++#include <linux/irqdomain.h>
++#include <linux/of_platform.h>
++#include <linux/of_irq.h>
++
++#include <asm/hardware/nvic.h>
++#include <asm/mach/arch.h>
++#include <asm/mach/time.h>
++
++#include "common.h"
++
++static void __init efm32_nvic_add_irq_domain(struct device_node *np,
++ struct device_node *interrupt_parent)
++{
++ irq_domain_add_simple(np, 0);
++}
++
++static const struct of_device_id efm32_irq_match[] __initconst = {
++ {
++ .compatible = "arm,cortex-m3-nvic",
++ .data = efm32_nvic_add_irq_domain,
++ }, {
++ /* sentinel */
++ }
++};
++
++static void __init efm32_init(void)
++{
++ int ret;
++
++ of_irq_init(efm32_irq_match);
++
++ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
++}
++
++static const char *const efm32gg_compat[] __initconst = {
++ "efm32,dk3750",
++ NULL
++};
++
++DT_MACHINE_START(EFM32DT, "EFM32 (Device Tree Support)")
++ .init_irq = nvic_init,
++ .timer = &efm32_timer,
++ .init_machine = efm32_init,
++ .dt_compat = efm32gg_compat,
++MACHINE_END
+diff --git a/arch/arm/mach-efm32/include/mach/debug-macro.S b/arch/arm/mach-efm32/include/mach/debug-macro.S
+new file mode 100644
+index 0000000..268d648
+--- /dev/null
++++ b/arch/arm/mach-efm32/include/mach/debug-macro.S
+@@ -0,0 +1,48 @@
++/*
++ * This program is free software; you can 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 UARTn_CMD 0x000c
++#define UARTn_CMD_TXEN 0x0004
++
++#define UARTn_STATUS 0x0010
++#define UARTn_STATUS_TXC 0x0020
++#define UARTn_STATUS_TXBL 0x0040
++
++#define UARTn_TXDATA 0x0034
++
++ .macro addruart,rx,tmp
++#if defined(CONFIG_DEBUG_EFM32_USART1)
++ ldr \rx, =(0x4000c400) /* USART1 */
++#elif defined(CONFIG_DEBUG_EFM32_UART1)
++ ldr \rx, =(0x4000e400) /* UART1 */
++#else
++#error "No debug port configured"
++#endif
++ /*
++ * enable TX. The driver might disable that to save energy. We
++ * don't care about disabling at the end as during debug power consumption isn't
++ * that important.
++ */
++ ldr \tmp, =(UARTn_CMD_TXEN)
++ str \tmp, [\rx, #UARTn_CMD]
++ .endm
++
++
++ .macro senduart,rd,rx
++ strb \rd, [\rx, #UARTn_TXDATA]
++ .endm
++
++ .macro waituart,rd,rx
++1001: ldr \rd, [\rx, #UARTn_STATUS]
++ tst \rd, #UARTn_STATUS_TXBL
++ beq 1001b
++ .endm
++
++ .macro busyuart,rd,rx
++1001: ldr \rd, [\rx, UARTn_STATUS]
++ tst \rd, #UARTn_STATUS_TXC
++ bne 1001b
++ .endm
+diff --git a/arch/arm/mach-efm32/include/mach/entry-macro.S b/arch/arm/mach-efm32/include/mach/entry-macro.S
+new file mode 100644
+index 0000000..75b304a
+--- /dev/null
++++ b/arch/arm/mach-efm32/include/mach/entry-macro.S
+@@ -0,0 +1,12 @@
++/*
++ *
++ */
++#include <asm/hardware/gic.h>
++
++ .macro get_irqnr_preamble, base, tmp
++ ldr \base, =gic_cpu_base_addr
++ ldr \base, [\base]
++ .endm
++
++ .macro arch_ret_to_user, tmp1, tmp2
++ .endm
+diff --git a/arch/arm/mach-efm32/include/mach/io.h b/arch/arm/mach-efm32/include/mach/io.h
+new file mode 100644
+index 0000000..bc3519b
+--- /dev/null
++++ b/arch/arm/mach-efm32/include/mach/io.h
+@@ -0,0 +1,6 @@
++#ifndef __MACH_IO_H__
++#define __MACH_IO_H__
++
++#define __mem_pci(a) (a)
++
++#endif /* __MACH_IO_H__ */
+diff --git a/arch/arm/mach-efm32/include/mach/irqs.h b/arch/arm/mach-efm32/include/mach/irqs.h
+new file mode 100644
+index 0000000..5fa84db
+--- /dev/null
++++ b/arch/arm/mach-efm32/include/mach/irqs.h
+@@ -0,0 +1,6 @@
++#ifndef __MACH_IRQS_H__
++#define __MACH_IRQS_H__
++
++#define NR_IRQS 37
++
++#endif /* __MACH_IRQS_H__ */
+diff --git a/arch/arm/mach-efm32/include/mach/system.h b/arch/arm/mach-efm32/include/mach/system.h
+new file mode 100644
+index 0000000..619222c
+--- /dev/null
++++ b/arch/arm/mach-efm32/include/mach/system.h
+@@ -0,0 +1,18 @@
++#ifndef __MACH_SYSTEM_H__
++#define __MACH_SYSTEM_H__
++
++#include <asm/io.h>
++
++static inline void arch_idle(void)
++{
++ cpu_do_idle();
++}
++
++static inline void arch_reset(char mode, const char *cmd)
++{
++ /* XXX: move this to (say) cpuv7m_reset */
++ dsb();
++ __raw_writel(0x05fa0004, (void __iomem *)0xe000ed0c);
++ dsb();
++}
++#endif /* __MACH_SYSTEM_H__ */
+diff --git a/arch/arm/mach-efm32/include/mach/timex.h b/arch/arm/mach-efm32/include/mach/timex.h
+new file mode 100644
+index 0000000..b408dce
+--- /dev/null
++++ b/arch/arm/mach-efm32/include/mach/timex.h
+@@ -0,0 +1,7 @@
++#ifndef __MACH_TIMEX_H__
++#define __MACH_TIMEX_H__
++
++/* just a bogus value */
++#define CLOCK_TICK_RATE 12345678
++
++#endif /* __MACH_TIMEX_H__ */
+diff --git a/arch/arm/mach-efm32/time.c b/arch/arm/mach-efm32/time.c
+new file mode 100644
+index 0000000..c8038b1
+--- /dev/null
++++ b/arch/arm/mach-efm32/time.c
+@@ -0,0 +1,170 @@
++#include <linux/kernel.h>
++#include <linux/clocksource.h>
++#include <linux/clockchips.h>
++#include <linux/irq.h>
++#include <linux/interrupt.h>
++#include <linux/stringify.h>
++
++#include <asm/mach/time.h>
++
++#include "common.h"
++
++#define BASEADDR_TIMER(n) IOMEM(0x40010000 + (n) * 0x400)
++
++#define TIMERn_CTRL 0x00
++#define TIMERn_CTRL_PRESC(val) (((val) & 0xf) << 24)
++#define TIMERn_CTRL_PRESC_1024 TIMERn_CTRL_PRESC(10)
++#define TIMERn_CTRL_CLKSEL(val) (((val) & 0x3) << 16)
++#define TIMERn_CTRL_CLKSEL_PRESCHFPERCLK TIMERn_CTRL_CLKSEL(0)
++#define TIMERn_CTRL_OSMEN 0x00000010
++#define TIMERn_CTRL_MODE(val) (((val) & 0x3) << 0)
++#define TIMERn_CTRL_MODE_UP TIMERn_CTRL_MODE(0)
++#define TIMERn_CTRL_MODE_DOWN TIMERn_CTRL_MODE(1)
++
++#define TIMERn_CMD 0x04
++#define TIMERn_CMD_START 0x1
++#define TIMERn_CMD_STOP 0x2
++
++#define TIMERn_IEN 0x0c
++#define TIMERn_IF 0x10
++#define TIMERn_IFS 0x14
++#define TIMERn_IFC 0x18
++#define TIMERn_IRQ_UF 0x2
++#define TIMERn_IRQ_OF 0x1
++
++#define TIMERn_TOP 0x1c
++#define TIMERn_CNT 0x24
++
++#define TIMER_CLOCKSOURCE 1
++#define TIMER_CLOCKEVENT 2
++#define IRQ_CLOCKEVENT 13
++
++static void efm32_timer_write(unsigned timerno, u32 val, unsigned offset)
++{
++ __raw_writel(val, BASEADDR_TIMER(timerno) + offset);
++}
++
++static void efm32_clock_event_set_mode(enum clock_event_mode mode,
++ struct clock_event_device *unused)
++{
++ switch (mode) {
++ case CLOCK_EVT_MODE_PERIODIC:
++ efm32_timer_write(TIMER_CLOCKEVENT,
++ TIMERn_CMD_STOP, TIMERn_CMD);
++ efm32_timer_write(TIMER_CLOCKEVENT, 137, TIMERn_TOP);
++ efm32_timer_write(TIMER_CLOCKEVENT,
++ TIMERn_CTRL_PRESC_1024 |
++ TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
++ TIMERn_CTRL_MODE_DOWN, TIMERn_CTRL);
++ efm32_timer_write(TIMER_CLOCKEVENT,
++ TIMERn_CMD_START, TIMERn_CMD);
++ break;
++
++ case CLOCK_EVT_MODE_ONESHOT:
++ efm32_timer_write(TIMER_CLOCKEVENT,
++ TIMERn_CMD_STOP, TIMERn_CMD);
++ efm32_timer_write(TIMER_CLOCKEVENT,
++ TIMERn_CTRL_PRESC_1024 |
++ TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
++ TIMERn_CTRL_OSMEN |
++ TIMERn_CTRL_MODE_DOWN, TIMERn_CTRL);
++ break;
++
++ case CLOCK_EVT_MODE_UNUSED:
++ case CLOCK_EVT_MODE_SHUTDOWN:
++ efm32_timer_write(TIMER_CLOCKEVENT, TIMERn_CMD_STOP,
++ TIMERn_CMD);
++ break;
++
++ case CLOCK_EVT_MODE_RESUME:
++ break;
++ }
++}
++
++static int efm32_clock_event_set_next_event(unsigned long evt,
++ struct clock_event_device *unused)
++{
++ efm32_timer_write(TIMER_CLOCKEVENT, TIMERn_CMD_STOP, TIMERn_CMD);
++ efm32_timer_write(TIMER_CLOCKEVENT, evt, TIMERn_CNT);
++ efm32_timer_write(TIMER_CLOCKEVENT, TIMERn_CMD_START, TIMERn_CMD);
++
++ return 0;
++}
++
++static struct clock_event_device efm32_clock_event_device = {
++ .name = "efm32 clockevent (" __stringify(TIMER_CLOCKEVENT) ")",
++ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_MODE_PERIODIC,
++ .set_mode = efm32_clock_event_set_mode,
++ .set_next_event = efm32_clock_event_set_next_event,
++ .rating = 200,
++};
++
++static irqreturn_t efm32_clock_event_handler(int irq, void *dev_id)
++{
++ struct clock_event_device *evt = &efm32_clock_event_device;
++
++ /* ack irq */
++ efm32_timer_write(TIMER_CLOCKEVENT, TIMERn_IRQ_UF, TIMERn_IFC);
++
++ evt->event_handler(evt);
++
++ return IRQ_HANDLED;
++}
++
++static struct irqaction efm32_clock_event_irq = {
++ .name = "efm32 clockevent",
++ .flags = IRQF_TIMER,
++ .handler = efm32_clock_event_handler,
++ .dev_id = &efm32_clock_event_device,
++};
++
++/*
++ * XXX: use clk_ API to get frequency and enabling of the clocks used.
++ * Here the reset defaults are used:
++ * - freq_{HFPERCLK} = freq_{HFCLK}
++ * (CMU_HFPERCLKDIV_HFPERCLKDIV = 0x0)
++ * - freq_{HFCLK} = freq_{HFRCO}
++ * (CMU_CTRL_HFCLKDIV = 0x0, CMU_STATUS_HFRCOSEL = 0x1)
++ * - freq_{HFRCO} = 14MHz
++ * (CMU_HFRCOCTRL_BAND = 0x3)
++ *
++ * So the HFPERCLK runs at 14MHz. The timer has an additional prescaler
++ * programmed to /1024. This make the timer run at
++ *
++ * 14 MHz / 1024 = 13671.875 Hz
++ *
++ * When HFXO is used HFPERCLK runs at 48 MHz, so the timer runs at
++ *
++ * 48 MHz / 1024 = 46875 Hz
++ *
++ */
++static void __init efm32_timer_init(void)
++{
++ /* enable CMU_HFPERCLKEN0_TIMERn for clocksource via bit-band */
++ __raw_writel(1, IOMEM(0x43900894 + 4 * TIMER_CLOCKSOURCE));
++
++ efm32_timer_write(TIMER_CLOCKSOURCE,
++ TIMERn_CTRL_PRESC_1024 |
++ TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
++ TIMERn_CTRL_MODE_UP, TIMERn_CTRL);
++ efm32_timer_write(TIMER_CLOCKSOURCE, TIMERn_CMD_START, TIMERn_CMD);
++
++ clocksource_mmio_init(BASEADDR_TIMER(TIMER_CLOCKSOURCE) + TIMERn_CNT,
++ "efm32 timer", 46875, 200, 16,
++ clocksource_mmio_readl_up);
++
++ /* enable CMU_HFPERCLKEN0_TIMERn for clockevent via bit-band */
++ __raw_writel(1, IOMEM(0x43900894 + 4 * TIMER_CLOCKEVENT));
++
++ efm32_timer_write(TIMER_CLOCKEVENT, TIMERn_IRQ_UF, TIMERn_IEN);
++
++ setup_irq(IRQ_CLOCKEVENT, &efm32_clock_event_irq);
++
++ /* XXX: tune min_delta */
++ clockevents_config_and_register(&efm32_clock_event_device,
++ 46875, 0xf, 0xffff);
++}
++
++struct sys_timer efm32_timer = {
++ .init = efm32_timer_init,
++};
diff --git a/patches/linux-3.6/0012-ARM-efm32-add-support-for-non-dt-builds-and-add-more.patch b/patches/linux-3.6/0012-ARM-efm32-add-support-for-non-dt-builds-and-add-more.patch
new file mode 100644
index 0000000..a496e26
--- /dev/null
+++ b/patches/linux-3.6/0012-ARM-efm32-add-support-for-non-dt-builds-and-add-more.patch
@@ -0,0 +1,845 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Thu, 17 Nov 2011 14:36:23 +0100
+Subject: [PATCH] ARM: efm32: add support for non-dt builds and add more
+ drivers
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+non-dt is more practical as it saves some precious RAM. For now it won't
+be mainlinable though. This needs to be resorted completely before being
+ready for mainline.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ arch/arm/Kconfig | 5 +
+ arch/arm/Kconfig-nommu | 6 +
+ arch/arm/mach-efm32/Kconfig | 5 +
+ arch/arm/mach-efm32/Makefile | 4 +-
+ arch/arm/mach-efm32/common.c | 207 +++++++++++++++++++++
+ arch/arm/mach-efm32/common.h | 7 +
+ arch/arm/mach-efm32/devices.h | 20 ++
+ arch/arm/mach-efm32/devices/Makefile | 3 +
+ arch/arm/mach-efm32/devices/pdev-efm32-adc.c | 18 ++
+ arch/arm/mach-efm32/devices/pdev-efm32-pinctrl.c | 24 +++
+ arch/arm/mach-efm32/devices/pdev-efm32-uart.c | 102 ++++++++++
+ arch/arm/mach-efm32/dtmachine.c | 18 ++
+ arch/arm/mach-efm32/include/mach/gpio.h | 1 +
+ arch/arm/mach-efm32/include/mach/irqs.h | 2 +-
+ arch/arm/mach-efm32/machines/Kconfig | 11 ++
+ arch/arm/mach-efm32/machines/Makefile | 1 +
+ arch/arm/mach-efm32/machines/efm32gg_dk3750.c | 216 ++++++++++++++++++++++
+ 17 files changed, 648 insertions(+), 2 deletions(-)
+ create mode 100644 arch/arm/mach-efm32/Kconfig
+ create mode 100644 arch/arm/mach-efm32/common.c
+ create mode 100644 arch/arm/mach-efm32/devices.h
+ create mode 100644 arch/arm/mach-efm32/devices/Makefile
+ create mode 100644 arch/arm/mach-efm32/devices/pdev-efm32-adc.c
+ create mode 100644 arch/arm/mach-efm32/devices/pdev-efm32-pinctrl.c
+ create mode 100644 arch/arm/mach-efm32/devices/pdev-efm32-uart.c
+ create mode 100644 arch/arm/mach-efm32/include/mach/gpio.h
+ create mode 100644 arch/arm/mach-efm32/machines/Kconfig
+ create mode 100644 arch/arm/mach-efm32/machines/Makefile
+ create mode 100644 arch/arm/mach-efm32/machines/efm32gg_dk3750.c
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 4831437..dffb4d9 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -444,9 +444,12 @@ config ARCH_EFM32
+ select CLKSRC_MMIO
+ select CPU_V7M
+ select GENERIC_CLOCKEVENTS
++ select GENERIC_GPIO
++ select ARCH_REQUIRE_GPIOLIB
+ select HAVE_CLK
+ select NO_DMA
+ select NO_IOPORT
++ select PINCTRL
+
+ config ARCH_EP93XX
+ bool "EP93xx-based"
+@@ -1052,6 +1055,8 @@ source "arch/arm/mach-davinci/Kconfig"
+
+ source "arch/arm/mach-dove/Kconfig"
+
++source "arch/arm/mach-efm32/Kconfig"
++
+ source "arch/arm/mach-ep93xx/Kconfig"
+
+ source "arch/arm/mach-footbridge/Kconfig"
+diff --git a/arch/arm/Kconfig-nommu b/arch/arm/Kconfig-nommu
+index c859495..4340f4f 100644
+--- a/arch/arm/Kconfig-nommu
++++ b/arch/arm/Kconfig-nommu
+@@ -11,18 +11,24 @@ config SET_MEM_PARAM
+
+ config DRAM_BASE
+ hex '(S)DRAM Base Address' if SET_MEM_PARAM
++ default 0x80000000 if EFM32GG_DK3750_FPGA
++ default 0x88000000 if MACH_EFM32GG_DK3750
+ default 0x00800000
+
+ config DRAM_SIZE
+ hex '(S)DRAM SIZE' if SET_MEM_PARAM
++ default 0x00100000 if EFM32GG_DK3750_FPGA
++ default 0x00400000 if MACH_EFM32GG_DK3750
+ default 0x00800000
+
+ config FLASH_MEM_BASE
+ hex 'FLASH Base Address' if SET_MEM_PARAM
++ default 0x00000000 if MACH_EFM32GG_DK3750
+ default 0x00400000
+
+ config FLASH_SIZE
+ hex 'FLASH Size' if SET_MEM_PARAM
++ default 0x00100000 if MACH_EFM32GG_DK3750
+ default 0x00400000
+
+ config PROCESSOR_ID
+diff --git a/arch/arm/mach-efm32/Kconfig b/arch/arm/mach-efm32/Kconfig
+new file mode 100644
+index 0000000..e82747f
+--- /dev/null
++++ b/arch/arm/mach-efm32/Kconfig
+@@ -0,0 +1,5 @@
++if ARCH_EFM32
++
++source "arch/arm/mach-efm32/machines/Kconfig"
++
++endif
+diff --git a/arch/arm/mach-efm32/Makefile b/arch/arm/mach-efm32/Makefile
+index 10a3426..f3a6932 100644
+--- a/arch/arm/mach-efm32/Makefile
++++ b/arch/arm/mach-efm32/Makefile
+@@ -1,3 +1,5 @@
+-obj-y += clk.o time.o
++obj-y += clk.o common.o time.o
+
+ obj-$(CONFIG_OF) += dtmachine.o
++
++obj-y += machines/ devices/
+diff --git a/arch/arm/mach-efm32/common.c b/arch/arm/mach-efm32/common.c
+new file mode 100644
+index 0000000..cb073ba
+--- /dev/null
++++ b/arch/arm/mach-efm32/common.c
+@@ -0,0 +1,207 @@
++/*
++ * Copyright (C) 2012 Uwe Kleine-Koenig for Pengutronix
++ *
++ * This program is free software; you can 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/bug.h>
++#include <linux/init.h>
++
++#include <asm/io.h>
++#include <asm/barrier.h>
++
++#include "common.h"
++
++/* move this somewhere else */
++void cm3_restart(char mode, const char *cmd)
++{
++ dsb();
++ __raw_writel(0x05fa0004, (void __iomem *)0xe000ed0c);
++ dsb();
++}
++
++#define MEM_INFO_FLASH (void __iomem *)0x0fe081f8
++#define MEM_INFO_RAM (void __iomem *)0x0fe081fa
++#define PART_NUMBER (void __iomem *)0x0fe081fc
++#define PART_FAMILY (void __iomem *)0x0fe081fe
++#define PROD_REV (void __iomem *)0x0fe081ff
++
++static const struct efm32_family_mapping {
++ u8 id;
++ const char *name;
++ const char *abbrev;
++} efm32_family_mapping[] __initconst = {
++ {
++ .id = 71,
++ .name = "Gecko",
++ .abbrev = "G",
++ }, {
++ .id = 72,
++ .name = "Giant Gecko",
++ .abbrev = "GG",
++ }, {
++ .id = 73,
++ .name = "Tiny Gecko",
++ .abbrev = "TG",
++ }, {
++ .id = 74,
++ .name = "Leopard Gecko",
++ .abbrev = "LG",
++ }, {
++ .id = 75,
++ .name = "Zero Gecko",
++ .abbrev = "ZG",
++ },
++};
++
++static const char *__init efm32_get_familyname(u8 id)
++{
++ size_t i;
++
++ for (i = 0; i < ARRAY_SIZE(efm32_family_mapping) &&
++ efm32_family_mapping[i].id <= id; ++i) {
++ if (efm32_family_mapping[i].id == id)
++ return efm32_family_mapping[i].name;
++ }
++
++ return "unknown";
++}
++
++static const char *__init efm32_get_familyabbrev(u8 id)
++{
++ size_t i;
++
++ for (i = 0; i < ARRAY_SIZE(efm32_family_mapping) &&
++ efm32_family_mapping[i].id <= id; ++i) {
++ if (efm32_family_mapping[i].id == id)
++ return efm32_family_mapping[i].abbrev;
++ }
++
++ return "unknown";
++}
++
++static char revbuf[4] __initdata = "";
++static volatile const u32 * const romtable = (void *)0xe00fffe0;
++
++static const char *__init efm32_get_rev(void)
++{
++ if (revbuf[0] == '\0') {
++ u32 major = romtable[0] & 0x3f;
++ u32 minor = (romtable[2] & 0xf0) | ((romtable[3] >> 4) & 0x0f);
++
++ if (minor < 25)
++ sprintf(revbuf, "%u%c", major, 'A' + minor);
++ else {
++ revbuf[0] = '?';
++ revbuf[1] = '\0';
++ }
++ }
++ return revbuf;
++}
++
++void __init efm32_print_cpuinfo(void)
++{
++ u16 partno = __raw_readw(PART_NUMBER);
++ u8 family = __raw_readb(PART_FAMILY);
++ u8 rev = __raw_readb(PROD_REV);
++ u16 flashsize = __raw_readw(MEM_INFO_FLASH);
++ u16 raminfo = __raw_readw(MEM_INFO_RAM);
++
++ pr_info("Energy Micro %s, EFM32%s%hdF%hd (rev %s, prodrev %hhd), %hd kB RAM\n",
++ efm32_get_familyname(family),
++ efm32_get_familyabbrev(family), partno,
++ flashsize, efm32_get_rev(), rev, raminfo);
++}
++
++static const struct {
++ u32 value;
++ u32 mask;
++ const char *cause;
++} efm32_reset_causes[] = {
++ {
++ .value = 0x0001,
++ .mask = 0x0001,
++ .cause = "A Power-on Reset has been performed",
++ }, {
++ .value = 0x0002,
++ .mask = 0x0083,
++ .cause = "A Brown-out has been detected on the unregulated power",
++ }, {
++ .value = 0x0004,
++ .mask = 0x001f,
++ .cause = "A Brown-out has been detected on the regulated power",
++ }, {
++ .value = 0x0008,
++ .mask = 0x000b,
++ .cause = "An external reset has been applied",
++ }, {
++ .value = 0x0010,
++ .mask = 0x0013,
++ .cause = "A watchdog reset has occurred",
++ }, {
++ .value = 0x0020,
++ .mask = 0x07ff,
++ .cause = "A lockup reset has occurred",
++ }, {
++ .value = 0x0080,
++ .mask = 0x07df,
++ .cause = "A system request reset has occurred",
++ }, {
++ .value = 0x0080,
++ .mask = 0x0799,
++ .cause = "The system as woken up from EM4",
++ }, {
++ .value = 0x0180,
++ .mask = 0x799,
++ .cause = "The system as woken up from EM4 on an EM4 wakeup reset request from pin",
++ }, {
++ .value = 0x0200,
++ .mask = 0x079f,
++ .cause = "A Brown-out has been detected on Analog Power Domain 0 (AVDD0)",
++ }, {
++ .value = 0x0400,
++ .mask = 0x079f,
++ .cause = "A Brown-out has been detected on Analog Power Domain 1 (AVDD1)",
++ }, {
++ .value = 0x0800,
++ .mask = 0x0800,
++ .cause = "A Brown-out has been detected by the Backup BOD on VDD_DREG",
++ }, {
++ .value = 0x1000,
++ .mask = 0x1000,
++ .cause = "A Brown-out has been detected by the Backup BOD on BU_VIN",
++ }, {
++ .value = 0x2000,
++ .mask = 0x2000,
++ .cause = "A Brown-out has been detected by the Backup BOD on unregulated power",
++ }, {
++ .value= 0x4000,
++ .mask = 0x4000,
++ .cause = "A Brown-out has been detected by the Backup BOD on regulated power",
++ }, {
++ .value = 0x8000,
++ .mask = 0x8000,
++ .cause = "The system has been in Backup mode",
++ },
++};
++
++void __init efm32_print_reset_cause(void)
++{
++ u32 rmu_rstcause = __raw_readl((void __iomem *)0x400ca004);
++ int i;
++
++ pr_info("Reset Cause: 0x%08x\n", rmu_rstcause);
++
++ for (i = 0; i < ARRAY_SIZE(efm32_reset_causes); ++i) {
++ if ((rmu_rstcause & efm32_reset_causes[i].mask) ==
++ efm32_reset_causes[i].value)
++ pr_info(" `-> %s.\n", efm32_reset_causes[i].cause);
++ }
++
++ /* clear RMU_RSTCAUSE */
++ __raw_writel(1, (void __iomem *)0x400ca008);
++ __raw_writel(1, (void __iomem *)0x400c6024);
++ __raw_writel(0, (void __iomem *)0x400c6024);
++}
+diff --git a/arch/arm/mach-efm32/common.h b/arch/arm/mach-efm32/common.h
+index d2ff797..237b412 100644
+--- a/arch/arm/mach-efm32/common.h
++++ b/arch/arm/mach-efm32/common.h
+@@ -1 +1,8 @@
+ extern struct sys_timer efm32_timer;
++
++/* XXX: find a better place for that */
++void cm3_restart(char mode, const char *cmd);
++
++void efm32_print_cpuinfo(void);
++
++void efm32_print_reset_cause(void);
+diff --git a/arch/arm/mach-efm32/devices.h b/arch/arm/mach-efm32/devices.h
+new file mode 100644
+index 0000000..6459921
+--- /dev/null
++++ b/arch/arm/mach-efm32/devices.h
+@@ -0,0 +1,20 @@
++#include <linux/platform_device.h>
++
++extern const struct platform_device_info efm32_adc_devinfo[];
++#define efm32_add_efm32_adc() \
++ platform_device_register_full(&efm32_adc_devinfo[0])
++
++#include <linux/platform_data/efm32-pinctrl.h>
++void efm32_add_efm32_pinctrl(const struct efm32_pinctrl_pdata *);
++
++extern const struct platform_device_info efm32_spi_devinfo[];
++#define efm32_add_efm32_spi(id) \
++ platform_device_register_full(&efm32_spi_devinfo[id])
++
++extern const struct platform_device_info efm32_uart_devinfo[];
++struct platform_device *_efm32gg_add_efm32_uart(
++ const struct platform_device_info *, u8 location);
++#define efm32gg_add_efm32_usart(id, loc) \
++ _efm32gg_add_efm32_uart(&efm32_uart_devinfo[id], loc)
++#define efm32gg_add_efm32_uart(id, loc) \
++ _efm32gg_add_efm32_uart(&efm32_uart_devinfo[id + 3], loc)
+diff --git a/arch/arm/mach-efm32/devices/Makefile b/arch/arm/mach-efm32/devices/Makefile
+new file mode 100644
+index 0000000..1492b3f
+--- /dev/null
++++ b/arch/arm/mach-efm32/devices/Makefile
+@@ -0,0 +1,3 @@
++obj-y += pdev-efm32-adc.o
++obj-y += pdev-efm32-pinctrl.o
++obj-y += pdev-efm32-uart.o
+diff --git a/arch/arm/mach-efm32/devices/pdev-efm32-adc.c b/arch/arm/mach-efm32/devices/pdev-efm32-adc.c
+new file mode 100644
+index 0000000..be8154b
+--- /dev/null
++++ b/arch/arm/mach-efm32/devices/pdev-efm32-adc.c
+@@ -0,0 +1,18 @@
++#include <linux/ioport.h>
++#include <linux/platform_device.h>
++
++#include "../devices.h"
++
++static const struct resource efm32_adc0_resources[] __initconst = {
++ DEFINE_RES_MEM(0x40002000, 0x400),
++ DEFINE_RES_IRQ(7),
++};
++
++const struct platform_device_info efm32_adc_devinfo[] __initconst = {
++ [0] = {
++ .name = "efm32-adc",
++ .id = 0,
++ .res = efm32_adc0_resources,
++ .num_res = ARRAY_SIZE(efm32_adc0_resources),
++ },
++};
+diff --git a/arch/arm/mach-efm32/devices/pdev-efm32-pinctrl.c b/arch/arm/mach-efm32/devices/pdev-efm32-pinctrl.c
+new file mode 100644
+index 0000000..4a878f1
+--- /dev/null
++++ b/arch/arm/mach-efm32/devices/pdev-efm32-pinctrl.c
+@@ -0,0 +1,24 @@
++#include <linux/ioport.h>
++#include <linux/platform_device.h>
++#include <linux/platform_data/efm32-pinctrl.h>
++#include <linux/pinctrl/pinctrl.h>
++
++#include "../devices.h"
++
++static const struct resource efm32_pinctrl_resources[] __initconst = {
++ DEFINE_RES_MEM(0x40006000, 0x1000),
++};
++
++static struct platform_device_info efm32_pinctrl_devinfo __initdata = {
++ .name = "efm32-pinctrl",
++ .id = -1,
++ .res = efm32_pinctrl_resources,
++ .num_res = ARRAY_SIZE(efm32_pinctrl_resources),
++ .size_data = sizeof(struct efm32_pinctrl_pdata),
++};
++
++void __init efm32_add_efm32_pinctrl(const struct efm32_pinctrl_pdata *pdata)
++{
++ efm32_pinctrl_devinfo.data = pdata;
++ platform_device_register_full(&efm32_pinctrl_devinfo);
++}
+diff --git a/arch/arm/mach-efm32/devices/pdev-efm32-uart.c b/arch/arm/mach-efm32/devices/pdev-efm32-uart.c
+new file mode 100644
+index 0000000..1a96772
+--- /dev/null
++++ b/arch/arm/mach-efm32/devices/pdev-efm32-uart.c
+@@ -0,0 +1,102 @@
++#include <linux/ioport.h>
++#include <linux/platform_device.h>
++
++#include <linux/platform_data/efm32-uart.h>
++
++#include "../devices.h"
++
++static const struct resource efm32_usart0_resources[] __initconst = {
++ DEFINE_RES_MEM(0x4000c000, 0x400),
++ DEFINE_RES_IRQ(3),
++};
++
++static const struct resource efm32_usart1_resources[] __initconst = {
++ DEFINE_RES_MEM(0x4000c400, 0x400),
++ DEFINE_RES_IRQ(15),
++};
++
++static const struct resource efm32_usart2_resources[] __initconst = {
++ DEFINE_RES_MEM(0x4000c800, 0x400),
++ DEFINE_RES_IRQ(18),
++};
++
++static const struct resource efm32_uart0_resources[] __initconst = {
++ DEFINE_RES_MEM(0x4000e000, 0x400),
++ DEFINE_RES_IRQ(20),
++};
++
++static const struct resource efm32_uart1_resources[] __initconst = {
++ DEFINE_RES_MEM(0x4000e400, 0x400),
++ DEFINE_RES_IRQ(22),
++};
++
++const struct platform_device_info efm32_uart_devinfo[] __initconst = {
++ [0] = {
++ .name = "efm32-uart",
++ .id = 0,
++ .res = efm32_usart0_resources,
++ .num_res = ARRAY_SIZE(efm32_usart0_resources),
++ },
++ [1] = {
++ .name = "efm32-uart",
++ .id = 1,
++ .res = efm32_usart1_resources,
++ .num_res = ARRAY_SIZE(efm32_usart1_resources),
++ },
++ [2] = {
++ .name = "efm32-uart",
++ .id = 2,
++ .res = efm32_usart2_resources,
++ .num_res = ARRAY_SIZE(efm32_usart2_resources),
++ },
++ [3] = {
++ .name = "efm32-uart",
++ .id = 3,
++ .res = efm32_uart0_resources,
++ .num_res = ARRAY_SIZE(efm32_uart0_resources),
++ },
++ [4] = {
++ .name = "efm32-uart",
++ .id = 4,
++ .res = efm32_uart1_resources,
++ .num_res = ARRAY_SIZE(efm32_uart1_resources),
++ },
++};
++
++const struct platform_device_info efm32_spi_devinfo[] __initconst = {
++ [0] = {
++ .name = "efm32-spi",
++ .id = 0,
++ .res = efm32_usart0_resources,
++ .num_res = ARRAY_SIZE(efm32_usart0_resources),
++ },
++ [1] = {
++ .name = "efm32-spi",
++ .id = 1,
++ .res = efm32_usart1_resources,
++ .num_res = ARRAY_SIZE(efm32_usart1_resources),
++ },
++ [2] = {
++ .name = "efm32-spi",
++ .id = 2,
++ .res = efm32_usart2_resources,
++ .num_res = ARRAY_SIZE(efm32_usart2_resources),
++ },
++};
++
++struct platform_device * __init _efm32gg_add_efm32_uart(
++ const struct platform_device_info *devinfo, u8 location)
++{
++ struct efm32_uart_pdata pdata = {
++ .location = location,
++ };
++ struct platform_device_info _devinfo = *devinfo;
++
++ /* only use pdata if location != 0 which is the default */
++ if (location) {
++ _devinfo.data = &pdata;
++ _devinfo.size_data = sizeof(pdata);
++ }
++
++ return platform_device_register_full(&_devinfo);
++}
+diff --git a/arch/arm/mach-efm32/dtmachine.c b/arch/arm/mach-efm32/dtmachine.c
+index 42d091c..ca6585e 100644
+--- a/arch/arm/mach-efm32/dtmachine.c
++++ b/arch/arm/mach-efm32/dtmachine.c
+@@ -9,6 +9,17 @@
+ #include <asm/mach/time.h>
+
+ #include "common.h"
++#include "devices.h"
++
++static const struct pinmux_map efm32_pinmux[] = {
++ {
++ .name = "us1@0",
++ .ctrl_dev_name = "pinctrl.0",
++ .function = "us1",
++ .group = "us1_loc0",
++ .hog_on_boot = 1,
++ },
++};
+
+ static void __init efm32_nvic_add_irq_domain(struct device_node *np,
+ struct device_node *interrupt_parent)
+@@ -32,6 +43,13 @@ static void __init efm32_init(void)
+ of_irq_init(efm32_irq_match);
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
++
++ /*
++ * Pinmuxing isn't specified in the device tree. Probably it's too heavy
++ * considering that there is only 4 MiB of RAM
++ */
++ efm32gg990_add_efm32_pinctrl();
++ pinmux_register_mappings(efm32_pinmux, ARRAY_SIZE(efm32_pinmux));
+ }
+
+ static const char *const efm32gg_compat[] __initconst = {
+diff --git a/arch/arm/mach-efm32/include/mach/gpio.h b/arch/arm/mach-efm32/include/mach/gpio.h
+new file mode 100644
+index 0000000..40a8c17
+--- /dev/null
++++ b/arch/arm/mach-efm32/include/mach/gpio.h
+@@ -0,0 +1 @@
++/* empty */
+diff --git a/arch/arm/mach-efm32/include/mach/irqs.h b/arch/arm/mach-efm32/include/mach/irqs.h
+index 5fa84db..f4c4b57 100644
+--- a/arch/arm/mach-efm32/include/mach/irqs.h
++++ b/arch/arm/mach-efm32/include/mach/irqs.h
+@@ -1,6 +1,6 @@
+ #ifndef __MACH_IRQS_H__
+ #define __MACH_IRQS_H__
+
+-#define NR_IRQS 37
++#define NR_IRQS 66
+
+ #endif /* __MACH_IRQS_H__ */
+diff --git a/arch/arm/mach-efm32/machines/Kconfig b/arch/arm/mach-efm32/machines/Kconfig
+new file mode 100644
+index 0000000..f060c08
+--- /dev/null
++++ b/arch/arm/mach-efm32/machines/Kconfig
+@@ -0,0 +1,11 @@
++config MACH_EFM32GG_DK3750
++ bool "EFM32GG_DK3750"
++ default y
++
++config EFM32GG_DK3750_FPGA
++ bool "pre-silicon Gecko"
++ depends on MACH_EFM32GG_DK3750
++ help
++ This option enables handling for the FPGA version of the Giant Gecko.
++ Namely:
++ - only one MiB of external DRAM
+diff --git a/arch/arm/mach-efm32/machines/Makefile b/arch/arm/mach-efm32/machines/Makefile
+new file mode 100644
+index 0000000..d76f15d
+--- /dev/null
++++ b/arch/arm/mach-efm32/machines/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_MACH_EFM32GG_DK3750) += efm32gg_dk3750.o
+diff --git a/arch/arm/mach-efm32/machines/efm32gg_dk3750.c b/arch/arm/mach-efm32/machines/efm32gg_dk3750.c
+new file mode 100644
+index 0000000..cdc7506
+--- /dev/null
++++ b/arch/arm/mach-efm32/machines/efm32gg_dk3750.c
+@@ -0,0 +1,216 @@
++/*
++ * Copyright (C) 2012 Uwe Kleine-Koenig for Pengutronix
++ *
++ * This program is free software; you can redistribute it and/or modify it under
++ * the terms of the GNU General Public License version 2 as published by the
++ * Free Software Foundation.
++ */
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/pinctrl/machine.h>
++#include <linux/spi/spi.h>
++#include <linux/spi/spi_gpio.h>
++#include <linux/spi/mmc_spi.h>
++#include <linux/gpio.h>
++#include <linux/platform_data/efm32-pinctrl.h>
++
++#include <asm/hardware/nvic.h>
++#include <asm/mach/arch.h>
++#include <asm/mach-types.h>
++#include <asm/io.h>
++
++#include "../common.h"
++#include "../devices.h"
++
++static const struct spi_gpio_platform_data
++ efm32gg_dk3750_spi_gpio_us0_pdata __initconst = {
++ .sck = 69, /* PE5 */
++ .mosi = 71, /* PE7 */
++ .miso = 70, /* PE6 */
++ .num_chipselect = 1,
++};
++
++static const struct platform_device_info
++ efm32gg_dk3750_spi_gpio_us0_devinfo __initconst = {
++ .name = "spi_gpio",
++ .id = 0,
++
++ .data = &efm32gg_dk3750_spi_gpio_us0_pdata,
++ .size_data = sizeof(efm32gg_dk3750_spi_gpio_us0_pdata),
++};
++
++static struct mmc_spi_platform_data efm32gg_dk3750_mmc_spi_pdata = {
++};
++
++static const struct spi_board_info
++ efm32gg_dk3750_spi_us0_board_info[] __initconst = {
++ {
++ .modalias = "mmc_spi",
++ .bus_num = 0,
++ .chip_select = 0,
++ .platform_data = &efm32gg_dk3750_mmc_spi_pdata,
++ .controller_data = (void *)68, /* PE4 */
++ .mode = SPI_MODE_0,
++ },
++};
++
++static void __init efm32gg_dk3750_prepare_microsd(void)
++{
++ /* enable microSD mux, XXX: pretty please */
++ {
++ u16 perfControl = readw((void __iomem *)0x80000018);
++ perfControl |= 1; /* Micro-SD SPI enable */
++ writew(perfControl, (void __iomem *)0x80000018);
++ }
++
++ spi_register_board_info(efm32gg_dk3750_spi_us0_board_info,
++ ARRAY_SIZE(efm32gg_dk3750_spi_us0_board_info));
++ platform_device_register_full(&efm32gg_dk3750_spi_gpio_us0_devinfo);
++}
++
++static struct spi_board_info
++ efm32gg_dk3750_spi_us1_board_info[] __initdata = {
++ {
++ .modalias = "ks8851",
++ .bus_num = 1,
++ .chip_select = 0,
++ .controller_data = (void *)51, /* PD3 */
++ .max_speed_hz = 6000000,
++ .mode = SPI_MODE_0,
++ },
++};
++
++static void __init efm32gg_dk3750_prepare_ethernet(void)
++{
++ /* enable ethernet mux, XXX: pretty please */
++ {
++ u16 perfControl = readw((void __iomem *)0x80000018);
++
++ writew(1 /* BC_SPI_DEMUX_SLAVE_ETHERNET */, (void __iomem *)0x8000001a);
++ perfControl |= 3 << 8; /* I2S/ETH/TFT SPI enable + I2S/ETH mux select */
++ writew(perfControl, (void __iomem *)0x80000018);
++ }
++
++ gpio_request_one(7, GPIOF_DIR_IN, "eth-irq");
++ efm32gg_dk3750_spi_us1_board_info[0].irq = gpio_to_irq(7);
++
++ spi_register_board_info(efm32gg_dk3750_spi_us1_board_info,
++ ARRAY_SIZE(efm32gg_dk3750_spi_us1_board_info));
++ efm32_add_efm32_spi(1);
++}
++
++static irqreturn_t c9wakeup_handler(int irq, void *null)
++{
++ pr_info("tralala\n");
++ return IRQ_HANDLED;
++}
++
++static int __init efm32gg_dk3750_prepare_c9wakeup(void)
++{
++ int ret;
++ ret = gpio_request(41, "c9wakeup");
++ if (ret) {
++ pr_warn("failed to request gpio41 (%d)\n", ret);
++ goto err_gpio_request;
++ }
++
++ /* XXX: filter */
++ ret = gpio_direction_input(41);
++ if (ret) {
++ pr_warn("failed to set gpio41 to input\n");
++ goto err_direction_input;
++ }
++
++ ret = gpio_to_irq(41);
++ if (ret < 0) {
++ pr_warn("gpio41 doesn't map to an irq (%d)\n", ret);
++ goto err_to_irq;
++ }
++ pr_info("using irq %d\n", ret);
++
++ ret = request_irq(ret, c9wakeup_handler, IRQF_TRIGGER_FALLING, "c9wakup", NULL);
++ if (ret) {
++ pr_warn("failed to request irq for gpio41 (%d)", ret);
++err_gpio_request:
++err_direction_input:
++err_to_irq:
++ gpio_free(41);
++ }
++ return ret;
++}
++module_init(efm32gg_dk3750_prepare_c9wakeup);
++
++const static struct efm32_pinctrl_pdata efm32gg_dk3750_pinctrl_pdata __initconst = {
++ .pindef = {
++ [7] = { /* PA7, eth irq */
++ .flags = EFM32_PINCTRL_FLAG_GPIOIN,
++ .mode_gpio_in = EFM32_MODE_INPUT,
++ },
++ [14] = { /* GPIO for EM demo */
++ .flags = EFM32_PINCTRL_FLAG_GPIOOUT,
++ .mode_gpio_out = EFM32_MODE_PUSHPULL,
++ },
++ [41] = { /* PC9, wakeup */
++ .flags = EFM32_PINCTRL_FLAG_GPIOIN,
++ .mode_gpio_in = EFM32_MODE_INPUTPULLUPFILTER,
++ },
++ [48] = { /* PD0, ETH_MOSI */
++ .flags = EFM32_PINCTRL_FLAG_GPIOOUT,
++ .mode_gpio_out = EFM32_MODE_PUSHPULL,
++ },
++ [49] = { /* PD1, ETH_MISO */
++ .flags = EFM32_PINCTRL_FLAG_GPIOIN,
++ .mode_gpio_in = EFM32_MODE_INPUT,
++ },
++ [50] = { /* PD2, ETH_SCLK */
++ .flags = EFM32_PINCTRL_FLAG_GPIOOUT,
++ .mode_gpio_out = EFM32_MODE_PUSHPULL,
++ },
++ [51] = { /* PD3, ETH_#CS */
++ .flags = EFM32_PINCTRL_FLAG_GPIOOUT,
++ .mode_gpio_out = EFM32_MODE_PUSHPULL,
++ },
++ [68] = { /* PE4, spi cs */
++ .flags = EFM32_PINCTRL_FLAG_GPIOOUT,
++ .mode_gpio_out = EFM32_MODE_PUSHPULL,
++ },
++ [69] = { /* PE5, spi sck */
++ .flags = EFM32_PINCTRL_FLAG_GPIOOUT,
++ .mode_gpio_out = EFM32_MODE_PUSHPULL,
++ },
++ [70] = { /* PE6, spi miso */
++ .flags = EFM32_PINCTRL_FLAG_GPIOIN,
++ .mode_gpio_in = EFM32_MODE_INPUT,
++ },
++ [71] = { /* PE7, spi mosi */
++ .flags = EFM32_PINCTRL_FLAG_GPIOOUT,
++ .mode_gpio_out = EFM32_MODE_PUSHPULL,
++ }
++ },
++};
++
++static void __init efm32gg_dk3750_init(void)
++{
++ efm32_print_cpuinfo();
++ efm32_print_reset_cause();
++
++#ifdef CONFIG_EFM32GG_DK3750_FPGA
++ efm32gg_add_efm32_usart(1, 0);
++#else
++ efm32gg_add_efm32_uart(1, 2);
++#endif
++
++ efm32_add_efm32_pinctrl(&efm32gg_dk3750_pinctrl_pdata);
++
++ efm32gg_dk3750_prepare_microsd();
++ efm32gg_dk3750_prepare_ethernet();
++ efm32_add_efm32_adc();
++
++}
++
++MACHINE_START(EFM32GG_DK3750, "EFM32 Giant Gecko Development Kit")
++ .init_irq = nvic_init,
++ .timer = &efm32_timer,
++ .init_machine = efm32gg_dk3750_init,
++ .restart = cm3_restart,
++MACHINE_END
diff --git a/patches/linux-3.6/0013-pinctrl-add-a-driver-for-Energy-Micro-s-efm32-SoCs.patch b/patches/linux-3.6/0013-pinctrl-add-a-driver-for-Energy-Micro-s-efm32-SoCs.patch
new file mode 100644
index 0000000..b071525
--- /dev/null
+++ b/patches/linux-3.6/0013-pinctrl-add-a-driver-for-Energy-Micro-s-efm32-SoCs.patch
@@ -0,0 +1,516 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Thu, 8 Dec 2011 23:37:41 +0100
+Subject: [PATCH] pinctrl: add a driver for Energy Micro's efm32 SoCs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ drivers/pinctrl/Kconfig | 6 +
+ drivers/pinctrl/Makefile | 1 +
+ drivers/pinctrl/pinctrl-efm32.c | 411 +++++++++++++++++++++++++++
+ include/linux/platform_data/efm32-pinctrl.h | 47 +++
+ 4 files changed, 465 insertions(+)
+ create mode 100644 drivers/pinctrl/pinctrl-efm32.c
+ create mode 100644 include/linux/platform_data/efm32-pinctrl.h
+
+diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
+index 54e3588..12c0807 100644
+--- a/drivers/pinctrl/Kconfig
++++ b/drivers/pinctrl/Kconfig
+@@ -26,6 +26,12 @@ config DEBUG_PINCTRL
+ help
+ Say Y here to add some extra checks and diagnostics to PINCTRL calls.
+
++config PINCTRL_EFM32
++ bool "EFM32 pin controller driver"
++ depends on ARCH_EFM32
++ default y
++ select PINMUX
++
+ config PINCTRL_IMX
+ bool
+ select PINMUX
+diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
+index f40b1f8..a871d0f 100644
+--- a/drivers/pinctrl/Makefile
++++ b/drivers/pinctrl/Makefile
+@@ -9,6 +9,7 @@ ifeq ($(CONFIG_OF),y)
+ obj-$(CONFIG_PINCTRL) += devicetree.o
+ endif
+ obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o
++obj-$(CONFIG_PINCTRL_EFM32) += pinctrl-efm32.o
+ obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o
+ obj-$(CONFIG_PINCTRL_IMX51) += pinctrl-imx51.o
+ obj-$(CONFIG_PINCTRL_IMX53) += pinctrl-imx53.o
+diff --git a/drivers/pinctrl/pinctrl-efm32.c b/drivers/pinctrl/pinctrl-efm32.c
+new file mode 100644
+index 0000000..39d2fd3
+--- /dev/null
++++ b/drivers/pinctrl/pinctrl-efm32.c
+@@ -0,0 +1,411 @@
++#include <linux/module.h>
++#include <linux/gpio.h>
++#include <linux/slab.h>
++#include <linux/platform_device.h>
++#include <linux/irq.h>
++#include <asm/io.h>
++#include <asm/mach/irq.h>
++#include <linux/platform_data/efm32-pinctrl.h>
++
++#define DRIVER_NAME "efm32-pinctrl"
++
++#define EFM32_REG_Px_CTRL 0x000
++#define EFM32_REG_Px_MODEL 0x004
++#define EFM32_REG_Px_MODEH 0x008
++#define EFM32_REG_Px_DOUTSET 0x010
++#define EFM32_REG_Px_DOUTCLR 0x014
++#define EFM32_REG_Px_DIN 0x01c
++
++#define EFM32_REG_EXTIPSELL 0x100
++#define EFM32_REG_EXTIPSELH 0x104
++#define EFM32_REG_EXTIRISE 0x108
++#define EFM32_REG_EXTIFALL 0x10c
++#define EFM32_REG_IEN 0x110
++#define EFM32_REG_IF 0x114
++#define EFM32_REG_IFS 0x118
++#define EFM32_REG_IFC 0x11c
++
++struct efm32_pinctrl_ddata {
++ struct platform_device *pdev;
++ spinlock_t lock;
++ struct irq_chip ic;
++ struct gpio_chip gc;
++ void __iomem *base;
++
++ /* -1 = unused, 0 -> irq triggers on port A, ... */
++ s8 irqport[16];
++
++ /* shadow values */
++ u32 ien;
++ u32 extirise, extifall;
++
++ /* track level sensitivity which is emulated using edge triggering */
++ u32 extilow, extihigh;
++};
++
++#define from_gpio_chip(chip) container_of((chip), struct efm32_pinctrl_ddata, gc)
++
++static void __efm32_pinctrl_set_mode(struct efm32_pinctrl_ddata *ddata,
++ unsigned pin, unsigned mode, unsigned dout)
++{
++ unsigned bank = pin / 16;
++ unsigned bankpin = pin % 16;
++ unsigned bank_regoff = bank * 0x24;
++ unsigned mode_regoff = bankpin < 8 ? EFM32_REG_Px_MODEL : EFM32_REG_Px_MODEH;
++ unsigned dout_regoff = dout ? EFM32_REG_Px_DOUTSET : EFM32_REG_Px_DOUTCLR;
++ u32 regmode;
++
++ if (mode & 0xf)
++ writel(1 << bankpin, ddata->base + bank_regoff + dout_regoff);
++
++ regmode = readl(ddata->base + bank_regoff + mode_regoff);
++
++ regmode &= ~(0xf << (4 * (bankpin % 8)));
++ regmode |= (mode & 0xf) << (4 * (bankpin % 8));
++
++ writel(regmode, ddata->base + bank_regoff + mode_regoff);
++
++ if (!(mode & 0xf))
++ writel(1 << bankpin, ddata->base + bank_regoff + dout_regoff);
++
++}
++static void efm32_pinctrl_set_mode(struct efm32_pinctrl_ddata *ddata,
++ unsigned pin, unsigned mode, unsigned dout)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&ddata->lock, flags);
++ __efm32_pinctrl_set_mode(ddata, pin, mode, dout);
++ spin_unlock_irqrestore(&ddata->lock, flags);
++}
++
++static int efm32_pinctrl_gpio_direction_input(struct gpio_chip *chip,
++ unsigned offset)
++{
++ struct efm32_pinctrl_ddata *ddata = from_gpio_chip(chip);
++ struct efm32_pinctrl_pdata *pdata = dev_get_platdata(&ddata->pdev->dev);
++
++ dev_dbg(&ddata->pdev->dev, "%s(%u)\n", __func__, offset);
++
++ if (!pdata || !(pdata->pindef[offset].flags &
++ EFM32_PINCTRL_FLAG_GPIOIN)) {
++ dev_dbg(&ddata->pdev->dev, "%s(%u) -> EINVAL\n", __func__, offset);
++ return -EINVAL;
++ }
++
++ efm32_pinctrl_set_mode(ddata, offset,
++ pdata->pindef[offset].mode_gpio_in & 0xf,
++ pdata->pindef[offset].mode_gpio_in & 0x10);
++
++ return 0;
++}
++
++static int efm32_pinctrl_gpio_get(struct gpio_chip *chip, unsigned offset)
++{
++ struct efm32_pinctrl_ddata *ddata = from_gpio_chip(chip);
++ unsigned bank = offset / 16;
++ unsigned bankpin = offset % 16;
++ unsigned bank_regoff = bank * 0x24;
++ u32 regdin;
++
++ regdin = readl(ddata->base + bank_regoff + EFM32_REG_Px_DIN);
++ dev_dbg(&ddata->pdev->dev, "%s(%u) -> %x\n", __func__,
++ offset, regdin & (1 << bankpin));
++
++ return regdin & (1 << bankpin);
++}
++
++static int efm32_pinctrl_gpio_direction_output(struct gpio_chip *chip,
++ unsigned offset, int value)
++{
++ struct efm32_pinctrl_ddata *ddata = from_gpio_chip(chip);
++ struct efm32_pinctrl_pdata *pdata = dev_get_platdata(&ddata->pdev->dev);
++
++ dev_dbg(&ddata->pdev->dev, "%s(%u, %d)\n", __func__, offset, value);
++
++ if (!pdata || !(pdata->pindef[offset].flags &
++ EFM32_PINCTRL_FLAG_GPIOOUT)) {
++ dev_dbg(&ddata->pdev->dev, "%s(%u) -> EINVAL\n", __func__, offset);
++ return -EINVAL;
++ }
++
++ efm32_pinctrl_set_mode(ddata, offset,
++ pdata->pindef[offset].mode_gpio_out & 0xf, value);
++ return 0;
++}
++
++static void efm32_pinctrl_gpio_set(struct gpio_chip *chip,
++ unsigned offset, int value)
++{
++ struct efm32_pinctrl_ddata *ddata = from_gpio_chip(chip);
++ unsigned bank = offset / 16;
++ unsigned bankpin = offset % 16;
++ unsigned bank_regoff = bank * 0x24;
++ unsigned dout_regoff = value ?
++ EFM32_REG_Px_DOUTSET : EFM32_REG_Px_DOUTCLR;
++
++ dev_dbg(&ddata->pdev->dev, "%s(%u, %d)\n", __func__, offset, value);
++
++ writel(1 << bankpin, ddata->base + bank_regoff + dout_regoff);
++}
++
++/* XXX */
++#define EFM32_GPIO_IRQ_OFFSET 50
++
++static int efm32_pinctrl_gpio_to_irq(struct gpio_chip *chip,
++ unsigned offset)
++{
++ struct efm32_pinctrl_ddata *ddata = from_gpio_chip(chip);
++
++ unsigned bank = offset / 16;
++ unsigned bankpin = offset % 16;
++ unsigned extipsel_refoff = bankpin < 8 ? EFM32_REG_EXTIPSELL : EFM32_REG_EXTIPSELH;
++ u32 extipsel;
++ unsigned long flags;
++
++ int ret = bankpin + EFM32_GPIO_IRQ_OFFSET;
++
++ spin_lock_irqsave(&ddata->lock, flags);
++ if (ddata->irqport[bankpin] >= 0 && ddata->irqport[bankpin] != bank) {
++ ret = -EINVAL;
++ goto out_unlock;
++ }
++
++ ddata->irqport[bankpin] = bank;
++
++ extipsel = readl(ddata->base + extipsel_refoff);
++ extipsel &= ~(0x7 << 4 * (bankpin % 8));
++ extipsel |= bank << 4 * (bankpin % 8);
++
++ writel(extipsel, ddata->base + extipsel_refoff);
++
++out_unlock:
++ spin_unlock_irqrestore(&ddata->lock, flags);
++
++ return ret;
++}
++
++#define from_irq_chip(chip) container_of((chip), struct efm32_pinctrl_ddata, ic)
++#define from_irq_data(data) from_irq_chip(irq_data_get_irq_chip((data)))
++#define efm32irq(data) (((data)->irq - EFM32_GPIO_IRQ_OFFSET) & 0xf)
++
++static void efm32_pinctrl_irq_ack(struct irq_data *data)
++{
++ struct efm32_pinctrl_ddata *ddata = from_irq_data(data);
++
++ writel(1 << efm32irq(data), ddata->base + EFM32_REG_IFC);
++}
++
++static void efm32_pinctrl_irq_mask(struct irq_data *data)
++{
++ struct efm32_pinctrl_ddata *ddata = from_irq_data(data);
++ unsigned long flags;
++
++ spin_lock_irqsave(&ddata->lock, flags);
++
++ ddata->ien &= ~(1 << efm32irq(data));
++ writel(ddata->ien, ddata->base + EFM32_REG_IEN);
++
++ spin_unlock_irqrestore(&ddata->lock, flags);
++}
++
++static void efm32_pinctrl_irq_unmask(struct irq_data *data)
++{
++ struct efm32_pinctrl_ddata *ddata = from_irq_data(data);
++ unsigned long flags;
++ u32 bitmask = 1 << efm32irq(data);
++
++ spin_lock_irqsave(&ddata->lock, flags);
++
++ ddata->ien |= bitmask;
++ writel(ddata->ien, ddata->base + EFM32_REG_IEN);
++
++ BUG_ON(ddata->irqport[efm32irq(data)] < 0);
++
++ /* retrigger irq on level sensitivity */
++ if ((ddata->extilow | ddata->extihigh) & bitmask) {
++ u32 din = readl(ddata->base + 0x24 * ddata->irqport[efm32irq(data)] + EFM32_REG_Px_DIN);
++ if ((din ^ ddata->extilow) & bitmask)
++ writel(bitmask, ddata->base + EFM32_REG_IFS);
++ }
++
++ spin_unlock_irqrestore(&ddata->lock, flags);
++}
++
++static int efm32_pinctrl_irq_set_type(struct irq_data *data,
++ unsigned int flow_type)
++{
++ struct efm32_pinctrl_ddata *ddata = from_irq_data(data);
++ unsigned long flags;
++
++ if ((flow_type & IRQ_TYPE_LEVEL_MASK) == IRQ_TYPE_LEVEL_MASK)
++ return -EINVAL;
++
++ spin_lock_irqsave(&ddata->lock, flags);
++
++ ddata->extirise &= ~(1 << efm32irq(data));
++ if (flow_type & IRQ_TYPE_EDGE_RISING)
++ ddata->extirise |= 1 << efm32irq(data);
++
++ ddata->extifall &= ~(1 << efm32irq(data));
++ if (flow_type & IRQ_TYPE_EDGE_FALLING)
++ ddata->extifall |= 1 << efm32irq(data);
++
++ /*
++ * There is no explict way to trigger on level sensitive irqs, so
++ * trigger on the corresponding edge and set the irq pending in the
++ * unmask irq callback if the level matches the corresponding level.
++ */
++ ddata->extilow &= ~(1 << efm32irq(data));
++ ddata->extihigh &= ~(1 << efm32irq(data));
++ if (flow_type & IRQ_TYPE_LEVEL_LOW) {
++ ddata->extilow |= 1 << efm32irq(data);
++ ddata->extifall |= 1 << efm32irq(data);
++ } else if (flow_type & IRQ_TYPE_LEVEL_HIGH) {
++ ddata->extihigh |= 1 << efm32irq(data);
++ ddata->extirise |= 1 << efm32irq(data);
++ }
++
++ writel(ddata->extirise, ddata->base + EFM32_REG_EXTIRISE);
++ writel(ddata->extifall, ddata->base + EFM32_REG_EXTIFALL);
++
++ spin_unlock_irqrestore(&ddata->lock, flags);
++
++ return 0;
++}
++
++static void efm32_pinctrl_gpio_handler(unsigned int irq, struct irq_desc *desc, u32 mask)
++{
++ struct irq_chip *parent_chip = irq_get_chip(irq);
++ struct efm32_pinctrl_ddata *ddata = irq_get_handler_data(irq);
++ u32 iflag;
++
++ chained_irq_enter(parent_chip, desc);
++
++ iflag = readl(ddata->base + EFM32_REG_IF);
++ iflag &= mask;
++ while (iflag) {
++ int bit = __ffs(iflag);
++
++ generic_handle_irq(EFM32_GPIO_IRQ_OFFSET + bit);
++ iflag &= ~BIT(bit);
++ }
++
++ chained_irq_exit(parent_chip, desc);
++}
++
++static void efm32_pinctrl_gpio_handler_even(unsigned int irq, struct irq_desc *desc)
++{
++ efm32_pinctrl_gpio_handler(irq, desc, 0x5555);
++}
++
++static void efm32_pinctrl_gpio_handler_odd(unsigned int irq, struct irq_desc *desc)
++{
++ efm32_pinctrl_gpio_handler(irq, desc, 0xaaaa);
++}
++
++static int __devinit efm32_pinctrl_probe(struct platform_device *pdev)
++{
++ struct efm32_pinctrl_ddata *ddata;
++ struct efm32_pinctrl_pdata *pdata;
++ struct resource *res;
++ int ret, i;
++
++ ddata = kzalloc(sizeof(*ddata), GFP_KERNEL);
++ if (!ddata)
++ return -ENOMEM;
++
++ ddata->pdev = pdev;
++
++ spin_lock_init(&ddata->lock);
++
++ for (i = 0; i < ARRAY_SIZE(ddata->irqport); ++i)
++ ddata->irqport[i] = -1;
++
++ ddata->ic.name = "efm32 gpio";
++ ddata->ic.irq_ack = efm32_pinctrl_irq_ack;
++ ddata->ic.irq_mask = efm32_pinctrl_irq_mask;
++ ddata->ic.irq_unmask = efm32_pinctrl_irq_unmask;
++ ddata->ic.irq_set_type = efm32_pinctrl_irq_set_type;
++
++ ddata->gc.label = "efm32 gpio";
++ ddata->gc.dev = &pdev->dev;
++ ddata->gc.owner = THIS_MODULE;
++ ddata->gc.direction_input = efm32_pinctrl_gpio_direction_input;
++ ddata->gc.get = efm32_pinctrl_gpio_get;
++ ddata->gc.direction_output = efm32_pinctrl_gpio_direction_output;
++ ddata->gc.set = efm32_pinctrl_gpio_set;
++ ddata->gc.to_irq = efm32_pinctrl_gpio_to_irq;
++ ddata->gc.ngpio = 6 * 16;
++ ddata->gc.base = 0;
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ ret = -ENODEV;
++ dev_dbg(&pdev->dev, "getting base address failed\n");
++ goto err_get_base;
++ }
++
++ ddata->base = ioremap(res->start, 0x140);
++ if (!ddata->base) {
++ ret = -ENOMEM;
++ dev_dbg(&pdev->dev, "failed to remap\n");
++ goto err_ioremap;
++ }
++
++ irq_set_chained_handler(1 /* IRQ_GPIO_EVEN */, efm32_pinctrl_gpio_handler_even);
++ irq_set_handler_data(1, ddata);
++
++ irq_set_chained_handler(11 /* IRQ_GPIO_ODD */, efm32_pinctrl_gpio_handler_odd);
++ irq_set_handler_data(11, ddata);
++
++ for (i = 0; i < 16; ++i) {
++ irq_set_chip_and_handler(EFM32_GPIO_IRQ_OFFSET + i, &ddata->ic,
++ handle_level_irq);
++ set_irq_flags(EFM32_GPIO_IRQ_OFFSET + i, IRQF_VALID);
++ }
++
++ pdata = dev_get_platdata(&pdev->dev);
++ if (pdata) {
++ for (i = 0; i < ARRAY_SIZE(pdata->pindef); ++i)
++ if (pdata->pindef[i].mode_initial > 0) {
++ unsigned mode =
++ pdata->pindef[i].mode_initial & 0xf;
++ unsigned dout =
++ pdata->pindef[i].mode_initial & 0x10;
++
++ __efm32_pinctrl_set_mode(ddata, i, mode, dout);
++ }
++ }
++
++ ret = gpiochip_add(&ddata->gc);
++ if (ret) {
++ dev_dbg(&pdev->dev, "failed to add gpio chip");
++
++ iounmap(ddata->base);
++err_ioremap:
++err_get_base:
++
++ kfree(ddata);
++ }
++
++ dev_dbg(&pdev->dev, "%s returns %d\n", __func__, ret);
++ return ret;
++}
++
++static struct platform_driver efm32_pinctrl_driver = {
++ .driver = {
++ .name = DRIVER_NAME,
++ .owner = THIS_MODULE,
++ },
++ .probe = efm32_pinctrl_probe,
++};
++
++static int __init efm32_pinctrl_init(void)
++{
++ return platform_driver_register(&efm32_pinctrl_driver);
++}
++postcore_initcall(efm32_pinctrl_init);
++
++MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
++MODULE_LICENSE("GPL v2");
+diff --git a/include/linux/platform_data/efm32-pinctrl.h b/include/linux/platform_data/efm32-pinctrl.h
+new file mode 100644
+index 0000000..3602f67
+--- /dev/null
++++ b/include/linux/platform_data/efm32-pinctrl.h
+@@ -0,0 +1,47 @@
++#ifndef __LINUX_PLATFORM_DATA_EFM32_PINCTRL_H__
++#define __LINUX_PLATFORM_DATA_EFM32_PINCTRL_H__
++
++#define EFM32_MODE_DISABLED 0x00
++#define EFM32_MODE_INPUT 0x01
++#define EFM32_MODE_INPUTFILTER 0x11
++#define EFM32_MODE_INPUTPULLDOWN 0x02
++#define EFM32_MODE_INPUTPULLUP 0x12
++#define EFM32_MODE_INPUTPULLDOWNFILTER 0x03
++#define EFM32_MODE_INPUTPULLUPFILTER 0x13
++#define EFM32_MODE_PUSHPULL 0x04
++#define EFM32_MODE_PUSHPULLDRIVE 0x05
++#define EFM32_MODE_WIREDOR 0x06
++#define EFM32_MODE_WIREDORPULLDOWN 0x07
++#define EFM32_MODE_WIREDAND 0x08
++#define EFM32_MODE_WIREDANDFILTER 0x09
++#define EFM32_MODE_WIREDANDPULLUP 0x0a
++#define EFM32_MODE_WIREDANDPULLUPFILTER 0x0b
++#define EFM32_MODE_WIREDANDDRIVE 0x0c
++#define EFM32_MODE_WIREDANDDRIVEFILTER 0x0d
++#define EFM32_MODE_WIREDANDDRIVEPULLUP 0x0e
++#define EFM32_MODE_WIREDANDDRIVEPULLUPFILTER 0x0f
++
++struct efm32_pinctrl_pindef {
++#define EFM32_PINCTRL_FLAG_INITIAL 1
++#define EFM32_PINCTRL_FLAG_GPIOIN 2
++#define EFM32_PINCTRL_FLAG_GPIOOUT 4
++
++ unsigned short flags;
++
++ /*
++ * These either take a value of the form
++ * ,-4-+-3-----0-.
++ * |DAT| MODE |
++ * `---+---------'
++ * with MODE being one of the EFM32_MODE_... above and DAT being the
++ * value written to DOUT (which matters also for the input modes).
++ */
++ unsigned short mode_initial;
++ unsigned short mode_gpio_in, mode_gpio_out;
++};
++
++struct efm32_pinctrl_pdata {
++ struct efm32_pinctrl_pindef pindef[96];
++};
++
++#endif /* ifndef __LINUX_PLATFORM_DATA_EFM32_PINCTRL_H__ */
diff --git a/patches/linux-3.6/0014-HACK-ARM-allow-a-bootloader-to-be-embedded-and-do-it.patch b/patches/linux-3.6/0014-HACK-ARM-allow-a-bootloader-to-be-embedded-and-do-it.patch
new file mode 100644
index 0000000..9375af4
--- /dev/null
+++ b/patches/linux-3.6/0014-HACK-ARM-allow-a-bootloader-to-be-embedded-and-do-it.patch
@@ -0,0 +1,322 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Sun, 30 Oct 2011 21:11:05 +0100
+Subject: [PATCH] HACK! ARM: allow a bootloader to be embedded and do it on
+ efm32
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ arch/arm/kernel/vmlinux.lds.S | 5 +
+ arch/arm/mach-efm32/Makefile | 2 +
+ arch/arm/mach-efm32/bootloader.S | 274 ++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 281 insertions(+)
+ create mode 100644 arch/arm/mach-efm32/bootloader.S
+
+diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
+index 36ff15b..cda2ca6 100644
+--- a/arch/arm/kernel/vmlinux.lds.S
++++ b/arch/arm/kernel/vmlinux.lds.S
+@@ -86,6 +86,11 @@ SECTIONS
+ #else
+ . = PAGE_OFFSET + TEXT_OFFSET;
+ #endif
++
++ .bootloader : {
++ *(.bootloader)
++ }
++
+ .head.text : {
+ _text = .;
+ HEAD_TEXT
+diff --git a/arch/arm/mach-efm32/Makefile b/arch/arm/mach-efm32/Makefile
+index f3a6932..c882ed0 100644
+--- a/arch/arm/mach-efm32/Makefile
++++ b/arch/arm/mach-efm32/Makefile
+@@ -1,3 +1,5 @@
++obj-y += bootloader.o
++
+ obj-y += clk.o common.o time.o
+
+ obj-$(CONFIG_OF) += dtmachine.o
+diff --git a/arch/arm/mach-efm32/bootloader.S b/arch/arm/mach-efm32/bootloader.S
+new file mode 100644
+index 0000000..2158feb
+--- /dev/null
++++ b/arch/arm/mach-efm32/bootloader.S
+@@ -0,0 +1,274 @@
++#if defined(CONFIG_OF) && !defined(CONFIG_EFM32GG_DK3750_FPGA)
++#define EFM32_USE_OF
++#endif
++#define EFM32_DT_IN_SRAM
++
++#ifdef CONFIG_EFM32GG_DK3750_FPGA
++/* USART1 */
++#define UARTBASE 0x4000c400
++#define UARTLOCATION 0
++#else
++/* UART1 */
++#define UARTBASE 0x4000e400
++#define UARTLOCATION 2
++#endif
++
++ .thumb
++
++ .section ".bootloader","ax"
++
++ /* M3 Vector table */
++ .int 0x10001000 @ Initial SP value
++ .int reset + 1 @ Reset
++
++reset:
++ /* init external RAM and serial port */
++ adr r0, reginit
++1:
++ ldr r1, [r0]
++ ldr r2, [r0, #4]
++ str r2, [r1]
++ add r0, #8
++ cmp r0, #(reginit_end)
++ blo 1b
++
++#ifndef CONFIG_EFM32GG_DK3750_FPGA
++ /* enable UART mux */
++ ldr r0, =(0x80000018)
++ mov r1, #0x1000
++ strh r1, [r0]
++
++ mov r1, #0x0001
++ strh r1, [r0, #-4]
++
++ /* give mux some time to enable the level shifter */
++ ldr r0, =0x4000
++1: subs r0, r0, #1
++ bne 1b
++#endif
++
++ ldr r0, =(UARTBASE + 0x34)
++ mov r1, 0x55
++ str r1, [r0]
++
++#ifndef CONFIG_EFM32GG_DK3750_FPGA
++ /* Zero PSRAM */
++ ldr r0, =(0x88000000)
++ ldr r1, =(0x88400000)
++ mov r2, #0
++ mov r3, #0
++ mov r4, #0
++ mov r5, #0
++1: stmia r0!, {r2-r5}
++ cmp r0, r1
++ bcc 1b
++
++ /* assert zeroing succeeded */
++ ldr r6, =(UARTBASE + 0x34)
++ mov r7, #'<'
++ str r7, [r6]
++ mov r7, #'*'
++ ldr r0, =(0x88000000)
++1: ldmia r0!, {r2-r5}
++ orr r2, r3
++ orr r4, r5
++ orr r2, r4
++ cmp r2, #0
++ it ne
++ strne r7, [r6]
++ cmp r0, r1
++ bcc 1b
++ mov r7, #'>'
++ str r7, [r6]
++#endif
++
++#if defined(EFM32_USE_OF) && defined(EFM32_DT_IN_SRAM)
++#define dtbaddr 0x10000000
++ ldr r0, =(dtbaddr)
++ ldr r1, =(dtb)
++ adr r2, dtbend
++ subs r2, r2, r1
++ bl _memcpy
++#endif
++ /* detect machine type; easy we know this is an efm32gg_dk3750 */
++ movw r0, #0
++ movw r1, #0xf11 @ machid for efm32gg_dk3750
++#ifdef EFM32_USE_OF
++#ifdef EFM32_DT_IN_SRAM
++ ldr r2, =(dtbaddr)
++#else
++ adr r2, dtb
++#endif
++#else
++ adr r2, ataglist
++#endif
++ movw r3, #0
++ movw r4, #0
++ movw r5, #0
++ movw r6, #0
++ movw r7, #0
++
++ b stext
++
++#ifdef EFM32_DT_IN_SRAM
++_memcpy:
++ @ copies r2 bytes from r1 to r0 with r2 > 0
++1:
++ ldrb r3, [r1], #1
++ strb r3, [r0], #1
++ subs r2, #1
++ bhi 1b
++ bx lr
++#endif
++
++ .ltorg
++
++ .align 3
++ /* register value pairs to initialize the machine */
++ .type reginit, %object
++reginit:
++ /* clocks */
++ .int 0x400C8020, 0x00000004 @ CMU_OSCENCMD |= HFXOEN
++
++ .int 0x400c8008, 0x00000100 @ CMU_HFPERCLKDIV, reset default
++ .int 0x43900814, 0x00000001 @ CMU_HFCORECLKEN0 |= EBI via bitband
++ .int 0x439008b4, 0x00000001 @ CMU_HFPERCLKEN0 |= GPIO via bitband
++ .int 0x43900884, 0x00000001 @ CMU_HFPERCLKEN0 |= USART1 via bitband
++#ifndef CONFIG_EFM32GG_DK3750_FPGA
++ .int 0x43900890, 0x00000001 @ CMU_HFPERCLKEN0 |= UART1 via bitband
++#endif
++
++ /* XXX */
++ .int 0x439008c0, 0x00000001 @ CMU_HFPERCLKEN0 |= ADC via bitband
++
++ /* pinmuxing */
++ .int 0x40006000, 0x00000000 @ GPIO_PA_CTRL, reset default
++ .int 0x40006014, 0x0000807f @ GPIO_PA_DOUTCLR; EBI AD8..15 set dataout to 0
++ .int 0x40006004, 0x04444444 @ GPIO_PA_MODEL; EBI AD9..15 set mode=pushpull
++ .int 0x40006008, 0x40000000 @ GPIO_PA_MODEH; EBI AD8 set mode=pushpull
++ .int 0x40006024, 0x00000000 @ GPIO_PB_CTRL, reset default
++#ifdef CONFIG_EFM32GG_DK3750_FPGA
++ .int 0x40006034, 0x00008000 @ GPIO_PB_DOUTSET; EBI mode on PB15 MCU_EBI_CONNECT (1)
++#else
++ .int 0x40006038, 0x00008000 @ GPIO_PB_DOUTCLR; EBI mode on PB15 MCU_EBI_CONNECT (0)
++#endif
++ .int 0x40006038, 0x0000007f @ GPIO_PB_DOUTCLR; EBI A16-22
++ .int 0x40006028, 0x04444444 @ GPIO_PB_MODEL; EBI A16-22
++#ifdef CONFIG_EFM32GG_DK3750_FPGA
++ .int 0x4000602c, 0x40000000 @ GPIO_PB_MODEH; MCU_EBI_CONNECT -> output
++#else
++ .int 0x40006034, 0x00000200 @ GPIO_PB_DOUTSET; set UART_TX to avoid false start
++ .int 0x4000602c, 0x40000140 @ GPIO_PB_MODEH; MCU_EBI_CONNECT -> output, UART_TX, UART_RX
++#endif
++
++ .int 0x40006048, 0x00000000 @ GPIO_PC_CTRL, reset default
++#ifdef CONFIG_EFM32GG_DK3750_FPGA
++ .int 0x40006058, 0x00000001 @ GPIO_PC_DOUTSET; set PC0 (USART1_TX) high to avoid false start
++#endif
++ .int 0x4000605c, 0x00000001 @ GPIO_PC_DOUTCLR; PC11 (EBI_ALE)
++#ifdef CONFIG_EFM32GG_DK3750_FPGA
++ .int 0x4000604c, 0x00000014 @ GPIO_PC_MODEL; PC0: Push-pull output, PC1 (USART1_RX): input
++#endif
++ .int 0x40006050, 0x00004000 @ GPIO_PC_MODEH; PC11: Push-pull output
++ .int 0x4000606c, 0x00000000 @ GPIO_PD_CTRL, reset default
++ .int 0x4000607c, 0x00003e00 @ GPIO_PD_DOUTSET, EBI CS0-3, spiconnect set dataout to 1
++ .int 0x40006074, 0x00444440 @ GPIO_PD_MODEH; EBI CS0-3, spiconnect set mode=pushpull
++ .int 0x40006090, 0x00000000 @ GPIO_PE_CTRL, reset default
++ .int 0x400060a4, 0x0000ff00 @ GPIO_PE_DOUTCLR; EBI AD0..7 set dataout to 0
++ .int 0x40006098, 0x44444444 @ GPIO_PE_MODEH; EBI AD0..7 set mode=pushpull
++ .int 0x400060b4, 0x00000000 @ GPIO_PF_CTRL, reset default
++ .int 0x400060c8, 0x000003c0 @ GPIO_PF_DOUTCLR; EBI Wen+Ren set dataout to 0
++ .int 0x400060b8, 0x44000000 @ GPIO_PF_MODEL; EBI Byte Lane 0 support BL0/BL1
++ .int 0x400060bc, 0x00000044 @ GPIO_PF_MODEH; EBI WEN, REN
++
++ /* EBI */
++#ifdef CONFIG_EFM32GG_DK3750_FPGA
++ .int 0x40008010, 0x00000000 @ EBI_POLARITY, ardy, ale, we, re, cs and bl active low
++ .int 0x40008000, 0x41000003 @ EBI_CTRL, enable ITS, D16, BL
++ .int 0x40008008, 0x00010101 @ EBI_RDTIMING, setup = strobe = hold = 1
++ .int 0x4000800c, 0x00020202 @ EBI_WRTIMING, setup = strobe = hold = 2
++ .int 0x40008004, 0x00000303 @ EBI_ADDRTIMING, setup = hold = 3
++ .int 0x40008014, 0x00540083 @ EBI_ROUTE
++ .int 0x40008000, 0x41000103 @ EBI_CTRL, bank0en
++#else
++ .int 0x40008000, 0x4f00d051 @ EBI_CTRL, enable ITS, mode0=mode2=mode3=D16A16ALE, bl0-3, noidle[023]
++ /* EBI PSRAM */
++ .int 0x40008028, 0x10000000 @ EBI_ADDRTIMING2; HALFALE
++ .int 0x4000802c, 0x20000400 @ EBI_RDTIMING2; Prefetch, StrobeCycles = 4, HoldCycles = SetupCycles = 0
++ .int 0x40008030, 0x00000200 @ EBI_WRTIMING2; StrobeCycles = 2, HoldCycles = SetupCycles = 0
++ .int 0x40008034, 0x00000008 @ EBI_POLARITY2, ARDY_, ALE, WE_, RE_, CS_, BL_
++
++ /* Board Control FPGA */
++ .int 0x40008004, 0x10000303 @ EBI_ADDRTIMING; HALFALE, HoldCycles = SetupCycles = 3
++ .int 0x40008008, 0x00030703 @ EBI_RDTIMING; StrobeCycles = 7, HoldCycles = SetupCycles = 3
++ .int 0x4000800c, 0x00030703 @ EBI_WRTIMING; StrobeCycles = 7, HoldCycles = SetupCycles = 3
++ .int 0x40008010, 0x00000008 @ EBI_POLARITY, ARDY_, ALE, WE_, RE_, CS_, BL_
++
++ /* external NOR flash */
++ .int 0x40008038, 0x10000000 @ EBI_ADDRTIMING3; HALFALE, HoldCycles = SetupCycles = 0
++ .int 0x4000803c, 0x00000700 @ EBI_RDTIMING3; StrobeCycles = 7, HoldCycles = SetupCycles = 0
++ .int 0x40008040, 0x00000200 @ EBI_WRTIMING3; StrobeCycles = 2, HoldCycles = SetupCycles =0
++ .int 0x40008044, 0x00000008 @ EBI_POLARITY3, ARDY_, ALE, WE_, RE_, CS_, BL_
++
++ .int 0x40008014, 0x105e00bb @ EBI_ROUTE
++ .int 0x40008000, 0x4f00dd51 @ EBI_CTRL, enable ITS, mode0=mode2=mode3=D16A16ALE, bl0-3, noidle[023], bank[023]en
++#endif
++
++ .int UARTBASE + 0x00, 0x00000000 @ UART1_CTRL
++ .int UARTBASE + 0x04, 0x00001005 @ UART1_FRAME
++ .int UARTBASE + 0x14, 0x00001900 @ UART1_CLKDIV
++ .int UARTBASE + 0x0c, 0x00000c04 @ UART1_CMD
++ .int UARTBASE + 0x54, 0x00000003 + (UARTLOCATION << 8) @ UART1_ROUTE
++ .int 0x400c8024, 0x00000002 @ CMU_CMD = HFCLKSEL_HFXO
++
++reginit_end:
++ .size reginit, . - reginit
++
++ .align 3
++#ifdef EFM32_USE_OF
++ .type dtb, %object
++dtb:
++ .incbin "arch/arm/boot/efm32gg-dk3750.dtb"
++dtbend:
++ .size dtb, . - dtb
++ .align 3
++
++#else /* ifdef CONFIG_OF */
++
++ .type ataglist, %object
++ataglist:
++ /* ATAG_CORE */
++ .int 0x00000005 /* .size */
++ .int 0x54410001 /* .tag = ATAG_CORE */
++ .int 0x00000001 /* .flags */
++ .int 0x00001000 /* .pagesize */
++ .int 0x000000ff /* .rootdev */
++ /* ATAG_MEM */
++ .int 0x00000004 /* .size */
++ .int 0x54410002 /* .tag = ATAG_MEM */
++#ifdef CONFIG_EFM32GG_DK3750_FPGA
++ .int 0x00100000 /* .size = 1 MiB */
++ .int 0x80000000 /* .start = SRAM_BASE */
++#else
++ .int 0x00400000 /* .size = 4 MiB */
++ .int 0x88000000 /* .start = SRAM_BASE */
++#endif
++ /* ATAG_CMDLINE */
++cmdline:
++ .int (cmdline_end - cmdline) >> 2 /* .size */
++ .int 0x54410009 /* .tag = ATAG_CMDLINE */
++ .ascii "console=ttyefm"
++#ifdef CONFIG_EFM32GG_DK3750_FPGA
++ .ascii "1"
++#else
++ .ascii "4"
++#endif
++ .asciz ",115200 ignore_loglevel ihash_entries=64 dhash_entries=64 rootfstype=romfs init=/linuxrc"
++ .align 2, 0
++cmdline_end:
++ /* ATAG_NONE */
++ .int 0x00000000 /* .size */
++ .int 0x00000000 /* .tag = ATAG_NONE */
++ataglist_end:
++ .size ataglist, . - ataglist
++#endif /* ifdef CONFIG_OF / else */
diff --git a/patches/linux-3.6/0015-HACK-don-t-reserve-memory-for-device-tree-if-it-s-be.patch b/patches/linux-3.6/0015-HACK-don-t-reserve-memory-for-device-tree-if-it-s-be.patch
new file mode 100644
index 0000000..80c1d6b
--- /dev/null
+++ b/patches/linux-3.6/0015-HACK-don-t-reserve-memory-for-device-tree-if-it-s-be.patch
@@ -0,0 +1,31 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Tue, 13 Dec 2011 21:37:46 +0100
+Subject: [PATCH] HACK! don't reserve memory for device tree if it's below
+ PHYS_OFFSET
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This allows to keep the device tree blob in the unregistered 128k SRAM
+on efm32.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ arch/arm/kernel/devtree.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
+index bee7f9d..4fc2acf 100644
+--- a/arch/arm/kernel/devtree.c
++++ b/arch/arm/kernel/devtree.c
+@@ -41,6 +41,10 @@ void __init arm_dt_memblock_reserve(void)
+ if (!initial_boot_params)
+ return;
+
++ if ((unsigned long)initial_boot_params < PHYS_OFFSET)
++ /* assume the dtb is located in ro memory */
++ return;
++
+ /* Reserve the dtb region */
+ memblock_reserve(virt_to_phys(initial_boot_params),
+ be32_to_cpu(initial_boot_params->totalsize));
diff --git a/patches/linux-3.6/0016-HACK-make-stack-dumps-provoked-by-BUG-a-bit-more-hel.patch b/patches/linux-3.6/0016-HACK-make-stack-dumps-provoked-by-BUG-a-bit-more-hel.patch
new file mode 100644
index 0000000..542f128
--- /dev/null
+++ b/patches/linux-3.6/0016-HACK-make-stack-dumps-provoked-by-BUG-a-bit-more-hel.patch
@@ -0,0 +1,35 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Wed, 14 Dec 2011 11:03:48 +0100
+Subject: [PATCH] HACK! make stack dumps provoked by BUG a bit more helpful
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+the right fix would be to continue unwinding at the end when process is
+in handler mode
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ arch/arm/kernel/process.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
+index c45099a..1776977 100644
+--- a/arch/arm/kernel/process.c
++++ b/arch/arm/kernel/process.c
+@@ -334,12 +334,14 @@ void __show_regs(struct pt_regs *regs)
+ #endif
+ }
+
++#include <asm/unwind.h>
++
+ void show_regs(struct pt_regs * regs)
+ {
+ printk("\n");
+ printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm);
+ __show_regs(regs);
+- dump_stack();
++ unwind_backtrace(regs, current);
+ }
+
+ ATOMIC_NOTIFIER_HEAD(thread_notify_head);
diff --git a/patches/linux-3.6/0017-ARM-v7m-add-trivial-suspend-support.patch b/patches/linux-3.6/0017-ARM-v7m-add-trivial-suspend-support.patch
new file mode 100644
index 0000000..7390ebc
--- /dev/null
+++ b/patches/linux-3.6/0017-ARM-v7m-add-trivial-suspend-support.patch
@@ -0,0 +1,95 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Wed, 1 Feb 2012 10:00:00 +0100
+Subject: [PATCH] ARM: v7m: add trivial suspend support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ arch/arm/Kconfig | 2 +-
+ arch/arm/kernel/suspend.c | 10 +++++++++-
+ arch/arm/mm/proc-v7m.S | 13 +++++++++++++
+ 3 files changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index dffb4d9..d3ec936 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -2331,7 +2331,7 @@ source "kernel/power/Kconfig"
+ config ARCH_SUSPEND_POSSIBLE
+ depends on !ARCH_S5PC100 && !ARCH_TEGRA
+ depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \
+- CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE || CPU_MOHAWK
++ CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE || CPU_MOHAWK || CPU_V7M
+ def_bool y
+
+ config ARM_CPU_SUSPEND
+diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
+index 1794cc3..c674832 100644
+--- a/arch/arm/kernel/suspend.c
++++ b/arch/arm/kernel/suspend.c
+@@ -20,7 +20,11 @@ void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
+ *save_ptr = virt_to_phys(ptr);
+
+ /* This must correspond to the LDM in cpu_resume() assembly */
++#ifdef CONFIG_MMU
+ *ptr++ = virt_to_phys(idmap_pgd);
++#else
++ *ptr++ = 0;
++#endif
+ *ptr++ = sp;
+ *ptr++ = virt_to_phys(cpu_do_resume);
+
+@@ -38,11 +42,13 @@ void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
+ */
+ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
+ {
+- struct mm_struct *mm = current->active_mm;
+ int ret;
++#ifdef CONFIG_MMU
++ struct mm_struct *mm = current->active_mm;
+
+ if (!idmap_pgd)
+ return -EINVAL;
++#endif
+
+ /*
+ * Provide a temporary page table with an identity mapping for
+@@ -51,10 +57,12 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
+ * back to the correct page tables.
+ */
+ ret = __cpu_suspend(arg, fn);
++#ifdef CONFIG_MMU
+ if (ret == 0) {
+ cpu_switch_mm(mm->pgd, mm);
+ local_flush_tlb_all();
+ }
++#endif
+
+ return ret;
+ }
+diff --git a/arch/arm/mm/proc-v7m.S b/arch/arm/mm/proc-v7m.S
+index 2b8eb97..42a0ed2 100644
+--- a/arch/arm/mm/proc-v7m.S
++++ b/arch/arm/mm/proc-v7m.S
+@@ -58,6 +58,19 @@ ENTRY(cpu_v7m_switch_mm)
+ mov pc, lr
+ ENDPROC(cpu_v7m_switch_mm)
+
++.globl cpu_v7m_suspend_size
++.equ cpu_v7m_suspend_size, 0
++
++#ifdef CONFIG_ARM_CPU_SUSPEND
++ENTRY(cpu_v7m_do_suspend)
++ mov pc, lr
++ENDPROC(cpu_v7m_do_suspend)
++
++ENTRY(cpu_v7m_do_resume)
++ mov pc, lr
++ENDPROC(cpu_v7m_do_resume)
++#endif
++
+ cpu_v7m_name:
+ .ascii "ARMv7-M Processor"
+ .align
diff --git a/patches/linux-3.6/0018-ARM-efm32-add-trivial-suspend-support.patch b/patches/linux-3.6/0018-ARM-efm32-add-trivial-suspend-support.patch
new file mode 100644
index 0000000..c096f67
--- /dev/null
+++ b/patches/linux-3.6/0018-ARM-efm32-add-trivial-suspend-support.patch
@@ -0,0 +1,71 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Wed, 1 Feb 2012 10:00:21 +0100
+Subject: [PATCH] ARM: efm32: add trivial suspend support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ arch/arm/mach-efm32/Makefile | 1 +
+ arch/arm/mach-efm32/pm.c | 40 ++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 41 insertions(+)
+ create mode 100644 arch/arm/mach-efm32/pm.c
+
+diff --git a/arch/arm/mach-efm32/Makefile b/arch/arm/mach-efm32/Makefile
+index c882ed0..420780e 100644
+--- a/arch/arm/mach-efm32/Makefile
++++ b/arch/arm/mach-efm32/Makefile
+@@ -3,5 +3,6 @@ obj-y += bootloader.o
+ obj-y += clk.o common.o time.o
+
+ obj-$(CONFIG_OF) += dtmachine.o
++obj-$(CONFIG_PM) += pm.o
+
+ obj-y += machines/ devices/
+diff --git a/arch/arm/mach-efm32/pm.c b/arch/arm/mach-efm32/pm.c
+new file mode 100644
+index 0000000..de03941
+--- /dev/null
++++ b/arch/arm/mach-efm32/pm.c
+@@ -0,0 +1,40 @@
++#include <linux/init.h>
++#include <linux/suspend.h>
++
++#include <asm/io.h>
++
++#include "cmu.h"
++
++static inline void v7m_write_scr(u32 val)
++{
++ writel(val, (u32 __iomem *)0xe000ed10);
++}
++
++static int efm32_suspend_enter(suspend_state_t state)
++{
++ u32 cmu_status = readl(CMU_STATUS);
++
++ v7m_write_scr(0x4);
++ cpu_do_idle();
++ v7m_write_scr(0x0);
++
++ if (cmu_status & CMU_STATUS_HFXOSEL) {
++ writel(CMU_OSCENCMD_HFXOEN, CMU_OSCENCMD);
++ writel(CMU_CMD_HFCLKSEL_HFXO, CMU_CMD);
++ }
++
++ return 0;
++}
++
++static const struct platform_suspend_ops efm32_suspend_ops = {
++ .valid = suspend_valid_only_mem,
++ .enter = efm32_suspend_enter,
++};
++
++static int __init efm32_pm_init(void)
++{
++ suspend_set_ops(&efm32_suspend_ops);
++
++ return 0;
++}
++arch_initcall(efm32_pm_init);
diff --git a/patches/linux-3.6/0019-HACK-ARM-increase-TASK_SIZE-for-MMU.patch b/patches/linux-3.6/0019-HACK-ARM-increase-TASK_SIZE-for-MMU.patch
new file mode 100644
index 0000000..5ec33f8
--- /dev/null
+++ b/patches/linux-3.6/0019-HACK-ARM-increase-TASK_SIZE-for-MMU.patch
@@ -0,0 +1,34 @@
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Thu, 4 Oct 2012 13:32:51 +0200
+Subject: [PATCH] HACK: ARM: increase TASK_SIZE for !MMU
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is needed for strncpy_from_user and friends since
+
+ 8c56cc8 (ARM: 7449/1: use generic strnlen_user and strncpy_from_user functions)
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+---
+ arch/arm/include/asm/memory.h | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
+index 5f6ddcc..6f36cf5 100644
+--- a/arch/arm/include/asm/memory.h
++++ b/arch/arm/include/asm/memory.h
+@@ -89,9 +89,12 @@
+ * It is difficult to define and perhaps will never meet the original meaning
+ * of this define that was meant to.
+ * Fortunately, there is no reference for this in noMMU mode, for now.
++ *
++ * HACK: copy_from_user must even handle copying from flash. So don't impose a
++ * limit at all. Not sure this is correct ...
+ */
+ #ifndef TASK_SIZE
+-#define TASK_SIZE (CONFIG_DRAM_SIZE)
++#define TASK_SIZE (~0UL)
+ #endif
+
+ #ifndef TASK_UNMAPPED_BASE
diff --git a/patches/linux-3.6/series b/patches/linux-3.6/series
new file mode 100644
index 0000000..4e1cd15
--- /dev/null
+++ b/patches/linux-3.6/series
@@ -0,0 +1,22 @@
+# generated by git-ptx-patches
+#tag:base --start-number 1
+0001-hwmon-efm32-adc-new-driver.patch
+0002-spi-new-controller-driver-for-efm32-SoCs.patch
+0003-ARM-make-cr_alignment-read-only-ifndef-CONFIG_CPU_CP.patch
+0004-Cortex-M3-Add-base-support-for-Cortex-M3.patch
+0005-Cortex-M3-Add-support-for-exception-handling.patch
+0006-Cortex-M3-Add-NVIC-support.patch
+0007-Cortex-M3-Allow-the-building-of-Cortex-M3-kernel-por.patch
+0008-HACK-ARM-no-we-don-t-enter-in-ARM.patch
+0009-mtd-maps-uclinux-fix-sparse-warnings-and-codingstyle.patch
+0010-mtd-maps-uclinux-add-support-for-romfs-in-RAM-or-ROM.patch
+0011-ARM-new-platform-for-Energy-Micro-s-EFM32-Cortex-M3-.patch
+0012-ARM-efm32-add-support-for-non-dt-builds-and-add-more.patch
+0013-pinctrl-add-a-driver-for-Energy-Micro-s-efm32-SoCs.patch
+0014-HACK-ARM-allow-a-bootloader-to-be-embedded-and-do-it.patch
+0015-HACK-don-t-reserve-memory-for-device-tree-if-it-s-be.patch
+0016-HACK-make-stack-dumps-provoked-by-BUG-a-bit-more-hel.patch
+0017-ARM-v7m-add-trivial-suspend-support.patch
+0018-ARM-efm32-add-trivial-suspend-support.patch
+0019-HACK-ARM-increase-TASK_SIZE-for-MMU.patch
+# 30205d7ea89c4c1756e0e2ef96a6e220 - git-ptx-patches magic
diff --git a/platformconfig b/platformconfig
new file mode 100644
index 0000000..2fa37b8
--- /dev/null
+++ b/platformconfig
@@ -0,0 +1,194 @@
+#
+# Automatically generated make config: don't edit
+# PTXdist 2012.09.1
+#
+PTXCONF_PLATFORMCONFIG_VERSION="2012.09.1"
+PTXCONF_RUNTIME=y
+PTXCONF_BUILDTIME=y
+PTXCONF__platformconfig_MAGIC__=y
+
+#
+# ------------------------------------
+#
+
+#
+# Target Platform Configuration
+#
+
+#
+# ------------------------------------
+#
+PTXCONF_PLATFORM="energymicro-efm32gg-dk3750"
+PTXCONF_PLATFORM_VERSION="-2012.10.0"
+
+#
+# architecture
+#
+# PTXCONF_ARCH_ALPHA is not set
+# PTXCONF_ARCH_AVR32 is not set
+# PTXCONF_ARCH_AVR is not set
+PTXCONF_ARCH_ARM=y
+# PTXCONF_ARCH_BLACKFIN is not set
+# PTXCONF_ARCH_X86 is not set
+# PTXCONF_ARCH_MINGW is not set
+# PTXCONF_ARCH_PPC is not set
+# PTXCONF_ARCH_M68K is not set
+# PTXCONF_ARCH_SPARC is not set
+# PTXCONF_ARCH_MICROBLAZE is not set
+# PTXCONF_ARCH_MIPS is not set
+# PTXCONF_ARCH_CRIS is not set
+# PTXCONF_ARCH_PARISC is not set
+# PTXCONF_ARCH_SH is not set
+PTXCONF_ARCH_SUPPORTS_ENDIAN_BIG=y
+PTXCONF_ARCH_SUPPORTS_ENDIAN_LITTLE=y
+# PTXCONF_ENDIAN_BIG is not set
+PTXCONF_ENDIAN_LITTLE=y
+# PTXCONF_ARCH_ARM_V6 is not set
+# PTXCONF_ARCH_ARM_IWMMXT is not set
+# PTXCONF_ARCH_ARM_NEON is not set
+# PTXCONF_HAS_HARDFLOAT is not set
+PTXCONF_HAS_MMU=y
+PTXCONF_SIZEOF_LONG_DOUBLE="8"
+PTXCONF_ARCH_STRING="arm"
+
+#
+# paths & directories
+#
+PTXCONF_SYSROOT_TARGET="${PTXDIST_PLATFORMDIR}/sysroot-target"
+PTXCONF_SYSROOT_HOST="${PTXDIST_PLATFORMDIR}/sysroot-host"
+PTXCONF_SYSROOT_CROSS="${PTXDIST_PLATFORMDIR}/sysroot-cross"
+
+#
+# toolchain
+#
+PTXCONF_CROSSCHAIN_VENDOR=""
+PTXCONF_CROSSCHAIN_CHECK="4.5.2"
+# PTXCONF_LIBC_GLIBC is not set
+PTXCONF_LIBC_UCLIBC=y
+PTXCONF_UCLIBC_VERSION="0.9.30.2"
+PTXCONF_GNU_TARGET="arm-uclinuxeabi"
+PTXCONF_COMPILER_PREFIX="${PTXCONF_GNU_TARGET}-"
+PTXCONF_COMPILER_PREFIX_KERNEL="${PTXCONF_COMPILER_PREFIX}"
+PTXCONF_COMPILER_PREFIX_BOOTLOADER="${PTXCONF_COMPILER_PREFIX}"
+
+#
+# extra toolchain options
+#
+PTXCONF_TARGET_EXTRA_CPPFLAGS=""
+PTXCONF_TARGET_EXTRA_CFLAGS="-march=armv7-m -mthumb"
+PTXCONF_TARGET_EXTRA_CXXFLAGS="-march=armv7-m -mthumb"
+PTXCONF_TARGET_EXTRA_LDFLAGS="-march=armv7-m -mthumb"
+PTXCONF_KERNEL=y
+# PTXCONF_KERNEL_INSTALL is not set
+# PTXCONF_KERNEL_MODULES is not set
+PTXCONF_KERNEL_VERSION="3.6"
+PTXCONF_KERNEL_MD5="1a1760420eac802c541a20ab51a093d1"
+PTXCONF_KERNEL_ARCH_STRING="arm"
+# PTXCONF_KERNEL_IMAGE_BZ is not set
+# PTXCONF_KERNEL_IMAGE_Z is not set
+PTXCONF_KERNEL_IMAGE_XIP=y
+# PTXCONF_KERNEL_IMAGE_U is not set
+# PTXCONF_KERNEL_IMAGE_VM is not set
+# PTXCONF_KERNEL_IMAGE_VMLINUX is not set
+# PTXCONF_KERNEL_IMAGE_RAW is not set
+# PTXCONF_KERNEL_IMAGE_SIMPLE is not set
+PTXCONF_KERNEL_IMAGE="xipImage"
+# PTXCONF_KERNEL_XZ is not set
+# PTXCONF_KERNEL_LZOP is not set
+
+#
+# patching & configuration
+#
+PTXCONF_KERNEL_SERIES="series"
+PTXCONF_KERNEL_CONFIG="kernelconfig-${PTXCONF_KERNEL_VERSION}"
+
+#
+# Development features
+#
+PTXCONF_KERNEL_EXTRA_MAKEVARS=""
+# PTXCONF_HOST_DTC is not set
+# PTXCONF_DTC is not set
+
+#
+# console options
+#
+PTXCONF_CONSOLE_NAME="ttyS0"
+PTXCONF_CONSOLE_SPEED="115200"
+
+#
+# extra kernel
+#
+
+#
+# bootloaders
+#
+# PTXCONF_AT91BOOTSTRAP is not set
+# PTXCONF_AT91BOOTSTRAP2 is not set
+PTXCONF_BAREBOX_ARCH_STRING="arm"
+# PTXCONF_BAREBOX is not set
+# PTXCONF_BAREBOX_MLO is not set
+# PTXCONF_GRUB is not set
+# PTXCONF_HOST_MXS_UTILS is not set
+# PTXCONF_U_BOOT_V2 is not set
+# PTXCONF_U_BOOT is not set
+# PTXCONF_X_LOAD is not set
+
+#
+# flash
+#
+PTXCONF_FLASH_BLOCKSIZE=""
+
+#
+# image creation options
+#
+# PTXCONF_IMAGE_BOOT_MLO_VFAT is not set
+# PTXCONF_IMAGE_CPIO is not set
+# PTXCONF_IMAGE_CPIO_GZ is not set
+# PTXCONF_IMAGE_EXT2 is not set
+# PTXCONF_IMAGE_HD is not set
+# PTXCONF_IMAGE_VDI is not set
+
+#
+# ipkg options
+#
+# PTXCONF_IMAGE_IPKG_PUSH_TO_REPOSITORY is not set
+# PTXCONF_IMAGE_INSTALL_FROM_IPKG_REPOSITORY is not set
+PTXCONF_IMAGE_IPKG_INDEX=y
+PTXCONF_IMAGE_IPKG_EXTRA_ARGS=""
+# PTXCONF_IMAGE_JFFS2 is not set
+PTXCONF_IMAGE_KERNEL=y
+# PTXCONF_IMAGE_KERNEL_INITRAMFS is not set
+PTXCONF_IMAGE_KERNEL_INSTALL_EARLY=y
+# PTXCONF_IMAGE_KERNEL_LZOP is not set
+PTXCONF_IMAGE_ROMFS=y
+PTXCONF_IMAGE_ROMFS_EXTRA_ARGS=""
+# PTXCONF_IMAGE_SQUASHFS is not set
+# PTXCONF_IMAGE_TGZ is not set
+# PTXCONF_IMAGE_UBI is not set
+# PTXCONF_IMAGE_UBIFS is not set
+# PTXCONF_IMAGE_UIMAGE is not set
+# PTXCONF_HOST_CDRKIT is not set
+# PTXCONF_HOST_CMAKE is not set
+# PTXCONF_HOST_CRAMFS is not set
+# PTXCONF_HOST_DOSFSTOOLS is not set
+# PTXCONF_HOST_E2FSPROGS is not set
+# PTXCONF_HOST_GENEXT2FS is not set
+# PTXCONF_HOST_GENPART is not set
+# PTXCONF_HOST_GETTEXT is not set
+# PTXCONF_HOST_LIBBLKID is not set
+# PTXCONF_HOST_LIBBZ2 is not set
+# PTXCONF_HOST_LIBCAP is not set
+# PTXCONF_HOST_LIBLZO is not set
+# PTXCONF_HOST_LIBUUID is not set
+# PTXCONF_HOST_LZOP is not set
+# PTXCONF_HOST_MKELFIMAGE is not set
+# PTXCONF_HOST_MTD_UTILS is not set
+# PTXCONF_HOST_MTOOLS is not set
+# PTXCONF_HOST_OPENSSL is not set
+# PTXCONF_HOST_SQUASHFS_TOOLS is not set
+# PTXCONF_HOST_U_BOOT_TOOLS is not set
+# PTXCONF_HOST_UTIL_LINUX_NG is not set
+# PTXCONF_HOST_XL_TOOLS is not set
+# PTXCONF_HOST_XZ is not set
+# PTXCONF_HOST_ZLIB is not set
+PTXCONF_HOST_GENROMFS=y