]> git.karo-electronics.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-blackfin
authorTom Rini <trini@ti.com>
Tue, 12 Aug 2014 20:54:55 +0000 (16:54 -0400)
committerTom Rini <trini@ti.com>
Tue, 12 Aug 2014 20:54:55 +0000 (16:54 -0400)
86 files changed:
MAINTAINERS [new file with mode: 0644]
Makefile
arch/arm/include/asm/emif.h
common/board_r.c
common/bootm.c
common/cmd_dfu.c
common/cmd_ext4.c
common/cmd_fat.c
common/cmd_fdt.c
common/cmd_fs.c
common/cmd_pxe.c
common/cmd_thordown.c
common/env_fat.c
common/fdt_support.c
common/image-fdt.c
common/image.c
common/lcd.c
doc/README.android-fastboot
doc/README.scrapyard
doc/git-mailrc
doc/uImage.FIT/signature.txt
drivers/dfu/Makefile
drivers/dfu/dfu.c
drivers/dfu/dfu_mmc.c
drivers/dfu/dfu_nand.c
drivers/dfu/dfu_ram.c
drivers/dfu/dfu_sf.c [new file with mode: 0644]
drivers/dma/Makefile
drivers/dma/omap3_dma.c [deleted file]
drivers/net/phy/vitesse.c
drivers/serial/ns16550.c
drivers/serial/serial_ns16550.c
drivers/serial/serial_sh.c
drivers/serial/serial_sh.h
drivers/serial/usbtty.h
drivers/usb/gadget/Makefile
drivers/usb/gadget/f_dfu.c
drivers/usb/gadget/f_thor.c
drivers/usb/gadget/omap1510_udc.c
drivers/usb/host/ehci-rmobile.c
drivers/video/Makefile
drivers/video/am335x-fb.c [new file with mode: 0644]
drivers/video/am335x-fb.h [new file with mode: 0644]
drivers/video/ipu.h
drivers/video/ipu_disp.c
drivers/video/ipu_regs.h
fs/ext4/ext4fs.c
fs/fat/fat.c
fs/fs.c
fs/sandbox/sandboxfs.c
include/config_distro_bootcmd.h [new file with mode: 0644]
include/configs/koelsch.h
include/configs/lager.h
include/configs/omap1510.h
include/configs/rpi_b.h
include/configs/tegra-common-post.h
include/configs/trats.h
include/configs/trats2.h
include/dfu.h
include/ext4fs.h
include/fat.h
include/fdt_support.h
include/fs.h
include/image.h
include/lcd.h
include/libfdt.h
include/ns16550.h
include/sandboxfs.h
include/u-boot/rsa.h
include/usb/udc.h
lib/libfdt/Makefile
lib/libfdt/fdt_addresses.c [new file with mode: 0644]
lib/libfdt/fdt_rw.c
lib/libfdt/fdt_sw.c
lib/libfdt/libfdt_internal.h
lib/lmb.c
lib/rsa/rsa-sign.c
lib/rsa/rsa-verify.c
net/bootp.c
net/bootp.h
net/net.c
scripts/get_maintainer.pl [new file with mode: 0755]
test/dfu/README [new file with mode: 0644]
test/dfu/dfu_gadget_test.sh [new file with mode: 0755]
test/dfu/dfu_gadget_test_init.sh [new file with mode: 0755]
test/vboot/vboot_test.sh

diff --git a/MAINTAINERS b/MAINTAINERS
new file mode 100644 (file)
index 0000000..af194ca
--- /dev/null
@@ -0,0 +1,405 @@
+Descriptions of section entries:
+
+       P: Person (obsolete)
+       M: Mail patches to: FullName <address@domain>
+       L: Mailing list that is relevant to this area
+       W: Web-page with status/info
+       Q: Patchwork web based patch tracking system site
+       T: SCM tree type and location.
+          Type is one of: git, hg, quilt, stgit, topgit
+       S: Status, one of the following:
+          Supported:   Someone is actually paid to look after this.
+          Maintained:  Someone actually looks after it.
+          Odd Fixes:   It has a maintainer but they don't have time to do
+                       much other than throw the odd patch in. See below..
+          Orphan:      No current maintainer [but maybe you could take the
+                       role as you write your new code].
+          Obsolete:    Old code. Something tagged obsolete generally means
+                       it has been replaced by a better system and you
+                       should be using that.
+       F: Files and directories with wildcard patterns.
+          A trailing slash includes all files and subdirectory files.
+          F:   drivers/net/    all files in and below drivers/net
+          F:   drivers/net/*   all files in drivers/net, but not below
+          F:   */net/*         all files in "any top level directory"/net
+          One pattern per line.  Multiple F: lines acceptable.
+       N: Files and directories with regex patterns.
+          N:   [^a-z]tegra     all files whose path contains the word tegra
+          One pattern per line.  Multiple N: lines acceptable.
+          scripts/get_maintainer.pl has different behavior for files that
+          match F: pattern and matches of N: patterns.  By default,
+          get_maintainer will not look at git log history when an F: pattern
+          match occurs.  When an N: match occurs, git log history is used
+          to also notify the people that have git commit signatures.
+       X: Files and directories that are NOT maintained, same rules as F:
+          Files exclusions are tested before file matches.
+          Can be useful for excluding a specific subdirectory, for instance:
+          F:   net/
+          X:   net/ipv6/
+          matches all files in and below net excluding net/ipv6/
+       K: Keyword perl extended regex pattern to match content in a
+          patch or file.  For instance:
+          K: of_get_profile
+             matches patches or files that contain "of_get_profile"
+          K: \b(printk|pr_(info|err))\b
+             matches patches or files that contain one or more of the words
+             printk, pr_info or pr_err
+          One regex pattern per line.  Multiple K: lines acceptable.
+
+Note: For the hard of thinking, this list is meant to remain in alphabetical
+order. If you could add yourselves to it in alphabetical order that would be
+so much easier [Ed]
+
+Maintainers List (try to look for most precise areas first)
+
+               -----------------------------------
+ARC
+M:     Alexey Brodkin <alexey.brodkin@synopsys.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-arc.git
+F:     arch/arc/
+
+ARM
+M:     Albert Aribaud <albert.u.boot@aribaud.net>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-arm.git
+F:     arch/arm/
+
+ARM ATMEL AT91
+M:     Andreas Bießmann <andreas.devel@googlemail.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-atmel.git
+F:     arch/arm/cpu/armv7/at91/
+F:     arch/arm/cpu/at91-common/
+F:     arch/arm/include/asm/arch-at91/
+
+ARM FREESCALE IMX
+M:     Stefano Babic <sbabic@denx.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-imx.git
+F:     arch/arm/cpu/arm1136/mx*/
+F:     arch/arm/cpu/arm926ejs/mx*/
+F:     arch/arm/cpu/arm926ejs/imx/
+F:     arch/arm/cpu/armv7/mx*/
+F:     arch/arm/cpu/armv7/vf610/
+F:     arch/arm/cpu/imx-common/
+F:     arch/arm/include/asm/arch-imx/
+F:     arch/arm/include/asm/arch-mx*/
+F:     arch/arm/include/asm/arch-vf610/
+F:     arch/arm/include/asm/imx-common/
+
+ARM MARVELL KIRKWOOD
+M:     Prafulla Wadaskar <prafulla@marvell.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-marvell.git
+F:     arch/arm/cpu/arm926ejs/kirkwood/
+F:     arch/arm/include/asm/arch-kirkwood/
+
+ARM MARVELL PXA
+M:     Marek Vasut <marex@denx.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-pxa.git
+F:     arch/arm/cpu/pxa/
+F:     arch/arm/include/asm/arch-pxa/
+
+ARM SAMSUNG
+M:     Minkyu Kang <mk7.kang@samsung.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-samsung.git
+F:     arch/arm/cpu/arm920t/s3c24x0/
+F:     arch/arm/cpu/armv7/exynos/
+F:     arch/arm/cpu/armv7/s5pc1xx/
+F:     arch/arm/cpu/armv7/s5p-common/
+F:     arch/arm/include/asm/arch-exynos/
+F:     arch/arm/include/asm/arch-s3c24x0/
+F:     arch/arm/include/asm/arch-s5pc1xx/
+
+ARM STM SPEAR
+M:     Vipin Kumar <vipin.kumar@st.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-stm.git
+F:     arch/arm/cpu/arm926ejs/spear/
+F:     arch/arm/include/asm/arch-spear/
+
+ARM SUNXI
+M:     Ian Campbell <ijc@hellion.org.uk>
+M:     Hans De Goede <hdegoede@redhat.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-sunxi.git
+F:     arch/arm/cpu/armv7/sunxi/
+F:     arch/arm/include/asm/arch-sunxi/
+
+ARM TEGRA
+M:     Tom Warren <twarren@nvidia.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-tegra.git
+F:     arch/arm/cpu/arm720t/tegra*/
+F:     arch/arm/cpu/armv7/tegra*/
+F:     arch/arm/cpu/tegra*/
+F:     arch/arm/include/asm/arch-tegra*/
+
+ARM TI
+M:     Tom Rini <trini@ti.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-ti.git
+F:     arch/arm/cpu/arm926ejs/davinci/
+F:     arch/arm/cpu/arm926ejs/omap/
+F:     arch/arm/cpu/armv7/omap*/
+F:     arch/arm/include/asm/arch-davinci/
+F:     arch/arm/include/asm/arch-omap*/
+F:     arch/arm/include/asm/ti-common/
+
+ARM ZYNQ
+M:     Michal Simek <monstr@monstr.eu>
+S:     Maintained
+F:     arch/arm/cpu/armv7/zynq/
+F:     arch/arm/include/asm/arch-zynq/
+
+AVR32
+M:     Andreas Bießmann <andreas.devel@googlemail.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-avr32.git
+F:     arch/avr32/
+
+BLACKFIN
+M:     Sonic Zhang <sonic.adi@gmail.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-blackfin.git
+F:     arch/blackfin/
+
+BUILDMAN
+M:     Simon Glass <sjg@chromium.org>
+S:     Maintained
+F:     tools/buildman/
+
+CFI FLASH
+M:     Stefan Roese <sr@denx.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-cfi-flash.git
+F:     drivers/mtd/*
+
+COLDFIRE
+M:     Jason Jin <jason.jin@freescale.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-coldfire.git
+F:     arch/m68k/
+
+DFU
+M:     Lukasz Majewski <l.majewski@samsung.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-dfu.git
+F:     drivers/dfu/
+
+DRIVER MODEL
+M:     Simon Glass <sjg@chromium.org>
+S:     Maintained
+F:     drivers/core/
+F:     include/dm/
+F:     test/dm/
+
+FLATTENED DEVICE TREE
+M:     Simon Glass <sjg@chromium.org>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-fdt.git
+F:     lib/fdtdec*
+F:     lib/libfdt/
+F:     include/fdt*
+F:     include/libfdt*
+F.     common/cmd_fdt.c
+F:     common/fdt_support.c
+
+FREEBSD
+M:     Rafal Jaworowski <raj@semihalf.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-freebsd.git
+
+FREESCALE QORIQ
+M:     York Sun <yorksun@freescale.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-fsl-qoriq.git
+
+I2C
+M:     Heiko Schocher <hs@denx.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-i2c.git
+F:     drivers/i2c/
+
+MICROBLAZE
+M:     Michal Simek <monstr@monstr.eu>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-microblaze.git
+F:     arch/microblaze/
+
+MIPS
+M:     Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-mips.git
+F:     arch/mips/
+
+MMC
+M:     Pantelis Antoniou <panto.antoniou-consulting.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-mmc.git
+F:     drivers/mmc/
+
+OPENRISC
+M:     Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
+S:     Maintained
+F:     arch/openrisc/
+
+PATMAN
+M:     Simon Glass <sjg@chromium.org>
+S:     Maintained
+F:     tools/patman/
+
+POWERPC
+M:     Wolfgang Denk <wd@denx.de>
+S:     Maintained
+F:     arch/powerpc/
+
+POWERPC MPC5XXX
+M:     Wolfgang Denk <wd@denx.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-mpc5xxx.git
+F:     arch/powerpc/cpu/mpc5*/
+
+POWERPC MPC8XX
+M:     Wolfgang Denk <wd@denx.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-mpc8xx.git
+F:     arch/powerpc/cpu/mpc8xx/
+
+POWERPC MPC82XX
+M:     Wolfgang Denk <wd@denx.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-mpc82xx.git
+F:     arch/powerpc/cpu/mpc82*/
+
+POWERPC MPC83XX
+M:     Kim Phillips <kim.phillips@freescale.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-mpc83xx.git
+F:     arch/powerpc/cpu/mpc83xx/
+F:     arch/powerpc/include/asm/arch-mpc83xx/
+
+POWERPC MPC85XX
+M:     York Sun <yorksun@freescale.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-mpc85xx.git
+F:     arch/powerpc/cpu/mpc85xx/
+
+POWERPC MPC86XX
+M:     York Sun <yorksun@freescale.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-mpc86xx.git
+F:     arch/powerpc/cpu/mpc86xx/
+
+POWERPC PPC74XX PPC7XX
+M:     Wolfgang Denk <wd@denx.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-74xx-7xx.git
+F:     arch/powerpc/cpu/74xx_7xx/
+
+POWERPC PPC4XX
+M:     Stefan Roese <sr@denx.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-ppc4xx.git
+F:     arch/powerpc/cpu/ppc4xx/
+
+NETWORK
+M:     Joe Hershberger <joe.hershberger@gmail.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-net.git
+F:     drivers/net/
+
+NAND FLASH
+M:     Scott Wood <scottwood@freescale.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-nand-flash.git
+F:     drivers/mtd/nand/
+
+NDS32
+M:     Macpaul Lin <macpaul@andestech.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-nds32.git
+F:     arch/nds32/
+
+NIOS
+M:     Thomas Chou <thomas@wytron.com.tw>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-nios.git
+F:     arch/nios2/
+
+ONENAND
+M:     Lukasz Majewski <l.majewski@samsung.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-onenand.git
+F:     drivers/mtd/onenand/
+
+SANDBOX
+M:     Simon Glass <sjg@chromium.org>
+S:     Maintained
+F:     arch/sandbox/
+
+SH
+M:     Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-sh.git
+F:     arch/sh/
+
+SPARC
+M:     Daniel Hellstrom <daniel@gaisler.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-sparc.git
+F:     arch/sparc/
+
+SPI
+M:     Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-spi.git
+F:     drivers/mtd/spi/
+F:     drivers/spi/
+F:     include/spi*
+
+TESTING
+M:     Detlev Zundel <dzu@denx.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-testing.git
+
+TQ GROUP
+M:     Martin Krause <martin.krause@tq-systems.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-tq-group.git
+
+UBI
+M:     Kyungmin Park <kmpark@infradead.org>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-ubi.git
+F:     drivers/mtd/ubi/
+
+USB
+M:     Marek Vasut <marex@denx.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-usb.git
+F:     drivers/usb/
+
+VIDEO
+M:     Anatolij Gustschin <agust@denx.de>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-video.git
+F:     drivers/video/
+
+X86
+M:     Simon Glass <sjg@chromium.org>
+S:     Maintained
+T:     git git://git.denx.de/u-boot-x86.git
+F:     arch/x86/
+
+THE REST
+M:     Tom Rini <trini@ti.com>
+L:     u-boot@lists.denx.de
+Q:     http://patchwork.ozlabs.org/project/uboot/list/
+S:     Maintained
+T:     git git://git.denx.de/u-boot.git
+F:     *
+F:     */
index 666d291137c6f7e4950ffee9ce875845ab283f84..b5d5e0110a16238ce2aee6d54ec57fb10eeddb31 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -802,14 +802,15 @@ u-boot.hex u-boot.srec: u-boot FORCE
 
 OBJCOPYFLAGS_u-boot.bin := -O binary
 
-binary_size_check: u-boot.bin System.map FORCE
-       @file_size=`stat -c %s u-boot.bin` ; \
-       map_size=$(shell cat System.map | \
+binary_size_check: u-boot.bin FORCE
+       @file_size=$(shell wc -c u-boot.bin | awk '{print $$1}') ; \
+       map_size=$(shell cat u-boot.map | \
                awk '/_image_copy_start/ {start = $$1} /_image_binary_end/ {end = $$1} END {if (start != "" && end != "") print "ibase=16; " toupper(end) " - " toupper(start)}' \
+               | sed 's/0X//g' \
                | bc); \
        if [ "" != "$$map_size" ]; then \
                if test $$map_size -ne $$file_size; then \
-                       echo "System.map shows a binary size of $$map_size" >&2 ; \
+                       echo "u-boot.map shows a binary size of $$map_size" >&2 ; \
                        echo "  but u-boot.bin shows $$file_size" >&2 ; \
                        exit 1; \
                fi \
index b8d6bdca9b13ead9143d2758b0d9f1456845d523..2fe5776c6cf390777f55c632068723e64d44034b 100644 (file)
@@ -878,7 +878,6 @@ struct dmm_lisa_map_regs {
        ((REG_CS_TIM << EMIF_REG_CS_TIM_SHIFT) & EMIF_REG_CS_TIM_MASK)|\
        ((REG_SR_TIM << EMIF_REG_SR_TIM_SHIFT) & EMIF_REG_SR_TIM_MASK)|\
        ((REG_PD_TIM << EMIF_REG_PD_TIM_SHIFT) & EMIF_REG_PD_TIM_MASK)|\
-       ((REG_PD_TIM << EMIF_REG_PD_TIM_SHIFT) & EMIF_REG_PD_TIM_MASK)|\
        ((LP_MODE_DISABLE << EMIF_REG_LP_MODE_SHIFT)\
                        & EMIF_REG_LP_MODE_MASK) |\
        ((DPD_DISABLE << EMIF_REG_DPD_EN_SHIFT)\
@@ -889,8 +888,6 @@ struct dmm_lisa_map_regs {
                        & EMIF_REG_CS_TIM_SHDW_MASK) |\
        ((REG_SR_TIM << EMIF_REG_SR_TIM_SHDW_SHIFT)\
                        & EMIF_REG_SR_TIM_SHDW_MASK) |\
-       ((REG_PD_TIM << EMIF_REG_PD_TIM_SHDW_SHIFT)\
-                       & EMIF_REG_PD_TIM_SHDW_MASK) |\
        ((REG_PD_TIM << EMIF_REG_PD_TIM_SHDW_SHIFT)\
                        & EMIF_REG_PD_TIM_SHDW_MASK))
 
index 8e7a3ac74cd297c8f9ad2539650f1a94ab1f34da..ba9a68dc6691d445e1803a1ad6eed06e661e5cee 100644 (file)
@@ -587,6 +587,7 @@ static int initr_doc(void)
 {
        puts("DOC:   ");
        doc_init();
+       return 0;
 }
 #endif
 
index 7ec2ed8f45cb98eb6947c8732fa6a341240167bc..76d811c98375ff33d07e6ef55e149a3cf96880a3 100644 (file)
@@ -731,26 +731,7 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
        int             os_noffset;
 #endif
 
-       /* find out kernel image address */
-       if (argc < 1) {
-               img_addr = load_addr;
-               debug("*  kernel: default image load address = 0x%08lx\n",
-                     load_addr);
-#if defined(CONFIG_FIT)
-       } else if (fit_parse_conf(argv[0], load_addr, &img_addr,
-                                 &fit_uname_config)) {
-               debug("*  kernel: config '%s' from image at 0x%08lx\n",
-                     fit_uname_config, img_addr);
-       } else if (fit_parse_subimage(argv[0], load_addr, &img_addr,
-                                    &fit_uname_kernel)) {
-               debug("*  kernel: subimage '%s' from image at 0x%08lx\n",
-                     fit_uname_kernel, img_addr);
-#endif
-       } else {
-               img_addr = simple_strtoul(argv[0], NULL, 16);
-               debug("*  kernel: cmdline image address = 0x%08lx\n",
-                     img_addr);
-       }
+       img_addr = genimg_get_kernel_addr(argv[0]);
 
        bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);
 
@@ -807,6 +788,10 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
 #endif
 #if defined(CONFIG_FIT)
        case IMAGE_FORMAT_FIT:
+               if (!fit_parse_conf(argv[0], load_addr, &img_addr,
+                                       &fit_uname_config))
+                       fit_parse_subimage(argv[0], load_addr, &img_addr,
+                                       &fit_uname_kernel);
                os_noffset = fit_image_load(images, img_addr,
                                &fit_uname_kernel, &fit_uname_config,
                                IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
index 433bddd5d2bdc83d9cf06fa943a44c08d9bba701..2633b30e556f4be8dd685405eb472c4a63acd725 100644 (file)
@@ -24,8 +24,7 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        int ret, i = 0;
 
-       ret = dfu_init_env_entities(interface, simple_strtoul(devstring,
-                                                             NULL, 10));
+       ret = dfu_init_env_entities(interface, devstring);
        if (ret)
                goto done;
 
index 68b047ba6aed1b07509b7ffd8b26fc715c139ce6..ecfc6d3c9bb077fa523ba6c476be388906862fbc 100644 (file)
 #include <usb.h>
 #endif
 
+int do_ext4_size(cmd_tbl_t *cmdtp, int flag, int argc,
+                                               char *const argv[])
+{
+       return do_size(cmdtp, flag, argc, argv, FS_TYPE_EXT);
+}
+
 int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc,
                                                char *const argv[])
 {
@@ -113,6 +119,14 @@ U_BOOT_CMD(ext4write, 6, 1, do_ext4_write,
 
 #endif
 
+U_BOOT_CMD(
+       ext4size,       4,      0,      do_ext4_size,
+       "determine a file's size",
+       "<interface> <dev[:part]> <filename>\n"
+       "    - Find file 'filename' from 'dev' on 'interface'\n"
+       "      and determine its size."
+);
+
 U_BOOT_CMD(ext4ls, 4, 1, do_ext4_ls,
           "list files in a directory (default /)",
           "<interface> <dev[:part]> [directory]\n"
@@ -120,6 +134,6 @@ U_BOOT_CMD(ext4ls, 4, 1, do_ext4_ls,
 
 U_BOOT_CMD(ext4load, 6, 0, do_ext4_load,
           "load binary file from a Ext4 filesystem",
-          "<interface> <dev[:part]> [addr] [filename] [bytes]\n"
+          "<interface> [<dev[:part]> [addr [filename [bytes [pos]]]]]\n"
           "    - load binary file 'filename' from 'dev' on 'interface'\n"
           "      to address 'addr' from ext4 filesystem");
index a4780174480ef858a17a9d804214bc518c9b7f44..633fbf1d311391bb9aa69fd9ce905013b12e9805 100644 (file)
 #include <fat.h>
 #include <fs.h>
 
+int do_fat_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       return do_size(cmdtp, flag, argc, argv, FS_TYPE_FAT);
+}
+
+U_BOOT_CMD(
+       fatsize,        4,      0,      do_fat_size,
+       "determine a file's size",
+       "<interface> <dev[:part]> <filename>\n"
+       "    - Find file 'filename' from 'dev' on 'interface'\n"
+       "      and determine its size."
+);
+
 int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        return do_load(cmdtp, flag, argc, argv, FS_TYPE_FAT);
index e86d992838ee2986f57e9466271b4d393a7e05a0..5640ded296895d8bf2dbd6b1e99ba565d52e1377 100644 (file)
@@ -621,7 +621,7 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        }
        /* resize the fdt */
        else if (strncmp(argv[1], "re", 2) == 0) {
-               fdt_resize(working_fdt);
+               fdt_shrink_to_minimum(working_fdt);
        }
        else {
                /* Unrecognized command */
index 78590d2ef0da8a30179dc0a8c7d3dacb26fe45c0..675434078633400ff85866e4c7554458412b7dc1 100644 (file)
 #include <command.h>
 #include <fs.h>
 
+static int do_size_wrapper(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       return do_size(cmdtp, flag, argc, argv, FS_TYPE_ANY);
+}
+
+U_BOOT_CMD(
+       size,   4,      0,      do_size_wrapper,
+       "determine a file's size",
+       "<interface> <dev[:part]> <filename>\n"
+       "    - Find file 'filename' from 'dev' on 'interface'\n"
+       "      and determine its size."
+);
+
 static int do_load_wrapper(cmd_tbl_t *cmdtp, int flag, int argc,
                                char * const argv[])
 {
index ba48692e8641aa6db1c93ce32bcc4ce041abc37e..c8163392326555ad96e5bcc9b3234e1a407cb82e 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright 2010-2011 Calxeda, Inc.
+ * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
@@ -609,6 +610,8 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
        char *bootargs;
        int bootm_argc = 3;
        int len = 0;
+       ulong kernel_addr;
+       void *buf;
 
        label_print(label);
 
@@ -771,11 +774,15 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
        if (bootm_argv[3])
                bootm_argc = 4;
 
-       do_bootm(cmdtp, 0, bootm_argc, bootm_argv);
-
+       kernel_addr = genimg_get_kernel_addr(bootm_argv[1]);
+       buf = map_sysmem(kernel_addr, 0);
+       /* Try bootm for legacy and FIT format image */
+       if (genimg_get_format(buf) != IMAGE_FORMAT_INVALID)
+               do_bootm(cmdtp, 0, bootm_argc, bootm_argv);
 #ifdef CONFIG_CMD_BOOTZ
-       /* Try booting a zImage if do_bootm returns */
-       do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
+       /* Try booting a zImage */
+       else
+               do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
 #endif
        return 1;
 }
@@ -1554,6 +1561,8 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        destroy_pxe_menu(cfg);
 
+       copy_filename(BootFile, "", sizeof(BootFile));
+
        return 0;
 }
 
index 2dd750928e41ad39c2a924b38140c898f5c114e7..8ed1dc6f9e47a4089885b4232d85bcaa7b3ab3b6 100644 (file)
@@ -26,10 +26,9 @@ int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
        puts("TIZEN \"THOR\" Downloader\n");
 
-       ret = dfu_init_env_entities(interface, simple_strtoul(devstring,
-                                                             NULL, 10));
+       ret = dfu_init_env_entities(interface, devstring);
        if (ret)
-               return ret;
+               goto done;
 
        int controller_index = simple_strtoul(usb_controller, NULL, 0);
        ret = board_usb_init(controller_index, USB_INIT_DEVICE);
@@ -57,6 +56,7 @@ int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 exit:
        g_dnl_unregister();
+done:
        dfu_free_entities();
 
        return ret;
index 328c09d45ff4c9b6b5120908bfb8ca9825ac67da..8db0160ceb0ced4fc703a2a11840d5e6bedde30d 100644 (file)
@@ -73,7 +73,7 @@ int saveenv(void)
 
 void env_relocate_spec(void)
 {
-       char buf[CONFIG_ENV_SIZE];
+       ALLOC_CACHE_ALIGN_BUFFER(char, buf, CONFIG_ENV_SIZE);
        block_dev_desc_t *dev_desc = NULL;
        disk_partition_t info;
        int dev, part;
@@ -92,7 +92,7 @@ void env_relocate_spec(void)
                goto err_env_relocate;
        }
 
-       err = file_fat_read(FAT_ENV_FILE, (uchar *)&buf, CONFIG_ENV_SIZE);
+       err = file_fat_read(FAT_ENV_FILE, buf, CONFIG_ENV_SIZE);
        if (err == -1) {
                printf("\n** Unable to read \"%s\" from %s%d:%d **\n",
                        FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part);
index 7927a83b896988441d3358a0071c55c26c4c2bb5..784a570a818bd94fdb8dd086a4020f5652c91c00 100644 (file)
@@ -508,7 +508,7 @@ void fdt_fixup_ethernet(void *fdt)
 }
 
 /* Resize the fdt to its actual size + a bit of padding */
-int fdt_resize(void *blob)
+int fdt_shrink_to_minimum(void *blob)
 {
        int i;
        uint64_t addr, size;
index db6e39556277323a522761827bea9d5516e07e23..a2342fa3dfdd07c1de766200986cfac97579aa4d 100644 (file)
@@ -479,7 +479,7 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob,
        lmb_free(lmb, (phys_addr_t)(u32)(uintptr_t)blob,
                 (phys_size_t)fdt_totalsize(blob));
 
-       ret = fdt_resize(blob);
+       ret = fdt_shrink_to_minimum(blob);
        if (ret < 0)
                return ret;
        of_size = ret;
index 11b3cf58e6fe197c48e724bbcd02532ea30cf5ae..a2999c0fbaf01df718f745b45e8c96980b16ff9d 100644 (file)
@@ -642,6 +642,49 @@ int genimg_get_comp_id(const char *name)
 }
 
 #ifndef USE_HOSTCC
+/**
+ * genimg_get_kernel_addr - get the real kernel address
+ * @img_addr: a string might contain real image address
+ *
+ * genimg_get_kernel_addr() get the real kernel start address from a string
+ * which is normally the first argv of bootm/bootz
+ *
+ * returns:
+ *     kernel start address
+ */
+ulong genimg_get_kernel_addr(char * const img_addr)
+{
+#if defined(CONFIG_FIT)
+       const char      *fit_uname_config = NULL;
+       const char      *fit_uname_kernel = NULL;
+#endif
+
+       ulong kernel_addr;
+
+       /* find out kernel image address */
+       if (!img_addr) {
+               kernel_addr = load_addr;
+               debug("*  kernel: default image load address = 0x%08lx\n",
+                     load_addr);
+#if defined(CONFIG_FIT)
+       } else if (fit_parse_conf(img_addr, load_addr, &kernel_addr,
+                                 &fit_uname_config)) {
+               debug("*  kernel: config '%s' from image at 0x%08lx\n",
+                     fit_uname_config, kernel_addr);
+       } else if (fit_parse_subimage(img_addr, load_addr, &kernel_addr,
+                                    &fit_uname_kernel)) {
+               debug("*  kernel: subimage '%s' from image at 0x%08lx\n",
+                     fit_uname_kernel, kernel_addr);
+#endif
+       } else {
+               kernel_addr = simple_strtoul(img_addr, NULL, 16);
+               debug("*  kernel: cmdline image address = 0x%08lx\n",
+                     kernel_addr);
+       }
+
+       return kernel_addr;
+}
+
 /**
  * genimg_get_format - get image format type
  * @img_addr: image start address
index feb913a7201354729d9f08b539352d66ad90cd55..217ec9dbd2e9ec3cefdaea4a63e5be2725b445dc 100644 (file)
 #if LCD_BPP == LCD_MONOCHROME
 # define COLOR_MASK(c)         ((c)      | (c) << 1 | (c) << 2 | (c) << 3 | \
                                 (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7)
-#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16)
+#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) || \
+       (LCD_BPP == LCD_COLOR32)
 # define COLOR_MASK(c)         (c)
 #else
 # error Unsupported LCD BPP.
 DECLARE_GLOBAL_DATA_PTR;
 
 static void lcd_drawchars(ushort x, ushort y, uchar *str, int count);
-static inline void lcd_puts_xy(ushort x, ushort y, uchar *s);
 static inline void lcd_putc_xy(ushort x, ushort y, uchar  c);
 
 static int lcd_init(void *lcdbase);
 
 static void *lcd_logo(void);
 
-static int lcd_getbgcolor(void);
 static void lcd_setfgcolor(int color);
 static void lcd_setbgcolor(int color);
 
@@ -177,10 +176,20 @@ static void console_scrollup(void)
               CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
 
        /* Clear the last rows */
+#if (LCD_BPP != LCD_COLOR32)
        memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
                COLOR_MASK(lcd_color_bg),
                CONSOLE_ROW_SIZE * rows);
-
+#else
+       u32 *ppix = lcd_console_address +
+                   CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows;
+       u32 i;
+       for (i = 0;
+           i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix);
+           i++) {
+               *ppix++ = COLOR_MASK(lcd_color_bg);
+       }
+#endif
        lcd_sync();
        console_row -= rows;
 }
@@ -308,13 +317,15 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
        ushort off  = x * (1 << LCD_BPP) % 8;
 #endif
 
-       dest = (uchar *)(lcd_base + y * lcd_line_length + x * (1 << LCD_BPP) / 8);
+       dest = (uchar *)(lcd_base + y * lcd_line_length + x * NBITS(LCD_BPP)/8);
 
        for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
                uchar *s = str;
                int i;
 #if LCD_BPP == LCD_COLOR16
                ushort *d = (ushort *)dest;
+#elif LCD_BPP == LCD_COLOR32
+               u32 *d = (u32 *)dest;
 #else
                uchar *d = dest;
 #endif
@@ -347,6 +358,12 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
                                                lcd_color_fg : lcd_color_bg;
                                bits <<= 1;
                        }
+#elif LCD_BPP == LCD_COLOR32
+                       for (c = 0; c < 8; ++c) {
+                               *d++ = (bits & 0x80) ?
+                                               lcd_color_fg : lcd_color_bg;
+                               bits <<= 1;
+                       }
 #endif
                }
 #if LCD_BPP == LCD_MONOCHROME
@@ -355,15 +372,6 @@ static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
        }
 }
 
-/*----------------------------------------------------------------------*/
-
-static inline void lcd_puts_xy(ushort x, ushort y, uchar *s)
-{
-       lcd_drawchars(x, y, s, strlen((char *)s));
-}
-
-/*----------------------------------------------------------------------*/
-
 static inline void lcd_putc_xy(ushort x, ushort y, uchar c)
 {
        lcd_drawchars(x, y, &c, 1);
@@ -476,9 +484,19 @@ void lcd_clear(void)
        test_pattern();
 #else
        /* set framebuffer to background color */
+#if (LCD_BPP != LCD_COLOR32)
        memset((char *)lcd_base,
-               COLOR_MASK(lcd_getbgcolor()),
+               COLOR_MASK(lcd_color_bg),
                lcd_line_length * panel_info.vl_row);
+#else
+       u32 *ppix = lcd_base;
+       u32 i;
+       for (i = 0;
+          i < (lcd_line_length * panel_info.vl_row)/NBYTES(panel_info.vl_bpix);
+          i++) {
+               *ppix++ = COLOR_MASK(lcd_color_bg);
+       }
+#endif
 #endif
        /* Paint the logo and retrieve LCD base address */
        debug("[LCD] Drawing the logo...\n");
@@ -586,20 +604,6 @@ static void lcd_setbgcolor(int color)
        lcd_color_bg = color;
 }
 
-/*----------------------------------------------------------------------*/
-
-int lcd_getfgcolor(void)
-{
-       return lcd_color_fg;
-}
-
-/*----------------------------------------------------------------------*/
-
-static int lcd_getbgcolor(void)
-{
-       return lcd_color_bg;
-}
-
 /************************************************************************/
 /* ** Chipset depending Bitmap / Logo stuff...                          */
 /************************************************************************/
@@ -938,8 +942,13 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                return 1;
        }
 
-       /* We support displaying 8bpp BMPs on 16bpp LCDs */
-       if (bpix != bmp_bpix && !(bmp_bpix == 8 && bpix == 16)) {
+       /*
+        * We support displaying 8bpp BMPs on 16bpp LCDs
+        * and displaying 24bpp BMPs on 32bpp LCDs
+        * */
+       if (bpix != bmp_bpix &&
+           !(bmp_bpix == 8 && bpix == 16) &&
+           !(bmp_bpix == 24 && bpix == 32)) {
                printf ("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n",
                        bpix, get_unaligned_le16(&bmp->header.bit_count));
                return 1;
@@ -1060,7 +1069,19 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
                }
                break;
 #endif /* CONFIG_BMP_16BPP */
-
+#if defined(CONFIG_BMP_24BMP)
+       case 24:
+               for (i = 0; i < height; ++i) {
+                       for (j = 0; j < width; j++) {
+                               *(fb++) = *(bmap++);
+                               *(fb++) = *(bmap++);
+                               *(fb++) = *(bmap++);
+                               *(fb++) = 0;
+                       }
+                       fb -= lcd_line_length + width * (bpix / 8);
+               }
+               break;
+#endif /* CONFIG_BMP_24BMP */
 #if defined(CONFIG_BMP_32BPP)
        case 32:
                for (i = 0; i < height; ++i) {
index f1d128caa96e05c70d6d2f7b58c18d5ad6bcd939..404572729a722346795b65f62627a168c4e3f0aa 100644 (file)
@@ -38,6 +38,10 @@ CONFIG_G_DNL_VENDOR_NUM
 CONFIG_G_DNL_PRODUCT_NUM
 CONFIG_G_DNL_MANUFACTURER
 
+NOTE: The CONFIG_G_DNL_VENDOR_NUM must be one of the numbers supported by
+the fastboot client. The list of vendor IDs supported can be found in the
+fastboot client source code (fastboot.c) mentioned above.
+
 The fastboot function is enabled by defining CONFIG_CMD_FASTBOOT and
 CONFIG_ANDROID_BOOT_IMAGE.
 
index 6a1d2a5c7e8d971b2af809cb6073f2e94714041c..b950a4174f72f5b2e28253333fa6e12adf81fadd 100644 (file)
@@ -5,23 +5,25 @@ by unnoticed, but often build errors will result.  If nobody cares any
 more to resolve such problems, then the code is really dead and will
 be removed from the U-Boot source tree.  The remainders rest in piece
 in the imperishable depths of the git history.  This document tries to
-maintain a list of such former fellows, so archeologists can check
-easily if here is something they might want to dig for...
+maintain a list of such former fellows, so archaeologists can check
+easily if there is something they might want to dig for...
+The list should be sorted in reverse chronological order.
 
 
 Board            Arch        CPU            Commit      Removed     Last known maintainer/contact
 =================================================================================================
-spc1920          powerpc     mpc8xx         -           -
-v37              powerpc     mpc8xx         -           -
-fads             powerpc     mpc8xx         -           -
-netphone         powerpc     mpc8xx         -           -
-netta2           powerpc     mpc8xx         -           -
-netta            powerpc     mpc8xx         -           -
-rbc823           powerpc     mpc8xx         -           -
-quantum          powerpc     mpc8xx         -           -
-RPXlite_dw       powerpc     mpc8xx         -           -
-qs850            powerpc     mpc8xx         -           -
-qs860t           powerpc     mpc8xx         -           -
+p1023rds         powerpc     mpc85xx        d0bc5140    2014-07-22  Roy Zang <tie-fei.zang@freescale.com>
+spc1920          powerpc     mpc8xx         98ad54be    2014-07-07
+v37              powerpc     mpc8xx         b8c1438a    2014-07-07
+fads             powerpc     mpc8xx         03f9d7d1    2014-07-07
+netphone         powerpc     mpc8xx         c51c1c9a    2014-07-07
+netta2           powerpc     mpc8xx         c51c1c9a    2014-07-07
+netta            powerpc     mpc8xx         c51c1c9a    2014-07-07
+rbc823           powerpc     mpc8xx         c750b9c0    2014-07-07
+quantum          powerpc     mpc8xx         0657e46e    2014-07-07
+RPXlite_dw       powerpc     mpc8xx         0657e46e    2014-07-07
+qs850            powerpc     mpc8xx         dab0f762    2014-07-07
+qs860t           powerpc     mpc8xx         dab0f762    2014-07-07
 simpc8313        powerpc     mpc83xx        7445207f    2014-06-05  Ron Madrid <info@sheldoninst.com>
 hidden_dragon    powerpc     mpc824x        3fe1a854    2014-05-30  Yusdi Santoso <yusdi_santoso@adaptec.com>
 debris           powerpc     mpc824x        7edb1f7b    2014-05-30  Sangmoon Kim <dogoil@etinsys.com>
@@ -33,6 +35,7 @@ zpc1900          powerpc     mpc8260        6f80bb48    2014-05-30  Yuli Barcohe
 mpc8260ads       powerpc     mpc8260        facb6725    2014-05-30  Yuli Barcohen <yuli@arabellasw.com>
 adder            powerpc     mpc8xx         373a9788    2014-05-30  Yuli Barcohen <yuli@arabellasw.com>
 quad100hd        powerpc     ppc405ep       3569571d    2014-05-30  Gary Jennejohn <gljennjohn@googlemail.com>
+incaip           mips        mips32         538cf92c    2014-04-20  Wolfgang Denk <wd@denx.de>
 lubbock          arm         pxa            36bf57b     2014-04-18  Kyle Harris <kharris@nexus-tech.net>
 EVB64260        powerpc     mpc824x        bb3aef9     2014-04-18
 MOUSSE           powerpc     mpc824x        03f2ecc     2014-04-18
@@ -149,4 +152,3 @@ MVS1             powerpc     MPC823         306620b     2008-08-26  Andre Schwar
 adsvix           ARM         PXA27x         7610db1     2008-07-30  Adrian Filipi <adrian.filipi@eurotech.com>
 R5200            ColdFire    -              48ead7a     2008-03-31  Zachary P. Landau <zachary.landau@labxtechnologies.com>
 CPCI440          powerpc     440GP          b568fd2     2007-12-27  Matthias Fuchs <matthias.fuchs@esd-electronics.com>
-incaip           mips        mips32         -           2014-04-17  Wolfgang Denk <wd@denx.de>
index 09857912935bd3f70ea23d4cab27cf096f5bf988..70405f2c968b674aa35ae05787e06aab350bed8d 100644 (file)
@@ -106,10 +106,11 @@ alias sh             superh
 alias x86            uboot, sjg, gruss
 
 # Subsystem aliases
+alias dm             uboot, sjg
 alias cfi            uboot, stroese
 alias dfu            uboot, lukma
 alias kerneldoc      uboot, marex
-alias fdt            uboot, Jerry Van Baren <vanbaren@cideas.com>
+alias fdt            uboot, sjg
 alias i2c            uboot, hs
 alias kconfig        uboot, masahiro
 alias mmc            uboot, panto
index a6ab543de43c18e6c11c2f3b9a4c893014848636..b2f89fcc65d0fd2a14693b26ce7f93ce0fe3412d 100644 (file)
@@ -66,7 +66,8 @@ Creating an RSA key and certificate
 -----------------------------------
 To create a new public key, size 2048 bits:
 
-$ openssl genrsa -F4 -out keys/dev.key 2048
+$ openssl genpkey -algorithm RSA -out keys/dev.key \
+    -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537
 
 To create a certificate for this:
 
@@ -159,6 +160,7 @@ For RSA the following are mandatory:
 
 - rsa,num-bits: Number of key bits (e.g. 2048)
 - rsa,modulus: Modulus (N) as a big-endian multi-word integer
+- rsa,exponent: Public exponent (E) as a 64 bit unsigned integer
 - rsa,r-squared: (2^num-bits)^2 as a big-endian multi-word integer
 - rsa,n0-inverse: -1 / modulus[0] mod 2^32
 
index def628dcdcc46e3aca2b3d9ef7504afe9a9c5082..5cc535efdd476db67629a0339636d7617caf4e10 100644 (file)
@@ -9,3 +9,4 @@ obj-$(CONFIG_DFU_FUNCTION) += dfu.o
 obj-$(CONFIG_DFU_MMC) += dfu_mmc.o
 obj-$(CONFIG_DFU_NAND) += dfu_nand.o
 obj-$(CONFIG_DFU_RAM) += dfu_ram.o
+obj-$(CONFIG_DFU_SF) += dfu_sf.o
index dc09ff6466e6f284bbc4c4764097fa612406d8a2..3512b149c560fc7fa32fa169bbfbd9ac70875bda 100644 (file)
@@ -44,7 +44,7 @@ static int dfu_find_alt_num(const char *s)
        return ++i;
 }
 
-int dfu_init_env_entities(char *interface, int dev)
+int dfu_init_env_entities(char *interface, char *devstr)
 {
        const char *str_env;
        char *env_bkp;
@@ -57,7 +57,7 @@ int dfu_init_env_entities(char *interface, int dev)
        }
 
        env_bkp = strdup(str_env);
-       ret = dfu_config_entities(env_bkp, interface, dev);
+       ret = dfu_config_entities(env_bkp, interface, devstr);
        if (ret) {
                error("DFU entities configuration failed!\n");
                return ret;
@@ -82,7 +82,7 @@ unsigned long dfu_get_buf_size(void)
        return dfu_buf_size;
 }
 
-unsigned char *dfu_get_buf(void)
+unsigned char *dfu_get_buf(struct dfu_entity *dfu)
 {
        char *s;
 
@@ -92,6 +92,8 @@ unsigned char *dfu_get_buf(void)
        s = getenv("dfu_bufsiz");
        dfu_buf_size = s ? (unsigned long)simple_strtol(s, NULL, 16) :
                        CONFIG_SYS_DFU_DATA_BUF_SIZE;
+       if (dfu->max_buf_size && dfu_buf_size > dfu->max_buf_size)
+               dfu_buf_size = dfu->max_buf_size;
 
        dfu_buf = memalign(CONFIG_SYS_CACHELINE_SIZE, dfu_buf_size);
        if (dfu_buf == NULL)
@@ -147,6 +149,19 @@ static int dfu_write_buffer_drain(struct dfu_entity *dfu)
        return ret;
 }
 
+void dfu_write_transaction_cleanup(struct dfu_entity *dfu)
+{
+       /* clear everything */
+       dfu_free_buf();
+       dfu->crc = 0;
+       dfu->offset = 0;
+       dfu->i_blk_seq_num = 0;
+       dfu->i_buf_start = dfu_buf;
+       dfu->i_buf_end = dfu_buf;
+       dfu->i_buf = dfu->i_buf_start;
+       dfu->inited = 0;
+}
+
 int dfu_flush(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
 {
        int ret = 0;
@@ -162,23 +177,14 @@ int dfu_flush(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
                printf("\nDFU complete %s: 0x%08x\n", dfu_hash_algo->name,
                       dfu->crc);
 
-       /* clear everything */
-       dfu_free_buf();
-       dfu->crc = 0;
-       dfu->offset = 0;
-       dfu->i_blk_seq_num = 0;
-       dfu->i_buf_start = dfu_buf;
-       dfu->i_buf_end = dfu_buf;
-       dfu->i_buf = dfu->i_buf_start;
-       dfu->inited = 0;
+       dfu_write_transaction_cleanup(dfu);
 
        return ret;
 }
 
 int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
 {
-       int ret = 0;
-       int tret;
+       int ret;
 
        debug("%s: name: %s buf: 0x%p size: 0x%x p_num: 0x%x offset: 0x%llx bufoffset: 0x%x\n",
              __func__, dfu->name, buf, size, blk_seq_num, dfu->offset,
@@ -190,10 +196,10 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
                dfu->offset = 0;
                dfu->bad_skip = 0;
                dfu->i_blk_seq_num = 0;
-               dfu->i_buf_start = dfu_get_buf();
+               dfu->i_buf_start = dfu_get_buf(dfu);
                if (dfu->i_buf_start == NULL)
                        return -ENOMEM;
-               dfu->i_buf_end = dfu_get_buf() + dfu_buf_size;
+               dfu->i_buf_end = dfu_get_buf(dfu) + dfu_buf_size;
                dfu->i_buf = dfu->i_buf_start;
 
                dfu->inited = 1;
@@ -202,6 +208,7 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
        if (dfu->i_blk_seq_num != blk_seq_num) {
                printf("%s: Wrong sequence number! [%d] [%d]\n",
                       __func__, dfu->i_blk_seq_num, blk_seq_num);
+               dfu_write_transaction_cleanup(dfu);
                return -1;
        }
 
@@ -223,15 +230,18 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
 
        /* flush buffer if overflow */
        if ((dfu->i_buf + size) > dfu->i_buf_end) {
-               tret = dfu_write_buffer_drain(dfu);
-               if (ret == 0)
-                       ret = tret;
+               ret = dfu_write_buffer_drain(dfu);
+               if (ret) {
+                       dfu_write_transaction_cleanup(dfu);
+                       return ret;
+               }
        }
 
        /* we should be in buffer now (if not then size too large) */
        if ((dfu->i_buf + size) > dfu->i_buf_end) {
                error("Buffer overflow! (0x%p + 0x%x > 0x%p)\n", dfu->i_buf,
                      size, dfu->i_buf_end);
+               dfu_write_transaction_cleanup(dfu);
                return -1;
        }
 
@@ -240,12 +250,14 @@ int dfu_write(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
 
        /* if end or if buffer full flush */
        if (size == 0 || (dfu->i_buf + size) > dfu->i_buf_end) {
-               tret = dfu_write_buffer_drain(dfu);
-               if (ret == 0)
-                       ret = tret;
+               ret = dfu_write_buffer_drain(dfu);
+               if (ret) {
+                       dfu_write_transaction_cleanup(dfu);
+                       return ret;
+               }
        }
 
-       return ret;
+       return 0;
 }
 
 static int dfu_read_buffer_fill(struct dfu_entity *dfu, void *buf, int size)
@@ -267,7 +279,6 @@ static int dfu_read_buffer_fill(struct dfu_entity *dfu, void *buf, int size)
 
                        dfu->i_buf += chunk;
                        dfu->b_left -= chunk;
-                       dfu->r_left -= chunk;
                        size -= chunk;
                        buf += chunk;
                        readn += chunk;
@@ -309,14 +320,23 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
               __func__, dfu->name, buf, size, blk_seq_num, dfu->i_buf);
 
        if (!dfu->inited) {
-               dfu->i_buf_start = dfu_get_buf();
+               dfu->i_buf_start = dfu_get_buf(dfu);
                if (dfu->i_buf_start == NULL)
                        return -ENOMEM;
 
-               ret = dfu->read_medium(dfu, 0, dfu->i_buf_start, &dfu->r_left);
-               if (ret != 0) {
-                       debug("%s: failed to get r_left\n", __func__);
-                       return ret;
+               dfu->r_left = dfu->get_medium_size(dfu);
+               if (dfu->r_left < 0)
+                       return dfu->r_left;
+               switch (dfu->layout) {
+               case DFU_RAW_ADDR:
+               case DFU_RAM_ADDR:
+                       break;
+               default:
+                       if (dfu->r_left > dfu_buf_size) {
+                               printf("%s: File too big for buffer\n",
+                                      __func__);
+                               return -EOVERFLOW;
+                       }
                }
 
                debug("%s: %s %ld [B]\n", __func__, dfu->name, dfu->r_left);
@@ -324,9 +344,9 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
                dfu->i_blk_seq_num = 0;
                dfu->crc = 0;
                dfu->offset = 0;
-               dfu->i_buf_end = dfu_get_buf() + dfu_buf_size;
+               dfu->i_buf_end = dfu_get_buf(dfu) + dfu_buf_size;
                dfu->i_buf = dfu->i_buf_start;
-               dfu->b_left = min(dfu_buf_size, dfu->r_left);
+               dfu->b_left = 0;
 
                dfu->bad_skip = 0;
 
@@ -371,26 +391,30 @@ int dfu_read(struct dfu_entity *dfu, void *buf, int size, int blk_seq_num)
 }
 
 static int dfu_fill_entity(struct dfu_entity *dfu, char *s, int alt,
-                          char *interface, int num)
+                          char *interface, char *devstr)
 {
        char *st;
 
-       debug("%s: %s interface: %s num: %d\n", __func__, s, interface, num);
+       debug("%s: %s interface: %s dev: %s\n", __func__, s, interface, devstr);
        st = strsep(&s, " ");
        strcpy(dfu->name, st);
 
-       dfu->dev_num = num;
        dfu->alt = alt;
+       dfu->max_buf_size = 0;
+       dfu->free_entity = NULL;
 
        /* Specific for mmc device */
        if (strcmp(interface, "mmc") == 0) {
-               if (dfu_fill_entity_mmc(dfu, s))
+               if (dfu_fill_entity_mmc(dfu, devstr, s))
                        return -1;
        } else if (strcmp(interface, "nand") == 0) {
-               if (dfu_fill_entity_nand(dfu, s))
+               if (dfu_fill_entity_nand(dfu, devstr, s))
                        return -1;
        } else if (strcmp(interface, "ram") == 0) {
-               if (dfu_fill_entity_ram(dfu, s))
+               if (dfu_fill_entity_ram(dfu, devstr, s))
+                       return -1;
+       } else if (strcmp(interface, "sf") == 0) {
+               if (dfu_fill_entity_sf(dfu, devstr, s))
                        return -1;
        } else {
                printf("%s: Device %s not (yet) supported!\n",
@@ -407,6 +431,8 @@ void dfu_free_entities(void)
 
        list_for_each_entry_safe_reverse(dfu, p, &dfu_list, list) {
                list_del(&dfu->list);
+               if (dfu->free_entity)
+                       dfu->free_entity(dfu);
                t = dfu;
        }
        if (t)
@@ -416,7 +442,7 @@ void dfu_free_entities(void)
        alt_num_cnt = 0;
 }
 
-int dfu_config_entities(char *env, char *interface, int num)
+int dfu_config_entities(char *env, char *interface, char *devstr)
 {
        struct dfu_entity *dfu;
        int i, ret;
@@ -439,7 +465,8 @@ int dfu_config_entities(char *env, char *interface, int num)
        for (i = 0; i < dfu_alt_num; i++) {
 
                s = strsep(&env, ";");
-               ret = dfu_fill_entity(&dfu[i], s, alt_num_cnt, interface, num);
+               ret = dfu_fill_entity(&dfu[i], s, alt_num_cnt, interface,
+                                     devstr);
                if (ret)
                        return -1;
 
index 63cc876612c9aa44df4539e5e6c1a3b1d0af0b14..72fa03eedaecd3700fea7d4ed4e277fad2112ce5 100644 (file)
@@ -12,6 +12,8 @@
 #include <errno.h>
 #include <div64.h>
 #include <dfu.h>
+#include <ext4fs.h>
+#include <fat.h>
 #include <mmc.h>
 
 static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE)
@@ -25,7 +27,7 @@ static int mmc_access_part(struct dfu_entity *dfu, struct mmc *mmc, int part)
        if (part == mmc->part_num)
                return 0;
 
-       ret = mmc_switch_part(dfu->dev_num, part);
+       ret = mmc_switch_part(dfu->data.mmc.dev_num, part);
        if (ret) {
                error("Cannot switch to partition %d\n", part);
                return ret;
@@ -38,7 +40,7 @@ static int mmc_access_part(struct dfu_entity *dfu, struct mmc *mmc, int part)
 static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
                        u64 offset, void *buf, long *len)
 {
-       struct mmc *mmc = find_mmc_device(dfu->dev_num);
+       struct mmc *mmc = find_mmc_device(dfu->data.mmc.dev_num);
        u32 blk_start, blk_count, n = 0;
        int ret, part_num_bkp = 0;
 
@@ -65,15 +67,15 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
        }
 
        debug("%s: %s dev: %d start: %d cnt: %d buf: 0x%p\n", __func__,
-             op == DFU_OP_READ ? "MMC READ" : "MMC WRITE", dfu->dev_num,
-             blk_start, blk_count, buf);
+             op == DFU_OP_READ ? "MMC READ" : "MMC WRITE",
+             dfu->data.mmc.dev_num, blk_start, blk_count, buf);
        switch (op) {
        case DFU_OP_READ:
-               n = mmc->block_dev.block_read(dfu->dev_num, blk_start,
+               n = mmc->block_dev.block_read(dfu->data.mmc.dev_num, blk_start,
                                              blk_count, buf);
                break;
        case DFU_OP_WRITE:
-               n = mmc->block_dev.block_write(dfu->dev_num, blk_start,
+               n = mmc->block_dev.block_write(dfu->data.mmc.dev_num, blk_start,
                                               blk_count, buf);
                break;
        default:
@@ -113,22 +115,17 @@ static int mmc_file_buffer(struct dfu_entity *dfu, void *buf, long *len)
 static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu,
                        void *buf, long *len)
 {
+       const char *fsname, *opname;
        char cmd_buf[DFU_CMD_BUF_SIZE];
        char *str_env;
        int ret;
 
        switch (dfu->layout) {
        case DFU_FS_FAT:
-               sprintf(cmd_buf, "fat%s mmc %d:%d 0x%x %s",
-                       op == DFU_OP_READ ? "load" : "write",
-                       dfu->data.mmc.dev, dfu->data.mmc.part,
-                       (unsigned int) buf, dfu->name);
+               fsname = "fat";
                break;
        case DFU_FS_EXT4:
-               sprintf(cmd_buf, "ext4%s mmc %d:%d 0x%x /%s",
-                       op == DFU_OP_READ ? "load" : "write",
-                       dfu->data.mmc.dev, dfu->data.mmc.part,
-                       (unsigned int) buf, dfu->name);
+               fsname = "ext4";
                break;
        default:
                printf("%s: Layout (%s) not (yet) supported!\n", __func__,
@@ -136,6 +133,28 @@ static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu,
                return -1;
        }
 
+       switch (op) {
+       case DFU_OP_READ:
+               opname = "load";
+               break;
+       case DFU_OP_WRITE:
+               opname = "write";
+               break;
+       case DFU_OP_SIZE:
+               opname = "size";
+               break;
+       default:
+               return -1;
+       }
+
+       sprintf(cmd_buf, "%s%s mmc %d:%d", fsname, opname,
+               dfu->data.mmc.dev, dfu->data.mmc.part);
+
+       if (op != DFU_OP_SIZE)
+               sprintf(cmd_buf + strlen(cmd_buf), " 0x%x", (unsigned int)buf);
+
+       sprintf(cmd_buf + strlen(cmd_buf), " %s", dfu->name);
+
        if (op == DFU_OP_WRITE)
                sprintf(cmd_buf + strlen(cmd_buf), " %lx", *len);
 
@@ -147,7 +166,7 @@ static int mmc_file_op(enum dfu_op op, struct dfu_entity *dfu,
                return ret;
        }
 
-       if (dfu->layout != DFU_RAW_ADDR && op == DFU_OP_READ) {
+       if (op != DFU_OP_WRITE) {
                str_env = getenv("filesize");
                if (str_env == NULL) {
                        puts("dfu: Wrong file size!\n");
@@ -196,6 +215,27 @@ int dfu_flush_medium_mmc(struct dfu_entity *dfu)
        return ret;
 }
 
+long dfu_get_medium_size_mmc(struct dfu_entity *dfu)
+{
+       int ret;
+       long len;
+
+       switch (dfu->layout) {
+       case DFU_RAW_ADDR:
+               return dfu->data.mmc.lba_size * dfu->data.mmc.lba_blk_size;
+       case DFU_FS_FAT:
+       case DFU_FS_EXT4:
+               ret = mmc_file_op(DFU_OP_SIZE, dfu, NULL, &len);
+               if (ret < 0)
+                       return ret;
+               return len;
+       default:
+               printf("%s: Layout (%s) not (yet) supported!\n", __func__,
+                      dfu_get_layout(dfu->layout));
+               return -1;
+       }
+}
+
 int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf,
                long *len)
 {
@@ -230,7 +270,7 @@ int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf,
  *     4th (optional):
  *             mmcpart <num> (access to HW eMMC partitions)
  */
-int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
+int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s)
 {
        const char *entity_type;
        size_t second_arg;
@@ -241,6 +281,8 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
        const char *argv[3];
        const char **parg = argv;
 
+       dfu->data.mmc.dev_num = simple_strtoul(devstr, NULL, 10);
+
        for (; parg < argv + sizeof(argv) / sizeof(*argv); ++parg) {
                *parg = strsep(&s, " ");
                if (*parg == NULL) {
@@ -257,9 +299,10 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
        second_arg = simple_strtoul(argv[1], NULL, 0);
        third_arg = simple_strtoul(argv[2], NULL, 0);
 
-       mmc = find_mmc_device(dfu->dev_num);
+       mmc = find_mmc_device(dfu->data.mmc.dev_num);
        if (mmc == NULL) {
-               error("Couldn't find MMC device no. %d.\n", dfu->dev_num);
+               error("Couldn't find MMC device no. %d.\n",
+                     dfu->data.mmc.dev_num);
                return -ENODEV;
        }
 
@@ -316,6 +359,7 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
        }
 
        dfu->dev_type = DFU_DEV_MMC;
+       dfu->get_medium_size = dfu_get_medium_size_mmc;
        dfu->read_medium = dfu_read_medium_mmc;
        dfu->write_medium = dfu_write_medium_mmc;
        dfu->flush_medium = dfu_flush_medium_mmc;
index ccdbef6b75f26fe78fe5fc52438d797bad5b3b46..f9ee18999ab76974e06afcc46f84a149ac56c768 100644 (file)
@@ -114,6 +114,11 @@ static int dfu_write_medium_nand(struct dfu_entity *dfu,
        return ret;
 }
 
+long dfu_get_medium_size_nand(struct dfu_entity *dfu)
+{
+       return dfu->data.nand.size;
+}
+
 static int dfu_read_medium_nand(struct dfu_entity *dfu, u64 offset, void *buf,
                long *len)
 {
@@ -121,7 +126,6 @@ static int dfu_read_medium_nand(struct dfu_entity *dfu, u64 offset, void *buf,
 
        switch (dfu->layout) {
        case DFU_RAW_ADDR:
-               *len = dfu->data.nand.size;
                ret = nand_block_read(dfu, offset, buf, len);
                break;
        default:
@@ -175,7 +179,7 @@ unsigned int dfu_polltimeout_nand(struct dfu_entity *dfu)
        return DFU_DEFAULT_POLL_TIMEOUT;
 }
 
-int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
+int dfu_fill_entity_nand(struct dfu_entity *dfu, char *devstr, char *s)
 {
        char *st;
        int ret, dev, part;
@@ -220,6 +224,7 @@ int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
                return -1;
        }
 
+       dfu->get_medium_size = dfu_get_medium_size_nand;
        dfu->read_medium = dfu_read_medium_nand;
        dfu->write_medium = dfu_write_medium_nand;
        dfu->flush_medium = dfu_flush_medium_nand;
index 335a8e1f2491cd9dc477885f83a76677a1725407..e094a946f6be708dfc31a23fdaf48bc7d13f7b9b 100644 (file)
@@ -41,18 +41,18 @@ static int dfu_write_medium_ram(struct dfu_entity *dfu, u64 offset,
        return dfu_transfer_medium_ram(DFU_OP_WRITE, dfu, offset, buf, len);
 }
 
+long dfu_get_medium_size_ram(struct dfu_entity *dfu)
+{
+       return dfu->data.ram.size;
+}
+
 static int dfu_read_medium_ram(struct dfu_entity *dfu, u64 offset,
                               void *buf, long *len)
 {
-       if (!*len) {
-               *len = dfu->data.ram.size;
-               return 0;
-       }
-
        return dfu_transfer_medium_ram(DFU_OP_READ, dfu, offset, buf, len);
 }
 
-int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s)
+int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr, char *s)
 {
        char *st;
 
@@ -69,6 +69,7 @@ int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s)
        dfu->data.ram.size = simple_strtoul(s, &s, 16);
 
        dfu->write_medium = dfu_write_medium_ram;
+       dfu->get_medium_size = dfu_get_medium_size_ram;
        dfu->read_medium = dfu_read_medium_ram;
 
        dfu->inited = 0;
diff --git a/drivers/dfu/dfu_sf.c b/drivers/dfu/dfu_sf.c
new file mode 100644 (file)
index 0000000..91f6df2
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <errno.h>
+#include <div64.h>
+#include <dfu.h>
+#include <spi_flash.h>
+
+static long dfu_get_medium_size_sf(struct dfu_entity *dfu)
+{
+       return dfu->data.sf.size;
+}
+
+static int dfu_read_medium_sf(struct dfu_entity *dfu, u64 offset, void *buf,
+               long *len)
+{
+       return spi_flash_read(dfu->data.sf.dev, offset, *len, buf);
+}
+
+static int dfu_write_medium_sf(struct dfu_entity *dfu,
+               u64 offset, void *buf, long *len)
+{
+       int ret;
+
+       ret = spi_flash_erase(dfu->data.sf.dev, offset, *len);
+       if (ret)
+               return ret;
+
+       ret = spi_flash_write(dfu->data.sf.dev, offset, *len, buf);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int dfu_flush_medium_sf(struct dfu_entity *dfu)
+{
+       return 0;
+}
+
+static unsigned int dfu_polltimeout_sf(struct dfu_entity *dfu)
+{
+       return DFU_DEFAULT_POLL_TIMEOUT;
+}
+
+static void dfu_free_entity_sf(struct dfu_entity *dfu)
+{
+       spi_flash_free(dfu->data.sf.dev);
+}
+
+static struct spi_flash *parse_dev(char *devstr)
+{
+       unsigned int bus;
+       unsigned int cs;
+       unsigned int speed = CONFIG_SF_DEFAULT_SPEED;
+       unsigned int mode = CONFIG_SF_DEFAULT_MODE;
+       char *s, *endp;
+       struct spi_flash *dev;
+
+       s = strsep(&devstr, ":");
+       if (!s || !*s || (bus = simple_strtoul(s, &endp, 0), *endp)) {
+               printf("Invalid SPI bus %s\n", s);
+               return NULL;
+       }
+
+       s = strsep(&devstr, ":");
+       if (!s || !*s || (cs = simple_strtoul(s, &endp, 0), *endp)) {
+               printf("Invalid SPI chip-select %s\n", s);
+               return NULL;
+       }
+
+       s = strsep(&devstr, ":");
+       if (s && *s) {
+               speed = simple_strtoul(s, &endp, 0);
+               if (*endp || !speed) {
+                       printf("Invalid SPI speed %s\n", s);
+                       return NULL;
+               }
+       }
+
+       s = strsep(&devstr, ":");
+       if (s && *s) {
+               mode = simple_strtoul(s, &endp, 0);
+               if (*endp || mode > 3) {
+                       printf("Invalid SPI mode %s\n", s);
+                       return NULL;
+               }
+       }
+
+       dev = spi_flash_probe(bus, cs, speed, mode);
+       if (!dev) {
+               printf("Failed to create SPI flash at %d:%d:%d:%d\n",
+                      bus, cs, speed, mode);
+               return NULL;
+       }
+
+       return dev;
+}
+
+int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, char *s)
+{
+       char *st;
+
+       dfu->data.sf.dev = parse_dev(devstr);
+       if (!dfu->data.sf.dev)
+               return -ENODEV;
+
+       dfu->dev_type = DFU_DEV_SF;
+       dfu->max_buf_size = dfu->data.sf.dev->sector_size;
+
+       st = strsep(&s, " ");
+       if (!strcmp(st, "raw")) {
+               dfu->layout = DFU_RAW_ADDR;
+               dfu->data.sf.start = simple_strtoul(s, &s, 16);
+               s++;
+               dfu->data.sf.size = simple_strtoul(s, &s, 16);
+       } else {
+               printf("%s: Memory layout (%s) not supported!\n", __func__, st);
+               spi_flash_free(dfu->data.sf.dev);
+               return -1;
+       }
+
+       dfu->get_medium_size = dfu_get_medium_size_sf;
+       dfu->read_medium = dfu_read_medium_sf;
+       dfu->write_medium = dfu_write_medium_sf;
+       dfu->flush_medium = dfu_flush_medium_sf;
+       dfu->poll_timeout = dfu_polltimeout_sf;
+       dfu->free_entity = dfu_free_entity_sf;
+
+       /* initial state */
+       dfu->inited = 0;
+
+       return 0;
+}
index 8b2821b762415dfc62f20ff1557efb936f641f18..a79c3919ddc7d452a41ca8bc8676b2c97c88ad54 100644 (file)
@@ -8,4 +8,3 @@
 obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
 obj-$(CONFIG_APBH_DMA) += apbh_dma.o
 obj-$(CONFIG_FSL_DMA) += fsl_dma.o
-obj-$(CONFIG_OMAP3_DMA) += omap3_dma.o
diff --git a/drivers/dma/omap3_dma.c b/drivers/dma/omap3_dma.c
deleted file mode 100644 (file)
index 3320b3d..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/* Copyright (C) 2011
- * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-/* This is a basic implementation of the SDMA/DMA4 controller of OMAP3
- * Tested on Silicon Revision major:0x4 minor:0x0
- */
-
-#include <common.h>
-#include <asm/arch/cpu.h>
-#include <asm/arch/omap3.h>
-#include <asm/arch/dma.h>
-#include <asm/io.h>
-#include <asm/errno.h>
-
-static struct dma4 *dma4_cfg = (struct dma4 *)OMAP34XX_DMA4_BASE;
-uint32_t dma_active; /* if a transfer is started the respective
-       bit is set for the logical channel */
-
-/* Check if we have the given channel
- * PARAMETERS:
- * chan: Channel number
- *
- * RETURN of non-zero means error */
-static inline int check_channel(uint32_t chan)
-{
-       if (chan < CHAN_NR_MIN || chan > CHAN_NR_MAX)
-               return -EINVAL;
-       return 0;
-}
-
-static inline void reset_irq(uint32_t chan)
-{
-       /* reset IRQ reason */
-       writel(0x1DFE, &dma4_cfg->chan[chan].csr);
-       /* reset IRQ */
-       writel((1 << chan), &dma4_cfg->irqstatus_l[0]);
-       dma_active &= ~(1 << chan);
-}
-
-/* Set Source, Destination and Size of DMA transfer for the
- * specified channel.
- * PARAMETERS:
- * chan: channel to use
- * src: source of the transfer
- * dst: destination of the transfer
- * sze: Size of the transfer
- *
- * RETURN of non-zero means error */
-int omap3_dma_conf_transfer(uint32_t chan, uint32_t *src, uint32_t *dst,
-               uint32_t sze)
-{
-       if (check_channel(chan))
-               return -EINVAL;
-       /* CDSA0 */
-       writel((uint32_t)src, &dma4_cfg->chan[chan].cssa);
-       writel((uint32_t)dst, &dma4_cfg->chan[chan].cdsa);
-       writel(sze, &dma4_cfg->chan[chan].cen);
-return 0;
-}
-
-/* Start the DMA transfer */
-int omap3_dma_start_transfer(uint32_t chan)
-{
-       uint32_t val;
-
-       if (check_channel(chan))
-               return -EINVAL;
-
-       val = readl(&dma4_cfg->chan[chan].ccr);
-       /* Test for channel already in use */
-       if (val & CCR_ENABLE_ENABLE)
-               return -EBUSY;
-
-       writel((val | CCR_ENABLE_ENABLE), &dma4_cfg->chan[chan].ccr);
-       dma_active |= (1 << chan);
-       debug("started transfer...\n");
-       return 0;
-}
-
-/* Busy-waiting for a DMA transfer
- * This has to be called before another transfer is started
- * PARAMETER
- * chan: Channel to wait for
- *
- * RETURN of non-zero means error*/
-int omap3_dma_wait_for_transfer(uint32_t chan)
-{
-       uint32_t val;
-
-       if (!(dma_active & (1 << chan))) {
-               val = readl(&dma4_cfg->irqstatus_l[0]);
-               if (!(val & chan)) {
-                       debug("dma: The channel you are trying to wait for "
-                               "was never activated - ERROR\n");
-                       return -1; /* channel was never active */
-               }
-       }
-
-       /* all irqs on line 0 */
-       while (!(readl(&dma4_cfg->irqstatus_l[0]) & (1 << chan)))
-               asm("nop");
-
-       val = readl(&dma4_cfg->chan[chan].csr);
-       if ((val & CSR_TRANS_ERR) | (val & CSR_SUPERVISOR_ERR) |
-                       (val & CSR_MISALIGNED_ADRS_ERR)) {
-               debug("err code: %X\n", val);
-               debug("dma: transfer error detected\n");
-               reset_irq(chan);
-               return -1;
-       }
-       reset_irq(chan);
-       return 0;
-}
-
-/* Get the revision of the DMA module
- * PARAMETER
- * minor: Address of minor revision to write
- * major: Address of major revision to write
- *
- * RETURN of non-zero means error
- */
-int omap3_dma_get_revision(uint32_t *minor, uint32_t *major)
-{
-       uint32_t val;
-
-       /* debug information */
-       val = readl(&dma4_cfg->revision);
-       *major = (val & 0x000000F0) >> 4;
-       *minor = (val & 0x0000000F);
-       debug("DMA Silicon revision (maj/min): 0x%X/0x%X\n", *major, *minor);
-       return 0;
-}
-
-/* Initial config of omap dma
- */
-void omap3_dma_init(void)
-{
-       dma_active = 0;
-       /* All interrupts on channel 0 */
-       writel(0xFFFFFFFF, &dma4_cfg->irqenable_l[0]);
-}
-
-/* set channel config to config
- *
- * RETURN of non-zero means error */
-int omap3_dma_conf_chan(uint32_t chan, struct dma4_chan *config)
-{
-       if (check_channel(chan))
-               return -EINVAL;
-
-       dma4_cfg->chan[chan] = *config;
-       return 0;
-}
-
-/* get channel config to config
- *
- * RETURN of non-zero means error */
-int omap3_dma_get_conf_chan(uint32_t chan, struct dma4_chan *config)
-{
-       if (check_channel(chan))
-               return -EINVAL;
-       *config = dma4_cfg->chan[chan];
-       return 0;
-}
index c58fe50b7206e8d6fd5e78e9dfaf8f510306d85f..2b29cd89f84d179c08de40620eccdd01d94bb250 100644 (file)
@@ -126,7 +126,6 @@ static int cis8204_config(struct phy_device *phydev)
        genphy_config_aneg(phydev);
 
        if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
-                       (phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
                        (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
                        (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID))
                phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON,
index 8e7052dda72046308a55783c84e52c342876c78c..079f67d3801b0c3297076beb62f7d8c02565323e 100644 (file)
@@ -81,7 +81,7 @@ void NS16550_init(NS16550_t com_port, int baud_divisor)
        serial_out(baud_divisor & 0xff, &com_port->dll);
        serial_out((baud_divisor >> 8) & 0xff, &com_port->dlm);
        serial_out(UART_LCRVAL, &com_port->lcr);
-#if (defined(CONFIG_OMAP) && !defined(CONFIG_OMAP3_ZOOM2)) || \
+#if defined(CONFIG_OMAP) || \
        defined(CONFIG_AM33XX) || defined(CONFIG_SOC_DA8XX) || \
        defined(CONFIG_TI81XX) || defined(CONFIG_AM43XX)
 
index 4413e6911872b38c403baca8c8662205b2b9eef0..dafeed742df49e7d56bf2774314ea535c228be22 100644 (file)
@@ -122,15 +122,6 @@ static int calc_divisor (NS16550_t port)
 {
        const unsigned int mode_x_div = 16;
 
-#ifdef CONFIG_OMAP1510
-       /* If can't cleanly clock 115200 set div to 1 */
-       if ((CONFIG_SYS_NS16550_CLK == 12000000) && (gd->baudrate == 115200)) {
-               port->osc_12m_sel = OSC_12M_SEL;        /* enable 6.5 * divisor */
-               return (1);                             /* return 1 for base divisor */
-       }
-       port->osc_12m_sel = 0;                  /* clear if previsouly set */
-#endif
-
        return DIV_ROUND_CLOSEST(CONFIG_SYS_NS16550_CLK,
                                                mode_x_div * gd->baudrate);
 }
index 0826d59ab2adbba604665b520278898130e9fa59..144a925394513d38b1677030cb97fcc5f96d84cb 100644 (file)
@@ -49,9 +49,15 @@ static struct uart_port sh_sci = {
 static void sh_serial_setbrg(void)
 {
        DECLARE_GLOBAL_DATA_PTR;
-
+#ifdef CONFIG_SCIF_USE_EXT_CLK
+       unsigned short dl = DL_VALUE(gd->baudrate, CONFIG_SH_SCIF_CLK_FREQ);
+       sci_out(&sh_sci, DL, dl);
+       /* Need wait: Clock * 1/dl \e$B!_\e(B 1/16 */
+       udelay((1000000 * dl * 16 / CONFIG_SYS_CLK_FREQ) * 1000 + 1);
+#else
        sci_out(&sh_sci, SCBRR,
                SCBRR_VALUE(gd->baudrate, CONFIG_SH_SCIF_CLK_FREQ));
+#endif
 }
 
 static int sh_serial_init(void)
index 341997c8ecbb1e4a129aa96d78b7dea8cd4a6f19..fe8cde4dedb5ffe3ea9c33779841038cbc9e90d6 100644 (file)
@@ -588,7 +588,8 @@ SCIF_FNS(SCSPTR,                        0,  0, 0, 0)
 #else
 SCIF_FNS(SCSPTR,                        0,  0, 0x20, 16)
 #endif
-#if defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791)
+#if defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) || \
+       defined(CONFIG_R8A7794)
 SCIF_FNS(DL,                           0,  0, 0x30, 16)
 SCIF_FNS(CKS,                          0,  0, 0x34, 16)
 #endif
@@ -734,8 +735,8 @@ static inline int scbrr_calc(struct uart_port port, int bps, int clk)
 #elif defined(__H8300H__) || defined(__H8300S__)
 #define SCBRR_VALUE(bps, clk) (((clk*1000/32)/bps)-1)
 #elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791)
-#define SCBRR DL
-#define SCBRR_VALUE(bps, clk) (clk / bps / 16)
+#define DL_VALUE(bps, clk) (clk / bps / 16) /* External Clock */
+#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1) /* Internal Clock */
 #else /* Generic SH */
 #define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1)
 #endif
index 21a3ef4d97ea94d2a167490d9389bfb7f8dd0f8c..538b6d715d42662c88a8726705f655889d819358 100644 (file)
@@ -14,8 +14,6 @@
 #include <usbdevice.h>
 #if defined(CONFIG_PPC)
 #include <usb/mpc8xx_udc.h>
-#elif defined(CONFIG_OMAP1510)
-#include <usb/omap1510_udc.h>
 #elif defined(CONFIG_CPU_PXA27X)
 #include <usb/pxa27x_udc.h>
 #elif defined(CONFIG_DW_UDC)
index 66becdc78226a942ccc1a621787e1ef2c0888fc7..4eea907d2eb6a6aabbe488496d22ef75d02284e1 100644 (file)
@@ -31,7 +31,6 @@ ifdef CONFIG_USB_DEVICE
 obj-y += core.o
 obj-y += ep0.o
 obj-$(CONFIG_DW_UDC) += designware_udc.o
-obj-$(CONFIG_OMAP1510) += omap1510_udc.o
 obj-$(CONFIG_OMAP1610) += omap1510_udc.o
 obj-$(CONFIG_MPC885_FAMILY) += mpc8xx_udc.o
 obj-$(CONFIG_CPU_PXA27X) += pxa27x_udc.o
index 859fe828de74c612cac582ae761b2e5e9a4804e4..9863dec44d993770c2f69963ca7197efa9dfb78c 100644 (file)
@@ -162,17 +162,27 @@ static void dfu_set_poll_timeout(struct dfu_status *dstat, unsigned int ms)
 static void dnload_request_complete(struct usb_ep *ep, struct usb_request *req)
 {
        struct f_dfu *f_dfu = req->context;
+       int ret;
 
-       dfu_write(dfu_get_entity(f_dfu->altsetting), req->buf,
-                 req->length, f_dfu->blk_seq_num);
+       ret = dfu_write(dfu_get_entity(f_dfu->altsetting), req->buf,
+                       req->length, f_dfu->blk_seq_num);
+       if (ret) {
+               f_dfu->dfu_status = DFU_STATUS_errUNKNOWN;
+               f_dfu->dfu_state = DFU_STATE_dfuERROR;
+       }
 }
 
 static void dnload_request_flush(struct usb_ep *ep, struct usb_request *req)
 {
        struct f_dfu *f_dfu = req->context;
+       int ret;
 
-       dfu_flush(dfu_get_entity(f_dfu->altsetting), req->buf,
-                 req->length, f_dfu->blk_seq_num);
+       ret = dfu_flush(dfu_get_entity(f_dfu->altsetting), req->buf,
+                       req->length, f_dfu->blk_seq_num);
+       if (ret) {
+               f_dfu->dfu_status = DFU_STATUS_errUNKNOWN;
+               f_dfu->dfu_state = DFU_STATE_dfuERROR;
+       }
 }
 
 static inline int dfu_get_manifest_timeout(struct dfu_entity *dfu)
@@ -770,6 +780,8 @@ static int dfu_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
        debug("%s: intf:%d alt:%d\n", __func__, intf, alt);
 
        f_dfu->altsetting = alt;
+       f_dfu->dfu_state = DFU_STATE_dfuIDLE;
+       f_dfu->dfu_status = DFU_STATUS_OK;
 
        return 0;
 }
index 4e06273f7fb7e678b96a6bb3e11d6b8d6a4830a5..c85b0fbd3ca5102d14c5d660a3733b7099ea8f61 100644 (file)
@@ -142,7 +142,8 @@ static long long int download_head(unsigned long long total,
                                   int *cnt)
 {
        long long int rcv_cnt = 0, left_to_rcv, ret_rcv;
-       void *transfer_buffer = dfu_get_buf();
+       struct dfu_entity *dfu_entity = dfu_get_entity(alt_setting_num);
+       void *transfer_buffer = dfu_get_buf(dfu_entity);
        void *buf = transfer_buffer;
        int usb_pkt_cnt = 0, ret;
 
@@ -205,7 +206,7 @@ static long long int download_head(unsigned long long total,
 static int download_tail(long long int left, int cnt)
 {
        struct dfu_entity *dfu_entity = dfu_get_entity(alt_setting_num);
-       void *transfer_buffer = dfu_get_buf();
+       void *transfer_buffer = dfu_get_buf(dfu_entity);
        int ret;
 
        debug("%s: left: %llu cnt: %d\n", __func__, left, cnt);
index bdc1b886f5f589cd06fa89d756dcddde1bc2b60e..959df8cdcdf7473e370d39187beefde8494219b0 100644 (file)
@@ -15,9 +15,6 @@
 
 #include <common.h>
 #include <asm/io.h>
-#ifdef CONFIG_OMAP_SX1
-#include <i2c.h>
-#endif
 #include <usbdevice.h>
 #include <usb/omap1510_udc.h>
 #include <usb/udc.h>
@@ -1097,20 +1094,6 @@ int udc_init (void)
        outw ((1 << 4) | (1 << 5), CLOCK_CTRL);
        UDCREG (CLOCK_CTRL);
 
-#ifdef CONFIG_OMAP1510
-       /* This code was originally implemented for OMAP1510 and
-        * therefore is only applicable for OMAP1510 boards. For
-        * OMAP5912 or OMAP16xx the register APLL_CTRL does not
-        * exist and DPLL_CTRL is already configured.
-        */
-
-       /* Set and check APLL */
-       outw (0x0008, APLL_CTRL);
-       UDCREG (APLL_CTRL);
-       /* Set and check DPLL */
-       outw (0x2210, DPLL_CTRL);
-       UDCREG (DPLL_CTRL);
-#endif
        /* Set and check SOFT
         * The below line of code has been changed to perform a
         * read-modify-write instead of a simple write for
@@ -1124,44 +1107,12 @@ int udc_init (void)
 
        /* Print banner with device revision */
        udc_rev = inw (UDC_REV) & 0xff;
-#ifdef CONFIG_OMAP1510
-       printf ("USB:   TI OMAP1510 USB function module rev %d.%d\n",
-               udc_rev >> 4, udc_rev & 0xf);
-#endif
 
 #ifdef CONFIG_OMAP1610
        printf ("USB:   TI OMAP5912 USB function module rev %d.%d\n",
                udc_rev >> 4, udc_rev & 0xf);
 #endif
 
-#ifdef CONFIG_OMAP_SX1
-       i2c_read (0x32, 0x04, 1, &value, 1);
-       value |= 0x04;
-       i2c_write (0x32, 0x04, 1, &value, 1);
-
-       i2c_read (0x32, 0x03, 1, &value, 1);
-       value |= 0x01;
-       i2c_write (0x32, 0x03, 1, &value, 1);
-
-       gpio = inl(GPIO_PIN_CONTROL_REG);
-       gpio |=  0x0002; /* A_IRDA_OFF */
-       gpio |=  0x0800; /* A_SWITCH   */
-       gpio |=  0x8000; /* A_USB_ON   */
-       outl (gpio, GPIO_PIN_CONTROL_REG);
-
-       gpio = inl(GPIO_DIR_CONTROL_REG);
-       gpio &= ~0x0002; /* A_IRDA_OFF */
-       gpio &= ~0x0800; /* A_SWITCH   */
-       gpio &= ~0x8000; /* A_USB_ON   */
-       outl (gpio, GPIO_DIR_CONTROL_REG);
-
-       gpio = inl(GPIO_DATA_OUTPUT_REG);
-       gpio |=  0x0002; /* A_IRDA_OFF */
-       gpio &= ~0x0800; /* A_SWITCH   */
-       gpio &= ~0x8000; /* A_USB_ON   */
-       outl (gpio, GPIO_DATA_OUTPUT_REG);
-#endif
-
        /* The VBUS_MODE bit selects whether VBUS detection is done via
         * software (1) or hardware (0).  When software detection is
         * selected, VBUS_CTRL selects whether USB is not connected (0)
index 049e4c4e6b01bd08dd46ffc1427dc6a6fe0c45a5..0d1a726d35ff6e4df02c44791c66257bd089b6db 100644 (file)
@@ -21,13 +21,16 @@ static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = {
        0xEE080000,     /* USB0 (EHCI) */
        0xEE0A0000,     /* USB1 */
        0xEE0C0000,     /* USB2 */
-       0xEE000000      /* USB3 (USB3.0 Host)*/
 };
 #elif defined(CONFIG_R8A7791)
 static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = {
        0xEE080000,     /* USB0 (EHCI) */
        0xEE0C0000,     /* USB1 */
-       0xEE000000      /* USB3 (USB3.0 Host)*/
+};
+#elif defined(CONFIG_R8A7794)
+static u32 usb_base_address[CONFIG_USB_MAX_CONTROLLER_COUNT] = {
+       0xEE080000,     /* USB0 (EHCI) */
+       0xEE0C0000,     /* USB1 */
 };
 #else
 #error rmobile EHCI USB driver not supported on this platform
index 945f35dc5d3e7692836516a81ab5510739c03b20..93a91c3fa61d126e3814012d68d6904d050ae1dc 100644 (file)
@@ -41,3 +41,4 @@ obj-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o
 obj-$(CONFIG_VIDEO_TEGRA) += tegra.o
 obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
 obj-$(CONFIG_FORMIKE) += formike.o
+obj-$(CONFIG_AM335X_LCD) += am335x-fb.o
diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c
new file mode 100644 (file)
index 0000000..ab98941
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2013 Hannes Petermaier <oe5hpm@oevsv.at>
+ * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
+ *
+ * minimal framebuffer driver for TI's AM335x SoC to be compatible with
+ * Wolfgang Denk's LCD-Framework (CONFIG_LCD, common/lcd.c)
+ *
+ * - supporting only 24bit RGB/TFT raster Mode (not using palette)
+ * - sets up LCD controller as in 'am335x_lcdpanel' struct given
+ * - starts output DMA from gd->fb_base buffer
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <asm/arch/hardware.h>
+#include <lcd.h>
+#include "am335x-fb.h"
+
+#if !defined(LCD_CNTL_BASE)
+#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!"
+#endif
+
+
+/* LCD Control Register */
+#define LCD_CLK_DIVISOR(x)                     ((x) << 8)
+#define LCD_RASTER_MODE                                0x01
+/* LCD Clock Enable Register */
+#define LCD_CORECLKEN                          (0x01 << 0)
+#define LCD_LIDDCLKEN                          (0x01 << 1)
+#define LCD_DMACLKEN                           (0x01 << 2)
+/* LCD DMA Control Register */
+#define LCD_DMA_BURST_SIZE(x)                  ((x) << 4)
+#define LCD_DMA_BURST_1                                0x0
+#define LCD_DMA_BURST_2                                0x1
+#define LCD_DMA_BURST_4                                0x2
+#define LCD_DMA_BURST_8                                0x3
+#define LCD_DMA_BURST_16                       0x4
+/* LCD Timing_0 Register */
+#define LCD_HBPLSB(x)                          ((((x)-1) & 0xFF) << 24)
+#define LCD_HFPLSB(x)                          ((((x)-1) & 0xFF) << 16)
+#define LCD_HSWLSB(x)                          ((((x)-1) & 0x3F) << 10)
+#define LCD_HORLSB(x)                          (((((x) >> 4)-1) & 0x3F) << 4)
+#define LCD_HORMSB(x)                          (((((x) >> 4)-1) & 0x40) >> 4)
+/* LCD Timing_1 Register */
+#define LCD_VBP(x)                             ((x) << 24)
+#define LCD_VFP(x)                             ((x) << 16)
+#define LCD_VSW(x)                             (((x)-1) << 10)
+#define LCD_VERLSB(x)                          (((x)-1) & 0x3FF)
+/* LCD Timing_2 Register */
+#define LCD_HSWMSB(x)                          ((((x)-1) & 0x3C0) << 21)
+#define LCD_VERMSB(x)                          ((((x)-1) & 0x400) << 16)
+#define LCD_HBPMSB(x)                          ((((x)-1) & 0x300) >> 4)
+#define LCD_HFPMSB(x)                          ((((x)-1) & 0x300) >> 8)
+#define LCD_INVMASK(x)                         ((x) & 0x3F00000)
+/* LCD Raster Ctrl Register */
+#define LCD_TFT_24BPP_MODE                     (1 << 25)
+#define LCD_TFT_24BPP_UNPACK                   (1 << 26)
+#define LCD_PALMODE_RAWDATA                    (0x10 << 20)
+#define LCD_TFT_MODE                           (0x01 << 7)
+#define LCD_RASTER_ENABLE                      (0x01 << 0)
+
+
+/* Macro definitions */
+#define FBSIZE(x)      ((x->hactive * x->vactive * x->bpp) >> 3)
+
+struct am335x_lcdhw {
+       unsigned int            pid;                    /* 0x00 */
+       unsigned int            ctrl;                   /* 0x04 */
+       unsigned int            gap0;                   /* 0x08 */
+       unsigned int            lidd_ctrl;              /* 0x0C */
+       unsigned int            lidd_cs0_conf;          /* 0x10 */
+       unsigned int            lidd_cs0_addr;          /* 0x14 */
+       unsigned int            lidd_cs0_data;          /* 0x18 */
+       unsigned int            lidd_cs1_conf;          /* 0x1C */
+       unsigned int            lidd_cs1_addr;          /* 0x20 */
+       unsigned int            lidd_cs1_data;          /* 0x24 */
+       unsigned int            raster_ctrl;            /* 0x28 */
+       unsigned int            raster_timing0;         /* 0x2C */
+       unsigned int            raster_timing1;         /* 0x30 */
+       unsigned int            raster_timing2;         /* 0x34 */
+       unsigned int            raster_subpanel;        /* 0x38 */
+       unsigned int            raster_subpanel2;       /* 0x3C */
+       unsigned int            lcddma_ctrl;            /* 0x40 */
+       unsigned int            lcddma_fb0_base;        /* 0x44 */
+       unsigned int            lcddma_fb0_ceiling;     /* 0x48 */
+       unsigned int            lcddma_fb1_base;        /* 0x4C */
+       unsigned int            lcddma_fb1_ceiling;     /* 0x50 */
+       unsigned int            sysconfig;              /* 0x54 */
+       unsigned int            irqstatus_raw;          /* 0x58 */
+       unsigned int            irqstatus;              /* 0x5C */
+       unsigned int            irqenable_set;          /* 0x60 */
+       unsigned int            irqenable_clear;        /* 0x64 */
+       unsigned int            gap1;                   /* 0x68 */
+       unsigned int            clkc_enable;            /* 0x6C */
+       unsigned int            clkc_reset;             /* 0x70 */
+};
+
+static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE;
+DECLARE_GLOBAL_DATA_PTR;
+
+int lcd_get_size(int *line_length)
+{
+       *line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
+       return *line_length * panel_info.vl_row + 0x20;
+}
+
+int am335xfb_init(struct am335x_lcdpanel *panel)
+{
+       if (0 == gd->fb_base) {
+               printf("ERROR: no valid fb_base stored in GLOBAL_DATA_PTR!\n");
+               return -1;
+       }
+       if (0 == panel) {
+               printf("ERROR: missing ptr to am335x_lcdpanel!\n");
+               return -1;
+       }
+
+       debug("setting up LCD-Controller for %dx%dx%d (hfp=%d,hbp=%d,hsw=%d / ",
+             panel->hactive, panel->vactive, panel->bpp,
+             panel->hfp, panel->hbp, panel->hsw);
+       debug("vfp=%d,vbp=%d,vsw=%d / clk-div=%d)\n",
+             panel->vfp, panel->vfp, panel->vsw, panel->pxl_clk_div);
+       debug("using frambuffer at 0x%08x with size %d.\n",
+             (unsigned int)gd->fb_base, FBSIZE(panel));
+
+       /* palette default entry */
+       memset((void *)gd->fb_base, 0, 0x20);
+       *(unsigned int *)gd->fb_base = 0x4000;
+
+       lcdhw->clkc_enable = LCD_CORECLKEN | LCD_LIDDCLKEN | LCD_DMACLKEN;
+       lcdhw->raster_ctrl = 0;
+       lcdhw->ctrl = LCD_CLK_DIVISOR(panel->pxl_clk_div) | LCD_RASTER_MODE;
+       lcdhw->lcddma_fb0_base = gd->fb_base;
+       lcdhw->lcddma_fb0_ceiling = gd->fb_base + FBSIZE(panel) + 0x20;
+       lcdhw->lcddma_fb1_base = gd->fb_base;
+       lcdhw->lcddma_fb1_ceiling = gd->fb_base + FBSIZE(panel) + 0x20;
+       lcdhw->lcddma_ctrl = LCD_DMA_BURST_SIZE(LCD_DMA_BURST_16);
+
+       lcdhw->raster_timing0 = LCD_HORLSB(panel->hactive) |
+                               LCD_HORMSB(panel->hactive) |
+                               LCD_HFPLSB(panel->hfp) |
+                               LCD_HBPLSB(panel->hbp) |
+                               LCD_HSWLSB(panel->hsw);
+       lcdhw->raster_timing1 = LCD_VBP(panel->vbp) |
+                               LCD_VFP(panel->vfp) |
+                               LCD_VSW(panel->vsw) |
+                               LCD_VERLSB(panel->vactive);
+       lcdhw->raster_timing2 = LCD_HSWMSB(panel->hsw) |
+                               LCD_VERMSB(panel->vactive) |
+                               LCD_INVMASK(panel->pol) |
+                               LCD_HBPMSB(panel->hbp) |
+                               LCD_HFPMSB(panel->hfp) |
+                               0x0000FF00;     /* clk cycles for ac-bias */
+       lcdhw->raster_ctrl =    LCD_TFT_24BPP_MODE |
+                               LCD_TFT_24BPP_UNPACK |
+                               LCD_PALMODE_RAWDATA |
+                               LCD_TFT_MODE |
+                               LCD_RASTER_ENABLE;
+
+       gd->fb_base += 0x20;    /* point fb behind palette */
+
+       /* turn ON display through powercontrol function if accessible */
+       if (0 != panel->panel_power_ctrl) {
+               mdelay(panel->pon_delay);
+               panel->panel_power_ctrl(1);
+       }
+
+       return 0;
+}
diff --git a/drivers/video/am335x-fb.h b/drivers/video/am335x-fb.h
new file mode 100644 (file)
index 0000000..8a0b131
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2013 Hannes Petermaier <oe5hpm@oevsv.at> -
+ * Bernecker & Rainer Industrieelektronik GmbH - http://www.br-automation.com
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef AM335X_FB_H
+#define AM335X_FB_H
+
+#define HSVS_CONTROL   (0x01 << 25)    /*
+                                        * 0 = lcd_lp and lcd_fp are driven on
+                                        * opposite edges of pixel clock than
+                                        * the lcd_pixel_o
+                                        * 1 = lcd_lp and lcd_fp are driven
+                                        * according to bit 24 Note that this
+                                        * bit MUST be set to '0' for Passive
+                                        * Matrix displays the edge timing is
+                                        * fixed
+                                        */
+#define HSVS_RISEFALL  (0x01 << 24)    /*
+                                        * 0 = lcd_lp and lcd_fp are driven on
+                                        * the rising edge of pixel clock (bit
+                                        * 25 must be set to 1)
+                                        * 1 = lcd_lp and lcd_fp are driven on
+                                        * the falling edge of pixel clock (bit
+                                        * 25 must be set to 1)
+                                        */
+#define DE_INVERT      (0x01 << 23)    /*
+                                        * 0 = DE is low-active
+                                        * 1 = DE is high-active
+                                        */
+#define PXCLK_INVERT   (0x01 << 22)    /*
+                                        * 0 = pix-clk is high-active
+                                        * 1 = pic-clk is low-active
+                                        */
+#define HSYNC_INVERT   (0x01 << 21)    /*
+                                        * 0 = HSYNC is active high
+                                        * 1 = HSYNC is avtive low
+                                        */
+#define VSYNC_INVERT   (0x01 << 20)    /*
+                                        * 0 = VSYNC is active high
+                                        * 1 = VSYNC is active low
+                                        */
+
+struct am335x_lcdpanel {
+       unsigned int    hactive;        /* Horizontal active area */
+       unsigned int    vactive;        /* Vertical active area */
+       unsigned int    bpp;            /* bits per pixel */
+       unsigned int    hfp;            /* Horizontal front porch */
+       unsigned int    hbp;            /* Horizontal back porch */
+       unsigned int    hsw;            /* Horizontal Sync Pulse Width */
+       unsigned int    vfp;            /* Vertical front porch */
+       unsigned int    vbp;            /* Vertical back porch */
+       unsigned int    vsw;            /* Vertical Sync Pulse Width */
+       unsigned int    pxl_clk_div;    /* Pixel clock divider*/
+       unsigned int    pol;            /* polarity of sync, clock signals */
+       unsigned int    pon_delay;      /*
+                                        * time in ms for turning on lcd after
+                                        * initializing lcd-controller
+                                        */
+       void (*panel_power_ctrl)(int);  /* fp for power on/off display */
+};
+
+int am335xfb_init(struct am335x_lcdpanel *panel);
+
+#endif  /* AM335X_FB_H */
index 3d2741f223eeffbf33deb8796bfd2ec162612991..091b58fb47bfccfa4bc30bfdd9e87006bbafa438 100644 (file)
@@ -175,6 +175,14 @@ typedef union {
        } mem_dp_fg_sync;
 } ipu_channel_params_t;
 
+/*
+ * Enumeration of IPU interrupts.
+ */
+enum ipu_irq_line {
+       IPU_IRQ_DP_SF_END = 448 + 3,
+       IPU_IRQ_DC_FC_1 = 448 + 9,
+};
+
 /*
  * Bitfield of Display Interface signal polarities.
  */
index cefd2dc14a2ebbcd9b6c91228da3fb361b8fc05d..948e1fc401facea11502734ac53e82dd70df36e5 100644 (file)
@@ -33,7 +33,7 @@ enum csc_type_t {
 
 struct dp_csc_param_t {
        int mode;
-       void *coeff;
+       const int (*coeff)[5][3];
 };
 
 #define SYNC_WAVE 0
@@ -666,13 +666,16 @@ void ipu_dp_dc_disable(ipu_channel_t channel, unsigned char swap)
        uint32_t csc;
        uint32_t dc_chan = 0;
        int timeout = 50;
+       int irq = 0;
 
        dc_swap = swap;
 
        if (channel == MEM_DC_SYNC) {
                dc_chan = 1;
+               irq = IPU_IRQ_DC_FC_1;
        } else if (channel == MEM_BG_SYNC) {
                dc_chan = 5;
+               irq = IPU_IRQ_DP_SF_END;
        } else if (channel == MEM_FG_SYNC) {
                /* Disable FG channel */
                dc_chan = 5;
@@ -723,25 +726,11 @@ void ipu_dp_dc_disable(ipu_channel_t channel, unsigned char swap)
                reg ^= DC_WR_CH_CONF_PROG_DI_ID;
                __raw_writel(reg, DC_WR_CH_CONF(dc_chan));
        } else {
-               timeout = 50;
-
-               /* Wait for DC triple buffer to empty */
-               if (g_dc_di_assignment[dc_chan] == 0)
-                       while ((__raw_readl(DC_STAT) & 0x00000002)
-                               != 0x00000002) {
-                               udelay(2000);
-                               timeout -= 2;
-                               if (timeout <= 0)
-                                       break;
-                       }
-               else if (g_dc_di_assignment[dc_chan] == 1)
-                       while ((__raw_readl(DC_STAT) & 0x00000020)
-                               != 0x00000020) {
-                               udelay(2000);
-                               timeout -= 2;
-                               if (timeout <= 0)
-                                       break;
-                       }
+               /* Make sure that we leave at the irq starting edge */
+               __raw_writel(IPUIRQ_2_MASK(irq), IPUIRQ_2_STATREG(irq));
+               do {
+                       reg = __raw_readl(IPUIRQ_2_STATREG(irq));
+               } while (!(reg & IPUIRQ_2_MASK(irq)));
 
                reg = __raw_readl(DC_WR_CH_CONF(dc_chan));
                reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK;
index 21e9c99e0e637b68e1c834e16189f7694d72b961..c2c134a7de0738beca41c7b871c0869d5f6fe031 100644 (file)
@@ -313,9 +313,12 @@ struct ipu_dmfc {
 
 #define IPU_STAT               ((struct ipu_stat *)(IPU_CTRL_BASE_ADDR + \
                                IPU_STAT_REG_BASE))
+#define IPU_INT_STAT(n)                (&IPU_STAT->int_stat[(n) - 1])
 #define IPU_CHA_CUR_BUF(ch)    (&IPU_STAT->cur_buf[ch / 32])
 #define IPU_CHA_BUF0_RDY(ch)   (&IPU_STAT->ch_buf0_rdy[ch / 32])
 #define IPU_CHA_BUF1_RDY(ch)   (&IPU_STAT->ch_buf1_rdy[ch / 32])
+#define IPUIRQ_2_STATREG(irq)  (IPU_INT_STAT(1) + ((irq) / 32))
+#define IPUIRQ_2_MASK(irq)     (1UL << ((irq) & 0x1F))
 
 #define IPU_INT_CTRL(n)                (&IPU_CM_REG->int_ctrl[(n) - 1])
 
index 417ce7b63bf0215122821cee7236e0062e9ee7ef..cbdc22026deb63a24968cbd3c0078407940bc5a2 100644 (file)
@@ -182,6 +182,11 @@ int ext4fs_exists(const char *filename)
        return file_len >= 0;
 }
 
+int ext4fs_size(const char *filename)
+{
+       return ext4fs_open(filename);
+}
+
 int ext4fs_read(char *buf, unsigned len)
 {
        if (ext4fs_root == NULL || ext4fs_file == NULL)
index 54f42eae0d05eec8d456bde67d2f52122d23d369..561921fa2d364e548629fe8152cb953861699b3f 100644 (file)
@@ -1243,6 +1243,11 @@ int fat_exists(const char *filename)
        return sz >= 0;
 }
 
+int fat_size(const char *filename)
+{
+       return do_fat_read_at(filename, 0, NULL, 0, LS_NO, 1);
+}
+
 long file_fat_read_at(const char *filename, unsigned long pos, void *buffer,
                      unsigned long maxsize)
 {
diff --git a/fs/fs.c b/fs/fs.c
index ea15c5f447bd3fb30ea4a5604a471b0b9a852110..dd680f39c9ca60472ea91f37a7a325f95da3b672 100644 (file)
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -46,6 +46,11 @@ static inline int fs_exists_unsupported(const char *filename)
        return 0;
 }
 
+static inline int fs_size_unsupported(const char *filename)
+{
+       return -1;
+}
+
 static inline int fs_read_unsupported(const char *filename, void *buf,
                                      int offset, int len)
 {
@@ -77,6 +82,7 @@ struct fstype_info {
                     disk_partition_t *fs_partition);
        int (*ls)(const char *dirname);
        int (*exists)(const char *filename);
+       int (*size)(const char *filename);
        int (*read)(const char *filename, void *buf, int offset, int len);
        int (*write)(const char *filename, void *buf, int offset, int len);
        void (*close)(void);
@@ -91,6 +97,7 @@ static struct fstype_info fstypes[] = {
                .close = fat_close,
                .ls = file_fat_ls,
                .exists = fat_exists,
+               .size = fat_size,
                .read = fat_read_file,
                .write = fs_write_unsupported,
        },
@@ -103,6 +110,7 @@ static struct fstype_info fstypes[] = {
                .close = ext4fs_close,
                .ls = ext4fs_ls,
                .exists = ext4fs_exists,
+               .size = ext4fs_size,
                .read = ext4_read_file,
                .write = fs_write_unsupported,
        },
@@ -115,6 +123,7 @@ static struct fstype_info fstypes[] = {
                .close = sandbox_fs_close,
                .ls = sandbox_fs_ls,
                .exists = sandbox_fs_exists,
+               .size = sandbox_fs_size,
                .read = fs_read_sandbox,
                .write = fs_write_sandbox,
        },
@@ -126,6 +135,7 @@ static struct fstype_info fstypes[] = {
                .close = fs_close_unsupported,
                .ls = fs_ls_unsupported,
                .exists = fs_exists_unsupported,
+               .size = fs_size_unsupported,
                .read = fs_read_unsupported,
                .write = fs_write_unsupported,
        },
@@ -223,6 +233,19 @@ int fs_exists(const char *filename)
        return ret;
 }
 
+int fs_size(const char *filename)
+{
+       int ret;
+
+       struct fstype_info *info = fs_get_info(fs_type);
+
+       ret = info->size(filename);
+
+       fs_close();
+
+       return ret;
+}
+
 int fs_read(const char *filename, ulong addr, int offset, int len)
 {
        struct fstype_info *info = fs_get_info(fs_type);
@@ -266,6 +289,26 @@ int fs_write(const char *filename, ulong addr, int offset, int len)
        return ret;
 }
 
+int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
+               int fstype)
+{
+       int size;
+
+       if (argc != 4)
+               return CMD_RET_USAGE;
+
+       if (fs_set_blk_dev(argv[1], argv[2], fstype))
+               return 1;
+
+       size = fs_size(argv[3]);
+       if (size < 0)
+               return CMD_RET_FAILURE;
+
+       setenv_hex("filesize", size);
+
+       return 0;
+}
+
 int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
                int fstype)
 {
index 85079788c990f712f8711b947539e2886d8684e9..ba6402c81c0a5a16ac10838cf0c5981331e9031c 100644 (file)
@@ -80,6 +80,11 @@ int sandbox_fs_exists(const char *filename)
        return sz >= 0;
 }
 
+int sandbox_fs_size(const char *filename)
+{
+       return os_get_filesize(filename);
+}
+
 void sandbox_fs_close(void)
 {
 }
diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
new file mode 100644 (file)
index 0000000..90d9901
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * (C) Copyright 2014
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * Copyright 2014 Red Hat, Inc.
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _CONFIG_CMD_DISTRO_BOOTCMD_H
+#define _CONFIG_CMD_DISTRO_BOOTCMD_H
+
+#define BOOTENV_SHARED_BLKDEV_BODY(devtypel) \
+               "if " #devtypel " dev ${devnum}; then " \
+                       "setenv devtype " #devtypel "; " \
+                       "run scan_dev_for_boot; " \
+               "fi\0"
+
+#define BOOTENV_SHARED_BLKDEV(devtypel) \
+       #devtypel "_boot=" \
+       BOOTENV_SHARED_BLKDEV_BODY(devtypel)
+
+#define BOOTENV_DEV_BLKDEV(devtypeu, devtypel, instance) \
+       "bootcmd_" #devtypel #instance "=" \
+               "setenv devnum " #instance "; " \
+               "run " #devtypel "_boot\0"
+
+#define BOOTENV_DEV_NAME_BLKDEV(devtypeu, devtypel, instance) \
+       #devtypel #instance " "
+
+#ifdef CONFIG_CMD_MMC
+#define BOOTENV_SHARED_MMC     BOOTENV_SHARED_BLKDEV(mmc)
+#define BOOTENV_DEV_MMC                BOOTENV_DEV_BLKDEV
+#define BOOTENV_DEV_NAME_MMC   BOOTENV_DEV_NAME_BLKDEV
+#else
+#define BOOTENV_SHARED_MMC
+#define BOOTENV_DEV_MMC \
+       BOOT_TARGET_DEVICES_references_MMC_without_CONFIG_CMD_MMC
+#define BOOTENV_DEV_NAME_MMC \
+       BOOT_TARGET_DEVICES_references_MMC_without_CONFIG_CMD_MMC
+#endif
+
+#ifdef CONFIG_CMD_SATA
+#define BOOTENV_SHARED_SATA    BOOTENV_SHARED_BLKDEV(sata)
+#define BOOTENV_DEV_SATA       BOOTENV_DEV_BLKDEV
+#define BOOTENV_DEV_NAME_SATA  BOOTENV_DEV_NAME_BLKDEV
+#else
+#define BOOTENV_SHARED_SATA
+#define BOOTENV_DEV_SATA \
+       BOOT_TARGET_DEVICES_references_SATA_without_CONFIG_CMD_SATA
+#define BOOTENV_DEV_NAME_SATA \
+       BOOT_TARGET_DEVICES_references_SATA_without_CONFIG_CMD_SATA
+#endif
+
+#ifdef CONFIG_CMD_SCSI
+#define BOOTENV_SHARED_SCSI    BOOTENV_SHARED_BLKDEV(scsi)
+#define BOOTENV_DEV_SCSI       BOOTENV_DEV_BLKDEV
+#define BOOTENV_DEV_NAME_SCSI  BOOTENV_DEV_NAME_BLKDEV
+#else
+#define BOOTENV_SHARED_SCSI
+#define BOOTENV_DEV_SCSI \
+       BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_CMD_SCSI
+#define BOOTENV_DEV_NAME_SCSI \
+       BOOT_TARGET_DEVICES_references_SCSI_without_CONFIG_CMD_SCSI
+#endif
+
+#ifdef CONFIG_CMD_IDE
+#define BOOTENV_SHARED_IDE     BOOTENV_SHARED_BLKDEV(ide)
+#define BOOTENV_DEV_IDE                BOOTENV_DEV_BLKDEV
+#define BOOTENV_DEV_NAME_IDE   BOOTENV_DEV_NAME_BLKDEV
+#else
+#define BOOTENV_SHARED_IDE
+#define BOOTENV_DEV_IDE \
+       BOOT_TARGET_DEVICES_references_IDE_without_CONFIG_CMD_IDE
+#define BOOTENV_DEV_NAME_IDE \
+       BOOT_TARGET_DEVICES_references_IDE_without_CONFIG_CMD_IDE
+#endif
+
+#ifdef CONFIG_CMD_USB
+#define BOOTENV_RUN_USB_INIT "run usb_init; "
+#define BOOTENV_SET_USB_NEED_INIT "setenv usb_need_init; "
+#define BOOTENV_SHARED_USB \
+       "usb_init=" \
+               "if ${usb_need_init}; then " \
+                       "setenv usb_need_init false; " \
+                       "usb start 0; " \
+               "fi\0" \
+       \
+       "usb_boot=" \
+               BOOTENV_RUN_USB_INIT \
+               BOOTENV_SHARED_BLKDEV_BODY(usb)
+#define BOOTENV_DEV_USB                BOOTENV_DEV_BLKDEV
+#define BOOTENV_DEV_NAME_USB   BOOTENV_DEV_NAME_BLKDEV
+#else
+#define BOOTENV_RUN_USB_INIT
+#define BOOTENV_SET_USB_NEED_INIT
+#define BOOTENV_SHARED_USB
+#define BOOTENV_DEV_USB \
+       BOOT_TARGET_DEVICES_references_USB_without_CONFIG_CMD_USB
+#define BOOTENV_DEV_NAME_USB \
+       BOOT_TARGET_DEVICES_references_USB_without_CONFIG_CMD_USB
+#endif
+
+#if defined(CONFIG_CMD_DHCP)
+#define BOOTENV_DEV_DHCP(devtypeu, devtypel, instance) \
+       "bootcmd_dhcp=" \
+               BOOTENV_RUN_USB_INIT \
+               "if dhcp ${scriptaddr} boot.scr.uimg; then " \
+                       "source ${scriptaddr}; " \
+               "fi\0"
+#define BOOTENV_DEV_NAME_DHCP(devtypeu, devtypel, instance) \
+       "dhcp "
+#else
+#define BOOTENV_DEV_DHCP \
+       BOOT_TARGET_DEVICES_references_DHCP_without_CONFIG_CMD_DHCP
+#define BOOTENV_DEV_NAME_DHCP \
+       BOOT_TARGET_DEVICES_references_DHCP_without_CONFIG_CMD_DHCP
+#endif
+
+#if defined(CONFIG_CMD_DHCP) && defined(CONFIG_CMD_PXE)
+#define BOOTENV_DEV_PXE(devtypeu, devtypel, instance) \
+       "bootcmd_pxe=" \
+               BOOTENV_RUN_USB_INIT \
+               "dhcp; " \
+               "if pxe get; then " \
+                       "pxe boot; " \
+               "fi\0"
+#define BOOTENV_DEV_NAME_PXE(devtypeu, devtypel, instance) \
+       "pxe "
+#else
+#define BOOTENV_DEV_PXE \
+       BOOT_TARGET_DEVICES_references_PXE_without_CONFIG_CMD_DHCP_or_PXE
+#define BOOTENV_DEV_NAME_PXE \
+       BOOT_TARGET_DEVICES_references_PXE_without_CONFIG_CMD_DHCP_or_PXE
+#endif
+
+#define BOOTENV_DEV_NAME(devtypeu, devtypel, instance) \
+       BOOTENV_DEV_NAME_##devtypeu(devtypeu, devtypel, instance)
+#define BOOTENV_BOOT_TARGETS \
+       "boot_targets=" BOOT_TARGET_DEVICES(BOOTENV_DEV_NAME) "\0"
+
+#define BOOTENV_DEV(devtypeu, devtypel, instance) \
+       BOOTENV_DEV_##devtypeu(devtypeu, devtypel, instance)
+#define BOOTENV \
+       BOOTENV_SHARED_MMC \
+       BOOTENV_SHARED_USB \
+       BOOTENV_SHARED_SATA \
+       BOOTENV_SHARED_SCSI \
+       BOOTENV_SHARED_IDE \
+       "boot_prefixes=/ /boot/\0" \
+       "boot_scripts=boot.scr.uimg boot.scr\0" \
+       BOOTENV_BOOT_TARGETS \
+       "bootpart=1\0" \
+       \
+       "boot_extlinux="                                                  \
+               "sysboot ${devtype} ${devnum}:${bootpart} any "           \
+                       "${scriptaddr} ${prefix}extlinux/extlinux.conf\0" \
+       \
+       "scan_dev_for_extlinux="                                          \
+               "if test -e ${devtype} ${devnum}:${bootpart} "            \
+                               "${prefix}extlinux/extlinux.conf; then "  \
+                       "echo Found ${prefix}extlinux/extlinux.conf; "    \
+                       "run boot_extlinux; "                             \
+                       "echo SCRIPT FAILED: continuing...; "             \
+               "fi\0"                                                    \
+       \
+       "boot_a_script="                                                  \
+               "load ${devtype} ${devnum}:${bootpart} "                  \
+                       "${scriptaddr} ${prefix}${script}; "              \
+               "source ${scriptaddr}\0"                                  \
+       \
+       "scan_dev_for_scripts="                                           \
+               "for script in ${boot_scripts}; do "                      \
+                       "if test -e ${devtype} ${devnum}:${bootpart} "    \
+                                       "${prefix}${script}; then "       \
+                               "echo Found U-Boot script "               \
+                                       "${prefix}${script}; "            \
+                               "run boot_a_script; "                     \
+                               "echo SCRIPT FAILED: continuing...; "     \
+                       "fi; "                                            \
+               "done\0"                                                  \
+       \
+       "scan_dev_for_boot="                                              \
+               "echo Scanning ${devtype} ${devnum}...; "                 \
+               "for prefix in ${boot_prefixes}; do "                     \
+                       "run scan_dev_for_extlinux; "                     \
+                       "run scan_dev_for_scripts; "                      \
+               "done\0"                                                  \
+       \
+       BOOT_TARGET_DEVICES(BOOTENV_DEV)                                  \
+       \
+       "bootcmd=" BOOTENV_SET_USB_NEED_INIT                              \
+               "for target in ${boot_targets}; do "                      \
+                       "run bootcmd_${target}; "                         \
+               "done\0"
+
+#endif  /* _CONFIG_CMD_DISTRO_BOOTCMD_H */
index 6795f28a11ed61461a7c04ef15206f514394dcc8..3c2b61353bb5ae7c18da428e58f2673db564c595 100644 (file)
 /* USB */
 #define CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_RMOBILE
-#define CONFIG_USB_MAX_CONTROLLER_COUNT        3
+#define CONFIG_USB_MAX_CONTROLLER_COUNT        2
 #define CONFIG_USB_STORAGE
 
 #endif /* __KOELSCH_H */
index f39a788e91e9164c94bcef39790cdbd29d3b5c82..74c998f3d45d0768e65966e29e78d15a0964c476 100644 (file)
 /* USB */
 #define CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_RMOBILE
-#define CONFIG_USB_MAX_CONTROLLER_COUNT        4
+#define CONFIG_USB_MAX_CONTROLLER_COUNT        3
 #define CONFIG_USB_STORAGE
 
 #endif /* __LAGER_H */
index 41f7973f2b8843287b5ccdc9e5e667dca4297154..5482722561e97e1758f473facd82a4e4ef23e224 100644 (file)
@@ -612,22 +612,6 @@ typedef struct {
 int cpu_type(void);
 #endif
 
-/*
- * EVM Implementation Specifics.
- *
- * *** NOTE ***
- * Any definitions in these files should be prefixed by an identifier -
- * eg. OMAP1510P1_FLASH0_BASE .
- *
- */
-#ifdef CONFIG_OMAP_INNOVATOR
-#include "innovator.h"
-#endif
-
-#ifdef CONFIG_OMAP_1510P1
-#include "omap1510p1.h"
-#endif
-
 /*****************************************************************************/
 
 #define CLKGEN_RESET_BASE (0xfffece00)
index 60f24895e5dd48b3c97cad80c93822adda418600..2d698094800f2c7bbc50d6f7b8ef63e27b5b7742 100644 (file)
                "env import -t -r ${loadaddr} ${filesize}; " \
        "fi"
 
+/* Shell */
+#define CONFIG_SYS_MAXARGS             8
+#define CONFIG_SYS_PROMPT              "U-Boot> "
+#define CONFIG_COMMAND_HISTORY
+
+/* Commands */
+#include <config_cmd_default.h>
+#define CONFIG_CMD_GPIO
+#define CONFIG_CMD_MMC
+#define CONFIG_PARTITION_UUIDS
+#define CONFIG_CMD_PART
+
+/* Device tree support */
+#define CONFIG_OF_BOARD_SETUP
+/* ATAGs support for bootm/bootz */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_INITRD_TAG
+
+#include <config_distro_defaults.h>
+
+/* Some things don't make sense on this HW or yet */
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_NET
+#undef CONFIG_CMD_NFS
+#undef CONFIG_CMD_SAVEENV
+#undef CONFIG_CMD_DHCP
+#undef CONFIG_CMD_MII
+#undef CONFIG_CMD_NET
+#undef CONFIG_CMD_PING
+
+/* Environment */
 #define ENV_DEVICE_SETTINGS \
        "stdin=serial,lcd\0" \
        "stdout=serial,lcd\0" \
        "fdtfile=bcm2835-rpi-b.dtb\0" \
        "ramdisk_addr_r=0x02100000\0" \
 
-#define BOOTCMDS_MMC \
-       "mmc_boot=" \
-               "setenv devtype mmc; " \
-               "if mmc dev ${devnum}; then " \
-                       "run scan_boot; " \
-               "fi\0" \
-       "bootcmd_mmc0=setenv devnum 0; run mmc_boot;\0"
-#define BOOT_TARGETS_MMC "mmc0"
-
-#define BOOTCMDS_COMMON \
-       "rootpart=1\0" \
-       \
-       "do_script_boot="                                                 \
-               "load ${devtype} ${devnum}:${rootpart} "                  \
-                       "${scriptaddr} ${prefix}${script}; "              \
-               "source ${scriptaddr}\0"                                  \
-       \
-       "script_boot="                                                    \
-               "for script in ${boot_scripts}; do "                      \
-                       "if test -e ${devtype} ${devnum}:${rootpart} "    \
-                                       "${prefix}${script}; then "       \
-                               "echo Found ${prefix}${script}; "         \
-                               "run do_script_boot; "                    \
-                               "echo SCRIPT FAILED: continuing...; "     \
-                       "fi; "                                            \
-               "done\0"                                                  \
-       \
-       "do_sysboot_boot="                                                \
-               "sysboot ${devtype} ${devnum}:${rootpart} any "           \
-                       "${scriptaddr} ${prefix}extlinux/extlinux.conf\0" \
-       \
-       "sysboot_boot="                                                   \
-               "if test -e ${devtype} ${devnum}:${rootpart} "            \
-                               "${prefix}extlinux/extlinux.conf; then "  \
-                       "echo Found ${prefix}extlinux/extlinux.conf; "    \
-                       "run do_sysboot_boot; "                           \
-                       "echo SCRIPT FAILED: continuing...; "             \
-               "fi\0"                                                    \
-       \
-       "scan_boot="                                                      \
-               "echo Scanning ${devtype} ${devnum}...; "                 \
-               "for prefix in ${boot_prefixes}; do "                     \
-                       "run sysboot_boot; "                              \
-                       "run script_boot; "                               \
-               "done\0"                                                  \
-       \
-       "boot_targets=" \
-               BOOT_TARGETS_MMC " " \
-               "\0" \
-       \
-       "boot_prefixes=/\0" \
-       \
-       "boot_scripts=boot.scr.uimg\0" \
-       \
-       BOOTCMDS_MMC
-
-#define CONFIG_BOOTCOMMAND \
-       "for target in ${boot_targets}; do run bootcmd_${target}; done"
-
-#define CONFIG_BOOTCOMMAND \
-       "for target in ${boot_targets}; do run bootcmd_${target}; done"
+#define BOOT_TARGET_DEVICES(func) \
+       func(MMC, mmc, 0)
+#include <config_distro_bootcmd.h>
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
        ENV_DEVICE_SETTINGS \
        ENV_MEM_LAYOUT_SETTINGS \
-       BOOTCMDS_COMMON
+       BOOTENV
 
 #define CONFIG_BOOTDELAY 2
 
-/* Shell */
-#define CONFIG_SYS_MAXARGS             8
-#define CONFIG_SYS_PROMPT              "U-Boot> "
-#define CONFIG_COMMAND_HISTORY
-
-/* Commands */
-#include <config_cmd_default.h>
-#define CONFIG_CMD_GPIO
-#define CONFIG_CMD_MMC
-#define CONFIG_PARTITION_UUIDS
-#define CONFIG_CMD_PART
-
-/* Device tree support */
-#define CONFIG_OF_BOARD_SETUP
-/* ATAGs support for bootm/bootz */
-#define CONFIG_SETUP_MEMORY_TAGS
-#define CONFIG_CMDLINE_TAG
-#define CONFIG_INITRD_TAG
-
-#include <config_distro_defaults.h>
-
-/* Some things don't make sense on this HW or yet */
-#undef CONFIG_CMD_FPGA
-#undef CONFIG_CMD_NET
-#undef CONFIG_CMD_NFS
-#undef CONFIG_CMD_SAVEENV
-#undef CONFIG_CMD_DHCP
-#undef CONFIG_CMD_MII
-#undef CONFIG_CMD_NET
-#undef CONFIG_CMD_PING
-
 #endif
index 1c770c90fecaa3d98a144f5dcfe523c531a36f07..c337e3016e7682b7c2e3da2250715b90ca041447 100644 (file)
 #ifndef __TEGRA_COMMON_POST_H
 #define __TEGRA_COMMON_POST_H
 
-#ifdef CONFIG_BOOTCOMMAND
-
-#define BOOTCMDS_COMMON ""
-
-#else
-
-#ifdef CONFIG_CMD_MMC
-#define BOOTCMDS_MMC \
-       "mmc_boot=" \
-               "setenv devtype mmc; " \
-               "if mmc dev ${devnum}; then " \
-                       "run scan_boot; " \
-               "fi\0" \
-       "bootcmd_mmc0=setenv devnum 0; run mmc_boot;\0" \
-       "bootcmd_mmc1=setenv devnum 1; run mmc_boot;\0"
-#define BOOT_TARGETS_MMC "mmc1 mmc0"
+#ifndef CONFIG_SPL_BUILD
+#define BOOT_TARGET_DEVICES(func) \
+       func(MMC, mmc, 1) \
+       func(MMC, mmc, 0) \
+       func(USB, usb, 0) \
+       func(PXE, pxe, na) \
+       func(DHCP, dhcp, na)
+#include <config_distro_bootcmd.h>
 #else
-#define BOOTCMDS_MMC ""
-#define BOOT_TARGETS_MMC ""
-#endif
-
-#ifdef CONFIG_CMD_USB
-#define BOOTCMD_INIT_USB "run usb_init; "
-#define BOOTCMDS_USB \
-       "usb_init=" \
-               "if ${usb_need_init}; then " \
-                       "set usb_need_init false; " \
-                       "usb start 0; " \
-               "fi\0" \
-       \
-       "usb_boot=" \
-               "setenv devtype usb; " \
-               BOOTCMD_INIT_USB \
-               "if usb dev ${devnum}; then " \
-                       "run scan_boot; " \
-               "fi\0" \
-       \
-       "bootcmd_usb0=setenv devnum 0; run usb_boot;\0"
-#define BOOT_TARGETS_USB "usb0"
-#else
-#define BOOTCMD_INIT_USB ""
-#define BOOTCMDS_USB ""
-#define BOOT_TARGETS_USB ""
-#endif
-
-#ifdef CONFIG_CMD_DHCP
-#define BOOTCMDS_DHCP \
-       "bootcmd_dhcp=" \
-               BOOTCMD_INIT_USB \
-               "if dhcp ${scriptaddr} boot.scr.uimg; then "\
-                       "source ${scriptaddr}; " \
-               "fi\0"
-#define BOOT_TARGETS_DHCP "dhcp"
-#else
-#define BOOTCMDS_DHCP ""
-#define BOOT_TARGETS_DHCP ""
-#endif
-
-#if defined(CONFIG_CMD_DHCP) && defined(CONFIG_CMD_PXE)
-#define BOOTCMDS_PXE \
-       "bootcmd_pxe=" \
-               BOOTCMD_INIT_USB \
-               "dhcp; " \
-               "if pxe get; then " \
-                       "pxe boot; " \
-               "fi\0"
-#define BOOT_TARGETS_PXE "pxe"
-#else
-#define BOOTCMDS_PXE ""
-#define BOOT_TARGETS_PXE ""
-#endif
-
-#define BOOTCMDS_COMMON \
-       "rootpart=1\0" \
-       \
-       "do_script_boot="                                                 \
-               "load ${devtype} ${devnum}:${rootpart} "                  \
-                       "${scriptaddr} ${prefix}${script}; "              \
-               "source ${scriptaddr}\0"                                  \
-       \
-       "script_boot="                                                    \
-               "for script in ${boot_scripts}; do "                      \
-                       "if test -e ${devtype} ${devnum}:${rootpart} "    \
-                                       "${prefix}${script}; then "       \
-                               "echo Found U-Boot script "               \
-                                       "${prefix}${script}; "            \
-                               "run do_script_boot; "                    \
-                               "echo SCRIPT FAILED: continuing...; "     \
-                       "fi; "                                            \
-               "done\0"                                                  \
-       \
-       "do_sysboot_boot="                                                \
-               "sysboot ${devtype} ${devnum}:${rootpart} any "           \
-                       "${scriptaddr} ${prefix}extlinux/extlinux.conf\0" \
-       \
-       "sysboot_boot="                                                   \
-               "if test -e ${devtype} ${devnum}:${rootpart} "            \
-                               "${prefix}extlinux/extlinux.conf; then "  \
-                       "echo Found ${prefix}extlinux/extlinux.conf; "    \
-                       "run do_sysboot_boot; "                           \
-                       "echo SCRIPT FAILED: continuing...; "             \
-               "fi\0"                                                    \
-       \
-       "scan_boot="                                                      \
-               "echo Scanning ${devtype} ${devnum}...; "                 \
-               "for prefix in ${boot_prefixes}; do "                     \
-                       "run sysboot_boot; "                              \
-                       "run script_boot; "                               \
-               "done\0"                                                  \
-       \
-       "boot_targets=" \
-               BOOT_TARGETS_MMC " " \
-               BOOT_TARGETS_USB " " \
-               BOOT_TARGETS_PXE " " \
-               BOOT_TARGETS_DHCP " " \
-               "\0" \
-       \
-       "boot_prefixes=/ /boot/\0" \
-       \
-       "boot_scripts=boot.scr.uimg boot.scr\0" \
-       \
-       BOOTCMDS_MMC \
-       BOOTCMDS_USB \
-       BOOTCMDS_DHCP \
-       BOOTCMDS_PXE
-
-#define CONFIG_BOOTCOMMAND \
-       "set usb_need_init; " \
-       "for target in ${boot_targets}; do run bootcmd_${target}; done"
-
+#define BOOTENV
 #endif
 
 #ifdef CONFIG_TEGRA_KEYBOARD
        MEM_LAYOUT_ENV_SETTINGS \
        "fdt_high=ffffffff\0" \
        "initrd_high=ffffffff\0" \
-       BOOTCMDS_COMMON \
+       BOOTENV \
        BOARD_EXTRA_ENV_SETTINGS
 
 #if defined(CONFIG_TEGRA20_SFLASH) || defined(CONFIG_TEGRA20_SLINK) || defined(CONFIG_TEGRA114_SPI)
index 90f19626a39e22b5b9f4c42886f7e38a91c4b73c..7db1db6074224590ea2f7119c61b8dc3ce85143c 100644 (file)
 
 #define CONFIG_DFU_ALT \
        "u-boot raw 0x80 0x400;" \
-       "uImage ext4 0 2;" \
-       "modem.bin ext4 0 2;" \
-       "exynos4210-trats.dtb ext4 0 2;" \
+       "/uImage ext4 0 2;" \
+       "/modem.bin ext4 0 2;" \
+       "/exynos4210-trats.dtb ext4 0 2;" \
        ""PARTS_CSA" part 0 1;" \
        ""PARTS_BOOT" part 0 2;" \
        ""PARTS_QBOOT" part 0 3;" \
index 206975bcae0ec4b88ac543186c1d9d7053394df4..f537e4fdc4c93889aaba2f80227a18b5ef61893d 100644 (file)
@@ -92,9 +92,9 @@
 
 #define CONFIG_DFU_ALT \
        "u-boot raw 0x80 0x800;" \
-       "uImage ext4 0 2;" \
-       "modem.bin ext4 0 2;" \
-       "exynos4412-trats2.dtb ext4 0 2;" \
+       "/uImage ext4 0 2;" \
+       "/modem.bin ext4 0 2;" \
+       "/exynos4412-trats2.dtb ext4 0 2;" \
        ""PARTS_CSA" part 0 1;" \
        ""PARTS_BOOT" part 0 2;" \
        ""PARTS_QBOOT" part 0 3;" \
index 26ffbc8e81d2d4ac82620b179a84f5077cf01b7b..7e0a99908ca426b9ad4053a6deb75370d15497b7 100644 (file)
@@ -14,6 +14,7 @@
 #include <common.h>
 #include <linux/list.h>
 #include <mmc.h>
+#include <spi_flash.h>
 #include <linux/usb/composite.h>
 
 enum dfu_device_type {
@@ -21,6 +22,7 @@ enum dfu_device_type {
        DFU_DEV_ONENAND,
        DFU_DEV_NAND,
        DFU_DEV_RAM,
+       DFU_DEV_SF,
 };
 
 enum dfu_layout {
@@ -35,9 +37,12 @@ enum dfu_layout {
 enum dfu_op {
        DFU_OP_READ = 1,
        DFU_OP_WRITE,
+       DFU_OP_SIZE,
 };
 
 struct mmc_internal_data {
+       int dev_num;
+
        /* RAW programming */
        unsigned int lba_start;
        unsigned int lba_size;
@@ -67,6 +72,14 @@ struct ram_internal_data {
        unsigned int    size;
 };
 
+struct sf_internal_data {
+       struct spi_flash *dev;
+
+       /* RAW programming */
+       u64 start;
+       u64 size;
+};
+
 #define DFU_NAME_SIZE                  32
 #define DFU_CMD_BUF_SIZE               128
 #ifndef CONFIG_SYS_DFU_DATA_BUF_SIZE
@@ -86,16 +99,19 @@ struct dfu_entity {
        char                    name[DFU_NAME_SIZE];
        int                     alt;
        void                    *dev_private;
-       int                     dev_num;
        enum dfu_device_type    dev_type;
        enum dfu_layout         layout;
+       unsigned long           max_buf_size;
 
        union {
                struct mmc_internal_data mmc;
                struct nand_internal_data nand;
                struct ram_internal_data ram;
+               struct sf_internal_data sf;
        } data;
 
+       long (*get_medium_size)(struct dfu_entity *dfu);
+
        int (*read_medium)(struct dfu_entity *dfu,
                        u64 offset, void *buf, long *len);
 
@@ -105,6 +121,8 @@ struct dfu_entity {
        int (*flush_medium)(struct dfu_entity *dfu);
        unsigned int (*poll_timeout)(struct dfu_entity *dfu);
 
+       void (*free_entity)(struct dfu_entity *dfu);
+
        struct list_head list;
 
        /* on the fly state */
@@ -122,7 +140,7 @@ struct dfu_entity {
        unsigned int inited:1;
 };
 
-int dfu_config_entities(char *s, char *interface, int num);
+int dfu_config_entities(char *s, char *interface, char *devstr);
 void dfu_free_entities(void);
 void dfu_show_entities(void);
 int dfu_get_alt_number(void);
@@ -133,8 +151,8 @@ char *dfu_extract_token(char** e, int *n);
 void dfu_trigger_reset(void);
 int dfu_get_alt(char *name);
 bool dfu_reset(void);
-int dfu_init_env_entities(char *interface, int dev);
-unsigned char *dfu_get_buf(void);
+int dfu_init_env_entities(char *interface, char *devstr);
+unsigned char *dfu_get_buf(struct dfu_entity *dfu);
 unsigned char *dfu_free_buf(void);
 unsigned long dfu_get_buf_size(void);
 
@@ -143,9 +161,10 @@ int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
 int dfu_flush(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
 /* Device specific */
 #ifdef CONFIG_DFU_MMC
-extern int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s);
+extern int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s);
 #else
-static inline int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
+static inline int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr,
+                                     char *s)
 {
        puts("MMC support not available!\n");
        return -1;
@@ -153,9 +172,10 @@ static inline int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
 #endif
 
 #ifdef CONFIG_DFU_NAND
-extern int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s);
+extern int dfu_fill_entity_nand(struct dfu_entity *dfu, char *devstr, char *s);
 #else
-static inline int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
+static inline int dfu_fill_entity_nand(struct dfu_entity *dfu, char *devstr,
+                                      char *s)
 {
        puts("NAND support not available!\n");
        return -1;
@@ -163,14 +183,26 @@ static inline int dfu_fill_entity_nand(struct dfu_entity *dfu, char *s)
 #endif
 
 #ifdef CONFIG_DFU_RAM
-extern int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s);
+extern int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr, char *s);
 #else
-static inline int dfu_fill_entity_ram(struct dfu_entity *dfu, char *s)
+static inline int dfu_fill_entity_ram(struct dfu_entity *dfu, char *devstr,
+                                     char *s)
 {
        puts("RAM support not available!\n");
        return -1;
 }
 #endif
 
+#ifdef CONFIG_DFU_SF
+extern int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, char *s);
+#else
+static inline int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr,
+                                    char *s)
+{
+       puts("SF support not available!\n");
+       return -1;
+}
+#endif
+
 int dfu_add(struct usb_configuration *c);
 #endif /* __DFU_ENTITY_H_ */
index fbbb002b16735725e9440cd2a7920139076e9beb..6c419f3a233759c7e0998a1e5a25d7792a00bcfe 100644 (file)
@@ -136,6 +136,7 @@ void ext4fs_close(void);
 void ext4fs_reinit_global(void);
 int ext4fs_ls(const char *dirname);
 int ext4fs_exists(const char *filename);
+int ext4fs_size(const char *filename);
 void ext4fs_free_node(struct ext2fs_node *node, struct ext2fs_node *currroot);
 int ext4fs_devread(lbaint_t sector, int byte_offset, int byte_len, char *buf);
 void ext4fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info);
index 63cf78779bd585d18516519593f4e86455bdf68c..20ca3f3dca7df4476c5e94b9925815ba08bb6378 100644 (file)
@@ -198,6 +198,7 @@ int file_cd(const char *path);
 int file_fat_detectfs(void);
 int file_fat_ls(const char *dir);
 int fat_exists(const char *filename);
+int fat_size(const char *filename);
 long file_fat_read_at(const char *filename, unsigned long pos, void *buffer,
                      unsigned long maxsize);
 long file_fat_read(const char *filename, void *buffer, unsigned long maxsize);
index fd44d7e2f6495227bbcc34e9ece430921082e4da..1bda686a0b944c4b213f395fcb915bc4d25abedb 100644 (file)
@@ -76,7 +76,7 @@ void ft_cpu_setup(void *blob, bd_t *bd);
 void ft_pci_setup(void *blob, bd_t *bd);
 
 void set_working_fdt_addr(void *addr);
-int fdt_resize(void *blob);
+int fdt_shrink_to_minimum(void *blob);
 int fdt_increase_size(void *fdt, int add_len);
 
 int fdt_fixup_nor_flash_size(void *blob);
index 26de0539f7d9d9f47e4250b46af92417dd5c9d26..06a45f2788323b5d0fef4debf677bcf942cebe4d 100644 (file)
@@ -50,6 +50,13 @@ int fs_ls(const char *dirname);
  */
 int fs_exists(const char *filename);
 
+/*
+ * Determine a file's size
+ *
+ * Returns the file's size in bytes, or a negative value if it doesn't exist.
+ */
+int fs_size(const char *filename);
+
 /*
  * Read file "filename" from the partition previously set by fs_set_blk_dev(),
  * to address "addr", starting at byte offset "offset", and reading "len"
@@ -75,6 +82,8 @@ int fs_write(const char *filename, ulong addr, int offset, int len);
  * Common implementation for various filesystem commands, optionally limited
  * to a specific filesystem type via the fstype parameter.
  */
+int do_size(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
+               int fstype);
 int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
                int fstype);
 int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
index 3e8f78d583de7da387567579d3b0920d536a9c0f..ca2fe862ce67bab7d15bc6805cb267f1486be71f 100644 (file)
@@ -424,6 +424,7 @@ enum fit_load_op {
 #define IMAGE_FORMAT_FIT       0x02    /* new, libfdt based format */
 #define IMAGE_FORMAT_ANDROID   0x03    /* Android boot image */
 
+ulong genimg_get_kernel_addr(char * const img_addr);
 int genimg_get_format(const void *img_addr);
 int genimg_has_config(bootm_headers_t *images);
 ulong genimg_get_image(ulong img_addr);
index cc2ee3f9564e553595e52767cfd23da747ea3767..ea5860c8619e751dd34679cc8d26d2a757c00368 100644 (file)
@@ -26,8 +26,6 @@ void lcd_enable(void);
 void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue);
 void lcd_initcolregs(void);
 
-int lcd_getfgcolor(void);
-
 /* gunzip_bmp used if CONFIG_VIDEO_BMP_GZIP */
 struct bmp_image *gunzip_bmp(unsigned long addr, unsigned long *lenp,
                             void **alloc_addr);
@@ -333,7 +331,7 @@ void lcd_sync(void);
 #define LCD_COLOR4     2
 #define LCD_COLOR8     3
 #define LCD_COLOR16    4
-
+#define LCD_COLOR32    5
 /*----------------------------------------------------------------------*/
 #if defined(CONFIG_LCD_INFO_BELOW_LOGO)
 # define LCD_INFO_X            0
@@ -384,6 +382,21 @@ void lcd_sync(void);
 # define CONSOLE_COLOR_GREY    14
 # define CONSOLE_COLOR_WHITE   15      /* Must remain last / highest   */
 
+#elif LCD_BPP == LCD_COLOR32
+/*
+ * 32bpp color definitions
+ */
+# define CONSOLE_COLOR_RED     0x00ff0000
+# define CONSOLE_COLOR_GREEN   0x0000ff00
+# define CONSOLE_COLOR_YELLOW  0x00ffff00
+# define CONSOLE_COLOR_BLUE    0x000000ff
+# define CONSOLE_COLOR_MAGENTA 0x00ff00ff
+# define CONSOLE_COLOR_CYAN    0x0000ffff
+# define CONSOLE_COLOR_GREY    0x00aaaaaa
+# define CONSOLE_COLOR_BLACK   0x00000000
+# define CONSOLE_COLOR_WHITE   0x00ffffff      /* Must remain last / highest*/
+# define NBYTES(bit_code)      (NBITS(bit_code) >> 3)
+
 #else
 
 /*
index 9eefaaf5f87a7de869f78a05c67bed09d56202bd..a1ef1e15df3ddbd8abec45766b9f9038f334bcc1 100644 (file)
         * Should never be returned, if it is, it indicates a bug in
         * libfdt itself. */
 
-#define FDT_ERR_MAX            13
+/* Errors in device tree content */
+#define FDT_ERR_BADNCELLS      14
+       /* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
+        * or similar property with a bad format or value */
+
+#define FDT_ERR_MAX            14
 
 /**********************************************************************/
 /* Low-level functions (you probably don't need these)                */
@@ -596,9 +601,9 @@ const char *fdt_get_alias_namelen(const void *fdt,
                                  const char *name, int namelen);
 
 /**
- * fdt_get_alias - retrieve the path referenced by a given alias
+ * fdt_get_alias - retreive the path referenced by a given alias
  * @fdt: pointer to the device tree blob
- * @name: name of the alias to look up
+ * @name: name of the alias th look up
  *
  * fdt_get_alias() retrieves the value of a given alias.  That is, the
  * value of the property named 'name' in the node /aliases.
@@ -731,7 +736,7 @@ int fdt_parent_offset(const void *fdt, int nodeoffset);
  *     offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
  *                                            propval, proplen);
  *     while (offset != -FDT_ERR_NOTFOUND) {
- *             ... other code here ...
+ *             // other code here
  *             offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
  *                                                    propval, proplen);
  *     }
@@ -816,7 +821,7 @@ int fdt_node_check_compatible(const void *fdt, int nodeoffset,
  * idiom can be used:
  *     offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
  *     while (offset != -FDT_ERR_NOTFOUND) {
- *             ... other code here ...
+ *             // other code here
  *             offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
  *     }
  *
@@ -852,6 +857,63 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
  */
 int fdt_stringlist_contains(const char *strlist, int listlen, const char *str);
 
+/**********************************************************************/
+/* Read-only functions (addressing related)                           */
+/**********************************************************************/
+
+/**
+ * FDT_MAX_NCELLS - maximum value for #address-cells and #size-cells
+ *
+ * This is the maximum value for #address-cells, #size-cells and
+ * similar properties that will be processed by libfdt.  IEE1275
+ * requires that OF implementations handle values up to 4.
+ * Implementations may support larger values, but in practice higher
+ * values aren't used.
+ */
+#define FDT_MAX_NCELLS         4
+
+/**
+ * fdt_address_cells - retrieve address size for a bus represented in the tree
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node to find the address size for
+ *
+ * When the node has a valid #address-cells property, returns its value.
+ *
+ * returns:
+ *     0 <= n < FDT_MAX_NCELLS, on success
+ *      2, if the node has no #address-cells property
+ *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
+ *             #address-cells property
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_address_cells(const void *fdt, int nodeoffset);
+
+/**
+ * fdt_size_cells - retrieve address range size for a bus represented in the
+ *                  tree
+ * @fdt: pointer to the device tree blob
+ * @nodeoffset: offset of the node to find the address range size for
+ *
+ * When the node has a valid #size-cells property, returns its value.
+ *
+ * returns:
+ *     0 <= n < FDT_MAX_NCELLS, on success
+ *      2, if the node has no #address-cells property
+ *      -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid
+ *             #size-cells property
+ *     -FDT_ERR_BADMAGIC,
+ *     -FDT_ERR_BADVERSION,
+ *     -FDT_ERR_BADSTATE,
+ *     -FDT_ERR_BADSTRUCTURE,
+ *     -FDT_ERR_TRUNCATED, standard meanings
+ */
+int fdt_size_cells(const void *fdt, int nodeoffset);
+
+
 /**********************************************************************/
 /* Write-in-place functions                                           */
 /**********************************************************************/
@@ -1023,6 +1085,7 @@ int fdt_nop_node(void *fdt, int nodeoffset);
 /**********************************************************************/
 
 int fdt_create(void *buf, int bufsize);
+int fdt_resize(void *fdt, void *buf, int bufsize);
 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
 int fdt_finish_reservemap(void *fdt);
 int fdt_begin_node(void *fdt, const char *name);
index 17f829f6f9b016da61a9d1770b5737e1894a8955..d1f3a906c095d8f0269f8ce376f92804e0c5943c 100644 (file)
@@ -64,8 +64,6 @@ struct NS16550 {
        UART_REG(uasr);         /* F */
        UART_REG(scr);          /* 10*/
        UART_REG(ssr);          /* 11*/
-       UART_REG(reg12);        /* 12*/
-       UART_REG(osc_12m_sel);  /* 13*/
 #endif
 };
 
@@ -164,11 +162,6 @@ typedef struct NS16550 *NS16550_t;
 #define UART_IER_THRI  0x02    /* Enable Transmitter holding register int. */
 #define UART_IER_RDI   0x01    /* Enable receiver data interrupt */
 
-
-#ifdef CONFIG_OMAP1510
-#define OSC_12M_SEL    0x01    /* selects 6.5 * current clk div */
-#endif
-
 /* useful defaults for LCR */
 #define UART_LCR_8N1   0x03
 
index a51ad13044e174440fff9c1f69c7f2cebe16bf23..e7c32623e101e31dde107d94468090dc3f041d4d 100644 (file)
@@ -26,6 +26,7 @@ long sandbox_fs_read_at(const char *filename, unsigned long pos,
 void sandbox_fs_close(void);
 int sandbox_fs_ls(const char *dirname);
 int sandbox_fs_exists(const char *filename);
+int sandbox_fs_size(const char *filename);
 int fs_read_sandbox(const char *filename, void *buf, int offset, int len);
 int fs_write_sandbox(const char *filename, void *buf, int offset, int len);
 
index 325751ab7e1896c548e2c229708ad1a04670c2f5..fd08a617fbb129034375415365b67d573ef9c6a3 100644 (file)
@@ -27,6 +27,7 @@ struct rsa_public_key {
        uint32_t n0inv;         /* -1 / modulus[0] mod 2^32 */
        uint32_t *modulus;      /* modulus as little endian array */
        uint32_t *rr;           /* R^2 as little endian array */
+       uint64_t exponent;      /* public exponent */
 };
 
 #if IMAGE_ENABLE_SIGN
index 1f545ec1b02d30d14b6161be73dcaa76c650155f..b2e0c6b6f5159d8768d382858809f55bc4160eb5 100644 (file)
@@ -12,8 +12,8 @@
 #define EP_MAX_PACKET_SIZE     64
 #endif
 
-#if !defined(CONFIG_PPC) && !defined(CONFIG_OMAP1510)
-/* omap1510_udc.h and mpc8xx_udc.h will set these values */
+#if !defined(CONFIG_PPC)
+/* mpc8xx_udc.h will set these values */
 #define UDC_OUT_PACKET_SIZE     EP_MAX_PACKET_SIZE
 #define UDC_IN_PACKET_SIZE      EP_MAX_PACKET_SIZE
 #define UDC_INT_PACKET_SIZE     EP_MAX_PACKET_SIZE
index a02c9b02add2d360e5aa5d0d53a2d620e98e9fda..6fe79e0b06e9c422b6bfcfffd8fdd968872960dc 100644 (file)
@@ -5,7 +5,8 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-COBJS-libfdt += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o fdt_empty_tree.o
+COBJS-libfdt += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o \
+       fdt_empty_tree.o fdt_addresses.o
 
 obj-$(CONFIG_OF_LIBFDT) += $(COBJS-libfdt)
 obj-$(CONFIG_FIT) += $(COBJS-libfdt)
diff --git a/lib/libfdt/fdt_addresses.c b/lib/libfdt/fdt_addresses.c
new file mode 100644 (file)
index 0000000..76054d9
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
+ * SPDX-License-Identifier:    GPL-2.0+ BSD-2-Clause
+ */
+#include "libfdt_env.h"
+
+#ifndef USE_HOSTCC
+#include <fdt.h>
+#include <libfdt.h>
+#else
+#include "fdt_host.h"
+#endif
+
+#include "libfdt_internal.h"
+
+int fdt_address_cells(const void *fdt, int nodeoffset)
+{
+       const fdt32_t *ac;
+       int val;
+       int len;
+
+       ac = fdt_getprop(fdt, nodeoffset, "#address-cells", &len);
+       if (!ac)
+               return 2;
+
+       if (len != sizeof(*ac))
+               return -FDT_ERR_BADNCELLS;
+
+       val = fdt32_to_cpu(*ac);
+       if ((val <= 0) || (val > FDT_MAX_NCELLS))
+               return -FDT_ERR_BADNCELLS;
+
+       return val;
+}
+
+int fdt_size_cells(const void *fdt, int nodeoffset)
+{
+       const fdt32_t *sc;
+       int val;
+       int len;
+
+       sc = fdt_getprop(fdt, nodeoffset, "#size-cells", &len);
+       if (!sc)
+               return 2;
+
+       if (len != sizeof(*sc))
+               return -FDT_ERR_BADNCELLS;
+
+       val = fdt32_to_cpu(*sc);
+       if ((val < 0) || (val > FDT_MAX_NCELLS))
+               return -FDT_ERR_BADNCELLS;
+
+       return val;
+}
index 6fa4f13073d28fd76c886b1154e254ca1c6e1fd0..bec8b8ad891846e5240c476cf3b15e34eb3f66e8 100644 (file)
@@ -43,9 +43,9 @@ static int _fdt_rw_check_header(void *fdt)
 
 #define FDT_RW_CHECK_HEADER(fdt) \
        { \
-               int err; \
-               if ((err = _fdt_rw_check_header(fdt)) != 0) \
-                       return err; \
+               int __err; \
+               if ((__err = _fdt_rw_check_header(fdt)) != 0) \
+                       return __err; \
        }
 
 static inline int _fdt_data_size(void *fdt)
index 580b57024ffc96843d718ed3ea7dd962acd52327..320a914991ad76f94fedc67de6ad8fc072e78413 100644 (file)
@@ -62,6 +62,38 @@ int fdt_create(void *buf, int bufsize)
        return 0;
 }
 
+int fdt_resize(void *fdt, void *buf, int bufsize)
+{
+       size_t headsize, tailsize;
+       char *oldtail, *newtail;
+
+       FDT_SW_CHECK_HEADER(fdt);
+
+       headsize = fdt_off_dt_struct(fdt);
+       tailsize = fdt_size_dt_strings(fdt);
+
+       if ((headsize + tailsize) > bufsize)
+               return -FDT_ERR_NOSPACE;
+
+       oldtail = (char *)fdt + fdt_totalsize(fdt) - tailsize;
+       newtail = (char *)buf + bufsize - tailsize;
+
+       /* Two cases to avoid clobbering data if the old and new
+        * buffers partially overlap */
+       if (buf <= fdt) {
+               memmove(buf, fdt, headsize);
+               memmove(newtail, oldtail, tailsize);
+       } else {
+               memmove(newtail, oldtail, tailsize);
+               memmove(buf, fdt, headsize);
+       }
+
+       fdt_set_off_dt_strings(buf, bufsize);
+       fdt_set_totalsize(buf, bufsize);
+
+       return 0;
+}
+
 int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
 {
        struct fdt_reserve_entry *re;
index 13cbc9af2ab9259ea1cb76c37cb489be6907ab57..9a79fe85ddaf092904cb1c1a421a98fee1dcf696 100644 (file)
@@ -12,9 +12,9 @@
 
 #define FDT_CHECK_HEADER(fdt) \
        { \
-               int err; \
-               if ((err = fdt_check_header(fdt)) != 0) \
-                       return err; \
+               int __err; \
+               if ((__err = fdt_check_header(fdt)) != 0) \
+                       return __err; \
        }
 
 int _fdt_check_node_offset(const void *fdt, int offset);
index 49a3c9e01e59d15152660d00847a825c33575d4b..41a2be463565c6b519841902cba45b43839ef69a 100644 (file)
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -295,7 +295,10 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy
                if (max_addr == LMB_ALLOC_ANYWHERE)
                        base = lmb_align_down(lmbbase + lmbsize - size, align);
                else if (lmbbase < max_addr) {
-                       base = min(lmbbase + lmbsize, max_addr);
+                       base = lmbbase + lmbsize;
+                       if (base < lmbbase)
+                               base = -1;
+                       base = min(base, max_addr);
                        base = lmb_align_down(base - size, align);
                } else
                        continue;
index 83f5e87838950a7fb63f2de0aac6891cf40e2abd..5d9716f01349f4074653f2735fa3e6204ddba8e7 100644 (file)
@@ -76,6 +76,7 @@ static int rsa_get_pub_key(const char *keydir, const char *name, RSA **rsap)
        rsa = EVP_PKEY_get1_RSA(key);
        if (!rsa) {
                rsa_err("Couldn't convert to a RSA style key");
+               ret = -EINVAL;
                goto err_rsa;
        }
        fclose(f);
@@ -260,11 +261,58 @@ err_priv:
        return ret;
 }
 
+/*
+ * rsa_get_exponent(): - Get the public exponent from an RSA key
+ */
+static int rsa_get_exponent(RSA *key, uint64_t *e)
+{
+       int ret;
+       BIGNUM *bn_te;
+       uint64_t te;
+
+       ret = -EINVAL;
+       bn_te = NULL;
+
+       if (!e)
+               goto cleanup;
+
+       if (BN_num_bits(key->e) > 64)
+               goto cleanup;
+
+       *e = BN_get_word(key->e);
+
+       if (BN_num_bits(key->e) < 33) {
+               ret = 0;
+               goto cleanup;
+       }
+
+       bn_te = BN_dup(key->e);
+       if (!bn_te)
+               goto cleanup;
+
+       if (!BN_rshift(bn_te, bn_te, 32))
+               goto cleanup;
+
+       if (!BN_mask_bits(bn_te, 32))
+               goto cleanup;
+
+       te = BN_get_word(bn_te);
+       te <<= 32;
+       *e |= te;
+       ret = 0;
+
+cleanup:
+       if (bn_te)
+               BN_free(bn_te);
+
+       return ret;
+}
+
 /*
  * rsa_get_params(): - Get the important parameters of an RSA public key
  */
-int rsa_get_params(RSA *key, uint32_t *n0_invp, BIGNUM **modulusp,
-                  BIGNUM **r_squaredp)
+int rsa_get_params(RSA *key, uint64_t *exponent, uint32_t *n0_invp,
+                  BIGNUM **modulusp, BIGNUM **r_squaredp)
 {
        BIGNUM *big1, *big2, *big32, *big2_32;
        BIGNUM *n, *r, *r_squared, *tmp;
@@ -286,6 +334,9 @@ int rsa_get_params(RSA *key, uint32_t *n0_invp, BIGNUM **modulusp,
                return -ENOMEM;
        }
 
+       if (0 != rsa_get_exponent(key, exponent))
+               ret = -1;
+
        if (!BN_copy(n, key->n) || !BN_set_word(big1, 1L) ||
            !BN_set_word(big2, 2L) || !BN_set_word(big32, 32L))
                ret = -1;
@@ -386,6 +437,7 @@ static int fdt_add_bignum(void *blob, int noffset, const char *prop_name,
 int rsa_add_verify_data(struct image_sign_info *info, void *keydest)
 {
        BIGNUM *modulus, *r_squared;
+       uint64_t exponent;
        uint32_t n0_inv;
        int parent, node;
        char name[100];
@@ -397,7 +449,7 @@ int rsa_add_verify_data(struct image_sign_info *info, void *keydest)
        ret = rsa_get_pub_key(info->keydir, info->keyname, &rsa);
        if (ret)
                return ret;
-       ret = rsa_get_params(rsa, &n0_inv, &modulus, &r_squared);
+       ret = rsa_get_params(rsa, &exponent, &n0_inv, &modulus, &r_squared);
        if (ret)
                return ret;
        bits = BN_num_bits(modulus);
@@ -441,6 +493,9 @@ int rsa_add_verify_data(struct image_sign_info *info, void *keydest)
                ret = fdt_setprop_u32(keydest, node, "rsa,num-bits", bits);
        if (!ret)
                ret = fdt_setprop_u32(keydest, node, "rsa,n0-inverse", n0_inv);
+       if (!ret) {
+               ret = fdt_setprop_u64(keydest, node, "rsa,exponent", exponent);
+       }
        if (!ret) {
                ret = fdt_add_bignum(keydest, node, "rsa,modulus", modulus,
                                     bits);
index bcb906368d0dc273eb462a023a8d0477f2c51795..4ef19b66f4b12588f2bbe0a978500a0718177336 100644 (file)
@@ -26,6 +26,9 @@
 #define get_unaligned_be32(a) fdt32_to_cpu(*(uint32_t *)a)
 #define put_unaligned_be32(a, b) (*(uint32_t *)(b) = cpu_to_fdt32(a))
 
+/* Default public exponent for backward compatibility */
+#define RSA_DEFAULT_PUBEXP     65537
+
 /**
  * subtract_modulus() - subtract modulus from the given value
  *
@@ -54,9 +57,9 @@ static void subtract_modulus(const struct rsa_public_key *key, uint32_t num[])
 static int greater_equal_modulus(const struct rsa_public_key *key,
                                 uint32_t num[])
 {
-       uint32_t i;
+       int i;
 
-       for (i = key->len - 1; i >= 0; i--) {
+       for (i = (int)key->len - 1; i >= 0; i--) {
                if (num[i] < key->modulus[i])
                        return 0;
                if (num[i] > key->modulus[i])
@@ -122,6 +125,48 @@ static void montgomery_mul(const struct rsa_public_key *key,
                montgomery_mul_add_step(key, result, a[i], b);
 }
 
+/**
+ * num_pub_exponent_bits() - Number of bits in the public exponent
+ *
+ * @key:       RSA key
+ * @num_bits:  Storage for the number of public exponent bits
+ */
+static int num_public_exponent_bits(const struct rsa_public_key *key,
+               int *num_bits)
+{
+       uint64_t exponent;
+       int exponent_bits;
+       const uint max_bits = (sizeof(exponent) * 8);
+
+       exponent = key->exponent;
+       exponent_bits = 0;
+
+       if (!exponent) {
+               *num_bits = exponent_bits;
+               return 0;
+       }
+
+       for (exponent_bits = 1; exponent_bits < max_bits + 1; ++exponent_bits)
+               if (!(exponent >>= 1)) {
+                       *num_bits = exponent_bits;
+                       return 0;
+               }
+
+       return -EINVAL;
+}
+
+/**
+ * is_public_exponent_bit_set() - Check if a bit in the public exponent is set
+ *
+ * @key:       RSA key
+ * @pos:       The bit position to check
+ */
+static int is_public_exponent_bit_set(const struct rsa_public_key *key,
+               int pos)
+{
+       return key->exponent & (1ULL << pos);
+}
+
 /**
  * pow_mod() - in-place public exponentiation
  *
@@ -132,6 +177,7 @@ static int pow_mod(const struct rsa_public_key *key, uint32_t *inout)
 {
        uint32_t *result, *ptr;
        uint i;
+       int j, k;
 
        /* Sanity check for stack size - key->len is in 32-bit words */
        if (key->len > RSA_MAX_KEY_BITS / 32) {
@@ -141,18 +187,48 @@ static int pow_mod(const struct rsa_public_key *key, uint32_t *inout)
        }
 
        uint32_t val[key->len], acc[key->len], tmp[key->len];
+       uint32_t a_scaled[key->len];
        result = tmp;  /* Re-use location. */
 
        /* Convert from big endian byte array to little endian word array. */
        for (i = 0, ptr = inout + key->len - 1; i < key->len; i++, ptr--)
                val[i] = get_unaligned_be32(ptr);
 
-       montgomery_mul(key, acc, val, key->rr);  /* axx = a * RR / R mod M */
-       for (i = 0; i < 16; i += 2) {
-               montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod M */
-               montgomery_mul(key, acc, tmp, tmp); /* acc = tmp^2 / R mod M */
+       if (0 != num_public_exponent_bits(key, &k))
+               return -EINVAL;
+
+       if (k < 2) {
+               debug("Public exponent is too short (%d bits, minimum 2)\n",
+                     k);
+               return -EINVAL;
        }
-       montgomery_mul(key, result, acc, val);  /* result = XX * a / R mod M */
+
+       if (!is_public_exponent_bit_set(key, 0)) {
+               debug("LSB of RSA public exponent must be set.\n");
+               return -EINVAL;
+       }
+
+       /* the bit at e[k-1] is 1 by definition, so start with: C := M */
+       montgomery_mul(key, acc, val, key->rr); /* acc = a * RR / R mod n */
+       /* retain scaled version for intermediate use */
+       memcpy(a_scaled, acc, key->len * sizeof(a_scaled[0]));
+
+       for (j = k - 2; j > 0; --j) {
+               montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */
+
+               if (is_public_exponent_bit_set(key, j)) {
+                       /* acc = tmp * val / R mod n */
+                       montgomery_mul(key, acc, tmp, a_scaled);
+               } else {
+                       /* e[j] == 0, copy tmp back to acc for next operation */
+                       memcpy(acc, tmp, key->len * sizeof(acc[0]));
+               }
+       }
+
+       /* the bit at e[0] is always 1 */
+       montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod n */
+       montgomery_mul(key, acc, tmp, val); /* acc = tmp * a / R mod M */
+       memcpy(result, acc, key->len * sizeof(result[0]));
 
        /* Make sure result < mod; result is at most 1x mod too large. */
        if (greater_equal_modulus(key, result))
@@ -229,6 +305,8 @@ static int rsa_verify_with_keynode(struct image_sign_info *info,
        const void *blob = info->fdt_blob;
        struct rsa_public_key key;
        const void *modulus, *rr;
+       const uint64_t *public_exponent;
+       int length;
        int ret;
 
        if (node < 0) {
@@ -241,6 +319,11 @@ static int rsa_verify_with_keynode(struct image_sign_info *info,
        }
        key.len = fdtdec_get_int(blob, node, "rsa,num-bits", 0);
        key.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0);
+       public_exponent = fdt_getprop(blob, node, "rsa,exponent", &length);
+       if (!public_exponent || length < sizeof(*public_exponent))
+               key.exponent = RSA_DEFAULT_PUBEXP;
+       else
+               key.exponent = fdt64_to_cpu(*public_exponent);
        modulus = fdt_getprop(blob, node, "rsa,modulus", NULL);
        rr = fdt_getprop(blob, node, "rsa,r-squared", NULL);
        if (!key.len || !modulus || !rr) {
index fdb97cb56252521237baf7b2f02c94f42724cd8d..a4f6db570c6c956db2e4e18d94b6923f5458ff4e 100644 (file)
 
 #define BOOTP_VENDOR_MAGIC     0x63825363      /* RFC1048 Magic Cookie */
 
-#define TIMEOUT                5000UL  /* Milliseconds before trying BOOTP again */
+/*
+ * The timeout for the initial BOOTP/DHCP request used to be described by a
+ * counter of fixed-length timeout periods. TIMEOUT_COUNT represents
+ * that counter
+ *
+ * Now that the timeout periods are variable (exponential backoff and retry)
+ * we convert the timeout count to the absolute time it would have take to
+ * execute that many retries, and keep sending retry packets until that time
+ * is reached.
+ */
 #ifndef CONFIG_NET_RETRY_COUNT
 # define TIMEOUT_COUNT 5               /* # of timeouts before giving up */
 #else
 # define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT)
 #endif
+#define TIMEOUT_MS     ((3 + (TIMEOUT_COUNT * 5)) * 1000)
 
 #define PORT_BOOTPS    67              /* BOOTP server UDP port */
 #define PORT_BOOTPC    68              /* BOOTP client UDP port */
@@ -39,6 +49,8 @@
 
 ulong          BootpID;
 int            BootpTry;
+ulong          bootp_start;
+ulong          bootp_timeout;
 
 #if defined(CONFIG_CMD_DHCP)
 static dhcp_state_t dhcp_state = INIT;
@@ -327,16 +339,21 @@ BootpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
 static void
 BootpTimeout(void)
 {
-       if (BootpTry >= TIMEOUT_COUNT) {
+       ulong time_taken = get_timer(bootp_start);
+
+       if (time_taken >= TIMEOUT_MS) {
 #ifdef CONFIG_BOOTP_MAY_FAIL
-               puts("\nRetry count exceeded\n");
+               puts("\nRetry time exceeded\n");
                net_set_state(NETLOOP_FAIL);
 #else
-               puts("\nRetry count exceeded; starting again\n");
+               puts("\nRetry time exceeded; starting again\n");
                NetStartAgain();
 #endif
        } else {
-               NetSetTimeout(TIMEOUT, BootpTimeout);
+               bootp_timeout *= 2;
+               if (bootp_timeout > 1000)
+                       bootp_timeout = 1000;
+               NetSetTimeout(bootp_timeout, BootpTimeout);
                BootpRequest();
        }
 }
@@ -597,6 +614,13 @@ static int BootpExtended(u8 *e)
 }
 #endif
 
+void BootpReset(void)
+{
+       BootpTry = 0;
+       bootp_start = get_timer(0);
+       bootp_timeout = 10;
+}
+
 void
 BootpRequest(void)
 {
@@ -685,7 +709,7 @@ BootpRequest(void)
        iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
        pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
        net_set_udp_header(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
-       NetSetTimeout(SELECT_TIMEOUT, BootpTimeout);
+       NetSetTimeout(bootp_timeout, BootpTimeout);
 
 #if defined(CONFIG_CMD_DHCP)
        dhcp_state = SELECTING;
@@ -918,7 +942,7 @@ DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
                                                htonl(BOOTP_VENDOR_MAGIC))
                                DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);
 
-                       NetSetTimeout(TIMEOUT, BootpTimeout);
+                       NetSetTimeout(5000, BootpTimeout);
                        DhcpSendRequestPkt(bp);
 #ifdef CONFIG_SYS_BOOTFILE_PREFIX
                }
index ecbcc4d5093c3dd4b2ba5e4b89e200bd32fe22d8..3b95a0a2ded87596636516c3b1b865aa79cf3aaf 100644 (file)
@@ -65,6 +65,7 @@ extern int    BootpTry;
 
 
 /* Send a BOOTP request */
+extern void BootpReset(void);
 extern void BootpRequest(void);
 
 /****************** DHCP Support *********************/
@@ -88,8 +89,6 @@ typedef enum { INIT,
 #define DHCP_NAK      6
 #define DHCP_RELEASE  7
 
-#define SELECT_TIMEOUT 3000UL  /* Milliseconds to wait for offers */
-
 /**********************************************************************/
 
 #endif /* __BOOTP_H__ */
index 0f7625fde1dc52de2df5fb3ecd91589db24c7c56..722089f3b931b58eb1fef6a766a5847ff78c3747 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -385,14 +385,14 @@ restart:
 #endif
 #if defined(CONFIG_CMD_DHCP)
                case DHCP:
-                       BootpTry = 0;
+                       BootpReset();
                        NetOurIP = 0;
                        DhcpRequest();          /* Basically same as BOOTP */
                        break;
 #endif
 
                case BOOTP:
-                       BootpTry = 0;
+                       BootpReset();
                        NetOurIP = 0;
                        BootpRequest();
                        break;
diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
new file mode 100755 (executable)
index 0000000..7717d68
--- /dev/null
@@ -0,0 +1,2270 @@
+#!/usr/bin/perl -w
+# (c) 2007, Joe Perches <joe@perches.com>
+#           created from checkpatch.pl
+#
+# Print selected MAINTAINERS information for
+# the files modified in a patch or for a file
+#
+# usage: perl scripts/get_maintainer.pl [OPTIONS] <patch>
+#        perl scripts/get_maintainer.pl [OPTIONS] -f <file>
+#
+# Licensed under the terms of the GNU GPL License version 2
+
+use strict;
+
+my $P = $0;
+my $V = '0.26';
+
+use Getopt::Long qw(:config no_auto_abbrev);
+use File::Find;
+
+my $lk_path = "./";
+my $email = 1;
+my $email_usename = 1;
+my $email_maintainer = 1;
+my $email_list = 1;
+my $email_subscriber_list = 0;
+my $email_git_penguin_chiefs = 0;
+my $email_git = 0;
+my $email_git_all_signature_types = 0;
+my $email_git_blame = 0;
+my $email_git_blame_signatures = 1;
+my $email_git_fallback = 1;
+my $email_git_min_signatures = 1;
+my $email_git_max_maintainers = 5;
+my $email_git_min_percent = 5;
+my $email_git_since = "1-year-ago";
+my $email_hg_since = "-365";
+my $interactive = 0;
+my $email_remove_duplicates = 1;
+my $email_use_mailmap = 1;
+my $output_multiline = 1;
+my $output_separator = ", ";
+my $output_roles = 0;
+my $output_rolestats = 1;
+my $scm = 0;
+my $web = 0;
+my $subsystem = 0;
+my $status = 0;
+my $keywords = 1;
+my $sections = 0;
+my $file_emails = 0;
+my $from_filename = 0;
+my $pattern_depth = 0;
+my $version = 0;
+my $help = 0;
+
+my $vcs_used = 0;
+
+my $exit = 0;
+
+my %commit_author_hash;
+my %commit_signer_hash;
+
+my @penguin_chief = ();
+push(@penguin_chief, "Tom Rini:trini\@ti.com");
+
+my @penguin_chief_names = ();
+foreach my $chief (@penguin_chief) {
+    if ($chief =~ m/^(.*):(.*)/) {
+       my $chief_name = $1;
+       my $chief_addr = $2;
+       push(@penguin_chief_names, $chief_name);
+    }
+}
+my $penguin_chiefs = "\(" . join("|", @penguin_chief_names) . "\)";
+
+# Signature types of people who are either
+#      a) responsible for the code in question, or
+#      b) familiar enough with it to give relevant feedback
+my @signature_tags = ();
+push(@signature_tags, "Signed-off-by:");
+push(@signature_tags, "Reviewed-by:");
+push(@signature_tags, "Acked-by:");
+
+my $signature_pattern = "\(" . join("|", @signature_tags) . "\)";
+
+# rfc822 email address - preloaded methods go here.
+my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])";
+my $rfc822_char = '[\\000-\\377]';
+
+# VCS command support: class-like functions and strings
+
+my %VCS_cmds;
+
+my %VCS_cmds_git = (
+    "execute_cmd" => \&git_execute_cmd,
+    "available" => '(which("git") ne "") && (-e ".git")',
+    "find_signers_cmd" =>
+       "git log --no-color --follow --since=\$email_git_since " .
+           '--numstat --no-merges ' .
+           '--format="GitCommit: %H%n' .
+                     'GitAuthor: %an <%ae>%n' .
+                     'GitDate: %aD%n' .
+                     'GitSubject: %s%n' .
+                     '%b%n"' .
+           " -- \$file",
+    "find_commit_signers_cmd" =>
+       "git log --no-color " .
+           '--numstat ' .
+           '--format="GitCommit: %H%n' .
+                     'GitAuthor: %an <%ae>%n' .
+                     'GitDate: %aD%n' .
+                     'GitSubject: %s%n' .
+                     '%b%n"' .
+           " -1 \$commit",
+    "find_commit_author_cmd" =>
+       "git log --no-color " .
+           '--numstat ' .
+           '--format="GitCommit: %H%n' .
+                     'GitAuthor: %an <%ae>%n' .
+                     'GitDate: %aD%n' .
+                     'GitSubject: %s%n"' .
+           " -1 \$commit",
+    "blame_range_cmd" => "git blame -l -L \$diff_start,+\$diff_length \$file",
+    "blame_file_cmd" => "git blame -l \$file",
+    "commit_pattern" => "^GitCommit: ([0-9a-f]{40,40})",
+    "blame_commit_pattern" => "^([0-9a-f]+) ",
+    "author_pattern" => "^GitAuthor: (.*)",
+    "subject_pattern" => "^GitSubject: (.*)",
+    "stat_pattern" => "^(\\d+)\\t(\\d+)\\t\$file\$",
+);
+
+my %VCS_cmds_hg = (
+    "execute_cmd" => \&hg_execute_cmd,
+    "available" => '(which("hg") ne "") && (-d ".hg")',
+    "find_signers_cmd" =>
+       "hg log --date=\$email_hg_since " .
+           "--template='HgCommit: {node}\\n" .
+                       "HgAuthor: {author}\\n" .
+                       "HgSubject: {desc}\\n'" .
+           " -- \$file",
+    "find_commit_signers_cmd" =>
+       "hg log " .
+           "--template='HgSubject: {desc}\\n'" .
+           " -r \$commit",
+    "find_commit_author_cmd" =>
+       "hg log " .
+           "--template='HgCommit: {node}\\n" .
+                       "HgAuthor: {author}\\n" .
+                       "HgSubject: {desc|firstline}\\n'" .
+           " -r \$commit",
+    "blame_range_cmd" => "",           # not supported
+    "blame_file_cmd" => "hg blame -n \$file",
+    "commit_pattern" => "^HgCommit: ([0-9a-f]{40,40})",
+    "blame_commit_pattern" => "^([ 0-9a-f]+):",
+    "author_pattern" => "^HgAuthor: (.*)",
+    "subject_pattern" => "^HgSubject: (.*)",
+    "stat_pattern" => "^(\\d+)\t(\\d+)\t\$file\$",
+);
+
+my $conf = which_conf(".get_maintainer.conf");
+if (-f $conf) {
+    my @conf_args;
+    open(my $conffile, '<', "$conf")
+       or warn "$P: Can't find a readable .get_maintainer.conf file $!\n";
+
+    while (<$conffile>) {
+       my $line = $_;
+
+       $line =~ s/\s*\n?$//g;
+       $line =~ s/^\s*//g;
+       $line =~ s/\s+/ /g;
+
+       next if ($line =~ m/^\s*#/);
+       next if ($line =~ m/^\s*$/);
+
+       my @words = split(" ", $line);
+       foreach my $word (@words) {
+           last if ($word =~ m/^#/);
+           push (@conf_args, $word);
+       }
+    }
+    close($conffile);
+    unshift(@ARGV, @conf_args) if @conf_args;
+}
+
+if (!GetOptions(
+               'email!' => \$email,
+               'git!' => \$email_git,
+               'git-all-signature-types!' => \$email_git_all_signature_types,
+               'git-blame!' => \$email_git_blame,
+               'git-blame-signatures!' => \$email_git_blame_signatures,
+               'git-fallback!' => \$email_git_fallback,
+               'git-chief-penguins!' => \$email_git_penguin_chiefs,
+               'git-min-signatures=i' => \$email_git_min_signatures,
+               'git-max-maintainers=i' => \$email_git_max_maintainers,
+               'git-min-percent=i' => \$email_git_min_percent,
+               'git-since=s' => \$email_git_since,
+               'hg-since=s' => \$email_hg_since,
+               'i|interactive!' => \$interactive,
+               'remove-duplicates!' => \$email_remove_duplicates,
+               'mailmap!' => \$email_use_mailmap,
+               'm!' => \$email_maintainer,
+               'n!' => \$email_usename,
+               'l!' => \$email_list,
+               's!' => \$email_subscriber_list,
+               'multiline!' => \$output_multiline,
+               'roles!' => \$output_roles,
+               'rolestats!' => \$output_rolestats,
+               'separator=s' => \$output_separator,
+               'subsystem!' => \$subsystem,
+               'status!' => \$status,
+               'scm!' => \$scm,
+               'web!' => \$web,
+               'pattern-depth=i' => \$pattern_depth,
+               'k|keywords!' => \$keywords,
+               'sections!' => \$sections,
+               'fe|file-emails!' => \$file_emails,
+               'f|file' => \$from_filename,
+               'v|version' => \$version,
+               'h|help|usage' => \$help,
+               )) {
+    die "$P: invalid argument - use --help if necessary\n";
+}
+
+if ($help != 0) {
+    usage();
+    exit 0;
+}
+
+if ($version != 0) {
+    print("${P} ${V}\n");
+    exit 0;
+}
+
+if (-t STDIN && !@ARGV) {
+    # We're talking to a terminal, but have no command line arguments.
+    die "$P: missing patchfile or -f file - use --help if necessary\n";
+}
+
+$output_multiline = 0 if ($output_separator ne ", ");
+$output_rolestats = 1 if ($interactive);
+$output_roles = 1 if ($output_rolestats);
+
+if ($sections) {
+    $email = 0;
+    $email_list = 0;
+    $scm = 0;
+    $status = 0;
+    $subsystem = 0;
+    $web = 0;
+    $keywords = 0;
+    $interactive = 0;
+} else {
+    my $selections = $email + $scm + $status + $subsystem + $web;
+    if ($selections == 0) {
+       die "$P:  Missing required option: email, scm, status, subsystem or web\n";
+    }
+}
+
+if ($email &&
+    ($email_maintainer + $email_list + $email_subscriber_list +
+     $email_git + $email_git_penguin_chiefs + $email_git_blame) == 0) {
+    die "$P: Please select at least 1 email option\n";
+}
+
+if (!top_of_kernel_tree($lk_path)) {
+    die "$P: The current directory does not appear to be "
+       . "a linux kernel source tree.\n";
+}
+
+## Read MAINTAINERS for type/value pairs
+
+my @typevalue = ();
+my %keyword_hash;
+
+my @maint_files = ();
+push(@maint_files, "${lk_path}MAINTAINERS");
+
+sub maint_wanted {
+    return unless $_ =~ /^MAINTAINERS/;
+    push(@maint_files, "$File::Find::name");
+}
+
+File::Find::find(\&maint_wanted, "${lk_path}board");
+
+foreach my $maint_file (@maint_files) {
+    my $maint;
+    open ($maint, '<', "$maint_file")
+       or die "$P: Can't open $maint_file: $!\n";
+    read_maintainers($maint);
+    close($maint);
+}
+
+sub read_maintainers {
+    my ($maint) = @_;
+
+    while (<$maint>) {
+       my $line = $_;
+
+       if ($line =~ m/^(\C):\s*(.*)/) {
+           my $type = $1;
+           my $value = $2;
+
+           ##Filename pattern matching
+           if ($type eq "F" || $type eq "X") {
+               $value =~ s@\.@\\\.@g;       ##Convert . to \.
+               $value =~ s/\*/\.\*/g;       ##Convert * to .*
+               $value =~ s/\?/\./g;         ##Convert ? to .
+               ##if pattern is a directory and it lacks a trailing slash, add one
+               if ((-d $value)) {
+                   $value =~ s@([^/])$@$1/@;
+               }
+           } elsif ($type eq "K") {
+               $keyword_hash{@typevalue} = $value;
+           }
+           push(@typevalue, "$type:$value");
+       } elsif (!/^(\s)*$/) {
+           $line =~ s/\n$//g;
+           push(@typevalue, $line);
+       }
+    }
+}
+
+
+#
+# Read mail address map
+#
+
+my $mailmap;
+
+read_mailmap();
+
+sub read_mailmap {
+    $mailmap = {
+       names => {},
+       addresses => {}
+    };
+
+    return if (!$email_use_mailmap || !(-f "${lk_path}.mailmap"));
+
+    open(my $mailmap_file, '<', "${lk_path}.mailmap")
+       or warn "$P: Can't open .mailmap: $!\n";
+
+    while (<$mailmap_file>) {
+       s/#.*$//; #strip comments
+       s/^\s+|\s+$//g; #trim
+
+       next if (/^\s*$/); #skip empty lines
+       #entries have one of the following formats:
+       # name1 <mail1>
+       # <mail1> <mail2>
+       # name1 <mail1> <mail2>
+       # name1 <mail1> name2 <mail2>
+       # (see man git-shortlog)
+
+       if (/^([^<]+)<([^>]+)>$/) {
+           my $real_name = $1;
+           my $address = $2;
+
+           $real_name =~ s/\s+$//;
+           ($real_name, $address) = parse_email("$real_name <$address>");
+           $mailmap->{names}->{$address} = $real_name;
+
+       } elsif (/^<([^>]+)>\s*<([^>]+)>$/) {
+           my $real_address = $1;
+           my $wrong_address = $2;
+
+           $mailmap->{addresses}->{$wrong_address} = $real_address;
+
+       } elsif (/^(.+)<([^>]+)>\s*<([^>]+)>$/) {
+           my $real_name = $1;
+           my $real_address = $2;
+           my $wrong_address = $3;
+
+           $real_name =~ s/\s+$//;
+           ($real_name, $real_address) =
+               parse_email("$real_name <$real_address>");
+           $mailmap->{names}->{$wrong_address} = $real_name;
+           $mailmap->{addresses}->{$wrong_address} = $real_address;
+
+       } elsif (/^(.+)<([^>]+)>\s*(.+)\s*<([^>]+)>$/) {
+           my $real_name = $1;
+           my $real_address = $2;
+           my $wrong_name = $3;
+           my $wrong_address = $4;
+
+           $real_name =~ s/\s+$//;
+           ($real_name, $real_address) =
+               parse_email("$real_name <$real_address>");
+
+           $wrong_name =~ s/\s+$//;
+           ($wrong_name, $wrong_address) =
+               parse_email("$wrong_name <$wrong_address>");
+
+           my $wrong_email = format_email($wrong_name, $wrong_address, 1);
+           $mailmap->{names}->{$wrong_email} = $real_name;
+           $mailmap->{addresses}->{$wrong_email} = $real_address;
+       }
+    }
+    close($mailmap_file);
+}
+
+## use the filenames on the command line or find the filenames in the patchfiles
+
+my @files = ();
+my @range = ();
+my @keyword_tvi = ();
+my @file_emails = ();
+
+if (!@ARGV) {
+    push(@ARGV, "&STDIN");
+}
+
+foreach my $file (@ARGV) {
+    if ($file ne "&STDIN") {
+       ##if $file is a directory and it lacks a trailing slash, add one
+       if ((-d $file)) {
+           $file =~ s@([^/])$@$1/@;
+       } elsif (!(-f $file)) {
+           die "$P: file '${file}' not found\n";
+       }
+    }
+    if ($from_filename) {
+       push(@files, $file);
+       if ($file ne "MAINTAINERS" && -f $file && ($keywords || $file_emails)) {
+           open(my $f, '<', $file)
+               or die "$P: Can't open $file: $!\n";
+           my $text = do { local($/) ; <$f> };
+           close($f);
+           if ($keywords) {
+               foreach my $line (keys %keyword_hash) {
+                   if ($text =~ m/$keyword_hash{$line}/x) {
+                       push(@keyword_tvi, $line);
+                   }
+               }
+           }
+           if ($file_emails) {
+               my @poss_addr = $text =~ m$[A-Za-zÀ-ÿ\"\' \,\.\+-]*\s*[\,]*\s*[\(\<\{]{0,1}[A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+\.[A-Za-z0-9]+[\)\>\}]{0,1}$g;
+               push(@file_emails, clean_file_emails(@poss_addr));
+           }
+       }
+    } else {
+       my $file_cnt = @files;
+       my $lastfile;
+
+       open(my $patch, "< $file")
+           or die "$P: Can't open $file: $!\n";
+
+       # We can check arbitrary information before the patch
+       # like the commit message, mail headers, etc...
+       # This allows us to match arbitrary keywords against any part
+       # of a git format-patch generated file (subject tags, etc...)
+
+       my $patch_prefix = "";                  #Parsing the intro
+
+       while (<$patch>) {
+           my $patch_line = $_;
+           if (m/^\+\+\+\s+(\S+)/ or m/^---\s+(\S+)/) {
+               my $filename = $1;
+               $filename =~ s@^[^/]*/@@;
+               $filename =~ s@\n@@;
+               $lastfile = $filename;
+               push(@files, $filename);
+               $patch_prefix = "^[+-].*";      #Now parsing the actual patch
+           } elsif (m/^\@\@ -(\d+),(\d+)/) {
+               if ($email_git_blame) {
+                   push(@range, "$lastfile:$1:$2");
+               }
+           } elsif ($keywords) {
+               foreach my $line (keys %keyword_hash) {
+                   if ($patch_line =~ m/${patch_prefix}$keyword_hash{$line}/x) {
+                       push(@keyword_tvi, $line);
+                   }
+               }
+           }
+       }
+       close($patch);
+
+       if ($file_cnt == @files) {
+           warn "$P: file '${file}' doesn't appear to be a patch.  "
+               . "Add -f to options?\n";
+       }
+       @files = sort_and_uniq(@files);
+    }
+}
+
+@file_emails = uniq(@file_emails);
+
+my %email_hash_name;
+my %email_hash_address;
+my @email_to = ();
+my %hash_list_to;
+my @list_to = ();
+my @scm = ();
+my @web = ();
+my @subsystem = ();
+my @status = ();
+my %deduplicate_name_hash = ();
+my %deduplicate_address_hash = ();
+
+my @maintainers = get_maintainers();
+
+if (@maintainers) {
+    @maintainers = merge_email(@maintainers);
+    output(@maintainers);
+}
+
+if ($scm) {
+    @scm = uniq(@scm);
+    output(@scm);
+}
+
+if ($status) {
+    @status = uniq(@status);
+    output(@status);
+}
+
+if ($subsystem) {
+    @subsystem = uniq(@subsystem);
+    output(@subsystem);
+}
+
+if ($web) {
+    @web = uniq(@web);
+    output(@web);
+}
+
+exit($exit);
+
+sub range_is_maintained {
+    my ($start, $end) = @_;
+
+    for (my $i = $start; $i < $end; $i++) {
+       my $line = $typevalue[$i];
+       if ($line =~ m/^(\C):\s*(.*)/) {
+           my $type = $1;
+           my $value = $2;
+           if ($type eq 'S') {
+               if ($value =~ /(maintain|support)/i) {
+                   return 1;
+               }
+           }
+       }
+    }
+    return 0;
+}
+
+sub range_has_maintainer {
+    my ($start, $end) = @_;
+
+    for (my $i = $start; $i < $end; $i++) {
+       my $line = $typevalue[$i];
+       if ($line =~ m/^(\C):\s*(.*)/) {
+           my $type = $1;
+           my $value = $2;
+           if ($type eq 'M') {
+               return 1;
+           }
+       }
+    }
+    return 0;
+}
+
+sub get_maintainers {
+    %email_hash_name = ();
+    %email_hash_address = ();
+    %commit_author_hash = ();
+    %commit_signer_hash = ();
+    @email_to = ();
+    %hash_list_to = ();
+    @list_to = ();
+    @scm = ();
+    @web = ();
+    @subsystem = ();
+    @status = ();
+    %deduplicate_name_hash = ();
+    %deduplicate_address_hash = ();
+    if ($email_git_all_signature_types) {
+       $signature_pattern = "(.+?)[Bb][Yy]:";
+    } else {
+       $signature_pattern = "\(" . join("|", @signature_tags) . "\)";
+    }
+
+    # Find responsible parties
+
+    my %exact_pattern_match_hash = ();
+
+    foreach my $file (@files) {
+
+       my %hash;
+       my $tvi = find_first_section();
+       while ($tvi < @typevalue) {
+           my $start = find_starting_index($tvi);
+           my $end = find_ending_index($tvi);
+           my $exclude = 0;
+           my $i;
+
+           #Do not match excluded file patterns
+
+           for ($i = $start; $i < $end; $i++) {
+               my $line = $typevalue[$i];
+               if ($line =~ m/^(\C):\s*(.*)/) {
+                   my $type = $1;
+                   my $value = $2;
+                   if ($type eq 'X') {
+                       if (file_match_pattern($file, $value)) {
+                           $exclude = 1;
+                           last;
+                       }
+                   }
+               }
+           }
+
+           if (!$exclude) {
+               for ($i = $start; $i < $end; $i++) {
+                   my $line = $typevalue[$i];
+                   if ($line =~ m/^(\C):\s*(.*)/) {
+                       my $type = $1;
+                       my $value = $2;
+                       if ($type eq 'F') {
+                           if (file_match_pattern($file, $value)) {
+                               my $value_pd = ($value =~ tr@/@@);
+                               my $file_pd = ($file  =~ tr@/@@);
+                               $value_pd++ if (substr($value,-1,1) ne "/");
+                               $value_pd = -1 if ($value =~ /^\.\*/);
+                               if ($value_pd >= $file_pd &&
+                                   range_is_maintained($start, $end) &&
+                                   range_has_maintainer($start, $end)) {
+                                   $exact_pattern_match_hash{$file} = 1;
+                               }
+                               if ($pattern_depth == 0 ||
+                                   (($file_pd - $value_pd) < $pattern_depth)) {
+                                   $hash{$tvi} = $value_pd;
+                               }
+                           }
+                       } elsif ($type eq 'N') {
+                           if ($file =~ m/$value/x) {
+                               $hash{$tvi} = 0;
+                           }
+                       }
+                   }
+               }
+           }
+           $tvi = $end + 1;
+       }
+
+       foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
+           add_categories($line);
+           if ($sections) {
+               my $i;
+               my $start = find_starting_index($line);
+               my $end = find_ending_index($line);
+               for ($i = $start; $i < $end; $i++) {
+                   my $line = $typevalue[$i];
+                   if ($line =~ /^[FX]:/) {            ##Restore file patterns
+                       $line =~ s/([^\\])\.([^\*])/$1\?$2/g;
+                       $line =~ s/([^\\])\.$/$1\?/g;   ##Convert . back to ?
+                       $line =~ s/\\\./\./g;           ##Convert \. to .
+                       $line =~ s/\.\*/\*/g;           ##Convert .* to *
+                   }
+                   $line =~ s/^([A-Z]):/$1:\t/g;
+                   print("$line\n");
+               }
+               print("\n");
+           }
+       }
+    }
+
+    if ($keywords) {
+       @keyword_tvi = sort_and_uniq(@keyword_tvi);
+       foreach my $line (@keyword_tvi) {
+           add_categories($line);
+       }
+    }
+
+    foreach my $email (@email_to, @list_to) {
+       $email->[0] = deduplicate_email($email->[0]);
+    }
+
+    foreach my $file (@files) {
+       if ($email &&
+           ($email_git || ($email_git_fallback &&
+                           !$exact_pattern_match_hash{$file}))) {
+           vcs_file_signoffs($file);
+       }
+       if ($email && $email_git_blame) {
+           vcs_file_blame($file);
+       }
+    }
+
+    if ($email) {
+       foreach my $chief (@penguin_chief) {
+           if ($chief =~ m/^(.*):(.*)/) {
+               my $email_address;
+
+               $email_address = format_email($1, $2, $email_usename);
+               if ($email_git_penguin_chiefs) {
+                   push(@email_to, [$email_address, 'chief penguin']);
+               } else {
+                   @email_to = grep($_->[0] !~ /${email_address}/, @email_to);
+               }
+           }
+       }
+
+       foreach my $email (@file_emails) {
+           my ($name, $address) = parse_email($email);
+
+           my $tmp_email = format_email($name, $address, $email_usename);
+           push_email_address($tmp_email, '');
+           add_role($tmp_email, 'in file');
+       }
+    }
+
+    my @to = ();
+    if ($email || $email_list) {
+       if ($email) {
+           @to = (@to, @email_to);
+       }
+       if ($email_list) {
+           @to = (@to, @list_to);
+       }
+    }
+
+    if ($interactive) {
+       @to = interactive_get_maintainers(\@to);
+    }
+
+    return @to;
+}
+
+sub file_match_pattern {
+    my ($file, $pattern) = @_;
+    if (substr($pattern, -1) eq "/") {
+       if ($file =~ m@^$pattern@) {
+           return 1;
+       }
+    } else {
+       if ($file =~ m@^$pattern@) {
+           my $s1 = ($file =~ tr@/@@);
+           my $s2 = ($pattern =~ tr@/@@);
+           if ($s1 == $s2) {
+               return 1;
+           }
+       }
+    }
+    return 0;
+}
+
+sub usage {
+    print <<EOT;
+usage: $P [options] patchfile
+       $P [options] -f file|directory
+version: $V
+
+MAINTAINER field selection options:
+  --email => print email address(es) if any
+    --git => include recent git \*-by: signers
+    --git-all-signature-types => include signers regardless of signature type
+        or use only ${signature_pattern} signers (default: $email_git_all_signature_types)
+    --git-fallback => use git when no exact MAINTAINERS pattern (default: $email_git_fallback)
+    --git-chief-penguins => include ${penguin_chiefs}
+    --git-min-signatures => number of signatures required (default: $email_git_min_signatures)
+    --git-max-maintainers => maximum maintainers to add (default: $email_git_max_maintainers)
+    --git-min-percent => minimum percentage of commits required (default: $email_git_min_percent)
+    --git-blame => use git blame to find modified commits for patch or file
+    --git-since => git history to use (default: $email_git_since)
+    --hg-since => hg history to use (default: $email_hg_since)
+    --interactive => display a menu (mostly useful if used with the --git option)
+    --m => include maintainer(s) if any
+    --n => include name 'Full Name <addr\@domain.tld>'
+    --l => include list(s) if any
+    --s => include subscriber only list(s) if any
+    --remove-duplicates => minimize duplicate email names/addresses
+    --roles => show roles (status:subsystem, git-signer, list, etc...)
+    --rolestats => show roles and statistics (commits/total_commits, %)
+    --file-emails => add email addresses found in -f file (default: 0 (off))
+  --scm => print SCM tree(s) if any
+  --status => print status if any
+  --subsystem => print subsystem name if any
+  --web => print website(s) if any
+
+Output type options:
+  --separator [, ] => separator for multiple entries on 1 line
+    using --separator also sets --nomultiline if --separator is not [, ]
+  --multiline => print 1 entry per line
+
+Other options:
+  --pattern-depth => Number of pattern directory traversals (default: 0 (all))
+  --keywords => scan patch for keywords (default: $keywords)
+  --sections => print all of the subsystem sections with pattern matches
+  --mailmap => use .mailmap file (default: $email_use_mailmap)
+  --version => show version
+  --help => show this help information
+
+Default options:
+  [--email --nogit --git-fallback --m --n --l --multiline -pattern-depth=0
+   --remove-duplicates --rolestats]
+
+Notes:
+  Using "-f directory" may give unexpected results:
+      Used with "--git", git signators for _all_ files in and below
+          directory are examined as git recurses directories.
+          Any specified X: (exclude) pattern matches are _not_ ignored.
+      Used with "--nogit", directory is used as a pattern match,
+          no individual file within the directory or subdirectory
+          is matched.
+      Used with "--git-blame", does not iterate all files in directory
+  Using "--git-blame" is slow and may add old committers and authors
+      that are no longer active maintainers to the output.
+  Using "--roles" or "--rolestats" with git send-email --cc-cmd or any
+      other automated tools that expect only ["name"] <email address>
+      may not work because of additional output after <email address>.
+  Using "--rolestats" and "--git-blame" shows the #/total=% commits,
+      not the percentage of the entire file authored.  # of commits is
+      not a good measure of amount of code authored.  1 major commit may
+      contain a thousand lines, 5 trivial commits may modify a single line.
+  If git is not installed, but mercurial (hg) is installed and an .hg
+      repository exists, the following options apply to mercurial:
+          --git,
+          --git-min-signatures, --git-max-maintainers, --git-min-percent, and
+          --git-blame
+      Use --hg-since not --git-since to control date selection
+  File ".get_maintainer.conf", if it exists in the linux kernel source root
+      directory, can change whatever get_maintainer defaults are desired.
+      Entries in this file can be any command line argument.
+      This file is prepended to any additional command line arguments.
+      Multiple lines and # comments are allowed.
+EOT
+}
+
+sub top_of_kernel_tree {
+    my ($lk_path) = @_;
+
+    if ($lk_path ne "" && substr($lk_path,length($lk_path)-1,1) ne "/") {
+       $lk_path .= "/";
+    }
+    if (   (-f "${lk_path}CREDITS")
+       && (-f "${lk_path}Kbuild")
+       && (-f "${lk_path}MAINTAINERS")
+       && (-f "${lk_path}Makefile")
+       && (-f "${lk_path}README")
+       && (-d "${lk_path}arch")
+       && (-d "${lk_path}board")
+       && (-d "${lk_path}common")
+       && (-d "${lk_path}doc")
+       && (-d "${lk_path}drivers")
+       && (-d "${lk_path}dts")
+       && (-d "${lk_path}fs")
+       && (-d "${lk_path}lib")
+       && (-d "${lk_path}include")
+       && (-d "${lk_path}net")
+       && (-d "${lk_path}post")
+       && (-d "${lk_path}scripts")
+       && (-d "${lk_path}test")
+       && (-d "${lk_path}tools")) {
+       return 1;
+    }
+    return 0;
+}
+
+sub parse_email {
+    my ($formatted_email) = @_;
+
+    my $name = "";
+    my $address = "";
+
+    if ($formatted_email =~ /^([^<]+)<(.+\@.*)>.*$/) {
+       $name = $1;
+       $address = $2;
+    } elsif ($formatted_email =~ /^\s*<(.+\@\S*)>.*$/) {
+       $address = $1;
+    } elsif ($formatted_email =~ /^(.+\@\S*).*$/) {
+       $address = $1;
+    }
+
+    $name =~ s/^\s+|\s+$//g;
+    $name =~ s/^\"|\"$//g;
+    $address =~ s/^\s+|\s+$//g;
+
+    if ($name =~ /[^\w \-]/i) {         ##has "must quote" chars
+       $name =~ s/(?<!\\)"/\\"/g;       ##escape quotes
+       $name = "\"$name\"";
+    }
+
+    return ($name, $address);
+}
+
+sub format_email {
+    my ($name, $address, $usename) = @_;
+
+    my $formatted_email;
+
+    $name =~ s/^\s+|\s+$//g;
+    $name =~ s/^\"|\"$//g;
+    $address =~ s/^\s+|\s+$//g;
+
+    if ($name =~ /[^\w \-]/i) {          ##has "must quote" chars
+       $name =~ s/(?<!\\)"/\\"/g;       ##escape quotes
+       $name = "\"$name\"";
+    }
+
+    if ($usename) {
+       if ("$name" eq "") {
+           $formatted_email = "$address";
+       } else {
+           $formatted_email = "$name <$address>";
+       }
+    } else {
+       $formatted_email = $address;
+    }
+
+    return $formatted_email;
+}
+
+sub find_first_section {
+    my $index = 0;
+
+    while ($index < @typevalue) {
+       my $tv = $typevalue[$index];
+       if (($tv =~ m/^(\C):\s*(.*)/)) {
+           last;
+       }
+       $index++;
+    }
+
+    return $index;
+}
+
+sub find_starting_index {
+    my ($index) = @_;
+
+    while ($index > 0) {
+       my $tv = $typevalue[$index];
+       if (!($tv =~ m/^(\C):\s*(.*)/)) {
+           last;
+       }
+       $index--;
+    }
+
+    return $index;
+}
+
+sub find_ending_index {
+    my ($index) = @_;
+
+    while ($index < @typevalue) {
+       my $tv = $typevalue[$index];
+       if (!($tv =~ m/^(\C):\s*(.*)/)) {
+           last;
+       }
+       $index++;
+    }
+
+    return $index;
+}
+
+sub get_maintainer_role {
+    my ($index) = @_;
+
+    my $i;
+    my $start = find_starting_index($index);
+    my $end = find_ending_index($index);
+
+    my $role = "unknown";
+    my $subsystem = $typevalue[$start];
+    if (length($subsystem) > 20) {
+       $subsystem = substr($subsystem, 0, 17);
+       $subsystem =~ s/\s*$//;
+       $subsystem = $subsystem . "...";
+    }
+
+    for ($i = $start + 1; $i < $end; $i++) {
+       my $tv = $typevalue[$i];
+       if ($tv =~ m/^(\C):\s*(.*)/) {
+           my $ptype = $1;
+           my $pvalue = $2;
+           if ($ptype eq "S") {
+               $role = $pvalue;
+           }
+       }
+    }
+
+    $role = lc($role);
+    if      ($role eq "supported") {
+       $role = "supporter";
+    } elsif ($role eq "maintained") {
+       $role = "maintainer";
+    } elsif ($role eq "odd fixes") {
+       $role = "odd fixer";
+    } elsif ($role eq "orphan") {
+       $role = "orphan minder";
+    } elsif ($role eq "obsolete") {
+       $role = "obsolete minder";
+    } elsif ($role eq "buried alive in reporters") {
+       $role = "chief penguin";
+    }
+
+    return $role . ":" . $subsystem;
+}
+
+sub get_list_role {
+    my ($index) = @_;
+
+    my $i;
+    my $start = find_starting_index($index);
+    my $end = find_ending_index($index);
+
+    my $subsystem = $typevalue[$start];
+    if (length($subsystem) > 20) {
+       $subsystem = substr($subsystem, 0, 17);
+       $subsystem =~ s/\s*$//;
+       $subsystem = $subsystem . "...";
+    }
+
+    if ($subsystem eq "THE REST") {
+       $subsystem = "";
+    }
+
+    return $subsystem;
+}
+
+sub add_categories {
+    my ($index) = @_;
+
+    my $i;
+    my $start = find_starting_index($index);
+    my $end = find_ending_index($index);
+
+    push(@subsystem, $typevalue[$start]);
+
+    for ($i = $start + 1; $i < $end; $i++) {
+       my $tv = $typevalue[$i];
+       if ($tv =~ m/^(\C):\s*(.*)/) {
+           my $ptype = $1;
+           my $pvalue = $2;
+           if ($ptype eq "L") {
+               my $list_address = $pvalue;
+               my $list_additional = "";
+               my $list_role = get_list_role($i);
+
+               if ($list_role ne "") {
+                   $list_role = ":" . $list_role;
+               }
+               if ($list_address =~ m/([^\s]+)\s+(.*)$/) {
+                   $list_address = $1;
+                   $list_additional = $2;
+               }
+               if ($list_additional =~ m/subscribers-only/) {
+                   if ($email_subscriber_list) {
+                       if (!$hash_list_to{lc($list_address)}) {
+                           $hash_list_to{lc($list_address)} = 1;
+                           push(@list_to, [$list_address,
+                                           "subscriber list${list_role}"]);
+                       }
+                   }
+               } else {
+                   if ($email_list) {
+                       if (!$hash_list_to{lc($list_address)}) {
+                           $hash_list_to{lc($list_address)} = 1;
+                           if ($list_additional =~ m/moderated/) {
+                               push(@list_to, [$list_address,
+                                               "moderated list${list_role}"]);
+                           } else {
+                               push(@list_to, [$list_address,
+                                               "open list${list_role}"]);
+                           }
+                       }
+                   }
+               }
+           } elsif ($ptype eq "M") {
+               my ($name, $address) = parse_email($pvalue);
+               if ($name eq "") {
+                   if ($i > 0) {
+                       my $tv = $typevalue[$i - 1];
+                       if ($tv =~ m/^(\C):\s*(.*)/) {
+                           if ($1 eq "P") {
+                               $name = $2;
+                               $pvalue = format_email($name, $address, $email_usename);
+                           }
+                       }
+                   }
+               }
+               if ($email_maintainer) {
+                   my $role = get_maintainer_role($i);
+                   push_email_addresses($pvalue, $role);
+               }
+           } elsif ($ptype eq "T") {
+               push(@scm, $pvalue);
+           } elsif ($ptype eq "W") {
+               push(@web, $pvalue);
+           } elsif ($ptype eq "S") {
+               push(@status, $pvalue);
+           }
+       }
+    }
+}
+
+sub email_inuse {
+    my ($name, $address) = @_;
+
+    return 1 if (($name eq "") && ($address eq ""));
+    return 1 if (($name ne "") && exists($email_hash_name{lc($name)}));
+    return 1 if (($address ne "") && exists($email_hash_address{lc($address)}));
+
+    return 0;
+}
+
+sub push_email_address {
+    my ($line, $role) = @_;
+
+    my ($name, $address) = parse_email($line);
+
+    if ($address eq "") {
+       return 0;
+    }
+
+    if (!$email_remove_duplicates) {
+       push(@email_to, [format_email($name, $address, $email_usename), $role]);
+    } elsif (!email_inuse($name, $address)) {
+       push(@email_to, [format_email($name, $address, $email_usename), $role]);
+       $email_hash_name{lc($name)}++ if ($name ne "");
+       $email_hash_address{lc($address)}++;
+    }
+
+    return 1;
+}
+
+sub push_email_addresses {
+    my ($address, $role) = @_;
+
+    my @address_list = ();
+
+    if (rfc822_valid($address)) {
+       push_email_address($address, $role);
+    } elsif (@address_list = rfc822_validlist($address)) {
+       my $array_count = shift(@address_list);
+       while (my $entry = shift(@address_list)) {
+           push_email_address($entry, $role);
+       }
+    } else {
+       if (!push_email_address($address, $role)) {
+           warn("Invalid MAINTAINERS address: '" . $address . "'\n");
+       }
+    }
+}
+
+sub add_role {
+    my ($line, $role) = @_;
+
+    my ($name, $address) = parse_email($line);
+    my $email = format_email($name, $address, $email_usename);
+
+    foreach my $entry (@email_to) {
+       if ($email_remove_duplicates) {
+           my ($entry_name, $entry_address) = parse_email($entry->[0]);
+           if (($name eq $entry_name || $address eq $entry_address)
+               && ($role eq "" || !($entry->[1] =~ m/$role/))
+           ) {
+               if ($entry->[1] eq "") {
+                   $entry->[1] = "$role";
+               } else {
+                   $entry->[1] = "$entry->[1],$role";
+               }
+           }
+       } else {
+           if ($email eq $entry->[0]
+               && ($role eq "" || !($entry->[1] =~ m/$role/))
+           ) {
+               if ($entry->[1] eq "") {
+                   $entry->[1] = "$role";
+               } else {
+                   $entry->[1] = "$entry->[1],$role";
+               }
+           }
+       }
+    }
+}
+
+sub which {
+    my ($bin) = @_;
+
+    foreach my $path (split(/:/, $ENV{PATH})) {
+       if (-e "$path/$bin") {
+           return "$path/$bin";
+       }
+    }
+
+    return "";
+}
+
+sub which_conf {
+    my ($conf) = @_;
+
+    foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
+       if (-e "$path/$conf") {
+           return "$path/$conf";
+       }
+    }
+
+    return "";
+}
+
+sub mailmap_email {
+    my ($line) = @_;
+
+    my ($name, $address) = parse_email($line);
+    my $email = format_email($name, $address, 1);
+    my $real_name = $name;
+    my $real_address = $address;
+
+    if (exists $mailmap->{names}->{$email} ||
+       exists $mailmap->{addresses}->{$email}) {
+       if (exists $mailmap->{names}->{$email}) {
+           $real_name = $mailmap->{names}->{$email};
+       }
+       if (exists $mailmap->{addresses}->{$email}) {
+           $real_address = $mailmap->{addresses}->{$email};
+       }
+    } else {
+       if (exists $mailmap->{names}->{$address}) {
+           $real_name = $mailmap->{names}->{$address};
+       }
+       if (exists $mailmap->{addresses}->{$address}) {
+           $real_address = $mailmap->{addresses}->{$address};
+       }
+    }
+    return format_email($real_name, $real_address, 1);
+}
+
+sub mailmap {
+    my (@addresses) = @_;
+
+    my @mapped_emails = ();
+    foreach my $line (@addresses) {
+       push(@mapped_emails, mailmap_email($line));
+    }
+    merge_by_realname(@mapped_emails) if ($email_use_mailmap);
+    return @mapped_emails;
+}
+
+sub merge_by_realname {
+    my %address_map;
+    my (@emails) = @_;
+
+    foreach my $email (@emails) {
+       my ($name, $address) = parse_email($email);
+       if (exists $address_map{$name}) {
+           $address = $address_map{$name};
+           $email = format_email($name, $address, 1);
+       } else {
+           $address_map{$name} = $address;
+       }
+    }
+}
+
+sub git_execute_cmd {
+    my ($cmd) = @_;
+    my @lines = ();
+
+    my $output = `$cmd`;
+    $output =~ s/^\s*//gm;
+    @lines = split("\n", $output);
+
+    return @lines;
+}
+
+sub hg_execute_cmd {
+    my ($cmd) = @_;
+    my @lines = ();
+
+    my $output = `$cmd`;
+    @lines = split("\n", $output);
+
+    return @lines;
+}
+
+sub extract_formatted_signatures {
+    my (@signature_lines) = @_;
+
+    my @type = @signature_lines;
+
+    s/\s*(.*):.*/$1/ for (@type);
+
+    # cut -f2- -d":"
+    s/\s*.*:\s*(.+)\s*/$1/ for (@signature_lines);
+
+## Reformat email addresses (with names) to avoid badly written signatures
+
+    foreach my $signer (@signature_lines) {
+       $signer = deduplicate_email($signer);
+    }
+
+    return (\@type, \@signature_lines);
+}
+
+sub vcs_find_signers {
+    my ($cmd, $file) = @_;
+    my $commits;
+    my @lines = ();
+    my @signatures = ();
+    my @authors = ();
+    my @stats = ();
+
+    @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
+
+    my $pattern = $VCS_cmds{"commit_pattern"};
+    my $author_pattern = $VCS_cmds{"author_pattern"};
+    my $stat_pattern = $VCS_cmds{"stat_pattern"};
+
+    $stat_pattern =~ s/(\$\w+)/$1/eeg;         #interpolate $stat_pattern
+
+    $commits = grep(/$pattern/, @lines);       # of commits
+
+    @authors = grep(/$author_pattern/, @lines);
+    @signatures = grep(/^[ \t]*${signature_pattern}.*\@.*$/, @lines);
+    @stats = grep(/$stat_pattern/, @lines);
+
+#    print("stats: <@stats>\n");
+
+    return (0, \@signatures, \@authors, \@stats) if !@signatures;
+
+    save_commits_by_author(@lines) if ($interactive);
+    save_commits_by_signer(@lines) if ($interactive);
+
+    if (!$email_git_penguin_chiefs) {
+       @signatures = grep(!/${penguin_chiefs}/i, @signatures);
+    }
+
+    my ($author_ref, $authors_ref) = extract_formatted_signatures(@authors);
+    my ($types_ref, $signers_ref) = extract_formatted_signatures(@signatures);
+
+    return ($commits, $signers_ref, $authors_ref, \@stats);
+}
+
+sub vcs_find_author {
+    my ($cmd) = @_;
+    my @lines = ();
+
+    @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
+
+    if (!$email_git_penguin_chiefs) {
+       @lines = grep(!/${penguin_chiefs}/i, @lines);
+    }
+
+    return @lines if !@lines;
+
+    my @authors = ();
+    foreach my $line (@lines) {
+       if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
+           my $author = $1;
+           my ($name, $address) = parse_email($author);
+           $author = format_email($name, $address, 1);
+           push(@authors, $author);
+       }
+    }
+
+    save_commits_by_author(@lines) if ($interactive);
+    save_commits_by_signer(@lines) if ($interactive);
+
+    return @authors;
+}
+
+sub vcs_save_commits {
+    my ($cmd) = @_;
+    my @lines = ();
+    my @commits = ();
+
+    @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
+
+    foreach my $line (@lines) {
+       if ($line =~ m/$VCS_cmds{"blame_commit_pattern"}/) {
+           push(@commits, $1);
+       }
+    }
+
+    return @commits;
+}
+
+sub vcs_blame {
+    my ($file) = @_;
+    my $cmd;
+    my @commits = ();
+
+    return @commits if (!(-f $file));
+
+    if (@range && $VCS_cmds{"blame_range_cmd"} eq "") {
+       my @all_commits = ();
+
+       $cmd = $VCS_cmds{"blame_file_cmd"};
+       $cmd =~ s/(\$\w+)/$1/eeg;               #interpolate $cmd
+       @all_commits = vcs_save_commits($cmd);
+
+       foreach my $file_range_diff (@range) {
+           next if (!($file_range_diff =~ m/(.+):(.+):(.+)/));
+           my $diff_file = $1;
+           my $diff_start = $2;
+           my $diff_length = $3;
+           next if ("$file" ne "$diff_file");
+           for (my $i = $diff_start; $i < $diff_start + $diff_length; $i++) {
+               push(@commits, $all_commits[$i]);
+           }
+       }
+    } elsif (@range) {
+       foreach my $file_range_diff (@range) {
+           next if (!($file_range_diff =~ m/(.+):(.+):(.+)/));
+           my $diff_file = $1;
+           my $diff_start = $2;
+           my $diff_length = $3;
+           next if ("$file" ne "$diff_file");
+           $cmd = $VCS_cmds{"blame_range_cmd"};
+           $cmd =~ s/(\$\w+)/$1/eeg;           #interpolate $cmd
+           push(@commits, vcs_save_commits($cmd));
+       }
+    } else {
+       $cmd = $VCS_cmds{"blame_file_cmd"};
+       $cmd =~ s/(\$\w+)/$1/eeg;               #interpolate $cmd
+       @commits = vcs_save_commits($cmd);
+    }
+
+    foreach my $commit (@commits) {
+       $commit =~ s/^\^//g;
+    }
+
+    return @commits;
+}
+
+my $printed_novcs = 0;
+sub vcs_exists {
+    %VCS_cmds = %VCS_cmds_git;
+    return 1 if eval $VCS_cmds{"available"};
+    %VCS_cmds = %VCS_cmds_hg;
+    return 2 if eval $VCS_cmds{"available"};
+    %VCS_cmds = ();
+    if (!$printed_novcs) {
+       warn("$P: No supported VCS found.  Add --nogit to options?\n");
+       warn("Using a git repository produces better results.\n");
+       warn("Try Linus Torvalds' latest git repository using:\n");
+       warn("git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git\n");
+       $printed_novcs = 1;
+    }
+    return 0;
+}
+
+sub vcs_is_git {
+    vcs_exists();
+    return $vcs_used == 1;
+}
+
+sub vcs_is_hg {
+    return $vcs_used == 2;
+}
+
+sub interactive_get_maintainers {
+    my ($list_ref) = @_;
+    my @list = @$list_ref;
+
+    vcs_exists();
+
+    my %selected;
+    my %authored;
+    my %signed;
+    my $count = 0;
+    my $maintained = 0;
+    foreach my $entry (@list) {
+       $maintained = 1 if ($entry->[1] =~ /^(maintainer|supporter)/i);
+       $selected{$count} = 1;
+       $authored{$count} = 0;
+       $signed{$count} = 0;
+       $count++;
+    }
+
+    #menu loop
+    my $done = 0;
+    my $print_options = 0;
+    my $redraw = 1;
+    while (!$done) {
+       $count = 0;
+       if ($redraw) {
+           printf STDERR "\n%1s %2s %-65s",
+                         "*", "#", "email/list and role:stats";
+           if ($email_git ||
+               ($email_git_fallback && !$maintained) ||
+               $email_git_blame) {
+               print STDERR "auth sign";
+           }
+           print STDERR "\n";
+           foreach my $entry (@list) {
+               my $email = $entry->[0];
+               my $role = $entry->[1];
+               my $sel = "";
+               $sel = "*" if ($selected{$count});
+               my $commit_author = $commit_author_hash{$email};
+               my $commit_signer = $commit_signer_hash{$email};
+               my $authored = 0;
+               my $signed = 0;
+               $authored++ for (@{$commit_author});
+               $signed++ for (@{$commit_signer});
+               printf STDERR "%1s %2d %-65s", $sel, $count + 1, $email;
+               printf STDERR "%4d %4d", $authored, $signed
+                   if ($authored > 0 || $signed > 0);
+               printf STDERR "\n     %s\n", $role;
+               if ($authored{$count}) {
+                   my $commit_author = $commit_author_hash{$email};
+                   foreach my $ref (@{$commit_author}) {
+                       print STDERR "     Author: @{$ref}[1]\n";
+                   }
+               }
+               if ($signed{$count}) {
+                   my $commit_signer = $commit_signer_hash{$email};
+                   foreach my $ref (@{$commit_signer}) {
+                       print STDERR "     @{$ref}[2]: @{$ref}[1]\n";
+                   }
+               }
+
+               $count++;
+           }
+       }
+       my $date_ref = \$email_git_since;
+       $date_ref = \$email_hg_since if (vcs_is_hg());
+       if ($print_options) {
+           $print_options = 0;
+           if (vcs_exists()) {
+               print STDERR <<EOT
+
+Version Control options:
+g  use git history      [$email_git]
+gf use git-fallback     [$email_git_fallback]
+b  use git blame        [$email_git_blame]
+bs use blame signatures [$email_git_blame_signatures]
+c# minimum commits      [$email_git_min_signatures]
+%# min percent          [$email_git_min_percent]
+d# history to use       [$$date_ref]
+x# max maintainers      [$email_git_max_maintainers]
+t  all signature types  [$email_git_all_signature_types]
+m  use .mailmap         [$email_use_mailmap]
+EOT
+           }
+           print STDERR <<EOT
+
+Additional options:
+0  toggle all
+tm toggle maintainers
+tg toggle git entries
+tl toggle open list entries
+ts toggle subscriber list entries
+f  emails in file       [$file_emails]
+k  keywords in file     [$keywords]
+r  remove duplicates    [$email_remove_duplicates]
+p# pattern match depth  [$pattern_depth]
+EOT
+       }
+       print STDERR
+"\n#(toggle), A#(author), S#(signed) *(all), ^(none), O(options), Y(approve): ";
+
+       my $input = <STDIN>;
+       chomp($input);
+
+       $redraw = 1;
+       my $rerun = 0;
+       my @wish = split(/[, ]+/, $input);
+       foreach my $nr (@wish) {
+           $nr = lc($nr);
+           my $sel = substr($nr, 0, 1);
+           my $str = substr($nr, 1);
+           my $val = 0;
+           $val = $1 if $str =~ /^(\d+)$/;
+
+           if ($sel eq "y") {
+               $interactive = 0;
+               $done = 1;
+               $output_rolestats = 0;
+               $output_roles = 0;
+               last;
+           } elsif ($nr =~ /^\d+$/ && $nr > 0 && $nr <= $count) {
+               $selected{$nr - 1} = !$selected{$nr - 1};
+           } elsif ($sel eq "*" || $sel eq '^') {
+               my $toggle = 0;
+               $toggle = 1 if ($sel eq '*');
+               for (my $i = 0; $i < $count; $i++) {
+                   $selected{$i} = $toggle;
+               }
+           } elsif ($sel eq "0") {
+               for (my $i = 0; $i < $count; $i++) {
+                   $selected{$i} = !$selected{$i};
+               }
+           } elsif ($sel eq "t") {
+               if (lc($str) eq "m") {
+                   for (my $i = 0; $i < $count; $i++) {
+                       $selected{$i} = !$selected{$i}
+                           if ($list[$i]->[1] =~ /^(maintainer|supporter)/i);
+                   }
+               } elsif (lc($str) eq "g") {
+                   for (my $i = 0; $i < $count; $i++) {
+                       $selected{$i} = !$selected{$i}
+                           if ($list[$i]->[1] =~ /^(author|commit|signer)/i);
+                   }
+               } elsif (lc($str) eq "l") {
+                   for (my $i = 0; $i < $count; $i++) {
+                       $selected{$i} = !$selected{$i}
+                           if ($list[$i]->[1] =~ /^(open list)/i);
+                   }
+               } elsif (lc($str) eq "s") {
+                   for (my $i = 0; $i < $count; $i++) {
+                       $selected{$i} = !$selected{$i}
+                           if ($list[$i]->[1] =~ /^(subscriber list)/i);
+                   }
+               }
+           } elsif ($sel eq "a") {
+               if ($val > 0 && $val <= $count) {
+                   $authored{$val - 1} = !$authored{$val - 1};
+               } elsif ($str eq '*' || $str eq '^') {
+                   my $toggle = 0;
+                   $toggle = 1 if ($str eq '*');
+                   for (my $i = 0; $i < $count; $i++) {
+                       $authored{$i} = $toggle;
+                   }
+               }
+           } elsif ($sel eq "s") {
+               if ($val > 0 && $val <= $count) {
+                   $signed{$val - 1} = !$signed{$val - 1};
+               } elsif ($str eq '*' || $str eq '^') {
+                   my $toggle = 0;
+                   $toggle = 1 if ($str eq '*');
+                   for (my $i = 0; $i < $count; $i++) {
+                       $signed{$i} = $toggle;
+                   }
+               }
+           } elsif ($sel eq "o") {
+               $print_options = 1;
+               $redraw = 1;
+           } elsif ($sel eq "g") {
+               if ($str eq "f") {
+                   bool_invert(\$email_git_fallback);
+               } else {
+                   bool_invert(\$email_git);
+               }
+               $rerun = 1;
+           } elsif ($sel eq "b") {
+               if ($str eq "s") {
+                   bool_invert(\$email_git_blame_signatures);
+               } else {
+                   bool_invert(\$email_git_blame);
+               }
+               $rerun = 1;
+           } elsif ($sel eq "c") {
+               if ($val > 0) {
+                   $email_git_min_signatures = $val;
+                   $rerun = 1;
+               }
+           } elsif ($sel eq "x") {
+               if ($val > 0) {
+                   $email_git_max_maintainers = $val;
+                   $rerun = 1;
+               }
+           } elsif ($sel eq "%") {
+               if ($str ne "" && $val >= 0) {
+                   $email_git_min_percent = $val;
+                   $rerun = 1;
+               }
+           } elsif ($sel eq "d") {
+               if (vcs_is_git()) {
+                   $email_git_since = $str;
+               } elsif (vcs_is_hg()) {
+                   $email_hg_since = $str;
+               }
+               $rerun = 1;
+           } elsif ($sel eq "t") {
+               bool_invert(\$email_git_all_signature_types);
+               $rerun = 1;
+           } elsif ($sel eq "f") {
+               bool_invert(\$file_emails);
+               $rerun = 1;
+           } elsif ($sel eq "r") {
+               bool_invert(\$email_remove_duplicates);
+               $rerun = 1;
+           } elsif ($sel eq "m") {
+               bool_invert(\$email_use_mailmap);
+               read_mailmap();
+               $rerun = 1;
+           } elsif ($sel eq "k") {
+               bool_invert(\$keywords);
+               $rerun = 1;
+           } elsif ($sel eq "p") {
+               if ($str ne "" && $val >= 0) {
+                   $pattern_depth = $val;
+                   $rerun = 1;
+               }
+           } elsif ($sel eq "h" || $sel eq "?") {
+               print STDERR <<EOT
+
+Interactive mode allows you to select the various maintainers, submitters,
+commit signers and mailing lists that could be CC'd on a patch.
+
+Any *'d entry is selected.
+
+If you have git or hg installed, you can choose to summarize the commit
+history of files in the patch.  Also, each line of the current file can
+be matched to its commit author and that commits signers with blame.
+
+Various knobs exist to control the length of time for active commit
+tracking, the maximum number of commit authors and signers to add,
+and such.
+
+Enter selections at the prompt until you are satisfied that the selected
+maintainers are appropriate.  You may enter multiple selections separated
+by either commas or spaces.
+
+EOT
+           } else {
+               print STDERR "invalid option: '$nr'\n";
+               $redraw = 0;
+           }
+       }
+       if ($rerun) {
+           print STDERR "git-blame can be very slow, please have patience..."
+               if ($email_git_blame);
+           goto &get_maintainers;
+       }
+    }
+
+    #drop not selected entries
+    $count = 0;
+    my @new_emailto = ();
+    foreach my $entry (@list) {
+       if ($selected{$count}) {
+           push(@new_emailto, $list[$count]);
+       }
+       $count++;
+    }
+    return @new_emailto;
+}
+
+sub bool_invert {
+    my ($bool_ref) = @_;
+
+    if ($$bool_ref) {
+       $$bool_ref = 0;
+    } else {
+       $$bool_ref = 1;
+    }
+}
+
+sub deduplicate_email {
+    my ($email) = @_;
+
+    my $matched = 0;
+    my ($name, $address) = parse_email($email);
+    $email = format_email($name, $address, 1);
+    $email = mailmap_email($email);
+
+    return $email if (!$email_remove_duplicates);
+
+    ($name, $address) = parse_email($email);
+
+    if ($name ne "" && $deduplicate_name_hash{lc($name)}) {
+       $name = $deduplicate_name_hash{lc($name)}->[0];
+       $address = $deduplicate_name_hash{lc($name)}->[1];
+       $matched = 1;
+    } elsif ($deduplicate_address_hash{lc($address)}) {
+       $name = $deduplicate_address_hash{lc($address)}->[0];
+       $address = $deduplicate_address_hash{lc($address)}->[1];
+       $matched = 1;
+    }
+    if (!$matched) {
+       $deduplicate_name_hash{lc($name)} = [ $name, $address ];
+       $deduplicate_address_hash{lc($address)} = [ $name, $address ];
+    }
+    $email = format_email($name, $address, 1);
+    $email = mailmap_email($email);
+    return $email;
+}
+
+sub save_commits_by_author {
+    my (@lines) = @_;
+
+    my @authors = ();
+    my @commits = ();
+    my @subjects = ();
+
+    foreach my $line (@lines) {
+       if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
+           my $author = $1;
+           $author = deduplicate_email($author);
+           push(@authors, $author);
+       }
+       push(@commits, $1) if ($line =~ m/$VCS_cmds{"commit_pattern"}/);
+       push(@subjects, $1) if ($line =~ m/$VCS_cmds{"subject_pattern"}/);
+    }
+
+    for (my $i = 0; $i < @authors; $i++) {
+       my $exists = 0;
+       foreach my $ref(@{$commit_author_hash{$authors[$i]}}) {
+           if (@{$ref}[0] eq $commits[$i] &&
+               @{$ref}[1] eq $subjects[$i]) {
+               $exists = 1;
+               last;
+           }
+       }
+       if (!$exists) {
+           push(@{$commit_author_hash{$authors[$i]}},
+                [ ($commits[$i], $subjects[$i]) ]);
+       }
+    }
+}
+
+sub save_commits_by_signer {
+    my (@lines) = @_;
+
+    my $commit = "";
+    my $subject = "";
+
+    foreach my $line (@lines) {
+       $commit = $1 if ($line =~ m/$VCS_cmds{"commit_pattern"}/);
+       $subject = $1 if ($line =~ m/$VCS_cmds{"subject_pattern"}/);
+       if ($line =~ /^[ \t]*${signature_pattern}.*\@.*$/) {
+           my @signatures = ($line);
+           my ($types_ref, $signers_ref) = extract_formatted_signatures(@signatures);
+           my @types = @$types_ref;
+           my @signers = @$signers_ref;
+
+           my $type = $types[0];
+           my $signer = $signers[0];
+
+           $signer = deduplicate_email($signer);
+
+           my $exists = 0;
+           foreach my $ref(@{$commit_signer_hash{$signer}}) {
+               if (@{$ref}[0] eq $commit &&
+                   @{$ref}[1] eq $subject &&
+                   @{$ref}[2] eq $type) {
+                   $exists = 1;
+                   last;
+               }
+           }
+           if (!$exists) {
+               push(@{$commit_signer_hash{$signer}},
+                    [ ($commit, $subject, $type) ]);
+           }
+       }
+    }
+}
+
+sub vcs_assign {
+    my ($role, $divisor, @lines) = @_;
+
+    my %hash;
+    my $count = 0;
+
+    return if (@lines <= 0);
+
+    if ($divisor <= 0) {
+       warn("Bad divisor in " . (caller(0))[3] . ": $divisor\n");
+       $divisor = 1;
+    }
+
+    @lines = mailmap(@lines);
+
+    return if (@lines <= 0);
+
+    @lines = sort(@lines);
+
+    # uniq -c
+    $hash{$_}++ for @lines;
+
+    # sort -rn
+    foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
+       my $sign_offs = $hash{$line};
+       my $percent = $sign_offs * 100 / $divisor;
+
+       $percent = 100 if ($percent > 100);
+       $count++;
+       last if ($sign_offs < $email_git_min_signatures ||
+                $count > $email_git_max_maintainers ||
+                $percent < $email_git_min_percent);
+       push_email_address($line, '');
+       if ($output_rolestats) {
+           my $fmt_percent = sprintf("%.0f", $percent);
+           add_role($line, "$role:$sign_offs/$divisor=$fmt_percent%");
+       } else {
+           add_role($line, $role);
+       }
+    }
+}
+
+sub vcs_file_signoffs {
+    my ($file) = @_;
+
+    my $authors_ref;
+    my $signers_ref;
+    my $stats_ref;
+    my @authors = ();
+    my @signers = ();
+    my @stats = ();
+    my $commits;
+
+    $vcs_used = vcs_exists();
+    return if (!$vcs_used);
+
+    my $cmd = $VCS_cmds{"find_signers_cmd"};
+    $cmd =~ s/(\$\w+)/$1/eeg;          # interpolate $cmd
+
+    ($commits, $signers_ref, $authors_ref, $stats_ref) = vcs_find_signers($cmd, $file);
+
+    @signers = @{$signers_ref} if defined $signers_ref;
+    @authors = @{$authors_ref} if defined $authors_ref;
+    @stats = @{$stats_ref} if defined $stats_ref;
+
+#    print("commits: <$commits>\nsigners:<@signers>\nauthors: <@authors>\nstats: <@stats>\n");
+
+    foreach my $signer (@signers) {
+       $signer = deduplicate_email($signer);
+    }
+
+    vcs_assign("commit_signer", $commits, @signers);
+    vcs_assign("authored", $commits, @authors);
+    if ($#authors == $#stats) {
+       my $stat_pattern = $VCS_cmds{"stat_pattern"};
+       $stat_pattern =~ s/(\$\w+)/$1/eeg;      #interpolate $stat_pattern
+
+       my $added = 0;
+       my $deleted = 0;
+       for (my $i = 0; $i <= $#stats; $i++) {
+           if ($stats[$i] =~ /$stat_pattern/) {
+               $added += $1;
+               $deleted += $2;
+           }
+       }
+       my @tmp_authors = uniq(@authors);
+       foreach my $author (@tmp_authors) {
+           $author = deduplicate_email($author);
+       }
+       @tmp_authors = uniq(@tmp_authors);
+       my @list_added = ();
+       my @list_deleted = ();
+       foreach my $author (@tmp_authors) {
+           my $auth_added = 0;
+           my $auth_deleted = 0;
+           for (my $i = 0; $i <= $#stats; $i++) {
+               if ($author eq deduplicate_email($authors[$i]) &&
+                   $stats[$i] =~ /$stat_pattern/) {
+                   $auth_added += $1;
+                   $auth_deleted += $2;
+               }
+           }
+           for (my $i = 0; $i < $auth_added; $i++) {
+               push(@list_added, $author);
+           }
+           for (my $i = 0; $i < $auth_deleted; $i++) {
+               push(@list_deleted, $author);
+           }
+       }
+       vcs_assign("added_lines", $added, @list_added);
+       vcs_assign("removed_lines", $deleted, @list_deleted);
+    }
+}
+
+sub vcs_file_blame {
+    my ($file) = @_;
+
+    my @signers = ();
+    my @all_commits = ();
+    my @commits = ();
+    my $total_commits;
+    my $total_lines;
+
+    $vcs_used = vcs_exists();
+    return if (!$vcs_used);
+
+    @all_commits = vcs_blame($file);
+    @commits = uniq(@all_commits);
+    $total_commits = @commits;
+    $total_lines = @all_commits;
+
+    if ($email_git_blame_signatures) {
+       if (vcs_is_hg()) {
+           my $commit_count;
+           my $commit_authors_ref;
+           my $commit_signers_ref;
+           my $stats_ref;
+           my @commit_authors = ();
+           my @commit_signers = ();
+           my $commit = join(" -r ", @commits);
+           my $cmd;
+
+           $cmd = $VCS_cmds{"find_commit_signers_cmd"};
+           $cmd =~ s/(\$\w+)/$1/eeg;   #substitute variables in $cmd
+
+           ($commit_count, $commit_signers_ref, $commit_authors_ref, $stats_ref) = vcs_find_signers($cmd, $file);
+           @commit_authors = @{$commit_authors_ref} if defined $commit_authors_ref;
+           @commit_signers = @{$commit_signers_ref} if defined $commit_signers_ref;
+
+           push(@signers, @commit_signers);
+       } else {
+           foreach my $commit (@commits) {
+               my $commit_count;
+               my $commit_authors_ref;
+               my $commit_signers_ref;
+               my $stats_ref;
+               my @commit_authors = ();
+               my @commit_signers = ();
+               my $cmd;
+
+               $cmd = $VCS_cmds{"find_commit_signers_cmd"};
+               $cmd =~ s/(\$\w+)/$1/eeg;       #substitute variables in $cmd
+
+               ($commit_count, $commit_signers_ref, $commit_authors_ref, $stats_ref) = vcs_find_signers($cmd, $file);
+               @commit_authors = @{$commit_authors_ref} if defined $commit_authors_ref;
+               @commit_signers = @{$commit_signers_ref} if defined $commit_signers_ref;
+
+               push(@signers, @commit_signers);
+           }
+       }
+    }
+
+    if ($from_filename) {
+       if ($output_rolestats) {
+           my @blame_signers;
+           if (vcs_is_hg()) {{         # Double brace for last exit
+               my $commit_count;
+               my @commit_signers = ();
+               @commits = uniq(@commits);
+               @commits = sort(@commits);
+               my $commit = join(" -r ", @commits);
+               my $cmd;
+
+               $cmd = $VCS_cmds{"find_commit_author_cmd"};
+               $cmd =~ s/(\$\w+)/$1/eeg;       #substitute variables in $cmd
+
+               my @lines = ();
+
+               @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
+
+               if (!$email_git_penguin_chiefs) {
+                   @lines = grep(!/${penguin_chiefs}/i, @lines);
+               }
+
+               last if !@lines;
+
+               my @authors = ();
+               foreach my $line (@lines) {
+                   if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
+                       my $author = $1;
+                       $author = deduplicate_email($author);
+                       push(@authors, $author);
+                   }
+               }
+
+               save_commits_by_author(@lines) if ($interactive);
+               save_commits_by_signer(@lines) if ($interactive);
+
+               push(@signers, @authors);
+           }}
+           else {
+               foreach my $commit (@commits) {
+                   my $i;
+                   my $cmd = $VCS_cmds{"find_commit_author_cmd"};
+                   $cmd =~ s/(\$\w+)/$1/eeg;   #interpolate $cmd
+                   my @author = vcs_find_author($cmd);
+                   next if !@author;
+
+                   my $formatted_author = deduplicate_email($author[0]);
+
+                   my $count = grep(/$commit/, @all_commits);
+                   for ($i = 0; $i < $count ; $i++) {
+                       push(@blame_signers, $formatted_author);
+                   }
+               }
+           }
+           if (@blame_signers) {
+               vcs_assign("authored lines", $total_lines, @blame_signers);
+           }
+       }
+       foreach my $signer (@signers) {
+           $signer = deduplicate_email($signer);
+       }
+       vcs_assign("commits", $total_commits, @signers);
+    } else {
+       foreach my $signer (@signers) {
+           $signer = deduplicate_email($signer);
+       }
+       vcs_assign("modified commits", $total_commits, @signers);
+    }
+}
+
+sub uniq {
+    my (@parms) = @_;
+
+    my %saw;
+    @parms = grep(!$saw{$_}++, @parms);
+    return @parms;
+}
+
+sub sort_and_uniq {
+    my (@parms) = @_;
+
+    my %saw;
+    @parms = sort @parms;
+    @parms = grep(!$saw{$_}++, @parms);
+    return @parms;
+}
+
+sub clean_file_emails {
+    my (@file_emails) = @_;
+    my @fmt_emails = ();
+
+    foreach my $email (@file_emails) {
+       $email =~ s/[\(\<\{]{0,1}([A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+)[\)\>\}]{0,1}/\<$1\>/g;
+       my ($name, $address) = parse_email($email);
+       if ($name eq '"[,\.]"') {
+           $name = "";
+       }
+
+       my @nw = split(/[^A-Za-zÀ-ÿ\'\,\.\+-]/, $name);
+       if (@nw > 2) {
+           my $first = $nw[@nw - 3];
+           my $middle = $nw[@nw - 2];
+           my $last = $nw[@nw - 1];
+
+           if (((length($first) == 1 && $first =~ m/[A-Za-z]/) ||
+                (length($first) == 2 && substr($first, -1) eq ".")) ||
+               (length($middle) == 1 ||
+                (length($middle) == 2 && substr($middle, -1) eq "."))) {
+               $name = "$first $middle $last";
+           } else {
+               $name = "$middle $last";
+           }
+       }
+
+       if (substr($name, -1) =~ /[,\.]/) {
+           $name = substr($name, 0, length($name) - 1);
+       } elsif (substr($name, -2) =~ /[,\.]"/) {
+           $name = substr($name, 0, length($name) - 2) . '"';
+       }
+
+       if (substr($name, 0, 1) =~ /[,\.]/) {
+           $name = substr($name, 1, length($name) - 1);
+       } elsif (substr($name, 0, 2) =~ /"[,\.]/) {
+           $name = '"' . substr($name, 2, length($name) - 2);
+       }
+
+       my $fmt_email = format_email($name, $address, $email_usename);
+       push(@fmt_emails, $fmt_email);
+    }
+    return @fmt_emails;
+}
+
+sub merge_email {
+    my @lines;
+    my %saw;
+
+    for (@_) {
+       my ($address, $role) = @$_;
+       if (!$saw{$address}) {
+           if ($output_roles) {
+               push(@lines, "$address ($role)");
+           } else {
+               push(@lines, $address);
+           }
+           $saw{$address} = 1;
+       }
+    }
+
+    return @lines;
+}
+
+sub output {
+    my (@parms) = @_;
+
+    if ($output_multiline) {
+       foreach my $line (@parms) {
+           print("${line}\n");
+       }
+    } else {
+       print(join($output_separator, @parms));
+       print("\n");
+    }
+}
+
+my $rfc822re;
+
+sub make_rfc822re {
+#   Basic lexical tokens are specials, domain_literal, quoted_string, atom, and
+#   comment.  We must allow for rfc822_lwsp (or comments) after each of these.
+#   This regexp will only work on addresses which have had comments stripped
+#   and replaced with rfc822_lwsp.
+
+    my $specials = '()<>@,;:\\\\".\\[\\]';
+    my $controls = '\\000-\\037\\177';
+
+    my $dtext = "[^\\[\\]\\r\\\\]";
+    my $domain_literal = "\\[(?:$dtext|\\\\.)*\\]$rfc822_lwsp*";
+
+    my $quoted_string = "\"(?:[^\\\"\\r\\\\]|\\\\.|$rfc822_lwsp)*\"$rfc822_lwsp*";
+
+#   Use zero-width assertion to spot the limit of an atom.  A simple
+#   $rfc822_lwsp* causes the regexp engine to hang occasionally.
+    my $atom = "[^$specials $controls]+(?:$rfc822_lwsp+|\\Z|(?=[\\[\"$specials]))";
+    my $word = "(?:$atom|$quoted_string)";
+    my $localpart = "$word(?:\\.$rfc822_lwsp*$word)*";
+
+    my $sub_domain = "(?:$atom|$domain_literal)";
+    my $domain = "$sub_domain(?:\\.$rfc822_lwsp*$sub_domain)*";
+
+    my $addr_spec = "$localpart\@$rfc822_lwsp*$domain";
+
+    my $phrase = "$word*";
+    my $route = "(?:\@$domain(?:,\@$rfc822_lwsp*$domain)*:$rfc822_lwsp*)";
+    my $route_addr = "\\<$rfc822_lwsp*$route?$addr_spec\\>$rfc822_lwsp*";
+    my $mailbox = "(?:$addr_spec|$phrase$route_addr)";
+
+    my $group = "$phrase:$rfc822_lwsp*(?:$mailbox(?:,\\s*$mailbox)*)?;\\s*";
+    my $address = "(?:$mailbox|$group)";
+
+    return "$rfc822_lwsp*$address";
+}
+
+sub rfc822_strip_comments {
+    my $s = shift;
+#   Recursively remove comments, and replace with a single space.  The simpler
+#   regexps in the Email Addressing FAQ are imperfect - they will miss escaped
+#   chars in atoms, for example.
+
+    while ($s =~ s/^((?:[^"\\]|\\.)*
+                    (?:"(?:[^"\\]|\\.)*"(?:[^"\\]|\\.)*)*)
+                    \((?:[^()\\]|\\.)*\)/$1 /osx) {}
+    return $s;
+}
+
+#   valid: returns true if the parameter is an RFC822 valid address
+#
+sub rfc822_valid {
+    my $s = rfc822_strip_comments(shift);
+
+    if (!$rfc822re) {
+        $rfc822re = make_rfc822re();
+    }
+
+    return $s =~ m/^$rfc822re$/so && $s =~ m/^$rfc822_char*$/;
+}
+
+#   validlist: In scalar context, returns true if the parameter is an RFC822
+#              valid list of addresses.
+#
+#              In list context, returns an empty list on failure (an invalid
+#              address was found); otherwise a list whose first element is the
+#              number of addresses found and whose remaining elements are the
+#              addresses.  This is needed to disambiguate failure (invalid)
+#              from success with no addresses found, because an empty string is
+#              a valid list.
+
+sub rfc822_validlist {
+    my $s = rfc822_strip_comments(shift);
+
+    if (!$rfc822re) {
+        $rfc822re = make_rfc822re();
+    }
+    # * null list items are valid according to the RFC
+    # * the '1' business is to aid in distinguishing failure from no results
+
+    my @r;
+    if ($s =~ m/^(?:$rfc822re)?(?:,(?:$rfc822re)?)*$/so &&
+       $s =~ m/^$rfc822_char*$/) {
+        while ($s =~ m/(?:^|,$rfc822_lwsp*)($rfc822re)/gos) {
+            push(@r, $1);
+        }
+        return wantarray ? (scalar(@r), @r) : 1;
+    }
+    return wantarray ? () : 0;
+}
diff --git a/test/dfu/README b/test/dfu/README
new file mode 100644 (file)
index 0000000..5176aba
--- /dev/null
@@ -0,0 +1,37 @@
+DFU TEST CASE DESCRIPTION:
+
+The prerequisites for running this script are assured by
+dfu_gadget_test_init.sh, which is automatically invoked by dfu_gadget_test.sh.
+In this file user is able to generate their own set of test files by altering
+the default set of TEST_FILES_SIZES variable.
+The dfu_gadget_test_init.sh would generate test images only if they are not
+already generated.
+
+On the target device, environment variable "dfu_alt_info" must contain at
+least:
+
+    dfu_test.bin fat 0 6;dfudummy.bin fat 0 6
+
+Depending on your device, you may need to replace "fat" with
+"ext4", and "6" with the relevant partition number. For reference please
+consult the config file for TRATS/TRATS2 devices
+(../../include/configs/trats{2}.h)
+
+One can use fat, ext4 or any other supported file system supported by U-Boot.
+These can be created by exporting storage devices via UMS (ums 0 mmc 0) and
+using standard tools on host (like mkfs.ext4).
+
+Example usage:
+1. On the target:
+   setenv dfu_alt_info dfu_test.bin fat 0 6\;dfudummy.bin fat 0 6
+   dfu 0 mmc 0
+2. On the host:
+   test/dfu/dfu_gadget_test.sh X Y  [test file name]
+   e.g. test/dfu/dfu_gadget_test.sh 0 1
+   or
+   e.g. test/dfu/dfu_gadget_test.sh 0 1 ./dat_960.img
+
+... where X and Y are dfu_test.bin's and dfudummy.bin's alt setting numbers.
+They can be obtained from dfu-util -l or $dfu_alt_info.
+It is also possible to pass optional [test file name] to force the script to
+test one particular file.
diff --git a/test/dfu/dfu_gadget_test.sh b/test/dfu/dfu_gadget_test.sh
new file mode 100755 (executable)
index 0000000..4133155
--- /dev/null
@@ -0,0 +1,94 @@
+#! /bin/bash
+
+set -e # any command return if not equal to zero
+clear
+
+COLOUR_RED="\33[31m"
+COLOUR_GREEN="\33[32m"
+COLOUR_DEFAULT="\33[0m"
+
+DIR=./
+SUFFIX=img
+RCV_DIR=rcv/
+LOG_FILE=./log/log-`date +%d-%m-%Y_%H-%M-%S`
+
+cd `dirname $0`
+./dfu_gadget_test_init.sh
+
+cleanup () {
+    rm -rf $DIR$RCV_DIR
+}
+
+die () {
+       printf "   $COLOUR_RED FAILED $COLOUR_DEFAULT \n"
+       cleanup
+       exit 1
+}
+
+calculate_md5sum () {
+    MD5SUM=`md5sum $1`
+    MD5SUM=`echo $MD5SUM | cut -d ' ' -f1`
+    echo "md5sum:"$MD5SUM
+}
+
+dfu_test_file () {
+    printf "$COLOUR_GREEN ========================================================================================= $COLOUR_DEFAULT\n"
+    printf "File:$COLOUR_GREEN %s $COLOUR_DEFAULT\n" $1
+
+    dfu-util -D $1 -a $TARGET_ALT_SETTING >> $LOG_FILE 2>&1 || die $?
+
+    echo -n "TX: "
+    calculate_md5sum $1
+
+    MD5_TX=$MD5SUM
+
+    dfu-util -D ${DIR}/dfudummy.bin -a $TARGET_ALT_SETTING_B >> $LOG_FILE 2>&1 || die $?
+
+    N_FILE=$DIR$RCV_DIR${1:2}"_rcv"
+
+    dfu-util -U $N_FILE -a $TARGET_ALT_SETTING >> $LOG_FILE 2>&1 || die $?
+
+    echo -n "RX: "
+    calculate_md5sum $N_FILE
+    MD5_RX=$MD5SUM
+
+    if [ "$MD5_TX" == "$MD5_RX" ]; then
+       printf "   $COLOUR_GREEN -------> OK $COLOUR_DEFAULT \n"
+    else
+       printf "   $COLOUR_RED -------> FAILED $COLOUR_DEFAULT \n"
+       cleanup
+       exit 1
+    fi
+
+}
+
+printf "$COLOUR_GREEN========================================================================================= $COLOUR_DEFAULT\n"
+echo "DFU EP0 transmission test program"
+echo "Trouble shoot -> disable DBG (even the KERN_DEBUG) in the UDC driver"
+echo "@ -> TRATS2 # dfu 0 mmc 0"
+cleanup
+mkdir -p $DIR$RCV_DIR
+touch $LOG_FILE
+
+if [ $# -eq 0 ]
+then
+       printf "   $COLOUR_RED Please pass alt setting number!!  $COLOUR_DEFAULT \n"
+       exit 0
+fi
+
+TARGET_ALT_SETTING=$1
+TARGET_ALT_SETTING_B=$2
+
+if [ -n "$3" ]
+then
+       dfu_test_file $3
+else
+       for file in $DIR*.$SUFFIX
+       do
+           dfu_test_file $file
+       done
+fi
+
+cleanup
+
+exit 0
diff --git a/test/dfu/dfu_gadget_test_init.sh b/test/dfu/dfu_gadget_test_init.sh
new file mode 100755 (executable)
index 0000000..2163a68
--- /dev/null
@@ -0,0 +1,31 @@
+#! /bin/bash
+
+set -e # any command return if not equal to zero
+clear
+
+COLOUR_RED="\33[31m"
+COLOUR_GREEN="\33[32m"
+COLOUR_DEFAULT="\33[0m"
+
+LOG_DIR="./log"
+
+TEST_FILES_SIZES="63 64 65 127 128 129 4095 4096 4097 959 960 961 1048575 1048576 8M"
+
+printf "Init script for generating data necessary for DFU test script"
+
+if [ ! -d $LOG_DIR ]; then
+    `mkdir $LOG_DIR`
+fi
+
+for size in $TEST_FILES_SIZES
+do
+    FILE="./dat_$size.img"
+    if [ ! -f $FILE ]; then
+       dd if=/dev/urandom of="./dat_$size.img" bs=$size count=1 > /dev/null 2>&1 || exit $?
+    fi
+done
+dd if=/dev/urandom of="./dfudummy.bin" bs=1024 count=1 > /dev/null 2>&1 || exit $?
+
+printf "$COLOUR_GREEN OK $COLOUR_DEFAULT \n"
+
+exit 0
index 8074fc6adc0708c984297c2172ad41ded4f0995e..6d7abb82bd72b85a861e3524a7b92c34e853817a 100755 (executable)
@@ -54,8 +54,16 @@ echo ${mkimage} -D "${dtc}"
 echo "Build keys"
 mkdir -p ${keys}
 
+PUBLIC_EXPONENT=${1}
+
+if [ -z "${PUBLIC_EXPONENT}" ]; then
+       PUBLIC_EXPONENT=65537
+fi
+
 # Create an RSA key pair
-openssl genrsa -F4 -out ${keys}/dev.key 2048 2>/dev/null
+openssl genpkey -algorithm RSA -out ${keys}/dev.key \
+    -pkeyopt rsa_keygen_bits:2048 \
+    -pkeyopt rsa_keygen_pubexp:${PUBLIC_EXPONENT} 2>/dev/null
 
 # Create a certificate containing the public key
 openssl req -batch -new -x509 -key ${keys}/dev.key -out ${keys}/dev.crt