summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2011-12-07 12:03:13 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2011-12-07 12:03:13 +0100
commit0ee6847f7b6d396d3756f6ecd0781a00b9cca980 (patch)
tree1f1bed639ac0bbc9091685538c791b4648f4c342
parent61b62f6d33d55c9b89ba8a6fbae84cb9c33e342a (diff)
parent8b3d10265da20b8be6138799cee704d53dee1c63 (diff)
downloadbarebox-0ee6847f7b6d396d3756f6ecd0781a00b9cca980.tar.gz
Merge branch 'next'
-rwxr-xr-xMAKEALL2
-rw-r--r--arch/arm/Kconfig5
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/boards/dss11/Makefile1
-rw-r--r--arch/arm/boards/dss11/config.h6
-rw-r--r--arch/arm/boards/dss11/env/config42
-rw-r--r--arch/arm/boards/dss11/init.c156
-rw-r--r--arch/arm/boards/eukrea_cpuimx25/env/bin/init_board2
-rw-r--r--arch/arm/boards/eukrea_cpuimx27/env/bin/init2
-rw-r--r--arch/arm/boards/eukrea_cpuimx35/env/bin/init_board2
-rw-r--r--arch/arm/boards/eukrea_cpuimx51/env/bin/init_board2
-rw-r--r--arch/arm/boards/freescale-mx53-loco/board.c36
-rw-r--r--arch/arm/boards/freescale-mx53-smd/Makefile2
-rw-r--r--arch/arm/boards/freescale-mx53-smd/board.c170
-rw-r--r--arch/arm/boards/freescale-mx53-smd/config.h (renamed from include/ata.h)29
-rw-r--r--arch/arm/boards/freescale-mx53-smd/env/config51
-rw-r--r--arch/arm/boards/freescale-mx53-smd/flash_header.c101
-rw-r--r--arch/arm/boards/freescale-mx53-smd/mx53-smd.dox4
-rw-r--r--arch/arm/boards/mini2440/mini2440.c2
-rw-r--r--arch/arm/boards/omap/board-beagle.c31
-rw-r--r--arch/arm/boards/panda/board.c19
-rw-r--r--arch/arm/boards/pcm049/board.c30
-rw-r--r--arch/arm/configs/at91rm9200ek_defconfig2
-rw-r--r--arch/arm/configs/at91sam9261ek_defconfig2
-rw-r--r--arch/arm/configs/at91sam9g10ek_defconfig2
-rw-r--r--arch/arm/configs/at91sam9m10g45ek_defconfig2
-rw-r--r--arch/arm/configs/cupid_defconfig2
-rw-r--r--arch/arm/configs/dss11_defconfig48
-rw-r--r--arch/arm/configs/eukrea_cpuimx25_defconfig2
-rw-r--r--arch/arm/configs/eukrea_cpuimx27_defconfig2
-rw-r--r--arch/arm/configs/eukrea_cpuimx35_defconfig2
-rw-r--r--arch/arm/configs/eukrea_cpuimx51_defconfig2
-rw-r--r--arch/arm/configs/freescale_mx35_3stack_defconfig2
-rw-r--r--arch/arm/configs/freescale_mx53_loco_defconfig2
-rw-r--r--arch/arm/configs/freescale_mx53_smd_defconfig51
-rw-r--r--arch/arm/configs/neso_defconfig2
-rw-r--r--arch/arm/configs/nhk8815_defconfig2
-rw-r--r--arch/arm/configs/omap3530_beagle_defconfig2
-rw-r--r--arch/arm/configs/panda_defconfig2
-rw-r--r--arch/arm/configs/pca100_defconfig2
-rw-r--r--arch/arm/configs/pcm037_defconfig2
-rw-r--r--arch/arm/configs/pcm043_defconfig2
-rw-r--r--arch/arm/configs/pcm049_defconfig2
-rw-r--r--arch/arm/configs/pm9261_defconfig2
-rw-r--r--arch/arm/configs/pm9g45_defconfig2
-rw-r--r--arch/arm/configs/scb9328_defconfig2
-rw-r--r--arch/arm/configs/versatilepb_defconfig2
-rw-r--r--arch/arm/cpu/Kconfig5
-rw-r--r--arch/arm/cpu/exceptions.S21
-rw-r--r--arch/arm/cpu/mmu.c6
-rw-r--r--arch/arm/lib/arm.c2
-rw-r--r--arch/arm/lib/armlinux.c108
-rw-r--r--arch/arm/lib/barebox.lds.S4
-rw-r--r--arch/arm/lib/bootm.c37
-rw-r--r--arch/arm/mach-at91/Kconfig8
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c41
-rw-r--r--arch/arm/mach-imx/Kconfig5
-rw-r--r--arch/arm/mach-imx/boot.c3
-rw-r--r--arch/arm/mach-imx/devices.c2
-rw-r--r--arch/arm/mach-imx/imx53.c9
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx25.h2
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx35.h6
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx51.h4
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx53.h15
-rw-r--r--arch/arm/mach-imx/include/mach/devices.h3
-rw-r--r--arch/arm/mach-imx/include/mach/esdhc.h43
-rw-r--r--arch/arm/mach-omap/Makefile3
-rw-r--r--arch/arm/mach-omap/xload.c41
-rw-r--r--arch/arm/mach-pxa/Kconfig37
-rw-r--r--arch/arm/mach-pxa/Makefile6
-rw-r--r--arch/arm/mach-pxa/clocksource.c45
-rw-r--r--arch/arm/mach-pxa/common.c37
-rw-r--r--arch/arm/mach-pxa/devices.c49
-rw-r--r--arch/arm/mach-pxa/gpio.c68
-rw-r--r--arch/arm/mach-pxa/include/mach/clock.h16
-rw-r--r--arch/arm/mach-pxa/include/mach/devices.h26
-rw-r--r--arch/arm/mach-pxa/include/mach/gpio.h132
-rw-r--r--arch/arm/mach-pxa/include/mach/hardware.h31
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa27x.h438
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h133
-rw-r--r--arch/arm/mach-pxa/include/mach/mfp.h21
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa-regs.h33
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa27x-regs.h6
-rw-r--r--arch/arm/mach-pxa/include/mach/pxa2xx-regs.h267
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-intc.h34
-rw-r--r--arch/arm/mach-pxa/include/mach/regs-ost.h34
-rw-r--r--arch/arm/mach-pxa/include/mach/udc_pxa2xx.h26
-rw-r--r--arch/arm/mach-pxa/include/plat/gpio.h74
-rw-r--r--arch/arm/mach-pxa/include/plat/mfp.h468
-rw-r--r--arch/arm/mach-pxa/mfp-pxa2xx.c189
-rw-r--r--arch/arm/mach-pxa/speed-pxa27x.c20
-rw-r--r--arch/arm/tools/mach-types473
-rw-r--r--arch/blackfin/boards/ipe337/barebox.lds.S4
-rw-r--r--arch/blackfin/lib/blackfin_linux.c3
-rw-r--r--arch/blackfin/lib/board.c2
-rw-r--r--arch/mips/configs/dlink-dir-320_defconfig2
-rw-r--r--arch/mips/configs/qemu-malta_defconfig2
-rw-r--r--arch/mips/lib/barebox.lds.S4
-rw-r--r--arch/mips/lib/memory.c2
-rw-r--r--arch/nios2/cpu/Makefile1
-rw-r--r--arch/nios2/cpu/barebox.lds.S4
-rw-r--r--arch/nios2/cpu/cpu.c3
-rw-r--r--arch/nios2/cpu/exceptions.S9
-rw-r--r--arch/nios2/cpu/interrupts.c140
-rw-r--r--arch/nios2/include/asm/spi.h1
-rw-r--r--arch/nios2/lib/board.c5
-rw-r--r--arch/nios2/lib/bootm.c7
-rw-r--r--arch/ppc/boards/pcm030/barebox.lds.S4
-rw-r--r--arch/ppc/lib/Makefile1
-rw-r--r--arch/ppc/lib/board.c9
-rw-r--r--arch/ppc/lib/interrupts.c133
-rw-r--r--arch/ppc/lib/ppclinux.c3
-rw-r--r--arch/ppc/mach-mpc5xxx/Makefile1
-rw-r--r--arch/ppc/mach-mpc5xxx/interrupts.c349
-rw-r--r--arch/ppc/mach-mpc5xxx/start.S9
-rw-r--r--arch/sandbox/Makefile13
-rw-r--r--arch/sandbox/board/barebox.lds.S5
-rw-r--r--arch/sandbox/include/asm/elf.h11
-rw-r--r--arch/sandbox/mach-sandbox/include/mach/linux.h2
-rw-r--r--arch/sandbox/os/common.c32
-rw-r--r--arch/x86/lib/barebox.lds.S9
-rw-r--r--arch/x86/lib/memory.c4
-rw-r--r--commands/Kconfig55
-rw-r--r--commands/Makefile6
-rw-r--r--commands/bootm.c340
-rw-r--r--commands/cp.c26
-rw-r--r--commands/iminfo.c71
-rw-r--r--commands/iomem.c56
-rw-r--r--commands/magicvar.c20
-rw-r--r--commands/uncompress.c (renamed from commands/unlzo.c)23
-rw-r--r--common/Kconfig18
-rw-r--r--common/Makefile4
-rw-r--r--common/console.c24
-rw-r--r--common/console_simple.c4
-rw-r--r--common/env.c22
-rw-r--r--common/filetype.c99
-rw-r--r--common/hush.c8
-rw-r--r--common/image.c3
-rw-r--r--common/memory.c58
-rw-r--r--common/partitions.c200
-rw-r--r--common/resource.c121
-rw-r--r--crypto/Kconfig3
-rw-r--r--crypto/Makefile1
-rw-r--r--crypto/crc7.c63
-rw-r--r--defaultenv/bin/boot2
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/ata/Kconfig41
-rw-r--r--drivers/ata/Makefile5
-rw-r--r--drivers/ata/disk_ata_drive.c618
-rw-r--r--drivers/ata/disk_bios_drive.c (renamed from drivers/ata/bios.c)102
-rw-r--r--drivers/ata/disk_drive.c248
-rw-r--r--drivers/ata/intf_platform_ide.c130
-rw-r--r--drivers/base/driver.c29
-rw-r--r--drivers/mci/Kconfig23
-rw-r--r--drivers/mci/Makefile1
-rw-r--r--drivers/mci/atmel_mci.c2
-rw-r--r--drivers/mci/imx-esdhc.c41
-rw-r--r--drivers/mci/mci-core.c264
-rw-r--r--drivers/mci/mci_spi.c430
-rw-r--r--drivers/mtd/nand/nand_base.c8
-rw-r--r--drivers/net/macb.c13
-rw-r--r--drivers/serial/Kconfig4
-rw-r--r--drivers/serial/Makefile1
-rw-r--r--drivers/serial/serial_pxa.c201
-rw-r--r--drivers/spi/altera_spi.c27
-rw-r--r--drivers/usb/gadget/Kconfig7
-rw-r--r--drivers/usb/gadget/Makefile1
-rw-r--r--drivers/usb/gadget/dfu.c2
-rw-r--r--drivers/usb/gadget/f_serial.c5
-rw-r--r--drivers/usb/gadget/pxa27x_udc.c1524
-rw-r--r--drivers/usb/gadget/pxa27x_udc.h393
-rw-r--r--drivers/usb/gadget/u_serial.c27
-rw-r--r--drivers/usb/storage/Kconfig1
-rw-r--r--drivers/usb/storage/usb.c130
-rw-r--r--drivers/usb/storage/usb.h8
-rw-r--r--fs/cramfs/cramfs.c2
-rw-r--r--fs/cramfs/uncompress.c93
-rw-r--r--fs/devfs-core.c14
-rw-r--r--fs/ramfs.c2
-rw-r--r--include/asm-generic/barebox.lds.h2
-rw-r--r--include/ata_drive.h100
-rw-r--r--include/boot.h6
-rw-r--r--include/bunzip2.h10
-rw-r--r--include/bzlib.h329
-rw-r--r--include/common.h23
-rw-r--r--include/console.h1
-rw-r--r--include/cramfs/cramfs_fs.h4
-rw-r--r--include/crc7.h14
-rw-r--r--include/disks.h41
-rw-r--r--include/driver.h7
-rw-r--r--include/environment.h3
-rw-r--r--include/filetype.h23
-rw-r--r--include/gunzip.h10
-rw-r--r--include/image.h3
-rw-r--r--include/libbb.h2
-rw-r--r--include/linux/ioport.h14
-rw-r--r--include/linux/zconf.h57
-rw-r--r--include/linux/zlib.h711
-rw-r--r--include/linux/zutil.h106
-rw-r--r--include/lzo.h6
-rw-r--r--include/magicvar.h32
-rw-r--r--include/mci.h21
-rw-r--r--include/memory.h5
-rw-r--r--include/platform_ide.h32
-rw-r--r--include/uncompress.h19
-rw-r--r--include/zlib.h434
-rw-r--r--lib/Kconfig6
-rw-r--r--lib/Makefile5
-rw-r--r--lib/bzlib.c1592
-rw-r--r--lib/bzlib_crctable.c145
-rw-r--r--lib/bzlib_decompress.c674
-rw-r--r--lib/bzlib_huffman.c229
-rw-r--r--lib/bzlib_randtable.c126
-rw-r--r--lib/copy_file.c21
-rw-r--r--lib/decompress_bunzip2.c756
-rw-r--r--lib/decompress_inflate.c183
-rw-r--r--lib/decompress_unlzo.c27
-rw-r--r--lib/gunzip.c85
-rw-r--r--lib/lzo/Kconfig1
-rw-r--r--lib/uncompress.c159
-rw-r--r--lib/vsprintf.c2
-rw-r--r--lib/zlib.c2158
-rw-r--r--lib/zlib_inflate/Makefile18
-rw-r--r--lib/zlib_inflate/inffast.c363
-rw-r--r--lib/zlib_inflate/inffast.h11
-rw-r--r--lib/zlib_inflate/inffixed.h94
-rw-r--r--lib/zlib_inflate/inflate.c918
-rw-r--r--lib/zlib_inflate/inflate.h111
-rw-r--r--lib/zlib_inflate/inftrees.c315
-rw-r--r--lib/zlib_inflate/inftrees.h59
-rw-r--r--lib/zlib_inflate/infutil.c47
-rw-r--r--lib/zlib_inflate/infutil.h25
-rw-r--r--lib/zlib_inflate/modules.builtin1
-rw-r--r--net/dhcp.c6
-rw-r--r--scripts/mkimage.c1
235 files changed, 12741 insertions, 7687 deletions
diff --git a/MAKEALL b/MAKEALL
index e987de2..25b9977 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -234,7 +234,7 @@ then
CONFIG="./${CONFIG}"
fi
- source "${CONFIG}"
+ . "${CONFIG}"
fi
[ -d "${LOGDIR}" ] || mkdir ${LOGDIR} || exit 1
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b15728e..40677a3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -62,6 +62,10 @@ config ARCH_NOMADIK
config ARCH_OMAP
bool "TI OMAP"
+config ARCH_PXA
+ bool "Intel/Marvell PXA based"
+ select GENERIC_GPIO
+
config ARCH_S3C24xx
bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
select CPU_ARM920T
@@ -81,6 +85,7 @@ source arch/arm/mach-mxs/Kconfig
source arch/arm/mach-netx/Kconfig
source arch/arm/mach-nomadik/Kconfig
source arch/arm/mach-omap/Kconfig
+source arch/arm/mach-pxa/Kconfig
source arch/arm/mach-s3c24xx/Kconfig
source arch/arm/mach-versatile/Kconfig
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 0c42f3d..e5e951c 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -27,6 +27,7 @@ arch-$(CONFIG_CPU_32v4T) :=-D__LINUX_ARM_ARCH__=4 -march=armv4t
# This selects how we optimise for the processor.
tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi
tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
+tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
ifeq ($(CONFIG_AEABI),y)
CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork
@@ -50,6 +51,7 @@ machine-$(CONFIG_ARCH_MXS) := mxs
machine-$(CONFIG_ARCH_NOMADIK) := nomadik
machine-$(CONFIG_ARCH_NETX) := netx
machine-$(CONFIG_ARCH_OMAP) := omap
+machine-$(CONFIG_ARCH_PXA) := pxa
machine-$(CONFIG_ARCH_S3C24xx) := s3c24xx
machine-$(CONFIG_ARCH_VERSATILE) := versatile
@@ -64,6 +66,7 @@ board-$(CONFIG_MACH_AT91SAM9263EK) := at91sam9263ek
board-$(CONFIG_MACH_AT91SAM9G10EK) := at91sam9261ek
board-$(CONFIG_MACH_AT91SAM9G20EK) := at91sam9260ek
board-$(CONFIG_MACH_AT91SAM9M10G45EK) := at91sam9m10g45ek
+board-$(CONFIG_MACH_DSS11) := dss11
board-$(CONFIG_MACH_EDB9301) := edb93xx
board-$(CONFIG_MACH_EDB9302) := edb93xx
board-$(CONFIG_MACH_EDB9302A) := edb93xx
@@ -103,6 +106,7 @@ board-$(CONFIG_MACH_CHUMBY) := chumby_falconwing
board-$(CONFIG_MACH_TX28) := karo-tx28
board-$(CONFIG_MACH_FREESCALE_MX51_PDK) := freescale-mx51-pdk
board-$(CONFIG_MACH_FREESCALE_MX53_LOCO) := freescale-mx53-loco
+board-$(CONFIG_MACH_FREESCALE_MX53_SMD) := freescale-mx53-smd
board-$(CONFIG_MACH_GUF_CUPID) := guf-cupid
board-$(CONFIG_MACH_MINI2440) := mini2440
board-$(CONFIG_MACH_USB_A9260) := usb-a926x
diff --git a/arch/arm/boards/dss11/Makefile b/arch/arm/boards/dss11/Makefile
new file mode 100644
index 0000000..eb072c0
--- /dev/null
+++ b/arch/arm/boards/dss11/Makefile
@@ -0,0 +1 @@
+obj-y += init.o
diff --git a/arch/arm/boards/dss11/config.h b/arch/arm/boards/dss11/config.h
new file mode 100644
index 0000000..006820c
--- /dev/null
+++ b/arch/arm/boards/dss11/config.h
@@ -0,0 +1,6 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define AT91_MAIN_CLOCK 18432000 /* 18.432 MHz crystal */
+
+#endif /* __CONFIG_H */
diff --git a/arch/arm/boards/dss11/env/config b/arch/arm/boards/dss11/env/config
new file mode 100644
index 0000000..5c9be7d
--- /dev/null
+++ b/arch/arm/boards/dss11/env/config
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'none' if you want to skip kernel ip autoconfiguration
+ip=dhcp
+
+# 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=tftp
+# can be either 'net', 'nand' or 'initrd'
+rootfs_loc=net
+
+# can be either 'jffs2' or 'ubifs'
+rootfs_type=ubifs
+rootfsimage=root.$rootfs_type
+
+# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo
+#kernelimage_type=zimage
+#kernelimage=zImage
+kernelimage_type=uimage
+kernelimage=uImage
+#kernelimage_type=raw
+#kernelimage=Image
+#kernelimage_type=raw_lzo
+#kernelimage=Image.lzo
+
+nand_device=atmel_nand
+nand_parts="128k(bootstrap),512k(barebox)ro,512k(barebox-env),2M(kernel-rescue),2M(kernel-prod),32M(rootfs-rescue),200M(rootfs-prod),-(config)"
+rootfs_mtdblock_nand=4
+
+autoboot_timeout=3
+
+bootargs="console=ttyS0,115200"
+
+# 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/dss11/init.c b/arch/arm/boards/dss11/init.c
new file mode 100644
index 0000000..96c4eef
--- /dev/null
+++ b/arch/arm/boards/dss11/init.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2011 Michael Grzeschik <mgr@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 <net.h>
+#include <mci.h>
+#include <init.h>
+#include <environment.h>
+#include <fec.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <partition.h>
+#include <fs.h>
+#include <fcntl.h>
+#include <asm/io.h>
+#include <asm/hardware.h>
+#include <nand.h>
+#include <linux/mtd/nand.h>
+#include <mach/board.h>
+#include <mach/at91sam9_smc.h>
+#include <mach/sam9_smc.h>
+#include <gpio.h>
+#include <mach/io.h>
+#include <mach/at91_pmc.h>
+#include <mach/at91_rstc.h>
+
+static struct atmel_nand_data nand_pdata = {
+ .ale = 21,
+ .cle = 22,
+/* .det_pin = ... not connected */
+ .ecc_mode = NAND_ECC_HW,
+ .rdy_pin = AT91_PIN_PC13,
+ .enable_pin = AT91_PIN_PC14,
+ .bus_width_16 = 1,
+};
+
+static struct sam9_smc_config dss11_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 1,
+ .ncs_write_setup = 0,
+ .nwe_setup = 1,
+
+ .ncs_read_pulse = 3,
+ .nrd_pulse = 3,
+ .ncs_write_pulse = 3,
+ .nwe_pulse = 3,
+
+ .read_cycle = 5,
+ .write_cycle = 5,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
+ .tdf_cycles = 2,
+};
+
+static void dss11_add_device_nand(void)
+{
+ /* setup bus-width (16) */
+ dss11_nand_smc_config.mode |= AT91_SMC_DBW_16;
+
+ /* configure chip-select 3 (NAND) */
+ sam9_smc_configure(3, &dss11_nand_smc_config);
+
+ at91_add_device_nand(&nand_pdata);
+}
+
+static struct at91_ether_platform_data macb_pdata = {
+ .phy_addr = 0,
+ .flags = AT91SAM_ETX2_ETX3_ALTERNATIVE,
+};
+
+static void dss11_phy_reset(void)
+{
+ unsigned long rstc;
+ at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_EMAC);
+
+ at91_set_gpio_input(AT91_PIN_PA14, 0);
+ at91_set_gpio_input(AT91_PIN_PA15, 0);
+ at91_set_gpio_input(AT91_PIN_PA17, 0);
+ at91_set_gpio_input(AT91_PIN_PA25, 0);
+ at91_set_gpio_input(AT91_PIN_PA26, 0);
+ at91_set_gpio_input(AT91_PIN_PA28, 0);
+
+ rstc = at91_sys_read(AT91_RSTC_MR) & AT91_RSTC_ERSTL;
+
+ /* Need to reset PHY -> 500ms reset */
+ at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
+ (AT91_RSTC_ERSTL & (0x0d << 8)) |
+ AT91_RSTC_URSTEN);
+
+ at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_EXTRST);
+
+ /* Wait for end hardware reset */
+ while (!(at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_NRSTL));
+
+ /* Restore NRST value */
+ at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
+ (rstc) |
+ AT91_RSTC_URSTEN);
+}
+
+static struct atmel_mci_platform_data dss11_mci_data = {
+ .bus_width = 4,
+ .host_caps = MMC_MODE_HS,
+};
+
+static struct at91_usbh_data dss11_usbh_data = {
+ .ports = 2,
+};
+
+static int dss11_mem_init(void)
+{
+ at91_add_device_sdram(64 * 1024 * 1024);
+
+ return 0;
+}
+mem_initcall(dss11_mem_init);
+
+static int dss11_devices_init(void)
+{
+ dss11_add_device_nand();
+ dss11_phy_reset();
+ at91_add_device_eth(&macb_pdata);
+ at91_add_device_mci(1, &dss11_mci_data);
+ at91_add_device_usbh_ohci(&dss11_usbh_data);
+
+ armlinux_set_bootparams((void *)(AT91_CHIPSELECT_1 + 0x100));
+ armlinux_set_architecture(MACH_TYPE_DSS11);
+
+ devfs_add_partition("nand0", 0x00000, 0x20000, PARTITION_FIXED, "bootstrap");
+ dev_add_bb_dev("bootstrap", "bootstrap.bb");
+ devfs_add_partition("nand0", 0x20000, 0x40000, PARTITION_FIXED, "barebox");
+ dev_add_bb_dev("barebox", "barebox.bb");
+ devfs_add_partition("nand0", 0x60000, 0x40000, PARTITION_FIXED, "barebox-env");
+ dev_add_bb_dev("barebox-env", "env0");
+
+ return 0;
+}
+device_initcall(dss11_devices_init);
+
+static int dss11_console_init(void)
+{
+ at91_register_uart(0, 0);
+ return 0;
+}
+console_initcall(dss11_console_init);
diff --git a/arch/arm/boards/eukrea_cpuimx25/env/bin/init_board b/arch/arm/boards/eukrea_cpuimx25/env/bin/init_board
index 72b4ab3..2199b88 100644
--- a/arch/arm/boards/eukrea_cpuimx25/env/bin/init_board
+++ b/arch/arm/boards/eukrea_cpuimx25/env/bin/init_board
@@ -4,7 +4,7 @@ if [ -f /env/logo.bmp ]; then
bmp /env/logo.bmp
fb0.enable=1
elif [ -f /env/logo.bmp.lzo ]; then
- unlzo /env/logo.bmp.lzo /logo.bmp
+ uncompress /env/logo.bmp.lzo /logo.bmp
bmp /logo.bmp
fb0.enable=1
fi
diff --git a/arch/arm/boards/eukrea_cpuimx27/env/bin/init b/arch/arm/boards/eukrea_cpuimx27/env/bin/init
index aefd67c..f84ace9 100644
--- a/arch/arm/boards/eukrea_cpuimx27/env/bin/init
+++ b/arch/arm/boards/eukrea_cpuimx27/env/bin/init
@@ -20,7 +20,7 @@ if [ -f /env/logo.bmp ]; then
bmp /env/logo.bmp
fb0.enable=1
elif [ -f /env/logo.bmp.lzo ]; then
- unlzo /env/logo.bmp.lzo /logo.bmp
+ uncompress /env/logo.bmp.lzo /logo.bmp
bmp /logo.bmp
fb0.enable=1
fi
diff --git a/arch/arm/boards/eukrea_cpuimx35/env/bin/init_board b/arch/arm/boards/eukrea_cpuimx35/env/bin/init_board
index 173ecf9..cb624e5 100644
--- a/arch/arm/boards/eukrea_cpuimx35/env/bin/init_board
+++ b/arch/arm/boards/eukrea_cpuimx35/env/bin/init_board
@@ -5,7 +5,7 @@ if [ -f /env/logo.bmp ]; then
fb0.enable=1
gpio_set_value 1 1
elif [ -f /env/logo.bmp.lzo ]; then
- unlzo /env/logo.bmp.lzo /logo.bmp
+ uncompress /env/logo.bmp.lzo /logo.bmp
bmp /logo.bmp
fb0.enable=1
gpio_set_value 1 1
diff --git a/arch/arm/boards/eukrea_cpuimx51/env/bin/init_board b/arch/arm/boards/eukrea_cpuimx51/env/bin/init_board
index 173ecf9..cb624e5 100644
--- a/arch/arm/boards/eukrea_cpuimx51/env/bin/init_board
+++ b/arch/arm/boards/eukrea_cpuimx51/env/bin/init_board
@@ -5,7 +5,7 @@ if [ -f /env/logo.bmp ]; then
fb0.enable=1
gpio_set_value 1 1
elif [ -f /env/logo.bmp.lzo ]; then
- unlzo /env/logo.bmp.lzo /logo.bmp
+ uncompress /env/logo.bmp.lzo /logo.bmp
bmp /logo.bmp
fb0.enable=1
gpio_set_value 1 1
diff --git a/arch/arm/boards/freescale-mx53-loco/board.c b/arch/arm/boards/freescale-mx53-loco/board.c
index 6a5ef37..aec2254 100644
--- a/arch/arm/boards/freescale-mx53-loco/board.c
+++ b/arch/arm/boards/freescale-mx53-loco/board.c
@@ -72,6 +72,22 @@ static struct pad_desc loco_pads[] = {
MX53_PAD_SD1_DATA3__ESDHC1_DAT3,
/* SD1_CD */
MX53_PAD_EIM_DA13__GPIO3_13,
+
+ /* SD3 */
+ MX53_PAD_PATA_DATA8__ESDHC3_DAT0,
+ MX53_PAD_PATA_DATA9__ESDHC3_DAT1,
+ MX53_PAD_PATA_DATA10__ESDHC3_DAT2,
+ MX53_PAD_PATA_DATA11__ESDHC3_DAT3,
+ MX53_PAD_PATA_DATA0__ESDHC3_DAT4,
+ MX53_PAD_PATA_DATA1__ESDHC3_DAT5,
+ MX53_PAD_PATA_DATA2__ESDHC3_DAT6,
+ MX53_PAD_PATA_DATA3__ESDHC3_DAT7,
+ MX53_PAD_PATA_IORDY__ESDHC3_CLK,
+ MX53_PAD_PATA_RESET_B__ESDHC3_CMD,
+ /* SD3_CD */
+ MX53_PAD_EIM_DA11__GPIO3_11,
+ /* SD3_WP */
+ MX53_PAD_EIM_DA12__GPIO3_12,
};
static int loco_mem_init(void)
@@ -92,11 +108,29 @@ static void loco_fec_reset(void)
gpio_set_value(LOCO_FEC_PHY_RST, 1);
}
+#define LOCO_SD3_CD IMX_GPIO_NR(3, 11)
+#define LOCO_SD3_WP IMX_GPIO_NR(3, 12)
+#define LOCO_SD1_CD IMX_GPIO_NR(3, 13)
+
+static struct esdhc_platform_data loco_sd1_data = {
+ .cd_gpio = LOCO_SD1_CD,
+ .cd_type = ESDHC_CD_GPIO,
+ .wp_type = ESDHC_WP_NONE,
+};
+
+static struct esdhc_platform_data loco_sd3_data = {
+ .cd_gpio = LOCO_SD3_CD,
+ .wp_gpio = LOCO_SD3_WP,
+ .cd_type = ESDHC_CD_GPIO,
+ .wp_type = ESDHC_WP_GPIO,
+};
+
static int loco_devices_init(void)
{
imx51_iim_register_fec_ethaddr();
imx53_add_fec(&fec_info);
- imx53_add_mmc0(NULL);
+ imx53_add_mmc0(&loco_sd1_data);
+ imx53_add_mmc2(&loco_sd3_data);
loco_fec_reset();
diff --git a/arch/arm/boards/freescale-mx53-smd/Makefile b/arch/arm/boards/freescale-mx53-smd/Makefile
new file mode 100644
index 0000000..b56ce7f
--- /dev/null
+++ b/arch/arm/boards/freescale-mx53-smd/Makefile
@@ -0,0 +1,2 @@
+obj-y += board.o
+obj-y += flash_header.o
diff --git a/arch/arm/boards/freescale-mx53-smd/board.c b/arch/arm/boards/freescale-mx53-smd/board.c
new file mode 100644
index 0000000..325458e
--- /dev/null
+++ b/arch/arm/boards/freescale-mx53-smd/board.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2007 Sascha Hauer, Pengutronix
+ * Copyright (C) 2011 Marc Kleine-Budde <mkl@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 <environment.h>
+#include <fcntl.h>
+#include <fec.h>
+#include <fs.h>
+#include <init.h>
+#include <nand.h>
+#include <net.h>
+#include <partition.h>
+#include <sizes.h>
+
+#include <generated/mach-types.h>
+
+#include <mach/imx-regs.h>
+#include <mach/iomux-mx53.h>
+#include <mach/devices-imx53.h>
+#include <mach/generic.h>
+#include <mach/gpio.h>
+#include <mach/imx-nand.h>
+#include <mach/iim.h>
+#include <mach/imx53.h>
+
+#include <asm/armlinux.h>
+#include <io.h>
+#include <asm/mmu.h>
+
+static struct fec_platform_data fec_info = {
+ .xcv_type = RMII,
+};
+
+static struct pad_desc smd_pads[] = {
+ /* UART1 */
+ MX53_PAD_CSI0_DAT10__UART1_TXD_MUX,
+ MX53_PAD_CSI0_DAT11__UART1_RXD_MUX,
+
+ /* UART2 */
+ MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX,
+ MX53_PAD_PATA_DMARQ__UART2_TXD_MUX,
+
+ /* UART3 */
+ MX53_PAD_PATA_CS_0__UART3_TXD_MUX,
+ MX53_PAD_PATA_CS_1__UART3_RXD_MUX,
+ MX53_PAD_PATA_DA_1__UART3_CTS,
+ MX53_PAD_PATA_DA_2__UART3_RTS,
+
+ /* FEC */
+ MX53_PAD_FEC_MDC__FEC_MDC,
+ MX53_PAD_FEC_MDIO__FEC_MDIO,
+ MX53_PAD_FEC_REF_CLK__FEC_TX_CLK,
+ MX53_PAD_FEC_RX_ER__FEC_RX_ER,
+ MX53_PAD_FEC_CRS_DV__FEC_RX_DV,
+ MX53_PAD_FEC_RXD1__FEC_RDATA_1,
+ MX53_PAD_FEC_RXD0__FEC_RDATA_0,
+ MX53_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX53_PAD_FEC_TXD1__FEC_TDATA_1,
+ MX53_PAD_FEC_TXD0__FEC_TDATA_0,
+ /* FEC_nRST */
+ MX53_PAD_PATA_DA_0__GPIO7_6,
+
+ /* SD1 */
+ MX53_PAD_SD1_CMD__ESDHC1_CMD,
+ MX53_PAD_SD1_CLK__ESDHC1_CLK,
+ MX53_PAD_SD1_DATA0__ESDHC1_DAT0,
+ MX53_PAD_SD1_DATA1__ESDHC1_DAT1,
+ MX53_PAD_SD1_DATA2__ESDHC1_DAT2,
+ MX53_PAD_SD1_DATA3__ESDHC1_DAT3,
+ /* SD1_CD */
+ MX53_PAD_EIM_DA13__GPIO3_13,
+ /* SD1_WP */
+ MX53_PAD_KEY_ROW2__GPIO4_11,
+
+ /* SD3 */
+ MX53_PAD_PATA_DATA8__ESDHC3_DAT0,
+ MX53_PAD_PATA_DATA9__ESDHC3_DAT1,
+ MX53_PAD_PATA_DATA10__ESDHC3_DAT2,
+ MX53_PAD_PATA_DATA11__ESDHC3_DAT3,
+ MX53_PAD_PATA_DATA0__ESDHC3_DAT4,
+ MX53_PAD_PATA_DATA1__ESDHC3_DAT5,
+ MX53_PAD_PATA_DATA2__ESDHC3_DAT6,
+ MX53_PAD_PATA_DATA3__ESDHC3_DAT7,
+ MX53_PAD_PATA_IORDY__ESDHC3_CLK,
+ MX53_PAD_PATA_RESET_B__ESDHC3_CMD,
+};
+
+static int smd_mem_init(void)
+{
+ arm_add_mem_device("ram0", 0x70000000, SZ_512M);
+ arm_add_mem_device("ram1", 0xb0000000, SZ_512M);
+
+ return 0;
+}
+mem_initcall(smd_mem_init);
+
+#define SMD_FEC_PHY_RST IMX_GPIO_NR(7, 6)
+
+static void smd_fec_reset(void)
+{
+ gpio_direction_output(SMD_FEC_PHY_RST, 0);
+ mdelay(1);
+ gpio_set_value(SMD_FEC_PHY_RST, 1);
+}
+
+#define LOCO_SD1_CD IMX_GPIO_NR(3, 13)
+#define LOCO_SD1_WP IMX_GPIO_NR(4, 11)
+
+static struct esdhc_platform_data loco_sd1_data = {
+ .cd_gpio = LOCO_SD1_CD,
+ .wp_gpio = LOCO_SD1_WP,
+ .cd_type = ESDHC_CD_GPIO,
+ .wp_type = ESDHC_WP_GPIO,
+};
+
+static struct esdhc_platform_data loco_sd3_data = {
+ .wp_type = ESDHC_WP_NONE,
+ .cd_type = ESDHC_CD_PERMANENT,
+};
+
+static int smd_devices_init(void)
+{
+ imx51_iim_register_fec_ethaddr();
+ imx53_add_fec(&fec_info);
+ imx53_add_mmc0(&loco_sd1_data);
+ imx53_add_mmc2(&loco_sd3_data);
+
+ smd_fec_reset();
+
+ armlinux_set_bootparams((void *)0x70000100);
+ armlinux_set_architecture(MACH_TYPE_MX53_SMD);
+
+ return 0;
+}
+device_initcall(smd_devices_init);
+
+static int smd_part_init(void)
+{
+ devfs_add_partition("disk0", 0x00000, 0x40000, PARTITION_FIXED, "self0");
+ devfs_add_partition("disk0", 0x40000, 0x20000, PARTITION_FIXED, "env0");
+
+ return 0;
+}
+late_initcall(smd_part_init);
+
+static int smd_console_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(smd_pads, ARRAY_SIZE(smd_pads));
+
+ mx53_init_lowlevel();
+
+ imx53_add_uart0();
+ imx53_add_uart1();
+ imx53_add_uart2();
+ return 0;
+}
+console_initcall(smd_console_init);
diff --git a/include/ata.h b/arch/arm/boards/freescale-mx53-smd/config.h
index d56399e..b7effe5 100644
--- a/include/ata.h
+++ b/arch/arm/boards/freescale-mx53-smd/config.h
@@ -1,5 +1,6 @@
-/*
- * Copyright (C) 2009 Juergen Beisert, Pengutronix
+/**
+ * @file
+ * @brief Global defintions for the ARM i.MX51 based babbage board
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -8,32 +9,16 @@
*
* 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
+ * 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 Declarations to communicate with ATA types of drives
- */
-
-#include <types.h>
-#include <driver.h>
+#ifndef __CONFIG_H
+#define __CONFIG_H
-/**
- * Access functions from drives through the specified interface
- */
-struct ata_interface {
- /** write a count of sectors from a buffer to the drive */
- int (*write)(struct device_d*, uint64_t, unsigned, const void*);
- /** read a count of sectors from the drive into the buffer */
- int (*read)(struct device_d*, uint64_t, unsigned, void*);
- /** private interface data */
- void *priv;
-};
+#endif /* __CONFIG_H */
diff --git a/arch/arm/boards/freescale-mx53-smd/env/config b/arch/arm/boards/freescale-mx53-smd/env/config
new file mode 100644
index 0000000..3659a62
--- /dev/null
+++ b/arch/arm/boards/freescale-mx53-smd/env/config
@@ -0,0 +1,51 @@
+#!/bin/sh
+
+machine=loco
+eth0.serverip=
+user=
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'none' if you want to skip kernel ip autoconfiguration
+ip=dhcp
+
+# 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', 'nor' or 'nand'
+kernel_loc=tftp
+# can be either 'net', 'nor', 'nand' or 'initrd'
+rootfs_loc=net
+
+# can be either 'jffs2' or 'ubifs'
+rootfs_type=ubifs
+rootfsimage=root-$machine.$rootfs_type
+
+# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo
+kernelimage_type=zimage
+kernelimage=zImage-$machine
+#kernelimage_type=uimage
+#kernelimage=uImage-$machine
+#kernelimage_type=raw
+#kernelimage=Image-$machine
+#kernelimage_type=raw_lzo
+#kernelimage=Image-$machine.lzo
+
+if [ -n $user ]; then
+ kernelimage="$user"-"$kernelimage"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/$machine"
+ rootfsimage="$user"-"$rootfsimage"
+else
+ nfsroot="$eth0.serverip:/path/to/nfs/root"
+fi
+
+autoboot_timeout=3
+
+bootargs="console=ttymxc0,115200"
+
+disk_parts="256k(barebox)ro,128k(bareboxenv),4M(kernel),-(root)"
+
+# 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/freescale-mx53-smd/flash_header.c b/arch/arm/boards/freescale-mx53-smd/flash_header.c
new file mode 100644
index 0000000..490e223
--- /dev/null
+++ b/arch/arm/boards/freescale-mx53-smd/flash_header.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2011 Marc Kleine-Budde <mkl@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 <asm/byteorder.h>
+#include <mach/imx-flash-header.h>
+
+void __naked __flash_header_start go(void)
+{
+ __asm__ __volatile__("b exception_vectors\n");
+}
+
+struct imx_dcd_v2_entry __dcd_entry_section dcd_entry[] = {
+ { .addr = cpu_to_be32(0x53fa8554), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x53fa8558), .val = cpu_to_be32(0x00300040), },
+ { .addr = cpu_to_be32(0x53fa8560), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x53fa8564), .val = cpu_to_be32(0x00300040), },
+ { .addr = cpu_to_be32(0x53fa8568), .val = cpu_to_be32(0x00300040), },
+ { .addr = cpu_to_be32(0x53fa8570), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x53fa8574), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x53fa8578), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x53fa857c), .val = cpu_to_be32(0x00300040), },
+ { .addr = cpu_to_be32(0x53fa8580), .val = cpu_to_be32(0x00300040), },
+ { .addr = cpu_to_be32(0x53fa8584), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x53fa8588), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x53fa8590), .val = cpu_to_be32(0x00300040), },
+ { .addr = cpu_to_be32(0x53fa8594), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x53fa86f0), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x53fa86f4), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa86fc), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa8714), .val = cpu_to_be32(0x00000000), },
+ { .addr = cpu_to_be32(0x53fa8718), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x53fa871c), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x53fa8720), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x53fa8724), .val = cpu_to_be32(0x04000000), },
+ { .addr = cpu_to_be32(0x53fa8728), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x53fa872c), .val = cpu_to_be32(0x00300000), },
+ { .addr = cpu_to_be32(0x63fd9088), .val = cpu_to_be32(0x35343535), },
+ { .addr = cpu_to_be32(0x63fd9090), .val = cpu_to_be32(0x4d444c44), },
+ { .addr = cpu_to_be32(0x63fd907c), .val = cpu_to_be32(0x01370138), },
+ { .addr = cpu_to_be32(0x63fd9080), .val = cpu_to_be32(0x013b013c), },
+ { .addr = cpu_to_be32(0x63fd9018), .val = cpu_to_be32(0x00011740), },
+ { .addr = cpu_to_be32(0x63fd9000), .val = cpu_to_be32(0xc3190000), },
+ { .addr = cpu_to_be32(0x63fd900c), .val = cpu_to_be32(0x9f5152e3), },
+ { .addr = cpu_to_be32(0x63fd9010), .val = cpu_to_be32(0xb68e8a63), },
+ { .addr = cpu_to_be32(0x63fd9014), .val = cpu_to_be32(0x01ff00db), },
+ { .addr = cpu_to_be32(0x63fd902c), .val = cpu_to_be32(0x000026d2), },
+ { .addr = cpu_to_be32(0x63fd9030), .val = cpu_to_be32(0x009f0e21), },
+ { .addr = cpu_to_be32(0x63fd9008), .val = cpu_to_be32(0x12273030), },
+ { .addr = cpu_to_be32(0x63fd9004), .val = cpu_to_be32(0x0002002d), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008032), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00008033), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00028031), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x052080b0), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x04008040), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x0000803a), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x0000803b), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00028039), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x05208138), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x04008048), },
+ { .addr = cpu_to_be32(0x63fd9020), .val = cpu_to_be32(0x00005800), },
+ { .addr = cpu_to_be32(0x63fd9040), .val = cpu_to_be32(0x04b80003), },
+ { .addr = cpu_to_be32(0x63fd9058), .val = cpu_to_be32(0x00022227), },
+ { .addr = cpu_to_be32(0x63fd901c), .val = cpu_to_be32(0x00000000), },
+};
+
+#define APP_DEST CONFIG_TEXT_BASE
+
+struct imx_flash_header_v2 __flash_header_section flash_header = {
+ .header.tag = IVT_HEADER_TAG,
+ .header.length = cpu_to_be16(32),
+ .header.version = IVT_VERSION,
+
+ .entry = APP_DEST + 0x1000,
+ .dcd_ptr = APP_DEST + 0x400 + offsetof(struct imx_flash_header_v2, dcd),
+ .boot_data_ptr = APP_DEST + 0x400 + offsetof(struct imx_flash_header_v2, boot_data),
+ .self = APP_DEST + 0x400,
+
+ .boot_data.start = APP_DEST,
+ .boot_data.size = 0x40000,
+
+ .dcd.header.tag = DCD_HEADER_TAG,
+ .dcd.header.length = cpu_to_be16(sizeof(struct imx_dcd) + sizeof(dcd_entry)),
+ .dcd.header.version = DCD_VERSION,
+
+ .dcd.command.tag = DCD_COMMAND_WRITE_TAG,
+ .dcd.command.length = cpu_to_be16(sizeof(struct imx_dcd_command) + sizeof(dcd_entry)),
+ .dcd.command.param = DCD_COMMAND_WRITE_PARAM,
+};
diff --git a/arch/arm/boards/freescale-mx53-smd/mx53-smd.dox b/arch/arm/boards/freescale-mx53-smd/mx53-smd.dox
new file mode 100644
index 0000000..1960508
--- /dev/null
+++ b/arch/arm/boards/freescale-mx53-smd/mx53-smd.dox
@@ -0,0 +1,4 @@
+/** @page board_loco Freescale i.MX53 SMD Board
+
+
+*/
diff --git a/arch/arm/boards/mini2440/mini2440.c b/arch/arm/boards/mini2440/mini2440.c
index b8042f2..b4cc0f8 100644
--- a/arch/arm/boards/mini2440/mini2440.c
+++ b/arch/arm/boards/mini2440/mini2440.c
@@ -314,6 +314,8 @@ static int mini2440_devices_init(void)
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);
armlinux_set_bootparams((void*)CS6_BASE + 0x100);
armlinux_set_architecture(MACH_TYPE_MINI2440);
diff --git a/arch/arm/boards/omap/board-beagle.c b/arch/arm/boards/omap/board-beagle.c
index bfb08f7..e5f0f94 100644
--- a/arch/arm/boards/omap/board-beagle.c
+++ b/arch/arm/boards/omap/board-beagle.c
@@ -313,34 +313,3 @@ static int beagle_devices_init(void)
return 0;
}
device_initcall(beagle_devices_init);
-
-#ifdef CONFIG_SHELL_NONE
-
-int run_shell(void)
-{
- int (*func)(void) = NULL;
-
- switch (omap3_bootsrc()) {
- case OMAP_BOOTSRC_MMC1:
- printf("booting from MMC1\n");
- func = omap_xload_boot_mmc();
- break;
- case OMAP_BOOTSRC_UNKNOWN:
- printf("unknown boot source. Fall back to nand\n");
- case OMAP_BOOTSRC_NAND:
- printf("booting from NAND\n");
- func = omap_xload_boot_nand(SZ_128K, SZ_256K);
- break;
- }
-
- if (!func) {
- printf("booting failed\n");
- while (1);
- }
-
- shutdown_barebox();
- func();
-
- while (1);
-}
-#endif
diff --git a/arch/arm/boards/panda/board.c b/arch/arm/boards/panda/board.c
index 6a149aa..be3ad77 100644
--- a/arch/arm/boards/panda/board.c
+++ b/arch/arm/boards/panda/board.c
@@ -170,22 +170,3 @@ static int panda_env_init(void)
}
late_initcall(panda_env_init);
#endif
-
-
-#ifdef CONFIG_SHELL_NONE
-int run_shell(void)
-{
- int (*func)(void);
-
- func = omap_xload_boot_mmc();
- if (!func) {
- printf("booting failed\n");
- while (1);
- }
-
- shutdown_barebox();
- func();
-
- while (1);
-}
-#endif
diff --git a/arch/arm/boards/pcm049/board.c b/arch/arm/boards/pcm049/board.c
index 8de333f..30e24bc 100644
--- a/arch/arm/boards/pcm049/board.c
+++ b/arch/arm/boards/pcm049/board.c
@@ -112,33 +112,3 @@ static int pcm049_devices_init(void)
return 0;
}
device_initcall(pcm049_devices_init);
-
-#ifdef CONFIG_SHELL_NONE
-int run_shell(void)
-{
- int (*func)(void) = NULL;
-
- switch (omap4_bootsrc()) {
- case OMAP_BOOTSRC_MMC1:
- printf("booting from MMC1\n");
- func = omap_xload_boot_mmc();
- break;
- case OMAP_BOOTSRC_UNKNOWN:
- printf("unknown boot source. Fall back to nand\n");
- case OMAP_BOOTSRC_NAND:
- printf("booting from NAND\n");
- func = omap_xload_boot_nand(SZ_128K, SZ_256K);
- break;
- }
-
- if (!func) {
- printf("booting failed\n");
- while (1);
- }
-
- shutdown_barebox();
- func();
-
- while (1);
-}
-#endif
diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig
index 0c10f88..584bfdf 100644
--- a/arch/arm/configs/at91rm9200ek_defconfig
+++ b/arch/arm/configs/at91rm9200ek_defconfig
@@ -33,7 +33,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
# CONFIG_SPI is not set
CONFIG_DRIVER_CFI=y
# CONFIG_DRIVER_CFI_INTEL is not set
diff --git a/arch/arm/configs/at91sam9261ek_defconfig b/arch/arm/configs/at91sam9261ek_defconfig
index c753eb3..a4adee9 100644
--- a/arch/arm/configs/at91sam9261ek_defconfig
+++ b/arch/arm/configs/at91sam9261ek_defconfig
@@ -33,7 +33,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/configs/at91sam9g10ek_defconfig b/arch/arm/configs/at91sam9g10ek_defconfig
index d39639a..9271b68 100644
--- a/arch/arm/configs/at91sam9g10ek_defconfig
+++ b/arch/arm/configs/at91sam9g10ek_defconfig
@@ -27,7 +27,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/configs/at91sam9m10g45ek_defconfig b/arch/arm/configs/at91sam9m10g45ek_defconfig
index 9699f5b..548fe6c 100644
--- a/arch/arm/configs/at91sam9m10g45ek_defconfig
+++ b/arch/arm/configs/at91sam9m10g45ek_defconfig
@@ -37,7 +37,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/configs/cupid_defconfig b/arch/arm/configs/cupid_defconfig
index b842469..3f5038f 100644
--- a/arch/arm/configs/cupid_defconfig
+++ b/arch/arm/configs/cupid_defconfig
@@ -35,7 +35,7 @@ CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_BMP=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/configs/dss11_defconfig b/arch/arm/configs/dss11_defconfig
new file mode 100644
index 0000000..71143c9
--- /dev/null
+++ b/arch/arm/configs/dss11_defconfig
@@ -0,0 +1,48 @@
+CONFIG_ARCH_AT91SAM9G20=y
+CONFIG_MACH_DSS11=y
+CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_PARTITION_DISK_DOS=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_LED=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_NFS=y
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_TFTP_PUSH=y
+CONFIG_DRIVER_NET_MACB=y
+CONFIG_DRIVER_SPI_ATMEL=y
+CONFIG_MTD=y
+CONFIG_NAND=y
+# CONFIG_NAND_ECC_HW_SYNDROME is not set
+# CONFIG_NAND_ECC_HW_NONE is not set
+CONFIG_NAND_ATMEL=y
+CONFIG_UBI=y
+CONFIG_DISK_WRITE=y
+CONFIG_USB=y
+CONFIG_USB_OHCI=y
+CONFIG_USB_OHCI_AT91=y
+CONFIG_USB_STORAGE=y
+CONFIG_MCI=y
+CONFIG_MCI_STARTUP=y
+# CONFIG_MCI_WRITE is not set
+CONFIG_MCI_ATMEL=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_LED_GPIO_RGB=y
+CONFIG_LED_TRIGGERS=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FAT_WRITE=y
+CONFIG_FS_FAT_LFN=y
diff --git a/arch/arm/configs/eukrea_cpuimx25_defconfig b/arch/arm/configs/eukrea_cpuimx25_defconfig
index 7fa2042..2a697be 100644
--- a/arch/arm/configs/eukrea_cpuimx25_defconfig
+++ b/arch/arm/configs/eukrea_cpuimx25_defconfig
@@ -35,7 +35,7 @@ CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_BMP=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_CMD_I2C=y
CONFIG_CMD_LED=y
CONFIG_CMD_LED_TRIGGER=y
diff --git a/arch/arm/configs/eukrea_cpuimx27_defconfig b/arch/arm/configs/eukrea_cpuimx27_defconfig
index 75b849b..93de428 100644
--- a/arch/arm/configs/eukrea_cpuimx27_defconfig
+++ b/arch/arm/configs/eukrea_cpuimx27_defconfig
@@ -33,7 +33,7 @@ CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_BMP=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_CMD_I2C=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
diff --git a/arch/arm/configs/eukrea_cpuimx35_defconfig b/arch/arm/configs/eukrea_cpuimx35_defconfig
index 6964332..7bbe0d5 100644
--- a/arch/arm/configs/eukrea_cpuimx35_defconfig
+++ b/arch/arm/configs/eukrea_cpuimx35_defconfig
@@ -34,7 +34,7 @@ CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_BMP=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_CMD_I2C=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
diff --git a/arch/arm/configs/eukrea_cpuimx51_defconfig b/arch/arm/configs/eukrea_cpuimx51_defconfig
index a9fca84..39fe962 100644
--- a/arch/arm/configs/eukrea_cpuimx51_defconfig
+++ b/arch/arm/configs/eukrea_cpuimx51_defconfig
@@ -32,7 +32,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_PING=y
diff --git a/arch/arm/configs/freescale_mx35_3stack_defconfig b/arch/arm/configs/freescale_mx35_3stack_defconfig
index 2c0e513..c8d159f 100644
--- a/arch/arm/configs/freescale_mx35_3stack_defconfig
+++ b/arch/arm/configs/freescale_mx35_3stack_defconfig
@@ -29,7 +29,7 @@ CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_BMP=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_CMD_I2C=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
diff --git a/arch/arm/configs/freescale_mx53_loco_defconfig b/arch/arm/configs/freescale_mx53_loco_defconfig
index 8e4a7ce..cb07f85 100644
--- a/arch/arm/configs/freescale_mx53_loco_defconfig
+++ b/arch/arm/configs/freescale_mx53_loco_defconfig
@@ -33,7 +33,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/configs/freescale_mx53_smd_defconfig b/arch/arm/configs/freescale_mx53_smd_defconfig
new file mode 100644
index 0000000..1548b05
--- /dev/null
+++ b/arch/arm/configs/freescale_mx53_smd_defconfig
@@ -0,0 +1,51 @@
+CONFIG_ARCH_IMX=y
+CONFIG_ARCH_IMX53=y
+CONFIG_MACH_FREESCALE_MX53_SMD=y
+CONFIG_IMX_IIM=y
+CONFIG_IMX_IIM_FUSE_BLOW=y
+CONFIG_AEABI=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_ARM_UNWIND=y
+CONFIG_MMU=y
+CONFIG_TEXT_BASE=0x7ff00000
+CONFIG_MALLOC_SIZE=0x2000000
+CONFIG_KALLSYMS=y
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="defaultenv arch/arm/boards/freescale-mx53-smd/env/"
+CONFIG_DEBUG_INFO=y
+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_FLASH=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_UNCOMPRESS=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_NFS=y
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_TFTP_PUSH=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_DRIVER_NET_FEC_IMX=y
+# CONFIG_SPI is not set
+CONFIG_MCI=y
+CONFIG_MCI_STARTUP=y
+CONFIG_MCI_IMX_ESDHC=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FAT_WRITE=y
+CONFIG_FS_FAT_LFN=y
diff --git a/arch/arm/configs/neso_defconfig b/arch/arm/configs/neso_defconfig
index 1b533df..dcc2f70 100644
--- a/arch/arm/configs/neso_defconfig
+++ b/arch/arm/configs/neso_defconfig
@@ -34,7 +34,7 @@ CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_BMP=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig
index b81afe2..597e9dd 100644
--- a/arch/arm/configs/nhk8815_defconfig
+++ b/arch/arm/configs/nhk8815_defconfig
@@ -34,7 +34,7 @@ CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/configs/omap3530_beagle_defconfig b/arch/arm/configs/omap3530_beagle_defconfig
index 8a12154..e0688ae 100644
--- a/arch/arm/configs/omap3530_beagle_defconfig
+++ b/arch/arm/configs/omap3530_beagle_defconfig
@@ -31,7 +31,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_CMD_I2C=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
diff --git a/arch/arm/configs/panda_defconfig b/arch/arm/configs/panda_defconfig
index 3ea2466..27592e5 100644
--- a/arch/arm/configs/panda_defconfig
+++ b/arch/arm/configs/panda_defconfig
@@ -34,7 +34,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/configs/pca100_defconfig b/arch/arm/configs/pca100_defconfig
index 88e7b9f..29e02c5 100644
--- a/arch/arm/configs/pca100_defconfig
+++ b/arch/arm/configs/pca100_defconfig
@@ -33,7 +33,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_PING=y
diff --git a/arch/arm/configs/pcm037_defconfig b/arch/arm/configs/pcm037_defconfig
index d9525a2..ec43317 100644
--- a/arch/arm/configs/pcm037_defconfig
+++ b/arch/arm/configs/pcm037_defconfig
@@ -31,7 +31,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/configs/pcm043_defconfig b/arch/arm/configs/pcm043_defconfig
index 3c728ed..e47bb35 100644
--- a/arch/arm/configs/pcm043_defconfig
+++ b/arch/arm/configs/pcm043_defconfig
@@ -36,7 +36,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/configs/pcm049_defconfig b/arch/arm/configs/pcm049_defconfig
index ed20f1b..9b4c341 100644
--- a/arch/arm/configs/pcm049_defconfig
+++ b/arch/arm/configs/pcm049_defconfig
@@ -35,7 +35,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/configs/pm9261_defconfig b/arch/arm/configs/pm9261_defconfig
index 0bd9483..89aa033 100644
--- a/arch/arm/configs/pm9261_defconfig
+++ b/arch/arm/configs/pm9261_defconfig
@@ -34,7 +34,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/configs/pm9g45_defconfig b/arch/arm/configs/pm9g45_defconfig
index 20bfd71..bf9af22 100644
--- a/arch/arm/configs/pm9g45_defconfig
+++ b/arch/arm/configs/pm9g45_defconfig
@@ -37,7 +37,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/configs/scb9328_defconfig b/arch/arm/configs/scb9328_defconfig
index 73ef238..4955646 100644
--- a/arch/arm/configs/scb9328_defconfig
+++ b/arch/arm/configs/scb9328_defconfig
@@ -28,7 +28,7 @@ CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_CMD_LED=y
CONFIG_CMD_LED_TRIGGER=y
CONFIG_NET=y
diff --git a/arch/arm/configs/versatilepb_defconfig b/arch/arm/configs/versatilepb_defconfig
index 6ffdf28..1b51d91 100644
--- a/arch/arm/configs/versatilepb_defconfig
+++ b/arch/arm/configs/versatilepb_defconfig
@@ -32,7 +32,7 @@ CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig
index 5337c46..f55e862 100644
--- a/arch/arm/cpu/Kconfig
+++ b/arch/arm/cpu/Kconfig
@@ -45,6 +45,11 @@ config CPU_V7
bool
select CPU_32v7
+# Xscale PXA25x, PXA27x
+config CPU_XSCALE
+ bool
+ select CPU_32v4T
+
# Figure out what processor architecture version we should be using.
# This defines the compiler instruction set which depends on the machine type.
config CPU_32v4T
diff --git a/arch/arm/cpu/exceptions.S b/arch/arm/cpu/exceptions.S
index a879755..6f35d40 100644
--- a/arch/arm/cpu/exceptions.S
+++ b/arch/arm/cpu/exceptions.S
@@ -140,25 +140,6 @@ data_abort:
.globl irq
.globl fiq
-#ifdef CONFIG_USE_IRQ
-
- .align 5
-irq:
- get_irq_stack
- irq_save_user_regs
- bl do_irq
- irq_restore_user_regs
-
- .align 5
-fiq:
- get_fiq_stack
- /* someone ought to write a more effiction fiq_save_user_regs */
- irq_save_user_regs
- bl do_fiq
- irq_restore_user_regs
-
-#else
-
.align 5
irq:
get_bad_stack
@@ -171,5 +152,3 @@ fiq:
bad_save_user_regs
bl do_fiq
-#endif
-
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 4446813..8e4e81a 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -9,7 +9,7 @@
static unsigned long *ttb;
-static void create_section(unsigned long virt, unsigned long phys, int size_m,
+static void create_sections(unsigned long virt, unsigned long phys, int size_m,
unsigned int flags)
{
int i;
@@ -226,7 +226,7 @@ static int mmu_init(void)
asm volatile ("mcr p15,0,%0,c3,c0,0" : : "r"(i) /*:*/);
/* create a flat mapping using 1MiB sections */
- create_section(0, 0, 4096, PMD_SECT_AP_WRITE | PMD_SECT_AP_READ |
+ create_sections(0, 0, 4096, PMD_SECT_AP_WRITE | PMD_SECT_AP_READ |
PMD_TYPE_SECT);
vectors_init();
@@ -237,7 +237,7 @@ static int mmu_init(void)
* below
*/
for_each_memory_bank(bank)
- create_section(bank->start, bank->start, bank->size >> 20,
+ create_sections(bank->start, bank->start, bank->size >> 20,
PMD_SECT_DEF_CACHED);
asm volatile (
diff --git a/arch/arm/lib/arm.c b/arch/arm/lib/arm.c
index c85aae1..80b62e9 100644
--- a/arch/arm/lib/arm.c
+++ b/arch/arm/lib/arm.c
@@ -7,7 +7,7 @@
static int arm_mem_malloc_init(void)
{
mem_malloc_init((void *)MALLOC_BASE,
- (void *)(MALLOC_BASE + MALLOC_SIZE));
+ (void *)(MALLOC_BASE + MALLOC_SIZE - 1));
return 0;
}
diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c
index d8ca477..bd9b72a 100644
--- a/arch/arm/lib/armlinux.c
+++ b/arch/arm/lib/armlinux.c
@@ -27,7 +27,6 @@
#include <driver.h>
#include <environment.h>
#include <image.h>
-#include <zlib.h>
#include <init.h>
#include <fs.h>
#include <linux/list.h>
@@ -37,6 +36,7 @@
#include <errno.h>
#include <memory.h>
#include <of.h>
+#include <magicvar.h>
#include <asm/byteorder.h>
#include <asm/setup.h>
@@ -45,11 +45,71 @@
#include <asm/system.h>
static struct tag *params;
-static int armlinux_architecture = 0;
static void *armlinux_bootparams = NULL;
-static unsigned int system_rev;
-static u64 system_serial;
+#ifndef CONFIG_ENVIRONMENT_VARIABLES
+static int armlinux_architecture;
+static u32 armlinux_system_rev;
+static u64 armlinux_system_serial;
+#endif
+
+BAREBOX_MAGICVAR(armlinux_architecture, "ARM machine ID");
+BAREBOX_MAGICVAR(armlinux_system_rev, "ARM system revision");
+BAREBOX_MAGICVAR(armlinux_system_serial, "ARM system serial");
+
+void armlinux_set_architecture(int architecture)
+{
+#ifdef CONFIG_ENVIRONMENT_VARIABLES
+ export_env_ull("armlinux_architecture", architecture);
+#else
+ armlinux_architecture = architecture;
+#endif
+}
+
+int armlinux_get_architecture(void)
+{
+#ifdef CONFIG_ENVIRONMENT_VARIABLES
+ return getenv_ull("armlinux_architecture");
+#else
+ return armlinux_architecture;
+#endif
+}
+
+void armlinux_set_revision(unsigned int rev)
+{
+#ifdef CONFIG_ENVIRONMENT_VARIABLES
+ export_env_ull("armlinux_system_rev", rev);
+#else
+ return armlinux_system_rev;
+#endif
+}
+
+unsigned int armlinux_get_revision(void)
+{
+#ifdef CONFIG_ENVIRONMENT_VARIABLES
+ return getenv_ull("armlinux_system_rev");
+#else
+ return armlinux_system_rev;
+#endif
+}
+
+void armlinux_set_serial(u64 serial)
+{
+#ifdef CONFIG_ENVIRONMENT_VARIABLES
+ export_env_ull("armlinux_system_serial", serial);
+#else
+ armlinux_system_serial = serial;
+#endif
+}
+
+u64 armlinux_get_serial(void)
+{
+#ifdef CONFIG_ENVIRONMENT_VARIABLES
+ return getenv_ull("armlinux_system_serial");
+#else
+ return armlinux_system_serial;
+#endif
+}
static void setup_start_tag(void)
{
@@ -117,6 +177,8 @@ static void setup_commandline_tag(const char *commandline, int swap)
static void setup_revision_tag(void)
{
+ u32 system_rev = armlinux_get_revision();
+
if (system_rev) {
params->hdr.tag = ATAG_REVISION;
params->hdr.size = tag_size(tag_revision);
@@ -129,6 +191,8 @@ static void setup_revision_tag(void)
static void setup_serial_tag(void)
{
+ u64 system_serial = armlinux_get_serial();
+
if (system_serial) {
params->hdr.tag = ATAG_SERIAL;
params->hdr.size = tag_size(tag_serialnr);
@@ -140,7 +204,7 @@ static void setup_serial_tag(void)
}
}
-static void setup_initrd_tag(image_header_t *header)
+static void setup_initrd_tag(unsigned long start, unsigned long size)
{
/* an ATAG_INITRD node tells the kernel where the compressed
* ramdisk can be found. ATAG_RDIMG is a better name, actually.
@@ -148,8 +212,8 @@ static void setup_initrd_tag(image_header_t *header)
params->hdr.tag = ATAG_INITRD2;
params->hdr.size = tag_size(tag_initrd);
- params->u.initrd.start = image_get_load(header);
- params->u.initrd.size = image_get_data_size(header);
+ params->u.initrd.start = start;
+ params->u.initrd.size = size;
params = tag_next(params);
}
@@ -168,15 +232,15 @@ static void setup_tags(struct image_data *data, int swap)
setup_memory_tags();
setup_commandline_tag(commandline, swap);
- if (data && data->initrd)
- setup_initrd_tag (&data->initrd->header);
+ if (data && (data->initrd_size > 0))
+ setup_initrd_tag(data->initrd_address, data->initrd_size);
setup_revision_tag();
setup_serial_tag();
setup_end_tag();
printf("commandline: %s\n"
- "arch_number: %d\n", commandline, armlinux_architecture);
+ "arch_number: %d\n", commandline, armlinux_get_architecture());
}
@@ -185,28 +249,6 @@ void armlinux_set_bootparams(void *params)
armlinux_bootparams = params;
}
-void armlinux_set_architecture(int architecture)
-{
- char *arch_number = asprintf("%d", architecture);
-
- armlinux_architecture = architecture;
-
- setenv("arch_number", arch_number);
- export("arch_number");
-
- kfree(arch_number);
-}
-
-void armlinux_set_revision(unsigned int rev)
-{
- system_rev = rev;
-}
-
-void armlinux_set_serial(u64 serial)
-{
- system_serial = serial;
-}
-
void start_linux(void *adr, int swap, struct image_data *data)
{
void (*kernel)(int zero, int arch, void *params) = adr;
@@ -229,5 +271,5 @@ void start_linux(void *adr, int swap, struct image_data *data)
__asm__ __volatile__("mcr p15, 0, %0, c1, c0" :: "r" (reg));
}
- kernel(0, armlinux_architecture, params);
+ kernel(0, armlinux_get_architecture(), params);
}
diff --git a/arch/arm/lib/barebox.lds.S b/arch/arm/lib/barebox.lds.S
index 81a9123..f05f345 100644
--- a/arch/arm/lib/barebox.lds.S
+++ b/arch/arm/lib/barebox.lds.S
@@ -80,6 +80,10 @@ SECTIONS
.barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
+ __barebox_magicvar_start = .;
+ .barebox_magicvar : { BAREBOX_MAGICVARS }
+ __barebox_magicvar_end = .;
+
__barebox_initcalls_start = .;
.barebox_initcalls : { INITCALLS }
__barebox_initcalls_end = .;
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 87bf3b3..031a269 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -4,7 +4,6 @@
#include <driver.h>
#include <environment.h>
#include <image.h>
-#include <zlib.h>
#include <init.h>
#include <fs.h>
#include <linux/list.h>
@@ -29,13 +28,6 @@ static int do_bootm_linux(struct image_data *data)
debug("## Transferring control to Linux (at address 0x%p) ...\n",
theKernel);
- if (relocate_image(data->os, (void *)image_get_load(os_header)))
- return -1;
-
- if (data->initrd)
- if (relocate_image(data->initrd, (void *)image_get_load(&data->initrd->header)))
- return -1;
-
/* we assume that the kernel is in place */
printf("\nStarting kernel %s...\n\n", data->initrd ? "with initrd " : "");
@@ -44,36 +36,7 @@ static int do_bootm_linux(struct image_data *data)
return -1;
}
-static int image_handle_cmdline_parse(struct image_data *data, int opt,
- char *optarg)
-{
- int ret = 1;
- int no;
-
- switch (opt) {
- case 'a':
- no = simple_strtoul(optarg, NULL, 0);
- armlinux_set_architecture(no);
- ret = 0;
- break;
- case 'R':
- no = simple_strtoul(optarg, NULL, 0);
- armlinux_set_revision(no);
- ret = 0;
- break;
- default:
- break;
- }
-
- return ret;
-}
-
static struct image_handler handler = {
- .cmdline_options = "a:R:",
- .cmdline_parse = image_handle_cmdline_parse,
- .help_string = " -a <arch> use architecture number <arch>\n"
- " -R <system_rev> use system revison <system_rev>\n",
-
.bootm = do_bootm_linux,
.image_type = IH_OS_LINUX,
};
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 2ac23b5..e0e17bb 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -20,6 +20,7 @@ config BOARDINFO
default "Ronetix PM9261" if MACH_PM9261
default "Ronetix PM9263" if MACH_PM9263
default "Ronetix PM9G45" if MACH_PM9G45
+ default "Aizo dSS11" if MACH_DSS11
config HAVE_NAND_ATMEL_BUSWIDTH_16
bool
@@ -175,6 +176,13 @@ config MACH_USB_A9G20
Select this if you are using a Calao Systems USB-A9G20.
<http://www.calao-systems.com>
+config MACH_DSS11
+ bool "aizo dSS11"
+ select HAVE_NAND_ATMEL_BUSWIDTH_16
+ help
+ Select this if you are using aizo dSS11
+ that embeds only one SD/MMC slot.
+
endchoice
endif
diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index 9d1acda..be1fdd9 100644
--- a/arch/arm/mach-at91/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -63,8 +63,13 @@ void at91_add_device_eth(struct at91_ether_platform_data *data)
at91_set_B_periph(AT91_PIN_PA25, 0); /* ERX2 */
at91_set_B_periph(AT91_PIN_PA26, 0); /* ERX3 */
at91_set_B_periph(AT91_PIN_PA27, 0); /* ERXCK */
- at91_set_B_periph(AT91_PIN_PA23, 0); /* ETX2 */
- at91_set_B_periph(AT91_PIN_PA24, 0); /* ETX3 */
+ if (data->flags & AT91SAM_ETX2_ETX3_ALTERNATIVE) {
+ at91_set_B_periph(AT91_PIN_PA10, 0); /* ETX2 */
+ at91_set_B_periph(AT91_PIN_PA11, 0); /* ETX3 */
+ } else {
+ at91_set_B_periph(AT91_PIN_PA23, 0); /* ETX2 */
+ at91_set_B_periph(AT91_PIN_PA24, 0); /* ETX3 */
+ }
at91_set_B_periph(AT91_PIN_PA22, 0); /* ETXER */
}
@@ -261,18 +266,32 @@ void at91_add_device_mci(short mmc_id, struct atmel_mci_platform_data *data)
/* CLK */
at91_set_A_periph(AT91_PIN_PA8, 0);
- /* CMD */
- at91_set_A_periph(AT91_PIN_PA7, 1);
- /* DAT0, maybe DAT1..DAT3 */
- at91_set_A_periph(AT91_PIN_PA6, 1);
- if (data->bus_width == 4) {
- at91_set_A_periph(AT91_PIN_PA9, 1);
- at91_set_A_periph(AT91_PIN_PA10, 1);
- at91_set_A_periph(AT91_PIN_PA11, 1);
+ if (mmc_id == 0) {
+ /* CMD */
+ at91_set_A_periph(AT91_PIN_PA7, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_A_periph(AT91_PIN_PA6, 1);
+ if (data->bus_width == 4) {
+ at91_set_A_periph(AT91_PIN_PA9, 1);
+ at91_set_A_periph(AT91_PIN_PA10, 1);
+ at91_set_A_periph(AT91_PIN_PA11, 1);
+ }
+ } else if (mmc_id == 1) {
+ /* CMD */
+ at91_set_B_periph(AT91_PIN_PA1, 1);
+
+ /* DAT0, maybe DAT1..DAT3 */
+ at91_set_B_periph(AT91_PIN_PA0, 1);
+ if (data->bus_width == 4) {
+ at91_set_B_periph(AT91_PIN_PA3, 1);
+ at91_set_B_periph(AT91_PIN_PA4, 1);
+ at91_set_B_periph(AT91_PIN_PA5, 1);
+ }
}
- dev = add_generic_device("atmel_mci", 0, NULL, AT91SAM9260_BASE_MCI, SZ_16K,
+ dev = add_generic_device("atmel_mci", mmc_id, NULL, AT91SAM9260_BASE_MCI, SZ_16K,
IORESOURCE_MEM, data);
}
#else
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 984d9dc..726920f 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -20,6 +20,7 @@ config ARCH_TEXT_BASE
default 0xa7e00000 if MACH_NESO
default 0x97f00000 if MACH_MX51_PDK
default 0x7ff00000 if MACH_MX53_LOCO
+ default 0x7ff00000 if MACH_MX53_SMD
default 0x87f00000 if MACH_GUF_CUPID
default 0x93d00000 if MACH_TX25
@@ -40,6 +41,7 @@ config BOARDINFO
default "Garz+Fricke Neso" if MACH_NESO
default "Freescale i.MX51 PDK" if MACH_FREESCALE_MX51_PDK
default "Freescale i.MX53 LOCO" if MACH_FREESCALE_MX53_LOCO
+ default "Freescale i.MX53 SMD" if MACH_FREESCALE_MX53_SMD
default "Garz+Fricke Cupid" if MACH_GUF_CUPID
default "Ka-Ro tx25" if MACH_TX25
@@ -402,6 +404,9 @@ choice
config MACH_FREESCALE_MX53_LOCO
bool "Freescale i.MX53 LOCO"
+config MACH_FREESCALE_MX53_SMD
+ bool "Freescale i.MX53 SMD"
+
endchoice
endif
diff --git a/arch/arm/mach-imx/boot.c b/arch/arm/mach-imx/boot.c
index f13d956..8b82655 100644
--- a/arch/arm/mach-imx/boot.c
+++ b/arch/arm/mach-imx/boot.c
@@ -18,6 +18,7 @@
#include <common.h>
#include <environment.h>
#include <init.h>
+#include <magicvar.h>
#include <io.h>
#include <mach/imx-regs.h>
@@ -88,4 +89,6 @@ static int imx_25_35_boot_save_loc(void)
coredevice_initcall(imx_25_35_boot_save_loc);
+BAREBOX_MAGICVAR(barebox_loc, "The source barebox has been booted from");
+
#endif
diff --git a/arch/arm/mach-imx/devices.c b/arch/arm/mach-imx/devices.c
index 5b062f5..6cd50f3 100644
--- a/arch/arm/mach-imx/devices.c
+++ b/arch/arm/mach-imx/devices.c
@@ -48,7 +48,7 @@ struct device_d *imx_add_mmc(void *base, int id, void *pdata)
return imx_add_device("imx-mmc", id, base, 0x1000, pdata);
}
-struct device_d *imx_add_esdhc(void *base, int id, void *pdata)
+struct device_d *imx_add_esdhc(void *base, int id, struct esdhc_platform_data *pdata)
{
return imx_add_device("imx-esdhc", id, base, 0x1000, pdata);
}
diff --git a/arch/arm/mach-imx/imx53.c b/arch/arm/mach-imx/imx53.c
index 7f3c5ba..64bec86 100644
--- a/arch/arm/mach-imx/imx53.c
+++ b/arch/arm/mach-imx/imx53.c
@@ -173,6 +173,15 @@ int mx53_init_lowlevel(void)
r = readl(ccm + MX5_CCM_CSCDR1);
r &= ~0x3f;
r |= 0x0a;
+
+ r &= ~MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK;
+ r &= ~MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK;
+ r |= 1 << MX5_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET;
+
+ r &= ~MX5_CCM_CSCDR1_ESDHC3_MX53_CLK_PRED_MASK;
+ r &= ~MX5_CCM_CSCDR1_ESDHC3_MX53_CLK_PODF_MASK;
+ r |= 1 << MX5_CCM_CSCDR1_ESDHC3_MX53_CLK_PODF_OFFSET;
+
writel(r, ccm + MX5_CCM_CSCDR1);
/* Restore the default values in the Gate registers */
diff --git a/arch/arm/mach-imx/include/mach/devices-imx25.h b/arch/arm/mach-imx/include/mach/devices-imx25.h
index eff5977..bd9dd0a 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx25.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx25.h
@@ -36,7 +36,7 @@ static inline struct device_d *imx25_add_fec(struct fec_platform_data *pdata)
return imx_add_fec((void *)IMX_FEC_BASE, pdata);
}
-static inline struct device_d *imx25_add_mmc0(void *pdata)
+static inline struct device_d *imx25_add_mmc0(struct esdhc_platform_data *pdata)
{
return imx_add_esdhc((void *)0x53fb4000, 0, pdata);
}
diff --git a/arch/arm/mach-imx/include/mach/devices-imx35.h b/arch/arm/mach-imx/include/mach/devices-imx35.h
index 69f4b36..6c0d750 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx35.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx35.h
@@ -41,17 +41,17 @@ static inline struct device_d *imx35_add_fec(struct fec_platform_data *pdata)
return imx_add_fec((void *)IMX_FEC_BASE, pdata);
}
-static inline struct device_d *imx35_add_mmc0(void *pdata)
+static inline struct device_d *imx35_add_mmc0(struct esdhc_platform_data *pdata)
{
return imx_add_esdhc((void *)IMX_SDHC1_BASE, 0, pdata);
}
-static inline struct device_d *imx35_add_mmc1(void *pdata)
+static inline struct device_d *imx35_add_mmc1(struct esdhc_platform_data *pdata)
{
return imx_add_esdhc((void *)IMX_SDHC2_BASE, 1, pdata);
}
-static inline struct device_d *imx35_add_mmc2(void *pdata)
+static inline struct device_d *imx35_add_mmc2(struct esdhc_platform_data *pdata)
{
return imx_add_esdhc((void *)IMX_SDHC3_BASE, 2, pdata);
}
diff --git a/arch/arm/mach-imx/include/mach/devices-imx51.h b/arch/arm/mach-imx/include/mach/devices-imx51.h
index 23410a9..d9bed8c 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx51.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx51.h
@@ -42,12 +42,12 @@ static inline struct device_d *imx51_add_fec(struct fec_platform_data *pdata)
return imx_add_fec((void *)MX51_MXC_FEC_BASE_ADDR, pdata);
}
-static inline struct device_d *imx51_add_mmc0(void *pdata)
+static inline struct device_d *imx51_add_mmc0(struct esdhc_platform_data *pdata)
{
return imx_add_esdhc((void *)MX51_MMC_SDHC1_BASE_ADDR, 0, pdata);
}
-static inline struct device_d *imx51_add_mmc1(void *pdata)
+static inline struct device_d *imx51_add_mmc1(struct esdhc_platform_data *pdata)
{
return imx_add_esdhc((void *)MX51_MMC_SDHC2_BASE_ADDR, 1, pdata);
}
diff --git a/arch/arm/mach-imx/include/mach/devices-imx53.h b/arch/arm/mach-imx/include/mach/devices-imx53.h
index 70e7671..1fc2417 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx53.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx53.h
@@ -31,24 +31,29 @@ static inline struct device_d *imx53_add_uart1(void)
return imx_add_uart((void *)MX53_UART2_BASE_ADDR, 1);
}
+static inline struct device_d *imx53_add_uart2(void)
+{
+ return imx_add_uart((void *)MX53_UART3_BASE_ADDR, 2);
+}
+
static inline struct device_d *imx53_add_fec(struct fec_platform_data *pdata)
{
return imx_add_fec((void *)MX53_FEC_BASE_ADDR, pdata);
}
-static inline struct device_d *imx53_add_mmc0(void *pdata)
+static inline struct device_d *imx53_add_mmc0(struct esdhc_platform_data *pdata)
{
return imx_add_esdhc((void *)MX53_ESDHC1_BASE_ADDR, 0, pdata);
}
-static inline struct device_d *imx53_add_mmc1(void *pdata)
+static inline struct device_d *imx53_add_mmc1(struct esdhc_platform_data *pdata)
{
- return imx_add_esdhc((void *)MX53_ESDHC2_BASE_ADDR, 0, pdata);
+ return imx_add_esdhc((void *)MX53_ESDHC2_BASE_ADDR, 1, pdata);
}
-static inline struct device_d *imx53_add_mmc2(void *pdata)
+static inline struct device_d *imx53_add_mmc2(struct esdhc_platform_data *pdata)
{
- return imx_add_esdhc((void *)MX53_ESDHC3_BASE_ADDR, 0, pdata);
+ return imx_add_esdhc((void *)MX53_ESDHC3_BASE_ADDR, 2, pdata);
}
static inline struct device_d *imx53_add_nand(struct imx_nand_platform_data *pdata)
diff --git a/arch/arm/mach-imx/include/mach/devices.h b/arch/arm/mach-imx/include/mach/devices.h
index 7338ac5..f0f730a 100644
--- a/arch/arm/mach-imx/include/mach/devices.h
+++ b/arch/arm/mach-imx/include/mach/devices.h
@@ -5,6 +5,7 @@
#include <mach/imx-nand.h>
#include <mach/imxfb.h>
#include <mach/imx-ipu-fb.h>
+#include <mach/esdhc.h>
struct device_d *imx_add_fec(void *base, struct fec_platform_data *pdata);
struct device_d *imx_add_spi(void *base, int id, struct spi_imx_master *pdata);
@@ -14,5 +15,5 @@ struct device_d *imx_add_nand(void *base, struct imx_nand_platform_data *pdata);
struct device_d *imx_add_fb(void *base, struct imx_fb_platform_data *pdata);
struct device_d *imx_add_ipufb(void *base, struct imx_ipu_fb_platform_data *pdata);
struct device_d *imx_add_mmc(void *base, int id, void *pdata);
-struct device_d *imx_add_esdhc(void *base, int id, void *pdata);
+struct device_d *imx_add_esdhc(void *base, int id, struct esdhc_platform_data *pdata);
diff --git a/arch/arm/mach-imx/include/mach/esdhc.h b/arch/arm/mach-imx/include/mach/esdhc.h
new file mode 100644
index 0000000..aaf9748
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/esdhc.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010 Wolfram Sang <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; version 2
+ * of the License.
+ */
+
+#ifndef __ASM_ARCH_IMX_ESDHC_H
+#define __ASM_ARCH_IMX_ESDHC_H
+
+enum wp_types {
+ ESDHC_WP_NONE, /* no WP, neither controller nor gpio */
+ ESDHC_WP_CONTROLLER, /* mmc controller internal WP */
+ ESDHC_WP_GPIO, /* external gpio pin for WP */
+};
+
+enum cd_types {
+ ESDHC_CD_NONE, /* no CD, neither controller nor gpio */
+ ESDHC_CD_CONTROLLER, /* mmc controller internal CD */
+ ESDHC_CD_GPIO, /* external gpio pin for CD */
+ ESDHC_CD_PERMANENT, /* no CD, card permanently wired to host */
+};
+
+/**
+ * struct esdhc_platform_data - platform data for esdhc on i.MX
+ *
+ * ESDHC_WP(CD)_CONTROLLER type is not available on i.MX25/35.
+ *
+ * @wp_gpio: gpio for write_protect
+ * @cd_gpio: gpio for card_detect interrupt
+ * @wp_type: type of write_protect method (see wp_types enum above)
+ * @cd_type: type of card_detect method (see cd_types enum above)
+ */
+
+struct esdhc_platform_data {
+ unsigned int wp_gpio;
+ unsigned int cd_gpio;
+ enum wp_types wp_type;
+ enum cd_types cd_type;
+};
+#endif /* __ASM_ARCH_IMX_ESDHC_H */
diff --git a/arch/arm/mach-omap/Makefile b/arch/arm/mach-omap/Makefile
index 7204746..07bf30a 100644
--- a/arch/arm/mach-omap/Makefile
+++ b/arch/arm/mach-omap/Makefile
@@ -25,4 +25,5 @@ obj-$(CONFIG_ARCH_OMAP3) += omap3_core.o omap3_generic.o
obj-$(CONFIG_ARCH_OMAP4) += omap4_generic.o omap4_clock.o
obj-$(CONFIG_OMAP3_CLOCK_CONFIG) += omap3_clock_core.o omap3_clock.o
obj-$(CONFIG_OMAP_GPMC) += gpmc.o devices-gpmc-nand.o
-obj-y += gpio.o xload.o
+obj-$(CONFIG_SHELL_NONE) += xload.o
+obj-y += gpio.o
diff --git a/arch/arm/mach-omap/xload.c b/arch/arm/mach-omap/xload.c
index 216b9b5..a52a8ba 100644
--- a/arch/arm/mach-omap/xload.c
+++ b/arch/arm/mach-omap/xload.c
@@ -52,3 +52,44 @@ void *omap_xload_boot_mmc(void)
return buf;
}
+
+enum omap_boot_src omap_bootsrc(void)
+{
+#if defined(CONFIG_ARCH_OMAP3)
+ return omap3_bootsrc();
+#elif defined(CONFIG_ARCH_OMAP4)
+ return omap4_bootsrc();
+#endif
+}
+
+/*
+ * Replaces the default shell in xload configuration
+ */
+int run_shell(void)
+{
+ int (*func)(void) = NULL;
+
+ switch (omap_bootsrc())
+ {
+ case OMAP_BOOTSRC_MMC1:
+ printf("booting from MMC1\n");
+ func = omap_xload_boot_mmc();
+ break;
+ case OMAP_BOOTSRC_UNKNOWN:
+ printf("unknown boot source. Fall back to nand\n");
+ case OMAP_BOOTSRC_NAND:
+ printf("booting from NAND\n");
+ func = omap_xload_boot_nand(SZ_128K, SZ_256K);
+ break;
+ }
+
+ if (!func) {
+ printf("booting failed\n");
+ while (1);
+ }
+
+ shutdown_barebox();
+ func();
+
+ while (1);
+}
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
new file mode 100644
index 0000000..9e3c53a
--- /dev/null
+++ b/arch/arm/mach-pxa/Kconfig
@@ -0,0 +1,37 @@
+if ARCH_PXA
+
+config ARCH_TEXT_BASE
+ hex
+
+config BOARDINFO
+ string
+
+# ----------------------------------------------------------
+
+config ARCH_PXA2XX
+ bool
+ select CPU_XSCALE
+
+choice
+ prompt "Intel/Marvell PXA Processor"
+
+config ARCH_PXA27X
+ bool "PXA27x"
+ select ARCH_PXA2XX
+
+endchoice
+
+# ----------------------------------------------------------
+
+if ARCH_PXA27X
+
+choice
+ prompt "PXA27x Board Type"
+
+endchoice
+
+endif
+
+# ----------------------------------------------------------
+
+endif
diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile
new file mode 100644
index 0000000..c01a9e0
--- /dev/null
+++ b/arch/arm/mach-pxa/Makefile
@@ -0,0 +1,6 @@
+obj-y += clocksource.o
+obj-y += common.o
+obj-y += gpio.o
+
+obj-$(CONFIG_ARCH_PXA2XX) += mfp-pxa2xx.o
+obj-$(CONFIG_ARCH_PXA27X) += speed-pxa27x.o
diff --git a/arch/arm/mach-pxa/clocksource.c b/arch/arm/mach-pxa/clocksource.c
new file mode 100644
index 0000000..04d090a
--- /dev/null
+++ b/arch/arm/mach-pxa/clocksource.c
@@ -0,0 +1,45 @@
+/*
+ * (C) Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <asm/io.h>
+
+#define OSCR 0x40A00010
+
+uint64_t pxa_clocksource_read(void)
+{
+ return readl(OSCR);
+}
+
+static struct clocksource cs = {
+ .read = pxa_clocksource_read,
+ .mask = 0xffffffff,
+ .shift = 20,
+};
+
+static int clocksource_init(void)
+{
+ cs.mult = clocksource_hz2mult(3250000, cs.shift);
+
+ init_clock(&cs);
+
+ return 0;
+}
+
+core_initcall(clocksource_init);
diff --git a/arch/arm/mach-pxa/common.c b/arch/arm/mach-pxa/common.c
new file mode 100644
index 0000000..82e81b7
--- /dev/null
+++ b/arch/arm/mach-pxa/common.c
@@ -0,0 +1,37 @@
+/*
+ * (C) Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#define OSMR3 0x40A0000C
+#define OSCR 0x40A00010
+#define OSSR 0x40A00014
+#define OWER 0x40A00018
+
+#define OWER_WME (1 << 0) /* Watch-dog Match Enable */
+#define OSSR_M3 (1 << 3) /* Match status channel 3 */
+
+void reset_cpu(ulong addr)
+{
+ /* Initialize the watchdog and let it fire */
+ writel(OWER_WME, OWER);
+ writel(OSSR_M3, OSSR);
+ writel(readl(OSCR) + 368640, OSMR3); /* ... in 100 ms */
+
+ while (1);
+}
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
new file mode 100644
index 0000000..1a396f1
--- /dev/null
+++ b/arch/arm/mach-pxa/devices.c
@@ -0,0 +1,49 @@
+/*
+ * (C) 2011 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * 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.
+ *
+ */
+#include <common.h>
+#include <driver.h>
+#include <mach/devices.h>
+#include <mach/pxafb.h>
+
+static inline struct device_d *pxa_add_device(char *name, int id, void *base,
+ int size, void *pdata)
+{
+ return add_generic_device(name, id, NULL, (resource_size_t)base, size,
+ IORESOURCE_MEM, pdata);
+}
+
+struct device_d *pxa_add_i2c(void *base, int id,
+ struct i2c_platform_data *pdata)
+{
+ return pxa_add_device("i2c-pxa", id, base, 0x1000, pdata);
+}
+
+struct device_d *pxa_add_uart(void *base, int id)
+{
+ return pxa_add_device("pxa_serial", id, base, 0x1000, NULL);
+}
+
+struct device_d *pxa_add_fb(void *base, struct pxafb_platform_data *pdata)
+{
+ return pxa_add_device("pxafb", -1, base, 0x1000, pdata);
+}
+
+struct device_d *pxa_add_mmc(void *base, int id, void *pdata)
+{
+ return pxa_add_device("pxa-mmc", id, base, 0x1000, pdata);
+}
diff --git a/arch/arm/mach-pxa/gpio.c b/arch/arm/mach-pxa/gpio.c
new file mode 100644
index 0000000..4e98493
--- /dev/null
+++ b/arch/arm/mach-pxa/gpio.c
@@ -0,0 +1,68 @@
+/*
+ * Generic PXA GPIO handling
+ *
+ * Author: Nicolas Pitre
+ * Created: Jun 15, 2001
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <errno.h>
+
+#include <mach/gpio.h>
+#include <asm/io.h>
+
+int pxa_last_gpio;
+
+struct pxa_gpio_chip {
+ void __iomem *regbase;
+};
+
+static struct pxa_gpio_chip *pxa_gpio_chips;
+
+#define for_each_gpio_chip(i, c) \
+ for (i = 0, c = &pxa_gpio_chips[0]; i <= pxa_last_gpio; i += 32, c++)
+
+static int __init pxa_init_gpio_chip(int gpio_end)
+{
+ int i, gpio, nbanks = gpio_to_bank(gpio_end) + 1;
+ struct pxa_gpio_chip *chips;
+
+ chips = kzalloc(nbanks * sizeof(struct pxa_gpio_chip), GFP_KERNEL);
+ if (chips == NULL) {
+ pr_err("%s: failed to allocate GPIO chips\n", __func__);
+ return -ENOMEM;
+ }
+
+ for (i = 0, gpio = 0; i < nbanks; i++, gpio += 32)
+ chips[i].regbase = (void __iomem *)GPIO_BANK(i);
+
+ pxa_gpio_chips = chips;
+ return 0;
+}
+
+int __init pxa_init_gpio(int start, int end)
+{
+ struct pxa_gpio_chip *c;
+ int err, gpio;
+
+ pxa_last_gpio = end;
+
+ /* Initialize GPIO chips */
+ err = pxa_init_gpio_chip(end);
+ if (err)
+ return err;
+
+ for_each_gpio_chip(gpio, c) {
+ /* clear all GPIO edge detects */
+ __raw_writel(0, c->regbase + GFER_OFFSET);
+ __raw_writel(0, c->regbase + GRER_OFFSET);
+ __raw_writel(~0, c->regbase + GEDR_OFFSET);
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-pxa/include/mach/clock.h b/arch/arm/mach-pxa/include/mach/clock.h
new file mode 100644
index 0000000..cd0ab8e
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/clock.h
@@ -0,0 +1,16 @@
+
+/*
+ * clock.h - definitions of the PXA clock functions
+ *
+ * Copyright (C) 2010 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef __MACH_CLOCK_H
+#define __MACH_CLOCK_H
+
+unsigned long pxa_get_uartclk(void);
+
+#endif /* !__MACH_CLOCK_H */
diff --git a/arch/arm/mach-pxa/include/mach/devices.h b/arch/arm/mach-pxa/include/mach/devices.h
new file mode 100644
index 0000000..e205b7c
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/devices.h
@@ -0,0 +1,26 @@
+/*
+ * (C) 2011 Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * 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.
+ *
+ */
+#include <i2c/i2c.h>
+#include <mach/pxafb.h>
+
+struct device_d *pxa_add_i2c(void *base, int id,
+ struct i2c_platform_data *pdata);
+struct device_d *pxa_add_uart(void *base, int id);
+struct device_d *pxa_add_fb(void *base, struct pxafb_platform_data *pdata);
+struct device_d *pxa_add_mmc(void *base, int id, void *pdata);
+
diff --git a/arch/arm/mach-pxa/include/mach/gpio.h b/arch/arm/mach-pxa/include/mach/gpio.h
new file mode 100644
index 0000000..e6724e1
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/gpio.h
@@ -0,0 +1,132 @@
+/*
+ * arch/arm/mach-pxa/include/mach/gpio.h
+ *
+ * PXA GPIO wrappers for arch-neutral GPIO calls
+ *
+ * Written by Philipp Zabel <philipp.zabel@gmail.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.
+ *
+ */
+
+#ifndef __ASM_ARCH_PXA_GPIO_H
+#define __ASM_ARCH_PXA_GPIO_H
+
+#include <mach/hardware.h>
+
+#define GPIO_REGS_VIRT (0x40E00000)
+
+#define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2))
+#define GPIO_REG(x) (*(volatile u32 *)(GPIO_REGS_VIRT + (x)))
+
+/* GPIO Pin Level Registers */
+#define GPLR0 GPIO_REG(BANK_OFF(0) + 0x00)
+#define GPLR1 GPIO_REG(BANK_OFF(1) + 0x00)
+#define GPLR2 GPIO_REG(BANK_OFF(2) + 0x00)
+#define GPLR3 GPIO_REG(BANK_OFF(3) + 0x00)
+
+/* GPIO Pin Direction Registers */
+#define GPDR0 GPIO_REG(BANK_OFF(0) + 0x0c)
+#define GPDR1 GPIO_REG(BANK_OFF(1) + 0x0c)
+#define GPDR2 GPIO_REG(BANK_OFF(2) + 0x0c)
+#define GPDR3 GPIO_REG(BANK_OFF(3) + 0x0c)
+
+/* GPIO Pin Output Set Registers */
+#define GPSR0 GPIO_REG(BANK_OFF(0) + 0x18)
+#define GPSR1 GPIO_REG(BANK_OFF(1) + 0x18)
+#define GPSR2 GPIO_REG(BANK_OFF(2) + 0x18)
+#define GPSR3 GPIO_REG(BANK_OFF(3) + 0x18)
+
+/* GPIO Pin Output Clear Registers */
+#define GPCR0 GPIO_REG(BANK_OFF(0) + 0x24)
+#define GPCR1 GPIO_REG(BANK_OFF(1) + 0x24)
+#define GPCR2 GPIO_REG(BANK_OFF(2) + 0x24)
+#define GPCR3 GPIO_REG(BANK_OFF(3) + 0x24)
+
+/* GPIO Rising Edge Detect Registers */
+#define GRER0 GPIO_REG(BANK_OFF(0) + 0x30)
+#define GRER1 GPIO_REG(BANK_OFF(1) + 0x30)
+#define GRER2 GPIO_REG(BANK_OFF(2) + 0x30)
+#define GRER3 GPIO_REG(BANK_OFF(3) + 0x30)
+
+/* GPIO Falling Edge Detect Registers */
+#define GFER0 GPIO_REG(BANK_OFF(0) + 0x3c)
+#define GFER1 GPIO_REG(BANK_OFF(1) + 0x3c)
+#define GFER2 GPIO_REG(BANK_OFF(2) + 0x3c)
+#define GFER3 GPIO_REG(BANK_OFF(3) + 0x3c)
+
+/* GPIO Edge Detect Status Registers */
+#define GEDR0 GPIO_REG(BANK_OFF(0) + 0x48)
+#define GEDR1 GPIO_REG(BANK_OFF(1) + 0x48)
+#define GEDR2 GPIO_REG(BANK_OFF(2) + 0x48)
+#define GEDR3 GPIO_REG(BANK_OFF(3) + 0x48)
+
+/* GPIO Alternate Function Select Registers */
+#define GAFR0_L GPIO_REG(0x0054)
+#define GAFR0_U GPIO_REG(0x0058)
+#define GAFR1_L GPIO_REG(0x005C)
+#define GAFR1_U GPIO_REG(0x0060)
+#define GAFR2_L GPIO_REG(0x0064)
+#define GAFR2_U GPIO_REG(0x0068)
+#define GAFR3_L GPIO_REG(0x006C)
+#define GAFR3_U GPIO_REG(0x0070)
+
+/* More handy macros. The argument is a literal GPIO number. */
+
+#define GPIO_bit(x) (1 << ((x) & 0x1f))
+
+#define GPLR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x00)
+#define GPDR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x0c)
+#define GPSR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x18)
+#define GPCR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x24)
+#define GRER(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x30)
+#define GFER(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x3c)
+#define GEDR(x) GPIO_REG(BANK_OFF((x) >> 5) + 0x48)
+#define GAFR(x) GPIO_REG(0x54 + (((x) & 0x70) >> 2))
+
+
+#define NR_BUILTIN_GPIO 128
+
+#define gpio_to_bank(gpio) ((gpio) >> 5)
+
+#ifdef CONFIG_CPU_PXA26x
+/* GPIO86/87/88/89 on PXA26x have their direction bits in GPDR2 inverted,
+ * as well as their Alternate Function value being '1' for GPIO in GAFRx.
+ */
+static inline int __gpio_is_inverted(unsigned gpio)
+{
+ return cpu_is_pxa25x() && gpio > 85;
+}
+#else
+static inline int __gpio_is_inverted(unsigned gpio) { return 0; }
+#endif
+
+/*
+ * On PXA25x and PXA27x, GAFRx and GPDRx together decide the alternate
+ * function of a GPIO, and GPDRx cannot be altered once configured. It
+ * is attributed as "occupied" here (I know this terminology isn't
+ * accurate, you are welcome to propose a better one :-)
+ */
+static inline int __gpio_is_occupied(unsigned gpio)
+{
+ if (cpu_is_pxa27x() || cpu_is_pxa25x()) {
+ int af = (GAFR(gpio) >> ((gpio & 0xf) * 2)) & 0x3;
+ int dir = GPDR(gpio) & GPIO_bit(gpio);
+
+ if (__gpio_is_inverted(gpio))
+ return af != 1 || dir == 0;
+ else
+ return af != 0 || dir != 0;
+ } else
+ return GPDR(gpio) & GPIO_bit(gpio);
+}
+#include <plat/gpio.h>
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/hardware.h b/arch/arm/mach-pxa/include/mach/hardware.h
new file mode 100644
index 0000000..e53085c
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/hardware.h
@@ -0,0 +1,31 @@
+/*
+ * (c) 2010 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * Copyright (C) 2010 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef __MACH_HARDWARE_H
+#define __MACH_HARDWARE_H
+
+#ifdef CONFIG_ARCH_PXA2XX
+#define cpu_is_pxa2xx() (1)
+#else
+#define cpi_is_pxa2xx() (0)
+#endif
+
+#ifdef CONFIG_ARCH_PXA25X
+#define cpu_is_pxa25x() (1)
+#else
+#define cpu_is_pxa25x() (0)
+#endif
+
+#ifdef CONFIG_ARCH_PXA27X
+#define cpu_is_pxa27x() (1)
+#else
+#define cpu_is_pxa27x() (0)
+#endif
+
+#endif /* !__MACH_HARDWARE_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
new file mode 100644
index 0000000..6543c05
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa27x.h
@@ -0,0 +1,438 @@
+#ifndef __ASM_ARCH_MFP_PXA27X_H
+#define __ASM_ARCH_MFP_PXA27X_H
+
+/*
+ * NOTE: for those special-function bidirectional GPIOs, as described
+ * in the "PXA27x Developer's Manual" Section 24.4.2.1, only its input
+ * alternative is preserved, the direction is actually selected by the
+ * specific controller, and this should work in most cases.
+ */
+
+#include <mach/mfp-pxa2xx.h>
+
+/* Note: GPIO3/GPIO4 will be driven by Power I2C when PCFR/PI2C_EN
+ * bit is set, regardless of the GPIO configuration
+ */
+#define GPIO3_GPIO MFP_CFG_IN(GPIO3, AF0)
+#define GPIO4_GPIO MFP_CFG_IN(GPIO4, AF0)
+
+/* GPIO */
+#define GPIO85_GPIO MFP_CFG_IN(GPIO85, AF0)
+#define GPIO86_GPIO MFP_CFG_IN(GPIO86, AF0)
+#define GPIO87_GPIO MFP_CFG_IN(GPIO87, AF0)
+#define GPIO88_GPIO MFP_CFG_IN(GPIO88, AF0)
+#define GPIO89_GPIO MFP_CFG_IN(GPIO89, AF0)
+#define GPIO90_GPIO MFP_CFG_IN(GPIO90, AF0)
+#define GPIO91_GPIO MFP_CFG_IN(GPIO91, AF0)
+#define GPIO92_GPIO MFP_CFG_IN(GPIO92, AF0)
+#define GPIO93_GPIO MFP_CFG_IN(GPIO93, AF0)
+#define GPIO94_GPIO MFP_CFG_IN(GPIO94, AF0)
+#define GPIO95_GPIO MFP_CFG_IN(GPIO95, AF0)
+#define GPIO96_GPIO MFP_CFG_IN(GPIO96, AF0)
+#define GPIO97_GPIO MFP_CFG_IN(GPIO97, AF0)
+#define GPIO98_GPIO MFP_CFG_IN(GPIO98, AF0)
+#define GPIO99_GPIO MFP_CFG_IN(GPIO99, AF0)
+#define GPIO100_GPIO MFP_CFG_IN(GPIO100, AF0)
+#define GPIO101_GPIO MFP_CFG_IN(GPIO101, AF0)
+#define GPIO102_GPIO MFP_CFG_IN(GPIO102, AF0)
+#define GPIO103_GPIO MFP_CFG_IN(GPIO103, AF0)
+#define GPIO104_GPIO MFP_CFG_IN(GPIO104, AF0)
+#define GPIO105_GPIO MFP_CFG_IN(GPIO105, AF0)
+#define GPIO106_GPIO MFP_CFG_IN(GPIO106, AF0)
+#define GPIO107_GPIO MFP_CFG_IN(GPIO107, AF0)
+#define GPIO108_GPIO MFP_CFG_IN(GPIO108, AF0)
+#define GPIO109_GPIO MFP_CFG_IN(GPIO109, AF0)
+#define GPIO110_GPIO MFP_CFG_IN(GPIO110, AF0)
+#define GPIO111_GPIO MFP_CFG_IN(GPIO111, AF0)
+#define GPIO112_GPIO MFP_CFG_IN(GPIO112, AF0)
+#define GPIO113_GPIO MFP_CFG_IN(GPIO113, AF0)
+#define GPIO114_GPIO MFP_CFG_IN(GPIO114, AF0)
+#define GPIO115_GPIO MFP_CFG_IN(GPIO115, AF0)
+#define GPIO116_GPIO MFP_CFG_IN(GPIO116, AF0)
+#define GPIO117_GPIO MFP_CFG_IN(GPIO117, AF0)
+#define GPIO118_GPIO MFP_CFG_IN(GPIO118, AF0)
+#define GPIO119_GPIO MFP_CFG_IN(GPIO119, AF0)
+#define GPIO120_GPIO MFP_CFG_IN(GPIO120, AF0)
+
+/* Crystal and Clock Signals */
+#define GPIO9_HZ_CLK MFP_CFG_OUT(GPIO9, AF1, DRIVE_LOW)
+#define GPIO10_HZ_CLK MFP_CFG_OUT(GPIO10, AF1, DRIVE_LOW)
+#define GPIO11_48_MHz MFP_CFG_OUT(GPIO11, AF3, DRIVE_LOW)
+#define GPIO12_48_MHz MFP_CFG_OUT(GPIO12, AF3, DRIVE_LOW)
+#define GPIO13_CLK_EXT MFP_CFG_IN(GPIO13, AF1)
+
+/* OS Timer Signals */
+#define GPIO11_EXT_SYNC_0 MFP_CFG_IN(GPIO11, AF1)
+#define GPIO12_EXT_SYNC_1 MFP_CFG_IN(GPIO12, AF1)
+#define GPIO9_CHOUT_0 MFP_CFG_OUT(GPIO9, AF3, DRIVE_LOW)
+#define GPIO10_CHOUT_1 MFP_CFG_OUT(GPIO10, AF3, DRIVE_LOW)
+#define GPIO11_CHOUT_0 MFP_CFG_OUT(GPIO11, AF1, DRIVE_LOW)
+#define GPIO12_CHOUT_1 MFP_CFG_OUT(GPIO12, AF1, DRIVE_LOW)
+
+/* SDRAM and Static Memory I/O Signals */
+#define GPIO20_nSDCS_2 MFP_CFG_OUT(GPIO20, AF1, DRIVE_HIGH)
+#define GPIO21_nSDCS_3 MFP_CFG_OUT(GPIO21, AF1, DRIVE_HIGH)
+#define GPIO15_nCS_1 MFP_CFG_OUT(GPIO15, AF2, DRIVE_HIGH)
+#define GPIO78_nCS_2 MFP_CFG_OUT(GPIO78, AF2, DRIVE_HIGH)
+#define GPIO79_nCS_3 MFP_CFG_OUT(GPIO79, AF2, DRIVE_HIGH)
+#define GPIO80_nCS_4 MFP_CFG_OUT(GPIO80, AF2, DRIVE_HIGH)
+#define GPIO33_nCS_5 MFP_CFG_OUT(GPIO33, AF2, DRIVE_HIGH)
+
+/* Miscellaneous I/O and DMA Signals */
+#define GPIO21_DVAL_0 MFP_CFG_OUT(GPIO21, AF2, DRIVE_HIGH)
+#define GPIO116_DVAL_0 MFP_CFG_OUT(GPIO116, AF1, DRIVE_HIGH)
+#define GPIO33_DVAL_1 MFP_CFG_OUT(GPIO33, AF1, DRIVE_HIGH)
+#define GPIO96_DVAL_1 MFP_CFG_OUT(GPIO96, AF2, DRIVE_HIGH)
+#define GPIO18_RDY MFP_CFG_IN(GPIO18, AF1)
+#define GPIO20_DREQ_0 MFP_CFG_IN(GPIO20, AF1)
+#define GPIO115_DREQ_0 MFP_CFG_IN(GPIO115, AF1)
+#define GPIO80_DREQ_1 MFP_CFG_IN(GPIO80, AF1)
+#define GPIO97_DREQ_1 MFP_CFG_IN(GPIO97, AF2)
+#define GPIO85_DREQ_2 MFP_CFG_IN(GPIO85, AF2)
+#define GPIO100_DREQ_2 MFP_CFG_IN(GPIO100, AF2)
+
+/* Alternate Bus Master Mode I/O Signals */
+#define GPIO20_MBREQ MFP_CFG_IN(GPIO20, AF2)
+#define GPIO80_MBREQ MFP_CFG_IN(GPIO80, AF2)
+#define GPIO96_MBREQ MFP_CFG_IN(GPIO96, AF2)
+#define GPIO115_MBREQ MFP_CFG_IN(GPIO115, AF3)
+#define GPIO21_MBGNT MFP_CFG_OUT(GPIO21, AF3, DRIVE_LOW)
+#define GPIO33_MBGNT MFP_CFG_OUT(GPIO33, AF3, DRIVE_LOW)
+#define GPIO97_MBGNT MFP_CFG_OUT(GPIO97, AF2, DRIVE_LOW)
+#define GPIO116_MBGNT MFP_CFG_OUT(GPIO116, AF3, DRIVE_LOW)
+
+/* PC CARD */
+#define GPIO15_nPCE_1 MFP_CFG_OUT(GPIO15, AF1, DRIVE_HIGH)
+#define GPIO85_nPCE_1 MFP_CFG_OUT(GPIO85, AF1, DRIVE_HIGH)
+#define GPIO86_nPCE_1 MFP_CFG_OUT(GPIO86, AF1, DRIVE_HIGH)
+#define GPIO102_nPCE_1 MFP_CFG_OUT(GPIO102, AF1, DRIVE_HIGH)
+#define GPIO54_nPCE_2 MFP_CFG_OUT(GPIO54, AF2, DRIVE_HIGH)
+#define GPIO78_nPCE_2 MFP_CFG_OUT(GPIO78, AF1, DRIVE_HIGH)
+#define GPIO87_nPCE_2 MFP_CFG_IN(GPIO87, AF1)
+#define GPIO55_nPREG MFP_CFG_OUT(GPIO55, AF2, DRIVE_HIGH)
+#define GPIO50_nPIOR MFP_CFG_OUT(GPIO50, AF2, DRIVE_HIGH)
+#define GPIO51_nPIOW MFP_CFG_OUT(GPIO51, AF2, DRIVE_HIGH)
+#define GPIO49_nPWE MFP_CFG_OUT(GPIO49, AF2, DRIVE_HIGH)
+#define GPIO48_nPOE MFP_CFG_OUT(GPIO48, AF2, DRIVE_HIGH)
+#define GPIO57_nIOIS16 MFP_CFG_IN(GPIO57, AF1)
+#define GPIO56_nPWAIT MFP_CFG_IN(GPIO56, AF1)
+#define GPIO79_PSKTSEL MFP_CFG_OUT(GPIO79, AF1, DRIVE_HIGH)
+#define GPIO104_PSKTSEL MFP_CFG_OUT(GPIO104, AF1, DRIVE_HIGH)
+
+/* I2C */
+#define GPIO117_I2C_SCL MFP_CFG_IN(GPIO117, AF1)
+#define GPIO118_I2C_SDA MFP_CFG_IN(GPIO118, AF1)
+
+/* FFUART */
+#define GPIO9_FFUART_CTS MFP_CFG_IN(GPIO9, AF3)
+#define GPIO26_FFUART_CTS MFP_CFG_IN(GPIO26, AF3)
+#define GPIO35_FFUART_CTS MFP_CFG_IN(GPIO35, AF1)
+#define GPIO100_FFUART_CTS MFP_CFG_IN(GPIO100, AF3)
+#define GPIO10_FFUART_DCD MFP_CFG_IN(GPIO10, AF1)
+#define GPIO36_FFUART_DCD MFP_CFG_IN(GPIO36, AF1)
+#define GPIO33_FFUART_DSR MFP_CFG_IN(GPIO33, AF2)
+#define GPIO37_FFUART_DSR MFP_CFG_IN(GPIO37, AF1)
+#define GPIO38_FFUART_RI MFP_CFG_IN(GPIO38, AF1)
+#define GPIO89_FFUART_RI MFP_CFG_IN(GPIO89, AF3)
+#define GPIO19_FFUART_RXD MFP_CFG_IN(GPIO19, AF3)
+#define GPIO33_FFUART_RXD MFP_CFG_IN(GPIO33, AF1)
+#define GPIO34_FFUART_RXD MFP_CFG_IN(GPIO34, AF1)
+#define GPIO41_FFUART_RXD MFP_CFG_IN(GPIO41, AF1)
+#define GPIO53_FFUART_RXD MFP_CFG_IN(GPIO53, AF1)
+#define GPIO85_FFUART_RXD MFP_CFG_IN(GPIO85, AF1)
+#define GPIO96_FFUART_RXD MFP_CFG_IN(GPIO96, AF3)
+#define GPIO102_FFUART_RXD MFP_CFG_IN(GPIO102, AF3)
+#define GPIO16_FFUART_TXD MFP_CFG_OUT(GPIO16, AF3, DRIVE_HIGH)
+#define GPIO37_FFUART_TXD MFP_CFG_OUT(GPIO37, AF3, DRIVE_HIGH)
+#define GPIO39_FFUART_TXD MFP_CFG_OUT(GPIO39, AF2, DRIVE_HIGH)
+#define GPIO83_FFUART_TXD MFP_CFG_OUT(GPIO83, AF2, DRIVE_HIGH)
+#define GPIO99_FFUART_TXD MFP_CFG_OUT(GPIO99, AF3, DRIVE_HIGH)
+#define GPIO27_FFUART_RTS MFP_CFG_OUT(GPIO27, AF3, DRIVE_HIGH)
+#define GPIO41_FFUART_RTS MFP_CFG_OUT(GPIO41, AF2, DRIVE_HIGH)
+#define GPIO83_FFUART_RTS MFP_CFG_OUT(GPIO83, AF3, DRIVE_HIGH)
+#define GPIO98_FFUART_RTS MFP_CFG_OUT(GPIO98, AF3, DRIVE_HIGH)
+#define GPIO40_FFUART_DTR MFP_CFG_OUT(GPIO40, AF2, DRIVE_HIGH)
+#define GPIO82_FFUART_DTR MFP_CFG_OUT(GPIO82, AF3, DRIVE_HIGH)
+
+/* BTUART */
+#define GPIO44_BTUART_CTS MFP_CFG_IN(GPIO44, AF1)
+#define GPIO42_BTUART_RXD MFP_CFG_IN(GPIO42, AF1)
+#define GPIO45_BTUART_RTS MFP_CFG_OUT(GPIO45, AF2, DRIVE_HIGH)
+#define GPIO43_BTUART_TXD MFP_CFG_OUT(GPIO43, AF2, DRIVE_HIGH)
+
+/* STUART */
+#define GPIO46_STUART_RXD MFP_CFG_IN(GPIO46, AF2)
+#define GPIO47_STUART_TXD MFP_CFG_OUT(GPIO47, AF1, DRIVE_HIGH)
+
+/* FICP */
+#define GPIO42_FICP_RXD MFP_CFG_IN(GPIO42, AF2)
+#define GPIO46_FICP_RXD MFP_CFG_IN(GPIO46, AF1)
+#define GPIO43_FICP_TXD MFP_CFG_OUT(GPIO43, AF1, DRIVE_HIGH)
+#define GPIO47_FICP_TXD MFP_CFG_OUT(GPIO47, AF2, DRIVE_HIGH)
+
+/* PWM 0/1/2/3 */
+#define GPIO11_PWM2_OUT MFP_CFG_OUT(GPIO11, AF2, DRIVE_LOW)
+#define GPIO12_PWM3_OUT MFP_CFG_OUT(GPIO12, AF2, DRIVE_LOW)
+#define GPIO16_PWM0_OUT MFP_CFG_OUT(GPIO16, AF2, DRIVE_LOW)
+#define GPIO17_PWM1_OUT MFP_CFG_OUT(GPIO17, AF2, DRIVE_LOW)
+#define GPIO38_PWM1_OUT MFP_CFG_OUT(GPIO38, AF3, DRIVE_LOW)
+#define GPIO46_PWM2_OUT MFP_CFG_OUT(GPIO46, AF2, DRIVE_LOW)
+#define GPIO47_PWM3_OUT MFP_CFG_OUT(GPIO47, AF3, DRIVE_LOW)
+#define GPIO79_PWM2_OUT MFP_CFG_OUT(GPIO79, AF3, DRIVE_LOW)
+#define GPIO80_PWM3_OUT MFP_CFG_OUT(GPIO80, AF3, DRIVE_LOW)
+#define GPIO115_PWM1_OUT MFP_CFG_OUT(GPIO115, AF3, DRIVE_LOW)
+
+/* AC97 */
+#define GPIO31_AC97_SYNC MFP_CFG_OUT(GPIO31, AF2, DRIVE_LOW)
+#define GPIO94_AC97_SYNC MFP_CFG_OUT(GPIO94, AF1, DRIVE_LOW)
+#define GPIO30_AC97_SDATA_OUT MFP_CFG_OUT(GPIO30, AF2, DRIVE_LOW)
+#define GPIO93_AC97_SDATA_OUT MFP_CFG_OUT(GPIO93, AF1, DRIVE_LOW)
+#define GPIO45_AC97_SYSCLK MFP_CFG_OUT(GPIO45, AF1, DRIVE_LOW)
+#define GPIO89_AC97_SYSCLK MFP_CFG_OUT(GPIO89, AF1, DRIVE_LOW)
+#define GPIO98_AC97_SYSCLK MFP_CFG_OUT(GPIO98, AF1, DRIVE_LOW)
+#define GPIO95_AC97_nRESET MFP_CFG_OUT(GPIO95, AF1, DRIVE_LOW)
+#define GPIO113_AC97_nRESET MFP_CFG_OUT(GPIO113, AF2, DRIVE_LOW)
+#define GPIO28_AC97_BITCLK MFP_CFG_IN(GPIO28, AF1)
+#define GPIO29_AC97_SDATA_IN_0 MFP_CFG_IN(GPIO29, AF1)
+#define GPIO116_AC97_SDATA_IN_0 MFP_CFG_IN(GPIO116, AF2)
+#define GPIO99_AC97_SDATA_IN_1 MFP_CFG_IN(GPIO99, AF2)
+
+/* I2S */
+#define GPIO28_I2S_BITCLK_IN MFP_CFG_IN(GPIO28, AF2)
+#define GPIO28_I2S_BITCLK_OUT MFP_CFG_OUT(GPIO28, AF1, DRIVE_LOW)
+#define GPIO29_I2S_SDATA_IN MFP_CFG_IN(GPIO29, AF2)
+#define GPIO30_I2S_SDATA_OUT MFP_CFG_OUT(GPIO30, AF1, DRIVE_LOW)
+#define GPIO31_I2S_SYNC MFP_CFG_OUT(GPIO31, AF1, DRIVE_LOW)
+#define GPIO113_I2S_SYSCLK MFP_CFG_OUT(GPIO113, AF1, DRIVE_LOW)
+
+/* SSP 1 */
+#define GPIO23_SSP1_SCLK MFP_CFG_OUT(GPIO23, AF2, DRIVE_LOW)
+#define GPIO29_SSP1_SCLK MFP_CFG_IN(GPIO29, AF3)
+#define GPIO27_SSP1_SYSCLK MFP_CFG_OUT(GPIO27, AF1, DRIVE_LOW)
+#define GPIO53_SSP1_SYSCLK MFP_CFG_OUT(GPIO53, AF3, DRIVE_LOW)
+#define GPIO24_SSP1_SFRM MFP_CFG_IN(GPIO24, AF2)
+#define GPIO28_SSP1_SFRM MFP_CFG_IN(GPIO28, AF3)
+#define GPIO25_SSP1_TXD MFP_CFG_OUT(GPIO25, AF2, DRIVE_LOW)
+#define GPIO57_SSP1_TXD MFP_CFG_OUT(GPIO57, AF3, DRIVE_LOW)
+#define GPIO26_SSP1_RXD MFP_CFG_IN(GPIO26, AF1)
+#define GPIO27_SSP1_SCLKEN MFP_CFG_IN(GPIO27, AF2)
+
+/* SSP 2 */
+#define GPIO19_SSP2_SCLK MFP_CFG_IN(GPIO19, AF1)
+#define GPIO22_SSP2_SCLK MFP_CFG_IN(GPIO22, AF3)
+#define GPIO29_SSP2_SCLK MFP_CFG_OUT(GPIO29, AF3, DRIVE_LOW)
+#define GPIO36_SSP2_SCLK MFP_CFG_IN(GPIO36, AF2)
+#define GPIO50_SSP2_SCLK MFP_CFG_IN(GPIO50, AF3)
+#define GPIO22_SSP2_SYSCLK MFP_CFG_OUT(GPIO22, AF2, DRIVE_LOW)
+#define GPIO14_SSP2_SFRM MFP_CFG_IN(GPIO14, AF2)
+#define GPIO37_SSP2_SFRM MFP_CFG_IN(GPIO37, AF2)
+#define GPIO87_SSP2_SFRM MFP_CFG_OUT(GPIO87, AF3, DRIVE_LOW)
+#define GPIO88_SSP2_SFRM MFP_CFG_IN(GPIO88, AF3)
+#define GPIO13_SSP2_TXD MFP_CFG_OUT(GPIO13, AF1, DRIVE_LOW)
+#define GPIO38_SSP2_TXD MFP_CFG_OUT(GPIO38, AF2, DRIVE_LOW)
+#define GPIO87_SSP2_TXD MFP_CFG_OUT(GPIO87, AF1, DRIVE_LOW)
+#define GPIO89_SSP2_TXD MFP_CFG_OUT(GPIO89, AF3, DRIVE_LOW)
+#define GPIO11_SSP2_RXD MFP_CFG_IN(GPIO11, AF2)
+#define GPIO29_SSP2_RXD MFP_CFG_OUT(GPIO29, AF1, DRIVE_LOW)
+#define GPIO40_SSP2_RXD MFP_CFG_IN(GPIO40, AF1)
+#define GPIO86_SSP2_RXD MFP_CFG_IN(GPIO86, AF1)
+#define GPIO88_SSP2_RXD MFP_CFG_IN(GPIO88, AF2)
+#define GPIO22_SSP2_EXTCLK MFP_CFG_IN(GPIO22, AF1)
+#define GPIO27_SSP2_EXTCLK MFP_CFG_IN(GPIO27, AF1)
+#define GPIO22_SSP2_SCLKEN MFP_CFG_IN(GPIO22, AF2)
+#define GPIO23_SSP2_SCLKEN MFP_CFG_IN(GPIO23, AF2)
+
+/* SSP 3 */
+#define GPIO34_SSP3_SCLK MFP_CFG_IN(GPIO34, AF3)
+#define GPIO40_SSP3_SCLK MFP_CFG_OUT(GPIO40, AF3, DRIVE_LOW)
+#define GPIO52_SSP3_SCLK MFP_CFG_IN(GPIO52, AF2)
+#define GPIO84_SSP3_SCLK MFP_CFG_IN(GPIO84, AF1)
+#define GPIO45_SSP3_SYSCLK MFP_CFG_OUT(GPIO45, AF3, DRIVE_LOW)
+#define GPIO35_SSP3_SFRM MFP_CFG_IN(GPIO35, AF3)
+#define GPIO39_SSP3_SFRM MFP_CFG_IN(GPIO39, AF3)
+#define GPIO83_SSP3_SFRM MFP_CFG_IN(GPIO83, AF1)
+#define GPIO35_SSP3_TXD MFP_CFG_OUT(GPIO35, AF3, DRIVE_LOW)
+#define GPIO38_SSP3_TXD MFP_CFG_OUT(GPIO38, AF1, DRIVE_LOW)
+#define GPIO81_SSP3_TXD MFP_CFG_OUT(GPIO81, AF1, DRIVE_LOW)
+#define GPIO41_SSP3_RXD MFP_CFG_IN(GPIO41, AF3)
+#define GPIO82_SSP3_RXD MFP_CFG_IN(GPIO82, AF1)
+#define GPIO89_SSP3_RXD MFP_CFG_IN(GPIO89, AF1)
+
+/* MMC */
+#define GPIO32_MMC_CLK MFP_CFG_OUT(GPIO32, AF2, DRIVE_LOW)
+#define GPIO92_MMC_DAT_0 MFP_CFG_IN(GPIO92, AF1)
+#define GPIO109_MMC_DAT_1 MFP_CFG_IN(GPIO109, AF1)
+#define GPIO110_MMC_DAT_2 MFP_CFG_IN(GPIO110, AF1)
+#define GPIO111_MMC_DAT_3 MFP_CFG_IN(GPIO111, AF1)
+#define GPIO112_MMC_CMD MFP_CFG_IN(GPIO112, AF1)
+
+/* LCD */
+#define GPIO58_LCD_LDD_0 MFP_CFG_OUT(GPIO58, AF2, DRIVE_LOW)
+#define GPIO59_LCD_LDD_1 MFP_CFG_OUT(GPIO59, AF2, DRIVE_LOW)
+#define GPIO60_LCD_LDD_2 MFP_CFG_OUT(GPIO60, AF2, DRIVE_LOW)
+#define GPIO61_LCD_LDD_3 MFP_CFG_OUT(GPIO61, AF2, DRIVE_LOW)
+#define GPIO62_LCD_LDD_4 MFP_CFG_OUT(GPIO62, AF2, DRIVE_LOW)
+#define GPIO63_LCD_LDD_5 MFP_CFG_OUT(GPIO63, AF2, DRIVE_LOW)
+#define GPIO64_LCD_LDD_6 MFP_CFG_OUT(GPIO64, AF2, DRIVE_LOW)
+#define GPIO65_LCD_LDD_7 MFP_CFG_OUT(GPIO65, AF2, DRIVE_LOW)
+#define GPIO66_LCD_LDD_8 MFP_CFG_OUT(GPIO66, AF2, DRIVE_LOW)
+#define GPIO67_LCD_LDD_9 MFP_CFG_OUT(GPIO67, AF2, DRIVE_LOW)
+#define GPIO68_LCD_LDD_10 MFP_CFG_OUT(GPIO68, AF2, DRIVE_LOW)
+#define GPIO69_LCD_LDD_11 MFP_CFG_OUT(GPIO69, AF2, DRIVE_LOW)
+#define GPIO70_LCD_LDD_12 MFP_CFG_OUT(GPIO70, AF2, DRIVE_LOW)
+#define GPIO71_LCD_LDD_13 MFP_CFG_OUT(GPIO71, AF2, DRIVE_LOW)
+#define GPIO72_LCD_LDD_14 MFP_CFG_OUT(GPIO72, AF2, DRIVE_LOW)
+#define GPIO73_LCD_LDD_15 MFP_CFG_OUT(GPIO73, AF2, DRIVE_LOW)
+#define GPIO86_LCD_LDD_16 MFP_CFG_OUT(GPIO86, AF2, DRIVE_LOW)
+#define GPIO87_LCD_LDD_17 MFP_CFG_OUT(GPIO87, AF2, DRIVE_LOW)
+#define GPIO74_LCD_FCLK MFP_CFG_OUT(GPIO74, AF2, DRIVE_LOW)
+#define GPIO75_LCD_LCLK MFP_CFG_OUT(GPIO75, AF2, DRIVE_LOW)
+#define GPIO76_LCD_PCLK MFP_CFG_OUT(GPIO76, AF2, DRIVE_LOW)
+#define GPIO77_LCD_BIAS MFP_CFG_OUT(GPIO77, AF2, DRIVE_LOW)
+#define GPIO14_LCD_VSYNC MFP_CFG_IN(GPIO14, AF1)
+#define GPIO19_LCD_CS MFP_CFG_OUT(GPIO19, AF2, DRIVE_LOW)
+
+/* Keypad */
+#define GPIO93_KP_DKIN_0 MFP_CFG_IN(GPIO93, AF1)
+#define GPIO94_KP_DKIN_1 MFP_CFG_IN(GPIO94, AF1)
+#define GPIO95_KP_DKIN_2 MFP_CFG_IN(GPIO95, AF1)
+#define GPIO96_KP_DKIN_3 MFP_CFG_IN(GPIO96, AF1)
+#define GPIO97_KP_DKIN_4 MFP_CFG_IN(GPIO97, AF1)
+#define GPIO98_KP_DKIN_5 MFP_CFG_IN(GPIO98, AF1)
+#define GPIO99_KP_DKIN_6 MFP_CFG_IN(GPIO99, AF1)
+#define GPIO13_KP_KDIN_7 MFP_CFG_IN(GPIO13, AF2)
+#define GPIO100_KP_MKIN_0 MFP_CFG_IN(GPIO100, AF1)
+#define GPIO101_KP_MKIN_1 MFP_CFG_IN(GPIO101, AF1)
+#define GPIO102_KP_MKIN_2 MFP_CFG_IN(GPIO102, AF1)
+#define GPIO34_KP_MKIN_3 MFP_CFG_IN(GPIO34, AF2)
+#define GPIO37_KP_MKIN_3 MFP_CFG_IN(GPIO37, AF3)
+#define GPIO97_KP_MKIN_3 MFP_CFG_IN(GPIO97, AF3)
+#define GPIO98_KP_MKIN_4 MFP_CFG_IN(GPIO98, AF3)
+#define GPIO38_KP_MKIN_4 MFP_CFG_IN(GPIO38, AF2)
+#define GPIO39_KP_MKIN_4 MFP_CFG_IN(GPIO39, AF1)
+#define GPIO16_KP_MKIN_5 MFP_CFG_IN(GPIO16, AF1)
+#define GPIO90_KP_MKIN_5 MFP_CFG_IN(GPIO90, AF1)
+#define GPIO99_KP_MKIN_5 MFP_CFG_IN(GPIO99, AF3)
+#define GPIO17_KP_MKIN_6 MFP_CFG_IN(GPIO17, AF1)
+#define GPIO91_KP_MKIN_6 MFP_CFG_IN(GPIO91, AF1)
+#define GPIO95_KP_MKIN_6 MFP_CFG_IN(GPIO95, AF3)
+#define GPIO13_KP_MKIN_7 MFP_CFG_IN(GPIO13, AF3)
+#define GPIO36_KP_MKIN_7 MFP_CFG_IN(GPIO36, AF3)
+#define GPIO103_KP_MKOUT_0 MFP_CFG_OUT(GPIO103, AF2, DRIVE_HIGH)
+#define GPIO104_KP_MKOUT_1 MFP_CFG_OUT(GPIO104, AF2, DRIVE_HIGH)
+#define GPIO105_KP_MKOUT_2 MFP_CFG_OUT(GPIO105, AF2, DRIVE_HIGH)
+#define GPIO106_KP_MKOUT_3 MFP_CFG_OUT(GPIO106, AF2, DRIVE_HIGH)
+#define GPIO107_KP_MKOUT_4 MFP_CFG_OUT(GPIO107, AF2, DRIVE_HIGH)
+#define GPIO108_KP_MKOUT_5 MFP_CFG_OUT(GPIO108, AF2, DRIVE_HIGH)
+#define GPIO35_KP_MKOUT_6 MFP_CFG_OUT(GPIO35, AF2, DRIVE_HIGH)
+#define GPIO22_KP_MKOUT_7 MFP_CFG_OUT(GPIO22, AF1, DRIVE_HIGH)
+#define GPIO40_KP_MKOUT_6 MFP_CFG_OUT(GPIO40, AF1, DRIVE_HIGH)
+#define GPIO41_KP_MKOUT_7 MFP_CFG_OUT(GPIO41, AF1, DRIVE_HIGH)
+#define GPIO96_KP_MKOUT_6 MFP_CFG_OUT(GPIO96, AF3, DRIVE_HIGH)
+
+/* USB P3 */
+#define GPIO10_USB_P3_5 MFP_CFG_IN(GPIO10, AF3)
+#define GPIO11_USB_P3_1 MFP_CFG_IN(GPIO11, AF3)
+#define GPIO30_USB_P3_2 MFP_CFG_OUT(GPIO30, AF3, DRIVE_LOW)
+#define GPIO31_USB_P3_6 MFP_CFG_OUT(GPIO31, AF3, DRIVE_LOW)
+#define GPIO56_USB_P3_4 MFP_CFG_OUT(GPIO56, AF1, DRIVE_LOW)
+#define GPIO86_USB_P3_5 MFP_CFG_IN(GPIO86, AF3)
+#define GPIO87_USB_P3_1 MFP_CFG_IN(GPIO87, AF3)
+#define GPIO90_USB_P3_5 MFP_CFG_IN(GPIO90, AF2)
+#define GPIO91_USB_P3_1 MFP_CFG_IN(GPIO91, AF2)
+#define GPIO113_USB_P3_3 MFP_CFG_IN(GPIO113, AF3)
+
+/* USB P2 */
+#define GPIO34_USB_P2_2 MFP_CFG_OUT(GPIO34, AF1, DRIVE_LOW)
+#define GPIO35_USB_P2_1 MFP_CFG_IN(GPIO35, AF2)
+#define GPIO36_USB_P2_4 MFP_CFG_OUT(GPIO36, AF1, DRIVE_LOW)
+#define GPIO37_USB_P2_8 MFP_CFG_OUT(GPIO37, AF1, DRIVE_LOW)
+#define GPIO38_USB_P2_3 MFP_CFG_IN(GPIO38, AF3)
+#define GPIO39_USB_P2_6 MFP_CFG_OUT(GPIO39, AF1, DRIVE_LOW)
+#define GPIO40_USB_P2_5 MFP_CFG_IN(GPIO40, AF3)
+#define GPIO41_USB_P2_7 MFP_CFG_IN(GPIO41, AF2)
+#define GPIO53_USB_P2_3 MFP_CFG_IN(GPIO53, AF2)
+
+/* USB Host Port 1/2 */
+#define GPIO88_USBH1_PWR MFP_CFG_IN(GPIO88, AF1)
+#define GPIO89_USBH1_PEN MFP_CFG_OUT(GPIO89, AF2, DRIVE_LOW)
+#define GPIO119_USBH2_PWR MFP_CFG_IN(GPIO119, AF1)
+#define GPIO120_USBH2_PEN MFP_CFG_OUT(GPIO120, AF2, DRIVE_LOW)
+
+/* QCI - default to Master Mode: CIF_FV/CIF_LV Direction In */
+#define GPIO115_CIF_DD_3 MFP_CFG_IN(GPIO115, AF2)
+#define GPIO116_CIF_DD_2 MFP_CFG_IN(GPIO116, AF1)
+#define GPIO12_CIF_DD_7 MFP_CFG_IN(GPIO12, AF2)
+#define GPIO17_CIF_DD_6 MFP_CFG_IN(GPIO17, AF2)
+#define GPIO23_CIF_MCLK MFP_CFG_OUT(GPIO23, AF1, DRIVE_LOW)
+#define GPIO24_CIF_FV MFP_CFG_IN(GPIO24, AF1)
+#define GPIO25_CIF_LV MFP_CFG_IN(GPIO25, AF1)
+#define GPIO26_CIF_PCLK MFP_CFG_IN(GPIO26, AF2)
+#define GPIO27_CIF_DD_0 MFP_CFG_IN(GPIO27, AF3)
+#define GPIO42_CIF_MCLK MFP_CFG_OUT(GPIO42, AF3, DRIVE_LOW)
+#define GPIO43_CIF_FV MFP_CFG_IN(GPIO43, AF3)
+#define GPIO44_CIF_LV MFP_CFG_IN(GPIO44, AF3)
+#define GPIO45_CIF_PCLK MFP_CFG_IN(GPIO45, AF3)
+#define GPIO47_CIF_DD_0 MFP_CFG_IN(GPIO47, AF1)
+#define GPIO48_CIF_DD_5 MFP_CFG_IN(GPIO48, AF1)
+#define GPIO50_CIF_DD_3 MFP_CFG_IN(GPIO50, AF1)
+#define GPIO51_CIF_DD_2 MFP_CFG_IN(GPIO51, AF1)
+#define GPIO52_CIF_DD_4 MFP_CFG_IN(GPIO52, AF1)
+#define GPIO53_CIF_MCLK MFP_CFG_OUT(GPIO53, AF2, DRIVE_LOW)
+#define GPIO54_CIF_PCLK MFP_CFG_IN(GPIO54, AF3)
+#define GPIO55_CIF_DD_1 MFP_CFG_IN(GPIO55, AF1)
+#define GPIO81_CIF_DD_0 MFP_CFG_IN(GPIO81, AF2)
+#define GPIO82_CIF_DD_5 MFP_CFG_IN(GPIO82, AF3)
+#define GPIO83_CIF_DD_4 MFP_CFG_IN(GPIO83, AF3)
+#define GPIO84_CIF_FV MFP_CFG_IN(GPIO84, AF3)
+#define GPIO85_CIF_LV MFP_CFG_IN(GPIO85, AF3)
+#define GPIO90_CIF_DD_4 MFP_CFG_IN(GPIO90, AF3)
+#define GPIO91_CIF_DD_5 MFP_CFG_IN(GPIO91, AF3)
+#define GPIO93_CIF_DD_6 MFP_CFG_IN(GPIO93, AF2)
+#define GPIO94_CIF_DD_5 MFP_CFG_IN(GPIO94, AF2)
+#define GPIO95_CIF_DD_4 MFP_CFG_IN(GPIO95, AF2)
+#define GPIO98_CIF_DD_0 MFP_CFG_IN(GPIO98, AF2)
+#define GPIO103_CIF_DD_3 MFP_CFG_IN(GPIO103, AF1)
+#define GPIO104_CIF_DD_2 MFP_CFG_IN(GPIO104, AF1)
+#define GPIO105_CIF_DD_1 MFP_CFG_IN(GPIO105, AF1)
+#define GPIO106_CIF_DD_9 MFP_CFG_IN(GPIO106, AF1)
+#define GPIO107_CIF_DD_8 MFP_CFG_IN(GPIO107, AF1)
+#define GPIO108_CIF_DD_7 MFP_CFG_IN(GPIO108, AF1)
+#define GPIO114_CIF_DD_1 MFP_CFG_IN(GPIO114, AF1)
+
+/* Universal Subscriber ID Interface */
+#define GPIO114_UVS0 MFP_CFG_OUT(GPIO114, AF2, DRIVE_LOW)
+#define GPIO115_nUVS1 MFP_CFG_OUT(GPIO115, AF2, DRIVE_LOW)
+#define GPIO116_nUVS2 MFP_CFG_OUT(GPIO116, AF2, DRIVE_LOW)
+#define GPIO14_UCLK MFP_CFG_OUT(GPIO14, AF3, DRIVE_LOW)
+#define GPIO91_UCLK MFP_CFG_OUT(GPIO91, AF2, DRIVE_LOW)
+#define GPIO19_nURST MFP_CFG_OUT(GPIO19, AF3, DRIVE_LOW)
+#define GPIO90_nURST MFP_CFG_OUT(GPIO90, AF2, DRIVE_LOW)
+#define GPIO116_UDET MFP_CFG_IN(GPIO116, AF3)
+#define GPIO114_UEN MFP_CFG_OUT(GPIO114, AF1, DRIVE_LOW)
+#define GPIO115_UEN MFP_CFG_OUT(GPIO115, AF1, DRIVE_LOW)
+
+/* Mobile Scalable Link (MSL) Interface */
+#define GPIO81_BB_OB_DAT_0 MFP_CFG_OUT(GPIO81, AF2, DRIVE_LOW)
+#define GPIO48_BB_OB_DAT_1 MFP_CFG_OUT(GPIO48, AF1, DRIVE_LOW)
+#define GPIO50_BB_OB_DAT_2 MFP_CFG_OUT(GPIO50, AF1, DRIVE_LOW)
+#define GPIO51_BB_OB_DAT_3 MFP_CFG_OUT(GPIO51, AF1, DRIVE_LOW)
+#define GPIO52_BB_OB_CLK MFP_CFG_OUT(GPIO52, AF1, DRIVE_LOW)
+#define GPIO53_BB_OB_STB MFP_CFG_OUT(GPIO53, AF1, DRIVE_LOW)
+#define GPIO54_BB_OB_WAIT MFP_CFG_IN(GPIO54, AF2)
+#define GPIO82_BB_IB_DAT_0 MFP_CFG_IN(GPIO82, AF2)
+#define GPIO55_BB_IB_DAT_1 MFP_CFG_IN(GPIO55, AF2)
+#define GPIO56_BB_IB_DAT_2 MFP_CFG_IN(GPIO56, AF2)
+#define GPIO57_BB_IB_DAT_3 MFP_CFG_IN(GPIO57, AF2)
+#define GPIO83_BB_IB_CLK MFP_CFG_IN(GPIO83, AF2)
+#define GPIO84_BB_IB_STB MFP_CFG_IN(GPIO84, AF2)
+#define GPIO85_BB_IB_WAIT MFP_CFG_OUT(GPIO85, AF2, DRIVE_LOW)
+
+/* Memory Stick Host Controller */
+#define GPIO92_MSBS MFP_CFG_OUT(GPIO92, AF2, DRIVE_LOW)
+#define GPIO109_MSSDIO MFP_CFG_IN(GPIO109, AF2)
+#define GPIO112_nMSINS MFP_CFG_IN(GPIO112, AF2)
+#define GPIO32_MSSCLK MFP_CFG_OUT(GPIO32, AF1, DRIVE_LOW)
+
+extern int keypad_set_wake(unsigned int on);
+#endif /* __ASM_ARCH_MFP_PXA27X_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
new file mode 100644
index 0000000..658b28e
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mfp-pxa2xx.h
@@ -0,0 +1,133 @@
+#ifndef __ASM_ARCH_MFP_PXA2XX_H
+#define __ASM_ARCH_MFP_PXA2XX_H
+
+#include <plat/mfp.h>
+
+/*
+ * the following MFP_xxx bit definitions in mfp.h are re-used for pxa2xx:
+ *
+ * MFP_PIN(x)
+ * MFP_AFx
+ * MFP_LPM_DRIVE_{LOW, HIGH}
+ * MFP_LPM_EDGE_x
+ *
+ * other MFP_x bit definitions will be ignored
+ *
+ * and adds the below two bits specifically for pxa2xx:
+ *
+ * bit 23 - Input/Output (PXA2xx specific)
+ * bit 24 - Wakeup Enable(PXA2xx specific)
+ */
+
+#define MFP_DIR_IN (0x0 << 23)
+#define MFP_DIR_OUT (0x1 << 23)
+#define MFP_DIR_MASK (0x1 << 23)
+#define MFP_DIR(x) (((x) >> 23) & 0x1)
+
+#define MFP_LPM_CAN_WAKEUP (0x1 << 24)
+#define WAKEUP_ON_EDGE_RISE (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_RISE)
+#define WAKEUP_ON_EDGE_FALL (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_FALL)
+#define WAKEUP_ON_EDGE_BOTH (MFP_LPM_CAN_WAKEUP | MFP_LPM_EDGE_BOTH)
+
+/* specifically for enabling wakeup on keypad GPIOs */
+#define WAKEUP_ON_LEVEL_HIGH (MFP_LPM_CAN_WAKEUP)
+
+#define MFP_CFG_IN(pin, af) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DIR_IN))
+
+/* NOTE: pins configured as output _must_ provide a low power state,
+ * and this state should help to minimize the power dissipation.
+ */
+#define MFP_CFG_OUT(pin, af, state) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state))
+
+/* Common configurations for pxa25x and pxa27x
+ *
+ * Note: pins configured as GPIO are always initialized to input
+ * so not to cause any side effect
+ */
+#define GPIO0_GPIO MFP_CFG_IN(GPIO0, AF0)
+#define GPIO1_GPIO MFP_CFG_IN(GPIO1, AF0)
+#define GPIO9_GPIO MFP_CFG_IN(GPIO9, AF0)
+#define GPIO10_GPIO MFP_CFG_IN(GPIO10, AF0)
+#define GPIO11_GPIO MFP_CFG_IN(GPIO11, AF0)
+#define GPIO12_GPIO MFP_CFG_IN(GPIO12, AF0)
+#define GPIO13_GPIO MFP_CFG_IN(GPIO13, AF0)
+#define GPIO14_GPIO MFP_CFG_IN(GPIO14, AF0)
+#define GPIO15_GPIO MFP_CFG_IN(GPIO15, AF0)
+#define GPIO16_GPIO MFP_CFG_IN(GPIO16, AF0)
+#define GPIO17_GPIO MFP_CFG_IN(GPIO17, AF0)
+#define GPIO18_GPIO MFP_CFG_IN(GPIO18, AF0)
+#define GPIO19_GPIO MFP_CFG_IN(GPIO19, AF0)
+#define GPIO20_GPIO MFP_CFG_IN(GPIO20, AF0)
+#define GPIO21_GPIO MFP_CFG_IN(GPIO21, AF0)
+#define GPIO22_GPIO MFP_CFG_IN(GPIO22, AF0)
+#define GPIO23_GPIO MFP_CFG_IN(GPIO23, AF0)
+#define GPIO24_GPIO MFP_CFG_IN(GPIO24, AF0)
+#define GPIO25_GPIO MFP_CFG_IN(GPIO25, AF0)
+#define GPIO26_GPIO MFP_CFG_IN(GPIO26, AF0)
+#define GPIO27_GPIO MFP_CFG_IN(GPIO27, AF0)
+#define GPIO28_GPIO MFP_CFG_IN(GPIO28, AF0)
+#define GPIO29_GPIO MFP_CFG_IN(GPIO29, AF0)
+#define GPIO30_GPIO MFP_CFG_IN(GPIO30, AF0)
+#define GPIO31_GPIO MFP_CFG_IN(GPIO31, AF0)
+#define GPIO32_GPIO MFP_CFG_IN(GPIO32, AF0)
+#define GPIO33_GPIO MFP_CFG_IN(GPIO33, AF0)
+#define GPIO34_GPIO MFP_CFG_IN(GPIO34, AF0)
+#define GPIO35_GPIO MFP_CFG_IN(GPIO35, AF0)
+#define GPIO36_GPIO MFP_CFG_IN(GPIO36, AF0)
+#define GPIO37_GPIO MFP_CFG_IN(GPIO37, AF0)
+#define GPIO38_GPIO MFP_CFG_IN(GPIO38, AF0)
+#define GPIO39_GPIO MFP_CFG_IN(GPIO39, AF0)
+#define GPIO40_GPIO MFP_CFG_IN(GPIO40, AF0)
+#define GPIO41_GPIO MFP_CFG_IN(GPIO41, AF0)
+#define GPIO42_GPIO MFP_CFG_IN(GPIO42, AF0)
+#define GPIO43_GPIO MFP_CFG_IN(GPIO43, AF0)
+#define GPIO44_GPIO MFP_CFG_IN(GPIO44, AF0)
+#define GPIO45_GPIO MFP_CFG_IN(GPIO45, AF0)
+#define GPIO46_GPIO MFP_CFG_IN(GPIO46, AF0)
+#define GPIO47_GPIO MFP_CFG_IN(GPIO47, AF0)
+#define GPIO48_GPIO MFP_CFG_IN(GPIO48, AF0)
+#define GPIO49_GPIO MFP_CFG_IN(GPIO49, AF0)
+#define GPIO50_GPIO MFP_CFG_IN(GPIO50, AF0)
+#define GPIO51_GPIO MFP_CFG_IN(GPIO51, AF0)
+#define GPIO52_GPIO MFP_CFG_IN(GPIO52, AF0)
+#define GPIO53_GPIO MFP_CFG_IN(GPIO53, AF0)
+#define GPIO54_GPIO MFP_CFG_IN(GPIO54, AF0)
+#define GPIO55_GPIO MFP_CFG_IN(GPIO55, AF0)
+#define GPIO56_GPIO MFP_CFG_IN(GPIO56, AF0)
+#define GPIO57_GPIO MFP_CFG_IN(GPIO57, AF0)
+#define GPIO58_GPIO MFP_CFG_IN(GPIO58, AF0)
+#define GPIO59_GPIO MFP_CFG_IN(GPIO59, AF0)
+#define GPIO60_GPIO MFP_CFG_IN(GPIO60, AF0)
+#define GPIO61_GPIO MFP_CFG_IN(GPIO61, AF0)
+#define GPIO62_GPIO MFP_CFG_IN(GPIO62, AF0)
+#define GPIO63_GPIO MFP_CFG_IN(GPIO63, AF0)
+#define GPIO64_GPIO MFP_CFG_IN(GPIO64, AF0)
+#define GPIO65_GPIO MFP_CFG_IN(GPIO65, AF0)
+#define GPIO66_GPIO MFP_CFG_IN(GPIO66, AF0)
+#define GPIO67_GPIO MFP_CFG_IN(GPIO67, AF0)
+#define GPIO68_GPIO MFP_CFG_IN(GPIO68, AF0)
+#define GPIO69_GPIO MFP_CFG_IN(GPIO69, AF0)
+#define GPIO70_GPIO MFP_CFG_IN(GPIO70, AF0)
+#define GPIO71_GPIO MFP_CFG_IN(GPIO71, AF0)
+#define GPIO72_GPIO MFP_CFG_IN(GPIO72, AF0)
+#define GPIO73_GPIO MFP_CFG_IN(GPIO73, AF0)
+#define GPIO74_GPIO MFP_CFG_IN(GPIO74, AF0)
+#define GPIO75_GPIO MFP_CFG_IN(GPIO75, AF0)
+#define GPIO76_GPIO MFP_CFG_IN(GPIO76, AF0)
+#define GPIO77_GPIO MFP_CFG_IN(GPIO77, AF0)
+#define GPIO78_GPIO MFP_CFG_IN(GPIO78, AF0)
+#define GPIO79_GPIO MFP_CFG_IN(GPIO79, AF0)
+#define GPIO80_GPIO MFP_CFG_IN(GPIO80, AF0)
+#define GPIO81_GPIO MFP_CFG_IN(GPIO81, AF0)
+#define GPIO82_GPIO MFP_CFG_IN(GPIO82, AF0)
+#define GPIO83_GPIO MFP_CFG_IN(GPIO83, AF0)
+#define GPIO84_GPIO MFP_CFG_IN(GPIO84, AF0)
+
+extern void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num);
+extern void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm);
+extern int gpio_set_wake(unsigned int gpio, unsigned int on);
+#endif /* __ASM_ARCH_MFP_PXA2XX_H */
diff --git a/arch/arm/mach-pxa/include/mach/mfp.h b/arch/arm/mach-pxa/include/mach/mfp.h
new file mode 100644
index 0000000..271e249
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/mfp.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-pxa/include/mach/mfp.h
+ *
+ * Multi-Function Pin Definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ *
+ * 2007-8-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_ARCH_MFP_H
+#define __ASM_ARCH_MFP_H
+
+#include <plat/mfp.h>
+
+#endif /* __ASM_ARCH_MFP_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa-regs.h b/arch/arm/mach-pxa/include/mach/pxa-regs.h
new file mode 100644
index 0000000..c32d2ae
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa-regs.h
@@ -0,0 +1,33 @@
+/*
+ * (c) 2010 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * Copyright (C) 2010 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef __MACH_PXA_REGS_H
+#define __MACH_PXA_REGS_H
+
+#ifndef __ASSEMBLY__
+# define __REG(x) (*((volatile u32 *)(x)))
+# define __REG16(x) (*(volatile u16 *)(x))
+# define __REG2(x, y) (*(volatile u32 *)((u32)&__REG(x) + (y)))
+#else
+# define __REG(x) (x)
+# define __REG16(x) (x)
+# define __REG2(x, y) ((x) + (y))
+#endif
+
+#ifdef CONFIG_ARCH_PXA2XX
+# include <mach/pxa2xx-regs.h>
+#endif
+
+#ifdef CONFIG_ARCH_PXA27X
+# include <mach/pxa27x-regs.h>
+#else
+# error "unknown PXA soc type"
+#endif
+
+#endif /* !__MACH_PXA_REGS_H */
diff --git a/arch/arm/mach-pxa/include/mach/pxa27x-regs.h b/arch/arm/mach-pxa/include/mach/pxa27x-regs.h
new file mode 100644
index 0000000..f4d88d4
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa27x-regs.h
@@ -0,0 +1,6 @@
+#ifndef __MACH_PXA27X_REGS
+#define __MACH_PXA27X_REGS
+
+/* this file intentionally left blank */
+
+#endif /* !__MACH_PXA27X_REGS */
diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
new file mode 100644
index 0000000..4762d8a
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
@@ -0,0 +1,267 @@
+/*
+ * arch/arm/mach-pxa/include/mach/pxa2xx-regs.h
+ *
+ * Taken from pxa-regs.h by Russell King
+ *
+ * Author: Nicolas Pitre
+ * Copyright: MontaVista Software Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __PXA2XX_REGS_H
+#define __PXA2XX_REGS_H
+
+#include <mach/hardware.h>
+
+/*
+ * PXA Chip selects
+ */
+#define PXA_CS0_PHYS 0x00000000
+#define PXA_CS1_PHYS 0x04000000
+#define PXA_CS2_PHYS 0x08000000
+#define PXA_CS3_PHYS 0x0C000000
+#define PXA_CS4_PHYS 0x10000000
+#define PXA_CS5_PHYS 0x14000000
+
+/*
+ * Memory controller
+ */
+#define MDCNFG_OFFSET 0x00000000
+#define MDREFR_OFFSET 0x00000004
+#define MSC0_OFFSET 0x00000008
+#define MSC1_OFFSET 0x0000000C
+#define MSC2_OFFSET 0x00000010
+#define MECR_OFFSET 0x00000014
+#define SXCNFG_OFFSET 0x0000001C
+#define FLYCNFG_OFFSET 0x00000020
+#define MCMEM0_OFFSET 0x00000028
+#define MCMEM1_OFFSET 0x0000002C
+#define MCATT0_OFFSET 0x00000030
+#define MCATT1_OFFSET 0x00000034
+#define MCIO0_OFFSET 0x00000038
+#define MCIO1_OFFSET 0x0000003C
+#define MDMRS_OFFSET 0x00000040
+
+#define MDCNFG __REG(0x48000000) /* SDRAM Configuration Register 0 */
+#define MDREFR __REG(0x48000004) /* SDRAM Refresh Control Register */
+#define MSC0 __REG(0x48000008) /* Static Memory Control Register 0 */
+#define MSC1 __REG(0x4800000C) /* Static Memory Control Register 1 */
+#define MSC2 __REG(0x48000010) /* Static Memory Control Register 2 */
+#define MECR __REG(0x48000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */
+#define SXLCR __REG(0x48000018) /* LCR value to be written to SDRAM-Timing Synchronous Flash */
+#define SXCNFG __REG(0x4800001C) /* Synchronous Static Memory Control Register */
+#define SXMRS __REG(0x48000024) /* MRS value to be written to Synchronous Flash or SMROM */
+#define MCMEM0 __REG(0x48000028) /* Card interface Common Memory Space Socket 0 Timing */
+#define MCMEM1 __REG(0x4800002C) /* Card interface Common Memory Space Socket 1 Timing */
+#define MCATT0 __REG(0x48000030) /* Card interface Attribute Space Socket 0 Timing Configuration */
+#define MCATT1 __REG(0x48000034) /* Card interface Attribute Space Socket 1 Timing Configuration */
+#define MCIO0 __REG(0x48000038) /* Card interface I/O Space Socket 0 Timing Configuration */
+#define MCIO1 __REG(0x4800003C) /* Card interface I/O Space Socket 1 Timing Configuration */
+#define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */
+#define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */
+
+/*
+ * More handy macros for PCMCIA
+ *
+ * Arg is socket number
+ */
+#define MCMEM(s) __REG2(0x48000028, (s)<<2 ) /* Card interface Common Memory Space Socket s Timing */
+#define MCATT(s) __REG2(0x48000030, (s)<<2 ) /* Card interface Attribute Space Socket s Timing Configuration */
+#define MCIO(s) __REG2(0x48000038, (s)<<2 ) /* Card interface I/O Space Socket s Timing Configuration */
+
+/* MECR register defines */
+#define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */
+#define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */
+
+#define MDCNFG_DE0 (1 << 0) /* SDRAM Bank 0 Enable */
+#define MDCNFG_DE1 (1 << 1) /* SDRAM Bank 1 Enable */
+#define MDCNFG_DE2 (1 << 16) /* SDRAM Bank 2 Enable */
+#define MDCNFG_DE3 (1 << 17) /* SDRAM Bank 3 Enable */
+
+#define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */
+#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */
+#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */
+#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */
+#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */
+#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */
+#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */
+#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */
+#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */
+#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */
+#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */
+#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */
+#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */
+#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */
+
+/*
+ * Power Manager
+ */
+
+#define PMCR __REG(0x40F00000) /* Power Manager Control Register */
+#define PSSR __REG(0x40F00004) /* Power Manager Sleep Status Register */
+#define PSPR __REG(0x40F00008) /* Power Manager Scratch Pad Register */
+#define PWER __REG(0x40F0000C) /* Power Manager Wake-up Enable Register */
+#define PRER __REG(0x40F00010) /* Power Manager GPIO Rising-Edge Detect Enable Register */
+#define PFER __REG(0x40F00014) /* Power Manager GPIO Falling-Edge Detect Enable Register */
+#define PEDR __REG(0x40F00018) /* Power Manager GPIO Edge Detect Status Register */
+#define PCFR __REG(0x40F0001C) /* Power Manager General Configuration Register */
+#define PGSR0 __REG(0x40F00020) /* Power Manager GPIO Sleep State Register for GP[31-0] */
+#define PGSR1 __REG(0x40F00024) /* Power Manager GPIO Sleep State Register for GP[63-32] */
+#define PGSR2 __REG(0x40F00028) /* Power Manager GPIO Sleep State Register for GP[84-64] */
+#define PGSR3 __REG(0x40F0002C) /* Power Manager GPIO Sleep State Register for GP[118-96] */
+#define RCSR __REG(0x40F00030) /* Reset Controller Status Register */
+
+#define PSLR __REG(0x40F00034) /* Power Manager Sleep Config Register */
+#define PSTR __REG(0x40F00038) /* Power Manager Standby Config Register */
+#define PSNR __REG(0x40F0003C) /* Power Manager Sense Config Register */
+#define PVCR __REG(0x40F00040) /* Power Manager VoltageControl Register */
+#define PKWR __REG(0x40F00050) /* Power Manager KB Wake-up Enable Reg */
+#define PKSR __REG(0x40F00054) /* Power Manager KB Level-Detect Register */
+#define PCMD(x) __REG2(0x40F00080, (x)<<2)
+#define PCMD0 __REG(0x40F00080 + 0 * 4)
+#define PCMD1 __REG(0x40F00080 + 1 * 4)
+#define PCMD2 __REG(0x40F00080 + 2 * 4)
+#define PCMD3 __REG(0x40F00080 + 3 * 4)
+#define PCMD4 __REG(0x40F00080 + 4 * 4)
+#define PCMD5 __REG(0x40F00080 + 5 * 4)
+#define PCMD6 __REG(0x40F00080 + 6 * 4)
+#define PCMD7 __REG(0x40F00080 + 7 * 4)
+#define PCMD8 __REG(0x40F00080 + 8 * 4)
+#define PCMD9 __REG(0x40F00080 + 9 * 4)
+#define PCMD10 __REG(0x40F00080 + 10 * 4)
+#define PCMD11 __REG(0x40F00080 + 11 * 4)
+#define PCMD12 __REG(0x40F00080 + 12 * 4)
+#define PCMD13 __REG(0x40F00080 + 13 * 4)
+#define PCMD14 __REG(0x40F00080 + 14 * 4)
+#define PCMD15 __REG(0x40F00080 + 15 * 4)
+#define PCMD16 __REG(0x40F00080 + 16 * 4)
+#define PCMD17 __REG(0x40F00080 + 17 * 4)
+#define PCMD18 __REG(0x40F00080 + 18 * 4)
+#define PCMD19 __REG(0x40F00080 + 19 * 4)
+#define PCMD20 __REG(0x40F00080 + 20 * 4)
+#define PCMD21 __REG(0x40F00080 + 21 * 4)
+#define PCMD22 __REG(0x40F00080 + 22 * 4)
+#define PCMD23 __REG(0x40F00080 + 23 * 4)
+#define PCMD24 __REG(0x40F00080 + 24 * 4)
+#define PCMD25 __REG(0x40F00080 + 25 * 4)
+#define PCMD26 __REG(0x40F00080 + 26 * 4)
+#define PCMD27 __REG(0x40F00080 + 27 * 4)
+#define PCMD28 __REG(0x40F00080 + 28 * 4)
+#define PCMD29 __REG(0x40F00080 + 29 * 4)
+#define PCMD30 __REG(0x40F00080 + 30 * 4)
+#define PCMD31 __REG(0x40F00080 + 31 * 4)
+
+#define PCMD_MBC (1<<12)
+#define PCMD_DCE (1<<11)
+#define PCMD_LC (1<<10)
+/* FIXME: PCMD_SQC need be checked. */
+#define PCMD_SQC (3<<8) /* currently only bit 8 is changeable,
+ bit 9 should be 0 all day. */
+#define PVCR_VCSA (0x1<<14)
+#define PVCR_CommandDelay (0xf80)
+#define PCFR_PI2C_EN (0x1 << 6)
+
+#define PSSR_OTGPH (1 << 6) /* OTG Peripheral control Hold */
+#define PSSR_RDH (1 << 5) /* Read Disable Hold */
+#define PSSR_PH (1 << 4) /* Peripheral Control Hold */
+#define PSSR_STS (1 << 3) /* Standby Mode Status */
+#define PSSR_VFS (1 << 2) /* VDD Fault Status */
+#define PSSR_BFS (1 << 1) /* Battery Fault Status */
+#define PSSR_SSS (1 << 0) /* Software Sleep Status */
+
+#define PSLR_SL_ROD (1 << 20) /* Sleep-Mode/Depp-Sleep Mode nRESET_OUT Disable */
+
+#define PCFR_RO (1 << 15) /* RDH Override */
+#define PCFR_PO (1 << 14) /* PH Override */
+#define PCFR_GPROD (1 << 12) /* GPIO nRESET_OUT Disable */
+#define PCFR_L1_EN (1 << 11) /* Sleep Mode L1 converter Enable */
+#define PCFR_FVC (1 << 10) /* Frequency/Voltage Change */
+#define PCFR_DC_EN (1 << 7) /* Sleep/deep-sleep DC-DC Converter Enable */
+#define PCFR_PI2CEN (1 << 6) /* Enable PI2C controller */
+#define PCFR_GPR_EN (1 << 4) /* nRESET_GPIO Pin Enable */
+#define PCFR_DS (1 << 3) /* Deep Sleep Mode */
+#define PCFR_FS (1 << 2) /* Float Static Chip Selects */
+#define PCFR_FP (1 << 1) /* Float PCMCIA controls */
+#define PCFR_OPDE (1 << 0) /* 3.6864 MHz oscillator power-down enable */
+
+#define RCSR_GPR (1 << 3) /* GPIO Reset */
+#define RCSR_SMR (1 << 2) /* Sleep Mode */
+#define RCSR_WDR (1 << 1) /* Watchdog Reset */
+#define RCSR_HWR (1 << 0) /* Hardware Reset */
+
+#define PWER_GPIO(Nb) (1 << Nb) /* GPIO [0..15] wake-up enable */
+#define PWER_GPIO0 PWER_GPIO(0) /* GPIO [0] wake-up enable */
+#define PWER_GPIO1 PWER_GPIO(1) /* GPIO [1] wake-up enable */
+#define PWER_GPIO2 PWER_GPIO(2) /* GPIO [2] wake-up enable */
+#define PWER_GPIO3 PWER_GPIO(3) /* GPIO [3] wake-up enable */
+#define PWER_GPIO4 PWER_GPIO(4) /* GPIO [4] wake-up enable */
+#define PWER_GPIO5 PWER_GPIO(5) /* GPIO [5] wake-up enable */
+#define PWER_GPIO6 PWER_GPIO(6) /* GPIO [6] wake-up enable */
+#define PWER_GPIO7 PWER_GPIO(7) /* GPIO [7] wake-up enable */
+#define PWER_GPIO8 PWER_GPIO(8) /* GPIO [8] wake-up enable */
+#define PWER_GPIO9 PWER_GPIO(9) /* GPIO [9] wake-up enable */
+#define PWER_GPIO10 PWER_GPIO(10) /* GPIO [10] wake-up enable */
+#define PWER_GPIO11 PWER_GPIO(11) /* GPIO [11] wake-up enable */
+#define PWER_GPIO12 PWER_GPIO(12) /* GPIO [12] wake-up enable */
+#define PWER_GPIO13 PWER_GPIO(13) /* GPIO [13] wake-up enable */
+#define PWER_GPIO14 PWER_GPIO(14) /* GPIO [14] wake-up enable */
+#define PWER_GPIO15 PWER_GPIO(15) /* GPIO [15] wake-up enable */
+#define PWER_RTC 0x80000000 /* RTC alarm wake-up enable */
+
+/*
+ * PXA2xx specific Core clock definitions
+ */
+#define CCCR __REG(0x41300000) /* Core Clock Configuration Register */
+#define CCSR __REG(0x4130000C) /* Core Clock Status Register */
+#define CKEN __REG(0x41300004) /* Clock Enable Register */
+#define OSCC __REG(0x41300008) /* Oscillator Configuration Register */
+
+#define CCCR_N_MASK 0x0380 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */
+#define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */
+#define CCCR_L_MASK 0x001f /* Crystal Frequency to Memory Frequency Multiplier */
+
+#define CKEN_AC97CONF (1 << 31) /* AC97 Controller Configuration */
+#define CKEN_CAMERA (1 << 24) /* Camera Interface Clock Enable */
+#define CKEN_SSP1 (1 << 23) /* SSP1 Unit Clock Enable */
+#define CKEN_MEMC (1 << 22) /* Memory Controller Clock Enable */
+#define CKEN_MEMSTK (1 << 21) /* Memory Stick Host Controller */
+#define CKEN_IM (1 << 20) /* Internal Memory Clock Enable */
+#define CKEN_KEYPAD (1 << 19) /* Keypad Interface Clock Enable */
+#define CKEN_USIM (1 << 18) /* USIM Unit Clock Enable */
+#define CKEN_MSL (1 << 17) /* MSL Unit Clock Enable */
+#define CKEN_LCD (1 << 16) /* LCD Unit Clock Enable */
+#define CKEN_PWRI2C (1 << 15) /* PWR I2C Unit Clock Enable */
+#define CKEN_I2C (1 << 14) /* I2C Unit Clock Enable */
+#define CKEN_FICP (1 << 13) /* FICP Unit Clock Enable */
+#define CKEN_MMC (1 << 12) /* MMC Unit Clock Enable */
+#define CKEN_USB (1 << 11) /* USB Unit Clock Enable */
+#define CKEN_ASSP (1 << 10) /* ASSP (1 << SSP3) Clock Enable */
+#define CKEN_USBHOST (1 << 10) /* USB Host Unit Clock Enable */
+#define CKEN_OSTIMER (1 << 9) /* OS Timer Unit Clock Enable */
+#define CKEN_NSSP (1 << 9) /* NSSP (1 << SSP2) Clock Enable */
+#define CKEN_I2S (1 << 8) /* I2S Unit Clock Enable */
+#define CKEN_BTUART (1 << 7) /* BTUART Unit Clock Enable */
+#define CKEN_FFUART (1 << 6) /* FFUART Unit Clock Enable */
+#define CKEN_STUART (1 << 5) /* STUART Unit Clock Enable */
+#define CKEN_HWUART (1 << 4) /* HWUART Unit Clock Enable */
+#define CKEN_SSP3 (1 << 4) /* SSP3 Unit Clock Enable */
+#define CKEN_SSP (1 << 3) /* SSP Unit Clock Enable */
+#define CKEN_SSP2 (1 << 3) /* SSP2 Unit Clock Enable */
+#define CKEN_AC97 (1 << 2) /* AC97 Unit Clock Enable */
+#define CKEN_PWM1 (1 << 1) /* PWM1 Clock Enable */
+#define CKEN_PWM0 (1 << 0) /* PWM0 Clock Enable */
+
+#define OSCC_OON (1 << 1) /* 32.768kHz OON (write-once only bit) */
+#define OSCC_OOK (1 << 0) /* 32.768kHz OOK (read-only bit) */
+
+/* PWRMODE register M field values */
+
+#define PWRMODE_IDLE 0x1
+#define PWRMODE_STANDBY 0x2
+#define PWRMODE_SLEEP 0x3
+#define PWRMODE_DEEPSLEEP 0x7
+
+#endif
diff --git a/arch/arm/mach-pxa/include/mach/regs-intc.h b/arch/arm/mach-pxa/include/mach/regs-intc.h
new file mode 100644
index 0000000..68464ce
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/regs-intc.h
@@ -0,0 +1,34 @@
+#ifndef __ASM_MACH_REGS_INTC_H
+#define __ASM_MACH_REGS_INTC_H
+
+#include <mach/hardware.h>
+
+/*
+ * Interrupt Controller
+ */
+
+#define ICIP __REG(0x40D00000) /* Interrupt Controller IRQ Pending Register */
+#define ICMR __REG(0x40D00004) /* Interrupt Controller Mask Register */
+#define ICLR __REG(0x40D00008) /* Interrupt Controller Level Register */
+#define ICFP __REG(0x40D0000C) /* Interrupt Controller FIQ Pending Register */
+#define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */
+#define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */
+#define ICHP __REG(0x40D00018) /* Interrupt Controller Highest Priority Register */
+
+#define ICIP2 __REG(0x40D0009C) /* Interrupt Controller IRQ Pending Register 2 */
+#define ICMR2 __REG(0x40D000A0) /* Interrupt Controller Mask Register 2 */
+#define ICLR2 __REG(0x40D000A4) /* Interrupt Controller Level Register 2 */
+#define ICFP2 __REG(0x40D000A8) /* Interrupt Controller FIQ Pending Register 2 */
+#define ICPR2 __REG(0x40D000AC) /* Interrupt Controller Pending Register 2 */
+
+#define ICIP3 __REG(0x40D00130) /* Interrupt Controller IRQ Pending Register 3 */
+#define ICMR3 __REG(0x40D00134) /* Interrupt Controller Mask Register 3 */
+#define ICLR3 __REG(0x40D00138) /* Interrupt Controller Level Register 3 */
+#define ICFP3 __REG(0x40D0013C) /* Interrupt Controller FIQ Pending Register 3 */
+#define ICPR3 __REG(0x40D00140) /* Interrupt Controller Pending Register 3 */
+
+#define IPR(x) __REG(0x40D0001C + (x < 32 ? (x << 2) \
+ : (x < 64 ? (0x94 + ((x - 32) << 2)) \
+ : (0x128 + ((x - 64) << 2)))))
+
+#endif /* __ASM_MACH_REGS_INTC_H */
diff --git a/arch/arm/mach-pxa/include/mach/regs-ost.h b/arch/arm/mach-pxa/include/mach/regs-ost.h
new file mode 100644
index 0000000..a3e5f86
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/regs-ost.h
@@ -0,0 +1,34 @@
+#ifndef __ASM_MACH_REGS_OST_H
+#define __ASM_MACH_REGS_OST_H
+
+#include <mach/hardware.h>
+
+/*
+ * OS Timer & Match Registers
+ */
+
+#define OSMR0 __REG(0x40A00000) /* */
+#define OSMR1 __REG(0x40A00004) /* */
+#define OSMR2 __REG(0x40A00008) /* */
+#define OSMR3 __REG(0x40A0000C) /* */
+#define OSMR4 __REG(0x40A00080) /* */
+#define OSCR __REG(0x40A00010) /* OS Timer Counter Register */
+#define OSCR4 __REG(0x40A00040) /* OS Timer Counter Register */
+#define OMCR4 __REG(0x40A000C0) /* */
+#define OSSR __REG(0x40A00014) /* OS Timer Status Register */
+#define OWER __REG(0x40A00018) /* OS Timer Watchdog Enable Register */
+#define OIER __REG(0x40A0001C) /* OS Timer Interrupt Enable Register */
+
+#define OSSR_M3 (1 << 3) /* Match status channel 3 */
+#define OSSR_M2 (1 << 2) /* Match status channel 2 */
+#define OSSR_M1 (1 << 1) /* Match status channel 1 */
+#define OSSR_M0 (1 << 0) /* Match status channel 0 */
+
+#define OWER_WME (1 << 0) /* Watchdog Match Enable */
+
+#define OIER_E3 (1 << 3) /* Interrupt enable channel 3 */
+#define OIER_E2 (1 << 2) /* Interrupt enable channel 2 */
+#define OIER_E1 (1 << 1) /* Interrupt enable channel 1 */
+#define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */
+
+#endif /* __ASM_MACH_REGS_OST_H */
diff --git a/arch/arm/mach-pxa/include/mach/udc_pxa2xx.h b/arch/arm/mach-pxa/include/mach/udc_pxa2xx.h
new file mode 100644
index 0000000..dcdd36a
--- /dev/null
+++ b/arch/arm/mach-pxa/include/mach/udc_pxa2xx.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-pxa/include/mach/udc_pxa2xx.h
+ *
+ * This supports machine-specific differences in how the PXA2xx
+ * USB Device Controller (UDC) is wired.
+ *
+ * It is set in linux/arch/arm/mach-pxa/<machine>.c or in
+ * linux/arch/mach-ixp4xx/<machine>.c and used in
+ * the probe routine of linux/drivers/usb/gadget/pxa2xx_udc.c
+ */
+
+struct pxa2xx_udc_mach_info {
+ int (*udc_is_connected)(void); /* do we see host? */
+ void (*udc_command)(int cmd);
+#define PXA2XX_UDC_CMD_CONNECT 0 /* let host see us */
+#define PXA2XX_UDC_CMD_DISCONNECT 1 /* so host won't see us */
+
+ /* Boards following the design guidelines in the developer's manual,
+ * with on-chip GPIOs not Lubbock's weird hardware, can have a sane
+ * VBUS IRQ and omit the methods above. Store the GPIO number
+ * here. Note that sometimes the signals go through inverters...
+ */
+ bool gpio_pullup_inverted;
+ int gpio_pullup; /* high == pullup activated */
+};
+
diff --git a/arch/arm/mach-pxa/include/plat/gpio.h b/arch/arm/mach-pxa/include/plat/gpio.h
new file mode 100644
index 0000000..4c7b526
--- /dev/null
+++ b/arch/arm/mach-pxa/include/plat/gpio.h
@@ -0,0 +1,74 @@
+#ifndef __PLAT_GPIO_H
+#define __PLAT_GPIO_H
+
+#include <mach/gpio.h>
+
+/*
+ * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with
+ * one set of registers. The register offsets are organized below:
+ *
+ * GPLR GPDR GPSR GPCR GRER GFER GEDR
+ * BANK 0 - 0x0000 0x000C 0x0018 0x0024 0x0030 0x003C 0x0048
+ * BANK 1 - 0x0004 0x0010 0x001C 0x0028 0x0034 0x0040 0x004C
+ * BANK 2 - 0x0008 0x0014 0x0020 0x002C 0x0038 0x0044 0x0050
+ *
+ * BANK 3 - 0x0100 0x010C 0x0118 0x0124 0x0130 0x013C 0x0148
+ * BANK 4 - 0x0104 0x0110 0x011C 0x0128 0x0134 0x0140 0x014C
+ * BANK 5 - 0x0108 0x0114 0x0120 0x012C 0x0138 0x0144 0x0150
+ *
+ * NOTE:
+ * BANK 3 is only available on PXA27x and later processors.
+ * BANK 4 and 5 are only available on PXA935
+ */
+
+#define GPIO_BANK(n) (GPIO_REGS_VIRT + BANK_OFF(n))
+
+#define GPLR_OFFSET 0x00
+#define GPDR_OFFSET 0x0C
+#define GPSR_OFFSET 0x18
+#define GPCR_OFFSET 0x24
+#define GRER_OFFSET 0x30
+#define GFER_OFFSET 0x3C
+#define GEDR_OFFSET 0x48
+
+static inline int gpio_get_value(unsigned gpio)
+{
+ return GPLR(gpio) & GPIO_bit(gpio);
+}
+
+static inline void gpio_set_value(unsigned gpio, int value)
+{
+ if (value)
+ GPSR(gpio) = GPIO_bit(gpio);
+ else
+ GPCR(gpio) = GPIO_bit(gpio);
+}
+
+static inline int gpio_direction_input(unsigned gpio)
+{
+ if (__gpio_is_inverted(gpio))
+ GPDR(gpio) |= GPIO_bit(gpio);
+ else
+ GPDR(gpio) &= ~GPIO_bit(gpio);
+ return 0;
+}
+
+static inline int gpio_direction_output(unsigned gpio, int value)
+{
+ gpio_set_value(gpio, value);
+ if (__gpio_is_inverted(gpio))
+ GPDR(gpio) &= ~GPIO_bit(gpio);
+ else
+ GPDR(gpio) |= GPIO_bit(gpio);
+ return 0;
+}
+
+/* NOTE: some PXAs have fewer on-chip GPIOs (like PXA255, with 85).
+ * Those cases currently cause holes in the GPIO number space, the
+ * actual number of the last GPIO is recorded by 'pxa_last_gpio'.
+ */
+extern int pxa_last_gpio;
+
+extern int pxa_init_gpio(int start, int end);
+
+#endif /* __PLAT_GPIO_H */
diff --git a/arch/arm/mach-pxa/include/plat/mfp.h b/arch/arm/mach-pxa/include/plat/mfp.h
new file mode 100644
index 0000000..755b020
--- /dev/null
+++ b/arch/arm/mach-pxa/include/plat/mfp.h
@@ -0,0 +1,468 @@
+/*
+ * arch/arm/plat-pxa/include/plat/mfp.h
+ *
+ * Common Multi-Function Pin Definitions
+ *
+ * Copyright (C) 2007 Marvell International Ltd.
+ *
+ * 2007-8-21: eric miao <eric.miao@marvell.com>
+ * initial version
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __ASM_PLAT_MFP_H
+#define __ASM_PLAT_MFP_H
+
+#define mfp_to_gpio(m) ((m) % 256)
+
+/* list of all the configurable MFP pins */
+enum {
+ MFP_PIN_INVALID = -1,
+
+ MFP_PIN_GPIO0 = 0,
+ MFP_PIN_GPIO1,
+ MFP_PIN_GPIO2,
+ MFP_PIN_GPIO3,
+ MFP_PIN_GPIO4,
+ MFP_PIN_GPIO5,
+ MFP_PIN_GPIO6,
+ MFP_PIN_GPIO7,
+ MFP_PIN_GPIO8,
+ MFP_PIN_GPIO9,
+ MFP_PIN_GPIO10,
+ MFP_PIN_GPIO11,
+ MFP_PIN_GPIO12,
+ MFP_PIN_GPIO13,
+ MFP_PIN_GPIO14,
+ MFP_PIN_GPIO15,
+ MFP_PIN_GPIO16,
+ MFP_PIN_GPIO17,
+ MFP_PIN_GPIO18,
+ MFP_PIN_GPIO19,
+ MFP_PIN_GPIO20,
+ MFP_PIN_GPIO21,
+ MFP_PIN_GPIO22,
+ MFP_PIN_GPIO23,
+ MFP_PIN_GPIO24,
+ MFP_PIN_GPIO25,
+ MFP_PIN_GPIO26,
+ MFP_PIN_GPIO27,
+ MFP_PIN_GPIO28,
+ MFP_PIN_GPIO29,
+ MFP_PIN_GPIO30,
+ MFP_PIN_GPIO31,
+ MFP_PIN_GPIO32,
+ MFP_PIN_GPIO33,
+ MFP_PIN_GPIO34,
+ MFP_PIN_GPIO35,
+ MFP_PIN_GPIO36,
+ MFP_PIN_GPIO37,
+ MFP_PIN_GPIO38,
+ MFP_PIN_GPIO39,
+ MFP_PIN_GPIO40,
+ MFP_PIN_GPIO41,
+ MFP_PIN_GPIO42,
+ MFP_PIN_GPIO43,
+ MFP_PIN_GPIO44,
+ MFP_PIN_GPIO45,
+ MFP_PIN_GPIO46,
+ MFP_PIN_GPIO47,
+ MFP_PIN_GPIO48,
+ MFP_PIN_GPIO49,
+ MFP_PIN_GPIO50,
+ MFP_PIN_GPIO51,
+ MFP_PIN_GPIO52,
+ MFP_PIN_GPIO53,
+ MFP_PIN_GPIO54,
+ MFP_PIN_GPIO55,
+ MFP_PIN_GPIO56,
+ MFP_PIN_GPIO57,
+ MFP_PIN_GPIO58,
+ MFP_PIN_GPIO59,
+ MFP_PIN_GPIO60,
+ MFP_PIN_GPIO61,
+ MFP_PIN_GPIO62,
+ MFP_PIN_GPIO63,
+ MFP_PIN_GPIO64,
+ MFP_PIN_GPIO65,
+ MFP_PIN_GPIO66,
+ MFP_PIN_GPIO67,
+ MFP_PIN_GPIO68,
+ MFP_PIN_GPIO69,
+ MFP_PIN_GPIO70,
+ MFP_PIN_GPIO71,
+ MFP_PIN_GPIO72,
+ MFP_PIN_GPIO73,
+ MFP_PIN_GPIO74,
+ MFP_PIN_GPIO75,
+ MFP_PIN_GPIO76,
+ MFP_PIN_GPIO77,
+ MFP_PIN_GPIO78,
+ MFP_PIN_GPIO79,
+ MFP_PIN_GPIO80,
+ MFP_PIN_GPIO81,
+ MFP_PIN_GPIO82,
+ MFP_PIN_GPIO83,
+ MFP_PIN_GPIO84,
+ MFP_PIN_GPIO85,
+ MFP_PIN_GPIO86,
+ MFP_PIN_GPIO87,
+ MFP_PIN_GPIO88,
+ MFP_PIN_GPIO89,
+ MFP_PIN_GPIO90,
+ MFP_PIN_GPIO91,
+ MFP_PIN_GPIO92,
+ MFP_PIN_GPIO93,
+ MFP_PIN_GPIO94,
+ MFP_PIN_GPIO95,
+ MFP_PIN_GPIO96,
+ MFP_PIN_GPIO97,
+ MFP_PIN_GPIO98,
+ MFP_PIN_GPIO99,
+ MFP_PIN_GPIO100,
+ MFP_PIN_GPIO101,
+ MFP_PIN_GPIO102,
+ MFP_PIN_GPIO103,
+ MFP_PIN_GPIO104,
+ MFP_PIN_GPIO105,
+ MFP_PIN_GPIO106,
+ MFP_PIN_GPIO107,
+ MFP_PIN_GPIO108,
+ MFP_PIN_GPIO109,
+ MFP_PIN_GPIO110,
+ MFP_PIN_GPIO111,
+ MFP_PIN_GPIO112,
+ MFP_PIN_GPIO113,
+ MFP_PIN_GPIO114,
+ MFP_PIN_GPIO115,
+ MFP_PIN_GPIO116,
+ MFP_PIN_GPIO117,
+ MFP_PIN_GPIO118,
+ MFP_PIN_GPIO119,
+ MFP_PIN_GPIO120,
+ MFP_PIN_GPIO121,
+ MFP_PIN_GPIO122,
+ MFP_PIN_GPIO123,
+ MFP_PIN_GPIO124,
+ MFP_PIN_GPIO125,
+ MFP_PIN_GPIO126,
+ MFP_PIN_GPIO127,
+
+ MFP_PIN_GPIO128,
+ MFP_PIN_GPIO129,
+ MFP_PIN_GPIO130,
+ MFP_PIN_GPIO131,
+ MFP_PIN_GPIO132,
+ MFP_PIN_GPIO133,
+ MFP_PIN_GPIO134,
+ MFP_PIN_GPIO135,
+ MFP_PIN_GPIO136,
+ MFP_PIN_GPIO137,
+ MFP_PIN_GPIO138,
+ MFP_PIN_GPIO139,
+ MFP_PIN_GPIO140,
+ MFP_PIN_GPIO141,
+ MFP_PIN_GPIO142,
+ MFP_PIN_GPIO143,
+ MFP_PIN_GPIO144,
+ MFP_PIN_GPIO145,
+ MFP_PIN_GPIO146,
+ MFP_PIN_GPIO147,
+ MFP_PIN_GPIO148,
+ MFP_PIN_GPIO149,
+ MFP_PIN_GPIO150,
+ MFP_PIN_GPIO151,
+ MFP_PIN_GPIO152,
+ MFP_PIN_GPIO153,
+ MFP_PIN_GPIO154,
+ MFP_PIN_GPIO155,
+ MFP_PIN_GPIO156,
+ MFP_PIN_GPIO157,
+ MFP_PIN_GPIO158,
+ MFP_PIN_GPIO159,
+ MFP_PIN_GPIO160,
+ MFP_PIN_GPIO161,
+ MFP_PIN_GPIO162,
+ MFP_PIN_GPIO163,
+ MFP_PIN_GPIO164,
+ MFP_PIN_GPIO165,
+ MFP_PIN_GPIO166,
+ MFP_PIN_GPIO167,
+ MFP_PIN_GPIO168,
+ MFP_PIN_GPIO169,
+ MFP_PIN_GPIO170,
+ MFP_PIN_GPIO171,
+ MFP_PIN_GPIO172,
+ MFP_PIN_GPIO173,
+ MFP_PIN_GPIO174,
+ MFP_PIN_GPIO175,
+ MFP_PIN_GPIO176,
+ MFP_PIN_GPIO177,
+ MFP_PIN_GPIO178,
+ MFP_PIN_GPIO179,
+ MFP_PIN_GPIO180,
+ MFP_PIN_GPIO181,
+ MFP_PIN_GPIO182,
+ MFP_PIN_GPIO183,
+ MFP_PIN_GPIO184,
+ MFP_PIN_GPIO185,
+ MFP_PIN_GPIO186,
+ MFP_PIN_GPIO187,
+ MFP_PIN_GPIO188,
+ MFP_PIN_GPIO189,
+ MFP_PIN_GPIO190,
+ MFP_PIN_GPIO191,
+
+ MFP_PIN_GPIO255 = 255,
+
+ MFP_PIN_GPIO0_2,
+ MFP_PIN_GPIO1_2,
+ MFP_PIN_GPIO2_2,
+ MFP_PIN_GPIO3_2,
+ MFP_PIN_GPIO4_2,
+ MFP_PIN_GPIO5_2,
+ MFP_PIN_GPIO6_2,
+ MFP_PIN_GPIO7_2,
+ MFP_PIN_GPIO8_2,
+ MFP_PIN_GPIO9_2,
+ MFP_PIN_GPIO10_2,
+ MFP_PIN_GPIO11_2,
+ MFP_PIN_GPIO12_2,
+ MFP_PIN_GPIO13_2,
+ MFP_PIN_GPIO14_2,
+ MFP_PIN_GPIO15_2,
+ MFP_PIN_GPIO16_2,
+ MFP_PIN_GPIO17_2,
+
+ MFP_PIN_ULPI_STP,
+ MFP_PIN_ULPI_NXT,
+ MFP_PIN_ULPI_DIR,
+
+ MFP_PIN_nXCVREN,
+ MFP_PIN_DF_CLE_nOE,
+ MFP_PIN_DF_nADV1_ALE,
+ MFP_PIN_DF_SCLK_E,
+ MFP_PIN_DF_SCLK_S,
+ MFP_PIN_nBE0,
+ MFP_PIN_nBE1,
+ MFP_PIN_DF_nADV2_ALE,
+ MFP_PIN_DF_INT_RnB,
+ MFP_PIN_DF_nCS0,
+ MFP_PIN_DF_nCS1,
+ MFP_PIN_nLUA,
+ MFP_PIN_nLLA,
+ MFP_PIN_DF_nWE,
+ MFP_PIN_DF_ALE_nWE,
+ MFP_PIN_DF_nRE_nOE,
+ MFP_PIN_DF_ADDR0,
+ MFP_PIN_DF_ADDR1,
+ MFP_PIN_DF_ADDR2,
+ MFP_PIN_DF_ADDR3,
+ MFP_PIN_DF_IO0,
+ MFP_PIN_DF_IO1,
+ MFP_PIN_DF_IO2,
+ MFP_PIN_DF_IO3,
+ MFP_PIN_DF_IO4,
+ MFP_PIN_DF_IO5,
+ MFP_PIN_DF_IO6,
+ MFP_PIN_DF_IO7,
+ MFP_PIN_DF_IO8,
+ MFP_PIN_DF_IO9,
+ MFP_PIN_DF_IO10,
+ MFP_PIN_DF_IO11,
+ MFP_PIN_DF_IO12,
+ MFP_PIN_DF_IO13,
+ MFP_PIN_DF_IO14,
+ MFP_PIN_DF_IO15,
+ MFP_PIN_DF_nCS0_SM_nCS2,
+ MFP_PIN_DF_nCS1_SM_nCS3,
+ MFP_PIN_SM_nCS0,
+ MFP_PIN_SM_nCS1,
+ MFP_PIN_DF_WEn,
+ MFP_PIN_DF_REn,
+ MFP_PIN_DF_CLE_SM_OEn,
+ MFP_PIN_DF_ALE_SM_WEn,
+ MFP_PIN_DF_RDY0,
+ MFP_PIN_DF_RDY1,
+
+ MFP_PIN_SM_SCLK,
+ MFP_PIN_SM_BE0,
+ MFP_PIN_SM_BE1,
+ MFP_PIN_SM_ADV,
+ MFP_PIN_SM_ADVMUX,
+ MFP_PIN_SM_RDY,
+
+ MFP_PIN_MMC1_DAT7,
+ MFP_PIN_MMC1_DAT6,
+ MFP_PIN_MMC1_DAT5,
+ MFP_PIN_MMC1_DAT4,
+ MFP_PIN_MMC1_DAT3,
+ MFP_PIN_MMC1_DAT2,
+ MFP_PIN_MMC1_DAT1,
+ MFP_PIN_MMC1_DAT0,
+ MFP_PIN_MMC1_CMD,
+ MFP_PIN_MMC1_CLK,
+ MFP_PIN_MMC1_CD,
+ MFP_PIN_MMC1_WP,
+
+ /* additional pins on PXA930 */
+ MFP_PIN_GSIM_UIO,
+ MFP_PIN_GSIM_UCLK,
+ MFP_PIN_GSIM_UDET,
+ MFP_PIN_GSIM_nURST,
+ MFP_PIN_PMIC_INT,
+ MFP_PIN_RDY,
+
+ MFP_PIN_MAX,
+};
+
+/*
+ * a possible MFP configuration is represented by a 32-bit integer
+ *
+ * bit 0.. 9 - MFP Pin Number (1024 Pins Maximum)
+ * bit 10..12 - Alternate Function Selection
+ * bit 13..15 - Drive Strength
+ * bit 16..18 - Low Power Mode State
+ * bit 19..20 - Low Power Mode Edge Detection
+ * bit 21..22 - Run Mode Pull State
+ *
+ * to facilitate the definition, the following macros are provided
+ *
+ * MFP_CFG_DEFAULT - default MFP configuration value, with
+ * alternate function = 0,
+ * drive strength = fast 3mA (MFP_DS03X)
+ * low power mode = default
+ * edge detection = none
+ *
+ * MFP_CFG - default MFPR value with alternate function
+ * MFP_CFG_DRV - default MFPR value with alternate function and
+ * pin drive strength
+ * MFP_CFG_LPM - default MFPR value with alternate function and
+ * low power mode
+ * MFP_CFG_X - default MFPR value with alternate function,
+ * pin drive strength and low power mode
+ */
+
+typedef unsigned long mfp_cfg_t;
+
+#define MFP_PIN(x) ((x) & 0x3ff)
+
+#define MFP_AF0 (0x0 << 10)
+#define MFP_AF1 (0x1 << 10)
+#define MFP_AF2 (0x2 << 10)
+#define MFP_AF3 (0x3 << 10)
+#define MFP_AF4 (0x4 << 10)
+#define MFP_AF5 (0x5 << 10)
+#define MFP_AF6 (0x6 << 10)
+#define MFP_AF7 (0x7 << 10)
+#define MFP_AF_MASK (0x7 << 10)
+#define MFP_AF(x) (((x) >> 10) & 0x7)
+
+#define MFP_DS01X (0x0 << 13)
+#define MFP_DS02X (0x1 << 13)
+#define MFP_DS03X (0x2 << 13)
+#define MFP_DS04X (0x3 << 13)
+#define MFP_DS06X (0x4 << 13)
+#define MFP_DS08X (0x5 << 13)
+#define MFP_DS10X (0x6 << 13)
+#define MFP_DS13X (0x7 << 13)
+#define MFP_DS_MASK (0x7 << 13)
+#define MFP_DS(x) (((x) >> 13) & 0x7)
+
+#define MFP_LPM_DEFAULT (0x0 << 16)
+#define MFP_LPM_DRIVE_LOW (0x1 << 16)
+#define MFP_LPM_DRIVE_HIGH (0x2 << 16)
+#define MFP_LPM_PULL_LOW (0x3 << 16)
+#define MFP_LPM_PULL_HIGH (0x4 << 16)
+#define MFP_LPM_FLOAT (0x5 << 16)
+#define MFP_LPM_INPUT (0x6 << 16)
+#define MFP_LPM_STATE_MASK (0x7 << 16)
+#define MFP_LPM_STATE(x) (((x) >> 16) & 0x7)
+
+#define MFP_LPM_EDGE_NONE (0x0 << 19)
+#define MFP_LPM_EDGE_RISE (0x1 << 19)
+#define MFP_LPM_EDGE_FALL (0x2 << 19)
+#define MFP_LPM_EDGE_BOTH (0x3 << 19)
+#define MFP_LPM_EDGE_MASK (0x3 << 19)
+#define MFP_LPM_EDGE(x) (((x) >> 19) & 0x3)
+
+#define MFP_PULL_NONE (0x0 << 21)
+#define MFP_PULL_LOW (0x1 << 21)
+#define MFP_PULL_HIGH (0x2 << 21)
+#define MFP_PULL_BOTH (0x3 << 21)
+#define MFP_PULL_FLOAT (0x4 << 21)
+#define MFP_PULL_MASK (0x7 << 21)
+#define MFP_PULL(x) (((x) >> 21) & 0x7)
+
+#define MFP_CFG_DEFAULT (MFP_AF0 | MFP_DS03X | MFP_LPM_DEFAULT |\
+ MFP_LPM_EDGE_NONE | MFP_PULL_NONE)
+
+#define MFP_CFG(pin, af) \
+ ((MFP_CFG_DEFAULT & ~MFP_AF_MASK) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af))
+
+#define MFP_CFG_DRV(pin, af, drv) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv))
+
+#define MFP_CFG_LPM(pin, af, lpm) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_LPM_STATE_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_LPM_##lpm))
+
+#define MFP_CFG_X(pin, af, drv, lpm) \
+ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DS_MASK | MFP_LPM_STATE_MASK)) |\
+ (MFP_PIN(MFP_PIN_##pin) | MFP_##af | MFP_##drv | MFP_LPM_##lpm))
+
+#if defined(CONFIG_PXA3xx) || defined(CONFIG_ARCH_MMP)
+/*
+ * each MFP pin will have a MFPR register, since the offset of the
+ * register varies between processors, the processor specific code
+ * should initialize the pin offsets by mfp_init()
+ *
+ * mfp_init_base() - accepts a virtual base for all MFPR registers and
+ * initialize the MFP table to a default state
+ *
+ * mfp_init_addr() - accepts a table of "mfp_addr_map" structure, which
+ * represents a range of MFP pins from "start" to "end", with the offset
+ * begining at "offset", to define a single pin, let "end" = -1.
+ *
+ * use
+ *
+ * MFP_ADDR_X() to define a range of pins
+ * MFP_ADDR() to define a single pin
+ * MFP_ADDR_END to signal the end of pin offset definitions
+ */
+struct mfp_addr_map {
+ unsigned int start;
+ unsigned int end;
+ unsigned long offset;
+};
+
+#define MFP_ADDR_X(start, end, offset) \
+ { MFP_PIN_##start, MFP_PIN_##end, offset }
+
+#define MFP_ADDR(pin, offset) \
+ { MFP_PIN_##pin, -1, offset }
+
+#define MFP_ADDR_END { MFP_PIN_INVALID, 0 }
+
+void __init mfp_init_base(unsigned long mfpr_base);
+void __init mfp_init_addr(struct mfp_addr_map *map);
+
+/*
+ * mfp_{read, write}() - for direct read/write access to the MFPR register
+ * mfp_config() - for configuring a group of MFPR registers
+ * mfp_config_lpm() - configuring all low power MFPR registers for suspend
+ * mfp_config_run() - configuring all run time MFPR registers after resume
+ */
+unsigned long mfp_read(int mfp);
+void mfp_write(int mfp, unsigned long mfpr_val);
+void mfp_config(unsigned long *mfp_cfgs, int num);
+void mfp_config_run(void);
+void mfp_config_lpm(void);
+#endif /* CONFIG_PXA3xx || CONFIG_ARCH_MMP */
+
+#endif /* __ASM_PLAT_MFP_H */
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c
new file mode 100644
index 0000000..4f393c4
--- /dev/null
+++ b/arch/arm/mach-pxa/mfp-pxa2xx.c
@@ -0,0 +1,189 @@
+/*
+ * linux/arch/arm/mach-pxa/mfp-pxa2xx.c
+ *
+ * PXA2xx pin mux configuration support
+ *
+ * The GPIOs on PXA2xx can be configured as one of many alternate
+ * functions, this is by concept samilar to the MFP configuration
+ * on PXA3xx, what's more important, the low power pin state and
+ * wakeup detection are also supported by the same framework.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <init.h>
+
+#include <mach/gpio.h>
+#include <mach/hardware.h>
+#include <mach/mfp-pxa2xx.h>
+#include <mach/pxa-regs.h>
+
+#define PGSR(x) __REG2(0x40F00020, (x) << 2)
+#define __GAFR(u, x) __REG2((u) ? 0x40E00058 : 0x40E00054, (x) << 3)
+#define GAFR_L(x) __GAFR(0, x)
+#define GAFR_U(x) __GAFR(1, x)
+
+struct gpio_desc {
+ unsigned valid:1;
+ unsigned dir_inverted:1;
+ unsigned long config;
+};
+
+static struct gpio_desc gpio_desc[MFP_PIN_GPIO127 + 1];
+
+static unsigned long gpdr_lpm[4];
+
+static int __mfp_config_gpio(unsigned gpio, unsigned long c)
+{
+ unsigned long gafr, mask = GPIO_bit(gpio);
+ int bank = gpio_to_bank(gpio);
+ int uorl = !!(gpio & 0x10); /* GAFRx_U or GAFRx_L ? */
+ int shft = (gpio & 0xf) << 1;
+ int fn = MFP_AF(c);
+ int is_out = (c & MFP_DIR_OUT) ? 1 : 0;
+
+ if (fn > 3)
+ return -EINVAL;
+
+ /* alternate function and direction at run-time */
+ gafr = (uorl == 0) ? GAFR_L(bank) : GAFR_U(bank);
+ gafr = (gafr & ~(0x3 << shft)) | (fn << shft);
+
+ if (uorl == 0)
+ GAFR_L(bank) = gafr;
+ else
+ GAFR_U(bank) = gafr;
+
+ if (is_out ^ gpio_desc[gpio].dir_inverted)
+ GPDR(gpio) |= mask;
+ else
+ GPDR(gpio) &= ~mask;
+
+ /* alternate function and direction at low power mode */
+ switch (c & MFP_LPM_STATE_MASK) {
+ case MFP_LPM_DRIVE_HIGH:
+ PGSR(bank) |= mask;
+ is_out = 1;
+ break;
+ case MFP_LPM_DRIVE_LOW:
+ PGSR(bank) &= ~mask;
+ is_out = 1;
+ break;
+ case MFP_LPM_DEFAULT:
+ break;
+ default:
+ /* warning and fall through, treat as MFP_LPM_DEFAULT */
+ pr_warning("%s: GPIO%d: unsupported low power mode\n",
+ __func__, gpio);
+ break;
+ }
+
+ if (is_out ^ gpio_desc[gpio].dir_inverted)
+ gpdr_lpm[bank] |= mask;
+ else
+ gpdr_lpm[bank] &= ~mask;
+
+ return 0;
+}
+
+static inline int __mfp_validate(int mfp)
+{
+ int gpio = mfp_to_gpio(mfp);
+
+ if ((mfp > MFP_PIN_GPIO127) || !gpio_desc[gpio].valid) {
+ pr_warning("%s: GPIO%d is invalid pin\n", __func__, gpio);
+ return -1;
+ }
+
+ return gpio;
+}
+
+void pxa2xx_mfp_config(unsigned long *mfp_cfgs, int num)
+{
+ unsigned long *c;
+ int i, gpio;
+
+ for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
+
+ gpio = __mfp_validate(MFP_PIN(*c));
+ if (gpio < 0)
+ continue;
+
+ gpio_desc[gpio].config = *c;
+ __mfp_config_gpio(gpio, *c);
+ }
+}
+
+void pxa2xx_mfp_set_lpm(int mfp, unsigned long lpm)
+{
+ unsigned long c;
+ int gpio;
+
+ gpio = __mfp_validate(mfp);
+ if (gpio < 0)
+ return;
+
+ c = gpio_desc[gpio].config;
+ c = (c & ~MFP_LPM_STATE_MASK) | lpm;
+ __mfp_config_gpio(gpio, c);
+}
+
+static void __init pxa25x_mfp_init(void)
+{
+ int i;
+
+ for (i = 0; i <= pxa_last_gpio; i++)
+ gpio_desc[i].valid = 1;
+
+ /* PXA26x has additional 4 GPIOs (86/87/88/89) which has the
+ * direction bit inverted in GPDR2. See PXA26x DM 4.1.1.
+ */
+ for (i = 86; i <= pxa_last_gpio; i++)
+ gpio_desc[i].dir_inverted = 1;
+}
+
+static void __init pxa27x_mfp_init(void)
+{
+ int i;
+
+ for (i = 0; i <= pxa_last_gpio; i++) {
+ /*
+ * skip GPIO2, 5, 6, 7, 8, they are not
+ * valid pins allow configuration
+ */
+ if (i == 2 || i == 5 || i == 6 || i == 7 || i == 8)
+ continue;
+
+ gpio_desc[i].valid = 1;
+ }
+}
+
+static int __init pxa2xx_mfp_init(void)
+{
+ int i;
+
+ if (!cpu_is_pxa2xx())
+ return 0;
+
+ if (cpu_is_pxa25x())
+ pxa25x_mfp_init();
+
+ if (cpu_is_pxa27x()) {
+ pxa_init_gpio(2, 120);
+ pxa27x_mfp_init();
+ }
+
+ /* clear RDH bit to enable GPIO receivers after reset/sleep exit */
+ PSSR = PSSR_RDH;
+
+ /* initialize gafr_run[], pgsr_lpm[] from existing values */
+ for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++)
+ gpdr_lpm[i] = GPDR(i * 32);
+
+ return 0;
+}
+postcore_initcall(pxa2xx_mfp_init);
diff --git a/arch/arm/mach-pxa/speed-pxa27x.c b/arch/arm/mach-pxa/speed-pxa27x.c
new file mode 100644
index 0000000..e8d147f
--- /dev/null
+++ b/arch/arm/mach-pxa/speed-pxa27x.c
@@ -0,0 +1,20 @@
+/*
+ * clock.h - implementation of the PXA clock functions
+ *
+ * Copyright (C) 2010 by Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#include <common.h>
+#include <mach/clock.h>
+#include <mach/pxa-regs.h>
+
+/* Crystal clock: 13MHz */
+#define BASE_CLK 13000000
+
+unsigned long pxa_get_uartclk(void)
+{
+ return 14857000;
+}
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 35acbf0..d593026 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
#
# http://www.arm.linux.org.uk/developer/machines/?action=new
#
-# Last update: Wed Mar 30 09:36:58 2011
+# Last update: Tue Dec 6 15:54:16 2011
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -1319,6 +1319,7 @@ mistral MACH_MISTRAL MISTRAL 1315
msm MACH_MSM MSM 1316
ct5910 MACH_CT5910 CT5910 1317
ct5912 MACH_CT5912 CT5912 1318
+argonst_mp MACH_HYNET_INE HYNET_INE 1319
hynet_app MACH_HYNET_APP HYNET_APP 1320
msm7200 MACH_MSM7200 MSM7200 1321
msm7600 MACH_MSM7600 MSM7600 1322
@@ -1557,7 +1558,7 @@ otter MACH_OTTER OTTER 1561
davinci_ldk MACH_DAVINCI_LDK DAVINCI_LDK 1562
phreedom MACH_PHREEDOM PHREEDOM 1563
sg310 MACH_SG310 SG310 1564
-ts_x09 MACH_TS209 TS209 1565
+ts209 MACH_TS209 TS209 1565
at91cap9adk MACH_AT91CAP9ADK AT91CAP9ADK 1566
tion9315 MACH_TION9315 TION9315 1567
mast MACH_MAST MAST 1568
@@ -1960,7 +1961,7 @@ ethernut5 MACH_ETHERNUT5 ETHERNUT5 1971
arm11 MACH_ARM11 ARM11 1972
cpuat9260 MACH_CPUAT9260 CPUAT9260 1973
cpupxa255 MACH_CPUPXA255 CPUPXA255 1974
-eukrea_cpuimx27 MACH_CPUIMX27 CPUIMX27 1975
+eukrea_cpuimx27 MACH_EUKREA_CPUIMX27 EUKREA_CPUIMX27 1975
cheflux MACH_CHEFLUX CHEFLUX 1976
eb_cpux9k2 MACH_EB_CPUX9K2 EB_CPUX9K2 1977
opcotec MACH_OPCOTEC OPCOTEC 1978
@@ -2554,6 +2555,7 @@ magnolia2 MACH_MAGNOLIA2 MAGNOLIA2 2573
emxx MACH_EMXX EMXX 2574
outlaw MACH_OUTLAW OUTLAW 2575
riot_bei2 MACH_RIOT_BEI2 RIOT_BEI2 2576
+riot_gx2 MACH_RIOT_VOX RIOT_VOX 2577
riot_x37 MACH_RIOT_X37 RIOT_X37 2578
mega25mx MACH_MEGA25MX MEGA25MX 2579
benzina2 MACH_BENZINA2 BENZINA2 2580
@@ -2567,7 +2569,7 @@ p3600 MACH_P3600 P3600 2587
dlt2 MACH_DLT2 DLT2 2588
df3120 MACH_DF3120 DF3120 2589
ecucore_9g20 MACH_ECUCORE_9G20 ECUCORE_9G20 2590
-nautel_lpc3240 MACH_NAUTEL_LPC3240 NAUTEL_LPC3240 2591
+nautel_am35xx MACH_NAUTEL_LPC3240 NAUTEL_LPC3240 2591
glacier MACH_GLACIER GLACIER 2592
phrazer_bulldog MACH_PHRAZER_BULLDOG PHRAZER_BULLDOG 2593
omap3_bulldog MACH_OMAP3_BULLDOG OMAP3_BULLDOG 2594
@@ -2599,7 +2601,7 @@ fujitsu_tvstbsoc1 MACH_FUJITSU_TVSTBSOC1 FUJITSU_TVSTBSOC1 2621
lexikon MACH_LEXIKON LEXIKON 2622
mini2440v2 MACH_MINI2440V2 MINI2440V2 2623
icontrol MACH_ICONTROL ICONTROL 2624
-gplugd MACH_SHEEVAD SHEEVAD 2625
+gplugd MACH_GPLUGD GPLUGD 2625
qsd8x50a_st1_1 MACH_QSD8X50A_ST1_1 QSD8X50A_ST1_1 2626
qsd8x50a_st1_5 MACH_QSD8X50A_ST1_5 QSD8X50A_ST1_5 2627
bee MACH_BEE BEE 2628
@@ -2652,7 +2654,7 @@ htcpanther_cdma MACH_HTCPANTHER_CDMA HTCPANTHER_CDMA 2674
reb01 MACH_REB01 REB01 2675
aquila MACH_AQUILA AQUILA 2676
spark_sls_hw2 MACH_SPARK_SLS_HW2 SPARK_SLS_HW2 2677
-sheeva_esata MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678
+esata_sheevaplug MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678
msm7x30_surf MACH_MSM7X30_SURF MSM7X30_SURF 2679
micro2440 MACH_MICRO2440 MICRO2440 2680
am2440 MACH_AM2440 AM2440 2681
@@ -2724,7 +2726,7 @@ vpnext_mpu MACH_VPNEXT_MPU VPNEXT_MPU 2747
bcmring_tablet_v1 MACH_BCMRING_TABLET_V1 BCMRING_TABLET_V1 2748
sgarm10 MACH_SGARM10 SGARM10 2749
cm_t3517 MACH_CM_T3517 CM_T3517 2750
-omap3_cps MACH_OMAP3_CPS OMAP3_CPS 2751
+dig297 MACH_OMAP3_CPS OMAP3_CPS 2751
axar1500_receiver MACH_AXAR1500_RECEIVER AXAR1500_RECEIVER 2752
wbd222 MACH_WBD222 WBD222 2753
mt65xx MACH_MT65XX MT65XX 2754
@@ -2748,6 +2750,7 @@ oreo_controller MACH_OREO_CONTROLLER OREO_CONTROLLER 2773
kopin_models MACH_KOPIN_MODELS KOPIN_MODELS 2774
ttc_vision2 MACH_TTC_VISION2 TTC_VISION2 2775
cns3420vb MACH_CNS3420VB CNS3420VB 2776
+lpc_evo MACH_LPC2 LPC2 2777
olympus MACH_OLYMPUS OLYMPUS 2778
vortex MACH_VORTEX VORTEX 2779
s5pc200 MACH_S5PC200 S5PC200 2780
@@ -2789,8 +2792,8 @@ teton_bga MACH_TETON_BGA TETON_BGA 2816
snapper9g45 MACH_SNAPPER9G45 SNAPPER9G45 2817
tam3517 MACH_TAM3517 TAM3517 2818
pdc100 MACH_PDC100 PDC100 2819
-eukrea_cpuimx25sd MACH_EUKREA_CPUIMX25 EUKREA_CPUIMX25 2820
-eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35 EUKREA_CPUIMX35 2821
+eukrea_cpuimx25sd MACH_EUKREA_CPUIMX25SD EUKREA_CPUIMX25SD 2820
+eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35SD EUKREA_CPUIMX35SD 2821
eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822
eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823
p565 MACH_P565 P565 2824
@@ -3018,6 +3021,7 @@ s5pc110_crespo MACH_S5PC110_CRESPO S5PC110_CRESPO 3052
controltek9g20 MACH_CONTROLTEK9G20 CONTROLTEK9G20 3053
tin307 MACH_TIN307 TIN307 3054
tin510 MACH_TIN510 TIN510 3055
+ep3505 MACH_EP3517 EP3517 3056
bluecheese MACH_BLUECHEESE BLUECHEESE 3057
tem3x30 MACH_TEM3X30 TEM3X30 3058
harvest_desoto MACH_HARVEST_DESOTO HARVEST_DESOTO 3059
@@ -3236,7 +3240,7 @@ omapl138_case_a3 MACH_OMAPL138_CASE_A3 OMAPL138_CASE_A3 3280
uemd MACH_UEMD UEMD 3281
ccwmx51mut MACH_CCWMX51MUT CCWMX51MUT 3282
rockhopper MACH_ROCKHOPPER ROCKHOPPER 3283
-nookcolor MACH_NOOKCOLOR NOOKCOLOR 3284
+encore MACH_ENCORE ENCORE 3284
hkdkc100 MACH_HKDKC100 HKDKC100 3285
ts42xx MACH_TS42XX TS42XX 3286
aebl MACH_AEBL AEBL 3287
@@ -3247,9 +3251,9 @@ isc3 MACH_ISC3 ISC3 3291
rascal MACH_RASCAL RASCAL 3292
hrefv60 MACH_HREFV60 HREFV60 3293
tpt_2_0 MACH_TPT_2_0 TPT_2_0 3294
-pyramid_td MACH_PYRAMID_TD PYRAMID_TD 3295
+pydtd MACH_PYRAMID_TD PYRAMID_TD 3295
splendor MACH_SPLENDOR SPLENDOR 3296
-guf_planet MACH_GUF_PLANET GUF_PLANET 3297
+guf_vincell MACH_GUF_PLANET GUF_PLANET 3297
msm8x60_qt MACH_MSM8X60_QT MSM8X60_QT 3298
htc_hd_mini MACH_HTC_HD_MINI HTC_HD_MINI 3299
athene MACH_ATHENE ATHENE 3300
@@ -3348,7 +3352,7 @@ geneva_b5 MACH_GENEVA_B5 GENEVA_B5 3393
spear1340 MACH_SPEAR1340 SPEAR1340 3394
rexmas MACH_REXMAS REXMAS 3395
msm8960_cdp MACH_MSM8960_CDP MSM8960_CDP 3396
-msm8960_mdp MACH_MSM8960_MDP MSM8960_MDP 3397
+msm8960_mtp MACH_MSM8960_MDP MSM8960_MDP 3397
msm8960_fluid MACH_MSM8960_FLUID MSM8960_FLUID 3398
msm8960_apq MACH_MSM8960_APQ MSM8960_APQ 3399
helios_v2 MACH_HELIOS_V2 HELIOS_V2 3400
@@ -3396,3 +3400,446 @@ nuc740evb MACH_NUC740EVB NUC740EVB 3441
nuc745evb MACH_NUC745EVB NUC745EVB 3442
transcede MACH_TRANSCEDE TRANSCEDE 3443
mora MACH_MORA MORA 3444
+nda_evm MACH_NDA_EVM NDA_EVM 3445
+timu MACH_TIMU TIMU 3446
+expressh MACH_EXPRESSH EXPRESSH 3447
+veridis_a300 MACH_VERIDIS_A300 VERIDIS_A300 3448
+dm368_leopard MACH_DM368_LEOPARD DM368_LEOPARD 3449
+omap_mcop MACH_OMAP_MCOP OMAP_MCOP 3450
+tritip MACH_TRITIP TRITIP 3451
+sm1k MACH_SM1K SM1K 3452
+monch MACH_MONCH MONCH 3453
+curacao MACH_CURACAO CURACAO 3454
+origen MACH_ORIGEN ORIGEN 3455
+epc10 MACH_EPC10 EPC10 3456
+sgh_i740 MACH_SGH_I740 SGH_I740 3457
+tuna MACH_TUNA TUNA 3458
+mx51_tulip MACH_MX51_TULIP MX51_TULIP 3459
+mx51_aster7 MACH_MX51_ASTER7 MX51_ASTER7 3460
+acro37xbrd MACH_ACRO37XBRD ACRO37XBRD 3461
+elke MACH_ELKE ELKE 3462
+sbc6000x MACH_SBC6000X SBC6000X 3463
+r1801e MACH_R1801E R1801E 3464
+h1600 MACH_H1600 H1600 3465
+mini210 MACH_MINI210 MINI210 3466
+mini8168 MACH_MINI8168 MINI8168 3467
+pc7308 MACH_PC7308 PC7308 3468
+ge863pro3 MACH_GE863 GE863 3469
+kmm2m01 MACH_KMM2M01 KMM2M01 3470
+mx51erebus MACH_MX51EREBUS MX51EREBUS 3471
+wm8650refboard MACH_WM8650REFBOARD WM8650REFBOARD 3472
+tuxrail MACH_TUXRAIL TUXRAIL 3473
+arthur MACH_ARTHUR ARTHUR 3474
+doorboy MACH_DOORBOY DOORBOY 3475
+xarina MACH_XARINA XARINA 3476
+roverx7 MACH_ROVERX7 ROVERX7 3477
+sdvr MACH_SDVR SDVR 3478
+acer_maya MACH_ACER_MAYA ACER_MAYA 3479
+pico MACH_PICO PICO 3480
+cwmx233 MACH_CWMX233 CWMX233 3481
+cwam1808 MACH_CWAM1808 CWAM1808 3482
+cwdm365 MACH_CWDM365 CWDM365 3483
+mx51_moray MACH_MX51_MORAY MX51_MORAY 3484
+thales_cbc MACH_THALES_CBC THALES_CBC 3485
+bluepoint MACH_BLUEPOINT BLUEPOINT 3486
+dir665 MACH_DIR665 DIR665 3487
+acmerover1 MACH_ACMEROVER1 ACMEROVER1 3488
+shooter_ct MACH_SHOOTER_CT SHOOTER_CT 3489
+bliss MACH_BLISS BLISS 3490
+blissc MACH_BLISSC BLISSC 3491
+thales_adc MACH_THALES_ADC THALES_ADC 3492
+ubisys_p9d_evp MACH_UBISYS_P9D_EVP UBISYS_P9D_EVP 3493
+atdgp318 MACH_ATDGP318 ATDGP318 3494
+dma210u MACH_DMA210U DMA210U 3495
+em_t3 MACH_EM_T3 EM_T3 3496
+htx3250 MACH_HTX3250 HTX3250 3497
+g50 MACH_G50 G50 3498
+eco5 MACH_ECO5 ECO5 3499
+wintergrasp MACH_WINTERGRASP WINTERGRASP 3500
+puro MACH_PURO PURO 3501
+shooter_k MACH_SHOOTER_K SHOOTER_K 3502
+nspire MACH_NSPIRE NSPIRE 3503
+mickxx MACH_MICKXX MICKXX 3504
+lxmb MACH_LXMB LXMB 3505
+tmdxscbp6618x MACH_TMDXSCBP6616X TMDXSCBP6616X 3506
+adam MACH_ADAM ADAM 3507
+b1004 MACH_B1004 B1004 3508
+oboea MACH_OBOEA OBOEA 3509
+a1015 MACH_A1015 A1015 3510
+robin_vbdt30 MACH_ROBIN_VBDT30 ROBIN_VBDT30 3511
+tegra_enterprise MACH_TEGRA_ENTERPRISE TEGRA_ENTERPRISE 3512
+rfl108200_mk10 MACH_RFL108200_MK10 RFL108200_MK10 3513
+rfl108300_mk16 MACH_RFL108300_MK16 RFL108300_MK16 3514
+rover_v7 MACH_ROVER_V7 ROVER_V7 3515
+miphone MACH_MIPHONE MIPHONE 3516
+femtobts MACH_FEMTOBTS FEMTOBTS 3517
+monopoli MACH_MONOPOLI MONOPOLI 3518
+boss MACH_BOSS BOSS 3519
+davinci_dm368_vtam MACH_DAVINCI_DM368_VTAM DAVINCI_DM368_VTAM 3520
+clcon MACH_CLCON CLCON 3521
+nokia_rm696 MACH_NOKIA_RM696 NOKIA_RM696 3522
+tahiti MACH_TAHITI TAHITI 3523
+fighter MACH_FIGHTER FIGHTER 3524
+sgh_i710 MACH_SGH_I710 SGH_I710 3525
+integreproscb MACH_INTEGREPROSCB INTEGREPROSCB 3526
+monza MACH_MONZA MONZA 3527
+calimain MACH_CALIMAIN CALIMAIN 3528
+mx6q_sabreauto MACH_MX6Q_SABREAUTO MX6Q_SABREAUTO 3529
+gma01x MACH_GMA01X GMA01X 3530
+sbc51 MACH_SBC51 SBC51 3531
+fit MACH_FIT FIT 3532
+steelhead MACH_STEELHEAD STEELHEAD 3533
+panther MACH_PANTHER PANTHER 3534
+msm8960_liquid MACH_MSM8960_LIQUID MSM8960_LIQUID 3535
+lexikonct MACH_LEXIKONCT LEXIKONCT 3536
+ns2816_stb MACH_NS2816_STB NS2816_STB 3537
+sei_mm2_lpc3250 MACH_SEI_MM2_LPC3250 SEI_MM2_LPC3250 3538
+cmimx53 MACH_CMIMX53 CMIMX53 3539
+sandwich MACH_SANDWICH SANDWICH 3540
+chief MACH_CHIEF CHIEF 3541
+pogo_e02 MACH_POGO_E02 POGO_E02 3542
+mikrap_x168 MACH_MIKRAP_X168 MIKRAP_X168 3543
+htcmozart MACH_HTCMOZART HTCMOZART 3544
+htcgold MACH_HTCGOLD HTCGOLD 3545
+mt72xx MACH_MT72XX MT72XX 3546
+mx51_ivy MACH_MX51_IVY MX51_IVY 3547
+mx51_lvd MACH_MX51_LVD MX51_LVD 3548
+omap3_wiser2 MACH_OMAP3_WISER2 OMAP3_WISER2 3549
+dreamplug MACH_DREAMPLUG DREAMPLUG 3550
+cobas_c_111 MACH_COBAS_C_111 COBAS_C_111 3551
+cobas_u_411 MACH_COBAS_U_411 COBAS_U_411 3552
+hssd MACH_HSSD HSSD 3553
+iom35x MACH_IOM35X IOM35X 3554
+psom_omap MACH_PSOM_OMAP PSOM_OMAP 3555
+iphone_2g MACH_IPHONE_2G IPHONE_2G 3556
+iphone_3g MACH_IPHONE_3G IPHONE_3G 3557
+ipod_touch_1g MACH_IPOD_TOUCH_1G IPOD_TOUCH_1G 3558
+pharos_tpc MACH_PHAROS_TPC PHAROS_TPC 3559
+mx53_hydra MACH_MX53_HYDRA MX53_HYDRA 3560
+ns2816_dev_board MACH_NS2816_DEV_BOARD NS2816_DEV_BOARD 3561
+iphone_3gs MACH_IPHONE_3GS IPHONE_3GS 3562
+iphone_4 MACH_IPHONE_4 IPHONE_4 3563
+ipod_touch_4g MACH_IPOD_TOUCH_4G IPOD_TOUCH_4G 3564
+dragon_e1100 MACH_DRAGON_E1100 DRAGON_E1100 3565
+topside MACH_TOPSIDE TOPSIDE 3566
+irisiii MACH_IRISIII IRISIII 3567
+deto_macarm9 MACH_DETO_MACARM9 DETO_MACARM9 3568
+eti_d1 MACH_ETI_D1 ETI_D1 3569
+som3530sdk MACH_SOM3530SDK SOM3530SDK 3570
+oc_engine MACH_OC_ENGINE OC_ENGINE 3571
+apq8064_sim MACH_APQ8064_SIM APQ8064_SIM 3572
+alps MACH_ALPS ALPS 3575
+tny_t3730 MACH_TNY_T3730 TNY_T3730 3576
+geryon_nfe MACH_GERYON_NFE GERYON_NFE 3577
+ns2816_ref_board MACH_NS2816_REF_BOARD NS2816_REF_BOARD 3578
+silverstone MACH_SILVERSTONE SILVERSTONE 3579
+mtt2440 MACH_MTT2440 MTT2440 3580
+ynicdb MACH_YNICDB YNICDB 3581
+bct MACH_BCT BCT 3582
+tuscan MACH_TUSCAN TUSCAN 3583
+xbt_sam9g45 MACH_XBT_SAM9G45 XBT_SAM9G45 3584
+enbw_cmc MACH_ENBW_CMC ENBW_CMC 3585
+msm8x60_dragon MACH_APQ8060_DRAGON APQ8060_DRAGON 3586
+ch104mx257 MACH_CH104MX257 CH104MX257 3587
+openpri MACH_OPENPRI OPENPRI 3588
+am335xevm MACH_AM335XEVM AM335XEVM 3589
+picodmb MACH_PICODMB PICODMB 3590
+waluigi MACH_WALUIGI WALUIGI 3591
+punicag7 MACH_PUNICAG7 PUNICAG7 3592
+ipad_1g MACH_IPAD_1G IPAD_1G 3593
+appletv_2g MACH_APPLETV_2G APPLETV_2G 3594
+mach_ecog45 MACH_MACH_ECOG45 MACH_ECOG45 3595
+ait_cam_enc_4xx MACH_AIT_CAM_ENC_4XX AIT_CAM_ENC_4XX 3596
+runnymede MACH_RUNNYMEDE RUNNYMEDE 3597
+play MACH_PLAY PLAY 3598
+hw90260 MACH_HW90260 HW90260 3599
+tagh MACH_TAGH TAGH 3600
+filbert MACH_FILBERT FILBERT 3601
+getinge_netcomv3 MACH_GETINGE_NETCOMV3 GETINGE_NETCOMV3 3602
+cw20 MACH_CW20 CW20 3603
+cinema MACH_CINEMA CINEMA 3604
+cinema_tea MACH_CINEMA_TEA CINEMA_TEA 3605
+cinema_coffee MACH_CINEMA_COFFEE CINEMA_COFFEE 3606
+cinema_juice MACH_CINEMA_JUICE CINEMA_JUICE 3607
+linux_pad MACH_THEPAD THEPAD 3608
+mx53_mirage2 MACH_MX53_MIRAGE2 MX53_MIRAGE2 3609
+mx53_efikasb MACH_MX53_EFIKASB MX53_EFIKASB 3610
+stm_b2000 MACH_STM_B2000 STM_B2000 3612
+m28evk MACH_M28EVK M28EVK 3613
+pda MACH_PDA PDA 3614
+meraki_mr58 MACH_MERAKI_MR58 MERAKI_MR58 3615
+kota2 MACH_KOTA2 KOTA2 3616
+letcool MACH_LETCOOL LETCOOL 3617
+mx27iat MACH_MX27IAT MX27IAT 3618
+apollo_td MACH_APOLLO_TD APOLLO_TD 3619
+arena MACH_ARENA ARENA 3620
+gsngateway MACH_GSNGATEWAY GSNGATEWAY 3621
+lf2000 MACH_LF2000 LF2000 3622
+bonito MACH_BONITO BONITO 3623
+asymptote MACH_ASYMPTOTE ASYMPTOTE 3624
+bst2brd MACH_BST2BRD BST2BRD 3625
+tx335s MACH_TX335S TX335S 3626
+pelco_tesla MACH_PELCO_TESLA PELCO_TESLA 3627
+rrhtestplat MACH_RRHTESTPLAT RRHTESTPLAT 3628
+vidtonic_pro MACH_VIDTONIC_PRO VIDTONIC_PRO 3629
+pl_apollo MACH_PL_APOLLO PL_APOLLO 3630
+pl_phoenix MACH_PL_PHOENIX PL_PHOENIX 3631
+m28cu3 MACH_M28CU3 M28CU3 3632
+vvbox_hd MACH_VVBOX_HD VVBOX_HD 3633
+coreware_sam9260_ MACH_COREWARE_SAM9260_ COREWARE_SAM9260_ 3634
+marmaduke MACH_MARMADUKE MARMADUKE 3635
+amg_xlcore_camera MACH_AMG_XLCORE_CAMERA AMG_XLCORE_CAMERA 3636
+omap3_egf MACH_OMAP3_EGF OMAP3_EGF 3637
+smdk4212 MACH_SMDK4212 SMDK4212 3638
+dnp9200 MACH_DNP9200 DNP9200 3639
+tf101 MACH_TF101 TF101 3640
+omap3silvio MACH_OMAP3SILVIO OMAP3SILVIO 3641
+picasso2 MACH_PICASSO2 PICASSO2 3642
+vangogh2 MACH_VANGOGH2 VANGOGH2 3643
+olpc_xo_1_75 MACH_OLPC_XO_1_75 OLPC_XO_1_75 3644
+gx400 MACH_GX400 GX400 3645
+gs300 MACH_GS300 GS300 3646
+acer_a9 MACH_ACER_A9 ACER_A9 3647
+vivow_evm MACH_VIVOW_EVM VIVOW_EVM 3648
+veloce_cxq MACH_VELOCE_CXQ VELOCE_CXQ 3649
+veloce_cxm MACH_VELOCE_CXM VELOCE_CXM 3650
+p1852 MACH_P1852 P1852 3651
+naxy100 MACH_NAXY100 NAXY100 3652
+taishan MACH_TAISHAN TAISHAN 3653
+touchlink MACH_TOUCHLINK TOUCHLINK 3654
+stm32f103ze MACH_STM32F103ZE STM32F103ZE 3655
+mcx MACH_MCX MCX 3656
+stm_nmhdk_fli7610 MACH_STM_NMHDK_FLI7610 STM_NMHDK_FLI7610 3657
+top28x MACH_TOP28X TOP28X 3658
+okl4vp_microvisor MACH_OKL4VP_MICROVISOR OKL4VP_MICROVISOR 3659
+pop MACH_POP POP 3660
+layer MACH_LAYER LAYER 3661
+trondheim MACH_TRONDHEIM TRONDHEIM 3662
+eva MACH_EVA EVA 3663
+trust_taurus MACH_TRUST_TAURUS TRUST_TAURUS 3664
+ns2816_huashan MACH_NS2816_HUASHAN NS2816_HUASHAN 3665
+ns2816_yangcheng MACH_NS2816_YANGCHENG NS2816_YANGCHENG 3666
+p852 MACH_P852 P852 3667
+flea3 MACH_FLEA3 FLEA3 3668
+bowfin MACH_BOWFIN BOWFIN 3669
+mv88de3100 MACH_MV88DE3100 MV88DE3100 3670
+pia_am35x MACH_PIA_AM35X PIA_AM35X 3671
+cedar MACH_CEDAR CEDAR 3672
+picasso_e MACH_PICASSO_E PICASSO_E 3673
+samsung_e60 MACH_SAMSUNG_E60 SAMSUNG_E60 3674
+msm9615_cdp MACH_MDM9615 MDM9615 3675
+sdvr_mini MACH_SDVR_MINI SDVR_MINI 3676
+omap3_ij3k MACH_OMAP3_IJ3K OMAP3_IJ3K 3677
+modasmc1 MACH_MODASMC1 MODASMC1 3678
+apq8064_rumi3 MACH_APQ8064_RUMI3 APQ8064_RUMI3 3679
+matrix506 MACH_MATRIX506 MATRIX506 3680
+msm9615_mtp MACH_MSM9615_MTP MSM9615_MTP 3681
+dm36x_spawndc MACH_DM36X_SPAWNDC DM36X_SPAWNDC 3682
+sff792 MACH_SFF792 SFF792 3683
+am335xiaevm MACH_AM335XIAEVM AM335XIAEVM 3684
+g3c2440 MACH_G3C2440 G3C2440 3685
+tion270 MACH_TION270 TION270 3686
+w22q7arm02 MACH_W22Q7ARM02 W22Q7ARM02 3687
+omap_cat MACH_OMAP_CAT OMAP_CAT 3688
+at91sam9n12ek MACH_AT91SAM9N12EK AT91SAM9N12EK 3689
+morrison MACH_MORRISON MORRISON 3690
+svdu MACH_SVDU SVDU 3691
+lpp01 MACH_LPP01 LPP01 3692
+ubc283 MACH_UBC283 UBC283 3693
+zeppelin MACH_ZEPPELIN ZEPPELIN 3694
+motus MACH_MOTUS MOTUS 3695
+neomainboard MACH_NEOMAINBOARD NEOMAINBOARD 3696
+devkit3250 MACH_DEVKIT3250 DEVKIT3250 3697
+devkit7000 MACH_DEVKIT7000 DEVKIT7000 3698
+fmc_uic MACH_FMC_UIC FMC_UIC 3699
+fmc_dcm MACH_FMC_DCM FMC_DCM 3700
+batwm MACH_BATWM BATWM 3701
+atlas6cb MACH_ATLAS6CB ATLAS6CB 3702
+quattro_f MACH_QUATTROF QUATTROF 3703
+quattro_u MACH_QUATTROU QUATTROU 3704
+blue MACH_BLUE BLUE 3705
+colorado MACH_COLORADO COLORADO 3706
+popc MACH_POPC POPC 3707
+promwad_jade MACH_PROMWAD_JADE PROMWAD_JADE 3708
+amp MACH_AMP AMP 3709
+gnet_amp MACH_GNET_AMP GNET_AMP 3710
+toques MACH_TOQUES TOQUES 3711
+apx4devkit MACH_APX4 APX4 3712
+dct_storm MACH_DCT_STORM DCT_STORM 3713
+dm8168z3 MACH_Z3 Z3 3714
+owl MACH_OWL OWL 3715
+cogent_csb1741 MACH_COGENT_CSB1741 COGENT_CSB1741 3716
+omap3_kiko MACH_OMAP3 OMAP3 3717
+adillustra610 MACH_ADILLUSTRA610 ADILLUSTRA610 3718
+ecafe_na04 MACH_ECAFE_NA04 ECAFE_NA04 3719
+popct MACH_POPCT POPCT 3720
+omap3_helena MACH_OMAP3_HELENA OMAP3_HELENA 3721
+ach MACH_ACH ACH 3722
+module_dtb MACH_MODULE_DTB MODULE_DTB 3723
+ratebox MACH_RACKBOX RACKBOX 3724
+oslo_elisabeth MACH_OSLO_ELISABETH OSLO_ELISABETH 3725
+tt01 MACH_TT01 TT01 3726
+msm8930_cdp MACH_MSM8930_CDP MSM8930_CDP 3727
+msm8930_mtp MACH_MSM8930_MTP MSM8930_MTP 3728
+msm8930_fluid MACH_MSM8930_FLUID MSM8930_FLUID 3729
+ltu11 MACH_LTU11 LTU11 3730
+am1808_spawnco MACH_AM1808_SPAWNCO AM1808_SPAWNCO 3731
+flx6410 MACH_FLX6410 FLX6410 3732
+mx6q_qsb MACH_MX6Q_QSB MX6Q_QSB 3733
+mx53_plt424 MACH_MX53_PLT424 MX53_PLT424 3734
+jasmine MACH_JASMINE JASMINE 3735
+l138_owlboard_plus MACH_L138_OWLBOARD_PLUS L138_OWLBOARD_PLUS 3736
+wr21 MACH_WR21 WR21 3737
+peaboy MACH_PEABOY PEABOY 3739
+mx28_plato MACH_MX28_PLATO MX28_PLATO 3740
+kacom2 MACH_KACOM2 KACOM2 3741
+slco MACH_SLCO SLCO 3742
+imx51pico MACH_IMX51PICO IMX51PICO 3743
+glink1 MACH_GLINK1 GLINK1 3744
+diamond MACH_DIAMOND DIAMOND 3745
+d9000 MACH_D9000 D9000 3746
+w5300e01 MACH_W5300E01 W5300E01 3747
+im6000 MACH_IM6000 IM6000 3748
+mx51_fred51 MACH_MX51_FRED51 MX51_FRED51 3749
+stm32f2 MACH_STM32F2 STM32F2 3750
+ville MACH_VILLE VILLE 3751
+ptip_murnau MACH_PTIP_MURNAU PTIP_MURNAU 3752
+ptip_classic MACH_PTIP_CLASSIC PTIP_CLASSIC 3753
+mx53grb MACH_MX53GRB MX53GRB 3754
+gagarin MACH_GAGARIN GAGARIN 3755
+msm7627a_qrd1 MACH_MSM7X27A_QRD1 MSM7X27A_QRD1 3756
+nas2big MACH_NAS2BIG NAS2BIG 3757
+superfemto MACH_SUPERFEMTO SUPERFEMTO 3758
+teufel MACH_TEUFEL TEUFEL 3759
+dinara MACH_DINARA DINARA 3760
+vanquish MACH_VANQUISH VANQUISH 3761
+zipabox1 MACH_ZIPABOX1 ZIPABOX1 3762
+u9540 MACH_U9540 U9540 3763
+jet MACH_JET JET 3764
+smdk4412 MACH_SMDK4412 SMDK4412 3765
+elite MACH_ELITE ELITE 3766
+spear320_hmi MACH_SPEAR320_HMI SPEAR320_HMI 3767
+ontario MACH_ONTARIO ONTARIO 3768
+mx6q_sabrelite MACH_MX6Q_SABRELITE MX6Q_SABRELITE 3769
+vc200 MACH_VC200 VC200 3770
+msm7625a_ffa MACH_MSM7625A_FFA MSM7625A_FFA 3771
+msm7625a_surf MACH_MSM7625A_SURF MSM7625A_SURF 3772
+benthossbp MACH_BENTHOSSBP BENTHOSSBP 3773
+smdk5210 MACH_SMDK5210 SMDK5210 3774
+empq2300 MACH_EMPQ2300 EMPQ2300 3775
+minipos MACH_MINIPOS MINIPOS 3776
+omap5_sevm MACH_OMAP5_SEVM OMAP5_SEVM 3777
+shelter MACH_SHELTER SHELTER 3778
+omap3_devkit8500 MACH_OMAP3_DEVKIT8500 OMAP3_DEVKIT8500 3779
+edgetd MACH_EDGETD EDGETD 3780
+copperyard MACH_COPPERYARD COPPERYARD 3781
+edge MACH_EDGE EDGE 3782
+edge_u MACH_EDGE_U EDGE_U 3783
+edge_td MACH_EDGE_TD EDGE_TD 3784
+wdss MACH_WDSS WDSS 3785
+dl_pb25 MACH_DL_PB25 DL_PB25 3786
+dss11 MACH_DSS11 DSS11 3787
+cpa MACH_CPA CPA 3788
+aptp2000 MACH_APTP2000 APTP2000 3789
+marzen MACH_MARZEN MARZEN 3790
+st_turbine MACH_ST_TURBINE ST_TURBINE 3791
+gtl_it3300 MACH_GTL_IT3300 GTL_IT3300 3792
+mx6_mule MACH_MX6_MULE MX6_MULE 3793
+v7pxa_dt MACH_V7PXA_DT V7PXA_DT 3794
+v7mmp_dt MACH_V7MMP_DT V7MMP_DT 3795
+dragon7 MACH_DRAGON7 DRAGON7 3796
+krome MACH_KROME KROME 3797
+oratisdante MACH_ORATISDANTE ORATISDANTE 3798
+fathom MACH_FATHOM FATHOM 3799
+dns325 MACH_DNS325 DNS325 3800
+sarnen MACH_SARNEN SARNEN 3801
+ubisys_g1 MACH_UBISYS_G1 UBISYS_G1 3802
+mx53_pf1 MACH_MX53_PF1 MX53_PF1 3803
+asanti MACH_ASANTI ASANTI 3804
+volta MACH_VOLTA VOLTA 3805
+potenza MACH_S5P6450 S5P6450 3806
+knight MACH_KNIGHT KNIGHT 3807
+beaglebone MACH_BEAGLEBONE BEAGLEBONE 3808
+becker MACH_BECKER BECKER 3809
+fc360 MACH_FC360 FC360 3810
+pmi2_xls MACH_PMI2_XLS PMI2_XLS 3811
+taranto MACH_TARANTO TARANTO 3812
+plutux MACH_PLUTUX PLUTUX 3813
+ipmp_medcom MACH_IPMP_MEDCOM IPMP_MEDCOM 3814
+absolut MACH_ABSOLUT ABSOLUT 3815
+awpb3 MACH_AWPB3 AWPB3 3816
+nfp32xx_dt MACH_NFP32XX_DT NFP32XX_DT 3817
+dl_pb53 MACH_DL_PB53 DL_PB53 3818
+acu_ii MACH_ACU_II ACU_II 3819
+avalon MACH_AVALON AVALON 3820
+sphinx MACH_SPHINX SPHINX 3821
+titan_t MACH_TITAN_T TITAN_T 3822
+harvest_boris MACH_HARVEST_BORIS HARVEST_BORIS 3823
+mach_msm7x30_m3s MACH_MACH_MSM7X30_M3S MACH_MSM7X30_M3S 3824
+smdk5250 MACH_SMDK5250 SMDK5250 3825
+imxt_lite MACH_IMXT_LITE IMXT_LITE 3826
+imxt_std MACH_IMXT_STD IMXT_STD 3827
+imxt_log MACH_IMXT_LOG IMXT_LOG 3828
+imxt_nav MACH_IMXT_NAV IMXT_NAV 3829
+imxt_full MACH_IMXT_FULL IMXT_FULL 3830
+ag09015 MACH_AG09015 AG09015 3831
+am3517_mt_ventoux MACH_AM3517_MT_VENTOUX AM3517_MT_VENTOUX 3832
+dp1arm9 MACH_DP1ARM9 DP1ARM9 3833
+picasso_m MACH_PICASSO_M PICASSO_M 3834
+video_gadget MACH_VIDEO_GADGET VIDEO_GADGET 3835
+mtt_om3x MACH_MTT_OM3X MTT_OM3X 3836
+mx6q_arm2 MACH_MX6Q_ARM2 MX6Q_ARM2 3837
+picosam9g45 MACH_PICOSAM9G45 PICOSAM9G45 3838
+vpm_dm365 MACH_VPM_DM365 VPM_DM365 3839
+bonfire MACH_BONFIRE BONFIRE 3840
+mt2p2d MACH_MT2P2D MT2P2D 3841
+sigpda01 MACH_SIGPDA01 SIGPDA01 3842
+cn27 MACH_CN27 CN27 3843
+mx25_cwtap MACH_MX25_CWTAP MX25_CWTAP 3844
+apf28 MACH_APF28 APF28 3845
+pelco_maxwell MACH_PELCO_MAXWELL PELCO_MAXWELL 3846
+ge_phoenix MACH_GE_PHOENIX GE_PHOENIX 3847
+empc_a500 MACH_EMPC_A500 EMPC_A500 3848
+ims_arm9 MACH_IMS_ARM9 IMS_ARM9 3849
+mini2416 MACH_MINI2416 MINI2416 3850
+mini2450 MACH_MINI2450 MINI2450 3851
+mini310 MACH_MINI310 MINI310 3852
+spear_hurricane MACH_SPEAR_HURRICANE SPEAR_HURRICANE 3853
+mt7208 MACH_MT7208 MT7208 3854
+lpc178x MACH_LPC178X LPC178X 3855
+farleys MACH_FARLEYS FARLEYS 3856
+efm32gg_dk3750 MACH_EFM32GG_DK3750 EFM32GG_DK3750 3857
+zeus_board MACH_ZEUS_BOARD ZEUS_BOARD 3858
+cc51 MACH_CC51 CC51 3859
+fxi_c210 MACH_FXI_C210 FXI_C210 3860
+msm8627_cdp MACH_MSM8627_CDP MSM8627_CDP 3861
+msm8627_mtp MACH_MSM8627_MTP MSM8627_MTP 3862
+armadillo800eva MACH_ARMADILLO800EVA ARMADILLO800EVA 3863
+primou MACH_PRIMOU PRIMOU 3864
+primoc MACH_PRIMOC PRIMOC 3865
+primoct MACH_PRIMOCT PRIMOCT 3866
+a9500 MACH_A9500 A9500 3867
+pue_td MACH_PULSE_TD PULSE_TD 3868
+pluto MACH_PLUTO PLUTO 3869
+acfx100 MACH_ACFX100 ACFX100 3870
+msm8625_rumi3 MACH_MSM8625_RUMI3 MSM8625_RUMI3 3871
+valente MACH_VALENTE VALENTE 3872
+crfs_rfeye MACH_CRFS_RFEYE CRFS_RFEYE 3873
+rfeye MACH_RFEYE RFEYE 3874
+phidget_sbc3 MACH_PHIDGET_SBC3 PHIDGET_SBC3 3875
+tcw_mika MACH_TCW_MIKA TCW_MIKA 3876
+imx28_egf MACH_IMX28_EGF IMX28_EGF 3877
+valente_wx MACH_VALENTE_WX VALENTE_WX 3878
+huangshans MACH_HUANGSHANS HUANGSHANS 3879
+bosphorus1 MACH_BOSPHORUS1 BOSPHORUS1 3880
+prima MACH_PRIMA PRIMA 3881
+meson3_skt MACH_M3_SKT M3_SKT 3882
+meson3_ref MACH_M3_REF M3_REF 3883
+evita_ulk MACH_EVITA_ULK EVITA_ULK 3884
+merisc600 MACH_MERISC600 MERISC600 3885
+dolak MACH_DOLAK DOLAK 3886
+sbc53 MACH_SBC53 SBC53 3887
+elite_ulk MACH_ELITE_ULK ELITE_ULK 3888
+pov2 MACH_POV2 POV2 3889
+ipod_touch_2g MACH_IPOD_TOUCH_2G IPOD_TOUCH_2G 3890
+da850_pqab MACH_DA850_PQAB DA850_PQAB 3891
diff --git a/arch/blackfin/boards/ipe337/barebox.lds.S b/arch/blackfin/boards/ipe337/barebox.lds.S
index 571eeb1..25ca988 100644
--- a/arch/blackfin/boards/ipe337/barebox.lds.S
+++ b/arch/blackfin/boards/ipe337/barebox.lds.S
@@ -71,6 +71,10 @@ SECTIONS
.barebox_cmd : { BAREBOX_CMDS }
___barebox_cmd_end = .;
+ __barebox_magicvar_start = .;
+ .barebox_magicvar : { BAREBOX_MAGICVARS }
+ __barebox_magicvar_end = .;
+
___barebox_initcalls_start = .;
.barebox_initcalls : { INITCALLS }
___barebox_initcalls_end = .;
diff --git a/arch/blackfin/lib/blackfin_linux.c b/arch/blackfin/lib/blackfin_linux.c
index a20cf55..9da9ec4 100644
--- a/arch/blackfin/lib/blackfin_linux.c
+++ b/arch/blackfin/lib/blackfin_linux.c
@@ -50,9 +50,6 @@ static int do_bootm_linux(struct image_data *idata)
appl = (int (*)(char *))image_get_ep(os_header);
printf("Starting Kernel at 0x%p\n", appl);
- if (relocate_image(os_handle, (void *)image_get_load(os_header)))
- return -1;
-
icache_disable();
strncpy(cmdlinedest, cmdline, 0x1000);
diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c
index d1b39fa..bf5c1b6 100644
--- a/arch/blackfin/lib/board.c
+++ b/arch/blackfin/lib/board.c
@@ -38,7 +38,7 @@
int blackfin_mem_malloc_init(void)
{
mem_malloc_init((void *)(MALLOC_BASE),
- (void *)(MALLOC_BASE + MALLOC_SIZE));
+ (void *)(MALLOC_BASE + MALLOC_SIZE - 1));
return 0;
}
diff --git a/arch/mips/configs/dlink-dir-320_defconfig b/arch/mips/configs/dlink-dir-320_defconfig
index dbce0b9..88c0e83 100644
--- a/arch/mips/configs/dlink-dir-320_defconfig
+++ b/arch/mips/configs/dlink-dir-320_defconfig
@@ -41,7 +41,7 @@ CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/mips/configs/qemu-malta_defconfig b/arch/mips/configs/qemu-malta_defconfig
index b6f53ca..eac21e7 100644
--- a/arch/mips/configs/qemu-malta_defconfig
+++ b/arch/mips/configs/qemu-malta_defconfig
@@ -40,7 +40,7 @@ CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
-CONFIG_CMD_UNLZO=y
+CONFIG_CMD_UNCOMPRESS=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
diff --git a/arch/mips/lib/barebox.lds.S b/arch/mips/lib/barebox.lds.S
index 0c57368..a607284 100644
--- a/arch/mips/lib/barebox.lds.S
+++ b/arch/mips/lib/barebox.lds.S
@@ -56,6 +56,10 @@ SECTIONS
.barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
+ __barebox_magicvar_start = .;
+ .barebox_magicvar : { BAREBOX_MAGICVARS }
+ __barebox_magicvar_end = .;
+
__barebox_initcalls_start = .;
.barebox_initcalls : { INITCALLS }
__barebox_initcalls_end = .;
diff --git a/arch/mips/lib/memory.c b/arch/mips/lib/memory.c
index ad9f6a6..8d2d51b 100644
--- a/arch/mips/lib/memory.c
+++ b/arch/mips/lib/memory.c
@@ -26,7 +26,7 @@
static int mips_mem_malloc_init(void)
{
mem_malloc_init((void *)MALLOC_BASE,
- (void *)(MALLOC_BASE + MALLOC_SIZE));
+ (void *)(MALLOC_BASE + MALLOC_SIZE - 1));
return 0;
}
core_initcall(mips_mem_malloc_init);
diff --git a/arch/nios2/cpu/Makefile b/arch/nios2/cpu/Makefile
index f15c721..0b59ec5 100644
--- a/arch/nios2/cpu/Makefile
+++ b/arch/nios2/cpu/Makefile
@@ -1,6 +1,5 @@
obj-y += start.o
obj-y += exceptions.o
obj-y += cpu.o
-obj-$(CONFIG_USE_IRQ) += interrupts.o
obj-y += traps.o
extra-y += barebox.lds
diff --git a/arch/nios2/cpu/barebox.lds.S b/arch/nios2/cpu/barebox.lds.S
index 2b626fb..934eaf7 100644
--- a/arch/nios2/cpu/barebox.lds.S
+++ b/arch/nios2/cpu/barebox.lds.S
@@ -56,6 +56,10 @@ SECTIONS
.barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
+ __barebox_magicvar_start = .;
+ .barebox_magicvar : { BAREBOX_MAGICVARS }
+ __barebox_magicvar_end = .;
+
__barebox_initcalls_start = .;
.barebox_initcalls : { INITCALLS }
__barebox_initcalls_end = .;
diff --git a/arch/nios2/cpu/cpu.c b/arch/nios2/cpu/cpu.c
index 102b12e..44ddf3c 100644
--- a/arch/nios2/cpu/cpu.c
+++ b/arch/nios2/cpu/cpu.c
@@ -26,9 +26,6 @@
void __noreturn reset_cpu(ulong ignored)
{
-#ifdef CONFIG_USE_IRQ
- disable_interrupts();
-#endif
/* indirect call to go beyond 256MB limitation of toolchain */
nios2_callr(RESET_ADDR);
diff --git a/arch/nios2/cpu/exceptions.S b/arch/nios2/cpu/exceptions.S
index 8e024ce..402e5af 100644
--- a/arch/nios2/cpu/exceptions.S
+++ b/arch/nios2/cpu/exceptions.S
@@ -82,16 +82,7 @@ _exception:
rdctl et, ipending
beq et, r0, 0f
-#ifdef CONFIG_USE_IRQ
-
- /* HARDWARE INTERRUPT: Call interrupt handler */
- movhi r3, %hi(external_interrupt)
- ori r3, r3, %lo(external_interrupt)
- mov r4, sp /* ptr to regs */
- callr r3
-#else
br _exception_return
-#endif
/* Return address fixup: execution resumes by re-issue of
* interrupted instruction at ea-4 (ea == r29). Here we do
diff --git a/arch/nios2/cpu/interrupts.c b/arch/nios2/cpu/interrupts.c
deleted file mode 100644
index f443bfd..0000000
--- a/arch/nios2/cpu/interrupts.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * (C) Copyright 2000-2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * (C) Copyright 2004, Psyent Corporation <www.psyent.com>
- * Scott McNutt <smcnutt@psyent.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
- */
-
-#include <nios2.h>
-#include <asm/nios2-io.h>
-#include <asm/types.h>
-#include <io.h>
-#include <asm/ptrace.h>
-#include <common.h>
-#include <command.h>
-#include <watchdog.h>
-
-/****************************************************************************/
-
-struct irq_action {
- interrupt_handler_t *handler;
- void *arg;
- int count;
-};
-
-static struct irq_action vecs[32];
-
-/****************************************************************************/
-
-int disable_interrupts(void)
-{
- int val = rdctl(CTL_STATUS);
- wrctl(CTL_STATUS, val & ~STATUS_IE);
- return val & STATUS_IE;
-}
-
-void enable_interrupts(void)
-{
- int val = rdctl(CTL_STATUS);
- wrctl(CTL_STATUS, val | STATUS_IE);
-}
-
-void external_interrupt(struct pt_regs *regs)
-{
- unsigned irqs;
- struct irq_action *act;
-
- /* Evaluate only irqs that are both enabled AND pending */
- irqs = rdctl(CTL_IENABLE) & rdctl(CTL_IPENDING);
- act = vecs;
-
- /* Assume (as does the Nios2 HAL) that bit 0 is highest
- * priority. NOTE: There is ALWAYS a handler assigned
- * (the default if no other).
- */
- while (irqs) {
- if (irqs & 1) {
- act->handler(act->arg);
- act->count++;
- }
- irqs >>= 1;
- act++;
- }
-
-}
-
-static void def_hdlr(void *arg)
-{
- unsigned irqs = rdctl(CTL_IENABLE);
-
- /* Disable the individual interrupt -- with gratuitous
- * warning.
- */
- irqs &= ~(1 << (int)arg);
- wrctl(CTL_IENABLE, irqs);
- printf("WARNING: Disabling unhandled interrupt: %d\n",
- (int)arg);
-}
-
-/*************************************************************************/
-void irq_install_handler(int irq, interrupt_handler_t *hdlr, void *arg)
-{
- int flag;
- struct irq_action *act;
- unsigned ena = rdctl(CTL_IENABLE);
-
- if ((irq < 0) || (irq > 31))
- return;
- act = &vecs[irq];
-
- flag = disable_interrupts();
- if (hdlr) {
- act->handler = hdlr;
- act->arg = arg;
- ena |= (1 << irq); /* enable */
- } else {
- act->handler = def_hdlr;
- act->arg = (void *)irq;
- ena &= ~(1 << irq); /* disable */
- }
- wrctl(CTL_IENABLE, ena);
-
- if (flag)
- enable_interrupts();
-}
-
-
-int interrupt_init(void)
-{
- int i;
-
- /* Assign the default handler to all */
- for (i = 0; i < 32; i++) {
- vecs[i].handler = def_hdlr;
- vecs[i].arg = (void *)i;
- vecs[i].count = 0;
- }
-
- enable_interrupts();
- return 0;
-}
-
diff --git a/arch/nios2/include/asm/spi.h b/arch/nios2/include/asm/spi.h
index 4e576b9..6c5740c 100644
--- a/arch/nios2/include/asm/spi.h
+++ b/arch/nios2/include/asm/spi.h
@@ -8,6 +8,7 @@ struct spi_altera_master {
int spi_mode;
int databits;
int speed;
+ int bus_num;
};
struct altera_spi {
diff --git a/arch/nios2/lib/board.c b/arch/nios2/lib/board.c
index 07f045b..ed3af49 100644
--- a/arch/nios2/lib/board.c
+++ b/arch/nios2/lib/board.c
@@ -31,7 +31,7 @@ int altera_mem_malloc_init(void)
{
mem_malloc_init((void *)(NIOS_SOPC_TEXT_BASE - MALLOC_SIZE),
- (void *)(NIOS_SOPC_TEXT_BASE));
+ (void *)(NIOS_SOPC_TEXT_BASE - 1));
return 0;
}
@@ -40,8 +40,5 @@ core_initcall(altera_mem_malloc_init);
void arch_shutdown(void)
{
-#ifdef CONFIG_USE_IRQ
- disable_interrupts();
-#endif
}
diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c
index 34e2bd2..b5b344f 100644
--- a/arch/nios2/lib/bootm.c
+++ b/arch/nios2/lib/bootm.c
@@ -43,13 +43,6 @@ static int do_bootm_linux(struct image_data *idata)
kernel = (void (*)(int, int, int, const char *))ntohl(os_header->ih_ep);
-#ifdef CONFIG_USE_IRQ
- disable_interrupts();
-#endif
-
- if (relocate_image(idata->os, (void *)ntohl(os_header->ih_load)))
- return -1;
-
/* kernel parameters passing
* r4 : NIOS magic
* r5 : initrd start
diff --git a/arch/ppc/boards/pcm030/barebox.lds.S b/arch/ppc/boards/pcm030/barebox.lds.S
index 4aacfc5..7dda039 100644
--- a/arch/ppc/boards/pcm030/barebox.lds.S
+++ b/arch/ppc/boards/pcm030/barebox.lds.S
@@ -102,6 +102,10 @@ SECTIONS
.barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
+ __barebox_magicvar_start = .;
+ .barebox_magicvar : { BAREBOX_MAGICVARS }
+ __barebox_magicvar_end = .;
+
__barebox_initcalls_start = .;
.barebox_initcalls : { INITCALLS }
__barebox_initcalls_end = .;
diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile
index c35fd08..b611ddf 100644
--- a/arch/ppc/lib/Makefile
+++ b/arch/ppc/lib/Makefile
@@ -1,7 +1,6 @@
obj-y += bat_rw.o
obj-y += board.o
obj-y += extable.o
-obj-$(CONFIG_USE_IRQ) += interrupts.o
obj-y += kgdb.o
obj-y += ppcstring.o
obj-y += ticks.o
diff --git a/arch/ppc/lib/board.c b/arch/ppc/lib/board.c
index 82ba458..0e839eb 100644
--- a/arch/ppc/lib/board.c
+++ b/arch/ppc/lib/board.c
@@ -56,20 +56,13 @@ void board_init_r (ulong end_of_ram)
debug("malloc_end: 0x%08x\n", malloc_end);
debug("TEXT_BASE after relocation: 0x%08x\n", _text_base);
- mem_malloc_init((void *)(malloc_end - MALLOC_SIZE), (void *)malloc_end);
+ mem_malloc_init((void *)(malloc_end - MALLOC_SIZE), (void *)(malloc_end - 1));
/*
* Setup trap handlers
*/
trap_init (0);
- /*
- * Enable Interrupts
- */
-#ifdef CONFIG_USE_IRQ
- interrupt_init ();
-#endif
-
/* Initialization complete - start the monitor */
start_barebox();
diff --git a/arch/ppc/lib/interrupts.c b/arch/ppc/lib/interrupts.c
deleted file mode 100644
index 72ddf36..0000000
--- a/arch/ppc/lib/interrupts.c
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * (C) Copyright 2000-2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * (C) Copyright 2003
- * Gleb Natapov <gnatapov@mrv.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
- */
-
-#include <common.h>
-#include <asm/processor.h>
-#include <watchdog.h>
-#ifdef CONFIG_STATUS_LED
-#include <status_led.h>
-#endif
-
-#ifdef CONFIG_SHOW_ACTIVITY
- extern void board_show_activity (ulong);
-#endif /* CONFIG_SHOW_ACTIVITY */
-
-#ifndef CFG_WATCHDOG_FREQ
-#define CFG_WATCHDOG_FREQ (CFG_HZ / 2)
-#endif
-
-extern int interrupt_init_cpu (unsigned *);
-extern void timer_interrupt_cpu (struct pt_regs *);
-
-static unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
-
-static __inline__ unsigned long get_msr (void)
-{
- unsigned long msr;
-
- asm volatile ("mfmsr %0":"=r" (msr):);
-
- return msr;
-}
-
-static __inline__ void set_msr (unsigned long msr)
-{
- asm volatile ("mtmsr %0"::"r" (msr));
-}
-
-static __inline__ unsigned long get_dec (void)
-{
- unsigned long val;
-
- asm volatile ("mfdec %0":"=r" (val):);
-
- return val;
-}
-
-
-static __inline__ void set_dec (unsigned long val)
-{
- if (val)
- asm volatile ("mtdec %0"::"r" (val));
-}
-
-
-void enable_interrupts (void)
-{
- set_msr (get_msr () | MSR_EE);
-}
-
-/* returns flag if MSR_EE was set before */
-int disable_interrupts (void)
-{
- ulong msr = get_msr ();
-
- set_msr (msr & ~MSR_EE);
- return ((msr & MSR_EE) != 0);
-}
-
-int interrupt_init (void)
-{
- int ret;
-
- /* call cpu specific function from $(CPU)/interrupts.c */
- ret = interrupt_init_cpu (&decrementer_count);
-
- if (ret)
- return ret;
-
- set_dec (decrementer_count);
-
- set_msr (get_msr () | MSR_EE);
-
- return (0);
-}
-
-static volatile ulong timestamp = 0;
-
-void timer_interrupt (struct pt_regs *regs)
-{
- /* call cpu specific function from $(CPU)/interrupts.c */
- timer_interrupt_cpu (regs);
-
- /* Restore Decrementer Count */
- set_dec (decrementer_count);
-
- timestamp++;
-
-#if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG)
- if ((timestamp % (CFG_WATCHDOG_FREQ)) == 0)
- WATCHDOG_RESET ();
-#endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */
-
-#ifdef CONFIG_STATUS_LED
- status_led_tick (timestamp);
-#endif /* CONFIG_STATUS_LED */
-
-#ifdef CONFIG_SHOW_ACTIVITY
- board_show_activity (timestamp);
-#endif /* CONFIG_SHOW_ACTIVITY */
-}
diff --git a/arch/ppc/lib/ppclinux.c b/arch/ppc/lib/ppclinux.c
index 531c215..471b303 100644
--- a/arch/ppc/lib/ppclinux.c
+++ b/arch/ppc/lib/ppclinux.c
@@ -200,9 +200,6 @@ static int do_bootm_linux(struct image_data *idata)
kernel = (void (*)(bd_t *, ulong, ulong, ulong, ulong))image_get_ep(os_header); /* FIXME */
- if (relocate_image(idata->os, (void *)image_get_load(os_header)))
- return -1;
-
#if defined(CFG_INIT_RAM_LOCK) && !defined(CONFIG_E500)
unlock_ram_in_cache();
#endif
diff --git a/arch/ppc/mach-mpc5xxx/Makefile b/arch/ppc/mach-mpc5xxx/Makefile
index e07062c..be68c99 100644
--- a/arch/ppc/mach-mpc5xxx/Makefile
+++ b/arch/ppc/mach-mpc5xxx/Makefile
@@ -5,7 +5,6 @@ obj-y += speed.o
obj-y += traps.o
extra-y += start.o
obj-$(CONFIG_MPC5200) += firmware_sc_task_bestcomm.impl.o
-obj-$(CONFIG_USE_IRQ) += interrupts.o
obj-$(CONFIG_REGINFO) += reginfo.o
#obj-y += firmware_sc_task.impl.o
diff --git a/arch/ppc/mach-mpc5xxx/interrupts.c b/arch/ppc/mach-mpc5xxx/interrupts.c
deleted file mode 100644
index 4838bc5..0000000
--- a/arch/ppc/mach-mpc5xxx/interrupts.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * (C) Copyright 2006
- * Detlev Zundel, DENX Software Engineering, dzu@denx.de
- *
- * (C) Copyright -2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * (C) Copyright 2001
- * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
- *
- * 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
- */
-
-/* this section was ripped out of arch/ppc/syslib/mpc52xx_pic.c in the
- * Linux 2.6 source with the following copyright.
- *
- * Based on (well, mostly copied from) the code from the 2.4 kernel by
- * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
- *
- * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
- * Copyright (C) 2003 Montavista Software, Inc
- */
-
-#include <common.h>
-#include <asm/processor.h>
-#include <io.h>
-#include <command.h>
-#include <mach/sdma.h>
-#include <asm/bitops.h>
-#include <mach/clocks.h>
-
-struct irq_action {
- interrupt_handler_t *handler;
- void *arg;
- ulong count;
-};
-
-static struct irq_action irq_handlers[NR_IRQS];
-
-static struct mpc5xxx_intr *intr;
-static struct mpc5xxx_sdma *sdma;
-
-static void mpc5xxx_ic_disable(unsigned int irq)
-{
- u32 val;
-
- if (irq == MPC5XXX_IRQ0) {
- val = in_be32(&intr->ctrl);
- val &= ~(1 << 11);
- out_be32(&intr->ctrl, val);
- } else if (irq < MPC5XXX_IRQ1) {
- BUG();
- } else if (irq <= MPC5XXX_IRQ3) {
- val = in_be32(&intr->ctrl);
- val &= ~(1 << (10 - (irq - MPC5XXX_IRQ1)));
- out_be32(&intr->ctrl, val);
- } else if (irq < MPC5XXX_SDMA_IRQ_BASE) {
- val = in_be32(&intr->main_mask);
- val |= 1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE));
- out_be32(&intr->main_mask, val);
- } else if (irq < MPC5XXX_PERP_IRQ_BASE) {
- val = in_be32(&sdma->IntMask);
- val |= 1 << (irq - MPC5XXX_SDMA_IRQ_BASE);
- out_be32(&sdma->IntMask, val);
- } else {
- val = in_be32(&intr->per_mask);
- val |= 1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE));
- out_be32(&intr->per_mask, val);
- }
-}
-
-static void mpc5xxx_ic_enable(unsigned int irq)
-{
- u32 val;
-
- if (irq == MPC5XXX_IRQ0) {
- val = in_be32(&intr->ctrl);
- val |= 1 << 11;
- out_be32(&intr->ctrl, val);
- } else if (irq < MPC5XXX_IRQ1) {
- BUG();
- } else if (irq <= MPC5XXX_IRQ3) {
- val = in_be32(&intr->ctrl);
- val |= 1 << (10 - (irq - MPC5XXX_IRQ1));
- out_be32(&intr->ctrl, val);
- } else if (irq < MPC5XXX_SDMA_IRQ_BASE) {
- val = in_be32(&intr->main_mask);
- val &= ~(1 << (16 - (irq - MPC5XXX_MAIN_IRQ_BASE)));
- out_be32(&intr->main_mask, val);
- } else if (irq < MPC5XXX_PERP_IRQ_BASE) {
- val = in_be32(&sdma->IntMask);
- val &= ~(1 << (irq - MPC5XXX_SDMA_IRQ_BASE));
- out_be32(&sdma->IntMask, val);
- } else {
- val = in_be32(&intr->per_mask);
- val &= ~(1 << (31 - (irq - MPC5XXX_PERP_IRQ_BASE)));
- out_be32(&intr->per_mask, val);
- }
-}
-
-static void mpc5xxx_ic_ack(unsigned int irq)
-{
- u32 val;
-
- /*
- * Only some irqs are reset here, others in interrupting hardware.
- */
-
- switch (irq) {
- case MPC5XXX_IRQ0:
- val = in_be32(&intr->ctrl);
- val |= 0x08000000;
- out_be32(&intr->ctrl, val);
- break;
- case MPC5XXX_CCS_IRQ:
- val = in_be32(&intr->enc_status);
- val |= 0x00000400;
- out_be32(&intr->enc_status, val);
- break;
- case MPC5XXX_IRQ1:
- val = in_be32(&intr->ctrl);
- val |= 0x04000000;
- out_be32(&intr->ctrl, val);
- break;
- case MPC5XXX_IRQ2:
- val = in_be32(&intr->ctrl);
- val |= 0x02000000;
- out_be32(&intr->ctrl, val);
- break;
- case MPC5XXX_IRQ3:
- val = in_be32(&intr->ctrl);
- val |= 0x01000000;
- out_be32(&intr->ctrl, val);
- break;
- default:
- if (irq >= MPC5XXX_SDMA_IRQ_BASE
- && irq < (MPC5XXX_SDMA_IRQ_BASE + MPC5XXX_SDMA_IRQ_NUM)) {
- out_be32(&sdma->IntPend,
- 1 << (irq - MPC5XXX_SDMA_IRQ_BASE));
- }
- break;
- }
-}
-
-static void mpc5xxx_ic_disable_and_ack(unsigned int irq)
-{
- mpc5xxx_ic_disable(irq);
- mpc5xxx_ic_ack(irq);
-}
-
-static void mpc5xxx_ic_end(unsigned int irq)
-{
- mpc5xxx_ic_enable(irq);
-}
-
-void mpc5xxx_init_irq(void)
-{
- u32 intr_ctrl;
-
- /* Remap the necessary zones */
- intr = (struct mpc5xxx_intr *)(MPC5XXX_ICTL);
- sdma = (struct mpc5xxx_sdma *)(MPC5XXX_SDMA);
-
- /* Disable all interrupt sources. */
- out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */
- out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */
- out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */
- out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */
- intr_ctrl = in_be32(&intr->ctrl);
- intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */
- 0x00ff0000 | /* IRQ 0-3 level sensitive low active */
- 0x00001000 | /* MEE master external enable */
- 0x00000000 | /* 0 means disable IRQ 0-3 */
- 0x00000001; /* CEb route critical normally */
- out_be32(&intr->ctrl, intr_ctrl);
-
- /* Zero a bunch of the priority settings. */
- out_be32(&intr->per_pri1, 0);
- out_be32(&intr->per_pri2, 0);
- out_be32(&intr->per_pri3, 0);
- out_be32(&intr->main_pri1, 0);
- out_be32(&intr->main_pri2, 0);
-}
-
-int mpc5xxx_get_irq(struct pt_regs *regs)
-{
- u32 status;
- int irq = -1;
-
- status = in_be32(&intr->enc_status);
-
- if (status & 0x00000400) { /* critical */
- irq = (status >> 8) & 0x3;
- if (irq == 2) /* high priority peripheral */
- goto peripheral;
- irq += MPC5XXX_CRIT_IRQ_BASE;
- } else if (status & 0x00200000) { /* main */
- irq = (status >> 16) & 0x1f;
- if (irq == 4) /* low priority peripheral */
- goto peripheral;
- irq += MPC5XXX_MAIN_IRQ_BASE;
- } else if (status & 0x20000000) { /* peripheral */
- peripheral:
- irq = (status >> 24) & 0x1f;
- if (irq == 0) { /* bestcomm */
- status = in_be32(&sdma->IntPend);
- irq = ffs(status) + MPC5XXX_SDMA_IRQ_BASE - 1;
- } else
- irq += MPC5XXX_PERP_IRQ_BASE;
- }
-
- return irq;
-}
-
-/****************************************************************************/
-
-int interrupt_init_cpu(ulong * decrementer_count)
-{
- *decrementer_count = get_timebase_clock() / 1000;
-
- mpc5xxx_init_irq();
-
- return 0;
-}
-
-/****************************************************************************/
-
-/*
- * Handle external interrupts
- */
-void external_interrupt(struct pt_regs *regs)
-{
- int irq, unmask = 1;
-
- irq = mpc5xxx_get_irq(regs);
-
- mpc5xxx_ic_disable_and_ack(irq);
-
- enable_interrupts();
-
- if (irq_handlers[irq].handler != NULL)
- (*irq_handlers[irq].handler) (irq_handlers[irq].arg);
- else {
- printf("\nBogus External Interrupt IRQ %d\n", irq);
- /*
- * turn off the bogus interrupt, otherwise it
- * might repeat forever
- */
- unmask = 0;
- }
-
- if (unmask)
- mpc5xxx_ic_end(irq);
-}
-
-void timer_interrupt_cpu(struct pt_regs *regs)
-{
- /* nothing to do here */
- return;
-}
-
-/****************************************************************************/
-
-/*
- * Install and free a interrupt handler.
- */
-
-void irq_install_handler(int irq, interrupt_handler_t * handler, void *arg)
-{
- if (irq < 0 || irq >= NR_IRQS) {
- printf("irq_install_handler: bad irq number %d\n", irq);
- return;
- }
-
- if (irq_handlers[irq].handler != NULL)
- printf("irq_install_handler: 0x%08lx replacing 0x%08lx\n",
- (ulong) handler, (ulong) irq_handlers[irq].handler);
-
- irq_handlers[irq].handler = handler;
- irq_handlers[irq].arg = arg;
-
- mpc5xxx_ic_enable(irq);
-}
-
-void irq_free_handler(int irq)
-{
- if (irq < 0 || irq >= NR_IRQS) {
- printf("irq_free_handler: bad irq number %d\n", irq);
- return;
- }
-
- mpc5xxx_ic_disable(irq);
-
- irq_handlers[irq].handler = NULL;
- irq_handlers[irq].arg = NULL;
-}
-
-/****************************************************************************/
-
-#if (CONFIG_COMMANDS & CFG_CMD_IRQ)
-void do_irqinfo(struct command * cmdtp, bd_t * bd, int flag, int argc, char *argv[])
-{
- int irq, re_enable;
- u32 intr_ctrl;
- char *irq_config[] = { "level sensitive, active high",
- "edge sensitive, rising active edge",
- "edge sensitive, falling active edge",
- "level sensitive, active low"
- };
-
- re_enable = disable_interrupts();
-
- intr_ctrl = in_be32(&intr->ctrl);
- printf("Interrupt configuration:\n");
-
- for (irq = 0; irq <= 3; irq++) {
- printf("IRQ%d: %s\n", irq,
- irq_config[(intr_ctrl >> (22 - 2 * irq)) & 0x3]);
- }
-
- puts("\nInterrupt-Information:\n" "Nr Routine Arg Count\n");
-
- for (irq = 0; irq < NR_IRQS; irq++)
- if (irq_handlers[irq].handler != NULL)
- printf("%02d %08lx %08lx %ld\n", irq,
- (ulong) irq_handlers[irq].handler,
- (ulong) irq_handlers[irq].arg,
- irq_handlers[irq].count);
-
- if (re_enable)
- enable_interrupts();
-}
-#endif
diff --git a/arch/ppc/mach-mpc5xxx/start.S b/arch/ppc/mach-mpc5xxx/start.S
index dc53c8a..7a4c16b 100644
--- a/arch/ppc/mach-mpc5xxx/start.S
+++ b/arch/ppc/mach-mpc5xxx/start.S
@@ -140,11 +140,6 @@ _start_of_vectors:
/* Instruction Storage exception. */
STD_EXCEPTION(0x400, InstStorage, UnknownException)
-/* External Interrupt exception. */
-#ifdef CONFIG_USE_IRQ
- STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
-#endif
-
/* Alignment exception. */
. = 0x600
Alignment:
@@ -184,11 +179,7 @@ ProgramCheck:
/* I guess we could implement decrementer, and may have
* to someday for timekeeping.
*/
-#ifdef CONFIG_USE_IRQ
- STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
-#else
STD_EXCEPTION(0x900, Decrementer, UnknownException)
-#endif
STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
STD_EXCEPTION(0xc00, SystemCall, UnknownException)
diff --git a/arch/sandbox/Makefile b/arch/sandbox/Makefile
index b88f1f6..9fd18a2 100644
--- a/arch/sandbox/Makefile
+++ b/arch/sandbox/Makefile
@@ -36,19 +36,6 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-e s/s390x/s390/ -e s/parisc64/parisc/ \
-e s/ppc.*/powerpc/ -e s/mips.*/mips/ )
-ifeq ($(SUBARCH),x86_64)
-ELF_CLASS := ELFCLASS64
-endif
-ifeq ($(SUBARCH),i386)
-ELF_CLASS := ELFCLASS32
-endif
-ifeq ($(SUBARCH),powerpc)
-ELF_CLASS := ELFCLASS32
-endif
-
-CPPFLAGS += -DELF_CLASS="$(ELF_CLASS)"
-export ELF_CLASS
-
archprepare: maketools
PHONY += maketools
diff --git a/arch/sandbox/board/barebox.lds.S b/arch/sandbox/board/barebox.lds.S
index 76975ee..db5b7de 100644
--- a/arch/sandbox/board/barebox.lds.S
+++ b/arch/sandbox/board/barebox.lds.S
@@ -8,6 +8,11 @@ SECTIONS
__barebox_initcalls_end = .;
. = ALIGN(64);
+ __barebox_magicvar_start = .;
+ .barebox_magicvar : { BAREBOX_MAGICVARS }
+ __barebox_magicvar_end = .;
+
+ . = ALIGN(64);
__barebox_cmd_start = .;
__barebox_cmd : { BAREBOX_CMDS }
__barebox_cmd_end = .;
diff --git a/arch/sandbox/include/asm/elf.h b/arch/sandbox/include/asm/elf.h
index b60d248..3939336 100644
--- a/arch/sandbox/include/asm/elf.h
+++ b/arch/sandbox/include/asm/elf.h
@@ -1,2 +1,11 @@
+#ifndef __ASM_SANDBOX_ELF_H__
+#define __ASM_SANDBOX_ELF_H__
-/* nothing yet */
+#if __SIZEOF_POINTER__ == 8
+#define ELF_CLASS ELFCLASS64
+#define CONFIG_PHYS_ADDR_T_64BIT
+#else
+#define ELF_CLASS ELFCLASS32
+#endif
+
+#endif /* __ASM_SANDBOX_ELF_H__ */
diff --git a/arch/sandbox/mach-sandbox/include/mach/linux.h b/arch/sandbox/mach-sandbox/include/mach/linux.h
index 7c2386d..5917fe9 100644
--- a/arch/sandbox/mach-sandbox/include/mach/linux.h
+++ b/arch/sandbox/mach-sandbox/include/mach/linux.h
@@ -10,6 +10,8 @@ ssize_t linux_write(int fd, const void *buf, size_t count);
off_t linux_lseek(int fildes, off_t offset);
int linux_tstc(int fd);
+int linux_execve(const char * filename, char *const argv[], char *const envp[]);
+
int barebox_register_console(char *name_template, int stdinfd, int stdoutfd);
struct linux_console_data {
diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c
index 5074a06..92b7dbb 100644
--- a/arch/sandbox/os/common.c
+++ b/arch/sandbox/os/common.c
@@ -45,6 +45,7 @@
#include <errno.h>
#include <signal.h>
#include <sys/select.h>
+#include <sys/wait.h>
/*
* ...except the ones needed to connect with barebox
*/
@@ -124,14 +125,6 @@ void __attribute__((noreturn)) reset_cpu(unsigned long addr)
exit(0);
}
-void enable_interrupts(void)
-{
-}
-
-void disable_interrupt(void)
-{
-}
-
int linux_read(int fd, void *buf, size_t count)
{
ssize_t ret;
@@ -193,6 +186,27 @@ off_t linux_lseek(int fd, off_t offset)
return lseek(fd, offset, SEEK_SET);
}
+int linux_execve(const char * filename, char *const argv[], char *const envp[])
+{
+ pid_t pid, tpid;
+ int execve_status;
+
+ pid = fork();
+
+ if (pid == -1) {
+ perror("linux_execve");
+ return pid;
+ } else if (pid == 0) {
+ exit(execve(filename, argv, envp));
+ } else {
+ do {
+ tpid = wait(&execve_status);
+ } while(tpid != pid);
+
+ return execve_status;
+ }
+}
+
extern void start_barebox(void);
extern void mem_malloc_init(void *start, void *end);
@@ -270,7 +284,7 @@ int main(int argc, char *argv[])
printf("unable to get malloc space\n");
exit(1);
}
- mem_malloc_init(ram, ram + malloc_size);
+ mem_malloc_init(ram, ram + malloc_size - 1);
while (1) {
int option_index = 0;
diff --git a/arch/x86/lib/barebox.lds.S b/arch/x86/lib/barebox.lds.S
index fffc3a5..716cea6 100644
--- a/arch/x86/lib/barebox.lds.S
+++ b/arch/x86/lib/barebox.lds.S
@@ -170,7 +170,14 @@ SECTIONS
. = ALIGN(4);
} > barebox
- .barebox_initcalls : AT ( LOADADDR(.barebox_cmd) + SIZEOF (.barebox_cmd) ) {
+ .barebox_magicvars : AT ( LOADADDR(.barebox_cmd) + SIZEOF (.barebox_cmd) ) {
+ __barebox_magicvar_start = .;
+ .barebox_magicvar : { BAREBOX_MAGICVARS }
+ __barebox_magicvar_end = .;
+ . = ALIGN(4);
+ } > barebox
+
+ .barebox_initcalls : AT ( LOADADDR(.barebox_magicvars) + SIZEOF (.barebox_magicvars) ) {
__barebox_initcalls_start = .;
INITCALLS
__barebox_initcalls_end = .;
diff --git a/arch/x86/lib/memory.c b/arch/x86/lib/memory.c
index fa7bc03..1774ef3 100644
--- a/arch/x86/lib/memory.c
+++ b/arch/x86/lib/memory.c
@@ -54,12 +54,12 @@ static int x86_mem_malloc_init(void)
*/
if (memory_size >= (15 * 1024 * 1024 + MALLOC_SIZE))
mem_malloc_init((void*)(16 * 1024 * 1024),
- (void*)(16 * 1024 * 1024) + MALLOC_SIZE);
+ (void*)(16 * 1024 * 1024 + MALLOC_SIZE - 1));
else
return -1;
#else
mem_malloc_init((void *)MALLOC_BASE,
- (void *)(MALLOC_BASE + MALLOC_SIZE));
+ (void *)(MALLOC_BASE + MALLOC_SIZE - 1));
#endif
return 0;
}
diff --git a/commands/Kconfig b/commands/Kconfig
index 18ab840..ebc9c7f 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -107,6 +107,12 @@ config CMD_TIME
checking for ctrl-c, so the time command can be used with commands
which are interruptible with ctrl-c.
+config CMD_LINUX_EXEC
+ bool "linux exec"
+ depends on LINUX
+ help
+ This command executes a command on the Linux host.
+
endmenu
menu "file commands "
@@ -215,6 +221,13 @@ config CMD_MEMINFO
tristate
prompt "meminfo"
+config CMD_IOMEM
+ tristate
+ prompt "iomem"
+ help
+ Show information about iomem usage. Pendant to 'cat /proc/iomem'
+ under Linux.
+
config CMD_MEMORY
bool
default y
@@ -292,23 +305,17 @@ config CMD_BOOTM
select CRC32
prompt "bootm"
-config CMD_BOOTM_ZLIB
- bool
- depends on CMD_BOOTM
- select ZLIB
- prompt "bootm with zlib support"
-
-config CMD_BOOTM_BZLIB
- bool
- depends on CMD_BOOTM
- select BZLIB
- prompt "bootm with bzlib support"
-
config CMD_BOOTM_SHOW_TYPE
bool
depends on CMD_BOOTM
prompt "show image information"
+config CMD_IMINFO
+ bool
+ prompt "iminfo"
+ help
+ Show information about uImages
+
config CMD_BOOTZ
tristate
default y
@@ -383,6 +390,20 @@ config CMD_HELP
default y
prompt "help"
+config CMD_MAGICVAR
+ tristate
+ prompt "magicvar"
+ help
+ barebox has some shell variables with special meanings. This
+ command shows the available magic variables.
+
+config CMD_MAGICVAR_HELP
+ bool
+ prompt "display description"
+ depends on CMD_MAGICVAR
+ help
+ Also display a description to the magic variables
+
config CMD_DEVINFO
tristate
default y
@@ -414,13 +435,13 @@ config CMD_GPIO
include gpio_set_value, gpio_get_value, gpio_direction_input and
gpio_direction_output commands to control gpios.
-config CMD_UNLZO
+config CMD_UNCOMPRESS
bool
- select LZO_DECOMPRESS
- prompt "unlzo"
+ prompt "uncompress"
help
- Say yes here to get the unlzo command. lzo is a fast compression
- algorithm by Markus Franz Xaver Johannes Oberhumer.
+ Say yes here to get the uncompress command. uncompress handles
+ lzo, gzip and bzip2 compressed files depending on the compiled
+ in compression libraries
config CMD_I2C
bool
diff --git a/commands/Makefile b/commands/Makefile
index 5c51916..aa013de 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_CMD_IMINFO) += iminfo.o
obj-$(CONFIG_CMD_LINUX16) += linux16.o
obj-$(CONFIG_CMD_LOADB) += loadb.o xyzModem.o
obj-$(CONFIG_CMD_LOADY) += loadb.o xyzModem.o
@@ -47,7 +48,7 @@ obj-$(CONFIG_CMD_INSMOD) += insmod.o
obj-$(CONFIG_CMD_BMP) += bmp.o
obj-$(CONFIG_USB_GADGET_DFU) += dfu.o
obj-$(CONFIG_CMD_GPIO) += gpio.o
-obj-$(CONFIG_CMD_UNLZO) += unlzo.o
+obj-$(CONFIG_CMD_UNCOMPRESS) += uncompress.o
obj-$(CONFIG_CMD_I2C) += i2c.o
obj-$(CONFIG_CMD_UBI) += ubi.o
obj-$(CONFIG_CMD_MENU) += menu.o
@@ -58,3 +59,6 @@ obj-$(CONFIG_CMD_LED_TRIGGER) += trigger.o
obj-$(CONFIG_CMD_USB) += usb.o
obj-$(CONFIG_CMD_TIME) += time.o
obj-$(CONFIG_CMD_OFTREE) += oftree.o
+obj-$(CONFIG_CMD_MAGICVAR) += magicvar.o
+obj-$(CONFIG_CMD_IOMEM) += iomem.o
+obj-$(CONFIG_CMD_LINUX_EXEC) += linux_exec.o
diff --git a/commands/bootm.c b/commands/bootm.c
index f11138a..859ec28 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -30,8 +30,6 @@
#include <command.h>
#include <image.h>
#include <malloc.h>
-#include <zlib.h>
-#include <bzlib.h>
#include <environment.h>
#include <asm/byteorder.h>
#include <xfuncs.h>
@@ -42,59 +40,10 @@
#include <boot.h>
#include <rtc.h>
#include <init.h>
+#include <magicvar.h>
+#include <uncompress.h>
#include <asm-generic/memory_layout.h>
-/*
- * Continue booting an OS image; caller already has:
- * - copied image header to global variable `header'
- * - checked header magic number, checksums (both header & image),
- * - verified image architecture (PPC) and type (KERNEL or MULTI),
- * - loaded (first part of) image to header load address,
- * - disabled interrupts.
- */
-typedef void boot_os_Fcn(struct command *cmdtp, int flag,
- int argc, char *argv[],
- ulong addr, /* of image to boot */
- ulong *len_ptr, /* multi-file image length table */
- int verify); /* getenv("verify")[0] != 'n' */
-
-#ifndef CFG_BOOTM_LEN
-#define CFG_BOOTM_LEN 0x800000 /* use 8MByte as default max gunzip size */
-#endif
-
-#ifdef CONFIG_SILENT_CONSOLE
-static void
-fixup_silent_linux ()
-{
- char buf[256], *start, *end;
- char *cmdline = getenv ("bootargs");
-
- /* Only fix cmdline when requested */
- if (!(gd->flags & GD_FLG_SILENT))
- return;
-
- debug ("before silent fix-up: %s\n", cmdline);
- if (cmdline) {
- if ((start = strstr (cmdline, "console=")) != NULL) {
- end = strchr (start, ' ');
- strncpy (buf, cmdline, (start - cmdline + 8));
- if (end)
- strcpy (buf + (start - cmdline + 8), end);
- else
- buf[start - cmdline + 8] = '\0';
- } else {
- strcpy (buf, cmdline);
- strcat (buf, " console=");
- }
- } else {
- strcpy (buf, "console=");
- }
-
- setenv ("bootargs", buf);
- debug ("after silent fix-up: %s\n", buf);
-}
-#endif /* CONFIG_SILENT_CONSOLE */
-
struct image_handle_data* image_handle_data_get_by_num(struct image_handle* handle, int num)
{
if (!handle || num < 0 || num >= handle->nb_data_entries)
@@ -108,50 +57,27 @@ int relocate_image(struct image_handle *handle, void *load_address)
image_header_t *hdr = &handle->header;
unsigned long len = image_get_size(hdr);
struct image_handle_data *iha;
- unsigned long data;
-
-#if defined CONFIG_CMD_BOOTM_ZLIB || defined CONFIG_CMD_BOOTM_BZLIB
- uint unc_len = CFG_BOOTM_LEN;
-#endif
+ void *data;
+ int ret;
iha = image_handle_data_get_by_num(handle, 0);
- data = (unsigned long)(iha->data);
+ data = iha->data;
switch (image_get_comp(hdr)) {
case IH_COMP_NONE:
- if(image_get_load(hdr) == data) {
+ if (load_address == data) {
printf (" XIP ... ");
} else {
- memmove ((void *) image_get_load(hdr), (uchar *)data, len);
+ memmove(load_address, data, len);
}
break;
-#ifdef CONFIG_CMD_BOOTM_ZLIB
- case IH_COMP_GZIP:
- printf (" Uncompressing ... ");
- if (gunzip (load_address, unc_len,
- (uchar *)data, &len) != 0)
- return -1;
- break;
-#endif
-#ifdef CONFIG_CMD_BOOTM_BZLIB
- case IH_COMP_BZIP2:
+ default:
printf (" Uncompressing ... ");
- /*
- * If we've got less than 4 MB of malloc() space,
- * use slower decompression algorithm which requires
- * at most 2300 KB of memory.
- */
- if (BZ2_bzBuffToBuffDecompress (load_address,
- &unc_len, (char *)data, len,
- MALLOC_SIZE < (4096 * 1024), 0)
- != BZ_OK)
- return -1;
+ ret = uncompress(data, len, NULL, NULL, load_address, NULL,
+ uncompress_err_stdout);
+ if (ret)
+ return ret;
break;
-#endif
- default:
- printf("Unimplemented compression type %d\n",
- image_get_comp(hdr));
- return -1;
}
return 0;
@@ -168,7 +94,7 @@ int register_image_handler(struct image_handler *handler)
/*
* generate a image_handle from a multi_image
- * this image_handle can be free by unmap_image
+ * this image_handle can be freed by unmap_image
*/
static struct image_handle *get_fake_image_handle(struct image_data *data, int num)
{
@@ -188,118 +114,53 @@ static struct image_handle *get_fake_image_handle(struct image_data *data, int n
return handle;
}
-static int initrd_handler_parse_options(struct image_data *data, int opt,
- char *optarg)
-{
- uint32_t initrd_start;
-
- switch(opt) {
- case 'L':
- if (!data->initrd) {
- eprintf("Warning -L ingnored. Specify the initrd first\n");
- break;
- }
- initrd_start = simple_strtoul(optarg, NULL, 0);
- printf("initrd_start=0x%x\n", initrd_start);
- data->initrd->header.ih_load = cpu_to_uimage(initrd_start);
- break;
- case 'r':
- printf("use initrd %s\n", optarg);
- /* check for multi image @<num> */
- if (optarg[0] == '@') {
- int num = simple_strtol(optarg + 1, NULL, 0);
-
- data->initrd = get_fake_image_handle(data, num);
- } else {
- data->initrd = map_image(optarg, data->verify);
- }
- if (!data->initrd)
- return -1;
- break;
- default:
- return 1;
- }
-
- return 0;
-}
-
-static struct image_handler initrd_handler = {
- .cmdline_options = "r:L:",
- .cmdline_parse = initrd_handler_parse_options,
- .help_string = " -r <initrd> specify an initrd image\n"
- " -L <load addr> specify initrd load address",
-};
-
-static int initrd_register_image_handler(void)
-{
- return register_image_handler(&initrd_handler);
-}
-
-late_initcall(initrd_register_image_handler);
-
-static int handler_parse_options(struct image_data *data, int opt, char *optarg)
-{
- struct image_handler *handler;
- int ret;
-
- list_for_each_entry(handler, &handler_list, list) {
- if (!handler->cmdline_parse)
- continue;
-
- ret = handler->cmdline_parse(data, opt, optarg);
- if (ret > 0)
- continue;
-
- return ret;
- }
-
- return -1;
-}
-
static int do_bootm(struct command *cmdtp, int argc, char *argv[])
{
int opt;
image_header_t *os_header;
- struct image_handle *os_handle, *initrd_handle = NULL;
+ struct image_handle *os_handle = NULL;
struct image_handler *handler;
struct image_data data;
- char options[53]; /* worst case: whole alphabet with colons */
+ int ret = 1;
memset(&data, 0, sizeof(struct image_data));
data.verify = 1;
+ data.initrd_address = ~0;
- /* Collect options from registered handlers */
- strcpy(options, "nh");
- list_for_each_entry(handler, &handler_list, list) {
- if (handler->cmdline_options)
- strcat(options, handler->cmdline_options);
- }
-
- while((opt = getopt(argc, argv, options)) > 0) {
+ while ((opt = getopt(argc, argv, "nr:L:")) > 0) {
switch(opt) {
case 'n':
data.verify = 0;
break;
- case 'h':
- printf("bootm advanced options:\n");
-
- list_for_each_entry(handler, &handler_list, list) {
- if (handler->help_string)
- printf("%s\n", handler->help_string);
+ case 'L':
+ data.initrd_address = simple_strtoul(optarg, NULL, 0);
+ break;
+ case 'r':
+ printf("use initrd %s\n", optarg);
+ /* check for multi image @<num> */
+ if (optarg[0] == '@') {
+ int num = simple_strtol(optarg + 1, NULL, 0);
+
+ data.initrd = get_fake_image_handle(&data, num);
+ } else {
+ data.initrd = map_image(optarg, data.verify);
}
-
- return 0;
+ if (!data.initrd)
+ goto err_out;
+ break;
default:
break;
}
}
- if (optind == argc)
- return COMMAND_ERROR_USAGE;
+ if (optind == argc) {
+ ret = COMMAND_ERROR_USAGE;
+ goto err_out;
+ }
os_handle = map_image(argv[optind], data.verify);
if (!os_handle)
- return 1;
+ goto err_out;
data.os = os_handle;
os_header = &os_handle->header;
@@ -310,31 +171,35 @@ static int do_bootm(struct command *cmdtp, int argc, char *argv[])
goto err_out;
}
- optind = 0;
-
- while((opt = getopt(argc, argv, options)) > 0) {
- switch(opt) {
- case 'h':
- case 'n':
- break;
- default:
- if (!handler_parse_options(&data, opt, optarg))
- continue;
-
- return 1;
- }
- }
-
/*
* We have reached the point of no return: we are going to
* overwrite all exception vector code, so we cannot easily
* recover from any failures any more...
*/
- disable_interrupts();
-
puts ("OK\n");
+ /*
+ * FIXME: we do not check at all whether
+ * - we will write the image to sdram
+ * - we overwrite ourselves
+ * - kernel and initrd overlap
+ */
+ ret = relocate_image(data.os, (void *)image_get_load(os_header));
+ if (ret)
+ goto err_out;
+
+ if (data.initrd) {
+ if (data.initrd && data.initrd_address == ~0)
+ data.initrd_address = uimage_to_cpu(data.initrd->header.ih_load);
+
+ data.initrd_size = image_get_data_size(&data.initrd->header);
+
+ ret = relocate_image(data.initrd, (void *)data.initrd_address);
+ if (ret)
+ goto err_out;
+ }
+
/* loop through the registered handlers */
list_for_each_entry(handler, &handler_list, list) {
if (image_get_os(os_header) == handler->image_type) {
@@ -350,15 +215,17 @@ static int do_bootm(struct command *cmdtp, int argc, char *argv[])
err_out:
if (os_handle)
unmap_image(os_handle);
- if (initrd_handle)
- unmap_image(initrd_handle);
- return 1;
+ if (data.initrd)
+ unmap_image(data.initrd);
+ return ret;
}
BAREBOX_CMD_HELP_START(bootm)
-BAREBOX_CMD_HELP_USAGE("bootm [-n] image\n")
+BAREBOX_CMD_HELP_USAGE("bootm [OPTIONS] image\n")
BAREBOX_CMD_HELP_SHORT("Boot an application image.\n")
BAREBOX_CMD_HELP_OPT ("-n", "Do not verify the image (speeds up boot process)\n")
+BAREBOX_CMD_HELP_OPT ("-r <initrd>","specify an initrd image\n")
+BAREBOX_CMD_HELP_OPT ("-L <load addr>","specify initrd load address")
BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(bootm)
@@ -367,84 +234,7 @@ BAREBOX_CMD_START(bootm)
BAREBOX_CMD_HELP(cmd_bootm_help)
BAREBOX_CMD_END
-/**
- * @page bootm_command
-
-\todo What does bootm do, what kind of image does it boot?
-
- */
-
-#ifdef CONFIG_CMD_IMI
-static int do_iminfo(struct command *cmdtp, int argc, char *argv[])
-{
- int arg;
- ulong addr;
- int rcode=0;
-
- if (argc < 2) {
- return image_info (load_addr);
- }
-
- for (arg=1; arg <argc; ++arg) {
- addr = simple_strtoul(argv[arg], NULL, 16);
- if (image_info (addr) != 0) rcode = 1;
- }
- return rcode;
-}
-
-static int image_info (ulong addr)
-{
- ulong data, len, checksum;
- image_header_t *hdr = &header;
-
- printf ("\n## Checking Image at %08lx ...\n", addr);
-
- /* Copy header so we can blank CRC field for re-calculation */
- memmove (&header, (char *)addr, image_get_header_size());
-
- if (image_get_magic(hdr) != IH_MAGIC) {
- puts (" Bad Magic Number\n");
- return 1;
- }
-
- data = (ulong)&header;
- len = image_get_header_size();
-
- checksum = image_get_hcrc(hdr);
- hdr->ih_hcrc = 0;
-
- if (crc32 (0, (uchar *)data, len) != checksum) {
- puts (" Bad Header Checksum\n");
- return 1;
- }
-
- /* for multi-file images we need the data part, too */
- print_image_hdr ((image_header_t *)addr);
-
- data = addr + image_get_header_size();
- len = image_get_size(hdr);
-
- puts (" Verifying Checksum ... ");
- if (crc32 (0, (uchar *)data, len) != image_get_dcrc(hdr)) {
- puts (" Bad Data CRC\n");
- return 1;
- }
- puts ("OK\n");
- return 0;
-}
-
-BAREBOX_CMD_HELP_START(iminfo)
-BAREBOX_CMD_HELP_USAGE("iminfo\n")
-BAREBOX_CMD_HELP_SHORT("Print header information for an application image.\n")
-BAREBOX_CMD_HELP_END
-
-BAREBOX_CMD_START(iminfo)
- .cmd = do_iminfo,
- .usage = "print header information for an application image",
- BAREBOX_CMD_HELP(cmd_iminfo_help)
-BAREBOX_CMD_END
-
-#endif /* CONFIG_CMD_IMI */
+BAREBOX_MAGICVAR(bootargs, "Linux Kernel parameters");
#ifdef CONFIG_BZLIB
void bz_internal_error(int errcode)
diff --git a/commands/cp.c b/commands/cp.c
index 3428105..f78e3de 100644
--- a/commands/cp.c
+++ b/commands/cp.c
@@ -32,6 +32,7 @@
#include <fs.h>
#include <malloc.h>
#include <libgen.h>
+#include <getopt.h>
/**
* @param[in] cmdtp FIXME
@@ -44,8 +45,21 @@ static int do_cp(struct command *cmdtp, int argc, char *argv[])
struct stat statbuf;
int last_is_dir = 0;
int i;
+ int opt;
+ int verbose = 0;
+ int argc_min;
- if (argc < 3)
+ while ((opt = getopt(argc, argv, "v")) > 0) {
+ switch (opt) {
+ case 'v':
+ verbose = 1;
+ break;
+ }
+ }
+
+ argc_min = optind + 2;
+
+ if (argc < argc_min)
return COMMAND_ERROR_USAGE;
if (!stat(argv[argc - 1], &statbuf)) {
@@ -53,21 +67,21 @@ static int do_cp(struct command *cmdtp, int argc, char *argv[])
last_is_dir = 1;
}
- if (argc > 3 && !last_is_dir) {
+ if (argc > argc_min && !last_is_dir) {
printf("cp: target `%s' is not a directory\n", argv[argc - 1]);
return 1;
}
- for (i = 1; i < argc - 1; i++) {
+ for (i = optind; i < argc - 1; i++) {
if (last_is_dir) {
char *dst;
dst = concat_path_file(argv[argc - 1], basename(argv[i]));
- ret = copy_file(argv[i], dst);
+ ret = copy_file(argv[i], dst, verbose);
if (ret)
goto out;
free(dst);
} else {
- ret = copy_file(argv[i], argv[argc - 1]);
+ ret = copy_file(argv[i], argv[argc - 1], verbose);
if (ret)
goto out;
}
@@ -79,7 +93,7 @@ out:
}
BAREBOX_CMD_HELP_START(cp)
-BAREBOX_CMD_HELP_USAGE("cp <source> <destination>\n")
+BAREBOX_CMD_HELP_USAGE("cp [-v] <source> <destination>\n")
BAREBOX_CMD_HELP_SHORT("copy file from <source> to <destination>.\n")
BAREBOX_CMD_HELP_END
diff --git a/commands/iminfo.c b/commands/iminfo.c
new file mode 100644
index 0000000..2fde9bc
--- /dev/null
+++ b/commands/iminfo.c
@@ -0,0 +1,71 @@
+#include <common.h>
+#include <command.h>
+#include <image.h>
+#include <fs.h>
+#include <malloc.h>
+#include <fcntl.h>
+#include <errno.h>
+
+static int image_info(image_header_t *hdr)
+{
+ u32 len, checksum;
+
+ if (image_get_magic(hdr) != IH_MAGIC) {
+ puts (" Bad Magic Number\n");
+ return 1;
+ }
+
+ len = image_get_header_size();
+
+ checksum = image_get_hcrc(hdr);
+ hdr->ih_hcrc = 0;
+
+ if (crc32 (0, hdr, len) != checksum) {
+ puts (" Bad Header Checksum\n");
+ return 1;
+ }
+
+ image_print_contents(hdr, NULL);
+
+ return 0;
+}
+
+static int do_iminfo(struct command *cmdtp, int argc, char *argv[])
+{
+ int rcode = 1;
+ int fd;
+ int ret;
+ image_header_t hdr;
+
+ if (argc != 2)
+ return COMMAND_ERROR_USAGE;
+
+ fd = open(argv[1], O_RDONLY);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+
+ ret = read(fd, &hdr, sizeof(image_header_t));
+ if (ret != sizeof(image_header_t))
+ goto err_out;
+
+ printf("Image at %s:\n", argv[1]);
+ image_info(&hdr);
+
+err_out:
+ close(fd);
+
+ return rcode;
+}
+
+BAREBOX_CMD_HELP_START(iminfo)
+BAREBOX_CMD_HELP_USAGE("iminfo\n")
+BAREBOX_CMD_HELP_SHORT("Print header information for an application image.\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(iminfo)
+ .cmd = do_iminfo,
+ .usage = "print header information for an application image",
+ BAREBOX_CMD_HELP(cmd_iminfo_help)
+BAREBOX_CMD_END
diff --git a/commands/iomem.c b/commands/iomem.c
new file mode 100644
index 0000000..78566c1
--- /dev/null
+++ b/commands/iomem.c
@@ -0,0 +1,56 @@
+/*
+ * iomem.c - barebox iomem command
+ *
+ * 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.
+ */
+#include <common.h>
+#include <command.h>
+
+static void __print_resources(struct resource *res, int indent)
+{
+ struct resource *r;
+ int i;
+
+ for (i = 0; i < indent; i++)
+ printf(" ");
+
+ printf("0x%08x - 0x%08x (size 0x%08x) %s\n", res->start,
+ res->start + res->size - 1,
+ res->size, res->name);
+
+ list_for_each_entry(r, &res->children, sibling)
+ __print_resources(r, indent + 1);
+}
+
+static void print_resources(struct resource *res)
+{
+ __print_resources(res, 0);
+}
+
+static int do_iomem(struct command *cmdtp, int argc, char *argv[])
+{
+ print_resources(&iomem_resource);
+
+ return 0;
+}
+
+BAREBOX_CMD_START(iomem)
+ .cmd = do_iomem,
+ .usage = "show iomem usage",
+BAREBOX_CMD_END
diff --git a/commands/magicvar.c b/commands/magicvar.c
new file mode 100644
index 0000000..31606d2
--- /dev/null
+++ b/commands/magicvar.c
@@ -0,0 +1,20 @@
+#include <common.h>
+#include <command.h>
+#include <magicvar.h>
+
+static int do_magicvar(struct command *cmdtp, int argc, char *argv[])
+{
+ struct magicvar *m;
+
+ for (m = &__barebox_magicvar_start;
+ m != &__barebox_magicvar_end;
+ m++)
+ printf("%-32s %s\n", m->name, m->description);
+
+ return 0;
+}
+
+BAREBOX_CMD_START(magicvar)
+ .cmd = do_magicvar,
+ .usage = "List information about magic variables",
+BAREBOX_CMD_END
diff --git a/commands/unlzo.c b/commands/uncompress.c
index 0b6dd4b..fff6227 100644
--- a/commands/unlzo.c
+++ b/commands/uncompress.c
@@ -1,5 +1,5 @@
/*
- * unlzo.c - uncompress a lzo compressed file
+ * uncompress.c - uncompress a lzo compressed file
*
* Copyright (c) 2010 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
*
@@ -25,11 +25,11 @@
#include <errno.h>
#include <fcntl.h>
#include <fs.h>
-#include <lzo.h>
+#include <uncompress.h>
-static int do_unlzo(struct command *cmdtp, int argc, char *argv[])
+static int do_uncompress(struct command *cmdtp, int argc, char *argv[])
{
- int from, to, ret, retlen;
+ int from, to, ret;
if (argc != 3)
return COMMAND_ERROR_USAGE;
@@ -47,7 +47,8 @@ static int do_unlzo(struct command *cmdtp, int argc, char *argv[])
goto exit_close;
}
- ret = unlzo(from, to, &retlen);
+ ret = uncompress_fd_to_fd(from, to, uncompress_err_stdout);
+
if (ret)
printf("failed to decompress\n");
@@ -57,13 +58,13 @@ exit_close:
return ret;
}
-static const __maybe_unused char cmd_unlzo_help[] =
-"Usage: unlzo <infile> <outfile>\n"
-"Uncompress a lzo compressed file\n";
+static const __maybe_unused char cmd_uncompress_help[] =
+"Usage: uncompress <infile> <outfile>\n"
+"Uncompress a compressed file\n";
-BAREBOX_CMD_START(unlzo)
- .cmd = do_unlzo,
+BAREBOX_CMD_START(uncompress)
+ .cmd = do_uncompress,
.usage = "lzop <infile> <outfile>",
- BAREBOX_CMD_HELP(cmd_unlzo_help)
+ BAREBOX_CMD_HELP(cmd_uncompress_help)
BAREBOX_CMD_END
diff --git a/common/Kconfig b/common/Kconfig
index 8e96920..1318e7d 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -406,6 +406,24 @@ config PARTITION
bool
prompt "Enable Partitions"
+if PARTITION
+
+config PARTITION_DISK
+ bool "DISK partition support"
+ help
+ Add support for handling common partition tables on all kind of disk
+ like devices (harddisks, CF cards, SD cards and so on)
+
+if PARTITION_DISK
+
+config PARTITION_DISK_DOS
+ bool "DOS partition support"
+ help
+ Add support to handle partitions in DOS style.
+
+endif
+endif
+
config DEFAULT_ENVIRONMENT
bool
default y
diff --git a/common/Makefile b/common/Makefile
index 7bb8ea4..9bce479 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -7,6 +7,8 @@ obj-$(CONFIG_ENV_HANDLING) += environment.o
obj-$(CONFIG_AUTO_COMPLETE) += complete.o
obj-$(CONFIG_POLLER) += poller.o
obj-$(CONFIG_BLOCK) += block.o
+obj-$(CONFIG_PARTITION_DISK) += partitions.o
+
obj-$(CONFIG_CMD_LOADS) += s_record.o
obj-$(CONFIG_OFTREE) += oftree.o
@@ -24,6 +26,8 @@ obj-$(CONFIG_CMD_BOOTM) += image.o
obj-y += startup.o
obj-y += misc.o
obj-y += memsize.o
+obj-y += filetype.o
+obj-y += resource.o
obj-$(CONFIG_MENU) += menu.o
obj-$(CONFIG_PASSWORD) += password.o
obj-$(CONFIG_MODULES) += module.o
diff --git a/common/console.c b/common/console.c
index e5c0581..cab8689 100644
--- a/common/console.c
+++ b/common/console.c
@@ -154,13 +154,9 @@ int console_register(struct console_device *newcdev)
list_add_tail(&newcdev->list, &console_list);
- if (console_output_buffer) {
- while (kfifo_getc(console_output_buffer, &ch) == 0)
- console_putc(CONSOLE_STDOUT, ch);
- kfifo_free(console_output_buffer);
- console_output_buffer = NULL;
- }
+ while (kfifo_getc(console_output_buffer, &ch) == 0)
+ console_putc(CONSOLE_STDOUT, ch);
if (first)
barebox_banner();
@@ -168,6 +164,22 @@ int console_register(struct console_device *newcdev)
}
EXPORT_SYMBOL(console_register);
+int console_unregister(struct console_device *cdev)
+{
+ struct device_d *dev = &cdev->class_dev;
+ int status;
+
+ list_del(&cdev->list);
+ if (list_empty(&console_list))
+ initialized = CONSOLE_UNINITIALIZED;
+
+ status = unregister_device(dev);
+ if (!status)
+ memset(cdev, 0, sizeof(*cdev));
+ return status;
+}
+EXPORT_SYMBOL(console_unregister);
+
static int getc_raw(void)
{
struct console_device *cdev;
diff --git a/common/console_simple.c b/common/console_simple.c
index 61a233d..73e4752 100644
--- a/common/console_simple.c
+++ b/common/console_simple.c
@@ -164,3 +164,7 @@ int console_register(struct console_device *newcdev)
}
return 0;
}
+
+int console_unregister(struct console_device *cdev)
+{
+}
diff --git a/common/env.c b/common/env.c
index 05ed714..e57a520 100644
--- a/common/env.c
+++ b/common/env.c
@@ -251,3 +251,25 @@ int export(const char *varname)
return 0;
}
EXPORT_SYMBOL(export);
+
+void export_env_ull(const char *name, unsigned long long val)
+{
+ char *valstr = asprintf("%lld", val);
+
+ setenv(name, valstr);
+ export(name);
+
+ kfree(valstr);
+}
+EXPORT_SYMBOL(export_env_ull);
+
+unsigned long long getenv_ull(const char *name)
+{
+ const char *valstr = getenv(name);
+
+ if (!valstr)
+ return 0;
+
+ return simple_strtoull(valstr, NULL, 0);
+}
+EXPORT_SYMBOL(getenv_ull);
diff --git a/common/filetype.c b/common/filetype.c
new file mode 100644
index 0000000..5635d40
--- /dev/null
+++ b/common/filetype.c
@@ -0,0 +1,99 @@
+/*
+ * filetype.c - detect filetypes
+ *
+ * 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.
+ */
+#include <common.h>
+#include <filetype.h>
+#include <asm/byteorder.h>
+#include <fcntl.h>
+#include <fs.h>
+#include <malloc.h>
+
+static const char *filetype_str[] = {
+ [filetype_unknown] = "unknown",
+ [filetype_arm_zimage] = "arm Linux zImage",
+ [filetype_lzo_compressed] = "lzo compressed",
+ [filetype_arm_barebox] = "arm barebox image",
+ [filetype_uimage] = "U-Boot uImage",
+ [filetype_ubi] = "UBI image",
+ [filetype_jffs2] = "JFFS2 image",
+ [filetype_gzip] = "gzip compressed",
+ [filetype_bzip2] = "bzip2 compressed",
+};
+
+const char *file_type_to_string(enum filetype f)
+{
+ if (f < ARRAY_SIZE(filetype_str))
+ return filetype_str[f];
+
+ return NULL;
+}
+
+enum filetype file_detect_type(void *_buf)
+{
+ u32 *buf = _buf;
+ u8 *buf8 = _buf;
+
+ if (buf[8] == 0x65726162 && buf[9] == 0x00786f62)
+ return filetype_arm_barebox;
+ if (buf[9] == 0x016f2818 || buf[9] == 0x18286f01)
+ return filetype_arm_zimage;
+ if (buf8[0] == 0x89 && buf8[1] == 0x4c && buf8[2] == 0x5a &&
+ buf8[3] == 0x4f)
+ return filetype_lzo_compressed;
+ if (buf[0] == be32_to_cpu(0x27051956))
+ return filetype_uimage;
+ if (buf[0] == 0x23494255)
+ return filetype_ubi;
+ if (buf[0] == 0x20031985)
+ return filetype_jffs2;
+ if (buf8[0] == 0x1f && buf8[1] == 0x8b && buf8[2] == 0x08)
+ return filetype_gzip;
+ if (buf8[0] == 'B' && buf8[1] == 'Z' && buf8[2] == 'h' &&
+ buf8[3] > '0' && buf8[3] <= '9')
+ return filetype_bzip2;
+
+ return filetype_unknown;
+}
+
+enum filetype file_name_detect_type(const char *filename)
+{
+ int fd, ret;
+ void *buf;
+ enum filetype type = filetype_unknown;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return fd;
+
+ buf = xmalloc(512);
+
+ ret = read(fd, buf, 512);
+ if (ret != 512)
+ goto err_out;
+
+ type = file_detect_type(buf);
+
+err_out:
+ close(fd);
+ free(buf);
+
+ return type;
+}
diff --git a/common/hush.c b/common/hush.c
index 573bd3e..b59e59d 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -122,6 +122,7 @@
#include <glob.h>
#include <getopt.h>
#include <libbb.h>
+#include <magicvar.h>
#include <linux/list.h>
/*cmd_boot.c*/
@@ -540,6 +541,8 @@ static int builtin_getopt(struct p_context *ctx, struct child_prog *child)
return 0;
}
+
+BAREBOX_MAGICVAR(OPTARG, "optarg for hush builtin getopt");
#endif
/* run_pipe_real() starts all the jobs, but doesn't wait for anything
@@ -1721,6 +1724,11 @@ BAREBOX_CMD_START(getopt)
BAREBOX_CMD_END
#endif
+BAREBOX_MAGICVAR(PATH, "colon seperated list of pathes to search for executables");
+#ifdef CONFIG_HUSH_FANCY_PROMPT
+BAREBOX_MAGICVAR(PS1, "hush prompt");
+#endif
+
/**
* @file
* @brief A prototype Bourne shell grammar parser
diff --git a/common/image.c b/common/image.c
index 4a6402d..d68889b 100644
--- a/common/image.c
+++ b/common/image.c
@@ -290,7 +290,7 @@ void image_print_contents(const image_header_t *hdr, void *data)
printf ("%sEntry Point: %08x\n", p, image_get_ep(hdr));
type = image_get_type(hdr);
- if (type == IH_TYPE_MULTI || type == IH_TYPE_SCRIPT) {
+ if (data && (type == IH_TYPE_MULTI || type == IH_TYPE_SCRIPT)) {
int i;
ulong img_data, len;
ulong count = image_multi_count(data);
@@ -404,6 +404,7 @@ err_out:
close(fd);
if (handle->flags & IH_MALLOC)
free(handle->data);
+ free(handle->data_entries);
free(handle);
return NULL;
}
diff --git a/common/memory.c b/common/memory.c
index 0ba9a18..7d0f4ca 100644
--- a/common/memory.c
+++ b/common/memory.c
@@ -25,6 +25,9 @@
#include <of.h>
#include <init.h>
#include <libfdt.h>
+#include <linux/ioport.h>
+#include <asm-generic/memory_layout.h>
+#include <asm/sections.h>
/*
* Begin and End of memory area for malloc(), and current "brk"
@@ -50,6 +53,33 @@ void mem_malloc_init(void *start, void *end)
malloc_brk = malloc_start;
}
+static int mem_malloc_resource(void)
+{
+ /*
+ * Normally it's a bug when one of these fails,
+ * but we have some setups where some of these
+ * regions are outside of sdram in which case
+ * the following fails.
+ */
+ request_sdram_region("malloc space",
+ malloc_start,
+ malloc_end - malloc_start + 1);
+ request_sdram_region("barebox",
+ (unsigned long)&_stext,
+ (unsigned long)&_etext -
+ (unsigned long)&_stext + 1);
+ request_sdram_region("bss",
+ (unsigned long)&__bss_start,
+ (unsigned long)&__bss_stop -
+ (unsigned long)&__bss_start + 1);
+#ifdef STACK_BASE
+ request_sdram_region("stack", STACK_BASE, STACK_SIZE);
+#endif
+
+ return 0;
+}
+coredevice_initcall(mem_malloc_resource);
+
static void *sbrk_no_zero(ptrdiff_t increment)
{
unsigned long old = malloc_brk;
@@ -82,6 +112,10 @@ 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);
+
+ BUG_ON(!bank->res);
+
dev = add_mem_device(name, start, size, IORESOURCE_MEM_WRITEABLE);
bank->dev = dev;
@@ -91,6 +125,30 @@ void barebox_add_memory_bank(const char *name, resource_size_t start,
list_add_tail(&bank->list, &memory_banks);
}
+/*
+ * Request a region from the registered sdram
+ */
+struct resource *request_sdram_region(const char *name, resource_size_t start,
+ resource_size_t size)
+{
+ struct memory_bank *bank;
+
+ for_each_memory_bank(bank) {
+ struct resource *res;
+
+ res = request_region(bank->res, name, start, size);
+ if (res)
+ return res;
+ }
+
+ return NULL;
+}
+
+int release_sdram_region(struct resource *res)
+{
+ return release_region(res);
+}
+
#ifdef CONFIG_OFTREE
/*
diff --git a/common/partitions.c b/common/partitions.c
new file mode 100644
index 0000000..e4f3ad6
--- /dev/null
+++ b/common/partitions.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2009...2011 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
+ *
+ */
+
+/**
+ * @file
+ * @brief Generic support for partition tables on disk like media
+ *
+ * @todo Support for disks larger than 4 GiB
+ * @todo Reliable size detection for BIOS based disks (on x86 only)
+ */
+#include <common.h>
+#include <malloc.h>
+#include <errno.h>
+#include <block.h>
+#include <asm/unaligned.h>
+#include <disks.h>
+
+struct partition {
+ uint64_t first_sec;
+ uint64_t size;
+};
+
+struct partition_desc {
+ int used_entries;
+ struct partition parts[8];
+};
+
+/**
+ * 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
+ * @return sector count
+ */
+static int disk_guess_size(struct device_d *dev, struct partition_entry *table)
+{
+ uint64_t size = 0;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (table[i].partition_start != 0) {
+ size += get_unaligned(&table[i].partition_start) - size;
+ 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;
+}
+
+/**
+ * Check if a DOS like partition describes this block device
+ * @param blk Block device to register to
+ * @param pd Where to store the partition information
+ *
+ * It seems at least on ARM this routine canot use temp. stack space for the
+ * sector. So, keep the malloc/free.
+ */
+static void __maybe_unused try_dos_partition(struct block_device *blk,
+ struct partition_desc *pd)
+{
+ uint8_t *buffer;
+ struct partition_entry *table;
+ struct partition pentry;
+ int i, rc;
+
+ buffer = xmalloc(SECTOR_SIZE);
+
+ /* read in the MBR to get the partition table */
+ rc = blk->ops->read(blk, buffer, 0, 1);
+ if (rc != 0) {
+ dev_err(blk->dev, "Cannot read MBR/partition table\n");
+ goto on_error;
+ }
+
+ if ((buffer[510] != 0x55) || (buffer[511] != 0xAA)) {
+ dev_info(blk->dev, "No partition table found\n");
+ goto on_error;
+ }
+
+ table = (struct partition_entry *)&buffer[446];
+
+ /* valid for x86 BIOS based disks only */
+ if (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;
+ pd->used_entries++;
+ } else {
+ dev_dbg(blk->dev, "Skipping empty partition %d\n", i);
+ }
+ }
+
+on_error:
+ free(buffer);
+}
+
+/**
+ * Register one partition on the given block device
+ * @param blk Block device to register to
+ * @param part Partition description
+ * @param no Partition number
+ * @return 0 on success
+ */
+static int register_one_partition(struct block_device *blk,
+ struct partition *part, int no)
+{
+ char partition_name[19];
+
+ sprintf(partition_name, "%s.%d", blk->cdev.name, no);
+ dev_dbg(blk->dev, "Registering partition %s on drive %s\n",
+ partition_name, blk->cdev.name);
+ return devfs_add_partition(blk->cdev.name,
+ part->first_sec * SECTOR_SIZE,
+ part->size * SECTOR_SIZE,
+ DEVFS_PARTITION_FIXED, partition_name);
+}
+
+/**
+ * Try to collect partition information on the given block device
+ * @param blk Block device to examine
+ * @return 0 most of the time, negative value else
+ *
+ * It is not a failure if no partition information is found
+ */
+int parse_partition_table(struct block_device *blk)
+{
+ struct partition_desc pdesc = { .used_entries = 0, };
+ int i;
+ int rc = 0;
+
+#ifdef CONFIG_PARTITION_DISK_DOS
+ try_dos_partition(blk, &pdesc);
+#endif
+ if (!pdesc.used_entries)
+ return 0;
+
+ /* at least one partition description found */
+ for (i = 0; i < pdesc.used_entries; i++) {
+ rc = register_one_partition(blk, &pdesc.parts[i], i);
+ if (rc != 0)
+ dev_err(blk->dev,
+ "Failed to register partition %d on %s (%d)\n",
+ i, blk->cdev.name, rc);
+ if (rc != -ENODEV)
+ rc = 0;
+ }
+
+ return rc;
+}
diff --git a/common/resource.c b/common/resource.c
new file mode 100644
index 0000000..63e9c49
--- /dev/null
+++ b/common/resource.c
@@ -0,0 +1,121 @@
+/*
+ * resource.c - barebox resource management
+ *
+ * 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.
+ */
+#include <common.h>
+#include <malloc.h>
+#include <errno.h>
+#include <init.h>
+#include <linux/ioport.h>
+
+static int init_resource(struct resource *res, const char *name)
+{
+ INIT_LIST_HEAD(&res->children);
+ res->parent = NULL;
+ res->name = xstrdup(name);
+
+ return 0;
+}
+
+/*
+ * request a region.
+ * This will succedd when the requested region is completely inside
+ * the parent resource and does not conflict with any of the child
+ * resources.
+ */
+struct resource *request_region(struct resource *parent,
+ const char *name, resource_size_t start,
+ resource_size_t size)
+{
+ struct resource *r, *new;
+
+ /* outside parent resource? */
+ if (start < parent->start ||
+ start + size > parent->start + parent->size) {
+ debug("%s: 0x%08x:0x%08x outside parent resource 0x%08x:0x%08x\n",
+ __func__, start, size, parent->start,
+ parent->size);
+ return NULL;
+ }
+
+ /*
+ * We keep the list of child resources ordered which helps
+ * us searching for conflicts here.
+ */
+ list_for_each_entry(r, &parent->children, sibling) {
+ if (start + size <= r->start)
+ goto ok;
+ if (start >= r->start + r->size)
+ continue;
+ debug("%s: 0x%08x:0x%08x conflicts with 0x%08x:0x%08x\n",
+ __func__, start, size, r->start, r->size);
+ return NULL;
+ }
+
+ok:
+ debug("%s ok: 0x%08x 0x%08x\n", __func__, start, size);
+
+ new = xzalloc(sizeof(*new));
+ init_resource(new, name);
+ new->start = start;
+ new->size = size;
+ new->parent = parent;
+ list_add_tail(&new->sibling, &r->sibling);
+
+ return new;
+}
+
+/*
+ * release a region previously requested with request_region
+ */
+int release_region(struct resource *res)
+{
+ if (!list_empty(&res->children))
+ return -EBUSY;
+
+ list_del(&res->sibling);
+ free((char *)res->name);
+ free(res);
+
+ return 0;
+}
+
+/* The root resource for the whole io space */
+struct resource iomem_resource = {
+ .start = 0,
+ .size = ~0,
+};
+
+/*
+ * request a region inside the io space
+ */
+struct resource *request_iomem_region(const char *name,
+ resource_size_t start, resource_size_t size)
+{
+ return request_region(&iomem_resource, name, start, size);
+}
+
+static int iomem_init(void)
+{
+ init_resource(&iomem_resource, "iomem");
+
+ return 0;
+}
+postcore_initcall(iomem_init);
diff --git a/crypto/Kconfig b/crypto/Kconfig
index a391ae6..a6fc1b8 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -4,6 +4,9 @@ config CRC32
config CRC16
bool
+config CRC7
+ bool
+
menuconfig DIGEST
bool "Digest "
diff --git a/crypto/Makefile b/crypto/Makefile
index 955a66d..7c5b035 100644
--- a/crypto/Makefile
+++ b/crypto/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_CRC32) += crc32.o
obj-$(CONFIG_CRC16) += crc16.o
+obj-$(CONFIG_CRC7) += crc7.o
obj-$(CONFIG_MD5) += md5.o
obj-$(CONFIG_SHA1) += sha1.o
obj-$(CONFIG_SHA224) += sha2.o
diff --git a/crypto/crc7.c b/crypto/crc7.c
new file mode 100644
index 0000000..8022199
--- /dev/null
+++ b/crypto/crc7.c
@@ -0,0 +1,63 @@
+/*
+ * crc7.c
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include <common.h>
+#include <crc7.h>
+
+
+/* Table for CRC-7 (polynomial x^7 + x^3 + 1) */
+const u8 crc7_syndrome_table[256] = {
+ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f,
+ 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
+ 0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26,
+ 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
+ 0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d,
+ 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
+ 0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14,
+ 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
+ 0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b,
+ 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
+ 0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42,
+ 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
+ 0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69,
+ 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
+ 0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70,
+ 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
+ 0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e,
+ 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
+ 0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67,
+ 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
+ 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
+ 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
+ 0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55,
+ 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
+ 0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a,
+ 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
+ 0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03,
+ 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
+ 0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28,
+ 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
+ 0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31,
+ 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79
+};
+
+/**
+ * crc7 - update the CRC7 for the data buffer
+ * @crc: previous CRC7 value
+ * @buffer: data pointer
+ * @len: number of bytes in the buffer
+ * Context: any
+ *
+ * Returns the updated CRC7 value.
+ */
+u8 crc7(u8 crc, const u8 *buffer, size_t len)
+{
+ while (len--)
+ crc = crc7_byte(crc, *buffer++);
+ return crc;
+}
+EXPORT_SYMBOL(crc7);
diff --git a/defaultenv/bin/boot b/defaultenv/bin/boot
index 6761d84..90ebf9a 100644
--- a/defaultenv/bin/boot
+++ b/defaultenv/bin/boot
@@ -124,6 +124,6 @@ elif [ x$kernelimage_type = xraw ]; then
fi
bootu /dev/ram0.kernelraw
elif [ x$kernelimage_type = xraw_lzo ]; then
- unlzo $kdev /dev/ram0.kernelraw
+ uncompress $kdev /dev/ram0.kernelraw
bootu /dev/ram0.kernelraw
fi
diff --git a/drivers/Makefile b/drivers/Makefile
index 16b3bb1..592c39e 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -4,7 +4,7 @@ obj-y += serial/
obj-y += mtd/
obj-y += nor/
obj-y += usb/
-obj-$(CONFIG_ATA) += ata/
+obj-$(CONFIG_DISK) += ata/
obj-$(CONFIG_SPI) += spi/
obj-$(CONFIG_I2C) += i2c/
obj-$(CONFIG_MCI) += mci/
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index d7f4dcb..fe6f5e6 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -1,25 +1,21 @@
-menuconfig ATA
+menuconfig DISK
select BLOCK
- bool "ATA "
+ select PARTITION
+ select PARTITION_DISK
+ bool "Disk support "
help
- Add support for ATA types of drives like harddisks and CDROMs.
+ Add support for disk like drives like harddisks, CDROMs, SD cards and
+ CF cards.
-if ATA
+if DISK
-comment "drive types"
-
-config ATA_WRITE
+config DISK_WRITE
select BLOCK_WRITE
- bool "support writing to ATA drives"
-
-config ATA_DISK
- bool "disk drives"
- help
- Add support for regular disk drives
+ bool "support writing to disk drives"
-comment "interface types"
+comment "drive types"
-config ATA_BIOS
+config DISK_BIOS
bool "BIOS based"
depends on X86_BIOS_BRINGUP
help
@@ -28,4 +24,19 @@ config ATA_BIOS
media to work on. Disadvantage is: Due to its 16 bit nature it is
slow.
+config DISK_ATA
+ bool "ATA type drives"
+ select DISK_DRIVE
+ help
+ Support for native ATA/IDE drives
+
+comment "interface types"
+
+config DISK_INTF_PLATFORM_IDE
+ bool "Platform IDE"
+ select DISK_ATA
+ help
+ Generic platform driver for simple IDE like interfaces to a connected
+ ATA device.
+
endif
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 30d15cc..2560076 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -1,7 +1,8 @@
# drive types
-obj-$(CONFIG_ATA_DISK) += disk_drive.o
+obj-$(CONFIG_DISK_BIOS) += disk_bios_drive.o
+obj-$(CONFIG_DISK_ATA) += disk_ata_drive.o
# interface types
-obj-$(CONFIG_ATA_BIOS) += bios.o
+obj-$(CONFIG_DISK_INTF_PLATFORM_IDE) += intf_platform_ide.o
diff --git a/drivers/ata/disk_ata_drive.c b/drivers/ata/disk_ata_drive.c
new file mode 100644
index 0000000..4602af3
--- /dev/null
+++ b/drivers/ata/disk_ata_drive.c
@@ -0,0 +1,618 @@
+/*
+ * Copyright (C) 2011 Juergen Beisert, Pengutronix
+ *
+ * Inspired from various soures like http://wiki.osdev.org/ATA_PIO_Mode,
+ * u-boot and the linux kernel
+ *
+ * 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 <xfuncs.h>
+#include <io.h>
+#include <malloc.h>
+#include <errno.h>
+#include <clock.h>
+#include <block.h>
+#include <ata_drive.h>
+#include <disks.h>
+
+#define ATA_CMD_ID_DEVICE 0xEC
+#define ATA_CMD_RD_CONF 0x40
+#define ATA_CMD_RD 0x20
+#define ATA_CMD_WR 0x30
+
+#define DISK_MASTER 0
+#define DISK_SLAVE 1
+
+/* max timeout for a rotating disk in [ms] */
+#define MAX_TIMEOUT 5000
+
+/**
+ * Collection of data we need to know about this drive
+ */
+struct ata_drive_access {
+ struct block_device blk; /**< the main device */
+ struct ata_ioports *io; /**< register file */
+ uint16_t id[(SECTOR_SIZE / sizeof(uint16_t))];
+};
+
+#define to_ata_drive_access(x) container_of((x), struct ata_drive_access, blk)
+
+#define ata_id_u32(id,n) \
+ (((uint32_t) (id)[(n) + 1] << 16) | ((uint32_t) (id)[(n)]))
+#define ata_id_u64(id,n) \
+ ( ((uint64_t) (id)[(n) + 3] << 48) | \
+ ((uint64_t) (id)[(n) + 2] << 32) | \
+ ((uint64_t) (id)[(n) + 1] << 16) | \
+ ((uint64_t) (id)[(n) + 0]) )
+
+#define ata_id_has_lba(id) ((id)[49] & (1 << 9))
+
+/* drive's status flags */
+#define ATA_STATUS_BUSY (1 << 7)
+#define ATA_STATUS_READY (1 << 6)
+#define ATA_STATUS_WR_FLT (1 << 5)
+#define ATA_STATUS_DRQ (1 << 4)
+#define ATA_STATUS_CORR (1 << 3)
+#define ATA_STATUS_ERROR (1 << 1)
+/* command flags */
+#define LBA_FLAG (1 << 6)
+#define ATA_DEVCTL_SOFT_RESET (1 << 2)
+#define ATA_DEVCTL_INTR_DISABLE (1 << 1)
+
+enum {
+ ATA_ID_SERNO = 10,
+#define ATA_ID_SERNO_LEN 20
+ ATA_ID_FW_REV = 23,
+#define ATA_ID_FW_REV_LEN 8
+ ATA_ID_PROD = 27,
+#define ATA_ID_PROD_LEN 40
+ ATA_ID_CAPABILITY = 49,
+ ATA_ID_FIELD_VALID = 53,
+ ATA_ID_LBA_CAPACITY = 60,
+ ATA_ID_MWDMA_MODES = 63,
+ ATA_ID_PIO_MODES = 64,
+ ATA_ID_QUEUE_DEPTH = 75,
+ ATA_ID_MAJOR_VER = 80,
+ ATA_ID_COMMAND_SET_1 = 82,
+ ATA_ID_COMMAND_SET_2 = 83,
+ ATA_ID_CFSSE = 84,
+ ATA_ID_CFS_ENABLE_1 = 85,
+ ATA_ID_CFS_ENABLE_2 = 86,
+ ATA_ID_CSF_DEFAULT = 87,
+ ATA_ID_UDMA_MODES = 88,
+ ATA_ID_HW_CONFIG = 93,
+ ATA_ID_LBA_CAPACITY_2 = 100,
+};
+
+static int ata_id_is_valid(const uint16_t *id)
+{
+ if ((id[ATA_ID_FIELD_VALID] & 1) == 0) {
+ pr_debug("Drive's ID seems invalid\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline int ata_id_has_lba48(const uint16_t *id)
+{
+ if ((id[ATA_ID_COMMAND_SET_2] & 0xC000) != 0x4000)
+ return 0;
+ if (!ata_id_u64(id, ATA_ID_LBA_CAPACITY_2))
+ return 0;
+ return id[ATA_ID_COMMAND_SET_2] & (1 << 10);
+}
+
+static uint64_t ata_id_n_sectors(uint16_t *id)
+{
+ if (ata_id_has_lba(id)) {
+ if (ata_id_has_lba48(id))
+ return ata_id_u64(id, ATA_ID_LBA_CAPACITY_2);
+ else
+ return ata_id_u32(id, ATA_ID_LBA_CAPACITY);
+ }
+
+ return 0;
+}
+
+static void ata_id_string(const uint16_t *id, unsigned char *s,
+ unsigned ofs, unsigned len)
+{
+ unsigned c;
+
+ while (len > 0) {
+ c = id[ofs] >> 8;
+ *s = c;
+ s++;
+
+ c = id[ofs] & 0xff;
+ *s = c;
+ s++;
+
+ ofs++;
+ len -= 2;
+ }
+}
+
+static void ata_id_c_string(const uint16_t *id, unsigned char *s,
+ unsigned ofs, unsigned len)
+{
+ unsigned char *p;
+
+ ata_id_string(id, s, ofs, len - 1);
+
+ p = s + strnlen((char *)s, len - 1);
+ while (p > s && p[-1] == ' ')
+ p--;
+ *p = '\0';
+}
+
+static void __maybe_unused ata_dump_id(uint16_t *id)
+{
+ unsigned char serial[ATA_ID_SERNO_LEN + 1];
+ unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
+ unsigned char product[ATA_ID_PROD_LEN + 1];
+ uint64_t n_sectors;
+
+ /* Serial number */
+ ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
+ printf("S/N: %s\n\r", serial);
+
+ /* Firmware version */
+ ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
+ printf("Firmware version: %s\n\r", firmware);
+
+ /* Product model */
+ ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
+ printf("Product model number: %s\n\r", product);
+
+ /* Total sectors of device */
+ n_sectors = ata_id_n_sectors(id);
+ printf("Capablity: %lld sectors\n\r", n_sectors);
+
+ printf ("id[49]: capabilities = 0x%04x\n"
+ "id[53]: field valid = 0x%04x\n"
+ "id[63]: mwdma = 0x%04x\n"
+ "id[64]: pio = 0x%04x\n"
+ "id[75]: queue depth = 0x%04x\n",
+ id[ATA_ID_CAPABILITY],
+ id[ATA_ID_FIELD_VALID],
+ id[ATA_ID_MWDMA_MODES],
+ id[ATA_ID_PIO_MODES],
+ id[ATA_ID_QUEUE_DEPTH]);
+
+ printf ("id[76]: sata capablity = 0x%04x\n"
+ "id[78]: sata features supported = 0x%04x\n"
+ "id[79]: sata features enable = 0x%04x\n",
+ id[76], /* FIXME */
+ id[78], /* FIXME */
+ id[79]); /* FIXME */
+
+ printf ("id[80]: major version = 0x%04x\n"
+ "id[81]: minor version = 0x%04x\n"
+ "id[82]: command set supported 1 = 0x%04x\n"
+ "id[83]: command set supported 2 = 0x%04x\n"
+ "id[84]: command set extension = 0x%04x\n",
+ id[ATA_ID_MAJOR_VER],
+ id[81], /* FIXME */
+ id[ATA_ID_COMMAND_SET_1],
+ id[ATA_ID_COMMAND_SET_2],
+ id[ATA_ID_CFSSE]);
+ printf ("id[85]: command set enable 1 = 0x%04x\n"
+ "id[86]: command set enable 2 = 0x%04x\n"
+ "id[87]: command set default = 0x%04x\n"
+ "id[88]: udma = 0x%04x\n"
+ "id[93]: hardware reset result = 0x%04x\n",
+ id[ATA_ID_CFS_ENABLE_1],
+ id[ATA_ID_CFS_ENABLE_2],
+ id[ATA_ID_CSF_DEFAULT],
+ id[ATA_ID_UDMA_MODES],
+ id[ATA_ID_HW_CONFIG]);
+}
+
+/**
+ * Swap little endian data on demand
+ * @param buf Buffer with little endian word data
+ * @param wds 16 bit word count
+ *
+ * ATA disks report their ID data in little endian notation on a 16 bit word
+ * base. So swap the buffer content if the running CPU differs in their
+ * endiaeness.
+ */
+static void ata_fix_endianess(uint16_t *buf, unsigned wds)
+{
+#if __BYTE_ORDER == __BIG_ENDIAN
+ unsigned u;
+
+ for (u = 0; u < wds; u++)
+ buf[u] = le16_to_cpu(buf[u]);
+#endif
+}
+
+/**
+ * Read the status register of the ATA drive
+ * @param io Register file
+ * @return Register's content
+ */
+static uint8_t ata_rd_status(struct ata_ioports *io)
+{
+ return readb(io->status_addr);
+}
+
+/**
+ * Wait until the disk is busy or time out
+ * @param io Register file
+ * @param timeout Timeout in [ms]
+ * @return 0 on success, -ETIMEDOUT else
+ */
+static int ata_wait_busy(struct ata_ioports *io, unsigned timeout)
+{
+ uint8_t status;
+ uint64_t start = get_time_ns();
+ uint64_t toffs = timeout * 1000 * 1000;
+
+ do {
+ status = ata_rd_status(io);
+ if (status & ATA_STATUS_BUSY)
+ return 0;
+ } while (!is_timeout(start, toffs));
+
+ return -ETIMEDOUT;
+}
+
+/**
+ * Wait until the disk is ready again or time out
+ * @param io Register file
+ * @param timeout Timeout in [ms]
+ * @return 0 on success, -ETIMEDOUT else
+ *
+ * This function is useful to check if the disk has accepted a command.
+ */
+static int ata_wait_ready(struct ata_ioports *io, unsigned timeout)
+{
+ uint8_t status;
+ uint64_t start = get_time_ns();
+ uint64_t toffs = timeout * 1000 * 1000;
+
+ do {
+ status = ata_rd_status(io);
+ if (!(status & ATA_STATUS_BUSY)) {
+ if (status & ATA_STATUS_READY)
+ return 0;
+ }
+ } while (!is_timeout(start, toffs));
+
+ return -ETIMEDOUT;
+}
+
+/**
+ * Setup the sector number in LBA notation (LBA28)
+ * @param io Register file
+ * @param drive 0 master drive, 1 slave drive
+ * @param num Sector number
+ *
+ * @todo LBA48 support
+ */
+static int ata_set_lba_sector(struct ata_ioports *io, unsigned drive, uint64_t num)
+{
+ if (num > 0x0FFFFFFF || drive > 1)
+ return -EINVAL;
+
+ writeb(0xA0 | LBA_FLAG | drive << 4 | num >> 24, io->device_addr);
+ writeb(0x00, io->error_addr);
+ writeb(0x01, io->nsect_addr);
+ writeb(num, io->lbal_addr); /* 0 ... 7 */
+ writeb(num >> 8, io->lbam_addr); /* 8 ... 15 */
+ writeb(num >> 16, io->lbah_addr); /* 16 ... 23 */
+
+ return 0;
+}
+
+/**
+ * Write an ATA command into the disk
+ * @param io Register file
+ * @param cmd Command to write
+ * @return 0 on success
+ */
+static int ata_wr_cmd(struct ata_ioports *io, uint8_t cmd)
+{
+ int rc;
+
+ rc = ata_wait_ready(io, MAX_TIMEOUT);
+ if (rc != 0)
+ return rc;
+
+ writeb(cmd, io->command_addr);
+ return 0;
+}
+
+/**
+ * Write a new value into the "device control register"
+ * @param io Register file
+ * @param val Value to write
+ */
+static void ata_wr_dev_ctrl(struct ata_ioports *io, uint8_t val)
+{
+ writeb(val, io->ctl_addr);
+}
+
+/**
+ * Read one sector from the drive (always SECTOR_SIZE bytes at once)
+ * @param io Register file
+ * @param buf Buffer to read the data into
+ */
+static void ata_rd_sector(struct ata_ioports *io, void *buf)
+{
+ unsigned u = SECTOR_SIZE / sizeof(uint16_t);
+ uint16_t *b = buf;
+
+ if (io->dataif_be) {
+ for (; u > 0; u--)
+ *b++ = be16_to_cpu(readw(io->data_addr));
+ } else {
+ for (; u > 0; u--)
+ *b++ = le16_to_cpu(readw(io->data_addr));
+ }
+}
+
+/**
+ * Write one sector into the drive
+ * @param io Register file
+ * @param buf Buffer to read the data from
+ */
+static void ata_wr_sector(struct ata_ioports *io, const void *buf)
+{
+ unsigned u = SECTOR_SIZE / sizeof(uint16_t);
+ const uint16_t *b = buf;
+
+ if (io->dataif_be) {
+ for (; u > 0; u--)
+ writew(cpu_to_be16(*b++), io->data_addr);
+ } else {
+ for (; u > 0; u--)
+ writew(cpu_to_le16(*b++), io->data_addr);
+ }
+}
+
+/**
+ * Read the ATA disk's description info
+ * @param d All we need to know about the disk
+ * @return 0 on success
+ */
+static int ata_get_id(struct ata_drive_access *d)
+{
+ int rc;
+
+ writeb(0xA0, d->io->device_addr); /* FIXME drive */
+ writeb(0x00, d->io->lbal_addr);
+ writeb(0x00, d->io->lbam_addr);
+ writeb(0x00, d->io->lbah_addr);
+
+ rc = ata_wr_cmd(d->io, ATA_CMD_ID_DEVICE);
+ if (rc != 0)
+ return rc;
+
+ rc = ata_wait_ready(d->io, MAX_TIMEOUT);
+ if (rc != 0)
+ return rc;
+
+ ata_rd_sector(d->io, &d->id);
+
+ ata_fix_endianess(d->id, SECTOR_SIZE / sizeof(uint16_t));
+
+ return ata_id_is_valid(d->id);
+}
+
+static int ata_reset(struct ata_ioports *io)
+{
+ int rc;
+ uint8_t reg;
+
+ /* try a hard reset first (if available) */
+ if (io->reset != NULL) {
+ pr_debug("%s: Resetting drive...\n", __func__);
+ io->reset(1);
+ rc = ata_wait_busy(io, 500);
+ io->reset(0);
+ if (rc == 0) {
+ rc = ata_wait_ready(io, MAX_TIMEOUT);
+ if (rc != 0)
+ return rc;
+ } else {
+ pr_debug("%s: Drive does not respond to RESET line. Ignored\n",
+ __func__);
+ }
+ }
+
+ /* try a soft reset */
+ ata_wr_dev_ctrl(io, ATA_DEVCTL_SOFT_RESET | ATA_DEVCTL_INTR_DISABLE);
+ rc = ata_wait_busy(io, MAX_TIMEOUT); /* does the drive accept the command? */
+ if (rc != 0) {
+ pr_debug("%s: Drive fails on soft reset\n", __func__);
+ return rc;
+ }
+ ata_wr_dev_ctrl(io, ATA_DEVCTL_INTR_DISABLE);
+ rc = ata_wait_ready(io, MAX_TIMEOUT);
+ if (rc != 0) {
+ pr_debug("%s: Drive fails after soft reset\n", __func__);
+ return rc;
+ }
+
+ reg = ata_rd_status(io) & 0xf;
+
+ if (reg == 0xf) {
+ pr_debug("%s: Seems no drive connected!\n", __func__);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/**
+ * Read a chunk of sectors from the drive
+ * @param blk All info about the block device we need
+ * @param buffer Buffer to read into
+ * @param block Sector's LBA number to start read from
+ * @param num_blocks Sector count to read
+ * @return 0 on success, anything else on failure
+ *
+ * This routine expects the buffer has the correct size to store all data!
+ *
+ * @note Due to 'block' is of type 'int' only small disks can be handled!
+ * @todo Optimize the read loop
+ */
+static int ata_read(struct block_device *blk, void *buffer, int block,
+ int num_blocks)
+{
+ int rc;
+ uint64_t sector = block;
+ struct ata_drive_access *drv = to_ata_drive_access(blk);
+
+ while (num_blocks) {
+ rc = ata_set_lba_sector(drv->io, DISK_MASTER, sector);
+ if (rc != 0)
+ return rc;
+ rc = ata_wr_cmd(drv->io, ATA_CMD_RD);
+ if (rc != 0)
+ return rc;
+ rc = ata_wait_ready(drv->io, MAX_TIMEOUT);
+ if (rc != 0)
+ return rc;
+ ata_rd_sector(drv->io, buffer);
+ num_blocks--;
+ sector++;
+ buffer += SECTOR_SIZE;
+ }
+
+ return 0;
+}
+
+/**
+ * Write a chunk of sectors into the drive
+ * @param blk All info about the block device we need
+ * @param buffer Buffer to write from
+ * @param block Sector's number to start write to
+ * @param num_blocks Sector count to write
+ * @return 0 on success, anything else on failure
+ *
+ * This routine expects the buffer has the correct size to read all data!
+ *
+ * @note Due to 'block' is of type 'int' only small disks can be handled!
+ * @todo Optimize the write loop
+ */
+static int __maybe_unused ata_write(struct block_device *blk,
+ const void *buffer, int block, int num_blocks)
+{
+ int rc;
+ uint64_t sector = block;
+ struct ata_drive_access *drv = to_ata_drive_access(blk);
+
+ while (num_blocks) {
+ rc = ata_set_lba_sector(drv->io, DISK_MASTER, sector);
+ if (rc != 0)
+ return rc;
+ rc = ata_wr_cmd(drv->io, ATA_CMD_WR);
+ if (rc != 0)
+ return rc;
+ ata_wr_sector(drv->io, buffer);
+ num_blocks--;
+ sector++;
+ buffer += SECTOR_SIZE;
+ }
+
+ return 0;
+}
+
+static struct block_device_ops ata_ops = {
+ .read = ata_read,
+#ifdef CONFIG_BLOCK_WRITE
+ .write = ata_write,
+#endif
+};
+
+/* until Barebox can handle 64 bit offsets */
+static int limit_disk_size(uint64_t val)
+{
+ if (val > (__INT_MAX__ / SECTOR_SIZE))
+ return (__INT_MAX__ / SECTOR_SIZE);
+ return (int)val;
+}
+
+/**
+ * Register an ATA drive behind an IDE like interface
+ * @param dev The interface device
+ * @param io ATA register file description
+ * @return 0 on success
+ */
+int register_ata_drive(struct device_d *dev, struct ata_ioports *io)
+{
+ int rc;
+ struct ata_drive_access *drive;
+
+ drive = xzalloc(sizeof(struct ata_drive_access));
+
+ drive->io = io;
+ drive->blk.dev = dev;
+ drive->blk.ops = &ata_ops;
+
+ rc = ata_reset(io);
+ if (rc) {
+ dev_dbg(dev, "Resetting failed\n");
+ goto on_error;
+ }
+
+ rc = ata_get_id(drive);
+ if (rc != 0) {
+ dev_dbg(dev, "Reading ID failed\n");
+ goto on_error;
+ }
+
+#ifdef DEBUG
+ ata_dump_id(drive->id);
+#endif
+ rc = cdev_find_free_index("disk");
+ if (rc == -1)
+ pr_err("Cannot find a free index for the disk node\n");
+
+ drive->blk.num_blocks = limit_disk_size(ata_id_n_sectors(drive->id));
+ drive->blk.cdev.name = asprintf("disk%d", rc);
+ drive->blk.blockbits = SECTOR_SHIFT;
+
+ rc = blockdevice_register(&drive->blk);
+ if (rc != 0) {
+ dev_err(dev, "Failed to register blockdevice\n");
+ goto on_error;
+ }
+
+ /* create partitions on demand */
+ rc = parse_partition_table(&drive->blk);
+ if (rc != 0)
+ dev_warn(dev, "No partition table found\n");
+
+ return 0;
+
+on_error:
+ free(drive);
+ return rc;
+}
+
+/**
+ * @file
+ * @brief Generic ATA disk drive support
+ *
+ * Please be aware: This driver covers only a subset of the available ATA drives
+ *
+ * @todo Support for disks larger than 4 GiB
+ * @todo LBA48
+ * @todo CHS
+ */
diff --git a/drivers/ata/bios.c b/drivers/ata/disk_bios_drive.c
index 6e2377c..7867245 100644
--- a/drivers/ata/bios.c
+++ b/drivers/ata/disk_bios_drive.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Juergen Beisert, Pengutronix
+ * Copyright (C) 2009...2011 Juergen Beisert, Pengutronix
*
* Mostly stolen from the GRUB2 project
* Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc.
@@ -43,15 +43,13 @@
* Note: This driver does only support LBA addressing. Currently no CHS!
*/
-#include <stdio.h>
-#include <linux/types.h>
+#include <common.h>
#include <init.h>
-#include <driver.h>
-#include <string.h>
-#include <xfuncs.h>
#include <asm/syslib.h>
-#include <ata.h>
#include <errno.h>
+#include <block.h>
+#include <disks.h>
+#include <malloc.h>
/**
* Sector count handled in one count
@@ -61,9 +59,6 @@
*/
#define SECTORS_AT_ONCE 64
-/** Size of one sector in bytes */
-#define SECTOR_SIZE 512
-
/** Command to read sectors from media */
#define BIOS_READ_CMD 0
@@ -89,10 +84,13 @@ struct DAPS
* Collection of data we need to know about the connected drive
*/
struct media_access {
+ struct block_device blk; /**< the main device */
int drive_no; /**< drive number used by the BIOS */
int is_cdrom; /**< drive is a CDROM e.g. no write support */
};
+#define to_media_access(x) container_of((x), struct media_access, blk)
+
/**
* Scratch memory for BIOS communication to handle data in chunks of 32 kiB
*
@@ -146,19 +144,23 @@ static int biosdisk_bios_call(struct media_access *media, int cmd, uint64_t sect
/**
* Read a chunk of sectors from media
- * @param dev our data we need to do the access
- * @param sector_start Sector's LBA number to start read from
- * @param sector_count Sectors to read
+ * @param blk All info about the block device we need
* @param buffer Buffer to read into
+ * @param block Sector's LBA number to start read from
+ * @param num_blocks Sector count to read
* @return 0 on success, anything else on failure
*
* This routine expects the buffer has the correct size to store all data!
+ *
+ * @note Due to 'block' is of type 'int' only small disks can be handled!
*/
-static int biosdisk_read(struct device_d *dev, uint64_t sector_start, unsigned sector_count, void *buffer)
+static int biosdisk_read(struct block_device *blk, void *buffer, int block,
+ int num_blocks)
{
int rc;
- struct ata_interface *intf = dev->platform_data;
- struct media_access *media = intf->priv;
+ uint64_t sector_start = block;
+ unsigned sector_count = num_blocks;
+ struct media_access *media = to_media_access(blk);
while (sector_count >= SECTORS_AT_ONCE) {
rc = biosdisk_bios_call(media, BIOS_READ_CMD, sector_start, SECTORS_AT_ONCE, scratch_buffer);
@@ -182,19 +184,23 @@ static int biosdisk_read(struct device_d *dev, uint64_t sector_start, unsigned s
/**
* Write a chunk of sectors to media
- * @param dev our data we need to do the access
- * @param sector_start Sector's LBA number to start write to
- * @param sector_count Sectors to write
+ * @param blk All info about the block device we need
* @param buffer Buffer to write from
+ * @param block Sector's LBA number to start write to
+ * @param num_blocks Sector count to write
* @return 0 on success, anything else on failure
*
* This routine expects the buffer has the correct size to read all data!
+ *
+ * @note Due to 'block' is of type 'int' only small disks can be handled!
*/
-static int biosdisk_write(struct device_d *dev, uint64_t sector_start, unsigned sector_count, const void *buffer)
+static int __maybe_unused biosdisk_write(struct block_device *blk,
+ const void *buffer, int block, int num_blocks)
{
int rc;
- struct ata_interface *intf = dev->platform_data;
- struct media_access *media = intf->priv;
+ uint64_t sector_start = block;
+ unsigned sector_count = num_blocks;
+ struct media_access *media = to_media_access(blk);
while (sector_count >= SECTORS_AT_ONCE) {
__builtin_memcpy(scratch_buffer, buffer, sizeof(scratch_buffer));
@@ -216,6 +222,13 @@ static int biosdisk_write(struct device_d *dev, uint64_t sector_start, unsigned
return rc;
}
+static struct block_device_ops bios_ata = {
+ .read = biosdisk_read,
+#ifdef CONFIG_BLOCK_WRITE
+ .write = biosdisk_write,
+#endif
+};
+
/**
* Probe for connected drives and register them
*
@@ -228,8 +241,6 @@ static int biosdisk_probe(struct device_d *dev)
{
int drive, rc;
struct media_access media, *m;
- struct device_d *drive_dev;
- struct ata_interface *p;
for (drive = 0x80; drive < 0x90; drive++) {
media.drive_no = drive;
@@ -240,27 +251,32 @@ static int biosdisk_probe(struct device_d *dev)
printf("BIOSdrive %d seems valid. Registering...\n", media.drive_no);
- drive_dev = xzalloc(sizeof(struct device_d) + sizeof(struct media_access) + sizeof(struct ata_interface));
- if (drive_dev == NULL) {
- dev_err(dev, "Out of memory\n");
- return -1;
+ m = xzalloc(sizeof(struct media_access));
+
+ m->blk.dev = dev;
+ m->blk.ops = &bios_ata;
+ /*
+ * keep the 'blk.num_blocks' member 0, as we don't know
+ * the size of this disk yet!
+ */
+ rc = cdev_find_free_index("disk");
+ if (rc < 0)
+ pr_err("Cannot find a free number for the disk node\n");
+ m->blk.cdev.name = asprintf("disk%d", rc);
+ m->blk.blockbits = SECTOR_SHIFT;
+
+ rc = blockdevice_register(&m->blk);
+ if (rc != 0) {
+ dev_err(dev, "Cannot register BIOSdrive %d\n",
+ media.drive_no);
+ free(m);
+ return rc;
}
- m = (struct media_access*)&drive_dev[1];
- p = (struct ata_interface*)&m[1];
-
- m->drive_no = drive;
- m->is_cdrom = 0;
-
- p->write = biosdisk_write;
- p->read = biosdisk_read;
- p->priv = m;
- strcpy(drive_dev->name, "biosdisk");
- drive_dev->id = drive - 0x80;
- drive_dev->resource[0].start = 0;
- drive_dev->platform_data = p;
-
- register_device(drive_dev);
+ /* create partitions on demand */
+ rc = parse_partition_table(&m->blk);
+ if (rc != 0)
+ dev_warn(dev, "No partition table found\n");
}
return 0;
diff --git a/drivers/ata/disk_drive.c b/drivers/ata/disk_drive.c
deleted file mode 100644
index a9d0dee..0000000
--- a/drivers/ata/disk_drive.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * Copyright (C) 2009 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
- *
- */
-
-/**
- * @file
- * @brief Generic disk drive support
- *
- * @todo Support for disks larger than 4 GiB
- * @todo Reliable size detection for BIOS based disks (on x86 only)
- */
-
-#include <stdio.h>
-#include <init.h>
-#include <driver.h>
-#include <types.h>
-#include <ata.h>
-#include <xfuncs.h>
-#include <errno.h>
-#include <string.h>
-#include <linux/kernel.h>
-#include <malloc.h>
-#include <common.h>
-#include <block.h>
-#include <asm/unaligned.h>
-
-/**
- * Description of one partition table entry (D*S type)
- */
-struct partition_entry {
- uint8_t boot_indicator;
- uint8_t chs_begin[3];
- uint8_t type;
- uint8_t chs_end[3];
- uint32_t partition_start;
- uint32_t partition_size;
-} __attribute__ ((packed));
-
-/** one for all */
-#define SECTOR_SIZE 512
-
-/**
- * Guess the size of the disk, based on the partition table entries
- * @param dev device to create partitions for
- * @param table partition table
- * @return size in sectors
- */
-#ifdef CONFIG_ATA_BIOS
-static unsigned long disk_guess_size(struct device_d *dev, struct partition_entry *table)
-{
- int part_order[4] = {0, 1, 2, 3};
- unsigned long size = 0;
- int i;
-
- /* TODO order the partitions */
-
- for (i = 0; i < 4; i++) {
- if (table[part_order[i]].partition_start != 0) {
- size += table[part_order[i]].partition_start - size; /* the gap */
- size += table[part_order[i]].partition_size;
- }
- }
-#if 1
-/* limit disk sizes we can't handle due to 32 bit limits */
- if (size > 0x7fffff) {
- dev_warn(dev, "Warning: Size limited due to 32 bit contraints\n");
- size = 0x7fffff;
- }
-#endif
- return size;
-}
-#endif
-
-/**
- * Register partitions found on the drive
- * @param dev device to create partitions for
- * @param table partition table
- * @return 0 on success
- */
-static int disk_register_partitions(struct device_d *dev, struct partition_entry *table)
-{
- int part_order[4] = {0, 1, 2, 3};
- int i, rc;
- char drive_name[16], partition_name[19];
- u32 partition_start, partition_size;
-
- /* TODO order the partitions */
-
- for (i = 0; i < 4; i++) {
- partition_start = get_unaligned(&table[part_order[i]].partition_start);
- partition_size = get_unaligned(&table[part_order[i]].partition_size);
-
- sprintf(drive_name, "%s%d", dev->name, dev->id);
- sprintf(partition_name, "%s%d.%d", dev->name, dev->id, i);
- if (partition_start != 0) {
-#if 1
-/* ignore partitions we can't handle due to 32 bit limits */
- if (partition_start > 0x7fffff)
- continue;
- if (partition_size > 0x7fffff)
- continue;
-#endif
- dev_dbg(dev, "Registering partition %s to drive %s\n",
- partition_name, drive_name);
- rc = devfs_add_partition(drive_name,
- partition_start * SECTOR_SIZE,
- partition_size * SECTOR_SIZE,
- DEVFS_PARTITION_FIXED, partition_name);
- if (rc != 0)
- dev_err(dev, "Failed to register partition %s (%d)\n", partition_name, rc);
- }
- }
-
- return 0;
-}
-
-struct ata_block_device {
- struct block_device blk;
- struct device_d *dev;
- struct ata_interface *intf;
-};
-
-static int atablk_read(struct block_device *blk, void *buf, int block,
- int num_blocks)
-{
- struct ata_block_device *atablk = container_of(blk, struct ata_block_device, blk);
-
- return atablk->intf->read(atablk->dev, block, num_blocks, buf);
-}
-
-#ifdef CONFIG_ATA_WRITE
-static int atablk_write(struct block_device *blk, const void *buf, int block,
- int num_blocks)
-{
- struct ata_block_device *atablk = container_of(blk, struct ata_block_device, blk);
-
- return atablk->intf->write(atablk->dev, block, num_blocks, buf);
-}
-#endif
-
-static struct block_device_ops ataops = {
- .read = atablk_read,
-#ifdef CONFIG_ATA_WRITE
- .write = atablk_write,
-#endif
-};
-
-/**
- * Probe the connected disk drive
- */
-static int disk_probe(struct device_d *dev)
-{
- uint8_t *sector;
- int rc;
- struct ata_interface *intf = dev->platform_data;
- struct ata_block_device *atablk = xzalloc(sizeof(*atablk));
-
- sector = xmalloc(SECTOR_SIZE);
-
- rc = intf->read(dev, 0, 1, sector);
- if (rc != 0) {
- dev_err(dev, "Cannot read MBR of this device\n");
- rc = -ENODEV;
- goto on_error;
- }
-
- /*
- * BIOS based disks needs special handling. Not the driver can
- * enumerate the hardware, the BIOS did it already. To show the user
- * the drive ordering must not correspond to the Linux drive order,
- * use the 'biosdisk' name instead.
- */
-#ifdef CONFIG_ATA_BIOS
- if (strcmp(dev->driver->name, "biosdisk") == 0)
- atablk->blk.cdev.name = asprintf("biosdisk%d", dev->id);
- else
-#endif
- atablk->blk.cdev.name = asprintf("disk%d", dev->id);
-
-#ifdef CONFIG_ATA_BIOS
- /* On x86, BIOS based disks are coming without a valid .size field */
- if (dev->resource[0].size == 0) {
- /* guess the size of this drive if not otherwise given */
- dev->resource[0].size = disk_guess_size(dev,
- (struct partition_entry*)&sector[446]) * SECTOR_SIZE;
- dev_info(dev, "Drive size guessed to %u kiB\n", dev->resource[0].size / 1024);
- }
-#endif
- atablk->blk.num_blocks = dev->resource[0].size / SECTOR_SIZE;
- atablk->blk.ops = &ataops;
- atablk->blk.blockbits = 9;
- atablk->blk.dev = dev;
- atablk->dev = dev;
- atablk->intf = intf;
- blockdevice_register(&atablk->blk);
-
- if ((sector[510] != 0x55) || (sector[511] != 0xAA)) {
- dev_info(dev, "No partition table found\n");
- rc = 0;
- goto on_error;
- }
-
-
- rc = disk_register_partitions(dev, (struct partition_entry*)&sector[446]);
-
-on_error:
- free(sector);
- return rc;
-}
-
-#ifdef CONFIG_ATA_BIOS
-static struct driver_d biosdisk_driver = {
- .name = "biosdisk",
- .probe = disk_probe,
-};
-#endif
-
-static struct driver_d disk_driver = {
- .name = "disk",
- .probe = disk_probe,
-};
-
-static int disk_init(void)
-{
-#ifdef CONFIG_ATA_BIOS
- register_driver(&biosdisk_driver);
-#endif
- register_driver(&disk_driver);
- return 0;
-}
-
-device_initcall(disk_init);
diff --git a/drivers/ata/intf_platform_ide.c b/drivers/ata/intf_platform_ide.c
new file mode 100644
index 0000000..1955a9c
--- /dev/null
+++ b/drivers/ata/intf_platform_ide.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2011 Juergen Beisert, Pengutronix
+ *
+ * Derived from the Linux kernel: Generic platform device PATA driver
+ * Copyright (C) 2006 - 2007 Paul Mundt
+ * Based on pata_pcmcia:
+ * Copyright 2005-2006 Red Hat Inc, all rights reserved.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * 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 <init.h>
+#include <xfuncs.h>
+#include <malloc.h>
+#include <errno.h>
+#include <ata_drive.h>
+#include <platform_ide.h>
+
+/**
+ * Setup the register specific addresses for an ATA like divice
+ * @param reg_base Base address of the standard ATA like registers
+ * @param alt_base Base address of the alternate ATA like registers
+ * @param ioaddr Register file structure to setup
+ * @param shift Shift offset between registers
+ *
+ * Some of the registers have different names but use the same offset. This is
+ * due to the fact read or write access at the same offset reaches different
+ * registers.
+ */
+static void platform_ide_setup_port(void *reg_base, void *alt_base,
+ struct ata_ioports *ioaddr, unsigned shift)
+{
+ /* standard registers (0 ... 7) */
+ ioaddr->cmd_addr = reg_base;
+
+ ioaddr->data_addr = reg_base + (IDE_REG_DATA << shift);
+
+ ioaddr->error_addr = reg_base + (IDE_REG_ERR << shift);
+ ioaddr->feature_addr = reg_base + (IDE_REG_FEATURE << shift);
+
+ ioaddr->nsect_addr = reg_base + (IDE_REG_NSECT << shift);
+
+ ioaddr->lbal_addr = reg_base + (IDE_REG_LBAL << shift);
+
+ ioaddr->lbam_addr = reg_base + (IDE_REG_LBAM << shift);
+
+ ioaddr->lbah_addr = reg_base + (IDE_REG_LBAH << shift);
+
+ ioaddr->device_addr = reg_base + (IDE_REG_DEVICE << shift);
+
+ ioaddr->status_addr = reg_base + (IDE_REG_STATUS << shift);
+ ioaddr->command_addr = reg_base + (IDE_REG_CMD << shift);
+
+ ioaddr->altstatus_addr = alt_base + (IDE_REG_ALT_STATUS << shift);
+ ioaddr->ctl_addr = alt_base + (IDE_REG_DEV_CTL << shift);
+
+ ioaddr->alt_dev_addr = alt_base + (IDE_REG_DRV_ADDR << shift);
+}
+
+static int platform_ide_probe(struct device_d *dev)
+{
+ int rc;
+ struct ide_port_info *pdata = dev->platform_data;
+ struct ata_ioports *io;
+ void *reg_base, *alt_base;
+
+ if (pdata == NULL) {
+ dev_err(dev, "No platform data. Cannot continue\n");
+ return -EINVAL;
+ }
+
+ io = xzalloc(sizeof(struct ata_ioports));
+ reg_base = dev_request_mem_region(dev, 0);
+ alt_base = dev_request_mem_region(dev, 1);
+ platform_ide_setup_port(reg_base, alt_base, io, pdata->ioport_shift);
+ io->reset = pdata->reset;
+ io->dataif_be = pdata->dataif_be;
+
+ rc = register_ata_drive(dev, io);
+ if (rc != 0) {
+ dev_err(dev, "Cannot register IDE interface\n");
+ free(io);
+ }
+
+ return rc;
+}
+
+static struct driver_d platform_ide_driver = {
+ .name = "ide_intf",
+ .probe = platform_ide_probe,
+};
+
+static int platform_ide_init(void)
+{
+ return register_driver(&platform_ide_driver);
+}
+
+device_initcall(platform_ide_init);
+
+/**
+ * @file
+ * @brief Interface driver for an ATA drive behind an IDE like interface
+ *
+ * This communication driver does all accesses to the drive via memory IO
+ * instructions.
+ *
+ * This kind of interface is also useable for regular bus like access, when
+ * there is no dedicated IDE available.
+ *
+ * "IDE like" means the platform data defines addresses to the register file
+ * of the attached ATA drive.
+ *
+ * This driver does not change any access timings due to the fact it has no idea
+ * how to do so. So, do not expect an impressive data throughput.
+ *
+ * @todo Support also the IO port access method, the x86 architecture is using
+ */
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 0b80103..0132e7d 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -214,7 +214,7 @@ int register_driver(struct driver_d *drv)
}
EXPORT_SYMBOL(register_driver);
-void __iomem *dev_get_mem_region(struct device_d *dev, int num)
+static struct resource *dev_get_resource(struct device_d *dev, int num)
{
int i, n = 0;
@@ -222,15 +222,40 @@ void __iomem *dev_get_mem_region(struct device_d *dev, int num)
struct resource *res = &dev->resource[i];
if (resource_type(res) == IORESOURCE_MEM) {
if (n == num)
- return (void __force __iomem *)res->start;
+ return res;
n++;
}
}
return NULL;
}
+
+void __iomem *dev_get_mem_region(struct device_d *dev, int num)
+{
+ struct resource *res;
+
+ res = dev_get_resource(dev, num);
+ if (!res)
+ return res;
+
+ return (void __force __iomem *)res->start;
+}
EXPORT_SYMBOL(dev_get_mem_region);
+void __iomem *dev_request_mem_region(struct device_d *dev, int num)
+{
+ struct resource *res;
+
+ res = dev_get_resource(dev, num);
+ if (!res)
+ return NULL;
+
+ res = request_iomem_region(dev_name(dev), res->start, res->size);
+
+ return (void __force __iomem *)res->start;
+}
+EXPORT_SYMBOL(dev_request_mem_region);
+
int dev_protect(struct device_d *dev, size_t count, unsigned long offset, int prot)
{
printf("%s: currently broken\n", __func__);
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 0d5a0e0..6ed21cd 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -1,7 +1,6 @@
menuconfig MCI
bool "MCI drivers "
- select ATA
- select ATA_DISK
+ select DISK
help
Add support for MCI drivers, used to handle MMC and SD cards
@@ -28,7 +27,7 @@ config MCI_INFO
config MCI_WRITE
bool "Support writing to MCI cards"
default y
- select ATA_WRITE
+ select DISK_WRITE
comment "--- MCI host drivers ---"
@@ -80,4 +79,22 @@ config MCI_ATMEL
Enable this entry to add support to read and write SD cards on a
Atmel AT91.
+config MCI_SPI
+ bool "MMC/SD over SPI"
+ depends on SPI
+ help
+ Some systems access MMC/SD/SDIO cards using a SPI controller
+ instead of using a "native" MMC/SD/SDIO controller. This has a
+ disadvantage of being relatively high overhead, but a compensating
+ advantage of working on many systems without dedicated MMC/SD/SDIO
+ controllers.
+
+config MMC_SPI_CRC_ON
+ bool "Enable CRC protection for transfers"
+ select CRC7
+ select CRC16
+ depends on MCI_SPI
+ help
+ Enable CRC protection for transfers
+
endif
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index 4fc0046..d7482dc 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_MCI_IMX) += imx.o
obj-$(CONFIG_MCI_IMX_ESDHC) += imx-esdhc.o
obj-$(CONFIG_MCI_OMAP_HSMMC) += omap_hsmmc.o
obj-$(CONFIG_MCI_ATMEL) += atmel_mci.o
+obj-$(CONFIG_MCI_SPI) += mci_spi.o
diff --git a/drivers/mci/atmel_mci.c b/drivers/mci/atmel_mci.c
index 4a29cad..15668fc 100644
--- a/drivers/mci/atmel_mci.c
+++ b/drivers/mci/atmel_mci.c
@@ -369,6 +369,8 @@ static void mci_set_ios(struct mci_host *mci, struct device_d *mci_dev,
atmel_mci_writel(host, AT91_MCI_SDCR, AT91_MCI_SDCBUS_1BIT);
break;
}
+ atmel_mci_writel(host, AT91_MCI_SDCR, atmel_mci_readl(host, AT91_MCI_SDCR)
+ | host->hw_dev->id);
if (clock) {
atmel_set_clk_rate(host, clock);
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index a0e61f0..fe55697 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -36,6 +36,8 @@
#include <asm/mmu.h>
#include <mach/clock.h>
#include <mach/generic.h>
+#include <mach/esdhc.h>
+#include <gpio.h>
#include "imx-esdhc.h"
@@ -107,7 +109,8 @@ u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
xfertyp |= XFERTYP_RSPTYP_48_BUSY;
else if (cmd->resp_type & MMC_RSP_PRESENT)
xfertyp |= XFERTYP_RSPTYP_48;
- if (cpu_is_mx53() && cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
+ if ((cpu_is_mx51() || cpu_is_mx53()) &&
+ cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
xfertyp |= SDHCI_CMD_ABORTCMD;
return XFERTYP_CMD(cmd->cmdidx) | xfertyp;
@@ -391,6 +394,31 @@ static void esdhc_set_ios(struct mci_host *mci, struct device_d *dev,
}
+static int esdhc_card_detect(struct fsl_esdhc_host *host)
+{
+ struct fsl_esdhc *regs = host->regs;
+ struct esdhc_platform_data *pdata = host->dev->platform_data;
+ int ret;
+
+ if (!pdata)
+ return 1;
+
+ switch (pdata->cd_type) {
+ case ESDHC_CD_NONE:
+ case ESDHC_CD_PERMANENT:
+ return 1;
+ case ESDHC_CD_CONTROLLER:
+ return !(esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL);
+ case ESDHC_CD_GPIO:
+ ret = gpio_direction_input(pdata->cd_gpio);
+ if (ret)
+ return ret;
+ return gpio_get_value(pdata->cd_gpio) ? 0 : 1;
+ }
+
+ return 0;
+}
+
static int esdhc_init(struct mci_host *mci, struct device_d *dev)
{
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
@@ -398,6 +426,16 @@ static int esdhc_init(struct mci_host *mci, struct device_d *dev)
int timeout = 1000;
int ret = 0;
+ ret = esdhc_card_detect(host);
+
+ if (ret == 0)
+ return -ENODEV;
+
+ if (ret < 0)
+ return ret;
+
+ ret = 0;
+
/* Enable cache snooping */
if (host && !host->no_snoop)
esdhc_write32(&regs->scr, 0x00000040);
@@ -484,7 +522,6 @@ static int fsl_esdhc_probe(struct device_d *dev)
host->mci.send_cmd = esdhc_send_cmd;
host->mci.set_ios = esdhc_set_ios;
host->mci.init = esdhc_init;
- host->mci.host_caps = MMC_MODE_4BIT;
host->mci.hw_dev = dev;
host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 09f7e29..e9fe87c 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -36,7 +36,8 @@
#include <errno.h>
#include <asm-generic/div64.h>
#include <asm/byteorder.h>
-#include <ata.h>
+#include <block.h>
+#include <disks.h>
#define MAX_BUFFER_NUMBER 0xffffffff
@@ -104,15 +105,23 @@ static void *sector_buf;
* @param mci_dev MCI instance
* @param src Where to read from to write to the card
* @param blocknum Block number to write
+ * @param blocks Block count to write
* @return Transaction status (0 on success)
*/
-#ifdef CONFIG_MCI_WRITE
-static int mci_block_write(struct device_d *mci_dev, const void *src, unsigned blocknum)
+static int mci_block_write(struct device_d *mci_dev, const void *src, int blocknum,
+ int blocks)
{
struct mci *mci = GET_MCI_DATA(mci_dev);
struct mci_cmd cmd;
struct mci_data data;
const void *buf;
+ unsigned mmccmd;
+ int ret;
+
+ if (blocks > 1)
+ mmccmd = MMC_CMD_WRITE_MULTIPLE_BLOCK;
+ else
+ mmccmd = MMC_CMD_WRITE_SINGLE_BLOCK;
if ((unsigned long)src & 0x3) {
memcpy(sector_buf, src, 512);
@@ -122,18 +131,30 @@ static int mci_block_write(struct device_d *mci_dev, const void *src, unsigned b
}
mci_setup_cmd(&cmd,
- MMC_CMD_WRITE_SINGLE_BLOCK,
+ mmccmd,
mci->high_capacity != 0 ? blocknum : blocknum * mci->write_bl_len,
MMC_RSP_R1);
data.src = buf;
- data.blocks = 1;
+ data.blocks = blocks;
data.blocksize = mci->write_bl_len;
data.flags = MMC_DATA_WRITE;
- return mci_send_cmd(mci_dev, &cmd, &data);
+ ret = mci_send_cmd(mci_dev, &cmd, &data);
+ if (ret)
+ return ret;
+
+ if (blocks > 1) {
+ mci_setup_cmd(&cmd,
+ MMC_CMD_STOP_TRANSMISSION,
+ 0, MMC_RSP_R1b);
+ ret = mci_send_cmd(mci_dev, &cmd, NULL);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
}
-#endif
/**
* Read one block of data from the card
@@ -142,7 +163,7 @@ static int mci_block_write(struct device_d *mci_dev, const void *src, unsigned b
* @param blocknum Block number to read
* @param blocks number of blocks to read
*/
-static int mci_read_block(struct device_d *mci_dev, void *dst, unsigned blocknum,
+static int mci_read_block(struct device_d *mci_dev, void *dst, int blocknum,
int blocks)
{
struct mci *mci = GET_MCI_DATA(mci_dev);
@@ -218,6 +239,7 @@ static int sd_send_op_cond(struct device_d *mci_dev)
int timeout = 1000;
int err;
unsigned voltages;
+ unsigned busy;
/*
* Most cards do not answer if some reserved bits
@@ -237,7 +259,7 @@ static int sd_send_op_cond(struct device_d *mci_dev)
}
mci_setup_cmd(&cmd, SD_CMD_APP_SEND_OP_COND,
- voltages | (mci->version == SD_VERSION_2 ? OCR_HCS : 0),
+ mmc_host_is_spi(host) ? 0 : (voltages | (mci->version == SD_VERSION_2 ? OCR_HCS : 0)),
MMC_RSP_R3);
err = mci_send_cmd(mci_dev, &cmd, NULL);
if (err) {
@@ -245,7 +267,13 @@ static int sd_send_op_cond(struct device_d *mci_dev)
return err;
}
udelay(1000);
- } while ((!(cmd.response[0] & OCR_BUSY)) && timeout--);
+
+ if (mmc_host_is_spi(host))
+ busy = cmd.response[0] & R1_SPI_IDLE;
+ else
+ busy = !(cmd.response[0] & OCR_BUSY);
+
+ } while (busy && timeout--);
if (timeout <= 0) {
pr_debug("SD operation condition set timed out\n");
@@ -255,6 +283,13 @@ static int sd_send_op_cond(struct device_d *mci_dev)
if (mci->version != SD_VERSION_2)
mci->version = SD_VERSION_1_0;
+ if (mmc_host_is_spi(host)) { /* read OCR for spi */
+ mci_setup_cmd(&cmd, MMC_CMD_SPI_READ_OCR, 0, MMC_RSP_R3);
+ err = mci_send_cmd(mci_dev, &cmd, NULL);
+ if (err)
+ return err;
+ }
+
mci->ocr = cmd.response[0];
mci->high_capacity = ((mci->ocr & OCR_HCS) == OCR_HCS);
@@ -453,11 +488,17 @@ static int sd_change_freq(struct device_d *mci_dev)
struct mci *mci = GET_MCI_DATA(mci_dev);
struct mci_cmd cmd;
struct mci_data data;
+#ifdef CONFIG_MCI_SPI
+ struct mci_host *host = GET_MCI_PDATA(mci_dev);
+#endif
uint32_t *switch_status = sector_buf;
uint32_t *scr = sector_buf;
int timeout;
int err;
+ if (mmc_host_is_spi(host))
+ return 0;
+
pr_debug("Changing transfer frequency\n");
mci->card_caps = 0;
@@ -748,10 +789,23 @@ static int mci_startup(struct device_d *mci_dev)
struct mci_cmd cmd;
int err;
+#ifdef CONFIG_MMC_SPI_CRC_ON
+ if (mmc_host_is_spi(host)) { /* enable CRC check for spi */
+
+ mci_setup_cmd(&cmd, MMC_CMD_SPI_CRC_ON_OFF, 1, MMC_RSP_R1);
+ err = mci_send_cmd(mci_dev, &cmd, NULL);
+
+ if (err) {
+ pr_debug("Can't enable CRC check : %d\n", err);
+ return err;
+ }
+ }
+#endif
+
pr_debug("Put the Card in Identify Mode\n");
/* Put the Card in Identify Mode */
- mci_setup_cmd(&cmd, MMC_CMD_ALL_SEND_CID, 0, MMC_RSP_R2);
+ mci_setup_cmd(&cmd, mmc_host_is_spi(host) ? MMC_CMD_SEND_CID : MMC_CMD_ALL_SEND_CID, 0, MMC_RSP_R2);
err = mci_send_cmd(mci_dev, &cmd, NULL);
if (err) {
pr_debug("Can't bring card into identify mode: %d\n", err);
@@ -768,12 +822,14 @@ static int mci_startup(struct device_d *mci_dev)
* For SD cards, get the Relatvie Address.
* This also puts the cards into Standby State
*/
- pr_debug("Get/Set relative address\n");
- mci_setup_cmd(&cmd, SD_CMD_SEND_RELATIVE_ADDR, mci->rca << 16, MMC_RSP_R6);
- err = mci_send_cmd(mci_dev, &cmd, NULL);
- if (err) {
- pr_debug("Get/Set relative address failed: %d\n", err);
- return err;
+ if (!mmc_host_is_spi(host)) { /* cmd not supported in spi */
+ pr_debug("Get/Set relative address\n");
+ mci_setup_cmd(&cmd, SD_CMD_SEND_RELATIVE_ADDR, mci->rca << 16, MMC_RSP_R6);
+ err = mci_send_cmd(mci_dev, &cmd, NULL);
+ if (err) {
+ pr_debug("Get/Set relative address failed: %d\n", err);
+ return err;
+ }
}
if (IS_SD(mci))
@@ -800,27 +856,29 @@ static int mci_startup(struct device_d *mci_dev)
mci_extract_card_capacity_from_csd(mci_dev);
/* sanitiy? */
- if (mci->read_bl_len > 512) {
- mci->read_bl_len = 512;
+ if (mci->read_bl_len > SECTOR_SIZE) {
+ mci->read_bl_len = SECTOR_SIZE;
pr_debug("Limiting max. read block size down to %u\n",
mci->read_bl_len);
}
- if (mci->write_bl_len > 512) {
- mci->write_bl_len = 512;
+ if (mci->write_bl_len > SECTOR_SIZE) {
+ mci->write_bl_len = SECTOR_SIZE;
pr_debug("Limiting max. write block size down to %u\n",
mci->read_bl_len);
}
pr_debug("Read block length: %u, Write block length: %u\n",
mci->read_bl_len, mci->write_bl_len);
- pr_debug("Select the card, and put it into Transfer Mode\n");
- /* Select the card, and put it into Transfer Mode */
- mci_setup_cmd(&cmd, MMC_CMD_SELECT_CARD, mci->rca << 16, MMC_RSP_R1b);
- err = mci_send_cmd(mci_dev, &cmd, NULL);
- if (err) {
- pr_debug("Putting in transfer mode failed: %d\n", err);
- return err;
+ if (!mmc_host_is_spi(host)) { /* cmd not supported in spi */
+ pr_debug("Select the card, and put it into Transfer Mode\n");
+ /* Select the card, and put it into Transfer Mode */
+ mci_setup_cmd(&cmd, MMC_CMD_SELECT_CARD, mci->rca << 16, MMC_RSP_R1b);
+ err = mci_send_cmd(mci_dev, &cmd, NULL);
+ if (err) {
+ pr_debug("Putting in transfer mode failed: %d\n", err);
+ return err;
+ }
}
if (IS_SD(mci))
@@ -936,77 +994,68 @@ static int sd_send_if_cond(struct device_d *mci_dev)
return 0;
}
-/* ------------------ attach to the ATA API --------------------------- */
+/* ------------------ attach to the blocklayer --------------------------- */
/**
* Write a chunk of sectors to media
- * @param disk_dev Disk device instance
- * @param sector_start Sector's number to start write to
- * @param sector_count Sectors to write
+ * @param blk All info about the block device we need
* @param buffer Buffer to write from
+ * @param block Sector's number to start write to
+ * @param num_blocks Sector count to write
* @return 0 on success, anything else on failure
*
* This routine expects the buffer has the correct size to read all data!
*/
-#ifdef CONFIG_MCI_WRITE
-static int mci_sd_write(struct device_d *disk_dev, uint64_t sector_start,
- unsigned sector_count, const void *buffer)
+static int __maybe_unused mci_sd_write(struct block_device *blk,
+ const void *buffer, int block, int num_blocks)
{
- struct ata_interface *intf = disk_dev->platform_data;
- struct device_d *mci_dev = intf->priv;
+ struct device_d *mci_dev = blk->dev;
struct mci *mci = GET_MCI_DATA(mci_dev);
int rc;
- pr_debug("%s: Write %u block(s), starting at %u\n",
- __func__, sector_count, (unsigned)sector_start);
+ pr_debug("%s: Write %d block(s), starting at %d\n",
+ __func__, num_blocks, block);
- if (mci->write_bl_len != 512) {
- pr_debug("MMC/SD block size is not 512 bytes (its %u bytes instead)\n",
- mci->read_bl_len);
+ if (mci->write_bl_len != SECTOR_SIZE) {
+ pr_debug("MMC/SD block size is not %d bytes (its %u bytes instead)\n",
+ SECTOR_SIZE, mci->read_bl_len);
return -EINVAL;
}
- while (sector_count) {
- /* size of the block number field in the MMC/SD command is 32 bit only */
- if (sector_start > MAX_BUFFER_NUMBER) {
- pr_debug("Cannot handle block number %llu. Too large!\n",
- sector_start);
- return -EINVAL;
- }
- rc = mci_block_write(mci_dev, buffer, sector_start);
- if (rc != 0) {
- pr_debug("Writing block %u failed with %d\n", (unsigned)sector_start, rc);
- return rc;
- }
- sector_count--;
- buffer += mci->write_bl_len;
- sector_start++;
+ /* size of the block number field in the MMC/SD command is 32 bit only */
+ if (block > MAX_BUFFER_NUMBER) {
+ pr_debug("Cannot handle block number %d. Too large!\n", block);
+ return -EINVAL;
+ }
+
+ rc = mci_block_write(mci_dev, buffer, block, num_blocks);
+ if (rc != 0) {
+ pr_debug("Writing block %d failed with %d\n", block, rc);
+ return rc;
}
return 0;
}
-#endif
/**
- * Read a chunk of sectors from media
- * @param disk_dev Disk device instance
- * @param sector_start Sector's number to start read from
- * @param sector_count Sectors to read
+ * Read a chunk of sectors from the drive
+ * @param blk All info about the block device we need
* @param buffer Buffer to read into
+ * @param block Sector's LBA number to start read from
+ * @param num_blocks Sector count to read
* @return 0 on success, anything else on failure
*
* This routine expects the buffer has the correct size to store all data!
*/
-static int mci_sd_read(struct device_d *disk_dev, uint64_t sector_start,
- unsigned sector_count, void *buffer)
+static int mci_sd_read(struct block_device *blk, void *buffer, int block,
+ int num_blocks)
{
- struct ata_interface *intf = disk_dev->platform_data;
- struct device_d *mci_dev = intf->priv;
+ struct device_d *mci_dev = blk->dev;
struct mci *mci = GET_MCI_DATA(mci_dev);
int rc;
- pr_debug("%s: Read %u block(s), starting at %u\n",
- __func__, sector_count, (unsigned)sector_start);
+ pr_debug("%s: Read %d block(s), starting at %d\n",
+ __func__, num_blocks, block);
if (mci->read_bl_len != 512) {
pr_debug("MMC/SD block size is not 512 bytes (its %u bytes instead)\n",
@@ -1014,21 +1063,15 @@ static int mci_sd_read(struct device_d *disk_dev, uint64_t sector_start,
return -EINVAL;
}
- while (sector_count) {
- int now = min(sector_count, 32U);
- if (sector_start > MAX_BUFFER_NUMBER) {
- pr_err("Cannot handle block number %u. Too large!\n",
- (unsigned)sector_start);
- return -EINVAL;
- }
- rc = mci_read_block(mci_dev, buffer, (unsigned)sector_start, now);
- if (rc != 0) {
- pr_debug("Reading block %u failed with %d\n", (unsigned)sector_start, rc);
- return rc;
- }
- sector_count -= now;
- buffer += mci->read_bl_len * now;
- sector_start += now;
+ if (block > MAX_BUFFER_NUMBER) {
+ pr_err("Cannot handle block number %d. Too large!\n", block);
+ return -EINVAL;
+ }
+
+ rc = mci_read_block(mci_dev, buffer, block, num_blocks);
+ if (rc != 0) {
+ pr_debug("Reading block %d failed with %d\n", block, rc);
+ return rc;
}
return 0;
@@ -1166,6 +1209,25 @@ static int mci_check_if_already_initialized(struct device_d *mci_dev)
return 0;
}
+static int mci_calc_blk_cnt(uint64_t cap, unsigned shift)
+{
+ unsigned ret = cap >> shift;
+
+ if (ret > 0x7fffffff) {
+ pr_warn("Limiting card size due to 31 bit contraints\n");
+ return 0x7fffffff;
+ }
+
+ return (int)ret;
+}
+
+static struct block_device_ops mci_ops = {
+ .read = mci_sd_read,
+#ifdef CONFIG_BLOCK_WRITE
+ .write = mci_sd_write,
+#endif
+};
+
/**
* Probe an MCI card at the given host interface
* @param mci_dev MCI device instance
@@ -1175,9 +1237,7 @@ static int mci_card_probe(struct device_d *mci_dev)
{
struct mci *mci = GET_MCI_DATA(mci_dev);
struct mci_host *host = GET_MCI_PDATA(mci_dev);
- struct ata_interface *p;
int rc;
- struct device_d *dev;
/* start with a host interface reset */
rc = (host->init)(host, mci_dev);
@@ -1221,16 +1281,29 @@ static int mci_card_probe(struct device_d *mci_dev)
* An MMC/SD card acts like an ordinary disk.
* So, re-use the disk driver to gain access to this media
*/
- p = xzalloc(sizeof(struct ata_interface));
+ mci->blk.dev = mci_dev;
+ mci->blk.ops = &mci_ops;
-#ifdef CONFIG_MCI_WRITE
- p->write = mci_sd_write;
-#endif
- p->read = mci_sd_read;
- p->priv = mci_dev;
+ rc = cdev_find_free_index("disk");
+ if (rc == -1)
+ pr_err("Cannot find a free number for the disk node\n");
- dev = add_generic_device("disk", -1, NULL, 0, mci->capacity, IORESOURCE_MEM, p);
- dev_add_child(&host->dev, dev);
+ mci->blk.cdev.name = asprintf("disk%d", rc);
+ mci->blk.blockbits = SECTOR_SHIFT;
+ mci->blk.num_blocks = mci_calc_blk_cnt(mci->capacity, mci->blk.blockbits);
+
+ rc = blockdevice_register(&mci->blk);
+ if (rc != 0) {
+ dev_err(mci_dev, "Failed to register MCI/SD blockdevice\n");
+ goto on_error;
+ }
+
+ /* create partitions on demand */
+ rc = parse_partition_table(&mci->blk);
+ if (rc != 0) {
+ dev_warn(mci_dev, "No partition table found\n");
+ rc = 0; /* it's not a failure */
+ }
pr_debug("SD Card successfully added\n");
@@ -1307,7 +1380,7 @@ static int mci_probe(struct device_d *mci_dev)
#ifdef CONFIG_MCI_STARTUP
/* if enabled, probe the attached card immediately */
rc = mci_card_probe(mci_dev);
- if (rc == -ENODEV) {
+ if (rc) {
/*
* If it fails, add the 'probe' parameter to give the user
* a chance to insert a card and try again. Note: This may fail
@@ -1361,8 +1434,9 @@ device_initcall(mci_init);
*/
int mci_register(struct mci_host *host)
{
- struct device_d *mci_dev = &host->dev;
+ struct device_d *mci_dev = xzalloc(sizeof(struct device_d));
+ mci_dev->id = -1;
strcpy(mci_dev->name, mci_driver.name);
mci_dev->platform_data = (void*)host;
dev_add_child(host->hw_dev, mci_dev);
diff --git a/drivers/mci/mci_spi.c b/drivers/mci/mci_spi.c
new file mode 100644
index 0000000..653910b
--- /dev/null
+++ b/drivers/mci/mci_spi.c
@@ -0,0 +1,430 @@
+/*
+ * (C) Copyright 2011 - Franck JULLIEN <elec4fun@gmail.com>
+ *
+ * This code was inspired from u-boot mmc_spi.c:
+ * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
+ *
+ * and linux mmc_spi.c:
+ * (C) Copyright 2005, Intec Automation,
+ * Mike Lavender (mike@steroidmicros)
+ * (C) Copyright 2006-2007, David Brownell
+ * (C) Copyright 2007, Axis Communications,
+ * Hans-Peter Nilsson (hp@axis.com)
+ * (C) Copyright 2007, ATRON electronic GmbH,
+ * Jan Nikitenko <jan.nikitenko@gmail.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 <init.h>
+#include <errno.h>
+#include <clock.h>
+#include <asm/io.h>
+#include <driver.h>
+#include <spi/spi.h>
+#include <mci.h>
+#include <crc.h>
+#include <crc7.h>
+
+#define to_spi_host(mci) container_of(mci, struct mmc_spi_host, mci)
+#define spi_setup(spi) spi->master->setup(spi)
+
+/* Response tokens used to ack each block written: */
+#define SPI_MMC_RESPONSE_CODE(x) ((x) & 0x1f)
+#define SPI_RESPONSE_ACCEPTED ((2 << 1)|1)
+
+/* Read and write blocks start with these tokens and end with crc;
+ * on error, read tokens act like a subset of R2_SPI_* values.
+ */
+#define SPI_TOKEN_SINGLE 0xFE /* single block r/w, multiblock read */
+#define SPI_TOKEN_MULTI_WRITE 0xFC /* multiblock write */
+#define SPI_TOKEN_STOP_TRAN 0xFD /* terminate multiblock write */
+
+/* MMC SPI commands start with a start bit "0" and a transmit bit "1" */
+#define MMC_SPI_CMD(x) (0x40 | (x & 0x3F))
+
+#define MMC_SPI_BLOCKSIZE 512
+
+/* timeout value */
+#define CTOUT 8
+#define RTOUT 3000000 /* 1 sec */
+#define WTOUT 3000000 /* 1 sec */
+
+struct mmc_spi_host {
+ struct mci_host mci;
+ struct spi_device *spi;
+ struct device_d *dev;
+
+ /* for bulk data transfers */
+ struct spi_transfer t_tx;
+ struct spi_message m_tx;
+
+ /* for status readback */
+ struct spi_transfer t_rx;
+ struct spi_message m_rx;
+
+ void *ones;
+};
+
+static char *maptype(struct mci_cmd *cmd)
+{
+ switch (cmd->resp_type) {
+ case MMC_RSP_NONE: return "NONE";
+ case MMC_RSP_R1: return "R1";
+ case MMC_RSP_R1b: return "R1B";
+ case MMC_RSP_R2: return "R2/R5";
+ case MMC_RSP_R3: return "R3/R4/R7";
+ default: return "?";
+ }
+}
+
+static inline int mmc_cs_off(struct mmc_spi_host *host)
+{
+ /* chipselect will always be inactive after setup() */
+ return spi_setup(host->spi);
+}
+
+static int
+mmc_spi_readbytes(struct mmc_spi_host *host, unsigned len, void *data)
+{
+ int status;
+
+ host->t_rx.len = len;
+ host->t_rx.rx_buf = data;
+
+ status = spi_sync(host->spi, &host->m_rx);
+
+ return status;
+}
+
+static int
+mmc_spi_writebytes(struct mmc_spi_host *host, unsigned len, void *data)
+{
+ int status;
+
+ host->t_tx.len = len;
+ host->t_tx.tx_buf = data;
+
+ status = spi_sync(host->spi, &host->m_tx);
+
+ return status;
+}
+
+/*
+ * Note that while the CRC, in general, is ignored in SPI mode, the very first
+ * command must be followed by a valid CRC, since the card is not yet in SPI mode.
+ * The CRC byte for a CMD0 command with a zero argument is a constant 0x4A. For
+ * simplicity, this CRC byte is always sent with every command.
+ */
+#define MMC_SPI_CMD0_CRC ((0x4a << 1) | 0x1)
+
+static int mmc_spi_command_send(struct mmc_spi_host *host, struct mci_cmd *cmd)
+{
+ uint8_t r1;
+ uint8_t command[7];
+ int i;
+
+ command[0] = 0xff;
+ command[1] = MMC_SPI_CMD(cmd->cmdidx);
+ command[2] = cmd->cmdarg >> 24;
+ command[3] = cmd->cmdarg >> 16;
+ command[4] = cmd->cmdarg >> 8;
+ command[5] = cmd->cmdarg;
+#ifdef CONFIG_MMC_SPI_CRC_ON
+ command[6] = (crc7(0, &command[1], 5) << 1) | 0x01;
+#else
+ command[6] = MMC_SPI_CMD0_CRC;
+#endif
+
+ mmc_spi_writebytes(host, 7, command);
+
+ for (i = 0; i < CTOUT; i++) {
+ mmc_spi_readbytes(host, 1, &r1);
+ if (i && ((r1 & 0x80) == 0)) { /* r1 response */
+ dev_dbg(host->dev, "%s: CMD%d, TRY %d, RESP %x\n", __func__, cmd->cmdidx, i, r1);
+ break;
+ }
+ }
+
+ return r1;
+}
+
+static uint mmc_spi_readdata(struct mmc_spi_host *host, void *xbuf,
+ uint32_t bcnt, uint32_t bsize)
+{
+ uint8_t *buf = xbuf;
+ uint8_t r1;
+ uint16_t crc;
+ int i;
+
+ while (bcnt--) {
+ for (i = 0; i < RTOUT; i++) {
+ mmc_spi_readbytes(host, 1, &r1);
+ if (r1 != 0xff) /* data token */
+ break;
+ }
+ if (r1 == SPI_TOKEN_SINGLE) {
+ mmc_spi_readbytes(host, bsize, buf);
+ mmc_spi_readbytes(host, 2, &crc);
+#ifdef CONFIG_MMC_SPI_CRC_ON
+ if (swab16(cyg_crc16(buf, bsize)) != crc) {
+ dev_dbg(host->dev, "%s: CRC error\n", __func__);
+ r1 = R1_SPI_COM_CRC;
+ break;
+ }
+#endif
+ r1 = 0;
+ } else {
+ r1 = R1_SPI_ERROR;
+ break;
+ }
+ buf += bsize;
+ }
+
+ return r1;
+}
+
+static uint mmc_spi_writedata(struct mmc_spi_host *host, const void *xbuf,
+ uint32_t bcnt, uint32_t bsize, int multi)
+{
+ const uint8_t *buf = xbuf;
+ uint8_t r1;
+ uint16_t crc = 0;
+ uint8_t tok[2];
+ int i;
+
+ tok[0] = 0xff;
+ tok[1] = multi ? SPI_TOKEN_MULTI_WRITE : SPI_TOKEN_SINGLE;
+
+ while (bcnt--) {
+#ifdef CONFIG_MMC_SPI_CRC_ON
+ crc = swab16(cyg_crc16((u8 *)buf, bsize));
+#endif
+ mmc_spi_writebytes(host, 2, tok);
+ mmc_spi_writebytes(host, bsize, (void *)buf);
+ mmc_spi_writebytes(host, 2, &crc);
+
+ for (i = 0; i < CTOUT; i++) {
+ mmc_spi_readbytes(host, 1, &r1);
+ if ((r1 & 0x11) == 0x01) /* response token */
+ break;
+ }
+
+ dev_dbg(host->dev,"%s : TOKEN%d RESP 0x%X\n", __func__, i, r1);
+ if (SPI_MMC_RESPONSE_CODE(r1) == SPI_RESPONSE_ACCEPTED) {
+ for (i = 0; i < WTOUT; i++) { /* wait busy */
+ mmc_spi_readbytes(host, 1, &r1);
+ if (i && r1 == 0xff) {
+ r1 = 0;
+ break;
+ }
+ }
+ if (i == WTOUT) {
+ dev_dbg(host->dev, "%s: wtout %x\n", __func__, r1);
+ r1 = R1_SPI_ERROR;
+ break;
+ }
+ } else {
+ dev_dbg(host->dev, "%s: err %x\n", __func__, r1);
+ r1 = R1_SPI_COM_CRC;
+ break;
+ }
+ buf += bsize;
+ }
+
+ if (multi && bcnt == -1) { /* stop multi write */
+ tok[1] = SPI_TOKEN_STOP_TRAN;
+ mmc_spi_writebytes(host, 2, tok);
+ for (i = 0; i < WTOUT; i++) { /* wait busy */
+ mmc_spi_readbytes(host, 1, &r1);
+ if (i && r1 == 0xff) {
+ r1 = 0;
+ break;
+ }
+ }
+ if (i == WTOUT) {
+ dev_dbg(host->dev, "%s: wstop %x\n", __func__, r1);
+ r1 = R1_SPI_ERROR;
+ }
+ }
+
+ return r1;
+}
+
+static int mmc_spi_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
+{
+ struct mmc_spi_host *host = to_spi_host(mci);
+ uint8_t r1;
+ int i;
+ int ret = 0;
+
+ dev_dbg(host->dev, "%s : CMD%02d, RESP %s, ARG 0x%X\n", __func__,
+ cmd->cmdidx, maptype(cmd), cmd->cmdarg);
+
+ r1 = mmc_spi_command_send(host, cmd);
+
+ cmd->response[0] = r1;
+
+ if (r1 == 0xff) { /* no response */
+ ret = -ETIME;
+ goto done;
+ } else if (r1 & R1_SPI_COM_CRC) {
+ ret = -ECOMM;
+ goto done;
+ } else if (r1 & ~R1_SPI_IDLE) { /* other errors */
+ ret = -ETIME;
+ goto done;
+ } else if (cmd->resp_type == MMC_RSP_R2) {
+ r1 = mmc_spi_readdata(host, cmd->response, 1, 16);
+ for (i = 0; i < 4; i++)
+ cmd->response[i] = swab32(cmd->response[i]);
+ dev_dbg(host->dev, "MMC_RSP_R2 -> %x %x %x %x\n", cmd->response[0], cmd->response[1],
+ cmd->response[2], cmd->response[3]);
+ } else if (!data) {
+ switch (cmd->cmdidx) {
+ case SD_CMD_SEND_IF_COND:
+ case MMC_CMD_SPI_READ_OCR:
+ mmc_spi_readbytes(host, 4, cmd->response);
+ cmd->response[0] = swab32(cmd->response[0]);
+ break;
+ }
+ } else {
+ if (data->flags == MMC_DATA_READ) {
+ dev_dbg(host->dev, "%s : DATA READ, %x blocks, bsize = 0x%X\n", __func__,
+ data->blocks, data->blocksize);
+ r1 = mmc_spi_readdata(host, data->dest,
+ data->blocks, data->blocksize);
+ } else if (data->flags == MMC_DATA_WRITE) {
+ dev_dbg(host->dev, "%s : DATA WRITE, %x blocks, bsize = 0x%X\n", __func__,
+ data->blocks, data->blocksize);
+ r1 = mmc_spi_writedata(host, data->src,
+ data->blocks, data->blocksize,
+ (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK));
+ }
+ if (r1 & R1_SPI_COM_CRC)
+ ret = -ECOMM;
+ else if (r1)
+ ret = -ETIME;
+ }
+
+done:
+ mmc_cs_off(host);
+ return ret;
+
+return 0;
+
+}
+
+static void mmc_spi_set_ios(struct mci_host *mci, struct device_d *mci_dev,
+ unsigned bus_width, unsigned clock)
+{
+ struct mmc_spi_host *host = to_spi_host(mci);
+
+ spi_setup(host->spi);
+}
+
+static int mmc_spi_init(struct mci_host *mci, struct device_d *mci_dev)
+{
+ struct mmc_spi_host *host = to_spi_host(mci);
+ mmc_spi_readbytes(host, 10, NULL);
+
+ /*
+ * Do a burst with chipselect active-high. We need to do this to
+ * meet the requirement of 74 clock cycles with both chipselect
+ * and CMD (MOSI) high before CMD0 ... after the card has been
+ * powered up to Vdd(min), and so is ready to take commands.
+ *
+ * Some cards are particularly needy of this (e.g. Viking "SD256")
+ * while most others don't seem to care.
+ *
+ * Note that this is one of the places MMC/SD plays games with the
+ * SPI protocol. Another is that when chipselect is released while
+ * the card returns BUSY status, the clock must issue several cycles
+ * with chipselect high before the card will stop driving its output.
+ */
+
+ host->spi->mode |= SPI_CS_HIGH;
+ if (spi_setup(host->spi) != 0) {
+ /* Just warn; most cards work without it. */
+ dev_warn(&host->spi->dev,
+ "can't change chip-select polarity\n");
+ host->spi->mode &= ~SPI_CS_HIGH;
+ } else {
+ mmc_spi_readbytes(host, 18, NULL);
+
+ host->spi->mode &= ~SPI_CS_HIGH;
+ if (spi_setup(host->spi) != 0) {
+ /* Wot, we can't get the same setup we had before? */
+ dev_err(&host->spi->dev,
+ "can't restore chip-select polarity\n");
+ }
+ }
+
+ return 0;
+}
+
+static int spi_mci_probe(struct device_d *dev)
+{
+ struct spi_device *spi = (struct spi_device *)dev->type_data;
+ struct mmc_spi_host *host;
+ void *ones;
+
+ host = xzalloc(sizeof(*host));
+ host->mci.send_cmd = mmc_spi_request;
+ host->mci.set_ios = mmc_spi_set_ios;
+ host->mci.init = mmc_spi_init;
+
+ host->dev = dev;
+ host->spi = spi;
+ dev->priv = host;
+
+ ones = xmalloc(MMC_SPI_BLOCKSIZE);
+ memset(ones, 0xff, MMC_SPI_BLOCKSIZE);
+
+ host->ones = ones;
+
+ spi_message_init(&host->m_tx);
+ spi_message_init(&host->m_rx);
+
+ spi_message_add_tail(&host->t_tx, &host->m_tx);
+ spi_message_add_tail(&host->t_rx, &host->m_rx);
+
+ host->t_rx.tx_buf = host->ones;
+ host->t_rx.cs_change = 1;
+
+ host->t_tx.cs_change = 1;
+
+ host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+ host->mci.host_caps = MMC_CAP_SPI;
+
+ mci_register(&host->mci);
+
+ return 0;
+}
+
+static struct driver_d spi_mci_driver = {
+ .name = "spi_mci",
+ .probe = spi_mci_probe,
+};
+
+static int spi_mci_init_driver(void)
+{
+ register_driver(&spi_mci_driver);
+ return 0;
+}
+
+device_initcall(spi_mci_init_driver);
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 2710f6a..ec0f4a3 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -1067,7 +1067,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
tmp_id = chip->read_byte(mtd);
if (tmp_manf != *maf_id || tmp_id != dev_id) {
- printk(KERN_INFO "%s: second ID read did not match "
+ printk(KERN_ERR "%s: second ID read did not match "
"%02x,%02x against %02x,%02x\n", __func__,
*maf_id, dev_id, tmp_manf, tmp_id);
return ERR_PTR(-ENODEV);
@@ -1081,8 +1081,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
}
}
- if (!type)
+ if (!type) {
+ printk(KERN_ERR "NAND type unknown: %02x,%02x\n", *maf_id, dev_id);
return ERR_PTR(-ENODEV);
+ }
if (!mtd->name)
mtd->name = type->name;
@@ -1209,7 +1211,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips)
type = nand_get_flash_type(mtd, chip, busw, &nand_maf_id);
if (IS_ERR(type)) {
- printk(KERN_WARNING "No NAND device found!!!\n");
+ printk(KERN_WARNING "No NAND device found (%ld)!\n", PTR_ERR(type));
chip->select_chip(mtd, -1);
return PTR_ERR(type);
}
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index c1f7f68..e1cfd85 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -302,18 +302,14 @@ static int macb_phy_read(struct mii_device *mdev, int addr, int reg)
unsigned long netctl;
unsigned long netstat;
unsigned long frame;
- int iflag;
int value;
uint64_t start;
debug("%s\n", __func__);
- iflag = disable_interrupts();
netctl = readl(macb->regs + MACB_NCR);
netctl |= MACB_BIT(MPE);
writel(netctl, macb->regs + MACB_NCR);
- if (iflag)
- enable_interrupts();
frame = (MACB_BF(SOF, 1)
| MACB_BF(RW, 2)
@@ -334,12 +330,9 @@ static int macb_phy_read(struct mii_device *mdev, int addr, int reg)
frame = readl(macb->regs + MACB_MAN);
value = MACB_BFEXT(DATA, frame);
- iflag = disable_interrupts();
netctl = readl(macb->regs + MACB_NCR);
netctl &= ~MACB_BIT(MPE);
writel(netctl, macb->regs + MACB_NCR);
- if (iflag)
- enable_interrupts();
return value;
}
@@ -355,12 +348,9 @@ static int macb_phy_write(struct mii_device *mdev, int addr, int reg, int value)
debug("%s\n", __func__);
- iflag = disable_interrupts();
netctl = readl(macb->regs + MACB_NCR);
netctl |= MACB_BIT(MPE);
writel(netctl, macb->regs + MACB_NCR);
- if (iflag)
- enable_interrupts();
frame = (MACB_BF(SOF, 1)
| MACB_BF(RW, 1)
@@ -374,12 +364,9 @@ static int macb_phy_write(struct mii_device *mdev, int addr, int reg, int value)
netstat = readl(macb->regs + MACB_NSR);
} while (!(netstat & MACB_BIT(IDLE)));
- iflag = disable_interrupts();
netctl = readl(macb->regs + MACB_NCR);
netctl &= ~MACB_BIT(MPE);
writel(netctl, macb->regs + MACB_NCR);
- if (iflag)
- enable_interrupts();
return 0;
}
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index c2bee79..592d543 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -92,4 +92,8 @@ config DRIVER_SERIAL_S3C24X0_AUTOSYNC
Say Y here if you want to use the auto flow feature of this
UART. RTS and CTS will be handled by the hardware when enabled.
+config DRIVER_SERIAL_PXA
+ bool "PXA serial driver"
+ depends on ARCH_PXA
+
endmenu
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 411b8c5..a702125 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -18,3 +18,4 @@ obj-$(CONFIG_DRIVER_SERIAL_PL010) += serial_pl010.o
obj-$(CONFIG_DRIVER_SERIAL_S3C24X0) += serial_s3c24x0.o
obj-$(CONFIG_DRIVER_SERIAL_ALTERA) += serial_altera.o
obj-$(CONFIG_DRIVER_SERIAL_ALTERA_JTAG) += serial_altera_jtag.o
+obj-$(CONFIG_DRIVER_SERIAL_PXA) += serial_pxa.o
diff --git a/drivers/serial/serial_pxa.c b/drivers/serial/serial_pxa.c
new file mode 100644
index 0000000..d295235
--- /dev/null
+++ b/drivers/serial/serial_pxa.c
@@ -0,0 +1,201 @@
+/*
+ * (c) 2009 Sascha Hauer <s.hauer@pengutronix.de>
+ * 2010 by Marc Kleine-Budde <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 <driver.h>
+#include <init.h>
+#include <malloc.h>
+
+#include <mach/clock.h>
+#include <asm/io.h>
+
+#define RBR 0x00 /* Receive Buffer Register (read only) */
+#define THR 0x00 /* Transmit Holding Register (write only) */
+#define IER 0x04 /* Interrupt Enable Register (read/write) */
+#define IIR 0x08 /* Interrupt ID Register (read only) */
+#define FCR 0x08 /* FIFO Control Register (write only) */
+#define LCR 0x0c /* Line Control Register (read/write) */
+#define MCR 0x10 /* Modem Control Register (read/write) */
+#define LSR 0x14 /* Line Status Register (read only) */
+#define MSR 0x18 /* Modem Status Register (read only) */
+#define SPR 0x1c /* Scratch Pad Register (read/write) */
+#define ISR 0x20 /* Infrared Selection Register (read/write) */
+#define DLL 0x00 /* Divisor Latch Low Register (DLAB = 1) (read/write) */
+#define DLH 0x04 /* Divisor Latch High Register (DLAB = 1) (read/write) */
+
+#define IER_DMAE (1 << 7) /* DMA Requests Enable */
+#define IER_UUE (1 << 6) /* UART Unit Enable */
+#define IER_NRZE (1 << 5) /* NRZ coding Enable */
+#define IER_RTIOE (1 << 4) /* Receiver Time Out Interrupt Enable */
+#define IER_MIE (1 << 3) /* Modem Interrupt Enable */
+#define IER_RLSE (1 << 2) /* Receiver Line Status Interrupt Enable */
+#define IER_TIE (1 << 1) /* Transmit Data request Interrupt Enable */
+#define IER_RAVIE (1 << 0) /* Receiver Data Available Interrupt Enable */
+
+#define IIR_FIFOES1 (1 << 7) /* FIFO Mode Enable Status */
+#define IIR_FIFOES0 (1 << 6) /* FIFO Mode Enable Status */
+#define IIR_TOD (1 << 3) /* Time Out Detected */
+#define IIR_IID2 (1 << 2) /* Interrupt Source Encoded */
+#define IIR_IID1 (1 << 1) /* Interrupt Source Encoded */
+#define IIR_IP (1 << 0) /* Interrupt Pending (active low) */
+
+#define FCR_ITL2 (1 << 7) /* Interrupt Trigger Level */
+#define FCR_ITL1 (1 << 6) /* Interrupt Trigger Level */
+#define FCR_RESETTF (1 << 2) /* Reset Transmitter FIFO */
+#define FCR_RESETRF (1 << 1) /* Reset Receiver FIFO */
+#define FCR_TRFIFOE (1 << 0) /* Transmit and Receive FIFO Enable */
+#define FCR_ITL_1 (0)
+#define FCR_ITL_8 (FCR_ITL1)
+#define FCR_ITL_16 (FCR_ITL2)
+#define FCR_ITL_32 (FCR_ITL2 | F CR_ITL1)
+
+#define LCR_DLAB (1 << 7) /* Divisor Latch Access Bit */
+#define LCR_SB (1 << 6) /* Set Break */
+#define LCR_STKYP (1 << 5) /* Sticky Parity */
+#define LCR_EPS (1 << 4) /* Even Parity Select */
+#define LCR_PEN (1 << 3) /* Parity Enable */
+#define LCR_STB (1 << 2) /* Stop Bit */
+#define LCR_WLS1 (1 << 1) /* Word Length Select */
+#define LCR_WLS0 (1 << 0) /* Word Length Select */
+#define LCR_WLEN8 (LCR_WLS1 | LCR_WLS0)
+ /* Wordlength: 8 bits */
+
+#define LSR_FIFOE (1 << 7) /* FIFO Error Status */
+#define LSR_TEMT (1 << 6) /* Transmitter Empty */
+#define LSR_TDRQ (1 << 5) /* Transmit Data Request */
+#define LSR_BI (1 << 4) /* Break Interrupt */
+#define LSR_FE (1 << 3) /* Framing Error */
+#define LSR_PE (1 << 2) /* Parity Error */
+#define LSR_OE (1 << 1) /* Overrun Error */
+#define LSR_DR (1 << 0) /* Data Ready */
+
+#define MCR_LOOP (1 << 4) /* */
+#define MCR_OUT2 (1 << 3) /* force MSR_DCD in loopback mode */
+#define MCR_OUT1 (1 << 2) /* force MSR_RI in loopback mode */
+#define MCR_RTS (1 << 1) /* Request to Send */
+#define MCR_DTR (1 << 0) /* Data Terminal Ready */
+
+#define MSR_DCD (1 << 7) /* Data Carrier Detect */
+#define MSR_RI (1 << 6) /* Ring Indicator */
+#define MSR_DSR (1 << 5) /* Data Set Ready */
+#define MSR_CTS (1 << 4) /* Clear To Send */
+#define MSR_DDCD (1 << 3) /* Delta Data Carrier Detect */
+#define MSR_TERI (1 << 2) /* Trailing Edge Ring Indicator */
+#define MSR_DDSR (1 << 1) /* Delta Data Set Ready */
+#define MSR_DCTS (1 << 0) /* Delta Clear To Send */
+
+struct pxa_serial_priv {
+ void __iomem *regs;
+ struct console_device cdev;
+};
+
+static void __iomem *to_regs(struct console_device *cdev)
+{
+ struct pxa_serial_priv *priv =
+ container_of(cdev, struct pxa_serial_priv, cdev);
+ return priv->regs;
+}
+
+static void pxa_serial_putc(struct console_device *cdev, char c)
+{
+ while (!(readl(to_regs(cdev) + LSR) & LSR_TEMT));
+
+ writel(c, to_regs(cdev) + THR);
+}
+
+static int pxa_serial_tstc(struct console_device *cdev)
+{
+ return readl(to_regs(cdev) + LSR) & LSR_DR;
+}
+
+static int pxa_serial_getc(struct console_device *cdev)
+{
+ while (!(readl(to_regs(cdev) + LSR) & LSR_DR));
+
+ return readl(to_regs(cdev) + RBR) & 0xff;
+}
+
+static void pxa_serial_flush(struct console_device *cdev)
+{
+}
+
+static int pxa_serial_setbaudrate(struct console_device *cdev, int baudrate)
+{
+ unsigned char cval = LCR_WLEN8; /* 8N1 */
+ unsigned int quot;
+
+ /* enable uart */
+ writel(IER_UUE, to_regs(cdev) + IER);
+
+ /* write divisor */
+ quot = (pxa_get_uartclk() + (8 * baudrate)) / (16 * baudrate);
+
+ writel(cval | LCR_DLAB, to_regs(cdev) + LCR); /* set DLAB */
+ writel(quot & 0xff, to_regs(cdev) + DLL);
+ /*
+ * work around Errata #75 according to Intel(R) PXA27x
+ * Processor Family Specification Update (Nov 2005)
+ */
+ readl(to_regs(cdev) + DLL);
+ writel(quot >> 8, to_regs(cdev) + DLH);
+ writel(cval, to_regs(cdev) + LCR); /* reset DLAB */
+
+ /* enable fifos */
+ writel(FCR_TRFIFOE, to_regs(cdev) + FCR);
+
+ return 0;
+}
+
+static int pxa_serial_probe(struct device_d *dev)
+{
+ struct console_device *cdev;
+ struct pxa_serial_priv *priv;
+
+ priv = xzalloc(sizeof(*priv));
+ cdev = &priv->cdev;
+ priv->regs = dev_request_mem_region(dev, 0);
+
+ dev->type_data = cdev;
+ cdev->dev = dev;
+ cdev->f_caps = CONSOLE_STDIN | CONSOLE_STDOUT | CONSOLE_STDERR;
+ cdev->tstc = pxa_serial_tstc;
+ cdev->putc = pxa_serial_putc;
+ cdev->getc = pxa_serial_getc;
+ cdev->flush = pxa_serial_flush;
+ cdev->setbrg = pxa_serial_setbaudrate;
+
+ console_register(cdev);
+
+ return 0;
+}
+
+static void pxa_serial_remove(struct device_d *dev)
+{
+ free(dev->type_data);
+}
+
+static struct driver_d pxa_serial_driver = {
+ .name = "pxa_serial",
+ .probe = pxa_serial_probe,
+ .remove = pxa_serial_remove,
+};
+
+static int pxa_serial_init(void)
+{
+ return register_driver(&pxa_serial_driver);
+}
+
+console_initcall(pxa_serial_init);
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
index 4fd82fb..6cf9942 100644
--- a/drivers/spi/altera_spi.c
+++ b/drivers/spi/altera_spi.c
@@ -25,6 +25,9 @@
#include <io.h>
#include <asm/spi.h>
#include <asm/nios2-io.h>
+#include <clock.h>
+
+static void altera_spi_cs_inactive(struct spi_device *spi);
static int altera_spi_setup(struct spi_device *spi)
{
@@ -49,6 +52,8 @@ static int altera_spi_setup(struct spi_device *spi)
return -1;
}
+ altera_spi_cs_inactive(spi);
+
dev_dbg(master->dev, " mode 0x%08x, bits_per_word: %d, speed: %d\n",
spi->mode, spi->bits_per_word, altera_spi->speed);
@@ -167,19 +172,38 @@ static int altera_spi_transfer(struct spi_device *spi, struct spi_message *mesg)
struct altera_spi *altera_spi = container_of(spi->master, struct altera_spi, master);
struct nios_spi *nios_spi = altera_spi->regs;
struct spi_transfer *t;
+ unsigned int cs_change;
+ const int nsecs = 50;
altera_spi_cs_active(spi);
+ cs_change = 0;
+
mesg->actual_length = 0;
list_for_each_entry(t, &mesg->transfers, transfer_list) {
+
+ if (cs_change) {
+ ndelay(nsecs);
+ altera_spi_cs_inactive(spi);
+ ndelay(nsecs);
+ altera_spi_cs_active(spi);
+ }
+
+ cs_change = t->cs_change;
+
mesg->actual_length += altera_spi_do_xfer(spi, t);
+
+ if (cs_change) {
+ altera_spi_cs_active(spi);
+ }
}
/* Wait the end of any pending transfer */
while ((readl(&nios_spi->status) & NIOS_SPI_TMT) == 0);
- altera_spi_cs_inactive(spi);
+ if (!cs_change)
+ altera_spi_cs_inactive(spi);
return 0;
}
@@ -199,6 +223,7 @@ static int altera_spi_probe(struct device_d *dev)
master->setup = altera_spi_setup;
master->transfer = altera_spi_transfer;
master->num_chipselect = pdata->num_chipselect;
+ master->bus_num = pdata->bus_num;
altera_spi->regs = dev_request_mem_region(dev, 0);
altera_spi->databits = pdata->databits;
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index b8375c6..472c591 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -14,6 +14,13 @@ config USB_GADGET_DRIVER_ARC
prompt "Arc OTG device core"
depends on ARCH_IMX
select USB_GADGET_DUALSPEED
+
+config USB_GADGET_DRIVER_PXA27X
+ bool
+ prompt "PXA27x gadget driver"
+ depends on ARCH_PXA
+ select USB_GADGET_DUALSPEED
+ select POLLER
endchoice
choice
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 804bb91..e034786 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_USB_GADGET) += composite.o config.o usbstring.o epautoconf.o
obj-$(CONFIG_USB_GADGET_SERIAL) += u_serial.o serial.o f_serial.o f_acm.o
obj-$(CONFIG_USB_GADGET_DFU) += dfu.o
obj-$(CONFIG_USB_GADGET_DRIVER_ARC) += fsl_udc.o
+obj-$(CONFIG_USB_GADGET_DRIVER_PXA27X) += pxa27x_udc.o
diff --git a/drivers/usb/gadget/dfu.c b/drivers/usb/gadget/dfu.c
index 1387c6d..0a0d244 100644
--- a/drivers/usb/gadget/dfu.c
+++ b/drivers/usb/gadget/dfu.c
@@ -259,7 +259,7 @@ static int handle_dnload(struct usb_function *f, const struct usb_ctrlrequest *c
ret = -EINVAL;
goto err_out;
}
- ret = copy_file(DFU_TEMPFILE, dfu_devs[dfualt].dev);
+ ret = copy_file(DFU_TEMPFILE, dfu_devs[dfualt].dev, 0);
if (ret) {
printf("copy file failed\n");
ret = -EINVAL;
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index 5b7eb2c..b933105 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -16,7 +16,6 @@
#include "gadget_chips.h"
#include "u_serial.h"
-
/*
* This function packages a simple "generic serial" port with no real
* control mechanisms, just raw data transfer over two bulk endpoints.
@@ -140,6 +139,7 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
gser->hs.in, gser->fs.in);
gser->port.out_desc = ep_choose(cdev->gadget,
gser->hs.out, gser->fs.out);
+ gserial_connect(&gser->port, gser->port_num);
}
return 0;
@@ -147,7 +147,10 @@ static int gser_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
static void gser_disable(struct usb_function *f)
{
+ struct f_gser *gser = func_to_gser(f);
+
DBG(cdev, "generic ttyGS%d deactivated\n", gser->port_num);
+ gserial_disconnect(&gser->port);
}
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c
new file mode 100644
index 0000000..d0dbee9
--- /dev/null
+++ b/drivers/usb/gadget/pxa27x_udc.c
@@ -0,0 +1,1524 @@
+/*
+ * Handles the Intel 27x USB Device Controller (UDC)
+ *
+ * Inspired by original driver by Frank Becker, David Brownell, and others.
+ * Copyright (C) 2008 Robert Jarzmik
+ *
+ * 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
+ *
+ * Taken from linux-2.6 kernel and adapted to barebox.
+ */
+#include <common.h>
+#include <errno.h>
+#include <clock.h>
+#include <io.h>
+#include <gpio.h>
+#include <init.h>
+#include <poller.h>
+
+#include <usb/ch9.h>
+#include <usb/gadget.h>
+
+#include "pxa27x_udc.h"
+#include <mach/udc_pxa2xx.h>
+#include <mach/pxa-regs.h>
+
+#define DRIVER_VERSION "2008-04-18"
+#define DRIVER_DESC "PXA 27x USB Device Controller driver"
+
+static const char driver_name[] = "pxa27x_udc";
+static struct pxa_udc *the_controller;
+
+static void handle_ep(struct pxa_ep *ep);
+
+static int is_match_usb_pxa(struct udc_usb_ep *udc_usb_ep, struct pxa_ep *ep,
+ int config, int interface, int altsetting)
+{
+ if (usb_endpoint_num(&udc_usb_ep->desc) != ep->addr)
+ return 0;
+ if (usb_endpoint_dir_in(&udc_usb_ep->desc) != ep->dir_in)
+ return 0;
+ if (usb_endpoint_type(&udc_usb_ep->desc) != ep->type)
+ return 0;
+ if ((ep->config != config) || (ep->interface != interface)
+ || (ep->alternate != altsetting))
+ return 0;
+ return 1;
+}
+
+static struct pxa_ep *find_pxa_ep(struct pxa_udc *udc,
+ struct udc_usb_ep *udc_usb_ep)
+{
+ int i;
+ struct pxa_ep *ep;
+ int cfg = udc->config;
+ int iface = udc->last_interface;
+ int alt = udc->last_alternate;
+
+ if (udc_usb_ep == &udc->udc_usb_ep[0])
+ return &udc->pxa_ep[0];
+
+ for (i = 1; i < NR_PXA_ENDPOINTS; i++) {
+ ep = &udc->pxa_ep[i];
+ if (is_match_usb_pxa(udc_usb_ep, ep, cfg, iface, alt))
+ return ep;
+ }
+ return NULL;
+}
+
+static void update_pxa_ep_matches(struct pxa_udc *udc)
+{
+ int i;
+ struct udc_usb_ep *udc_usb_ep;
+
+ for (i = 1; i < NR_USB_ENDPOINTS; i++) {
+ udc_usb_ep = &udc->udc_usb_ep[i];
+ if (udc_usb_ep->pxa_ep)
+ udc_usb_ep->pxa_ep = find_pxa_ep(udc, udc_usb_ep);
+ }
+}
+
+static void pio_irq_enable(struct pxa_ep *ep)
+{
+ struct pxa_udc *udc = ep->dev;
+ int index = EPIDX(ep);
+ u32 udcicr0 = udc_readl(udc, UDCICR0);
+ u32 udcicr1 = udc_readl(udc, UDCICR1);
+
+ if (index < 16)
+ udc_writel(udc, UDCICR0, udcicr0 | (3 << (index * 2)));
+ else
+ udc_writel(udc, UDCICR1, udcicr1 | (3 << ((index - 16) * 2)));
+}
+
+static void pio_irq_disable(struct pxa_ep *ep)
+{
+ struct pxa_udc *udc = ep->dev;
+ int index = EPIDX(ep);
+ u32 udcicr0 = udc_readl(udc, UDCICR0);
+ u32 udcicr1 = udc_readl(udc, UDCICR1);
+
+ if (index < 16)
+ udc_writel(udc, UDCICR0, udcicr0 & ~(3 << (index * 2)));
+ else
+ udc_writel(udc, UDCICR1, udcicr1 & ~(3 << ((index - 16) * 2)));
+}
+
+static inline void udc_set_mask_UDCCR(struct pxa_udc *udc, int mask)
+{
+ u32 udccr = udc_readl(udc, UDCCR);
+ udc_writel(udc, UDCCR,
+ (udccr & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS));
+}
+
+static inline void udc_clear_mask_UDCCR(struct pxa_udc *udc, int mask)
+{
+ u32 udccr = udc_readl(udc, UDCCR);
+ udc_writel(udc, UDCCR,
+ (udccr & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS));
+}
+
+static inline void ep_write_UDCCSR(struct pxa_ep *ep, int mask)
+{
+ if (is_ep0(ep))
+ mask |= UDCCSR0_ACM;
+ udc_ep_writel(ep, UDCCSR, mask);
+}
+
+static int ep_count_bytes_remain(struct pxa_ep *ep)
+{
+ if (ep->dir_in)
+ return -EOPNOTSUPP;
+ return udc_ep_readl(ep, UDCBCR) & 0x3ff;
+}
+
+static int ep_is_empty(struct pxa_ep *ep)
+{
+ int ret;
+
+ if (!is_ep0(ep) && ep->dir_in)
+ return -EOPNOTSUPP;
+ if (is_ep0(ep))
+ ret = !(udc_ep_readl(ep, UDCCSR) & UDCCSR0_RNE);
+ else
+ ret = !(udc_ep_readl(ep, UDCCSR) & UDCCSR_BNE);
+ return ret;
+}
+
+static int ep_is_full(struct pxa_ep *ep)
+{
+ if (is_ep0(ep))
+ return udc_ep_readl(ep, UDCCSR) & UDCCSR0_IPR;
+ if (!ep->dir_in)
+ return -EOPNOTSUPP;
+ return !(udc_ep_readl(ep, UDCCSR) & UDCCSR_BNF);
+}
+
+static int epout_has_pkt(struct pxa_ep *ep)
+{
+ if (!is_ep0(ep) && ep->dir_in)
+ return -EOPNOTSUPP;
+ if (is_ep0(ep))
+ return udc_ep_readl(ep, UDCCSR) & UDCCSR0_OPC;
+ return udc_ep_readl(ep, UDCCSR) & UDCCSR_PC;
+}
+
+static void set_ep0state(struct pxa_udc *udc, int state)
+{
+ struct pxa_ep *ep = &udc->pxa_ep[0];
+ char *old_stname = EP0_STNAME(udc);
+
+ udc->ep0state = state;
+ ep_dbg(ep, "state=%s->%s, udccsr0=0x%03x, udcbcr=%d\n", old_stname,
+ EP0_STNAME(udc), udc_ep_readl(ep, UDCCSR),
+ udc_ep_readl(ep, UDCBCR));
+}
+
+static void ep0_idle(struct pxa_udc *dev)
+{
+ set_ep0state(dev, WAIT_FOR_SETUP);
+}
+
+static __init void pxa_ep_setup(struct pxa_ep *ep)
+{
+ u32 new_udccr;
+
+ new_udccr = ((ep->config << UDCCONR_CN_S) & UDCCONR_CN)
+ | ((ep->interface << UDCCONR_IN_S) & UDCCONR_IN)
+ | ((ep->alternate << UDCCONR_AISN_S) & UDCCONR_AISN)
+ | ((EPADDR(ep) << UDCCONR_EN_S) & UDCCONR_EN)
+ | ((EPXFERTYPE(ep) << UDCCONR_ET_S) & UDCCONR_ET)
+ | ((ep->dir_in) ? UDCCONR_ED : 0)
+ | ((ep->fifo_size << UDCCONR_MPS_S) & UDCCONR_MPS)
+ | UDCCONR_EE;
+
+ udc_ep_writel(ep, UDCCR, new_udccr);
+}
+
+static __init void pxa_eps_setup(struct pxa_udc *dev)
+{
+ unsigned int i;
+
+ dev_dbg(dev->dev, "%s: dev=%p\n", __func__, dev);
+
+ for (i = 1; i < NR_PXA_ENDPOINTS; i++)
+ pxa_ep_setup(&dev->pxa_ep[i]);
+}
+
+static struct usb_request *pxa_ep_alloc_request(struct usb_ep *_ep)
+{
+ struct pxa27x_request *req;
+
+ req = xzalloc(sizeof *req);
+ if (!req)
+ return NULL;
+
+ INIT_LIST_HEAD(&req->queue);
+ req->in_use = 0;
+ req->udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+
+ return &req->req;
+}
+
+static void pxa_ep_free_request(struct usb_ep *_ep, struct usb_request *_req)
+{
+ struct pxa27x_request *req;
+
+ req = container_of(_req, struct pxa27x_request, req);
+ WARN_ON(!list_empty(&req->queue));
+ kfree(req);
+}
+
+static void ep_add_request(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+ if (unlikely(!req))
+ return;
+ ep_vdbg(ep, "req:%p, lg=%d, udccsr=0x%03x\n", req,
+ req->req.length, udc_ep_readl(ep, UDCCSR));
+
+ req->in_use = 1;
+ list_add_tail(&req->queue, &ep->queue);
+ pio_irq_enable(ep);
+}
+
+static void ep_del_request(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+ if (unlikely(!req))
+ return;
+ ep_vdbg(ep, "req:%p, lg=%d, udccsr=0x%03x\n", req,
+ req->req.length, udc_ep_readl(ep, UDCCSR));
+
+ list_del_init(&req->queue);
+ req->in_use = 0;
+ if (!is_ep0(ep) && list_empty(&ep->queue))
+ pio_irq_disable(ep);
+}
+
+static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status)
+{
+ ep_del_request(ep, req);
+ if (likely(req->req.status == -EINPROGRESS))
+ req->req.status = status;
+ else
+ status = req->req.status;
+
+ if (status && status != -ESHUTDOWN)
+ ep_dbg(ep, "complete req %p stat %d len %u/%u\n",
+ &req->req, status,
+ req->req.actual, req->req.length);
+
+ req->req.complete(&req->udc_usb_ep->usb_ep, &req->req);
+}
+
+static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+ req_done(ep, req, 0);
+}
+
+static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+ set_ep0state(ep->dev, OUT_STATUS_STAGE);
+ ep_end_out_req(ep, req);
+ ep0_idle(ep->dev);
+}
+
+static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+ req_done(ep, req, 0);
+}
+
+static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+ set_ep0state(ep->dev, IN_STATUS_STAGE);
+ ep_end_in_req(ep, req);
+}
+
+static void nuke(struct pxa_ep *ep, int status)
+{
+ struct pxa27x_request *req;
+
+ while (!list_empty(&ep->queue)) {
+ req = list_entry(ep->queue.next, struct pxa27x_request, queue);
+ req_done(ep, req, status);
+ }
+}
+
+static int read_packet(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+ u32 *buf;
+ int bytes_ep, bufferspace, count, i;
+
+ bytes_ep = ep_count_bytes_remain(ep);
+ bufferspace = req->req.length - req->req.actual;
+
+ buf = (u32 *)(req->req.buf + req->req.actual);
+
+ if (likely(!ep_is_empty(ep)))
+ count = min(bytes_ep, bufferspace);
+ else /* zlp */
+ count = 0;
+
+ for (i = count; i > 0; i -= 4)
+ *buf++ = udc_ep_readl(ep, UDCDR);
+ req->req.actual += count;
+
+ ep_write_UDCCSR(ep, UDCCSR_PC);
+
+ return count;
+}
+
+static int write_packet(struct pxa_ep *ep, struct pxa27x_request *req,
+ unsigned int max)
+{
+ int length, count, remain, i;
+ u32 *buf;
+ u8 *buf_8;
+
+ buf = (u32 *)(req->req.buf + req->req.actual);
+ prefetch(buf);
+
+ length = min(req->req.length - req->req.actual, max);
+ req->req.actual += length;
+
+ remain = length & 0x3;
+ count = length & ~(0x3);
+ for (i = count; i > 0 ; i -= 4)
+ udc_ep_writel(ep, UDCDR, *buf++);
+
+ buf_8 = (u8 *)buf;
+ for (i = remain; i > 0; i--)
+ udc_ep_writeb(ep, UDCDR, *buf_8++);
+
+ ep_vdbg(ep, "length=%d+%d, udccsr=0x%03x\n", count, remain,
+ udc_ep_readl(ep, UDCCSR));
+
+ return length;
+}
+
+static int read_fifo(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+ int count, is_short, completed = 0;
+
+ while (epout_has_pkt(ep)) {
+ count = read_packet(ep, req);
+
+ is_short = (count < ep->fifo_size);
+ ep_dbg(ep, "read udccsr:%03x, count:%d bytes%s req %p %d/%d\n",
+ udc_ep_readl(ep, UDCCSR), count, is_short ? "/S" : "",
+ &req->req, req->req.actual, req->req.length);
+
+ /* completion */
+ if (is_short || req->req.actual == req->req.length) {
+ completed = 1;
+ break;
+ }
+ /* finished that packet. the next one may be waiting... */
+ }
+ return completed;
+}
+
+static int write_fifo(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+ unsigned max;
+ int count, is_short, is_last = 0, completed = 0, totcount = 0;
+ u32 udccsr;
+
+ max = ep->fifo_size;
+ do {
+ is_short = 0;
+
+ udccsr = udc_ep_readl(ep, UDCCSR);
+ if (udccsr & UDCCSR_PC) {
+ ep_vdbg(ep, "Clearing Transmit Complete, udccsr=%x\n",
+ udccsr);
+ ep_write_UDCCSR(ep, UDCCSR_PC);
+ }
+ if (udccsr & UDCCSR_TRN) {
+ ep_vdbg(ep, "Clearing Underrun on, udccsr=%x\n",
+ udccsr);
+ ep_write_UDCCSR(ep, UDCCSR_TRN);
+ }
+
+ count = write_packet(ep, req, max);
+ totcount += count;
+
+ /* last packet is usually short (or a zlp) */
+ if (unlikely(count < max)) {
+ is_last = 1;
+ is_short = 1;
+ } else {
+ if (likely(req->req.length > req->req.actual)
+ || req->req.zero)
+ is_last = 0;
+ else
+ is_last = 1;
+ /* interrupt/iso maxpacket may not fill the fifo */
+ is_short = unlikely(max < ep->fifo_size);
+ }
+
+ if (is_short)
+ ep_write_UDCCSR(ep, UDCCSR_SP);
+
+ /* requests complete when all IN data is in the FIFO */
+ if (is_last) {
+ completed = 1;
+ break;
+ }
+ } while (!ep_is_full(ep));
+
+ ep_dbg(ep, "wrote count:%d bytes%s%s, left:%d req=%p\n",
+ totcount, is_last ? "/L" : "", is_short ? "/S" : "",
+ req->req.length - req->req.actual, &req->req);
+
+ return completed;
+}
+
+static int read_ep0_fifo(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+ int count, is_short, completed = 0;
+
+ while (epout_has_pkt(ep)) {
+ count = read_packet(ep, req);
+ ep_write_UDCCSR(ep, UDCCSR0_OPC);
+
+ is_short = (count < ep->fifo_size);
+ ep_dbg(ep, "read udccsr:%03x, count:%d bytes%s req %p %d/%d\n",
+ udc_ep_readl(ep, UDCCSR), count, is_short ? "/S" : "",
+ &req->req, req->req.actual, req->req.length);
+
+ if (is_short || req->req.actual >= req->req.length) {
+ completed = 1;
+ break;
+ }
+ }
+
+ return completed;
+}
+
+static int write_ep0_fifo(struct pxa_ep *ep, struct pxa27x_request *req)
+{
+ unsigned count;
+ int is_last, is_short;
+
+ count = write_packet(ep, req, EP0_FIFO_SIZE);
+
+ is_short = (count < EP0_FIFO_SIZE);
+ is_last = ((count == 0) || (count < EP0_FIFO_SIZE));
+
+ /* Sends either a short packet or a 0 length packet */
+ if (unlikely(is_short))
+ ep_write_UDCCSR(ep, UDCCSR0_IPR);
+
+ ep_dbg(ep, "in %d bytes%s%s, %d left, req=%p, udccsr0=0x%03x\n",
+ count, is_short ? "/S" : "", is_last ? "/L" : "",
+ req->req.length - req->req.actual,
+ &req->req, udc_ep_readl(ep, UDCCSR));
+
+ return is_last;
+}
+
+static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req)
+{
+ struct udc_usb_ep *udc_usb_ep;
+ struct pxa_ep *ep;
+ struct pxa27x_request *req;
+ struct pxa_udc *dev;
+ int rc = 0;
+ int is_first_req;
+ unsigned length;
+
+ req = container_of(_req, struct pxa27x_request, req);
+ udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+
+ if (unlikely(!_req || !_req->complete || !_req->buf))
+ return -EINVAL;
+
+ if (unlikely(!_ep))
+ return -EINVAL;
+
+ dev = udc_usb_ep->dev;
+ ep = udc_usb_ep->pxa_ep;
+ if (unlikely(!ep))
+ return -EINVAL;
+
+ dev = ep->dev;
+ if (unlikely(!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)) {
+ ep_dbg(ep, "bogus device state\n");
+ return -ESHUTDOWN;
+ }
+
+ /* iso is always one packet per request, that's the only way
+ * we can report per-packet status. that also helps with dma.
+ */
+ if (unlikely(EPXFERTYPE_is_ISO(ep)
+ && req->req.length > ep->fifo_size))
+ return -EMSGSIZE;
+
+ is_first_req = list_empty(&ep->queue);
+ ep_dbg(ep, "queue req %p(first=%s), len %d buf %p\n",
+ _req, is_first_req ? "yes" : "no",
+ _req->length, _req->buf);
+
+ if (!ep->enabled) {
+ _req->status = -ESHUTDOWN;
+ rc = -ESHUTDOWN;
+ goto out_locked;
+ }
+
+ if (req->in_use) {
+ ep_err(ep, "refusing to queue req %p (already queued)\n", req);
+ goto out_locked;
+ }
+
+ length = _req->length;
+ _req->status = -EINPROGRESS;
+ _req->actual = 0;
+
+ ep_add_request(ep, req);
+
+ if (is_ep0(ep)) {
+ switch (dev->ep0state) {
+ case WAIT_ACK_SET_CONF_INTERF:
+ if (length == 0) {
+ ep_end_in_req(ep, req);
+ } else {
+ ep_err(ep, "got a request of %d bytes while"
+ "in state WAIT_ACK_SET_CONF_INTERF\n",
+ length);
+ ep_del_request(ep, req);
+ rc = -EL2HLT;
+ }
+ ep0_idle(ep->dev);
+ break;
+ case IN_DATA_STAGE:
+ if (!ep_is_full(ep))
+ if (write_ep0_fifo(ep, req))
+ ep0_end_in_req(ep, req);
+ break;
+ case OUT_DATA_STAGE:
+ if ((length == 0) || !epout_has_pkt(ep))
+ if (read_ep0_fifo(ep, req))
+ ep0_end_out_req(ep, req);
+ break;
+ default:
+ ep_err(ep, "odd state %s to send me a request\n",
+ EP0_STNAME(ep->dev));
+ ep_del_request(ep, req);
+ rc = -EL2HLT;
+ break;
+ }
+ } else {
+ handle_ep(ep);
+ }
+
+out:
+ return rc;
+out_locked:
+ goto out;
+}
+
+static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
+{
+ struct pxa_ep *ep;
+ struct udc_usb_ep *udc_usb_ep;
+ struct pxa27x_request *req;
+ int rc = -EINVAL;
+
+ if (!_ep)
+ return rc;
+ udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+ ep = udc_usb_ep->pxa_ep;
+ if (!ep || is_ep0(ep))
+ return rc;
+
+ /* make sure it's actually queued on this endpoint */
+ list_for_each_entry(req, &ep->queue, queue) {
+ if (&req->req == _req) {
+ rc = 0;
+ break;
+ }
+ }
+
+ if (!rc)
+ req_done(ep, req, -ECONNRESET);
+ return rc;
+}
+
+static int pxa_ep_set_halt(struct usb_ep *_ep, int value)
+{
+ struct pxa_ep *ep;
+ struct udc_usb_ep *udc_usb_ep;
+ int rc;
+
+
+ if (!_ep)
+ return -EINVAL;
+ udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+ ep = udc_usb_ep->pxa_ep;
+ if (!ep || is_ep0(ep))
+ return -EINVAL;
+
+ if (value == 0) {
+ /*
+ * This path (reset toggle+halt) is needed to implement
+ * SET_INTERFACE on normal hardware. but it can't be
+ * done from software on the PXA UDC, and the hardware
+ * forgets to do it as part of SET_INTERFACE automagic.
+ */
+ ep_dbg(ep, "only host can clear halt\n");
+ return -EROFS;
+ }
+
+ rc = -EAGAIN;
+ if (ep->dir_in && (ep_is_full(ep) || !list_empty(&ep->queue)))
+ goto out;
+
+ /* FST, FEF bits are the same for control and non control endpoints */
+ rc = 0;
+ ep_write_UDCCSR(ep, UDCCSR_FST | UDCCSR_FEF);
+ if (is_ep0(ep))
+ set_ep0state(ep->dev, STALL);
+
+out:
+ return rc;
+}
+
+static int pxa_ep_fifo_status(struct usb_ep *_ep)
+{
+ struct pxa_ep *ep;
+ struct udc_usb_ep *udc_usb_ep;
+
+ if (!_ep)
+ return -ENODEV;
+ udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+ ep = udc_usb_ep->pxa_ep;
+ if (!ep || is_ep0(ep))
+ return -ENODEV;
+
+ if (ep->dir_in)
+ return -EOPNOTSUPP;
+ if (ep->dev->gadget.speed == USB_SPEED_UNKNOWN || ep_is_empty(ep))
+ return 0;
+ else
+ return ep_count_bytes_remain(ep) + 1;
+}
+
+static void pxa_ep_fifo_flush(struct usb_ep *_ep)
+{
+ struct pxa_ep *ep;
+ struct udc_usb_ep *udc_usb_ep;
+
+ if (!_ep)
+ return;
+ udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+ ep = udc_usb_ep->pxa_ep;
+ if (!ep || is_ep0(ep))
+ return;
+
+ if (unlikely(!list_empty(&ep->queue)))
+ ep_dbg(ep, "called while queue list not empty\n");
+ ep_dbg(ep, "called\n");
+
+ /* for OUT, just read and discard the FIFO contents. */
+ if (!ep->dir_in) {
+ while (!ep_is_empty(ep))
+ udc_ep_readl(ep, UDCDR);
+ } else {
+ /* most IN status is the same, but ISO can't stall */
+ ep_write_UDCCSR(ep,
+ UDCCSR_PC | UDCCSR_FEF | UDCCSR_TRN
+ | (EPXFERTYPE_is_ISO(ep) ? 0 : UDCCSR_SST));
+ }
+}
+
+static int pxa_ep_enable(struct usb_ep *_ep,
+ const struct usb_endpoint_descriptor *desc)
+{
+ struct pxa_ep *ep;
+ struct udc_usb_ep *udc_usb_ep;
+ struct pxa_udc *udc;
+
+ if (!_ep || !desc)
+ return -EINVAL;
+
+ udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+ if (udc_usb_ep->pxa_ep) {
+ ep = udc_usb_ep->pxa_ep;
+ ep_warn(ep, "usb_ep %s already enabled, doing nothing\n",
+ _ep->name);
+ } else {
+ ep = find_pxa_ep(udc_usb_ep->dev, udc_usb_ep);
+ }
+
+ if (!ep || is_ep0(ep)) {
+ dev_err(udc_usb_ep->dev->dev,
+ "unable to match pxa_ep for ep %s\n",
+ _ep->name);
+ return -EINVAL;
+ }
+
+ if ((desc->bDescriptorType != USB_DT_ENDPOINT)
+ || (ep->type != usb_endpoint_type(desc))) {
+ ep_err(ep, "type mismatch\n");
+ return -EINVAL;
+ }
+
+ if (ep->fifo_size < le16_to_cpu(desc->wMaxPacketSize)) {
+ ep_err(ep, "bad maxpacket\n");
+ return -ERANGE;
+ }
+
+ udc_usb_ep->pxa_ep = ep;
+ udc = ep->dev;
+
+ if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
+ ep_err(ep, "bogus device state\n");
+ return -ESHUTDOWN;
+ }
+
+ ep->enabled = 1;
+
+ /* flush fifo (mostly for OUT buffers) */
+ pxa_ep_fifo_flush(_ep);
+
+ ep_dbg(ep, "enabled\n");
+ return 0;
+}
+
+static int pxa_ep_disable(struct usb_ep *_ep)
+{
+ struct pxa_ep *ep;
+ struct udc_usb_ep *udc_usb_ep;
+
+ if (!_ep)
+ return -EINVAL;
+
+ udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep);
+ ep = udc_usb_ep->pxa_ep;
+ if (!ep || is_ep0(ep) || !list_empty(&ep->queue))
+ return -EINVAL;
+
+ ep->enabled = 0;
+ nuke(ep, -ESHUTDOWN);
+
+ pxa_ep_fifo_flush(_ep);
+ udc_usb_ep->pxa_ep = NULL;
+
+ ep_dbg(ep, "disabled\n");
+ return 0;
+}
+
+static struct usb_ep_ops pxa_ep_ops = {
+ .enable = pxa_ep_enable,
+ .disable = pxa_ep_disable,
+
+ .alloc_request = pxa_ep_alloc_request,
+ .free_request = pxa_ep_free_request,
+
+ .queue = pxa_ep_queue,
+ .dequeue = pxa_ep_dequeue,
+
+ .set_halt = pxa_ep_set_halt,
+ .fifo_status = pxa_ep_fifo_status,
+ .fifo_flush = pxa_ep_fifo_flush,
+};
+
+static void dplus_pullup(struct pxa_udc *udc, int on)
+{
+ if (on) {
+ if (udc->mach->gpio_pullup > 0)
+ gpio_set_value(udc->mach->gpio_pullup,
+ !udc->mach->gpio_pullup_inverted);
+ if (udc->mach->udc_command)
+ udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
+ } else {
+ if (udc->mach->gpio_pullup > 0)
+ gpio_set_value(udc->mach->gpio_pullup,
+ udc->mach->gpio_pullup_inverted);
+ if (udc->mach->udc_command)
+ udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
+ }
+ udc->pullup_on = on;
+}
+
+/**
+ * pxa_udc_get_frame - Returns usb frame number
+ * @_gadget: usb gadget
+ */
+static int pxa_udc_get_frame(struct usb_gadget *_gadget)
+{
+ struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+ return udc_readl(udc, UDCFNR) & 0x7ff;
+}
+
+static int pxa_udc_wakeup(struct usb_gadget *_gadget)
+{
+ struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+ /* host may not have enabled remote wakeup */
+ if ((udc_readl(udc, UDCCR) & UDCCR_DWRE) == 0)
+ return -EHOSTUNREACH;
+ udc_set_mask_UDCCR(udc, UDCCR_UDR);
+ return 0;
+}
+
+static void udc_enable(struct pxa_udc *udc);
+static void udc_disable(struct pxa_udc *udc);
+
+static int should_enable_udc(struct pxa_udc *udc)
+{
+ int put_on;
+
+ put_on = ((udc->pullup_on) && (udc->driver));
+ put_on &= udc->vbus_sensed;
+ return put_on;
+}
+
+static int should_disable_udc(struct pxa_udc *udc)
+{
+ int put_off;
+
+ put_off = ((!udc->pullup_on) || (!udc->driver));
+ put_off |= !udc->vbus_sensed;
+ return put_off;
+}
+
+static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active)
+{
+ struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+ if ((udc->mach->gpio_pullup < 0) && !udc->mach->udc_command)
+ return -EOPNOTSUPP;
+
+ dplus_pullup(udc, is_active);
+
+ if (should_enable_udc(udc))
+ udc_enable(udc);
+ if (should_disable_udc(udc))
+ udc_disable(udc);
+ return 0;
+}
+
+static int pxa_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
+{
+ struct pxa_udc *udc = to_gadget_udc(_gadget);
+
+ udc->vbus_sensed = is_active;
+ if (should_enable_udc(udc))
+ udc_enable(udc);
+ if (should_disable_udc(udc))
+ udc_disable(udc);
+
+ return 0;
+}
+
+static const struct usb_gadget_ops pxa_udc_ops = {
+ .get_frame = pxa_udc_get_frame,
+ .wakeup = pxa_udc_wakeup,
+ .pullup = pxa_udc_pullup,
+ .vbus_session = pxa_udc_vbus_session,
+};
+
+static void clk_enable(void)
+{
+ CKEN |= CKEN_USB;
+}
+
+static void clk_disable(void)
+{
+ CKEN &= ~CKEN_USB;
+}
+
+static void udc_disable(struct pxa_udc *udc)
+{
+ if (!udc->enabled)
+ return;
+
+ udc_writel(udc, UDCICR0, 0);
+ udc_writel(udc, UDCICR1, 0);
+
+ udc_clear_mask_UDCCR(udc, UDCCR_UDE);
+ clk_disable();
+
+ ep0_idle(udc);
+ udc->gadget.speed = USB_SPEED_UNKNOWN;
+
+ udc->enabled = 0;
+}
+
+static __init void udc_init_data(struct pxa_udc *dev)
+{
+ int i;
+ struct pxa_ep *ep;
+
+ /* device/ep0 records init */
+ INIT_LIST_HEAD(&dev->gadget.ep_list);
+ INIT_LIST_HEAD(&dev->gadget.ep0->ep_list);
+ dev->udc_usb_ep[0].pxa_ep = &dev->pxa_ep[0];
+ ep0_idle(dev);
+
+ /* PXA endpoints init */
+ for (i = 0; i < NR_PXA_ENDPOINTS; i++) {
+ ep = &dev->pxa_ep[i];
+
+ ep->enabled = is_ep0(ep);
+ INIT_LIST_HEAD(&ep->queue);
+ }
+
+ /* USB endpoints init */
+ for (i = 1; i < NR_USB_ENDPOINTS; i++)
+ list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list,
+ &dev->gadget.ep_list);
+}
+
+static void udc_enable(struct pxa_udc *udc)
+{
+ if (udc->enabled)
+ return;
+
+ udc_writel(udc, UDCICR0, 0);
+ udc_writel(udc, UDCICR1, 0);
+ udc_clear_mask_UDCCR(udc, UDCCR_UDE);
+
+ clk_enable();
+
+ ep0_idle(udc);
+ udc->gadget.speed = USB_SPEED_FULL;
+ memset(&udc->stats, 0, sizeof(udc->stats));
+
+ udc_set_mask_UDCCR(udc, UDCCR_UDE);
+ ep_write_UDCCSR(&udc->pxa_ep[0], UDCCSR0_ACM);
+ udelay(2);
+ if (udc_readl(udc, UDCCR) & UDCCR_EMCE)
+ dev_err(udc->dev, "Configuration errors, udc disabled\n");
+
+ /*
+ * Caller must be able to sleep in order to cope with startup transients
+ */
+ mdelay(100);
+
+ /* enable suspend/resume and reset irqs */
+ udc_writel(udc, UDCICR1,
+ UDCICR1_IECC | UDCICR1_IERU
+ | UDCICR1_IESU | UDCICR1_IERS);
+
+ pio_irq_enable(&udc->pxa_ep[0]);
+ udc->enabled = 1;
+}
+
+int usb_gadget_register_driver(struct usb_gadget_driver *driver)
+{
+ struct pxa_udc *udc = the_controller;
+ int retval;
+
+ if (!driver || driver->speed < USB_SPEED_FULL || !driver->bind
+ || !driver->disconnect || !driver->setup)
+ return -EINVAL;
+ if (!udc)
+ return -ENODEV;
+ if (udc->driver)
+ return -EBUSY;
+
+ /* first hook up the driver ... */
+ udc->driver = driver;
+ dplus_pullup(udc, 1);
+
+ retval = driver->bind(&udc->gadget);
+ if (retval) {
+ dev_err(udc->dev, "bind to function %s --> error %d\n",
+ driver->function, retval);
+ goto bind_fail;
+ }
+ dev_dbg(udc->dev, "registered gadget function '%s'\n",
+ driver->function);
+
+ if (should_enable_udc(udc))
+ udc_enable(udc);
+ return 0;
+
+bind_fail:
+ return retval;
+}
+EXPORT_SYMBOL(usb_gadget_register_driver);
+
+static void stop_activity(struct pxa_udc *udc, struct usb_gadget_driver *driver)
+{
+ int i;
+
+ /* don't disconnect drivers more than once */
+ if (udc->gadget.speed == USB_SPEED_UNKNOWN)
+ driver = NULL;
+ udc->gadget.speed = USB_SPEED_UNKNOWN;
+
+ for (i = 0; i < NR_USB_ENDPOINTS; i++)
+ pxa_ep_disable(&udc->udc_usb_ep[i].usb_ep);
+
+ if (driver)
+ driver->disconnect(&udc->gadget);
+}
+
+int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
+{
+ struct pxa_udc *udc = the_controller;
+
+ if (!udc)
+ return -ENODEV;
+ if (!driver || driver != udc->driver || !driver->unbind)
+ return -EINVAL;
+
+ stop_activity(udc, driver);
+ udc_disable(udc);
+ dplus_pullup(udc, 0);
+
+ driver->disconnect(&udc->gadget);
+ driver->unbind(&udc->gadget);
+ udc->driver = NULL;
+
+ /*
+ dev_info(udc->dev, "unregistered gadget driver '%s'\n",
+ driver->driver.name);
+ */
+ return 0;
+}
+EXPORT_SYMBOL(usb_gadget_unregister_driver);
+
+static void handle_ep0_ctrl_req(struct pxa_udc *udc,
+ struct pxa27x_request *req)
+{
+ struct pxa_ep *ep = &udc->pxa_ep[0];
+ union {
+ struct usb_ctrlrequest r;
+ u32 word[2];
+ } u;
+ int i;
+ int have_extrabytes = 0;
+
+ nuke(ep, -EPROTO);
+
+ /*
+ * In the PXA320 manual, in the section about Back-to-Back setup
+ * packets, it describes this situation. The solution is to set OPC to
+ * get rid of the status packet, and then continue with the setup
+ * packet. Generalize to pxa27x CPUs.
+ */
+ if (epout_has_pkt(ep) && (ep_count_bytes_remain(ep) == 0))
+ ep_write_UDCCSR(ep, UDCCSR0_OPC);
+
+ /* read SETUP packet */
+ for (i = 0; i < 2; i++) {
+ if (unlikely(ep_is_empty(ep)))
+ goto stall;
+ u.word[i] = udc_ep_readl(ep, UDCDR);
+ }
+
+ have_extrabytes = !ep_is_empty(ep);
+ while (!ep_is_empty(ep)) {
+ i = udc_ep_readl(ep, UDCDR);
+ ep_err(ep, "wrong to have extra bytes for setup : 0x%08x\n", i);
+ }
+
+ ep_dbg(ep, "SETUP %02x.%02x v%04x i%04x l%04x\n",
+ u.r.bRequestType, u.r.bRequest,
+ le16_to_cpu(u.r.wValue), le16_to_cpu(u.r.wIndex),
+ le16_to_cpu(u.r.wLength));
+ if (unlikely(have_extrabytes))
+ goto stall;
+
+ if (u.r.bRequestType & USB_DIR_IN)
+ set_ep0state(udc, IN_DATA_STAGE);
+ else
+ set_ep0state(udc, OUT_DATA_STAGE);
+
+ /* Tell UDC to enter Data Stage */
+ ep_write_UDCCSR(ep, UDCCSR0_SA | UDCCSR0_OPC);
+
+ i = udc->driver->setup(&udc->gadget, &u.r);
+ if (i < 0)
+ goto stall;
+out:
+ return;
+stall:
+ ep_dbg(ep, "protocol STALL, udccsr0=%03x err %d\n",
+ udc_ep_readl(ep, UDCCSR), i);
+ ep_write_UDCCSR(ep, UDCCSR0_FST | UDCCSR0_FTF);
+ set_ep0state(udc, STALL);
+ goto out;
+}
+
+static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq)
+{
+ u32 udccsr0;
+ struct pxa_ep *ep = &udc->pxa_ep[0];
+ struct pxa27x_request *req = NULL;
+ int completed = 0;
+
+ if (!list_empty(&ep->queue))
+ req = list_entry(ep->queue.next, struct pxa27x_request, queue);
+
+ udccsr0 = udc_ep_readl(ep, UDCCSR);
+ ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n",
+ EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR),
+ (fifo_irq << 1 | opc_irq));
+
+ if (udccsr0 & UDCCSR0_SST) {
+ ep_dbg(ep, "clearing stall status\n");
+ nuke(ep, -EPIPE);
+ ep_write_UDCCSR(ep, UDCCSR0_SST);
+ ep0_idle(udc);
+ }
+
+ if (udccsr0 & UDCCSR0_SA) {
+ nuke(ep, 0);
+ set_ep0state(udc, SETUP_STAGE);
+ }
+
+ switch (udc->ep0state) {
+ case WAIT_FOR_SETUP:
+ /*
+ * Hardware bug : beware, we cannot clear OPC, since we would
+ * miss a potential OPC irq for a setup packet.
+ * So, we only do ... nothing, and hope for a next irq with
+ * UDCCSR0_SA set.
+ */
+ break;
+ case SETUP_STAGE:
+ udccsr0 &= UDCCSR0_CTRL_REQ_MASK;
+ if (likely(udccsr0 == UDCCSR0_CTRL_REQ_MASK))
+ handle_ep0_ctrl_req(udc, req);
+ break;
+ case IN_DATA_STAGE: /* GET_DESCRIPTOR */
+ if (epout_has_pkt(ep))
+ ep_write_UDCCSR(ep, UDCCSR0_OPC);
+ if (req && !ep_is_full(ep))
+ completed = write_ep0_fifo(ep, req);
+ if (completed)
+ ep0_end_in_req(ep, req);
+ break;
+ case OUT_DATA_STAGE: /* SET_DESCRIPTOR */
+ if (epout_has_pkt(ep) && req)
+ completed = read_ep0_fifo(ep, req);
+ if (completed)
+ ep0_end_out_req(ep, req);
+ break;
+ case STALL:
+ ep_write_UDCCSR(ep, UDCCSR0_FST);
+ break;
+ case IN_STATUS_STAGE:
+ /*
+ * Hardware bug : beware, we cannot clear OPC, since we would
+ * miss a potential PC irq for a setup packet.
+ * So, we only put the ep0 into WAIT_FOR_SETUP state.
+ */
+ if (opc_irq)
+ ep0_idle(udc);
+ break;
+ case OUT_STATUS_STAGE:
+ case WAIT_ACK_SET_CONF_INTERF:
+ ep_warn(ep, "should never get in %s state here!!!\n",
+ EP0_STNAME(ep->dev));
+ ep0_idle(udc);
+ break;
+ }
+}
+
+static void handle_ep(struct pxa_ep *ep)
+{
+ struct pxa27x_request *req;
+ int completed;
+ u32 udccsr;
+ int is_in = ep->dir_in;
+ int loop = 0;
+
+ do {
+ completed = 0;
+ udccsr = udc_ep_readl(ep, UDCCSR);
+
+ if (likely(!list_empty(&ep->queue)))
+ req = list_entry(ep->queue.next,
+ struct pxa27x_request, queue);
+ else
+ req = NULL;
+
+ ep_dbg(ep, "req:%p, udccsr 0x%03x loop=%d\n",
+ req, udccsr, loop++);
+
+ if (unlikely(udccsr & (UDCCSR_SST | UDCCSR_TRN)))
+ udc_ep_writel(ep, UDCCSR,
+ udccsr & (UDCCSR_SST | UDCCSR_TRN));
+ if (!req)
+ break;
+
+ if (unlikely(is_in)) {
+ if (likely(!ep_is_full(ep)))
+ completed = write_fifo(ep, req);
+ } else {
+ if (likely(epout_has_pkt(ep)))
+ completed = read_fifo(ep, req);
+ }
+
+ if (completed) {
+ if (is_in)
+ ep_end_in_req(ep, req);
+ else
+ ep_end_out_req(ep, req);
+ }
+ } while (completed);
+
+ return;
+}
+
+static void pxa27x_change_configuration(struct pxa_udc *udc, int config)
+{
+ struct usb_ctrlrequest req ;
+
+ dev_dbg(udc->dev, "config=%d\n", config);
+
+ udc->config = config;
+ udc->last_interface = 0;
+ udc->last_alternate = 0;
+
+ req.bRequestType = 0;
+ req.bRequest = USB_REQ_SET_CONFIGURATION;
+ req.wValue = config;
+ req.wIndex = 0;
+ req.wLength = 0;
+
+ set_ep0state(udc, WAIT_ACK_SET_CONF_INTERF);
+ udc->driver->setup(&udc->gadget, &req);
+}
+
+static void pxa27x_change_interface(struct pxa_udc *udc, int iface, int alt)
+{
+ struct usb_ctrlrequest req;
+
+ dev_dbg(udc->dev, "interface=%d, alternate setting=%d\n", iface, alt);
+
+ udc->last_interface = iface;
+ udc->last_alternate = alt;
+
+ req.bRequestType = USB_RECIP_INTERFACE;
+ req.bRequest = USB_REQ_SET_INTERFACE;
+ req.wValue = alt;
+ req.wIndex = iface;
+ req.wLength = 0;
+
+ set_ep0state(udc, WAIT_ACK_SET_CONF_INTERF);
+ ep_write_UDCCSR(&udc->pxa_ep[0], UDCCSR0_AREN);
+ udc->driver->setup(&udc->gadget, &req);
+}
+
+static void irq_handle_data(struct pxa_udc *udc)
+{
+ int i;
+ struct pxa_ep *ep;
+ u32 udcisr0 = udc_readl(udc, UDCISR0) & UDCCISR0_EP_MASK;
+ u32 udcisr1 = udc_readl(udc, UDCISR1) & UDCCISR1_EP_MASK;
+
+ if (udcisr0 & UDCISR_INT_MASK) {
+ udc_writel(udc, UDCISR0, UDCISR_INT(0, UDCISR_INT_MASK));
+ handle_ep0(udc, !!(udcisr0 & UDCICR_FIFOERR),
+ !!(udcisr0 & UDCICR_PKTCOMPL));
+ }
+
+ udcisr0 >>= 2;
+ for (i = 1; udcisr0 != 0 && i < 16; udcisr0 >>= 2, i++) {
+ if (!(udcisr0 & UDCISR_INT_MASK))
+ continue;
+
+ udc_writel(udc, UDCISR0, UDCISR_INT(i, UDCISR_INT_MASK));
+
+ WARN_ON(i >= ARRAY_SIZE(udc->pxa_ep));
+ if (i < ARRAY_SIZE(udc->pxa_ep)) {
+ ep = &udc->pxa_ep[i];
+ if (ep->enabled)
+ handle_ep(ep);
+ }
+ }
+
+ for (i = 16; udcisr1 != 0 && i < 24; udcisr1 >>= 2, i++) {
+ udc_writel(udc, UDCISR1, UDCISR_INT(i - 16, UDCISR_INT_MASK));
+ if (!(udcisr1 & UDCISR_INT_MASK))
+ continue;
+
+ WARN_ON(i >= ARRAY_SIZE(udc->pxa_ep));
+ if (i < ARRAY_SIZE(udc->pxa_ep)) {
+ ep = &udc->pxa_ep[i];
+ if (ep->enabled)
+ handle_ep(ep);
+ }
+ }
+
+}
+
+static void irq_udc_suspend(struct pxa_udc *udc)
+{
+ udc_writel(udc, UDCISR1, UDCISR1_IRSU);
+
+ if (udc->gadget.speed != USB_SPEED_UNKNOWN
+ && udc->driver && udc->driver->suspend)
+ udc->driver->suspend(&udc->gadget);
+ ep0_idle(udc);
+}
+
+static void irq_udc_resume(struct pxa_udc *udc)
+{
+ udc_writel(udc, UDCISR1, UDCISR1_IRRU);
+
+ if (udc->gadget.speed != USB_SPEED_UNKNOWN
+ && udc->driver && udc->driver->resume)
+ udc->driver->resume(&udc->gadget);
+}
+
+static void irq_udc_reconfig(struct pxa_udc *udc)
+{
+ unsigned config, interface, alternate, config_change;
+ u32 udccr = udc_readl(udc, UDCCR);
+
+ udc_writel(udc, UDCISR1, UDCISR1_IRCC);
+
+ config = (udccr & UDCCR_ACN) >> UDCCR_ACN_S;
+ config_change = (config != udc->config);
+ if (config_change)
+ update_pxa_ep_matches(udc);
+ udc_set_mask_UDCCR(udc, UDCCR_SMAC);
+ ep_write_UDCCSR(&udc->pxa_ep[0], UDCCSR0_AREN);
+
+ pxa27x_change_configuration(udc, config);
+ interface = (udccr & UDCCR_AIN) >> UDCCR_AIN_S;
+ alternate = (udccr & UDCCR_AAISN) >> UDCCR_AAISN_S;
+
+ /*
+ * barebox specific: do not call change interface, as change_config has
+ * already setup the gadget.
+ * pxa27x_change_interface(udc, interface, alternate);
+ */
+}
+
+static void irq_udc_reset(struct pxa_udc *udc)
+{
+ u32 udccr = udc_readl(udc, UDCCR);
+ struct pxa_ep *ep = &udc->pxa_ep[0];
+
+ dev_info(udc->dev, "USB reset\n");
+ udc_writel(udc, UDCISR1, UDCISR1_IRRS);
+
+ if ((udccr & UDCCR_UDA) == 0) {
+ dev_dbg(udc->dev, "USB reset start\n");
+ stop_activity(udc, udc->driver);
+ }
+ udc->gadget.speed = USB_SPEED_FULL;
+
+ nuke(ep, -EPROTO);
+ ep_write_UDCCSR(ep, UDCCSR0_FTF | UDCCSR0_OPC);
+ ep0_idle(udc);
+}
+
+int usb_gadget_poll(void)
+{
+ struct pxa_udc *udc = the_controller;
+ u32 udcisr0 = udc_readl(udc, UDCISR0);
+ u32 udcisr1 = udc_readl(udc, UDCISR1);
+ u32 udccr = udc_readl(udc, UDCCR);
+ u32 udcisr1_spec;
+ int ret = 0;
+
+ udc->vbus_sensed = udc->mach->udc_is_connected();
+ if (should_enable_udc(udc))
+ udc_enable(udc);
+ if (should_disable_udc(udc)) {
+ stop_activity(udc, udc->driver);
+ udc_disable(udc);
+ }
+
+ if (!udc->enabled)
+ return -EIO;
+
+ dev_dbg(udc->dev, "Interrupt, UDCISR0:0x%08x, UDCISR1:0x%08x, "
+ "UDCCR:0x%08x\n", udcisr0, udcisr1, udccr);
+
+ udcisr1_spec = udcisr1 & 0xf8000000;
+ if (unlikely(udcisr1_spec & UDCISR1_IRSU))
+ irq_udc_suspend(udc);
+ if (unlikely(udcisr1_spec & UDCISR1_IRRU))
+ irq_udc_resume(udc);
+ if (unlikely(udcisr1_spec & UDCISR1_IRCC))
+ irq_udc_reconfig(udc);
+ if (unlikely(udcisr1_spec & UDCISR1_IRRS))
+ irq_udc_reset(udc);
+ if (udcisr1_spec)
+ ret = 1;
+
+ if ((udcisr0 & UDCCISR0_EP_MASK) | (udcisr1 & UDCCISR1_EP_MASK)) {
+ irq_handle_data(udc);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+static struct pxa_udc memory = {
+ .gadget = {
+ .ops = &pxa_udc_ops,
+ .ep0 = &memory.udc_usb_ep[0].usb_ep,
+ .name = driver_name,
+ },
+
+ .udc_usb_ep = {
+ USB_EP_CTRL,
+ USB_EP_OUT_BULK(1),
+ USB_EP_IN_BULK(2),
+ USB_EP_IN_ISO(3),
+ USB_EP_OUT_ISO(4),
+ USB_EP_IN_INT(5),
+ },
+
+ .pxa_ep = {
+ PXA_EP_CTRL,
+ /* Endpoints for gadget zero */
+ PXA_EP_OUT_BULK(1, 1, 3, 0, 0),
+ PXA_EP_IN_BULK(2, 2, 3, 0, 0),
+ /* Endpoints for ether gadget, file storage gadget */
+ PXA_EP_OUT_BULK(3, 1, 1, 0, 0),
+ PXA_EP_IN_BULK(4, 2, 1, 0, 0),
+ PXA_EP_IN_ISO(5, 3, 1, 0, 0),
+ PXA_EP_OUT_ISO(6, 4, 1, 0, 0),
+ PXA_EP_IN_INT(7, 5, 1, 0, 0),
+ /* Endpoints for RNDIS, serial */
+ PXA_EP_OUT_BULK(8, 1, 2, 0, 0),
+ PXA_EP_IN_BULK(9, 2, 2, 0, 0),
+ PXA_EP_IN_INT(10, 5, 2, 0, 0),
+ /*
+ * All the following endpoints are only for completion. They
+ * won't never work, as multiple interfaces are really broken on
+ * the pxa.
+ */
+ PXA_EP_OUT_BULK(11, 1, 2, 1, 0),
+ PXA_EP_IN_BULK(12, 2, 2, 1, 0),
+ /* Endpoint for CDC Ether */
+ PXA_EP_OUT_BULK(13, 1, 1, 1, 1),
+ PXA_EP_IN_BULK(14, 2, 1, 1, 1),
+ }
+};
+
+static int __init pxa_udc_probe(struct device_d *dev)
+{
+ struct pxa_udc *udc = &memory;
+ int gpio;
+
+ udc->regs = dev_request_mem_region(dev, 0);
+ if (!udc->regs)
+ return -ENXIO;
+
+ udc->dev = dev;
+ udc->mach = dev->platform_data;
+
+ gpio = udc->mach->gpio_pullup;
+ if (gpio >= 0) {
+ gpio_direction_output(gpio,
+ udc->mach->gpio_pullup_inverted);
+ }
+
+ udc->vbus_sensed = 0;
+
+ the_controller = udc;
+ udc_init_data(udc);
+ pxa_eps_setup(udc);
+ return 0;
+}
+
+#define pxa27x_clear_otgph() do {} while (0)
+
+static struct driver_d udc_driver = {
+ .name = "pxa27x-udc",
+ .probe = pxa_udc_probe,
+};
+
+static int pxa27x_udc_poller(struct poller_struct *poller)
+{
+ return usb_gadget_poll();
+}
+static struct poller_struct poller = {
+ .func = pxa27x_udc_poller
+};
+
+static int __init pxa27x_udc_init(void)
+{
+ register_driver(&udc_driver);
+ poller_register(&poller);
+ return 0;
+}
+
+device_initcall(pxa27x_udc_init);
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h
new file mode 100644
index 0000000..eace2e4
--- /dev/null
+++ b/drivers/usb/gadget/pxa27x_udc.h
@@ -0,0 +1,393 @@
+/*
+ * linux/drivers/usb/gadget/pxa27x_udc.h
+ * Intel PXA27x on-chip full speed USB device controller
+ *
+ * Inspired by original driver by Frank Becker, David Brownell, and others.
+ * Copyright (C) 2008 Robert Jarzmik
+ *
+ * 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
+ *
+ * Taken from linux-2.6 kernel and adapted to barebox.
+ */
+
+#ifndef __LINUX_USB_GADGET_PXA27X_H
+#define __LINUX_USB_GADGET_PXA27X_H
+
+/*
+ * Register definitions
+ */
+/* Offsets */
+#define UDCCR 0x0000 /* UDC Control Register */
+#define UDCICR0 0x0004 /* UDC Interrupt Control Register0 */
+#define UDCICR1 0x0008 /* UDC Interrupt Control Register1 */
+#define UDCISR0 0x000C /* UDC Interrupt Status Register 0 */
+#define UDCISR1 0x0010 /* UDC Interrupt Status Register 1 */
+#define UDCFNR 0x0014 /* UDC Frame Number Register */
+#define UDCOTGICR 0x0018 /* UDC On-The-Go interrupt control */
+#define UP2OCR 0x0020 /* USB Port 2 Output Control register */
+#define UP3OCR 0x0024 /* USB Port 3 Output Control register */
+#define UDCCSRn(x) (0x0100 + ((x)<<2)) /* UDC Control/Status register */
+#define UDCBCRn(x) (0x0200 + ((x)<<2)) /* UDC Byte Count Register */
+#define UDCDRn(x) (0x0300 + ((x)<<2)) /* UDC Data Register */
+#define UDCCRn(x) (0x0400 + ((x)<<2)) /* UDC Control Register */
+
+#define UDCCR_OEN (1 << 31) /* On-the-Go Enable */
+#define UDCCR_AALTHNP (1 << 30) /* A-device Alternate Host Negotiation
+ Protocol Port Support */
+#define UDCCR_AHNP (1 << 29) /* A-device Host Negotiation Protocol
+ Support */
+#define UDCCR_BHNP (1 << 28) /* B-device Host Negotiation Protocol
+ Enable */
+#define UDCCR_DWRE (1 << 16) /* Device Remote Wake-up Enable */
+#define UDCCR_ACN (0x03 << 11) /* Active UDC configuration Number */
+#define UDCCR_ACN_S 11
+#define UDCCR_AIN (0x07 << 8) /* Active UDC interface Number */
+#define UDCCR_AIN_S 8
+#define UDCCR_AAISN (0x07 << 5) /* Active UDC Alternate Interface
+ Setting Number */
+#define UDCCR_AAISN_S 5
+#define UDCCR_SMAC (1 << 4) /* Switch Endpoint Memory to Active
+ Configuration */
+#define UDCCR_EMCE (1 << 3) /* Endpoint Memory Configuration
+ Error */
+#define UDCCR_UDR (1 << 2) /* UDC Resume */
+#define UDCCR_UDA (1 << 1) /* UDC Active */
+#define UDCCR_UDE (1 << 0) /* UDC Enable */
+
+#define UDCICR_INT(n, intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
+#define UDCICR1_IECC (1 << 31) /* IntEn - Configuration Change */
+#define UDCICR1_IESOF (1 << 30) /* IntEn - Start of Frame */
+#define UDCICR1_IERU (1 << 29) /* IntEn - Resume */
+#define UDCICR1_IESU (1 << 28) /* IntEn - Suspend */
+#define UDCICR1_IERS (1 << 27) /* IntEn - Reset */
+#define UDCICR_FIFOERR (1 << 1) /* FIFO Error interrupt for EP */
+#define UDCICR_PKTCOMPL (1 << 0) /* Packet Complete interrupt for EP */
+#define UDCICR_INT_MASK (UDCICR_FIFOERR | UDCICR_PKTCOMPL)
+
+#define UDCISR_INT(n, intr) (((intr) & 0x03) << (((n) & 0x0F) * 2))
+#define UDCISR1_IRCC (1 << 31) /* IntReq - Configuration Change */
+#define UDCISR1_IRSOF (1 << 30) /* IntReq - Start of Frame */
+#define UDCISR1_IRRU (1 << 29) /* IntReq - Resume */
+#define UDCISR1_IRSU (1 << 28) /* IntReq - Suspend */
+#define UDCISR1_IRRS (1 << 27) /* IntReq - Reset */
+#define UDCISR_INT_MASK (UDCICR_FIFOERR | UDCICR_PKTCOMPL)
+
+#define UDCOTGICR_IESF (1 << 24) /* OTG SET_FEATURE command recvd */
+#define UDCOTGICR_IEXR (1 << 17) /* Extra Transceiver Interrupt
+ Rising Edge Interrupt Enable */
+#define UDCOTGICR_IEXF (1 << 16) /* Extra Transceiver Interrupt
+ Falling Edge Interrupt Enable */
+#define UDCOTGICR_IEVV40R (1 << 9) /* OTG Vbus Valid 4.0V Rising Edge
+ Interrupt Enable */
+#define UDCOTGICR_IEVV40F (1 << 8) /* OTG Vbus Valid 4.0V Falling Edge
+ Interrupt Enable */
+#define UDCOTGICR_IEVV44R (1 << 7) /* OTG Vbus Valid 4.4V Rising Edge
+ Interrupt Enable */
+#define UDCOTGICR_IEVV44F (1 << 6) /* OTG Vbus Valid 4.4V Falling Edge
+ Interrupt Enable */
+#define UDCOTGICR_IESVR (1 << 5) /* OTG Session Valid Rising Edge
+ Interrupt Enable */
+#define UDCOTGICR_IESVF (1 << 4) /* OTG Session Valid Falling Edge
+ Interrupt Enable */
+#define UDCOTGICR_IESDR (1 << 3) /* OTG A-Device SRP Detect Rising
+ Edge Interrupt Enable */
+#define UDCOTGICR_IESDF (1 << 2) /* OTG A-Device SRP Detect Falling
+ Edge Interrupt Enable */
+#define UDCOTGICR_IEIDR (1 << 1) /* OTG ID Change Rising Edge
+ Interrupt Enable */
+#define UDCOTGICR_IEIDF (1 << 0) /* OTG ID Change Falling Edge
+ Interrupt Enable */
+
+/* Host Port 2 field bits */
+#define UP2OCR_CPVEN (1 << 0) /* Charge Pump Vbus Enable */
+#define UP2OCR_CPVPE (1 << 1) /* Charge Pump Vbus Pulse Enable */
+ /* Transceiver enablers */
+#define UP2OCR_DPPDE (1 << 2) /* D+ Pull Down Enable */
+#define UP2OCR_DMPDE (1 << 3) /* D- Pull Down Enable */
+#define UP2OCR_DPPUE (1 << 4) /* D+ Pull Up Enable */
+#define UP2OCR_DMPUE (1 << 5) /* D- Pull Up Enable */
+#define UP2OCR_DPPUBE (1 << 6) /* D+ Pull Up Bypass Enable */
+#define UP2OCR_DMPUBE (1 << 7) /* D- Pull Up Bypass Enable */
+#define UP2OCR_EXSP (1 << 8) /* External Transceiver Speed Control */
+#define UP2OCR_EXSUS (1 << 9) /* External Transceiver Speed Enable */
+#define UP2OCR_IDON (1 << 10) /* OTG ID Read Enable */
+#define UP2OCR_HXS (1 << 16) /* Transceiver Output Select */
+#define UP2OCR_HXOE (1 << 17) /* Transceiver Output Enable */
+#define UP2OCR_SEOS (1 << 24) /* Single-Ended Output Select */
+
+#define UDCCSR0_ACM (1 << 9) /* Ack Control Mode */
+#define UDCCSR0_AREN (1 << 8) /* Ack Response Enable */
+#define UDCCSR0_SA (1 << 7) /* Setup Active */
+#define UDCCSR0_RNE (1 << 6) /* Receive FIFO Not Empty */
+#define UDCCSR0_FST (1 << 5) /* Force Stall */
+#define UDCCSR0_SST (1 << 4) /* Sent Stall */
+#define UDCCSR0_DME (1 << 3) /* DMA Enable */
+#define UDCCSR0_FTF (1 << 2) /* Flush Transmit FIFO */
+#define UDCCSR0_IPR (1 << 1) /* IN Packet Ready */
+#define UDCCSR0_OPC (1 << 0) /* OUT Packet Complete */
+
+#define UDCCSR_DPE (1 << 9) /* Data Packet Error */
+#define UDCCSR_FEF (1 << 8) /* Flush Endpoint FIFO */
+#define UDCCSR_SP (1 << 7) /* Short Packet Control/Status */
+#define UDCCSR_BNE (1 << 6) /* Buffer Not Empty (IN endpoints) */
+#define UDCCSR_BNF (1 << 6) /* Buffer Not Full (OUT endpoints) */
+#define UDCCSR_FST (1 << 5) /* Force STALL */
+#define UDCCSR_SST (1 << 4) /* Sent STALL */
+#define UDCCSR_DME (1 << 3) /* DMA Enable */
+#define UDCCSR_TRN (1 << 2) /* Tx/Rx NAK */
+#define UDCCSR_PC (1 << 1) /* Packet Complete */
+#define UDCCSR_FS (1 << 0) /* FIFO needs service */
+
+#define UDCCONR_CN (0x03 << 25) /* Configuration Number */
+#define UDCCONR_CN_S 25
+#define UDCCONR_IN (0x07 << 22) /* Interface Number */
+#define UDCCONR_IN_S 22
+#define UDCCONR_AISN (0x07 << 19) /* Alternate Interface Number */
+#define UDCCONR_AISN_S 19
+#define UDCCONR_EN (0x0f << 15) /* Endpoint Number */
+#define UDCCONR_EN_S 15
+#define UDCCONR_ET (0x03 << 13) /* Endpoint Type: */
+#define UDCCONR_ET_S 13
+#define UDCCONR_ET_INT (0x03 << 13) /* Interrupt */
+#define UDCCONR_ET_BULK (0x02 << 13) /* Bulk */
+#define UDCCONR_ET_ISO (0x01 << 13) /* Isochronous */
+#define UDCCONR_ET_NU (0x00 << 13) /* Not used */
+#define UDCCONR_ED (1 << 12) /* Endpoint Direction */
+#define UDCCONR_MPS (0x3ff << 2) /* Maximum Packet Size */
+#define UDCCONR_MPS_S 2
+#define UDCCONR_DE (1 << 1) /* Double Buffering Enable */
+#define UDCCONR_EE (1 << 0) /* Endpoint Enable */
+
+#define UDCCR_MASK_BITS (UDCCR_OEN | UDCCR_SMAC | UDCCR_UDR | UDCCR_UDE)
+#define UDCCSR_WR_MASK (UDCCSR_DME | UDCCSR_FST)
+#define UDC_FNR_MASK (0x7ff)
+#define UDC_BCR_MASK (0x3ff)
+
+/*
+ * UDCCR = UDC Endpoint Configuration Registers
+ * UDCCSR = UDC Control/Status Register for this EP
+ * UDCBCR = UDC Byte Count Remaining (contents of OUT fifo)
+ * UDCDR = UDC Endpoint Data Register (the fifo)
+ */
+#define ofs_UDCCR(ep) (UDCCRn(ep->idx))
+#define ofs_UDCCSR(ep) (UDCCSRn(ep->idx))
+#define ofs_UDCBCR(ep) (UDCBCRn(ep->idx))
+#define ofs_UDCDR(ep) (UDCDRn(ep->idx))
+
+/* Register access macros */
+#define udc_ep_readl(ep, reg) \
+ readl((ep)->dev->regs + ofs_##reg(ep))
+#define udc_ep_writel(ep, reg, value) \
+ writel((value), ep->dev->regs + ofs_##reg(ep))
+#define udc_ep_readb(ep, reg) \
+ readb((ep)->dev->regs + ofs_##reg(ep))
+#define udc_ep_writeb(ep, reg, value) \
+ writeb((value), ep->dev->regs + ofs_##reg(ep))
+#define udc_readl(dev, reg) \
+ readl((dev)->regs + (reg))
+#define udc_writel(udc, reg, value) \
+ writel((value), (udc)->regs + (reg))
+
+#define UDCCSR_MASK (UDCCSR_FST | UDCCSR_DME)
+#define UDCCISR0_EP_MASK (~0)
+#define UDCCISR1_EP_MASK 0xffff
+#define UDCCSR0_CTRL_REQ_MASK (UDCCSR0_OPC | UDCCSR0_SA | UDCCSR0_RNE)
+
+#define EPIDX(ep) (ep->idx)
+#define EPADDR(ep) (ep->addr)
+#define EPXFERTYPE(ep) (ep->type)
+#define EPNAME(ep) (ep->name)
+#define is_ep0(ep) (!ep->idx)
+#define EPXFERTYPE_is_ISO(ep) (EPXFERTYPE(ep) == USB_ENDPOINT_XFER_ISOC)
+
+/*
+ * Endpoint definition helpers
+ */
+#define USB_EP_DEF(addr, bname, dir, type, maxpkt) \
+{ .usb_ep = { .name = bname, .ops = &pxa_ep_ops, .maxpacket = maxpkt, }, \
+ .desc = { .bEndpointAddress = addr | (dir ? USB_DIR_IN : 0), \
+ .bmAttributes = type, \
+ .wMaxPacketSize = maxpkt, }, \
+ .dev = &memory \
+}
+#define USB_EP_BULK(addr, bname, dir) \
+ USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_BULK, BULK_FIFO_SIZE)
+#define USB_EP_ISO(addr, bname, dir) \
+ USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_ISOC, ISO_FIFO_SIZE)
+#define USB_EP_INT(addr, bname, dir) \
+ USB_EP_DEF(addr, bname, dir, USB_ENDPOINT_XFER_INT, INT_FIFO_SIZE)
+#define USB_EP_IN_BULK(n) USB_EP_BULK(n, "ep" #n "in-bulk", 1)
+#define USB_EP_OUT_BULK(n) USB_EP_BULK(n, "ep" #n "out-bulk", 0)
+#define USB_EP_IN_ISO(n) USB_EP_ISO(n, "ep" #n "in-iso", 1)
+#define USB_EP_OUT_ISO(n) USB_EP_ISO(n, "ep" #n "out-iso", 0)
+#define USB_EP_IN_INT(n) USB_EP_INT(n, "ep" #n "in-int", 1)
+#define USB_EP_CTRL USB_EP_DEF(0, "ep0", 0, 0, EP0_FIFO_SIZE)
+
+#define PXA_EP_DEF(_idx, _addr, dir, _type, maxpkt, _config, iface, altset) \
+{ \
+ .dev = &memory, \
+ .name = "ep" #_idx, \
+ .idx = _idx, .enabled = 0, \
+ .dir_in = dir, .addr = _addr, \
+ .config = _config, .interface = iface, .alternate = altset, \
+ .type = _type, .fifo_size = maxpkt, \
+}
+#define PXA_EP_BULK(_idx, addr, dir, config, iface, alt) \
+ PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_BULK, BULK_FIFO_SIZE, \
+ config, iface, alt)
+#define PXA_EP_ISO(_idx, addr, dir, config, iface, alt) \
+ PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_ISOC, ISO_FIFO_SIZE, \
+ config, iface, alt)
+#define PXA_EP_INT(_idx, addr, dir, config, iface, alt) \
+ PXA_EP_DEF(_idx, addr, dir, USB_ENDPOINT_XFER_INT, INT_FIFO_SIZE, \
+ config, iface, alt)
+#define PXA_EP_IN_BULK(i, adr, c, f, a) PXA_EP_BULK(i, adr, 1, c, f, a)
+#define PXA_EP_OUT_BULK(i, adr, c, f, a) PXA_EP_BULK(i, adr, 0, c, f, a)
+#define PXA_EP_IN_ISO(i, adr, c, f, a) PXA_EP_ISO(i, adr, 1, c, f, a)
+#define PXA_EP_OUT_ISO(i, adr, c, f, a) PXA_EP_ISO(i, adr, 0, c, f, a)
+#define PXA_EP_IN_INT(i, adr, c, f, a) PXA_EP_INT(i, adr, 1, c, f, a)
+#define PXA_EP_CTRL PXA_EP_DEF(0, 0, 0, 0, EP0_FIFO_SIZE, 0, 0, 0)
+
+struct pxa27x_udc;
+
+struct stats {
+ unsigned long in_ops;
+ unsigned long out_ops;
+ unsigned long in_bytes;
+ unsigned long out_bytes;
+ unsigned long irqs;
+};
+
+/**
+ * struct udc_usb_ep - container of each usb_ep structure
+ * @usb_ep: usb endpoint
+ * @desc: usb descriptor, especially type and address
+ * @dev: udc managing this endpoint
+ * @pxa_ep: matching pxa_ep (cache of find_pxa_ep() call)
+ */
+struct udc_usb_ep {
+ struct usb_ep usb_ep;
+ struct usb_endpoint_descriptor desc;
+ struct pxa_udc *dev;
+ struct pxa_ep *pxa_ep;
+};
+
+struct pxa_ep {
+ struct pxa_udc *dev;
+
+ struct list_head queue;
+ unsigned enabled:1;
+
+ unsigned idx:5;
+ char *name;
+
+ /*
+ * Specific pxa endpoint data, needed for hardware initialization
+ */
+ unsigned dir_in:1;
+ unsigned addr:4;
+ unsigned config:2;
+ unsigned interface:3;
+ unsigned alternate:3;
+ unsigned fifo_size;
+ unsigned type;
+};
+
+struct pxa27x_request {
+ struct usb_request req;
+ struct udc_usb_ep *udc_usb_ep;
+ unsigned in_use:1;
+ struct list_head queue;
+};
+
+enum ep0_state {
+ WAIT_FOR_SETUP,
+ SETUP_STAGE,
+ IN_DATA_STAGE,
+ OUT_DATA_STAGE,
+ IN_STATUS_STAGE,
+ OUT_STATUS_STAGE,
+ STALL,
+ WAIT_ACK_SET_CONF_INTERF
+};
+
+static char *ep0_state_name[] = {
+ "WAIT_FOR_SETUP", "SETUP_STAGE", "IN_DATA_STAGE", "OUT_DATA_STAGE",
+ "IN_STATUS_STAGE", "OUT_STATUS_STAGE", "STALL",
+ "WAIT_ACK_SET_CONF_INTERF"
+};
+#define EP0_STNAME(udc) ep0_state_name[(udc)->ep0state]
+
+#define EP0_FIFO_SIZE 16U
+#define BULK_FIFO_SIZE 64U
+#define ISO_FIFO_SIZE 256U
+#define INT_FIFO_SIZE 16U
+
+struct udc_stats {
+ unsigned long irqs_reset;
+ unsigned long irqs_suspend;
+ unsigned long irqs_resume;
+ unsigned long irqs_reconfig;
+};
+
+#define NR_USB_ENDPOINTS (1 + 5) /* ep0 + ep1in-bulk + .. + ep3in-iso */
+#define NR_PXA_ENDPOINTS (1 + 14) /* ep0 + epA + epB + .. + epX */
+
+struct pxa_udc {
+ void __iomem *regs;
+ int irq;
+ struct clk *clk;
+ struct device_d *dev;
+
+ struct usb_gadget gadget;
+ struct usb_gadget_driver *driver;
+ struct pxa2xx_udc_mach_info *mach;
+
+ enum ep0_state ep0state;
+ struct udc_stats stats;
+
+ struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS];
+ struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS];
+
+ unsigned enabled:1;
+ unsigned pullup_on:1;
+ unsigned pullup_resume:1;
+ unsigned vbus_sensed:1;
+ unsigned config:2;
+ unsigned last_interface:3;
+ unsigned last_alternate:3;
+
+};
+
+static inline struct pxa_udc *to_gadget_udc(struct usb_gadget *gadget)
+{
+ return container_of(gadget, struct pxa_udc, gadget);
+}
+
+/*
+ * Debugging/message support
+ */
+#define ep_dbg(ep, fmt, arg...) \
+ dev_dbg(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg)
+#define ep_vdbg(ep, fmt, arg...) \
+ dev_dbg(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg)
+#define ep_err(ep, fmt, arg...) \
+ dev_err(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg)
+#define ep_info(ep, fmt, arg...) \
+ dev_info(ep->dev->dev, "%s:%s: " fmt, EPNAME(ep), __func__, ## arg)
+#define ep_warn(ep, fmt, arg...) \
+ dev_warn(ep->dev->dev, "%s:%s:" fmt, EPNAME(ep), __func__, ## arg)
+
+#endif /* __LINUX_USB_GADGET_PXA27X_H */
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c
index d3baed7..49aedc2 100644
--- a/drivers/usb/gadget/u_serial.c
+++ b/drivers/usb/gadget/u_serial.c
@@ -367,12 +367,13 @@ static void serial_putc(struct console_device *cdev, char c)
struct gs_port *port = container_of(cdev,
struct gs_port, cdev);
struct list_head *pool = &port->write_pool;
- struct usb_ep *in = port->port_usb->in;
+ struct usb_ep *in;
struct usb_request *req;
int status;
if (list_empty(pool))
return;
+ in = port->port_usb->in;
req = list_entry(pool->next, struct usb_request, list);
req->length = 1;
@@ -381,8 +382,8 @@ static void serial_putc(struct console_device *cdev, char c)
*(unsigned char *)req->buf = c;
status = usb_ep_queue(in, req);
- while (list_empty(pool))
- fsl_udc_irq();
+ while (status >= 0 && list_empty(pool))
+ status = usb_gadget_poll();
}
static int serial_tstc(struct console_device *cdev)
@@ -399,7 +400,10 @@ static int serial_getc(struct console_device *cdev)
struct gs_port, cdev);
unsigned char ch;
- while (kfifo_getc(port->recv_fifo, &ch));
+ if (!port->port_usb)
+ return -EIO;
+ while (kfifo_getc(port->recv_fifo, &ch))
+ usb_gadget_poll();
return ch;
}
@@ -421,6 +425,10 @@ int gserial_connect(struct gserial *gser, u8 port_num)
/* we "know" gserial_cleanup() hasn't been called */
port = ports[port_num].port;
+ /* In case of multiple activation (ie. multiple SET_INTERFACE) */
+ if (port->port_usb)
+ return 0;
+
/* activate the endpoints */
status = usb_ep_enable(gser->in, gser->in_desc);
if (status < 0)
@@ -475,7 +483,7 @@ static int do_mycdev(struct command *cmdtp, int argc, char *argv[])
printf("%c", i);
mdelay(500);
for (j = 0; j < 100; j++)
- fsl_udc_irq();
+ usb_gadget_poll();
}
return 0;
}
@@ -498,7 +506,9 @@ BAREBOX_CMD_END
void gserial_disconnect(struct gserial *gser)
{
struct gs_port *port = gser->ioport;
-printf("%s\n", __func__);
+ struct console_device *cdev;
+
+ printf("%s\n", __func__);
if (!port)
return;
@@ -518,8 +528,9 @@ printf("%s\n", __func__);
gser->in->driver_data = NULL;
/* finally, free any unused/unusable I/O buffers */
-
gs_free_requests(gser->out, &port->read_pool);
gs_free_requests(gser->in, &port->write_pool);
-}
+ cdev = &port->cdev;
+ console_unregister(cdev);
+}
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index f6c8c06..b80c039 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -1,2 +1,3 @@
config USB_STORAGE
tristate "USB Mass Storage support"
+ select DISK
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index d033b29..865ba8e 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -96,8 +96,8 @@ static int usb_stor_test_unit_ready(ccb *srb, struct us_data *us)
retries = 10;
do {
US_DEBUGP("SCSI_TST_U_RDY\n");
- memset(&srb->cmd[0], 0, 6);
- srb->cmdlen = 6;
+ memset(&srb->cmd[0], 0, 12);
+ srb->cmdlen = 12;
srb->cmd[0] = SCSI_TST_U_RDY;
srb->datalen = 0;
result = us->transport(srb, us);
@@ -193,35 +193,34 @@ static int usb_stor_write_10(ccb *srb, struct us_data *us,
* Disk driver interface
***********************************************************************/
-#define US_MAX_IO_BLK 32U
+#define US_MAX_IO_BLK 32
+
+#define to_usb_mass_storage(x) container_of((x), struct us_blk_dev, blk)
enum { io_rd, io_wr };
/* Read / write a chunk of sectors on media */
-static int usb_stor_blk_io(int io_op, struct device_d *disk_dev,
- uint64_t sector_start, unsigned sector_count,
- void *buffer)
+static int usb_stor_blk_io(int io_op, struct block_device *disk_dev,
+ int sector_start, int sector_count, void *buffer)
{
- struct ata_interface *pata_if = disk_dev->platform_data;
- struct us_blk_dev *pblk_dev = (struct us_blk_dev *)pata_if->priv;
+ struct us_blk_dev *pblk_dev = to_usb_mass_storage(disk_dev);
struct us_data *us = pblk_dev->us;
ccb us_ccb;
- ushort const sector_size = 512;
unsigned sectors_done;
if (sector_count == 0)
return 0;
/* check for unsupported block size */
- if (pblk_dev->blksz != sector_size) {
- US_DEBUGP("%s: unsupported block size %lu\n",
- __func__, pblk_dev->blksz);
+ if (pblk_dev->blk.blockbits != SECTOR_SHIFT) {
+ US_DEBUGP("%s: unsupported block shift %d\n",
+ __func__, pblk_dev->blk.blockbits);
return -EINVAL;
}
/* check for invalid sector_start */
- if (sector_start >= pblk_dev->blknum || sector_start > (ulong)-1) {
- US_DEBUGP("%s: start sector %llu too large\n",
+ if (sector_start >= pblk_dev->blk.num_blocks || sector_start > (ulong)-1) {
+ US_DEBUGP("%s: start sector %d too large\n",
__func__, sector_start);
return -EINVAL;
}
@@ -242,21 +241,21 @@ static int usb_stor_blk_io(int io_op, struct device_d *disk_dev,
sector_count = INT_MAX;
US_DEBUGP("Restricting I/O to %u blocks\n", sector_count);
}
- if (sector_start + sector_count > pblk_dev->blknum) {
- sector_count = pblk_dev->blknum - sector_start;
+ if (sector_start + sector_count > pblk_dev->blk.num_blocks) {
+ sector_count = pblk_dev->blk.num_blocks - sector_start;
US_DEBUGP("Restricting I/O to %u blocks\n", sector_count);
}
/* read / write the requested data */
- US_DEBUGP("%s %u block(s), starting from %llu\n",
+ US_DEBUGP("%s %u block(s), starting from %d\n",
((io_op == io_rd) ? "Read" : "Write"),
sector_count, sector_start);
sectors_done = 0;
while (sector_count > 0) {
int result;
- ushort n = (ushort)min(sector_count, US_MAX_IO_BLK);
- us_ccb.pdata = buffer + sectors_done * sector_size;
- us_ccb.datalen = n * (ulong)sector_size;
+ unsigned n = min(sector_count, US_MAX_IO_BLK);
+ us_ccb.pdata = buffer + (sectors_done * SECTOR_SIZE);
+ us_ccb.datalen = n * SECTOR_SIZE;
if (io_op == io_rd)
result = usb_stor_read_10(&us_ccb, us,
(ulong)sector_start, n);
@@ -264,7 +263,7 @@ static int usb_stor_blk_io(int io_op, struct device_d *disk_dev,
result = usb_stor_write_10(&us_ccb, us,
(ulong)sector_start, n);
if (result != 0) {
- US_DEBUGP("I/O error at sector %llu\n", sector_start);
+ US_DEBUGP("I/O error at sector %d\n", sector_start);
break;
}
sector_start += n;
@@ -274,27 +273,31 @@ static int usb_stor_blk_io(int io_op, struct device_d *disk_dev,
usb_disable_asynch(0);
- US_DEBUGP("Successful I/O of %u blocks\n", sectors_done);
+ US_DEBUGP("Successful I/O of %d blocks\n", sectors_done);
return (sector_count != 0) ? -EIO : 0;
}
/* Write a chunk of sectors to media */
-static int usb_stor_blk_write(struct device_d *disk_dev, uint64_t sector_start,
- unsigned sector_count, const void *buffer)
+static int __maybe_unused usb_stor_blk_write(struct block_device *blk,
+ const void *buffer, int block, int num_blocks)
{
- return usb_stor_blk_io(io_wr, disk_dev, sector_start, sector_count,
- (void *)buffer);
+ return usb_stor_blk_io(io_wr, blk, block, num_blocks, (void *)buffer);
}
/* Read a chunk of sectors from media */
-static int usb_stor_blk_read(struct device_d *disk_dev, uint64_t sector_start,
- unsigned sector_count, void *buffer)
+static int usb_stor_blk_read(struct block_device *blk, void *buffer, int block,
+ int num_blocks)
{
- return usb_stor_blk_io(io_rd, disk_dev, sector_start, sector_count,
- buffer);
+ return usb_stor_blk_io(io_rd, blk, block, num_blocks, buffer);
}
+static struct block_device_ops usb_mass_storage_ops = {
+ .read = usb_stor_blk_read,
+#ifdef CONFIG_BLOCK_WRITE
+ .write = usb_stor_blk_write,
+#endif
+};
/***********************************************************************
* Block device routines
@@ -302,6 +305,16 @@ static int usb_stor_blk_read(struct device_d *disk_dev, uint64_t sector_start,
static unsigned char us_io_buf[512];
+static int usb_limit_blk_cnt(unsigned cnt)
+{
+ if (cnt > 0x7fffffff) {
+ pr_warn("Limiting device size due to 31 bit contraints\n");
+ return 0x7fffffff;
+ }
+
+ return (int)cnt;
+}
+
/* Prepare a disk device */
static int usb_stor_init_blkdev(struct us_blk_dev *pblk_dev)
{
@@ -313,7 +326,7 @@ static int usb_stor_init_blkdev(struct us_blk_dev *pblk_dev)
us_ccb.pdata = us_io_buf;
us_ccb.lun = pblk_dev->lun;
- pblk_dev->blknum = 0;
+ pblk_dev->blk.num_blocks = 0;
usb_disable_asynch(1);
/* get device info */
@@ -350,11 +363,12 @@ static int usb_stor_init_blkdev(struct us_blk_dev *pblk_dev)
}
pcap = (unsigned long *)us_ccb.pdata;
US_DEBUGP("Read Capacity returns: 0x%lx, 0x%lx\n", pcap[0], pcap[1]);
- pblk_dev->blknum = be32_to_cpu(pcap[0]);
- pblk_dev->blksz = be32_to_cpu(pcap[1]);
- pblk_dev->blknum++;
- US_DEBUGP("Capacity = 0x%llx, blocksz = 0x%lx\n",
- pblk_dev->blknum, pblk_dev->blksz);
+ pblk_dev->blk.num_blocks = usb_limit_blk_cnt(be32_to_cpu(pcap[0]) + 1);
+ if (be32_to_cpu(pcap[1]) != SECTOR_SIZE)
+ pr_warn("Support only %d bytes sectors\n", SECTOR_SIZE);
+ pblk_dev->blk.blockbits = SECTOR_SHIFT;
+ US_DEBUGP("Capacity = 0x%x, blockshift = 0x%x\n",
+ pblk_dev->blk.num_blocks, pblk_dev->blk.blockbits);
Exit:
usb_disable_asynch(0);
@@ -362,39 +376,45 @@ Exit:
}
/* Create and register a disk device for the specified LUN */
-static int usb_stor_add_blkdev(struct us_data *us, unsigned char lun)
+static int usb_stor_add_blkdev(struct us_data *us, struct device_d *dev,
+ unsigned char lun)
{
struct us_blk_dev *pblk_dev;
- struct device_d *pdev;
- struct ata_interface *pata_if;
int result;
- /* allocate blk dev data */
- pblk_dev = (struct us_blk_dev *)malloc(sizeof(struct us_blk_dev));
- if (!pblk_dev)
- return -ENOMEM;
- memset(pblk_dev, 0, sizeof(struct us_blk_dev));
+ /* allocate a new USB block device */
+ pblk_dev = xzalloc(sizeof(struct us_blk_dev));
/* initialize blk dev data */
+ pblk_dev->blk.dev = dev;
+ pblk_dev->blk.ops = &usb_mass_storage_ops;
pblk_dev->us = us;
pblk_dev->lun = lun;
- pata_if = &pblk_dev->ata_if;
- pata_if->read = &usb_stor_blk_read;
- pata_if->write = &usb_stor_blk_write;
- pata_if->priv = pblk_dev;
- pdev = &pblk_dev->dev;
- strcpy(pdev->name, "disk");
- pdev->platform_data = pata_if;
/* read some info and get the unit ready */
result = usb_stor_init_blkdev(pblk_dev);
if (result < 0)
goto BadDevice;
- /* register disk device */
- result = register_device(pdev);
- if (result < 0)
+ result = cdev_find_free_index("disk");
+ if (result == -1)
+ pr_err("Cannot find a free number for the disk node\n");
+ pr_info("Using index %d for the new disk\n", result);
+
+ pblk_dev->blk.cdev.name = asprintf("disk%d", result);
+ pblk_dev->blk.blockbits = SECTOR_SHIFT;
+
+ result = blockdevice_register(&pblk_dev->blk);
+ if (result != 0) {
+ dev_err(dev, "Failed to register blockdevice\n");
goto BadDevice;
+ }
+
+ /* create partitions on demand */
+ result = parse_partition_table(&pblk_dev->blk);
+ if (result != 0)
+ dev_warn(dev, "No partition table found\n");
+
list_add_tail(&pblk_dev->list, &us_blkdev_list);
US_DEBUGP("USB disk device successfully added\n");
@@ -485,7 +505,7 @@ static int usb_stor_scan(struct usb_device *usbdev, struct us_data *us)
/* register a disk device for each active LUN */
for (lun=0; lun<=us->max_lun; lun++) {
- if (usb_stor_add_blkdev(us, lun) == 0)
+ if (usb_stor_add_blkdev(us, &usbdev->dev, lun) == 0)
num_devs++;
}
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 17a1e12..5942393 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -26,7 +26,8 @@
#define _STORAGE_USB_H_
#include <usb/usb.h>
-#include <ata.h>
+#include <block.h>
+#include <disks.h>
#include <scsi.h>
#include <linux/list.h>
@@ -85,10 +86,7 @@ struct us_data {
/* one us_blk_dev object allocated per LUN */
struct us_blk_dev {
struct us_data *us; /* LUN's enclosing dev */
- struct device_d dev; /* intf to generic driver */
- struct ata_interface ata_if; /* intf to "disk" driver */
- uint64_t blknum; /* capacity */
- unsigned long blksz; /* block size */
+ struct block_device blk; /* the blockdevice for the dev */
unsigned char lun; /* the LUN of this blk dev */
struct list_head list; /* siblings */
};
diff --git a/fs/cramfs/cramfs.c b/fs/cramfs/cramfs.c
index b9ab50f..bdbb47e 100644
--- a/fs/cramfs/cramfs.c
+++ b/fs/cramfs/cramfs.c
@@ -337,7 +337,7 @@ static int cramfs_read(struct device_d *_dev, FILE *f, void *buf, size_t size)
if (priv->curr_base < 0 || priv->curr_base != base) {
cdev_read(priv->cdev, cramfs_read_buf, 4096, base, 0);
- priv->curr_block_len = cramfs_uncompress_block(priv->buf,
+ priv->curr_block_len = cramfs_uncompress_block(priv->buf, 4096,
cramfs_read_buf, 4096);
if (priv->curr_block_len <= 0)
break;
diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c
index 659869b..b7887bd 100644
--- a/fs/cramfs/uncompress.c
+++ b/fs/cramfs/uncompress.c
@@ -1,12 +1,7 @@
/*
* uncompress.c
*
- * Copyright (C) 1999 Linus Torvalds
- * Copyright (C) 2000-2002 Transmeta Corporation
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
+ * (C) Copyright 1999 Linus Torvalds
*
* cramfs interfaces to the uncompression library. There's really just
* three entrypoints:
@@ -22,81 +17,63 @@
#include <common.h>
#include <malloc.h>
-#include <watchdog.h>
-#include <zlib.h>
+#include <linux/kernel.h>
+#include <errno.h>
+#include <linux/zlib.h>
+#include <asm/byteorder.h>
+#include <cramfs/cramfs_fs.h>
static z_stream stream;
-
-#define ZALLOC_ALIGNMENT 16
-
-static void *zalloc (void *x, unsigned items, unsigned size)
-{
- void *p;
-
- size *= items;
- size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
-
- p = malloc (size);
-
- return (p);
-}
-
-static void zfree (void *x, void *addr, unsigned nb)
-{
- free (addr);
-}
+static int initialized;
/* Returns length of decompressed data. */
-int cramfs_uncompress_block (void *dst, void *src, int srclen)
+int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen)
{
int err;
- inflateReset (&stream);
-
stream.next_in = src;
stream.avail_in = srclen;
stream.next_out = dst;
- stream.avail_out = 4096 * 2;
+ stream.avail_out = dstlen;
- err = inflate (&stream, Z_FINISH);
+ err = zlib_inflateReset(&stream);
+ if (err != Z_OK) {
+ printk("zlib_inflateReset error %d\n", err);
+ zlib_inflateEnd(&stream);
+ zlib_inflateInit(&stream);
+ }
+ err = zlib_inflate(&stream, Z_FINISH);
if (err != Z_STREAM_END)
goto err;
return stream.total_out;
- err:
- /*printf ("Error %d while decompressing!\n", err); */
- /*printf ("%p(%d)->%p\n", src, srclen, dst); */
- return -1;
+err:
+ printk("Error %d while decompressing!\n", err);
+ printk("%p(%d)->%p(%d)\n", src, srclen, dst, dstlen);
+ return -EIO;
}
-int cramfs_uncompress_init (void)
+int cramfs_uncompress_init(void)
{
- int err;
-
- stream.zalloc = zalloc;
- stream.zfree = zfree;
- stream.next_in = 0;
- stream.avail_in = 0;
-
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
- stream.outcb = (cb_func) WATCHDOG_RESET;
-#else
- stream.outcb = Z_NULL;
-#endif /* CONFIG_HW_WATCHDOG */
-
- err = inflateInit (&stream);
- if (err != Z_OK) {
- printf ("Error: inflateInit2() returned %d\n", err);
- return -1;
+ if (!initialized++) {
+ stream.workspace = malloc(zlib_inflate_workspacesize());
+ if ( !stream.workspace ) {
+ initialized = 0;
+ return -ENOMEM;
+ }
+ stream.next_in = NULL;
+ stream.avail_in = 0;
+ zlib_inflateInit(&stream);
}
-
return 0;
}
-int cramfs_uncompress_exit (void)
+void cramfs_uncompress_exit(void)
{
- inflateEnd (&stream);
- return 0;
+ if (!--initialized) {
+ zlib_inflateEnd(&stream);
+ vfree(stream.workspace);
+ }
}
diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index 519e18e..9bc3126 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -40,6 +40,20 @@ struct cdev *cdev_by_name(const char *filename)
return NULL;
}
+int cdev_find_free_index(const char *basename)
+{
+ int i;
+ char fname[100];
+
+ for (i = 0; i < 1000; i++) {
+ snprintf(fname, sizeof(fname), "%s%d", basename, i);
+ if (cdev_by_name(fname) == NULL)
+ return i;
+ }
+
+ return -EBUSY; /* all indexes are used */
+}
+
struct cdev *cdev_open(const char *name, unsigned long flags)
{
struct cdev *cdev = cdev_by_name(name);
diff --git a/fs/ramfs.c b/fs/ramfs.c
index db417e1..5e352f2 100644
--- a/fs/ramfs.c
+++ b/fs/ramfs.c
@@ -30,7 +30,7 @@
#include <linux/stat.h>
#include <xfuncs.h>
-#define CHUNK_SIZE 4096
+#define CHUNK_SIZE (4096 * 2)
struct ramfs_chunk {
char *data;
diff --git a/include/asm-generic/barebox.lds.h b/include/asm-generic/barebox.lds.h
index 8aee5d2..5467d3a 100644
--- a/include/asm-generic/barebox.lds.h
+++ b/include/asm-generic/barebox.lds.h
@@ -24,3 +24,5 @@
#define BAREBOX_CMDS KEEP(*(SORT_BY_NAME(.barebox_cmd*)))
#define BAREBOX_SYMS KEEP(*(__usymtab))
+
+#define BAREBOX_MAGICVARS KEEP(*(SORT_BY_NAME(.barebox_magicvar*)))
diff --git a/include/ata_drive.h b/include/ata_drive.h
new file mode 100644
index 0000000..cdd8049
--- /dev/null
+++ b/include/ata_drive.h
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+#ifndef ATA_DISK_H
+# define ATA_DISK
+
+/* IDE register file */
+#define IDE_REG_DATA 0x00
+#define IDE_REG_ERR 0x01
+#define IDE_REG_NSECT 0x02
+#define IDE_REG_LBAL 0x03
+#define IDE_REG_LBAM 0x04
+#define IDE_REG_LBAH 0x05
+#define IDE_REG_DEVICE 0x06
+#define IDE_REG_STATUS 0x07
+
+#define IDE_REG_FEATURE IDE_REG_ERR /* and their aliases */
+#define IDE_REG_CMD IDE_REG_STATUS
+
+#define IDE_REG_ALT_STATUS 0x00
+#define IDE_REG_DEV_CTL 0x00
+#define IDE_REG_DRV_ADDR 0x01
+
+/** addresses of each individual IDE drive register */
+struct ata_ioports {
+ void __iomem *cmd_addr;
+ void __iomem *data_addr;
+ void __iomem *error_addr;
+ void __iomem *feature_addr;
+ void __iomem *nsect_addr;
+ void __iomem *lbal_addr;
+ void __iomem *lbam_addr;
+ void __iomem *lbah_addr;
+ void __iomem *device_addr;
+ void __iomem *status_addr;
+ void __iomem *command_addr;
+ void __iomem *altstatus_addr;
+ void __iomem *ctl_addr;
+ void __iomem *alt_dev_addr;
+
+ /* hard reset line handling */
+ void (*reset)(int); /* true: assert reset, false: de-assert reset */
+ int dataif_be; /* true if 16 bit data register is big endian */
+};
+
+struct device_d;
+extern int register_ata_drive(struct device_d*, struct ata_ioports*);
+
+/**
+ * @file
+ * @brief Register file examples of generic types of ATA devices
+ *
+ * PC IDE:
+ *
+ * Offset Read Write Note
+ *-----------------------------------------------------------
+ * 0x1f0 data data 16 bit register
+ * 0x1f1 error feature
+ * 0x1f2 sec cnt set cnt
+ * 0x1f3 sec no sec no
+ * 0x1f4 cyl low cyl low
+ * 0x1f5 cyl high cyl high
+ * 0x1f6 head head
+ * 0x1f7 status command
+ * 0x3f6 alt status dev cntrl
+ * 0x3f7 drv addr
+ *
+ * PCMCIA memory mapped:
+ *
+ * Offset Read Write Note
+ *-----------------------------------------------------------
+ * 0x0 data data 16 bit register
+ * 0x1 error feature
+ * 0x2 sec cnt set cnt
+ * 0x3 sec no sec no
+ * 0x4 cyl low cyl low
+ * 0x5 cyl high cyl high
+ * 0x6 head head
+ * 0x7 status command
+ * 0x8 data data 16 bit or 8 bit register (even byte)
+ * 0x9 data data 8 bit register (odd byte)
+ * 0xd error feature dup of offset 1
+ * 0xe alt status dev cntrl
+ * 0xf drv addr
+ * 0x400 data data 16 bit area with 1 kiB in size
+ */
+
+#endif /* ATA_DISK */
diff --git a/include/boot.h b/include/boot.h
index 623f443..b67e034 100644
--- a/include/boot.h
+++ b/include/boot.h
@@ -9,15 +9,13 @@ struct image_data {
struct image_handle *initrd;
const char *oftree;
int verify;
+ unsigned long initrd_address;
+ unsigned long initrd_size;
};
struct image_handler {
struct list_head list;
- char *cmdline_options;
- int (*cmdline_parse)(struct image_data *data, int opt, char *optarg);
- char *help_string;
-
int image_type;
int (*bootm)(struct image_data *data);
};
diff --git a/include/bunzip2.h b/include/bunzip2.h
new file mode 100644
index 0000000..1152721
--- /dev/null
+++ b/include/bunzip2.h
@@ -0,0 +1,10 @@
+#ifndef DECOMPRESS_BUNZIP2_H
+#define DECOMPRESS_BUNZIP2_H
+
+int bunzip2(unsigned char *inbuf, int len,
+ int(*fill)(void*, unsigned int),
+ int(*flush)(void*, unsigned int),
+ unsigned char *output,
+ int *pos,
+ void(*error)(char *x));
+#endif
diff --git a/include/bzlib.h b/include/bzlib.h
deleted file mode 100644
index 4b0f820..0000000
--- a/include/bzlib.h
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * This file is a modified version of bzlib.h from the bzip2-1.0.2
- * distribution which can be found at http://sources.redhat.com/bzip2/
- */
-
-/*-------------------------------------------------------------*/
-/*--- Public header file for the library. ---*/
-/*--- bzlib.h ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@acm.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-
-#ifndef _BZLIB_H
-#define _BZLIB_H
-
-/* Configure for barebox environment */
-#define BZ_NO_STDIO
-#define BZ_NO_COMPRESS
-/* End of configuration for barebox environment */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define BZ_RUN 0
-#define BZ_FLUSH 1
-#define BZ_FINISH 2
-
-#define BZ_OK 0
-#define BZ_RUN_OK 1
-#define BZ_FLUSH_OK 2
-#define BZ_FINISH_OK 3
-#define BZ_STREAM_END 4
-#define BZ_SEQUENCE_ERROR (-1)
-#define BZ_PARAM_ERROR (-2)
-#define BZ_MEM_ERROR (-3)
-#define BZ_DATA_ERROR (-4)
-#define BZ_DATA_ERROR_MAGIC (-5)
-#define BZ_IO_ERROR (-6)
-#define BZ_UNEXPECTED_EOF (-7)
-#define BZ_OUTBUFF_FULL (-8)
-#define BZ_CONFIG_ERROR (-9)
-
-typedef
- struct {
- char *next_in;
- unsigned int avail_in;
- unsigned int total_in_lo32;
- unsigned int total_in_hi32;
-
- char *next_out;
- unsigned int avail_out;
- unsigned int total_out_lo32;
- unsigned int total_out_hi32;
-
- void *state;
-
- void *(*bzalloc)(void *,int,int);
- void (*bzfree)(void *,void *);
- void *opaque;
- }
- bz_stream;
-
-
-#ifndef BZ_IMPORT
-#define BZ_EXPORT
-#endif
-
-#ifdef _WIN32
-# include <windows.h>
-# ifdef small
- /* windows.h define small to char */
-# undef small
-# endif
-# ifdef BZ_EXPORT
-# define BZ_API(func) WINAPI func
-# define BZ_EXTERN extern
-# else
- /* import windows dll dynamically */
-# define BZ_API(func) (WINAPI * func)
-# define BZ_EXTERN
-# endif
-#else
-# define BZ_API(func) func
-# define BZ_EXTERN extern
-#endif
-
-
-/*-- Core (low-level) library functions --*/
-
-BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
- bz_stream* strm,
- int blockSize100k,
- int verbosity,
- int workFactor
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzCompress) (
- bz_stream* strm,
- int action
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
- bz_stream* strm
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
- bz_stream *strm,
- int verbosity,
- int small
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
- bz_stream* strm
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
- bz_stream *strm
- );
-
-
-/*-- High(er) level library functions --*/
-
-#ifndef BZ_NO_STDIO
-#define BZ_MAX_UNUSED 5000
-
-/* Need a definitition for FILE */
-#include <stdio.h>
-
-typedef void BZFILE;
-
-BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
- int* bzerror,
- FILE* f,
- int verbosity,
- int small,
- void* unused,
- int nUnused
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
- int* bzerror,
- BZFILE* b
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
- int* bzerror,
- BZFILE* b,
- void** unused,
- int* nUnused
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzRead) (
- int* bzerror,
- BZFILE* b,
- void* buf,
- int len
- );
-
-BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
- int* bzerror,
- FILE* f,
- int blockSize100k,
- int verbosity,
- int workFactor
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzWrite) (
- int* bzerror,
- BZFILE* b,
- void* buf,
- int len
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
- int* bzerror,
- BZFILE* b,
- int abandon,
- unsigned int* nbytes_in,
- unsigned int* nbytes_out
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
- int* bzerror,
- BZFILE* b,
- int abandon,
- unsigned int* nbytes_in_lo32,
- unsigned int* nbytes_in_hi32,
- unsigned int* nbytes_out_lo32,
- unsigned int* nbytes_out_hi32
- );
-#endif
-
-
-/*-- Utility functions --*/
-
-BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
- char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int blockSize100k,
- int verbosity,
- int workFactor
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
- char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int small,
- int verbosity
- );
-
-
-/*--
- Code contributed by Yoshioka Tsuneo
- (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
- to support better zlib compatibility.
- This code is not _officially_ part of libbzip2 (yet);
- I haven't tested it, documented it, or considered the
- threading-safeness of it.
- If this code breaks, please contact both Yoshioka and me.
---*/
-
-BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
- void
- );
-
-#ifndef BZ_NO_STDIO
-BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
- const char *path,
- const char *mode
- );
-
-BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
- int fd,
- const char *mode
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzread) (
- BZFILE* b,
- void* buf,
- int len
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzwrite) (
- BZFILE* b,
- void* buf,
- int len
- );
-
-BZ_EXTERN int BZ_API(BZ2_bzflush) (
- BZFILE* b
- );
-
-BZ_EXTERN void BZ_API(BZ2_bzclose) (
- BZFILE* b
- );
-
-BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
- BZFILE *b,
- int *errnum
- );
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-/*-------------------------------------------------------------*/
-/*--- end bzlib.h ---*/
-/*-------------------------------------------------------------*/
diff --git a/include/common.h b/include/common.h
index e34bbea..d594e63 100644
--- a/include/common.h
+++ b/include/common.h
@@ -107,36 +107,13 @@ long get_ram_size (volatile long *, long);
/* $(CPU)/cpu.c */
void __noreturn reset_cpu(unsigned long addr);
-/* $(CPU)/interrupts.c */
-//void timer_interrupt (struct pt_regs *);
-//void external_interrupt (struct pt_regs *);
-void irq_install_handler(int, interrupt_handler_t *, void *);
-void irq_free_handler (int);
-#ifdef CONFIG_USE_IRQ
-void enable_interrupts (void);
-int disable_interrupts (void);
-#else
-static inline void enable_interrupts(void)
-{
-}
-
-static inline int disable_interrupts(void)
-{
- return 0;
-}
-#endif
-
/* lib_$(ARCH)/time.c */
void udelay (unsigned long);
void mdelay (unsigned long);
-int gunzip(void *dst, int dstlen, unsigned char *src, unsigned long *lenp);
-
/* lib_generic/vsprintf.c */
ulong simple_strtoul(const char *cp,char **endp,unsigned int base);
-#ifdef CFG_64BIT_VSPRINTF
unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base);
-#endif
long simple_strtol(const char *cp,char **endp,unsigned int base);
/* lib_generic/crc32.c */
diff --git a/include/console.h b/include/console.h
index 3bcc5db..c0817f6 100644
--- a/include/console.h
+++ b/include/console.h
@@ -49,6 +49,7 @@ struct console_device {
};
int console_register(struct console_device *cdev);
+int console_unregister(struct console_device *cdev);
extern struct list_head console_list;
#define for_each_console(console) list_for_each_entry(console, &console_list, list)
diff --git a/include/cramfs/cramfs_fs.h b/include/cramfs/cramfs_fs.h
index 3d3c56f..af2940b 100644
--- a/include/cramfs/cramfs_fs.h
+++ b/include/cramfs/cramfs_fs.h
@@ -119,8 +119,8 @@ struct cramfs_super {
#endif
/* Uncompression interfaces to the underlying zlib */
-int cramfs_uncompress_block(void *dst, void *src, int srclen);
+int cramfs_uncompress_block(void *dst, int dstlen, void *src, int srclen);
int cramfs_uncompress_init(void);
-int cramfs_uncompress_exit(void);
+void cramfs_uncompress_exit(void);
#endif /* __CRAMFS_H */
diff --git a/include/crc7.h b/include/crc7.h
new file mode 100644
index 0000000..0c41cc3
--- /dev/null
+++ b/include/crc7.h
@@ -0,0 +1,14 @@
+#ifndef _LINUX_CRC7_H
+#define _LINUX_CRC7_H
+#include <common.h>
+
+extern const u8 crc7_syndrome_table[256];
+
+static inline u8 crc7_byte(u8 crc, u8 data)
+{
+ return crc7_syndrome_table[(crc << 1) ^ data];
+}
+
+extern u8 crc7(u8 crc, const u8 *buffer, size_t len);
+
+#endif
diff --git a/include/disks.h b/include/disks.h
new file mode 100644
index 0000000..9932750
--- /dev/null
+++ b/include/disks.h
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+#ifndef DISKS_H
+#define DISKS_H
+
+struct block_device;
+
+/** Size of one sector in bytes */
+#define SECTOR_SIZE 512
+
+/** Size of one sector in bit shift */
+#define SECTOR_SHIFT 9
+
+/**
+ * Description of one partition table entry (D*S type)
+ */
+struct partition_entry {
+ uint8_t boot_indicator; /*! Maybe marked as an active partition */
+ uint8_t chs_begin[3]; /*! Start of the partition in cylinders, heads and sectors */
+ uint8_t type; /*! Filesystem type */
+ uint8_t chs_end[3]; /*! End of the partition in cylinders, heads and sectors */
+ uint32_t partition_start; /*! Start of the partition in LBA notation */
+ uint32_t partition_size; /*! Start of the partition in LBA notation */
+} __attribute__ ((packed));
+
+extern int parse_partition_table(struct block_device*);
+
+#endif /* DISKS_H */
diff --git a/include/driver.h b/include/driver.h
index 80de0c8..bbe7248 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -190,11 +190,7 @@ void __iomem *dev_get_mem_region(struct device_d *dev, int num);
/*
* exlusively request register base 'num' for a device
*/
-static inline void __iomem *dev_request_mem_region(struct device_d *dev, int num)
-{
- /* no resource tracking yet */
- return dev_get_mem_region(dev, num);
-}
+void __iomem *dev_request_mem_region(struct device_d *dev, int num);
/*
* register a generic device
@@ -394,6 +390,7 @@ struct cdev {
int devfs_create(struct cdev *);
int devfs_remove(struct cdev *);
+int cdev_find_free_index(const char *);
struct cdev *cdev_by_name(const char *filename);
struct cdev *cdev_open(const char *name, unsigned long flags);
void cdev_close(struct cdev *cdev);
diff --git a/include/environment.h b/include/environment.h
index da032e2..6d38755 100644
--- a/include/environment.h
+++ b/include/environment.h
@@ -59,6 +59,9 @@ static inline int setenv(const char *var, const char *val)
}
#endif
+void export_env_ull(const char *name, unsigned long long val);
+unsigned long long getenv_ull(const char *name);
+
int env_pop_context(void);
int env_push_context(void);
diff --git a/include/filetype.h b/include/filetype.h
new file mode 100644
index 0000000..64d32ef
--- /dev/null
+++ b/include/filetype.h
@@ -0,0 +1,23 @@
+#ifndef __FILE_TYPE_H
+#define __FILE_TYPE_H
+
+/*
+ * List of file types we know
+ */
+enum filetype {
+ filetype_unknown,
+ filetype_arm_zimage,
+ filetype_lzo_compressed,
+ filetype_arm_barebox,
+ filetype_uimage,
+ filetype_ubi,
+ filetype_jffs2,
+ filetype_gzip,
+ filetype_bzip2,
+};
+
+const char *file_type_to_string(enum filetype f);
+enum filetype file_detect_type(void *_buf);
+enum filetype file_name_detect_type(const char *filename);
+
+#endif /* __FILE_TYPE_H */
diff --git a/include/gunzip.h b/include/gunzip.h
new file mode 100644
index 0000000..8c0aef1
--- /dev/null
+++ b/include/gunzip.h
@@ -0,0 +1,10 @@
+#ifndef INFLATE_H
+#define INFLATE_H
+
+int gunzip(unsigned char *inbuf, int len,
+ int(*fill)(void*, unsigned int),
+ int(*flush)(void*, unsigned int),
+ unsigned char *output,
+ int *pos,
+ void(*error_fn)(char *x));
+#endif
diff --git a/include/image.h b/include/image.h
index 691bf2d..f3a9949 100644
--- a/include/image.h
+++ b/include/image.h
@@ -335,9 +335,6 @@ void image_print_size(uint32_t size);
void image_print_contents(const image_header_t *hdr, void *data);
-/* commamds/bootm.c */
-void print_image_hdr (image_header_t *hdr);
-
/*
* Load an image into memory. Returns a pointer to the loaded
* image.
diff --git a/include/libbb.h b/include/libbb.h
index 0962969..2d17c3f 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -26,7 +26,7 @@ int recursive_action(const char *fileName, unsigned flags,
char * safe_strncpy(char *dst, const char *src, size_t size);
-int copy_file(const char *src, const char *dst);
+int copy_file(const char *src, const char *dst, int verbose);
int process_escape_sequence(const char *source, char *dest, int destlen);
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 5143115..c837b53 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -20,6 +20,9 @@ struct resource {
resource_size_t size;
const char *name;
unsigned long flags;
+ struct resource *parent;
+ struct list_head children;
+ struct list_head sibling;
};
/*
@@ -111,5 +114,16 @@ static inline unsigned long resource_type(const struct resource *res)
return res->flags & IORESOURCE_TYPE_BITS;
}
+struct resource *request_iomem_region(const char *name,
+ resource_size_t start, resource_size_t size);
+
+struct resource *request_region(struct resource *parent,
+ const char *name, resource_size_t start,
+ resource_size_t size);
+
+int release_region(struct resource *res);
+
+extern struct resource iomem_resource;
+
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_IOPORT_H */
diff --git a/include/linux/zconf.h b/include/linux/zconf.h
new file mode 100644
index 0000000..9e8750e
--- /dev/null
+++ b/include/linux/zconf.h
@@ -0,0 +1,57 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# define MAX_MEM_LEVEL 8
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+
+/* default memLevel */
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+
+ /* Type declarations */
+
+typedef unsigned char Byte; /* 8 bits */
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+typedef void *voidp;
+
+#endif /* _ZCONF_H */
diff --git a/include/linux/zlib.h b/include/linux/zlib.h
new file mode 100644
index 0000000..d8bd20c
--- /dev/null
+++ b/include/linux/zlib.h
@@ -0,0 +1,711 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+
+ Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#include <linux/zconf.h>
+
+/* zlib deflate based on ZLIB_VERSION "1.1.3" */
+/* zlib inflate based on ZLIB_VERSION "1.2.3" */
+
+/*
+ This is a modified version of zlib for use inside the Linux kernel.
+ The main changes are to perform all memory allocation in advance.
+
+ Inflation Changes:
+ * Z_PACKET_FLUSH is added and used by ppp_deflate. Before returning
+ this checks there is no more input data available and the next data
+ is a STORED block. It also resets the mode to be read for the next
+ data, all as per PPP requirements.
+ * Addition of zlib_inflateIncomp which copies incompressible data into
+ the history window and adjusts the accoutning without calling
+ zlib_inflate itself to inflate the data.
+*/
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed
+ data. This version of the library supports only one compression method
+ (deflation) but other algorithms will be added later and will have the same
+ stream interface.
+
+ Compression can be done in a single step if the buffers are large
+ enough (for example if an input file is mmap'ed), or can be done by
+ repeated calls of the compression function. In the latter case, the
+ application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never
+ crash even in case of corrupted input.
+*/
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ const Byte *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total nb of input bytes read so far */
+
+ Byte *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total nb of bytes output so far */
+
+ char *msg; /* last error message, NULL if no error */
+ struct internal_state *state; /* not visible by applications */
+
+ void *workspace; /* memory allocated for this stream */
+
+ int data_type; /* best guess about the data type: ascii or binary */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream *z_streamp;
+
+/*
+ The application must update next_in and avail_in when avail_in has
+ dropped to zero. It must update next_out and avail_out when avail_out
+ has dropped to zero. The application must initialize zalloc, zfree and
+ opaque before calling the init function. All other fields are set by the
+ compression library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this
+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
+ have their offset normalized to zero. The default allocation function
+ provided by this library ensures this (see zutil.c). To reduce memory
+ requirements and avoid any allocation of 64K objects, at the expense of
+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or
+ progress reports. After compression, total_in holds the total size of
+ the uncompressed data and may be saved for use in the decompressor
+ (particularly if the decompressor wants to decompress everything in
+ a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_PACKET_FLUSH 2
+#define Z_SYNC_FLUSH 3
+#define Z_FULL_FLUSH 4
+#define Z_FINISH 5
+#define Z_BLOCK 6 /* Only for inflate at present */
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_ASCII 1
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+ /* basic functions */
+
+extern int zlib_deflate_workspacesize (int windowBits, int memLevel);
+/*
+ Returns the number of bytes that needs to be allocated for a per-
+ stream workspace with the specified parameters. A pointer to this
+ number of bytes should be returned in stream->workspace before
+ you call zlib_deflateInit() or zlib_deflateInit2(). If you call
+ zlib_deflateInit(), specify windowBits = MAX_WBITS and memLevel =
+ MAX_MEM_LEVEL here. If you call zlib_deflateInit2(), the windowBits
+ and memLevel parameters passed to zlib_deflateInit2() must not
+ exceed those passed here.
+*/
+
+/*
+extern int deflateInit (z_streamp strm, int level);
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller.
+ If zalloc and zfree are set to NULL, deflateInit updates them to
+ use default allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
+ all (the input data is simply copied a block at a time).
+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+ compression (currently equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION).
+ msg is set to null if there is no error message. deflateInit does not
+ perform any compression: this will be done by deflate().
+*/
+
+
+extern int zlib_deflate (z_streamp strm, int flush);
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce some
+ output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications).
+ Some output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating avail_in or avail_out accordingly; avail_out
+ should never be zero before the call. The application can consume the
+ compressed output when it wants, for example when the output buffer is full
+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+ and with zero avail_out, it must be called again after making room in the
+ output buffer because there might be more output pending.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In particular
+ avail_in is zero after the call if enough output space has been provided
+ before the call.) Flushing may degrade compression for some compression
+ algorithms and so it should be used only when necessary.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ the compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out).
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there
+ was enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the
+ stream are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least
+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return
+ Z_STREAM_END, then it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update data_type if it can make a good guess about
+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect
+ the compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero).
+*/
+
+
+extern int zlib_deflateEnd (z_streamp strm);
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case,
+ msg may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+extern int zlib_inflate_workspacesize (void);
+/*
+ Returns the number of bytes that needs to be allocated for a per-
+ stream workspace. A pointer to this number of bytes should be
+ returned in stream->workspace before calling zlib_inflateInit().
+*/
+
+/*
+extern int zlib_inflateInit (z_streamp strm);
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, and workspace must be initialized before by
+ the caller. If next_in is not NULL and avail_in is large enough (the exact
+ value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller. msg is set to null if there is no error
+ message. inflateInit does not perform any decompression apart from reading
+ the zlib header if present: this will be done by inflate(). (So next_in and
+ avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+extern int zlib_inflate (z_streamp strm, int flush);
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing
+ will resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there
+ is no more input data or no more space in the output buffer (see below
+ about the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating the next_* and avail_* values accordingly.
+ The application can consume the uncompressed output when it wants, for
+ example when the output buffer is full (avail_out == 0), or after each
+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+ must be called again after making room in the output buffer because there
+ might be more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
+ Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate() stop
+ if and when it gets to the next deflate block boundary. When decoding the
+ zlib or gzip format, this will cause inflate() to return immediately after
+ the header and before the first block. When doing a raw inflate, inflate()
+ will go ahead and process the first block, and will return when it gets to
+ the end of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ Also to assist in this, on return inflate() will set strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64
+ if inflate() is currently decoding the last block in the deflate stream,
+ plus 128 if inflate() returned immediately after decoding an end-of-block
+ code or decoding the complete header up to just before the first byte of the
+ deflate stream. The end-of-block will not be indicated until all of the
+ uncompressed data from that block has been written to strm->next_out. The
+ number of unused bits may in general be greater than seven, except when
+ bit 7 of data_type is set, in which case the number of unused bits will be
+ less than eight.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step
+ (a single call of inflate), the parameter flush should be set to
+ Z_FINISH. In this case all pending input is processed and all pending
+ output is flushed; avail_out must be large enough to hold all the
+ uncompressed data. (The size of the uncompressed data may have been saved
+ by the compressor for this purpose.) The next operation on this stream must
+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+ is never required, but can be used to inform inflate that a faster approach
+ may be used for the single inflate() call.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the only effect of the flush parameter in this implementation
+ is on the return value of inflate(), as noted below, or when it returns early
+ because Z_BLOCK is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the adler32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the adler32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed adler32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() will decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically. Any information
+ contained in the gzip header is not retained, so applications that need that
+ information should instead use raw inflate, see inflateInit2() below, or
+ inflateBack() and perform their own processing of the gzip header and
+ trailer.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
+ Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may then
+ call inflateSync() to look for a good compression block if a partial recovery
+ of the data is desired.
+*/
+
+
+extern int zlib_inflateEnd (z_streamp strm);
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+extern int deflateInit2 (z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy);
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by
+ the caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but
+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
+ for optimal speed. The default value is 8. See zconf.h for total memory
+ usage as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match). Filtered data consists mostly of small values with a
+ somewhat random distribution. In this case, the compression algorithm is
+ tuned to compress them better. The effect of Z_FILTERED is to force more
+ Huffman coding and less string matching; it is somewhat intermediate
+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
+ the compression ratio but not the correctness of the compressed output even
+ if it is not set appropriately.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+ method). msg is set to null if there is no error message. deflateInit2 does
+ not perform any compression: this will be done by deflate().
+*/
+
+#if 0
+extern int zlib_deflateSetDictionary (z_streamp strm,
+ const Byte *dictionary,
+ uInt dictLength);
+#endif
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. This function must be called
+ immediately after deflateInit, deflateInit2 or deflateReset, before any
+ call of deflate. The compressor and decompressor must use exactly the same
+ dictionary (see inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size in
+ deflate or deflate2. Thus the strings most likely to be useful should be
+ put at the end of the dictionary, not at the front.
+
+ Upon return of this function, strm->adler is set to the Adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The Adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.)
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if the compression method is bsort). deflateSetDictionary does not
+ perform any compression: this will be done by deflate().
+*/
+
+#if 0
+extern int zlib_deflateCopy (z_streamp dest, z_streamp source);
+#endif
+
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and
+ can consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+extern int zlib_deflateReset (z_streamp strm);
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state.
+ The stream will keep the same compression level and any other attributes
+ that may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+static inline unsigned long deflateBound(unsigned long s)
+{
+ return s + ((s + 7) >> 3) + ((s + 63) >> 6) + 11;
+}
+
+#if 0
+extern int zlib_deflateParams (z_streamp strm, int level, int strategy);
+#endif
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different
+ strategy. If the compression level is changed, the input available so far
+ is compressed with the old level (and may be flushed); the new level will
+ take effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to
+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+ if strm->avail_out was zero.
+*/
+
+/*
+extern int inflateInit2 (z_streamp strm, int windowBits);
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an adler32 or a crc32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
+ a crc32 instead of an adler32.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
+ is set to null if there is no error message. inflateInit2 does not perform
+ any decompression apart from reading the zlib header if present: this will
+ be done by inflate(). (So next_in and avail_in may be modified, but next_out
+ and avail_out are unchanged.)
+*/
+
+extern int zlib_inflateSetDictionary (z_streamp strm,
+ const Byte *dictionary,
+ uInt dictLength);
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called
+ immediately after inflateInit2() or inflateReset() and before any call of
+ inflate() to set the dictionary. The application must insure that the
+ dictionary that was used for compression is provided.
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+#if 0
+extern int zlib_inflateSync (z_streamp strm);
+#endif
+/*
+ Skips invalid compressed data until a full flush point (see above the
+ description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+ case, the application may save the current current value of total_in which
+ indicates where valid compressed data was found. In the error case, the
+ application may repeatedly call inflateSync, providing more input each time,
+ until success or end of the input data.
+*/
+
+extern int zlib_inflateReset (z_streamp strm);
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state.
+ The stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+extern int zlib_inflateIncomp (z_stream *strm);
+/*
+ This function adds the data at next_in (avail_in bytes) to the output
+ history without performing any output. There must be no pending output,
+ and the decompressor must be expecting to see the start of a block.
+ Calling this function is equivalent to decompressing a stored block
+ containing the data at next_in (except that the data is not output).
+*/
+
+#define zlib_deflateInit(strm, level) \
+ zlib_deflateInit2((strm), (level), Z_DEFLATED, MAX_WBITS, \
+ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY)
+#define zlib_inflateInit(strm) \
+ zlib_inflateInit2((strm), DEF_WBITS)
+
+extern int zlib_deflateInit2(z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy);
+extern int zlib_inflateInit2(z_streamp strm, int windowBits);
+
+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+/* Utility function: initialize zlib, unpack binary blob, clean up zlib,
+ * return len or negative error code. */
+extern int zlib_inflate_blob(void *dst, unsigned dst_sz, const void *src, unsigned src_sz);
+
+#endif /* _ZLIB_H */
diff --git a/include/linux/zutil.h b/include/linux/zutil.h
new file mode 100644
index 0000000..6adfa9a
--- /dev/null
+++ b/include/linux/zutil.h
@@ -0,0 +1,106 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id: zutil.h,v 1.1 2000/01/01 03:32:23 davem Exp $ */
+
+#ifndef _Z_UTIL_H
+#define _Z_UTIL_H
+
+#include <linux/zlib.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+ /* common constants */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+ /* target dependencies */
+
+ /* Common defaults */
+
+#ifndef OS_CODE
+# define OS_CODE 0x03 /* assume Unix */
+#endif
+
+ /* functions */
+
+typedef uLong (*check_func) (uLong check, const Byte *buf,
+ uInt len);
+
+
+ /* checksum functions */
+
+#define BASE 65521L /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+/* ========================================================================= */
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is NULL, this function returns
+ the required initial value for the checksum.
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster. Usage example:
+
+ uLong adler = adler32(0L, NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+static inline uLong zlib_adler32(uLong adler,
+ const Byte *buf,
+ uInt len)
+{
+ unsigned long s1 = adler & 0xffff;
+ unsigned long s2 = (adler >> 16) & 0xffff;
+ int k;
+
+ if (buf == NULL) return 1L;
+
+ while (len > 0) {
+ k = len < NMAX ? len : NMAX;
+ len -= k;
+ while (k >= 16) {
+ DO16(buf);
+ buf += 16;
+ k -= 16;
+ }
+ if (k != 0) do {
+ s1 += *buf++;
+ s2 += s1;
+ } while (--k);
+ s1 %= BASE;
+ s2 %= BASE;
+ }
+ return (s2 << 16) | s1;
+}
+
+#endif /* _Z_UTIL_H */
diff --git a/include/lzo.h b/include/lzo.h
index 5694985..0530a68 100644
--- a/include/lzo.h
+++ b/include/lzo.h
@@ -41,6 +41,10 @@ int lzo1x_decompress_safe(const unsigned char *src, size_t src_len,
#define LZO_E_INPUT_NOT_CONSUMED (-8)
#define LZO_E_NOT_YET_IMPLEMENTED (-9)
-int unlzo(int in_fd, int out_fd, int *dest_len);
+int decompress_unlzo(u8 *input, int in_len,
+ int (*fill) (void *, unsigned int),
+ int (*flush) (void *, unsigned int),
+ u8 *output, int *posp,
+ void (*error) (char *x));
#endif
diff --git a/include/magicvar.h b/include/magicvar.h
new file mode 100644
index 0000000..d27a2e3
--- /dev/null
+++ b/include/magicvar.h
@@ -0,0 +1,32 @@
+#ifndef __MAGIC_VARS_H
+#define __MAGIC_VARS_H
+
+#include <linux/stringify.h>
+
+struct magicvar {
+ const char *name;
+ const char *description;
+};
+
+extern struct magicvar __barebox_magicvar_start;
+extern struct magicvar __barebox_magicvar_end;
+
+#ifdef CONFIG_CMD_MAGICVAR_HELP
+#define MAGICVAR_DESCRIPTION(d) (d)
+#else
+#define MAGICVAR_DESCRIPTION(d) NULL
+#endif
+
+#ifdef CONFIG_CMD_MAGICVAR
+#define BAREBOX_MAGICVAR(_name, _description) \
+extern const struct magicvar __barebox_magicvar_##_name; \
+const struct magicvar __barebox_magicvar_##_name \
+ __attribute__ ((unused,section (".barebox_magicvar_" __stringify(_name)))) = { \
+ .name = #_name, \
+ .description = MAGICVAR_DESCRIPTION(_description), \
+};
+#else
+#define BAREBOX_MAGICVAR(_name, _description)
+#endif
+
+#endif /* __MAGIC_VARS_H */
diff --git a/include/mci.h b/include/mci.h
index 69cffe8..d3b3082 100644
--- a/include/mci.h
+++ b/include/mci.h
@@ -31,6 +31,7 @@
#define _MCI_H_
#include <linux/list.h>
+#include <block.h>
/* Firmware revisions for SD cards */
#define SD_VERSION_SD 0x20000
@@ -49,6 +50,7 @@
#define MMC_MODE_HS 0x001
#define MMC_MODE_HS_52MHz 0x010
+#define MMC_CAP_SPI 0x020
#define MMC_MODE_4BIT 0x100
#define MMC_MODE_8BIT 0x200
@@ -56,6 +58,12 @@
#define IS_SD(x) (x->version & SD_VERSION_SD)
+#ifdef CONFIG_MCI_SPI
+#define mmc_host_is_spi(host) ((host)->host_caps & MMC_CAP_SPI)
+#else
+#define mmc_host_is_spi(host) 0
+#endif
+
#define MMC_DATA_READ 1
#define MMC_DATA_WRITE 2
@@ -78,6 +86,8 @@
#define MMC_CMD_WRITE_SINGLE_BLOCK 24
#define MMC_CMD_WRITE_MULTIPLE_BLOCK 25
#define MMC_CMD_APP_CMD 55
+#define MMC_CMD_SPI_READ_OCR 58
+#define MMC_CMD_SPI_CRC_ON_OFF 59
#define SD_CMD_SEND_RELATIVE_ADDR 3
#define SD_CMD_SWITCH_FUNC 6
@@ -155,6 +165,15 @@
#define R1_ILLEGAL_COMMAND (1 << 22)
#define R1_APP_CMD (1 << 5)
+#define R1_SPI_IDLE (1 << 0)
+#define R1_SPI_ERASE_RESET (1 << 1)
+#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
+#define R1_SPI_COM_CRC (1 << 3)
+#define R1_SPI_ERASE_SEQ (1 << 4)
+#define R1_SPI_ADDRESS (1 << 5)
+#define R1_SPI_PARAMETER (1 << 6)
+#define R1_SPI_ERROR (1 << 7)
+
/* response types */
#define MMC_RSP_PRESENT (1 << 0)
#define MMC_RSP_136 (1 << 1) /* 136 bit response */
@@ -194,7 +213,6 @@ struct mci_data {
/** host information */
struct mci_host {
struct device_d *hw_dev; /**< the host MCI hardware device */
- struct device_d dev; /**< our device */
unsigned voltages;
unsigned host_caps; /**< Host's interface capabilities, refer MMC_VDD_* */
unsigned f_min; /**< host interface lower limit */
@@ -212,6 +230,7 @@ struct mci_host {
/** MMC/SD and interface instance information */
struct mci {
+ struct block_device blk; /**< the blockdevice for the card */
unsigned version;
/** != 0 when a high capacity card is connected (OCR -> OCR_HCS) */
int high_capacity;
diff --git a/include/memory.h b/include/memory.h
index cb185af..4be4340 100644
--- a/include/memory.h
+++ b/include/memory.h
@@ -13,6 +13,7 @@ struct memory_bank {
struct device_d *dev;
unsigned long start;
unsigned long size;
+ struct resource *res;
};
extern struct list_head memory_banks;
@@ -22,4 +23,8 @@ void barebox_add_memory_bank(const char *name, resource_size_t start,
#define for_each_memory_bank(mem) list_for_each_entry(mem, &memory_banks, list)
+struct resource *request_sdram_region(const char *name, resource_size_t start,
+ resource_size_t size);
+int release_sdram_region(struct resource *res);
+
#endif
diff --git a/include/platform_ide.h b/include/platform_ide.h
new file mode 100644
index 0000000..f71fbfb
--- /dev/null
+++ b/include/platform_ide.h
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+#ifndef __PLATFORM_IDE_H
+#define __PLATFORM_IDE_H
+
+struct ide_port_info {
+ /*
+ * I/O port shift, for platforms with ports that are
+ * constantly spaced and need larger than the 1-byte
+ * spacing
+ */
+ unsigned ioport_shift;
+ int dataif_be; /* true if 16 bit data register is big endian */
+
+ /* handle hard reset of this port */
+ void (*reset)(int); /* true: assert reset, false: de-assert reset */
+};
+
+#endif /* __PLATFORM_IDE_H */
diff --git a/include/uncompress.h b/include/uncompress.h
new file mode 100644
index 0000000..d146c90
--- /dev/null
+++ b/include/uncompress.h
@@ -0,0 +1,19 @@
+#ifndef __UNCOMPRESS_H
+#define __UNCOMPRESS_H
+
+int uncompress(unsigned char *inbuf, int len,
+ int(*fill)(void*, unsigned int),
+ int(*flush)(void*, unsigned int),
+ unsigned char *output,
+ int *pos,
+ void(*error_fn)(char *x));
+
+int uncompress_fd_to_fd(int infd, int outfd,
+ void(*error_fn)(char *x));
+
+int uncompress_fd_to_buf(int infd, void *output,
+ void(*error_fn)(char *x));
+
+void uncompress_err_stdout(char *);
+
+#endif /* __UNCOMPRESS_H */
diff --git a/include/zlib.h b/include/zlib.h
deleted file mode 100644
index e441494..0000000
--- a/include/zlib.h
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * This file is derived from zlib.h and zconf.h from the zlib-0.95
- * distribution by Jean-loup Gailly and Mark Adler, with some additions
- * by Paul Mackerras to aid in implementing Deflate compression and
- * decompression for PPP packets.
- */
-
-/*
- * ==FILEVERSION 960122==
- *
- * This marker is used by the Linux installation script to determine
- * whether an up-to-date version of this file is already installed.
- */
-
-/* zlib.h -- interface of the 'zlib' general purpose compression library
- version 0.95, Aug 16th, 1995.
-
- Copyright (C) 1995 Jean-loup Gailly and Mark Adler
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- Jean-loup Gailly Mark Adler
- gzip@prep.ai.mit.edu madler@alumni.caltech.edu
- */
-
-#ifndef _ZLIB_H
-#define _ZLIB_H
-
-/* #include "zconf.h" */ /* included directly here */
-
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */
-
-/*
- The library does not install any signal handler. It is recommended to
- add at least a handler for SIGSEGV when decompressing; the library checks
- the consistency of the input data whenever possible but may go nuts
- for some forms of corrupted input.
- */
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints
- * at addresses which are not a multiple of their size.
- * Under DOS, -DFAR=far or -DFAR=__far may be needed.
- */
-
-#ifndef STDC
-# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
-# define STDC
-# endif
-#endif
-
-#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
-# include <unix.h>
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-# ifdef MAXSEG_64K
-# define MAX_MEM_LEVEL 8
-# else
-# define MAX_MEM_LEVEL 9
-# endif
-#endif
-
-#ifndef FAR
-# define FAR
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
-#ifndef MAX_WBITS
-# define MAX_WBITS 15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
- 1 << (windowBits+2) + 1 << (memLevel+9)
- that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
- make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
- The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
- /* Type declarations */
-
-#ifndef OF /* function prototypes */
-# ifdef STDC
-# define OF(args) args
-# else
-# define OF(args) ()
-# endif
-#endif
-
-typedef unsigned char Byte; /* 8 bits */
-typedef unsigned int uInt; /* 16 bits or more */
-typedef unsigned long uLong; /* 32 bits or more */
-
-typedef Byte FAR Bytef;
-typedef char FAR charf;
-typedef int FAR intf;
-typedef uInt FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
- typedef void FAR *voidpf;
- typedef void *voidp;
-#else
- typedef Byte FAR *voidpf;
- typedef Byte *voidp;
-#endif
-
-/* end of original zconf.h */
-
-#define ZLIB_VERSION "0.95P"
-
-/*
- The 'zlib' compression library provides in-memory compression and
- decompression functions, including integrity checks of the uncompressed
- data. This version of the library supports only one compression method
- (deflation) but other algorithms may be added later and will have the same
- stream interface.
-
- For compression the application must provide the output buffer and
- may optionally provide the input buffer for optimization. For decompression,
- the application must provide the input buffer and may optionally provide
- the output buffer for optimization.
-
- Compression can be done in a single step if the buffers are large
- enough (for example if an input file is mmap'ed), or can be done by
- repeated calls of the compression function. In the latter case, the
- application must provide more input and/or consume the output
- (providing more output space) before each call.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes));
-
-typedef void (*cb_func) OF((Bytef *buf, uInt len));
-
-struct internal_state;
-
-typedef struct z_stream_s {
- Bytef *next_in; /* next input byte */
- uInt avail_in; /* number of bytes available at next_in */
- uLong total_in; /* total nb of input bytes read so far */
-
- Bytef *next_out; /* next output byte should be put there */
- uInt avail_out; /* remaining free space at next_out */
- uLong total_out; /* total nb of bytes output so far */
-
- char *msg; /* last error message, NULL if no error */
- struct internal_state FAR *state; /* not visible by applications */
-
- alloc_func zalloc; /* used to allocate the internal state */
- free_func zfree; /* used to free the internal state */
- voidp opaque; /* private data object passed to zalloc and zfree */
-
- Byte data_type; /* best guess about the data type: ascii or binary */
-
- cb_func outcb; /* called regularly just before blocks of output */
-
-} z_stream;
-
-/*
- The application must update next_in and avail_in when avail_in has
- dropped to zero. It must update next_out and avail_out when avail_out
- has dropped to zero. The application must initialize zalloc, zfree and
- opaque before calling the init function. All other fields are set by the
- compression library and must not be updated by the application.
-
- The opaque value provided by the application will be passed as the first
- parameter for calls of zalloc and zfree. This can be useful for custom
- memory management. The compression library attaches no meaning to the
- opaque value.
-
- zalloc must return Z_NULL if there is not enough memory for the object.
- On 16-bit systems, the functions zalloc and zfree must be able to allocate
- exactly 65536 bytes, but will not be required to allocate more than this
- if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
- pointers returned by zalloc for objects of exactly 65536 bytes *must*
- have their offset normalized to zero. The default allocation function
- provided by this library ensures this (see zutil.c). To reduce memory
- requirements and avoid any allocation of 64K objects, at the expense of
- compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
- The fields total_in and total_out can be used for statistics or
- progress reports. After compression, total_in holds the total size of
- the uncompressed data and may be saved for use in the decompressor
- (particularly if the decompressor wants to decompress everything in
- a single step).
-*/
-
- /* constants */
-
-#define Z_NO_FLUSH 0
-#define Z_PARTIAL_FLUSH 1
-#define Z_FULL_FLUSH 2
-#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */
-#define Z_FINISH 4
-#define Z_PACKET_FLUSH 5
-/* See deflate() below for the usage of these constants */
-
-#define Z_OK 0
-#define Z_STREAM_END 1
-#define Z_ERRNO (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR (-3)
-#define Z_MEM_ERROR (-4)
-#define Z_BUF_ERROR (-5)
-/* error codes for the compression/decompression functions */
-
-#define Z_BEST_SPEED 1
-#define Z_BEST_COMPRESSION 9
-#define Z_DEFAULT_COMPRESSION (-1)
-/* compression levels */
-
-#define Z_FILTERED 1
-#define Z_HUFFMAN_ONLY 2
-#define Z_DEFAULT_STRATEGY 0
-
-#define Z_BINARY 0
-#define Z_ASCII 1
-#define Z_UNKNOWN 2
-/* Used to set the data_type field */
-
-#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-
-extern char *zlib_version;
-/* The application can compare zlib_version and ZLIB_VERSION for consistency.
- If the first character differs, the library code actually used is
- not compatible with the zlib.h header file used by the application.
- */
-
- /* basic functions */
-
-extern int inflateInit OF((z_stream *strm));
-/*
- Initializes the internal stream state for decompression. The fields
- zalloc and zfree must be initialized before by the caller. If zalloc and
- zfree are set to Z_NULL, inflateInit updates them to use default allocation
- functions.
-
- inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
- enough memory. msg is set to null if there is no error message.
- inflateInit does not perform any decompression: this will be done by
- inflate().
-*/
-
-
-extern int inflate OF((z_stream *strm, int flush));
-/*
- Performs one or both of the following actions:
-
- - Decompress more input starting at next_in and update next_in and avail_in
- accordingly. If not all input can be processed (because there is not
- enough room in the output buffer), next_in is updated and processing
- will resume at this point for the next call of inflate().
-
- - Provide more output starting at next_out and update next_out and avail_out
- accordingly. inflate() always provides as much output as possible
- (until there is no more input data or no more space in the output buffer).
-
- Before the call of inflate(), the application should ensure that at least
- one of the actions is possible, by providing more input and/or consuming
- more output, and updating the next_* and avail_* values accordingly.
- The application can consume the uncompressed output when it wants, for
- example when the output buffer is full (avail_out == 0), or after each
- call of inflate().
-
- If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
- inflate flushes as much output as possible to the output buffer. The
- flushing behavior of inflate is not specified for values of the flush
- parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
- current implementation actually flushes as much output as possible
- anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data
- has been consumed, it is expecting to see the length field of a stored
- block; if not, it returns Z_DATA_ERROR.
-
- inflate() should normally be called until it returns Z_STREAM_END or an
- error. However if all decompression is to be performed in a single step
- (a single call of inflate), the parameter flush should be set to
- Z_FINISH. In this case all pending input is processed and all pending
- output is flushed; avail_out must be large enough to hold all the
- uncompressed data. (The size of the uncompressed data may have been saved
- by the compressor for this purpose.) The next operation on this stream must
- be inflateEnd to deallocate the decompression state. The use of Z_FINISH
- is never required, but can be used to inform inflate that a faster routine
- may be used for the single inflate() call.
-
- inflate() returns Z_OK if some progress has been made (more input
- processed or more output produced), Z_STREAM_END if the end of the
- compressed data has been reached and all uncompressed output has been
- produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
- the stream structure was inconsistent (for example if next_in or next_out
- was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
- progress is possible or if there was not enough room in the output buffer
- when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
- call inflateSync to look for a good compression block. */
-
-
-extern int inflateEnd OF((z_stream *strm));
-/*
- All dynamically allocated data structures for this stream are freed.
- This function discards any unprocessed input and does not flush any
- pending output.
-
- inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
- was inconsistent. In the error case, msg may be set but then points to a
- static string (which must not be deallocated).
-*/
-
- /* advanced functions */
-
-extern int inflateInit2 OF((z_stream *strm,
- int windowBits));
-/*
- This is another version of inflateInit with more compression options. The
- fields next_out, zalloc and zfree must be initialized before by the caller.
-
- The windowBits parameter is the base two logarithm of the maximum window
- size (the size of the history buffer). It should be in the range 8..15 for
- this version of the library (the value 16 will be allowed soon). The
- default value is 15 if inflateInit is used instead. If a compressed stream
- with a larger window size is given as input, inflate() will return with
- the error code Z_DATA_ERROR instead of trying to allocate a larger window.
-
- If next_out is not null, the library will use this buffer for the history
- buffer; the buffer must either be large enough to hold the entire output
- data, or have at least 1<<windowBits bytes. If next_out is null, the
- library will allocate its own buffer (and leave next_out null). next_in
- need not be provided here but must be provided by the application for the
- next call of inflate().
-
- If the history buffer is provided by the application, next_out must
- never be changed by the application since the decompressor maintains
- history information inside this buffer from call to call; the application
- can only reset next_out to the beginning of the history buffer when
- avail_out is zero and all output has been consumed.
-
- inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
- not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
- windowBits < 8). msg is set to null if there is no error message.
- inflateInit2 does not perform any decompression: this will be done by
- inflate().
-*/
-
-extern int inflateSync OF((z_stream *strm));
-/*
- Skips invalid compressed data until the special marker (see deflate()
- above) can be found, or until all available input is skipped. No output
- is provided.
-
- inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
- if no more input was provided, Z_DATA_ERROR if no marker has been found,
- or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
- case, the application may save the current current value of total_in which
- indicates where valid compressed data was found. In the error case, the
- application may repeatedly call inflateSync, providing more input each time,
- until success or end of the input data.
-*/
-
-extern int inflateReset OF((z_stream *strm));
-/*
- This function is equivalent to inflateEnd followed by inflateInit,
- but does not free and reallocate all the internal decompression state.
- The stream will keep attributes that may have been set by inflateInit2.
-
- inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
- stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-extern int inflateIncomp OF((z_stream *strm));
-/*
- This function adds the data at next_in (avail_in bytes) to the output
- history without performing any output. There must be no pending output,
- and the decompressor must be expecting to see the start of a block.
- Calling this function is equivalent to decompressing a stored block
- containing the data at next_in (except that the data is not output).
-*/
-
- /* checksum functions */
-
-/*
- This function is not related to compression but is exported
- anyway because it might be useful in applications using the
- compression library.
-*/
-
-extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
-
-/*
- Update a running Adler-32 checksum with the bytes buf[0..len-1] and
- return the updated checksum. If buf is NULL, this function returns
- the required initial value for the checksum.
- An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
- much faster. Usage example:
-
- uLong adler = adler32(0L, Z_NULL, 0);
-
- while (read_buffer(buffer, length) != EOF) {
- adler = adler32(adler, buffer, length);
- }
- if (adler != original_adler) error();
-*/
-
-#ifndef _Z_UTIL_H
- struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-#endif /* _ZLIB_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index 531398f..e16dd35 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -1,8 +1,9 @@
+menu "Library routines"
config ZLIB
- bool
+ bool "include gzip uncompression support"
config BZLIB
- bool
+ bool "include bzip2 uncompression support"
config GENERIC_FIND_NEXT_BIT
def_bool n
@@ -18,3 +19,4 @@ config FDT
config OFTREE
select FDT
bool
+endmenu
diff --git a/lib/Makefile b/lib/Makefile
index cb72842..ae76b4c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -15,8 +15,8 @@ obj-y += libgen.o
obj-y += stringlist.o
obj-y += recursive_action.o
obj-y += make_directory.o
-obj-$(CONFIG_BZLIB) += bzlib.o bzlib_crctable.o bzlib_decompress.o bzlib_huffman.o bzlib_randtable.o
-obj-$(CONFIG_ZLIB) += zlib.o gunzip.o
+obj-$(CONFIG_BZLIB) += decompress_bunzip2.o
+obj-$(CONFIG_ZLIB) += decompress_inflate.o zlib_inflate/
obj-$(CONFIG_CMDLINE_EDITING) += readline.o
obj-$(CONFIG_SIMPLE_READLINE) += readline_simple.o
obj-$(CONFIG_GLOB) += fnmatch.o
@@ -30,3 +30,4 @@ obj-y += show_progress.o
obj-$(CONFIG_LZO_DECOMPRESS) += decompress_unlzo.o
obj-$(CONFIG_PROCESS_ESCAPE_SEQUENCE) += process_escape_sequence.o
obj-$(CONFIG_FDT) += fdt/
+obj-y += uncompress.o
diff --git a/lib/bzlib.c b/lib/bzlib.c
deleted file mode 100644
index 4c928ca..0000000
--- a/lib/bzlib.c
+++ /dev/null
@@ -1,1592 +0,0 @@
-#include <config.h>
-#include <common.h>
-#include <watchdog.h>
-
-/*
- * This file is a modified version of bzlib.c from the bzip2-1.0.2
- * distribution which can be found at http://sources.redhat.com/bzip2/
- */
-
-/*-------------------------------------------------------------*/
-/*--- Library top-level functions. ---*/
-/*--- bzlib.c ---*/
-/*-------------------------------------------------------------*/
-
-/*--
- This file is a part of bzip2 and/or libbzip2, a program and
- library for lossless, block-sorting data compression.
-
- Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. The origin of this software must not be misrepresented; you must
- not claim that you wrote the original software. If you use this
- software in a product, an acknowledgment in the product
- documentation would be appreciated but is not required.
-
- 3. Altered source versions must be plainly marked as such, and must
- not be misrepresented as being the original software.
-
- 4. The name of the author may not be used to endorse or promote
- products derived from this software without specific prior written
- permission.
-
- THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- Julian Seward, Cambridge, UK.
- jseward@acm.org
- bzip2/libbzip2 version 1.0 of 21 March 2000
-
- This program is based on (at least) the work of:
- Mike Burrows
- David Wheeler
- Peter Fenwick
- Alistair Moffat
- Radford Neal
- Ian H. Witten
- Robert Sedgewick
- Jon L. Bentley
-
- For more information on these sources, see the manual.
---*/
-
-/*--
- CHANGES
- ~~~~~~~
- 0.9.0 -- original version.
-
- 0.9.0a/b -- no changes in this file.
-
- 0.9.0c
- * made zero-length BZ_FLUSH work correctly in bzCompress().
- * fixed bzWrite/bzRead to ignore zero-length requests.
- * fixed bzread to correctly handle read requests after EOF.
- * wrong parameter order in call to bzDecompressInit in
- bzBuffToBuffDecompress. Fixed.
---*/
-
-#include "bzlib_private.h"
-
-/*---------------------------------------------------*/
-/*--- Compression stuff ---*/
-/*---------------------------------------------------*/
-
-
-/*---------------------------------------------------*/
-#ifndef BZ_NO_STDIO
-void BZ2_bz__AssertH__fail ( int errcode )
-{
- fprintf(stderr,
- "\n\nbzip2/libbzip2: internal error number %d.\n"
- "This is a bug in bzip2/libbzip2, %s.\n"
- "Please report it to me at: jseward@acm.org. If this happened\n"
- "when you were using some program which uses libbzip2 as a\n"
- "component, you should also report this bug to the author(s)\n"
- "of that program. Please make an effort to report this bug;\n"
- "timely and accurate bug reports eventually lead to higher\n"
- "quality software. Thanks. Julian Seward, 30 December 2001.\n\n",
- errcode,
- BZ2_bzlibVersion()
- );
-
- if (errcode == 1007) {
- fprintf(stderr,
- "\n*** A special note about internal error number 1007 ***\n"
- "\n"
- "Experience suggests that a common cause of i.e. 1007\n"
- "is unreliable memory or other hardware. The 1007 assertion\n"
- "just happens to cross-check the results of huge numbers of\n"
- "memory reads/writes, and so acts (unintendedly) as a stress\n"
- "test of your memory system.\n"
- "\n"
- "I suggest the following: try compressing the file again,\n"
- "possibly monitoring progress in detail with the -vv flag.\n"
- "\n"
- "* If the error cannot be reproduced, and/or happens at different\n"
- " points in compression, you may have a flaky memory system.\n"
- " Try a memory-test program. I have used Memtest86\n"
- " (www.memtest86.com). At the time of writing it is free (GPLd).\n"
- " Memtest86 tests memory much more thorougly than your BIOSs\n"
- " power-on test, and may find failures that the BIOS doesn't.\n"
- "\n"
- "* If the error can be repeatably reproduced, this is a bug in\n"
- " bzip2, and I would very much like to hear about it. Please\n"
- " let me know, and, ideally, save a copy of the file causing the\n"
- " problem -- without which I will be unable to investigate it.\n"
- "\n"
- );
- }
-
- exit(3);
-}
-#endif
-
-
-/*---------------------------------------------------*/
-static
-int bz_config_ok ( void )
-{
- if (sizeof(int) != 4) return 0;
- if (sizeof(short) != 2) return 0;
- if (sizeof(char) != 1) return 0;
- return 1;
-}
-
-
-/*---------------------------------------------------*/
-static
-void* default_bzalloc ( void* opaque, Int32 items, Int32 size )
-{
- void* v = malloc ( items * size );
- return v;
-}
-
-static
-void default_bzfree ( void* opaque, void* addr )
-{
- if (addr != NULL) free ( addr );
-}
-
-#ifndef BZ_NO_COMPRESS
-/*---------------------------------------------------*/
-static
-void prepare_new_block ( EState* s )
-{
- Int32 i;
- s->nblock = 0;
- s->numZ = 0;
- s->state_out_pos = 0;
- BZ_INITIALISE_CRC ( s->blockCRC );
- for (i = 0; i < 256; i++) s->inUse[i] = False;
- s->blockNo++;
-}
-
-
-/*---------------------------------------------------*/
-static
-void init_RL ( EState* s )
-{
- s->state_in_ch = 256;
- s->state_in_len = 0;
-}
-
-
-static
-Bool isempty_RL ( EState* s )
-{
- if (s->state_in_ch < 256 && s->state_in_len > 0)
- return False; else
- return True;
-}
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompressInit)
- ( bz_stream* strm,
- int blockSize100k,
- int verbosity,
- int workFactor )
-{
- Int32 n;
- EState* s;
-
- if (!bz_config_ok()) return BZ_CONFIG_ERROR;
-
- if (strm == NULL ||
- blockSize100k < 1 || blockSize100k > 9 ||
- workFactor < 0 || workFactor > 250)
- return BZ_PARAM_ERROR;
-
- if (workFactor == 0) workFactor = 30;
- if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
- if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
-
- s = BZALLOC( sizeof(EState) );
- if (s == NULL) return BZ_MEM_ERROR;
- s->strm = strm;
-
- s->arr1 = NULL;
- s->arr2 = NULL;
- s->ftab = NULL;
-
- n = 100000 * blockSize100k;
- s->arr1 = BZALLOC( n * sizeof(UInt32) );
- s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) );
- s->ftab = BZALLOC( 65537 * sizeof(UInt32) );
-
- if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) {
- if (s->arr1 != NULL) BZFREE(s->arr1);
- if (s->arr2 != NULL) BZFREE(s->arr2);
- if (s->ftab != NULL) BZFREE(s->ftab);
- if (s != NULL) BZFREE(s);
- return BZ_MEM_ERROR;
- }
-
- s->blockNo = 0;
- s->state = BZ_S_INPUT;
- s->mode = BZ_M_RUNNING;
- s->combinedCRC = 0;
- s->blockSize100k = blockSize100k;
- s->nblockMAX = 100000 * blockSize100k - 19;
- s->verbosity = verbosity;
- s->workFactor = workFactor;
-
- s->block = (UChar*)s->arr2;
- s->mtfv = (UInt16*)s->arr1;
- s->zbits = NULL;
- s->ptr = (UInt32*)s->arr1;
-
- strm->state = s;
- strm->total_in_lo32 = 0;
- strm->total_in_hi32 = 0;
- strm->total_out_lo32 = 0;
- strm->total_out_hi32 = 0;
- init_RL ( s );
- prepare_new_block ( s );
- return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-static
-void add_pair_to_block ( EState* s )
-{
- Int32 i;
- UChar ch = (UChar)(s->state_in_ch);
- for (i = 0; i < s->state_in_len; i++) {
- BZ_UPDATE_CRC( s->blockCRC, ch );
- }
- s->inUse[s->state_in_ch] = True;
- switch (s->state_in_len) {
- case 1:
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- break;
- case 2:
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- break;
- case 3:
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- break;
- default:
- s->inUse[s->state_in_len-4] = True;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = (UChar)ch; s->nblock++;
- s->block[s->nblock] = ((UChar)(s->state_in_len-4));
- s->nblock++;
- break;
- }
-}
-
-
-/*---------------------------------------------------*/
-static
-void flush_RL ( EState* s )
-{
- if (s->state_in_ch < 256) add_pair_to_block ( s );
- init_RL ( s );
-}
-
-
-/*---------------------------------------------------*/
-#define ADD_CHAR_TO_BLOCK(zs,zchh0) \
-{ \
- UInt32 zchh = (UInt32)(zchh0); \
- /*-- fast track the common case --*/ \
- if (zchh != zs->state_in_ch && \
- zs->state_in_len == 1) { \
- UChar ch = (UChar)(zs->state_in_ch); \
- BZ_UPDATE_CRC( zs->blockCRC, ch ); \
- zs->inUse[zs->state_in_ch] = True; \
- zs->block[zs->nblock] = (UChar)ch; \
- zs->nblock++; \
- zs->state_in_ch = zchh; \
- } \
- else \
- /*-- general, uncommon cases --*/ \
- if (zchh != zs->state_in_ch || \
- zs->state_in_len == 255) { \
- if (zs->state_in_ch < 256) \
- add_pair_to_block ( zs ); \
- zs->state_in_ch = zchh; \
- zs->state_in_len = 1; \
- } else { \
- zs->state_in_len++; \
- } \
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool copy_input_until_stop ( EState* s )
-{
- Bool progress_in = False;
-
- if (s->mode == BZ_M_RUNNING) {
-
- /*-- fast track the common case --*/
- while (True) {
- /*-- block full? --*/
- if (s->nblock >= s->nblockMAX) break;
- /*-- no input? --*/
- if (s->strm->avail_in == 0) break;
- progress_in = True;
- ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
- s->strm->next_in++;
- s->strm->avail_in--;
- s->strm->total_in_lo32++;
- if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
- }
-
- } else {
-
- /*-- general, uncommon case --*/
- while (True) {
- /*-- block full? --*/
- if (s->nblock >= s->nblockMAX) break;
- /*-- no input? --*/
- if (s->strm->avail_in == 0) break;
- /*-- flush/finish end? --*/
- if (s->avail_in_expect == 0) break;
- progress_in = True;
- ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) );
- s->strm->next_in++;
- s->strm->avail_in--;
- s->strm->total_in_lo32++;
- if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++;
- s->avail_in_expect--;
- }
- }
- return progress_in;
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool copy_output_until_stop ( EState* s )
-{
- Bool progress_out = False;
-
- while (True) {
-
- /*-- no output space? --*/
- if (s->strm->avail_out == 0) break;
-
- /*-- block done? --*/
- if (s->state_out_pos >= s->numZ) break;
-
- progress_out = True;
- *(s->strm->next_out) = s->zbits[s->state_out_pos];
- s->state_out_pos++;
- s->strm->avail_out--;
- s->strm->next_out++;
- s->strm->total_out_lo32++;
- if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
- }
-
- return progress_out;
-}
-
-
-/*---------------------------------------------------*/
-static
-Bool handle_compress ( bz_stream* strm )
-{
- Bool progress_in = False;
- Bool progress_out = False;
- EState* s = strm->state;
-
- while (True) {
-
- if (s->state == BZ_S_OUTPUT) {
- progress_out |= copy_output_until_stop ( s );
- if (s->state_out_pos < s->numZ) break;
- if (s->mode == BZ_M_FINISHING &&
- s->avail_in_expect == 0 &&
- isempty_RL(s)) break;
- prepare_new_block ( s );
- s->state = BZ_S_INPUT;
- if (s->mode == BZ_M_FLUSHING &&
- s->avail_in_expect == 0 &&
- isempty_RL(s)) break;
- }
-
- if (s->state == BZ_S_INPUT) {
- progress_in |= copy_input_until_stop ( s );
- if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
- flush_RL ( s );
- BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) );
- s->state = BZ_S_OUTPUT;
- }
- else
- if (s->nblock >= s->nblockMAX) {
- BZ2_compressBlock ( s, False );
- s->state = BZ_S_OUTPUT;
- }
- else
- if (s->strm->avail_in == 0) {
- break;
- }
- }
-
- }
-
- return progress_in || progress_out;
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action )
-{
- Bool progress;
- EState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- preswitch:
- switch (s->mode) {
-
- case BZ_M_IDLE:
- return BZ_SEQUENCE_ERROR;
-
- case BZ_M_RUNNING:
- if (action == BZ_RUN) {
- progress = handle_compress ( strm );
- return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;
- }
- else
- if (action == BZ_FLUSH) {
- s->avail_in_expect = strm->avail_in;
- s->mode = BZ_M_FLUSHING;
- goto preswitch;
- }
- else
- if (action == BZ_FINISH) {
- s->avail_in_expect = strm->avail_in;
- s->mode = BZ_M_FINISHING;
- goto preswitch;
- }
- else
- return BZ_PARAM_ERROR;
-
- case BZ_M_FLUSHING:
- if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR;
- if (s->avail_in_expect != s->strm->avail_in)
- return BZ_SEQUENCE_ERROR;
- progress = handle_compress ( strm );
- if (s->avail_in_expect > 0 || !isempty_RL(s) ||
- s->state_out_pos < s->numZ) return BZ_FLUSH_OK;
- s->mode = BZ_M_RUNNING;
- return BZ_RUN_OK;
-
- case BZ_M_FINISHING:
- if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR;
- if (s->avail_in_expect != s->strm->avail_in)
- return BZ_SEQUENCE_ERROR;
- progress = handle_compress ( strm );
- if (!progress) return BZ_SEQUENCE_ERROR;
- if (s->avail_in_expect > 0 || !isempty_RL(s) ||
- s->state_out_pos < s->numZ) return BZ_FINISH_OK;
- s->mode = BZ_M_IDLE;
- return BZ_STREAM_END;
- }
- return BZ_OK; /*--not reached--*/
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm )
-{
- EState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- if (s->arr1 != NULL) BZFREE(s->arr1);
- if (s->arr2 != NULL) BZFREE(s->arr2);
- if (s->ftab != NULL) BZFREE(s->ftab);
- BZFREE(strm->state);
-
- strm->state = NULL;
-
- return BZ_OK;
-}
-#endif /* BZ_NO_COMPRESS */
-
-/*---------------------------------------------------*/
-/*--- Decompression stuff ---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompressInit)
- ( bz_stream* strm,
- int verbosity,
- int small )
-{
- DState* s;
-
- if (!bz_config_ok()) return BZ_CONFIG_ERROR;
-
- if (strm == NULL) return BZ_PARAM_ERROR;
- if (small != 0 && small != 1) return BZ_PARAM_ERROR;
- if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR;
-
- if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc;
- if (strm->bzfree == NULL) strm->bzfree = default_bzfree;
-
- s = BZALLOC( sizeof(DState) );
- if (s == NULL) return BZ_MEM_ERROR;
- s->strm = strm;
- strm->state = s;
- s->state = BZ_X_MAGIC_1;
- s->bsLive = 0;
- s->bsBuff = 0;
- s->calculatedCombinedCRC = 0;
- strm->total_in_lo32 = 0;
- strm->total_in_hi32 = 0;
- strm->total_out_lo32 = 0;
- strm->total_out_hi32 = 0;
- s->smallDecompress = (Bool)small;
- s->ll4 = NULL;
- s->ll16 = NULL;
- s->tt = NULL;
- s->currBlockNo = 0;
- s->verbosity = verbosity;
-
- return BZ_OK;
-}
-
-
-/*---------------------------------------------------*/
-static
-void unRLE_obuf_to_output_FAST ( DState* s )
-{
- UChar k1;
-
- if (s->blockRandomised) {
-
- while (True) {
- /* try to finish existing run */
- while (True) {
- if (s->strm->avail_out == 0) return;
- if (s->state_out_len == 0) break;
- *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
- BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
- s->state_out_len--;
- s->strm->next_out++;
- s->strm->avail_out--;
- s->strm->total_out_lo32++;
- if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
- }
-
- /* can a new run be started? */
- if (s->nblock_used == s->save_nblock+1) return;
-
-
- s->state_out_len = 1;
- s->state_out_ch = s->k0;
- BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 2;
- BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 3;
- BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- BZ_GET_FAST(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- s->state_out_len = ((Int32)k1) + 4;
- BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK;
- s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
- }
-
- } else {
-
- /* restore */
- UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC;
- UChar c_state_out_ch = s->state_out_ch;
- Int32 c_state_out_len = s->state_out_len;
- Int32 c_nblock_used = s->nblock_used;
- Int32 c_k0 = s->k0;
- UInt32* c_tt = s->tt;
- UInt32 c_tPos = s->tPos;
- char* cs_next_out = s->strm->next_out;
- unsigned int cs_avail_out = s->strm->avail_out;
- /* end restore */
-
- UInt32 avail_out_INIT = cs_avail_out;
- Int32 s_save_nblockPP = s->save_nblock+1;
- unsigned int total_out_lo32_old;
-
- while (True) {
-
- /* try to finish existing run */
- if (c_state_out_len > 0) {
- while (True) {
- if (cs_avail_out == 0) goto return_notr;
- if (c_state_out_len == 1) break;
- *( (UChar*)(cs_next_out) ) = c_state_out_ch;
- BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
- c_state_out_len--;
- cs_next_out++;
- cs_avail_out--;
- }
- s_state_out_len_eq_one:
- {
- if (cs_avail_out == 0) {
- c_state_out_len = 1; goto return_notr;
- };
- *( (UChar*)(cs_next_out) ) = c_state_out_ch;
- BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch );
- cs_next_out++;
- cs_avail_out--;
- }
- }
- /* can a new run be started? */
- if (c_nblock_used == s_save_nblockPP) {
- c_state_out_len = 0; goto return_notr;
- };
- c_state_out_ch = c_k0;
- BZ_GET_FAST_C(k1); c_nblock_used++;
- if (k1 != c_k0) {
- c_k0 = k1; goto s_state_out_len_eq_one;
- };
- if (c_nblock_used == s_save_nblockPP)
- goto s_state_out_len_eq_one;
-
- c_state_out_len = 2;
- BZ_GET_FAST_C(k1); c_nblock_used++;
- if (c_nblock_used == s_save_nblockPP) continue;
- if (k1 != c_k0) { c_k0 = k1; continue; };
-
- c_state_out_len = 3;
- BZ_GET_FAST_C(k1); c_nblock_used++;
- if (c_nblock_used == s_save_nblockPP) continue;
- if (k1 != c_k0) { c_k0 = k1; continue; };
-
- BZ_GET_FAST_C(k1); c_nblock_used++;
- c_state_out_len = ((Int32)k1) + 4;
- BZ_GET_FAST_C(c_k0); c_nblock_used++;
- }
-
- return_notr:
- total_out_lo32_old = s->strm->total_out_lo32;
- s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out);
- if (s->strm->total_out_lo32 < total_out_lo32_old)
- s->strm->total_out_hi32++;
-
- /* save */
- s->calculatedBlockCRC = c_calculatedBlockCRC;
- s->state_out_ch = c_state_out_ch;
- s->state_out_len = c_state_out_len;
- s->nblock_used = c_nblock_used;
- s->k0 = c_k0;
- s->tt = c_tt;
- s->tPos = c_tPos;
- s->strm->next_out = cs_next_out;
- s->strm->avail_out = cs_avail_out;
- /* end save */
- }
-}
-
-
-/*---------------------------------------------------*/
-__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab )
-{
- Int32 nb, na, mid;
- nb = 0;
- na = 256;
- do {
- mid = (nb + na) >> 1;
- if (indx >= cftab[mid]) nb = mid; else na = mid;
- }
- while (na - nb != 1);
- return nb;
-}
-
-
-/*---------------------------------------------------*/
-static
-void unRLE_obuf_to_output_SMALL ( DState* s )
-{
- UChar k1;
-
- if (s->blockRandomised) {
-
- while (True) {
- /* try to finish existing run */
- while (True) {
- if (s->strm->avail_out == 0) return;
- if (s->state_out_len == 0) break;
- *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
- BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
- s->state_out_len--;
- s->strm->next_out++;
- s->strm->avail_out--;
- s->strm->total_out_lo32++;
- if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
- }
-
- /* can a new run be started? */
- if (s->nblock_used == s->save_nblock+1) return;
-
-
- s->state_out_len = 1;
- s->state_out_ch = s->k0;
- BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 2;
- BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 3;
- BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK;
- k1 ^= BZ_RAND_MASK; s->nblock_used++;
- s->state_out_len = ((Int32)k1) + 4;
- BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK;
- s->k0 ^= BZ_RAND_MASK; s->nblock_used++;
- }
-
- } else {
-
- while (True) {
- /* try to finish existing run */
- while (True) {
- if (s->strm->avail_out == 0) return;
- if (s->state_out_len == 0) break;
- *( (UChar*)(s->strm->next_out) ) = s->state_out_ch;
- BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch );
- s->state_out_len--;
- s->strm->next_out++;
- s->strm->avail_out--;
- s->strm->total_out_lo32++;
- if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++;
- }
-
- /* can a new run be started? */
- if (s->nblock_used == s->save_nblock+1) return;
-
- s->state_out_len = 1;
- s->state_out_ch = s->k0;
- BZ_GET_SMALL(k1); s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 2;
- BZ_GET_SMALL(k1); s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- s->state_out_len = 3;
- BZ_GET_SMALL(k1); s->nblock_used++;
- if (s->nblock_used == s->save_nblock+1) continue;
- if (k1 != s->k0) { s->k0 = k1; continue; };
-
- BZ_GET_SMALL(k1); s->nblock_used++;
- s->state_out_len = ((Int32)k1) + 4;
- BZ_GET_SMALL(s->k0); s->nblock_used++;
- }
-
- }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompress) ( bz_stream *strm )
-{
- DState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- while (True) {
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
- WATCHDOG_RESET();
-#endif
- if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR;
- if (s->state == BZ_X_OUTPUT) {
- if (s->smallDecompress)
- unRLE_obuf_to_output_SMALL ( s ); else
- unRLE_obuf_to_output_FAST ( s );
- if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) {
- BZ_FINALISE_CRC ( s->calculatedBlockCRC );
- if (s->verbosity >= 3)
- VPrintf2 ( " {0x%x, 0x%x}", s->storedBlockCRC,
- s->calculatedBlockCRC );
- if (s->verbosity >= 2) VPrintf0 ( "]" );
- if (s->calculatedBlockCRC != s->storedBlockCRC)
- return BZ_DATA_ERROR;
- s->calculatedCombinedCRC
- = (s->calculatedCombinedCRC << 1) |
- (s->calculatedCombinedCRC >> 31);
- s->calculatedCombinedCRC ^= s->calculatedBlockCRC;
- s->state = BZ_X_BLKHDR_1;
- } else {
- return BZ_OK;
- }
- }
- if (s->state >= BZ_X_MAGIC_1) {
- Int32 r = BZ2_decompress ( s );
- if (r == BZ_STREAM_END) {
- if (s->verbosity >= 3)
- VPrintf2 ( "\n combined CRCs: stored = 0x%x, computed = 0x%x",
- s->storedCombinedCRC, s->calculatedCombinedCRC );
- if (s->calculatedCombinedCRC != s->storedCombinedCRC)
- return BZ_DATA_ERROR;
- return r;
- }
- if (s->state != BZ_X_OUTPUT) return r;
- }
- }
-
- AssertH ( 0, 6001 );
-
- return 0; /*NOTREACHED*/
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm )
-{
- DState* s;
- if (strm == NULL) return BZ_PARAM_ERROR;
- s = strm->state;
- if (s == NULL) return BZ_PARAM_ERROR;
- if (s->strm != strm) return BZ_PARAM_ERROR;
-
- if (s->tt != NULL) BZFREE(s->tt);
- if (s->ll16 != NULL) BZFREE(s->ll16);
- if (s->ll4 != NULL) BZFREE(s->ll4);
-
- BZFREE(strm->state);
- strm->state = NULL;
-
- return BZ_OK;
-}
-
-
-#ifndef BZ_NO_STDIO
-/*---------------------------------------------------*/
-/*--- File I/O stuff ---*/
-/*---------------------------------------------------*/
-
-#define BZ_SETERR(eee) \
-{ \
- if (bzerror != NULL) *bzerror = eee; \
- if (bzf != NULL) bzf->lastErr = eee; \
-}
-
-typedef
- struct {
- FILE* handle;
- Char buf[BZ_MAX_UNUSED];
- Int32 bufN;
- Bool writing;
- bz_stream strm;
- Int32 lastErr;
- Bool initialisedOk;
- }
- bzFile;
-
-
-/*---------------------------------------------*/
-static Bool myfeof ( FILE* f )
-{
- Int32 c = fgetc ( f );
- if (c == EOF) return True;
- ungetc ( c, f );
- return False;
-}
-
-
-/*---------------------------------------------------*/
-BZFILE* BZ_API(BZ2_bzWriteOpen)
- ( int* bzerror,
- FILE* f,
- int blockSize100k,
- int verbosity,
- int workFactor )
-{
- Int32 ret;
- bzFile* bzf = NULL;
-
- BZ_SETERR(BZ_OK);
-
- if (f == NULL ||
- (blockSize100k < 1 || blockSize100k > 9) ||
- (workFactor < 0 || workFactor > 250) ||
- (verbosity < 0 || verbosity > 4))
- { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
-
- if (ferror(f))
- { BZ_SETERR(BZ_IO_ERROR); return NULL; };
-
- bzf = malloc ( sizeof(bzFile) );
- if (bzf == NULL)
- { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
-
- BZ_SETERR(BZ_OK);
- bzf->initialisedOk = False;
- bzf->bufN = 0;
- bzf->handle = f;
- bzf->writing = True;
- bzf->strm.bzalloc = NULL;
- bzf->strm.bzfree = NULL;
- bzf->strm.opaque = NULL;
-
- if (workFactor == 0) workFactor = 30;
- ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k,
- verbosity, workFactor );
- if (ret != BZ_OK)
- { BZ_SETERR(ret); free(bzf); return NULL; };
-
- bzf->strm.avail_in = 0;
- bzf->initialisedOk = True;
- return bzf;
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzWrite)
- ( int* bzerror,
- BZFILE* b,
- void* buf,
- int len )
-{
- Int32 n, n2, ret;
- bzFile* bzf = (bzFile*)b;
-
- BZ_SETERR(BZ_OK);
- if (bzf == NULL || buf == NULL || len < 0)
- { BZ_SETERR(BZ_PARAM_ERROR); return; };
- if (!(bzf->writing))
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
-
- if (len == 0)
- { BZ_SETERR(BZ_OK); return; };
-
- bzf->strm.avail_in = len;
- bzf->strm.next_in = buf;
-
- while (True) {
- bzf->strm.avail_out = BZ_MAX_UNUSED;
- bzf->strm.next_out = bzf->buf;
- ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN );
- if (ret != BZ_RUN_OK)
- { BZ_SETERR(ret); return; };
-
- if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
- n = BZ_MAX_UNUSED - bzf->strm.avail_out;
- n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
- n, bzf->handle );
- if (n != n2 || ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
- }
-
- if (bzf->strm.avail_in == 0)
- { BZ_SETERR(BZ_OK); return; };
- }
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzWriteClose)
- ( int* bzerror,
- BZFILE* b,
- int abandon,
- unsigned int* nbytes_in,
- unsigned int* nbytes_out )
-{
- BZ2_bzWriteClose64 ( bzerror, b, abandon,
- nbytes_in, NULL, nbytes_out, NULL );
-}
-
-
-void BZ_API(BZ2_bzWriteClose64)
- ( int* bzerror,
- BZFILE* b,
- int abandon,
- unsigned int* nbytes_in_lo32,
- unsigned int* nbytes_in_hi32,
- unsigned int* nbytes_out_lo32,
- unsigned int* nbytes_out_hi32 )
-{
- Int32 n, n2, ret;
- bzFile* bzf = (bzFile*)b;
-
- if (bzf == NULL)
- { BZ_SETERR(BZ_OK); return; };
- if (!(bzf->writing))
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
-
- if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0;
- if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0;
- if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0;
- if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0;
-
- if ((!abandon) && bzf->lastErr == BZ_OK) {
- while (True) {
- bzf->strm.avail_out = BZ_MAX_UNUSED;
- bzf->strm.next_out = bzf->buf;
- ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH );
- if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END)
- { BZ_SETERR(ret); return; };
-
- if (bzf->strm.avail_out < BZ_MAX_UNUSED) {
- n = BZ_MAX_UNUSED - bzf->strm.avail_out;
- n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar),
- n, bzf->handle );
- if (n != n2 || ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
- }
-
- if (ret == BZ_STREAM_END) break;
- }
- }
-
- if ( !abandon && !ferror ( bzf->handle ) ) {
- fflush ( bzf->handle );
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return; };
- }
-
- if (nbytes_in_lo32 != NULL)
- *nbytes_in_lo32 = bzf->strm.total_in_lo32;
- if (nbytes_in_hi32 != NULL)
- *nbytes_in_hi32 = bzf->strm.total_in_hi32;
- if (nbytes_out_lo32 != NULL)
- *nbytes_out_lo32 = bzf->strm.total_out_lo32;
- if (nbytes_out_hi32 != NULL)
- *nbytes_out_hi32 = bzf->strm.total_out_hi32;
-
- BZ_SETERR(BZ_OK);
- BZ2_bzCompressEnd ( &(bzf->strm) );
- free ( bzf );
-}
-
-
-/*---------------------------------------------------*/
-BZFILE* BZ_API(BZ2_bzReadOpen)
- ( int* bzerror,
- FILE* f,
- int verbosity,
- int small,
- void* unused,
- int nUnused )
-{
- bzFile* bzf = NULL;
- int ret;
-
- BZ_SETERR(BZ_OK);
-
- if (f == NULL ||
- (small != 0 && small != 1) ||
- (verbosity < 0 || verbosity > 4) ||
- (unused == NULL && nUnused != 0) ||
- (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED)))
- { BZ_SETERR(BZ_PARAM_ERROR); return NULL; };
-
- if (ferror(f))
- { BZ_SETERR(BZ_IO_ERROR); return NULL; };
-
- bzf = malloc ( sizeof(bzFile) );
- if (bzf == NULL)
- { BZ_SETERR(BZ_MEM_ERROR); return NULL; };
-
- BZ_SETERR(BZ_OK);
-
- bzf->initialisedOk = False;
- bzf->handle = f;
- bzf->bufN = 0;
- bzf->writing = False;
- bzf->strm.bzalloc = NULL;
- bzf->strm.bzfree = NULL;
- bzf->strm.opaque = NULL;
-
- while (nUnused > 0) {
- bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++;
- unused = ((void*)( 1 + ((UChar*)(unused)) ));
- nUnused--;
- }
-
- ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small );
- if (ret != BZ_OK)
- { BZ_SETERR(ret); free(bzf); return NULL; };
-
- bzf->strm.avail_in = bzf->bufN;
- bzf->strm.next_in = bzf->buf;
-
- bzf->initialisedOk = True;
- return bzf;
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b )
-{
- bzFile* bzf = (bzFile*)b;
-
- BZ_SETERR(BZ_OK);
- if (bzf == NULL)
- { BZ_SETERR(BZ_OK); return; };
-
- if (bzf->writing)
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
-
- if (bzf->initialisedOk)
- (void)BZ2_bzDecompressEnd ( &(bzf->strm) );
- free ( bzf );
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzRead)
- ( int* bzerror,
- BZFILE* b,
- void* buf,
- int len )
-{
- Int32 n, ret;
- bzFile* bzf = (bzFile*)b;
-
- BZ_SETERR(BZ_OK);
-
- if (bzf == NULL || buf == NULL || len < 0)
- { BZ_SETERR(BZ_PARAM_ERROR); return 0; };
-
- if (bzf->writing)
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; };
-
- if (len == 0)
- { BZ_SETERR(BZ_OK); return 0; };
-
- bzf->strm.avail_out = len;
- bzf->strm.next_out = buf;
-
- while (True) {
-
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return 0; };
-
- if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) {
- n = fread ( bzf->buf, sizeof(UChar),
- BZ_MAX_UNUSED, bzf->handle );
- if (ferror(bzf->handle))
- { BZ_SETERR(BZ_IO_ERROR); return 0; };
- bzf->bufN = n;
- bzf->strm.avail_in = bzf->bufN;
- bzf->strm.next_in = bzf->buf;
- }
-
- ret = BZ2_bzDecompress ( &(bzf->strm) );
-
- if (ret != BZ_OK && ret != BZ_STREAM_END)
- { BZ_SETERR(ret); return 0; };
-
- if (ret == BZ_OK && myfeof(bzf->handle) &&
- bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0)
- { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; };
-
- if (ret == BZ_STREAM_END)
- { BZ_SETERR(BZ_STREAM_END);
- return len - bzf->strm.avail_out; };
- if (bzf->strm.avail_out == 0)
- { BZ_SETERR(BZ_OK); return len; };
-
- }
-
- return 0; /*not reached*/
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzReadGetUnused)
- ( int* bzerror,
- BZFILE* b,
- void** unused,
- int* nUnused )
-{
- bzFile* bzf = (bzFile*)b;
- if (bzf == NULL)
- { BZ_SETERR(BZ_PARAM_ERROR); return; };
- if (bzf->lastErr != BZ_STREAM_END)
- { BZ_SETERR(BZ_SEQUENCE_ERROR); return; };
- if (unused == NULL || nUnused == NULL)
- { BZ_SETERR(BZ_PARAM_ERROR); return; };
-
- BZ_SETERR(BZ_OK);
- *nUnused = bzf->strm.avail_in;
- *unused = bzf->strm.next_in;
-}
-#endif
-
-
-/*---------------------------------------------------*/
-/*--- Misc convenience stuff ---*/
-/*---------------------------------------------------*/
-#ifndef BZ_NO_COMPRESS
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzBuffToBuffCompress)
- ( char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int blockSize100k,
- int verbosity,
- int workFactor )
-{
- bz_stream strm;
- int ret;
-
- if (dest == NULL || destLen == NULL ||
- source == NULL ||
- blockSize100k < 1 || blockSize100k > 9 ||
- verbosity < 0 || verbosity > 4 ||
- workFactor < 0 || workFactor > 250)
- return BZ_PARAM_ERROR;
-
- if (workFactor == 0) workFactor = 30;
- strm.bzalloc = NULL;
- strm.bzfree = NULL;
- strm.opaque = NULL;
- ret = BZ2_bzCompressInit ( &strm, blockSize100k,
- verbosity, workFactor );
- if (ret != BZ_OK) return ret;
-
- strm.next_in = source;
- strm.next_out = dest;
- strm.avail_in = sourceLen;
- strm.avail_out = *destLen;
-
- ret = BZ2_bzCompress ( &strm, BZ_FINISH );
- if (ret == BZ_FINISH_OK) goto output_overflow;
- if (ret != BZ_STREAM_END) goto errhandler;
-
- /* normal termination */
- *destLen -= strm.avail_out;
- BZ2_bzCompressEnd ( &strm );
- return BZ_OK;
-
- output_overflow:
- BZ2_bzCompressEnd ( &strm );
- return BZ_OUTBUFF_FULL;
-
- errhandler:
- BZ2_bzCompressEnd ( &strm );
- return ret;
-}
-#endif /* BZ_NO_COMPRESS */
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzBuffToBuffDecompress)
- ( char* dest,
- unsigned int* destLen,
- char* source,
- unsigned int sourceLen,
- int small,
- int verbosity )
-{
- bz_stream strm;
- int ret;
-
- if (destLen == NULL || source == NULL)
- return BZ_PARAM_ERROR;
-
- strm.bzalloc = NULL;
- strm.bzfree = NULL;
- strm.opaque = NULL;
- ret = BZ2_bzDecompressInit ( &strm, verbosity, small );
- if (ret != BZ_OK) return ret;
-
- strm.next_in = source;
- strm.next_out = dest;
- strm.avail_in = sourceLen;
- strm.avail_out = *destLen;
-
- ret = BZ2_bzDecompress ( &strm );
- if (ret == BZ_OK) goto output_overflow_or_eof;
- if (ret != BZ_STREAM_END) goto errhandler;
-
- /* normal termination */
- *destLen -= strm.avail_out;
- BZ2_bzDecompressEnd ( &strm );
- return BZ_OK;
-
- output_overflow_or_eof:
- if (strm.avail_out > 0) {
- BZ2_bzDecompressEnd ( &strm );
- return BZ_UNEXPECTED_EOF;
- } else {
- BZ2_bzDecompressEnd ( &strm );
- return BZ_OUTBUFF_FULL;
- };
-
- errhandler:
- BZ2_bzDecompressEnd ( &strm );
- return ret;
-}
-
-
-/*---------------------------------------------------*/
-/*--
- Code contributed by Yoshioka Tsuneo
- (QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
- to support better zlib compatibility.
- This code is not _officially_ part of libbzip2 (yet);
- I haven't tested it, documented it, or considered the
- threading-safeness of it.
- If this code breaks, please contact both Yoshioka and me.
---*/
-/*---------------------------------------------------*/
-
-/*---------------------------------------------------*/
-/*--
- return version like "0.9.0c".
---*/
-const char * BZ_API(BZ2_bzlibVersion)(void)
-{
- return BZ_VERSION;
-}
-
-
-#ifndef BZ_NO_STDIO
-/*---------------------------------------------------*/
-
-#if defined(_WIN32) || defined(OS2) || defined(MSDOS)
-# include <fcntl.h>
-# include <io.h>
-# define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY)
-#else
-# define SET_BINARY_MODE(file)
-#endif
-static
-BZFILE * bzopen_or_bzdopen
- ( const char *path, /* no use when bzdopen */
- int fd, /* no use when bzdopen */
- const char *mode,
- int open_mode) /* bzopen: 0, bzdopen:1 */
-{
- int bzerr;
- char unused[BZ_MAX_UNUSED];
- int blockSize100k = 9;
- int writing = 0;
- char mode2[10] = "";
- FILE *fp = NULL;
- BZFILE *bzfp = NULL;
- int verbosity = 0;
- int workFactor = 30;
- int smallMode = 0;
- int nUnused = 0;
-
- if (mode == NULL) return NULL;
- while (*mode) {
- switch (*mode) {
- case 'r':
- writing = 0; break;
- case 'w':
- writing = 1; break;
- case 's':
- smallMode = 1; break;
- default:
- if (isdigit((int)(*mode))) {
- blockSize100k = *mode-BZ_HDR_0;
- }
- }
- mode++;
- }
- strcat(mode2, writing ? "w" : "r" );
- strcat(mode2,"b"); /* binary mode */
-
- if (open_mode==0) {
- if (path==NULL || strcmp(path,"")==0) {
- fp = (writing ? stdout : stdin);
- SET_BINARY_MODE(fp);
- } else {
- fp = fopen(path,mode2);
- }
- } else {
-#ifdef BZ_STRICT_ANSI
- fp = NULL;
-#else
- fp = fdopen(fd,mode2);
-#endif
- }
- if (fp == NULL) return NULL;
-
- if (writing) {
- /* Guard against total chaos and anarchy -- JRS */
- if (blockSize100k < 1) blockSize100k = 1;
- if (blockSize100k > 9) blockSize100k = 9;
- bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k,
- verbosity,workFactor);
- } else {
- bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode,
- unused,nUnused);
- }
- if (bzfp == NULL) {
- if (fp != stdin && fp != stdout) fclose(fp);
- return NULL;
- }
- return bzfp;
-}
-
-
-/*---------------------------------------------------*/
-/*--
- open file for read or write.
- ex) bzopen("file","w9")
- case path="" or NULL => use stdin or stdout.
---*/
-BZFILE * BZ_API(BZ2_bzopen)
- ( const char *path,
- const char *mode )
-{
- return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0);
-}
-
-
-/*---------------------------------------------------*/
-BZFILE * BZ_API(BZ2_bzdopen)
- ( int fd,
- const char *mode )
-{
- return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1);
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len )
-{
- int bzerr, nread;
- if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0;
- nread = BZ2_bzRead(&bzerr,b,buf,len);
- if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) {
- return nread;
- } else {
- return -1;
- }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len )
-{
- int bzerr;
-
- BZ2_bzWrite(&bzerr,b,buf,len);
- if(bzerr == BZ_OK){
- return len;
- }else{
- return -1;
- }
-}
-
-
-/*---------------------------------------------------*/
-int BZ_API(BZ2_bzflush) (BZFILE *b)
-{
- /* do nothing now... */
- return 0;
-}
-
-
-/*---------------------------------------------------*/
-void BZ_API(BZ2_bzclose) (BZFILE* b)
-{
- int bzerr;
- FILE *fp = ((bzFile *)b)->handle;
-
- if (b==NULL) {return;}
- if(((bzFile*)b)->writing){
- BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL);
- if(bzerr != BZ_OK){
- BZ2_bzWriteClose(NULL,b,1,NULL,NULL);
- }
- }else{
- BZ2_bzReadClose(&bzerr,b);
- }
- if(fp!=stdin && fp!=stdout){
- fclose(fp);
- }
-}
-
-
-/*---------------------------------------------------*/
-/*--
- return last error code
---*/
-static char *bzerrorstrings[] = {
- "OK"
- ,"SEQUENCE_ERROR"
- ,"PARAM_ERROR"
- ,"MEM_ERROR"
- ,"DATA_ERROR"
- ,"DATA_ERROR_MAGIC"
- ,"IO_ERROR"
- ,"UNEXPECTED_EOF"
- ,"OUTBUFF_FULL"
- ,"CONFIG_ERROR"
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
- ,"???" /* for future */
-};
-
-
-const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum)
-{
- int err = ((bzFile *)b)->lastErr;
-
- if(err>0) err = 0;
- *errnum = err;
- return bzerrorstrings[err*-1];
-}
-#endif
diff --git a/lib/bzlib_crctable.c b/lib/bzlib_crctable.c
deleted file mode 100644
index 325b966..0000000
--- a/lib/bzlib_crctable.c
+++ /dev/null
@@ -1,145 +0,0 @@
-#include <config.h>
-
-/*-------------------------------------------------------------*/
-/*--- Table for doing CRCs ---*/
-/*--- crctable.c ---*/
-/*-------------------------------------------------------------*/