summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configs/platform-ti/barebox.config346
-rw-r--r--configs/platform-ti/barebox_mlo.config228
-rw-r--r--configs/platform-ti/config/images/boot-mlo-vfat.config10
-rw-r--r--configs/platform-ti/patches/barebox-2012.07.0/0000-barebox-v2012.07.0-to-master.patch12305
-rw-r--r--configs/platform-ti/patches/barebox-2012.07.0/0001-WIP-beaglebone-add-support-for-AM335x-and-board.patch3688
-rw-r--r--configs/platform-ti/patches/barebox-2012.07.0/series2
-rw-r--r--configs/platform-ti/platformconfig29
-rw-r--r--configs/platform-ti/platforms/image-boot-mlo.in12
8 files changed, 16604 insertions, 16 deletions
diff --git a/configs/platform-ti/barebox.config b/configs/platform-ti/barebox.config
new file mode 100644
index 0000000..2e5e08f
--- /dev/null
+++ b/configs/platform-ti/barebox.config
@@ -0,0 +1,346 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Barebox/arm 2012.07.0 Configuration
+#
+# CONFIG_BOARD_LINKER_SCRIPT is not set
+CONFIG_GENERIC_LINKER_SCRIPT=y
+CONFIG_ARM=y
+CONFIG_ARM_LINUX=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_MXS is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_NOMADIK is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_S3C24xx is not set
+# CONFIG_ARCH_S5PCxx is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_TEGRA is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+
+#
+# processor features
+#
+# CONFIG_BOOT_ENDIANNESS_SWITCH is not set
+CONFIG_BOARDINFO="Texas Instrument's Beagle Bone"
+
+#
+# OMAP Features
+#
+CONFIG_OMAP3_LOWLEVEL_INIT=y
+CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
+CONFIG_OMAP_CLOCK_ALL=y
+CONFIG_OMAP_CLOCK_SOURCE_S32K=y
+# CONFIG_OMAP3_CLOCK_CONFIG is not set
+# CONFIG_OMAP_GPMC is not set
+# CONFIG_OMAP_BUILD_IFT is not set
+# CONFIG_MACH_OMAP343xSDP is not set
+# CONFIG_MACH_BEAGLE is not set
+CONFIG_MACH_BEAGLEBONE=y
+# CONFIG_MACH_OMAP3EVM is not set
+# CONFIG_MACH_PCAAL1 is not set
+CONFIG_AEABI=y
+# CONFIG_THUMB2_BAREBOX is not set
+
+#
+# Arm specific settings
+#
+CONFIG_CMD_ARM_CPUINFO=y
+# CONFIG_CMD_ARM_MMUINFO is not set
+# CONFIG_CPU_V7_DCACHE_SKIP is not set
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_ARM_EXCEPTIONS=y
+CONFIG_ARM_UNWIND=y
+CONFIG_DEFCONFIG_LIST="$ARCH_DEFCONFIG"
+CONFIG_HAS_KALLSYMS=y
+CONFIG_HAS_MODULES=y
+CONFIG_CMD_MEMORY=y
+CONFIG_ENV_HANDLING=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_BLOCK=y
+CONFIG_BLOCK_WRITE=y
+CONFIG_HAVE_NOSHELL=y
+CONFIG_FILETYPE=y
+CONFIG_BINFMT=y
+CONFIG_GLOBALVAR=y
+
+#
+# General Settings
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_BANNER=y
+CONFIG_ENVIRONMENT_VARIABLES=y
+
+#
+# memory layout
+#
+CONFIG_MMU=y
+CONFIG_HAVE_CONFIGURABLE_TEXT_BASE=y
+CONFIG_TEXT_BASE=0x81000000
+CONFIG_BAREBOX_MAX_IMAGE_SIZE=0xffffffff
+CONFIG_BAREBOX_MAX_BARE_INIT_SIZE=0xffffffff
+CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y
+CONFIG_MEMORY_LAYOUT_DEFAULT=y
+# CONFIG_MEMORY_LAYOUT_FIXED is not set
+CONFIG_STACK_SIZE=0x8000
+CONFIG_MALLOC_SIZE=0x400000
+# CONFIG_BROKEN is not set
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_MALLOC_DLMALLOC=y
+# CONFIG_MALLOC_TLSF is not set
+CONFIG_KALLSYMS=y
+CONFIG_ARCH_HAS_LOWLEVEL_INIT=y
+CONFIG_PROMPT="barebox> "
+CONFIG_BAUDRATE=115200
+CONFIG_LONGHELP=y
+CONFIG_CBSIZE=1024
+CONFIG_MAXARGS=16
+CONFIG_SHELL_HUSH=y
+# CONFIG_SHELL_SIMPLE is not set
+# CONFIG_SHELL_NONE is not set
+CONFIG_GLOB=y
+CONFIG_GLOB_SORT=y
+CONFIG_PROMPT_HUSH_PS2="> "
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_HUSH_GETOPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+# CONFIG_PASSWORD is not set
+CONFIG_DYNAMIC_CRC_TABLE=y
+CONFIG_ERRNO_MESSAGES=y
+# CONFIG_TIMESTAMP is not set
+CONFIG_CONSOLE_FULL=y
+CONFIG_CONSOLE_ACTIVATE_FIRST=y
+CONFIG_PARTITION=y
+CONFIG_PARTITION_DISK=y
+CONFIG_PARTITION_DISK_DOS=y
+CONFIG_DEFAULT_ENVIRONMENT=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+# CONFIG_DEFAULT_ENVIRONMENT_GENERIC is not set
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/beaglebone/env"
+# CONFIG_BAREBOXENV_TARGET is not set
+# CONFIG_POLLER is not set
+
+#
+# Debugging
+#
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_ENABLE_FLASH_NOISE is not set
+# CONFIG_ENABLE_PARTITION_NOISE is not set
+# CONFIG_ENABLE_DEVICE_NOISE is not set
+# CONFIG_DEBUG_LL is not set
+CONFIG_HAS_DEBUG_LL=y
+CONFIG_COMMAND_SUPPORT=y
+# CONFIG_HAS_POWEROFF is not set
+
+#
+# commands
+#
+
+#
+# scripting
+#
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+# CONFIG_CMD_MSLEEP is not set
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TRUE=y
+CONFIG_CMD_FALSE=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+# CONFIG_CMD_LOGIN is not set
+# CONFIG_CMD_PASSWD is not set
+CONFIG_CMD_TIME=y
+CONFIG_CMD_GLOBAL=y
+
+#
+# file commands
+#
+CONFIG_CMD_LS=y
+CONFIG_CMD_RM=y
+CONFIG_CMD_CAT=y
+CONFIG_CMD_MKDIR=y
+CONFIG_CMD_RMDIR=y
+CONFIG_CMD_CP=y
+CONFIG_CMD_PWD=y
+CONFIG_CMD_CD=y
+CONFIG_CMD_MOUNT=y
+CONFIG_CMD_UMOUNT=y
+CONFIG_CMD_AUTOMOUNT=y
+CONFIG_CMD_BASENAME=y
+CONFIG_CMD_DIRNAME=y
+
+#
+# console
+#
+CONFIG_CMD_CLEAR=y
+CONFIG_CMD_ECHO=y
+CONFIG_CMD_ECHO_E=y
+
+#
+# memory
+#
+# CONFIG_CMD_LOADB is not set
+# CONFIG_CMD_LOADY is not set
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_IOMEM is not set
+CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
+# CONFIG_CMD_MD5SUM is not set
+# CONFIG_CMD_SHA1SUM is not set
+# CONFIG_CMD_SHA256SUM is not set
+# CONFIG_CMD_SHA224SUM is not set
+# CONFIG_CMD_MTEST is not set
+
+#
+# flash
+#
+# CONFIG_CMD_FLASH is not set
+
+#
+# booting
+#
+CONFIG_CMD_BOOTM=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_BOOTM_VERBOSE=y
+CONFIG_CMD_BOOTM_INITRD=y
+CONFIG_CMD_BOOTM_OFTREE=y
+CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
+# CONFIG_CMD_BOOTM_AIMAGE is not set
+CONFIG_CMD_UIMAGE=y
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_BOOTU=y
+CONFIG_FLEXIBLE_BOOTARGS=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_TEST=y
+CONFIG_CMD_VERSION=y
+CONFIG_CMD_HELP=y
+CONFIG_CMD_MAGICVAR=y
+CONFIG_CMD_MAGICVAR_HELP=y
+CONFIG_CMD_DEVINFO=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_UNCOMPRESS=y
+# CONFIG_NET is not set
+
+#
+# Drivers
+#
+
+#
+# serial drivers
+#
+# CONFIG_DRIVER_SERIAL_ARM_DCC is not set
+CONFIG_DRIVER_SERIAL_NS16550=y
+CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS=y
+
+#
+# SPI drivers
+#
+# CONFIG_SPI is not set
+# CONFIG_I2C is not set
+
+#
+# flash drivers
+#
+# CONFIG_DRIVER_CFI is not set
+# CONFIG_MTD is not set
+CONFIG_DISK=y
+CONFIG_DISK_WRITE=y
+
+#
+# drive types
+#
+# CONFIG_DISK_ATA is not set
+
+#
+# interface types
+#
+# CONFIG_DISK_INTF_PLATFORM_IDE is not set
+# CONFIG_USB is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_VIDEO is not set
+CONFIG_MCI=y
+
+#
+# --- Feature list ---
+#
+CONFIG_MCI_STARTUP=y
+CONFIG_MCI_INFO=y
+CONFIG_MCI_WRITE=y
+
+#
+# --- MCI host drivers ---
+#
+CONFIG_MCI_OMAP_HSMMC=y
+
+#
+# MFD
+#
+# CONFIG_LED is not set
+
+#
+# EEPROM support
+#
+
+#
+# Input device support
+#
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_PWM is not set
+
+#
+# DMA support
+#
+
+#
+# Filesystem support
+#
+CONFIG_FS_AUTOMOUNT=y
+# CONFIG_FS_CRAMFS is not set
+CONFIG_FS_RAMFS=y
+CONFIG_FS_DEVFS=y
+# CONFIG_FS_NFS is not set
+CONFIG_FS_FAT=y
+CONFIG_FS_FAT_WRITE=y
+CONFIG_FS_FAT_LFN=y
+
+#
+# Library routines
+#
+CONFIG_PARAMETER=y
+CONFIG_UNCOMPRESS=y
+# CONFIG_ZLIB is not set
+# CONFIG_BZLIB is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_PROCESS_ESCAPE_SEQUENCE=y
+# CONFIG_LZO_DECOMPRESS is not set
+CONFIG_FDT=y
+CONFIG_OFTREE=y
+CONFIG_QSORT=y
+CONFIG_CRC32=y
+# CONFIG_DIGEST is not set
diff --git a/configs/platform-ti/barebox_mlo.config b/configs/platform-ti/barebox_mlo.config
new file mode 100644
index 0000000..b83ffb1
--- /dev/null
+++ b/configs/platform-ti/barebox_mlo.config
@@ -0,0 +1,228 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# Barebox/arm 2012.07.0 Configuration
+#
+# CONFIG_BOARD_LINKER_SCRIPT is not set
+CONFIG_GENERIC_LINKER_SCRIPT=y
+CONFIG_ARM=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_MXS is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_NOMADIK is not set
+CONFIG_ARCH_OMAP=y
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_S3C24xx is not set
+# CONFIG_ARCH_S5PCxx is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_TEGRA is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+
+#
+# processor features
+#
+# CONFIG_BOOT_ENDIANNESS_SWITCH is not set
+CONFIG_BOARDINFO="Texas Instrument's Beagle Bone"
+
+#
+# OMAP Features
+#
+CONFIG_OMAP3_LOWLEVEL_INIT=y
+CONFIG_ARCH_OMAP3=y
+# CONFIG_ARCH_OMAP4 is not set
+CONFIG_OMAP_CLOCK_ALL=y
+CONFIG_OMAP_CLOCK_SOURCE_S32K=y
+# CONFIG_OMAP3_CLOCK_CONFIG is not set
+# CONFIG_OMAP_GPMC is not set
+CONFIG_OMAP_BUILD_IFT=y
+# CONFIG_MACH_OMAP343xSDP is not set
+# CONFIG_MACH_BEAGLE is not set
+CONFIG_MACH_BEAGLEBONE=y
+# CONFIG_MACH_OMAP3EVM is not set
+# CONFIG_MACH_PCAAL1 is not set
+CONFIG_ARM_ASM_UNIFIED=y
+CONFIG_AEABI=y
+CONFIG_THUMB2_BAREBOX=y
+
+#
+# Arm specific settings
+#
+# CONFIG_CMD_ARM_CPUINFO is not set
+# CONFIG_CMD_ARM_MMUINFO is not set
+# CONFIG_CPU_V7_DCACHE_SKIP is not set
+# CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS is not set
+CONFIG_ARM_EXCEPTIONS=y
+# CONFIG_ARM_UNWIND is not set
+CONFIG_DEFCONFIG_LIST="$ARCH_DEFCONFIG"
+CONFIG_HAS_KALLSYMS=y
+CONFIG_HAS_MODULES=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_BLOCK=y
+CONFIG_BLOCK_WRITE=y
+CONFIG_HAVE_NOSHELL=y
+
+#
+# General Settings
+#
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_BANNER=y
+CONFIG_ENVIRONMENT_VARIABLES=y
+
+#
+# memory layout
+#
+CONFIG_MMU=y
+CONFIG_HAVE_CONFIGURABLE_TEXT_BASE=y
+CONFIG_TEXT_BASE=0x402F0400
+CONFIG_BAREBOX_MAX_IMAGE_SIZE=0xffffffff
+CONFIG_BAREBOX_MAX_BARE_INIT_SIZE=0xffffffff
+CONFIG_HAVE_CONFIGURABLE_MEMORY_LAYOUT=y
+# CONFIG_MEMORY_LAYOUT_DEFAULT is not set
+CONFIG_MEMORY_LAYOUT_FIXED=y
+CONFIG_STACK_BASE=0x4030B800
+CONFIG_STACK_SIZE=0x1600
+CONFIG_MALLOC_BASE=0x8F000000
+CONFIG_MALLOC_SIZE=0x1000000
+# CONFIG_BROKEN is not set
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_MALLOC_DLMALLOC=y
+# CONFIG_MALLOC_TLSF is not set
+# CONFIG_MALLOC_DUMMY is not set
+# CONFIG_KALLSYMS is not set
+CONFIG_ARCH_HAS_LOWLEVEL_INIT=y
+CONFIG_PROMPT="MLO>"
+CONFIG_BAUDRATE=115200
+CONFIG_SIMPLE_READLINE=y
+CONFIG_LONGHELP=y
+CONFIG_CBSIZE=1024
+CONFIG_MAXARGS=16
+# CONFIG_SHELL_HUSH is not set
+# CONFIG_SHELL_SIMPLE is not set
+CONFIG_SHELL_NONE=y
+# CONFIG_CMDLINE_EDITING is not set
+# CONFIG_PASSWORD is not set
+# CONFIG_ERRNO_MESSAGES is not set
+# CONFIG_TIMESTAMP is not set
+CONFIG_CONSOLE_FULL=y
+CONFIG_CONSOLE_ACTIVATE_FIRST=y
+CONFIG_PARTITION=y
+CONFIG_PARTITION_DISK=y
+CONFIG_PARTITION_DISK_DOS=y
+# CONFIG_DEFAULT_ENVIRONMENT is not set
+# CONFIG_BAREBOXENV_TARGET is not set
+# CONFIG_POLLER is not set
+
+#
+# Debugging
+#
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_ENABLE_FLASH_NOISE is not set
+# CONFIG_ENABLE_PARTITION_NOISE is not set
+# CONFIG_ENABLE_DEVICE_NOISE is not set
+# CONFIG_DEBUG_LL is not set
+CONFIG_HAS_DEBUG_LL=y
+# CONFIG_HAS_POWEROFF is not set
+# CONFIG_NET is not set
+
+#
+# Drivers
+#
+
+#
+# serial drivers
+#
+# CONFIG_DRIVER_SERIAL_ARM_DCC is not set
+CONFIG_DRIVER_SERIAL_NS16550=y
+CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS=y
+
+#
+# SPI drivers
+#
+# CONFIG_SPI is not set
+# CONFIG_I2C is not set
+
+#
+# flash drivers
+#
+# CONFIG_DRIVER_CFI is not set
+# CONFIG_MTD is not set
+CONFIG_DISK=y
+CONFIG_DISK_WRITE=y
+
+#
+# drive types
+#
+# CONFIG_DISK_ATA is not set
+
+#
+# interface types
+#
+# CONFIG_DISK_INTF_PLATFORM_IDE is not set
+# CONFIG_USB is not set
+# CONFIG_USB_GADGET is not set
+# CONFIG_VIDEO is not set
+CONFIG_MCI=y
+
+#
+# --- Feature list ---
+#
+CONFIG_MCI_STARTUP=y
+CONFIG_MCI_WRITE=y
+
+#
+# --- MCI host drivers ---
+#
+CONFIG_MCI_OMAP_HSMMC=y
+
+#
+# MFD
+#
+# CONFIG_LED is not set
+
+#
+# EEPROM support
+#
+
+#
+# Input device support
+#
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_PWM is not set
+
+#
+# DMA support
+#
+
+#
+# Filesystem support
+#
+# CONFIG_FS_CRAMFS is not set
+# CONFIG_FS_RAMFS is not set
+# CONFIG_FS_DEVFS is not set
+# CONFIG_FS_NFS is not set
+CONFIG_FS_FAT=y
+# CONFIG_FS_FAT_WRITE is not set
+CONFIG_FS_FAT_LFN=y
+
+#
+# Library routines
+#
+# CONFIG_ZLIB is not set
+# CONFIG_BZLIB is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+# CONFIG_PROCESS_ESCAPE_SEQUENCE is not set
+# CONFIG_LZO_DECOMPRESS is not set
+# CONFIG_DIGEST is not set
diff --git a/configs/platform-ti/config/images/boot-mlo-vfat.config b/configs/platform-ti/config/images/boot-mlo-vfat.config
new file mode 100644
index 0000000..3b5f9b5
--- /dev/null
+++ b/configs/platform-ti/config/images/boot-mlo-vfat.config
@@ -0,0 +1,10 @@
+image @IMAGE@ {
+ vfat {
+ file MLO { image = "MLO"}
+ file barebox.bin { image = "barebox-image" }
+ file barebox.env { image = "barebox-default-environment" }
+ file uImage { image = "linuximage" }
+ }
+ name = boot-mlo
+ size = 10M
+}
diff --git a/configs/platform-ti/patches/barebox-2012.07.0/0000-barebox-v2012.07.0-to-master.patch b/configs/platform-ti/patches/barebox-2012.07.0/0000-barebox-v2012.07.0-to-master.patch
new file mode 100644
index 0000000..4519124
--- /dev/null
+++ b/configs/platform-ti/patches/barebox-2012.07.0/0000-barebox-v2012.07.0-to-master.patch
@@ -0,0 +1,12305 @@
+diff --git a/.gitignore b/.gitignore
+index df0ed2c..fd429fa 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -65,3 +65,4 @@ cscope.*
+ *.patch
+ scripts/gen_netx_image
+ scripts/s5p_cksum
++scripts/bareboxenv-target
+diff --git a/Makefile b/Makefile
+index 63da477..ebcf9bf 100644
+--- a/Makefile
++++ b/Makefile
+@@ -540,7 +540,7 @@ quiet_cmd_check_file_size = CHKSIZE $@
+ max_size=`printf "%d" $2`; \
+ if [ $$size -gt $$max_size ] ; \
+ then \
+- echo "$@ size $$size > of the maximum size $$max_size"; \
++ echo "$@ size $$size > of the maximum size $$max_size" >&2; \
+ exit 1 ; \
+ fi;
+
+@@ -1003,6 +1003,7 @@ CLEAN_DIRS += $(MODVERDIR)
+ CLEAN_FILES += barebox System.map include/generated/barebox_default_env.h \
+ .tmp_version .tmp_barebox* barebox.bin barebox.map barebox.S \
+ .tmp_kallsyms* barebox_default_env* barebox.ldr \
++ scripts/bareboxenv-target \
+ Doxyfile.version barebox.srec barebox.s5p
+
+ # Directories & files removed with 'make mrproper'
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 3eada5b..af4cb59 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -135,7 +135,15 @@ config CMD_ARM_CPUINFO
+ default y
+ help
+ Say yes here to get a cpuinfo command to show some
+- information about the cp15 registers
++ CPU information using the cp15 registers
++
++config CMD_ARM_MMUINFO
++ bool "mmuinfo command"
++ depends on CPU_V7
++ default n
++ help
++ Say yes here to get a mmuinfo command to show some
++ MMU and cache information using the cp15 registers
+
+ config CPU_V7_DCACHE_SKIP
+ bool "Skip DCache Invalidate"
+diff --git a/arch/arm/Makefile b/arch/arm/Makefile
+index bd684dc..1225df7 100644
+--- a/arch/arm/Makefile
++++ b/arch/arm/Makefile
+@@ -136,6 +136,7 @@ board-$(CONFIG_MACH_TQMA53) := tqma53
+ board-$(CONFIG_MACH_TX51) := karo-tx51
+ board-$(CONFIG_MACH_MX6Q_ARM2) := freescale-mx6-arm2
+ board-$(CONFIG_MACH_TOSHIBA_AC100) := toshiba-ac100
++board-$(CONFIG_MACH_CCMX51) := ccxmx51
+
+ machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
+
+diff --git a/arch/arm/boards/a9m2410/a9m2410.c b/arch/arm/boards/a9m2410/a9m2410.c
+index eaafdbd..e2044a9 100644
+--- a/arch/arm/boards/a9m2410/a9m2410.c
++++ b/arch/arm/boards/a9m2410/a9m2410.c
+@@ -32,6 +32,7 @@
+ #include <partition.h>
+ #include <nand.h>
+ #include <io.h>
++#include <mach/devices-s3c24xx.h>
+ #include <mach/s3c-iomap.h>
+ #include <mach/s3c24xx-nand.h>
+ #include <mach/s3c-generic.h>
+@@ -109,8 +110,7 @@ static int a9m2410_devices_init(void)
+ writel(reg, S3C_MISCCR);
+
+ /* ----------- the devices the boot loader should work with -------- */
+- add_generic_device("s3c24x0_nand", DEVICE_ID_DYNAMIC, NULL, S3C24X0_NAND_BASE,
+- 0, IORESOURCE_MEM, &nand_info);
++ s3c24xx_add_nand(&nand_info);
+ /*
+ * SMSC 91C111 network controller on the baseboard
+ * connected to CS line 1 and interrupt line
+@@ -145,8 +145,7 @@ void __bare_init nand_boot(void)
+
+ static int a9m2410_console_init(void)
+ {
+- add_generic_device("s3c_serial", DEVICE_ID_DYNAMIC, NULL, S3C_UART1_BASE,
+- S3C_UART1_SIZE, IORESOURCE_MEM, NULL);
++ s3c24xx_add_uart1();
+ return 0;
+ }
+
+diff --git a/arch/arm/boards/a9m2440/a9m2440.c b/arch/arm/boards/a9m2440/a9m2440.c
+index 1d20248..8975c15 100644
+--- a/arch/arm/boards/a9m2440/a9m2440.c
++++ b/arch/arm/boards/a9m2440/a9m2440.c
+@@ -32,6 +32,7 @@
+ #include <partition.h>
+ #include <nand.h>
+ #include <io.h>
++#include <mach/devices-s3c24xx.h>
+ #include <mach/s3c-iomap.h>
+ #include <mach/s3c24xx-nand.h>
+ #include <mach/s3c-generic.h>
+@@ -129,8 +130,7 @@ static int a9m2440_devices_init(void)
+ writel(reg, S3C_MISCCR);
+
+ /* ----------- the devices the boot loader should work with -------- */
+- add_generic_device("s3c24x0_nand", DEVICE_ID_DYNAMIC, NULL, S3C24X0_NAND_BASE, 0,
+- IORESOURCE_MEM, &nand_info);
++ s3c24xx_add_nand(&nand_info);
+ /*
+ * cs8900 network controller onboard
+ * Connected to CS line 5 + A24 and interrupt line EINT9,
+@@ -164,8 +164,7 @@ void __bare_init nand_boot(void)
+
+ static int a9m2440_console_init(void)
+ {
+- add_generic_device("s3c_serial", DEVICE_ID_DYNAMIC, NULL, S3C_UART1_BASE,
+- S3C_UART1_SIZE, IORESOURCE_MEM, NULL);
++ s3c24xx_add_uart1();
+ return 0;
+ }
+
+diff --git a/arch/arm/boards/ccxmx51/Makefile b/arch/arm/boards/ccxmx51/Makefile
+new file mode 100644
+index 0000000..249927e
+--- /dev/null
++++ b/arch/arm/boards/ccxmx51/Makefile
+@@ -0,0 +1,2 @@
++obj-y += flash_header.o ccxmx51.o
++obj-$(CONFIG_MACH_CCMX51_BASEBOARD) += ccxmx51js.o
+diff --git a/arch/arm/boards/ccxmx51/ccxmx51.c b/arch/arm/boards/ccxmx51/ccxmx51.c
+new file mode 100644
+index 0000000..f494174
+--- /dev/null
++++ b/arch/arm/boards/ccxmx51/ccxmx51.c
+@@ -0,0 +1,489 @@
++/*
++ * (C) Copyright 2009-2010 Digi International, Inc.
++ * Copyright (C) 2007 Sascha Hauer, Pengutronix
++ * (c) 2011 Eukrea Electromatique, Eric BĂ©nard <eric@eukrea.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <net.h>
++#include <init.h>
++#include <environment.h>
++#include <mach/imx-regs.h>
++#include <fec.h>
++#include <mach/gpio.h>
++#include <asm/armlinux.h>
++#include <generated/mach-types.h>
++#include <partition.h>
++#include <fs.h>
++#include <fcntl.h>
++#include <sizes.h>
++#include <nand.h>
++#include <notifier.h>
++#include <spi/spi.h>
++#include <mfd/mc13xxx.h>
++#include <asm/io.h>
++#include <mach/imx-nand.h>
++#include <mach/spi.h>
++#include <mach/generic.h>
++#include <mach/iomux-mx51.h>
++#include <mach/devices-imx51.h>
++#include <mach/iim.h>
++#include <mach/clock-imx51_53.h>
++#include <mach/imx5.h>
++
++#include "ccxmx51.h"
++
++static struct ccxmx51_ident ccxmx51_ids[] = {
++/* 0x00 */ { "Unknown", 0, 0, 0, 0, 0 },
++/* 0x01 */ { "Not supported", 0, 0, 0, 0, 0 },
++/* 0x02 */ { "i.MX515@800MHz, Wireless, PHY, Ext. Eth, Accel", SZ_512M, 0, 1, 1, 1 },
++/* 0x03 */ { "i.MX515@800MHz, PHY, Ext. Eth, Accel", SZ_512M, 0, 1, 1, 0 },
++/* 0x04 */ { "i.MX515@600MHz, Wireless, PHY, Ext. Eth, Accel", SZ_512M, 1, 1, 1, 1 },
++/* 0x05 */ { "i.MX515@600MHz, PHY, Ext. Eth, Accel", SZ_512M, 1, 1, 1, 0 },
++/* 0x06 */ { "i.MX515@800MHz, Wireless, PHY, Accel", SZ_512M, 0, 1, 0, 1 },
++/* 0x07 */ { "i.MX515@800MHz, PHY, Accel", SZ_512M, 0, 1, 0, 0 },
++/* 0x08 */ { "i.MX515@800MHz, Wireless, PHY, Accel", SZ_256M, 0, 1, 0, 1 },
++/* 0x09 */ { "i.MX515@800MHz, PHY, Accel", SZ_256M, 0, 1, 0, 0 },
++/* 0x0a */ { "i.MX515@600MHz, Wireless, PHY, Accel", SZ_256M, 1, 1, 0, 1 },
++/* 0x0b */ { "i.MX515@600MHz, PHY, Accel", SZ_256M, 1, 1, 0, 0 },
++/* 0x0c */ { "i.MX515@800MHz, Wireless, PHY, Accel", SZ_128M, 0, 1, 0, 1 },
++/* 0x0d */ { "i.MX512@800MHz", SZ_128M, 0, 0, 0, 0 },
++/* 0x0e */ { "i.MX515@800MHz, Wireless, PHY, Accel", SZ_512M, 0, 1, 0, 1 },
++/* 0x0f */ { "i.MX515@600MHz, PHY, Accel", SZ_128M, 1, 1, 0, 0 },
++/* 0x10 */ { "i.MX515@600MHz, Wireless, PHY, Accel", SZ_128M, 1, 1, 0, 1 },
++/* 0x11 */ { "i.MX515@800MHz, PHY, Accel", SZ_128M, 0, 1, 0, 0 },
++/* 0x12 */ { "i.MX515@600MHz, Wireless, PHY, Accel", SZ_512M, 1, 1, 0, 1 },
++/* 0x13 */ { "i.MX515@800MHz, PHY, Accel", SZ_512M, 0, 1, 0, 0 },
++};
++
++struct ccxmx51_ident *ccxmx51_id;
++
++struct imx_nand_platform_data nand_info = {
++ .width = 1,
++ .hw_ecc = 1,
++ .flash_bbt = 1,
++};
++
++#ifdef CONFIG_DRIVER_NET_FEC_IMX
++static struct fec_platform_data fec_info = {
++ .xcv_type = MII100,
++ .phy_addr = 7,
++};
++#endif
++
++static iomux_v3_cfg_t ccxmx51_pads[] = {
++ /* UART1 */
++ MX51_PAD_UART1_RXD__UART1_RXD,
++ MX51_PAD_UART1_TXD__UART1_TXD,
++ /* UART2 */
++ MX51_PAD_UART2_RXD__UART2_RXD,
++ MX51_PAD_UART2_TXD__UART2_TXD,
++ /* UART3 */
++ MX51_PAD_UART3_RXD__UART3_RXD,
++ MX51_PAD_UART3_TXD__UART3_TXD,
++ /* I2C2 */
++ MX51_PAD_GPIO1_2__I2C2_SCL,
++ MX51_PAD_GPIO1_3__I2C2_SDA,
++ /* eCSPI1 */
++ MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI,
++ MX51_PAD_CSPI1_MISO__ECSPI1_MISO,
++ MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
++ MX51_PAD_CSPI1_RDY__ECSPI1_RDY,
++ MX51_PAD_CSPI1_SS0__ECSPI1_SS0,
++ MX51_PAD_CSPI1_SS1__ECSPI1_SS1,
++ /* FEC */
++ MX51_PAD_DISP2_DAT14__FEC_RDATA0,
++ MX51_PAD_DI2_DISP_CLK__FEC_RDATA1,
++ MX51_PAD_DI_GP4__FEC_RDATA2,
++ MX51_PAD_DISP2_DAT0__FEC_RDATA3,
++ MX51_PAD_DISP2_DAT15__FEC_TDATA0,
++ MX51_PAD_DISP2_DAT6__FEC_TDATA1,
++ MX51_PAD_DISP2_DAT7__FEC_TDATA2,
++ MX51_PAD_DISP2_DAT8__FEC_TDATA3,
++ MX51_PAD_DISP2_DAT9__FEC_TX_EN,
++ MX51_PAD_DISP2_DAT10__FEC_COL,
++ MX51_PAD_DISP2_DAT11__FEC_RX_CLK,
++ MX51_PAD_DISP2_DAT12__FEC_RX_DV,
++ MX51_PAD_DISP2_DAT13__FEC_TX_CLK,
++ MX51_PAD_DI2_PIN2__FEC_MDC,
++ MX51_PAD_DI2_PIN4__FEC_CRS,
++ MX51_PAD_DI2_PIN3__FEC_MDIO,
++ MX51_PAD_DI_GP3__FEC_TX_ER,
++ MX51_PAD_DISP2_DAT1__FEC_RX_ER,
++ /* WEIM */
++ MX51_PAD_EIM_DA0__EIM_DA0,
++ MX51_PAD_EIM_DA1__EIM_DA1,
++ MX51_PAD_EIM_DA2__EIM_DA2,
++ MX51_PAD_EIM_DA3__EIM_DA3,
++ MX51_PAD_EIM_DA4__EIM_DA4,
++ MX51_PAD_EIM_DA5__EIM_DA5,
++ MX51_PAD_EIM_DA6__EIM_DA6,
++ MX51_PAD_EIM_DA7__EIM_DA7,
++ MX51_PAD_EIM_D16__EIM_D16,
++ MX51_PAD_EIM_D17__EIM_D17,
++ MX51_PAD_EIM_D18__EIM_D18,
++ MX51_PAD_EIM_D19__EIM_D19,
++ MX51_PAD_EIM_D20__EIM_D20,
++ MX51_PAD_EIM_D21__EIM_D21,
++ MX51_PAD_EIM_D22__EIM_D22,
++ MX51_PAD_EIM_D23__EIM_D23,
++ MX51_PAD_EIM_D24__EIM_D24,
++ MX51_PAD_EIM_D25__EIM_D25,
++ MX51_PAD_EIM_D26__EIM_D26,
++ MX51_PAD_EIM_D27__EIM_D27,
++ MX51_PAD_EIM_D28__EIM_D28,
++ MX51_PAD_EIM_D29__EIM_D29,
++ MX51_PAD_EIM_D30__EIM_D30,
++ MX51_PAD_EIM_D31__EIM_D31,
++ MX51_PAD_EIM_OE__EIM_OE,
++ MX51_PAD_EIM_CS5__EIM_CS5,
++ /* NAND */
++ MX51_PAD_NANDF_D0__NANDF_D0,
++ MX51_PAD_NANDF_D1__NANDF_D1,
++ MX51_PAD_NANDF_D2__NANDF_D2,
++ MX51_PAD_NANDF_D3__NANDF_D3,
++ MX51_PAD_NANDF_D4__NANDF_D4,
++ MX51_PAD_NANDF_D5__NANDF_D5,
++ MX51_PAD_NANDF_D6__NANDF_D6,
++ MX51_PAD_NANDF_D7__NANDF_D7,
++ MX51_PAD_NANDF_ALE__NANDF_ALE,
++ MX51_PAD_NANDF_CLE__NANDF_CLE,
++ MX51_PAD_NANDF_RE_B__NANDF_RE_B,
++ MX51_PAD_NANDF_WE_B__NANDF_WE_B,
++ MX51_PAD_NANDF_WP_B__NANDF_WP_B,
++ MX51_PAD_NANDF_CS0__NANDF_CS0,
++ MX51_PAD_NANDF_RB0__NANDF_RB0,
++ /* LAN9221 IRQ (GPIO1.9) */
++ MX51_PAD_GPIO1_9__GPIO1_9,
++ /* MC13892 IRQ (GPIO1.5) */
++ MX51_PAD_GPIO1_5__GPIO1_5,
++ /* MMA7455LR IRQ1 (GPIO1.7) */
++ MX51_PAD_GPIO1_7__GPIO1_7,
++ /* MMA7455LR IRQ2 (GPIO1.6) */
++ MX51_PAD_GPIO1_6__GPIO1_6,
++};
++
++#define CCXMX51_ECSPI1_CS0 IMX_GPIO_NR(4, 24)
++#define CCXMX51_ECSPI1_CS1 IMX_GPIO_NR(4, 25)
++
++static int ecspi_0_cs[] = { CCXMX51_ECSPI1_CS0, CCXMX51_ECSPI1_CS1, };
++
++static struct spi_imx_master ecspi_0_data = {
++ .chipselect = ecspi_0_cs,
++ .num_chipselect = ARRAY_SIZE(ecspi_0_cs),
++};
++
++static const struct spi_board_info ccxmx51_spi_board_info[] = {
++ {
++ .name = "mc13xxx-spi",
++ .max_speed_hz = 6000000,
++ .bus_num = 0,
++ .chip_select = 0,
++ },
++};
++
++static int ccxmx51_mem_init(void)
++{
++ /* Add minimal SDRAM first */
++ arm_add_mem_device("ram0", MX51_CSD0_BASE_ADDR, SZ_128M);
++
++ return 0;
++}
++mem_initcall(ccxmx51_mem_init);
++
++static void ccxmx51_otghost_init(void)
++{
++#define MX51_USBOTHER_REGS_OFFSET 0x800
++#define MX51_USBCTRL_OFFSET 0x0
++#define MX51_USB_PHY_CTR_FUNC_OFFSET 0x8
++#define MX51_USB_PHY_CTR_FUNC2_OFFSET 0xc
++#define MX51_USB_UTMI_PHYCTRL1_PLLDIV_MASK 0x3
++#define MX51_USB_PLL_DIV_19_2_MHZ 0x00
++#define MX51_USB_PLL_DIV_24_MHZ 0x01
++#define MX51_USB_PLL_DIV_26_MHZ 0x02
++#define MX51_USB_PLL_DIV_27_MHZ 0x03
++#define MX51_OTG_PHYCTRL_OC_DIS_BIT (1 << 8)
++#define MX51_OTG_UCTRL_OWIE_BIT (1 << 27)
++#define MX51_OTG_UCTRL_OPM_BIT (1 << 24)
++
++#define USBOTHER_BASE (MX51_OTG_BASE_ADDR + MX51_USBOTHER_REGS_OFFSET)
++
++ u32 reg;
++
++ /* Set sysclock to 24 MHz */
++ reg = readl(USBOTHER_BASE + MX51_USB_PHY_CTR_FUNC2_OFFSET);
++ reg &= ~MX51_USB_UTMI_PHYCTRL1_PLLDIV_MASK;
++ reg |= MX51_USB_PLL_DIV_24_MHZ;
++ writel(reg, USBOTHER_BASE + MX51_USB_PHY_CTR_FUNC2_OFFSET);
++
++ /* OC is not used */
++ reg = readl(USBOTHER_BASE + MX51_USB_PHY_CTR_FUNC_OFFSET);
++ reg |= MX51_OTG_PHYCTRL_OC_DIS_BIT;
++ writel(reg, USBOTHER_BASE + MX51_USB_PHY_CTR_FUNC_OFFSET);
++
++ /* Power pins enable */
++ reg = readl(USBOTHER_BASE + MX51_USBCTRL_OFFSET);
++ reg |= MX51_OTG_UCTRL_OWIE_BIT | MX51_OTG_UCTRL_OPM_BIT;
++ writel(reg, USBOTHER_BASE + MX51_USBCTRL_OFFSET);
++
++ /* Setup PORTSC */
++ reg = readl(MX51_OTG_BASE_ADDR + 0x184);
++ reg &= ~(3 << 30);
++ reg |= 1 << 28;
++ writel(reg, MX51_OTG_BASE_ADDR + 0x184);
++
++ mdelay(10);
++
++ add_generic_usb_ehci_device(0, MX51_OTG_BASE_ADDR, NULL);
++}
++
++static int ccxmx51_power_init(void)
++{
++ struct mc13xxx *mc13xxx_dev;
++ u32 val;
++
++ mc13xxx_dev = mc13xxx_get();
++ if (!mc13xxx_dev)
++ return -ENODEV;
++
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_POWER_MISC, &val);
++ /* Reset devices by clearing GP01-GPO4 */
++ val &= ~((1 << 21) | (3 << 12) | (3 << 10) | (3 << 8) | (3 << 6));
++ /* Switching off the PWGT1SPIEN */
++ val |= (1 << 15);
++ /* Switching on the PWGT2SPIEN */
++ val &= ~(1 << 16);
++ /* Enable short circuit protection */
++ val |= (1 << 0);
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_POWER_MISC, val);
++
++ /* Allow charger to charge (4.2V and 560mA) */
++ val = 0x238033;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_CHARGE, val);
++
++ /* Set core voltage (SW1) to 1.1V */
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_SW_0, &val);
++ val &= ~0x00001f;
++ val |= 0x000014;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_SW_0, val);
++
++ if (imx_silicon_revision() < IMX_CHIP_REV_3_0) {
++ /* Setup VCC (SW2) to 1.25 */
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_SW_1, &val);
++ val &= ~0x00001f;
++ val |= 0x00001a;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_SW_1, val);
++
++ /* Setup 1V2_DIG1 (SW3) to 1.25 */
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_SW_2, &val);
++ val &= ~0x00001f;
++ val |= 0x00001a;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_SW_2, val);
++ } else {
++ /* Setup VCC (SW2) to 1.225 */
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_SW_1, &val);
++ val &= ~0x00001f;
++ val |= 0x000019;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_SW_1, val);
++
++ /* Setup 1V2_DIG1 (SW3) to 1.2 */
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_SW_2, &val);
++ val &= ~0x00001f;
++ val |= 0x000018;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_SW_2, val);
++ }
++
++ if (mc13xxx_dev->revision <= MC13892_REVISION_2_0) {
++ /* Set switchers in PWM mode for Atlas 2.0 and lower */
++ /* Setup the switcher mode for SW1 & SW2*/
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_SW_4, &val);
++ val &= ~0x003c0f;
++ val |= 0x001405;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_SW_4, val);
++
++ /* Setup the switcher mode for SW3 & SW4 */
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_SW_5, &val);
++ val &= ~0x000f0f;
++ val |= 0x000505;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_SW_5, val);
++ } else {
++ /* Set switchers in Auto in NORMAL mode & STANDBY mode for Atlas 2.0a */
++ /* Setup the switcher mode for SW1 & SW2*/
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_SW_4, &val);
++ val &= ~0x003c0f;
++ val |= 0x002008;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_SW_4, val);
++
++ /* Setup the switcher mode for SW3 & SW4 */
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_SW_5, &val);
++ val &= ~0x000f0f;
++ val |= 0x000808;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_SW_5, val);
++ }
++
++ /* Set VVIDEO to 2.775V, VAUDIO to 3V, VSD to 3.15V */
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_SETTING_1, &val);
++ val &= ~0x0001fc;
++ val |= 0x0001f4;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_SETTING_1, val);
++
++ /* Configure VGEN3 and VCAM regulators to use external PNP */
++ val = 0x000208;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_MODE_1, val);
++ udelay(200);
++
++ /* Set VGEN3 to 1.8V */
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_SETTING_0, &val);
++ val &= ~(1 << 14);
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_SETTING_0, val);
++
++ /* Enable VGEN3, VCAM, VAUDIO, VVIDEO, VSD regulators */
++ val = 0x049249;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_MODE_1, val);
++
++ /* Enable USB1 charger */
++ val = 0x000409;
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_USB1, val);
++
++ /* Set VCOIN to 3.0V and Enable It */
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_POWER_CTL0, &val);
++ val &= ~(7 << 20);
++ val |= (4 << 20) | (1 << 23);
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_POWER_CTL0, val);
++ /* Keeps VSRTC and CLK32KMCU */
++ val |= (1 << 4);
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_POWER_CTL0, val);
++
++ /* De-assert reset of external devices on GP01, GPO2, GPO3 and GPO4 */
++ mc13xxx_reg_read(mc13xxx_dev, MC13892_REG_POWER_MISC, &val);
++ /* GPO1 - External */
++ /* GP02 - LAN9221 */
++ /* GP03 - FEC */
++ /* GP04 - Wireless */
++ if (IS_ENABLED(CONFIG_DRIVER_NET_SMC911X) && ccxmx51_id->eth0)
++ val |= (1 << 8);
++ if (IS_ENABLED(CONFIG_DRIVER_NET_FEC_IMX) && ccxmx51_id->eth1)
++ val |= (1 << 10);
++ if (ccxmx51_id->wless)
++ val |= (1 << 12);
++ mc13xxx_reg_write(mc13xxx_dev, MC13892_REG_POWER_MISC, val);
++
++ udelay(100);
++
++ return 0;
++}
++
++static int ccxmx51_devices_init(void)
++{
++ u8 hwid[6];
++ int pwr;
++ char manloc;
++
++ if ((imx_iim_read(1, 9, hwid, sizeof(hwid)) != sizeof(hwid)) || (hwid[0] < 0x02) || (hwid[0] >= ARRAY_SIZE(ccxmx51_ids)))
++ memset(hwid, 0x00, sizeof(hwid));
++
++ ccxmx51_id = &ccxmx51_ids[hwid[0]];
++ printf("Module Variant: %s (0x%02x)\n", ccxmx51_id->id_string, hwid[0]);
++
++ if (hwid[0]) {
++ printf("Module HW Rev : %02x\n", hwid[1]);
++ switch (hwid[2] & 0xc0) {
++ case 0x00:
++ manloc = 'B';
++ break;
++ case 0x40:
++ manloc = 'W';
++ break;
++ case 0x80:
++ manloc = 'S';
++ break;
++ default:
++ manloc = 'N';
++ break;
++ }
++ printf("Module Serial : %c%d\n", manloc, ((hwid[2] & 0x3f) << 24) | (hwid[3] << 16) | (hwid[4] << 8) | hwid[5]);
++ if ((ccxmx51_id->mem_sz - SZ_128M) > 0)
++ arm_add_mem_device("ram1", MX51_CSD0_BASE_ADDR + SZ_128M, ccxmx51_id->mem_sz - SZ_128M);
++ }
++
++ imx51_add_uart1();
++ imx51_add_uart2();
++
++ spi_register_board_info(ccxmx51_spi_board_info, ARRAY_SIZE(ccxmx51_spi_board_info));
++ imx51_add_spi0(&ecspi_0_data);
++
++ pwr = ccxmx51_power_init();
++ console_flush();
++ imx51_init_lowlevel((ccxmx51_id->industrial || pwr) ? 600 : 800);
++ clock_notifier_call_chain();
++ if (pwr)
++ printf("Could not setup PMIC. Clocks not adjusted.\n");
++
++ imx51_add_i2c1(NULL);
++
++ imx51_add_nand(&nand_info);
++ devfs_add_partition("nand0", 0x00000, 0x80000, DEVFS_PARTITION_FIXED, "self_raw");
++ dev_add_bb_dev("self_raw", "self0");
++ devfs_add_partition("nand0", 0x80000, 0x40000, DEVFS_PARTITION_FIXED, "env_raw");
++ dev_add_bb_dev("env_raw", "env0");
++
++#ifdef CONFIG_DRIVER_NET_FEC_IMX
++ if (ccxmx51_id->eth0 && !pwr) {
++ imx51_add_fec(&fec_info);
++ eth_register_ethaddr(0, hwid);
++ }
++#endif
++
++#ifdef CONFIG_DRIVER_NET_SMC911X
++ if (ccxmx51_id->eth1 && !pwr) {
++ /* Configure the WEIM CS5 timming, bus width, etc */
++ /* 16 bit on DATA[31..16], not multiplexed, async */
++ writel(0x00420081, MX51_WEIM_BASE_ADDR + WEIM_CSxGCR1(5));
++ /* ADH has not effect on non muxed bus */
++ writel(0, MX51_WEIM_BASE_ADDR + WEIM_CSxGCR2(5));
++ /* RWSC=50, RADVA=2, RADVN=6, OEA=0, OEN=0, RCSA=0, RCSN=0 */
++ writel(0x32260000, MX51_WEIM_BASE_ADDR + WEIM_CSxRCR1(5));
++ /* APR=0 */
++ writel(0, MX51_WEIM_BASE_ADDR + WEIM_CSxRCR2(5));
++ /* WAL=0, WBED=1, WWSC=50, WADVA=2, WADVN=6, WEA=0, WEN=0, WCSA=0 */
++ writel(0x72080f00, MX51_WEIM_BASE_ADDR + WEIM_CSxWCR1(5));
++
++ /* LAN9221 network controller */
++ add_generic_device("smc911x", 1, NULL, MX51_CS5_BASE_ADDR, SZ_4K, IORESOURCE_MEM, NULL);
++ }
++#endif
++
++ ccxmx51_otghost_init();
++
++ armlinux_set_bootparams((void *)(MX51_CSD0_BASE_ADDR + 0x100));
++
++ armlinux_set_architecture(ccxmx51_id->wless ? MACH_TYPE_CCWMX51 : MACH_TYPE_CCMX51);
++
++ return 0;
++}
++device_initcall(ccxmx51_devices_init);
++
++static int ccxmx51_console_init(void)
++{
++ mxc_iomux_v3_setup_multiple_pads(ccxmx51_pads, ARRAY_SIZE(ccxmx51_pads));
++
++ imx51_add_uart0();
++
++ return 0;
++}
++console_initcall(ccxmx51_console_init);
+diff --git a/arch/arm/boards/ccxmx51/ccxmx51.dox b/arch/arm/boards/ccxmx51/ccxmx51.dox
+new file mode 100644
+index 0000000..cc28e8d
+--- /dev/null
++++ b/arch/arm/boards/ccxmx51/ccxmx51.dox
+@@ -0,0 +1,7 @@
++/** @page ccxmx51 Digi ConnectCore board
++
++This boards is based on a Freescale i.MX51 CPU. The board is shipped with:
++- Up to 8 GB NAND Flash.
++- Up to 512 MB DDR2 RAM.
++
++*/
+diff --git a/arch/arm/boards/ccxmx51/ccxmx51.h b/arch/arm/boards/ccxmx51/ccxmx51.h
+new file mode 100644
+index 0000000..3feacac
+--- /dev/null
++++ b/arch/arm/boards/ccxmx51/ccxmx51.h
+@@ -0,0 +1,35 @@
++/*
++ * Copyright 2010 Digi International Inc. All Rights Reserved.
++ */
++
++/*
++ * The code contained herein is licensed under the GNU General Public
++ * License. You may obtain a copy of the GNU General Public License
++ * Version 2 or later at the following locations:
++ *
++ * http://www.opensource.org/licenses/gpl-license.html
++ * http://www.gnu.org/copyleft/gpl.html
++ */
++
++#ifndef _CCXMX51_H_
++#define _CCXMX51_H_
++
++struct ccxmx51_hwid {
++ u8 variant;
++ u8 version;
++ u32 sn;
++ char mloc;
++};
++
++struct ccxmx51_ident {
++ const char *id_string;
++ const int mem_sz;
++ const char industrial;
++ const char eth0;
++ const char eth1;
++ const char wless;
++};
++
++extern struct ccxmx51_ident *ccxmx51_id;
++
++#endif /* _CCXMX51_H_ */
+diff --git a/arch/arm/boards/ccxmx51/ccxmx51js.c b/arch/arm/boards/ccxmx51/ccxmx51js.c
+new file mode 100644
+index 0000000..f04615d
+--- /dev/null
++++ b/arch/arm/boards/ccxmx51/ccxmx51js.c
+@@ -0,0 +1,90 @@
++/*
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <io.h>
++#include <init.h>
++#include <mci.h>
++#include <asm/armlinux.h>
++#include <mach/imx-regs.h>
++#include <mach/iomux-mx51.h>
++#include <mach/devices-imx51.h>
++#include <generated/mach-types.h>
++
++#include "ccxmx51.h"
++
++static iomux_v3_cfg_t ccxmx51js_pads[] = {
++ /* SD1 */
++ MX51_PAD_SD1_CLK__SD1_CLK,
++ MX51_PAD_SD1_CMD__SD1_CMD,
++ MX51_PAD_SD1_DATA0__SD1_DATA0,
++ MX51_PAD_SD1_DATA1__SD1_DATA1,
++ MX51_PAD_SD1_DATA2__SD1_DATA2,
++ MX51_PAD_SD1_DATA3__SD1_DATA3,
++ /* SD3 */
++ MX51_PAD_NANDF_CS7__SD3_CLK,
++ MX51_PAD_NANDF_RDY_INT__SD3_CMD,
++ MX51_PAD_NANDF_D8__SD3_DATA0,
++ MX51_PAD_NANDF_D9__SD3_DATA1,
++ MX51_PAD_NANDF_D10__SD3_DATA2,
++ MX51_PAD_NANDF_D11__SD3_DATA3,
++ MX51_PAD_NANDF_D12__SD3_DAT4,
++ MX51_PAD_NANDF_D13__SD3_DAT5,
++ MX51_PAD_NANDF_D14__SD3_DAT6,
++ MX51_PAD_NANDF_D15__SD3_DAT7,
++ /* USB HOST1 */
++ MX51_PAD_USBH1_CLK__USBH1_CLK,
++ MX51_PAD_USBH1_DIR__USBH1_DIR,
++ MX51_PAD_USBH1_NXT__USBH1_NXT,
++ MX51_PAD_USBH1_STP__USBH1_STP,
++ MX51_PAD_USBH1_DATA0__USBH1_DATA0,
++ MX51_PAD_USBH1_DATA1__USBH1_DATA1,
++ MX51_PAD_USBH1_DATA2__USBH1_DATA2,
++ MX51_PAD_USBH1_DATA3__USBH1_DATA3,
++ MX51_PAD_USBH1_DATA4__USBH1_DATA4,
++ MX51_PAD_USBH1_DATA5__USBH1_DATA5,
++ MX51_PAD_USBH1_DATA6__USBH1_DATA6,
++ MX51_PAD_USBH1_DATA7__USBH1_DATA7,
++};
++
++static struct esdhc_platform_data sdhc1_pdata = {
++ .cd_type = ESDHC_CD_NONE,
++ .wp_type = ESDHC_WP_NONE,
++ .caps = MMC_MODE_4BIT,
++};
++
++static struct esdhc_platform_data sdhc3_pdata = {
++ .cd_type = ESDHC_CD_NONE,
++ .wp_type = ESDHC_WP_NONE,
++ .caps = MMC_MODE_4BIT | MMC_MODE_8BIT,
++};
++
++static int ccxmx51js_init(void)
++{
++ mxc_iomux_v3_setup_multiple_pads(ccxmx51js_pads, ARRAY_SIZE(ccxmx51js_pads));
++
++ if (IS_ENABLED(CONFIG_MCI_IMX_ESDHC)) {
++ imx51_add_mmc0(&sdhc1_pdata);
++ imx51_add_mmc2(&sdhc3_pdata);
++ }
++
++ armlinux_set_architecture(ccxmx51_id->wless ? MACH_TYPE_CCWMX51JS : MACH_TYPE_CCMX51JS);
++
++ return 0;
++}
++
++late_initcall(ccxmx51js_init);
+diff --git a/arch/arm/boards/ccxmx51/config.h b/arch/arm/boards/ccxmx51/config.h
+new file mode 100644
+index 0000000..fdf2f81
+--- /dev/null
++++ b/arch/arm/boards/ccxmx51/config.h
+@@ -0,0 +1,24 @@
++/**
++ * @file
++ * @brief Global defintions for the ARM i.MX51 based ccmx51 board
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#endif /* __CONFIG_H */
+diff --git a/arch/arm/boards/ccxmx51/env/config b/arch/arm/boards/ccxmx51/env/config
+new file mode 100644
+index 0000000..bbd43e7
+--- /dev/null
++++ b/arch/arm/boards/ccxmx51/env/config
+@@ -0,0 +1,37 @@
++#!/bin/sh
++
++machine=ccmx51
++
++# use 'dhcp' to do dhcp in barebox and in kernel
++# use 'none' if you want to skip kernel ip autoconfiguration
++ip=none
++
++# or set your networking parameters here
++#eth0.ipaddr=a.b.c.d
++#eth0.netmask=a.b.c.d
++#eth0.gateway=a.b.c.d
++#eth0.serverip=a.b.c.d
++
++# can be either 'nfs', 'tftp' or 'nand'
++kernel_loc=nand
++# can be either 'net', 'nand' or 'initrd'
++rootfs_loc=nand
++
++# rootfs
++rootfs_type=cramfs
++
++# kernel
++kernelimage_type=zimage
++kernel_img=/dev/nand0.kernel
++
++autoboot_timeout=3
++
++bootargs="console=ttymxc0,115200"
++
++device_type="nand"
++nand_device="mxc_nand"
++nand_parts="512k(barebox)ro,256k(bareboxenv),3328k(kernel),-(root)"
++rootfs_mtdblock_nand=3
++
++# set a fancy prompt (if support is compiled in)
++PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m "
+diff --git a/arch/arm/boards/ccxmx51/flash_header.c b/arch/arm/boards/ccxmx51/flash_header.c
+new file mode 100644
+index 0000000..c148eea
+--- /dev/null
++++ b/arch/arm/boards/ccxmx51/flash_header.c
+@@ -0,0 +1,84 @@
++#include <common.h>
++#include <mach/imx-flash-header.h>
++#include <asm/barebox-arm-head.h>
++
++void __naked __flash_header_start go(void)
++{
++ barebox_arm_head();
++}
++
++struct imx_dcd_entry __dcd_entry_section dcd_entry[] = {
++ { .ptr_type = 4, .addr = 0x73fa88a0, .val = 0x00000200, },
++ { .ptr_type = 4, .addr = 0x73fa850c, .val = 0x000020c5, },
++ { .ptr_type = 4, .addr = 0x73fa8510, .val = 0x000020c5, },
++ { .ptr_type = 4, .addr = 0x73fa883c, .val = 0x00000002, },
++ { .ptr_type = 4, .addr = 0x73fa8848, .val = 0x00000002, },
++ { .ptr_type = 4, .addr = 0x73fa84b8, .val = 0x000000e7, },
++ { .ptr_type = 4, .addr = 0x73fa84bc, .val = 0x00000045, },
++ { .ptr_type = 4, .addr = 0x73fa84c0, .val = 0x00000045, },
++ { .ptr_type = 4, .addr = 0x73fa84c4, .val = 0x00000045, },
++ { .ptr_type = 4, .addr = 0x73fa84c8, .val = 0x00000045, },
++ { .ptr_type = 4, .addr = 0x73fa8820, .val = 0x00000000, },
++ { .ptr_type = 4, .addr = 0x73fa84a4, .val = 0x00000003, },
++ { .ptr_type = 4, .addr = 0x73fa84a8, .val = 0x00000003, },
++ { .ptr_type = 4, .addr = 0x73fa84ac, .val = 0x000000e3, },
++ { .ptr_type = 4, .addr = 0x73fa84b0, .val = 0x000000e3, },
++ { .ptr_type = 4, .addr = 0x73fa84b4, .val = 0x000000e3, },
++ { .ptr_type = 4, .addr = 0x73fa84cc, .val = 0x000000e3, },
++ { .ptr_type = 4, .addr = 0x73fa84d0, .val = 0x000000e2, },
++ { .ptr_type = 4, .addr = 0x73fa882c, .val = 0x00000004, },
++ { .ptr_type = 4, .addr = 0x73fa88a4, .val = 0x00000004, },
++ { .ptr_type = 4, .addr = 0x73fa88ac, .val = 0x00000004, },
++ { .ptr_type = 4, .addr = 0x73fa88b8, .val = 0x00000004, },
++ { .ptr_type = 4, .addr = 0x83fd9000, .val = 0x82a20000, },
++ { .ptr_type = 4, .addr = 0x83fd9008, .val = 0x82a20000, },
++ { .ptr_type = 4, .addr = 0x83fd9010, .val = 0x000ad0d0, },
++ { .ptr_type = 4, .addr = 0x83fd9004, .val = 0x3f3584ab, },
++ { .ptr_type = 4, .addr = 0x83fd900c, .val = 0x3f3584ab, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x04008008, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801a, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801b, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00448019, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x07328018, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x04008008, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008010, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008010, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x06328018, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x03808019, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00408019, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008000, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0400800c, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801e, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801f, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801d, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0732801c, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0400800c, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008014, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008014, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0632801c, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0380801d, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0040801d, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008004, },
++ { .ptr_type = 4, .addr = 0x83fd9000, .val = 0xb2a20000, },
++ { .ptr_type = 4, .addr = 0x83fd9008, .val = 0xb2a20000, },
++ { .ptr_type = 4, .addr = 0x83fd9010, .val = 0x000ad6d0, },
++ { .ptr_type = 4, .addr = 0x83fd9034, .val = 0x90000000, },
++ { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00000000, },
++};
++
++#define APP_DEST 0x90000000
++
++struct imx_flash_header __flash_header_section flash_header = {
++ .app_code_jump_vector = APP_DEST + 0x1000,
++ .app_code_barker = APP_CODE_BARKER,
++ .app_code_csf = 0,
++ .dcd_ptr_ptr = APP_DEST + 0x400 + offsetof(struct imx_flash_header, dcd),
++ .super_root_key = 0,
++ .dcd = APP_DEST + 0x400 + offsetof(struct imx_flash_header, dcd_barker),
++ .app_dest = APP_DEST,
++ .dcd_barker = DCD_BARKER,
++ .dcd_block_len = sizeof (dcd_entry),
++};
++
++unsigned long __image_len_section barebox_len = DCD_BAREBOX_SIZE;
++
+diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
+index 38f28be..b40713d 100644
+--- a/arch/arm/boards/chumby_falconwing/falconwing.c
++++ b/arch/arm/boards/chumby_falconwing/falconwing.c
+@@ -316,7 +316,7 @@ static void falconwing_init_usb(void)
+ /* bring USB hub out of reset */
+ gpio_direction_output(GPIO_USB_HUB_RESET, 1);
+
+- imx_usb_phy_enable();
++ imx23_usb_phy_enable();
+
+ add_generic_usb_ehci_device(-1, IMX_USB_BASE, NULL);
+ }
+diff --git a/arch/arm/boards/eukrea_cpuimx51/eukrea_cpuimx51.c b/arch/arm/boards/eukrea_cpuimx51/eukrea_cpuimx51.c
+index 3cc7a72..35c114d 100644
+--- a/arch/arm/boards/eukrea_cpuimx51/eukrea_cpuimx51.c
++++ b/arch/arm/boards/eukrea_cpuimx51/eukrea_cpuimx51.c
+@@ -53,6 +53,11 @@ struct imx_nand_platform_data nand_info = {
+ };
+
+ static iomux_v3_cfg_t eukrea_cpuimx51_pads[] = {
++ /* UART1 */
++ MX51_PAD_UART1_RXD__UART1_RXD,
++ MX51_PAD_UART1_TXD__UART1_TXD,
++ MX51_PAD_UART1_RTS__UART1_RTS,
++ MX51_PAD_UART1_CTS__UART1_CTS,
+ /* FEC */
+ MX51_PAD_DISP2_DAT1__FEC_RX_ER,
+ MX51_PAD_DISP2_DAT15__FEC_TDATA0,
+@@ -141,12 +146,8 @@ static int eukrea_cpuimx51_console_init(void)
+
+ imx51_init_lowlevel(800);
+
+- writel(0, 0x73fa8228);
+- writel(0, 0x73fa822c);
+- writel(0, 0x73fa8230);
+- writel(0, 0x73fa8234);
+-
+ imx51_add_uart0();
++
+ return 0;
+ }
+
+diff --git a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
+index 9168ed8..1283e17 100644
+--- a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
++++ b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c
+@@ -22,17 +22,18 @@
+ #include <init.h>
+ #include <mci.h>
+ #include <io.h>
++#include <net.h>
+
+ #include <mach/clock.h>
+ #include <mach/imx-regs.h>
+ #include <mach/iomux-imx28.h>
+ #include <mach/mci.h>
++#include <mach/fb.h>
++#include <mach/ocotp.h>
+
+ #include <asm/armlinux.h>
+ #include <asm/mmu.h>
+
+-#include <mach/fb.h>
+-
+ #include <generated/mach-types.h>
+
+ #define MX28EVK_FEC_PHY_RESET_GPIO 141
+@@ -118,6 +119,27 @@ static struct mxs_mci_platform_data mci_pdata = {
+ };
+
+ /* fec */
++static void mx28_evk_get_ethaddr(void)
++{
++ u8 mac_ocotp[3], mac[6];
++ int ret;
++
++ ret = mxs_ocotp_read(mac_ocotp, 3, 0);
++ if (ret != 3) {
++ pr_err("Reading MAC from OCOTP failed!\n");
++ return;
++ }
++
++ mac[0] = 0x00;
++ mac[1] = 0x04;
++ mac[2] = 0x9f;
++ mac[3] = mac_ocotp[2];
++ mac[4] = mac_ocotp[1];
++ mac[5] = mac_ocotp[0];
++
++ eth_register_ethaddr(0, mac);
++}
++
+ static void __init mx28_evk_fec_reset(void)
+ {
+ mdelay(1);
+@@ -208,6 +230,10 @@ static int mx28_evk_devices_init(void)
+ add_generic_device("stmfb", 0, NULL, IMX_FB_BASE, 4096,
+ IORESOURCE_MEM, &mx28_evk_fb_pdata);
+
++ add_generic_device("ocotp", 0, NULL, IMX_OCOTP_BASE, 0,
++ IORESOURCE_MEM, NULL);
++ mx28_evk_get_ethaddr(); /* must be after registering ocotp */
++
+ imx_enable_enetclk();
+ mx28_evk_fec_reset();
+ add_generic_device("fec_imx", 0, NULL, IMX_FEC0_BASE, 0,
+diff --git a/arch/arm/boards/freescale-mx51-pdk/board.c b/arch/arm/boards/freescale-mx51-pdk/board.c
+index 0bb2ffe..3a568d0 100644
+--- a/arch/arm/boards/freescale-mx51-pdk/board.c
++++ b/arch/arm/boards/freescale-mx51-pdk/board.c
+@@ -48,6 +48,12 @@ static struct fec_platform_data fec_info = {
+ };
+
+ static iomux_v3_cfg_t f3s_pads[] = {
++ /* UART1 */
++ MX51_PAD_UART1_RXD__UART1_RXD,
++ MX51_PAD_UART1_TXD__UART1_TXD,
++ MX51_PAD_UART1_RTS__UART1_RTS,
++ MX51_PAD_UART1_CTS__UART1_CTS,
++ /* FEC */
+ MX51_PAD_EIM_EB2__FEC_MDIO,
+ MX51_PAD_EIM_EB3__FEC_RDATA1,
+ MX51_PAD_EIM_CS2__FEC_RDATA2,
+@@ -246,6 +252,7 @@ static int f3s_devices_init(void)
+ imx51_iim_register_fec_ethaddr();
+ imx51_add_fec(&fec_info);
+ imx51_add_mmc0(NULL);
++ imx51_add_mmc1(NULL);
+
+ armlinux_set_bootparams((void *)0x90000100);
+ armlinux_set_architecture(MACH_TYPE_MX51_BABBAGE);
+@@ -268,12 +275,8 @@ static int f3s_console_init(void)
+ {
+ mxc_iomux_v3_setup_multiple_pads(f3s_pads, ARRAY_SIZE(f3s_pads));
+
+- writel(0, 0x73fa8228);
+- writel(0, 0x73fa822c);
+- writel(0, 0x73fa8230);
+- writel(0, 0x73fa8234);
+-
+ imx51_add_uart0();
++
+ return 0;
+ }
+
+diff --git a/arch/arm/boards/mini2440/mini2440.c b/arch/arm/boards/mini2440/mini2440.c
+index 3d3b820..3523949 100644
+--- a/arch/arm/boards/mini2440/mini2440.c
++++ b/arch/arm/boards/mini2440/mini2440.c
+@@ -39,6 +39,7 @@
+ #include <io.h>
+ #include <mach/gpio.h>
+ #include <mach/s3c-iomap.h>
++#include <mach/devices-s3c24xx.h>
+ #include <mach/s3c24xx-nand.h>
+ #include <mach/s3c-generic.h>
+ #include <mach/s3c-mci.h>
+@@ -297,8 +298,7 @@ static int mini2440_devices_init(void)
+ reg |= 0x10000;
+ writel(reg, S3C_MISCCR);
+
+- add_generic_device("s3c24x0_nand", DEVICE_ID_DYNAMIC, NULL, S3C24X0_NAND_BASE,
+- 0, IORESOURCE_MEM, &nand_info);
++ s3c24xx_add_nand(&nand_info);
+
+ add_dm9000_device(0, S3C_CS4_BASE + 0x300, S3C_CS4_BASE + 0x304,
+ IORESOURCE_MEM_16BIT, &dm9000_data);
+@@ -312,12 +312,9 @@ static int mini2440_devices_init(void)
+ devfs_add_partition("nand0", 0x40000, 0x20000, DEVFS_PARTITION_FIXED, "env_raw");
+ dev_add_bb_dev("env_raw", "env0");
+ #endif
+- add_generic_device("s3c_mci", 0, NULL, S3C2410_SDI_BASE, 0,
+- IORESOURCE_MEM, &mci_data);
+- add_generic_device("s3c_fb", 0, NULL, S3C2410_LCD_BASE, 0,
+- IORESOURCE_MEM, &s3c24x0_fb_data);
+- add_generic_device("ohci", 0, NULL, S3C2410_USB_HOST_BASE, 0x100,
+- IORESOURCE_MEM, NULL);
++ s3c24xx_add_mci(&mci_data);
++ s3c24xx_add_fb(&s3c24x0_fb_data);
++ s3c24xx_add_ohci();
+ armlinux_set_bootparams((void*)S3C_SDRAM_BASE + 0x100);
+ armlinux_set_architecture(MACH_TYPE_MINI2440);
+
+@@ -344,8 +341,7 @@ static int mini2440_console_init(void)
+ s3c_gpio_mode(GPH2_TXD0);
+ s3c_gpio_mode(GPH3_RXD0);
+
+- add_generic_device("s3c_serial", DEVICE_ID_DYNAMIC, NULL, S3C_UART1_BASE,
+- S3C_UART1_SIZE, IORESOURCE_MEM, NULL);
++ s3c24xx_add_uart1();
+ return 0;
+ }
+
+diff --git a/arch/arm/boards/nhk8815/setup.c b/arch/arm/boards/nhk8815/setup.c
+index 173892a..ccc0510 100644
+--- a/arch/arm/boards/nhk8815/setup.c
++++ b/arch/arm/boards/nhk8815/setup.c
+@@ -55,15 +55,15 @@ static struct nomadik_nand_platform_data nhk8815_nand_data = {
+ static struct resource nhk8815_nand_resources[] = {
+ {
+ .start = NAND_IO_ADDR,
+- .size = 0xfff,
++ .end = NAND_IO_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = NAND_IO_CMD,
+- .size = 0xfff,
++ .end = NAND_IO_CMD + 0xfff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = NAND_IO_DATA,
+- .size = 0xfff,
++ .end = NAND_IO_CMD + 0xfff,
+ .flags = IORESOURCE_MEM,
+ }
+ };
+diff --git a/arch/arm/boards/pcm038/pcm970.c b/arch/arm/boards/pcm038/pcm970.c
+index ca10afb..df9b852 100644
+--- a/arch/arm/boards/pcm038/pcm970.c
++++ b/arch/arm/boards/pcm038/pcm970.c
+@@ -55,7 +55,7 @@ static void pcm970_usbh2_init(void)
+ static struct resource pcm970_ide_resources[] = {
+ {
+ .start = IMX_PCMCIA_MEM_BASE,
+- .size = SZ_1K,
++ .end = IMX_PCMCIA_MEM_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+diff --git a/arch/arm/configs/at91sam9m10g45ek_defconfig b/arch/arm/configs/at91sam9m10g45ek_defconfig
+index b72e964..e22f80a 100644
+--- a/arch/arm/configs/at91sam9m10g45ek_defconfig
++++ b/arch/arm/configs/at91sam9m10g45ek_defconfig
+@@ -1,5 +1,4 @@
+ CONFIG_ARCH_AT91SAM9G45=y
+-CONFIG_MACH_AT91SAM9M10G45EK=y
+ CONFIG_AEABI=y
+ # CONFIG_CMD_ARM_CPUINFO is not set
+ CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+@@ -75,3 +74,4 @@ CONFIG_LED_TRIGGERS=y
+ CONFIG_FS_FAT=y
+ CONFIG_FS_FAT_WRITE=y
+ CONFIG_FS_FAT_LFN=y
++CONFIG_LZO_DECOMPRESS=y
+diff --git a/arch/arm/configs/ccmx51_defconfig b/arch/arm/configs/ccmx51_defconfig
+new file mode 100644
+index 0000000..d14de55
+--- /dev/null
++++ b/arch/arm/configs/ccmx51_defconfig
+@@ -0,0 +1,55 @@
++CONFIG_ARCH_IMX=y
++CONFIG_ARCH_IMX51=y
++CONFIG_MACH_CCMX51=y
++CONFIG_AEABI=y
++CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
++CONFIG_MALLOC_SIZE=0x2000000
++CONFIG_LONGHELP=y
++CONFIG_GLOB=y
++CONFIG_HUSH_FANCY_PROMPT=y
++CONFIG_CMDLINE_EDITING=y
++CONFIG_AUTO_COMPLETE=y
++CONFIG_PARTITION=y
++CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
++CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/ccxmx51/env"
++CONFIG_CMD_EDIT=y
++CONFIG_CMD_SLEEP=y
++CONFIG_CMD_SAVEENV=y
++CONFIG_CMD_LOADENV=y
++CONFIG_CMD_EXPORT=y
++CONFIG_CMD_PRINTENV=y
++CONFIG_CMD_READLINE=y
++CONFIG_CMD_ECHO_E=y
++CONFIG_CMD_MEMINFO=y
++CONFIG_CMD_MTEST=y
++CONFIG_CMD_FLASH=y
++CONFIG_CMD_BOOTM_ZLIB=y
++CONFIG_CMD_BOOTM_BZLIB=y
++CONFIG_CMD_BOOTM_SHOW_TYPE=y
++CONFIG_CMD_RESET=y
++CONFIG_CMD_GO=y
++CONFIG_CMD_TIMEOUT=y
++CONFIG_CMD_PARTITION=y
++CONFIG_CMD_GPIO=y
++CONFIG_CMD_UNLZO=y
++CONFIG_CMD_I2C=y
++CONFIG_NET=y
++CONFIG_NET_DHCP=y
++CONFIG_NET_PING=y
++CONFIG_NET_TFTP=y
++CONFIG_DRIVER_NET_SMC911X=y
++CONFIG_DRIVER_NET_FEC_IMX=y
++CONFIG_DRIVER_SPI_IMX=y
++CONFIG_I2C=y
++CONFIG_I2C_IMX=y
++CONFIG_MTD=y
++CONFIG_NAND=y
++CONFIG_NAND_IMX=y
++CONFIG_USB=y
++CONFIG_USB_EHCI=y
++CONFIG_MCI=y
++# CONFIG_MCI_WRITE is not set
++CONFIG_MCI_IMX_ESDHC=y
++CONFIG_FS_CRAMFS=y
++CONFIG_FS_FAT=y
++CONFIG_FS_FAT_LFN=y
+diff --git a/arch/arm/configs/eukrea_cpuimx25_defconfig b/arch/arm/configs/eukrea_cpuimx25_defconfig
+index 94ae670..f7207e8 100644
+--- a/arch/arm/configs/eukrea_cpuimx25_defconfig
++++ b/arch/arm/configs/eukrea_cpuimx25_defconfig
+@@ -8,6 +8,7 @@ CONFIG_MMU=y
+ CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
+ CONFIG_MALLOC_SIZE=0x800000
+ CONFIG_EXPERIMENTAL=y
++CONFIG_MALLOC_TLSF=y
+ CONFIG_LONGHELP=y
+ CONFIG_GLOB=y
+ CONFIG_HUSH_FANCY_PROMPT=y
+diff --git a/arch/arm/configs/eukrea_cpuimx35_defconfig b/arch/arm/configs/eukrea_cpuimx35_defconfig
+index a888765..880beb6 100644
+--- a/arch/arm/configs/eukrea_cpuimx35_defconfig
++++ b/arch/arm/configs/eukrea_cpuimx35_defconfig
+@@ -9,6 +9,7 @@ CONFIG_MMU=y
+ CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
+ CONFIG_MALLOC_SIZE=0x800000
+ CONFIG_EXPERIMENTAL=y
++CONFIG_MALLOC_TLSF=y
+ CONFIG_LONGHELP=y
+ CONFIG_GLOB=y
+ CONFIG_HUSH_FANCY_PROMPT=y
+diff --git a/arch/arm/configs/eukrea_cpuimx51_defconfig b/arch/arm/configs/eukrea_cpuimx51_defconfig
+index f6fd7bc..7261796 100644
+--- a/arch/arm/configs/eukrea_cpuimx51_defconfig
++++ b/arch/arm/configs/eukrea_cpuimx51_defconfig
+@@ -7,6 +7,7 @@ CONFIG_MMU=y
+ CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
+ CONFIG_MALLOC_SIZE=0x2000000
+ CONFIG_EXPERIMENTAL=y
++CONFIG_MALLOC_TLSF=y
+ CONFIG_LONGHELP=y
+ CONFIG_GLOB=y
+ CONFIG_HUSH_FANCY_PROMPT=y
+diff --git a/arch/arm/configs/usb_a9260_defconfig b/arch/arm/configs/usb_a9260_defconfig
+index 85e7878..a9574c4 100644
+--- a/arch/arm/configs/usb_a9260_defconfig
++++ b/arch/arm/configs/usb_a9260_defconfig
+@@ -6,6 +6,7 @@ CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+ CONFIG_MMU=y
+ CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
+ CONFIG_EXPERIMENTAL=y
++CONFIG_MALLOC_TLSF=y
+ CONFIG_PROMPT="USB-9G20:"
+ CONFIG_LONGHELP=y
+ CONFIG_GLOB=y
+diff --git a/arch/arm/configs/usb_a9263_128mib_defconfig b/arch/arm/configs/usb_a9263_128mib_defconfig
+index 23bc3d7..d31057f 100644
+--- a/arch/arm/configs/usb_a9263_128mib_defconfig
++++ b/arch/arm/configs/usb_a9263_128mib_defconfig
+@@ -1,12 +1,13 @@
+ CONFIG_ARCH_AT91SAM9263=y
+ CONFIG_MACH_USB_A9263=y
++CONFIG_AT91_HAVE_SRAM_128M=y
+ CONFIG_AEABI=y
+ # CONFIG_CMD_ARM_CPUINFO is not set
+-CONFIG_AT91_HAVE_SRAM_128M=y
+ CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+ CONFIG_MMU=y
+ CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
+ CONFIG_EXPERIMENTAL=y
++CONFIG_MALLOC_TLSF=y
+ CONFIG_PROMPT="USB-9263:"
+ CONFIG_LONGHELP=y
+ CONFIG_GLOB=y
+diff --git a/arch/arm/configs/usb_a9263_defconfig b/arch/arm/configs/usb_a9263_defconfig
+index 96ea3e1..b57c300 100644
+--- a/arch/arm/configs/usb_a9263_defconfig
++++ b/arch/arm/configs/usb_a9263_defconfig
+@@ -6,6 +6,7 @@ CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+ CONFIG_MMU=y
+ CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
+ CONFIG_EXPERIMENTAL=y
++CONFIG_MALLOC_TLSF=y
+ CONFIG_PROMPT="USB-9263:"
+ CONFIG_LONGHELP=y
+ CONFIG_GLOB=y
+@@ -22,7 +23,6 @@ CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/usb-a926x/env"
+ CONFIG_CMD_EDIT=y
+ CONFIG_CMD_SLEEP=y
+ CONFIG_CMD_SAVEENV=y
+-CONFIG_CMD_LOADENV=y
+ CONFIG_CMD_EXPORT=y
+ CONFIG_CMD_PRINTENV=y
+ CONFIG_CMD_READLINE=y
+diff --git a/arch/arm/configs/usb_a9g20_128mib_defconfig b/arch/arm/configs/usb_a9g20_128mib_defconfig
+index c25d7de..6b02342 100644
+--- a/arch/arm/configs/usb_a9g20_128mib_defconfig
++++ b/arch/arm/configs/usb_a9g20_128mib_defconfig
+@@ -1,12 +1,13 @@
+ CONFIG_ARCH_AT91SAM9G20=y
+ CONFIG_MACH_USB_A9G20=y
++CONFIG_AT91_HAVE_SRAM_128M=y
+ CONFIG_AEABI=y
+ # CONFIG_CMD_ARM_CPUINFO is not set
+-CONFIG_AT91_HAVE_SRAM_128M=y
+ CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+ CONFIG_MMU=y
+ CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
+ CONFIG_EXPERIMENTAL=y
++CONFIG_MALLOC_TLSF=y
+ CONFIG_PROMPT="USB-9G20:"
+ CONFIG_LONGHELP=y
+ CONFIG_GLOB=y
+diff --git a/arch/arm/configs/usb_a9g20_defconfig b/arch/arm/configs/usb_a9g20_defconfig
+index d645adb..30bf380 100644
+--- a/arch/arm/configs/usb_a9g20_defconfig
++++ b/arch/arm/configs/usb_a9g20_defconfig
+@@ -6,6 +6,7 @@ CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+ CONFIG_MMU=y
+ CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
+ CONFIG_EXPERIMENTAL=y
++CONFIG_MALLOC_TLSF=y
+ CONFIG_PROMPT="USB-9G20:"
+ CONFIG_LONGHELP=y
+ CONFIG_GLOB=y
+diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
+index e30ae1c..93a34a9 100644
+--- a/arch/arm/cpu/Makefile
++++ b/arch/arm/cpu/Makefile
+@@ -7,6 +7,7 @@ obj-y += start.o
+ # Any variants can be called as start-armxyz.S
+ #
+ obj-$(CONFIG_CMD_ARM_CPUINFO) += cpuinfo.o
++obj-$(CONFIG_CMD_ARM_MMUINFO) += mmuinfo.o
+ obj-$(CONFIG_MMU) += mmu.o
+ obj-$(CONFIG_CPU_32v4T) += cache-armv4.o
+ obj-$(CONFIG_CPU_32v5) += cache-armv5.o
+diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
+index c19f931..607f357 100644
+--- a/arch/arm/cpu/mmu.c
++++ b/arch/arm/cpu/mmu.c
+@@ -147,7 +147,7 @@ static int arm_mmu_remap_sdram(struct memory_bank *bank)
+ if ((phys & (SZ_1M - 1)) || (bank->size & (SZ_1M - 1)))
+ return -EINVAL;
+
+- ptes = memalign(0x400, num_ptes * sizeof(u32));
++ ptes = memalign(PAGE_SIZE, num_ptes * sizeof(u32));
+
+ debug("ptes: 0x%p ttb_start: 0x%08lx ttb_end: 0x%08lx\n",
+ ptes, ttb_start, ttb_end);
+@@ -165,6 +165,9 @@ static int arm_mmu_remap_sdram(struct memory_bank *bank)
+ pte += 256;
+ }
+
++ dma_flush_range((unsigned long)ttb, (unsigned long)ttb + 0x4000);
++ dma_flush_range((unsigned long)ptes, num_ptes * sizeof(u32));
++
+ tlb_invalidate();
+
+ return 0;
+@@ -299,11 +302,9 @@ void *dma_alloc_coherent(size_t size)
+ size = PAGE_ALIGN(size);
+ ret = xmemalign(4096, size);
+
+-#ifdef CONFIG_MMU
+ dma_inv_range((unsigned long)ret, (unsigned long)ret + size);
+
+ remap_range(ret, size, PTE_FLAGS_UNCACHED);
+-#endif
+
+ return ret;
+ }
+@@ -320,9 +321,7 @@ void *phys_to_virt(unsigned long phys)
+
+ void dma_free_coherent(void *mem, size_t size)
+ {
+-#ifdef CONFIG_MMU
+ remap_range(mem, size, PTE_FLAGS_CACHED);
+-#endif
+
+ free(mem);
+ }
+diff --git a/arch/arm/cpu/mmuinfo.c b/arch/arm/cpu/mmuinfo.c
+new file mode 100644
+index 0000000..6bea34e
+--- /dev/null
++++ b/arch/arm/cpu/mmuinfo.c
+@@ -0,0 +1,111 @@
++/*
++ * mmuinfo.c - Show MMU/cache information from cp15 registers
++ *
++ * Copyright (c) Jan Luebbe <j.luebbe@pengutronix.de>, Pengutronix
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can 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 program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <command.h>
++
++static char *inner_attr[] = {
++ "0b000 Non-cacheable",
++ "0b001 Strongly-ordered",
++ "0b010 (reserved)",
++ "0b011 Device",
++ "0b100 (reserved)",
++ "0b101 Write-Back, Write-Allocate",
++ "0b110 Write-Through",
++ "0b111 Write-Back, no Write-Allocate",
++};
++
++static char *outer_attr[] = {
++ "0b00 Non-cacheable",
++ "0b01 Write-Back, Write-Allocate",
++ "0b10 Write-Through, no Write-Allocate",
++ "0b11 Write-Back, no Write-Allocate",
++};
++
++static void decode_par(unsigned long par)
++{
++ printf(" Physical Address [31:12]: 0x%08lx\n", par & 0xFFFFF000);
++ printf(" Reserved [11]: 0x%lx\n", (par >> 11) & 0x1);
++ printf(" Not Outer Shareable [10]: 0x%lx\n", (par >> 10) & 0x1);
++ printf(" Non-Secure [9]: 0x%lx\n", (par >> 9) & 0x1);
++ printf(" Impl. def. [8]: 0x%lx\n", (par >> 8) & 0x1);
++ printf(" Shareable [7]: 0x%lx\n", (par >> 7) & 0x1);
++ printf(" Inner mem. attr. [6:4]: 0x%lx (%s)\n", (par >> 4) & 0x7,
++ inner_attr[(par >> 4) & 0x7]);
++ printf(" Outer mem. attr. [3:2]: 0x%lx (%s)\n", (par >> 2) & 0x3,
++ outer_attr[(par >> 2) & 0x3]);
++ printf(" SuperSection [1]: 0x%lx\n", (par >> 1) & 0x1);
++ printf(" Failure [0]: 0x%lx\n", (par >> 0) & 0x1);
++}
++
++static int do_mmuinfo(int argc, char *argv[])
++{
++ unsigned long addr = 0, priv_read, priv_write;
++
++ if (argc < 2)
++ return COMMAND_ERROR_USAGE;
++
++ addr = strtoul_suffix(argv[1], NULL, 0);
++
++ __asm__ __volatile__(
++ "mcr p15, 0, %0, c7, c8, 0 @ write VA to PA translation (priv read)\n"
++ :
++ : "r" (addr)
++ : "memory");
++
++ __asm__ __volatile__(
++ "mrc p15, 0, %0, c7, c4, 0 @ read PAR\n"
++ : "=r" (priv_read)
++ :
++ : "memory");
++
++ __asm__ __volatile__(
++ "mcr p15, 0, %0, c7, c8, 1 @ write VA to PA translation (priv write)\n"
++ :
++ : "r" (addr)
++ : "memory");
++
++ __asm__ __volatile__(
++ "mrc p15, 0, %0, c7, c4, 0 @ read PAR\n"
++ : "=r" (priv_write)
++ :
++ : "memory");
++
++ printf("PAR result for 0x%08lx: \n", addr);
++ printf(" privileged read: 0x%08lx\n", priv_read);
++ decode_par(priv_read);
++ printf(" privileged write: 0x%08lx\n", priv_write);
++ decode_par(priv_write);
++
++ return 0;
++}
++
++BAREBOX_CMD_HELP_START(mmuinfo)
++BAREBOX_CMD_HELP_USAGE("mmuinfo <address>\n")
++BAREBOX_CMD_HELP_SHORT("Show MMU/cache information for an address.\n")
++BAREBOX_CMD_HELP_END
++
++BAREBOX_CMD_START(mmuinfo)
++ .cmd = do_mmuinfo,
++ .usage = "mmuinfo <address>",
++ BAREBOX_CMD_HELP(cmd_mmuinfo_help)
++BAREBOX_CMD_END
+diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
+index 3c282ee..523179d 100644
+--- a/arch/arm/cpu/start.c
++++ b/arch/arm/cpu/start.c
+@@ -81,13 +81,11 @@ void __naked __bare_init reset(void)
+ r &= ~(CR_M | CR_C | CR_B | CR_S | CR_R | CR_V);
+ r |= CR_I;
+
+- if (!(r & CR_U))
+- /* catch unaligned access on architectures which do not
+- * support unaligned access */
+- r |= CR_A;
+- else
+- r &= ~CR_A;
+-
++#if __LINUX_ARM_ARCH__ >= 6
++ r |= CR_U;
++#else
++ r |= CR_A;
++#endif
+
+ #ifdef __ARMEB__
+ r |= CR_B;
+diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h
+new file mode 100644
+index 0000000..cb9cd1b
+--- /dev/null
++++ b/arch/arm/include/asm/dma.h
+@@ -0,0 +1,8 @@
++/*
++ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
++ *
++ * This file is released under the GPLv2
++ *
++ */
++
++#include <asm/mmu.h>
+diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
+index f5ae7a8..a66da8c 100644
+--- a/arch/arm/include/asm/mmu.h
++++ b/arch/arm/include/asm/mmu.h
+@@ -1,9 +1,12 @@
+ #ifndef __ASM_MMU_H
+ #define __ASM_MMU_H
+
+-#include <asm/pgtable.h>
+-#include <malloc.h>
++#include <common.h>
+ #include <errno.h>
++#include <malloc.h>
++#include <xfuncs.h>
++
++#include <asm/pgtable.h>
+
+ #define PMD_SECT_DEF_UNCACHED (PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT)
+ #define PMD_SECT_DEF_CACHED (PMD_SECT_WB | PMD_SECT_DEF_UNCACHED)
+@@ -23,6 +26,12 @@ static inline void setup_dma_coherent(unsigned long offset)
+ {
+ }
+
++#define dma_alloc dma_alloc
++static inline void *dma_alloc(size_t size)
++{
++ return xmemalign(64, ALIGN(size, 64));
++}
++
+ #ifdef CONFIG_MMU
+ void *dma_alloc_coherent(size_t size);
+ void dma_free_coherent(void *mem, size_t size);
+diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
+index 033e2eb..3a00437 100644
+--- a/arch/arm/lib/bootm.c
++++ b/arch/arm/lib/bootm.c
+@@ -80,7 +80,7 @@ static int __do_bootm_linux(struct image_data *data, int swap)
+
+ if (data->initrd_res) {
+ initrd_start = data->initrd_res->start;
+- initrd_size = data->initrd_res->size;
++ initrd_size = resource_size(data->initrd_res);
+ }
+
+ if (bootm_verbose(data)) {
+@@ -154,7 +154,7 @@ static int do_bootz_linux_fdt(int fd, struct image_data *data)
+ }
+ } else {
+
+- of_res = request_sdram_region("oftree", r->start + r->size, end);
++ of_res = request_sdram_region("oftree", r->start + resource_size(r), end);
+ if (!of_res) {
+ perror("zImage: oftree request_sdram_region");
+ return -ENOMEM;
+@@ -310,9 +310,9 @@ static int aimage_load_resource(int fd, struct resource *r, void* buf, int ps)
+ {
+ int ret;
+ void *image = (void *)r->start;
+- unsigned to_read = ps - r->size % ps;
++ unsigned to_read = ps - resource_size(r) % ps;
+
+- ret = read_full(fd, image, r->size);
++ ret = read_full(fd, image, resource_size(r));
+ if (ret < 0)
+ return ret;
+
+diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
+index 3297a89..b56ca14 100644
+--- a/arch/arm/mach-at91/at91sam9260_devices.c
++++ b/arch/arm/mach-at91/at91sam9260_devices.c
+@@ -111,12 +111,12 @@ void at91_add_device_eth(int id, struct at91_ether_platform_data *data) {}
+ static struct resource nand_resources[] = {
+ [0] = {
+ .start = AT91_CHIPSELECT_3,
+- .size = SZ_256M,
++ .end = AT91_CHIPSELECT_3 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC,
+- .size = 512,
++ .end = AT91_BASE_SYS + AT91_ECC + 512 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+ };
+diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
+index 2ebc4da..7f916d2 100644
+--- a/arch/arm/mach-at91/at91sam9263_devices.c
++++ b/arch/arm/mach-at91/at91sam9263_devices.c
+@@ -113,12 +113,12 @@ void at91_add_device_eth(int id, struct at91_ether_platform_data *data) {}
+ static struct resource nand_resources[] = {
+ [0] = {
+ .start = AT91_CHIPSELECT_3,
+- .size = SZ_256M,
++ .end = AT91_CHIPSELECT_3 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC0,
+- .size = 512,
++ .end = AT91_BASE_SYS + AT91_ECC0 + 512 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+ };
+diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
+index d406bcc..22b455e 100644
+--- a/arch/arm/mach-at91/at91sam9g45_devices.c
++++ b/arch/arm/mach-at91/at91sam9g45_devices.c
+@@ -93,12 +93,12 @@ void at91_add_device_eth(int id, struct at91_ether_platform_data *data) {}
+ static struct resource nand_resources[] = {
+ [0] = {
+ .start = AT91_CHIPSELECT_3,
+- .size = SZ_256M,
++ .end = AT91_CHIPSELECT_3 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_ECC,
+- .size = 512,
++ .end = AT91_BASE_SYS + AT91_ECC + 512 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+ };
+diff --git a/arch/arm/mach-at91/at91sam9x5_devices.c b/arch/arm/mach-at91/at91sam9x5_devices.c
+index 50bad7f..26a380d 100644
+--- a/arch/arm/mach-at91/at91sam9x5_devices.c
++++ b/arch/arm/mach-at91/at91sam9x5_devices.c
+@@ -130,12 +130,12 @@ void at91_add_device_eth(int id, struct at91_ether_platform_data *data) {}
+ static struct resource nand_resources[] = {
+ [0] = {
+ .start = AT91_CHIPSELECT_3,
+- .size = SZ_256M,
++ .end = AT91_CHIPSELECT_3 + SZ_256M - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91_BASE_SYS + AT91_PMECC,
+- .size = 512,
++ .end = AT91_BASE_SYS + AT91_PMECC + 512 - 1,
+ .flags = IORESOURCE_MEM,
+ }
+ };
+diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
+index 564e2fe..5b77245 100644
+--- a/arch/arm/mach-imx/Kconfig
++++ b/arch/arm/mach-imx/Kconfig
+@@ -26,6 +26,7 @@ config ARCH_TEXT_BASE
+ default 0x7ff00000 if MACH_TQMA53
+ default 0x97f00000 if MACH_TX51
+ default 0x4fc00000 if MACH_MX6Q_ARM2
++ default 0x97f00000 if MACH_CCMX51
+
+ config BOARDINFO
+ default "Eukrea CPUIMX25" if MACH_EUKREA_CPUIMX25
+@@ -50,6 +51,7 @@ config BOARDINFO
+ default "TQ tqma53" if MACH_TQMA53
+ default "Ka-Ro tx51" if MACH_TX51
+ default "Freescale i.MX6q armadillo2" if MACH_MX6Q_ARM2
++ default "ConnectCore i.MX51" if MACH_CCMX51
+
+ choice
+ prompt "Select boot mode"
+@@ -391,7 +393,7 @@ choice
+ prompt "i.MX51 Board Type"
+
+ config MACH_FREESCALE_MX51_PDK
+- select DEFAULT_ENVIRONMENT_GENERIC_NEW
++ select HAVE_DEFAULT_ENVIRONMENT_NEW
+ bool "Freescale i.MX51 PDK"
+
+ config MACH_EUKREA_CPUIMX51SD
+@@ -405,6 +407,23 @@ config MACH_TX51
+ help
+ Say Y here if you are using the Ka-Ro tx51 board
+
++config MACH_CCMX51
++ bool "ConnectCore i.MX51"
++ select IMX_IIM
++ select SPI
++ select DRIVER_SPI_IMX
++ select MFD_MC13XXX
++ help
++ Say Y here if you are using Digi ConnectCore (W)i-i.MX51
++ equipped with a Freescale i.MX51 Processor
++
++config MACH_CCMX51_BASEBOARD
++ bool "Digi development board for CCMX51 module"
++ depends on MACH_CCMX51
++ default y
++ help
++ This adds board specific devices that can be found on Digi
++ evaluation board for CCMX51 module.
+
+ endchoice
+
+@@ -517,7 +536,7 @@ menu "i.MX specific settings "
+
+ config IMX_CLKO
+ bool "clko command"
+- depends on ARCH_IMX21 || ARCH_IMX27 || ARCH_IMX35 || ARCH_IMX25
++ depends on ARCH_IMX21 || ARCH_IMX27 || ARCH_IMX35 || ARCH_IMX25 || ARCH_IMX51
+ help
+ The i.MX SoCs have a Pin which can output different reference frequencies.
+ Say y here if you want to have the clko command which lets you select the
+diff --git a/arch/arm/mach-imx/clko.c b/arch/arm/mach-imx/clko.c
+index 0e4fbcc..aeafaa9 100644
+--- a/arch/arm/mach-imx/clko.c
++++ b/arch/arm/mach-imx/clko.c
+@@ -6,15 +6,18 @@
+
+ static int do_clko(int argc, char *argv[])
+ {
+- int opt, div = 0, src = -2, ret;
++ int opt, div = 0, src = -2, num = 1, ret;
+
+- while((opt = getopt(argc, argv, "d:s:")) > 0) {
++ while((opt = getopt(argc, argv, "n:d:s:")) > 0) {
+ switch(opt) {
++ case 'n':
++ num = simple_strtoul(optarg, NULL, 0);
++ break;
+ case 'd':
+ div = simple_strtoul(optarg, NULL, 0);
+ break;
+ case 's':
+- src = simple_strtoul(optarg, NULL, 0);
++ src = simple_strtol(optarg, NULL, 0);
+ break;
+ }
+ }
+@@ -23,17 +26,19 @@ static int do_clko(int argc, char *argv[])
+ return COMMAND_ERROR_USAGE;
+
+ if (src == -1) {
+- imx_clko_set_src(-1);
++ imx_clko_set_src(num, -1);
+ return 0;
+ }
+
+ if (src != -2)
+- imx_clko_set_src(src);
++ imx_clko_set_src(num, src);
+
+ if (div != 0) {
+- ret = imx_clko_set_div(div);
+- if (ret != div)
+- printf("limited divider to %d\n", ret);
++ ret = imx_clko_set_div(num, div);
++ if (ret < 0)
++ printf("CLKO-line %i not supported.\n", num);
++ else if (ret != div)
++ printf("Divider limited to %d.\n", ret);
+ }
+
+ return 0;
+@@ -42,7 +47,8 @@ static int do_clko(int argc, char *argv[])
+ static __maybe_unused char cmd_clko_help[] =
+ "Usage: clko [OPTION]...\n"
+ "Route different signals to the i.MX clko pin\n"
+-" -d <div> Divider\n"
++" -n <num> Number of CLKO-line (Default 1)\n"
++" -d <div> Divider\n"
+ " -s <source> Clock select. See Ref. Manual for valid sources. Use -1\n"
+ " for disabling clock output\n";
+
+diff --git a/arch/arm/mach-imx/clocksource.c b/arch/arm/mach-imx/clocksource.c
+index 4f5895c..4e77ece 100644
+--- a/arch/arm/mach-imx/clocksource.c
++++ b/arch/arm/mach-imx/clocksource.c
+@@ -38,7 +38,7 @@
+ #include <io.h>
+
+ #define GPT(x) __REG(IMX_TIM1_BASE + (x))
+-#define timer_base (IMX_TIM1_BASE)
++#define timer_base IOMEM(IMX_TIM1_BASE)
+
+ static uint64_t imx_clocksource_read(void)
+ {
+@@ -120,15 +120,17 @@ core_initcall(clocksource_init);
+ */
+ void __noreturn reset_cpu (unsigned long addr)
+ {
++ void __iomem *wdt = IOMEM(IMX_WDT_BASE);
++
+ /* Disable watchdog and set Time-Out field to 0 */
+- writew(0x0, IMX_WDT_BASE + WDOG_WCR);
++ writew(0x0, wdt + WDOG_WCR);
+
+ /* Write Service Sequence */
+- writew(0x5555, IMX_WDT_BASE + WDOG_WSR);
+- writew(0xaaaa, IMX_WDT_BASE + WDOG_WSR);
++ writew(0x5555, wdt + WDOG_WSR);
++ writew(0xaaaa, wdt + WDOG_WSR);
+
+ /* Enable watchdog */
+- writew(WDOG_WCR_WDE, IMX_WDT_BASE + WDOG_WCR);
++ writew(WDOG_WCR_WDE, wdt + WDOG_WCR);
+
+ while (1);
+ /*NOTREACHED*/
+diff --git a/arch/arm/mach-imx/iim.c b/arch/arm/mach-imx/iim.c
+index f2ace8a..0da8ea0 100644
+--- a/arch/arm/mach-imx/iim.c
++++ b/arch/arm/mach-imx/iim.c
+@@ -84,7 +84,7 @@ static int do_fuse_sense(void __iomem *reg_base, unsigned int bank,
+ }
+
+ static ssize_t imx_iim_cdev_read(struct cdev *cdev, void *buf, size_t count,
+- ulong offset, ulong flags)
++ loff_t offset, ulong flags)
+ {
+ ulong size, i;
+ struct iim_priv *priv = cdev->priv;
+@@ -94,7 +94,7 @@ static ssize_t imx_iim_cdev_read(struct cdev *cdev, void *buf, size_t count,
+ if ((sense_param = dev_get_param(cdev->dev, "explicit_sense_enable")))
+ explicit_sense = simple_strtoul(sense_param, NULL, 0);
+
+- size = min((ulong)count, priv->banksize - offset);
++ size = min((loff_t)count, priv->banksize - offset);
+ if (explicit_sense) {
+ for (i = 0; i < size; i++) {
+ int row_val;
+@@ -176,7 +176,7 @@ out:
+ #endif /* CONFIG_IMX_IIM_FUSE_BLOW */
+
+ static ssize_t imx_iim_cdev_write(struct cdev *cdev, const void *buf, size_t count,
+- ulong offset, ulong flags)
++ loff_t offset, ulong flags)
+ {
+ ulong size, i;
+ struct iim_priv *priv = cdev->priv;
+@@ -186,7 +186,7 @@ static ssize_t imx_iim_cdev_write(struct cdev *cdev, const void *buf, size_t cou
+ if ((write_param = dev_get_param(cdev->dev, "permanent_write_enable")))
+ blow_enable = simple_strtoul(write_param, NULL, 0);
+
+- size = min((ulong)count, priv->banksize - offset);
++ size = min((loff_t)count, priv->banksize - offset);
+ #ifdef CONFIG_IMX_IIM_FUSE_BLOW
+ if (blow_enable) {
+ for (i = 0; i < size; i++) {
+diff --git a/arch/arm/mach-imx/include/mach/clock.h b/arch/arm/mach-imx/include/mach/clock.h
+index 1082178..050b7f8 100644
+--- a/arch/arm/mach-imx/include/mach/clock.h
++++ b/arch/arm/mach-imx/include/mach/clock.h
+@@ -30,9 +30,11 @@ ulong imx_get_lcdclk(void);
+ ulong imx_get_i2cclk(void);
+ ulong imx_get_mmcclk(void);
+ ulong imx_get_cspiclk(void);
++ulong imx_get_ipgclk(void);
++ulong imx_get_usbclk(void);
+
+-int imx_clko_set_div(int div);
+-void imx_clko_set_src(int src);
++int imx_clko_set_div(int num, int div);
++void imx_clko_set_src(int num, int src);
+
+ void imx_dump_clocks(void);
+
+diff --git a/arch/arm/mach-imx/include/mach/devices-imx51.h b/arch/arm/mach-imx/include/mach/devices-imx51.h
+index 5de0fa7..dbf5862 100644
+--- a/arch/arm/mach-imx/include/mach/devices-imx51.h
++++ b/arch/arm/mach-imx/include/mach/devices-imx51.h
+@@ -67,11 +67,11 @@ static inline struct device_d *imx51_add_nand(struct imx_nand_platform_data *pda
+ struct resource res[] = {
+ {
+ .start = MX51_NFC_BASE_ADDR,
+- .size = SZ_4K,
++ .end = MX51_NFC_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX51_NFC_AXI_BASE_ADDR,
+- .size = SZ_4K,
++ .end = MX51_NFC_AXI_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+diff --git a/arch/arm/mach-imx/include/mach/devices-imx53.h b/arch/arm/mach-imx/include/mach/devices-imx53.h
+index a9fe454..0fc4b5c 100644
+--- a/arch/arm/mach-imx/include/mach/devices-imx53.h
++++ b/arch/arm/mach-imx/include/mach/devices-imx53.h
+@@ -61,11 +61,11 @@ static inline struct device_d *imx53_add_nand(struct imx_nand_platform_data *pda
+ struct resource res[] = {
+ {
+ .start = MX53_NFC_BASE_ADDR,
+- .size = SZ_4K,
++ .end = MX53_NFC_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX53_NFC_AXI_BASE_ADDR,
+- .size = SZ_4K,
++ .end = MX53_NFC_AXI_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+diff --git a/arch/arm/mach-imx/include/mach/iomux-mx51.h b/arch/arm/mach-imx/include/mach/iomux-mx51.h
+index c7f5169..36c8989 100644
+--- a/arch/arm/mach-imx/include/mach/iomux-mx51.h
++++ b/arch/arm/mach-imx/include/mach/iomux-mx51.h
+@@ -256,13 +256,13 @@
+ #define MX51_PAD_NANDF_RB1__GPIO3_9 IOMUX_PAD(0x4fc, 0x120, 3, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_NANDF_RB1__NANDF_RB1 IOMUX_PAD(0x4fc, 0x120, 0, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_NANDF_RB1__PATA_IORDY IOMUX_PAD(0x4fc, 0x120, 1, __NA_, 0, NO_PAD_CTRL)
+-#define MX51_PAD_NANDF_RB1__SD4_CMD IOMUX_PAD(0x4fc, 0x120, 5, __NA_, 0, MX51_SDHCI_PAD_CTRL)
++#define MX51_PAD_NANDF_RB1__SD4_CMD IOMUX_PAD(0x4fc, 0x120, 0x15, __NA_, 0, MX51_SDHCI_PAD_CTRL)
+ #define MX51_PAD_NANDF_RB2__DISP2_WAIT IOMUX_PAD(0x500, 0x124, 5, 0x9a8, 0, NO_PAD_CTRL)
+ #define MX51_PAD_NANDF_RB2__ECSPI2_SCLK IOMUX_PAD(0x500, 0x124, 2, __NA_, 0, MX51_ECSPI_PAD_CTRL)
+ #define MX51_PAD_NANDF_RB2__FEC_COL IOMUX_PAD(0x500, 0x124, 1, 0x94c, 0, MX51_PAD_CTRL_2)
+ #define MX51_PAD_NANDF_RB2__GPIO3_10 IOMUX_PAD(0x500, 0x124, 3, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_NANDF_RB2__NANDF_RB2 IOMUX_PAD(0x500, 0x124, 0, __NA_, 0, NO_PAD_CTRL)
+-#define MX51_PAD_NANDF_RB2__USBH3_H3_DP IOMUX_PAD(0x500, 0x124, 7, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_NANDF_RB2__USBH3_H3_DP IOMUX_PAD(0x500, 0x124, 0x17, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_NANDF_RB2__USBH3_NXT IOMUX_PAD(0x500, 0x124, 6, 0xa20, 0, NO_PAD_CTRL)
+ #define MX51_PAD_NANDF_RB3__DISP1_WAIT IOMUX_PAD(0x504, 0x128, 5, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_NANDF_RB3__ECSPI2_MISO IOMUX_PAD(0x504, 0x128, 2, __NA_, 0, MX51_ECSPI_PAD_CTRL)
+@@ -270,7 +270,7 @@
+ #define MX51_PAD_NANDF_RB3__GPIO3_11 IOMUX_PAD(0x504, 0x128, 3, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_NANDF_RB3__NANDF_RB3 IOMUX_PAD(0x504, 0x128, 0, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_NANDF_RB3__USBH3_CLK IOMUX_PAD(0x504, 0x128, 6, 0x9f8, 0, NO_PAD_CTRL)
+-#define MX51_PAD_NANDF_RB3__USBH3_H3_DM IOMUX_PAD(0x504, 0x128, 7, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_NANDF_RB3__USBH3_H3_DM IOMUX_PAD(0x504, 0x128, 0x17, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO_NAND__GPIO_NAND IOMUX_PAD(0x514, 0x12c, 0, 0x998, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_GPIO_NAND__PATA_INTRQ IOMUX_PAD(0x514, 0x12c, 1, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_NANDF_CS0__GPIO3_16 IOMUX_PAD(0x518, 0x130, 3, __NA_, 0, MX51_GPIO_PAD_CTRL)
+@@ -283,13 +283,13 @@
+ #define MX51_PAD_NANDF_CS2__NANDF_CS2 IOMUX_PAD(0x520, 0x138, 0, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_NANDF_CS2__PATA_CS_0 IOMUX_PAD(0x520, 0x138, 1, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_NANDF_CS2__SD4_CLK IOMUX_PAD(0x520, 0x138, 5, __NA_, 0, MX51_SDHCI_PAD_CTRL | PAD_CTL_HYS)
+-#define MX51_PAD_NANDF_CS2__USBH3_H1_DP IOMUX_PAD(0x520, 0x138, 7, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_NANDF_CS2__USBH3_H1_DP IOMUX_PAD(0x520, 0x138, 0x17, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_NANDF_CS3__FEC_MDC IOMUX_PAD(0x524, 0x13c, 2, __NA_, 0, MX51_PAD_CTRL_5)
+ #define MX51_PAD_NANDF_CS3__GPIO3_19 IOMUX_PAD(0x524, 0x13c, 3, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_NANDF_CS3__NANDF_CS3 IOMUX_PAD(0x524, 0x13c, 0, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_NANDF_CS3__PATA_CS_1 IOMUX_PAD(0x524, 0x13c, 1, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_NANDF_CS3__SD4_DAT0 IOMUX_PAD(0x524, 0x13c, 5, __NA_, 0, MX51_SDHCI_PAD_CTRL)
+-#define MX51_PAD_NANDF_CS3__USBH3_H1_DM IOMUX_PAD(0x524, 0x13c, 7, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_NANDF_CS3__USBH3_H1_DM IOMUX_PAD(0x524, 0x13c, 0x17, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_NANDF_CS4__FEC_TDATA1 IOMUX_PAD(0x528, 0x140, 2, __NA_, 0, MX51_PAD_CTRL_5)
+ #define MX51_PAD_NANDF_CS4__GPIO3_20 IOMUX_PAD(0x528, 0x140, 3, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_NANDF_CS4__NANDF_CS4 IOMUX_PAD(0x528, 0x140, 0, __NA_, 0, NO_PAD_CTRL)
+@@ -316,7 +316,7 @@
+ #define MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK IOMUX_PAD(0x538, 0x150, 1, 0x974, 0, MX51_PAD_CTRL_4)
+ #define MX51_PAD_NANDF_RDY_INT__GPIO3_24 IOMUX_PAD(0x538, 0x150, 3, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT IOMUX_PAD(0x538, 0x150, 0, 0x938, 0, NO_PAD_CTRL)
+-#define MX51_PAD_NANDF_RDY_INT__SD3_CMD IOMUX_PAD(0x538, 0x150, 5, __NA_, 0, MX51_SDHCI_PAD_CTRL)
++#define MX51_PAD_NANDF_RDY_INT__SD3_CMD IOMUX_PAD(0x538, 0x150, 0x15, __NA_, 0, MX51_SDHCI_PAD_CTRL)
+ #define MX51_PAD_NANDF_D15__ECSPI2_MOSI IOMUX_PAD(0x53c, 0x154, 2, __NA_, 0, MX51_ECSPI_PAD_CTRL)
+ #define MX51_PAD_NANDF_D15__GPIO3_25 IOMUX_PAD(0x53c, 0x154, 3, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_NANDF_D15__NANDF_D15 IOMUX_PAD(0x53c, 0x154, 0, __NA_, 0, NO_PAD_CTRL)
+@@ -672,23 +672,23 @@
+ #define MX51_PAD_DISP2_DAT5__DISP2_DAT5 IOMUX_PAD(0x770, 0x368, 0, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT6__DISP2_DAT6 IOMUX_PAD(0x774, 0x36c, 0, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT6__FEC_TDATA1 IOMUX_PAD(0x774, 0x36c, 2, __NA_, 0, MX51_PAD_CTRL_5)
+-#define MX51_PAD_DISP2_DAT6__GPIO1_19 IOMUX_PAD(0x774, 0x36c, 5, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_DISP2_DAT6__GPIO1_19 IOMUX_PAD(0x774, 0x36c, 5, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT6__KEY_ROW4 IOMUX_PAD(0x774, 0x36c, 4, 0x9d0, 1, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT6__USBH3_STP IOMUX_PAD(0x774, 0x36c, 3, 0xa24, 1, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT7__DISP2_DAT7 IOMUX_PAD(0x778, 0x370, 0, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT7__FEC_TDATA2 IOMUX_PAD(0x778, 0x370, 2, __NA_, 0, MX51_PAD_CTRL_5)
+-#define MX51_PAD_DISP2_DAT7__GPIO1_29 IOMUX_PAD(0x778, 0x370, 5, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_DISP2_DAT7__GPIO1_29 IOMUX_PAD(0x778, 0x370, 5, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT7__KEY_ROW5 IOMUX_PAD(0x778, 0x370, 4, 0x9d4, 1, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT7__USBH3_NXT IOMUX_PAD(0x778, 0x370, 3, 0xa20, 1, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT8__DISP2_DAT8 IOMUX_PAD(0x77c, 0x374, 0, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT8__FEC_TDATA3 IOMUX_PAD(0x77c, 0x374, 2, __NA_, 0, MX51_PAD_CTRL_5)
+-#define MX51_PAD_DISP2_DAT8__GPIO1_30 IOMUX_PAD(0x77c, 0x374, 5, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_DISP2_DAT8__GPIO1_30 IOMUX_PAD(0x77c, 0x374, 5, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT8__KEY_ROW6 IOMUX_PAD(0x77c, 0x374, 4, 0x9d8, 1, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT8__USBH3_DATA0 IOMUX_PAD(0x77c, 0x374, 3, 0x9fc, 1, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT9__AUD6_RXC IOMUX_PAD(0x780, 0x378, 4, 0x8f4, 1, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT9__DISP2_DAT9 IOMUX_PAD(0x780, 0x378, 0, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT9__FEC_TX_EN IOMUX_PAD(0x780, 0x378, 2, __NA_, 0, MX51_PAD_CTRL_5)
+-#define MX51_PAD_DISP2_DAT9__GPIO1_31 IOMUX_PAD(0x780, 0x378, 5, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_DISP2_DAT9__GPIO1_31 IOMUX_PAD(0x780, 0x378, 5, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT9__USBH3_DATA1 IOMUX_PAD(0x780, 0x378, 3, 0xa00, 1, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT10__DISP2_DAT10 IOMUX_PAD(0x784, 0x37c, 0, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT10__DISP2_SER_CS IOMUX_PAD(0x784, 0x37c, 5, __NA_, 0, NO_PAD_CTRL)
+@@ -698,7 +698,7 @@
+ #define MX51_PAD_DISP2_DAT11__AUD6_TXD IOMUX_PAD(0x788, 0x380, 4, 0x8f0, 1, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT11__DISP2_DAT11 IOMUX_PAD(0x788, 0x380, 0, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT11__FEC_RX_CLK IOMUX_PAD(0x788, 0x380, 2, 0x968, 1, NO_PAD_CTRL)
+-#define MX51_PAD_DISP2_DAT11__GPIO1_10 IOMUX_PAD(0x788, 0x380, 7, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_DISP2_DAT11__GPIO1_10 IOMUX_PAD(0x788, 0x380, 7, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT11__USBH3_DATA3 IOMUX_PAD(0x788, 0x380, 3, 0xa08, 1, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT12__AUD6_RXD IOMUX_PAD(0x78c, 0x384, 4, 0x8ec, 1, NO_PAD_CTRL)
+ #define MX51_PAD_DISP2_DAT12__DISP2_DAT12 IOMUX_PAD(0x78c, 0x384, 0, __NA_, 0, NO_PAD_CTRL)
+@@ -746,16 +746,16 @@
+ #define MX51_PAD_SD1_DATA3__CSPI_SS1 IOMUX_PAD(0x7b0, 0x3a8, 2, 0x920, 1, MX51_ECSPI_PAD_CTRL)
+ #define MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7b0, 0x3a8, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL)
+ #define MX51_PAD_GPIO1_0__CSPI_SS2 IOMUX_PAD(0x7b4, 0x3ac, 2, 0x924, 0, MX51_ECSPI_PAD_CTRL)
+-#define MX51_PAD_GPIO1_0__GPIO1_0 IOMUX_PAD(0x7b4, 0x3ac, 1, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_GPIO1_0__GPIO1_0 IOMUX_PAD(0x7b4, 0x3ac, 1, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_0__SD1_CD IOMUX_PAD(0x7b4, 0x3ac, 0, __NA_, 0, MX51_ESDHC_PAD_CTRL)
+ #define MX51_PAD_GPIO1_1__CSPI_MISO IOMUX_PAD(0x7b8, 0x3b0, 2, 0x918, 2, MX51_ECSPI_PAD_CTRL)
+-#define MX51_PAD_GPIO1_1__GPIO1_1 IOMUX_PAD(0x7b8, 0x3b0, 1, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_GPIO1_1__GPIO1_1 IOMUX_PAD(0x7b8, 0x3b0, 1, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_1__SD1_WP IOMUX_PAD(0x7b8, 0x3b0, 0, __NA_, 0, MX51_ESDHC_PAD_CTRL)
+ #define MX51_PAD_EIM_DA12__EIM_DA12 IOMUX_PAD(__NA_, 0x04c, 0, 0x000, 0, NO_PAD_CTRL)
+ #define MX51_PAD_EIM_DA13__EIM_DA13 IOMUX_PAD(__NA_, 0x050, 0, 0x000, 0, NO_PAD_CTRL)
+ #define MX51_PAD_EIM_DA14__EIM_DA14 IOMUX_PAD(__NA_, 0x054, 0, 0x000, 0, NO_PAD_CTRL)
+ #define MX51_PAD_EIM_DA15__EIM_DA15 IOMUX_PAD(__NA_, 0x058, 0, 0x000, 0, NO_PAD_CTRL)
+-#define MX51_PAD_SD2_CMD__CSPI_MOSI IOMUX_PAD(__NA_, 0x3b4, 2, 0x91c, 3, MX51_ECSPI_PAD_CTRL)
++#define MX51_PAD_SD2_CMD__CSPI_MOSI IOMUX_PAD(0x7bc, 0x3b4, 2, 0x91c, 3, MX51_ECSPI_PAD_CTRL)
+ #define MX51_PAD_SD2_CMD__I2C1_SCL IOMUX_PAD(0x7bc, 0x3b4, 0x11, 0x9b0, 2, MX51_I2C_PAD_CTRL)
+ #define MX51_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x7bc, 0x3b4, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL)
+ #define MX51_PAD_SD2_CLK__CSPI_SCLK IOMUX_PAD(0x7c0, 0x3b8, 2, 0x914, 3, MX51_ECSPI_PAD_CTRL)
+@@ -766,19 +766,19 @@
+ #define MX51_PAD_SD2_DATA0__SD2_DATA0 IOMUX_PAD(0x7c4, 0x3bc, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL)
+ #define MX51_PAD_SD2_DATA1__SD1_DAT5 IOMUX_PAD(0x7c8, 0x3c0, 1, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_SD2_DATA1__SD2_DATA1 IOMUX_PAD(0x7c8, 0x3c0, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL)
+-#define MX51_PAD_SD2_DATA1__USBH3_H2_DP IOMUX_PAD(0x7c8, 0x3c0, 2, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_SD2_DATA1__USBH3_H2_DP IOMUX_PAD(0x7c8, 0x3c0, 0x12, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_SD2_DATA2__SD1_DAT6 IOMUX_PAD(0x7cc, 0x3c4, 1, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_SD2_DATA2__SD2_DATA2 IOMUX_PAD(0x7cc, 0x3c4, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL)
+-#define MX51_PAD_SD2_DATA2__USBH3_H2_DM IOMUX_PAD(0x7cc, 0x3c4, 2, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_SD2_DATA2__USBH3_H2_DM IOMUX_PAD(0x7cc, 0x3c4, 0x12, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_SD2_DATA3__CSPI_SS2 IOMUX_PAD(0x7d0, 0x3c8, 2, 0x924, 1, MX51_ECSPI_PAD_CTRL)
+ #define MX51_PAD_SD2_DATA3__SD1_DAT7 IOMUX_PAD(0x7d0, 0x3c8, 1, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_SD2_DATA3__SD2_DATA3 IOMUX_PAD(0x7d0, 0x3c8, 0x10, __NA_, 0, MX51_SDHCI_PAD_CTRL)
+ #define MX51_PAD_GPIO1_2__CCM_OUT_2 IOMUX_PAD(0x7d4, 0x3cc, 5, __NA_, 0, NO_PAD_CTRL)
+-#define MX51_PAD_GPIO1_2__GPIO1_2 IOMUX_PAD(0x7d4, 0x3cc, 0, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_GPIO1_2__GPIO1_2 IOMUX_PAD(0x7d4, 0x3cc, 0, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_2__I2C2_SCL IOMUX_PAD(0x7d4, 0x3cc, 0x12, 0x9b8, 3, MX51_I2C_PAD_CTRL)
+ #define MX51_PAD_GPIO1_2__PLL1_BYP IOMUX_PAD(0x7d4, 0x3cc, 7, 0x90c, 1, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_2__PWM1_PWMO IOMUX_PAD(0x7d4, 0x3cc, 1, __NA_, 0, NO_PAD_CTRL)
+-#define MX51_PAD_GPIO1_3__GPIO1_3 IOMUX_PAD(0x7d8, 0x3d0, 0, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_GPIO1_3__GPIO1_3 IOMUX_PAD(0x7d8, 0x3d0, 0, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_3__I2C2_SDA IOMUX_PAD(0x7d8, 0x3d0, 0x12, 0x9bc, 3, MX51_I2C_PAD_CTRL)
+ #define MX51_PAD_GPIO1_3__PLL2_BYP IOMUX_PAD(0x7d8, 0x3d0, 7, 0x910, 1, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_3__PWM2_PWMO IOMUX_PAD(0x7d8, 0x3d0, 1, __NA_, 0, NO_PAD_CTRL)
+@@ -786,27 +786,27 @@
+ #define MX51_PAD_PMIC_INT_REQ__PMIC_PMU_IRQ_B IOMUX_PAD(0x7fc, 0x3d4, 1, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_4__DISP2_EXT_CLK IOMUX_PAD(0x804, 0x3d8, 4, 0x908, 1, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_4__EIM_RDY IOMUX_PAD(0x804, 0x3d8, 3, 0x938, 1, NO_PAD_CTRL)
+-#define MX51_PAD_GPIO1_4__GPIO1_4 IOMUX_PAD(0x804, 0x3d8, 0, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_GPIO1_4__GPIO1_4 IOMUX_PAD(0x804, 0x3d8, 0, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_4__WDOG1_WDOG_B IOMUX_PAD(0x804, 0x3d8, 2, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_5__CSI2_MCLK IOMUX_PAD(0x808, 0x3dc, 6, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_5__DISP2_PIN16 IOMUX_PAD(0x808, 0x3dc, 3, __NA_, 0, NO_PAD_CTRL)
+-#define MX51_PAD_GPIO1_5__GPIO1_5 IOMUX_PAD(0x808, 0x3dc, 0, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_GPIO1_5__GPIO1_5 IOMUX_PAD(0x808, 0x3dc, 0, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_5__WDOG2_WDOG_B IOMUX_PAD(0x808, 0x3dc, 2, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_6__DISP2_PIN17 IOMUX_PAD(0x80c, 0x3e0, 4, __NA_, 0, NO_PAD_CTRL)
+-#define MX51_PAD_GPIO1_6__GPIO1_6 IOMUX_PAD(0x80c, 0x3e0, 0, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_GPIO1_6__GPIO1_6 IOMUX_PAD(0x80c, 0x3e0, 0, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_6__REF_EN_B IOMUX_PAD(0x80c, 0x3e0, 3, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_7__CCM_OUT_0 IOMUX_PAD(0x810, 0x3e4, 3, __NA_, 0, NO_PAD_CTRL)
+-#define MX51_PAD_GPIO1_7__GPIO1_7 IOMUX_PAD(0x810, 0x3e4, 0, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_GPIO1_7__GPIO1_7 IOMUX_PAD(0x810, 0x3e4, 0, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_7__SD2_WP IOMUX_PAD(0x810, 0x3e4, 6, __NA_, 0, MX51_ESDHC_PAD_CTRL)
+ #define MX51_PAD_GPIO1_7__SPDIF_OUT1 IOMUX_PAD(0x810, 0x3e4, 2, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_8__CSI2_DATA_EN IOMUX_PAD(0x814, 0x3e8, 2, 0x99c, 2, NO_PAD_CTRL)
+-#define MX51_PAD_GPIO1_8__GPIO1_8 IOMUX_PAD(0x814, 0x3e8, 0, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_GPIO1_8__GPIO1_8 IOMUX_PAD(0x814, 0x3e8, 0, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_8__SD2_CD IOMUX_PAD(0x814, 0x3e8, 6, __NA_, 0, MX51_ESDHC_PAD_CTRL)
+ #define MX51_PAD_GPIO1_8__USBH3_PWR IOMUX_PAD(0x814, 0x3e8, 1, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_9__CCM_OUT_1 IOMUX_PAD(0x818, 0x3ec, 3, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_9__DISP2_D1_CS IOMUX_PAD(0x818, 0x3ec, 2, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_9__DISP2_SER_CS IOMUX_PAD(0x818, 0x3ec, 7, __NA_, 0, NO_PAD_CTRL)
+-#define MX51_PAD_GPIO1_9__GPIO1_9 IOMUX_PAD(0x818, 0x3ec, 0, __NA_, 0, NO_PAD_CTRL)
++#define MX51_PAD_GPIO1_9__GPIO1_9 IOMUX_PAD(0x818, 0x3ec, 0, __NA_, 0, MX51_GPIO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_9__SD2_LCTL IOMUX_PAD(0x818, 0x3ec, 6, __NA_, 0, NO_PAD_CTRL)
+ #define MX51_PAD_GPIO1_9__USBH3_OC IOMUX_PAD(0x818, 0x3ec, 1, __NA_, 0, NO_PAD_CTRL)
+
+diff --git a/arch/arm/mach-imx/speed-imx21.c b/arch/arm/mach-imx/speed-imx21.c
+index 6ab1dca..4729583 100644
+--- a/arch/arm/mach-imx/speed-imx21.c
++++ b/arch/arm/mach-imx/speed-imx21.c
+@@ -16,6 +16,7 @@
+ */
+
+ #include <common.h>
++#include <asm-generic/errno.h>
+ #include <mach/imx-regs.h>
+ #include <mach/generic.h>
+ #include <mach/clock.h>
+@@ -162,9 +163,13 @@ void imx_dump_clocks(void)
+ * Returns the new divider (which may be smaller
+ * than the desired one)
+ */
+-int imx_clko_set_div(int div)
++int imx_clko_set_div(int num, int div)
+ {
+ ulong pcdr;
++
++ if (num != 1)
++ return -ENODEV;
++
+ div--;
+ div &= 0x7;
+
+@@ -178,11 +183,11 @@ int imx_clko_set_div(int div)
+ /*
+ * Set the clock source for the CLKO pin
+ */
+-void imx_clko_set_src(int src)
++void imx_clko_set_src(int num, int src)
+ {
+ unsigned long ccsr;
+
+- if (src < 0) {
++ if (src < 0 || num != 1) {
+ return;
+ }
+
+diff --git a/arch/arm/mach-imx/speed-imx25.c b/arch/arm/mach-imx/speed-imx25.c
+index f6dcacb..ed14113 100644
+--- a/arch/arm/mach-imx/speed-imx25.c
++++ b/arch/arm/mach-imx/speed-imx25.c
+@@ -1,4 +1,5 @@
+ #include <common.h>
++#include <asm-generic/errno.h>
+ #include <mach/imx-regs.h>
+ #include <io.h>
+ #include <mach/clock.h>
+@@ -111,10 +112,13 @@ void imx_dump_clocks(void)
+ * the new divider (which may be smaller
+ * than the desired one)
+ */
+-int imx_clko_set_div(int div)
++int imx_clko_set_div(int num, int div)
+ {
+ unsigned long mcr = readl(IMX_CCM_BASE + 0x64);
+
++ if (num != 1)
++ return -ENODEV;
++
+ div -= 1;
+ div &= 0x3f;
+
+@@ -129,10 +133,13 @@ int imx_clko_set_div(int div)
+ /*
+ * Set the clock source for the CLKO pin
+ */
+-void imx_clko_set_src(int src)
++void imx_clko_set_src(int num, int src)
+ {
+ unsigned long mcr = readl(IMX_CCM_BASE + 0x64);
+
++ if (num != 1)
++ return;
++
+ if (src < 0) {
+ mcr &= ~(1 << 30);
+ writel(mcr, IMX_CCM_BASE + 0x64);
+diff --git a/arch/arm/mach-imx/speed-imx27.c b/arch/arm/mach-imx/speed-imx27.c
+index aba5097..644fd04 100644
+--- a/arch/arm/mach-imx/speed-imx27.c
++++ b/arch/arm/mach-imx/speed-imx27.c
+@@ -16,6 +16,7 @@
+ */
+
+ #include <common.h>
++#include <asm-generic/errno.h>
+ #include <mach/imx-regs.h>
+ #include <mach/generic.h>
+ #include <mach/clock.h>
+@@ -189,9 +190,13 @@ void imx_dump_clocks(void)
+ * the new divider (which may be smaller
+ * than the desired one)
+ */
+-int imx_clko_set_div(int div)
++int imx_clko_set_div(int num, int div)
+ {
+ ulong pcdr;
++
++ if (num != 1)
++ return -ENODEV;
++
+ div--;
+ div &= 0x7;
+
+@@ -205,10 +210,13 @@ int imx_clko_set_div(int div)
+ /*
+ * Set the clock source for the CLKO pin
+ */
+-void imx_clko_set_src(int src)
++void imx_clko_set_src(int num, int src)
+ {
+ unsigned long ccsr;
+
++ if (num != 1)
++ return;
++
+ if (src < 0) {
+ PCDR0 &= ~(1 << 25);
+ return;
+diff --git a/arch/arm/mach-imx/speed-imx35.c b/arch/arm/mach-imx/speed-imx35.c
+index 1e1c39f..684dc14 100644
+--- a/arch/arm/mach-imx/speed-imx35.c
++++ b/arch/arm/mach-imx/speed-imx35.c
+@@ -16,6 +16,7 @@
+ */
+
+ #include <common.h>
++#include <asm-generic/errno.h>
+ #include <mach/imx-regs.h>
+ #include <io.h>
+ #include <mach/clock.h>
+@@ -84,7 +85,7 @@ unsigned long imx_get_ahbclk(void)
+ return fref / aad->ahb;
+ }
+
+-static unsigned long imx_get_ipgclk(void)
++unsigned long imx_get_ipgclk(void)
+ {
+ ulong clk = imx_get_ahbclk();
+
+@@ -203,10 +204,13 @@ void imx_dump_clocks(void)
+ * the new divider (which may be smaller
+ * than the desired one)
+ */
+-int imx_clko_set_div(int div)
++int imx_clko_set_div(int num, int div)
+ {
+ unsigned long cosr = readl(IMX_CCM_BASE + CCM_COSR);
+
++ if (num != 1)
++ return -ENODEV;
++
+ div -= 1;
+ div &= 0x3f;
+
+@@ -221,10 +225,13 @@ int imx_clko_set_div(int div)
+ /*
+ * Set the clock source for the CLKO pin
+ */
+-void imx_clko_set_src(int src)
++void imx_clko_set_src(int num, int src)
+ {
+ unsigned long cosr = readl(IMX_CCM_BASE + CCM_COSR);
+
++ if (num != 1)
++ return;
++
+ if (src < 0) {
+ cosr &= ~(1 << 5);
+ writel(cosr, IMX_CCM_BASE + CCM_COSR);
+diff --git a/arch/arm/mach-imx/speed-imx51.c b/arch/arm/mach-imx/speed-imx51.c
+index 8d1ecf3..87fbc75 100644
+--- a/arch/arm/mach-imx/speed-imx51.c
++++ b/arch/arm/mach-imx/speed-imx51.c
+@@ -1,12 +1,19 @@
+ #include <common.h>
+ #include <io.h>
+ #include <asm-generic/div64.h>
++#include <asm-generic/errno.h>
+ #include <mach/imx51-regs.h>
++#include <mach/clock.h>
+ #include <mach/clock-imx51_53.h>
+
+ static u32 ccm_readl(u32 ofs)
+ {
+- return readl(MX51_CCM_BASE_ADDR + ofs);
++ return readl(IOMEM(MX51_CCM_BASE_ADDR) + ofs);
++}
++
++static void ccm_writel(u32 val, u32 ofs)
++{
++ writel(val, MX51_CCM_BASE_ADDR + ofs);
+ }
+
+ static unsigned long ckil_get_rate(void)
+@@ -142,7 +149,7 @@ unsigned long imx_get_uartclk(void)
+ return parent_rate / (prediv * podf);
+ }
+
+-static unsigned long imx_get_ahbclk(void)
++unsigned long imx_get_ahbclk(void)
+ {
+ u32 reg, div;
+
+@@ -221,6 +228,70 @@ unsigned long imx_get_usbclk(void)
+ return rate / (prediv * podf);
+ }
+
++/*
++ * Set the divider of the CLKO pin. Returns
++ * the new divider (which may be smaller
++ * than the desired one)
++ */
++int imx_clko_set_div(int num, int div)
++{
++ u32 ccosr = ccm_readl(MX5_CCM_CCOSR);
++
++ div--;
++
++ switch (num) {
++ case 1:
++ div &= 0x7;
++ ccosr &= ~(0x7 << 4);
++ ccosr |= div << 4;
++ ccm_writel(ccosr, MX5_CCM_CCOSR);
++ break;
++ case 2:
++ div &= 0x7;
++ ccosr &= ~(0x7 << 21);
++ ccosr |= div << 21;
++ ccm_writel(ccosr, MX5_CCM_CCOSR);
++ break;
++ default:
++ return -ENODEV;
++ }
++
++ return div + 1;
++}
++
++/*
++ * Set the clock source for the CLKO pin
++ */
++void imx_clko_set_src(int num, int src)
++{
++ u32 ccosr = ccm_readl(MX5_CCM_CCOSR);
++
++ switch (num) {
++ case 1:
++ if (src < 0) {
++ ccosr &= ~(1 << 7);
++ break;
++ }
++ ccosr &= ~0xf;
++ ccosr |= src & 0xf;
++ ccosr |= 1 << 7;
++ break;
++ case 2:
++ if (src < 0) {
++ ccosr &= ~(1 << 24);
++ break;
++ }
++ ccosr &= ~(0x1f << 16);
++ ccosr |= (src & 0x1f) << 16;
++ ccosr |= 1 << 24;
++ break;
++ default:
++ return;
++ }
++
++ ccm_writel(ccosr, MX5_CCM_CCOSR);
++}
++
+ void imx_dump_clocks(void)
+ {
+ printf("pll1: %ld\n", pll1_main_get_rate());
+diff --git a/arch/arm/mach-imx/speed-imx53.c b/arch/arm/mach-imx/speed-imx53.c
+index 634341e..653dae3 100644
+--- a/arch/arm/mach-imx/speed-imx53.c
++++ b/arch/arm/mach-imx/speed-imx53.c
+@@ -2,6 +2,7 @@
+ #include <io.h>
+ #include <asm-generic/div64.h>
+ #include <mach/imx-regs.h>
++#include <mach/clock.h>
+ #include "mach/clock-imx51_53.h"
+
+ static u32 ccm_readl(u32 ofs)
+@@ -139,7 +140,7 @@ unsigned long imx_get_uartclk(void)
+ return parent_rate / (prediv * podf);
+ }
+
+-static unsigned long imx_get_ahbclk(void)
++unsigned long imx_get_ahbclk(void)
+ {
+ u32 reg, div;
+
+diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
+index 3348a3c..746c986 100644
+--- a/arch/arm/mach-mxs/Kconfig
++++ b/arch/arm/mach-mxs/Kconfig
+@@ -61,6 +61,7 @@ config MACH_TX28
+
+ config MACH_MX28EVK
+ bool "mx28-evk"
++ select MXS_OCOTP
+ help
+ Say Y here if you are using the Freescale i.MX28-EVK board
+
+@@ -80,6 +81,25 @@ config MXS_OCOTP
+ internal view). Don't use register offsets here, the SET, CLR and
+ TGL registers are not mapped!
+
++config MXS_OCOTP_WRITABLE
++ bool "OCOTP write support"
++ depends on MXS_OCOTP
++ help
++ Enable this option to add writing to OCOTP.
++ Warning: blown bits can not be unblown. Use with care.
++
++ Before being actually able to blow the bits, you need to explicitely
++ enable writing:
++ ocotp0.permanent_write_enable=1
++
++config MXS_CMD_BCB
++ depends on NAND_MXS
++ tristate "Nand bcb command"
++ help
++ To be able to boot from NAND the i.MX23/28 need a Boot Control Block
++ in flash. This option enabled the 'bcb' command which can be used to
++ generate this block during runtime.
++
+ endmenu
+
+ menu "Board specific settings "
+diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
+index 172d928..fe93096 100644
+--- a/arch/arm/mach-mxs/Makefile
++++ b/arch/arm/mach-mxs/Makefile
+@@ -1,5 +1,6 @@
+-obj-y += imx.o iomux-imx.o reset-imx.o
++obj-y += imx.o iomux-imx.o power.o common.o
+ obj-$(CONFIG_DRIVER_VIDEO_STM) += imx_lcd_clk.o
+-obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o clocksource-imx23.o usb.o
+-obj-$(CONFIG_ARCH_IMX28) += speed-imx28.o clocksource-imx28.o
++obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o clocksource-imx23.o usb-imx23.o soc-imx23.o
++obj-$(CONFIG_ARCH_IMX28) += speed-imx28.o clocksource-imx28.o usb-imx28.o soc-imx28.o
+ obj-$(CONFIG_MXS_OCOTP) += ocotp.o
++obj-$(CONFIG_MXS_CMD_BCB) += bcb.o
+diff --git a/arch/arm/mach-mxs/bcb.c b/arch/arm/mach-mxs/bcb.c
+new file mode 100644
+index 0000000..d0a3ddc
+--- /dev/null
++++ b/arch/arm/mach-mxs/bcb.c
+@@ -0,0 +1,399 @@
++/*
++ * (C) Copyright 2011 Wolfram Sang, Pengutronix e.K.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * Based on a similar function in Karo Electronics TX28-U-Boot (flash.c).
++ * Probably written by Lothar WaĂźmann (like tx28.c).
++ */
++
++#include <common.h>
++#include <command.h>
++#include <environment.h>
++#include <malloc.h>
++#include <nand.h>
++#include <sizes.h>
++#include <errno.h>
++#include <io.h>
++
++#include <mach/imx-regs.h>
++
++#include <linux/err.h>
++#include <linux/mtd/nand.h>
++
++#define FCB_START_BLOCK 0
++#define NUM_FCB_BLOCKS 1
++#define MAX_FCB_BLOCKS 32768
++
++#define GPMI_TIMING0 0x00000070
++#define GPMI_TIMING0_ADDRESS_SETUP_MASK (0xff << 16)
++#define GPMI_TIMING0_ADDRESS_SETUP_OFFSET 16
++#define GPMI_TIMING0_DATA_HOLD_MASK (0xff << 8)
++#define GPMI_TIMING0_DATA_HOLD_OFFSET 8
++#define GPMI_TIMING0_DATA_SETUP_MASK 0xff
++#define GPMI_TIMING0_DATA_SETUP_OFFSET 0
++
++#define GPMI_TIMING1 0x00000080
++
++#define BCH_MODE 0x00000020
++
++#define BCH_FLASH0LAYOUT0 0x00000080
++#define BCH_FLASHLAYOUT0_NBLOCKS_MASK (0xff << 24)
++#define BCH_FLASHLAYOUT0_NBLOCKS_OFFSET 24
++#define BCH_FLASHLAYOUT0_META_SIZE_MASK (0xff << 16)
++#define BCH_FLASHLAYOUT0_META_SIZE_OFFSET 16
++#define BCH_FLASHLAYOUT0_ECC0_MASK (0xf << 12)
++#define BCH_FLASHLAYOUT0_ECC0_OFFSET 12
++#define BCH_FLASHLAYOUT0_DATA0_SIZE_MASK 0xfff
++#define BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET 0
++
++#define BCH_FLASH0LAYOUT1 0x00000090
++#define BCH_FLASHLAYOUT1_PAGE_SIZE_MASK (0xffff << 16)
++#define BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET 16
++#define BCH_FLASHLAYOUT1_ECCN_MASK (0xf << 12)
++#define BCH_FLASHLAYOUT1_ECCN_OFFSET 12
++#define BCH_FLASHLAYOUT1_DATAN_SIZE_MASK 0xfff
++#define BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET 0
++
++struct mx28_nand_timing {
++ u8 data_setup;
++ u8 data_hold;
++ u8 address_setup;
++ u8 dsample_time;
++ u8 nand_timing_state;
++ u8 tREA;
++ u8 tRLOH;
++ u8 tRHOH;
++};
++
++struct mx28_fcb {
++ u32 checksum;
++ u32 fingerprint;
++ u32 version;
++ struct mx28_nand_timing timing;
++ u32 page_data_size;
++ u32 total_page_size;
++ u32 sectors_per_block;
++ u32 number_of_nands; /* not used by ROM code */
++ u32 total_internal_die; /* not used by ROM code */
++ u32 cell_type; /* not used by ROM code */
++ u32 ecc_blockn_type;
++ u32 ecc_block0_size;
++ u32 ecc_blockn_size;
++ u32 ecc_block0_type;
++ u32 metadata_size;
++ u32 ecc_blocks_per_page;
++ u32 rsrvd[6]; /* not used by ROM code */
++ u32 bch_mode;
++ u32 boot_patch;
++ u32 patch_sectors;
++ u32 fw1_start_page;
++ u32 fw2_start_page;
++ u32 fw1_sectors;
++ u32 fw2_sectors;
++ u32 dbbt_search_area;
++ u32 bb_mark_byte;
++ u32 bb_mark_startbit;
++ u32 bb_mark_phys_offset;
++};
++
++struct mx28_dbbt_header {
++ u32 checksum;
++ u32 fingerprint;
++ u32 version;
++ u32 number_bb;
++ u32 number_pages;
++ u8 spare[492];
++};
++
++struct mx28_dbbt {
++ u32 nand_number;
++ u32 number_bb;
++ u32 bb_num[2040 / 4];
++};
++
++#define BF_VAL(v, bf) (((v) & bf##_MASK) >> bf##_OFFSET)
++#define GETBIT(v,n) (((v) >> (n)) & 0x1)
++
++static u8 calculate_parity_13_8(u8 d)
++{
++ u8 p = 0;
++
++ p |= (GETBIT(d, 6) ^ GETBIT(d, 5) ^ GETBIT(d, 3) ^ GETBIT(d, 2)) << 0;
++ p |= (GETBIT(d, 7) ^ GETBIT(d, 5) ^ GETBIT(d, 4) ^ GETBIT(d, 2) ^ GETBIT(d, 1)) << 1;
++ p |= (GETBIT(d, 7) ^ GETBIT(d, 6) ^ GETBIT(d, 5) ^ GETBIT(d, 1) ^ GETBIT(d, 0)) << 2;
++ p |= (GETBIT(d, 7) ^ GETBIT(d, 4) ^ GETBIT(d, 3) ^ GETBIT(d, 0)) << 3;
++ p |= (GETBIT(d, 6) ^ GETBIT(d, 4) ^ GETBIT(d, 3) ^ GETBIT(d, 2) ^ GETBIT(d, 1) ^ GETBIT(d, 0)) << 4;
++ return p;
++}
++
++static void encode_hamming_13_8(void *_src, void *_ecc, size_t size)
++{
++ int i;
++ u8 *src = _src;
++ u8 *ecc = _ecc;
++
++ for (i = 0; i < size; i++)
++ ecc[i] = calculate_parity_13_8(src[i]);
++}
++
++static u32 calc_chksum(void *buf, size_t size)
++{
++ u32 chksum = 0;
++ u8 *bp = buf;
++ size_t i;
++
++ for (i = 0; i < size; i++)
++ chksum += bp[i];
++
++ return ~chksum;
++}
++
++/*
++ Physical organisation of data in NAND flash:
++ metadata
++ payload chunk 0 (may be empty)
++ ecc for metadata + payload chunk 0
++ payload chunk 1
++ ecc for payload chunk 1
++...
++ payload chunk n
++ ecc for payload chunk n
++ */
++
++static int calc_bb_offset(struct mtd_info *mtd, struct mx28_fcb *fcb)
++{
++ int bb_mark_offset;
++ int chunk_data_size = fcb->ecc_blockn_size * 8;
++ int chunk_ecc_size = (fcb->ecc_blockn_type << 1) * 13;
++ int chunk_total_size = chunk_data_size + chunk_ecc_size;
++ int bb_mark_chunk, bb_mark_chunk_offs;
++
++ bb_mark_offset = (mtd->writesize - fcb->metadata_size) * 8;
++ if (fcb->ecc_block0_size == 0)
++ bb_mark_offset -= (fcb->ecc_block0_type << 1) * 13;
++
++ bb_mark_chunk = bb_mark_offset / chunk_total_size;
++ bb_mark_chunk_offs = bb_mark_offset - (bb_mark_chunk * chunk_total_size);
++ if (bb_mark_chunk_offs > chunk_data_size) {
++ printf("Unsupported ECC layout; BB mark resides in ECC data: %u\n",
++ bb_mark_chunk_offs);
++ return -EINVAL;
++ }
++ bb_mark_offset -= bb_mark_chunk * chunk_ecc_size;
++ return bb_mark_offset;
++}
++
++static struct mx28_fcb *create_fcb(struct mtd_info *mtd, void *buf, unsigned fw1_start_block,
++ size_t fw_size, unsigned fw2_start_block)
++{
++ u32 fl0, fl1, t0;
++ int metadata_size;
++ int bb_mark_bit_offs;
++ struct mx28_fcb *fcb;
++ int fcb_offs;
++ void __iomem *bch_regs = (void *)MXS_BCH_BASE;
++ void __iomem *gpmi_regs = (void *)MXS_GPMI_BASE;
++
++ fl0 = readl(bch_regs + BCH_FLASH0LAYOUT0);
++ fl1 = readl(bch_regs + BCH_FLASH0LAYOUT1);
++ t0 = readl(gpmi_regs + GPMI_TIMING0);
++ metadata_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_META_SIZE);
++
++ fcb = buf + ALIGN(metadata_size, 4);
++ fcb_offs = (void *)fcb - buf;
++
++ memset(buf, 0x00, fcb_offs);
++ memset(fcb, 0x00, sizeof(*fcb));
++ memset(fcb + 1, 0xff, mtd->erasesize - fcb_offs - sizeof(*fcb));
++
++ strncpy((char *)&fcb->fingerprint, "FCB ", 4);
++ fcb->version = cpu_to_be32(1);
++
++ fcb->timing.data_setup = BF_VAL(t0, GPMI_TIMING0_DATA_SETUP);
++ fcb->timing.data_hold = BF_VAL(t0, GPMI_TIMING0_DATA_HOLD);
++ fcb->timing.address_setup = BF_VAL(t0, GPMI_TIMING0_ADDRESS_SETUP);
++
++ fcb->page_data_size = mtd->writesize;
++ fcb->total_page_size = mtd->writesize + mtd->oobsize;
++ fcb->sectors_per_block = mtd->erasesize / mtd->writesize;
++
++ fcb->ecc_block0_type = BF_VAL(fl0, BCH_FLASHLAYOUT0_ECC0);
++ fcb->ecc_block0_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_DATA0_SIZE);
++ fcb->ecc_blockn_type = BF_VAL(fl1, BCH_FLASHLAYOUT1_ECCN);
++ fcb->ecc_blockn_size = BF_VAL(fl1, BCH_FLASHLAYOUT1_DATAN_SIZE);
++
++ fcb->metadata_size = BF_VAL(fl0, BCH_FLASHLAYOUT0_META_SIZE);
++ fcb->ecc_blocks_per_page = BF_VAL(fl0, BCH_FLASHLAYOUT0_NBLOCKS);
++ fcb->bch_mode = readl(bch_regs + BCH_MODE);
++/*
++ fcb->boot_patch = 0;
++ fcb->patch_sectors = 0;
++*/
++ fcb->fw1_start_page = fw1_start_block / mtd->writesize;
++ fcb->fw1_sectors = DIV_ROUND_UP(fw_size, mtd->writesize);
++
++ if (fw2_start_block != 0 && fw2_start_block < mtd->size / mtd->erasesize) {
++ fcb->fw2_start_page = fw2_start_block / mtd->writesize;
++ fcb->fw2_sectors = fcb->fw1_sectors;
++ }
++
++ fcb->dbbt_search_area = 1;
++
++ bb_mark_bit_offs = calc_bb_offset(mtd, fcb);
++ if (bb_mark_bit_offs < 0)
++ return ERR_PTR(bb_mark_bit_offs);
++ fcb->bb_mark_byte = bb_mark_bit_offs / 8;
++ fcb->bb_mark_startbit = bb_mark_bit_offs % 8;
++ fcb->bb_mark_phys_offset = mtd->writesize;
++
++ fcb->checksum = calc_chksum(&fcb->fingerprint, 512 - 4);
++ return fcb;
++}
++
++static int find_fcb(struct mtd_info *mtd, void *ref, int page)
++{
++ int ret = 0;
++ struct nand_chip *chip = mtd->priv;
++ void *buf = malloc(mtd->erasesize);
++
++ if (buf == NULL)
++ return -ENOMEM;
++
++ chip->select_chip(mtd, 0);
++ chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
++ ret = chip->ecc.read_page_raw(mtd, chip, buf);
++ if (ret) {
++ printf("Failed to read FCB from page %u: %d\n", page, ret);
++ return ret;
++ }
++ chip->select_chip(mtd, -1);
++ if (memcmp(buf, ref, mtd->writesize) == 0) {
++ printf("%s: Found FCB in page %u (%08x)\n", __func__,
++ page, page * mtd->writesize);
++ ret = 1;
++ }
++ free(buf);
++ return ret;
++}
++
++static int write_fcb(struct mtd_info *mtd, void *buf, int block)
++{
++ int ret;
++ struct nand_chip *chip = mtd->priv;
++ int page = block / mtd->writesize;
++ struct erase_info erase_opts = {
++ .mtd = mtd,
++ .addr = block,
++ .len = mtd->erasesize,
++ .callback = NULL,
++ };
++
++ ret = find_fcb(mtd, buf, page);
++ if (ret > 0) {
++ printf("FCB at block %08x is up to date\n", block);
++ return 0;
++ }
++
++ ret = mtd->erase(mtd, &erase_opts);
++ if (ret) {
++ printf("Failed to erase FCB block %08x\n", block);
++ return ret;
++ }
++
++ printf("Writing FCB to block %08x\n", block);
++ chip->select_chip(mtd, 0);
++ ret = chip->write_page(mtd, chip, buf, page, 0, 1);
++ if (ret) {
++ printf("Failed to write FCB to block %08x: %d\n", block, ret);
++ }
++ chip->select_chip(mtd, -1);
++ return ret;
++}
++
++int update_bcb(int argc, char *argv[])
++{
++ int ret;
++ int block;
++ void *buf;
++ struct mx28_fcb *fcb;
++ struct cdev *tmp_cdev, *bcb_cdev, *firmware_cdev;
++ unsigned long fw2_offset = 0;
++ struct mtd_info *mtd;
++ unsigned fcb_written = 0;
++
++ if (argc == 1)
++ return COMMAND_ERROR_USAGE;
++
++ tmp_cdev = cdev_by_name("nand0");
++ if (!tmp_cdev || !tmp_cdev->mtd) {
++ pr_err("%s: No NAND device!\n", __func__);
++ return -ENODEV;
++ }
++
++ mtd = tmp_cdev->mtd;
++
++ bcb_cdev = cdev_by_name("nand0.bcb");
++ if (!bcb_cdev) {
++ pr_err("%s: No FCB device!\n", __func__);
++ return -ENODEV;
++ }
++
++ firmware_cdev = cdev_by_name(argv[1]);
++ if (!firmware_cdev) {
++ pr_err("%s: Bootstream-Image not found!\n", __func__);
++ return -ENODEV;
++ }
++
++ if (argc > 2) {
++ tmp_cdev = cdev_by_name(argv[2]);
++ if (!tmp_cdev) {
++ pr_err("%s: Redundant Bootstream-Image not found!\n", __func__);
++ return -ENODEV;
++ }
++ fw2_offset = tmp_cdev->offset;
++ }
++
++ buf = malloc(mtd->erasesize);
++ if (!buf)
++ return -ENOMEM;
++
++ fcb = create_fcb(mtd, buf, firmware_cdev->offset, firmware_cdev->size, fw2_offset);
++ if (IS_ERR(fcb)) {
++ printf("Failed to initialize FCB: %ld\n", PTR_ERR(fcb));
++ return PTR_ERR(fcb);
++ }
++ encode_hamming_13_8(fcb, (void *)fcb + 512, 512);
++
++ for (block = bcb_cdev->offset; block < bcb_cdev->offset + bcb_cdev->size / 2;
++ block += mtd->erasesize) {
++
++ if (nand_isbad_bbt(mtd, block, false))
++ continue;
++
++ ret = write_fcb(mtd, buf, block);
++ if (ret) {
++ printf("Failed to write FCB to block %u\n", block);
++ return ret;
++ }
++
++ fcb_written++;
++ }
++
++ return fcb_written ? 0 : -ENOSPC;
++}
++
++BAREBOX_CMD_HELP_START(bcb)
++BAREBOX_CMD_HELP_USAGE("bcb <first_bootstream> [second_bootstream]\n")
++BAREBOX_CMD_HELP_SHORT("Write a BCB to NAND flash which an MX23/28 needs to boot.\n")
++BAREBOX_CMD_HELP_TEXT ("Example: bcb nand0.bootstream\n")
++BAREBOX_CMD_HELP_END
++
++BAREBOX_CMD_START(bcb)
++ .cmd = update_bcb,
++ .usage = "Writes a MX23/28 BCB data structure to flash",
++ BAREBOX_CMD_HELP(cmd_bcb_help)
++BAREBOX_CMD_END
+diff --git a/arch/arm/mach-mxs/common.c b/arch/arm/mach-mxs/common.c
+new file mode 100644
+index 0000000..3730633
+--- /dev/null
++++ b/arch/arm/mach-mxs/common.c
+@@ -0,0 +1,33 @@
++#include <common.h>
++#include <io.h>
++#include <mach/mxs.h>
++#include <mach/imx-regs.h>
++
++#define MXS_BLOCK_SFTRST (1 << 31)
++#define MXS_BLOCK_CLKGATE (1 << 30)
++
++int mxs_reset_block(void __iomem *reg, int just_enable)
++{
++ /* Clear SFTRST */
++ writel(MXS_BLOCK_SFTRST, reg + BIT_CLR);
++ mdelay(1);
++
++ /* Clear CLKGATE */
++ writel(MXS_BLOCK_CLKGATE, reg + BIT_CLR);
++
++ if (!just_enable) {
++ /* Set SFTRST */
++ writel(MXS_BLOCK_SFTRST, reg + BIT_SET);
++ mdelay(1);
++ }
++
++ /* Clear SFTRST */
++ writel(MXS_BLOCK_SFTRST, reg + BIT_CLR);
++ mdelay(1);
++
++ /* Clear CLKGATE */
++ writel(MXS_BLOCK_CLKGATE, reg + BIT_CLR);
++ mdelay(1);
++
++ return 0;
++}
+diff --git a/arch/arm/mach-mxs/include/mach/clock-imx23.h b/arch/arm/mach-mxs/include/mach/clock-imx23.h
+index 723f343..6507792 100644
+--- a/arch/arm/mach-mxs/include/mach/clock-imx23.h
++++ b/arch/arm/mach-mxs/include/mach/clock-imx23.h
+@@ -18,11 +18,13 @@ unsigned imx_get_emiclk(void);
+ unsigned imx_get_ioclk(void);
+ unsigned imx_get_armclk(void);
+ unsigned imx_get_hclk(void);
++unsigned imx_set_hclk(unsigned);
+ unsigned imx_get_xclk(void);
+ unsigned imx_get_sspclk(unsigned);
+ unsigned imx_set_sspclk(unsigned, unsigned, int);
+ unsigned imx_set_ioclk(unsigned);
+ unsigned imx_set_lcdifclk(unsigned);
+ unsigned imx_get_lcdifclk(void);
++void imx_enable_nandclk(void);
+
+ #endif /* MACH_CLOCK_IMX23_H */
+diff --git a/arch/arm/mach-mxs/include/mach/clock-imx28.h b/arch/arm/mach-mxs/include/mach/clock-imx28.h
+index 45fb043..0604f0a 100644
+--- a/arch/arm/mach-mxs/include/mach/clock-imx28.h
++++ b/arch/arm/mach-mxs/include/mach/clock-imx28.h
+@@ -18,6 +18,7 @@ unsigned imx_get_emiclk(void);
+ unsigned imx_get_ioclk(unsigned);
+ unsigned imx_get_armclk(void);
+ unsigned imx_get_hclk(void);
++unsigned imx_set_hclk(unsigned);
+ unsigned imx_get_xclk(void);
+ unsigned imx_get_sspclk(unsigned);
+ unsigned imx_set_sspclk(unsigned, unsigned, int);
+@@ -26,6 +27,7 @@ unsigned imx_set_lcdifclk(unsigned);
+ unsigned imx_get_lcdifclk(void);
+ unsigned imx_get_fecclk(void);
+ void imx_enable_enetclk(void);
++void imx_enable_nandclk(void);
+
+ #endif /* MACH_CLOCK_IMX28_H */
+
+diff --git a/arch/arm/mach-mxs/include/mach/dma.h b/arch/arm/mach-mxs/include/mach/dma.h
+new file mode 100644
+index 0000000..52747e2
+--- /dev/null
++++ b/arch/arm/mach-mxs/include/mach/dma.h
+@@ -0,0 +1,145 @@
++/*
++ * Freescale i.MX28 APBH DMA
++ *
++ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
++ * on behalf of DENX Software Engineering GmbH
++ *
++ * Based on code from LTIB:
++ * Copyright 2008-2010 Freescale Semiconductor, Inc. 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 as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ *
++ */
++
++#ifndef __DMA_H__
++#define __DMA_H__
++
++#include <linux/list.h>
++
++#ifndef CONFIG_ARCH_DMA_PIO_WORDS
++#define DMA_PIO_WORDS 15
++#else
++#define DMA_PIO_WORDS CONFIG_ARCH_DMA_PIO_WORDS
++#endif
++
++#define MXS_DMA_ALIGNMENT 32
++
++/*
++ * MXS DMA channels
++ */
++enum {
++ MXS_DMA_CHANNEL_AHB_APBH_SSP0 = 0,
++ MXS_DMA_CHANNEL_AHB_APBH_SSP1,
++ MXS_DMA_CHANNEL_AHB_APBH_SSP2,
++ MXS_DMA_CHANNEL_AHB_APBH_SSP3,
++ MXS_DMA_CHANNEL_AHB_APBH_GPMI0,
++ MXS_DMA_CHANNEL_AHB_APBH_GPMI1,
++ MXS_DMA_CHANNEL_AHB_APBH_GPMI2,
++ MXS_DMA_CHANNEL_AHB_APBH_GPMI3,
++ MXS_DMA_CHANNEL_AHB_APBH_GPMI4,
++ MXS_DMA_CHANNEL_AHB_APBH_GPMI5,
++ MXS_DMA_CHANNEL_AHB_APBH_GPMI6,
++ MXS_DMA_CHANNEL_AHB_APBH_GPMI7,
++ MXS_DMA_CHANNEL_AHB_APBH_SSP,
++ MXS_MAX_DMA_CHANNELS,
++};
++
++/*
++ * MXS DMA hardware command.
++ *
++ * This structure describes the in-memory layout of an entire DMA command,
++ * including space for the maximum number of PIO accesses. See the appropriate
++ * reference manual for a detailed description of what these fields mean to the
++ * DMA hardware.
++ */
++#define MXS_DMA_DESC_COMMAND_MASK 0x3
++#define MXS_DMA_DESC_COMMAND_OFFSET 0
++#define MXS_DMA_DESC_COMMAND_NO_DMAXFER 0x0
++#define MXS_DMA_DESC_COMMAND_DMA_WRITE 0x1
++#define MXS_DMA_DESC_COMMAND_DMA_READ 0x2
++#define MXS_DMA_DESC_COMMAND_DMA_SENSE 0x3
++#define MXS_DMA_DESC_CHAIN (1 << 2)
++#define MXS_DMA_DESC_IRQ (1 << 3)
++#define MXS_DMA_DESC_NAND_LOCK (1 << 4)
++#define MXS_DMA_DESC_NAND_WAIT_4_READY (1 << 5)
++#define MXS_DMA_DESC_DEC_SEM (1 << 6)
++#define MXS_DMA_DESC_WAIT4END (1 << 7)
++#define MXS_DMA_DESC_HALT_ON_TERMINATE (1 << 8)
++#define MXS_DMA_DESC_TERMINATE_FLUSH (1 << 9)
++#define MXS_DMA_DESC_PIO_WORDS_MASK (0xf << 12)
++#define MXS_DMA_DESC_PIO_WORDS_OFFSET 12
++#define MXS_DMA_DESC_BYTES_MASK (0xffff << 16)
++#define MXS_DMA_DESC_BYTES_OFFSET 16
++
++struct mxs_dma_cmd {
++ unsigned long next;
++ unsigned long data;
++ union {
++ dma_addr_t address;
++ unsigned long alternate;
++ };
++ unsigned long pio_words[DMA_PIO_WORDS];
++};
++
++/*
++ * MXS DMA command descriptor.
++ *
++ * This structure incorporates an MXS DMA hardware command structure, along
++ * with metadata.
++ */
++#define MXS_DMA_DESC_FIRST (1 << 0)
++#define MXS_DMA_DESC_LAST (1 << 1)
++#define MXS_DMA_DESC_READY (1 << 31)
++
++struct mxs_dma_desc {
++ struct mxs_dma_cmd cmd;
++ unsigned int flags;
++ dma_addr_t address;
++ void *buffer;
++ struct list_head node;
++};
++
++/**
++ * MXS DMA channel
++ *
++ * This structure represents a single DMA channel. The MXS platform code
++ * maintains an array of these structures to represent every DMA channel in the
++ * system (see mxs_dma_channels).
++ */
++#define MXS_DMA_FLAGS_IDLE 0
++#define MXS_DMA_FLAGS_BUSY (1 << 0)
++#define MXS_DMA_FLAGS_FREE 0
++#define MXS_DMA_FLAGS_ALLOCATED (1 << 16)
++#define MXS_DMA_FLAGS_VALID (1 << 31)
++
++struct mxs_dma_chan {
++ const char *name;
++ unsigned long dev;
++ struct mxs_dma_device *dma;
++ unsigned int flags;
++ unsigned int active_num;
++ unsigned int pending_num;
++ struct list_head active;
++ struct list_head done;
++};
++
++struct mxs_dma_desc *mxs_dma_desc_alloc(void);
++void mxs_dma_desc_free(struct mxs_dma_desc *);
++int mxs_dma_desc_append(int channel, struct mxs_dma_desc *pdesc);
++
++int mxs_dma_go(int chan);
++int mxs_dma_init(void);
++
++#endif /* __DMA_H__ */
+diff --git a/arch/arm/mach-mxs/include/mach/imx23-regs.h b/arch/arm/mach-mxs/include/mach/imx23-regs.h
+index 60f5bf9..7ea3057 100644
+--- a/arch/arm/mach-mxs/include/mach/imx23-regs.h
++++ b/arch/arm/mach-mxs/include/mach/imx23-regs.h
+@@ -27,6 +27,9 @@
+ #endif
+
+ #define IMX_MEMORY_BASE 0x40000000
++#define MXS_APBH_BASE 0x80004000
++#define MXS_BCH_BASE 0x8000a000
++#define MXS_GPMI_BASE 0x8000c000
+ #define IMX_UART1_BASE 0x8006c000
+ #define IMX_UART2_BASE 0x8006e000
+ #define IMX_DBGUART_BASE 0x80070000
+diff --git a/arch/arm/mach-mxs/include/mach/imx28-regs.h b/arch/arm/mach-mxs/include/mach/imx28-regs.h
+index 9a2052c..16bf5f7 100644
+--- a/arch/arm/mach-mxs/include/mach/imx28-regs.h
++++ b/arch/arm/mach-mxs/include/mach/imx28-regs.h
+@@ -23,15 +23,19 @@
+ #define IMX_SRAM_BASE 0x00000000
+ #define IMX_MEMORY_BASE 0x40000000
+
+-#define IMX_NFC_BASE 0x8000C000
++#define MXS_APBH_BASE 0x80004000
++#define MXS_BCH_BASE 0x8000a000
++#define MXS_GPMI_BASE 0x8000c000
+ #define IMX_SSP0_BASE 0x80010000
+ #define IMX_SSP1_BASE 0x80012000
+ #define IMX_SSP2_BASE 0x80014000
+ #define IMX_SSP3_BASE 0x80016000
+ #define IMX_IOMUXC_BASE 0x80018000
++#define IMX_DIGCTL_BASE 0x8001c000
+ #define IMX_OCOTP_BASE 0x8002c000
+ #define IMX_FB_BASE 0x80030000
+ #define IMX_CCM_BASE 0x80040000
++#define IMX_POWER_BASE 0x80044000
+ #define IMX_WDT_BASE 0x80056000
+ #define IMX_I2C0_BASE 0x80058000
+ #define IMX_I2C1_BASE 0x8005a000
+@@ -42,6 +46,9 @@
+ #define IMX_UART3_BASE 0x80070000
+ #define IMX_UART4_BASE 0x80072000
+ #define IMX_DBGUART_BASE 0x80074000
++#define IMX_USBPHY0_BASE 0x8007c000
++#define IMX_USBPHY1_BASE 0x8007e000
++#define IMX_USB_BASE 0x80080000
+ #define IMX_FEC0_BASE 0x800F0000
+ #define IMX_FEC1_BASE 0x800F4000
+
+diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
+new file mode 100644
+index 0000000..182ed8a
+--- /dev/null
++++ b/arch/arm/mach-mxs/include/mach/mxs.h
+@@ -0,0 +1,6 @@
++#ifndef __MACH_MXS_H
++#define __MACH_MXS_H
++
++int mxs_reset_block(void __iomem *reg, int just_enable);
++
++#endif /* __MACH_MXS_H */
+diff --git a/arch/arm/mach-mxs/include/mach/power.h b/arch/arm/mach-mxs/include/mach/power.h
+new file mode 100644
+index 0000000..f429b3c
+--- /dev/null
++++ b/arch/arm/mach-mxs/include/mach/power.h
+@@ -0,0 +1,8 @@
++#ifndef __MACH_POWER_H
++#define __MACH_POWER_H
++
++void imx_power_prepare_usbphy(void);
++int imx_get_vddio(void);
++int imx_set_vddio(int);
++
++#endif /* __MACH_POWER_H */
+diff --git a/arch/arm/mach-mxs/include/mach/usb.h b/arch/arm/mach-mxs/include/mach/usb.h
+index af7d885..2d31b0d 100644
+--- a/arch/arm/mach-mxs/include/mach/usb.h
++++ b/arch/arm/mach-mxs/include/mach/usb.h
+@@ -1,6 +1,9 @@
+ #ifndef __MACH_USB_H
+ #define __MACH_USB_H
+
+-int imx_usb_phy_enable(void);
++int imx23_usb_phy_enable(void);
++
++int imx28_usb_phy0_enable(void);
++int imx28_usb_phy1_enable(void);
+
+ #endif /* __MACH_USB_H */
+diff --git a/arch/arm/mach-mxs/iomux-imx.c b/arch/arm/mach-mxs/iomux-imx.c
+index 6bcde03..a3ecb94 100644
+--- a/arch/arm/mach-mxs/iomux-imx.c
++++ b/arch/arm/mach-mxs/iomux-imx.c
+@@ -131,7 +131,7 @@ void imx_gpio_mode(uint32_t m)
+ if (BK_PRESENT(m)) {
+ reg_offset = calc_pullup_reg(gpio_pin);
+ writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset +
+- (GET_BITKEEPER(m) == 1 ? BIT_SET : BIT_CLR));
++ (GET_BITKEEPER(m) == 1 ? BIT_CLR : BIT_SET));
+ }
+
+ if (GET_FUNC(m) == IS_GPIO) {
+diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
+index 38f9ffd..7824402 100644
+--- a/arch/arm/mach-mxs/ocotp.c
++++ b/arch/arm/mach-mxs/ocotp.c
+@@ -25,27 +25,45 @@
+ #include <mach/generic.h>
+ #include <mach/ocotp.h>
+ #include <mach/imx-regs.h>
++#include <mach/clock-imx28.h>
++#include <mach/power.h>
+
+ #define DRIVERNAME "ocotp"
+
+-#define OCOTP_WORD_OFFSET 0x20
++#define OCOTP_CTRL 0x0
++# define OCOTP_CTRL_ADDR_MASK 0x3f
++# define OCOTP_CTRL_BUSY (1 << 8)
++# define OCOTP_CTRL_ERROR (1 << 9)
++# define OCOTP_CTRL_RD_BANK_OPEN (1 << 12)
++# define OCOTP_CTRL_WR_UNLOCK 0x3e770000
++
++#define OCOTP_DATA 0x10
+
+-#define BM_OCOTP_CTRL_BUSY (1 << 8)
+-#define BM_OCOTP_CTRL_ERROR (1 << 9)
+-#define BM_OCOTP_CTRL_RD_BANK_OPEN (1 << 12)
++#define OCOTP_WORD_OFFSET 0x20
+
+ struct ocotp_priv {
+ struct cdev cdev;
+ void __iomem *base;
+ };
+
++static int mxs_ocotp_wait_busy(struct ocotp_priv *priv)
++{
++ uint64_t start = get_time_ns();
++
++ /* check both BUSY and ERROR cleared */
++ while (readl(priv->base + OCOTP_CTRL) & (OCOTP_CTRL_BUSY | OCOTP_CTRL_ERROR))
++ if (is_timeout(start, MSECOND))
++ return -ETIMEDOUT;
++
++ return 0;
++}
++
+ static ssize_t mxs_ocotp_cdev_read(struct cdev *cdev, void *buf, size_t count,
+- ulong offset, ulong flags)
++ loff_t offset, ulong flags)
+ {
+ struct ocotp_priv *priv = cdev->priv;
+ void __iomem *base = priv->base;
+- size_t size = min((ulong)count, cdev->size - offset);
+- uint64_t start;
++ size_t size = min((loff_t)count, cdev->size - offset);
+ int i;
+
+ /*
+@@ -54,25 +72,20 @@ static ssize_t mxs_ocotp_cdev_read(struct cdev *cdev, void *buf, size_t count,
+ */
+
+ /* try to clear ERROR bit */
+- writel(BM_OCOTP_CTRL_ERROR, base + BIT_CLR);
++ writel(OCOTP_CTRL_ERROR, base + OCOTP_CTRL + BIT_CLR);
+
+- /* check both BUSY and ERROR cleared */
+- start = get_time_ns();
+- while (readl(base) & (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR))
+- if (is_timeout(start, MSECOND))
+- return -ETIMEDOUT;
++ if (mxs_ocotp_wait_busy(priv))
++ return -ETIMEDOUT;
+
+ /* open OCOTP banks for read */
+- writel(BM_OCOTP_CTRL_RD_BANK_OPEN, base + BIT_SET);
++ writel(OCOTP_CTRL_RD_BANK_OPEN, base + OCOTP_CTRL + BIT_SET);
+
+ /* approximately wait 32 hclk cycles */
+ udelay(1);
+
+ /* poll BUSY bit becoming cleared */
+- start = get_time_ns();
+- while (readl(base) & BM_OCOTP_CTRL_BUSY)
+- if (is_timeout(start, MSECOND))
+- return -ETIMEDOUT;
++ if (mxs_ocotp_wait_busy(priv))
++ return -ETIMEDOUT;
+
+ for (i = 0; i < size; i++)
+ /* When reading bytewise, we need to hop over the SET/CLR/TGL regs */
+@@ -80,16 +93,107 @@ static ssize_t mxs_ocotp_cdev_read(struct cdev *cdev, void *buf, size_t count,
+ (((i + offset) & 0xfc) << 2) + ((i + offset) & 3));
+
+ /* close banks for power saving */
+- writel(BM_OCOTP_CTRL_RD_BANK_OPEN, base + BIT_CLR);
++ writel(OCOTP_CTRL_RD_BANK_OPEN, base + OCOTP_CTRL + BIT_CLR);
+
+ return size;
+ }
+
++static ssize_t mxs_ocotp_cdev_write(struct cdev *cdev, const void *buf, size_t count,
++ loff_t offset, ulong flags)
++{
++ struct ocotp_priv *priv = cdev->priv;
++ void __iomem *base = priv->base;
++ const char *write_param;
++ unsigned int write_enabled = 0;
++ unsigned long old_hclk, aligned_offset;
++ int old_vddio, num_words, num_bytes, i, ret = 0;
++ u8 *work_buf;
++ u32 reg;
++
++ write_param = dev_get_param(cdev->dev, "permanent_write_enable");
++ if (write_param)
++ write_enabled = simple_strtoul(write_param, NULL, 0);
++
++ if (!write_param || !write_enabled)
++ return -EPERM;
++
++ /* we can only work on u32, so calc some helpers */
++ aligned_offset = offset & ~3UL;
++ num_words = DIV_ROUND_UP(offset - aligned_offset + count, 4);
++ num_bytes = num_words << 2;
++
++ /* read in all words which will be modified */
++ work_buf = xmalloc(num_bytes);
++
++ i = mxs_ocotp_cdev_read(cdev, work_buf, num_bytes, aligned_offset, 0);
++ if (i != num_bytes) {
++ ret = -ENXIO;
++ goto free_mem;
++ }
++
++ /* modify read words with to be written data */
++ for (i = 0; i < count; i++)
++ work_buf[offset - aligned_offset + i] |= ((u8 *)buf)[i];
++
++ /* prepare system for OTP write */
++ old_hclk = imx_get_hclk();
++ old_vddio = imx_get_vddio();
++
++ imx_set_hclk(24000000);
++ imx_set_vddio(2800000);
++
++ writel(OCOTP_CTRL_RD_BANK_OPEN, base + OCOTP_CTRL + BIT_CLR);
++
++ if (mxs_ocotp_wait_busy(priv)) {
++ ret = -ETIMEDOUT;
++ goto restore_system;
++ }
++
++ /* write word for word via data register */
++ for (i = 0; i < num_words; i++) {
++ reg = readl(base + OCOTP_CTRL) & ~OCOTP_CTRL_ADDR_MASK;
++ reg |= OCOTP_CTRL_WR_UNLOCK | ((aligned_offset >> 2) + i);
++ writel(reg, base + OCOTP_CTRL);
++
++ writel(((u32 *)work_buf)[i], base + OCOTP_DATA);
++
++ if (mxs_ocotp_wait_busy(priv)) {
++ ret = -ETIMEDOUT;
++ goto restore_system;
++ }
++
++ mdelay(2);
++ }
++
++restore_system:
++ imx_set_vddio(old_vddio);
++ imx_set_hclk(old_hclk);
++free_mem:
++ free(work_buf);
++
++ return ret;
++}
++
+ static struct file_operations mxs_ocotp_ops = {
+ .read = mxs_ocotp_cdev_read,
+ .lseek = dev_lseek_default,
+ };
+
++static int mxs_ocotp_write_enable_set(struct device_d *dev, struct param_d *param,
++ const char *val)
++{
++ unsigned long write_enable;
++
++ if (!val)
++ return -EINVAL;
++
++ write_enable = simple_strtoul(val, NULL, 0);
++ if (write_enable > 1)
++ return -EINVAL;
++
++ return dev_param_set_generic(dev, param, write_enable ? "1" : "0");
++}
++
+ static int mxs_ocotp_probe(struct device_d *dev)
+ {
+ int err;
+@@ -106,6 +210,18 @@ static int mxs_ocotp_probe(struct device_d *dev)
+ if (err < 0)
+ return err;
+
++ if (IS_ENABLED(CONFIG_MXS_OCOTP_WRITABLE)) {
++ mxs_ocotp_ops.write = mxs_ocotp_cdev_write;
++
++ err = dev_add_param(dev, "permanent_write_enable",
++ mxs_ocotp_write_enable_set, NULL, 0);
++ if (err < 0)
++ return err;
++ err = dev_set_param(dev, "permanent_write_enable", "0");
++ if (err < 0)
++ return err;
++ }
++
+ return 0;
+ }
+
+diff --git a/arch/arm/mach-mxs/power.c b/arch/arm/mach-mxs/power.c
+new file mode 100644
+index 0000000..f4d0b9e
+--- /dev/null
++++ b/arch/arm/mach-mxs/power.c
+@@ -0,0 +1,84 @@
++/*
++ * i.MX28 power related functions
++ *
++ * Copyright 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
++ * Copyright (C) 2012 Wolfram Sang, Pengutronix <w.sang@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++#include <common.h>
++#include <io.h>
++#include <errno.h>
++#include <mach/imx-regs.h>
++
++#define POWER_CTRL (IMX_POWER_BASE + 0x0)
++#define POWER_CTRL_CLKGATE 0x40000000
++
++#define POWER_VDDIOCTRL (IMX_POWER_BASE + 0x60)
++
++#define POWER_STS (IMX_POWER_BASE + 0xc0)
++#define POWER_STS_VBUSVALID 0x00000002
++#define POWER_STS_BVALID 0x00000004
++#define POWER_STS_AVALID 0x00000008
++
++#define POWER_DEBUG (IMX_POWER_BASE + 0x110)
++#define POWER_DEBUG_BVALIDPIOLOCK 0x00000002
++#define POWER_DEBUG_AVALIDPIOLOCK 0x00000004
++#define POWER_DEBUG_VBUSVALIDPIOLOCK 0x00000008
++
++#define TRG_MASK 0x1f
++
++int imx_get_vddio(void)
++{
++ u32 val;
++
++ val = readl(POWER_VDDIOCTRL) & TRG_MASK;
++ if (val > 0x10)
++ val = 0x10;
++
++ return 2800000 + val * 50000;
++}
++
++int imx_set_vddio(int new_voltage_uV)
++{
++ u32 reg, val;
++
++ if (new_voltage_uV < 2800000 || new_voltage_uV > 3600000)
++ return -EINVAL;
++
++ val = (new_voltage_uV - 2800000) / 50000;
++ reg = readl(POWER_VDDIOCTRL) & ~TRG_MASK;
++ writel(reg | val, POWER_VDDIOCTRL);
++
++ /*
++ * Wait for power to become stable. We just wait, because DC_OK can
++ * only detect rising voltages for DCDC. For all other cases, bootlets
++ * also do simple waiting, although horribly nested. We just take the
++ * maximum value of all cases from the bootlets and then add some.
++ */
++ mdelay(30);
++
++ return 2800000 + val * 50000;
++}
++
++void imx_power_prepare_usbphy(void)
++{
++ u32 reg;
++
++ /*
++ * Set these bits so that we can force the OTG bits high
++ * so the ARC core operates properly
++ */
++ writel(POWER_CTRL_CLKGATE, POWER_CTRL + BIT_CLR);
++
++ writel(POWER_DEBUG_VBUSVALIDPIOLOCK |
++ POWER_DEBUG_AVALIDPIOLOCK |
++ POWER_DEBUG_BVALIDPIOLOCK, POWER_DEBUG + BIT_SET);
++
++ reg = readl(POWER_STS);
++ reg |= POWER_STS_BVALID | POWER_STS_AVALID | POWER_STS_VBUSVALID;
++ writel(reg, POWER_STS);
++}
+diff --git a/arch/arm/mach-mxs/reset-imx.c b/arch/arm/mach-mxs/reset-imx.c
+deleted file mode 100644
+index cfb3548..0000000
+--- a/arch/arm/mach-mxs/reset-imx.c
++++ /dev/null
+@@ -1,61 +0,0 @@
+-/*
+- * (C) Copyright 2010 Juergen Beisert - Pengutronix
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License as
+- * published by the Free Software Foundation; either version 2 of
+- * the License, or (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+- * MA 02111-1307 USA
+- */
+-
+-#include <common.h>
+-#include <init.h>
+-#include <notifier.h>
+-#include <mach/imx-regs.h>
+-#include <io.h>
+-
+-#define HW_RTC_CTRL 0x000
+-# define BM_RTC_CTRL_WATCHDOGEN (1 << 4)
+-#define HW_RTC_CTRL_SET 0x004
+-#define HW_RTC_CTRL_CLR 0x008
+-#define HW_RTC_CTRL_TOG 0x00C
+-
+-#define HW_RTC_WATCHDOG 0x050
+-#define HW_RTC_WATCHDOG_SET 0x054
+-#define HW_RTC_WATCHDOG_CLR 0x058
+-#define HW_RTC_WATCHDOG_TOG 0x05C
+-
+-#define WDOG_COUNTER_RATE 1000 /* 1 kHz clock */
+-
+-#define HW_RTC_PERSISTENT1 0x070
+-# define BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER 0x80000000
+-#define HW_RTC_PERSISTENT1_SET 0x074
+-#define HW_RTC_PERSISTENT1_CLR 0x078
+-#define HW_RTC_PERSISTENT1_TOG 0x07C
+-
+-/*
+- * Reset the cpu by setting up the watchdog timer and let it time out
+- *
+- * TODO There is a much easier way to reset the CPU: Refer bit 2 in
+- * the HW_CLKCTRL_RESET register, data sheet page 106/4-30
+- */
+-void __noreturn reset_cpu (unsigned long addr)
+-{
+- writel(WDOG_COUNTER_RATE, IMX_WDT_BASE + HW_RTC_WATCHDOG);
+- writel(BM_RTC_CTRL_WATCHDOGEN, IMX_WDT_BASE + HW_RTC_CTRL_SET);
+- writel(BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER, IMX_WDT_BASE + HW_RTC_PERSISTENT1);
+-
+- while (1)
+- ;
+- /*NOTREACHED*/
+-}
+-EXPORT_SYMBOL(reset_cpu);
+diff --git a/arch/arm/mach-mxs/soc-imx23.c b/arch/arm/mach-mxs/soc-imx23.c
+new file mode 100644
+index 0000000..6819b3c
+--- /dev/null
++++ b/arch/arm/mach-mxs/soc-imx23.c
+@@ -0,0 +1,37 @@
++/*
++ * (c) 2012 Juergen Beisert <kernel@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * Collection of some SoC specific functions
++ */
++
++#include <common.h>
++#include <init.h>
++#include <mach/imx-regs.h>
++#include <io.h>
++
++#define HW_CLKCTRL_RESET 0x120
++# define HW_CLKCTRL_RESET_CHIP (1 << 1)
++
++/* Reset the full i.MX23 SoC via a chipset feature */
++void __noreturn reset_cpu(unsigned long addr)
++{
++ u32 reg;
++
++ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_RESET);
++ writel(reg | HW_CLKCTRL_RESET_CHIP, IMX_CCM_BASE + HW_CLKCTRL_RESET);
++
++ while (1)
++ ;
++ /*NOTREACHED*/
++}
++EXPORT_SYMBOL(reset_cpu);
+diff --git a/arch/arm/mach-mxs/soc-imx28.c b/arch/arm/mach-mxs/soc-imx28.c
+new file mode 100644
+index 0000000..a181b75
+--- /dev/null
++++ b/arch/arm/mach-mxs/soc-imx28.c
+@@ -0,0 +1,37 @@
++/*
++ * (c) 2012 Juergen Beisert <kernel@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * Collection of some SoC specific functions
++ */
++
++#include <common.h>
++#include <init.h>
++#include <mach/imx-regs.h>
++#include <io.h>
++
++#define HW_CLKCTRL_RESET 0x1e0
++# define HW_CLKCTRL_RESET_CHIP (1 << 1)
++
++/* Reset the full i.MX28 SoC via a chipset feature */
++void __noreturn reset_cpu(unsigned long addr)
++{
++ u32 reg;
++
++ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_RESET);
++ writel(reg | HW_CLKCTRL_RESET_CHIP, IMX_CCM_BASE + HW_CLKCTRL_RESET);
++
++ while (1)
++ ;
++ /*NOTREACHED*/
++}
++EXPORT_SYMBOL(reset_cpu);
+diff --git a/arch/arm/mach-mxs/speed-imx23.c b/arch/arm/mach-mxs/speed-imx23.c
+index b10c786..5d0c90d 100644
+--- a/arch/arm/mach-mxs/speed-imx23.c
++++ b/arch/arm/mach-mxs/speed-imx23.c
+@@ -47,6 +47,8 @@
+ # define GET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+ # define SET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+ #define HW_CLKCTRL_GPMI 0x080
++# define CLKCTRL_GPMI_CLKGATE (1 << 31)
++# define CLKCTRL_GPMI_DIV_MASK 0x3ff
+ /* note: no set/clear register! */
+ #define HW_CLKCTRL_SPDIF 0x090
+ /* note: no set/clear register! */
+@@ -184,12 +186,34 @@ unsigned imx_get_hclk(void)
+
+ if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
+ rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+- rate >>= 5U; /* / 32 */
++ rate = DIV_ROUND_UP(rate, 32);
+ } else
+- rate /= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
++ rate = DIV_ROUND_UP(rate,
++ readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f);
+ return rate * 1000;
+ }
+
++unsigned imx_set_hclk(unsigned nc)
++{
++ unsigned root_rate = imx_get_armclk();
++ unsigned reg, div;
++
++ div = DIV_ROUND_UP(root_rate, nc);
++ if ((div == 0) || (div >= 32))
++ return 0;
++
++ if ((root_rate < nc) && (root_rate == 64000000))
++ div = 3;
++
++ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & ~0x3f;
++ writel(reg | div, IMX_CCM_BASE + HW_CLKCTRL_HBUS);
++
++ while (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & (1 << 31))
++ ;
++
++ return imx_get_hclk();
++}
++
+ /*
+ * Source of UART, debug UART, audio, PWM, dri, timer, digctl
+ */
+@@ -266,6 +290,23 @@ unsigned imx_set_sspclk(unsigned index, unsigned nc, int high)
+ return imx_get_sspclk(index);
+ }
+
++void imx_enable_nandclk(void)
++{
++ uint32_t reg;
++
++ /* Clear bypass bit; refman says clear, but fsl-code does set. Hooray! */
++ writel(CLKCTRL_CLKSEQ_BYPASS_GPMI,
++ IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_SET);
++
++ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_GPMI) & ~CLKCTRL_GPMI_CLKGATE;
++ writel(reg, IMX_CCM_BASE + HW_CLKCTRL_GPMI);
++ udelay(1000);
++ /* Initialize DIV to 1 */
++ reg &= ~CLKCTRL_GPMI_DIV_MASK;
++ reg |= 1;
++ writel(reg, IMX_CCM_BASE + HW_CLKCTRL_GPMI);
++}
++
+ void imx_dump_clocks(void)
+ {
+ printf("mpll: %10u kHz\n", imx_get_mpllclk() / 1000);
+diff --git a/arch/arm/mach-mxs/speed-imx28.c b/arch/arm/mach-mxs/speed-imx28.c
+index 67cdbdf..df55f64 100644
+--- a/arch/arm/mach-mxs/speed-imx28.c
++++ b/arch/arm/mach-mxs/speed-imx28.c
+@@ -48,6 +48,8 @@
+ # define GET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+ # define SET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+ #define HW_CLKCTRL_GPMI 0x0d0
++# define CLKCTRL_GPMI_CLKGATE (1 << 31)
++# define CLKCTRL_GPMI_DIV_MASK 0x3ff
+ /* note: no set/clear register! */
+ #define HW_CLKCTRL_SPDIF 0x0e0
+ /* note: no set/clear register! */
+@@ -251,12 +253,34 @@ unsigned imx_get_hclk(void)
+
+ if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
+ rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+- rate /= 32;
++ rate = DIV_ROUND_UP(rate, 32);
+ } else
+- rate /= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
++ rate = DIV_ROUND_UP(rate,
++ readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f);
+ return rate * 1000;
+ }
+
++unsigned imx_set_hclk(unsigned nc)
++{
++ unsigned root_rate = imx_get_armclk();
++ unsigned reg, div;
++
++ div = DIV_ROUND_UP(root_rate, nc);
++ if ((div == 0) || (div >= 32))
++ return 0;
++
++ if ((root_rate < nc) && (root_rate == 64000000))
++ div = 3;
++
++ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & ~0x3f;
++ writel(reg | div, IMX_CCM_BASE + HW_CLKCTRL_HBUS);
++
++ while (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & (1 << 31))
++ ;
++
++ return imx_get_hclk();
++}
++
+ /*
+ * Source of UART, debug UART, audio, PWM, dri, timer, digctl
+ */
+@@ -376,6 +400,23 @@ void imx_enable_enetclk(void)
+ IMX_CCM_BASE + HW_CLKCTRL_ENET);
+ }
+
++void imx_enable_nandclk(void)
++{
++ uint32_t reg;
++
++ /* Clear bypass bit; refman says clear, but fsl-code does set. Hooray! */
++ writel(CLKCTRL_CLKSEQ_BYPASS_GPMI,
++ IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_SET);
++
++ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_GPMI) & ~CLKCTRL_GPMI_CLKGATE;
++ writel(reg, IMX_CCM_BASE + HW_CLKCTRL_GPMI);
++ udelay(1000);
++ /* Initialize DIV to 1 */
++ reg &= ~CLKCTRL_GPMI_DIV_MASK;
++ reg |= 1;
++ writel(reg, IMX_CCM_BASE + HW_CLKCTRL_GPMI);
++}
++
+ void imx_dump_clocks(void)
+ {
+ printf("mpll: %10u kHz\n", imx_get_mpllclk() / 1000);
+diff --git a/arch/arm/mach-mxs/usb-imx23.c b/arch/arm/mach-mxs/usb-imx23.c
+new file mode 100644
+index 0000000..9aaf4bc
+--- /dev/null
++++ b/arch/arm/mach-mxs/usb-imx23.c
+@@ -0,0 +1,65 @@
++/*
++ * i.MX23 USBPHY setup
++ *
++ * Copyright 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#include <common.h>
++#include <io.h>
++#include <mach/imx-regs.h>
++#include <mach/power.h>
++
++#define USBPHY_PWD (IMX_USBPHY_BASE + 0x0)
++
++#define USBPHY_CTRL (IMX_USBPHY_BASE + 0x30)
++#define USBPHY_CTRL_SFTRST 0x80000000
++#define USBPHY_CTRL_CLKGATE 0x40000000
++
++#define CLK_PLLCTRL0 (IMX_CCM_BASE + 0x0)
++#define PLLCTRL0_EN_USB_CLKS 0x00040000
++
++#define DIGCTRL_CTRL (IMX_DIGCTL_BASE + 0x0)
++#define DIGCTL_CTRL_USB_CLKGATE 0x00000004
++
++#define SET 0x4
++#define CLR 0x8
++
++int imx23_usb_phy_enable(void)
++{
++ imx_power_prepare_usbphy();
++
++ /* Reset USBPHY module */
++ writel(USBPHY_CTRL_SFTRST, USBPHY_CTRL + SET);
++ udelay(10);
++
++ /* Remove CLKGATE and SFTRST */
++ writel(USBPHY_CTRL_CLKGATE | USBPHY_CTRL_SFTRST, USBPHY_CTRL + CLR);
++
++ /* Turn on the USB clocks */
++ writel(PLLCTRL0_EN_USB_CLKS, CLK_PLLCTRL0 + SET);
++ writel(DIGCTL_CTRL_USB_CLKGATE, DIGCTRL_CTRL + CLR);
++
++ /* Power up the PHY */
++ writel(0, USBPHY_PWD);
++
++ /*
++ * Set precharge bit to cure overshoot problems at the
++ * start of packets
++ */
++ writel(1, USBPHY_CTRL + SET);
++
++ return 0;
++}
+diff --git a/arch/arm/mach-mxs/usb-imx28.c b/arch/arm/mach-mxs/usb-imx28.c
+new file mode 100644
+index 0000000..61d59c3
+--- /dev/null
++++ b/arch/arm/mach-mxs/usb-imx28.c
+@@ -0,0 +1,101 @@
++/*
++ * i.MX28 USBPHY setup
++ *
++ * Copyright 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++#include <common.h>
++#include <io.h>
++#include <errno.h>
++#include <mach/imx-regs.h>
++
++#define POWER_CTRL (IMX_POWER_BASE + 0x0)
++#define POWER_CTRL_CLKGATE 0x40000000
++
++#define POWER_STS (IMX_POWER_BASE + 0xc0)
++#define POWER_STS_VBUSVALID 0x00000002
++#define POWER_STS_BVALID 0x00000004
++#define POWER_STS_AVALID 0x00000008
++
++#define POWER_DEBUG (IMX_POWER_BASE + 0x110)
++#define POWER_DEBUG_BVALIDPIOLOCK 0x00000002
++#define POWER_DEBUG_AVALIDPIOLOCK 0x00000004
++#define POWER_DEBUG_VBUSVALIDPIOLOCK 0x00000008
++
++#define USBPHY_PWD 0x0
++
++#define USBPHY_CTRL 0x30
++#define USBPHY_CTRL_SFTRST (1 << 31)
++#define USBPHY_CTRL_CLKGATE (1 << 30)
++#define USBPHY_CTRL_ENUTMILEVEL3 (1 << 15)
++#define USBPHY_CTRL_ENUTMILEVEL2 (1 << 14)
++
++#define CLK_PLL0CTRL0 (IMX_CCM_BASE + 0x0)
++#define CLK_PLL1CTRL0 (IMX_CCM_BASE + 0x20)
++#define PLLCTRL0_EN_USB_CLKS (1 << 18)
++
++#define DIGCTRL_CTRL (IMX_DIGCTL_BASE + 0x0)
++#define DIGCTL_CTRL_USB0_CLKGATE (1 << 2)
++#define DIGCTL_CTRL_USB1_CLKGATE (1 << 16)
++
++#define SET 0x4
++#define CLR 0x8
++
++static void imx28_usb_phy_reset(void __iomem *phybase)
++{
++ /* Reset USBPHY module */
++ writel(USBPHY_CTRL_SFTRST, phybase + USBPHY_CTRL + SET);
++ udelay(10);
++ writel(USBPHY_CTRL_CLKGATE | USBPHY_CTRL_SFTRST,
++ phybase + USBPHY_CTRL + CLR);
++}
++
++static void imx28_usb_phy_enable(void __iomem *phybase)
++{
++ /* Power up the PHY */
++ writel(0, phybase + USBPHY_PWD);
++
++ writel(USBPHY_CTRL_ENUTMILEVEL3 | USBPHY_CTRL_ENUTMILEVEL2 | 1,
++ phybase + USBPHY_CTRL + SET);
++}
++
++int imx28_usb_phy0_enable(void)
++{
++ imx28_usb_phy_reset((void *)IMX_USBPHY0_BASE);
++
++ /* Turn on the USB clocks */
++ writel(PLLCTRL0_EN_USB_CLKS, CLK_PLL0CTRL0 + SET);
++
++ writel(DIGCTL_CTRL_USB0_CLKGATE, DIGCTRL_CTRL + CLR);
++
++ imx28_usb_phy_enable((void *)IMX_USBPHY0_BASE);
++
++ return 0;
++}
++
++int imx28_usb_phy1_enable(void)
++{
++ imx28_usb_phy_reset((void *)IMX_USBPHY1_BASE);
++
++ /* Turn on the USB clocks */
++ writel(PLLCTRL0_EN_USB_CLKS, CLK_PLL1CTRL0 + SET);
++
++ writel(DIGCTL_CTRL_USB1_CLKGATE, DIGCTRL_CTRL + CLR);
++
++ imx28_usb_phy_enable((void *)IMX_USBPHY1_BASE);
++
++ return 0;
++}
+diff --git a/arch/arm/mach-mxs/usb.c b/arch/arm/mach-mxs/usb.c
+deleted file mode 100644
+index b7a9376..0000000
+--- a/arch/arm/mach-mxs/usb.c
++++ /dev/null
+@@ -1,92 +0,0 @@
+-/*
+- * i.MX23/28 USBPHY setup
+- *
+- * Copyright 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
+- *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; either version 2 of the License, or
+- * (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+- * GNU General Public License for more details.
+- *
+- * You should have received a copy of the GNU General Public License
+- * along with this program; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- */
+-#include <common.h>
+-#include <io.h>
+-#include <mach/imx-regs.h>
+-
+-#define POWER_CTRL (IMX_POWER_BASE + 0x0)
+-#define POWER_CTRL_CLKGATE 0x40000000
+-
+-#define POWER_STS (IMX_POWER_BASE + 0xc0)
+-#define POWER_STS_VBUSVALID 0x00000002
+-#define POWER_STS_BVALID 0x00000004
+-#define POWER_STS_AVALID 0x00000008
+-
+-#define POWER_DEBUG (IMX_POWER_BASE + 0x110)
+-#define POWER_DEBUG_BVALIDPIOLOCK 0x00000002
+-#define POWER_DEBUG_AVALIDPIOLOCK 0x00000004
+-#define POWER_DEBUG_VBUSVALIDPIOLOCK 0x00000008
+-
+-#define USBPHY_PWD (IMX_USBPHY_BASE + 0x0)
+-
+-#define USBPHY_CTRL (IMX_USBPHY_BASE + 0x30)
+-#define USBPHY_CTRL_SFTRST 0x80000000
+-#define USBPHY_CTRL_CLKGATE 0x40000000
+-
+-#define CLK_PLLCTRL0 (IMX_CCM_BASE + 0x0)
+-#define PLLCTRL0_EN_USB_CLKS 0x00040000
+-
+-#define DIGCTRL_CTRL (IMX_DIGCTL_BASE + 0x0)
+-#define DIGCTL_CTRL_USB_CLKGATE 0x00000004
+-
+-#define SET 0x4
+-#define CLR 0x8
+-
+-int imx_usb_phy_enable(void)
+-{
+- u32 reg;
+-
+- /*
+- * Set these bits so that we can force the OTG bits high
+- * so the ARC core operates properly
+- */
+- writel(POWER_CTRL_CLKGATE, POWER_CTRL + CLR);
+-
+- writel(POWER_DEBUG_VBUSVALIDPIOLOCK |
+- POWER_DEBUG_AVALIDPIOLOCK |
+- POWER_DEBUG_BVALIDPIOLOCK, POWER_DEBUG + SET);
+-
+- reg = readl(POWER_STS);
+- reg |= POWER_STS_BVALID | POWER_STS_AVALID | POWER_STS_VBUSVALID;
+- writel(reg, POWER_STS);
+-
+- /* Reset USBPHY module */
+- writel(USBPHY_CTRL_SFTRST, USBPHY_CTRL + SET);
+- udelay(10);
+-
+- /* Remove CLKGATE and SFTRST */
+- writel(USBPHY_CTRL_CLKGATE | USBPHY_CTRL_SFTRST, USBPHY_CTRL + CLR);
+-
+- /* Turn on the USB clocks */
+- writel(PLLCTRL0_EN_USB_CLKS, CLK_PLLCTRL0 + SET);
+- writel(DIGCTL_CTRL_USB_CLKGATE, DIGCTRL_CTRL + CLR);
+-
+- /* Power up the PHY */
+- writel(0, USBPHY_PWD);
+-
+- /*
+- * Set precharge bit to cure overshoot problems at the
+- * start of packets
+- */
+- writel(1, USBPHY_CTRL + SET);
+-
+- return 0;
+-}
+-
+diff --git a/arch/arm/mach-samsung/include/mach/devices-s3c24xx.h b/arch/arm/mach-samsung/include/mach/devices-s3c24xx.h
+new file mode 100644
+index 0000000..51fd9a1
+--- /dev/null
++++ b/arch/arm/mach-samsung/include/mach/devices-s3c24xx.h
+@@ -0,0 +1,55 @@
++/*
++ * Copyright 2012 Juergen Beisert
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#ifndef INCLUDE_MACH_DEVICES_S3C24XX_H
++# define INCLUDE_MACH_DEVICES_S3C24XX_H
++
++#include <driver.h>
++#include <mach/s3c24xx-iomap.h>
++#include <mach/s3c24xx-nand.h>
++#include <mach/s3c-mci.h>
++#include <mach/s3c24xx-fb.h>
++
++static inline void s3c24xx_add_nand(struct s3c24x0_nand_platform_data *d)
++{
++ add_generic_device("s3c24x0_nand", DEVICE_ID_DYNAMIC, NULL,
++ S3C24X0_NAND_BASE, 0x80, IORESOURCE_MEM, d);
++}
++
++static inline void s3c24xx_add_mci(struct s3c_mci_platform_data *d)
++{
++ add_generic_device("s3c_mci", DEVICE_ID_DYNAMIC, NULL,
++ S3C2410_SDI_BASE, 0x80, IORESOURCE_MEM, d);
++}
++
++static inline void s3c24xx_add_fb(struct s3c_fb_platform_data *d)
++{
++ add_generic_device("s3c_fb", DEVICE_ID_DYNAMIC, NULL,
++ S3C2410_LCD_BASE, 0x80, IORESOURCE_MEM, d);
++}
++
++static inline void s3c24xx_add_ohci(void)
++{
++ add_generic_device("ohci", DEVICE_ID_DYNAMIC, NULL,
++ S3C2410_USB_HOST_BASE, 0x100, IORESOURCE_MEM, NULL);
++}
++
++static inline void s3c24xx_add_uart1(void)
++{
++ add_generic_device("s3c_serial", DEVICE_ID_DYNAMIC, NULL, S3C_UART1_BASE,
++ S3C_UART1_SIZE, IORESOURCE_MEM, NULL);
++}
++
++#endif /* INCLUDE_MACH_DEVICES_S3C24XX_H */
+diff --git a/arch/arm/mach-samsung/include/mach/s3c24xx-nand.h b/arch/arm/mach-samsung/include/mach/s3c24xx-nand.h
+index acd78b8..fa88da1 100644
+--- a/arch/arm/mach-samsung/include/mach/s3c24xx-nand.h
++++ b/arch/arm/mach-samsung/include/mach/s3c24xx-nand.h
+@@ -18,6 +18,9 @@
+ *
+ */
+
++#ifndef MACH_S3C24XX_NAND_H
++# define MACH_S3C24XX_NAND_H
++
+ #ifdef CONFIG_S3C_NAND_BOOT
+ extern void s3c24x0_nand_load_image(void*, int, int);
+ #endif
+@@ -52,3 +55,5 @@ struct s3c24x0_nand_platform_data {
+ * @file
+ * @brief Basic declaration to use the s3c24x0 NAND driver
+ */
++
++#endif /* MACH_S3C24XX_NAND_H */
+diff --git a/arch/blackfin/include/asm/bitops.h b/arch/blackfin/include/asm/bitops.h
+index cdcb2f8..623ddfb 100644
+--- a/arch/blackfin/include/asm/bitops.h
++++ b/arch/blackfin/include/asm/bitops.h
+@@ -268,7 +268,10 @@ static __inline__ int find_next_zero_bit(void *addr, int size, int offset)
+ return result + ffz(tmp);
+ }
+
++#include <asm-generic/bitops/__ffs.h>
++#include <asm-generic/bitops/__fls.h>
+ #include <asm-generic/bitops/ffs.h>
++#include <asm-generic/bitops/fls.h>
+ #include <asm-generic/bitops/hweight.h>
+
+ static __inline__ int ext2_set_bit(int nr, volatile void *addr)
+diff --git a/arch/blackfin/include/asm/dma.h b/arch/blackfin/include/asm/dma.h
+new file mode 100644
+index 0000000..27d269f
+--- /dev/null
++++ b/arch/blackfin/include/asm/dma.h
+@@ -0,0 +1,13 @@
++/*
++ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
++ *
++ * This file is released under the GPLv2
++ *
++ */
++
++#ifndef __ASM_DMA_H
++#define __ASM_DMA_H
++
++/* empty */
++
++#endif /* __ASM_DMA_H */
+diff --git a/arch/blackfin/lib/Makefile b/arch/blackfin/lib/Makefile
+index 2f77318..cefb4dc 100644
+--- a/arch/blackfin/lib/Makefile
++++ b/arch/blackfin/lib/Makefile
+@@ -8,6 +8,7 @@ obj-y += smulsi3_highpart.o
+ obj-y += umodsi3.o
+ obj-y += lshrdi3.o
+ obj-y += ashldi3.o
++obj-y += ashrdi3.o
+ obj-y += divsi3.o
+ obj-y += modsi3.o
+ obj-y += cpu.o
+diff --git a/arch/blackfin/lib/ashrdi3.c b/arch/blackfin/lib/ashrdi3.c
+new file mode 100644
+index 0000000..b5b351e
+--- /dev/null
++++ b/arch/blackfin/lib/ashrdi3.c
+@@ -0,0 +1,36 @@
++/*
++ * Copyright 2004-2009 Analog Devices Inc.
++ *
++ * Licensed under the GPL-2 or later.
++ */
++
++#include "gcclib.h"
++
++#ifdef CONFIG_ARITHMETIC_OPS_L1
++DItype __ashrdi3(DItype u, word_type b)__attribute__((l1_text));
++#endif
++
++DItype __ashrdi3(DItype u, word_type b)
++{
++ DIunion w;
++ word_type bm;
++ DIunion uu;
++
++ if (b == 0)
++ return u;
++
++ uu.ll = u;
++
++ bm = (sizeof(SItype) * BITS_PER_UNIT) - b;
++ if (bm <= 0) {
++ /* w.s.high = 1..1 or 0..0 */
++ w.s.high = uu.s.high >> (sizeof(SItype) * BITS_PER_UNIT - 1);
++ w.s.low = uu.s.high >> -bm;
++ } else {
++ USItype carries = (USItype) uu.s.high << bm;
++ w.s.high = uu.s.high >> b;
++ w.s.low = ((USItype) uu.s.low >> b) | carries;
++ }
++
++ return w.ll;
++}
+diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
+index 001ebf2..bf1ac6e 100644
+--- a/arch/mips/include/asm/bitops.h
++++ b/arch/mips/include/asm/bitops.h
+@@ -28,5 +28,8 @@
+ #define _ASM_MIPS_BITOPS_H_
+
+ #include <asm-generic/bitops/__ffs.h>
++#include <asm-generic/bitops/__fls.h>
++#include <asm-generic/bitops/ffs.h>
++#include <asm-generic/bitops/fls.h>
+
+ #endif /* _ASM_MIPS_BITOPS_H_ */
+diff --git a/arch/mips/include/asm/dma.h b/arch/mips/include/asm/dma.h
+new file mode 100644
+index 0000000..27d269f
+--- /dev/null
++++ b/arch/mips/include/asm/dma.h
+@@ -0,0 +1,13 @@
++/*
++ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
++ *
++ * This file is released under the GPLv2
++ *
++ */
++
++#ifndef __ASM_DMA_H
++#define __ASM_DMA_H
++
++/* empty */
++
++#endif /* __ASM_DMA_H */
+diff --git a/arch/mips/mach-xburst/Kconfig b/arch/mips/mach-xburst/Kconfig
+index 60e411c..c72b741 100644
+--- a/arch/mips/mach-xburst/Kconfig
++++ b/arch/mips/mach-xburst/Kconfig
+@@ -12,6 +12,7 @@ choice
+
+ config BOARD_RZX50
+ bool "Ritmix RZX-50"
++ select HAS_POWEROFF
+ select CPU_JZ4755
+
+ endchoice
+diff --git a/arch/mips/mach-xburst/csrc-jz4750.c b/arch/mips/mach-xburst/csrc-jz4750.c
+index f625b70..36e401e 100644
+--- a/arch/mips/mach-xburst/csrc-jz4750.c
++++ b/arch/mips/mach-xburst/csrc-jz4750.c
+@@ -28,7 +28,7 @@
+ #include <io.h>
+ #include <mach/jz4750d_regs.h>
+
+-#define JZ_TIMER_CLOCK 40000
++#define JZ_TIMER_CLOCK 24000000
+
+ static uint64_t jz4750_cs_read(void)
+ {
+@@ -38,12 +38,13 @@ static uint64_t jz4750_cs_read(void)
+ static struct clocksource jz4750_cs = {
+ .read = jz4750_cs_read,
+ .mask = CLOCKSOURCE_MASK(32),
+- .shift = 10,
+ };
+
+ static int clocksource_init(void)
+ {
+- jz4750_cs.mult = clocksource_hz2mult(JZ_TIMER_CLOCK, jz4750_cs.shift);
++ clocks_calc_mult_shift(&jz4750_cs.mult, &jz4750_cs.shift,
++ JZ_TIMER_CLOCK, NSEC_PER_SEC, 10);
++
+ init_clock(&jz4750_cs);
+
+ __raw_writel(TCU_OSTCSR_PRESCALE1 | TCU_OSTCSR_EXT_EN,
+diff --git a/arch/mips/mach-xburst/include/mach/jz4750d_regs.h b/arch/mips/mach-xburst/include/mach/jz4750d_regs.h
+index 717493b..eafdd2f 100644
+--- a/arch/mips/mach-xburst/include/mach/jz4750d_regs.h
++++ b/arch/mips/mach-xburst/include/mach/jz4750d_regs.h
+@@ -15,6 +15,7 @@
+
+ #define TCU_BASE 0xb0002000
+ #define WDT_BASE 0xb0002000
++#define RTC_BASE 0xb0003000
+ #define UART1_BASE 0xb0031000
+
+ /*************************************************************************
+@@ -77,4 +78,34 @@
+
+ #define WDT_TCER_TCEN (1 << 0)
+
++/*************************************************************************
++ * RTC
++ *************************************************************************/
++#define RTC_RCR (RTC_BASE + 0x00) /* RTC Control Register */
++#define RTC_RSR (RTC_BASE + 0x04) /* RTC Second Register */
++#define RTC_RSAR (RTC_BASE + 0x08) /* RTC Second Alarm Register */
++#define RTC_RGR (RTC_BASE + 0x0c) /* RTC Regulator Register */
++
++#define RTC_HCR (RTC_BASE + 0x20) /* Hibernate Control Register */
++#define RTC_HWFCR (RTC_BASE + 0x24) /* Hibernate Wakeup Filter Counter Reg */
++#define RTC_HRCR (RTC_BASE + 0x28) /* Hibernate Reset Counter Register */
++#define RTC_HWCR (RTC_BASE + 0x2c) /* Hibernate Wakeup Control Register */
++#define RTC_HWRSR (RTC_BASE + 0x30) /* Hibernate Wakeup Status Register */
++#define RTC_HSPR (RTC_BASE + 0x34) /* Hibernate Scratch Pattern Register */
++
++/* RTC Control Register */
++#define RTC_RCR_WRDY_BIT 7
++#define RTC_RCR_WRDY (1 << 7) /* Write Ready Flag */
++#define RTC_RCR_1HZ_BIT 6
++#define RTC_RCR_1HZ (1 << RTC_RCR_1HZ_BIT) /* 1Hz Flag */
++#define RTC_RCR_1HZIE (1 << 5) /* 1Hz Interrupt Enable */
++#define RTC_RCR_AF_BIT 4
++#define RTC_RCR_AF (1 << RTC_RCR_AF_BIT) /* Alarm Flag */
++#define RTC_RCR_AIE (1 << 3) /* Alarm Interrupt Enable */
++#define RTC_RCR_AE (1 << 2) /* Alarm Enable */
++#define RTC_RCR_RTCE (1 << 0) /* RTC Enable */
++
++/* Hibernate Control Register */
++#define RTC_HCR_PD (1 << 0) /* Power Down */
++
+ #endif /* __JZ4750D_REGS_H__ */
+diff --git a/arch/mips/mach-xburst/reset-jz4750.c b/arch/mips/mach-xburst/reset-jz4750.c
+index 3540ca9..765c033 100644
+--- a/arch/mips/mach-xburst/reset-jz4750.c
++++ b/arch/mips/mach-xburst/reset-jz4750.c
+@@ -29,6 +29,19 @@
+
+ #define JZ_EXTAL 24000000
+
++static void __noreturn jz4750d_halt(void)
++{
++ while (1) {
++ __asm__(".set push;\n"
++ ".set mips3;\n"
++ "wait;\n"
++ ".set pop;\n"
++ );
++ }
++
++ unreachable();
++}
++
+ void __noreturn reset_cpu(ulong addr)
+ {
+ __raw_writew(WDT_TCSR_PRESCALE4 | WDT_TCSR_EXT_EN, (u16 *)WDT_TCSR);
+@@ -44,3 +57,18 @@ void __noreturn reset_cpu(ulong addr)
+ unreachable();
+ }
+ EXPORT_SYMBOL(reset_cpu);
++
++void __noreturn poweroff()
++{
++ u32 ctrl;
++
++ shutdown_barebox();
++
++ do {
++ ctrl = readl((u32 *)RTC_RCR);
++ } while (!(ctrl & RTC_RCR_WRDY));
++
++ writel(RTC_HCR_PD, (u32 *)RTC_HCR);
++ jz4750d_halt();
++}
++EXPORT_SYMBOL(poweroff);
+diff --git a/arch/nios2/boards/generic/generic.c b/arch/nios2/boards/generic/generic.c
+index b51b94a..2c998fe 100644
+--- a/arch/nios2/boards/generic/generic.c
++++ b/arch/nios2/boards/generic/generic.c
+@@ -9,17 +9,17 @@ static int phy_address = 1;
+ static struct resource mac_resources[] = {
+ [0] = {
+ .start = NIOS_SOPC_TSE_BASE,
+- .size = 0x400,
++ .end = NIOS_SOPC_TSE_BASE + 0x400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = NIOS_SOPC_SGDMA_RX_BASE,
+- .size = 0x40,
++ .end = 0x40 + NIOS_SOPC_SGDMA_RX_BASE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = NIOS_SOPC_SGDMA_TX_BASE,
+- .size = 0x40,
++ .end = 0x40 + NIOS_SOPC_SGDMA_TX_BASE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ };
+diff --git a/arch/nios2/include/asm/bitops.h b/arch/nios2/include/asm/bitops.h
+index ab0e3d5..0712845 100644
+--- a/arch/nios2/include/asm/bitops.h
++++ b/arch/nios2/include/asm/bitops.h
+@@ -1,4 +1,9 @@
+ #ifndef _ASM_BITOPS_H
+ #define _ASM_BITOPS_H
+
++#include <asm-generic/bitops/__ffs.h>
++#include <asm-generic/bitops/__fls.h>
++#include <asm-generic/bitops/ffs.h>
++#include <asm-generic/bitops/fls.h>
++
+ #endif /* _ASM_BITOPS_H */
+diff --git a/arch/nios2/include/asm/dma-mapping.h b/arch/nios2/include/asm/dma-mapping.h
+index 5b70f4c..9819a97 100644
+--- a/arch/nios2/include/asm/dma-mapping.h
++++ b/arch/nios2/include/asm/dma-mapping.h
+@@ -1,8 +1,12 @@
+ #ifndef __ASM_NIOS2_DMA_MAPPING_H
+ #define __ASM_NIOS2_DMA_MAPPING_H
+
++#include <common.h>
++#include <xfuncs.h>
++
+ #include <asm/cache.h>
+
++
+ /* dma_alloc_coherent() return cache-line aligned allocation which is mapped
+ * to uncached io region.
+ *
+@@ -22,4 +26,10 @@ static inline void *dma_alloc_coherent(size_t len, unsigned long *handle)
+ return (void *)(*handle | IO_REGION_BASE);
+ }
+
++#define dma_alloc dma_alloc
++static inline void *dma_alloc(size_t size)
++{
++ return xmemalign(DCACHE_LINE_SIZE, ALIGN(size, DCACHE_LINE_SIZE));
++}
++
+ #endif /* __ASM_NIOS2_DMA_MAPPING_H */
+diff --git a/arch/nios2/include/asm/dma.h b/arch/nios2/include/asm/dma.h
+new file mode 100644
+index 0000000..8f709d2
+--- /dev/null
++++ b/arch/nios2/include/asm/dma.h
+@@ -0,0 +1,8 @@
++/*
++ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
++ *
++ * This file is released under the GPLv2
++ *
++ */
++
++#include <asm/dma-mapping.h>
+diff --git a/arch/openrisc/Makefile b/arch/openrisc/Makefile
+index fd8bbbf..1f4b175 100644
+--- a/arch/openrisc/Makefile
++++ b/arch/openrisc/Makefile
+@@ -1,5 +1,7 @@
+ CPPFLAGS += -D__OR1K__ -ffixed-r10 -mhard-mul -mhard-div
+
++LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
++
+ board-$(CONFIG_GENERIC) := generic
+
+ KALLSYMS += --symbol-prefix=_
+@@ -18,4 +20,6 @@ common-y += $(BOARD)
+ common-y += arch/openrisc/lib/
+ common-y += arch/openrisc/cpu/
+
++common-y += $(LIBGCC)
++
+ lds-y += arch/openrisc/cpu/barebox.lds
+diff --git a/arch/openrisc/include/asm/dma.h b/arch/openrisc/include/asm/dma.h
+new file mode 100644
+index 0000000..27d269f
+--- /dev/null
++++ b/arch/openrisc/include/asm/dma.h
+@@ -0,0 +1,13 @@
++/*
++ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
++ *
++ * This file is released under the GPLv2
++ *
++ */
++
++#ifndef __ASM_DMA_H
++#define __ASM_DMA_H
++
++/* empty */
++
++#endif /* __ASM_DMA_H */
+diff --git a/arch/ppc/include/asm/dma.h b/arch/ppc/include/asm/dma.h
+new file mode 100644
+index 0000000..27d269f
+--- /dev/null
++++ b/arch/ppc/include/asm/dma.h
+@@ -0,0 +1,13 @@
++/*
++ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
++ *
++ * This file is released under the GPLv2
++ *
++ */
++
++#ifndef __ASM_DMA_H
++#define __ASM_DMA_H
++
++/* empty */
++
++#endif /* __ASM_DMA_H */
+diff --git a/arch/ppc/mach-mpc85xx/include/mach/clocks.h b/arch/ppc/mach-mpc85xx/include/mach/clocks.h
+index 9477168..2ab367b 100644
+--- a/arch/ppc/mach-mpc85xx/include/mach/clocks.h
++++ b/arch/ppc/mach-mpc85xx/include/mach/clocks.h
+@@ -10,8 +10,6 @@ struct sys_info {
+ unsigned long freqLocalBus;
+ };
+
+-#define NSEC_PER_SEC 1000000000L
+-
+ unsigned long fsl_get_bus_freq(ulong dummy);
+ unsigned long fsl_get_timebase_clock(void);
+ void fsl_get_sys_info(struct sys_info *sysInfo);
+diff --git a/arch/sandbox/board/hostfile.c b/arch/sandbox/board/hostfile.c
+index 90a9741..96fa100 100644
+--- a/arch/sandbox/board/hostfile.c
++++ b/arch/sandbox/board/hostfile.c
+@@ -34,7 +34,7 @@ struct hf_priv {
+ struct hf_platform_data *pdata;
+ };
+
+-static ssize_t hf_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags)
++static ssize_t hf_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags)
+ {
+ struct hf_platform_data *hf = cdev->priv;
+ int fd = hf->fd;
+@@ -45,7 +45,7 @@ static ssize_t hf_read(struct cdev *cdev, void *buf, size_t count, ulong offset,
+ return linux_read(fd, buf, count);
+ }
+
+-static ssize_t hf_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags)
++static ssize_t hf_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags)
+ {
+ struct hf_platform_data *hf = cdev->priv;
+ int fd = hf->fd;
+diff --git a/arch/sandbox/include/asm/dma.h b/arch/sandbox/include/asm/dma.h
+new file mode 100644
+index 0000000..4595367
+--- /dev/null
++++ b/arch/sandbox/include/asm/dma.h
+@@ -0,0 +1,13 @@
++/*
++ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
++ *
++ * This file is released under the GPLv2
++ *
++ */
++
++#ifndef __ASM_DMA_H
++#define __ASM_DMA_H
++
++/* empty*/
++
++#endif /* __ASM_DMA_H */
+diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
+index b43afa3..830b1a5 100644
+--- a/arch/x86/include/asm/bitops.h
++++ b/arch/x86/include/asm/bitops.h
+@@ -27,6 +27,11 @@
+ #ifndef _ASM_X86_BITOPS_H_
+ #define _ASM_X86_BITOPS_H_
+
+-/* nothing special yet */
++#define BITS_PER_LONG 32
++
++#include <asm-generic/bitops/__fls.h>
++#include <asm-generic/bitops/__ffs.h>
++#include <asm-generic/bitops/fls.h>
++#include <asm-generic/bitops/ffs.h>
+
+ #endif /* _ASM_X86_BITOPS_H_ */
+diff --git a/arch/x86/include/asm/dma.h b/arch/x86/include/asm/dma.h
+new file mode 100644
+index 0000000..27d269f
+--- /dev/null
++++ b/arch/x86/include/asm/dma.h
+@@ -0,0 +1,13 @@
++/*
++ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
++ *
++ * This file is released under the GPLv2
++ *
++ */
++
++#ifndef __ASM_DMA_H
++#define __ASM_DMA_H
++
++/* empty */
++
++#endif /* __ASM_DMA_H */
+diff --git a/commands/Kconfig b/commands/Kconfig
+index 52e1f17..2478e3f 100644
+--- a/commands/Kconfig
++++ b/commands/Kconfig
+@@ -6,6 +6,10 @@ config COMMAND_SUPPORT
+ depends on !SHELL_NONE
+ default y
+
++config HAS_POWEROFF
++ bool
++ default n
++
+ if COMMAND_SUPPORT
+
+ menu "commands "
+@@ -25,6 +29,10 @@ config CMD_SLEEP
+ tristate
+ prompt "sleep"
+
++config CMD_MSLEEP
++ tristate
++ prompt "msleep"
++
+ config CMD_SAVEENV
+ tristate
+ select ENV_HANDLING
+@@ -198,6 +206,20 @@ config CMD_AUTOMOUNT
+ this directory available (discover USB devices, bring network interface
+ up and finally mount the filesystem).
+
++config CMD_BASENAME
++ tristate
++ prompt "basename"
++ help
++ Strip directory and suffix from filenames and store the result in a
++ environment variable
++
++config CMD_DIRNAME
++ tristate
++ prompt "dirname"
++ help
++ Strip last component of file name and store the result in a
++ environment variable
++
+ endmenu
+
+ menu "console "
+@@ -422,6 +444,11 @@ config CMD_RESET
+ tristate
+ prompt "reset"
+
++config CMD_POWEROFF
++ tristate
++ depends on HAS_POWEROFF
++ prompt "poweroff"
++
+ config CMD_GO
+ tristate
+ prompt "go"
+@@ -552,6 +579,25 @@ config CMD_USB
+ help
+ The usb command allows to rescan for USB devices.
+
++menuconfig CMD_WD
++ bool
++ depends on WATCHDOG
++ prompt "wd command "
++ help
++ The 'wd' command which allows to start, stop and trigger the onboard
++ watchdog.
++
++if CMD_WD
++
++config CMD_WD_DEFAULT_TIMOUT
++ int
++ prompt "default timeout"
++ help
++ Define the default timeout value in [seconds] if the first call of
++ 'wd' is done without a timeout value (which means the watchdog gets
++ enabled and re-triggered with the default timeout value).
++endif
++
+ endmenu
+
+ endif
+diff --git a/commands/Makefile b/commands/Makefile
+index 4c8a0a9..54191b4 100644
+--- a/commands/Makefile
++++ b/commands/Makefile
+@@ -1,3 +1,4 @@
++obj-y += stddev.o
+ obj-$(CONFIG_CMD_BOOTM) += bootm.o
+ obj-$(CONFIG_CMD_UIMAGE) += uimage.o
+ obj-$(CONFIG_CMD_LINUX16) += linux16.o
+@@ -10,7 +11,9 @@ obj-$(CONFIG_CMD_MTEST) += memtest.o
+ obj-$(CONFIG_CMD_EDIT) += edit.o
+ obj-$(CONFIG_CMD_EXEC) += exec.o
+ obj-$(CONFIG_CMD_SLEEP) += sleep.o
++obj-$(CONFIG_CMD_MSLEEP) += msleep.o
+ obj-$(CONFIG_CMD_RESET) += reset.o
++obj-$(CONFIG_CMD_POWEROFF) += poweroff.o
+ obj-$(CONFIG_CMD_GO) += go.o
+ obj-$(CONFIG_NET) += net.o
+ obj-$(CONFIG_CMD_PARTITION) += partition.o
+@@ -57,6 +60,7 @@ obj-$(CONFIG_CMD_MENU) += menu.o
+ obj-$(CONFIG_CMD_PASSWD) += passwd.o
+ obj-$(CONFIG_CMD_LOGIN) += login.o
+ obj-$(CONFIG_CMD_LED) += led.o
++obj-$(CONFIG_CMD_WD) += wd.o
+ obj-$(CONFIG_CMD_LED_TRIGGER) += trigger.o
+ obj-$(CONFIG_CMD_USB) += usb.o
+ obj-$(CONFIG_CMD_TIME) += time.o
+@@ -66,3 +70,5 @@ obj-$(CONFIG_CMD_IOMEM) += iomem.o
+ obj-$(CONFIG_CMD_LINUX_EXEC) += linux_exec.o
+ obj-$(CONFIG_CMD_AUTOMOUNT) += automount.o
+ obj-$(CONFIG_CMD_GLOBAL) += global.o
++obj-$(CONFIG_CMD_BASENAME) += basename.o
++obj-$(CONFIG_CMD_DIRNAME) += dirname.o
+diff --git a/commands/basename.c b/commands/basename.c
+new file mode 100644
+index 0000000..b47ff8c
+--- /dev/null
++++ b/commands/basename.c
+@@ -0,0 +1,47 @@
++/*
++ * basename.c - strip directory and suffix from filenames
++ *
++ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can 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 program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <command.h>
++#include <libgen.h>
++#include <environment.h>
++
++static int do_basename(int argc, char *argv[])
++{
++ if (argc != 3)
++ return COMMAND_ERROR_USAGE;
++
++ setenv(argv[2], basename(argv[1]));
++
++ return 0;
++}
++
++BAREBOX_CMD_HELP_START(basename)
++BAREBOX_CMD_HELP_USAGE("basename NAME BASENAME\n")
++BAREBOX_CMD_HELP_SHORT("strip NAME and store into $BASENAME\n")
++BAREBOX_CMD_HELP_END
++
++BAREBOX_CMD_START(basename)
++ .cmd = do_basename,
++ .usage = "strip directory and suffix from filenames",
++ BAREBOX_CMD_HELP(cmd_basename_help)
++BAREBOX_CMD_END
+diff --git a/commands/bootm.c b/commands/bootm.c
+index 2989d39..3c47ab5 100644
+--- a/commands/bootm.c
++++ b/commands/bootm.c
+@@ -383,8 +383,7 @@ static int do_bootm(int argc, char *argv[])
+ if (data.os_res)
+ printf("OS image is at 0x%08x-0x%08x\n",
+ data.os_res->start,
+- data.os_res->start +
+- data.os_res->size - 1);
++ data.os_res->end);
+ else
+ printf("OS image not yet relocated\n");
+
+@@ -399,8 +398,7 @@ static int do_bootm(int argc, char *argv[])
+ if (data.initrd_res)
+ printf("initrd is at 0x%08x-0x%08x\n",
+ data.initrd_res->start,
+- data.initrd_res->start +
+- data.initrd_res->size - 1);
++ data.initrd_res->end);
+ else
+ printf("initrd image not yet relocated\n");
+ }
+diff --git a/commands/crc.c b/commands/crc.c
+index df22941..8f80e42 100644
+--- a/commands/crc.c
++++ b/commands/crc.c
+@@ -47,9 +47,12 @@ static int file_crc(char* filename, ulong start, ulong size, ulong *crc,
+ }
+
+ if (start > 0) {
+- ret = lseek(fd, start, SEEK_SET);
+- if (ret == -1) {
++ off_t lseek_ret;
++ errno = 0;
++ lseek_ret = lseek(fd, start, SEEK_SET);
++ if (lseek_ret == (off_t)-1 && errno) {
+ perror("lseek");
++ ret = -1;
+ goto out;
+ }
+ }
+@@ -84,8 +87,8 @@ out:
+
+ static int do_crc(int argc, char *argv[])
+ {
+- ulong start = 0, size = ~0, total = 0;
+- ulong crc = 0, vcrc = 0;
++ loff_t start = 0, size = ~0;
++ ulong crc = 0, vcrc = 0, total = 0;
+ char *filename = "/dev/mem";
+ #ifdef CONFIG_CMD_CRC_CMP
+ char *vfilename = NULL;
+diff --git a/commands/digest.c b/commands/digest.c
+index 8432914..07cbec9 100644
+--- a/commands/digest.c
++++ b/commands/digest.c
+@@ -51,7 +51,7 @@ static int do_digest(char *algorithm, int argc, char *argv[])
+ argv++;
+ while (*argv) {
+ char *filename = "/dev/mem";
+- ulong start = 0, size = ~0;
++ loff_t start = 0, size = ~0;
+
+ /* arguments are either file, file+area or area */
+ if (parse_area_spec(*argv, &start, &size)) {
+@@ -66,7 +66,7 @@ static int do_digest(char *algorithm, int argc, char *argv[])
+ for (i = 0; i < d->length; i++)
+ printf("%02x", hash[i]);
+
+- printf(" %s\t0x%08lx ... 0x%08lx\n", filename, start, start + size);
++ printf(" %s\t0x%08llx ... 0x%08llx\n", filename, start, start + size);
+
+ argv++;
+ }
+diff --git a/commands/dirname.c b/commands/dirname.c
+new file mode 100644
+index 0000000..cf1d0a0
+--- /dev/null
++++ b/commands/dirname.c
+@@ -0,0 +1,47 @@
++/*
++ * dirname.c - strip directory and suffix from filenames
++ *
++ * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can 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 program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <command.h>
++#include <libgen.h>
++#include <environment.h>
++
++static int do_dirname(int argc, char *argv[])
++{
++ if (argc != 3)
++ return COMMAND_ERROR_USAGE;
++
++ setenv(argv[2], dirname(argv[1]));
++
++ return 0;
++}
++
++BAREBOX_CMD_HELP_START(dirname)
++BAREBOX_CMD_HELP_USAGE("dirname NAME DIRNAME\n")
++BAREBOX_CMD_HELP_SHORT("strip last componext of NAME and store into $DIRNAME\n")
++BAREBOX_CMD_HELP_END
++
++BAREBOX_CMD_START(dirname)
++ .cmd = do_dirname,
++ .usage = "strip last component from file name",
++ BAREBOX_CMD_HELP(cmd_dirname_help)
++BAREBOX_CMD_END
+diff --git a/commands/flash.c b/commands/flash.c
+index 1fcb1cf..d71349a 100644
+--- a/commands/flash.c
++++ b/commands/flash.c
+@@ -41,7 +41,7 @@ static int do_flerase(int argc, char *argv[])
+ int fd;
+ char *filename = NULL;
+ struct stat s;
+- unsigned long start = 0, size = ~0;
++ loff_t start = 0, size = ~0;
+ int ret = 0;
+
+ if (argc == 1)
+@@ -109,7 +109,7 @@ static int do_protect(int argc, char *argv[])
+ char *filename = NULL;
+ struct stat s;
+ int prot = 1;
+- unsigned long start = 0, size = ~0;
++ loff_t start = 0, size = ~0;
+ int ret = 0, err;
+
+ if (argc == 1)
+diff --git a/commands/go.c b/commands/go.c
+index e9e9d40..14569a5 100644
+--- a/commands/go.c
++++ b/commands/go.c
+@@ -92,5 +92,5 @@ BAREBOX_CMD_START(go)
+ .cmd = do_go,
+ .usage = "start application at address or file",
+ BAREBOX_CMD_HELP(cmd_go_help)
+- BAREBOX_CMD_COMPLETE(cammand_var_complete)
++ BAREBOX_CMD_COMPLETE(command_var_complete)
+ BAREBOX_CMD_END
+diff --git a/commands/iomem.c b/commands/iomem.c
+index 70355fd..c22878c 100644
+--- a/commands/iomem.c
++++ b/commands/iomem.c
+@@ -32,8 +32,7 @@ static void __print_resources(struct resource *res, int indent)
+
+ printf(PRINTF_CONVERSION_RESOURCE " - " PRINTF_CONVERSION_RESOURCE
+ " (size " PRINTF_CONVERSION_RESOURCE ") %s\n", res->start,
+- res->start + res->size - 1,
+- res->size, res->name);
++ res->end, resource_size(res), res->name);
+
+ list_for_each_entry(r, &res->children, sibling)
+ __print_resources(r, indent + 1);
+diff --git a/commands/ls.c b/commands/ls.c
+index ad609f3..fbcbadc 100644
+--- a/commands/ls.c
++++ b/commands/ls.c
+@@ -35,7 +35,7 @@ static void ls_one(const char *path, struct stat *s)
+ unsigned int namelen = strlen(path);
+
+ mkmodestr(s->st_mode, modestr);
+- printf("%s %10lu %*.*s\n", modestr, s->st_size, namelen, namelen, path);
++ printf("%s %10llu %*.*s\n", modestr, s->st_size, namelen, namelen, path);
+ }
+
+ int ls(const char *path, ulong flags)
+diff --git a/commands/mem.c b/commands/mem.c
+index 080bfde..5322def 100644
+--- a/commands/mem.c
++++ b/commands/mem.c
+@@ -43,7 +43,7 @@
+ #define PRINTF(fmt,args...)
+ #endif
+
+-#define RW_BUF_SIZE (ulong)4096
++#define RW_BUF_SIZE 4096
+ static char *rw_buf;
+
+ static char *DEVMEM = "/dev/mem";
+@@ -55,7 +55,7 @@ static char *DEVMEM = "/dev/mem";
+ */
+ #define DISP_LINE_LEN 16
+
+-int memory_display(char *addr, ulong offs, ulong nbytes, int size)
++int memory_display(char *addr, loff_t offs, ulong nbytes, int size)
+ {
+ ulong linebytes, i;
+ u_char *cp;
+@@ -72,7 +72,7 @@ int memory_display(char *addr, ulong offs, ulong nbytes, int size)
+ u_char *ucp = (u_char *)linebuf;
+ uint count = 52;
+
+- printf("%08lx:", offs);
++ printf("%08llx:", offs);
+ linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
+
+ for (i = 0; i < linebytes; i += size) {
+@@ -108,7 +108,7 @@ int memory_display(char *addr, ulong offs, ulong nbytes, int size)
+ return 0;
+ }
+
+-static int open_and_lseek(const char *filename, int mode, off_t pos)
++static int open_and_lseek(const char *filename, int mode, loff_t pos)
+ {
+ int fd, ret;
+
+@@ -163,7 +163,7 @@ static int mem_parse_options(int argc, char *argv[], char *optstr, int *mode,
+
+ static int do_mem_md(int argc, char *argv[])
+ {
+- ulong start = 0, size = 0x100;
++ loff_t start = 0, size = 0x100;
+ int r, now;
+ int ret = 0;
+ int fd;
+@@ -180,6 +180,8 @@ static int do_mem_md(int argc, char *argv[])
+ }
+ if (size == ~0)
+ size = 0x100;
++ } else {
++ return COMMAND_ERROR_USAGE;
+ }
+
+ fd = open_and_lseek(filename, mode | O_RDONLY, start);
+@@ -187,7 +189,7 @@ static int do_mem_md(int argc, char *argv[])
+ return 1;
+
+ do {
+- now = min(size, RW_BUF_SIZE);
++ now = min(size, (loff_t)RW_BUF_SIZE);
+ r = read(fd, rw_buf, now);
+ if (r < 0) {
+ perror("read");
+@@ -240,7 +242,7 @@ static int do_mem_mw(int argc, char *argv[])
+ int fd;
+ char *filename = DEVMEM;
+ int mode = O_RWSIZE_4;
+- ulong adr;
++ loff_t adr;
+
+ if (mem_parse_options(argc, argv, "bwld:", &mode, NULL, &filename) < 0)
+ return 1;
+@@ -248,7 +250,7 @@ static int do_mem_mw(int argc, char *argv[])
+ if (optind + 1 >= argc)
+ return COMMAND_ERROR_USAGE;
+
+- adr = strtoul_suffix(argv[optind++], NULL, 0);
++ adr = strtoull_suffix(argv[optind++], NULL, 0);
+
+ fd = open_and_lseek(filename, mode | O_WRONLY, adr);
+ if (fd < 0)
+@@ -300,7 +302,7 @@ BAREBOX_CMD_END
+
+ static int do_mem_cmp(int argc, char *argv[])
+ {
+- ulong addr1, addr2, count = ~0;
++ loff_t addr1, addr2, count = ~0;
+ int mode = O_RWSIZE_1;
+ char *sourcefile = DEVMEM;
+ char *destfile = DEVMEM;
+@@ -316,8 +318,8 @@ static int do_mem_cmp(int argc, char *argv[])
+ if (optind + 2 > argc)
+ return COMMAND_ERROR_USAGE;
+
+- addr1 = strtoul_suffix(argv[optind], NULL, 0);
+- addr2 = strtoul_suffix(argv[optind + 1], NULL, 0);
++ addr1 = strtoull_suffix(argv[optind], NULL, 0);
++ addr2 = strtoull_suffix(argv[optind + 1], NULL, 0);
+
+ if (optind + 2 == argc) {
+ if (sourcefile == DEVMEM) {
+@@ -330,7 +332,7 @@ static int do_mem_cmp(int argc, char *argv[])
+ }
+ count = statbuf.st_size - addr1;
+ } else {
+- count = strtoul_suffix(argv[optind + 2], NULL, 0);
++ count = strtoull_suffix(argv[optind + 2], NULL, 0);
+ }
+
+ sourcefd = open_and_lseek(sourcefile, mode | O_RDONLY, addr1);
+@@ -348,7 +350,7 @@ static int do_mem_cmp(int argc, char *argv[])
+ while (count > 0) {
+ int now, r1, r2, i;
+
+- now = min(RW_BUF_SIZE, count);
++ now = min((loff_t)RW_BUF_SIZE, count);
+
+ r1 = read(sourcefd, rw_buf, now);
+ if (r1 < 0) {
+@@ -409,8 +411,7 @@ BAREBOX_CMD_END
+
+ static int do_mem_cp(int argc, char *argv[])
+ {
+- ulong count;
+- ulong dest, src;
++ loff_t count, dest, src;
+ char *sourcefile = DEVMEM;
+ char *destfile = DEVMEM;
+ int sourcefd, destfd;
+@@ -424,8 +425,8 @@ static int do_mem_cp(int argc, char *argv[])
+ if (optind + 2 > argc)
+ return COMMAND_ERROR_USAGE;
+
+- src = strtoul_suffix(argv[optind], NULL, 0);
+- dest = strtoul_suffix(argv[optind + 1], NULL, 0);
++ src = strtoull_suffix(argv[optind], NULL, 0);
++ dest = strtoull_suffix(argv[optind + 1], NULL, 0);
+
+ if (optind + 2 == argc) {
+ if (sourcefile == DEVMEM) {
+@@ -438,7 +439,7 @@ static int do_mem_cp(int argc, char *argv[])
+ }
+ count = statbuf.st_size - src;
+ } else {
+- count = strtoul_suffix(argv[optind + 2], NULL, 0);
++ count = strtoull_suffix(argv[optind + 2], NULL, 0);
+ }
+
+ sourcefd = open_and_lseek(sourcefile, mode | O_RDONLY, src);
+@@ -454,7 +455,7 @@ static int do_mem_cp(int argc, char *argv[])
+ while (count > 0) {
+ int now, r, w, tmp;
+
+- now = min(RW_BUF_SIZE, count);
++ now = min((loff_t)RW_BUF_SIZE, count);
+
+ r = read(sourcefd, rw_buf, now);
+ if (r < 0) {
+@@ -516,7 +517,7 @@ BAREBOX_CMD_END
+
+ static int do_memset(int argc, char *argv[])
+ {
+- ulong s, c, n;
++ loff_t s, c, n;
+ int fd;
+ char *buf;
+ int mode = O_RWSIZE_1;
+@@ -529,9 +530,9 @@ static int do_memset(int argc, char *argv[])
+ if (optind + 3 > argc)
+ return COMMAND_ERROR_USAGE;
+
+- s = strtoul_suffix(argv[optind], NULL, 0);
+- c = strtoul_suffix(argv[optind + 1], NULL, 0);
+- n = strtoul_suffix(argv[optind + 2], NULL, 0);
++ s = strtoull_suffix(argv[optind], NULL, 0);
++ c = strtoull_suffix(argv[optind + 1], NULL, 0);
++ n = strtoull_suffix(argv[optind + 2], NULL, 0);
+
+ fd = open_and_lseek(file, mode | O_WRONLY, s);
+ if (fd < 0)
+@@ -543,7 +544,7 @@ static int do_memset(int argc, char *argv[])
+ while (n > 0) {
+ int now;
+
+- now = min(RW_BUF_SIZE, n);
++ now = min((loff_t)RW_BUF_SIZE, n);
+
+ ret = write(fd, buf, now);
+ if (ret < 0) {
+@@ -594,7 +595,7 @@ static int mem_probe(struct device_d *dev)
+ dev->priv = cdev;
+
+ cdev->name = (char*)dev->resource[0].name;
+- cdev->size = (unsigned long)dev->resource[0].size;
++ cdev->size = (unsigned long)resource_size(&dev->resource[0]);
+ cdev->ops = &memops;
+ cdev->dev = dev;
+
+@@ -623,32 +624,3 @@ static int mem_init(void)
+ }
+
+ device_initcall(mem_init);
+-
+-static ssize_t zero_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags)
+-{
+- memset(buf, 0, count);
+- return count;
+-}
+-
+-static struct file_operations zeroops = {
+- .read = zero_read,
+- .lseek = dev_lseek_default,
+-};
+-
+-static int zero_init(void)
+-{
+- struct cdev *cdev;
+-
+- cdev = xzalloc(sizeof (*cdev));
+-
+- cdev->name = "zero";
+- cdev->size = ~0;
+- cdev->ops = &zeroops;
+-
+- devfs_create(cdev);
+-
+- return 0;
+-}
+-
+-device_initcall(zero_init);
+-
+diff --git a/commands/msleep.c b/commands/msleep.c
+new file mode 100644
+index 0000000..c9fa23c
+--- /dev/null
++++ b/commands/msleep.c
+@@ -0,0 +1,40 @@
++/*
++ * msleep.c - delay execution for n milliseconds
++ *
++ * Copyright (c) 2012 Steffen Trumtrar <s.trumtrar@pengutronix.de>, Pengutronix
++ *
++ * derived from commands/sleep.c
++ *
++ * This program is free software; you can 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 program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ */
++
++#include <common.h>
++#include <command.h>
++#include <clock.h>
++
++static int do_msleep(int argc, char *argv[])
++{
++ ulong delay;
++
++ if (argc != 2)
++ return COMMAND_ERROR_USAGE;
++
++ delay = simple_strtoul(argv[1], NULL, 10);
++
++ mdelay(delay);
++
++ return 0;
++}
++
++BAREBOX_CMD_START(msleep)
++ .cmd = do_msleep,
++ .usage = "delay execution for n milliseconds",
++BAREBOX_CMD_END
+diff --git a/commands/nand.c b/commands/nand.c
+index 34aa07b..6124dae 100644
+--- a/commands/nand.c
++++ b/commands/nand.c
+@@ -79,6 +79,7 @@ static int do_nand(int argc, char *argv[])
+ if (command & NAND_MARKBAD) {
+ if (optind < argc) {
+ int ret = 0, fd;
++ loff_t __badblock = badblock;
+
+ printf("marking block at 0x%08x on %s as bad\n", badblock, argv[optind]);
+
+@@ -88,7 +89,7 @@ static int do_nand(int argc, char *argv[])
+ return 1;
+ }
+
+- ret = ioctl(fd, MEMSETBADBLOCK, (void *)badblock);
++ ret = ioctl(fd, MEMSETBADBLOCK, &__badblock);
+ if (ret)
+ perror("ioctl");
+
+diff --git a/commands/nandtest.c b/commands/nandtest.c
+index d923e42..06b7f94 100644
+--- a/commands/nandtest.c
++++ b/commands/nandtest.c
+@@ -307,11 +307,11 @@ static int do_nandtest(int argc, char *argv[])
+ for (test_ofs = flash_offset;
+ test_ofs < flash_offset+length;
+ test_ofs += meminfo.erasesize) {
+-
++ loff_t __test_ofs = test_ofs;
+ srand(seed);
+ seed = rand();
+
+- if (ioctl(fd, MEMGETBADBLOCK, (void *)test_ofs)) {
++ if (ioctl(fd, MEMGETBADBLOCK, &__test_ofs)) {
+ printf("\rBad block at 0x%08x\n",
+ (unsigned)(test_ofs +
+ memregion.offset));
+diff --git a/commands/net.c b/commands/net.c
+index a453f4e..e77f12f 100644
+--- a/commands/net.c
++++ b/commands/net.c
+@@ -36,35 +36,6 @@
+ #include <errno.h>
+ #include <libbb.h>
+
+-#ifdef CONFIG_NET_RARP
+-extern void RarpRequest(void);
+-
+-static int do_rarpb(int argc, char *argv[])
+-{
+- int size;
+-
+- if (NetLoopInit(RARP) < 0)
+- return 1;
+-
+- NetOurIP = 0;
+- RarpRequest(); /* Basically same as BOOTP */
+-
+- if ((size = NetLoop()) < 0)
+- return 1;
+-
+- /* NetLoop ok, update environment */
+- netboot_update_env();
+-
+- return 0;
+-}
+-
+-BAREBOX_CMD_START(rarpboot)
+- .cmd = do_rarpb,
+- .usage = "boot image via network using rarp/tftp protocol",
+- BAREBOX_CMD_HELP("[loadAddress] [bootfilename]\n")
+-BAREBOX_CMD_END
+-#endif /* CONFIG_NET_RARP */
+-
+ static int do_ethact(int argc, char *argv[])
+ {
+ struct eth_device *edev;
+diff --git a/commands/poweroff.c b/commands/poweroff.c
+new file mode 100644
+index 0000000..ebb146c
+--- /dev/null
++++ b/commands/poweroff.c
+@@ -0,0 +1,37 @@
++/*
++ * poweroff.c - turn board's power off
++ *
++ * Copyright (C) 2011 Antony Pavlov <antonynpavlov@gmail.com>
++ *
++ * This file is part of barebox.
++ * See file CREDITS for list of people who contributed to this project.
++ *
++ * This program is free software; you can 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 program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <command.h>
++
++static int cmd_poweroff(int argc, char *argv[])
++{
++ poweroff();
++
++ /* Not reached */
++ return 1;
++}
++
++BAREBOX_CMD_START(poweroff)
++ .cmd = cmd_poweroff,
++ .usage = "Perform POWER OFF of the board",
++BAREBOX_CMD_END
+diff --git a/commands/sleep.c b/commands/sleep.c
+index c5f7867..950ec08 100644
+--- a/commands/sleep.c
++++ b/commands/sleep.c
+@@ -47,5 +47,5 @@ static int do_sleep(int argc, char *argv[])
+ BAREBOX_CMD_START(sleep)
+ .cmd = do_sleep,
+ .usage = "delay execution for n seconds",
+- BAREBOX_CMD_COMPLETE(cammand_var_complete)
++ BAREBOX_CMD_COMPLETE(command_var_complete)
+ BAREBOX_CMD_END
+diff --git a/commands/stddev.c b/commands/stddev.c
+new file mode 100644
+index 0000000..098aea8
+--- /dev/null
++++ b/commands/stddev.c
+@@ -0,0 +1,106 @@
++/*
++ * Copyright (c) 2011 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can 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 program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ * MA 02111-1307 USA
++ */
++
++#include <common.h>
++#include <init.h>
++
++static ssize_t zero_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags)
++{
++ memset(buf, 0, count);
++ return count;
++}
++
++static struct file_operations zeroops = {
++ .read = zero_read,
++ .lseek = dev_lseek_default,
++};
++
++static int zero_init(void)
++{
++ struct cdev *cdev;
++
++ cdev = xzalloc(sizeof (*cdev));
++
++ cdev->name = "zero";
++ cdev->flags = DEVFS_IS_CHARACTER_DEV;
++ cdev->ops = &zeroops;
++
++ devfs_create(cdev);
++
++ return 0;
++}
++
++device_initcall(zero_init);
++
++static ssize_t full_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags)
++{
++ memset(buf, 0xff, count);
++ return count;
++}
++
++static struct file_operations fullops = {
++ .read = full_read,
++ .lseek = dev_lseek_default,
++};
++
++static int full_init(void)
++{
++ struct cdev *cdev;
++
++ cdev = xzalloc(sizeof (*cdev));
++
++ cdev->name = "full";
++ cdev->flags = DEVFS_IS_CHARACTER_DEV;
++ cdev->ops = &fullops;
++
++ devfs_create(cdev);
++
++ return 0;
++}
++
++device_initcall(full_init);
++
++static ssize_t null_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags)
++{
++ return count;
++}
++
++static struct file_operations nullops = {
++ .write = null_write,
++ .lseek = dev_lseek_default,
++};
++
++static int null_init(void)
++{
++ struct cdev *cdev;
++
++ cdev = xzalloc(sizeof (*cdev));
++
++ cdev->name = "null";
++ cdev->flags = DEVFS_IS_CHARACTER_DEV;
++ cdev->ops = &nullops;
++
++ devfs_create(cdev);
++
++ return 0;
++}
++
++device_initcall(null_init);
+diff --git a/commands/wd.c b/commands/wd.c
+new file mode 100644
+index 0000000..080bab9
+--- /dev/null
++++ b/commands/wd.c
+@@ -0,0 +1,68 @@
++/*
++ * (c) 2012 Juergen Beisert <kernel@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <common.h>
++#include <command.h>
++#include <errno.h>
++#include <linux/ctype.h>
++#include <watchdog.h>
++
++/* default timeout in [sec] */
++static unsigned timeout = CONFIG_CMD_WD_DEFAULT_TIMOUT;
++
++static int do_wd(int argc, char *argv[])
++{
++ int rc;
++
++ if (argc > 1) {
++ if (isdigit(*argv[1])) {
++ timeout = simple_strtoul(argv[1], NULL, 0);
++ } else {
++ printf("numerical parameter expected\n");
++ return 1;
++ }
++ }
++
++ rc = watchdog_set_timeout(timeout);
++ if (rc < 0) {
++ switch (rc) {
++ case -EINVAL:
++ printf("Timeout value out of range\n");
++ break;
++ case -ENOSYS:
++ printf("Watchdog cannot be disabled\n");
++ break;
++ default:
++ printf("Watchdog fails: '%s'\n", strerror(-rc));
++ break;
++ }
++
++ return 1;
++ }
++
++ return 0;
++}
++
++BAREBOX_CMD_HELP_START(wd)
++BAREBOX_CMD_HELP_USAGE("wd [<time>]\n")
++BAREBOX_CMD_HELP_SHORT("enable the watchdog to bark in <time> seconds. "
++ "When <time> is 0, the watchdog gets disabled,\n"
++ "without a parameter the watchdog will be re-triggered\n")
++BAREBOX_CMD_HELP_END
++
++BAREBOX_CMD_START(wd)
++ .cmd = do_wd,
++ .usage = "enable/disable/trigger the watchdog",
++ BAREBOX_CMD_HELP(cmd_wd_help)
++BAREBOX_CMD_END
+diff --git a/common/block.c b/common/block.c
+index 71ecfd5..7ad5ecc 100644
+--- a/common/block.c
++++ b/common/block.c
+@@ -24,6 +24,7 @@
+ #include <malloc.h>
+ #include <linux/err.h>
+ #include <linux/list.h>
++#include <dma.h>
+
+ #define BLOCKSIZE(blk) (1 << blk->blockbits)
+
+@@ -179,7 +180,7 @@ static void *block_get(struct block_device *blk, int block)
+ }
+
+ static ssize_t block_read(struct cdev *cdev, void *buf, size_t count,
+- unsigned long offset, unsigned long flags)
++ loff_t offset, unsigned long flags)
+ {
+ struct block_device *blk = cdev->priv;
+ unsigned long mask = BLOCKSIZE(blk) - 1;
+@@ -256,7 +257,7 @@ static int block_put(struct block_device *blk, const void *buf, int block)
+ }
+
+ static ssize_t block_write(struct cdev *cdev, const void *buf, size_t count,
+- unsigned long offset, ulong flags)
++ loff_t offset, ulong flags)
+ {
+ struct block_device *blk = cdev->priv;
+ unsigned long mask = BLOCKSIZE(blk) - 1;
+@@ -338,7 +339,7 @@ static struct file_operations block_ops = {
+
+ int blockdevice_register(struct block_device *blk)
+ {
+- size_t size = blk->num_blocks * BLOCKSIZE(blk);
++ loff_t size = (loff_t)blk->num_blocks * BLOCKSIZE(blk);
+ int ret;
+ int i;
+
+@@ -357,7 +358,7 @@ int blockdevice_register(struct block_device *blk)
+
+ for (i = 0; i < 8; i++) {
+ struct chunk *chunk = xzalloc(sizeof(*chunk));
+- chunk->data = xmalloc(BUFSIZE);
++ chunk->data = dma_alloc(BUFSIZE);
+ chunk->num = i;
+ list_add_tail(&chunk->list, &blk->idle_blocks);
+ }
+@@ -376,12 +377,12 @@ int blockdevice_unregister(struct block_device *blk)
+ writebuffer_flush(blk);
+
+ list_for_each_entry_safe(chunk, tmp, &blk->buffered_blocks, list) {
+- free(chunk->data);
++ dma_free(chunk->data);
+ free(chunk);
+ }
+
+ list_for_each_entry_safe(chunk, tmp, &blk->idle_blocks, list) {
+- free(chunk->data);
++ dma_free(chunk->data);
+ free(chunk);
+ }
+
+diff --git a/common/complete.c b/common/complete.c
+index 0780888..a8bde8d 100644
+--- a/common/complete.c
++++ b/common/complete.c
+@@ -198,7 +198,7 @@ int empty_complete(struct string_list *sl, char *instr)
+ return COMPLETE_END;
+ }
+
+-int cammand_var_complete(struct string_list *sl, char *instr)
++int command_var_complete(struct string_list *sl, char *instr)
+ {
+ return COMPLETE_CONTINUE;
+ }
+@@ -221,7 +221,7 @@ static int env_param_complete(struct string_list *sl, char *instr, int eval)
+ end = ' ';
+ }
+
+- instr_param = strrchr(instr, '.');
++ instr_param = strchr(instr, '.');
+ len = strlen(instr);
+
+ current_c = get_current_context();
+diff --git a/common/filetype.c b/common/filetype.c
+index 39c2098..1a5b82d 100644
+--- a/common/filetype.c
++++ b/common/filetype.c
+@@ -39,6 +39,7 @@ static const char *filetype_str[] = {
+ [filetype_oftree] = "open firmware flat device tree",
+ [filetype_aimage] = "Android boot image",
+ [filetype_sh] = "Bourne Shell",
++ [filetype_mips_barebox] = "MIPS barebox image",
+ };
+
+ const char *file_type_to_string(enum filetype f)
+diff --git a/common/memory.c b/common/memory.c
+index 3b4a5ef..f04cfac 100644
+--- a/common/memory.c
++++ b/common/memory.c
+@@ -122,7 +122,7 @@ void barebox_add_memory_bank(const char *name, resource_size_t start,
+ struct memory_bank *bank = xzalloc(sizeof(*bank));
+ struct device_d *dev;
+
+- bank->res = request_iomem_region(name, start, size);
++ bank->res = request_iomem_region(name, start, start + size - 1);
+
+ BUG_ON(!bank->res);
+
+@@ -146,7 +146,7 @@ struct resource *request_sdram_region(const char *name, resource_size_t start,
+ for_each_memory_bank(bank) {
+ struct resource *res;
+
+- res = request_region(bank->res, name, start, size);
++ res = request_region(bank->res, name, start, start + size - 1);
+ if (res)
+ return res;
+ }
+diff --git a/common/menu.c b/common/menu.c
+index 6c530b6..9f536d6 100644
+--- a/common/menu.c
++++ b/common/menu.c
+@@ -53,7 +53,6 @@ void menu_free(struct menu *m)
+ free(m->name);
+ free(m->display);
+ free(m->auto_display);
+- free(m->display_buffer);
+
+ list_for_each_entry_safe(me, tmp, &m->entries, list)
+ menu_entry_free(me);
+@@ -87,15 +86,9 @@ EXPORT_SYMBOL(menu_remove);
+
+ int menu_add_entry(struct menu *m, struct menu_entry *me)
+ {
+- int len;
+-
+ if (!m || !me || !me->display)
+ return -EINVAL;
+
+- len = strlen(me->display);
+-
+- m->width = max(len, m->width);
+-
+ m->nb_entries++;
+ me->num = m->nb_entries;
+ list_add_tail(&me->list, &m->entries);
+@@ -160,6 +153,18 @@ void menu_entry_free(struct menu_entry *me)
+ }
+ EXPORT_SYMBOL(menu_entry_free);
+
++static void __print_entry(const char *str)
++{
++ static char outstr[256];
++
++ if (IS_ENABLED(CONFIG_SHELL_HUSH)) {
++ process_escape_sequence(str, outstr, 256);
++ puts(outstr);
++ } else {
++ puts(str);
++ }
++}
++
+ static void print_menu_entry(struct menu *m, struct menu_entry *me,
+ int selected)
+ {
+@@ -174,17 +179,11 @@ static void print_menu_entry(struct menu *m, struct menu_entry *me,
+ puts(" ");
+ }
+
+- if (IS_ENABLED(CONFIG_SHELL_HUSH))
+- process_escape_sequence(me->display, m->display_buffer,
+- m->display_buffer_size);
+-
+ printf(" %d: ", me->num);
+ if (selected)
+ puts("\e[7m");
+- if (IS_ENABLED(CONFIG_SHELL_HUSH))
+- puts(m->display_buffer);
+- else
+- puts(me->display);
++
++ __print_entry(me->display);
+
+ if (selected)
+ puts("\e[m");
+@@ -241,13 +240,7 @@ static void print_menu(struct menu *m)
+ clear();
+ gotoXY(1, 2);
+ if(m->display) {
+- if (IS_ENABLED(CONFIG_SHELL_HUSH)) {
+- process_escape_sequence(m->display, m->display_buffer,
+- m->display_buffer_size);
+- puts(m->display_buffer);
+- } else {
+- puts(m->display);
+- }
++ __print_entry(m->display);
+ } else {
+ puts("Menu : ");
+ puts(m->name);
+@@ -266,50 +259,16 @@ static void print_menu(struct menu *m)
+ print_menu_entry(m, m->selected, 1);
+ }
+
+-static int menu_alloc_display_buffer(struct menu *m)
+-{
+- int min_size;
+-
+- if (m->display)
+- min_size = max((int)strlen(m->display), m->width);
+- else
+- min_size = m->width;
+-
+-
+- if (m->display_buffer) {
+- if (m->display_buffer_size >= min_size)
+- return 0;
+- m->display_buffer = realloc(m->display_buffer, min_size * sizeof(char));
+- } else {
+- m->display_buffer = calloc(min_size, sizeof(char));
+- }
+-
+- if (!m->display_buffer) {
+- perror("display_buffer");
+- return -ENOMEM;
+- }
+-
+- m->display_buffer_size = min_size;
+-
+- return 0;
+-}
+-
+ int menu_show(struct menu *m)
+ {
+ int ch, ch_previous = 0;
+- int escape = 0;
+ int countdown;
+ int auto_display_len = 16;
+ uint64_t start, second;
+- int ret;
+
+ if(!m || list_empty(&m->entries))
+ return -EINVAL;
+
+- ret = menu_alloc_display_buffer(m);
+- if (ret)
+- return ret;
+-
+ print_menu(m);
+
+ countdown = m->auto_select;
+@@ -344,41 +303,34 @@ int menu_show(struct menu *m)
+ gotoXY(m->selected->num + 1, 3);
+
+ do {
++ struct menu_entry *old_selected = m->selected;
++ int repaint = 0;
++
+ if (m->auto_select >= 0)
+ ch = KEY_RETURN;
+ else
+- ch = getc();
++ ch = read_key();
+
+ m->auto_select = -1;
+
+- switch(ch) {
+- case 0x1b:
+- escape = 1;
+- break;
+- case '[':
+- if (escape)
+- break;
+- case 'A': /* up */
+- escape = 0;
+- print_menu_entry(m, m->selected, 0);
++ switch (ch) {
++ case KEY_UP:
+ m->selected = list_entry(m->selected->list.prev, struct menu_entry,
+ list);
+ if (&(m->selected->list) == &(m->entries)) {
+ m->selected = list_entry(m->selected->list.prev, struct menu_entry,
+ list);
+ }
+- print_menu_entry(m, m->selected, 1);
++ repaint = 1;
+ break;
+- case 'B': /* down */
+- escape = 0;
+- print_menu_entry(m, m->selected, 0);
++ case KEY_DOWN:
+ m->selected = list_entry(m->selected->list.next, struct menu_entry,
+ list);
+ if (&(m->selected->list) == &(m->entries)) {
+ m->selected = list_entry(m->selected->list.next, struct menu_entry,
+ list);
+ }
+- print_menu_entry(m, m->selected, 1);
++ repaint = 1;
+ break;
+ case ' ':
+ if (m->selected->type != MENU_ENTRY_BOX)
+@@ -386,7 +338,7 @@ int menu_show(struct menu *m)
+ m->selected->box_state = !m->selected->box_state;
+ if (m->selected->action)
+ m->selected->action(m, m->selected);
+- print_menu_entry(m, m->selected, 1);
++ repaint = 1;
+ break;
+ case KEY_ENTER:
+ if (ch_previous == KEY_RETURN)
+@@ -401,9 +353,24 @@ int menu_show(struct menu *m)
+ return m->selected->num;
+ else
+ print_menu(m);
++ break;
++ case KEY_HOME:
++ m->selected = list_first_entry(&m->entries, struct menu_entry, list);
++ repaint = 1;
++ break;
++ case KEY_END:
++ m->selected = list_last_entry(&m->entries, struct menu_entry, list);
++ repaint = 1;
++ break;
+ default:
+ break;
+ }
++
++ if (repaint) {
++ print_menu_entry(m, old_selected, 0);
++ print_menu_entry(m, m->selected, 1);
++ }
++
+ ch_previous = ch;
+ } while(1);
+
+diff --git a/common/oftree.c b/common/oftree.c
+index 49758a9..677e934 100644
+--- a/common/oftree.c
++++ b/common/oftree.c
+@@ -207,7 +207,7 @@ int fdt_find_and_setprop(struct fdt_header *fdt, const char *node,
+ if (nodeoff < 0)
+ return nodeoff;
+
+- if ((!create) && (fdt_get_property(fdt, nodeoff, prop, 0) == NULL))
++ if ((!create) && (fdt_get_property(fdt, nodeoff, prop, NULL) == NULL))
+ return 0; /* create flag not set; so exit quietly */
+
+ return fdt_setprop(fdt, nodeoff, prop, val, len);
+diff --git a/common/partitions.c b/common/partitions.c
+index 74b4f12..78b09fc 100644
+--- a/common/partitions.c
++++ b/common/partitions.c
+@@ -31,6 +31,7 @@
+ #include <block.h>
+ #include <asm/unaligned.h>
+ #include <disks.h>
++#include <dma.h>
+
+ struct partition {
+ uint64_t first_sec;
+@@ -43,23 +44,6 @@ struct partition_desc {
+ };
+
+ /**
+- * Reject values which cannot be used in Barebox
+- * @param val Value to be check
+- * @return 0 if value can be used in Barebox, -EINVAL if not
+- *
+- * @note this routine can be removed when Barebox uses file offsets larger
+- * than 32 bit
+- */
+-static int check_offset_value(uint64_t val)
+-{
+-#if 1 /* until Barebox can handle 64 bit offsets */
+- if (val > (__INT_MAX__ / SECTOR_SIZE))
+- return -EINVAL;
+-#endif
+- return 0;
+-}
+-
+-/**
+ * Guess the size of the disk, based on the partition table entries
+ * @param dev device to create partitions for
+ * @param table partition table
+@@ -76,12 +60,6 @@ static int disk_guess_size(struct device_d *dev, struct partition_entry *table)
+ size += get_unaligned(&table[i].partition_size);
+ }
+ }
+- /* limit disk sector counts we can't handle due to 32 bit limits */
+- if (check_offset_value(size) != 0) {
+- dev_warn(dev, "Warning: Sector count limited due to 31 bit"
+- "contraints\n");
+- size = __INT_MAX__ / SECTOR_SIZE;
+- }
+
+ return (int)size;
+ }
+@@ -102,7 +80,7 @@ static void __maybe_unused try_dos_partition(struct block_device *blk,
+ struct partition pentry;
+ int i, rc;
+
+- buffer = xmalloc(SECTOR_SIZE);
++ buffer = dma_alloc(SECTOR_SIZE);
+
+ /* read in the MBR to get the partition table */
+ rc = blk->ops->read(blk, buffer, 0, 1);
+@@ -119,19 +97,13 @@ static void __maybe_unused try_dos_partition(struct block_device *blk,
+ table = (struct partition_entry *)&buffer[446];
+
+ /* valid for x86 BIOS based disks only */
+- if (blk->num_blocks == 0)
++ if (IS_ENABLED(CONFIG_DISK_BIOS) && blk->num_blocks == 0)
+ blk->num_blocks = disk_guess_size(blk->dev, table);
+
+ for (i = 0; i < 4; i++) {
+ pentry.first_sec = get_unaligned(&table[i].partition_start);
+ pentry.size = get_unaligned(&table[i].partition_size);
+
+- /* do we have to ignore this partition due to limitations? */
+- if (check_offset_value(pentry.first_sec) != 0)
+- continue;
+- if (check_offset_value(pentry.size) != 0)
+- continue;
+-
+ if (pentry.first_sec != 0) {
+ pd->parts[pd->used_entries].first_sec = pentry.first_sec;
+ pd->parts[pd->used_entries].size = pentry.size;
+@@ -142,7 +114,7 @@ static void __maybe_unused try_dos_partition(struct block_device *blk,
+ }
+
+ on_error:
+- free(buffer);
++ dma_free(buffer);
+ }
+
+ /**
+diff --git a/common/resource.c b/common/resource.c
+index 63e9c49..ce5aa27 100644
+--- a/common/resource.c
++++ b/common/resource.c
+@@ -42,16 +42,20 @@ static int init_resource(struct resource *res, const char *name)
+ */
+ struct resource *request_region(struct resource *parent,
+ const char *name, resource_size_t start,
+- resource_size_t size)
++ resource_size_t end)
+ {
+ struct resource *r, *new;
+
++ if (end < start) {
++ debug("%s: request region 0x%08x:0x%08x: end < start\n",
++ __func__, start, end);
++ return NULL;
++ }
++
+ /* outside parent resource? */
+- if (start < parent->start ||
+- start + size > parent->start + parent->size) {
++ if (start < parent->start || end > parent->end) {
+ debug("%s: 0x%08x:0x%08x outside parent resource 0x%08x:0x%08x\n",
+- __func__, start, size, parent->start,
+- parent->size);
++ __func__, start, end, parent->start, parent->end);
+ return NULL;
+ }
+
+@@ -60,22 +64,22 @@ struct resource *request_region(struct resource *parent,
+ * us searching for conflicts here.
+ */
+ list_for_each_entry(r, &parent->children, sibling) {
+- if (start + size <= r->start)
++ if (end < r->start)
+ goto ok;
+- if (start >= r->start + r->size)
++ if (start > r->end)
+ continue;
+ debug("%s: 0x%08x:0x%08x conflicts with 0x%08x:0x%08x\n",
+- __func__, start, size, r->start, r->size);
++ __func__, start, end, r->start, r->end);
+ return NULL;
+ }
+
+ ok:
+- debug("%s ok: 0x%08x 0x%08x\n", __func__, start, size);
++ debug("%s ok: 0x%08x:0x%08x\n", __func__, start, end);
+
+ new = xzalloc(sizeof(*new));
+ init_resource(new, name);
+ new->start = start;
+- new->size = size;
++ new->end = end;
+ new->parent = parent;
+ list_add_tail(&new->sibling, &r->sibling);
+
+@@ -100,16 +104,16 @@ int release_region(struct resource *res)
+ /* The root resource for the whole io space */
+ struct resource iomem_resource = {
+ .start = 0,
+- .size = ~0,
++ .end = 0xffffffff,
+ };
+
+ /*
+ * request a region inside the io space
+ */
+ struct resource *request_iomem_region(const char *name,
+- resource_size_t start, resource_size_t size)
++ resource_size_t start, resource_size_t end)
+ {
+- return request_region(&iomem_resource, name, start, size);
++ return request_region(&iomem_resource, name, start, end);
+ }
+
+ static int iomem_init(void)
+diff --git a/common/tlsf.c b/common/tlsf.c
+index c810e8d..9515ac7 100644
+--- a/common/tlsf.c
++++ b/common/tlsf.c
+@@ -367,7 +367,7 @@ static block_header_t* search_suitable_block(pool_t* pool, int* fli, int* sli)
+ if (!fl_map)
+ {
+ /* No free blocks available, memory has been exhausted. */
+- return 0;
++ return NULL;
+ }
+
+ fl = tlsf_ffs(fl_map);
+@@ -563,7 +563,7 @@ static block_header_t* block_trim_free_leading(pool_t* pool, block_header_t* blo
+ static block_header_t* block_locate_free(pool_t* pool, size_t size)
+ {
+ int fl = 0, sl = 0;
+- block_header_t* block = 0;
++ block_header_t* block = NULL;
+
+ if (size)
+ {
+@@ -582,7 +582,7 @@ static block_header_t* block_locate_free(pool_t* pool, size_t size)
+
+ static void* block_prepare_used(pool_t* pool, block_header_t* block, size_t size)
+ {
+- void* p = 0;
++ void* p = NULL;
+ if (block)
+ {
+ block_trim_free(pool, block, size);
+@@ -737,7 +737,7 @@ size_t tlsf_block_size(void* ptr)
+ ** tlsf_create, equal to the size of a pool_t plus overhead of the initial
+ ** free block and the sentinel block.
+ */
+-size_t tlsf_overhead()
++size_t tlsf_overhead(void)
+ {
+ const size_t pool_overhead = sizeof(pool_t) + 2 * block_header_overhead;
+ return pool_overhead;
+@@ -790,7 +790,7 @@ tlsf_pool tlsf_create(void* mem, size_t bytes)
+ (unsigned int)(pool_overhead + block_size_min),
+ (unsigned int)(pool_overhead + block_size_max));
+ #endif
+- return 0;
++ return NULL;
+ }
+
+ /* Construct a valid pool object. */
+@@ -915,7 +915,7 @@ void tlsf_free(tlsf_pool tlsf, void* ptr)
+ void* tlsf_realloc(tlsf_pool tlsf, void* ptr, size_t size)
+ {
+ pool_t* pool = tlsf_cast(pool_t*, tlsf);
+- void* p = 0;
++ void* p = NULL;
+
+ /* Zero-size requests are treated as free. */
+ if (ptr && size == 0)
+diff --git a/common/uimage.c b/common/uimage.c
+index 945f3d6..43878b5 100644
+--- a/common/uimage.c
++++ b/common/uimage.c
+@@ -354,9 +354,9 @@ static struct resource *uimage_resource;
+
+ static int uimage_sdram_flush(void *buf, unsigned int len)
+ {
+- if (uimage_size + len > uimage_resource->size) {
+- resource_size_t start = uimage_resource->start;
+- resource_size_t size = uimage_resource->size + len;
++ if (uimage_size + len > resource_size(uimage_resource)) {
++ resource_size_t start = resource_size(uimage_resource);
++ resource_size_t size = resource_size(uimage_resource) + len;
+ release_sdram_region(uimage_resource);
+
+ uimage_resource = request_sdram_region("uimage",
+diff --git a/defaultenv-2/base/bin/ifup b/defaultenv-2/base/bin/ifup
+index 9f6fd6b..37b986c 100644
+--- a/defaultenv-2/base/bin/ifup
++++ b/defaultenv-2/base/bin/ifup
+@@ -51,9 +51,17 @@ if [ "$ip" = static ]; then
+ ${interface}.netmask=$netmask
+ ${interface}.serverip=$serverip
+ ${interface}.gateway=$gateway
++ ret=0
+ elif [ "$ip" = dhcp ]; then
+ dhcp
+- exit $?
++ ret=$?
++ if [ $ret = 0 -a -n "$serverip" ]; then
++ ${interface}.serverip=$serverip
++ fi
++fi
++
++if [ $ret = 0 ]; then
++ echo -o /tmp/network/$interface up
+ fi
+
+-echo -o /tmp/network/$interface up
++exit $ret
+diff --git a/defaultenv-2/base/bin/init b/defaultenv-2/base/bin/init
+index e293c62..9d7eb2e 100644
+--- a/defaultenv-2/base/bin/init
++++ b/defaultenv-2/base/bin/init
+@@ -4,8 +4,6 @@ export PATH=/env/bin
+
+ global hostname=generic
+ global user=none
+-global tftp.server
+-global tftp.path=/mnt/tftp-dhcp
+ global autoboot_timeout=3
+ global boot.default=net
+ global allow_color=true
+diff --git a/defaultenv-2/base/boot/initrd b/defaultenv-2/base/boot/initrd
+index 1a1e629..79a353a 100644
+--- a/defaultenv-2/base/boot/initrd
++++ b/defaultenv-2/base/boot/initrd
+@@ -5,8 +5,9 @@ if [ "$1" = menu ]; then
+ exit
+ fi
+
+-global.bootm.image="${global.tftp.path}/${global.user}-linux-${global.hostname}"
+-global.bootm.initrd="${global.tftp.path}/initramfs"
++path="/mnt/tftp"
++global.bootm.image="${path}/${global.user}-linux-${global.hostname}"
++global.bootm.initrd="${path}/initramfs"
+ bootargs-root-initrd
+ #global.bootm.oftree=<path to oftree>
+
+diff --git a/defaultenv-2/base/boot/net b/defaultenv-2/base/boot/net
+index 2684c20..922bef1 100644
+--- a/defaultenv-2/base/boot/net
++++ b/defaultenv-2/base/boot/net
+@@ -5,8 +5,10 @@ if [ "$1" = menu ]; then
+ exit
+ fi
+
+-global.bootm.image="${global.tftp.path}/${global.user}-linux-${global.hostname}"
+-#global.bootm.oftree="${global.tftp.path}/${global.user}-oftree-${global.hostname}"
++path="/mnt/tftp"
++
++global.bootm.image="${path}/${global.user}-linux-${global.hostname}"
++#global.bootm.oftree="${path}/${global.user}-oftree-${global.hostname}"
+ nfsroot="/home/${global.user}/nfsroot/${global.hostname}"
+ bootargs-ip
+ bootargs-root-nfs -n "$nfsroot"
+diff --git a/defaultenv-2/base/init/automount b/defaultenv-2/base/init/automount
+index 63099f9..7b53309 100644
+--- a/defaultenv-2/base/init/automount
++++ b/defaultenv-2/base/init/automount
+@@ -5,10 +5,10 @@ if [ "$1" = menu ]; then
+ exit
+ fi
+
+-# automount server returned from dhcp server
++# automount tftp server based on $eth0.serverip
+
+-mkdir -p /mnt/tftp-dhcp
+-automount /mnt/tftp-dhcp 'ifup eth0 && mount $eth0.serverip tftp /mnt/tftp-dhcp'
++mkdir -p /mnt/tftp
++automount /mnt/tftp 'ifup eth0 && mount $eth0.serverip tftp /mnt/tftp'
+
+ # automount nfs server example
+
+@@ -16,11 +16,6 @@ automount /mnt/tftp-dhcp 'ifup eth0 && mount $eth0.serverip tftp /mnt/tftp-dhcp'
+ #mkdir -p /mnt/${nfshost}
+ #automount /mnt/$nfshost "ifup eth0 && mount ${nfshost}:/tftpboot nfs /mnt/${nfshost}"
+
+-# static tftp server example
+-
+-#mkdir -p /mnt/tftp
+-#automount -d /mnt/tftp 'ifup eth0 && mount $serverip tftp /mnt/tftp'
+-
+ # FAT on usb disk example
+
+ #mkdir -p /mnt/fat
+diff --git a/defaultenv-2/base/init/general b/defaultenv-2/base/init/general
+index ad6c860..98a92d1 100644
+--- a/defaultenv-2/base/init/general
++++ b/defaultenv-2/base/init/general
+@@ -13,6 +13,3 @@ global.autoboot_timeout=3
+
+ # default boot entry (one of /env/boot/*)
+ global.boot.default=net
+-
+-# default tftp path
+-global.tftp.path=/mnt/tftp-dhcp
+diff --git a/defaultenv/bin/init b/defaultenv/bin/init
+index 6e85a82..f535e37 100644
+--- a/defaultenv/bin/init
++++ b/defaultenv/bin/init
+@@ -23,7 +23,7 @@ fi
+
+ if [ -f /env/bin/boot_board ]; then
+ . /env/bin/boot_board
+-else
++elif [ -n $autoboot_timeout ]; then
+ echo
+ echo -n "Hit any key to stop autoboot: "
+ timeout -a $autoboot_timeout
+diff --git a/drivers/Kconfig b/drivers/Kconfig
+index c52c56a..883b0e7 100644
+--- a/drivers/Kconfig
++++ b/drivers/Kconfig
+@@ -15,7 +15,8 @@ source "drivers/mfd/Kconfig"
+ source "drivers/led/Kconfig"
+ source "drivers/eeprom/Kconfig"
+ source "drivers/input/Kconfig"
+-
++source "drivers/watchdog/Kconfig"
+ source "drivers/pwm/Kconfig"
++source "drivers/dma/Kconfig"
+
+ endmenu
+diff --git a/drivers/Makefile b/drivers/Makefile
+index 3aefc12..ea3263f 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -15,3 +15,5 @@ obj-$(CONFIG_LED) += led/
+ obj-y += eeprom/
+ obj-$(CONFIG_PWM) += pwm/
+ obj-y += input/
++obj-y += dma/
++obj-y += watchdog/
+diff --git a/drivers/ata/disk_ata_drive.c b/drivers/ata/disk_ata_drive.c
+index 4602af3..d5c5837 100644
+--- a/drivers/ata/disk_ata_drive.c
++++ b/drivers/ata/disk_ata_drive.c
+@@ -231,7 +231,7 @@ static void __maybe_unused ata_dump_id(uint16_t *id)
+ */
+ static void ata_fix_endianess(uint16_t *buf, unsigned wds)
+ {
+-#if __BYTE_ORDER == __BIG_ENDIAN
++#ifdef __BIG_ENDIAN
+ unsigned u;
+
+ for (u = 0; u < wds; u++)
+diff --git a/drivers/base/driver.c b/drivers/base/driver.c
+index 81cedca..6cd4286 100644
+--- a/drivers/base/driver.c
++++ b/drivers/base/driver.c
+@@ -241,15 +241,15 @@ static struct resource *dev_get_resource(struct device_d *dev, int num)
+ return NULL;
+ }
+
+-void __iomem *dev_get_mem_region(struct device_d *dev, int num)
++void *dev_get_mem_region(struct device_d *dev, int num)
+ {
+ struct resource *res;
+
+ res = dev_get_resource(dev, num);
+ if (!res)
+- return res;
++ return NULL;
+
+- return (void __force __iomem *)res->start;
++ return (void __force *)res->start;
+ }
+ EXPORT_SYMBOL(dev_get_mem_region);
+
+@@ -261,7 +261,7 @@ void __iomem *dev_request_mem_region(struct device_d *dev, int num)
+ if (!res)
+ return NULL;
+
+- res = request_iomem_region(dev_name(dev), res->start, res->size);
++ res = request_iomem_region(dev_name(dev), res->start, res->end);
+ if (!res)
+ return NULL;
+
+@@ -339,7 +339,7 @@ static int do_devinfo_subtree(struct device_d *dev, int depth)
+ list_for_each_entry(cdev, &dev->cdevs, devices_list) {
+ for (i = 0; i < depth + 1; i++)
+ printf(" ");
+- printf("`---- 0x%08lx-0x%08lx: /dev/%s\n",
++ printf("`---- 0x%08llx-0x%08llx: /dev/%s\n",
+ cdev->offset,
+ cdev->offset + cdev->size - 1,
+ cdev->name);
+@@ -392,7 +392,7 @@ static int do_devinfo(int argc, char *argv[])
+ printf("name : %s\n", res->name);
+ printf("start : " PRINTF_CONVERSION_RESOURCE "\nsize : "
+ PRINTF_CONVERSION_RESOURCE "\n",
+- res->start, res->size);
++ res->start, resource_size(res));
+ }
+
+ printf("driver: %s\n\n", dev->driver ?
+diff --git a/drivers/base/resource.c b/drivers/base/resource.c
+index 9844d1a..988d27e 100644
+--- a/drivers/base/resource.c
++++ b/drivers/base/resource.c
+@@ -47,7 +47,7 @@ struct device_d *add_generic_device(const char* devname, int id, const char *res
+ if (resname)
+ res[0].name = xstrdup(resname);
+ res[0].start = start;
+- res[0].size = size;
++ res[0].end = start + size - 1;
+ res[0].flags = flags;
+
+ return add_generic_device_res(devname, id, res, 1, pdata);
+@@ -94,10 +94,10 @@ struct device_d *add_dm9000_device(int id, resource_size_t base,
+ }
+
+ res[0].start = base;
+- res[0].size = size;
++ res[0].end = base + size - 1;
+ res[0].flags = IORESOURCE_MEM | flags;
+ res[1].start = data;
+- res[1].size = size;
++ res[1].end = data + size - 1;
+ res[1].flags = IORESOURCE_MEM | flags;
+
+ return add_generic_device_res("dm9000", id, res, 2, pdata);
+@@ -113,10 +113,10 @@ struct device_d *add_usb_ehci_device(int id, resource_size_t hccr,
+
+ res = xzalloc(sizeof(struct resource) * 2);
+ res[0].start = hccr;
+- res[0].size = 0x10;
++ res[0].end = hccr + 0x10 - 1;
+ res[0].flags = IORESOURCE_MEM;
+ res[1].start = hcor;
+- res[1].size = 0xc0;
++ res[1].end = hcor + 0xc0 - 1;
+ res[1].flags = IORESOURCE_MEM;
+
+ return add_generic_device_res("ehci", id, res, 2, pdata);
+@@ -146,10 +146,10 @@ struct device_d *add_ks8851_device(int id, resource_size_t addr,
+ res = xzalloc(sizeof(struct resource) * 2);
+
+ res[0].start = addr;
+- res[0].size = size;
++ res[0].end = addr + size - 1;
+ res[0].flags = IORESOURCE_MEM | flags;
+ res[1].start = addr_cmd;
+- res[1].size = size;
++ res[1].end = addr_cmd + size - 1;
+ res[1].flags = IORESOURCE_MEM | flags;
+
+ return add_generic_device_res("ks8851_mll", id, res, 2, pdata);
+diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
+new file mode 100644
+index 0000000..ec6c894
+--- /dev/null
++++ b/drivers/dma/Kconfig
+@@ -0,0 +1,8 @@
++menu "DMA support"
++
++config MXS_APBH_DMA
++ tristate "MXS APBH DMA ENGINE"
++ depends on ARCH_IMX23 || ARCH_IMX28
++ help
++ Experimental!
++endmenu
+diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
+new file mode 100644
+index 0000000..7a3a3b2
+--- /dev/null
++++ b/drivers/dma/Makefile
+@@ -0,0 +1 @@
++obj-$(CONFIG_MXS_APBH_DMA) += apbh_dma.o
+diff --git a/drivers/dma/apbh_dma.c b/drivers/dma/apbh_dma.c
+new file mode 100644
+index 0000000..363878f
+--- /dev/null
++++ b/drivers/dma/apbh_dma.c
+@@ -0,0 +1,598 @@
++/*
++ * Freescale i.MX28 APBH DMA driver
++ *
++ * Copyright (C) 2011 Wolfram Sang <w.sang@pengutronix.de>
++ *
++ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
++ * on behalf of DENX Software Engineering GmbH
++ *
++ * Based on code from LTIB:
++ * Copyright (C) 2010 Freescale Semiconductor, Inc. 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 as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/list.h>
++
++#include <common.h>
++#include <malloc.h>
++#include <errno.h>
++#include <asm/mmu.h>
++#include <asm/io.h>
++#include <mach/clock.h>
++#include <mach/imx-regs.h>
++#include <mach/dma.h>
++#include <mach/mxs.h>
++
++#define HW_APBHX_CTRL0 0x000
++#define BM_APBH_CTRL0_APB_BURST8_EN (1 << 29)
++#define BM_APBH_CTRL0_APB_BURST_EN (1 << 28)
++#define BP_APBH_CTRL0_CLKGATE_CHANNEL 8
++#define BP_APBH_CTRL0_RESET_CHANNEL 16
++#define HW_APBHX_CTRL1 0x010
++#define BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN 16
++#define HW_APBHX_CTRL2 0x020
++#define HW_APBHX_CHANNEL_CTRL 0x030
++#define BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL 16
++#define HW_APBH_VERSION (cpu_is_mx23() ? 0x3f0 : 0x800)
++#define HW_APBX_VERSION 0x800
++#define BP_APBHX_VERSION_MAJOR 24
++#define HW_APBHX_CHn_NXTCMDAR(n) \
++ ((apbh_is_old ? 0x050 : 0x110) + (n) * 0x70)
++#define HW_APBHX_CHn_SEMA(n) \
++ ((apbh_is_old ? 0x080 : 0x140) + (n) * 0x70)
++#define BM_APBHX_CHn_SEMA_PHORE (0xff << 16)
++#define BP_APBHX_CHn_SEMA_PHORE 16
++
++static struct mxs_dma_chan mxs_dma_channels[MXS_MAX_DMA_CHANNELS];
++static bool apbh_is_old;
++
++/*
++ * Test is the DMA channel is valid channel
++ */
++int mxs_dma_validate_chan(int channel)
++{
++ struct mxs_dma_chan *pchan;
++
++ if ((channel < 0) || (channel >= MXS_MAX_DMA_CHANNELS))
++ return -EINVAL;
++
++ pchan = mxs_dma_channels + channel;
++ if (!(pchan->flags & MXS_DMA_FLAGS_ALLOCATED))
++ return -EINVAL;
++
++ return 0;
++}
++
++/*
++ * Return the address of the command within a descriptor.
++ */
++static unsigned int mxs_dma_cmd_address(struct mxs_dma_desc *desc)
++{
++ return desc->address + offsetof(struct mxs_dma_desc, cmd);
++}
++
++/*
++ * Read a DMA channel's hardware semaphore.
++ *
++ * As used by the MXS platform's DMA software, the DMA channel's hardware
++ * semaphore reflects the number of DMA commands the hardware will process, but
++ * has not yet finished. This is a volatile value read directly from hardware,
++ * so it must be be viewed as immediately stale.
++ *
++ * If the channel is not marked busy, or has finished processing all its
++ * commands, this value should be zero.
++ *
++ * See mxs_dma_append() for details on how DMA command blocks must be configured
++ * to maintain the expected behavior of the semaphore's value.
++ */
++static int mxs_dma_read_semaphore(int channel)
++{
++ void __iomem *apbh_regs = (void *)MXS_APBH_BASE;
++ uint32_t tmp;
++ int ret;
++
++ ret = mxs_dma_validate_chan(channel);
++ if (ret)
++ return ret;
++
++ tmp = readl(apbh_regs + HW_APBHX_CHn_SEMA(channel));
++
++ tmp &= BM_APBHX_CHn_SEMA_PHORE;
++ tmp >>= BP_APBHX_CHn_SEMA_PHORE;
++
++ return tmp;
++}
++
++/*
++ * Enable a DMA channel.
++ *
++ * If the given channel has any DMA descriptors on its active list, this
++ * function causes the DMA hardware to begin processing them.
++ *
++ * This function marks the DMA channel as "busy," whether or not there are any
++ * descriptors to process.
++ */
++static int mxs_dma_enable(int channel)
++{
++ void __iomem *apbh_regs = (void *)MXS_APBH_BASE;
++ unsigned int sem;
++ struct mxs_dma_chan *pchan;
++ struct mxs_dma_desc *pdesc;
++ int channel_bit, ret;
++
++ ret = mxs_dma_validate_chan(channel);
++ if (ret)
++ return ret;
++
++ pchan = mxs_dma_channels + channel;
++
++ if (pchan->pending_num == 0) {
++ pchan->flags |= MXS_DMA_FLAGS_BUSY;
++ return 0;
++ }
++
++ pdesc = list_first_entry(&pchan->active, struct mxs_dma_desc, node);
++ if (pdesc == NULL)
++ return -EFAULT;
++
++ if (pchan->flags & MXS_DMA_FLAGS_BUSY) {
++ if (!(pdesc->cmd.data & MXS_DMA_DESC_CHAIN))
++ return 0;
++
++ sem = mxs_dma_read_semaphore(channel);
++ if (sem == 0)
++ return 0;
++
++ if (sem == 1) {
++ pdesc = list_entry(pdesc->node.next,
++ struct mxs_dma_desc, node);
++ writel(mxs_dma_cmd_address(pdesc),
++ apbh_regs + HW_APBHX_CHn_NXTCMDAR(channel));
++ }
++ writel(pchan->pending_num,
++ apbh_regs + HW_APBHX_CHn_SEMA(channel));
++ pchan->active_num += pchan->pending_num;
++ pchan->pending_num = 0;
++ } else {
++ pchan->active_num += pchan->pending_num;
++ pchan->pending_num = 0;
++ writel(mxs_dma_cmd_address(pdesc),
++ apbh_regs + HW_APBHX_CHn_NXTCMDAR(channel));
++ writel(pchan->active_num,
++ apbh_regs + HW_APBHX_CHn_SEMA(channel));
++ channel_bit = channel + (apbh_is_old ? BP_APBH_CTRL0_CLKGATE_CHANNEL : 0);
++ writel(1 << channel_bit, apbh_regs + HW_APBHX_CTRL0 + BIT_CLR);
++ }
++
++ pchan->flags |= MXS_DMA_FLAGS_BUSY;
++ return 0;
++}
++
++/*
++ * Disable a DMA channel.
++ *
++ * This function shuts down a DMA channel and marks it as "not busy." Any
++ * descriptors on the active list are immediately moved to the head of the
++ * "done" list, whether or not they have actually been processed by the
++ * hardware. The "ready" flags of these descriptors are NOT cleared, so they
++ * still appear to be active.
++ *
++ * This function immediately shuts down a DMA channel's hardware, aborting any
++ * I/O that may be in progress, potentially leaving I/O hardware in an undefined
++ * state. It is unwise to call this function if there is ANY chance the hardware
++ * is still processing a command.
++ */
++static int mxs_dma_disable(int channel)
++{
++ struct mxs_dma_chan *pchan;
++ void __iomem *apbh_regs = (void *)MXS_APBH_BASE;
++ int channel_bit, ret;
++
++ ret = mxs_dma_validate_chan(channel);
++ if (ret)
++ return ret;
++
++ pchan = mxs_dma_channels + channel;
++
++ if (!(pchan->flags & MXS_DMA_FLAGS_BUSY))
++ return -EINVAL;
++
++ channel_bit = channel + (apbh_is_old ? BP_APBH_CTRL0_CLKGATE_CHANNEL : 0);
++ writel(1 << channel_bit, apbh_regs + HW_APBHX_CTRL0 + BIT_SET);
++
++ pchan->flags &= ~MXS_DMA_FLAGS_BUSY;
++ pchan->active_num = 0;
++ pchan->pending_num = 0;
++ list_splice_init(&pchan->active, &pchan->done);
++
++ return 0;
++}
++
++/*
++ * Resets the DMA channel hardware.
++ */
++static int mxs_dma_reset(int channel)
++{
++ void __iomem *apbh_regs = (void *)MXS_APBH_BASE;
++ int ret;
++
++ ret = mxs_dma_validate_chan(channel);
++ if (ret)
++ return ret;
++
++ if (apbh_is_old)
++ writel(1 << (channel + BP_APBH_CTRL0_RESET_CHANNEL),
++ apbh_regs + HW_APBHX_CTRL0 + BIT_SET);
++ else
++ writel(1 << (channel + BP_APBHX_CHANNEL_CTRL_RESET_CHANNEL),
++ apbh_regs + HW_APBHX_CHANNEL_CTRL + BIT_SET);
++
++ return 0;
++}
++
++/*
++ * Enable or disable DMA interrupt.
++ *
++ * This function enables the given DMA channel to interrupt the CPU.
++ */
++static int mxs_dma_enable_irq(int channel, int enable)
++{
++ void __iomem *apbh_regs = (void *)MXS_APBH_BASE;
++ int ret;
++
++ ret = mxs_dma_validate_chan(channel);
++ if (ret)
++ return ret;
++
++ if (enable)
++ writel(1 << (channel + BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN),
++ apbh_regs + HW_APBHX_CTRL1 + BIT_SET);
++ else
++ writel(1 << (channel + BP_APBHX_CTRL1_CH_CMDCMPLT_IRQ_EN),
++ apbh_regs + HW_APBHX_CTRL1 + BIT_CLR);
++
++ return 0;
++}
++
++/*
++ * Clear DMA interrupt.
++ *
++ * The software that is using the DMA channel must register to receive its
++ * interrupts and, when they arrive, must call this function to clear them.
++ */
++static int mxs_dma_ack_irq(int channel)
++{
++ void __iomem *apbh_regs = (void *)MXS_APBH_BASE;
++ int ret;
++
++ ret = mxs_dma_validate_chan(channel);
++ if (ret)
++ return ret;
++
++ writel(1 << channel, apbh_regs + HW_APBHX_CTRL1 + BIT_CLR);
++ writel(1 << channel, apbh_regs + HW_APBHX_CTRL2 + BIT_CLR);
++
++ return 0;
++}
++
++/*
++ * Request to reserve a DMA channel
++ */
++static int mxs_dma_request(int channel)
++{
++ struct mxs_dma_chan *pchan;
++
++ if ((channel < 0) || (channel >= MXS_MAX_DMA_CHANNELS))
++ return -EINVAL;
++
++ pchan = mxs_dma_channels + channel;
++ if ((pchan->flags & MXS_DMA_FLAGS_VALID) != MXS_DMA_FLAGS_VALID)
++ return -ENODEV;
++
++ if (pchan->flags & MXS_DMA_FLAGS_ALLOCATED)
++ return -EBUSY;
++
++ pchan->flags |= MXS_DMA_FLAGS_ALLOCATED;
++ pchan->active_num = 0;
++ pchan->pending_num = 0;
++
++ INIT_LIST_HEAD(&pchan->active);
++ INIT_LIST_HEAD(&pchan->done);
++
++ return 0;
++}
++
++/*
++ * Release a DMA channel.
++ *
++ * This function releases a DMA channel from its current owner.
++ *
++ * The channel will NOT be released if it's marked "busy" (see
++ * mxs_dma_enable()).
++ */
++static int mxs_dma_release(int channel)
++{
++ struct mxs_dma_chan *pchan;
++ int ret;
++
++ ret = mxs_dma_validate_chan(channel);
++ if (ret)
++ return ret;
++
++ pchan = mxs_dma_channels + channel;
++
++ if (pchan->flags & MXS_DMA_FLAGS_BUSY)
++ return -EBUSY;
++
++ pchan->dev = 0;
++ pchan->active_num = 0;
++ pchan->pending_num = 0;
++ pchan->flags &= ~MXS_DMA_FLAGS_ALLOCATED;
++
++ return 0;
++}
++
++/*
++ * Allocate DMA descriptor
++ */
++struct mxs_dma_desc *mxs_dma_desc_alloc(void)
++{
++ struct mxs_dma_desc *pdesc;
++
++ pdesc = dma_alloc_coherent(sizeof(struct mxs_dma_desc));
++
++ if (pdesc == NULL)
++ return NULL;
++
++ memset(pdesc, 0, sizeof(*pdesc));
++ pdesc->address = (dma_addr_t)pdesc;
++
++ return pdesc;
++};
++
++/*
++ * Free DMA descriptor
++ */
++void mxs_dma_desc_free(struct mxs_dma_desc *pdesc)
++{
++ if (pdesc == NULL)
++ return;
++
++ free(pdesc);
++}
++
++/*
++ * Add a DMA descriptor to a channel.
++ *
++ * If the descriptor list for this channel is not empty, this function sets the
++ * CHAIN bit and the NEXTCMD_ADDR fields in the last descriptor's DMA command so
++ * it will chain to the new descriptor's command.
++ *
++ * Then, this function marks the new descriptor as "ready," adds it to the end
++ * of the active descriptor list, and increments the count of pending
++ * descriptors.
++ *
++ * The MXS platform DMA software imposes some rules on DMA commands to maintain
++ * important invariants. These rules are NOT checked, but they must be carefully
++ * applied by software that uses MXS DMA channels.
++ *
++ * Invariant:
++ * The DMA channel's hardware semaphore must reflect the number of DMA
++ * commands the hardware will process, but has not yet finished.
++ *
++ * Explanation:
++ * A DMA channel begins processing commands when its hardware semaphore is
++ * written with a value greater than zero, and it stops processing commands
++ * when the semaphore returns to zero.
++ *
++ * When a channel finishes a DMA command, it will decrement its semaphore if
++ * the DECREMENT_SEMAPHORE bit is set in that command's flags bits.
++ *
++ * In principle, it's not necessary for the DECREMENT_SEMAPHORE to be set,
++ * unless it suits the purposes of the software. For example, one could
++ * construct a series of five DMA commands, with the DECREMENT_SEMAPHORE
++ * bit set only in the last one. Then, setting the DMA channel's hardware
++ * semaphore to one would cause the entire series of five commands to be
++ * processed. However, this example would violate the invariant given above.
++ *
++ * Rule:
++ * ALL DMA commands MUST have the DECREMENT_SEMAPHORE bit set so that the DMA
++ * channel's hardware semaphore will be decremented EVERY time a command is
++ * processed.
++ */
++int mxs_dma_desc_append(int channel, struct mxs_dma_desc *pdesc)
++{
++ struct mxs_dma_chan *pchan;
++ struct mxs_dma_desc *last;
++ int ret;
++
++ ret = mxs_dma_validate_chan(channel);
++ if (ret)
++ return ret;
++
++ pchan = mxs_dma_channels + channel;
++
++ pdesc->cmd.next = mxs_dma_cmd_address(pdesc);
++ pdesc->flags |= MXS_DMA_DESC_FIRST | MXS_DMA_DESC_LAST;
++
++ if (!list_empty(&pchan->active)) {
++ last = list_entry(pchan->active.prev, struct mxs_dma_desc,
++ node);
++
++ pdesc->flags &= ~MXS_DMA_DESC_FIRST;
++ last->flags &= ~MXS_DMA_DESC_LAST;
++
++ last->cmd.next = mxs_dma_cmd_address(pdesc);
++ last->cmd.data |= MXS_DMA_DESC_CHAIN;
++ }
++ pdesc->flags |= MXS_DMA_DESC_READY;
++ if (pdesc->flags & MXS_DMA_DESC_FIRST)
++ pchan->pending_num++;
++ list_add_tail(&pdesc->node, &pchan->active);
++
++ return ret;
++}
++
++/*
++ * Clean up processed DMA descriptors.
++ *
++ * This function removes processed DMA descriptors from the "active" list. Pass
++ * in a non-NULL list head to get the descriptors moved to your list. Pass NULL
++ * to get the descriptors moved to the channel's "done" list. Descriptors on
++ * the "done" list can be retrieved with mxs_dma_get_finished().
++ *
++ * This function marks the DMA channel as "not busy" if no unprocessed
++ * descriptors remain on the "active" list.
++ */
++static int mxs_dma_finish(int channel, struct list_head *head)
++{
++ int sem;
++ struct mxs_dma_chan *pchan;
++ struct list_head *p, *q;
++ struct mxs_dma_desc *pdesc;
++ int ret;
++
++ ret = mxs_dma_validate_chan(channel);
++ if (ret)
++ return ret;
++
++ pchan = mxs_dma_channels + channel;
++
++ sem = mxs_dma_read_semaphore(channel);
++ if (sem < 0)
++ return sem;
++
++ if (sem == pchan->active_num)
++ return 0;
++
++ list_for_each_safe(p, q, &pchan->active) {
++ if ((pchan->active_num) <= sem)
++ break;
++
++ pdesc = list_entry(p, struct mxs_dma_desc, node);
++ pdesc->flags &= ~MXS_DMA_DESC_READY;
++
++ if (head)
++ list_move_tail(p, head);
++ else
++ list_move_tail(p, &pchan->done);
++
++ if (pdesc->flags & MXS_DMA_DESC_LAST)
++ pchan->active_num--;
++ }
++
++ if (sem == 0)
++ pchan->flags &= ~MXS_DMA_FLAGS_BUSY;
++
++ return 0;
++}
++
++/*
++ * Wait for DMA channel to complete
++ */
++static int mxs_dma_wait_complete(uint32_t timeout, unsigned int chan)
++{
++ void __iomem *apbh_regs = (void *)MXS_APBH_BASE;
++ int ret;
++
++ ret = mxs_dma_validate_chan(chan);
++ if (ret)
++ return ret;
++
++ while (--timeout) {
++ if (readl(apbh_regs + HW_APBHX_CTRL1) & (1 << chan))
++ break;
++ udelay(1);
++ }
++
++ if (timeout == 0) {
++ ret = -ETIMEDOUT;
++ mxs_dma_reset(chan);
++ }
++
++ return ret;
++}
++
++/*
++ * Execute the DMA channel
++ */
++int mxs_dma_go(int chan)
++{
++ uint32_t timeout = 10000;
++ int ret;
++
++ LIST_HEAD(tmp_desc_list);
++
++ mxs_dma_enable_irq(chan, 1);
++ mxs_dma_enable(chan);
++
++ /* Wait for DMA to finish. */
++ ret = mxs_dma_wait_complete(timeout, chan);
++
++ /* Clear out the descriptors we just ran. */
++ mxs_dma_finish(chan, &tmp_desc_list);
++
++ /* Shut the DMA channel down. */
++ mxs_dma_ack_irq(chan);
++ mxs_dma_reset(chan);
++ mxs_dma_enable_irq(chan, 0);
++ mxs_dma_disable(chan);
++
++ return ret;
++}
++
++/*
++ * Initialize the DMA hardware
++ */
++int mxs_dma_init(void)
++{
++ void __iomem *apbh_regs = (void *)MXS_APBH_BASE;
++ struct mxs_dma_chan *pchan;
++ int ret, channel;
++ u32 val, reg;
++
++ mxs_reset_block(apbh_regs, 0);
++
++ /* HACK: Get CPUID and determine APBH version */
++ val = readl(0x8001c310) >> 16;
++ if (val == 0x2800)
++ reg = MXS_APBH_BASE + 0x0800;
++ else
++ reg = MXS_APBH_BASE + 0x03f0;
++
++ apbh_is_old = (readl((void *)reg) >> 24) < 3;
++
++ writel(BM_APBH_CTRL0_APB_BURST8_EN,
++ apbh_regs + HW_APBHX_CTRL0 + BIT_SET);
++
++ writel(BM_APBH_CTRL0_APB_BURST_EN,
++ apbh_regs + HW_APBHX_CTRL0 + BIT_SET);
++
++ for (channel = 0; channel < MXS_MAX_DMA_CHANNELS; channel++) {
++ pchan = mxs_dma_channels + channel;
++ pchan->flags = MXS_DMA_FLAGS_VALID;
++
++ ret = mxs_dma_request(channel);
++
++ if (ret) {
++ printf("MXS DMA: Can't acquire DMA channel %i\n",
++ channel);
++
++ goto err;
++ }
++
++ mxs_dma_reset(channel);
++ mxs_dma_ack_irq(channel);
++ }
++
++ return 0;
++
++err:
++ while (--channel >= 0)
++ mxs_dma_release(channel);
++ return ret;
++}
+diff --git a/drivers/eeprom/at25.c b/drivers/eeprom/at25.c
+index 8a979d5..03d191e 100644
+--- a/drivers/eeprom/at25.c
++++ b/drivers/eeprom/at25.c
+@@ -67,7 +67,7 @@ struct at25_data {
+ static ssize_t at25_ee_read(struct cdev *cdev,
+ void *buf,
+ size_t count,
+- ulong offset,
++ loff_t offset,
+ ulong flags)
+ {
+ u8 command[EE_MAXADDRLEN + 1];
+@@ -117,7 +117,7 @@ static ssize_t at25_ee_read(struct cdev *cdev,
+ */
+ status = spi_sync(at25->spi, &m);
+ dev_dbg(at25->cdev.dev,
+- "read %d bytes at %lu --> %d\n",
++ "read %d bytes at %llu --> %d\n",
+ count, offset, (int) status);
+
+ return status ? status : count;
+@@ -126,7 +126,7 @@ static ssize_t at25_ee_read(struct cdev *cdev,
+ static ssize_t at25_ee_write(struct cdev *cdev,
+ const void *buf,
+ size_t count,
+- ulong off,
++ loff_t off,
+ ulong flags)
+ {
+ ssize_t status = 0;
+@@ -232,7 +232,7 @@ static ssize_t at25_ee_write(struct cdev *cdev,
+ return written ? written : status;
+ }
+
+-static off_t at25_ee_lseek(struct cdev *cdev, off_t off)
++static loff_t at25_ee_lseek(struct cdev *cdev, loff_t off)
+ {
+ return off;
+ }
+diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
+index ae3c805..585cab9 100644
+--- a/drivers/mci/imx-esdhc.c
++++ b/drivers/mci/imx-esdhc.c
+@@ -70,7 +70,7 @@ struct fsl_esdhc {
+
+ struct fsl_esdhc_host {
+ struct mci_host mci;
+- struct fsl_esdhc *regs;
++ struct fsl_esdhc __iomem *regs;
+ u32 no_snoop;
+ unsigned long cur_clock;
+ struct device_d *dev;
+@@ -81,7 +81,7 @@ struct fsl_esdhc_host {
+ #define SDHCI_CMD_ABORTCMD (0xC0 << 16)
+
+ /* Return the XFERTYP flags for a given command and data packet */
+-u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
++static u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
+ {
+ u32 xfertyp = 0;
+
+@@ -185,7 +185,7 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
+ static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data)
+ {
+ struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
+- struct fsl_esdhc *regs = host->regs;
++ struct fsl_esdhc __iomem *regs = host->regs;
+ #ifndef CONFIG_MCI_IMX_ESDHC_PIO
+ u32 wml_value;
+
+@@ -237,7 +237,7 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
+ u32 xfertyp, mixctrl;
+ u32 irqstat;
+ struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
+- struct fsl_esdhc *regs = host->regs;
++ struct fsl_esdhc __iomem *regs = host->regs;
+ int ret;
+
+ esdhc_write32(&regs->irqstat, -1);
+@@ -353,11 +353,11 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
+ return 0;
+ }
+
+-void set_sysctl(struct mci_host *mci, u32 clock)
++static void set_sysctl(struct mci_host *mci, u32 clock)
+ {
+ int div, pre_div;
+ struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
+- struct fsl_esdhc *regs = host->regs;
++ struct fsl_esdhc __iomem *regs = host->regs;
+ int sdhc_clk = imx_get_mmcclk();
+ u32 clk;
+
+@@ -400,7 +400,7 @@ void set_sysctl(struct mci_host *mci, u32 clock)
+ static void esdhc_set_ios(struct mci_host *mci, struct mci_ios *ios)
+ {
+ struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
+- struct fsl_esdhc *regs = host->regs;
++ struct fsl_esdhc __iomem *regs = host->regs;
+
+ /* Set the clock speed */
+ set_sysctl(mci, ios->clock);
+@@ -425,7 +425,7 @@ static void esdhc_set_ios(struct mci_host *mci, struct mci_ios *ios)
+
+ static int esdhc_card_detect(struct fsl_esdhc_host *host)
+ {
+- struct fsl_esdhc *regs = host->regs;
++ struct fsl_esdhc __iomem *regs = host->regs;
+ struct esdhc_platform_data *pdata = host->dev->platform_data;
+ int ret;
+
+@@ -451,7 +451,7 @@ static int esdhc_card_detect(struct fsl_esdhc_host *host)
+ static int esdhc_init(struct mci_host *mci, struct device_d *dev)
+ {
+ struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
+- struct fsl_esdhc *regs = host->regs;
++ struct fsl_esdhc __iomem *regs = host->regs;
+ int timeout = 1000;
+ int ret = 0;
+
+@@ -493,7 +493,7 @@ static int esdhc_init(struct mci_host *mci, struct device_d *dev)
+ return ret;
+ }
+
+-static int esdhc_reset(struct fsl_esdhc *regs)
++static int esdhc_reset(struct fsl_esdhc __iomem *regs)
+ {
+ uint64_t start;
+
+diff --git a/drivers/mci/imx-esdhc.h b/drivers/mci/imx-esdhc.h
+index 19fed5a..7d5ed85 100644
+--- a/drivers/mci/imx-esdhc.h
++++ b/drivers/mci/imx-esdhc.h
+@@ -39,7 +39,6 @@
+ #define SYSCTL_PEREN 0x00000004
+ #define SYSCTL_HCKEN 0x00000002
+ #define SYSCTL_IPGEN 0x00000001
+-#define SYSCTL_RSTA 0x01000000
+
+ #define IRQSTAT 0x0002e030
+ #define IRQSTAT_DMAE (0x10000000)
+diff --git a/drivers/mfd/lp3972.c b/drivers/mfd/lp3972.c
+index 9826699..0f3093b 100644
+--- a/drivers/mfd/lp3972.c
++++ b/drivers/mfd/lp3972.c
+@@ -58,7 +58,7 @@ static u32 lp_read_reg(struct lp_priv *lp, int reg)
+ return buf;
+ }
+
+-static ssize_t lp_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
++static ssize_t lp_read(struct cdev *cdev, void *_buf, size_t count, loff_t offset, ulong flags)
+ {
+ struct lp_priv *priv = to_lp_priv(cdev);
+ int i = count;
+diff --git a/drivers/mfd/mc13xxx.c b/drivers/mfd/mc13xxx.c
+index f9477a3..2934e9d 100644
+--- a/drivers/mfd/mc13xxx.c
++++ b/drivers/mfd/mc13xxx.c
+@@ -160,7 +160,7 @@ int mc13xxx_set_bits(struct mc13xxx *mc13xxx, u8 reg, u32 mask, u32 val)
+ }
+ EXPORT_SYMBOL(mc13xxx_set_bits);
+
+-static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
++static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, loff_t offset, ulong flags)
+ {
+ struct mc13xxx *priv = to_mc13xxx(cdev);
+ u32 *buf = _buf;
+@@ -181,7 +181,7 @@ static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset
+ return count;
+ }
+
+-static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags)
++static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, loff_t offset, ulong flags)
+ {
+ struct mc13xxx *mc13xxx = to_mc13xxx(cdev);
+ const u32 *buf = _buf;
+diff --git a/drivers/mfd/mc34704.c b/drivers/mfd/mc34704.c
+index a2171b3..20c01e2 100644
+--- a/drivers/mfd/mc34704.c
++++ b/drivers/mfd/mc34704.c
+@@ -65,7 +65,7 @@ int mc34704_reg_write(struct mc34704 *mc34704, u8 reg, u8 val)
+ EXPORT_SYMBOL(mc34704_reg_write)
+
+ static ssize_t mc34704_read(struct cdev *cdev, void *_buf, size_t count,
+- ulong offset, ulong flags)
++ loff_t offset, ulong flags)
+ {
+ struct mc34704 *priv = to_mc34704(cdev);
+ u8 *buf = _buf;
+@@ -85,7 +85,7 @@ static ssize_t mc34704_read(struct cdev *cdev, void *_buf, size_t count,
+ }
+
+ static ssize_t mc34704_write(struct cdev *cdev, const void *_buf, size_t count,
+- ulong offset, ulong flags)
++ loff_t offset, ulong flags)
+ {
+ struct mc34704 *mc34704 = to_mc34704(cdev);
+ const u8 *buf = _buf;
+diff --git a/drivers/mfd/mc34708.c b/drivers/mfd/mc34708.c
+index e7f40c0..02c58a9 100644
+--- a/drivers/mfd/mc34708.c
++++ b/drivers/mfd/mc34708.c
+@@ -163,7 +163,8 @@ int mc34708_set_bits(struct mc34708 *mc34708, enum mc34708_reg reg, u32 mask, u3
+ }
+ EXPORT_SYMBOL(mc34708_set_bits);
+
+-static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
++static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count,
++ loff_t offset, ulong flags)
+ {
+ struct mc34708 *priv = to_mc34708(cdev);
+ u32 *buf = _buf;
+@@ -184,7 +185,8 @@ static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset
+ return count;
+ }
+
+-static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags)
++static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count,
++ loff_t offset, ulong flags)
+ {
+ struct mc34708 *mc34708 = to_mc34708(cdev);
+ const u32 *buf = _buf;
+diff --git a/drivers/mfd/mc9sdz60.c b/drivers/mfd/mc9sdz60.c
+index db208ec..0cd5007 100644
+--- a/drivers/mfd/mc9sdz60.c
++++ b/drivers/mfd/mc9sdz60.c
+@@ -78,7 +78,7 @@ int mc9sdz60_set_bits(struct mc9sdz60 *mc9sdz60, enum mc9sdz60_reg reg, u8 mask,
+ }
+ EXPORT_SYMBOL(mc9sdz60_set_bits);
+
+-static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
++static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, loff_t offset, ulong flags)
+ {
+ struct mc9sdz60 *mc9sdz60 = to_mc9sdz60(cdev);
+ u8 *buf = _buf;
+@@ -97,7 +97,7 @@ static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset
+ return count;
+ }
+
+-static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags)
++static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, loff_t offset, ulong flags)
+ {
+ struct mc9sdz60 *mc9sdz60 = to_mc9sdz60(cdev);
+ const u8 *buf = _buf;
+diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
+index cb2c03d..20bde2c 100644
+--- a/drivers/mfd/twl-core.c
++++ b/drivers/mfd/twl-core.c
+@@ -112,7 +112,7 @@ int twlcore_set_bits(struct twlcore *twlcore, u16 reg, u8 mask, u8 val)
+ EXPORT_SYMBOL(twlcore_set_bits);
+
+ static ssize_t twl_read(struct cdev *cdev, void *_buf, size_t count,
+- ulong offset, ulong flags)
++ loff_t offset, ulong flags)
+ {
+ struct twlcore *priv = to_twlcore(cdev);
+ u8 *buf = _buf;
+@@ -131,7 +131,7 @@ static ssize_t twl_read(struct cdev *cdev, void *_buf, size_t count,
+ }
+
+ static ssize_t twl_write(struct cdev *cdev, const void *_buf, size_t count,
+- ulong offset, ulong flags)
++ loff_t offset, ulong flags)
+ {
+ struct twlcore *twlcore = to_twlcore(cdev);
+ const u8 *buf = _buf;
+diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
+index 87dcba6..5510439 100644
+--- a/drivers/mtd/core.c
++++ b/drivers/mtd/core.c
+@@ -31,11 +31,12 @@
+ static LIST_HEAD(mtd_register_hooks);
+
+ static ssize_t mtd_read(struct cdev *cdev, void* buf, size_t count,
+- ulong offset, ulong flags)
++ loff_t _offset, ulong flags)
+ {
+ struct mtd_info *mtd = cdev->priv;
+ size_t retlen;
+ int ret;
++ unsigned long offset = _offset;
+
+ debug("mtd_read: 0x%08lx 0x%08x\n", offset, count);
+
+@@ -64,13 +65,14 @@ static int all_ff(const void *buf, int len)
+ }
+
+ static ssize_t mtd_write(struct cdev* cdev, const void *buf, size_t _count,
+- ulong offset, ulong flags)
++ loff_t _offset, ulong flags)
+ {
+ struct mtd_info *mtd = cdev->priv;
+ size_t retlen, now;
+ int ret = 0;
+ void *wrbuf = NULL;
+ size_t count = _count;
++ unsigned long offset = _offset;
+
+ if (NOTALIGNED(offset)) {
+ printf("offset 0x%0lx not page aligned\n", offset);
+@@ -123,16 +125,17 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf)
+ struct mtd_ecc_stats *ecc = buf;
+ #endif
+ struct region_info_user *reg = buf;
++ loff_t *offset = buf;
+
+ switch (request) {
+ case MEMGETBADBLOCK:
+- dev_dbg(cdev->dev, "MEMGETBADBLOCK: 0x%08lx\n", (off_t)buf);
+- ret = mtd->block_isbad(mtd, (off_t)buf);
++ dev_dbg(cdev->dev, "MEMGETBADBLOCK: 0x%08llx\n", *offset);
++ ret = mtd->block_isbad(mtd, *offset);
+ break;
+ #ifdef CONFIG_MTD_WRITE
+ case MEMSETBADBLOCK:
+- dev_dbg(cdev->dev, "MEMSETBADBLOCK: 0x%08lx\n", (off_t)buf);
+- ret = mtd->block_markbad(mtd, (off_t)buf);
++ dev_dbg(cdev->dev, "MEMSETBADBLOCK: 0x%08llx\n", *offset);
++ ret = mtd->block_markbad(mtd, *offset);
+ break;
+ #endif
+ case MEMGETINFO:
+@@ -156,9 +159,10 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf)
+ #endif
+ case MEMGETREGIONINFO:
+ if (cdev->mtd) {
++ unsigned long size = cdev->size;
+ reg->offset = cdev->offset;
+ reg->erasesize = cdev->mtd->erasesize;
+- reg->numblocks = cdev->size/reg->erasesize;
++ reg->numblocks = size / reg->erasesize;
+ reg->regionindex = cdev->mtd->index;
+ }
+ break;
+@@ -170,7 +174,7 @@ int mtd_ioctl(struct cdev *cdev, int request, void *buf)
+ }
+
+ #ifdef CONFIG_MTD_WRITE
+-static ssize_t mtd_erase(struct cdev *cdev, size_t count, unsigned long offset)
++static ssize_t mtd_erase(struct cdev *cdev, size_t count, loff_t offset)
+ {
+ struct mtd_info *mtd = cdev->priv;
+ struct erase_info erase;
+diff --git a/drivers/mtd/mtdoob.c b/drivers/mtd/mtdoob.c
+index be656a4..e4dd1a0 100644
+--- a/drivers/mtd/mtdoob.c
++++ b/drivers/mtd/mtdoob.c
+@@ -38,11 +38,12 @@ static struct mtd_info *to_mtd(struct cdev *cdev)
+ }
+
+ static ssize_t mtd_read_oob(struct cdev *cdev, void *buf, size_t count,
+- ulong offset, ulong flags)
++ loff_t _offset, ulong flags)
+ {
+ struct mtd_info *mtd = to_mtd(cdev);
+ struct mtd_oob_ops ops;
+ int ret;
++ unsigned long offset = _offset;
+
+ if (count < mtd->oobsize)
+ return -EINVAL;
+diff --git a/drivers/mtd/mtdraw.c b/drivers/mtd/mtdraw.c
+index 7abe235..24f7358 100644
+--- a/drivers/mtd/mtdraw.c
++++ b/drivers/mtd/mtdraw.c
+@@ -116,12 +116,13 @@ err:
+ }
+
+ static ssize_t mtdraw_read(struct cdev *cdev, void *buf, size_t count,
+- ulong offset, ulong flags)
++ loff_t _offset, ulong flags)
+ {
+ struct mtd_info *mtd = to_mtd(cdev);
+ ssize_t retlen = 0, ret = 1, toread;
+ ulong numpage;
+ int skip;
++ unsigned long offset = _offset;
+
+ numpage = offset / (mtd->writesize + mtd->oobsize);
+ skip = offset % (mtd->writesize + mtd->oobsize);
+@@ -167,13 +168,14 @@ static void mtdraw_fillbuf(struct mtdraw *mtdraw, const void *src, int nbbytes)
+ }
+
+ static ssize_t mtdraw_write(struct cdev *cdev, const void *buf, size_t count,
+- ulong offset, ulong flags)
++ loff_t _offset, ulong flags)
+ {
+ struct mtdraw *mtdraw = to_mtdraw(cdev);
+ struct mtd_info *mtd = to_mtd(cdev);
+ int bsz = mtd->writesize + mtd->oobsize;
+ ulong numpage;
+ size_t retlen = 0, tofill;
++ unsigned long offset = _offset;
+ int ret = 0;
+
+ if (mtdraw->write_fill &&
+@@ -220,10 +222,11 @@ static ssize_t mtdraw_write(struct cdev *cdev, const void *buf, size_t count,
+ }
+ }
+
+-static ssize_t mtdraw_erase(struct cdev *cdev, size_t count, ulong offset)
++static ssize_t mtdraw_erase(struct cdev *cdev, size_t count, loff_t _offset)
+ {
+ struct mtd_info *mtd = to_mtd(cdev);
+ struct erase_info erase;
++ unsigned long offset = _offset;
+ int ret;
+
+ offset = offset / (mtd->writesize + mtd->oobsize) * mtd->writesize;
+diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
+index 926a64b..3f90643 100644
+--- a/drivers/mtd/nand/Kconfig
++++ b/drivers/mtd/nand/Kconfig
+@@ -53,6 +53,11 @@ config NAND_IMX
+ prompt "i.MX NAND driver"
+ depends on ARCH_IMX
+
++config NAND_MXS
++ bool
++ prompt "i.MX23/28 NAND driver"
++ depends on MXS_APBH_DMA
++
+ config NAND_OMAP_GPMC
+ tristate "NAND Flash Support for GPMC based OMAP platforms"
+ depends on OMAP_GPMC
+diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
+index 5c6d8b3..1dcfb76 100644
+--- a/drivers/mtd/nand/Makefile
++++ b/drivers/mtd/nand/Makefile
+@@ -15,3 +15,4 @@ obj-$(CONFIG_NAND_IMX) += nand_imx.o
+ obj-$(CONFIG_NAND_OMAP_GPMC) += nand_omap_gpmc.o nand_omap_bch_decoder.o
+ obj-$(CONFIG_NAND_ATMEL) += atmel_nand.o
+ obj-$(CONFIG_NAND_S3C24XX) += nand_s3c24xx.o
++obj-$(CONFIG_NAND_MXS) += nand_mxs.o
+diff --git a/drivers/mtd/nand/nand-bb.c b/drivers/mtd/nand/nand-bb.c
+index bd30438..519337e 100644
+--- a/drivers/mtd/nand/nand-bb.c
++++ b/drivers/mtd/nand/nand-bb.c
+@@ -42,9 +42,9 @@ struct nand_bb {
+
+ struct mtd_info_user info;
+
+- size_t raw_size;
+- size_t size;
+- off_t offset;
++ loff_t raw_size;
++ loff_t size;
++ loff_t offset;
+ unsigned long flags;
+ void *writebuf;
+
+@@ -54,27 +54,27 @@ struct nand_bb {
+ };
+
+ static ssize_t nand_bb_read(struct cdev *cdev, void *buf, size_t count,
+- unsigned long offset, ulong flags)
++ loff_t offset, ulong flags)
+ {
+ struct nand_bb *bb = cdev->priv;
+ struct cdev *parent = bb->cdev_parent;
+ int ret, bytes = 0, now;
+
+- debug("%s %d %d\n", __func__, offset, count);
++ debug("%s 0x%08llx %d\n", __func__, offset, count);
+
+ while(count) {
+- ret = cdev_ioctl(parent, MEMGETBADBLOCK, (void *)bb->offset);
++ ret = cdev_ioctl(parent, MEMGETBADBLOCK, &bb->offset);
+ if (ret < 0)
+ return ret;
+
+ if (ret) {
+- printf("skipping bad block at 0x%08lx\n", bb->offset);
++ printf("skipping bad block at 0x%08llx\n", bb->offset);
+ bb->offset += bb->info.erasesize;
+ continue;
+ }
+
+ now = min(count, (size_t)(bb->info.erasesize -
+- (bb->offset % bb->info.erasesize)));
++ ((size_t)bb->offset % bb->info.erasesize)));
+ ret = cdev_read(parent, buf, now, bb->offset, 0);
+ if (ret < 0)
+ return ret;
+@@ -96,15 +96,15 @@ static int nand_bb_write_buf(struct nand_bb *bb, size_t count)
+ int ret, now;
+ struct cdev *parent = bb->cdev_parent;
+ void *buf = bb->writebuf;
+- int cur_ofs = bb->offset & ~(BB_WRITEBUF_SIZE - 1);
++ loff_t cur_ofs = bb->offset & ~(BB_WRITEBUF_SIZE - 1);
+
+ while (count) {
+- ret = cdev_ioctl(parent, MEMGETBADBLOCK, (void *)cur_ofs);
++ ret = cdev_ioctl(parent, MEMGETBADBLOCK, &cur_ofs);
+ if (ret < 0)
+ return ret;
+
+ if (ret) {
+- debug("skipping bad block at 0x%08x\n", cur_ofs);
++ debug("skipping bad block at 0x%08llx\n", cur_ofs);
+ bb->offset += bb->info.erasesize;
+ cur_ofs += bb->info.erasesize;
+ continue;
+@@ -123,12 +123,12 @@ static int nand_bb_write_buf(struct nand_bb *bb, size_t count)
+ }
+
+ static ssize_t nand_bb_write(struct cdev *cdev, const void *buf, size_t count,
+- unsigned long offset, ulong flags)
++ loff_t offset, ulong flags)
+ {
+ struct nand_bb *bb = cdev->priv;
+ int bytes = count, now, wroffs, ret;
+
+- debug("%s offset: 0x%08x count: 0x%08x\n", __func__, offset, count);
++ debug("%s offset: 0x%08llx count: 0x%08x\n", __func__, offset, count);
+
+ while (count) {
+ wroffs = bb->offset % BB_WRITEBUF_SIZE;
+@@ -152,7 +152,7 @@ static ssize_t nand_bb_write(struct cdev *cdev, const void *buf, size_t count,
+ return bytes;
+ }
+
+-static int nand_bb_erase(struct cdev *cdev, size_t count, unsigned long offset)
++static int nand_bb_erase(struct cdev *cdev, size_t count, loff_t offset)
+ {
+ struct nand_bb *bb = cdev->priv;
+
+@@ -197,11 +197,11 @@ static int nand_bb_close(struct cdev *cdev)
+
+ static int nand_bb_calc_size(struct nand_bb *bb)
+ {
+- ulong pos = 0;
++ loff_t pos = 0;
+ int ret;
+
+ while (pos < bb->raw_size) {
+- ret = cdev_ioctl(bb->cdev_parent, MEMGETBADBLOCK, (void *)pos);
++ ret = cdev_ioctl(bb->cdev_parent, MEMGETBADBLOCK, &pos);
+ if (ret < 0)
+ return ret;
+ if (!ret)
+@@ -213,10 +213,10 @@ static int nand_bb_calc_size(struct nand_bb *bb)
+ return 0;
+ }
+
+-static off_t nand_bb_lseek(struct cdev *cdev, off_t __offset)
++static loff_t nand_bb_lseek(struct cdev *cdev, loff_t __offset)
+ {
+ struct nand_bb *bb = cdev->priv;
+- unsigned long raw_pos = 0;
++ loff_t raw_pos = 0;
+ uint32_t offset = __offset;
+ int ret;
+
+@@ -226,7 +226,7 @@ static off_t nand_bb_lseek(struct cdev *cdev, off_t __offset)
+ while (raw_pos < bb->raw_size) {
+ off_t now = min(offset, bb->info.erasesize);
+
+- ret = cdev_ioctl(bb->cdev_parent, MEMGETBADBLOCK, (void *)raw_pos);
++ ret = cdev_ioctl(bb->cdev_parent, MEMGETBADBLOCK, &raw_pos);
+ if (ret < 0)
+ return ret;
+ if (!ret) {
+diff --git a/drivers/mtd/nand/nand_mxs.c b/drivers/mtd/nand/nand_mxs.c
+new file mode 100644
+index 0000000..ba49287
+--- /dev/null
++++ b/drivers/mtd/nand/nand_mxs.c
+@@ -0,0 +1,1258 @@
++/*
++ * Freescale i.MX28 NAND flash driver
++ *
++ * Copyright (C) 2011 Wolfram Sang <w.sang@pengutronix.de>
++ *
++ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
++ * on behalf of DENX Software Engineering GmbH
++ *
++ * Based on code from LTIB:
++ * Freescale GPMI NFC NAND Flash Driver
++ *
++ * Copyright (C) 2010 Freescale Semiconductor, Inc.
++ * Copyright (C) 2008 Embedded Alley Solutions, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++
++#include <linux/mtd/mtd.h>
++#include <linux/mtd/nand.h>
++#include <linux/types.h>
++#include <common.h>
++#include <malloc.h>
++#include <errno.h>
++#include <driver.h>
++#include <init.h>
++#include <asm/mmu.h>
++#include <asm/io.h>
++#include <mach/clock.h>
++#include <mach/imx-regs.h>
++#include <mach/dma.h>
++#include <mach/mxs.h>
++
++#define MX28_BLOCK_SFTRST (1 << 31)
++#define MX28_BLOCK_CLKGATE (1 << 30)
++
++#define GPMI_CTRL0 0x00000000
++#define GPMI_CTRL0_RUN (1 << 29)
++#define GPMI_CTRL0_DEV_IRQ_EN (1 << 28)
++/* Disable for now since we don't need it and it is different on MX23.
++#define GPMI_CTRL0_LOCK_CS (1 << 27)
++*/
++#define GPMI_CTRL0_UDMA (1 << 26)
++#define GPMI_CTRL0_COMMAND_MODE_MASK (0x3 << 24)
++#define GPMI_CTRL0_COMMAND_MODE_OFFSET 24
++#define GPMI_CTRL0_COMMAND_MODE_WRITE (0x0 << 24)
++#define GPMI_CTRL0_COMMAND_MODE_READ (0x1 << 24)
++#define GPMI_CTRL0_COMMAND_MODE_READ_AND_COMPARE (0x2 << 24)
++#define GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY (0x3 << 24)
++#define GPMI_CTRL0_WORD_LENGTH (1 << 23)
++/* Careful: Is 0x3 on MX23
++#define GPMI_CTRL0_CS_MASK (0x7 << 20)
++*/
++#define GPMI_CTRL0_CS_OFFSET 20
++#define GPMI_CTRL0_ADDRESS_MASK (0x7 << 17)
++#define GPMI_CTRL0_ADDRESS_OFFSET 17
++#define GPMI_CTRL0_ADDRESS_NAND_DATA (0x0 << 17)
++#define GPMI_CTRL0_ADDRESS_NAND_CLE (0x1 << 17)
++#define GPMI_CTRL0_ADDRESS_NAND_ALE (0x2 << 17)
++#define GPMI_CTRL0_ADDRESS_INCREMENT (1 << 16)
++#define GPMI_CTRL0_XFER_COUNT_MASK 0xffff
++#define GPMI_CTRL0_XFER_COUNT_OFFSET 0
++
++#define GPMI_CTRL1 0x00000060
++#define GPMI_CTRL1_DECOUPLE_CS (1 << 24)
++#define GPMI_CTRL1_WRN_DLY_SEL_MASK (0x3 << 22)
++#define GPMI_CTRL1_WRN_DLY_SEL_OFFSET 22
++#define GPMI_CTRL1_TIMEOUT_IRQ_EN (1 << 20)
++#define GPMI_CTRL1_GANGED_RDYBUSY (1 << 19)
++#define GPMI_CTRL1_BCH_MODE (1 << 18)
++#define GPMI_CTRL1_DLL_ENABLE (1 << 17)
++#define GPMI_CTRL1_HALF_PERIOD (1 << 16)
++#define GPMI_CTRL1_RDN_DELAY_MASK (0xf << 12)
++#define GPMI_CTRL1_RDN_DELAY_OFFSET 12
++#define GPMI_CTRL1_DMA2ECC_MODE (1 << 11)
++#define GPMI_CTRL1_DEV_IRQ (1 << 10)
++#define GPMI_CTRL1_TIMEOUT_IRQ (1 << 9)
++#define GPMI_CTRL1_BURST_EN (1 << 8)
++#define GPMI_CTRL1_ABORT_WAIT_REQUEST (1 << 7)
++#define GPMI_CTRL1_ABORT_WAIT_FOR_READY_CHANNEL_MASK (0x7 << 4)
++#define GPMI_CTRL1_ABORT_WAIT_FOR_READY_CHANNEL_OFFSET 4
++#define GPMI_CTRL1_DEV_RESET (1 << 3)
++#define GPMI_CTRL1_ATA_IRQRDY_POLARITY (1 << 2)
++#define GPMI_CTRL1_CAMERA_MODE (1 << 1)
++#define GPMI_CTRL1_GPMI_MODE (1 << 0)
++
++#define GPMI_ECCCTRL_HANDLE_MASK (0xffff << 16)
++#define GPMI_ECCCTRL_HANDLE_OFFSET 16
++#define GPMI_ECCCTRL_ECC_CMD_MASK (0x3 << 13)
++#define GPMI_ECCCTRL_ECC_CMD_OFFSET 13
++#define GPMI_ECCCTRL_ECC_CMD_DECODE (0x0 << 13)
++#define GPMI_ECCCTRL_ECC_CMD_ENCODE (0x1 << 13)
++#define GPMI_ECCCTRL_ENABLE_ECC (1 << 12)
++#define GPMI_ECCCTRL_BUFFER_MASK_MASK 0x1ff
++#define GPMI_ECCCTRL_BUFFER_MASK_OFFSET 0
++#define GPMI_ECCCTRL_BUFFER_MASK_BCH_AUXONLY 0x100
++#define GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE 0x1ff
++
++#define GPMI_STAT 0x000000b0
++#define GPMI_STAT_READY_BUSY_OFFSET 24
++
++#define GPMI_DEBUG 0x000000c0
++#define GPMI_DEBUG_READY0_OFFSET 28
++
++#define GPMI_VERSION 0x000000d0
++#define GPMI_VERSION_MINOR_OFFSET 16
++#define GPMI_VERSION_TYPE_MX23 0x0300
++
++#define BCH_CTRL 0x00000000
++#define BCH_CTRL_COMPLETE_IRQ (1 << 0)
++#define BCH_CTRL_COMPLETE_IRQ_EN (1 << 8)
++
++#define BCH_LAYOUTSELECT 0x00000070
++
++#define BCH_FLASH0LAYOUT0 0x00000080
++#define BCH_FLASHLAYOUT0_NBLOCKS_MASK (0xff << 24)
++#define BCH_FLASHLAYOUT0_NBLOCKS_OFFSET 24
++#define BCH_FLASHLAYOUT0_META_SIZE_MASK (0xff << 16)
++#define BCH_FLASHLAYOUT0_META_SIZE_OFFSET 16
++#define BCH_FLASHLAYOUT0_ECC0_MASK (0xf << 12)
++#define BCH_FLASHLAYOUT0_ECC0_OFFSET 12
++
++#define BCH_FLASH0LAYOUT1 0x00000090
++#define BCH_FLASHLAYOUT1_PAGE_SIZE_MASK (0xffff << 16)
++#define BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET 16
++#define BCH_FLASHLAYOUT1_ECCN_MASK (0xf << 12)
++#define BCH_FLASHLAYOUT1_ECCN_OFFSET 12
++
++#define MXS_NAND_DMA_DESCRIPTOR_COUNT 4
++
++#define MXS_NAND_CHUNK_DATA_CHUNK_SIZE 512
++#define MXS_NAND_METADATA_SIZE 10
++
++#define MXS_NAND_COMMAND_BUFFER_SIZE 32
++
++#define MXS_NAND_BCH_TIMEOUT 10000
++
++struct mxs_nand_info {
++ struct nand_chip nand_chip;
++ void __iomem *io_base;
++ struct mtd_info mtd;
++ u32 version;
++
++ int cur_chip;
++
++ uint32_t cmd_queue_len;
++
++ uint8_t *cmd_buf;
++ uint8_t *data_buf;
++ uint8_t *oob_buf;
++
++ uint8_t marking_block_bad;
++ uint8_t raw_oob_mode;
++
++ /* Functions with altered behaviour */
++ int (*hooked_read_oob)(struct mtd_info *mtd,
++ loff_t from, struct mtd_oob_ops *ops);
++ int (*hooked_write_oob)(struct mtd_info *mtd,
++ loff_t to, struct mtd_oob_ops *ops);
++ int (*hooked_block_markbad)(struct mtd_info *mtd,
++ loff_t ofs);
++
++ /* DMA descriptors */
++ struct mxs_dma_desc **desc;
++ uint32_t desc_index;
++};
++
++struct nand_ecclayout fake_ecc_layout;
++
++static struct mxs_dma_desc *mxs_nand_get_dma_desc(struct mxs_nand_info *info)
++{
++ struct mxs_dma_desc *desc;
++
++ if (info->desc_index >= MXS_NAND_DMA_DESCRIPTOR_COUNT) {
++ printf("MXS NAND: Too many DMA descriptors requested\n");
++ return NULL;
++ }
++
++ desc = info->desc[info->desc_index];
++ info->desc_index++;
++
++ return desc;
++}
++
++static void mxs_nand_return_dma_descs(struct mxs_nand_info *info)
++{
++ int i;
++ struct mxs_dma_desc *desc;
++
++ for (i = 0; i < info->desc_index; i++) {
++ desc = info->desc[i];
++ memset(desc, 0, sizeof(struct mxs_dma_desc));
++ desc->address = (dma_addr_t)desc;
++ }
++
++ info->desc_index = 0;
++}
++
++static uint32_t mxs_nand_ecc_chunk_cnt(uint32_t page_data_size)
++{
++ return page_data_size / MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
++}
++
++static uint32_t mxs_nand_ecc_size_in_bits(uint32_t ecc_strength)
++{
++ return ecc_strength * 13;
++}
++
++static uint32_t mxs_nand_aux_status_offset(void)
++{
++ return (MXS_NAND_METADATA_SIZE + 0x3) & ~0x3;
++}
++
++static inline uint32_t mxs_nand_get_ecc_strength(uint32_t page_data_size,
++ uint32_t page_oob_size)
++{
++ if (page_data_size == 2048)
++ return 8;
++
++ if (page_data_size == 4096) {
++ if (page_oob_size == 128)
++ return 8;
++
++ if (page_oob_size == 218)
++ return 16;
++ }
++
++ return 0;
++}
++
++static inline uint32_t mxs_nand_get_mark_offset(uint32_t page_data_size,
++ uint32_t ecc_strength)
++{
++ uint32_t chunk_data_size_in_bits;
++ uint32_t chunk_ecc_size_in_bits;
++ uint32_t chunk_total_size_in_bits;
++ uint32_t block_mark_chunk_number;
++ uint32_t block_mark_chunk_bit_offset;
++ uint32_t block_mark_bit_offset;
++
++ chunk_data_size_in_bits = MXS_NAND_CHUNK_DATA_CHUNK_SIZE * 8;
++ chunk_ecc_size_in_bits = mxs_nand_ecc_size_in_bits(ecc_strength);
++
++ chunk_total_size_in_bits =
++ chunk_data_size_in_bits + chunk_ecc_size_in_bits;
++
++ /* Compute the bit offset of the block mark within the physical page. */
++ block_mark_bit_offset = page_data_size * 8;
++
++ /* Subtract the metadata bits. */
++ block_mark_bit_offset -= MXS_NAND_METADATA_SIZE * 8;
++
++ /*
++ * Compute the chunk number (starting at zero) in which the block mark
++ * appears.
++ */
++ block_mark_chunk_number =
++ block_mark_bit_offset / chunk_total_size_in_bits;
++
++ /*
++ * Compute the bit offset of the block mark within its chunk, and
++ * validate it.
++ */
++ block_mark_chunk_bit_offset = block_mark_bit_offset -
++ (block_mark_chunk_number * chunk_total_size_in_bits);
++
++ if (block_mark_chunk_bit_offset > chunk_data_size_in_bits)
++ return 1;
++
++ /*
++ * Now that we know the chunk number in which the block mark appears,
++ * we can subtract all the ECC bits that appear before it.
++ */
++ block_mark_bit_offset -=
++ block_mark_chunk_number * chunk_ecc_size_in_bits;
++
++ return block_mark_bit_offset;
++}
++
++static uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd)
++{
++ uint32_t ecc_strength;
++ ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize);
++ return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) >> 3;
++}
++
++static uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd)
++{
++ uint32_t ecc_strength;
++ ecc_strength = mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize);
++ return mxs_nand_get_mark_offset(mtd->writesize, ecc_strength) & 0x7;
++}
++
++/*
++ * Wait for BCH complete IRQ and clear the IRQ
++ */
++static int mxs_nand_wait_for_bch_complete(void)
++{
++ void __iomem *bch_regs = (void __iomem *)MXS_BCH_BASE;
++ int timeout = MXS_NAND_BCH_TIMEOUT;
++ int ret;
++
++ while (--timeout) {
++ if (readl(bch_regs + BCH_CTRL) & BCH_CTRL_COMPLETE_IRQ)
++ break;
++ udelay(1);
++ }
++
++ ret = (timeout == 0) ? -ETIMEDOUT : 0;
++
++ writel(BCH_CTRL_COMPLETE_IRQ, bch_regs + BCH_CTRL + BIT_CLR);
++
++ return ret;
++}
++
++/*
++ * This is the function that we install in the cmd_ctrl function pointer of the
++ * owning struct nand_chip. The only functions in the reference implementation
++ * that use these functions pointers are cmdfunc and select_chip.
++ *
++ * In this driver, we implement our own select_chip, so this function will only
++ * be called by the reference implementation's cmdfunc. For this reason, we can
++ * ignore the chip enable bit and concentrate only on sending bytes to the NAND
++ * Flash.
++ */
++static void mxs_nand_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl)
++{
++ struct nand_chip *nand = mtd->priv;
++ struct mxs_nand_info *nand_info = nand->priv;
++ struct mxs_dma_desc *d;
++ uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip;
++ int ret;
++
++ /*
++ * If this condition is true, something is _VERY_ wrong in MTD
++ * subsystem!
++ */
++ if (nand_info->cmd_queue_len == MXS_NAND_COMMAND_BUFFER_SIZE) {
++ printf("MXS NAND: Command queue too long\n");
++ return;
++ }
++
++ /*
++ * Every operation begins with a command byte and a series of zero or
++ * more address bytes. These are distinguished by either the Address
++ * Latch Enable (ALE) or Command Latch Enable (CLE) signals being
++ * asserted. When MTD is ready to execute the command, it will
++ * deasert both latch enables.
++ *
++ * Rather than run a separate DMA operation for every single byte, we
++ * queue them up and run a single DMA operation for the entire series
++ * of command and data bytes.
++ */
++ if (ctrl & (NAND_ALE | NAND_CLE)) {
++ if (data != NAND_CMD_NONE)
++ nand_info->cmd_buf[nand_info->cmd_queue_len++] = data;
++ return;
++ }
++
++ /*
++ * If control arrives here, MTD has deasserted both the ALE and CLE,
++ * which means it's ready to run an operation. Check if we have any
++ * bytes to send.
++ */
++ if (nand_info->cmd_queue_len == 0)
++ return;
++
++ /* Compile the DMA descriptor -- a descriptor that sends command. */
++ d = mxs_nand_get_dma_desc(nand_info);
++ d->cmd.data =
++ MXS_DMA_DESC_COMMAND_DMA_READ | MXS_DMA_DESC_IRQ |
++ MXS_DMA_DESC_CHAIN | MXS_DMA_DESC_DEC_SEM |
++ MXS_DMA_DESC_WAIT4END | (3 << MXS_DMA_DESC_PIO_WORDS_OFFSET) |
++ (nand_info->cmd_queue_len << MXS_DMA_DESC_BYTES_OFFSET);
++
++ d->cmd.address = (dma_addr_t)nand_info->cmd_buf;
++
++ d->cmd.pio_words[0] =
++ GPMI_CTRL0_COMMAND_MODE_WRITE |
++ GPMI_CTRL0_WORD_LENGTH |
++ (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
++ GPMI_CTRL0_ADDRESS_NAND_CLE |
++ GPMI_CTRL0_ADDRESS_INCREMENT |
++ nand_info->cmd_queue_len;
++
++ mxs_dma_desc_append(channel, d);
++
++ /* Execute the DMA chain. */
++ ret = mxs_dma_go(channel);
++ if (ret)
++ printf("MXS NAND: Error sending command\n");
++
++ mxs_nand_return_dma_descs(nand_info);
++
++ /* Reset the command queue. */
++ nand_info->cmd_queue_len = 0;
++}
++
++/*
++ * Test if the NAND flash is ready.
++ */
++static int mxs_nand_device_ready(struct mtd_info *mtd)
++{
++ struct nand_chip *chip = mtd->priv;
++ struct mxs_nand_info *nand_info = chip->priv;
++ void __iomem *gpmi_regs = (void *)MXS_GPMI_BASE;
++ uint32_t tmp;
++
++ if (nand_info->version > GPMI_VERSION_TYPE_MX23) {
++ tmp = readl(gpmi_regs + GPMI_STAT);
++ tmp >>= (GPMI_STAT_READY_BUSY_OFFSET + nand_info->cur_chip);
++ } else {
++ tmp = readl(gpmi_regs + GPMI_DEBUG);
++ tmp >>= (GPMI_DEBUG_READY0_OFFSET + nand_info->cur_chip);
++ }
++ return tmp & 1;
++}
++
++/*
++ * Select the NAND chip.
++ */
++static void mxs_nand_select_chip(struct mtd_info *mtd, int chip)
++{
++ struct nand_chip *nand = mtd->priv;
++ struct mxs_nand_info *nand_info = nand->priv;
++
++ nand_info->cur_chip = chip;
++}
++
++/*
++ * Handle block mark swapping.
++ *
++ * Note that, when this function is called, it doesn't know whether it's
++ * swapping the block mark, or swapping it *back* -- but it doesn't matter
++ * because the the operation is the same.
++ */
++static void mxs_nand_swap_block_mark(struct mtd_info *mtd,
++ uint8_t *data_buf, uint8_t *oob_buf)
++{
++ struct nand_chip *chip = mtd->priv;
++ struct mxs_nand_info *nand_info = chip->priv;
++
++ uint32_t bit_offset;
++ uint32_t buf_offset;
++
++ uint32_t src;
++ uint32_t dst;
++
++ /* Don't do swapping on MX23 */
++ if (nand_info->version == GPMI_VERSION_TYPE_MX23)
++ return;
++
++ bit_offset = mxs_nand_mark_bit_offset(mtd);
++ buf_offset = mxs_nand_mark_byte_offset(mtd);
++
++ /*
++ * Get the byte from the data area that overlays the block mark. Since
++ * the ECC engine applies its own view to the bits in the page, the
++ * physical block mark won't (in general) appear on a byte boundary in
++ * the data.
++ */
++ src = data_buf[buf_offset] >> bit_offset;
++ src |= data_buf[buf_offset + 1] << (8 - bit_offset);
++
++ dst = oob_buf[0];
++
++ oob_buf[0] = src;
++
++ data_buf[buf_offset] &= ~(0xff << bit_offset);
++ data_buf[buf_offset + 1] &= 0xff << bit_offset;
++
++ data_buf[buf_offset] |= dst << bit_offset;
++ data_buf[buf_offset + 1] |= dst >> (8 - bit_offset);
++}
++
++/*
++ * Read data from NAND.
++ */
++static void mxs_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int length)
++{
++ struct nand_chip *nand = mtd->priv;
++ struct mxs_nand_info *nand_info = nand->priv;
++ struct mxs_dma_desc *d;
++ uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip;
++ int ret;
++
++ if (length > NAND_MAX_PAGESIZE) {
++ printf("MXS NAND: DMA buffer too big\n");
++ return;
++ }
++
++ if (!buf) {
++ printf("MXS NAND: DMA buffer is NULL\n");
++ return;
++ }
++
++ /* Compile the DMA descriptor - a descriptor that reads data. */
++ d = mxs_nand_get_dma_desc(nand_info);
++ d->cmd.data =
++ MXS_DMA_DESC_COMMAND_DMA_WRITE | MXS_DMA_DESC_IRQ |
++ MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END |
++ (1 << MXS_DMA_DESC_PIO_WORDS_OFFSET) |
++ (length << MXS_DMA_DESC_BYTES_OFFSET);
++
++ d->cmd.address = (dma_addr_t)nand_info->data_buf;
++
++ d->cmd.pio_words[0] =
++ GPMI_CTRL0_COMMAND_MODE_READ |
++ GPMI_CTRL0_WORD_LENGTH |
++ (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
++ GPMI_CTRL0_ADDRESS_NAND_DATA |
++ length;
++
++ mxs_dma_desc_append(channel, d);
++
++ /*
++ * A DMA descriptor that waits for the command to end and the chip to
++ * become ready.
++ *
++ * I think we actually should *not* be waiting for the chip to become
++ * ready because, after all, we don't care. I think the original code
++ * did that and no one has re-thought it yet.
++ */
++ d = mxs_nand_get_dma_desc(nand_info);
++ d->cmd.data =
++ MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ |
++ MXS_DMA_DESC_NAND_WAIT_4_READY | MXS_DMA_DESC_DEC_SEM |
++ MXS_DMA_DESC_WAIT4END | (4 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
++
++ d->cmd.address = 0;
++
++ d->cmd.pio_words[0] =
++ GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
++ GPMI_CTRL0_WORD_LENGTH |
++ (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
++ GPMI_CTRL0_ADDRESS_NAND_DATA;
++
++ mxs_dma_desc_append(channel, d);
++
++ /* Execute the DMA chain. */
++ ret = mxs_dma_go(channel);
++ if (ret) {
++ printf("MXS NAND: DMA read error\n");
++ goto rtn;
++ }
++
++ memcpy(buf, nand_info->data_buf, length);
++
++rtn:
++ mxs_nand_return_dma_descs(nand_info);
++}
++
++/*
++ * Write data to NAND.
++ */
++static void mxs_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf,
++ int length)
++{
++ struct nand_chip *nand = mtd->priv;
++ struct mxs_nand_info *nand_info = nand->priv;
++ struct mxs_dma_desc *d;
++ uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip;
++ int ret;
++
++ if (length > NAND_MAX_PAGESIZE) {
++ printf("MXS NAND: DMA buffer too big\n");
++ return;
++ }
++
++ if (!buf) {
++ printf("MXS NAND: DMA buffer is NULL\n");
++ return;
++ }
++
++ memcpy(nand_info->data_buf, buf, length);
++
++ /* Compile the DMA descriptor - a descriptor that writes data. */
++ d = mxs_nand_get_dma_desc(nand_info);
++ d->cmd.data =
++ MXS_DMA_DESC_COMMAND_DMA_READ | MXS_DMA_DESC_IRQ |
++ MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END |
++ (4 << MXS_DMA_DESC_PIO_WORDS_OFFSET) |
++ (length << MXS_DMA_DESC_BYTES_OFFSET);
++
++ d->cmd.address = (dma_addr_t)nand_info->data_buf;
++
++ d->cmd.pio_words[0] =
++ GPMI_CTRL0_COMMAND_MODE_WRITE |
++ GPMI_CTRL0_WORD_LENGTH |
++ (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
++ GPMI_CTRL0_ADDRESS_NAND_DATA |
++ length;
++
++ mxs_dma_desc_append(channel, d);
++
++ /* Execute the DMA chain. */
++ ret = mxs_dma_go(channel);
++ if (ret)
++ printf("MXS NAND: DMA write error\n");
++
++ mxs_nand_return_dma_descs(nand_info);
++}
++
++/*
++ * Read a single byte from NAND.
++ */
++static uint8_t mxs_nand_read_byte(struct mtd_info *mtd)
++{
++ uint8_t buf;
++ mxs_nand_read_buf(mtd, &buf, 1);
++ return buf;
++}
++
++/*
++ * Read a page from NAND.
++ */
++static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
++ uint8_t *buf)
++{
++ struct mxs_nand_info *nand_info = nand->priv;
++ struct mxs_dma_desc *d;
++ uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip;
++ uint32_t corrected = 0, failed = 0;
++ uint8_t *status;
++ int i, ret;
++
++ /* Compile the DMA descriptor - wait for ready. */
++ d = mxs_nand_get_dma_desc(nand_info);
++ d->cmd.data =
++ MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN |
++ MXS_DMA_DESC_NAND_WAIT_4_READY | MXS_DMA_DESC_WAIT4END |
++ (1 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
++
++ d->cmd.address = 0;
++
++ d->cmd.pio_words[0] =
++ GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
++ GPMI_CTRL0_WORD_LENGTH |
++ (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
++ GPMI_CTRL0_ADDRESS_NAND_DATA;
++
++ mxs_dma_desc_append(channel, d);
++
++ /* Compile the DMA descriptor - enable the BCH block and read. */
++ d = mxs_nand_get_dma_desc(nand_info);
++ d->cmd.data =
++ MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN |
++ MXS_DMA_DESC_WAIT4END | (6 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
++
++ d->cmd.address = 0;
++
++ d->cmd.pio_words[0] =
++ GPMI_CTRL0_COMMAND_MODE_READ |
++ GPMI_CTRL0_WORD_LENGTH |
++ (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
++ GPMI_CTRL0_ADDRESS_NAND_DATA |
++ (mtd->writesize + mtd->oobsize);
++ d->cmd.pio_words[1] = 0;
++ d->cmd.pio_words[2] =
++ GPMI_ECCCTRL_ENABLE_ECC |
++ GPMI_ECCCTRL_ECC_CMD_DECODE |
++ GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE;
++ d->cmd.pio_words[3] = mtd->writesize + mtd->oobsize;
++ d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
++ d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
++
++ mxs_dma_desc_append(channel, d);
++
++ /* Compile the DMA descriptor - disable the BCH block. */
++ d = mxs_nand_get_dma_desc(nand_info);
++ d->cmd.data =
++ MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_CHAIN |
++ MXS_DMA_DESC_NAND_WAIT_4_READY | MXS_DMA_DESC_WAIT4END |
++ (3 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
++
++ d->cmd.address = 0;
++
++ d->cmd.pio_words[0] =
++ GPMI_CTRL0_COMMAND_MODE_WAIT_FOR_READY |
++ GPMI_CTRL0_WORD_LENGTH |
++ (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
++ GPMI_CTRL0_ADDRESS_NAND_DATA |
++ (mtd->writesize + mtd->oobsize);
++ d->cmd.pio_words[1] = 0;
++ d->cmd.pio_words[2] = 0;
++
++ mxs_dma_desc_append(channel, d);
++
++ /* Compile the DMA descriptor - deassert the NAND lock and interrupt. */
++ d = mxs_nand_get_dma_desc(nand_info);
++ d->cmd.data =
++ MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ |
++ MXS_DMA_DESC_DEC_SEM;
++
++ d->cmd.address = 0;
++
++ mxs_dma_desc_append(channel, d);
++
++ /* Execute the DMA chain. */
++ ret = mxs_dma_go(channel);
++ if (ret) {
++ printf("MXS NAND: DMA read error\n");
++ goto rtn;
++ }
++
++ ret = mxs_nand_wait_for_bch_complete();
++ if (ret) {
++ printf("MXS NAND: BCH read timeout\n");
++ goto rtn;
++ }
++
++ /* Read DMA completed, now do the mark swapping. */
++ mxs_nand_swap_block_mark(mtd, nand_info->data_buf, nand_info->oob_buf);
++
++ /* Loop over status bytes, accumulating ECC status. */
++ status = nand_info->oob_buf + mxs_nand_aux_status_offset();
++ for (i = 0; i < mxs_nand_ecc_chunk_cnt(mtd->writesize); i++) {
++ if (status[i] == 0x00)
++ continue;
++
++ if (status[i] == 0xff)
++ continue;
++
++ if (status[i] == 0xfe) {
++ failed++;
++ continue;
++ }
++
++ corrected += status[i];
++ }
++
++ /* Propagate ECC status to the owning MTD. */
++ mtd->ecc_stats.failed += failed;
++ mtd->ecc_stats.corrected += corrected;
++
++ /*
++ * It's time to deliver the OOB bytes. See mxs_nand_ecc_read_oob() for
++ * details about our policy for delivering the OOB.
++ *
++ * We fill the caller's buffer with set bits, and then copy the block
++ * mark to the caller's buffer. Note that, if block mark swapping was
++ * necessary, it has already been done, so we can rely on the first
++ * byte of the auxiliary buffer to contain the block mark.
++ */
++ memset(nand->oob_poi, 0xff, mtd->oobsize);
++
++ nand->oob_poi[0] = nand_info->oob_buf[0];
++
++ memcpy(buf, nand_info->data_buf, mtd->writesize);
++
++rtn:
++ mxs_nand_return_dma_descs(nand_info);
++
++ return ret;
++}
++
++/*
++ * Write a page to NAND.
++ */
++static void mxs_nand_ecc_write_page(struct mtd_info *mtd,
++ struct nand_chip *nand, const uint8_t *buf)
++{
++ struct mxs_nand_info *nand_info = nand->priv;
++ struct mxs_dma_desc *d;
++ uint32_t channel = MXS_DMA_CHANNEL_AHB_APBH_GPMI0 + nand_info->cur_chip;
++ int ret;
++
++ memcpy(nand_info->data_buf, buf, mtd->writesize);
++ memcpy(nand_info->oob_buf, nand->oob_poi, mtd->oobsize);
++
++ /* Handle block mark swapping. */
++ mxs_nand_swap_block_mark(mtd, nand_info->data_buf, nand_info->oob_buf);
++
++ /* Compile the DMA descriptor - write data. */
++ d = mxs_nand_get_dma_desc(nand_info);
++ d->cmd.data =
++ MXS_DMA_DESC_COMMAND_NO_DMAXFER | MXS_DMA_DESC_IRQ |
++ MXS_DMA_DESC_DEC_SEM | MXS_DMA_DESC_WAIT4END |
++ (6 << MXS_DMA_DESC_PIO_WORDS_OFFSET);
++
++ d->cmd.address = 0;
++
++ d->cmd.pio_words[0] =
++ GPMI_CTRL0_COMMAND_MODE_WRITE |
++ GPMI_CTRL0_WORD_LENGTH |
++ (nand_info->cur_chip << GPMI_CTRL0_CS_OFFSET) |
++ GPMI_CTRL0_ADDRESS_NAND_DATA;
++ d->cmd.pio_words[1] = 0;
++ d->cmd.pio_words[2] =
++ GPMI_ECCCTRL_ENABLE_ECC |
++ GPMI_ECCCTRL_ECC_CMD_ENCODE |
++ GPMI_ECCCTRL_BUFFER_MASK_BCH_PAGE;
++ d->cmd.pio_words[3] = (mtd->writesize + mtd->oobsize);
++ d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf;
++ d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf;
++
++ mxs_dma_desc_append(channel, d);
++
++ /* Execute the DMA chain. */
++ ret = mxs_dma_go(channel);
++ if (ret) {
++ printf("MXS NAND: DMA write error\n");
++ goto rtn;
++ }
++
++ ret = mxs_nand_wait_for_bch_complete();
++ if (ret) {
++ printf("MXS NAND: BCH write timeout\n");
++ goto rtn;
++ }
++
++rtn:
++ mxs_nand_return_dma_descs(nand_info);
++}
++
++/*
++ * Read OOB from NAND.
++ *
++ * This function is a veneer that replaces the function originally installed by
++ * the NAND Flash MTD code.
++ */
++static int mxs_nand_hook_read_oob(struct mtd_info *mtd, loff_t from,
++ struct mtd_oob_ops *ops)
++{
++ struct nand_chip *chip = mtd->priv;
++ struct mxs_nand_info *nand_info = chip->priv;
++ int ret;
++
++ if (ops->mode == MTD_OOB_RAW)
++ nand_info->raw_oob_mode = 1;
++ else
++ nand_info->raw_oob_mode = 0;
++
++ ret = nand_info->hooked_read_oob(mtd, from, ops);
++
++ nand_info->raw_oob_mode = 0;
++
++ return ret;
++}
++
++/*
++ * Write OOB to NAND.
++ *
++ * This function is a veneer that replaces the function originally installed by
++ * the NAND Flash MTD code.
++ */
++static int mxs_nand_hook_write_oob(struct mtd_info *mtd, loff_t to,
++ struct mtd_oob_ops *ops)
++{
++ struct nand_chip *chip = mtd->priv;
++ struct mxs_nand_info *nand_info = chip->priv;
++ int ret;
++
++ if (ops->mode == MTD_OOB_RAW)
++ nand_info->raw_oob_mode = 1;
++ else
++ nand_info->raw_oob_mode = 0;
++
++ ret = nand_info->hooked_write_oob(mtd, to, ops);
++
++ nand_info->raw_oob_mode = 0;
++
++ return ret;
++}
++
++/*
++ * Mark a block bad in NAND.
++ *
++ * This function is a veneer that replaces the function originally installed by
++ * the NAND Flash MTD code.
++ */
++static int mxs_nand_hook_block_markbad(struct mtd_info *mtd, loff_t ofs)
++{
++ struct nand_chip *chip = mtd->priv;
++ struct mxs_nand_info *nand_info = chip->priv;
++ int ret;
++
++ nand_info->marking_block_bad = 1;
++
++ ret = nand_info->hooked_block_markbad(mtd, ofs);
++
++ nand_info->marking_block_bad = 0;
++
++ return ret;
++}
++
++/*
++ * There are several places in this driver where we have to handle the OOB and
++ * block marks. This is the function where things are the most complicated, so
++ * this is where we try to explain it all. All the other places refer back to
++ * here.
++ *
++ * These are the rules, in order of decreasing importance:
++ *
++ * 1) Nothing the caller does can be allowed to imperil the block mark, so all
++ * write operations take measures to protect it.
++ *
++ * 2) In read operations, the first byte of the OOB we return must reflect the
++ * true state of the block mark, no matter where that block mark appears in
++ * the physical page.
++ *
++ * 3) ECC-based read operations return an OOB full of set bits (since we never
++ * allow ECC-based writes to the OOB, it doesn't matter what ECC-based reads
++ * return).
++ *
++ * 4) "Raw" read operations return a direct view of the physical bytes in the
++ * page, using the conventional definition of which bytes are data and which
++ * are OOB. This gives the caller a way to see the actual, physical bytes
++ * in the page, without the distortions applied by our ECC engine.
++ *
++ * What we do for this specific read operation depends on whether we're doing
++ * "raw" read, or an ECC-based read.
++ *
++ * It turns out that knowing whether we want an "ECC-based" or "raw" read is not
++ * easy. When reading a page, for example, the NAND Flash MTD code calls our
++ * ecc.read_page or ecc.read_page_raw function. Thus, the fact that MTD wants an
++ * ECC-based or raw view of the page is implicit in which function it calls
++ * (there is a similar pair of ECC-based/raw functions for writing).
++ *
++ * Since MTD assumes the OOB is not covered by ECC, there is no pair of
++ * ECC-based/raw functions for reading or or writing the OOB. The fact that the
++ * caller wants an ECC-based or raw view of the page is not propagated down to
++ * this driver.
++ *
++ * Since our OOB *is* covered by ECC, we need this information. So, we hook the
++ * ecc.read_oob and ecc.write_oob function pointers in the owning
++ * struct mtd_info with our own functions. These hook functions set the
++ * raw_oob_mode field so that, when control finally arrives here, we'll know
++ * what to do.
++ */
++static int mxs_nand_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *nand,
++ int page, int cmd)
++{
++ struct mxs_nand_info *nand_info = nand->priv;
++ int column;
++
++ /*
++ * First, fill in the OOB buffer. If we're doing a raw read, we need to
++ * get the bytes from the physical page. If we're not doing a raw read,
++ * we need to fill the buffer with set bits.
++ */
++ if (nand_info->raw_oob_mode && nand_info->version > GPMI_VERSION_TYPE_MX23) {
++ /*
++ * If control arrives here, we're doing a "raw" read. Send the
++ * command to read the conventional OOB and read it.
++ */
++ nand->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page);
++ nand->read_buf(mtd, nand->oob_poi, mtd->oobsize);
++ } else {
++ /*
++ * If control arrives here, we're not doing a "raw" read. Fill
++ * the OOB buffer with set bits and correct the block mark.
++ */
++ memset(nand->oob_poi, 0xff, mtd->oobsize);
++
++ column = nand_info->version == GPMI_VERSION_TYPE_MX23 ? 0 : mtd->writesize;
++ nand->cmdfunc(mtd, NAND_CMD_READ0, column, page);
++ mxs_nand_read_buf(mtd, nand->oob_poi, 1);
++ }
++
++ return 0;
++
++}
++
++/*
++ * Write OOB data to NAND.
++ */
++static int mxs_nand_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *nand,
++ int page)
++{
++ struct mxs_nand_info *nand_info = nand->priv;
++ int column;
++ uint8_t block_mark = 0;
++
++ /*
++ * There are fundamental incompatibilities between the i.MX GPMI NFC and
++ * the NAND Flash MTD model that make it essentially impossible to write
++ * the out-of-band bytes.
++ *
++ * We permit *ONE* exception. If the *intent* of writing the OOB is to
++ * mark a block bad, we can do that.
++ */
++
++ if (!nand_info->marking_block_bad) {
++ printf("NXS NAND: Writing OOB isn't supported\n");
++ return -EIO;
++ }
++
++ column = nand_info->version == GPMI_VERSION_TYPE_MX23 ? 0 : mtd->writesize;
++ /* Write the block mark. */
++ nand->cmdfunc(mtd, NAND_CMD_SEQIN, column, page);
++ nand->write_buf(mtd, &block_mark, 1);
++ nand->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
++
++ /* Check if it worked. */
++ if (nand->waitfunc(mtd, nand) & NAND_STATUS_FAIL)
++ return -EIO;
++
++ return 0;
++}
++
++/*
++ * Claims all blocks are good.
++ *
++ * In principle, this function is *only* called when the NAND Flash MTD system
++ * isn't allowed to keep an in-memory bad block table, so it is forced to ask
++ * the driver for bad block information.
++ *
++ * In fact, we permit the NAND Flash MTD system to have an in-memory BBT, so
++ * this function is *only* called when we take it away.
++ *
++ * Thus, this function is only called when we want *all* blocks to look good,
++ * so it *always* return success.
++ */
++static int mxs_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
++{
++ return 0;
++}
++
++/*
++ * Nominally, the purpose of this function is to look for or create the bad
++ * block table. In fact, since the we call this function at the very end of
++ * the initialization process started by nand_scan(), and we doesn't have a
++ * more formal mechanism, we "hook" this function to continue init process.
++ *
++ * At this point, the physical NAND Flash chips have been identified and
++ * counted, so we know the physical geometry. This enables us to make some
++ * important configuration decisions.
++ *
++ * The return value of this function propogates directly back to this driver's
++ * call to nand_scan(). Anything other than zero will cause this driver to
++ * tear everything down and declare failure.
++ */
++static int mxs_nand_scan_bbt(struct mtd_info *mtd)
++{
++ struct nand_chip *nand = mtd->priv;
++ struct mxs_nand_info *nand_info = nand->priv;
++ void __iomem *bch_regs = (void __iomem *)MXS_BCH_BASE;
++ uint32_t tmp;
++
++ /* Reset BCH. Don't use SFTRST on MX23 due to Errata #2847 */
++ mxs_reset_block(bch_regs + BCH_CTRL, nand_info->version == GPMI_VERSION_TYPE_MX23);
++
++ /* Configure layout 0 */
++ tmp = (mxs_nand_ecc_chunk_cnt(mtd->writesize) - 1)
++ << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET;
++ tmp |= MXS_NAND_METADATA_SIZE << BCH_FLASHLAYOUT0_META_SIZE_OFFSET;
++ tmp |= (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
++ << BCH_FLASHLAYOUT0_ECC0_OFFSET;
++ tmp |= MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
++ writel(tmp, bch_regs + BCH_FLASH0LAYOUT0);
++
++ tmp = (mtd->writesize + mtd->oobsize)
++ << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET;
++ tmp |= (mxs_nand_get_ecc_strength(mtd->writesize, mtd->oobsize) >> 1)
++ << BCH_FLASHLAYOUT1_ECCN_OFFSET;
++ tmp |= MXS_NAND_CHUNK_DATA_CHUNK_SIZE;
++ writel(tmp, bch_regs + BCH_FLASH0LAYOUT1);
++
++ /* Set *all* chip selects to use layout 0 */
++ writel(0, bch_regs + BCH_LAYOUTSELECT);
++
++ /* Enable BCH complete interrupt */
++ writel(BCH_CTRL_COMPLETE_IRQ_EN, bch_regs + BCH_CTRL + BIT_SET);
++
++ /* Hook some operations at the MTD level. */
++ if (mtd->read_oob != mxs_nand_hook_read_oob) {
++ nand_info->hooked_read_oob = mtd->read_oob;
++ mtd->read_oob = mxs_nand_hook_read_oob;
++ }
++
++ if (mtd->write_oob != mxs_nand_hook_write_oob) {
++ nand_info->hooked_write_oob = mtd->write_oob;
++ mtd->write_oob = mxs_nand_hook_write_oob;
++ }
++
++ if (mtd->block_markbad != mxs_nand_hook_block_markbad) {
++ nand_info->hooked_block_markbad = mtd->block_markbad;
++ mtd->block_markbad = mxs_nand_hook_block_markbad;
++ }
++
++ /* We use the reference implementation for bad block management. */
++ return nand_default_bbt(mtd);
++}
++
++/*
++ * Allocate DMA buffers
++ */
++int mxs_nand_alloc_buffers(struct mxs_nand_info *nand_info)
++{
++ uint8_t *buf;
++ const int size = NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE;
++
++ /* DMA buffers */
++ buf = dma_alloc_coherent(size);
++ if (!buf) {
++ printf("MXS NAND: Error allocating DMA buffers\n");
++ return -ENOMEM;
++ }
++
++ memset(buf, 0, size);
++
++ nand_info->data_buf = buf;
++ nand_info->oob_buf = buf + NAND_MAX_PAGESIZE;
++
++ /* Command buffers */
++ nand_info->cmd_buf = dma_alloc_coherent(MXS_NAND_COMMAND_BUFFER_SIZE);
++ if (!nand_info->cmd_buf) {
++ free(buf);
++ printf("MXS NAND: Error allocating command buffers\n");
++ return -ENOMEM;
++ }
++ memset(nand_info->cmd_buf, 0, MXS_NAND_COMMAND_BUFFER_SIZE);
++ nand_info->cmd_queue_len = 0;
++
++ return 0;
++}
++
++/*
++ * Initializes the NFC hardware.
++ */
++int mxs_nand_hw_init(struct mxs_nand_info *info)
++{
++ void __iomem *gpmi_regs = (void *)MXS_GPMI_BASE;
++ int i = 0;
++ u32 val;
++
++ info->desc = malloc(sizeof(struct mxs_dma_desc *) *
++ MXS_NAND_DMA_DESCRIPTOR_COUNT);
++ if (!info->desc)
++ goto err1;
++
++ /* Allocate the DMA descriptors. */
++ for (i = 0; i < MXS_NAND_DMA_DESCRIPTOR_COUNT; i++) {
++ info->desc[i] = mxs_dma_desc_alloc();
++ if (!info->desc[i])
++ goto err2;
++ }
++
++ /* Init the DMA controller. */
++ mxs_dma_init();
++
++ imx_enable_nandclk();
++
++ /* Reset the GPMI block. */
++ mxs_reset_block(gpmi_regs + GPMI_CTRL0, 0);
++
++ /*
++ * Choose NAND mode, set IRQ polarity, disable write protection and
++ * select BCH ECC.
++ */
++ val = readl(gpmi_regs + GPMI_CTRL1);
++ val &= ~GPMI_CTRL1_GPMI_MODE;
++ val |= GPMI_CTRL1_ATA_IRQRDY_POLARITY | GPMI_CTRL1_DEV_RESET |
++ GPMI_CTRL1_BCH_MODE;
++ writel(val, gpmi_regs + GPMI_CTRL1);
++
++ val = readl(gpmi_regs + GPMI_VERSION);
++ info->version = val >> GPMI_VERSION_MINOR_OFFSET;
++
++ return 0;
++
++err2:
++ free(info->desc);
++err1:
++ for (--i; i >= 0; i--)
++ mxs_dma_desc_free(info->desc[i]);
++ printf("MXS NAND: Unable to allocate DMA descriptors\n");
++ return -ENOMEM;
++}
++
++static int mxs_nand_probe(struct device_d *dev)
++{
++ struct mxs_nand_info *nand_info;
++ struct nand_chip *nand;
++ struct mtd_info *mtd;
++ int err;
++
++ nand_info = kzalloc(sizeof(struct mxs_nand_info), GFP_KERNEL);
++ if (!nand_info) {
++ printf("MXS NAND: Failed to allocate private data\n");
++ return -ENOMEM;
++ }
++
++ /* XXX: Remove u-boot specific access pointers and use io_base instead? */
++ nand_info->io_base = dev_request_mem_region(dev, 0);
++
++ err = mxs_nand_alloc_buffers(nand_info);
++ if (err)
++ goto err1;
++
++ err = mxs_nand_hw_init(nand_info);
++ if (err)
++ goto err2;
++
++ memset(&fake_ecc_layout, 0, sizeof(fake_ecc_layout));
++
++ /* structures must be linked */
++ nand = &nand_info->nand_chip;
++ mtd = &nand_info->mtd;
++ mtd->priv = nand;
++
++ nand->priv = nand_info;
++ nand->options |= NAND_NO_SUBPAGE_WRITE;
++
++ nand->cmd_ctrl = mxs_nand_cmd_ctrl;
++
++ nand->dev_ready = mxs_nand_device_ready;
++ nand->select_chip = mxs_nand_select_chip;
++ nand->block_bad = mxs_nand_block_bad;
++ nand->scan_bbt = mxs_nand_scan_bbt;
++
++ nand->read_byte = mxs_nand_read_byte;
++
++ nand->read_buf = mxs_nand_read_buf;
++ nand->write_buf = mxs_nand_write_buf;
++
++ nand->ecc.read_page = mxs_nand_ecc_read_page;
++ nand->ecc.write_page = mxs_nand_ecc_write_page;
++ nand->ecc.read_oob = mxs_nand_ecc_read_oob;
++ nand->ecc.write_oob = mxs_nand_ecc_write_oob;
++
++ nand->ecc.layout = &fake_ecc_layout;
++ nand->ecc.mode = NAND_ECC_HW;
++ nand->ecc.bytes = 9;
++ nand->ecc.size = 512;
++
++ /* Scan to find existence of the device */
++ err = nand_scan(mtd, 1);
++ if (err)
++ goto err2;
++
++ return add_mtd_device(mtd, "nand");
++err2:
++ free(nand_info->data_buf);
++ free(nand_info->cmd_buf);
++err1:
++ free(nand_info);
++ return err;
++}
++
++static struct driver_d mxs_nand_driver = {
++ .name = "mxs_nand",
++ .probe = mxs_nand_probe,
++};
++
++static int __init mxs_nand_init(void)
++{
++ return register_driver(&mxs_nand_driver);
++}
++
++device_initcall(mxs_nand_init);
++
++MODULE_AUTHOR("Denx Software Engeneering and Wolfram Sang");
++MODULE_DESCRIPTION("MXS NAND MTD driver");
++MODULE_LICENSE("GPL");
+diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
+index 95bef1f..c99b64d 100644
+--- a/drivers/mtd/ubi/cdev.c
++++ b/drivers/mtd/ubi/cdev.c
+@@ -12,7 +12,7 @@ struct ubi_volume_cdev_priv {
+ };
+
+ static ssize_t ubi_volume_cdev_read(struct cdev *cdev, void *buf, size_t size,
+- unsigned long offset, unsigned long flags)
++ loff_t offset, unsigned long flags)
+ {
+ struct ubi_volume_cdev_priv *priv = cdev->priv;
+ struct ubi_volume *vol = priv->vol;
+@@ -23,7 +23,7 @@ static ssize_t ubi_volume_cdev_read(struct cdev *cdev, void *buf, size_t size,
+ loff_t offp = offset;
+ int usable_leb_size = vol->usable_leb_size;
+
+- printf("%s: %d @ 0x%08lx\n", __func__, size, offset);
++ printf("%s: %d @ 0x%08llx\n", __func__, size, offset);
+
+ len = size > usable_leb_size ? usable_leb_size : size;
+
+@@ -56,7 +56,7 @@ static ssize_t ubi_volume_cdev_read(struct cdev *cdev, void *buf, size_t size,
+ }
+
+ static ssize_t ubi_volume_cdev_write(struct cdev* cdev, const void *buf,
+- size_t size, unsigned long offset, unsigned long flags)
++ size_t size, loff_t offset, unsigned long flags)
+ {
+ struct ubi_volume_cdev_priv *priv = cdev->priv;
+ struct ubi_volume *vol = priv->vol;
+@@ -121,7 +121,7 @@ static int ubi_volume_cdev_close(struct cdev *cdev)
+ return 0;
+ }
+
+-static off_t ubi_volume_cdev_lseek(struct cdev *cdev, off_t ofs)
++static loff_t ubi_volume_cdev_lseek(struct cdev *cdev, loff_t ofs)
+ {
+ struct ubi_volume_cdev_priv *priv = cdev->priv;
+
+diff --git a/drivers/mtd/ubi/ubi-barebox.h b/drivers/mtd/ubi/ubi-barebox.h
+index d23228f..72f29a6 100644
+--- a/drivers/mtd/ubi/ubi-barebox.h
++++ b/drivers/mtd/ubi/ubi-barebox.h
+@@ -135,7 +135,6 @@ struct kmem_cache { int i; };
+ #define GFP_KERNEL 0
+ #define GFP_NOFS 1
+
+-#define __user
+ #define __init
+ #define __exit
+
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index 172cc39..749ea6a 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -13,6 +13,9 @@ config HAS_AT91_ETHER
+ config HAS_NETX_ETHER
+ bool
+
++config HAS_DESIGNWARE_ETH
++ bool
++
+ config ARCH_HAS_FEC_IMX
+ bool
+
+@@ -108,6 +111,19 @@ config DRIVER_NET_KS8851_MLL
+ This option enables support for the Micrel KS8851 MLL
+ ethernet chip.
+
++config DRIVER_NET_DESIGNWARE
++ bool "Designware Universal MAC ethernet driver"
++ select MIIDEV
++ depends on HAS_DESIGNWARE_ETH
++ help
++ This option enables support for the Synopsys
++ Designware Core Univesal MAC 10M/100M/1G ethernet IP.
++
++config DRIVER_NET_DESIGNWARE_ALTDESCRIPTOR
++ bool
++ depends on DRIVER_NET_DESIGNWARE
++ default n
++
+ source "drivers/net/usb/Kconfig"
+
+ endmenu
+diff --git a/drivers/net/Makefile b/drivers/net/Makefile
+index 34dbee9..29727b7 100644
+--- a/drivers/net/Makefile
++++ b/drivers/net/Makefile
+@@ -13,3 +13,4 @@ obj-$(CONFIG_MIIDEV) += miidev.o
+ obj-$(CONFIG_NET_USB) += usb/
+ obj-$(CONFIG_DRIVER_NET_TSE) += altera_tse.o
+ obj-$(CONFIG_DRIVER_NET_KS8851_MLL) += ks8851_mll.o
++obj-$(CONFIG_DRIVER_NET_DESIGNWARE) += designware.o
+diff --git a/drivers/net/designware.c b/drivers/net/designware.c
+new file mode 100644
+index 0000000..379b4e3
+--- /dev/null
++++ b/drivers/net/designware.c
+@@ -0,0 +1,436 @@
++/*
++ * (C) Copyright 2010
++ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++/*
++ * Designware ethernet IP driver for u-boot
++ */
++
++#include <common.h>
++#include <init.h>
++#include <io.h>
++#include <net.h>
++#include <miidev.h>
++#include <asm/mmu.h>
++#include <net/designware.h>
++#include "designware.h"
++
++
++struct dw_eth_dev {
++ struct eth_device netdev;
++ struct mii_device miidev;
++
++ void (*fix_mac_speed)(int speed);
++ u8 macaddr[6];
++ u32 tx_currdescnum;
++ u32 rx_currdescnum;
++
++ struct dmamacdescr *tx_mac_descrtable;
++ struct dmamacdescr *rx_mac_descrtable;
++
++ u8 *txbuffs;
++ u8 *rxbuffs;
++
++ struct eth_mac_regs *mac_regs_p;
++ struct eth_dma_regs *dma_regs_p;
++};
++
++/* Speed specific definitions */
++#define SPEED_10M 1
++#define SPEED_100M 2
++#define SPEED_1000M 3
++
++/* Duplex mode specific definitions */
++#define HALF_DUPLEX 1
++#define FULL_DUPLEX 2
++
++
++static int dwc_ether_mii_read(struct mii_device *dev, int addr, int reg)
++{
++ struct dw_eth_dev *priv = dev->edev->priv;
++ struct eth_mac_regs *mac_p = priv->mac_regs_p;
++ u64 start;
++ u32 miiaddr;
++
++ miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \
++ ((reg << MIIREGSHIFT) & MII_REGMSK);
++
++ writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
++
++ start = get_time_ns();
++ while (readl(&mac_p->miiaddr) & MII_BUSY) {
++ if (is_timeout(start, 10 * MSECOND)) {
++ dev_err(&priv->netdev.dev, "MDIO timeout\n");
++ return -EIO;
++ }
++ }
++ return readl(&mac_p->miidata) & 0xffff;
++}
++
++static int dwc_ether_mii_write(struct mii_device *dev, int addr, int reg, int val)
++{
++ struct dw_eth_dev *priv = dev->edev->priv;
++ struct eth_mac_regs *mac_p = priv->mac_regs_p;
++ u64 start;
++ u32 miiaddr;
++
++ writel(val, &mac_p->miidata);
++ miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \
++ ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE;
++
++ writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
++
++ start = get_time_ns();
++ while (readl(&mac_p->miiaddr) & MII_BUSY) {
++ if (is_timeout(start, 10 * MSECOND)) {
++ dev_err(&priv->netdev.dev, "MDIO timeout\n");
++ return -EIO;
++ }
++ }
++
++ /* Needed as a fix for ST-Phy */
++ dwc_ether_mii_read(dev, addr, reg);
++ return 0;
++}
++
++
++static int mac_reset(struct eth_device *dev)
++{
++ struct dw_eth_dev *priv = dev->priv;
++ struct eth_mac_regs *mac_p = priv->mac_regs_p;
++ struct eth_dma_regs *dma_p = priv->dma_regs_p;
++ u64 start;
++
++ writel(DMAMAC_SRST, &dma_p->busmode);
++ writel(MII_PORTSELECT, &mac_p->conf);
++
++ start = get_time_ns();
++ while (readl(&dma_p->busmode) & DMAMAC_SRST) {
++ if (is_timeout(start, 10 * MSECOND)) {
++ dev_err(&priv->netdev.dev, "MAC reset timeout\n");
++ return -EIO;
++ }
++ }
++ return 0;
++}
++
++static void tx_descs_init(struct eth_device *dev)
++{
++ struct dw_eth_dev *priv = dev->priv;
++ struct eth_dma_regs *dma_p = priv->dma_regs_p;
++ struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0];
++ char *txbuffs = &priv->txbuffs[0];
++ struct dmamacdescr *desc_p;
++ u32 idx;
++
++ for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) {
++ desc_p = &desc_table_p[idx];
++ desc_p->dmamac_addr = &txbuffs[idx * CONFIG_ETH_BUFSIZE];
++ desc_p->dmamac_next = &desc_table_p[idx + 1];
++
++#if defined(CONFIG_DRIVER_NET_DESIGNWARE_ALTDESCRIPTOR)
++ desc_p->txrx_status &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
++ DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \
++ DESC_TXSTS_TXCHECKINSCTRL | \
++ DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
++
++ desc_p->txrx_status |= DESC_TXSTS_TXCHAIN;
++ desc_p->dmamac_cntl = 0;
++ desc_p->txrx_status &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
++#else
++ desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN;
++ desc_p->txrx_status = 0;
++#endif
++ }
++
++ /* Correcting the last pointer of the chain */
++ desc_p->dmamac_next = &desc_table_p[0];
++
++ writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr);
++}
++
++static void rx_descs_init(struct eth_device *dev)
++{
++ struct dw_eth_dev *priv = dev->priv;
++ struct eth_dma_regs *dma_p = priv->dma_regs_p;
++ struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0];
++ char *rxbuffs = &priv->rxbuffs[0];
++ struct dmamacdescr *desc_p;
++ u32 idx;
++
++ for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) {
++ desc_p = &desc_table_p[idx];
++ desc_p->dmamac_addr = &rxbuffs[idx * CONFIG_ETH_BUFSIZE];
++ desc_p->dmamac_next = &desc_table_p[idx + 1];
++
++ desc_p->dmamac_cntl =
++ (MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) | \
++ DESC_RXCTRL_RXCHAIN;
++
++ dma_inv_range((unsigned long)desc_p->dmamac_addr,
++ (unsigned long)desc_p->dmamac_addr + CONFIG_ETH_BUFSIZE);
++ desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
++ }
++
++ /* Correcting the last pointer of the chain */
++ desc_p->dmamac_next = &desc_table_p[0];
++
++ writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr);
++}
++
++static void descs_init(struct eth_device *dev)
++{
++ tx_descs_init(dev);
++ rx_descs_init(dev);
++}
++
++static int dwc_ether_init(struct eth_device *dev)
++{
++ struct dw_eth_dev *priv = dev->priv;
++ struct eth_mac_regs *mac_p = priv->mac_regs_p;
++ struct eth_dma_regs *dma_p = priv->dma_regs_p;
++
++ if (mac_reset(dev) < 0)
++ return -1;
++
++ /* HW MAC address is lost during MAC reset */
++ dev->set_ethaddr(dev, priv->macaddr);
++
++ writel(FIXEDBURST | PRIORXTX_41 | BURST_16, &dma_p->busmode);
++ writel(FLUSHTXFIFO | readl(&dma_p->opmode), &dma_p->opmode);
++ writel(STOREFORWARD | TXSECONDFRAME, &dma_p->opmode);
++ writel(FRAMEBURSTENABLE | DISABLERXOWN, &mac_p->conf);
++ return 0;
++}
++
++static int dwc_ether_open(struct eth_device *dev)
++{
++ struct dw_eth_dev *priv = dev->priv;
++ struct eth_mac_regs *mac_p = priv->mac_regs_p;
++ struct eth_dma_regs *dma_p = priv->dma_regs_p;
++ u32 conf;
++ int link, speed;
++
++ miidev_wait_aneg(&priv->miidev);
++ miidev_print_status(&priv->miidev);
++ link = miidev_get_status(&priv->miidev);
++
++ if (priv->fix_mac_speed) {
++ speed = link & MIIDEV_STATUS_IS_1000MBIT ? 1000 :
++ (link & MIIDEV_STATUS_IS_100MBIT ? 100 : 10);
++ priv->fix_mac_speed(speed);
++ }
++
++ conf = readl(&mac_p->conf);
++ if (link & MIIDEV_STATUS_IS_FULL_DUPLEX)
++ conf |= FULLDPLXMODE;
++ else
++ conf &= ~FULLDPLXMODE;
++ if (link & MIIDEV_STATUS_IS_1000MBIT)
++ conf &= ~MII_PORTSELECT;
++ else
++ conf |= MII_PORTSELECT;
++ writel(conf, &mac_p->conf);
++
++ descs_init(dev);
++
++ /*
++ * Start/Enable xfer at dma as well as mac level
++ */
++ writel(readl(&dma_p->opmode) | RXSTART, &dma_p->opmode);
++ writel(readl(&dma_p->opmode) | TXSTART, &dma_p->opmode);
++ writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf);
++ return 0;
++}
++
++static int dwc_ether_send(struct eth_device *dev, void *packet, int length)
++{
++ struct dw_eth_dev *priv = dev->priv;
++ struct eth_dma_regs *dma_p = priv->dma_regs_p;
++ u32 desc_num = priv->tx_currdescnum;
++ struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
++
++ /* Check if the descriptor is owned by CPU */
++ if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) {
++ dev_err(&dev->dev, "CPU not owner of tx frame\n");
++ return -1;
++ }
++
++ memcpy((void *)desc_p->dmamac_addr, packet, length);
++ dma_flush_range((unsigned long)desc_p->dmamac_addr,
++ (unsigned long)desc_p->dmamac_addr + length);
++
++#if defined(CONFIG_DRIVER_NET_DESIGNWARE_ALTDESCRIPTOR)
++ desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
++ desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) & \
++ DESC_TXCTRL_SIZE1MASK;
++
++ desc_p->txrx_status &= ~(DESC_TXSTS_MSK);
++ desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA;
++#else
++ desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) & \
++ DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | \
++ DESC_TXCTRL_TXFIRST;
++
++ desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
++#endif
++
++ /* Test the wrap-around condition. */
++ if (++desc_num >= CONFIG_TX_DESCR_NUM)
++ desc_num = 0;
++
++ priv->tx_currdescnum = desc_num;
++
++ /* Start the transmission */
++ writel(POLL_DATA, &dma_p->txpolldemand);
++ return 0;
++}
++
++static int dwc_ether_rx(struct eth_device *dev)
++{
++ struct dw_eth_dev *priv = dev->priv;
++ u32 desc_num = priv->rx_currdescnum;
++ struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
++
++ u32 status = desc_p->txrx_status;
++ int length = 0;
++
++ /* Check if the owner is the CPU */
++ if (status & DESC_RXSTS_OWNBYDMA)
++ return 0;
++
++ length = (status & DESC_RXSTS_FRMLENMSK) >> \
++ DESC_RXSTS_FRMLENSHFT;
++
++ net_receive(desc_p->dmamac_addr, length);
++
++ /*
++ * Make the current descriptor valid again and go to
++ * the next one
++ */
++ dma_inv_range((unsigned long)desc_p->dmamac_addr,
++ (unsigned long)desc_p->dmamac_addr + length);
++ desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
++
++ /* Test the wrap-around condition. */
++ if (++desc_num >= CONFIG_RX_DESCR_NUM)
++ desc_num = 0;
++
++ priv->rx_currdescnum = desc_num;
++
++ return length;
++}
++
++static void dwc_ether_halt (struct eth_device *dev)
++{
++ struct dw_eth_dev *priv = dev->priv;
++
++ mac_reset(dev);
++ priv->tx_currdescnum = priv->rx_currdescnum = 0;
++}
++
++static int dwc_ether_get_ethaddr(struct eth_device *dev, u8 adr[6])
++{
++ /* we have no EEPROM */
++ return -1;
++}
++
++static int dwc_ether_set_ethaddr(struct eth_device *dev, u8 adr[6])
++{
++ struct dw_eth_dev *priv = dev->priv;
++ struct eth_mac_regs *mac_p = priv->mac_regs_p;
++ u32 macid_lo, macid_hi;
++
++ macid_lo = adr[0] + (adr[1] << 8) + \
++ (adr[2] << 16) + (adr[3] << 24);
++ macid_hi = adr[4] + (adr[5] << 8);
++ writel(macid_hi, &mac_p->macaddr0hi);
++ writel(macid_lo, &mac_p->macaddr0lo);
++ memcpy(priv->macaddr, adr, 6);
++ return 0;
++}
++
++static int dwc_ether_probe(struct device_d *dev)
++{
++ struct dw_eth_dev *priv;
++ struct eth_device *edev;
++ struct mii_device *miidev;
++ void __iomem *base;
++ struct dwc_ether_platform_data *pdata = dev->platform_data;
++
++ if (!pdata) {
++ printf("dwc_ether: no platform_data\n");
++ return -ENODEV;
++ }
++
++ priv = xzalloc(sizeof(struct dw_eth_dev));
++
++ base = dev_request_mem_region(dev, 0);
++ priv->mac_regs_p = base;
++ dev_info(dev, "MAC version %08x\n", readl(&priv->mac_regs_p->version));
++ priv->dma_regs_p = base + DW_DMA_BASE_OFFSET;
++ priv->tx_mac_descrtable = dma_alloc_coherent(
++ CONFIG_TX_DESCR_NUM * sizeof(struct dmamacdescr));
++ priv->rx_mac_descrtable = dma_alloc_coherent(
++ CONFIG_RX_DESCR_NUM * sizeof(struct dmamacdescr));
++ priv->txbuffs = malloc(TX_TOTAL_BUFSIZE);
++ priv->rxbuffs = malloc(RX_TOTAL_BUFSIZE);
++ priv->fix_mac_speed = pdata->fix_mac_speed;
++
++ edev = &priv->netdev;
++ miidev = &priv->miidev;
++ edev->priv = priv;
++
++ edev->init = dwc_ether_init;
++ edev->open = dwc_ether_open;
++ edev->send = dwc_ether_send;
++ edev->recv = dwc_ether_rx;
++ edev->halt = dwc_ether_halt;
++ edev->get_ethaddr = dwc_ether_get_ethaddr;
++ edev->set_ethaddr = dwc_ether_set_ethaddr;
++
++ miidev->address = pdata->phy_addr;
++ miidev->read = dwc_ether_mii_read;
++ miidev->write = dwc_ether_mii_write;
++ miidev->edev = edev;
++
++ mii_register(miidev);
++ eth_register(edev);
++ return 0;
++}
++
++static void dwc_ether_remove(struct device_d *dev)
++{
++}
++
++static struct driver_d dwc_ether_driver = {
++ .name = "designware_eth",
++ .probe = dwc_ether_probe,
++ .remove = dwc_ether_remove,
++};
++
++static int dwc_ether_driver_init(void)
++{
++ register_driver(&dwc_ether_driver);
++ return 0;
++}
++device_initcall(dwc_ether_driver_init);
+diff --git a/drivers/net/designware.h b/drivers/net/designware.h
+new file mode 100644
+index 0000000..db2ead4
+--- /dev/null
++++ b/drivers/net/designware.h
+@@ -0,0 +1,230 @@
++/*
++ * (C) Copyright 2010
++ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __DESIGNWARE_ETH_H
++#define __DESIGNWARE_ETH_H
++
++#define CONFIG_TX_DESCR_NUM 16
++#define CONFIG_RX_DESCR_NUM 16
++#define CONFIG_ETH_BUFSIZE 2048
++#define TX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM)
++#define RX_TOTAL_BUFSIZE (CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM)
++
++struct eth_mac_regs {
++ u32 conf; /* 0x00 */
++ u32 framefilt; /* 0x04 */
++ u32 hashtablehigh; /* 0x08 */
++ u32 hashtablelow; /* 0x0c */
++ u32 miiaddr; /* 0x10 */
++ u32 miidata; /* 0x14 */
++ u32 flowcontrol; /* 0x18 */
++ u32 vlantag; /* 0x1c */
++ u32 version; /* 0x20 */
++ u8 reserved_1[20];
++ u32 intreg; /* 0x38 */
++ u32 intmask; /* 0x3c */
++ u32 macaddr0hi; /* 0x40 */
++ u32 macaddr0lo; /* 0x44 */
++};
++
++/* MAC configuration register definitions */
++#define FRAMEBURSTENABLE (1 << 21)
++#define MII_PORTSELECT (1 << 15)
++#define FES_100 (1 << 14)
++#define DISABLERXOWN (1 << 13)
++#define FULLDPLXMODE (1 << 11)
++#define RXENABLE (1 << 2)
++#define TXENABLE (1 << 3)
++
++/* MII address register definitions */
++#define MII_BUSY (1 << 0)
++#define MII_WRITE (1 << 1)
++#define MII_CLKRANGE_60_100M (0)
++#define MII_CLKRANGE_100_150M (0x4)
++#define MII_CLKRANGE_20_35M (0x8)
++#define MII_CLKRANGE_35_60M (0xC)
++#define MII_CLKRANGE_150_250M (0x10)
++#define MII_CLKRANGE_250_300M (0x14)
++
++#define MIIADDRSHIFT (11)
++#define MIIREGSHIFT (6)
++#define MII_REGMSK (0x1F << 6)
++#define MII_ADDRMSK (0x1F << 11)
++
++
++struct eth_dma_regs {
++ u32 busmode; /* 0x00 */
++ u32 txpolldemand; /* 0x04 */
++ u32 rxpolldemand; /* 0x08 */
++ u32 rxdesclistaddr; /* 0x0c */
++ u32 txdesclistaddr; /* 0x10 */
++ u32 status; /* 0x14 */
++ u32 opmode; /* 0x18 */
++ u32 intenable; /* 0x1c */
++ u8 reserved[40];
++ u32 currhosttxdesc; /* 0x48 */
++ u32 currhostrxdesc; /* 0x4c */
++ u32 currhosttxbuffaddr; /* 0x50 */
++ u32 currhostrxbuffaddr; /* 0x54 */
++};
++
++#define DW_DMA_BASE_OFFSET (0x1000)
++
++/* Bus mode register definitions */
++#define FIXEDBURST (1 << 16)
++#define PRIORXTX_41 (3 << 14)
++#define PRIORXTX_31 (2 << 14)
++#define PRIORXTX_21 (1 << 14)
++#define PRIORXTX_11 (0 << 14)
++#define BURST_1 (1 << 8)
++#define BURST_2 (2 << 8)
++#define BURST_4 (4 << 8)
++#define BURST_8 (8 << 8)
++#define BURST_16 (16 << 8)
++#define BURST_32 (32 << 8)
++#define RXHIGHPRIO (1 << 1)
++#define DMAMAC_SRST (1 << 0)
++
++/* Poll demand definitions */
++#define POLL_DATA (0xFFFFFFFF)
++
++/* Operation mode definitions */
++#define STOREFORWARD (1 << 21)
++#define FLUSHTXFIFO (1 << 20)
++#define TXSTART (1 << 13)
++#define TXSECONDFRAME (1 << 2)
++#define RXSTART (1 << 1)
++
++/* Descriptior related definitions */
++#define MAC_MAX_FRAME_SZ (1600)
++
++struct dmamacdescr {
++ u32 txrx_status;
++ u32 dmamac_cntl;
++ void *dmamac_addr;
++ struct dmamacdescr *dmamac_next;
++};
++
++/*
++ * txrx_status definitions
++ */
++
++/* tx status bits definitions */
++#if defined(CONFIG_DRIVER_NET_DESIGNWARE_ALTDESCRIPTOR)
++
++#define DESC_TXSTS_OWNBYDMA (1 << 31)
++#define DESC_TXSTS_TXINT (1 << 30)
++#define DESC_TXSTS_TXLAST (1 << 29)
++#define DESC_TXSTS_TXFIRST (1 << 28)
++#define DESC_TXSTS_TXCRCDIS (1 << 27)
++
++#define DESC_TXSTS_TXPADDIS (1 << 26)
++#define DESC_TXSTS_TXCHECKINSCTRL (3 << 22)
++#define DESC_TXSTS_TXRINGEND (1 << 21)
++#define DESC_TXSTS_TXCHAIN (1 << 20)
++#define DESC_TXSTS_MSK (0x1FFFF << 0)
++
++#else
++
++#define DESC_TXSTS_OWNBYDMA (1 << 31)
++#define DESC_TXSTS_MSK (0x1FFFF << 0)
++
++#endif
++
++/* rx status bits definitions */
++#define DESC_RXSTS_OWNBYDMA (1 << 31)
++#define DESC_RXSTS_DAFILTERFAIL (1 << 30)
++#define DESC_RXSTS_FRMLENMSK (0x3FFF << 16)
++#define DESC_RXSTS_FRMLENSHFT (16)
++
++#define DESC_RXSTS_ERROR (1 << 15)
++#define DESC_RXSTS_RXTRUNCATED (1 << 14)
++#define DESC_RXSTS_SAFILTERFAIL (1 << 13)
++#define DESC_RXSTS_RXIPC_GIANTFRAME (1 << 12)
++#define DESC_RXSTS_RXDAMAGED (1 << 11)
++#define DESC_RXSTS_RXVLANTAG (1 << 10)
++#define DESC_RXSTS_RXFIRST (1 << 9)
++#define DESC_RXSTS_RXLAST (1 << 8)
++#define DESC_RXSTS_RXIPC_GIANT (1 << 7)
++#define DESC_RXSTS_RXCOLLISION (1 << 6)
++#define DESC_RXSTS_RXFRAMEETHER (1 << 5)
++#define DESC_RXSTS_RXWATCHDOG (1 << 4)
++#define DESC_RXSTS_RXMIIERROR (1 << 3)
++#define DESC_RXSTS_RXDRIBBLING (1 << 2)
++#define DESC_RXSTS_RXCRC (1 << 1)
++
++/*
++ * dmamac_cntl definitions
++ */
++
++/* tx control bits definitions */
++#if defined(CONFIG_DRIVER_NET_DESIGNWARE_ALTDESCRIPTOR)
++
++#define DESC_TXCTRL_SIZE1MASK (0x1FFF << 0)
++#define DESC_TXCTRL_SIZE1SHFT (0)
++#define DESC_TXCTRL_SIZE2MASK (0x1FFF << 16)
++#define DESC_TXCTRL_SIZE2SHFT (16)
++
++#else
++
++#define DESC_TXCTRL_TXINT (1 << 31)
++#define DESC_TXCTRL_TXLAST (1 << 30)
++#define DESC_TXCTRL_TXFIRST (1 << 29)
++#define DESC_TXCTRL_TXCHECKINSCTRL (3 << 27)
++#define DESC_TXCTRL_TXCRCDIS (1 << 26)
++#define DESC_TXCTRL_TXRINGEND (1 << 25)
++#define DESC_TXCTRL_TXCHAIN (1 << 24)
++
++#define DESC_TXCTRL_SIZE1MASK (0x7FF << 0)
++#define DESC_TXCTRL_SIZE1SHFT (0)
++#define DESC_TXCTRL_SIZE2MASK (0x7FF << 11)
++#define DESC_TXCTRL_SIZE2SHFT (11)
++
++#endif
++
++/* rx control bits definitions */
++#if defined(CONFIG_DRIVER_NET_DESIGNWARE_ALTDESCRIPTOR)
++
++#define DESC_RXCTRL_RXINTDIS (1 << 31)
++#define DESC_RXCTRL_RXRINGEND (1 << 15)
++#define DESC_RXCTRL_RXCHAIN (1 << 14)
++
++#define DESC_RXCTRL_SIZE1MASK (0x1FFF << 0)
++#define DESC_RXCTRL_SIZE1SHFT (0)
++#define DESC_RXCTRL_SIZE2MASK (0x1FFF << 16)
++#define DESC_RXCTRL_SIZE2SHFT (16)
++
++#else
++
++#define DESC_RXCTRL_RXINTDIS (1 << 31)
++#define DESC_RXCTRL_RXRINGEND (1 << 25)
++#define DESC_RXCTRL_RXCHAIN (1 << 24)
++
++#define DESC_RXCTRL_SIZE1MASK (0x7FF << 0)
++#define DESC_RXCTRL_SIZE1SHFT (0)
++#define DESC_RXCTRL_SIZE2MASK (0x7FF << 11)
++#define DESC_RXCTRL_SIZE2SHFT (11)
++
++#endif
++
++#endif
+diff --git a/drivers/net/miidev.c b/drivers/net/miidev.c
+index f47fc9e..b49944b 100644
+--- a/drivers/net/miidev.c
++++ b/drivers/net/miidev.c
+@@ -123,7 +123,7 @@ int miidev_wait_aneg(struct mii_device *mdev)
+
+ int miidev_get_status(struct mii_device *mdev)
+ {
+- int ret, status;
++ int ret, status, adv, lpa;
+
+ ret = mii_read(mdev, mdev->address, MII_BMSR);
+ if (ret < 0)
+@@ -136,13 +136,31 @@ int miidev_get_status(struct mii_device *mdev)
+ goto err_out;
+
+ if (ret & BMCR_ANENABLE) {
+- ret = mii_read(mdev, mdev->address, MII_LPA);
+- if (ret < 0)
++ if (mdev->capabilities & MIIDEV_CAPABLE_1000M) {
++ lpa = mii_read(mdev, mdev->address, MII_STAT1000);
++ if (lpa < 0)
++ goto err_out;
++ adv = mii_read(mdev, mdev->address, MII_CTRL1000);
++ if (adv < 0)
++ goto err_out;
++ lpa &= adv << 2;
++ if (lpa & (LPA_1000FULL | LPA_1000HALF)) {
++ if (lpa & LPA_1000FULL)
++ status |= MIIDEV_STATUS_IS_FULL_DUPLEX;
++ status |= MIIDEV_STATUS_IS_1000MBIT;
++ return status;
++ }
++ }
++ lpa = mii_read(mdev, mdev->address, MII_LPA);
++ if (lpa < 0)
+ goto err_out;
+-
+- status |= ret & LPA_DUPLEX ? MIIDEV_STATUS_IS_FULL_DUPLEX : 0;
+- status |= ret & LPA_100 ? MIIDEV_STATUS_IS_100MBIT :
+- MIIDEV_STATUS_IS_10MBIT;
++ adv = mii_read(mdev, mdev->address, MII_ADVERTISE);
++ if (adv < 0)
++ goto err_out;
++ lpa &= adv;
++ status |= lpa & LPA_DUPLEX ? MIIDEV_STATUS_IS_FULL_DUPLEX : 0;
++ status |= lpa & LPA_100 ? MIIDEV_STATUS_IS_100MBIT :
++ MIIDEV_STATUS_IS_10MBIT;
+ } else {
+ status |= ret & BMCR_FULLDPLX ? MIIDEV_STATUS_IS_FULL_DUPLEX : 0;
+ status |= ret & BMCR_SPEED100 ? MIIDEV_STATUS_IS_100MBIT :
+@@ -170,8 +188,8 @@ int miidev_print_status(struct mii_device *mdev)
+ return status;
+
+ duplex = status & MIIDEV_STATUS_IS_FULL_DUPLEX ? "Full" : "Half";
+- speed = status & MIIDEV_STATUS_IS_100MBIT ? 100 : 10;
+-
++ speed = status & MIIDEV_STATUS_IS_1000MBIT ? 1000 :
++ (status & MIIDEV_STATUS_IS_100MBIT ? 100 : 10);
+
+ printf("%s: Link is %s", mdev->cdev.name,
+ status & MIIDEV_STATUS_IS_UP ? "up" : "down");
+@@ -180,33 +198,33 @@ int miidev_print_status(struct mii_device *mdev)
+ return 0;
+ }
+
+-static ssize_t miidev_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
++static ssize_t miidev_read(struct cdev *cdev, void *_buf, size_t count, loff_t offset, ulong flags)
+ {
+ int i = count;
+ uint16_t *buf = _buf;
+ struct mii_device *mdev = cdev->priv;
+
+- while (i > 1) {
+- *buf = mii_read(mdev, mdev->address, offset);
++ while (i > 0) {
++ *buf = mii_read(mdev, mdev->address, offset / 2);
+ buf++;
+ i -= 2;
+- offset++;
++ offset += 2;
+ }
+
+ return count;
+ }
+
+-static ssize_t miidev_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags)
++static ssize_t miidev_write(struct cdev *cdev, const void *_buf, size_t count, loff_t offset, ulong flags)
+ {
+ int i = count;
+ const uint16_t *buf = _buf;
+ struct mii_device *mdev = cdev->priv;
+
+- while (i > 1) {
+- mii_write(mdev, mdev->address, offset, *buf);
++ while (i > 0) {
++ mii_write(mdev, mdev->address, offset / 2, *buf);
+ buf++;
+ i -= 2;
+- offset++;
++ offset += 2;
+ }
+
+ return count;
+@@ -221,7 +239,27 @@ static struct file_operations miidev_ops = {
+ static int miidev_probe(struct device_d *dev)
+ {
+ struct mii_device *mdev = dev->priv;
++ int val;
++ int caps = 0;
+
++ val = mii_read(mdev, mdev->address, MII_PHYSID1);
++ if (val < 0 || val == 0xffff)
++ goto err_out;
++ val = mii_read(mdev, mdev->address, MII_PHYSID2);
++ if (val < 0 || val == 0xffff)
++ goto err_out;
++ val = mii_read(mdev, mdev->address, MII_BMSR);
++ if (val < 0)
++ goto err_out;
++ if (val & BMSR_ESTATEN) {
++ val = mii_read(mdev, mdev->address, MII_ESTATUS);
++ if (val < 0)
++ goto err_out;
++ if (val & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF))
++ caps = MIIDEV_CAPABLE_1000M;
++ }
++
++ mdev->capabilities = caps;
+ mdev->cdev.name = asprintf("phy%d", dev->id);
+ mdev->cdev.size = 64;
+ mdev->cdev.ops = &miidev_ops;
+@@ -230,6 +268,10 @@ static int miidev_probe(struct device_d *dev)
+ devfs_create(&mdev->cdev);
+ list_add_tail(&mdev->list, &miidev_list);
+ return 0;
++
++err_out:
++ dev_err(dev, "cannot read PHY registers (addr %d)\n", mdev->address);
++ return -ENODEV;
+ }
+
+ static void miidev_remove(struct device_d *dev)
+diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
+index 800c188..7dddbbc 100644
+--- a/drivers/net/smc911x.c
++++ b/drivers/net/smc911x.c
+@@ -691,7 +691,7 @@ static int smc911x_probe(struct device_d *dev)
+ struct smc911x_priv *priv;
+ uint32_t val;
+ int i;
+- void *base;
++ void __iomem *base;
+
+ base = dev_request_mem_region(dev, 0);
+
+diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
+index 654e647..16885c0 100644
+--- a/drivers/nor/cfi_flash.c
++++ b/drivers/nor/cfi_flash.c
+@@ -82,9 +82,9 @@ static void flash_add_byte (struct flash_info *info, cfiword_t * cword, uchar c)
+ return;
+ }
+
+-#if __BYTE_ORDER == __BIG_ENDIAN
++#ifdef __BIG_ENDIAN
+ *cword = (*cword << 8) | c;
+-#else
++#elif defined __LITTLE_ENDIAN
+
+ if (bankwidth_is_2(info))
+ *cword = (*cword >> 8) | (u16)c << 8;
+@@ -92,6 +92,8 @@ static void flash_add_byte (struct flash_info *info, cfiword_t * cword, uchar c)
+ *cword = (*cword >> 8) | (u32)c << 24;
+ else if (bankwidth_is_8(info))
+ *cword = (*cword >> 8) | (u64)c << 56;
++#else
++#error "could not determine byte order"
+ #endif
+ }
+
+@@ -167,7 +169,7 @@ static void flash_printqry (struct cfi_qry *qry)
+ uchar flash_read_uchar (struct flash_info *info, uint offset)
+ {
+ uchar *cp = flash_make_addr(info, 0, offset);
+-#if __BYTE_ORDER == __LITTLE_ENDIAN
++#if defined __LITTLE_ENDIAN
+ return flash_read8(cp);
+ #else
+ return flash_read8(cp + info->portwidth - 1);
+@@ -195,7 +197,7 @@ static ulong flash_read_long (struct flash_info *info, flash_sect_t sect, uint o
+ debug ("addr[%x] = 0x%x\n", x, flash_read8(addr + x));
+ }
+ #endif
+-#if __BYTE_ORDER == __LITTLE_ENDIAN
++#if defined __LITTLE_ENDIAN
+ retval = ((flash_read8(addr) << 16) |
+ (flash_read8(addr + info->portwidth) << 24) |
+ (flash_read8(addr + 2 * info->portwidth)) |
+@@ -456,7 +458,7 @@ flash_sect_t find_sector (struct flash_info *info, ulong addr)
+ return sector;
+ }
+
+-static int __cfi_erase(struct cdev *cdev, size_t count, unsigned long offset,
++static int __cfi_erase(struct cdev *cdev, size_t count, loff_t offset,
+ int verbose)
+ {
+ struct flash_info *finfo = (struct flash_info *)cdev->priv;
+@@ -491,7 +493,7 @@ out:
+ return ret;
+ }
+
+-static int cfi_erase(struct cdev *cdev, size_t count, unsigned long offset)
++static int cfi_erase(struct cdev *cdev, size_t count, loff_t offset)
+ {
+ return __cfi_erase(cdev, count, offset, 1);
+ }
+@@ -628,7 +630,7 @@ static int flash_real_protect (struct flash_info *info, long sector, int prot)
+ return retcode;
+ }
+
+-static int cfi_protect(struct cdev *cdev, size_t count, unsigned long offset, int prot)
++static int cfi_protect(struct cdev *cdev, size_t count, loff_t offset, int prot)
+ {
+ struct flash_info *finfo = (struct flash_info *)cdev->priv;
+ unsigned long start, end;
+@@ -651,7 +653,7 @@ out:
+ return ret;
+ }
+
+-static ssize_t cfi_write(struct cdev *cdev, const void *buf, size_t count, unsigned long offset, ulong flags)
++static ssize_t cfi_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags)
+ {
+ struct flash_info *finfo = (struct flash_info *)cdev->priv;
+ int ret;
+diff --git a/drivers/nor/m25p80.c b/drivers/nor/m25p80.c
+index 77669c2..1440227 100644
+--- a/drivers/nor/m25p80.c
++++ b/drivers/nor/m25p80.c
+@@ -194,13 +194,14 @@ static int erase_sector(struct m25p *flash, u32 offset)
+ * Erase an address range on the flash chip. The address range may extend
+ * one or more erase sectors. Return an error is there is a problem erasing.
+ */
+-static ssize_t m25p80_erase(struct cdev *cdev, size_t count, unsigned long offset)
++static ssize_t m25p80_erase(struct cdev *cdev, size_t count, loff_t offset)
+ {
+ struct m25p *flash = cdev->priv;
+ u32 addr, len;
+ u32 start_sector;
+ u32 end_sector;
+ u32 progress = 0;
++ int eraseshift = ffs(flash->erasesize) - 1;
+
+ dev_dbg(&flash->spi->dev, "%s %s 0x%llx, len %lld\n",
+ __func__, "at", (long long)offset, (long long)count);
+@@ -212,8 +213,8 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, unsigned long offse
+ addr = offset;
+ len = count;
+
+- start_sector = offset / flash->erasesize;
+- end_sector = (offset + count - 1) / flash->erasesize;
++ start_sector = offset >> eraseshift;
++ end_sector = (offset + count - 1) >> eraseshift;
+ init_progression_bar(end_sector - start_sector + 1);
+
+ /* whole-chip erase? */
+@@ -250,7 +251,8 @@ static ssize_t m25p80_erase(struct cdev *cdev, size_t count, unsigned long offse
+ return 0;
+ }
+
+-ssize_t m25p80_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags)
++ssize_t m25p80_read(struct cdev *cdev, void *buf, size_t count, loff_t offset,
++ ulong flags)
+ {
+ struct m25p *flash = cdev->priv;
+ struct spi_transfer t[2];
+@@ -302,7 +304,8 @@ ssize_t m25p80_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ul
+ return retlen;
+ }
+
+-ssize_t m25p80_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags)
++ssize_t m25p80_write(struct cdev *cdev, const void *buf, size_t count,
++ loff_t offset, ulong flags)
+ {
+ struct m25p *flash = cdev->priv;
+ struct spi_transfer t[2];
+@@ -381,7 +384,8 @@ ssize_t m25p80_write(struct cdev *cdev, const void *buf, size_t count, ulong off
+ return retlen;
+ }
+ #ifdef CONFIG_MTD_SST25L
+-ssize_t sst_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags)
++ssize_t sst_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset,
++ ulong flags)
+ {
+ struct m25p *flash = cdev->priv;
+ struct spi_transfer t[2];
+diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
+index bd2938d..a5075d5 100644
+--- a/drivers/usb/core/usb.c
++++ b/drivers/usb/core/usb.c
+@@ -52,6 +52,7 @@
+ #include <asm/byteorder.h>
+ #include <xfuncs.h>
+ #include <init.h>
++#include <dma.h>
+
+ #include <usb/usb.h>
+
+@@ -67,7 +68,6 @@
+
+ static int dev_index;
+ static int asynch_allowed;
+-static struct devrequest setup_packet;
+
+ static int usb_hub_probe(struct usb_device *dev, int ifnum);
+ static int hub_port_reset(struct usb_device *dev, int port,
+@@ -80,8 +80,8 @@ static void print_usb_device(struct usb_device *dev)
+ {
+ printf("Bus %03d Device %03d: ID %04x:%04x %s\n",
+ dev->host->busnum, dev->devnum,
+- dev->descriptor.idVendor,
+- dev->descriptor.idProduct,
++ dev->descriptor->idVendor,
++ dev->descriptor->idProduct,
+ dev->prod);
+ }
+
+@@ -299,12 +299,14 @@ static int usb_new_device(struct usb_device *dev)
+ {
+ int addr, err;
+ int tmp;
+- unsigned char tmpbuf[USB_BUFSIZ];
++ void *buf;
+ struct usb_device_descriptor *desc;
+ int port = -1;
+ struct usb_device *parent = dev->parent;
+ unsigned short portstatus;
+
++ buf = dma_alloc(USB_BUFSIZ);
++
+ /* We still haven't set the Address yet */
+ addr = dev->devnum;
+ dev->devnum = 0;
+@@ -322,8 +324,8 @@ static int usb_new_device(struct usb_device *dev)
+ * the maxpacket size is 8 or 16 the device may be waiting to transmit
+ * some more, or keeps on retransmitting the 8 byte header. */
+
+- desc = (struct usb_device_descriptor *)tmpbuf;
+- dev->descriptor.bMaxPacketSize0 = 64; /* Start off at 64 bytes */
++ desc = buf;
++ dev->descriptor->bMaxPacketSize0 = 64; /* Start off at 64 bytes */
+ /* Default to 64 byte max packet size */
+ dev->maxpacketsize = PACKET_SIZE_64;
+ dev->epmaxpacketin[0] = 64;
+@@ -332,10 +334,10 @@ static int usb_new_device(struct usb_device *dev)
+ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
+ if (err < 0) {
+ USB_PRINTF("%s: usb_get_descriptor() failed with %d\n", __func__, err);
+- return 1;
++ goto err_out;
+ }
+
+- dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0;
++ dev->descriptor->bMaxPacketSize0 = desc->bMaxPacketSize0;
+
+ /* find the port number we're at */
+ if (parent) {
+@@ -349,20 +351,21 @@ static int usb_new_device(struct usb_device *dev)
+ }
+ if (port < 0) {
+ printf("%s: cannot locate device's port.\n", __func__);
+- return 1;
++ err = -ENODEV;
++ goto err_out;
+ }
+
+ /* reset the port for the second time */
+ err = hub_port_reset(dev->parent, port, &portstatus);
+ if (err < 0) {
+ printf("\n Couldn't reset port %i\n", port);
+- return 1;
++ goto err_out;
+ }
+ }
+
+- dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0;
+- dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
+- switch (dev->descriptor.bMaxPacketSize0) {
++ dev->epmaxpacketin[0] = dev->descriptor->bMaxPacketSize0;
++ dev->epmaxpacketout[0] = dev->descriptor->bMaxPacketSize0;
++ switch (dev->descriptor->bMaxPacketSize0) {
+ case 8:
+ dev->maxpacketsize = PACKET_SIZE_8;
+ break;
+@@ -383,15 +386,15 @@ static int usb_new_device(struct usb_device *dev)
+ if (err < 0) {
+ printf("\n USB device not accepting new address " \
+ "(error=%lX)\n", dev->status);
+- return 1;
++ goto err_out;
+ }
+
+ wait_ms(10); /* Let the SET_ADDRESS settle */
+
+- tmp = sizeof(dev->descriptor);
++ tmp = sizeof(*dev->descriptor);
+
+ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
+- &dev->descriptor, sizeof(dev->descriptor));
++ dev->descriptor, sizeof(*dev->descriptor));
+ if (err < tmp) {
+ if (err < 0)
+ printf("unable to get device descriptor (error=%d)\n",
+@@ -399,37 +402,37 @@ static int usb_new_device(struct usb_device *dev)
+ else
+ printf("USB device descriptor short read " \
+ "(expected %i, got %i)\n", tmp, err);
+- return 1;
++ goto err_out;
+ }
+ /* correct le values */
+- le16_to_cpus(&dev->descriptor.bcdUSB);
+- le16_to_cpus(&dev->descriptor.idVendor);
+- le16_to_cpus(&dev->descriptor.idProduct);
+- le16_to_cpus(&dev->descriptor.bcdDevice);
++ le16_to_cpus(&dev->descriptor->bcdUSB);
++ le16_to_cpus(&dev->descriptor->idVendor);
++ le16_to_cpus(&dev->descriptor->idProduct);
++ le16_to_cpus(&dev->descriptor->bcdDevice);
+ /* only support for one config for now */
+- usb_get_configuration_no(dev, &tmpbuf[0], 0);
+- usb_parse_config(dev, &tmpbuf[0], 0);
++ usb_get_configuration_no(dev, buf, 0);
++ usb_parse_config(dev, buf, 0);
+ usb_set_maxpacket(dev);
+ /* we set the default configuration here */
+ if (usb_set_configuration(dev, dev->config.bConfigurationValue)) {
+ printf("failed to set default configuration " \
+ "len %d, status %lX\n", dev->act_len, dev->status);
+- return -1;
++ goto err_out;
+ }
+ USB_PRINTF("new device: Mfr=%d, Product=%d, SerialNumber=%d\n",
+- dev->descriptor.iManufacturer, dev->descriptor.iProduct,
+- dev->descriptor.iSerialNumber);
++ dev->descriptor->iManufacturer, dev->descriptor->iProduct,
++ dev->descriptor->iSerialNumber);
+ memset(dev->mf, 0, sizeof(dev->mf));
+ memset(dev->prod, 0, sizeof(dev->prod));
+ memset(dev->serial, 0, sizeof(dev->serial));
+- if (dev->descriptor.iManufacturer)
+- usb_string(dev, dev->descriptor.iManufacturer,
++ if (dev->descriptor->iManufacturer)
++ usb_string(dev, dev->descriptor->iManufacturer,
+ dev->mf, sizeof(dev->mf));
+- if (dev->descriptor.iProduct)
+- usb_string(dev, dev->descriptor.iProduct,
++ if (dev->descriptor->iProduct)
++ usb_string(dev, dev->descriptor->iProduct,
+ dev->prod, sizeof(dev->prod));
+- if (dev->descriptor.iSerialNumber)
+- usb_string(dev, dev->descriptor.iSerialNumber,
++ if (dev->descriptor->iSerialNumber)
++ usb_string(dev, dev->descriptor->iSerialNumber,
+ dev->serial, sizeof(dev->serial));
+ /* now prode if the device is a hub */
+ usb_hub_probe(dev, 0);
+@@ -441,7 +444,11 @@ static int usb_new_device(struct usb_device *dev)
+ register_device(&dev->dev);
+ list_add_tail(&dev->list, &usb_device_list);
+
+- return 0;
++ err = 0;
++
++err_out:
++ dma_free(buf);
++ return err;
+ }
+
+ static struct usb_device *usb_alloc_new_device(void)
+@@ -454,6 +461,8 @@ static struct usb_device *usb_alloc_new_device(void)
+ usbdev->devnum = dev_index + 1;
+ usbdev->maxchild = 0;
+ usbdev->dev.bus = &usb_bus_type;
++ usbdev->setup_packet = dma_alloc(sizeof(*usbdev->setup_packet));
++ usbdev->descriptor = dma_alloc(sizeof(*usbdev->descriptor));
+
+ dev_index++;
+
+@@ -471,6 +480,8 @@ void usb_rescan(void)
+ unregister_device(&dev->dev);
+ if (dev->hub)
+ free(dev->hub);
++ dma_free(dev->setup_packet);
++ dma_free(dev->descriptor);
+ free(dev);
+ }
+
+@@ -532,6 +543,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
+ {
+ struct usb_host *host = dev->host;
+ int ret;
++ struct devrequest *setup_packet = dev->setup_packet;
+
+ if ((timeout == 0) && (!asynch_allowed)) {
+ /* request for a asynch control pipe is not allowed */
+@@ -539,17 +551,18 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,
+ }
+
+ /* set setup command */
+- setup_packet.requesttype = requesttype;
+- setup_packet.request = request;
+- setup_packet.value = cpu_to_le16(value);
+- setup_packet.index = cpu_to_le16(index);
+- setup_packet.length = cpu_to_le16(size);
++ setup_packet->requesttype = requesttype;
++ setup_packet->request = request;
++ setup_packet->value = cpu_to_le16(value);
++ setup_packet->index = cpu_to_le16(index);
++ setup_packet->length = cpu_to_le16(size);
+ USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \
+ "value 0x%X index 0x%X length 0x%X\n",
+ request, requesttype, value, index, size);
+ dev->status = USB_ST_NOT_PROC; /*not yet processed */
+
+- ret = host->submit_control_msg(dev, pipe, data, size, &setup_packet, timeout);
++ ret = host->submit_control_msg(dev, pipe, data, size, setup_packet,
++ timeout);
+ if (ret)
+ return ret;
+
+@@ -1284,11 +1297,11 @@ int usb_driver_register(struct usb_driver *drv)
+ static int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
+ {
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+- id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
++ id->idVendor != le16_to_cpu(dev->descriptor->idVendor))
+ return 0;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
+- id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
++ id->idProduct != le16_to_cpu(dev->descriptor->idProduct))
+ return 0;
+
+ return 1;
+@@ -1311,7 +1324,7 @@ static int usb_match_one_id(struct usb_device *usbdev,
+ /* The interface class, subclass, and protocol should never be
+ * checked for a match if the device class is Vendor Specific,
+ * unless the match record specifies the Vendor ID. */
+- if (usbdev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&
++ if (usbdev->descriptor->bDeviceClass == USB_CLASS_VENDOR_SPEC &&
+ !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+ (id->match_flags & USB_DEVICE_ID_MATCH_INT_INFO))
+ return 0;
+@@ -1371,7 +1384,8 @@ static int usb_match(struct device_d *dev, struct driver_d *drv)
+ struct usb_driver *usbdrv = container_of(dev->driver, struct usb_driver, driver);
+ const struct usb_device_id *id;
+
+- debug("matching: 0x%04x 0x%04x\n", usbdev->descriptor.idVendor, usbdev->descriptor.idProduct);
++ debug("matching: 0x%04x 0x%04x\n", usbdev->descriptor->idVendor,
++ usbdev->descriptor->idProduct);
+
+ id = usb_match_id(usbdev, usbdrv->id_table);
+ if (id) {
+diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
+index fd70e62..44e58d7 100644
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -22,6 +22,7 @@
+
+ #include <common.h>
+ #include <errno.h>
++#include <dma.h>
+ #include <usb/composite.h>
+ #include <asm/byteorder.h>
+
+@@ -867,7 +868,7 @@ composite_unbind(struct usb_gadget *gadget)
+ composite->unbind(cdev);
+
+ if (cdev->req) {
+- kfree(cdev->req->buf);
++ dma_free(cdev->req->buf);
+ usb_ep_free_request(gadget->ep0, cdev->req);
+ }
+ kfree(cdev);
+@@ -911,7 +912,7 @@ static int __init composite_bind(struct usb_gadget *gadget)
+ cdev->req = usb_ep_alloc_request(gadget->ep0);
+ if (!cdev->req)
+ goto fail;
+- cdev->req->buf = malloc(USB_BUFSIZ);
++ cdev->req->buf = dma_alloc(USB_BUFSIZ);
+ if (!cdev->req->buf)
+ goto fail;
+ cdev->req->complete = composite_setup_complete;
+diff --git a/drivers/usb/gadget/dfu.c b/drivers/usb/gadget/dfu.c
+index f26c1e4..e205c65 100644
+--- a/drivers/usb/gadget/dfu.c
++++ b/drivers/usb/gadget/dfu.c
+@@ -40,6 +40,7 @@
+ * - make 'dnstate' attached to 'struct usb_device_instance'
+ */
+
++#include <dma.h>
+ #include <asm/byteorder.h>
+ #include <usb/composite.h>
+ #include <linux/types.h>
+@@ -183,7 +184,7 @@ dfu_unbind(struct usb_configuration *c, struct usb_function *f)
+ if (gadget_is_dualspeed(c->cdev->gadget))
+ free(f->hs_descriptors);
+
+- free(dfu->dnreq->buf);
++ dma_free(dfu->dnreq->buf);
+ usb_ep_free_request(c->cdev->gadget->ep0, dfu->dnreq);
+ free(dfu);
+ }
+@@ -602,7 +603,7 @@ static int dfu_bind_config(struct usb_configuration *c)
+ dfu->dnreq = usb_ep_alloc_request(c->cdev->gadget->ep0);
+ if (!dfu->dnreq)
+ printf("usb_ep_alloc_request failed\n");
+- dfu->dnreq->buf = xmalloc(CONFIG_USBD_DFU_XFER_SIZE);
++ dfu->dnreq->buf = dma_alloc(CONFIG_USBD_DFU_XFER_SIZE);
+ dfu->dnreq->complete = dn_complete;
+ dfu->dnreq->zero = 0;
+
+diff --git a/drivers/usb/gadget/fsl_udc.c b/drivers/usb/gadget/fsl_udc.c
+index 5b64ec2..5537a0e 100644
+--- a/drivers/usb/gadget/fsl_udc.c
++++ b/drivers/usb/gadget/fsl_udc.c
+@@ -1,5 +1,6 @@
+ #include <common.h>
+ #include <errno.h>
++#include <dma.h>
+ #include <init.h>
+ #include <clock.h>
+ #include <usb/ch9.h>
+@@ -8,7 +9,6 @@
+ #include <io.h>
+ #include <poller.h>
+ #include <asm/byteorder.h>
+-#include <asm/mmu.h>
+
+ /* ### define USB registers here
+ */
+@@ -519,7 +519,7 @@ static void dump_msg(const char *label, const u8 * buf, unsigned int length)
+ * 2 + ((windex & USB_DIR_IN) ? 1 : 0))
+ #define get_pipe_by_ep(EP) (ep_index(EP) * 2 + ep_is_in(EP))
+
+-static struct usb_dr_device *dr_regs;
++static struct usb_dr_device __iomem *dr_regs;
+ static struct fsl_udc *udc_controller = NULL;
+
+ static const struct usb_endpoint_descriptor
+@@ -2109,7 +2109,8 @@ static int struct_udc_setup(struct fsl_udc *udc,
+ udc->status_req = container_of(fsl_alloc_request(NULL),
+ struct fsl_req, req);
+ /* allocate a small amount of memory to get valid address */
+- udc->status_req->req.buf = xmalloc(8);
++ udc->status_req->req.buf = dma_alloc(8);
++ udc->status_req->req.length = 8;
+ udc->resume_state = USB_STATE_NOTATTACHED;
+ udc->usb_state = USB_STATE_POWERED;
+ udc->ep0_dir = 0;
+diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
+index a2473a9..c2f48ce 100644
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -120,63 +120,6 @@ static struct descriptor {
+
+ #define ehci_is_TDI() (ehci->flags & EHCI_HAS_TT)
+
+-#ifdef CONFIG_MMU
+-/*
+- * Routines to handle (flush/invalidate) the dcache for the QH and qTD
+- * structures and data buffers. This is needed on platforms using this
+- * EHCI support with dcache enabled.
+- */
+-static void flush_invalidate(void *addr, int size, int flush)
+-{
+- if (flush) {
+- dma_flush_range((unsigned long)addr, (unsigned long)(addr + size));
+- } else {
+- dma_inv_range((unsigned long)addr, (unsigned long)(addr + size));
+- }
+-}
+-
+-static void cache_qtd(struct qTD *qtd, int flush)
+-{
+- u32 *ptr = (u32 *)qtd->qt_buffer[0];
+- int len = (qtd->qt_token & 0x7fff0000) >> 16;
+-
+- if (ptr && len)
+- flush_invalidate(ptr, len, flush);
+-}
+-
+-static void cache_qh(struct ehci_priv *ehci, int flush)
+-{
+- int i;
+-
+- flush_invalidate(ehci->qh_list, sizeof(struct QH) * NUM_QH, flush);
+- flush_invalidate(ehci->td, sizeof(struct qTD) * NUM_TD, flush);
+-
+- for (i = 0; i < NUM_TD; i ++)
+- cache_qtd(&ehci->td[i], flush);
+-}
+-
+-static inline void ehci_flush_dcache(struct ehci_priv *ehci)
+-{
+- cache_qh(ehci, 1);
+-}
+-
+-static inline void ehci_invalidate_dcache(struct ehci_priv *ehci)
+-{
+- cache_qh(ehci, 0);
+-}
+-#else /* CONFIG_MMU */
+-/*
+- *
+- */
+-static inline void ehci_flush_dcache(struct ehci_priv *ehci)
+-{
+-}
+-
+-static inline void ehci_invalidate_dcache(struct ehci_priv *ehci)
+-{
+-}
+-#endif /* CONFIG_MMU */
+-
+ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
+ {
+ uint32_t result;
+@@ -231,6 +174,9 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
+ int idx;
+
+ addr = (uint32_t) buf;
++ td->qtd_dma = addr;
++ td->length = sz;
++
+ idx = 0;
+ while (idx < 5) {
+ td->qt_buffer[idx] = cpu_to_hc32(addr);
+@@ -264,7 +210,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
+ uint32_t endpt, token, usbsts;
+ uint32_t c, toggle;
+ uint32_t cmd;
+- int ret = 0;
++ int ret = 0, i;
+ uint64_t start, timeout_val;
+
+ debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe,
+@@ -296,11 +242,11 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
+ (dev->portnr << 23) |
+ (dev->parent->devnum << 16) | (0 << 8) | (0 << 0);
+ qh->qh_endpt2 = cpu_to_hc32(endpt);
+- qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+- qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
++ qh->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
++ qh->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+
+ td = NULL;
+- tdp = &qh->qh_overlay.qt_next;
++ tdp = &qh->qt_next;
+
+ toggle =
+ usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
+@@ -363,7 +309,14 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
+ ehci->qh_list->qh_link = cpu_to_hc32((uint32_t) qh | QH_LINK_TYPE_QH);
+
+ /* Flush dcache */
+- ehci_flush_dcache(ehci);
++ if (IS_ENABLED(CONFIG_MMU)) {
++ for (i = 0; i < NUM_TD; i ++) {
++ struct qTD *qtd = &ehci->td[i];
++ if (!qtd->qtd_dma)
++ continue;
++ dma_flush_range(qtd->qtd_dma, qtd->qtd_dma + qtd->length);
++ }
++ }
+
+ usbsts = ehci_readl(&ehci->hcor->or_usbsts);
+ ehci_writel(&ehci->hcor->or_usbsts, (usbsts & 0x3f));
+@@ -384,8 +337,6 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
+ start = get_time_ns();
+ vtd = td;
+ do {
+- /* Invalidate dcache */
+- ehci_invalidate_dcache(ehci);
+ token = hc32_to_cpu(vtd->qt_token);
+ if (is_timeout(start, timeout_val)) {
+ /* Disable async schedule. */
+@@ -394,11 +345,20 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
+ ehci_writel(&ehci->hcor->or_usbcmd, cmd);
+
+ ret = handshake(&ehci->hcor->or_usbsts, STD_ASS, 0, 100 * 1000);
+- ehci_writel(&qh->qh_overlay.qt_token, 0);
++ ehci_writel(&qh->qt_token, 0);
+ return -ETIMEDOUT;
+ }
+ } while (token & 0x80);
+
++ if (IS_ENABLED(CONFIG_MMU)) {
++ for (i = 0; i < NUM_TD; i ++) {
++ struct qTD *qtd = &ehci->td[i];
++ if (!qtd->qtd_dma)
++ continue;
++ dma_inv_range(qtd->qtd_dma, qtd->qtd_dma + qtd->length);
++ }
++ }
++
+ /* Disable async schedule. */
+ cmd = ehci_readl(&ehci->hcor->or_usbcmd);
+ cmd &= ~CMD_ASE;
+@@ -413,7 +373,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
+
+ ehci->qh_list->qh_link = cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
+
+- token = hc32_to_cpu(qh->qh_overlay.qt_token);
++ token = hc32_to_cpu(qh->qt_token);
+ if (!(token & 0x80)) {
+ debug("TOKEN=0x%08x\n", token);
+ switch (token & 0xfc) {
+@@ -451,10 +411,10 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
+
+ fail:
+ printf("fail1\n");
+- td = (void *)hc32_to_cpu(qh->qh_overlay.qt_next);
++ td = (void *)hc32_to_cpu(qh->qt_next);
+ while (td != (void *)QT_NEXT_TERMINATE) {
+- qh->qh_overlay.qt_next = td->qt_next;
+- td = (void *)hc32_to_cpu(qh->qh_overlay.qt_next);
++ qh->qt_next = td->qt_next;
++ td = (void *)hc32_to_cpu(qh->qt_next);
+ }
+ return -1;
+ }
+@@ -770,9 +730,9 @@ static int ehci_init(struct usb_host *host)
+ ehci->qh_list->qh_link = cpu_to_hc32((uint32_t)ehci->qh_list | QH_LINK_TYPE_QH);
+ ehci->qh_list->qh_endpt1 = cpu_to_hc32((1 << 15) | (USB_SPEED_HIGH << 12));
+ ehci->qh_list->qh_curtd = cpu_to_hc32(QT_NEXT_TERMINATE);
+- ehci->qh_list->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
+- ehci->qh_list->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
+- ehci->qh_list->qh_overlay.qt_token = cpu_to_hc32(0x40);
++ ehci->qh_list->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
++ ehci->qh_list->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
++ ehci->qh_list->qt_token = cpu_to_hc32(0x40);
+
+ /* Set async. queue head pointer. */
+ ehci_writel(&ehci->hcor->or_asynclistaddr, (uint32_t)ehci->qh_list);
+@@ -878,8 +838,8 @@ static int ehci_probe(struct device_d *dev)
+ ehci->hccr = dev_request_mem_region(dev, 0);
+ ehci->hcor = dev_request_mem_region(dev, 1);
+
+- ehci->qh_list = xmemalign(32, sizeof(struct QH) * NUM_QH);
+- ehci->td = xmemalign(32, sizeof(struct qTD) * NUM_TD);
++ ehci->qh_list = dma_alloc_coherent(sizeof(struct QH) * NUM_TD);
++ ehci->td = dma_alloc_coherent(sizeof(struct qTD) * NUM_TD);
+
+ host->init = ehci_init;
+ host->submit_int_msg = submit_int_msg;
+diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
+index eac93db..b127b95 100644
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -166,7 +166,9 @@ struct qTD {
+ uint32_t qt_altnext;
+ uint32_t qt_token;
+ uint32_t qt_buffer[5];
+-};
++ unsigned long qtd_dma;
++ size_t length;
++} __attribute__ ((aligned (32)));
+
+ /* Queue Head (QH). */
+ struct QH {
+@@ -179,7 +181,11 @@ struct QH {
+ uint32_t qh_endpt1;
+ uint32_t qh_endpt2;
+ uint32_t qh_curtd;
+- struct qTD qh_overlay;
++ /* qtd overlay (hardware parts of a struct qTD) */
++ uint32_t qt_next;
++ uint32_t qt_altnext;
++ uint32_t qt_token;
++ uint32_t qt_buffer[5];
+ /*
+ * Add dummy fill value to make the size of this struct
+ * aligned to 32 bytes
+diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
+index 2ce7c6e..b3e9909 100644
+--- a/drivers/usb/host/ohci-at91.c
++++ b/drivers/usb/host/ohci-at91.c
+@@ -64,7 +64,7 @@ static int at91_ohci_probe(struct device_d *dev)
+ writel(0, &regs->control);
+
+ add_generic_device("ohci", DEVICE_ID_DYNAMIC, NULL, dev->resource[0].start,
+- dev->resource[0].size, IORESOURCE_MEM, NULL);
++ resource_size(&dev->resource[0]), IORESOURCE_MEM, NULL);
+
+ return 0;
+ }
+diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
+index 05e4094..f10d827 100644
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -415,7 +415,7 @@ static void ohci_dump(struct ohci *controller, int verbose)
+
+ /* get a transfer request */
+
+-int sohci_submit_job(struct urb_priv *urb, struct devrequest *setup)
++static int sohci_submit_job(struct urb_priv *urb, struct devrequest *setup)
+ {
+ struct ed *ed;
+ int i, size = 0;
+@@ -498,7 +498,7 @@ int sohci_submit_job(struct urb_priv *urb, struct devrequest *setup)
+ static inline int sohci_return_job(struct ohci *hc, struct urb_priv *urb)
+ {
+ #ifdef ENBALE_PIPE_INTERRUPT
+- struct ohci_regs *regs = hc->regs;
++ struct ohci_regs __iomem *regs = hc->regs;
+ #endif
+
+ switch (usb_pipetype(urb->pipe)) {
+@@ -848,7 +848,7 @@ static void td_fill(struct ohci *ohci, unsigned int info,
+ }
+ #endif
+ if (!len)
+- data = 0;
++ data = NULL;
+
+ td->hwINFO = m32_swap(info);
+ td->hwCBP = virt_to_phys((void *)m32_swap((unsigned long)data));
+@@ -894,7 +894,7 @@ static void td_submit_job(struct usb_device *dev, unsigned long pipe,
+ if (data_len)
+ data = buffer;
+ else
+- data = 0;
++ data = NULL;
+
+ switch (usb_pipetype(pipe)) {
+ case PIPE_BULK:
+@@ -1214,32 +1214,6 @@ static inline void wr_rh_portstat(struct ohci *ohci, int wIndex, __u32 value)
+ writel(value, &ohci->regs->roothub.portstatus[wIndex-1]);
+ }
+
+-/* request to virtual root hub */
+-
+-int rh_check_port_status(struct ohci *controller)
+-{
+- __u32 temp, ndp, i;
+- int res;
+-
+- res = -1;
+- temp = roothub_a(controller);
+- ndp = (temp & RH_A_NDP);
+-#ifdef CONFIG_AT91C_PQFP_UHPBUG
+- ndp = (ndp == 2) ? 1 : 0;
+-#endif
+- for (i = 0; i < ndp; i++) {
+- temp = roothub_portstatus(controller, i);
+- /* check for a device disconnect */
+- if (((temp & (RH_PS_PESC | RH_PS_CSC)) ==
+- (RH_PS_PESC | RH_PS_CSC)) &&
+- ((temp & RH_PS_CCS) == 0)) {
+- res = i;
+- break;
+- }
+- }
+- return res;
+-}
+-
+ static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int transfer_len, struct devrequest *cmd)
+ {
+@@ -1502,7 +1476,7 @@ static int ohci_submit_rh_msg(struct usb_device *dev, unsigned long pipe,
+
+ /* common code for handling submit messages - used for all but root hub */
+ /* accesses. */
+-int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
++static int submit_common_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int transfer_len, struct devrequest *setup, int interval,
+ int timeout)
+ {
+@@ -1721,7 +1695,7 @@ static int hc_start(struct ohci *ohci)
+
+ static int hc_interrupt(struct ohci *ohci)
+ {
+- struct ohci_regs *regs = ohci->regs;
++ struct ohci_regs __iomem *regs = ohci->regs;
+ int ints;
+ int stat = 0;
+
+@@ -1840,7 +1814,7 @@ static int ohci_probe(struct device_d *dev)
+
+ usb_register_host(host);
+
+- ohci->regs = (void *)dev->resource[0].start;
++ ohci->regs = dev_request_mem_region(dev, 0);
+
+ return 0;
+ }
+diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
+index 9132963..9c9b837 100644
+--- a/drivers/usb/host/ohci.h
++++ b/drivers/usb/host/ohci.h
+@@ -408,7 +408,7 @@ struct ohci {
+ int disabled; /* e.g. got a UE, we're hung */
+ unsigned long flags; /* for HC bugs */
+
+- struct ohci_regs *regs; /* OHCI controller's memory */
++ struct ohci_regs __iomem *regs; /* OHCI controller's memory */
+
+ int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load balancing)*/
+ struct ed *ed_rm_list[2]; /* lists of all endpoints to be removed */
+diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
+index e7a5972..68170b6 100644
+--- a/drivers/usb/storage/transport.c
++++ b/drivers/usb/storage/transport.c
+@@ -26,6 +26,7 @@
+ #include <clock.h>
+ #include <scsi.h>
+ #include <errno.h>
++#include <dma.h>
+
+ #undef USB_STOR_DEBUG
+
+@@ -65,8 +66,8 @@ int usb_stor_Bulk_clear_endpt_stall(struct us_data *us, unsigned int pipe)
+ /* Determine what the maximum LUN supported is */
+ int usb_stor_Bulk_max_lun(struct us_data *us)
+ {
+- int len;
+- unsigned char iobuf[1];
++ int len, ret = 0;
++ unsigned char *iobuf = dma_alloc(1);
+
+ /* issue the command */
+ iobuf[0] = 0;
+@@ -81,7 +82,9 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
+
+ /* if we have a successful request, return the result */
+ if (len > 0)
+- return (int)iobuf[0];
++ ret = iobuf[0];
++
++ dma_free(iobuf);
+
+ /*
+ * Some devices don't like GetMaxLUN. They may STALL the control
+@@ -90,7 +93,7 @@ int usb_stor_Bulk_max_lun(struct us_data *us)
+ * ways. In these cases the best approach is to use the default
+ * value: only one LUN.
+ */
+- return 0;
++ return ret;
+ }
+
+ int usb_stor_Bulk_transport(ccb *srb, struct us_data *us)
+diff --git a/drivers/video/fb.c b/drivers/video/fb.c
+index 0be465f..d885570 100644
+--- a/drivers/video/fb.c
++++ b/drivers/video/fb.c
+@@ -86,7 +86,7 @@ static int fb_setup_mode(struct device_d *dev, struct param_d *param,
+ if (!ret) {
+ dev->resource[0].start = (resource_size_t)info->screen_base;
+ info->cdev.size = info->xres * info->yres * (info->bits_per_pixel >> 3);
+- dev->resource[0].size = info->cdev.size;
++ dev->resource[0].end = info->cdev.size - 1;
+ dev_param_set_generic(dev, param, val);
+ } else
+ info->cdev.size = 0;
+@@ -116,7 +116,7 @@ int register_framebuffer(struct fb_info *info)
+ info->cdev.priv = info;
+ dev->resource = xzalloc(sizeof(struct resource));
+ dev->resource[0].start = (resource_size_t)info->screen_base;
+- dev->resource[0].size = info->cdev.size;
++ dev->resource[0].end = info->cdev.size - 1;
+ dev->resource[0].flags = IORESOURCE_MEM;
+ dev->num_resources = 1;
+
+diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
+new file mode 100644
+index 0000000..8fdc7a5
+--- /dev/null
++++ b/drivers/watchdog/Kconfig
+@@ -0,0 +1,15 @@
++menuconfig WATCHDOG
++ bool "Watchdog support "
++ help
++ Many platforms support a watchdog to keep track of a working machine.
++ This framework provides routines to handle these watchdogs.
++
++if WATCHDOG
++
++config WATCHDOG_MXS28
++ bool "i.MX28"
++ depends on ARCH_IMX28
++ help
++ Add support for watchdog management for the i.MX28 SoC.
++
++endif
+diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
+new file mode 100644
+index 0000000..b29103b
+--- /dev/null
++++ b/drivers/watchdog/Makefile
+@@ -0,0 +1,2 @@
++obj-$(CONFIG_WATCHDOG) += wd_core.o
++obj-$(CONFIG_WATCHDOG_MXS28) += im28wd.o
+diff --git a/drivers/watchdog/im28wd.c b/drivers/watchdog/im28wd.c
+new file mode 100644
+index 0000000..b016910
+--- /dev/null
++++ b/drivers/watchdog/im28wd.c
+@@ -0,0 +1,124 @@
++/*
++ * (c) 2012 Juergen Beisert <kernel@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * Note: this driver works for the i.MX28 SoC. It might work for the
++ * i.MX23 Soc as well, but is not tested yet.
++ */
++
++#include <common.h>
++#include <init.h>
++#include <io.h>
++#include <errno.h>
++#include <malloc.h>
++#include <watchdog.h>
++
++#define MXS_RTC_CTRL 0x0
++#define MXS_RTC_SET_ADDR 0x4
++#define MXS_RTC_CLR_ADDR 0x8
++# define MXS_RTC_CTRL_WATCHDOGEN (1 << 4)
++
++#define MXS_RTC_STAT 0x10
++# define MXS_RTC_STAT_WD_PRESENT (1 << 29)
++
++#define MXS_RTC_WATCHDOG 0x50
++
++#define MXS_RTC_PERSISTENT0 0x60
++/* dubious meaning from inside the SoC's firmware ROM */
++# define MXS_RTC_PERSISTENT0_EXT_RST (1 << 21)
++/* dubious meaning from inside the SoC's firmware ROM */
++# define MXS_RTC_PERSISTENT0_THM_RST (1 << 20)
++
++#define MXS_RTC_PERSISTENT1 0x70
++/* dubious meaning from inside the SoC's firmware ROM */
++# define MXS_RTC_PERSISTENT1_FORCE_UPDATER (1 << 31)
++
++#define MXS_RTC_DEBUG 0xc0
++
++#define WDOG_TICK_RATE 1000 /* the watchdog uses a 1 kHz clock rate */
++
++struct imx28_wd {
++ struct watchdog wd;
++ void __iomem *regs;
++};
++
++#define to_imx28_wd(h) container_of(h, struct imx28_wd, wd)
++
++static int imx28_watchdog_set_timeout(struct watchdog *wd, unsigned timeout)
++{
++ struct imx28_wd *pwd = (struct imx28_wd *)to_imx28_wd(wd);
++ void __iomem *base;
++
++ if (timeout > (ULONG_MAX / WDOG_TICK_RATE))
++ return -EINVAL;
++
++ if (timeout) {
++ writel(timeout * WDOG_TICK_RATE, pwd->regs + MXS_RTC_WATCHDOG);
++ base = pwd->regs + MXS_RTC_SET_ADDR;
++ } else {
++ base = pwd->regs + MXS_RTC_CLR_ADDR;
++ }
++ writel(MXS_RTC_CTRL_WATCHDOGEN, base + MXS_RTC_CTRL);
++ writel(MXS_RTC_PERSISTENT1_FORCE_UPDATER, base + MXS_RTC_PERSISTENT1);
++
++ return 0;
++}
++
++static int imx28_wd_probe(struct device_d *dev)
++{
++ struct imx28_wd *priv;
++ int rc;
++
++ priv = xzalloc(sizeof(struct imx28_wd));
++ priv->regs = dev_request_mem_region(dev, 0);
++ priv->wd.set_timeout = imx28_watchdog_set_timeout;
++
++ if (!(readl(priv->regs + MXS_RTC_STAT) & MXS_RTC_STAT_WD_PRESENT)) {
++ rc = -ENODEV;
++ goto on_error;
++ }
++
++ /* disable the debug feature to ensure a working WD */
++ writel(0x00000000, priv->regs + MXS_RTC_DEBUG);
++
++ rc = watchdog_register(&priv->wd);
++ if (rc != 0)
++ goto on_error;
++
++ dev->priv = priv;
++ return 0;
++
++on_error:
++ free(priv);
++ return rc;
++}
++
++static void imx28_wd_remove(struct device_d *dev)
++{
++ struct imx28_wd *priv= dev->priv;
++ watchdog_deregister(&priv->wd);
++ free(priv);
++}
++
++static struct driver_d imx28_wd_driver = {
++ .name = "im28wd",
++ .probe = imx28_wd_probe,
++ .remove = imx28_wd_remove,
++};
++
++static int imx28_wd_init(void)
++{
++ register_driver(&imx28_wd_driver);
++ return 0;
++}
++
++device_initcall(imx28_wd_init);
+diff --git a/drivers/watchdog/wd_core.c b/drivers/watchdog/wd_core.c
+new file mode 100644
+index 0000000..3d0cfc6
+--- /dev/null
++++ b/drivers/watchdog/wd_core.c
+@@ -0,0 +1,57 @@
++/*
++ * (c) 2012 Juergen Beisert <kernel@pengutronix.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <common.h>
++#include <command.h>
++#include <errno.h>
++#include <linux/ctype.h>
++#include <watchdog.h>
++
++/*
++ * Note: this simple framework supports one watchdog only.
++ */
++static struct watchdog *watchdog;
++
++int watchdog_register(struct watchdog *wd)
++{
++ if (watchdog != NULL)
++ return -EBUSY;
++
++ watchdog = wd;
++ return 0;
++}
++EXPORT_SYMBOL(watchdog_register);
++
++int watchdog_deregister(struct watchdog *wd)
++{
++ if (watchdog == NULL || wd != watchdog)
++ return -ENODEV;
++
++ watchdog = NULL;
++ return 0;
++}
++EXPORT_SYMBOL(watchdog_deregister);
++
++/*
++ * start, stop or retrigger the watchdog
++ * timeout in [seconds]. timeout of '0' will disable the watchdog (if possible)
++ */
++int watchdog_set_timeout(unsigned timeout)
++{
++ if (watchdog == NULL)
++ return -ENODEV;
++
++ return watchdog->set_timeout(watchdog, timeout);
++}
++EXPORT_SYMBOL(watchdog_set_timeout);
+diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c
+index c7c798b..99f6d49 100644
+--- a/fs/cramfs/cramfs.c
++++ b/fs/cramfs/cramfs.c
+@@ -358,7 +358,7 @@ static int cramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
+ return outsize;
+ }
+
+-static off_t cramfs_lseek(struct device_d *dev, FILE *f, off_t pos)
++static loff_t cramfs_lseek(struct device_d *dev, FILE *f, loff_t pos)
+ {
+ f->pos = pos;
+ return f->pos;
+diff --git a/fs/devfs-core.c b/fs/devfs-core.c
+index ff6a976..cdb8f79 100644
+--- a/fs/devfs-core.c
++++ b/fs/devfs-core.c
+@@ -96,7 +96,7 @@ void cdev_close(struct cdev *cdev)
+ cdev->ops->close(cdev);
+ }
+
+-ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags)
++ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags)
+ {
+ if (!cdev->ops->read)
+ return -ENOSYS;
+@@ -104,7 +104,7 @@ ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulon
+ return cdev->ops->read(cdev, buf, count, cdev->offset +offset, flags);
+ }
+
+-ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags)
++ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags)
+ {
+ if (!cdev->ops->write)
+ return -ENOSYS;
+@@ -123,15 +123,15 @@ int cdev_flush(struct cdev *cdev)
+ static int partition_ioctl(struct cdev *cdev, int request, void *buf)
+ {
+ int ret = 0;
+- size_t offset;
++ loff_t offset, *_buf = buf;
+ struct mtd_info_user *user = buf;
+
+ switch (request) {
+ case MEMSETBADBLOCK:
+ case MEMGETBADBLOCK:
+- offset = (off_t)buf;
++ offset = *_buf;
+ offset += cdev->offset;
+- ret = cdev->ops->ioctl(cdev, request, (void *)offset);
++ ret = cdev->ops->ioctl(cdev, request, &offset);
+ break;
+ case MEMGETINFO:
+ if (cdev->mtd) {
+@@ -165,10 +165,11 @@ static int partition_ioctl(struct cdev *cdev, int request, void *buf)
+ case MEMGETREGIONINFO:
+ if (cdev->mtd) {
+ struct region_info_user *reg = buf;
++ int erasesize_shift = ffs(cdev->mtd->erasesize) - 1;
+
+ reg->offset = cdev->offset;
+ reg->erasesize = cdev->mtd->erasesize;
+- reg->numblocks = cdev->size/reg->erasesize;
++ reg->numblocks = cdev->size >> erasesize_shift;
+ reg->regionindex = cdev->mtd->index;
+ }
+ break;
+@@ -191,7 +192,7 @@ int cdev_ioctl(struct cdev *cdev, int request, void *buf)
+ return cdev->ops->ioctl(cdev, request, buf);
+ }
+
+-int cdev_erase(struct cdev *cdev, size_t count, unsigned long offset)
++int cdev_erase(struct cdev *cdev, size_t count, loff_t offset)
+ {
+ if (!cdev->ops->erase)
+ return -ENOSYS;
+@@ -226,7 +227,7 @@ int devfs_remove(struct cdev *cdev)
+ return 0;
+ }
+
+-int devfs_add_partition(const char *devname, unsigned long offset, size_t size,
++int devfs_add_partition(const char *devname, loff_t offset, loff_t size,
+ int flags, const char *name)
+ {
+ struct cdev *cdev, *new;
+diff --git a/fs/devfs.c b/fs/devfs.c
+index ae48451..fccf25a 100644
+--- a/fs/devfs.c
++++ b/fs/devfs.c
+@@ -49,13 +49,16 @@ static int devfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t s
+ {
+ struct cdev *cdev = f->inode;
+
++ if (cdev->flags & DEVFS_PARTITION_READONLY)
++ return -EPERM;
++
+ return cdev_write(cdev, buf, size, f->pos, f->flags);
+ }
+
+-static off_t devfs_lseek(struct device_d *_dev, FILE *f, off_t pos)
++static loff_t devfs_lseek(struct device_d *_dev, FILE *f, loff_t pos)
+ {
+ struct cdev *cdev = f->inode;
+- off_t ret = -1;
++ loff_t ret = -1;
+
+ if (cdev->ops->lseek)
+ ret = cdev->ops->lseek(cdev, pos + cdev->offset);
+@@ -66,10 +69,13 @@ static off_t devfs_lseek(struct device_d *_dev, FILE *f, off_t pos)
+ return ret - cdev->offset;
+ }
+
+-static int devfs_erase(struct device_d *_dev, FILE *f, size_t count, unsigned long offset)
++static int devfs_erase(struct device_d *_dev, FILE *f, size_t count, loff_t offset)
+ {
+ struct cdev *cdev = f->inode;
+
++ if (cdev->flags & DEVFS_PARTITION_READONLY)
++ return -EPERM;
++
+ if (!cdev->ops->erase)
+ return -ENOSYS;
+
+@@ -79,7 +85,7 @@ static int devfs_erase(struct device_d *_dev, FILE *f, size_t count, unsigned lo
+ return cdev->ops->erase(cdev, count, offset + cdev->offset);
+ }
+
+-static int devfs_protect(struct device_d *_dev, FILE *f, size_t count, unsigned long offset, int prot)
++static int devfs_protect(struct device_d *_dev, FILE *f, size_t count, loff_t offset, int prot)
+ {
+ struct cdev *cdev = f->inode;
+
+@@ -100,7 +106,7 @@ static int devfs_memmap(struct device_d *_dev, FILE *f, void **map, int flags)
+ ret = cdev->ops->memmap(cdev, map, flags);
+
+ if (!ret)
+- *map = (void *)((unsigned long)*map + cdev->offset);
++ *map = (void *)((unsigned long)*map + (unsigned long)cdev->offset);
+
+ return ret;
+ }
+@@ -115,7 +121,8 @@ static int devfs_open(struct device_d *_dev, FILE *f, const char *filename)
+ if (!cdev)
+ return -ENOENT;
+
+- f->size = cdev->size;
++ f->size = cdev->flags & DEVFS_IS_CHARACTER_DEV ?
++ FILE_SIZE_STREAM : cdev->size;
+ f->inode = cdev;
+
+ if (cdev->ops->open) {
+@@ -166,7 +173,7 @@ static int devfs_truncate(struct device_d *dev, FILE *f, ulong size)
+ {
+ if (f->dev->num_resources < 1)
+ return -ENOSPC;
+- if (size > f->dev->resource[0].size)
++ if (size > resource_size(&f->dev->resource[0]))
+ return -ENOSPC;
+ return 0;
+ }
+diff --git a/fs/fat/fat.c b/fs/fat/fat.c
+index 21464bd..5e6c81c 100644
+--- a/fs/fat/fat.c
++++ b/fs/fat/fat.c
+@@ -49,7 +49,7 @@ DRESULT disk_read(FATFS *fat, BYTE *buf, DWORD sector, BYTE count)
+
+ debug("%s: sector: %ld count: %d\n", __func__, sector, count);
+
+- ret = cdev_read(priv->cdev, buf, count << 9, sector * 512, 0);
++ ret = cdev_read(priv->cdev, buf, count << 9, (loff_t)sector * 512, 0);
+ if (ret != count << 9)
+ return ret;
+
+@@ -64,7 +64,7 @@ DRESULT disk_write(FATFS *fat, const BYTE *buf, DWORD sector, BYTE count)
+ debug("%s: buf: %p sector: %ld count: %d\n",
+ __func__, buf, sector, count);
+
+- ret = cdev_write(priv->cdev, buf, count << 9, sector * 512, 0);
++ ret = cdev_write(priv->cdev, buf, count << 9, (loff_t)sector * 512, 0);
+ if (ret != count << 9)
+ return ret;
+
+@@ -271,7 +271,7 @@ static int fat_read(struct device_d *_dev, FILE *f, void *buf, size_t insize)
+ return outsize;
+ }
+
+-static off_t fat_lseek(struct device_d *dev, FILE *f, off_t pos)
++static loff_t fat_lseek(struct device_d *dev, FILE *f, loff_t pos)
+ {
+ FIL *f_file = f->inode;
+ int ret;
+diff --git a/fs/fat/ff.c b/fs/fat/ff.c
+index 2d476ee..66db1d6 100644
+--- a/fs/fat/ff.c
++++ b/fs/fat/ff.c
+@@ -1043,7 +1043,7 @@ int dir_register ( /* 0:Successful, FR_DENIED:No free entry or too many SFN coll
+
+ if (sn[NS] & NS_LOSS) {
+ /* When LFN is out of 8.3 format, generate a numbered name */
+- fn[NS] = 0; dj->lfn = 0; /* Find only SFN */
++ fn[NS] = 0; dj->lfn = NULL; /* Find only SFN */
+ for (n = 1; n < 100; n++) {
+ gen_numname(fn, sn, lfn, n); /* Generate a numbered name */
+ res = dir_find(dj); /* Check if the name collides with existing SFN */
+@@ -1496,7 +1496,7 @@ int follow_path ( /* 0(0): successful, !=0: error code */
+ if ((UINT)*path < ' ') {
+ /* Nul path means the start directory itself */
+ res = dir_sdi(dj, 0);
+- dj->dir = 0;
++ dj->dir = NULL;
+ return res;
+ }
+
+@@ -1718,7 +1718,7 @@ int f_open (
+ DEF_NAMEBUF;
+
+
+- fp->fs = 0; /* Clear file object */
++ fp->fs = NULL; /* Clear file object */
+
+ #ifdef CONFIG_FS_FAT_WRITE
+ mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW;
+@@ -2059,7 +2059,7 @@ int f_close (
+ /* Flush cached data */
+ res = f_sync(fp);
+ if (res == 0)
+- fp->fs = 0; /* Discard file object */
++ fp->fs = NULL; /* Discard file object */
+ return res;
+ #endif
+ }
+@@ -2308,7 +2308,7 @@ int f_getfree (
+ } else {
+ clst = fatfs->n_fatent;
+ sect = fatfs->fatbase;
+- i = 0; p = 0;
++ i = 0; p = NULL;
+ do {
+ if (!i) {
+ res = move_window(fatfs, sect++);
+diff --git a/fs/fs.c b/fs/fs.c
+index af73c8c..0b376a5 100644
+--- a/fs/fs.c
++++ b/fs/fs.c
+@@ -33,6 +33,7 @@
+ #include <libbb.h>
+ #include <magicvar.h>
+ #include <environment.h>
++#include <libgen.h>
+
+ void *read_file(const char *filename, size_t *size)
+ {
+@@ -427,6 +428,25 @@ out:
+ return ret;
+ }
+
++static int parent_check_directory(const char *path)
++{
++ struct stat s;
++ int ret;
++ char *dir = dirname(xstrdup(path));
++
++ ret = stat(dir, &s);
++
++ free(dir);
++
++ if (ret)
++ return -ENOENT;
++
++ if (!S_ISDIR(s.st_mode))
++ return -ENOTDIR;
++
++ return 0;
++}
++
+ const char *getcwd(void)
+ {
+ return cwd;
+@@ -515,6 +535,12 @@ int open(const char *pathname, int flags, ...)
+ goto out1;
+ }
+
++ if (exist_err) {
++ ret = parent_check_directory(path);
++ if (ret)
++ goto out1;
++ }
++
+ f = get_file();
+ if (!f) {
+ ret = -EMFILE;
+@@ -617,7 +643,7 @@ int read(int fd, void *buf, size_t count)
+
+ fsdrv = dev_to_fs_driver(dev);
+
+- if (f->pos + count > f->size)
++ if (f->size != FILE_SIZE_STREAM && f->pos + count > f->size)
+ count = f->size - f->pos;
+
+ if (!count)
+@@ -646,7 +672,7 @@ ssize_t write(int fd, const void *buf, size_t count)
+ dev = f->dev;
+
+ fsdrv = dev_to_fs_driver(dev);
+- if (f->pos + count > f->size) {
++ if (f->size != FILE_SIZE_STREAM && f->pos + count > f->size) {
+ ret = fsdrv->truncate(dev, f, f->pos + count);
+ if (ret) {
+ if (ret != -ENOSPC)
+@@ -692,12 +718,12 @@ int flush(int fd)
+ return ret;
+ }
+
+-off_t lseek(int fildes, off_t offset, int whence)
++loff_t lseek(int fildes, loff_t offset, int whence)
+ {
+ struct device_d *dev;
+ struct fs_driver_d *fsdrv;
+ FILE *f = &files[fildes];
+- off_t pos;
++ loff_t pos;
+ int ret;
+
+ if (check_fd(fildes))
+@@ -714,12 +740,12 @@ off_t lseek(int fildes, off_t offset, int whence)
+
+ switch (whence) {
+ case SEEK_SET:
+- if (offset > f->size)
++ if (f->size != FILE_SIZE_STREAM && offset > f->size)
+ goto out;
+ pos = offset;
+ break;
+ case SEEK_CUR:
+- if (offset + f->pos > f->size)
++ if (f->size != FILE_SIZE_STREAM && offset + f->pos > f->size)
+ goto out;
+ pos = f->pos + offset;
+ break;
+@@ -1153,6 +1179,10 @@ int mkdir (const char *pathname, mode_t mode)
+ char *freep = p;
+ int ret;
+
++ ret = parent_check_directory(p);
++ if (ret)
++ goto out;
++
+ ret = path_check_prereq(pathname, S_UB_DOES_NOT_EXIST);
+ if (ret)
+ goto out;
+@@ -1243,7 +1273,7 @@ static void memcpy_sz(void *_dst, const void *_src, ulong count, ulong rwsize)
+ }
+ }
+
+-ssize_t mem_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags)
++ssize_t mem_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags)
+ {
+ ulong size;
+ struct device_d *dev;
+@@ -1252,13 +1282,13 @@ ssize_t mem_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong
+ return -1;
+ dev = cdev->dev;
+
+- size = min((ulong)count, dev->resource[0].size - offset);
++ size = min((loff_t)count, resource_size(&dev->resource[0]) - offset);
+ memcpy_sz(buf, dev_get_mem_region(dev, 0) + offset, size, flags & O_RWSIZE_MASK);
+ return size;
+ }
+ EXPORT_SYMBOL(mem_read);
+
+-ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags)
++ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags)
+ {
+ ulong size;
+ struct device_d *dev;
+@@ -1267,7 +1297,7 @@ ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count, ulong offset
+ return -1;
+ dev = cdev->dev;
+
+- size = min((ulong)count, dev->resource[0].size - offset);
++ size = min((loff_t)count, resource_size(&dev->resource[0]) - offset);
+ memcpy_sz(dev_get_mem_region(dev, 0) + offset, buf, size, flags & O_RWSIZE_MASK);
+ return size;
+ }
+diff --git a/fs/nfs.c b/fs/nfs.c
+index 75a8f25..79e667f 100644
+--- a/fs/nfs.c
++++ b/fs/nfs.c
+@@ -805,7 +805,7 @@ static int nfs_read(struct device_d *dev, FILE *file, void *buf, size_t insize)
+ return outsize;
+ }
+
+-static off_t nfs_lseek(struct device_d *dev, FILE *file, off_t pos)
++static loff_t nfs_lseek(struct device_d *dev, FILE *file, loff_t pos)
+ {
+ struct file_priv *priv = file->inode;
+
+diff --git a/fs/ramfs.c b/fs/ramfs.c
+index cec5e76..91d06b8 100644
+--- a/fs/ramfs.c
++++ b/fs/ramfs.c
+@@ -428,7 +428,7 @@ static int ramfs_write(struct device_d *_dev, FILE *f, const void *buf, size_t i
+ return insize;
+ }
+
+-static off_t ramfs_lseek(struct device_d *dev, FILE *f, off_t pos)
++static loff_t ramfs_lseek(struct device_d *dev, FILE *f, loff_t pos)
+ {
+ f->pos = pos;
+ return f->pos;
+diff --git a/fs/tftp.c b/fs/tftp.c
+index 6586270..b58d6fc 100644
+--- a/fs/tftp.c
++++ b/fs/tftp.c
+@@ -569,7 +569,7 @@ static int tftp_read(struct device_d *dev, FILE *f, void *buf, size_t insize)
+ return outsize;
+ }
+
+-static off_t tftp_lseek(struct device_d *dev, FILE *f, off_t pos)
++static loff_t tftp_lseek(struct device_d *dev, FILE *f, loff_t pos)
+ {
+ /* not implemented in tftp protocol */
+ return -ENOSYS;
+diff --git a/include/clock.h b/include/clock.h
+index 123f874..c01a8d0 100644
+--- a/include/clock.h
++++ b/include/clock.h
+@@ -3,6 +3,8 @@
+ #ifndef CLOCK_H
+ #define CLOCK_H
+
++#include <linux/time.h>
++
+ #define CLOCKSOURCE_MASK(bits) (uint64_t)((bits) < 64 ? ((1ULL<<(bits))-1) : -1)
+
+ struct clocksource {
+diff --git a/include/common.h b/include/common.h
+index d2347f8..df12083 100644
+--- a/include/common.h
++++ b/include/common.h
+@@ -34,6 +34,24 @@
+ #include <linux/stddef.h>
+ #include <asm/common.h>
+
++/*
++ * sanity check. The Linux Kernel defines only one of __LITTLE_ENDIAN and
++ * __BIG_ENDIAN. Endianess can then be tested with #ifdef __xx_ENDIAN. Userspace
++ * always defined both __LITTLE_ENDIAN and __BIG_ENDIAN and byteorder can then
++ * be tested with #if __BYTE_ORDER == __xx_ENDIAN.
++ *
++ * As we tend to use a lot of Kernel code in barebox we use the kernel way of
++ * determing the byte order. Make sure here that architecture code properly
++ * defines it.
++ */
++#include <asm/byteorder.h>
++#if defined __LITTLE_ENDIAN && defined __BIG_ENDIAN
++#error "both __LITTLE_ENDIAN and __BIG_ENDIAN are defined"
++#endif
++#if !defined __LITTLE_ENDIAN && !defined __BIG_ENDIAN
++#error "None of __LITTLE_ENDIAN and __BIG_ENDIAN are defined"
++#endif
++
+ #define pr_info(fmt, arg...) printf(fmt, ##arg)
+ #define pr_notice(fmt, arg...) printf(fmt, ##arg)
+ #define pr_err(fmt, arg...) printf(fmt, ##arg)
+@@ -102,6 +120,7 @@ long get_ram_size (volatile long *, long);
+
+ /* $(CPU)/cpu.c */
+ void __noreturn reset_cpu(unsigned long addr);
++void __noreturn poweroff(void);
+
+ /* lib_$(ARCH)/time.c */
+ void udelay (unsigned long);
+@@ -138,10 +157,11 @@ struct memarea_info {
+ unsigned long flags;
+ };
+
+-int parse_area_spec(const char *str, ulong *start, ulong *size);
++int parse_area_spec(const char *str, loff_t *start, loff_t *size);
+
+ /* Just like simple_strtoul(), but this one honors a K/M/G suffix */
+ unsigned long strtoul_suffix(const char *str, char **endp, int base);
++unsigned long long strtoull_suffix(const char *str, char **endp, int base);
+
+ void start_barebox(void);
+ void shutdown_barebox(void);
+@@ -210,7 +230,7 @@ int run_shell(void);
+ #define PAGE_SIZE 4096
+ #define PAGE_SHIFT 12
+
+-int memory_display(char *addr, ulong offs, ulong nbytes, int size);
++int memory_display(char *addr, loff_t offs, ulong nbytes, int size);
+
+ extern const char version_string[];
+ #ifdef CONFIG_BANNER
+diff --git a/include/complete.h b/include/complete.h
+index 8248c64..33b848c 100644
+--- a/include/complete.h
++++ b/include/complete.h
+@@ -15,7 +15,7 @@ int command_complete(struct string_list *sl, char *instr);
+ int device_complete(struct string_list *sl, char *instr);
+ int empty_complete(struct string_list *sl, char *instr);
+ int eth_complete(struct string_list *sl, char *instr);
+-int cammand_var_complete(struct string_list *sl, char *instr);
++int command_var_complete(struct string_list *sl, char *instr);
+ int devfs_partition_complete(struct string_list *sl, char *instr);
+
+ #endif /* __COMPLETE_ */
+diff --git a/include/cramfs/cramfs_fs.h b/include/cramfs/cramfs_fs.h
+index af2940b..8c53fc7 100644
+--- a/include/cramfs/cramfs_fs.h
++++ b/include/cramfs/cramfs_fs.h
+@@ -84,11 +84,7 @@ struct cramfs_super {
+ | CRAMFS_FLAG_WRONG_SIGNATURE \
+ | CRAMFS_FLAG_SHIFTED_ROOT_OFFSET )
+
+-#ifndef __BYTE_ORDER
+-#error "No byte order defined in __BYTE_ORDER"
+-#endif
+-
+-#if __BYTE_ORDER == __LITTLE_ENDIAN
++#ifdef __LITTLE_ENDIAN
+ #define CRAMFS_16(x) (x)
+ #define CRAMFS_24(x) (x)
+ #define CRAMFS_32(x) (x)
+@@ -96,7 +92,7 @@ struct cramfs_super {
+ #define CRAMFS_GET_OFFSET(x) ((x)->offset)
+ #define CRAMFS_SET_OFFSET(x,y) ((x)->offset = (y))
+ #define CRAMFS_SET_NAMELEN(x,y) ((x)->namelen = (y))
+-#elif __BYTE_ORDER ==__BIG_ENDIAN
++#elif defined __BIG_ENDIAN
+ #ifdef __KERNEL__
+ #define CRAMFS_16(x) swab16(x)
+ #define CRAMFS_24(x) ((swab32(x)) >> 8)
+diff --git a/include/dma.h b/include/dma.h
+new file mode 100644
+index 0000000..899f831
+--- /dev/null
++++ b/include/dma.h
+@@ -0,0 +1,30 @@
++/*
++ * Copyright (C) 2012 by Marc Kleine-Budde <mkl@pengutronix.de>
++ *
++ * This file is released under the GPLv2
++ *
++ */
++
++#ifndef __DMA_H
++#define __DMA_H
++
++#include <malloc.h>
++#include <xfuncs.h>
++
++#include <asm/dma.h>
++
++#ifndef dma_alloc
++static inline void *dma_alloc(size_t size)
++{
++ return xmalloc(size);
++}
++#endif
++
++#ifndef dma_free
++static inline void dma_free(void *mem)
++{
++ free(mem);
++}
++#endif
++
++#endif /* __DMA_H */
+diff --git a/include/driver.h b/include/driver.h
+index 09dd1e4..7d597b4 100644
+--- a/include/driver.h
++++ b/include/driver.h
+@@ -183,7 +183,7 @@ static inline const char *dev_name(const struct device_d *dev)
+ /*
+ * get register base 'num' for a device
+ */
+-void __iomem *dev_get_mem_region(struct device_d *dev, int num);
++void *dev_get_mem_region(struct device_d *dev, int num);
+
+ /*
+ * exlusively request register base 'num' for a device
+@@ -301,8 +301,8 @@ struct cdev;
+ int dev_protect(struct device_d *dev, size_t count, unsigned long offset, int prot);
+
+ /* These are used by drivers which work with direct memory accesses */
+-ssize_t mem_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags);
+-ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags);
++ssize_t mem_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags);
++ssize_t mem_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags);
+ int mem_memmap(struct cdev *cdev, void **map, int flags);
+
+ /* Use this if you have nothing to do in your drivers probe function */
+@@ -316,7 +316,7 @@ void devices_shutdown(void);
+ int generic_memmap_ro(struct cdev *dev, void **map, int flags);
+ int generic_memmap_rw(struct cdev *dev, void **map, int flags);
+
+-static inline off_t dev_lseek_default(struct cdev *cdev, off_t ofs)
++static inline loff_t dev_lseek_default(struct cdev *cdev, loff_t ofs)
+ {
+ return ofs;
+ }
+@@ -373,18 +373,18 @@ extern struct bus_type platform_bus;
+
+ struct file_operations {
+ /*! Called in response of reading from this device. Required */
+- ssize_t (*read)(struct cdev*, void* buf, size_t count, ulong offset, ulong flags);
++ ssize_t (*read)(struct cdev*, void* buf, size_t count, loff_t offset, ulong flags);
+
+ /*! Called in response of write to this device. Required */
+- ssize_t (*write)(struct cdev*, const void* buf, size_t count, ulong offset, ulong flags);
++ ssize_t (*write)(struct cdev*, const void* buf, size_t count, loff_t offset, ulong flags);
+
+ int (*ioctl)(struct cdev*, int, void *);
+- off_t (*lseek)(struct cdev*, off_t);
++ loff_t (*lseek)(struct cdev*, loff_t);
+ int (*open)(struct cdev*, unsigned long flags);
+ int (*close)(struct cdev*);
+ int (*flush)(struct cdev*);
+- int (*erase)(struct cdev*, size_t count, unsigned long offset);
+- int (*protect)(struct cdev*, size_t count, unsigned long offset, int prot);
++ int (*erase)(struct cdev*, size_t count, loff_t offset);
++ int (*protect)(struct cdev*, size_t count, loff_t offset, int prot);
+ int (*memmap)(struct cdev*, void **map, int flags);
+ };
+
+@@ -395,8 +395,8 @@ struct cdev {
+ struct list_head list;
+ struct list_head devices_list;
+ char *name;
+- unsigned long offset;
+- size_t size;
++ loff_t offset;
++ loff_t size;
+ unsigned int flags;
+ int open;
+ struct mtd_info *mtd;
+@@ -409,16 +409,17 @@ struct cdev *cdev_by_name(const char *filename);
+ struct cdev *cdev_open(const char *name, unsigned long flags);
+ void cdev_close(struct cdev *cdev);
+ int cdev_flush(struct cdev *cdev);
+-ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, ulong offset, ulong flags);
+-ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, ulong offset, ulong flags);
++ssize_t cdev_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags);
++ssize_t cdev_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags);
+ int cdev_ioctl(struct cdev *cdev, int cmd, void *buf);
+-int cdev_erase(struct cdev *cdev, size_t count, unsigned long offset);
++int cdev_erase(struct cdev *cdev, size_t count, loff_t offset);
+
+ #define DEVFS_PARTITION_FIXED (1 << 0)
+ #define DEVFS_PARTITION_READONLY (1 << 1)
+ #define DEVFS_IS_PARTITION (1 << 2)
++#define DEVFS_IS_CHARACTER_DEV (1 << 3)
+
+-int devfs_add_partition(const char *devname, unsigned long offset, size_t size,
++int devfs_add_partition(const char *devname, loff_t offset, loff_t size,
+ int flags, const char *name);
+ int devfs_del_partition(const char *name);
+
+diff --git a/include/envfs.h b/include/envfs.h
+index 67b8902..ba976d6 100644
+--- a/include/envfs.h
++++ b/include/envfs.h
+@@ -34,11 +34,25 @@ struct envfs_super {
+ uint32_t sb_crc; /* crc for the superblock */
+ };
+
+-#ifndef __BYTE_ORDER
+-#error "No byte order defined in __BYTE_ORDER"
++#ifdef __BAREBOX__
++# ifdef __LITTLE_ENDIAN
++# define ENVFS_ORDER_LITTLE
++# elif defined __BIG_ENDIAN
++# define ENVFS_ORDER_BIG
++# else
++# error "could not determine byte order"
++# endif
++#else
++# if __BYTE_ORDER == __LITTLE_ENDIAN
++# define ENVFS_ORDER_LITTLE
++# elif __BYTE_ORDER == __BIG_ENDIAN
++# define ENVFS_ORDER_BIG
++# else
++# error "could not determine byte order"
++# endif
+ #endif
+
+-#if __BYTE_ORDER == __LITTLE_ENDIAN
++#ifdef ENVFS_ORDER_LITTLE
+ #define ENVFS_16(x) (x)
+ #define ENVFS_24(x) (x)
+ #define ENVFS_32(x) (x)
+@@ -46,7 +60,7 @@ struct envfs_super {
+ #define ENVFS_GET_OFFSET(x) ((x)->offset)
+ #define ENVFS_SET_OFFSET(x,y) ((x)->offset = (y))
+ #define ENVFS_SET_NAMELEN(x,y) ((x)->namelen = (y))
+-#elif __BYTE_ORDER == __BIG_ENDIAN
++#elif defined ENVFS_ORDER_BIG
+ #ifdef __KERNEL__
+ #define ENVFS_16(x) swab16(x)
+ #define ENVFS_24(x) ((swab32(x)) >> 8)
+diff --git a/include/fs.h b/include/fs.h
+index d82f026..c0b9f71 100644
+--- a/include/fs.h
++++ b/include/fs.h
+@@ -23,8 +23,9 @@ typedef struct dir {
+
+ typedef struct filep {
+ struct device_d *dev; /* The device this FILE belongs to */
+- ulong pos; /* current position in stream */
+- ulong size; /* The size of this inode */
++ loff_t pos; /* current position in stream */
++#define FILE_SIZE_STREAM ((loff_t) -1)
++ loff_t size; /* The size of this inode */
+ ulong flags; /* the O_* flags from open */
+
+ void *inode; /* private to the filesystem driver */
+@@ -54,7 +55,7 @@ struct fs_driver_d {
+ int (*read)(struct device_d *dev, FILE *f, void *buf, size_t size);
+ int (*write)(struct device_d *dev, FILE *f, const void *buf, size_t size);
+ int (*flush)(struct device_d *dev, FILE *f);
+- off_t (*lseek)(struct device_d *dev, FILE *f, off_t pos);
++ loff_t (*lseek)(struct device_d *dev, FILE *f, loff_t pos);
+
+ struct dir* (*opendir)(struct device_d *dev, const char *pathname);
+ struct dirent* (*readdir)(struct device_d *dev, struct dir *dir);
+@@ -63,9 +64,9 @@ struct fs_driver_d {
+
+ int (*ioctl)(struct device_d *dev, FILE *f, int request, void *buf);
+ int (*erase)(struct device_d *dev, FILE *f, size_t count,
+- unsigned long offset);
++ loff_t offset);
+ int (*protect)(struct device_d *dev, FILE *f, size_t count,
+- unsigned long offset, int prot);
++ loff_t offset, int prot);
+
+ int (*memmap)(struct device_d *dev, FILE *f, void **map, int flags);
+
+@@ -109,7 +110,7 @@ ssize_t write(int fd, const void *buf, size_t count);
+ #define SEEK_CUR 2
+ #define SEEK_END 3
+
+-off_t lseek(int fildes, off_t offset, int whence);
++loff_t lseek(int fildes, loff_t offset, int whence);
+ int mkdir (const char *pathname, mode_t mode);
+
+ /* Create a directory and its parents */
+diff --git a/include/linux/byteorder/generic.h b/include/linux/byteorder/generic.h
+index aab8f4b..2d68d99 100644
+--- a/include/linux/byteorder/generic.h
++++ b/include/linux/byteorder/generic.h
+@@ -78,13 +78,6 @@
+ *
+ */
+
+-#ifndef __LITTLE_ENDIAN
+-#define __LITTLE_ENDIAN 1234
+-#endif
+-#ifndef __BIG_ENDIAN
+-#define __BIG_ENDIAN 4321
+-#endif
+-
+ #if defined(__KERNEL__)
+ /*
+ * inside the kernel, we can use nicknames;
+diff --git a/include/linux/compiler.h b/include/linux/compiler.h
+index 5be3dab..cc8c4de 100644
+--- a/include/linux/compiler.h
++++ b/include/linux/compiler.h
+@@ -4,7 +4,7 @@
+ #ifndef __ASSEMBLY__
+
+ #ifdef __CHECKER__
+-# define __user __attribute__((noderef, address_space(1)))
++# define __user /* no user address space in barebox */
+ # define __kernel /* default address space */
+ # define __safe __attribute__((safe))
+ # define __force __attribute__((force))
+diff --git a/include/linux/ioport.h b/include/linux/ioport.h
+index 3f95ddd..6d6cd68 100644
+--- a/include/linux/ioport.h
++++ b/include/linux/ioport.h
+@@ -17,7 +17,7 @@
+ */
+ struct resource {
+ resource_size_t start;
+- resource_size_t size;
++ resource_size_t end;
+ const char *name;
+ unsigned long flags;
+ struct resource *parent;
+@@ -113,7 +113,7 @@ struct resource {
+
+ static inline resource_size_t resource_size(const struct resource *res)
+ {
+- return res->size;
++ return res->end - res->start + 1;
+ }
+ static inline unsigned long resource_type(const struct resource *res)
+ {
+@@ -121,10 +121,10 @@ static inline unsigned long resource_type(const struct resource *res)
+ }
+
+ struct resource *request_iomem_region(const char *name,
+- resource_size_t start, resource_size_t size);
++ resource_size_t start, resource_size_t end);
+
+ struct resource *request_region(struct resource *parent,
+- const char *name, resource_size_t start,
++ const char *name, resource_size_t end,
+ resource_size_t size);
+
+ int release_region(struct resource *res);
+diff --git a/include/linux/stat.h b/include/linux/stat.h
+index bc7dce4..af022c5 100644
+--- a/include/linux/stat.h
++++ b/include/linux/stat.h
+@@ -52,7 +52,7 @@ struct stat {
+ unsigned short st_gid;
+ unsigned short st_rdev;
+ unsigned short __pad2;
+- unsigned long st_size;
++ loff_t st_size;
+ unsigned long st_blksize;
+ unsigned long st_blocks;
+ unsigned long st_atime;
+diff --git a/include/linux/time.h b/include/linux/time.h
+index bf12b99..3942e82 100644
+--- a/include/linux/time.h
++++ b/include/linux/time.h
+@@ -3,156 +3,6 @@
+
+ #include <linux/types.h>
+
+-#define _DEFUN(a,b,c) a(c)
+-#define _CONST const
+-#define _AND ,
+-
+-#define _REENT_ONLY
+-
+-#define SECSPERMIN 60L
+-#define MINSPERHOUR 60L
+-#define HOURSPERDAY 24L
+-#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
+-#define SECSPERDAY (SECSPERHOUR * HOURSPERDAY)
+-#define DAYSPERWEEK 7
+-#define MONSPERYEAR 12
+-
+-#define YEAR_BASE 1900
+-#define EPOCH_YEAR 1970
+-#define EPOCH_WDAY 4
+-
+-#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+-
+-
+-/* Used by other time functions. */
+-struct tm {
+- int tm_sec; /* Seconds. [0-60] (1 leap second) */
+- int tm_min; /* Minutes. [0-59] */
+- int tm_hour; /* Hours. [0-23] */
+- int tm_mday; /* Day. [1-31] */
+- int tm_mon; /* Month. [0-11] */
+- int tm_year; /* Year - 1900. */
+- int tm_wday; /* Day of week. [0-6] */
+- int tm_yday; /* Days in year.[0-365] */
+- int tm_isdst; /* DST. [-1/0/1]*/
+-
+-# ifdef __USE_BSD
+- long int tm_gmtoff; /* Seconds east of UTC. */
+- __const char *tm_zone; /* Timezone abbreviation. */
+-# else
+- long int __tm_gmtoff; /* Seconds east of UTC. */
+- __const char *__tm_zone; /* Timezone abbreviation. */
+-# endif
+-};
+-
+-static inline char *
+-_DEFUN (asctime_r, (tim_p, result),
+- _CONST struct tm *tim_p _AND
+- char *result)
+-{
+- static _CONST char day_name[7][3] = {
+- "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+- };
+- static _CONST char mon_name[12][3] = {
+- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+- };
+-
+- sprintf (result, "%.3s %.3s %.2d %.2d:%.2d:%.2d %d\n",
+- day_name[tim_p->tm_wday],
+- mon_name[tim_p->tm_mon],
+- tim_p->tm_mday, tim_p->tm_hour, tim_p->tm_min,
+- tim_p->tm_sec, 1900 + tim_p->tm_year);
+- return result;
+-}
+-
+-static inline struct tm *
+-_DEFUN (localtime_r, (tim_p, res),
+- _CONST time_t * tim_p _AND
+- struct tm *res)
+-{
+- static _CONST int mon_lengths[2][MONSPERYEAR] = {
+- {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+- {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
+- } ;
+-
+- static _CONST int year_lengths[2] = {
+- 365,
+- 366
+- } ;
+-
+- long days, rem;
+- int y;
+- int yleap;
+- _CONST int *ip;
+-
+- days = ((long) *tim_p) / SECSPERDAY;
+- rem = ((long) *tim_p) % SECSPERDAY;
+- while (rem < 0)
+- {
+- rem += SECSPERDAY;
+- --days;
+- }
+- while (rem >= SECSPERDAY)
+- {
+- rem -= SECSPERDAY;
+- ++days;
+- }
+-
+- /* compute hour, min, and sec */
+- res->tm_hour = (int) (rem / SECSPERHOUR);
+- rem %= SECSPERHOUR;
+- res->tm_min = (int) (rem / SECSPERMIN);
+- res->tm_sec = (int) (rem % SECSPERMIN);
+-
+- /* compute day of week */
+- if ((res->tm_wday = ((EPOCH_WDAY + days) % DAYSPERWEEK)) < 0)
+- res->tm_wday += DAYSPERWEEK;
+-
+- /* compute year & day of year */
+- y = EPOCH_YEAR;
+- if (days >= 0)
+- {
+- for (;;)
+- {
+- yleap = isleap(y);
+- if (days < year_lengths[yleap])
+- break;
+- y++;
+- days -= year_lengths[yleap];
+- }
+- }
+- else
+- {
+- do
+- {
+- --y;
+- yleap = isleap(y);
+- days += year_lengths[yleap];
+- } while (days < 0);
+- }
+-
+- res->tm_year = y - YEAR_BASE;
+- res->tm_yday = days;
+- ip = mon_lengths[yleap];
+- for (res->tm_mon = 0; days >= ip[res->tm_mon]; ++res->tm_mon)
+- days -= ip[res->tm_mon];
+- res->tm_mday = days + 1;
+-
+- /* set daylight saving time flag */
+- res->tm_isdst = -1;
+-
+- return (res);
+-}
+-
+-static inline char *
+-_DEFUN (ctime_r, (tim_p, result),
+- _CONST time_t * tim_p _AND
+- char * result)
+-
+-{
+- struct tm tm;
+- return asctime_r (localtime_r (tim_p, &tm), result);
+-}
++#define NSEC_PER_SEC 1000000000L
+
+ #endif
+diff --git a/include/menu.h b/include/menu.h
+index 74abcfb..40f8eab 100644
+--- a/include/menu.h
++++ b/include/menu.h
+@@ -60,9 +60,6 @@ struct menu {
+ struct list_head entries;
+
+ int nb_entries;
+- int width;
+- char *display_buffer;
+- int display_buffer_size;
+
+ struct menu_entry *selected;
+ void *priv;
+diff --git a/include/miidev.h b/include/miidev.h
+index 622784f..4bbf94c 100644
+--- a/include/miidev.h
++++ b/include/miidev.h
+@@ -31,6 +31,8 @@
+ #define MIIDEV_FORCE_10 (1 << 0)
+ #define MIIDEV_FORCE_LINK (1 << 1)
+
++#define MIIDEV_CAPABLE_1000M (1 << 0)
++
+ struct mii_device {
+ struct device_d dev;
+ struct device_d *parent;
+@@ -40,6 +42,7 @@ struct mii_device {
+ int (*write) (struct mii_device *dev, int addr, int reg, int value);
+
+ int flags;
++ int capabilities;
+
+ struct eth_device *edev;
+ struct cdev cdev;
+@@ -55,6 +58,7 @@ int miidev_get_status(struct mii_device *mdev);
+ #define MIIDEV_STATUS_IS_FULL_DUPLEX (1 << 1)
+ #define MIIDEV_STATUS_IS_10MBIT (1 << 2)
+ #define MIIDEV_STATUS_IS_100MBIT (1 << 3)
++#define MIIDEV_STATUS_IS_1000MBIT (1 << 4)
+ int miidev_print_status(struct mii_device *mdev);
+
+ static int inline mii_write(struct mii_device *dev, int addr, int reg, int value)
+diff --git a/include/net.h b/include/net.h
+index 08f897e..9152943 100644
+--- a/include/net.h
++++ b/include/net.h
+@@ -38,8 +38,8 @@ struct eth_device {
+ int (*send) (struct eth_device*, void *packet, int length);
+ int (*recv) (struct eth_device*);
+ void (*halt) (struct eth_device*);
+- int (*get_ethaddr) (struct eth_device*, unsigned char *adr);
+- int (*set_ethaddr) (struct eth_device*, unsigned char *adr);
++ int (*get_ethaddr) (struct eth_device*, u8 adr[6]);
++ int (*set_ethaddr) (struct eth_device*, u8 adr[6]);
+
+ struct eth_device *next;
+ void *priv;
+@@ -287,8 +287,8 @@ int string_to_ip(const char *s, IPaddr_t *ip);
+ IPaddr_t getenv_ip(const char *name);
+ int setenv_ip(const char *name, IPaddr_t ip);
+
+-int string_to_ethaddr(const char *str, char *enetaddr);
+-void ethaddr_to_string(const unsigned char *enetaddr, char *str);
++int string_to_ethaddr(const char *str, u8 enetaddr[6]);
++void ethaddr_to_string(const u8 enetaddr[6], char *str);
+
+ #ifdef CONFIG_NET_RESOLV
+ IPaddr_t resolv(char *host);
+diff --git a/include/net/designware.h b/include/net/designware.h
+new file mode 100644
+index 0000000..3f9f5b9
+--- /dev/null
++++ b/include/net/designware.h
+@@ -0,0 +1,9 @@
++#ifndef __DWC_UNIMAC_H
++#define __DWC_UNIMAC_H
++
++struct dwc_ether_platform_data {
++ u8 phy_addr;
++ void (*fix_mac_speed)(int speed);
++};
++
++#endif
+diff --git a/include/partition.h b/include/partition.h
+index 0827bb4..8ad7490 100644
+--- a/include/partition.h
++++ b/include/partition.h
+@@ -8,7 +8,7 @@ struct partition {
+
+ int flags;
+
+- unsigned long offset;
++ loff_t offset;
+
+ struct device_d *physdev;
+ struct device_d device;
+diff --git a/include/qsort.h b/include/qsort.h
+index bbb2359..d279dc2 100644
+--- a/include/qsort.h
++++ b/include/qsort.h
+@@ -4,4 +4,6 @@
+ void qsort(void *base, size_t nel, size_t width,
+ int (*comp)(const void *, const void *));
+
++int strcmp_compar(const void *p1, const void *p2);
++
+ #endif /* __QSORT_H */
+diff --git a/include/usb/usb.h b/include/usb/usb.h
+index 296e4e8..19b092e 100644
+--- a/include/usb/usb.h
++++ b/include/usb/usb.h
+@@ -159,8 +159,9 @@ struct usb_device {
+ int epmaxpacketout[16]; /* OUTput endpoint specific maximums */
+
+ int configno; /* selected config number */
+- struct usb_device_descriptor descriptor; /* Device Descriptor */
++ struct usb_device_descriptor *descriptor; /* Device Descriptor */
+ struct usb_config_descriptor config; /* config descriptor */
++ struct devrequest *setup_packet;
+
+ int have_langid; /* whether string_langid is valid yet */
+ int string_langid; /* language ID for strings */
+@@ -270,12 +271,14 @@ void usb_rescan(void);
+ ((x_ & 0xFF000000UL) >> 24)); \
+ })
+
+-#if __BYTE_ORDER == __LITTLE_ENDIAN
++#ifdef __LITTLE_ENDIAN
+ # define swap_16(x) (x)
+ # define swap_32(x) (x)
+-#else
++#elif defined BIG_ENDIAN
+ # define swap_16(x) __swap_16(x)
+ # define swap_32(x) __swap_32(x)
++#else
++#error "could not determine byte order"
+ #endif
+
+ /*
+diff --git a/include/watchdog.h b/include/watchdog.h
+new file mode 100644
+index 0000000..3e2d08e
+--- /dev/null
++++ b/include/watchdog.h
+@@ -0,0 +1,24 @@
++/*
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef INCLUDE_WATCHDOG_H
++# define INCLUDE_WATCHDOG_H
++
++struct watchdog {
++ int (*set_timeout)(struct watchdog *, unsigned);
++};
++
++int watchdog_register(struct watchdog *);
++int watchdog_deregister(struct watchdog *);
++int watchdog_set_timeout(unsigned);
++
++#endif /* INCLUDE_WATCHDOG_H */
+diff --git a/lib/misc.c b/lib/misc.c
+index 549b960..8a95396 100644
+--- a/lib/misc.c
++++ b/lib/misc.c
+@@ -27,15 +27,15 @@
+ #include <linux/ctype.h>
+
+ /*
+- * Like simple_strtoul() but handles an optional G, M, K or k
++ * Like simple_strtoull() but handles an optional G, M, K or k
+ * suffix for Gigabyte, Megabyte or Kilobyte
+ */
+-unsigned long strtoul_suffix(const char *str, char **endp, int base)
++unsigned long long strtoull_suffix(const char *str, char **endp, int base)
+ {
+- unsigned long val;
++ unsigned long long val;
+ char *end;
+
+- val = simple_strtoul(str, &end, base);
++ val = simple_strtoull(str, &end, base);
+
+ switch (*end) {
+ case 'G':
+@@ -55,6 +55,12 @@ unsigned long strtoul_suffix(const char *str, char **endp, int base)
+
+ return val;
+ }
++EXPORT_SYMBOL(strtoull_suffix);
++
++unsigned long strtoul_suffix(const char *str, char **endp, int base)
++{
++ return strtoull_suffix(str, endp, base);
++}
+ EXPORT_SYMBOL(strtoul_suffix);
+
+ /*
+@@ -69,15 +75,15 @@ EXPORT_SYMBOL(strtoul_suffix);
+ * 0x1000 -> start = 0x1000, size = ~0
+ * 1M+1k -> start = 0x100000, size = 0x400
+ */
+-int parse_area_spec(const char *str, ulong *start, ulong *size)
++int parse_area_spec(const char *str, loff_t *start, loff_t *size)
+ {
+ char *endp;
+- ulong end;
++ loff_t end;
+
+ if (!isdigit(*str))
+ return -1;
+
+- *start = strtoul_suffix(str, &endp, 0);
++ *start = strtoull_suffix(str, &endp, 0);
+
+ str = endp;
+
+@@ -89,7 +95,7 @@ int parse_area_spec(const char *str, ulong *start, ulong *size)
+
+ if (*str == '-') {
+ /* beginning and end given */
+- end = strtoul_suffix(str + 1, NULL, 0);
++ end = strtoull_suffix(str + 1, NULL, 0);
+ if (end < *start) {
+ printf("end < start\n");
+ return -1;
+@@ -100,7 +106,7 @@ int parse_area_spec(const char *str, ulong *start, ulong *size)
+
+ if (*str == '+') {
+ /* beginning and size given */
+- *size = strtoul_suffix(str + 1, NULL, 0);
++ *size = strtoull_suffix(str + 1, NULL, 0);
+ return 0;
+ }
+
+diff --git a/lib/vsprintf.c b/lib/vsprintf.c
+index 9763515..17c1973 100644
+--- a/lib/vsprintf.c
++++ b/lib/vsprintf.c
+@@ -83,6 +83,7 @@ unsigned long long simple_strtoull (const char *cp, char **endp, unsigned int ba
+ *endp = (char *) cp;
+ return result;
+ }
++EXPORT_SYMBOL(simple_strtoll);
+
+ /* we use this so that we can do without the ctype library */
+ #define is_digit(c) ((c) >= '0' && (c) <= '9')
+diff --git a/net/eth.c b/net/eth.c
+index 2b492ad..c034eaa 100644
+--- a/net/eth.c
++++ b/net/eth.c
+@@ -100,11 +100,9 @@ struct eth_device * eth_get_current(void)
+ struct eth_device *eth_get_byname(char *ethname)
+ {
+ struct eth_device *edev;
+- char name[MAX_DRIVER_NAME];
+
+ list_for_each_entry(edev, &netdev_list, list) {
+- sprintf(name, "%s%d", edev->dev.name, edev->dev.id);
+- if (!strcmp(ethname, name))
++ if (!strcmp(ethname, dev_name(&edev->dev)))
+ return edev;
+ }
+ return NULL;
+@@ -169,7 +167,7 @@ int eth_rx(void)
+ static int eth_set_ethaddr(struct device_d *dev, struct param_d *param, const char *val)
+ {
+ struct eth_device *edev = dev_to_edev(dev);
+- char ethaddr[sizeof("xx:xx:xx:xx:xx:xx")];
++ u8 ethaddr[6];
+
+ if (!val)
+ return dev_param_set_generic(dev, param, NULL);
+diff --git a/net/net.c b/net/net.c
+index c803c48..54d8c25 100644
+--- a/net/net.c
++++ b/net/net.c
+@@ -159,7 +159,7 @@ void print_IPaddr (IPaddr_t x)
+ puts(ip_to_string(x));
+ }
+
+-int string_to_ethaddr(const char *str, char *enetaddr)
++int string_to_ethaddr(const char *str, u8 enetaddr[6])
+ {
+ int reg;
+ char *e;
+@@ -181,7 +181,7 @@ int string_to_ethaddr(const char *str, char *enetaddr)
+ return 0;
+ }
+
+-void ethaddr_to_string(const unsigned char *enetaddr, char *str)
++void ethaddr_to_string(const u8 enetaddr[6], char *str)
+ {
+ sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X",
+ enetaddr[0], enetaddr[1], enetaddr[2], enetaddr[3],
diff --git a/configs/platform-ti/patches/barebox-2012.07.0/0001-WIP-beaglebone-add-support-for-AM335x-and-board.patch b/configs/platform-ti/patches/barebox-2012.07.0/0001-WIP-beaglebone-add-support-for-AM335x-and-board.patch
new file mode 100644
index 0000000..4959538
--- /dev/null
+++ b/configs/platform-ti/patches/barebox-2012.07.0/0001-WIP-beaglebone-add-support-for-AM335x-and-board.patch
@@ -0,0 +1,3688 @@
+From 0513a2da4d48ed0c573384335f7f2ff71b44422d Mon Sep 17 00:00:00 2001
+From: Jan Luebbe <jluebbe@debian.org>
+Date: Sat, 23 Jun 2012 21:39:36 +0200
+Subject: [PATCH] WIP beaglebone: add support for AM335x and board
+
+Signed-off-by: Jan Luebbe <jluebbe@debian.org>
+---
+ Makefile | 5 +
+ arch/arm/Makefile | 1 +
+ arch/arm/boards/beaglebone/Makefile | 1 +
+ arch/arm/boards/beaglebone/board.c | 509 ++++++++++++++
+ arch/arm/boards/beaglebone/clock.h | 36 +
+ arch/arm/boards/beaglebone/clocks_am335x.h | 65 ++
+ arch/arm/boards/beaglebone/clocks_ti814x.h | 72 ++
+ arch/arm/boards/beaglebone/clocks_ti816x.h | 162 +++++
+ arch/arm/boards/beaglebone/common_def.h | 48 ++
+ arch/arm/boards/beaglebone/config.h | 24 +
+ arch/arm/boards/beaglebone/cpu.h | 726 ++++++++++++++++++++
+ arch/arm/boards/beaglebone/ddr_defs.h | 362 ++++++++++
+ arch/arm/boards/beaglebone/env/boot/sd | 16 +
+ arch/arm/boards/beaglebone/env/init/bootargs-base | 8 +
+ arch/arm/boards/beaglebone/env/init/general | 18 +
+ arch/arm/boards/beaglebone/hardware.h | 117 ++++
+ arch/arm/boards/beaglebone/mux.c | 707 +++++++++++++++++++
+ arch/arm/boards/beaglebone/pll.c | 293 ++++++++
+ arch/arm/configs/am335x_beaglebone_defconfig | 58 ++
+ .../configs/am335x_beaglebone_mlo_large_defconfig | 50 ++
+ .../configs/am335x_beaglebone_mlo_small_defconfig | 32 +
+ arch/arm/cpu/start.c | 14 +-
+ arch/arm/mach-omap/Kconfig | 11 +-
+ arch/arm/mach-omap/omap3_generic.c | 2 +
+ arch/arm/mach-omap/s32k_clksource.c | 5 +-
+ arch/arm/mach-omap/xload.c | 5 +-
+ common/startup.c | 5 +
+ 27 files changed, 3348 insertions(+), 4 deletions(-)
+ create mode 100644 arch/arm/boards/beaglebone/Makefile
+ create mode 100644 arch/arm/boards/beaglebone/board.c
+ create mode 100644 arch/arm/boards/beaglebone/clock.h
+ create mode 100644 arch/arm/boards/beaglebone/clocks_am335x.h
+ create mode 100644 arch/arm/boards/beaglebone/clocks_ti814x.h
+ create mode 100644 arch/arm/boards/beaglebone/clocks_ti816x.h
+ create mode 100644 arch/arm/boards/beaglebone/common_def.h
+ create mode 100644 arch/arm/boards/beaglebone/config.h
+ create mode 100644 arch/arm/boards/beaglebone/cpu.h
+ create mode 100644 arch/arm/boards/beaglebone/ddr_defs.h
+ create mode 100644 arch/arm/boards/beaglebone/env/boot/sd
+ create mode 100644 arch/arm/boards/beaglebone/env/init/bootargs-base
+ create mode 100644 arch/arm/boards/beaglebone/env/init/general
+ create mode 100644 arch/arm/boards/beaglebone/hardware.h
+ create mode 100644 arch/arm/boards/beaglebone/mux.c
+ create mode 100644 arch/arm/boards/beaglebone/pll.c
+ create mode 100644 arch/arm/configs/am335x_beaglebone_defconfig
+ create mode 100644 arch/arm/configs/am335x_beaglebone_mlo_large_defconfig
+ create mode 100644 arch/arm/configs/am335x_beaglebone_mlo_small_defconfig
+
+diff --git a/Makefile b/Makefile
+index ebcf9bf..8355da3 100644
+--- a/Makefile
++++ b/Makefile
+@@ -672,6 +672,11 @@ barebox.bin: barebox FORCE
+ $(call if_changed,objcopy)
+ $(call cmd,check_file_size,$(CONFIG_BAREBOX_MAX_IMAGE_SIZE))
+
++barebox.img: barebox.bin
++ $(srctree)/scripts/mkimage -A $(ARCH) -T firmware -C none \
++ -O barebox -a $(CONFIG_TEXT_BASE) -e $(CONFIG_TEXT_BASE) \
++ -n "barebox $(KERNELRELEASE)" -d $< $@
++
+ ifdef CONFIG_X86
+ barebox.S: barebox
+ ifdef CONFIG_X86_HDBOOT
+diff --git a/arch/arm/Makefile b/arch/arm/Makefile
+index 1225df7..92f5ef7 100644
+--- a/arch/arm/Makefile
++++ b/arch/arm/Makefile
+@@ -99,6 +99,7 @@ board-$(CONFIG_MACH_NOMADIK_8815NHK) := nhk8815
+ board-$(CONFIG_MACH_NXDB500) := netx
+ board-$(CONFIG_MACH_OMAP343xSDP) := omap343xdsp
+ board-$(CONFIG_MACH_BEAGLE) := beagle
++board-$(CONFIG_MACH_BEAGLEBONE) := beaglebone
+ board-$(CONFIG_MACH_OMAP3EVM) := omap3evm
+ board-$(CONFIG_MACH_PANDA) := panda
+ board-$(CONFIG_MACH_PCM049) := pcm049
+diff --git a/arch/arm/boards/beaglebone/Makefile b/arch/arm/boards/beaglebone/Makefile
+new file mode 100644
+index 0000000..529eb26
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/Makefile
+@@ -0,0 +1 @@
++obj-y += board.o mux.o pll.o
+diff --git a/arch/arm/boards/beaglebone/board.c b/arch/arm/boards/beaglebone/board.c
+new file mode 100644
+index 0000000..ca94060
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/board.c
+@@ -0,0 +1,509 @@
++/*
++ * (C) Copyright 2008
++ * Texas Instruments, <www.ti.com>
++ * Raghavendra KH <r-khandenahally@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++/**
++ * @file
++ * @brief Beagle Specific Board Initialization routines
++ */
++
++/**
++ * @page ti_beagle Texas Instruments Beagle Board
++ *
++ * FileName: arch/arm/boards/omap/board-beagle.c
++ *
++ * Beagle Board from Texas Instruments as described here:
++ * http://www.beagleboard.org
++ *
++ * This board is based on OMAP3530.
++ * More on OMAP3530 (including documentation can be found here):
++ * http://focus.ti.com/docs/prod/folders/print/omap3530.html
++ *
++ * This file provides initialization in two stages:
++ * @li boot time initialization - do basics required to get SDRAM working.
++ * This is run from SRAM - so no case constructs and global vars can be used.
++ * @li run time initialization - this is for the rest of the initializations
++ * such as flash, uart etc.
++ *
++ * Boot time initialization includes:
++ * @li SDRAM initialization.
++ * @li Pin Muxing relevant for Beagle.
++ *
++ * Run time initialization includes
++ * @li serial @ref serial_ns16550.c driver device definition
++ *
++ * Originally from arch/arm/boards/omap/board-sdp343x.c
++ */
++
++#include <common.h>
++#include <console.h>
++#include <init.h>
++#include <driver.h>
++#include <fs.h>
++#include <linux/stat.h>
++#include <environment.h>
++#include <sizes.h>
++#include <io.h>
++#include <ns16550.h>
++#include <asm/armlinux.h>
++#include <generated/mach-types.h>
++#include <mach/silicon.h>
++#include <mach/sdrc.h>
++#include <mach/sys_info.h>
++#include <mach/syslib.h>
++#include <mach/control.h>
++#include <mach/omap3-mux.h>
++#include <mach/gpmc.h>
++#include <mach/ehci.h>
++#include <i2c/i2c.h>
++#include <linux/err.h>
++#include <usb/ehci.h>
++#include <mach/xload.h>
++
++#include "config.h"
++#include "common_def.h"
++#include "cpu.h"
++#include "ddr_defs.h"
++
++/* from U-Boot's board/ti/am335x/evm.c */
++
++/* UART Defines */
++#define UART_SYSCFG_OFFSET (0x54)
++#define UART_SYSSTS_OFFSET (0x58)
++
++#define UART_RESET (0x1 << 1)
++#define UART_CLK_RUNNING_MASK 0x1
++#define UART_SMART_IDLE_EN (0x1 << 0x3)
++
++static void Data_Macro_Config(int dataMacroNum)
++{
++ u32 BaseAddrOffset = 0x00;;
++
++ if (dataMacroNum == 1)
++ BaseAddrOffset = 0xA4;
++
++ __raw_writel(((DDR2_RD_DQS<<30)|(DDR2_RD_DQS<<20)
++ |(DDR2_RD_DQS<<10)|(DDR2_RD_DQS<<0)),
++ (DATA0_RD_DQS_SLAVE_RATIO_0 + BaseAddrOffset));
++ __raw_writel(DDR2_RD_DQS>>2,
++ (DATA0_RD_DQS_SLAVE_RATIO_1 + BaseAddrOffset));
++ __raw_writel(((DDR2_WR_DQS<<30)|(DDR2_WR_DQS<<20)
++ |(DDR2_WR_DQS<<10)|(DDR2_WR_DQS<<0)),
++ (DATA0_WR_DQS_SLAVE_RATIO_0 + BaseAddrOffset));
++ __raw_writel(DDR2_WR_DQS>>2,
++ (DATA0_WR_DQS_SLAVE_RATIO_1 + BaseAddrOffset));
++ __raw_writel(((DDR2_PHY_WRLVL<<30)|(DDR2_PHY_WRLVL<<20)
++ |(DDR2_PHY_WRLVL<<10)|(DDR2_PHY_WRLVL<<0)),
++ (DATA0_WRLVL_INIT_RATIO_0 + BaseAddrOffset));
++ __raw_writel(DDR2_PHY_WRLVL>>2,
++ (DATA0_WRLVL_INIT_RATIO_1 + BaseAddrOffset));
++ __raw_writel(((DDR2_PHY_GATELVL<<30)|(DDR2_PHY_GATELVL<<20)
++ |(DDR2_PHY_GATELVL<<10)|(DDR2_PHY_GATELVL<<0)),
++ (DATA0_GATELVL_INIT_RATIO_0 + BaseAddrOffset));
++ __raw_writel(DDR2_PHY_GATELVL>>2,
++ (DATA0_GATELVL_INIT_RATIO_1 + BaseAddrOffset));
++ __raw_writel(((DDR2_PHY_FIFO_WE<<30)|(DDR2_PHY_FIFO_WE<<20)
++ |(DDR2_PHY_FIFO_WE<<10)|(DDR2_PHY_FIFO_WE<<0)),
++ (DATA0_FIFO_WE_SLAVE_RATIO_0 + BaseAddrOffset));
++ __raw_writel(DDR2_PHY_FIFO_WE>>2,
++ (DATA0_FIFO_WE_SLAVE_RATIO_1 + BaseAddrOffset));
++ __raw_writel(((DDR2_PHY_WR_DATA<<30)|(DDR2_PHY_WR_DATA<<20)
++ |(DDR2_PHY_WR_DATA<<10)|(DDR2_PHY_WR_DATA<<0)),
++ (DATA0_WR_DATA_SLAVE_RATIO_0 + BaseAddrOffset));
++ __raw_writel(DDR2_PHY_WR_DATA>>2,
++ (DATA0_WR_DATA_SLAVE_RATIO_1 + BaseAddrOffset));
++ __raw_writel(PHY_DLL_LOCK_DIFF,
++ (DATA0_DLL_LOCK_DIFF_0 + BaseAddrOffset));
++}
++
++static void Cmd_Macro_Config(void)
++{
++ __raw_writel(DDR2_RATIO, CMD0_CTRL_SLAVE_RATIO_0);
++ __raw_writel(CMD_FORCE, CMD0_CTRL_SLAVE_FORCE_0);
++ __raw_writel(CMD_DELAY, CMD0_CTRL_SLAVE_DELAY_0);
++ __raw_writel(DDR2_DLL_LOCK_DIFF, CMD0_DLL_LOCK_DIFF_0);
++ __raw_writel(DDR2_INVERT_CLKOUT, CMD0_INVERT_CLKOUT_0);
++
++ __raw_writel(DDR2_RATIO, CMD1_CTRL_SLAVE_RATIO_0);
++ __raw_writel(CMD_FORCE, CMD1_CTRL_SLAVE_FORCE_0);
++ __raw_writel(CMD_DELAY, CMD1_CTRL_SLAVE_DELAY_0);
++ __raw_writel(DDR2_DLL_LOCK_DIFF, CMD1_DLL_LOCK_DIFF_0);
++ __raw_writel(DDR2_INVERT_CLKOUT, CMD1_INVERT_CLKOUT_0);
++
++ __raw_writel(DDR2_RATIO, CMD2_CTRL_SLAVE_RATIO_0);
++ __raw_writel(CMD_FORCE, CMD2_CTRL_SLAVE_FORCE_0);
++ __raw_writel(CMD_DELAY, CMD2_CTRL_SLAVE_DELAY_0);
++ __raw_writel(DDR2_DLL_LOCK_DIFF, CMD2_DLL_LOCK_DIFF_0);
++ __raw_writel(DDR2_INVERT_CLKOUT, CMD2_INVERT_CLKOUT_0);
++}
++
++static void config_vtp(void)
++{
++ __raw_writel(__raw_readl(VTP0_CTRL_REG) | VTP_CTRL_ENABLE,
++ VTP0_CTRL_REG);
++ __raw_writel(__raw_readl(VTP0_CTRL_REG) & (~VTP_CTRL_START_EN),
++ VTP0_CTRL_REG);
++ __raw_writel(__raw_readl(VTP0_CTRL_REG) | VTP_CTRL_START_EN,
++ VTP0_CTRL_REG);
++
++ /* Poll for READY */
++ while ((__raw_readl(VTP0_CTRL_REG) & VTP_CTRL_READY) != VTP_CTRL_READY);
++}
++
++static void config_emif_ddr2(void)
++{
++ u32 i;
++
++ /*Program EMIF0 CFG Registers*/
++ __raw_writel(EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1);
++ __raw_writel(EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1_SHADOW);
++ __raw_writel(EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_2);
++ __raw_writel(EMIF_TIM1, EMIF4_0_SDRAM_TIM_1);
++ __raw_writel(EMIF_TIM1, EMIF4_0_SDRAM_TIM_1_SHADOW);
++ __raw_writel(EMIF_TIM2, EMIF4_0_SDRAM_TIM_2);
++ __raw_writel(EMIF_TIM2, EMIF4_0_SDRAM_TIM_2_SHADOW);
++ __raw_writel(EMIF_TIM3, EMIF4_0_SDRAM_TIM_3);
++ __raw_writel(EMIF_TIM3, EMIF4_0_SDRAM_TIM_3_SHADOW);
++
++ __raw_writel(EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG);
++ __raw_writel(EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG2);
++
++ /* __raw_writel(EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL);
++ __raw_writel(EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL_SHD); */
++ __raw_writel(0x00004650, EMIF4_0_SDRAM_REF_CTRL);
++ __raw_writel(0x00004650, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
++
++ for (i = 0; i < 5000; i++) {
++
++ }
++
++ /* __raw_writel(EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL);
++ __raw_writel(EMIF_SDMGT, EMIF0_0_SDRAM_MGMT_CTRL_SHD); */
++ __raw_writel(EMIF_SDREF, EMIF4_0_SDRAM_REF_CTRL);
++ __raw_writel(EMIF_SDREF, EMIF4_0_SDRAM_REF_CTRL_SHADOW);
++
++ __raw_writel(EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG);
++ __raw_writel(EMIF_SDCFG, EMIF4_0_SDRAM_CONFIG2);
++}
++
++/* void DDR2_EMIF_Config(void); */
++static void config_am335x_ddr(void)
++{
++ int data_macro_0 = 0;
++ int data_macro_1 = 1;
++
++ enable_ddr_clocks();
++
++ config_vtp();
++
++ Cmd_Macro_Config();
++
++ Data_Macro_Config(data_macro_0);
++ Data_Macro_Config(data_macro_1);
++
++ __raw_writel(PHY_RANK0_DELAY, DATA0_RANK0_DELAYS_0);
++ __raw_writel(PHY_RANK0_DELAY, DATA1_RANK0_DELAYS_0);
++
++ __raw_writel(DDR_IOCTRL_VALUE, DDR_CMD0_IOCTRL);
++ __raw_writel(DDR_IOCTRL_VALUE, DDR_CMD1_IOCTRL);
++ __raw_writel(DDR_IOCTRL_VALUE, DDR_CMD2_IOCTRL);
++ __raw_writel(DDR_IOCTRL_VALUE, DDR_DATA0_IOCTRL);
++ __raw_writel(DDR_IOCTRL_VALUE, DDR_DATA1_IOCTRL);
++
++ __raw_writel(__raw_readl(DDR_IO_CTRL) & 0xefffffff, DDR_IO_CTRL);
++ __raw_writel(__raw_readl(DDR_CKE_CTRL) | 0x00000001, DDR_CKE_CTRL);
++
++ config_emif_ddr2();
++}
++
++/**
++ * @brief Do the pin muxing required for Board operation.
++ * We enable ONLY the pins we require to set. OMAP provides pins which do not
++ * have alternate modes. Such pins done need to be set.
++ *
++ * See @ref MUX_VAL for description of the muxing mode.
++ *
++ * @return void
++ */
++static void mux_config(void)
++{
++ /* SDRC_D0 - SDRC_D31 default mux mode is mode0 */
++
++ /* GPMC */
++ MUX_VAL(CP(GPMC_A1), (IDIS | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_A2), (IDIS | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_A3), (IDIS | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_A4), (IDIS | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_A5), (IDIS | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_A6), (IDIS | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_A7), (IDIS | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_A8), (IDIS | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_A9), (IDIS | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_A10), (IDIS | PTD | DIS | M0));
++
++ /* D0-D7 default mux mode is mode0 */
++ MUX_VAL(CP(GPMC_D8), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_D9), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_D10), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_D11), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_D12), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_D13), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_D14), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_D15), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_CLK), (IDIS | PTD | DIS | M0));
++ /* GPMC_NADV_ALE default mux mode is mode0 */
++ /* GPMC_NOE default mux mode is mode0 */
++ /* GPMC_NWE default mux mode is mode0 */
++ /* GPMC_NBE0_CLE default mux mode is mode0 */
++ MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_NBE1), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0));
++ /* GPMC_WAIT0 default mux mode is mode0 */
++ MUX_VAL(CP(GPMC_WAIT1), (IEN | PTU | EN | M0));
++
++ /* SERIAL INTERFACE */
++ MUX_VAL(CP(UART3_CTS_RCTX), (IEN | PTD | EN | M0));
++ MUX_VAL(CP(UART3_RTS_SD), (IDIS | PTD | DIS | M0));
++ MUX_VAL(CP(UART3_RX_IRRX), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(UART3_TX_IRTX), (IDIS | PTD | DIS | M0));
++ MUX_VAL(CP(HSUSB0_CLK), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(HSUSB0_STP), (IDIS | PTU | EN | M0));
++ MUX_VAL(CP(HSUSB0_DIR), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(HSUSB0_NXT), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(HSUSB0_DATA0), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(HSUSB0_DATA1), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(HSUSB0_DATA2), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(HSUSB0_DATA3), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(HSUSB0_DATA4), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(HSUSB0_DATA5), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(HSUSB0_DATA6), (IEN | PTD | DIS | M0));
++ MUX_VAL(CP(HSUSB0_DATA7), (IEN | PTD | DIS | M0));
++ /* I2C1_SCL default mux mode is mode0 */
++ /* I2C1_SDA default mux mode is mode0 */
++ /* USB EHCI (port 2) */
++ MUX_VAL(CP(MCSPI1_CS3), (IEN | PTU | DIS | M3));
++ MUX_VAL(CP(MCSPI2_CLK), (IEN | PTU | DIS | M3));
++ MUX_VAL(CP(MCSPI2_SIMO), (IEN | PTU | DIS | M3));
++ MUX_VAL(CP(MCSPI2_SOMI), (IEN | PTU | DIS | M3));
++ MUX_VAL(CP(MCSPI2_CS0), (IEN | PTU | DIS | M3));
++ MUX_VAL(CP(MCSPI2_CS1), (IEN | PTU | DIS | M3));
++ MUX_VAL(CP(ETK_D10_ES2), (IDIS | PTU | DIS | M3));
++ MUX_VAL(CP(ETK_D11_ES2), (IDIS | PTU | DIS | M3));
++ MUX_VAL(CP(ETK_D12_ES2), (IEN | PTU | DIS | M3));
++ MUX_VAL(CP(ETK_D13_ES2), (IEN | PTU | DIS | M3));
++ MUX_VAL(CP(ETK_D14_ES2), (IEN | PTU | DIS | M3));
++ MUX_VAL(CP(ETK_D15_ES2), (IEN | PTU | DIS | M3));
++ MUX_VAL(CP(UART2_RX), (IEN | PTD | DIS | M4)) /*GPIO_147*/;
++}
++
++
++/*
++ * early system init of muxing and clocks.
++ */
++void s_init(void)
++{
++ u32 regVal, uart_base;
++
++ /* Setup the PLLs and the clocks for the peripherals */
++ pll_init();
++
++ /* UART softreset */
++ uart_base = DEFAULT_UART_BASE;
++
++ enable_uart0_pin_mux();
++
++ regVal = __raw_readl(uart_base + UART_SYSCFG_OFFSET);
++ regVal |= UART_RESET;
++ __raw_writel(regVal, (uart_base + UART_SYSCFG_OFFSET) );
++ while ((__raw_readl(uart_base + UART_SYSSTS_OFFSET) &
++ UART_CLK_RUNNING_MASK) != UART_CLK_RUNNING_MASK);
++
++ /* Disable smart idle */
++ regVal = __raw_readl((uart_base + UART_SYSCFG_OFFSET));
++ regVal |= UART_SMART_IDLE_EN;
++ __raw_writel(regVal, (uart_base + UART_SYSCFG_OFFSET));
++
++ /* Initialize the Timer */
++ //init_timer();
++
++ //preloader_console_init();
++
++ config_am335x_ddr();
++}
++
++
++/**
++ * @brief The basic entry point for board initialization.
++ *
++ * This is called as part of machine init (after arch init).
++ * This is again called with stack in SRAM, so not too many
++ * constructs possible here.
++ *
++ * @return void
++ */
++static int beagle_board_init(void)
++{
++ int in_sdram = running_in_sdram();
++
++ /* Can be removed as A8 comes up with L2 enabled */
++ //l2_cache_enable();
++
++ /* WDT1 is already running when the bootloader gets control
++ * Disable it to avoid "random" resets
++ */
++ writel(0xFEED0075, 0x4030b000);
++ __raw_writel(0xAAAA, WDT_WSPR);
++ while(__raw_readl(WDT_WWPS) != 0x0);
++ __raw_writel(0x5555, WDT_WSPR);
++ while(__raw_readl(WDT_WWPS) != 0x0);
++
++ //omap3_core_init();
++ writel(in_sdram, 0x4030b004);
++ writel(0xFEED0080, 0x4030b000);
++
++ //mux_config();
++ enable_uart0_pin_mux();
++ /* Dont reconfigure SDRAM while running in SDRAM! */
++ if (!in_sdram)
++ s_init();
++
++ writel(0xFEED0090, 0x4030b000);
++ //writel(0xFEED03FF, 0x4030b000); while(1);
++ return 0;
++}
++pure_initcall(beagle_board_init);
++
++/******************** Board Run Time *******************/
++
++#ifdef CONFIG_DRIVER_SERIAL_NS16550
++
++static struct NS16550_plat serial_plat = {
++ .clock = 48000000, /* 48MHz (APLL96/2) */
++ .shift = 2,
++};
++
++/**
++ * @brief UART serial port initialization - remember to enable COM clocks in
++ * arch
++ *
++ * @return result of device registration
++ */
++static int beagle_console_init(void)
++{
++ /* Register the serial port */
++ add_ns16550_device(-1, 0x44e09000, 1024, IORESOURCE_MEM_8BIT,
++ &serial_plat);
++
++ return 0;
++}
++console_initcall(beagle_console_init);
++#endif /* CONFIG_DRIVER_SERIAL_NS16550 */
++
++#ifdef CONFIG_USB_EHCI_OMAP
++static struct omap_hcd omap_ehci_pdata = {
++ .port_mode[0] = EHCI_HCD_OMAP_MODE_PHY,
++ .port_mode[1] = EHCI_HCD_OMAP_MODE_PHY,
++ .port_mode[2] = EHCI_HCD_OMAP_MODE_UNKNOWN,
++ .phy_reset = 1,
++ .reset_gpio_port[0] = -EINVAL,
++ .reset_gpio_port[1] = 147,
++ .reset_gpio_port[2] = -EINVAL
++};
++
++static struct ehci_platform_data ehci_pdata = {
++ .flags = 0,
++};
++#endif /* CONFIG_USB_EHCI_OMAP */
++
++static struct i2c_board_info i2c_devices[] = {
++ {
++ I2C_BOARD_INFO("twl4030", 0x48),
++ },
++};
++
++static int beagle_mem_init(void)
++{
++ arm_add_mem_device("ram0", 0x80000000, 256 * 1024 * 1024);
++
++ return 0;
++}
++mem_initcall(beagle_mem_init);
++
++static int beagle_devices_init(void)
++{
++// i2c_register_board_info(0, i2c_devices, ARRAY_SIZE(i2c_devices));
++// add_generic_device("i2c-omap", DEVICE_ID_DYNAMIC, NULL, OMAP_I2C1_BASE, SZ_4K,
++// IORESOURCE_MEM, NULL);
++
++#ifdef CONFIG_USB_EHCI_OMAP
++// if (ehci_omap_init(&omap_ehci_pdata) >= 0)
++// add_usb_ehci_device(DEVICE_ID_DYNAMIC, OMAP_EHCI_BASE,
++// OMAP_EHCI_BASE + 0x10, &ehci_pdata);
++#endif /* CONFIG_USB_EHCI_OMAP */
++#ifdef CONFIG_OMAP_GPMC
++ /* WP is made high and WAIT1 active Low */
++ //gpmc_generic_init(0x10);
++#endif
++
++ add_generic_device("omap-hsmmc", DEVICE_ID_DYNAMIC, NULL, 0x48060100, SZ_4K,
++ IORESOURCE_MEM, NULL);
++
++ armlinux_set_bootparams((void *)0x80000100);
++ //armlinux_set_architecture(MACH_TYPE_OMAP_GENERIC);
++ armlinux_set_architecture(3589);
++
++ return 0;
++}
++device_initcall(beagle_devices_init);
++
++#ifdef CONFIG_DEFAULT_ENVIRONMENT
++static int beaglebone_env_init(void)
++{
++ struct stat s;
++ char *diskdev = "/dev/disk0.0";
++ int ret;
++
++ ret = stat(diskdev, &s);
++ if (ret) {
++ printf("device %s not found. Using default environment\n", diskdev);
++ return 0;
++ }
++
++ mkdir ("/boot", 0666);
++ ret = mount(diskdev, "fat", "/boot");
++ if (ret) {
++ printf("failed to mount %s\n", diskdev);
++ return 0;
++ }
++
++ default_environment_path = "/boot/barebox.env";
++
++ return 0;
++}
++late_initcall(beaglebone_env_init);
++#endif
++
++void __noreturn reset_cpu(unsigned long addr)
++{
++ writel(PRM_RSTCTRL_RESET, PRM_RSTCTRL);
++
++ while (1);
++}
++EXPORT_SYMBOL(reset_cpu);
+diff --git a/arch/arm/boards/beaglebone/clock.h b/arch/arm/boards/beaglebone/clock.h
+new file mode 100644
+index 0000000..0aeaa5f
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/clock.h
+@@ -0,0 +1,36 @@
++/*
++ * (C) Copyright 2006-2008
++ * Texas Instruments, <www.ti.com>
++ * Richard Woodruff <r-woodruff2@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++#ifndef _CLOCKS_H_
++#define _CLOCKS_H_
++
++#ifdef CONFIG_TI816X
++#include "clocks_ti816x.h"
++#endif
++
++#ifdef CONFIG_TI814X
++#include "clocks_ti814x.h"
++#endif
++
++#ifdef CONFIG_AM335X
++#include "clocks_am335x.h"
++#endif
++#endif
++
+diff --git a/arch/arm/boards/beaglebone/clocks_am335x.h b/arch/arm/boards/beaglebone/clocks_am335x.h
+new file mode 100644
+index 0000000..b5fbc29
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/clocks_am335x.h
+@@ -0,0 +1,65 @@
++/*
++ * clocks_am335x.h
++ *
++ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++#ifndef _CLOCKS_AM335X_H_
++#define _CLOCKS_AM335X_H_
++
++/* Put the pll config values over here */
++
++#define OSC 24
++
++/* MAIN PLL Fdll = 1 GHZ, */
++#define MPUPLL_M_500 500 /* 125 * n */
++#define MPUPLL_M_550 550 /* 125 * n */
++#define MPUPLL_M_600 600 /* 125 * n */
++#define MPUPLL_M_720 720 /* 125 * n */
++
++#define MPUPLL_N 23 /* (n -1 ) */
++#define MPUPLL_M2 1
++
++/* Core PLL Fdll = 1 GHZ, */
++#define COREPLL_M 1000 /* 125 * n */
++#define COREPLL_N 23 /* (n -1 ) */
++
++#define COREPLL_M4 10 /* CORE_CLKOUTM4 = 200 MHZ */
++#define COREPLL_M5 8 /* CORE_CLKOUTM5 = 250 MHZ */
++#define COREPLL_M6 4 /* CORE_CLKOUTM6 = 500 MHZ */
++
++/*
++ * USB PHY clock is 960 MHZ. Since, this comes directly from Fdll, Fdll
++ * frequency needs to be set to 960 MHZ. Hence,
++ * For clkout = 192 MHZ, Fdll = 960 MHZ, divider values are given below
++ */
++#define PERPLL_M 960
++#define PERPLL_N 23
++#define PERPLL_M2 5
++
++/* DDR Freq is 166 MHZ for now*/
++/* Set Fdll = 400 MHZ , Fdll = M * 2 * CLKINP/ N + 1; clkout = Fdll /(2 * M2) */
++#if (CONFIG_AM335X_EVM_IS_13x13 == 1)
++#define DDRPLL_M 166 /* M/N + 1 = 25/3 */
++#else
++#define DDRPLL_M 266
++#endif
++
++#define DDRPLL_N 23
++#define DDRPLL_M2 1
++
++#endif /* endif _CLOCKS_AM335X_H_ */
+diff --git a/arch/arm/boards/beaglebone/clocks_ti814x.h b/arch/arm/boards/beaglebone/clocks_ti814x.h
+new file mode 100644
+index 0000000..1b41c6f
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/clocks_ti814x.h
+@@ -0,0 +1,72 @@
++/*
++ * (C) Copyright 2006-2008
++ * Texas Instruments, <www.ti.com>
++ * Richard Woodruff <r-woodruff2@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++#ifndef _CLOCKS_TI814X_H_
++#define _CLOCKS_TI814X_H_
++
++/* CLK_SRC */
++#define OSC_SRC0 0
++#define OSC_SRC1 1
++
++#define L3_OSC_SRC OSC_SRC0
++#define AUDIO_OSC_SRC OSC_SRC0
++
++/* Put the pll config values over here */
++#define AUDIO_N 19
++#define AUDIO_M 500
++#define AUDIO_M2 2
++#define AUDIO_CLKCTRL 0x801
++
++#define MODENA_N 0x10001
++#define MODENA_M 0x3C
++#define MODENA_M2 1
++#define MODENA_CLKCTRL 0x1
++
++#define L3_N 19
++#define L3_M 880
++#define L3_M2 4
++#define L3_CLKCTRL 0x801
++
++#define DDR_N 19
++#define DDR_M 666
++#define DDR_M2 2
++#define DDR_CLKCTRL 0x801
++
++#define DSP_N 19
++#define DSP_M 500
++#define DSP_M2 1
++#define DSP_CLKCTRL 0x801
++
++#define IVA_N 19
++#define IVA_M 640
++#define IVA_M2 2
++#define IVA_CLKCTRL 0x801
++
++#define ISS_N 19
++#define ISS_M 800
++#define ISS_M2 2
++#define ISS_CLKCTRL 0x801
++
++#define USB_N 19
++#define USB_M 960
++#define USB_M2 1
++#define USB_CLKCTRL 0x200a0801
++#endif /* endif _CLOCKS_TI814X_H_ */
++
+diff --git a/arch/arm/boards/beaglebone/clocks_ti816x.h b/arch/arm/boards/beaglebone/clocks_ti816x.h
+new file mode 100644
+index 0000000..8590c2f
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/clocks_ti816x.h
+@@ -0,0 +1,162 @@
++/*
++ * (C) Copyright 2006-2008
++ * Texas Instruments, <www.ti.com>
++ * Richard Woodruff <r-woodruff2@ti.com>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++#ifndef _CLOCKS_TI816X_H_
++#define _CLOCKS_TI816X_H_
++
++/*
++ * In TI816x the 27MHz crystal generates various root clks (main pll, audio pll, video pll and ddr pll)
++ * From these root clks the SYSCLKs are generated by making use of dividers and multipliers
++ */
++
++#define FAPLL_K 8
++#define SYSCLK_2_DIV 1
++#define OSC_FREQ 27
++#define DDR_PLL_400 /* Values supported 400,531,675,796 */
++
++/* Main PLL */
++#define MAIN_N 64
++#define MAIN_P 0x1
++#define MAIN_INTFREQ1 0x8
++#define MAIN_FRACFREQ1 0x800000
++#define MAIN_MDIV1 0x2
++#define MAIN_INTFREQ2 0xE
++#define MAIN_FRACFREQ2 0x0
++#define MAIN_MDIV2 0x1
++#define MAIN_INTFREQ3 0x8
++#define MAIN_FRACFREQ3 0xAAAAB0
++#define MAIN_MDIV3 0x3
++#define MAIN_INTFREQ4 0x9
++#define MAIN_FRACFREQ4 0x55554F
++#define MAIN_MDIV4 0x3
++#define MAIN_INTFREQ5 0x9
++#define MAIN_FRACFREQ5 0x374BC6
++#define MAIN_MDIV5 0xC
++#define MAIN_MDIV6 0x48
++#define MAIN_MDIV7 0x4
++
++/* DDR PLL */
++/* For 400 MHz */
++#if defined(DDR_PLL_400)
++#define DDR_N 59
++#define DDR_P 0x1
++#define DDR_MDIV1 0x4
++#define DDR_INTFREQ2 0x8
++#define DDR_FRACFREQ2 0xD99999
++#define DDR_MDIV2 0x1E
++#define DDR_INTFREQ3 0x8
++#define DDR_FRACFREQ3 0x0
++#define DDR_MDIV3 0x4
++#define DDR_INTFREQ4 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ4 0x0
++#define DDR_MDIV4 0x4
++#define DDR_INTFREQ5 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ5 0x0
++#define DDR_MDIV5 0x4
++#endif
++
++/* For 531 MHz */
++#if defined(DDR_PLL_531)
++#define DDR_N 59
++#define DDR_P 0x1
++#define DDR_MDIV1 0x3
++#define DDR_INTFREQ2 0x8
++#define DDR_FRACFREQ2 0xD99999
++#define DDR_MDIV2 0x1E
++#define DDR_INTFREQ3 0x8
++#define DDR_FRACFREQ3 0x0
++#define DDR_MDIV3 0x4
++#define DDR_INTFREQ4 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ4 0x0
++#define DDR_MDIV4 0x4
++#define DDR_INTFREQ5 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ5 0x0
++#define DDR_MDIV5 0x4
++#endif
++
++/* For 675 MHz */
++#if defined(DDR_PLL_675)
++#define DDR_N 50
++#define DDR_P 0x1
++#define DDR_MDIV1 0x2
++#define DDR_INTFREQ2 0x9
++#define DDR_FRACFREQ2 0x0
++#define DDR_MDIV2 0x19
++#define DDR_INTFREQ3 0x13
++#define DDR_FRACFREQ3 0x800000
++#define DDR_MDIV3 0x2
++#define DDR_INTFREQ4 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ4 0x0
++#define DDR_MDIV4 0x4
++#define DDR_INTFREQ5 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ5 0x0
++#define DDR_MDIV5 0x4
++#endif
++
++/* For 796 MHz */
++#if defined(DDR_PLL_796)
++#define DDR_N 59
++#define DDR_P 0x1
++#define DDR_MDIV1 0x2
++#define DDR_INTFREQ2 0x8
++#define DDR_FRACFREQ2 0xD99999
++#define DDR_MDIV2 0x1E
++#define DDR_INTFREQ3 0x8
++#define DDR_FRACFREQ3 0x0
++#define DDR_MDIV3 0x4
++#define DDR_INTFREQ4 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ4 0x0
++#define DDR_MDIV4 0x4
++#define DDR_INTFREQ5 0xE /* Expansion DDR clk */
++#define DDR_FRACFREQ5 0x0
++#define DDR_MDIV5 0x4
++#endif
++
++/* Video PLL */
++#define VIDEO_N 110
++#define VIDEO_P 0x2
++#define VIDEO_INTFREQ1 0xB
++#define VIDEO_FRACFREQ1 0x0
++#define VIDEO_MDIV1 0x5
++#define VIDEO_INTFREQ2 0xA
++#define VIDEO_FRACFREQ2 0x0
++#define VIDEO_MDIV2 0x2
++#define VIDEO_INTFREQ3 0xA
++#define VIDEO_FRACFREQ3 0x0
++#define VIDEO_MDIV3 0x2
++
++/* Audio PLL */
++#define AUDIO_N 64
++#define AUDIO_P 0x19
++#define AUDIO_INTFREQ2 0xE
++#define AUDIO_FRACFREQ2 0x0
++#define AUDIO_MDIV2 0x4
++#define AUDIO_INTFREQ3 0x9
++#define AUDIO_FRACFREQ3 0x0
++#define AUDIO_MDIV3 0x5
++#define AUDIO_INTFREQ4 0x9
++#define AUDIO_FRACFREQ4 0xCBC148
++#define AUDIO_MDIV4 0x14
++#define AUDIO_INTFREQ5 0xD
++#define AUDIO_FRACFREQ5 0x800000
++#define AUDIO_MDIV5 0x14
++
++#endif /* endif _CLOCKS_TI816X_H_ */
++
+diff --git a/arch/arm/boards/beaglebone/common_def.h b/arch/arm/boards/beaglebone/common_def.h
+new file mode 100644
+index 0000000..21a50dd
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/common_def.h
+@@ -0,0 +1,48 @@
++/*
++ * common_def.h
++ *
++ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++#ifndef __COMMON_DEF_H__
++#define __COMMON_DEF_H__
++
++/* AM335X type */
++#define BONE_BOARD 0
++#define GP_BOARD 1
++#define IA_BOARD 2
++#define IPP_BOARD 3
++#define BASE_BOARD 4
++
++/* Profiles */
++#define PROFILE_NONE 0x0
++#define PROFILE_0 (1 << 0)
++#define PROFILE_1 (1 << 1)
++#define PROFILE_2 (1 << 2)
++#define PROFILE_3 (1 << 3)
++#define PROFILE_4 (1 << 4)
++#define PROFILE_5 (1 << 5)
++#define PROFILE_6 (1 << 6)
++#define PROFILE_7 (1 << 7)
++#define PROFILE_ALL 0xFF
++
++extern void pll_init(void);
++extern void mpu_pll_config(int mpupll_M);
++extern void enable_ddr_clocks(void);
++
++extern void enable_i2c0_pin_mux(void);
++extern void enable_uart0_pin_mux(void);
++extern void configure_evm_pin_mux(unsigned char daughter_board_id,
++ char daughter_board_version[],
++ unsigned short daughter_board_profile,
++ unsigned int daughter_board_flag);
++
++#endif/*__COMMON_DEF_H__ */
+diff --git a/arch/arm/boards/beaglebone/config.h b/arch/arm/boards/beaglebone/config.h
+new file mode 100644
+index 0000000..80be07a
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/config.h
+@@ -0,0 +1,24 @@
++/**
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ */
++
++#ifndef __CONFIG_H
++#define __CONFIG_H
++
++#define CONFIG_AM335X
++#define CONFIG_TI81XX
++
++#endif /* __CONFIG_H */
+diff --git a/arch/arm/boards/beaglebone/cpu.h b/arch/arm/boards/beaglebone/cpu.h
+new file mode 100644
+index 0000000..da22b1d
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/cpu.h
+@@ -0,0 +1,726 @@
++/*
++ * (C) Copyright 2006
++ * Texas Instruments, <www.ti.com>
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; either version 2 of
++ * the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
++ * MA 02111-1307 USA
++ *
++ */
++
++#ifndef _TI81XX_CPU_H
++#define _TI81XX_CPU_H
++
++#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
++#include <asm/types.h>
++#endif /* !(__KERNEL_STRICT_NAMES || __ASSEMBLY__) */
++
++#include "hardware.h"
++
++//#define BIT(x) (1 << x)
++#define CL_BIT(x) (0 << x)
++
++/* Timer registers */
++#define TIMER_TCLR 0x38 /* Timer control register */
++#define TIMER_TCRR 0x3C /* Timer counter register */
++#define TIMER_TLDR 0x40 /* Timer load value register*/
++
++/* Timer 32 bit registers */
++#ifndef __KERNEL_STRICT_NAMES
++#ifndef __ASSEMBLY__
++struct gptimer {
++ u32 tidr; /* 0x00 r */
++ u8 res1[0xc];
++ u32 tiocp_cfg; /* 0x10 rw */
++ u8 res2[0xc];
++ u32 tier; /* 0x20 rw */
++ u32 tistatr;/* 0x24 r */
++ u32 tistat; /* 0x28 r */
++ u32 tisr; /* 0x2c rw */
++ u32 tcicr; /* 0x30 rw */
++ u32 twer; /* 0x34 rw */
++ u32 tclr; /* 0x38 rw - control reg */
++ u32 tcrr; /* 0x3c rw - counter reg */
++ u32 tldr; /* 0x40 rw - load reg */
++ u32 ttgr; /* 0x44 rw */
++ u32 twpc; /* 0x48 r*/
++ u32 tmar; /* 0x4c rw*/
++ u32 tcar1; /* 0x50 r */
++ u32 tscir; /* 0x54 r */
++ u32 tcar2; /* 0x58 r */
++};
++#endif /* __ASSEMBLY__ */
++#endif /* __KERNEL_STRICT_NAMES */
++
++/* Timer register bits */
++#define TCLR_ST BIT(0) /* Start=1 Stop=0 */
++#define TCLR_AR BIT(1) /* Auto reload */
++#define TCLR_PRE BIT(5) /* Pre-scaler enable */
++#define TCLR_PTV_SHIFT (2) /* Pre-scaler shift value */
++#define TCLR_PRE_DISABLE CL_BIT(5) /* Pre-scalar disable */
++
++/* Control */
++#define CONTROL_STATUS (CTRL_BASE + 0x40)
++
++/* device type */
++#define DEVICE_MASK (BIT(8) | BIT(9) | BIT(10))
++#define TST_DEVICE 0x0
++#define EMU_DEVICE 0x1
++#define HS_DEVICE 0x2
++#define GP_DEVICE 0x3
++
++/* rom boot device/mode id */
++#define BOOT_DEVICE_OFFSET 8
++#define BOOT_DEVICE_MASK 0xff
++
++/* cpu-id for TI81XX family */
++#define TI8168 0xb81e
++#define AM335X 0xB944
++
++#define DEVICE_ID (CTRL_BASE + 0x0600)
++/* This gives the status of the boot mode pins on the evm */
++#define SYSBOOT_MASK (BIT(0) | BIT(1) | BIT(2) |BIT(3) |BIT(4))
++
++/* Reset control */
++#ifdef CONFIG_AM335X
++#define PRM_RSTCTRL (PRCM_BASE + 0x0F00)
++#else
++#define PRM_RSTCTRL (PRCM_BASE + 0x00A0)
++#endif
++#define PRM_RSTCTRL_RESET 0x01
++
++/* TI816X specific bits for PRM_DEVICE module */
++#define GLOBAL_RST_COLD BIT(1)
++
++/* PLL related registers */
++#ifdef CONFIG_TI816X
++#define MAINPLL_CTRL (CTRL_BASE + 0x0400)
++#define MAINPLL_PWD (CTRL_BASE + 0x0404)
++#define MAINPLL_FREQ1 (CTRL_BASE + 0x0408)
++#define MAINPLL_DIV1 (CTRL_BASE + 0x040C)
++#define MAINPLL_FREQ2 (CTRL_BASE + 0x0410)
++#define MAINPLL_DIV2 (CTRL_BASE + 0x0414)
++#define MAINPLL_FREQ3 (CTRL_BASE + 0x0418)
++#define MAINPLL_DIV3 (CTRL_BASE + 0x041C)
++#define MAINPLL_FREQ4 (CTRL_BASE + 0x0420)
++#define MAINPLL_DIV4 (CTRL_BASE + 0x0424)
++#define MAINPLL_FREQ5 (CTRL_BASE + 0x0428)
++#define MAINPLL_DIV5 (CTRL_BASE + 0x042C)
++#define MAINPLL_DIV6 (CTRL_BASE + 0x0434)
++#define MAINPLL_DIV7 (CTRL_BASE + 0x043C)
++
++#define DDRPLL_CTRL (CTRL_BASE + 0x0440)
++#define DDRPLL_PWD (CTRL_BASE + 0x0444)
++#define DDRPLL_DIV1 (CTRL_BASE + 0x044C)
++#define DDRPLL_FREQ2 (CTRL_BASE + 0x0450)
++#define DDRPLL_DIV2 (CTRL_BASE + 0x0454)
++#define DDRPLL_FREQ3 (CTRL_BASE + 0x0458)
++#define DDRPLL_DIV3 (CTRL_BASE + 0x045C)
++#define DDRPLL_FREQ4 (CTRL_BASE + 0x0460)
++#define DDRPLL_DIV4 (CTRL_BASE + 0x0464)
++#define DDRPLL_FREQ5 (CTRL_BASE + 0x0468)
++#define DDRPLL_DIV5 (CTRL_BASE + 0x046C)
++
++#define DDR_RCD (CTRL_BASE + 0x070C)
++
++#define VIDEOPLL_CTRL (CTRL_BASE + 0x0470)
++#define VIDEOPLL_PWD (CTRL_BASE + 0x0474)
++#define VIDEOPLL_FREQ1 (CTRL_BASE + 0x0478)
++#define VIDEOPLL_DIV1 (CTRL_BASE + 0x047C)
++#define VIDEOPLL_FREQ2 (CTRL_BASE + 0x0480)
++#define VIDEOPLL_DIV2 (CTRL_BASE + 0x0484)
++#define VIDEOPLL_FREQ3 (CTRL_BASE + 0x0488)
++#define VIDEOPLL_DIV3 (CTRL_BASE + 0x048C)
++
++#define AUDIOPLL_CTRL (CTRL_BASE + 0x04A0)
++#define AUDIOPLL_PWD (CTRL_BASE + 0x04A4)
++#define AUDIOPLL_FREQ2 (CTRL_BASE + 0x04B0)
++#define AUDIOPLL_DIV2 (CTRL_BASE + 0x04B4)
++#define AUDIOPLL_FREQ3 (CTRL_BASE + 0x04B8)
++#define AUDIOPLL_DIV3 (CTRL_BASE + 0x04BC)
++#define AUDIOPLL_FREQ4 (CTRL_BASE + 0x04C0)
++#define AUDIOPLL_DIV4 (CTRL_BASE + 0x04C4)
++#define AUDIOPLL_FREQ5 (CTRL_BASE + 0x04C8)
++#define AUDIOPLL_DIV5 (CTRL_BASE + 0x04CC)
++
++#endif
++
++#ifdef CONFIG_TI814X
++
++#define GMII_SEL (CTRL_BASE + 0x650)
++
++#define PCIE_PLLCFG0 (CTRL_BASE + 0x6D8)
++#define PCIE_PLLCFG1 (CTRL_BASE + 0x6DC)
++#define PCIE_PLLCFG2 (CTRL_BASE + 0x6E0)
++#define PCIE_PLLCFG3 (CTRL_BASE + 0x6E4)
++#define PCIE_PLLCFG4 (CTRL_BASE + 0x6E8)
++#define PCIE_PLLSTATUS (CTRL_BASE + 0x6EC)
++#define PCIE_RXSTATUS (CTRL_BASE + 0x6F0)
++#define PCIE_TXSTATUS (CTRL_BASE + 0x6F4)
++#define SERDES_REFCLK_CTRL (CTRL_BASE + 0xE24)
++
++#define SATA_PLLCFG0 (CTRL_BASE + 0x720)
++#define SATA_PLLCFG1 (CTRL_BASE + 0x724)
++#define SATA_PLLCFG2 (CTRL_BASE + 0x728)
++#define SATA_PLLCFG3 (CTRL_BASE + 0x72C)
++#define SATA_PLLCFG4 (CTRL_BASE + 0x730)
++#define SATA_PLLSTATUS (CTRL_BASE + 0x734)
++#define SATA_RXSTATUS (CTRL_BASE + 0x738)
++#define SATA_TXSTATUS (CTRL_BASE + 0x73C)
++
++/* pin muxing registers */
++#define PIN_CTRL_BASE (CTRL_BASE + 0x800)
++#define N_PINS (271) /* PIN1=800, PIN 271=800+270*4=C38) */
++
++/* Clocks are derived from ADPLLJ */
++#define ADPLLJ_CLKCTRL 0x4
++#define ADPLLJ_TENABLE 0x8
++#define ADPLLJ_TENABLEDIV 0xC
++#define ADPLLJ_M2NDIV 0x10
++#define ADPLLJ_MN2DIV 0x14
++#define ADPLLJ_STATUS 0x24
++
++/* ADPLLJ register values */
++#define ADPLLJ_CLKCTRL_HS2 0x00000801 /* HS2 mode, TINT2 = 1 */
++#define ADPLLJ_CLKCTRL_HS1 0x00001001 /* HS1 mode, TINT2 = 1 */
++#define ADPLLJ_CLKCTRL_CLKDCO 0x200A0000 /* Enable CLKDCOEN, CLKLDOEN, CLKDCOPWDNZ */
++
++#define MODENA_PLL_BASE (PLL_SUBSYS_BASE + 0x048)
++#define DSP_PLL_BASE (PLL_SUBSYS_BASE + 0x080)
++#define SGX_PLL_BASE (PLL_SUBSYS_BASE + 0x0B0)
++#define IVA_PLL_BASE (PLL_SUBSYS_BASE + 0x0E0)
++#define L3_PLL_BASE (PLL_SUBSYS_BASE + 0x110)
++#define ISS_PLL_BASE (PLL_SUBSYS_BASE + 0x140)
++#define DSS_PLL_BASE (PLL_SUBSYS_BASE + 0x170)
++#define VIDEO0_PLL_BASE (PLL_SUBSYS_BASE + 0x1A0)
++#define VIDEO1_PLL_BASE (PLL_SUBSYS_BASE + 0x1D0)
++#define HDMI_PLL_BASE (PLL_SUBSYS_BASE + 0x200)
++#define AUDIO_PLL_BASE (PLL_SUBSYS_BASE + 0x230)
++#define USB_PLL_BASE (PLL_SUBSYS_BASE + 0x260)
++#define DDR_PLL_BASE (PLL_SUBSYS_BASE + 0x290)
++
++#define OSC_SRC_CTRL (PLL_SUBSYS_BASE + 0x2C0)
++#define ARM_CLKSRC (PLL_SUBSYS_BASE + 0x2C4)
++#define VIDEO_PLL_CLKSRC (PLL_SUBSYS_BASE + 0x2C8)
++#define MLB_ATL_CLKSRC (PLL_SUBSYS_BASE + 0x2CC)
++#define McASP235_AUX_CLKSRC (PLL_SUBSYS_BASE + 0x2D0)
++#define McASP_AHCLK_CLKSRC (PLL_SUBSYS_BASE + 0x2D4)
++#define McBSP_UART_CLKSRC (PLL_SUBSYS_BASE + 0x2D8)
++#define HDMI_I2S_CLKSRC (PLL_SUBSYS_BASE + 0x2DC)
++#define DMTIMER_CLKSRC (PLL_SUBSYS_BASE + 0x2E0)
++#define CLKOUT_MUX (PLL_SUBSYS_BASE + 0x2E4)
++#define RMII_REFCLK_SRC (PLL_SUBSYS_BASE + 0x2E8)
++#define SECSS_CLKSRC (PLL_SUBSYS_BASE + 0x2EC)
++#define SYSCLK18_SRC (PLL_SUBSYS_BASE + 0x2F0)
++#define WDT0_CLKSRC (PLL_SUBSYS_BASE + 0x2F4)
++
++#endif
++
++#ifdef CONFIG_AM335X
++/* Module Offsets */
++#define CM_PER (PRCM_BASE + 0x0)
++#define CM_WKUP (PRCM_BASE + 0x400)
++#define CM_DPLL (PRCM_BASE + 0x500)
++#define CM_DEVICE (PRCM_BASE + 0x0700)
++#define CM_CEFUSE (PRCM_BASE + 0x0A00)
++#define PRM_DEVICE (PRCM_BASE + 0x0F00)
++
++/* Register Offsets */
++/* Core PLL ADPLLS */
++#define CM_CLKSEL_DPLL_CORE (CM_WKUP + 0x68)
++#define CM_CLKMODE_DPLL_CORE (CM_WKUP + 0x90)
++
++/* Core HSDIV */
++#define CM_DIV_M4_DPLL_CORE (CM_WKUP + 0x80)
++#define CM_DIV_M5_DPLL_CORE (CM_WKUP + 0x84)
++#define CM_DIV_M6_DPLL_CORE (CM_WKUP + 0xD8)
++#define CM_IDLEST_DPLL_CORE (CM_WKUP + 0x5c)
++
++/* Peripheral PLL */
++#define CM_CLKSEL_DPLL_PER (CM_WKUP + 0x9c)
++#define CM_CLKMODE_DPLL_PER (CM_WKUP + 0x8c)
++#define CM_DIV_M2_DPLL_PER (CM_WKUP + 0xAC)
++#define CM_IDLEST_DPLL_PER (CM_WKUP + 0x70)
++
++/* Display PLL */
++#define CM_CLKSEL_DPLL_DISP (CM_WKUP + 0x54)
++#define CM_CLKMODE_DPLL_DISP (CM_WKUP + 0x98)
++#define CM_DIV_M2_DPLL_DISP (CM_WKUP + 0xA4)
++
++/* DDR PLL */
++#define CM_CLKSEL_DPLL_DDR (CM_WKUP + 0x40)
++#define CM_CLKMODE_DPLL_DDR (CM_WKUP + 0x94)
++#define CM_DIV_M2_DPLL_DDR (CM_WKUP + 0xA0)
++#define CM_IDLEST_DPLL_DDR (CM_WKUP + 0x34)
++
++/* MPU PLL */
++#define CM_CLKSEL_DPLL_MPU (CM_WKUP + 0x2c)
++#define CM_CLKMODE_DPLL_MPU (CM_WKUP + 0x88)
++#define CM_DIV_M2_DPLL_MPU (CM_WKUP + 0xA8)
++#define CM_IDLEST_DPLL_MPU (CM_WKUP + 0x20)
++
++/* TIMER Clock Source Select */
++#define CLKSEL_TIMER2_CLK (CM_DPLL + 0x8)
++
++/* Interconnect clocks */
++#define CM_PER_L4LS_CLKCTRL (CM_PER + 0x60) /* EMIF */
++#define CM_PER_L4FW_CLKCTRL (CM_PER + 0x64) /* EMIF FW */
++#define CM_PER_L3_CLKCTRL (CM_PER + 0xE0) /* OCMC RAM */
++#define CM_PER_L3_INSTR_CLKCTRL (CM_PER + 0xDC)
++#define CM_PER_L4HS_CLKCTRL (CM_PER + 0x120)
++#define CM_WKUP_L4WKUP_CLKCTRL (CM_WKUP + 0x0c)/* UART0 */
++
++/* Domain Wake UP */
++#define CM_WKUP_CLKSTCTRL (CM_WKUP + 0) /* UART0 */
++#define CM_PER_L4LS_CLKSTCTRL (CM_PER + 0x0) /* TIMER2 */
++#define CM_PER_L3_CLKSTCTRL (CM_PER + 0x0c) /* EMIF */
++#define CM_PER_L4FW_CLKSTCTRL (CM_PER + 0x08) /* EMIF FW */
++#define CM_PER_L3S_CLKSTCTRL (CM_PER + 0x4)
++#define CM_PER_L4HS_CLKSTCTRL (CM_PER + 0x011c)
++#define CM_CEFUSE_CLKSTCTRL (CM_CEFUSE + 0x0)
++
++/* Module Enable Registers */
++#define CM_PER_TIMER2_CLKCTRL (CM_PER + 0x80) /* Timer2 */
++#define CM_WKUP_UART0_CLKCTRL (CM_WKUP + 0xB4)/* UART0 */
++#define CM_WKUP_CONTROL_CLKCTRL (CM_WKUP + 0x4) /* Control Module */
++#define CM_PER_EMIF_CLKCTRL (CM_PER + 0x28) /* EMIF */
++#define CM_PER_EMIF_FW_CLKCTRL (CM_PER + 0xD0) /* EMIF FW */
++#define CM_PER_GPMC_CLKCTRL (CM_PER + 0x30) /* GPMC */
++#define CM_PER_ELM_CLKCTRL (CM_PER + 0x40) /* ELM */
++#define CM_PER_SPI0_CLKCTRL (CM_PER + 0x4c) /* SPI0 */
++#define CM_PER_SPI1_CLKCTRL (CM_PER + 0x50) /* SPI1 */
++#define CM_WKUP_I2C0_CLKCTRL (CM_WKUP + 0xB8) /* I2C0 */
++#define CM_PER_CPGMAC0_CLKCTRL (CM_PER + 0x14) /* Ethernet */
++#define CM_PER_CPSW_CLKSTCTRL (CM_PER + 0x144)/* Ethernet */
++#define CM_PER_OCMCRAM_CLKCTRL (CM_PER + 0x2C) /* OCMC RAM */
++#define CM_PER_GPIO2_CLKCTRL (CM_PER + 0xB0) /* GPIO2 */
++#define CM_PER_UART3_CLKCTRL (CM_PER + 0x74) /* UART3 */
++#define CM_PER_I2C1_CLKCTRL (CM_PER + 0x48) /* I2C1 */
++#define CM_PER_I2C2_CLKCTRL (CM_PER + 0x44) /* I2C2 */
++#define CM_WKUP_GPIO0_CLKCTRL (CM_WKUP + 0x8) /* GPIO0 */
++
++#define CM_PER_MMC0_CLKCTRL (CM_PER + 0x3C)
++#define CM_PER_MMC1_CLKCTRL (CM_PER + 0xF4)
++#define CM_PER_MMC2_CLKCTRL (CM_PER + 0xF8)
++
++#endif /* CONFIG_AM335X */
++
++/* PRCM */
++#define CM_DPLL_OFFSET (PRCM_BASE + 0x0300)
++
++#ifdef CONFIG_TI816X
++#define CM_TIMER1_CLKSEL (CM_DPLL_OFFSET + 0x90)
++
++/* Timers */
++#define CM_ALWON_TIMER_0_CLKCTRL (PRCM_BASE + 0x156C)
++#define CM_ALWON_TIMER_1_CLKCTRL (PRCM_BASE + 0x1570)
++#define CM_ALWON_TIMER_2_CLKCTRL (PRCM_BASE + 0x1574)
++#define CM_ALWON_TIMER_3_CLKCTRL (PRCM_BASE + 0x1578)
++#define CM_ALWON_TIMER_4_CLKCTRL (PRCM_BASE + 0x157C)
++#define CM_ALWON_TIMER_5_CLKCTRL (PRCM_BASE + 0x1580)
++#define CM_ALWON_TIMER_6_CLKCTRL (PRCM_BASE + 0x1584)
++#define CM_ALWON_TIMER_7_CLKCTRL (PRCM_BASE + 0x1588)
++#endif
++
++#define CM_ALWON_WDTIMER_CLKCTRL (PRCM_BASE + 0x158C)
++#define CM_ALWON_SPI_CLKCTRL (PRCM_BASE + 0x1590)
++#define CM_ALWON_CONTROL_CLKCTRL (PRCM_BASE + 0x15C4)
++
++#define CM_ALWON_L3_SLOW_CLKSTCTRL (PRCM_BASE + 0x1400)
++
++#ifdef CONFIG_TI816X
++#define CM_ALWON_CUST_EFUSE_CLKCTRL (PRCM_BASE + 0x1628)
++#endif
++
++#define CM_ALWON_GPIO_0_CLKCTRL (PRCM_BASE + 0x155c)
++#define CM_ALWON_GPIO_0_OPTFCLKEN_DBCLK (PRCM_BASE + 0x155c)
++
++/* Ethernet */
++#define CM_ETHERNET_CLKSTCTRL (PRCM_BASE + 0x1404)
++#define CM_ALWON_ETHERNET_0_CLKCTRL (PRCM_BASE + 0x15D4)
++#define CM_ALWON_ETHERNET_1_CLKCTRL (PRCM_BASE + 0x15D8)
++
++/* UARTs */
++#define CM_ALWON_UART_0_CLKCTRL (PRCM_BASE + 0x1550)
++#define CM_ALWON_UART_1_CLKCTRL (PRCM_BASE + 0x1554)
++#define CM_ALWON_UART_2_CLKCTRL (PRCM_BASE + 0x1558)
++
++/* I2C */
++/* Note: In ti814x I2C0 and I2C2 have common clk control */
++#define CM_ALWON_I2C_0_CLKCTRL (PRCM_BASE + 0x1564)
++
++/* HSMMC */
++#ifdef CONFIG_TI816X
++#define CM_ALWON_HSMMC_CLKCTRL (PRCM_BASE + 0x15B0)
++#endif
++
++#ifdef CONFIG_TI814X
++#define CM_ALWON_HSMMC_CLKCTRL (PRCM_BASE + 0x1620)
++#endif
++
++/* UART2 registers */
++#ifdef CONFIG_TI816X
++#define DEFAULT_UART_BASE UART2_BASE
++#endif
++
++#ifdef CONFIG_TI814X
++#define DEFAULT_UART_BASE UART0_BASE
++#endif
++
++#ifdef CONFIG_AM335X
++#define DEFAULT_UART_BASE UART0_BASE
++#endif
++/* UART registers */
++/*TODO:Move to a new file */
++#define UART_SYSCFG (DEFAULT_UART_BASE + 0x54)
++#define UART_SYSSTS (DEFAULT_UART_BASE + 0x58)
++#define UART_LCR (DEFAULT_UART_BASE + 0x0C)
++#define UART_EFR (DEFAULT_UART_BASE + 0x08)
++#define UART_MCR (DEFAULT_UART_BASE + 0x10)
++#define UART_SCR (DEFAULT_UART_BASE + 0x40)
++#define UART_TCR (DEFAULT_UART_BASE + 0x18)
++#define UART_FCR (DEFAULT_UART_BASE + 0x08)
++#define UART_DLL (DEFAULT_UART_BASE + 0x00)
++#define UART_DLH (DEFAULT_UART_BASE + 0x04)
++#define UART_MDR (DEFAULT_UART_BASE + 0x20)
++
++/*DMM & EMIF4 MMR Declaration*/
++/*TODO: Move to a new file */
++#define DMM_LISA_MAP__0 (DMM_BASE + 0x40)
++#define DMM_LISA_MAP__1 (DMM_BASE + 0x44)
++#define DMM_LISA_MAP__2 (DMM_BASE + 0x48)
++#define DMM_LISA_MAP__3 (DMM_BASE + 0x4C)
++#define DMM_PAT_BASE_ADDR (DMM_BASE + 0x460)
++
++#ifdef CONFIG_AM335X
++#define EMIF_MOD_ID_REV (EMIF4_0_CFG_BASE + 0x0)
++#define EMIF4_0_SDRAM_STATUS (EMIF4_0_CFG_BASE + 0x04)
++#define EMIF4_0_SDRAM_CONFIG (EMIF4_0_CFG_BASE + 0x08)
++#define EMIF4_0_SDRAM_CONFIG2 (EMIF4_0_CFG_BASE + 0x0C)
++#define EMIF4_0_SDRAM_REF_CTRL (EMIF4_0_CFG_BASE + 0x10)
++#define EMIF4_0_SDRAM_REF_CTRL_SHADOW (EMIF4_0_CFG_BASE + 0x14)
++#define EMIF4_0_SDRAM_TIM_1 (EMIF4_0_CFG_BASE + 0x18)
++#define EMIF4_0_SDRAM_TIM_1_SHADOW (EMIF4_0_CFG_BASE + 0x1C)
++#define EMIF4_0_SDRAM_TIM_2 (EMIF4_0_CFG_BASE + 0x20)
++#define EMIF4_0_SDRAM_TIM_2_SHADOW (EMIF4_0_CFG_BASE + 0x24)
++#define EMIF4_0_SDRAM_TIM_3 (EMIF4_0_CFG_BASE + 0x28)
++#define EMIF4_0_SDRAM_TIM_3_SHADOW (EMIF4_0_CFG_BASE + 0x2C)
++#define EMIF0_0_SDRAM_MGMT_CTRL (EMIF4_0_CFG_BASE + 0x38)
++#define EMIF0_0_SDRAM_MGMT_CTRL_SHD (EMIF4_0_CFG_BASE + 0x3C)
++#define EMIF4_0_DDR_PHY_CTRL_1 (EMIF4_0_CFG_BASE + 0xE4)
++#define EMIF4_0_DDR_PHY_CTRL_1_SHADOW (EMIF4_0_CFG_BASE + 0xE8)
++#define EMIF4_0_DDR_PHY_CTRL_2 (EMIF4_0_CFG_BASE + 0xEC)
++#define EMIF4_0_IODFT_TLGC (EMIF4_0_CFG_BASE + 0x60)
++#else
++#define EMIF4_0_SDRAM_CONFIG (EMIF4_0_CFG_BASE + 0x08)
++#define EMIF4_0_SDRAM_CONFIG2 (EMIF4_0_CFG_BASE + 0x0C)
++#define EMIF4_0_SDRAM_REF_CTRL (EMIF4_0_CFG_BASE + 0x10)
++#define EMIF4_0_SDRAM_REF_CTRL_SHADOW (EMIF4_0_CFG_BASE + 0x14)
++#define EMIF4_0_SDRAM_TIM_1 (EMIF4_0_CFG_BASE + 0x18)
++#define EMIF4_0_SDRAM_TIM_1_SHADOW (EMIF4_0_CFG_BASE + 0x1C)
++#define EMIF4_0_SDRAM_TIM_2 (EMIF4_0_CFG_BASE + 0x20)
++#define EMIF4_0_SDRAM_TIM_2_SHADOW (EMIF4_0_CFG_BASE + 0x24)
++#define EMIF4_0_SDRAM_TIM_3 (EMIF4_0_CFG_BASE + 0x28)
++#define EMIF4_0_SDRAM_TIM_3_SHADOW (EMIF4_0_CFG_BASE + 0x2C)
++#define EMIF4_0_DDR_PHY_CTRL_1 (EMIF4_0_CFG_BASE + 0xE4)
++#define EMIF4_0_DDR_PHY_CTRL_1_SHADOW (EMIF4_0_CFG_BASE + 0xE8)
++#define EMIF4_0_IODFT_TLGC (EMIF4_0_CFG_BASE + 0x60)
++#endif
++
++#define EMIF4_1_SDRAM_CONFIG (EMIF4_1_CFG_BASE + 0x08)
++#define EMIF4_1_SDRAM_CONFIG2 (EMIF4_1_CFG_BASE + 0x0C)
++#define EMIF4_1_SDRAM_REF_CTRL (EMIF4_1_CFG_BASE + 0x10)
++#define EMIF4_1_SDRAM_REF_CTRL_SHADOW (EMIF4_1_CFG_BASE + 0x14)
++#define EMIF4_1_SDRAM_TIM_1 (EMIF4_1_CFG_BASE + 0x18)
++#define EMIF4_1_SDRAM_TIM_1_SHADOW (EMIF4_1_CFG_BASE + 0x1C)
++#define EMIF4_1_SDRAM_TIM_2 (EMIF4_1_CFG_BASE + 0x20)
++#define EMIF4_1_SDRAM_TIM_2_SHADOW (EMIF4_1_CFG_BASE + 0x24)
++#define EMIF4_1_SDRAM_TIM_3 (EMIF4_1_CFG_BASE + 0x28)
++#define EMIF4_1_SDRAM_TIM_3_SHADOW (EMIF4_1_CFG_BASE + 0x2C)
++#define EMIF4_1_DDR_PHY_CTRL_1 (EMIF4_1_CFG_BASE + 0xE4)
++#define EMIF4_1_DDR_PHY_CTRL_1_SHADOW (EMIF4_1_CFG_BASE + 0xE8)
++#define EMIF4_1_IODFT_TLGC (EMIF4_1_CFG_BASE + 0x60)
++
++#ifdef CONFIG_AM335X
++#define VTP0_CTRL_REG 0x44E10E0C
++#else
++#define VTP0_CTRL_REG 0x48140E0C
++#endif
++#define VTP1_CTRL_REG 0x48140E10
++
++/*EMIF4 PRCM Defintion*/
++#define CM_DEFAULT_L3_FAST_CLKSTCTRL (PRCM_BASE + 0x0508)
++#define CM_DEFAULT_EMIF_0_CLKCTRL (PRCM_BASE + 0x0520)
++#define CM_DEFAULT_EMIF_1_CLKCTRL (PRCM_BASE + 0x0524)
++#define CM_DEFAULT_DMM_CLKCTRL (PRCM_BASE + 0x0528)
++#define CM_DEFAULT_FW_CLKCTRL (PRCM_BASE + 0x052C)
++
++/* Smartreflex Registers */
++#define TI816X_SMRT_SCALE_ADDR (CTRL_BASE + 0x06A0)
++#define TI816X_SMRT_OPP_SVT_ADDR (CTRL_BASE + 0x06A8)
++#define TI816X_SMRT_OPP_HVT_ADDR (CTRL_BASE + 0x06AC)
++
++
++/* ALWON PRCM */
++#ifdef CONFIG_AM335X
++#define CM_ALWON_OCMC_0_CLKSTCTRL CM_PER_L3_CLKSTCTRL
++#define CM_ALWON_OCMC_0_CLKCTRL CM_PER_OCMCRAM_CLKCTRL
++#else
++#define CM_ALWON_OCMC_0_CLKSTCTRL (PRCM_BASE + 0x1414)
++#define CM_ALWON_OCMC_0_CLKCTRL (PRCM_BASE + 0x15B4)
++#endif
++
++#ifdef CONFIG_TI816X
++#define CM_ALWON_OCMC_1_CLKSTCTRL (PRCM_BASE + 0x1418)
++#define CM_ALWON_OCMC_1_CLKCTRL (PRCM_BASE + 0x15B8)
++#endif
++
++#ifdef CONFIG_AM335X
++#define CM_ALWON_GPMC_CLKCTRL CM_PER_GPMC_CLKCTRL
++#else
++#define CM_ALWON_GPMC_CLKCTRL (PRCM_BASE + 0x15D0)
++#endif
++
++/* OCMC */
++#ifdef CONFIG_TI816X
++#define SRAM0_SIZE (0x40000)
++#define SRAM_GPMC_STACK_SIZE (0x40)
++#endif
++
++#if defined(CONFIG_AM335X) || defined(CONFIG_TI814X)
++#define SRAM0_SIZE (0x1B400) /* 109 KB */
++#define SRAM_GPMC_STACK_SIZE (0x40)
++#endif
++
++#define LOW_LEVEL_SRAM_STACK (SRAM0_START + SRAM0_SIZE - 4)
++
++/* GPMC related */
++#define GPMC_CONFIG_CS0 (0x60)
++#define GPMC_CONFIG_CS0_BASE (GPMC_BASE + GPMC_CONFIG_CS0)
++#define GPMC_CONFIG1 (0x00)
++#define GPMC_CONFIG2 (0x04)
++#define GPMC_CONFIG3 (0x08)
++#define GPMC_CONFIG4 (0x0C)
++#define GPMC_CONFIG5 (0x10)
++#define GPMC_CONFIG6 (0x14)
++#define GPMC_CONFIG7 (0x18)
++
++/* PAD configuration register offsets and values for gpmc address
++ * lines a12 - a26
++ */
++#ifdef CONFIG_TI816X
++
++#define TIM7_OUT (CTRL_BASE + 0xb34) /* a12 */
++#define UART1_CTSN (CTRL_BASE + 0xadc) /* a13 */
++#define UART1_RTSN (CTRL_BASE + 0xad8) /* a14 */
++#define UART2_RTSN (CTRL_BASE + 0xae8) /* a15 */
++#define SC1_RST (CTRL_BASE + 0xb10) /* a15 */
++#define UART2_CTSN (CTRL_BASE + 0xaec) /* a16 */
++#define UART0_RIN (CTRL_BASE + 0xacc) /* a17 */
++#define UART0_DCDN (CTRL_BASE + 0xac8) /* a18 */
++#define UART0_DSRN (CTRL_BASE + 0xac4) /* a19 */
++#define UART0_DTRN (CTRL_BASE + 0xac0) /* a20 */
++#define SPI_SCS3 (CTRL_BASE + 0xaa4) /* a21 */
++#define SPI_SC2 (CTRL_BASE + 0xaa0) /* a22 */
++#define GPO_IO6 (CTRL_BASE + 0xca0) /* a23 */
++#define TIM6_OUT (CTRL_BASE + 0xb30) /* a24 */
++#define SC0_DATA (CTRL_BASE + 0xafc) /* a25 */
++#define GPMC_A27 (CTRL_BASE + 0xba0) /* a27 */
++
++/* MMC Pad register offsets */
++#define MMC_POW (CTRL_BASE + 0xa70)
++#define MMC_CLK (CTRL_BASE + 0xa74)
++#define MMC_CMD (CTRL_BASE + 0xa78)
++#define MMC_DAT0 (CTRL_BASE + 0xa7c)
++#define MMC_DAT1_SDIRQ (CTRL_BASE + 0xa80)
++#define MMC_DAT2_SDRW (CTRL_BASE + 0xa84)
++#define MMC_DAT3 (CTRL_BASE + 0xa88)
++
++#define GPMC_A12 TIM7_OUT
++#define GPMC_A13 UART1_CTSN
++#define GPMC_A14 UART1_RTSN
++#define GPMC_A15 UART2_RTSN
++#define GPMC_A16 UART2_CTSN
++#define GPMC_A17 UART0_RIN
++#define GPMC_A18 UART0_DCDN
++#define GPMC_A19 UART0_DSRN
++#define GPMC_A20 UART0_DTRN
++#define GPMC_A21 SPI_SCS3
++#define GPMC_A22 SPI_SC2
++#define GPMC_A23 GPO_IO6
++#define GPMC_A24 TIM6_OUT
++#define GPMC_A25 SC0_DATA
++#endif
++
++#ifdef CONFIG_AM335X
++#define GPMC_A12 (CTRL_BASE + 0x8c0) /* LCD_DATA8 */
++#define GPMC_A13 (CTRL_BASE + 0x8c4) /* LCD_DATA9 */
++#define GPMC_A14 (CTRL_BASE + 0x8c8) /* LCD_DATA10 */
++#define GPMC_A15 (CTRL_BASE + 0x8cc) /* LCD_DATA11 */
++#define GPMC_A16 (CTRL_BASE + 0x8d0) /* LCD_DATA12 */
++#define GPMC_A17 (CTRL_BASE + 0x8d4) /* LCD_DATA13 */
++#define GPMC_A18 (CTRL_BASE + 0x8d8) /* LCD_DATA14 */
++#define GPMC_A19 (CTRL_BASE + 0x8dc) /* LCD_DATA15 */
++#define GPMC_A20 (CTRL_BASE + 0x850) /* GPMC_A4 */
++#define GPMC_A21 (CTRL_BASE + 0x854) /* GPMC_A5 */
++#define GPMC_A22 (CTRL_BASE + 0x858) /* GPMC_A6 */
++
++/* DDR offsets */
++#define DDR_PHY_BASE_ADDR 0x44E12000
++#define DDR_IO_CTRL 0x44E10E04
++#define DDR_CKE_CTRL 0x44E1131C
++#define CONTROL_BASE_ADDR 0x44E10000
++
++#define DDR_CMD0_IOCTRL (CONTROL_BASE_ADDR + 0x1404)
++#define DDR_CMD1_IOCTRL (CONTROL_BASE_ADDR + 0x1408)
++#define DDR_CMD2_IOCTRL (CONTROL_BASE_ADDR + 0x140C)
++#define DDR_DATA0_IOCTRL (CONTROL_BASE_ADDR + 0x1440)
++#define DDR_DATA1_IOCTRL (CONTROL_BASE_ADDR + 0x1444)
++
++#define CMD0_CTRL_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x01C)
++#define CMD0_CTRL_SLAVE_FORCE_0 (DDR_PHY_BASE_ADDR + 0x020)
++#define CMD0_CTRL_SLAVE_DELAY_0 (DDR_PHY_BASE_ADDR + 0x024)
++#define CMD0_DLL_LOCK_DIFF_0 (DDR_PHY_BASE_ADDR + 0x028)
++#define CMD0_INVERT_CLKOUT_0 (DDR_PHY_BASE_ADDR + 0x02C)
++
++#define CMD1_CTRL_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x050)
++#define CMD1_CTRL_SLAVE_FORCE_0 (DDR_PHY_BASE_ADDR + 0x054)
++#define CMD1_CTRL_SLAVE_DELAY_0 (DDR_PHY_BASE_ADDR + 0x058)
++#define CMD1_DLL_LOCK_DIFF_0 (DDR_PHY_BASE_ADDR + 0x05C)
++#define CMD1_INVERT_CLKOUT_0 (DDR_PHY_BASE_ADDR + 0x060)
++
++#define CMD2_CTRL_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x084)
++#define CMD2_CTRL_SLAVE_FORCE_0 (DDR_PHY_BASE_ADDR + 0x088)
++#define CMD2_CTRL_SLAVE_DELAY_0 (DDR_PHY_BASE_ADDR + 0x08C)
++#define CMD2_DLL_LOCK_DIFF_0 (DDR_PHY_BASE_ADDR + 0x090)
++#define CMD2_INVERT_CLKOUT_0 (DDR_PHY_BASE_ADDR + 0x094)
++
++#define DATA0_RD_DQS_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x0C8)
++#define DATA0_RD_DQS_SLAVE_RATIO_1 (DDR_PHY_BASE_ADDR + 0x0CC)
++#define DATA0_WR_DQS_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x0DC)
++
++#define DATA0_WR_DQS_SLAVE_RATIO_1 (DDR_PHY_BASE_ADDR + 0x0E0)
++#define DATA0_WRLVL_INIT_RATIO_0 (DDR_PHY_BASE_ADDR + 0x0F0)
++
++#define DATA0_WRLVL_INIT_RATIO_1 (DDR_PHY_BASE_ADDR + 0x0F4)
++#define DATA0_GATELVL_INIT_RATIO_0 (DDR_PHY_BASE_ADDR + 0x0FC)
++
++#define DATA0_GATELVL_INIT_RATIO_1 (DDR_PHY_BASE_ADDR + 0x100)
++#define DATA0_FIFO_WE_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x108)
++
++#define DATA0_FIFO_WE_SLAVE_RATIO_1 (DDR_PHY_BASE_ADDR + 0x10C)
++#define DATA0_WR_DATA_SLAVE_RATIO_0 (DDR_PHY_BASE_ADDR + 0x120)
++
++#define DATA0_WR_DATA_SLAVE_RATIO_1 (DDR_PHY_BASE_ADDR + 0x124)
++#define DATA0_DLL_LOCK_DIFF_0 (DDR_PHY_BASE_ADDR + 0x138)
++
++#define DATA0_RANK0_DELAYS_0 (DDR_PHY_BASE_ADDR + 0x134)
++#define DATA1_RANK0_DELAYS_0 (DDR_PHY_BASE_ADDR + 0x1D8)
++
++#endif
++
++#ifndef __KERNEL_STRICT_NAMES
++#ifndef __ASSEMBLY__
++struct gpmc_cs {
++ u32 config1; /* 0x00 */
++ u32 config2; /* 0x04 */
++ u32 config3; /* 0x08 */
++ u32 config4; /* 0x0C */
++ u32 config5; /* 0x10 */
++ u32 config6; /* 0x14 */
++ u32 config7; /* 0x18 */
++ u32 nand_cmd; /* 0x1C */
++ u32 nand_adr; /* 0x20 */
++ u32 nand_dat; /* 0x24 */
++ u8 res[8]; /* blow up to 0x30 byte */
++};
++
++struct bch_res_0_3 {
++ u32 bch_result_x[4];
++};
++
++
++
++struct gpmc {
++ u8 res1[0x10];
++ u32 sysconfig; /* 0x10 */
++ u8 res2[0x4];
++ u32 irqstatus; /* 0x18 */
++ u32 irqenable; /* 0x1C */
++ u8 res3[0x20];
++ u32 timeout_control; /* 0x40 */
++ u8 res4[0xC];
++ u32 config; /* 0x50 */
++ u32 status; /* 0x54 */
++ u8 res5[0x8]; /* 0x58 */
++ struct gpmc_cs cs[8]; /* 0x60, 0x90, .. */
++ u8 res6[0x14]; /* 0x1E0 */
++ u32 ecc_config; /* 0x1F4 */
++ u32 ecc_control; /* 0x1F8 */
++ u32 ecc_size_config; /* 0x1FC */
++ u32 ecc1_result; /* 0x200 */
++ u32 ecc2_result; /* 0x204 */
++ u32 ecc3_result; /* 0x208 */
++ u32 ecc4_result; /* 0x20C */
++ u32 ecc5_result; /* 0x210 */
++ u32 ecc6_result; /* 0x214 */
++ u32 ecc7_result; /* 0x218 */
++ u32 ecc8_result; /* 0x21C */
++ u32 ecc9_result; /* 0x220 */
++ u8 res7[12]; /* 0x224 */
++ u32 testmomde_ctrl; /* 0x230 */
++ u8 res8[12]; /* 0x234 */
++ struct bch_res_0_3 bch_result_0_3[2]; /* 0x240 */
++};
++
++/* Used for board specific gpmc initialization */
++extern struct gpmc *gpmc_cfg;
++
++#endif /* __ASSEMBLY__ */
++#endif /* __KERNEL_STRICT_NAMES */
++
++/* Ethernet MAC ID from EFuse */
++#define MAC_ID0_LO (CTRL_BASE + 0x630)
++#define MAC_ID0_HI (CTRL_BASE + 0x634)
++#define MAC_ID1_LO (CTRL_BASE + 0x638)
++#define MAC_ID1_HI (CTRL_BASE + 0x63c)
++#define MAC_MII_SEL (CTRL_BASE + 0x650)
++
++/* WDT related */
++/* TODO: Move to a new file */
++#define WDT_WDSC (WDT_BASE + 0x010)
++#define WDT_WDST (WDT_BASE + 0x014)
++#define WDT_WISR (WDT_BASE + 0x018)
++#define WDT_WIER (WDT_BASE + 0x01C)
++#define WDT_WWER (WDT_BASE + 0x020)
++#define WDT_WCLR (WDT_BASE + 0x024)
++#define WDT_WCRR (WDT_BASE + 0x028)
++#define WDT_WLDR (WDT_BASE + 0x02C)
++#define WDT_WTGR (WDT_BASE + 0x030)
++#define WDT_WWPS (WDT_BASE + 0x034)
++#define WDT_WDLY (WDT_BASE + 0x044)
++#define WDT_WSPR (WDT_BASE + 0x048)
++#define WDT_WIRQEOI (WDT_BASE + 0x050)
++#define WDT_WIRQSTATRAW (WDT_BASE + 0x054)
++#define WDT_WIRQSTAT (WDT_BASE + 0x058)
++#define WDT_WIRQENSET (WDT_BASE + 0x05C)
++#define WDT_WIRQENCLR (WDT_BASE + 0x060)
++
++#define WDT_UNFREEZE (CTRL_BASE + 0x100)
++
++#endif /* _TI816X_CPU_H */
++
+diff --git a/arch/arm/boards/beaglebone/ddr_defs.h b/arch/arm/boards/beaglebone/ddr_defs.h
+new file mode 100644
+index 0000000..4ae1e10
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/ddr_defs.h
+@@ -0,0 +1,362 @@
++/*
++ * Copyright (C) 2010 Texas Instruments
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ * ----------------------------------------------------------------------------
++ *
++ */
++
++#ifndef _DDR_DEFS_H
++#define _DDR_DEFS_H
++
++#include "hardware.h"
++
++#ifdef CONFIG_TI816X_EVM_DDR3
++
++#define CONFIG_TI816X_DDR3_400 /* Values supported 400,531,675,796 */
++#define CONFIG_TI816X_DDR3_SW_LEVELING /* Enable software leveling as part of DDR3 init*/
++
++
++/*
++ * DDR3 force values. These are board dependent
++ */
++
++/* EVM 400 MHz clock Settings
++ * EVM has only a single RANK (chip select) */
++#define N_RANK 1
++
++/*
++ * Invert clock adds an additional half cycle delay on the command
++ * interface. The additional half cycle, is usually meant to enable
++ * leveling in the situation that DQS is later than CK on the board. It
++ * also helps provide some additional margin for leveling.
++ *
++ * For the EVM this is helping us with additional room for the write
++ * leveling. Since the dqs delays are very small.
++ */
++#define INVERT_CLOCK 1
++
++/*
++ * CMD_SLAVE_RATIO determines where is the command placed with respect
++ * to the clock edge. This is a ratio, implying 0x100 is one cycle.
++ * Ideally the command is centered so - this should be half cycle
++ * delay (0x80). But if invert clock is in use, an additional half
++ * cycle must be added
++ */
++#define CMD_SLAVE_FROM_INV_CLOCK(i) (((i)==0) ? 0x80 : 0x100)
++#define CMD_SLAVE_RATIO CMD_SLAVE_FROM_INV_CLOCK(INVERT_CLOCK)
++
++#ifdef TI816X_DDR3_PG_1_0
++/*
++ * EMIF PHY allows for controlling write DQS delay w.r.t. clock. The
++ * value may be forced or use values determined from the leveling
++ * process. Since we are doing the leveling - these are actually
++ * don't care and are not used. The force is in delay units
++ */
++#define WR_DQS_FORCE_3 0x00000010
++#define WR_DQS_FORCE_2 0x00000010
++#define WR_DQS_FORCE_1 0x00000010
++#define WR_DQS_FORCE_0 0x00000010
++
++/*
++ * EMIF PHY allows for controlling how much the read DQS must be
++ * delayed to sample the data correctly. Ideally this is about half a
++ * cycle. The force here is delay units. The value here is in use -
++ * as the current leveling process may not obtain this reliably. The
++ * value has been determined via various tests on the EVM and changing
++ * this setting is no recomended.
++ */
++#define RD_DQS_FORCE_0 0x00000028
++#define RD_DQS_FORCE_1 0x00000028
++#define RD_DQS_FORCE_2 0x00000028
++#define RD_DQS_FORCE_3 0x00000028
++
++/*
++ * read gate represents the round trip delay from command to read data
++ * on the board + some package delay. This is the period for which
++ * the bust may be tristated between a write and a read command and
++ * hence must not be sampled (gated off). This is actually determined
++ * via the read leveling process and hence this value is a don't care
++ * for the EVM
++ */
++#define RD_GATE_FORCE_3 0x44
++#define RD_GATE_FORCE_2 0x44
++#define RD_GATE_FORCE_1 0x44
++#define RD_GATE_FORCE_0 0x44
++
++#endif
++
++/*
++ * This represents the initial value for the leveling process. The
++ * value is a ratio - so 0x100 represents one cycle. The real delay
++ * is determined through the leveling process.
++ *
++ * During the leveling process, 0x20 is subtracted from the value, so
++ * we have added that to the value we want to set. We also set the
++ * values such that byte3 completes leveling after byte2 and byte1
++ * after byte0.
++ */
++#define WR_DQS_RATIO_0 0x20
++#define WR_DQS_RATIO_1 0x20
++#define WR_DQS_RATIO_2 0x20
++#define WR_DQS_RATIO_3 0x20
++
++#ifdef TI816X_DDR3_PG_1_0
++/*
++ * read dqs ratio is only used in DDR2
++ */
++#define RD_DQS_RATIO_0 0x40
++#define RD_DQS_RATIO_1 0x40
++#define RD_DQS_RATIO_2 0x40
++#define RD_DQS_RATIO_3 0x40
++#endif
++
++/*
++ * This represents the initial value for the leveling process. The
++ * value is a ratio - so 0x100 represents one cycle. The real delay
++ * is determined through the leveling process.
++ *
++ * During the leveling process, 0x20 is subtracted from the value, so
++ * we have added that to the value we want to set. We also set the
++ * values such that byte3 completes leveling after byte2 and byte1
++ * after byte0.
++ */
++#define RD_GATE_RATIO_0 0x20
++#define RD_GATE_RATIO_1 0x20
++#define RD_GATE_RATIO_2 0x20
++#define RD_GATE_RATIO_3 0x20
++
++#ifdef TI816X_DDR3_PG_1_0
++/*
++ * currently there is an issue with the automatic training process for
++ * DDR3 by setting the initial leveling ratios appropriately we are
++ * able to work arround write leveling and read gate leveling. How
++ * ever the automatic process may not work well for the read eye
++ * training (determining rd dqs delay). To work arround this - we
++ * leverage the pre-knowledge of a working RD DQS delay and make the
++ * leveling process complete by forcing good and bad values
++ * This is enabled via HACK_EYE_TRAINING
++ */
++#define HACK_EYE_TRAINING 0
++
++/*
++ * only the rd dqs delay needs to be forced. Others are determined via the leveling process
++ */
++#define USE_WR_DQS_FORCE 0
++#define USE_RD_DQS_FORCE HACK_EYE_TRAINING
++#define USE_RD_GATE_FORCE 0
++
++#endif
++/*
++ * data rate in MHz. The DDR clock will be 1/2 of this value
++ */
++#define DDR_DATA_RATE 800
++
++#define USE_EMIF0 1
++#define USE_EMIF1 1
++
++/*
++ * EMIF Paramters. Refer the EMIF register documentation and the
++ * memory datasheet for details
++ */
++/* For 400 MHz */
++#if defined(CONFIG_TI816X_DDR3_400)
++#define EMIF_TIM1 0x0CCCE524
++#define EMIF_TIM2 0x30308023
++#define EMIF_TIM3 0x009F82CF
++#define EMIF_SDREF 0x10000C30
++#define EMIF_SDCFG 0x62A41032
++#define EMIF_PHYCFG 0x0000010B
++
++#if defined(CONFIG_TI816X_DDR3_SW_LEVELING)
++/* These values are obtained from the CCS app */
++#define RD_DQS_GATE 0x12A
++#define RD_DQS 0x3B
++#define WR_DQS 0xA6
++#endif
++
++#endif /* CONFIG_TI816X_DDR3_400 */
++
++/* For 531 MHz */
++#if defined(CONFIG_TI816X_DDR3_531)
++#define EMIF_TIM1 0x0EF136AC
++#define EMIF_TIM2 0x30408063
++#define EMIF_TIM3 0x009F83AF
++#define EMIF_SDREF 0x1000102E
++#define EMIF_SDCFG 0x62A51832
++#define EMIF_PHYCFG 0x0000010C
++
++#if defined(CONFIG_TI816X_DDR3_SW_LEVELING)
++/* These values are obtained from the CCS app */
++#define RD_DQS_GATE 0x13D
++#define RD_DQS 0x39
++#define WR_DQS 0xB4
++#endif
++
++#endif /* CONFIG_TI816X_DDR_531 */
++
++/* For 675 MHz */
++#if defined(CONFIG_TI816X_DDR3_675)
++#define EMIF_TIM1 0x13358875
++#define EMIF_TIM2 0x5051806C
++#define EMIF_TIM3 0x009F84AF
++#define EMIF_SDREF 0x10001491
++#define EMIF_SDCFG 0x62A63032
++#define EMIF_PHYCFG 0x0000010F
++
++#if defined(CONFIG_TI816X_DDR3_SW_LEVELING)
++/* These values are obtained from the CCS app */
++#define RD_DQS_GATE 0x196
++#define RD_DQS 0x39
++#define WR_DQS 0x91
++
++#endif
++
++#endif /* CONFIG_TI816X_DDR3_675 */
++
++/* For 796 MHz */
++#if defined(CONFIG_TI816X_DDR3_796)
++#define EMIF_TIM1 0x1779C9FE
++#define EMIF_TIM2 0x50608074
++#define EMIF_TIM3 0x009F857F
++#define EMIF_SDREF 0x10001841
++#define EMIF_SDCFG 0x62A73832
++#define EMIF_PHYCFG 0x00000110
++
++#if defined(CONFIG_TI816X_DDR3_SW_LEVELING)
++/* These values are obtained from the CCS app */
++#define RD_DQS_GATE 0x1B3
++#define RD_DQS 0x35
++#define WR_DQS 0x93
++
++#endif
++
++#endif /* CONFIG_TI816X_DDR_796 */
++
++
++#if defined(CONFIG_TI816X_DDR3_SW_LEVELING)
++#define WR_DQS_RATIO_BYTE_LANE3 ((WR_DQS << 10) | WR_DQS)
++#define WR_DQS_RATIO_BYTE_LANE2 ((WR_DQS << 10) | WR_DQS)
++#define WR_DQS_RATIO_BYTE_LANE1 ((WR_DQS << 10) | WR_DQS)
++#define WR_DQS_RATIO_BYTE_LANE0 ((WR_DQS << 10) | WR_DQS)
++
++#define WR_DATA_RATIO_BYTE_LANE3 (((WR_DQS + 0x40) << 10) | (WR_DQS + 0x40))
++#define WR_DATA_RATIO_BYTE_LANE2 (((WR_DQS + 0x40) << 10) | (WR_DQS + 0x40))
++#define WR_DATA_RATIO_BYTE_LANE1 (((WR_DQS + 0x40) << 10) | (WR_DQS + 0x40))
++#define WR_DATA_RATIO_BYTE_LANE0 (((WR_DQS + 0x40) << 10) | (WR_DQS + 0x40))
++
++#define RD_DQS_RATIO ((RD_DQS << 10) | RD_DQS)
++
++#define DQS_GATE_BYTE_LANE0 ((RD_DQS_GATE << 10) | RD_DQS_GATE)
++#define DQS_GATE_BYTE_LANE1 ((RD_DQS_GATE << 10) | RD_DQS_GATE)
++#define DQS_GATE_BYTE_LANE2 ((RD_DQS_GATE << 10) | RD_DQS_GATE)
++#define DQS_GATE_BYTE_LANE3 ((RD_DQS_GATE << 10) | RD_DQS_GATE)
++
++#endif /* CONFIG_TI816X_DDR3_SW_LEVELING */
++
++#endif /* CONFIG_TI816X_EVM_DDR3 */
++
++#ifdef CONFIG_TI816X_EVM_DDR2
++
++#define INVERT_CLK_OUT 0x0
++#define CMD_SLAVE_RATIO 0x80
++/*
++ * DDR2 ratio values. These are board dependent
++ * obtained from sweep experiments
++ */
++
++/* EVM 400 MHz clock Settings */
++
++#define WR_DQS_RATIO_BYTE_LANE3 ((0x4a << 10) | 0x4a)
++#define WR_DQS_RATIO_BYTE_LANE2 ((0x4a << 10) | 0x4a)
++#define WR_DQS_RATIO_BYTE_LANE1 ((0x4a << 10) | 0x4a)
++#define WR_DQS_RATIO_BYTE_LANE0 ((0x4a << 10) | 0x4a)
++
++#define WR_DATA_RATIO_BYTE_LANE3 (((0x4a + 0x40) << 10) | (0x4a + 0x40))
++#define WR_DATA_RATIO_BYTE_LANE2 (((0x4a + 0x40) << 10) | (0x4a + 0x40))
++#define WR_DATA_RATIO_BYTE_LANE1 (((0x4a + 0x40) << 10) | (0x4a + 0x40))
++#define WR_DATA_RATIO_BYTE_LANE0 (((0x4a + 0x40) << 10) | (0x4a + 0x40))
++
++#define RD_DQS_RATIO ((0x40 << 10) | 0x40)
++
++#define DQS_GATE_BYTE_LANE0 ((0x13a << 10) | 0x13a)
++#define DQS_GATE_BYTE_LANE1 ((0x13a << 10) | 0x13a)
++#define DQS_GATE_BYTE_LANE2 ((0x13a << 10) | 0x13a)
++#define DQS_GATE_BYTE_LANE3 ((0x13a << 10) | 0x13a)
++
++/*
++ * EMIF Paramters
++ */
++#define EMIF_TIM1 0xAAB15E2
++#define EMIF_TIM2 0x423631D2
++#define EMIF_TIM3 0x80032F
++#define EMIF_SDREF 0x10000C30
++#define EMIF_SDCFG 0x43801A3A /* 32 bit ddr2, CL=6, CWL=5, 13 rows, 8 banks, 10 bit column, 2 CS */
++#define EMIF_PHYCFG 0x0000010B /* local odt = 1, read latency = 11 (max = 12, min=6) */
++
++#endif /* CONFIG_TI816X_EVM_DDR2 */
++
++#ifdef CONFIG_TI814X_EVM_DDR2
++/* ti814x specific settings to be added */
++#endif
++
++/* AM335X EMIF Register values */
++#ifdef CONFIG_AM335X
++#define EMIF_SDMGT 0x80000000
++#define EMIF_SDRAM 0x00004650
++#define EMIF_PHYCFG 0x2
++#define DDR_PHY_RESET (0x1 << 10)
++#define DDR_FUNCTIONAL_MODE_EN 0x1
++#define DDR_PHY_READY (0x1 << 2)
++#define VTP_CTRL_READY (0x1 << 5)
++#define VTP_CTRL_ENABLE (0x1 << 6)
++#define VTP_CTRL_LOCK_EN (0x1 << 4)
++#define VTP_CTRL_START_EN (0x1)
++#define DDR2_RATIO 0x80 /* for mDDR */
++#define CMD_FORCE 0x00 /* common #def */
++#define CMD_DELAY 0x00
++#if (CONFIG_AM335X_EVM_IS_13x13 == 1)
++#define EMIF_READ_LATENCY 0x05
++#define EMIF_TIM1 0x04446249
++#define EMIF_TIM2 0x101731C0
++#define EMIF_TIM3 0x137
++#define EMIF_SDCFG 0x20004EA3
++#define EMIF_SDREF 0x57c
++#define DDR2_DLL_LOCK_DIFF 0x4
++#define DDR2_RD_DQS 0x40
++#define DDR2_PHY_FIFO_WE 0x56
++#else
++#define EMIF_READ_LATENCY 0x05
++#define EMIF_TIM1 0x0666B3D6
++#define EMIF_TIM2 0x143731DA
++#define EMIF_TIM3 0x00000347
++#define EMIF_SDCFG 0x43805332
++#define EMIF_SDREF 0x0000081a
++#define DDR2_DLL_LOCK_DIFF 0x0
++#define DDR2_RD_DQS 0x12
++#define DDR2_PHY_FIFO_WE 0x80
++#endif
++#define DDR2_INVERT_CLKOUT 0x00
++#define DDR2_WR_DQS 0x00
++#define DDR2_PHY_WRLVL 0x00
++#define DDR2_PHY_GATELVL 0x00
++#define DDR2_PHY_WR_DATA 0x40
++#define PHY_RANK0_DELAY 0x01
++#define PHY_DLL_LOCK_DIFF 0x0
++#define DDR_IOCTRL_VALUE 0x18B
++#endif
++
++#endif /* _DDR_DEFS_H */
++
+diff --git a/arch/arm/boards/beaglebone/env/boot/sd b/arch/arm/boards/beaglebone/env/boot/sd
+new file mode 100644
+index 0000000..f3f276c
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/env/boot/sd
+@@ -0,0 +1,16 @@
++#!/bin/sh
++
++if [ "$1" = menu ]; then
++ boot-menu-add-entry "$0" "kernel & rootfs on SD card"
++ exit
++fi
++
++global.bootm.image=/boot/uImage
++#global.bootm.oftree=<path to oftree>
++#global.bootm.initrd=<path to initrd>
++
++#bootargs-root-nfs -n "<path on server>" -s <serverip>
++#bootargs-root-jffs2 -m <mtdname>
++#bootargs-root-ubi -r <volume> -m <mtdname>
++
++global.linux.bootargs.root="root=/dev/mmcblk0p2 rootfstype=ext4 rootwait ro"
+diff --git a/arch/arm/boards/beaglebone/env/init/bootargs-base b/arch/arm/boards/beaglebone/env/init/bootargs-base
+new file mode 100644
+index 0000000..333856e
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/env/init/bootargs-base
+@@ -0,0 +1,8 @@
++#!/bin/sh
++
++if [ "$1" = menu ]; then
++ init-menu-add-entry "$0" "Base bootargs"
++ exit
++fi
++
++global.linux.bootargs.base="console=ttyO0,115200n8"
+diff --git a/arch/arm/boards/beaglebone/env/init/general b/arch/arm/boards/beaglebone/env/init/general
+new file mode 100644
+index 0000000..bbd7ee3
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/env/init/general
+@@ -0,0 +1,18 @@
++#!/bin/sh
++
++if [ "$1" = menu ]; then
++ init-menu-add-entry "$0" "general config settings"
++ exit
++fi
++
++# user (used for network filenames)
++global.user=jlu
++
++# timeout in seconds before the default boot entry is started
++global.autoboot_timeout=3
++
++# default boot entry (one of /env/boot/*)
++global.boot.default=sd
++
++# default tftp path
++global.tftp.path=/mnt/tftp-dhcp
+diff --git a/arch/arm/boards/beaglebone/hardware.h b/arch/arm/boards/beaglebone/hardware.h
+new file mode 100644
+index 0000000..ee4256a
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/hardware.h
+@@ -0,0 +1,117 @@
++/*
++ * Copyright (C) 2009, Texas Instruments, Incorporated
++ *
++ * See file CREDITS for list of people who contributed to this
++ * project.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#ifndef __TI81XX_HARDWARE_H
++#define __TI81XX_HARDWARE_H
++
++/* The objective is to keep only the overall memory map here
++ * The break-up of the memory map for individual modules registers should
++ * be in a different file like cpu.h so that this is the only place
++ * where change is needed for new SoCs when the IP is otherwise the same
++ */
++#ifdef CONFIG_AM335X
++#define SRAM0_START 0x402F0400
++#else
++#define SRAM0_START 0x40300000
++#endif
++#ifdef CONFIG_AM335X
++#define UART0_BASE 0x44E09000
++#else
++#define UART0_BASE 0x48020000
++#endif
++#define UART1_BASE 0x48022000
++#define UART2_BASE 0x48024000
++#define UART3_BASE 0x481A6000
++
++/* DM Timer base addresses */
++#define DM_TIMER0_BASE 0x4802C000
++#define DM_TIMER1_BASE 0x4802E000
++#define DM_TIMER2_BASE 0x48040000
++#define DM_TIMER3_BASE 0x48042000
++#define DM_TIMER4_BASE 0x48044000
++#define DM_TIMER5_BASE 0x48046000
++#define DM_TIMER6_BASE 0x48048000
++#define DM_TIMER7_BASE 0x4804A000
++
++/* GPIO Base address */
++#define GPIO0_BASE 0x48032000
++#define GPIO1_BASE 0x4804C000
++#ifdef CONFIG_AM335X
++#define GPIO2_BASE 0x481AC000
++#endif
++/* BCH Error Location Module */
++#define ELM_BASE 0x48080000
++
++/* Watchdog Timer */
++#ifdef CONFIG_AM335X
++#define WDT_BASE 0x44E35000
++#else
++#define WDT_BASE 0x480C2000
++#endif
++
++/* Control Module Base Address */
++#ifdef CONFIG_AM335X
++#define CTRL_BASE 0x44E10000
++#else
++#define CTRL_BASE 0x48140000
++#endif
++
++/* PRCM Base Address */
++#ifdef CONFIG_AM335X
++#define PRCM_BASE 0x44E00000
++#else
++#define PRCM_BASE 0x48180000
++#endif
++
++/* PLL Subsystem Base Address */
++#ifdef CONFIG_TI814X
++#define PLL_SUBSYS_BASE 0x481C5000
++#endif
++
++/* EMIF Base address */
++#define EMIF4_0_CFG_BASE 0x4C000000
++#define EMIF4_1_CFG_BASE 0x4D000000
++#define DMM_BASE 0x4E000000
++
++#ifdef CONFIG_TI816X
++#define DDRPHY_0_CONFIG_BASE 0x48198000
++#define DDRPHY_1_CONFIG_BASE 0x4819a000
++#define DDRPHY_CONFIG_BASE ((emif == 0) ? DDRPHY_0_CONFIG_BASE:DDRPHY_1_CONFIG_BASE)
++#endif
++
++#ifdef CONFIG_TI814X
++#define DDRPHY_0_CONFIG_BASE (CTRL_BASE + 0x1400)
++#define DDRPHY_1_CONFIG_BASE (CTRL_BASE + 0x1500)
++#define DDRPHY_CONFIG_BASE ((emif == 0) ? DDRPHY_0_CONFIG_BASE:DDRPHY_1_CONFIG_BASE)
++#endif
++
++#ifdef CONFIG_AM335X
++#define DDRPHY_0_CONFIG_BASE (CTRL_BASE + 0x1400)
++#define DDRPHY_CONFIG_BASE DDRPHY_0_CONFIG_BASE
++#endif
++
++/* GPMC Base address */
++#define GPMC_BASE 0x50000000
++
++/* CPSW Config space */
++#define TI814X_CPSW_BASE 0x4A100000
++#define TI814X_CPSW_MDIO_BASE 0x4A100800
++
++#define AM335X_CPSW_BASE 0x4A100000
++#define AM335X_CPSW_MDIO_BASE 0x4A101000
++
++#endif /* __TI81XX_HARDWARE_H */
++
+diff --git a/arch/arm/boards/beaglebone/mux.c b/arch/arm/boards/beaglebone/mux.c
+new file mode 100644
+index 0000000..7fac302
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/mux.c
+@@ -0,0 +1,707 @@
++/*
++ * mux.c
++ *
++ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++#include <common.h>
++#include <config.h>
++#include <asm/io.h>
++#include "config.h"
++#include "common_def.h"
++#include "hardware.h"
++
++#define MUX_CFG(value, offset) \
++ __raw_writel(value, (CTRL_BASE + offset));
++
++/* PAD Control Fields */
++#define SLEWCTRL (0x1 << 6)
++#define RXACTIVE (0x1 << 5)
++#define PULLUP_EN (0x1 << 4) /* Pull UP Selection */
++#define PULLUDEN (0x0 << 3) /* Pull up enabled */
++#define PULLUDDIS (0x1 << 3) /* Pull up disabled */
++#define MODE(val) val
++
++/*
++ * PAD CONTROL OFFSETS
++ * Field names corresponds to the pad signal name
++ */
++struct pad_signals {
++ int gpmc_ad0;
++ int gpmc_ad1;
++ int gpmc_ad2;
++ int gpmc_ad3;
++ int gpmc_ad4;
++ int gpmc_ad5;
++ int gpmc_ad6;
++ int gpmc_ad7;
++ int gpmc_ad8;
++ int gpmc_ad9;
++ int gpmc_ad10;
++ int gpmc_ad11;
++ int gpmc_ad12;
++ int gpmc_ad13;
++ int gpmc_ad14;
++ int gpmc_ad15;
++ int gpmc_a0;
++ int gpmc_a1;
++ int gpmc_a2;
++ int gpmc_a3;
++ int gpmc_a4;
++ int gpmc_a5;
++ int gpmc_a6;
++ int gpmc_a7;
++ int gpmc_a8;
++ int gpmc_a9;
++ int gpmc_a10;
++ int gpmc_a11;
++ int gpmc_wait0;
++ int gpmc_wpn;
++ int gpmc_be1n;
++ int gpmc_csn0;
++ int gpmc_csn1;
++ int gpmc_csn2;
++ int gpmc_csn3;
++ int gpmc_clk;
++ int gpmc_advn_ale;
++ int gpmc_oen_ren;
++ int gpmc_wen;
++ int gpmc_be0n_cle;
++ int lcd_data0;
++ int lcd_data1;
++ int lcd_data2;
++ int lcd_data3;
++ int lcd_data4;
++ int lcd_data5;
++ int lcd_data6;
++ int lcd_data7;
++ int lcd_data8;
++ int lcd_data9;
++ int lcd_data10;
++ int lcd_data11;
++ int lcd_data12;
++ int lcd_data13;
++ int lcd_data14;
++ int lcd_data15;
++ int lcd_vsync;
++ int lcd_hsync;
++ int lcd_pclk;
++ int lcd_ac_bias_en;
++ int mmc0_dat3;
++ int mmc0_dat2;
++ int mmc0_dat1;
++ int mmc0_dat0;
++ int mmc0_clk;
++ int mmc0_cmd;
++ int mii1_col;
++ int mii1_crs;
++ int mii1_rxerr;
++ int mii1_txen;
++ int mii1_rxdv;
++ int mii1_txd3;
++ int mii1_txd2;
++ int mii1_txd1;
++ int mii1_txd0;
++ int mii1_txclk;
++ int mii1_rxclk;
++ int mii1_rxd3;
++ int mii1_rxd2;
++ int mii1_rxd1;
++ int mii1_rxd0;
++ int rmii1_refclk;
++ int mdio_data;
++ int mdio_clk;
++ int spi0_sclk;
++ int spi0_d0;
++ int spi0_d1;
++ int spi0_cs0;
++ int spi0_cs1;
++ int ecap0_in_pwm0_out;
++ int uart0_ctsn;
++ int uart0_rtsn;
++ int uart0_rxd;
++ int uart0_txd;
++ int uart1_ctsn;
++ int uart1_rtsn;
++ int uart1_rxd;
++ int uart1_txd;
++ int i2c0_sda;
++ int i2c0_scl;
++ int mcasp0_aclkx;
++ int mcasp0_fsx;
++ int mcasp0_axr0;
++ int mcasp0_ahclkr;
++ int mcasp0_aclkr;
++ int mcasp0_fsr;
++ int mcasp0_axr1;
++ int mcasp0_ahclkx;
++ int xdma_event_intr0;
++ int xdma_event_intr1;
++ int nresetin_out;
++ int porz;
++ int nnmi;
++ int osc0_in;
++ int osc0_out;
++ int rsvd1;
++ int tms;
++ int tdi;
++ int tdo;
++ int tck;
++ int ntrst;
++ int emu0;
++ int emu1;
++ int osc1_in;
++ int osc1_out;
++ int pmic_power_en;
++ int rtc_porz;
++ int rsvd2;
++ int ext_wakeup;
++ int enz_kaldo_1p8v;
++ int usb0_dm;
++ int usb0_dp;
++ int usb0_ce;
++ int usb0_id;
++ int usb0_vbus;
++ int usb0_drvvbus;
++ int usb1_dm;
++ int usb1_dp;
++ int usb1_ce;
++ int usb1_id;
++ int usb1_vbus;
++ int usb1_drvvbus;
++ int ddr_resetn;
++ int ddr_csn0;
++ int ddr_cke;
++ int ddr_ck;
++ int ddr_nck;
++ int ddr_casn;
++ int ddr_rasn;
++ int ddr_wen;
++ int ddr_ba0;
++ int ddr_ba1;
++ int ddr_ba2;
++ int ddr_a0;
++ int ddr_a1;
++ int ddr_a2;
++ int ddr_a3;
++ int ddr_a4;
++ int ddr_a5;
++ int ddr_a6;
++ int ddr_a7;
++ int ddr_a8;
++ int ddr_a9;
++ int ddr_a10;
++ int ddr_a11;
++ int ddr_a12;
++ int ddr_a13;
++ int ddr_a14;
++ int ddr_a15;
++ int ddr_odt;
++ int ddr_d0;
++ int ddr_d1;
++ int ddr_d2;
++ int ddr_d3;
++ int ddr_d4;
++ int ddr_d5;
++ int ddr_d6;
++ int ddr_d7;
++ int ddr_d8;
++ int ddr_d9;
++ int ddr_d10;
++ int ddr_d11;
++ int ddr_d12;
++ int ddr_d13;
++ int ddr_d14;
++ int ddr_d15;
++ int ddr_dqm0;
++ int ddr_dqm1;
++ int ddr_dqs0;
++ int ddr_dqsn0;
++ int ddr_dqs1;
++ int ddr_dqsn1;
++ int ddr_vref;
++ int ddr_vtp;
++ int ddr_strben0;
++ int ddr_strben1;
++ int ain7;
++ int ain6;
++ int ain5;
++ int ain4;
++ int ain3;
++ int ain2;
++ int ain1;
++ int ain0;
++ int vrefp;
++ int vrefn;
++};
++
++struct module_pin_mux {
++ short reg_offset;
++ unsigned char val;
++};
++
++struct evm_pin_mux {
++ struct module_pin_mux *mod_pin_mux;
++ unsigned short profile;
++/*
++* If the device is required on both baseboard & daughter board (ex i2c),
++* specify DEV_ON_BASEBOARD
++*/
++#define DEV_ON_BASEBOARD 0
++#define DEV_ON_DGHTR_BRD 1
++ unsigned short device_on;
++};
++
++#define PAD_CTRL_BASE 0x800
++#define OFFSET(x) (unsigned int) (&((struct pad_signals *) \
++ (PAD_CTRL_BASE))->x)
++
++static struct module_pin_mux uart0_pin_mux[] = {
++ {OFFSET(uart0_rxd), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* UART0_RXD */
++ {OFFSET(uart0_txd), (MODE(0) | PULLUDEN)}, /* UART0_TXD */
++ {-1},
++};
++
++static struct module_pin_mux uart3_pin_mux[] = {
++ {OFFSET(spi0_cs1), (MODE(1) | PULLUDEN | RXACTIVE)}, /* UART3_RXD */
++ {OFFSET(ecap0_in_pwm0_out), (MODE(1) | PULLUDEN)}, /* UART3_TXD */
++ {-1},
++};
++
++
++#ifdef CONFIG_NAND
++static struct module_pin_mux nand_pin_mux[] = {
++ {OFFSET(gpmc_ad0), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD0 */
++ {OFFSET(gpmc_ad1), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD1 */
++ {OFFSET(gpmc_ad2), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD2 */
++ {OFFSET(gpmc_ad3), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD3 */
++ {OFFSET(gpmc_ad4), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD4 */
++ {OFFSET(gpmc_ad5), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD5 */
++ {OFFSET(gpmc_ad6), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD6 */
++ {OFFSET(gpmc_ad7), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD7 */
++ {OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* NAND WAIT */
++ {OFFSET(gpmc_wpn), (MODE(7) | PULLUP_EN | RXACTIVE)}, /* NAND_WPN */
++ {OFFSET(gpmc_csn0), (MODE(0) | PULLUDEN)}, /* NAND_CS0 */
++ {OFFSET(gpmc_advn_ale), (MODE(0) | PULLUDEN)}, /* NAND_ADV_ALE */
++ {OFFSET(gpmc_oen_ren), (MODE(0) | PULLUDEN)}, /* NAND_OE */
++ {OFFSET(gpmc_wen), (MODE(0) | PULLUDEN)}, /* NAND_WEN */
++ {OFFSET(gpmc_be0n_cle), (MODE(0) | PULLUDEN)}, /* NAND_BE_CLE */
++ {-1},
++};
++#endif
++
++static struct module_pin_mux i2c0_pin_mux[] = {
++ {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
++ {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
++ {-1},
++};
++
++static struct module_pin_mux i2c1_pin_mux[] = {
++ {OFFSET(spi0_d1), (MODE(2) | RXACTIVE | PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
++ {OFFSET(spi0_cs0), (MODE(2) | RXACTIVE | PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
++ {-1},
++};
++
++static struct module_pin_mux i2c2_pin_mux[] = {
++ {OFFSET(uart1_ctsn), (MODE(3) | RXACTIVE | PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
++ {OFFSET(uart1_rtsn), (MODE(3) | RXACTIVE | PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
++ {-1},
++};
++
++#ifndef CONFIG_NO_ETH
++static struct module_pin_mux rgmii1_pin_mux[] = {
++ {OFFSET(mii1_txen), MODE(2)}, /* RGMII1_TCTL */
++ {OFFSET(mii1_rxdv), MODE(2) | RXACTIVE}, /* RGMII1_RCTL */
++ {OFFSET(mii1_txd3), MODE(2)}, /* RGMII1_TD3 */
++ {OFFSET(mii1_txd2), MODE(2)}, /* RGMII1_TD2 */
++ {OFFSET(mii1_txd1), MODE(2)}, /* RGMII1_TD1 */
++ {OFFSET(mii1_txd0), MODE(2)}, /* RGMII1_TD0 */
++ {OFFSET(mii1_txclk), MODE(2)}, /* RGMII1_TCLK */
++ {OFFSET(mii1_rxclk), MODE(2) | RXACTIVE}, /* RGMII1_RCLK */
++ {OFFSET(mii1_rxd3), MODE(2) | RXACTIVE}, /* RGMII1_RD3 */
++ {OFFSET(mii1_rxd2), MODE(2) | RXACTIVE}, /* RGMII1_RD2 */
++ {OFFSET(mii1_rxd1), MODE(2) | RXACTIVE}, /* RGMII1_RD1 */
++ {OFFSET(mii1_rxd0), MODE(2) | RXACTIVE}, /* RGMII1_RD0 */
++ {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
++ {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
++ {-1},
++};
++
++static struct module_pin_mux rgmii2_pin_mux[] = {
++ {OFFSET(gpmc_a0), MODE(2)}, /* RGMII2_TCTL */
++ {OFFSET(gpmc_a1), MODE(2) | RXACTIVE}, /* RGMII2_RCTL */
++ {OFFSET(gpmc_a2), MODE(2)}, /* RGMII2_TD3 */
++ {OFFSET(gpmc_a3), MODE(2)}, /* RGMII2_TD2 */
++ {OFFSET(gpmc_a4), MODE(2)}, /* RGMII2_TD1 */
++ {OFFSET(gpmc_a5), MODE(2)}, /* RGMII2_TD0 */
++ {OFFSET(gpmc_a6), MODE(2)}, /* RGMII2_TCLK */
++ {OFFSET(gpmc_a7), MODE(2) | RXACTIVE}, /* RGMII2_RCLK */
++ {OFFSET(gpmc_a8), MODE(2) | RXACTIVE}, /* RGMII2_RD3 */
++ {OFFSET(gpmc_a9), MODE(2) | RXACTIVE}, /* RGMII2_RD2 */
++ {OFFSET(gpmc_a10), MODE(2) | RXACTIVE}, /* RGMII2_RD1 */
++ {OFFSET(gpmc_a11), MODE(2) | RXACTIVE}, /* RGMII2_RD0 */
++ {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
++ {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
++ {-1},
++};
++
++static struct module_pin_mux mii1_pin_mux[] = {
++ {OFFSET(mii1_rxerr), MODE(0) | RXACTIVE}, /* MII1_RXERR */
++ {OFFSET(mii1_txen), MODE(0)}, /* MII1_TXEN */
++ {OFFSET(mii1_rxdv), MODE(0) | RXACTIVE}, /* MII1_RXDV */
++ {OFFSET(mii1_txd3), MODE(0)}, /* MII1_TXD3 */
++ {OFFSET(mii1_txd2), MODE(0)}, /* MII1_TXD2 */
++ {OFFSET(mii1_txd1), MODE(0)}, /* MII1_TXD1 */
++ {OFFSET(mii1_txd0), MODE(0)}, /* MII1_TXD0 */
++ {OFFSET(mii1_txclk), MODE(0) | RXACTIVE}, /* MII1_TXCLK */
++ {OFFSET(mii1_rxclk), MODE(0) | RXACTIVE}, /* MII1_RXCLK */
++ {OFFSET(mii1_rxd3), MODE(0) | RXACTIVE}, /* MII1_RXD3 */
++ {OFFSET(mii1_rxd2), MODE(0) | RXACTIVE}, /* MII1_RXD2 */
++ {OFFSET(mii1_rxd1), MODE(0) | RXACTIVE}, /* MII1_RXD1 */
++ {OFFSET(mii1_rxd0), MODE(0) | RXACTIVE}, /* MII1_RXD0 */
++ {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
++ {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
++ {-1},
++};
++
++static struct module_pin_mux rmii1_pin_mux[] = {
++ {OFFSET(mii1_crs), MODE(1) | RXACTIVE}, /* RMII1_CRS */
++ {OFFSET(mii1_rxerr), MODE(1) | RXACTIVE}, /* RMII1_RXERR */
++ {OFFSET(mii1_txen), MODE(1)}, /* RMII1_TXEN */
++ {OFFSET(mii1_txd1), MODE(1)}, /* RMII1_TXD1 */
++ {OFFSET(mii1_txd0), MODE(1)}, /* RMII1_TXD0 */
++ {OFFSET(mii1_rxd1), MODE(1) | RXACTIVE}, /* RMII1_RXD1 */
++ {OFFSET(mii1_rxd0), MODE(1) | RXACTIVE}, /* RMII1_RXD0 */
++ {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
++ {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
++ {OFFSET(rmii1_refclk), MODE(0) | RXACTIVE}, /* RMII1_REFCLK */
++ {-1},
++};
++#endif
++
++#ifdef CONFIG_NOR
++static struct module_pin_mux nor_pin_mux[] = {
++ {OFFSET(lcd_data0), MODE(1) | PULLUDEN}, /* NOR_A0 */
++ {OFFSET(lcd_data1), MODE(1) | PULLUDEN}, /* NOR_A1 */
++ {OFFSET(lcd_data2), MODE(1) | PULLUDEN}, /* NOR_A2 */
++ {OFFSET(lcd_data3), MODE(1) | PULLUDEN}, /* NOR_A3 */
++ {OFFSET(lcd_data4), MODE(1) | PULLUDEN}, /* NOR_A4 */
++ {OFFSET(lcd_data5), MODE(1) | PULLUDEN}, /* NOR_A5 */
++ {OFFSET(lcd_data6), MODE(1) | PULLUDEN}, /* NOR_A6 */
++ {OFFSET(lcd_data7), MODE(1) | PULLUDEN}, /* NOR_A7 */
++ {OFFSET(gpmc_a8), MODE(0)}, /* NOR_A8 */
++ {OFFSET(gpmc_a9), MODE(0)}, /* NOR_A9 */
++ {OFFSET(gpmc_a10), MODE(0)}, /* NOR_A10 */
++ {OFFSET(gpmc_a11), MODE(0)}, /* NOR_A11 */
++ {OFFSET(lcd_data8), MODE(1) | PULLUDEN}, /* NOR_A12 */
++ {OFFSET(lcd_data9), MODE(1) | PULLUDEN}, /* NOR_A13 */
++ {OFFSET(lcd_data10), MODE(1) | PULLUDEN}, /* NOR_A14 */
++ {OFFSET(lcd_data11), MODE(1) | PULLUDEN}, /* NOR_A15 */
++ {OFFSET(lcd_data12), MODE(1) | PULLUDEN}, /* NOR_A16 */
++ {OFFSET(lcd_data13), MODE(1) | PULLUDEN}, /* NOR_A17 */
++ {OFFSET(lcd_data14), MODE(1) | PULLUDEN}, /* NOR_A18 */
++ {OFFSET(lcd_data15), MODE(1) | PULLUDEN}, /* NOR_A19 */
++ {OFFSET(gpmc_a4), MODE(4)}, /* NOR_A20 */
++ {OFFSET(gpmc_a5), MODE(4)}, /* NOR_A21 */
++ {OFFSET(gpmc_a6), MODE(4)}, /* NOR_A22 */
++ {OFFSET(gpmc_ad0), MODE(0) | RXACTIVE}, /* NOR_AD0 */
++ {OFFSET(gpmc_ad1), MODE(0) | RXACTIVE}, /* NOR_AD1 */
++ {OFFSET(gpmc_ad2), MODE(0) | RXACTIVE}, /* NOR_AD2 */
++ {OFFSET(gpmc_ad3), MODE(0) | RXACTIVE}, /* NOR_AD3 */
++ {OFFSET(gpmc_ad4), MODE(0) | RXACTIVE}, /* NOR_AD4 */
++ {OFFSET(gpmc_ad5), MODE(0) | RXACTIVE}, /* NOR_AD5 */
++ {OFFSET(gpmc_ad6), MODE(0) | RXACTIVE}, /* NOR_AD6 */
++ {OFFSET(gpmc_ad7), MODE(0) | RXACTIVE}, /* NOR_AD7 */
++ {OFFSET(gpmc_ad8), MODE(0) | RXACTIVE}, /* NOR_AD8 */
++ {OFFSET(gpmc_ad9), MODE(0) | RXACTIVE}, /* NOR_AD9 */
++ {OFFSET(gpmc_ad10), MODE(0) | RXACTIVE}, /* NOR_AD10 */
++ {OFFSET(gpmc_ad11), MODE(0) | RXACTIVE}, /* NOR_AD11 */
++ {OFFSET(gpmc_ad12), MODE(0) | RXACTIVE}, /* NOR_AD12 */
++ {OFFSET(gpmc_ad13), MODE(0) | RXACTIVE}, /* NOR_AD13 */
++ {OFFSET(gpmc_ad14), MODE(0) | RXACTIVE}, /* NOR_AD14 */
++ {OFFSET(gpmc_ad15), MODE(0) | RXACTIVE}, /* NOR_AD15 */
++ {OFFSET(gpmc_csn0), (MODE(0) | PULLUP_EN)}, /* NOR_CE */
++ {OFFSET(gpmc_oen_ren), (MODE(0) | PULLUP_EN)}, /* NOR_OE */
++ {OFFSET(gpmc_wen), (MODE(0) | PULLUP_EN)}, /* NOR_WEN */
++ {OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* NOR WAIT */
++ {OFFSET(lcd_ac_bias_en), MODE(7) | RXACTIVE | PULLUDEN}, /* NOR RESET */
++ {-1},
++};
++#endif
++
++#ifdef CONFIG_MMC
++static struct module_pin_mux mmc0_pin_mux[] = {
++ {OFFSET(mmc0_dat3), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT3 */
++ {OFFSET(mmc0_dat2), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT2 */
++ {OFFSET(mmc0_dat1), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT1 */
++ {OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_DAT0 */
++ {OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CLK */
++ {OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* MMC0_CMD */
++ {OFFSET(mcasp0_aclkr), (MODE(4) | RXACTIVE)}, /* MMC0_WP */
++ {OFFSET(spi0_cs1), (MODE(5) | RXACTIVE | PULLUP_EN)}, /* MMC0_CD */
++ {-1},
++};
++
++static struct module_pin_mux mmc1_pin_mux[] = {
++ {OFFSET(gpmc_ad3), (MODE(1) | RXACTIVE)}, /* MMC1_DAT3 */
++ {OFFSET(gpmc_ad2), (MODE(1) | RXACTIVE)}, /* MMC1_DAT2 */
++ {OFFSET(gpmc_ad1), (MODE(1) | RXACTIVE)}, /* MMC1_DAT1 */
++ {OFFSET(gpmc_ad0), (MODE(1) | RXACTIVE)}, /* MMC1_DAT0 */
++ {OFFSET(gpmc_csn1), (MODE(2) | RXACTIVE | PULLUP_EN)}, /* MMC1_CLK */
++ {OFFSET(gpmc_csn2), (MODE(2) | RXACTIVE | PULLUP_EN)}, /* MMC1_CMD */
++ {OFFSET(uart1_rxd), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_WP */
++ {OFFSET(mcasp0_fsx), (MODE(4) | RXACTIVE)}, /* MMC1_CD */
++ {-1},
++};
++#endif
++
++#ifdef CONFIG_SPI
++static struct module_pin_mux spi0_pin_mux[] = {
++ {OFFSET(spi0_sclk), MODE(0) | PULLUDEN | RXACTIVE}, /*SPI0_SCLK */
++ {OFFSET(spi0_d0), MODE(0) | PULLUDEN | PULLUP_EN |
++ RXACTIVE}, /*SPI0_D0 */
++ {OFFSET(spi0_d1), MODE(0) | PULLUDEN |
++ RXACTIVE}, /*SPI0_D1 */
++ {OFFSET(spi0_cs0), MODE(0) | PULLUDEN | PULLUP_EN | RXACTIVE}, /*SPI0_CS0 */
++ {-1},
++};
++
++static struct module_pin_mux spi1_pin_mux[] = {
++ {OFFSET(mcasp0_aclkx), MODE(3) | PULLUDEN | RXACTIVE}, /*SPI0_SCLK */
++ {OFFSET(mcasp0_fsx), MODE(3) | PULLUDEN | PULLUP_EN |
++ RXACTIVE}, /*SPI0_D0 */
++ {OFFSET(mcasp0_axr0), MODE(3) | PULLUDEN | RXACTIVE}, /*SPI0_D1 */
++ {OFFSET(mcasp0_ahclkr), MODE(3) | PULLUDEN | PULLUP_EN |
++ RXACTIVE}, /*SPI0_CS0 */
++ {-1},
++};
++#endif
++
++/*
++ * Update the structure with the modules present in the general purpose
++ * board and the profiles in which the modules are present.
++ * If the module is physically present but if it is not available
++ * in any of the profile, then do not update it.
++ * For eg, nand is avialable only in the profiles 0 and 1, whereas
++ * UART0 is available in all the profiles.
++ */
++static struct evm_pin_mux general_purpose_evm_pin_mux[] = {
++ {uart0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {i2c1_pin_mux, PROFILE_ALL & ~PROFILE_2 & ~PROFILE_4, DEV_ON_BASEBOARD},
++#ifdef CONFIG_NAND
++ {nand_pin_mux, PROFILE_ALL & ~PROFILE_2 & ~PROFILE_3, DEV_ON_DGHTR_BRD},
++#endif
++#ifndef CONFIG_NO_ETH
++ {rgmii1_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {rgmii2_pin_mux, PROFILE_1 | PROFILE_2 | PROFILE_4 | PROFILE_6,
++ DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_NOR
++ {nor_pin_mux, PROFILE_3, DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_MMC
++ {mmc0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {mmc1_pin_mux, PROFILE_2, DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_SPI
++ {spi0_pin_mux, PROFILE_2, DEV_ON_DGHTR_BRD},
++#endif
++ {0},
++};
++
++/*
++ * Update the structure with the modules present in the ia daughter board and
++ * the profiles in which the modules are present. If the module is physically
++ * present but if it is not available in any of the profile, then do not update
++ */
++static struct evm_pin_mux ia_motor_control_evm_pin_mux[] = {
++#ifdef CONFIG_NAND
++ {nand_pin_mux, PROFILE_ALL, DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_MMC
++ {mmc0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++#endif
++#ifdef CONFIG_SPI
++ {spi1_pin_mux, PROFILE_ALL, DEV_ON_DGHTR_BRD},
++#endif
++#ifndef CONFIG_NO_ETH
++ {mii1_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++#endif
++ {uart3_pin_mux, PROFILE_ALL, DEV_ON_DGHTR_BRD},
++ {0},
++};
++
++/* IP Phone EVM has single profile */
++static struct evm_pin_mux ip_phone_evm_pin_mux[] = {
++ {uart0_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++ {i2c1_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++#ifdef CONFIG_NAND
++ {nand_pin_mux, PROFILE_0, DEV_ON_BASEBOARD},
++#endif
++#ifndef CONFIG_NO_ETH
++ {rgmii1_pin_mux, PROFILE_0, DEV_ON_BASEBOARD},
++ {rgmii2_pin_mux, PROFILE_0, DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_MMC
++ {mmc0_pin_mux, PROFILE_0, DEV_ON_BASEBOARD},
++#endif
++ {0},
++};
++
++/* Base board has single profile */
++static struct evm_pin_mux low_cost_evm_pin_mux[] = {
++ {uart0_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++ {i2c1_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++#ifdef CONFIG_NAND
++ {nand_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++#endif
++#ifndef CONFIG_NO_ETH
++ {rgmii1_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++#endif
++#ifdef CONFIG_MMC
++ {mmc0_pin_mux, PROFILE_NONE, DEV_ON_BASEBOARD},
++#endif
++ {0},
++};
++
++static struct evm_pin_mux beaglebone_pin_mux[] = {
++ {uart0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {i2c1_pin_mux, PROFILE_ALL & ~PROFILE_2 & ~PROFILE_4, DEV_ON_BASEBOARD},
++ {i2c2_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++#ifdef CONFIG_NAND
++ {nand_pin_mux, PROFILE_ALL & ~PROFILE_2 & ~PROFILE_3, DEV_ON_DGHTR_BRD},
++#endif
++#ifndef CONFIG_NO_ETH
++ {mii1_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++#endif
++#ifdef CONFIG_MMC
++ {mmc0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {mmc1_pin_mux, PROFILE_2, DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_SPI
++ {spi0_pin_mux, PROFILE_2, DEV_ON_DGHTR_BRD},
++#endif
++ {0},
++};
++
++static struct evm_pin_mux beaglebone_old_pin_mux[] = {
++ {uart0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {i2c1_pin_mux, PROFILE_ALL & ~PROFILE_2 & ~PROFILE_4, DEV_ON_BASEBOARD},
++ {i2c2_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++#ifdef CONFIG_NAND
++ {nand_pin_mux, PROFILE_ALL & ~PROFILE_2 & ~PROFILE_3, DEV_ON_DGHTR_BRD},
++#endif
++#ifndef CONFIG_NO_ETH
++ {rmii1_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++#endif
++#ifdef CONFIG_MMC
++ {mmc0_pin_mux, PROFILE_ALL, DEV_ON_BASEBOARD},
++ {mmc1_pin_mux, PROFILE_2, DEV_ON_DGHTR_BRD},
++#endif
++#ifdef CONFIG_SPI
++ {spi0_pin_mux, PROFILE_2, DEV_ON_DGHTR_BRD},
++#endif
++ {0},
++};
++
++static struct evm_pin_mux *am335x_evm_pin_mux[] = {
++ beaglebone_pin_mux,
++ general_purpose_evm_pin_mux,
++ ia_motor_control_evm_pin_mux,
++ ip_phone_evm_pin_mux,
++ low_cost_evm_pin_mux,
++};
++
++/*
++ * Configure the pin mux for the module
++ */
++static void configure_module_pin_mux(struct module_pin_mux *mod_pin_mux)
++{
++ int i;
++
++ if (!mod_pin_mux)
++ return;
++
++ for (i = 0; mod_pin_mux[i].reg_offset != -1; i++)
++ MUX_CFG(mod_pin_mux[i].val, mod_pin_mux[i].reg_offset);
++}
++
++/*
++ * Check each module in the daughter board(first argument) whether it is
++ * available in the selected profile(second argument). If the module is not
++ * available in the selected profile, skip the corresponding configuration.
++ */
++static void set_evm_pin_mux(struct evm_pin_mux *pin_mux,
++ int prof, unsigned int dghtr_brd_flg)
++{
++ int i;
++
++ if (!pin_mux)
++ return;
++
++ /*
++ * Only General Purpose & Industrial Auto Motro Control
++ * EVM has profiles. So check if this evm has profile.
++ * If not, ignore the profile comparison
++ */
++
++ /*
++ * If the device is on baseboard, directly configure it. Else (device on
++ * Daughter board), check if the daughter card is detected.
++ */
++
++ for (i = 0; pin_mux[i].mod_pin_mux != 0; i++) {
++ if ((pin_mux[i].profile & prof) ||
++ (prof == PROFILE_NONE)) {
++ if (pin_mux->device_on == DEV_ON_BASEBOARD)
++ configure_module_pin_mux(pin_mux[i].
++ mod_pin_mux);
++ else if (dghtr_brd_flg)
++ configure_module_pin_mux(pin_mux[i].
++ mod_pin_mux);
++ }
++ }
++}
++
++void configure_evm_pin_mux(unsigned char dghtr_brd_id, char version[4], unsigned short
++ profile, unsigned int daughter_board_flag)
++{
++ if (dghtr_brd_id > BASE_BOARD)
++ return;
++
++ /* Setup correct evm pinmux for older bone boards (Rev < A2) */
++ if (dghtr_brd_id == BONE_BOARD &&
++ (!strncmp(version, "00A2", 4) || !strncmp(version, "00A1", 4)))
++ am335x_evm_pin_mux[dghtr_brd_id] = beaglebone_old_pin_mux;
++
++ set_evm_pin_mux(am335x_evm_pin_mux[dghtr_brd_id], profile,
++ daughter_board_flag);
++}
++
++void enable_i2c0_pin_mux(void)
++{
++ configure_module_pin_mux(i2c0_pin_mux);
++}
++
++void enable_i2c1_pin_mux(void)
++{
++ configure_module_pin_mux(i2c1_pin_mux);
++}
++
++void enable_i2c2_pin_mux(void)
++{
++ configure_module_pin_mux(i2c2_pin_mux);
++}
++
++void enable_uart0_pin_mux(void)
++{
++ configure_module_pin_mux(uart0_pin_mux);
++}
+diff --git a/arch/arm/boards/beaglebone/pll.c b/arch/arm/boards/beaglebone/pll.c
+new file mode 100644
+index 0000000..bc09fea
+--- /dev/null
++++ b/arch/arm/boards/beaglebone/pll.c
+@@ -0,0 +1,293 @@
++/*
++ * pll.c
++ *
++ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation version 2.
++ *
++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
++ * kind, whether express or implied; without even the implied warranty
++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++#include <common.h>
++#include <asm/io.h>
++#include "config.h"
++#include "common_def.h"
++#include "cpu.h"
++#include "clock.h"
++#include "hardware.h"
++
++#define PRCM_MOD_EN 0x2
++#define PRCM_FORCE_WAKEUP 0x2
++
++#define PRCM_EMIF_CLK_ACTIVITY (0x1 << 2)
++#define PRCM_L3_GCLK_ACTIVITY (0x1 << 4)
++
++#define PLL_BYPASS_MODE 0x4
++#define PLL_LOCK_MODE 0x7
++#define PLL_MULTIPLIER_SHIFT 8
++
++static void interface_clocks_enable(void)
++{
++ /* Enable all the Interconnect Modules */
++ __raw_writel(PRCM_MOD_EN, CM_PER_L3_CLKCTRL);
++ while (__raw_readl(CM_PER_L3_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_PER_L4LS_CLKCTRL);
++ while (__raw_readl(CM_PER_L4LS_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_PER_L4FW_CLKCTRL);
++ while (__raw_readl(CM_PER_L4FW_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_WKUP_L4WKUP_CLKCTRL);
++ while (__raw_readl(CM_WKUP_L4WKUP_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_PER_L3_INSTR_CLKCTRL);
++ while (__raw_readl(CM_PER_L3_INSTR_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_PER_L4HS_CLKCTRL);
++ while (__raw_readl(CM_PER_L4HS_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_PER_SPI1_CLKCTRL);
++ while (__raw_readl(CM_PER_SPI1_CLKCTRL) != PRCM_MOD_EN);
++
++ /* GPIO0 */
++ __raw_writel(PRCM_MOD_EN, CM_WKUP_GPIO0_CLKCTRL);
++ while (__raw_readl(CM_WKUP_GPIO0_CLKCTRL) != PRCM_MOD_EN);
++}
++
++static void power_domain_transition_enable(void)
++{
++ /*
++ * Force power domain wake up transition
++ * Ensure that the corresponding interface clock is active before
++ * using the peripheral
++ */
++ __raw_writel(PRCM_FORCE_WAKEUP, CM_PER_L3_CLKSTCTRL);
++
++ __raw_writel(PRCM_FORCE_WAKEUP, CM_PER_L4LS_CLKSTCTRL);
++
++ __raw_writel(PRCM_FORCE_WAKEUP, CM_WKUP_CLKSTCTRL);
++
++ __raw_writel(PRCM_FORCE_WAKEUP, CM_PER_L4FW_CLKSTCTRL);
++
++ __raw_writel(PRCM_FORCE_WAKEUP, CM_PER_L3S_CLKSTCTRL);
++}
++
++/*
++ * Enable the module clock and the power domain for required peripherals
++ */
++static void per_clocks_enable(void)
++{
++ /* Enable the module clock */
++ __raw_writel(PRCM_MOD_EN, CM_PER_TIMER2_CLKCTRL);
++ while (__raw_readl(CM_PER_TIMER2_CLKCTRL) != PRCM_MOD_EN);
++
++ /* Select the Master osc 24 MHZ as Timer2 clock source */
++ __raw_writel(0x1, CLKSEL_TIMER2_CLK);
++
++ /* UART0 */
++ __raw_writel(PRCM_MOD_EN, CM_WKUP_UART0_CLKCTRL);
++ while (__raw_readl(CM_WKUP_UART0_CLKCTRL) != PRCM_MOD_EN);
++
++ /* UART3 */
++ __raw_writel(PRCM_MOD_EN, CM_PER_UART3_CLKCTRL);
++ while (__raw_readl(CM_PER_UART3_CLKCTRL) != PRCM_MOD_EN);
++
++ /* GPMC */
++ __raw_writel(PRCM_MOD_EN, CM_PER_GPMC_CLKCTRL);
++ while (__raw_readl(CM_PER_GPMC_CLKCTRL) != PRCM_MOD_EN);
++
++ /* ELM */
++ __raw_writel(PRCM_MOD_EN, CM_PER_ELM_CLKCTRL);
++ while (__raw_readl(CM_PER_ELM_CLKCTRL) != PRCM_MOD_EN);
++
++ /* i2c0 */
++ __raw_writel(PRCM_MOD_EN, CM_WKUP_I2C0_CLKCTRL);
++ while (__raw_readl(CM_WKUP_I2C0_CLKCTRL) != PRCM_MOD_EN);
++
++ /* i2c1 */
++ __raw_writel(PRCM_MOD_EN, CM_PER_I2C1_CLKCTRL);
++ while (__raw_readl(CM_PER_I2C1_CLKCTRL) != PRCM_MOD_EN);
++
++ /* i2c2 */
++ __raw_writel(PRCM_MOD_EN, CM_PER_I2C2_CLKCTRL);
++ while (__raw_readl(CM_PER_I2C2_CLKCTRL) != PRCM_MOD_EN);
++
++ /* Ethernet */
++ __raw_writel(PRCM_MOD_EN, CM_PER_CPGMAC0_CLKCTRL);
++ __raw_writel(PRCM_MOD_EN, CM_PER_CPSW_CLKSTCTRL);
++ while ((__raw_readl(CM_PER_CPGMAC0_CLKCTRL) & 0x30000) != 0x0);
++
++ /* MMC 0 & 1 */
++ __raw_writel(PRCM_MOD_EN, CM_PER_MMC0_CLKCTRL);
++ while (__raw_readl(CM_PER_MMC0_CLKCTRL) != PRCM_MOD_EN);
++ __raw_writel(PRCM_MOD_EN, CM_PER_MMC1_CLKCTRL);
++ while (__raw_readl(CM_PER_MMC1_CLKCTRL) != PRCM_MOD_EN);
++
++ /* Enable the control module though RBL would have done it*/
++ __raw_writel(PRCM_MOD_EN, CM_WKUP_CONTROL_CLKCTRL);
++ while (__raw_readl(CM_WKUP_CONTROL_CLKCTRL) != PRCM_MOD_EN);
++
++ /* SPI 0 & 1 */
++ __raw_writel(PRCM_MOD_EN, CM_PER_SPI0_CLKCTRL);
++ while (__raw_readl(CM_PER_SPI0_CLKCTRL) != PRCM_MOD_EN);
++
++ __raw_writel(PRCM_MOD_EN, CM_PER_SPI1_CLKCTRL);
++ while (__raw_readl(CM_PER_SPI1_CLKCTRL) != PRCM_MOD_EN);
++}
++
++void mpu_pll_config(int mpupll_M)
++{
++ u32 clkmode, clksel, div_m2;
++
++ clkmode = __raw_readl(CM_CLKMODE_DPLL_MPU);
++ clksel = __raw_readl(CM_CLKSEL_DPLL_MPU);
++ div_m2 = __raw_readl(CM_DIV_M2_DPLL_MPU);
++
++ /* Set the PLL to bypass Mode */
++ __raw_writel(PLL_BYPASS_MODE, CM_CLKMODE_DPLL_MPU);
++
++ while(__raw_readl(CM_IDLEST_DPLL_MPU) != 0x00000100);
++
++ clksel = clksel & (~0x7ffff);
++ clksel = clksel | ((mpupll_M << 0x8) | MPUPLL_N);
++ __raw_writel(clksel, CM_CLKSEL_DPLL_MPU);
++
++ div_m2 = div_m2 & ~0x1f;
++ div_m2 = div_m2 | MPUPLL_M2;
++ __raw_writel(div_m2, CM_DIV_M2_DPLL_MPU);
++
++ clkmode = clkmode | 0x7;
++ __raw_writel(clkmode, CM_CLKMODE_DPLL_MPU);
++
++ while(__raw_readl(CM_IDLEST_DPLL_MPU) != 0x1);
++}
++
++static void core_pll_config(void)
++{
++ u32 clkmode, clksel, div_m4, div_m5, div_m6;
++
++ clkmode = __raw_readl(CM_CLKMODE_DPLL_CORE);
++ clksel = __raw_readl(CM_CLKSEL_DPLL_CORE);
++ div_m4 = __raw_readl(CM_DIV_M4_DPLL_CORE);
++ div_m5 = __raw_readl(CM_DIV_M5_DPLL_CORE);
++ div_m6 = __raw_readl(CM_DIV_M6_DPLL_CORE);
++
++ /* Set the PLL to bypass Mode */
++ __raw_writel(PLL_BYPASS_MODE, CM_CLKMODE_DPLL_CORE);
++
++ while(__raw_readl(CM_IDLEST_DPLL_CORE) != 0x00000100);
++
++ clksel = clksel & (~0x7ffff);
++ clksel = clksel | ((COREPLL_M << 0x8) | COREPLL_N);
++ __raw_writel(clksel, CM_CLKSEL_DPLL_CORE);
++
++ div_m4 = div_m4 & ~0x1f;
++ div_m4 = div_m4 | COREPLL_M4;
++ __raw_writel(div_m4, CM_DIV_M4_DPLL_CORE);
++
++ div_m5 = div_m5 & ~0x1f;
++ div_m5 = div_m5 | COREPLL_M5;
++ __raw_writel(div_m5, CM_DIV_M5_DPLL_CORE);
++
++ div_m6 = div_m6 & ~0x1f;
++ div_m6 = div_m6 | COREPLL_M6;
++ __raw_writel(div_m6, CM_DIV_M6_DPLL_CORE);
++
++
++ clkmode = clkmode | 0x7;
++ __raw_writel(clkmode, CM_CLKMODE_DPLL_CORE);
++
++ while(__raw_readl(CM_IDLEST_DPLL_CORE) != 0x1);
++}
++
++static void per_pll_config(void)
++{
++ u32 clkmode, clksel, div_m2;
++
++ clkmode = __raw_readl(CM_CLKMODE_DPLL_PER);
++ clksel = __raw_readl(CM_CLKSEL_DPLL_PER);
++ div_m2 = __raw_readl(CM_DIV_M2_DPLL_PER);
++
++ /* Set the PLL to bypass Mode */
++ __raw_writel(PLL_BYPASS_MODE, CM_CLKMODE_DPLL_PER);
++
++ while(__raw_readl(CM_IDLEST_DPLL_PER) != 0x00000100);
++
++ clksel = clksel & (~0x7ffff);
++ clksel = clksel | ((PERPLL_M << 0x8) | PERPLL_N);
++ __raw_writel(clksel, CM_CLKSEL_DPLL_PER);
++
++ div_m2 = div_m2 & ~0x7f;
++ div_m2 = div_m2 | PERPLL_M2;
++ __raw_writel(div_m2, CM_DIV_M2_DPLL_PER);
++
++ clkmode = clkmode | 0x7;
++ __raw_writel(clkmode, CM_CLKMODE_DPLL_PER);
++
++ while(__raw_readl(CM_IDLEST_DPLL_PER) != 0x1);
++}
++
++static void ddr_pll_config(void)
++{
++ u32 clkmode, clksel, div_m2;
++
++ clkmode = __raw_readl(CM_CLKMODE_DPLL_DDR);
++ clksel = __raw_readl(CM_CLKSEL_DPLL_DDR);
++ div_m2 = __raw_readl(CM_DIV_M2_DPLL_DDR);
++
++ /* Set the PLL to bypass Mode */
++ clkmode = (clkmode & 0xfffffff8) | 0x00000004;
++ __raw_writel(clkmode, CM_CLKMODE_DPLL_DDR);
++
++ while ((__raw_readl(CM_IDLEST_DPLL_DDR) & 0x00000100) != 0x00000100);
++
++ clksel = clksel & (~0x7ffff);
++ clksel = clksel | ((DDRPLL_M << 0x8) | DDRPLL_N);
++ __raw_writel(clksel, CM_CLKSEL_DPLL_DDR);
++
++ div_m2 = div_m2 & 0xFFFFFFE0;
++ div_m2 = div_m2 | DDRPLL_M2;
++ __raw_writel(div_m2, CM_DIV_M2_DPLL_DDR);
++
++ clkmode = (clkmode & 0xfffffff8) | 0x7;
++ __raw_writel(clkmode, CM_CLKMODE_DPLL_DDR);
++
++ while ((__raw_readl(CM_IDLEST_DPLL_DDR) & 0x00000001) != 0x1);
++}
++
++void enable_ddr_clocks(void)
++{
++ /* Enable the EMIF_FW Functional clock */
++ __raw_writel(PRCM_MOD_EN, CM_PER_EMIF_FW_CLKCTRL);
++ /* Enable EMIF0 Clock */
++ __raw_writel(PRCM_MOD_EN, CM_PER_EMIF_CLKCTRL);
++ /* Poll for emif_gclk & L3_G clock are active */
++ while ((__raw_readl(CM_PER_L3_CLKSTCTRL) & (PRCM_EMIF_CLK_ACTIVITY |
++ PRCM_L3_GCLK_ACTIVITY)) != (PRCM_EMIF_CLK_ACTIVITY |
++ PRCM_L3_GCLK_ACTIVITY));
++ /* Poll if module is functional */
++ while ((__raw_readl(CM_PER_EMIF_CLKCTRL)) != PRCM_MOD_EN);
++
++}
++
++/*
++ * Configure the PLL/PRCM for necessary peripherals
++ */
++void pll_init()
++{
++ mpu_pll_config(MPUPLL_M_500);
++ core_pll_config();
++ per_pll_config();
++ ddr_pll_config();
++ /* Enable the required interconnect clocks */
++ interface_clocks_enable();
++ /* Enable power domain transition */
++ power_domain_transition_enable();
++ /* Enable the required peripherals */
++ per_clocks_enable();
++}
+diff --git a/arch/arm/configs/am335x_beaglebone_defconfig b/arch/arm/configs/am335x_beaglebone_defconfig
+new file mode 100644
+index 0000000..a4279f1
+--- /dev/null
++++ b/arch/arm/configs/am335x_beaglebone_defconfig
+@@ -0,0 +1,58 @@
++CONFIG_ARCH_OMAP=y
++# CONFIG_OMAP3_CLOCK_CONFIG is not set
++# CONFIG_OMAP_GPMC is not set
++CONFIG_MACH_BEAGLEBONE=y
++CONFIG_AEABI=y
++CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
++CONFIG_ARM_UNWIND=y
++CONFIG_MMU=y
++CONFIG_TEXT_BASE=0x81000000
++CONFIG_KALLSYMS=y
++CONFIG_PROMPT="barebox> "
++CONFIG_LONGHELP=y
++CONFIG_HUSH_FANCY_PROMPT=y
++CONFIG_CMDLINE_EDITING=y
++CONFIG_AUTO_COMPLETE=y
++CONFIG_MENU=y
++# CONFIG_TIMESTAMP is not set
++CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
++CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/beaglebone/env"
++CONFIG_CMD_EDIT=y
++CONFIG_CMD_SLEEP=y
++CONFIG_CMD_SAVEENV=y
++CONFIG_CMD_EXPORT=y
++CONFIG_CMD_PRINTENV=y
++CONFIG_CMD_READLINE=y
++CONFIG_CMD_MENU=y
++CONFIG_CMD_MENU_MANAGEMENT=y
++CONFIG_CMD_TIME=y
++CONFIG_CMD_BASENAME=y
++CONFIG_CMD_DIRNAME=y
++CONFIG_CMD_ECHO_E=y
++CONFIG_CMD_MEMINFO=y
++CONFIG_CMD_CRC=y
++CONFIG_CMD_CRC_CMP=y
++CONFIG_CMD_BOOTM_SHOW_TYPE=y
++CONFIG_CMD_BOOTM_VERBOSE=y
++CONFIG_CMD_BOOTM_INITRD=y
++CONFIG_CMD_BOOTM_OFTREE=y
++CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
++CONFIG_CMD_UIMAGE=y
++CONFIG_CMD_RESET=y
++CONFIG_CMD_GO=y
++CONFIG_CMD_OFTREE=y
++CONFIG_CMD_TIMEOUT=y
++CONFIG_CMD_PARTITION=y
++CONFIG_CMD_MAGICVAR=y
++CONFIG_CMD_MAGICVAR_HELP=y
++CONFIG_CMD_GPIO=y
++CONFIG_CMD_UNCOMPRESS=y
++CONFIG_DRIVER_SERIAL_NS16550=y
++CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS=y
++# CONFIG_SPI is not set
++CONFIG_MCI=y
++CONFIG_MCI_STARTUP=y
++CONFIG_MCI_OMAP_HSMMC=y
++CONFIG_FS_FAT=y
++CONFIG_FS_FAT_WRITE=y
++CONFIG_FS_FAT_LFN=y
+diff --git a/arch/arm/configs/am335x_beaglebone_mlo_large_defconfig b/arch/arm/configs/am335x_beaglebone_mlo_large_defconfig
+new file mode 100644
+index 0000000..0a2d3a8
+--- /dev/null
++++ b/arch/arm/configs/am335x_beaglebone_mlo_large_defconfig
+@@ -0,0 +1,50 @@
++CONFIG_ARCH_OMAP=y
++# CONFIG_OMAP3_CLOCK_CONFIG is not set
++# CONFIG_OMAP_GPMC is not set
++CONFIG_OMAP_BUILD_IFT=y
++CONFIG_MACH_BEAGLEBONE=y
++CONFIG_AEABI=y
++CONFIG_THUMB2_BAREBOX=y
++CONFIG_MMU=y
++CONFIG_TEXT_BASE=0x402F0400
++CONFIG_MEMORY_LAYOUT_FIXED=y
++CONFIG_STACK_BASE=0x4030B800
++CONFIG_STACK_SIZE=0x1600
++CONFIG_MALLOC_BASE=0x8F000000
++CONFIG_MALLOC_SIZE=0x1000000
++CONFIG_PROMPT="MLO>"
++CONFIG_LONGHELP=y
++# CONFIG_ERRNO_MESSAGES is not set
++# CONFIG_TIMESTAMP is not set
++CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
++CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/beaglebone/env"
++CONFIG_CMD_EXPORT=y
++# CONFIG_CMD_RM is not set
++# CONFIG_CMD_CAT is not set
++# CONFIG_CMD_RMDIR is not set
++# CONFIG_CMD_CP is not set
++# CONFIG_CMD_PWD is not set
++# CONFIG_CMD_CD is not set
++# CONFIG_CMD_UMOUNT is not set
++# CONFIG_CMD_CLEAR is not set
++CONFIG_CMD_LOADB=y
++CONFIG_CMD_LOADY=y
++CONFIG_CMD_BOOTM_SHOW_TYPE=y
++CONFIG_CMD_BOOTM_VERBOSE=y
++CONFIG_CMD_BOOTM_INITRD=y
++CONFIG_CMD_BOOTM_OFTREE=y
++CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
++# CONFIG_CMD_BOOTZ is not set
++# CONFIG_CMD_BOOTU is not set
++CONFIG_CMD_GO=y
++CONFIG_CMD_TIMEOUT=y
++# CONFIG_CMD_VERSION is not set
++# CONFIG_CMD_HELP is not set
++CONFIG_DRIVER_SERIAL_NS16550=y
++CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS=y
++# CONFIG_SPI is not set
++CONFIG_MCI=y
++CONFIG_MCI_STARTUP=y
++CONFIG_MCI_OMAP_HSMMC=y
++CONFIG_FS_FAT=y
++CONFIG_FS_FAT_LFN=y
+diff --git a/arch/arm/configs/am335x_beaglebone_mlo_small_defconfig b/arch/arm/configs/am335x_beaglebone_mlo_small_defconfig
+new file mode 100644
+index 0000000..162e893
+--- /dev/null
++++ b/arch/arm/configs/am335x_beaglebone_mlo_small_defconfig
+@@ -0,0 +1,32 @@
++CONFIG_ARCH_OMAP=y
++# CONFIG_OMAP3_CLOCK_CONFIG is not set
++# CONFIG_OMAP_GPMC is not set
++CONFIG_OMAP_BUILD_IFT=y
++CONFIG_MACH_BEAGLEBONE=y
++CONFIG_AEABI=y
++CONFIG_THUMB2_BAREBOX=y
++# CONFIG_CMD_ARM_CPUINFO is not set
++CONFIG_ENVIRONMENT_VARIABLES=y
++CONFIG_MMU=y
++CONFIG_TEXT_BASE=0x402F0400
++CONFIG_MEMORY_LAYOUT_FIXED=y
++CONFIG_STACK_BASE=0x4030B800
++CONFIG_STACK_SIZE=0x1600
++CONFIG_MALLOC_BASE=0x8F000000
++CONFIG_MALLOC_SIZE=0x1000000
++CONFIG_PROMPT="MLO>"
++CONFIG_LONGHELP=y
++CONFIG_SHELL_NONE=y
++# CONFIG_ERRNO_MESSAGES is not set
++# CONFIG_TIMESTAMP is not set
++# CONFIG_DEFAULT_ENVIRONMENT is not set
++CONFIG_DRIVER_SERIAL_NS16550=y
++CONFIG_DRIVER_SERIAL_NS16550_OMAP_EXTENSIONS=y
++# CONFIG_SPI is not set
++CONFIG_MCI=y
++CONFIG_MCI_STARTUP=y
++CONFIG_MCI_OMAP_HSMMC=y
++# CONFIG_FS_RAMFS is not set
++# CONFIG_FS_DEVFS is not set
++CONFIG_FS_FAT=y
++CONFIG_FS_FAT_LFN=y
+diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
+index 523179d..5505ed3 100644
+--- a/arch/arm/cpu/start.c
++++ b/arch/arm/cpu/start.c
+@@ -22,6 +22,7 @@
+
+ #include <common.h>
+ #include <init.h>
++#include <io.h>
+ #include <asm/barebox-arm.h>
+ #include <asm/barebox-arm-head.h>
+ #include <asm/system.h>
+@@ -66,16 +67,22 @@ void __naked __bare_init reset(void)
+ {
+ uint32_t r;
+
++ writel(0xFEED, 0x4030b000);
+ /* set the cpu to SVC32 mode */
+ __asm__ __volatile__("mrs %0, cpsr":"=r"(r));
+ r &= ~0x1f;
+ r |= 0xd3;
+ __asm__ __volatile__("msr cpsr, %0" : : "r"(r));
+
++ writel(0xFEED0000, 0x4030b000);
++ //writel(0x59, 0x44e09000);
++ writel(0xFEED0001, 0x4030b000);
++
+ #ifdef CONFIG_ARCH_HAS_LOWLEVEL_INIT
+- arch_init_lowlevel();
++//arch_init_lowlevel();
+ #endif
+
++ writel(0xFEED0010, 0x4030b000);
+ /* disable MMU stuff and caches */
+ r = get_cr();
+ r &= ~(CR_M | CR_C | CR_B | CR_S | CR_R | CR_V);
+@@ -87,13 +94,16 @@ void __naked __bare_init reset(void)
+ r |= CR_A;
+ #endif
+
++ writel(0xFEED0020, 0x4030b000);
+ #ifdef __ARMEB__
+ r |= CR_B;
+ #endif
+ set_cr(r);
++ writel(0xFEED0030, 0x4030b000);
+
+ #ifdef CONFIG_MACH_DO_LOWLEVEL_INIT
+ board_init_lowlevel();
++ writel(0xFEED0040, 0x4030b000);
+ #endif
+ board_init_lowlevel_return();
+ }
+@@ -112,6 +122,7 @@ void __naked __section(.text_ll_return) board_init_lowlevel_return(void)
+ */
+ __asm__ __volatile__("1: adr %0, 1b":"=r"(addr));
+
++ writel(0xFEED0050, 0x4030b000);
+ /* Setup the stack */
+ r = STACK_BASE + STACK_SIZE - 16;
+ __asm__ __volatile__("mov sp, %0" : : "r"(r));
+@@ -131,6 +142,7 @@ void __naked __section(.text_ll_return) board_init_lowlevel_return(void)
+ __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
+
+ /* call start_barebox with its absolute address */
++ writel(0xFEED0060, 0x4030b000);
+ r = (unsigned int)&start_barebox;
+ __asm__ __volatile__("mov pc, %0" : : "r"(r));
+ }
+diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig
+index 386c484..117b1cf 100644
+--- a/arch/arm/mach-omap/Kconfig
++++ b/arch/arm/mach-omap/Kconfig
+@@ -98,7 +98,8 @@ config ARCH_TEXT_BASE
+
+ config BOARDINFO
+ default "Texas Instrument's SDP343x" if MACH_OMAP343xSDP
+- default "Texas Instrument's Beagle" if MACH_BEAGLE
++ default "Texas Instrument's Beagle Board" if MACH_BEAGLE
++ default "Texas Instrument's Beagle Bone" if MACH_BEAGLEBONE
+ default "Texas Instrument's OMAP3EVM" if MACH_OMAP3EVM
+ default "Texas Instrument's Panda" if MACH_PANDA
+ default "Phytec phyCORE pcm049" if MACH_PCM049
+@@ -123,6 +124,14 @@ config MACH_BEAGLE
+ help
+ Say Y here if you are using Beagle Board
+
++config MACH_BEAGLEBONE
++ bool "Texas Instrument's Beagle Bone"
++ select OMAP_CLOCK_ALL
++ select HAVE_NOSHELL
++ depends on ARCH_OMAP3
++ help
++ Say Y here if you are using Beagle Bone
++
+ config MACH_OMAP3EVM
+ bool "Texas Instrument's OMAP3 EVM"
+ select OMAP_CLOCK_ALL
+diff --git a/arch/arm/mach-omap/omap3_generic.c b/arch/arm/mach-omap/omap3_generic.c
+index 4ab265a..ccc4bdd 100644
+--- a/arch/arm/mach-omap/omap3_generic.c
++++ b/arch/arm/mach-omap/omap3_generic.c
+@@ -57,6 +57,7 @@
+ *
+ * @return void
+ */
++#if 0
+ void __noreturn reset_cpu(unsigned long addr)
+ {
+ writel(PRM_RSTCTRL_RESET, PRM_REG(RSTCTRL));
+@@ -64,6 +65,7 @@ void __noreturn reset_cpu(unsigned long addr)
+ while (1);
+ }
+ EXPORT_SYMBOL(reset_cpu);
++#endif
+
+ /**
+ * @brief Low level CPU type
+diff --git a/arch/arm/mach-omap/s32k_clksource.c b/arch/arm/mach-omap/s32k_clksource.c
+index 3ed9448..2c21fe7 100644
+--- a/arch/arm/mach-omap/s32k_clksource.c
++++ b/arch/arm/mach-omap/s32k_clksource.c
+@@ -50,7 +50,8 @@
+ */
+ static uint64_t s32k_clocksource_read(void)
+ {
+- return readl(S32K_CR);
++// return readl(S32K_CR);
++ return readl(0x44e0503c);
+ }
+
+ /* A bit obvious isn't it? */
+@@ -73,6 +74,8 @@ static int s32k_clocksource_init(void)
+ {
+ s32k_cs.mult = clocksource_hz2mult(S32K_FREQUENCY, s32k_cs.shift);
+
++ writel(0x00000003, 0x44e05038);
++
+ return init_clock(&s32k_cs);
+ }
+
+diff --git a/arch/arm/mach-omap/xload.c b/arch/arm/mach-omap/xload.c
+index 13024ab..29daaaf 100644
+--- a/arch/arm/mach-omap/xload.c
++++ b/arch/arm/mach-omap/xload.c
+@@ -56,7 +56,10 @@ void *omap_xload_boot_mmc(void)
+
+ enum omap_boot_src omap_bootsrc(void)
+ {
+-#if defined(CONFIG_ARCH_OMAP3)
++#if defined(CONFIG_MACH_BEAGLEBONE)
++ /* only support for MMC */
++ return OMAP_BOOTSRC_MMC1;
++#elif defined(CONFIG_ARCH_OMAP3)
+ return omap3_bootsrc();
+ #elif defined(CONFIG_ARCH_OMAP4)
+ return omap4_bootsrc();
+diff --git a/common/startup.c b/common/startup.c
+index abd1b77..4a2ef49 100644
+--- a/common/startup.c
++++ b/common/startup.c
+@@ -31,6 +31,7 @@
+ */
+ #include <common.h>
+ #include <init.h>
++#include <io.h>
+ #include <command.h>
+ #include <malloc.h>
+ #include <memory.h>
+@@ -122,10 +123,14 @@ void start_barebox (void)
+ for (initcall = __barebox_initcalls_start;
+ initcall < __barebox_initcalls_end; initcall++) {
+ debug("initcall-> %pS\n", *initcall);
++ writel(initcall, 0x4030b004);
++ writel(0xFEED0070, 0x4030b000);
+ result = (*initcall)();
+ debug("initcall<- %pS (%d)\n", *initcall, result);
+ }
+
++ //writel(r, 0x4030b004);
++ //writel(0xFEED02FF, 0x4030b000); while(1);
+ debug("initcalls done\n");
+
+ display_meminfo();
+--
+1.7.10.4
+
diff --git a/configs/platform-ti/patches/barebox-2012.07.0/series b/configs/platform-ti/patches/barebox-2012.07.0/series
new file mode 100644
index 0000000..636ae83
--- /dev/null
+++ b/configs/platform-ti/patches/barebox-2012.07.0/series
@@ -0,0 +1,2 @@
+0000-barebox-v2012.07.0-to-master.patch
+0001-WIP-beaglebone-add-support-for-AM335x-and-board.patch
diff --git a/configs/platform-ti/platformconfig b/configs/platform-ti/platformconfig
index 34129d9..31c5e33 100644
--- a/configs/platform-ti/platformconfig
+++ b/configs/platform-ti/platformconfig
@@ -126,26 +126,23 @@ PTXCONF_CONSOLE_SPEED="115200"
#
# PTXCONF_AT91BOOTSTRAP is not set
# PTXCONF_AT91BOOTSTRAP2 is not set
-# PTXCONF_BAREBOX is not set
-# PTXCONF_BAREBOX_MLO is not set
+PTXCONF_BAREBOX=y
+PTXCONF_BAREBOX_VERSION="2012.07.0"
+PTXCONF_BAREBOX_MD5="7d3293e72afe7726ac3d0f2b6fe961cf"
+PTXCONF_BAREBOX_CONFIG="barebox.config"
+PTXCONF_BAREBOX_ARCH_STRING="arm"
+# PTXCONF_BAREBOX_EXTRA_ENV is not set
+# PTXCONF_BAREBOX_BAREBOXENV is not set
+PTXCONF_BAREBOX_MLO=y
+PTXCONF_BAREBOX_MLO_VERSION="${PTXCONF_BAREBOX_VERSION}"
+PTXCONF_BAREBOX_MLO_MD5="${PTXCONF_BAREBOX_MD5}"
+PTXCONF_BAREBOX_MLO_ARCH_STRING="arm"
+PTXCONF_BAREBOX_MLO_CONFIG="barebox_mlo.config"
PTXCONF_BOOTLOADER=y
# PTXCONF_GRUB is not set
# PTXCONF_HOST_MXS_UTILS is not set
# PTXCONF_U_BOOT_V2 is not set
-PTXCONF_U_BOOT=y
-PTXCONF_U_BOOT_VERSION="2011.09"
-PTXCONF_U_BOOT_MD5="259017613713c01bd9bcc82edc153e4f"
-PTXCONF_U_BOOT_PROMPT="uboot> "
-PTXCONF_U_BOOT_SERIES="series"
-PTXCONF_U_BOOT_CONFIG="am335x_evm_config"
-
-#
-# target install
-#
-# PTXCONF_U_BOOT_INSTALL_SREC is not set
-# PTXCONF_U_BOOT_INSTALL_ELF is not set
-PTXCONF_U_BOOT_INSTALL_MLO=y
-PTXCONF_U_BOOT_INSTALL_U_BOOT_IMG=y
+# PTXCONF_U_BOOT is not set
# PTXCONF_X_LOAD is not set
#
diff --git a/configs/platform-ti/platforms/image-boot-mlo.in b/configs/platform-ti/platforms/image-boot-mlo.in
new file mode 100644
index 0000000..d2f5deb
--- /dev/null
+++ b/configs/platform-ti/platforms/image-boot-mlo.in
@@ -0,0 +1,12 @@
+## SECTION=image2
+
+config IMAGE_BOOT_MLO
+ tristate
+ select HOST_GENIMAGE
+ select IMAGE_VFAT_TOOLS
+ select BAREBOX
+ select BAREBOX_MLO
+ select KERNEL
+ prompt "Generate images/boot-mlo.vfat"
+ help
+ FIXME