diff options
author | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2012-10-08 15:03:32 +0200 |
---|---|---|
committer | Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | 2012-10-08 15:03:32 +0200 |
commit | 771037416ed13636bfcbe6d16ce3c3d516c85dc4 (patch) | |
tree | 1622d0f2cac83f128dc99242bb0256b8b19b323e | |
download | OSELAS.BSP-EnergyMicro-Gecko-771037416ed13636bfcbe6d16ce3c3d516c85dc4.tar.gz OSELAS.BSP-EnergyMicro-Gecko-771037416ed13636bfcbe6d16ce3c3d516c85dc4.tar.xz |
platform-energymicro-efm32gg-dk3750: initial code drop
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, ®s, 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 |