]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-sunxi
authorTom Rini <trini@ti.com>
Mon, 2 Feb 2015 15:11:44 +0000 (10:11 -0500)
committerTom Rini <trini@ti.com>
Mon, 2 Feb 2015 15:11:44 +0000 (10:11 -0500)
269 files changed:
Kconfig
Makefile
README
arch/arm/Kconfig
arch/arm/cpu/armv7/cpu.c
arch/arm/cpu/armv7/exynos/pinmux.c
arch/arm/cpu/armv7/start.S
arch/arm/cpu/tegra20-common/pmu.c
arch/arm/dts/exynos4.dtsi
arch/arm/dts/exynos4210-origen.dts
arch/arm/dts/exynos4210-trats.dts
arch/arm/dts/exynos4210-universal_c210.dts
arch/arm/dts/exynos4412-odroid.dts
arch/arm/dts/exynos4412-trats2.dts
arch/arm/dts/exynos5.dtsi
arch/arm/dts/exynos5250-arndale.dts
arch/arm/dts/exynos5250-smdk5250.dts
arch/arm/dts/exynos5250-snow.dts
arch/arm/dts/exynos5420-peach-pit.dts
arch/arm/dts/exynos5422-odroidxu3.dts
arch/arm/dts/exynos5800-peach-pi.dts
arch/arm/dts/tegra114-dalmore.dts
arch/arm/dts/tegra124-jetson-tk1.dts
arch/arm/dts/tegra124-venice2.dts
arch/arm/dts/tegra20-colibri_t20_iris.dts
arch/arm/dts/tegra20-harmony.dts
arch/arm/dts/tegra20-medcom-wide.dts
arch/arm/dts/tegra20-paz00.dts
arch/arm/dts/tegra20-seaboard.dts
arch/arm/dts/tegra20-tamonten.dtsi
arch/arm/dts/tegra20-tec.dts
arch/arm/dts/tegra20-trimslice.dts
arch/arm/dts/tegra20-ventana.dts
arch/arm/dts/tegra20-whistler.dts
arch/arm/dts/tegra30-apalis.dts
arch/arm/dts/tegra30-beaver.dts
arch/arm/dts/tegra30-cardhu.dts
arch/arm/dts/tegra30-colibri.dts
arch/arm/dts/tegra30-tamonten.dtsi
arch/arm/include/asm/arch-exynos/pinmux.h
arch/arm/include/asm/arch-pantheon/gpio.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra/tegra_mmc.h
arch/arm/include/asm/arch-tegra20/display.h
arch/arm/include/asm/arch-zynq/gpio.h
arch/blackfin/cpu/cpu.c
arch/mips/Kconfig
arch/mips/Makefile
arch/mips/cpu/Makefile [new file with mode: 0644]
arch/mips/cpu/cpu.c [new file with mode: 0644]
arch/mips/cpu/interrupts.c [moved from arch/mips/cpu/mips32/interrupts.c with 100% similarity]
arch/mips/cpu/mips32/Makefile [deleted file]
arch/mips/cpu/mips64/Makefile [deleted file]
arch/mips/cpu/mips64/cache.S [deleted file]
arch/mips/cpu/mips64/cpu.c [deleted file]
arch/mips/cpu/mips64/interrupts.c [deleted file]
arch/mips/cpu/mips64/start.S [deleted file]
arch/mips/cpu/mips64/time.c [deleted file]
arch/mips/cpu/start.S [moved from arch/mips/cpu/mips32/start.S with 61% similarity]
arch/mips/cpu/time.c [moved from arch/mips/cpu/mips32/time.c with 100% similarity]
arch/mips/include/asm/cacheops.h
arch/mips/include/asm/malta.h
arch/mips/lib/Makefile
arch/mips/lib/cache.c [moved from arch/mips/cpu/mips32/cpu.c with 55% similarity]
arch/mips/lib/cache_init.S [moved from arch/mips/cpu/mips32/cache.S with 59% similarity]
arch/mips/mach-au1x00/Makefile [moved from arch/mips/cpu/mips32/au1x00/Makefile with 100% similarity]
arch/mips/mach-au1x00/au1x00_eth.c [moved from arch/mips/cpu/mips32/au1x00/au1x00_eth.c with 98% similarity]
arch/mips/mach-au1x00/au1x00_ide.c [moved from arch/mips/cpu/mips32/au1x00/au1x00_ide.c with 100% similarity]
arch/mips/mach-au1x00/au1x00_serial.c [moved from arch/mips/cpu/mips32/au1x00/au1x00_serial.c with 100% similarity]
arch/mips/mach-au1x00/au1x00_usb_ohci.c [moved from arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c with 100% similarity]
arch/mips/mach-au1x00/au1x00_usb_ohci.h [moved from arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.h with 100% similarity]
arch/mips/mach-au1x00/config.mk [moved from arch/mips/cpu/mips32/au1x00/config.mk with 100% similarity]
arch/sandbox/cpu/start.c
arch/sandbox/dts/sandbox.dts
board/BuS/eb_cpux9k2/cpux9k2.c
board/armltd/vexpress64/Kconfig
board/armltd/vexpress64/MAINTAINERS
board/avionic-design/common/tamonten-ng.c
board/imgtec/malta/malta.c
board/nvidia/cardhu/cardhu.c
board/nvidia/dalmore/dalmore.c
board/nvidia/whistler/whistler.c
board/samsung/odroid/odroid.c
board/sandbox/README.sandbox
board/toradex/apalis_t30/apalis_t30.c
common/Makefile
common/board_f.c
common/board_info.c [new file with mode: 0644]
common/board_r.c
common/cmd_bootm.c
common/cmd_demo.c
common/cmd_fpga.c
common/cmd_fs.c
common/cmd_gettime.c
common/cmd_i2c.c
common/cmd_load.c
common/cmd_part.c
common/cmd_ximg.c
common/console.c
common/exports.c
common/hash.c
common/image-fit.c
common/image-sig.c
common/image.c
configs/am335x_boneblack_vboot_defconfig
configs/ids8313_defconfig
configs/ph1_ld4_defconfig
configs/ph1_pro4_defconfig
configs/ph1_sld8_defconfig
configs/sandbox_defconfig
configs/vexpress_aemv8a_defconfig
configs/vexpress_aemv8a_juno_defconfig [new file with mode: 0644]
configs/vexpress_aemv8a_semi_defconfig
configs/zynq_microzed_defconfig
configs/zynq_zc70x_defconfig
configs/zynq_zc770_xm010_defconfig
configs/zynq_zc770_xm012_defconfig
configs/zynq_zc770_xm013_defconfig
configs/zynq_zed_defconfig
configs/zynq_zybo_defconfig
doc/README.distro [new file with mode: 0644]
doc/README.standalone
doc/device-tree-bindings/gpio/gpio-samsung.txt [new file with mode: 0644]
doc/device-tree-bindings/gpio/gpio.txt [new file with mode: 0644]
doc/device-tree-bindings/gpio/nvidia,tegra20-gpio.txt [new file with mode: 0644]
doc/device-tree-bindings/i2c/i2c.txt [new file with mode: 0644]
doc/driver-model/README.txt
doc/driver-model/spi-howto.txt
doc/uImage.FIT/source_file_format.txt
doc/uImage.FIT/verified-boot.txt
drivers/core/device-remove.c
drivers/core/device.c
drivers/core/root.c
drivers/core/uclass.c
drivers/crypto/Kconfig
drivers/crypto/Makefile
drivers/crypto/fsl/Kconfig [new file with mode: 0644]
drivers/crypto/fsl/Makefile
drivers/crypto/fsl/fsl_rsa.c [new file with mode: 0644]
drivers/crypto/fsl/jobdesc.c
drivers/crypto/fsl/jobdesc.h
drivers/crypto/fsl/rsa_caam.h [new file with mode: 0644]
drivers/crypto/rsa_mod_exp/Kconfig [new file with mode: 0644]
drivers/crypto/rsa_mod_exp/Makefile [new file with mode: 0644]
drivers/crypto/rsa_mod_exp/mod_exp_sw.c [new file with mode: 0644]
drivers/crypto/rsa_mod_exp/mod_exp_uclass.c [new file with mode: 0644]
drivers/demo/demo-shape.c
drivers/demo/demo-uclass.c
drivers/gpio/gpio-uclass.c
drivers/gpio/s5p_gpio.c
drivers/gpio/sandbox.c
drivers/gpio/tegra_gpio.c
drivers/i2c/Kconfig
drivers/i2c/Makefile
drivers/i2c/i2c-uclass-compat.c [new file with mode: 0644]
drivers/i2c/i2c-uclass.c
drivers/i2c/i2c-uniphier-f.c [new file with mode: 0644]
drivers/i2c/i2c-uniphier.c [new file with mode: 0644]
drivers/i2c/s3c24x0_i2c.c
drivers/i2c/sandbox_i2c.c
drivers/i2c/tegra_i2c.c
drivers/misc/cros_ec.c
drivers/misc/cros_ec_i2c.c
drivers/misc/cros_ec_spi.c
drivers/mmc/s5p_sdhci.c
drivers/mmc/tegra_mmc.c
drivers/mtd/nand/tegra_nand.c
drivers/mtd/spi/sandbox.c
drivers/mtd/spi/sf_probe.c
drivers/net/designware.c
drivers/net/e1000.c
drivers/net/phy/micrel.c
drivers/net/smc91111.h
drivers/net/tsec.c
drivers/pci/pci_rom.c
drivers/power/as3722.c
drivers/power/tps6586x.c
drivers/serial/serial-uclass.c
drivers/spi/cadence_qspi.c
drivers/spi/designware_spi.c
drivers/spi/exynos_spi.c
drivers/spi/sandbox_spi.c
drivers/spi/soft_spi.c
drivers/spi/spi-uclass.c
drivers/spi/tegra114_spi.c
drivers/spi/tegra20_sflash.c
drivers/spi/tegra20_slink.c
drivers/usb/host/ehci-exynos.c
drivers/usb/host/ehci-tegra.c
drivers/usb/host/xhci-exynos5.c
drivers/video/tegra.c
examples/standalone/stubs.c
fs/fs.c
include/_exports.h
include/asm-generic/global_data.h
include/asm-generic/gpio.h
include/common.h
include/config_distro_bootcmd.h
include/configs/am335x_evm.h
include/configs/arndale.h
include/configs/exynos5-common.h
include/configs/exynos5250-common.h
include/configs/ids8313.h
include/configs/malta.h
include/configs/odroid.h
include/configs/sandbox.h
include/configs/smdk5250.h
include/configs/snow.h
include/configs/ti_am335x_common.h
include/configs/uniphier.h
include/configs/vexpress_aemv8a.h
include/configs/vexpress_common.h
include/configs/zynq-common.h
include/cros_ec.h
include/dm-demo.h
include/dm/device.h
include/dm/test.h
include/dm/uclass-id.h
include/dm/uclass-internal.h
include/dm/uclass.h
include/exports.h
include/fdtdec.h
include/fs.h
include/hash.h
include/i2c.h
include/image.h
include/linker_lists.h
include/sdhci.h
include/spi.h
include/u-boot/rsa-checksum.h
include/u-boot/rsa-mod-exp.h [new file with mode: 0644]
lib/Kconfig
lib/fdtdec.c
lib/rsa/Kconfig [new file with mode: 0644]
lib/rsa/Makefile
lib/rsa/rsa-checksum.c
lib/rsa/rsa-mod-exp.c [new file with mode: 0644]
lib/rsa/rsa-verify.c
test/dm/bus.c
test/dm/core.c
test/dm/gpio.c
test/dm/i2c.c
test/dm/spi.c
test/dm/test-dm.sh
test/dm/test-fdt.c
test/dm/test.dts
test/image/test-imagetools.sh
tools/Makefile
tools/aisimage.c
tools/atmelimage.c
tools/default_image.c
tools/dumpimage.c
tools/fit_image.c
tools/gpimage-common.c
tools/gpimage.c
tools/imagetool.c
tools/imagetool.h
tools/imagetool.lds [new file with mode: 0644]
tools/imximage.c
tools/kwbimage.c
tools/mkimage.c
tools/mxsimage.c
tools/omapimage.c
tools/patman/README
tools/patman/gitutil.py
tools/patman/patchstream.py
tools/patman/series.py
tools/pblimage.c
tools/socfpgaimage.c
tools/ublimage.c

diff --git a/Kconfig b/Kconfig
index 4157da3c68485540597b7e8993d6786676ac5d25..fed488fdaf94212dfce21902d2cf812a827f819e 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -116,8 +116,9 @@ config FIT_VERBOSE
        depends on FIT
 
 config FIT_SIGNATURE
-       bool "Enabel signature verification of FIT uImages"
+       bool "Enable signature verification of FIT uImages"
        depends on FIT
+       select RSA
        help
          This option enables signature verification of FIT uImages,
          using a hash signed and verified using RSA.
index ea5ae8fac72f3b0c8f1c7807b4fc4dfaeca15ea1..9b406c844700f9674f4a787cb95019e6d7d4c115 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -776,6 +776,13 @@ ifneq ($(CONFIG_SYS_GENERIC_BOARD),y)
        @echo "See doc/README.generic-board for further information"
        @echo "===================================================="
 endif
+ifeq ($(CONFIG_DM_I2C_COMPAT),y)
+       @echo "===================== WARNING ======================"
+       @echo "This board uses CONFIG_DM_I2C_COMPAT. Please remove"
+       @echo "(possibly in a subsequent patch in your series)"
+       @echo "before sending patches to the mailing list."
+       @echo "===================================================="
+endif
 
 PHONY += dtbs
 dtbs dts/dt.dtb: checkdtc u-boot
diff --git a/README b/README
index fefa71c0a6c5f3adf8ed437e6956227a0e502e8b..a28ff133ee057c17af79a397e44325328f82dedf 100644 (file)
--- a/README
+++ b/README
@@ -3176,8 +3176,13 @@ CBFS (Coreboot Filesystem) support
                This enables the RSA algorithm used for FIT image verification
                in U-Boot. See doc/uImage.FIT/signature.txt for more information.
 
+               The Modular Exponentiation algorithm in RSA is implemented using
+               driver model. So CONFIG_DM needs to be enabled by default for this
+               library to function.
+
                The signing part is build into mkimage regardless of this
-               option.
+               option. The software based modular exponentiation is built into
+               mkimage irrespective of this option.
 
 - bootcount support:
                CONFIG_BOOTCOUNT_LIMIT
@@ -5899,9 +5904,10 @@ option performs the converse operation of the mkimage's second form (the "-d"
 option). Given an image built by mkimage, the dumpimage extracts a "data file"
 from the image:
 
-       tools/dumpimage -i image -p position data_file
-         -i ==> extract from the 'image' a specific 'data_file', \
-          indexed by 'position'
+       tools/dumpimage -i image -T type -p position data_file
+         -i ==> extract from the 'image' a specific 'data_file'
+         -T ==> set image type to 'type'
+         -p ==> 'position' (starting at 0) of the 'data_file' inside the 'image'
 
 
 Installing a Linux Image:
index 5eb1d03cfaafbdb8faf75c01cb5cc5839c0102a1..986b4c5d81db1009110eafb2c4606c79675c03a7 100644 (file)
@@ -51,6 +51,13 @@ config SYS_CPU
         default "sa1100" if CPU_SA1100
        default "armv8" if ARM64
 
+config SEMIHOSTING
+       bool "support boot from semihosting"
+       help
+         In emulated environments, semihosting is a way for
+         the hosted environment to call out to the emulator to
+         retrieve files from the host machine.
+
 choice
        prompt "Target select"
 
@@ -720,10 +727,19 @@ config TEGRA
        select CPU_ARM720T if SPL_BUILD
        select CPU_V7 if !SPL_BUILD
 
-config TARGET_VEXPRESS_AEMV8A
+config TARGET_VEXPRESS64_AEMV8A
        bool "Support vexpress_aemv8a"
        select ARM64
 
+config TARGET_VEXPRESS64_BASE_FVP
+       bool "Support Versatile Express ARMv8a FVP BASE model"
+       select ARM64
+       select SEMIHOSTING
+
+config TARGET_VEXPRESS64_JUNO
+       bool "Support Versatile Express Juno Development Platform"
+       select ARM64
+
 config TARGET_LS2085A_EMU
        bool "Support ls2085a_emu"
        select ARM64
index 01cdb7ee76b7f13aaeb1c396e9f7a5e0829fbeeb..c56417dd2f1ec81d8fa1088d8c12fc0aaf6c3848 100644 (file)
@@ -53,7 +53,7 @@ int cleanup_before_linux(void)
         * After D-cache is flushed and before it is disabled there may
         * be some new valid entries brought into the cache. We are sure
         * that these lines are not dirty and will not affect our execution.
-        * (because unwinding the call-stack and setting a bit in CP15 SCTRL
+        * (because unwinding the call-stack and setting a bit in CP15 SCTLR
         * is all we did during this. We have not pushed anything on to the
         * stack. Neither have we affected any static data)
         * So just invalidate the entire d-cache again to avoid coherency
index 94d02970516e9efce5065852bf73182647dfd9de..be43e224fa37074bf2a939ad3e486f3268833910 100644 (file)
@@ -266,22 +266,33 @@ static void exynos5_sromc_config(int flags)
 
 static void exynos5_i2c_config(int peripheral, int flags)
 {
+       int func01, func23;
+
+        /* High-Speed I2C */
+       if (flags & PINMUX_FLAG_HS_MODE) {
+               func01 = 4;
+               func23 = 4;
+       } else {
+               func01 = 2;
+               func23 = 3;
+       }
+
        switch (peripheral) {
        case PERIPH_ID_I2C0:
-               gpio_cfg_pin(EXYNOS5_GPIO_B30, S5P_GPIO_FUNC(0x2));
-               gpio_cfg_pin(EXYNOS5_GPIO_B31, S5P_GPIO_FUNC(0x2));
+               gpio_cfg_pin(EXYNOS5_GPIO_B30, S5P_GPIO_FUNC(func01));
+               gpio_cfg_pin(EXYNOS5_GPIO_B31, S5P_GPIO_FUNC(func01));
                break;
        case PERIPH_ID_I2C1:
-               gpio_cfg_pin(EXYNOS5_GPIO_B32, S5P_GPIO_FUNC(0x2));
-               gpio_cfg_pin(EXYNOS5_GPIO_B33, S5P_GPIO_FUNC(0x2));
+               gpio_cfg_pin(EXYNOS5_GPIO_B32, S5P_GPIO_FUNC(func01));
+               gpio_cfg_pin(EXYNOS5_GPIO_B33, S5P_GPIO_FUNC(func01));
                break;
        case PERIPH_ID_I2C2:
-               gpio_cfg_pin(EXYNOS5_GPIO_A06, S5P_GPIO_FUNC(0x3));
-               gpio_cfg_pin(EXYNOS5_GPIO_A07, S5P_GPIO_FUNC(0x3));
+               gpio_cfg_pin(EXYNOS5_GPIO_A06, S5P_GPIO_FUNC(func23));
+               gpio_cfg_pin(EXYNOS5_GPIO_A07, S5P_GPIO_FUNC(func23));
                break;
        case PERIPH_ID_I2C3:
-               gpio_cfg_pin(EXYNOS5_GPIO_A12, S5P_GPIO_FUNC(0x3));
-               gpio_cfg_pin(EXYNOS5_GPIO_A13, S5P_GPIO_FUNC(0x3));
+               gpio_cfg_pin(EXYNOS5_GPIO_A12, S5P_GPIO_FUNC(func23));
+               gpio_cfg_pin(EXYNOS5_GPIO_A13, S5P_GPIO_FUNC(func23));
                break;
        case PERIPH_ID_I2C4:
                gpio_cfg_pin(EXYNOS5_GPIO_A20, S5P_GPIO_FUNC(0x3));
index fdc05b942f15bb80415c295faba6832e689d8b01..70048c10aee6736117e078931b75c4b6ba7756a5 100644 (file)
@@ -52,10 +52,10 @@ reset:
  * Continue to use ROM code vector only in OMAP4 spl)
  */
 #if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
-       /* Set V=0 in CP15 SCTRL register - for VBAR to point to vector */
-       mrc     p15, 0, r0, c1, c0, 0   @ Read CP15 SCTRL Register
+       /* Set V=0 in CP15 SCTLR register - for VBAR to point to vector */
+       mrc     p15, 0, r0, c1, c0, 0   @ Read CP15 SCTLR Register
        bic     r0, #CR_V               @ V = 0
-       mcr     p15, 0, r0, c1, c0, 0   @ Write CP15 SCTRL Register
+       mcr     p15, 0, r0, c1, c0, 0   @ Write CP15 SCTLR Register
 
        /* Set vector address in CP15 VBAR register */
        ldr     r0, =_start
index 36a76a24d971e7d012570cc7ad7e3c16a2a1a4f5..a774246a2779435b47376b4f7e2cb093a59a991d 100644 (file)
@@ -52,7 +52,7 @@ int pmu_set_nominal(void)
                debug("%s: Cannot find DVC I2C bus\n", __func__);
                return ret;
        }
-       ret = i2c_get_chip(bus, PMI_I2C_ADDRESS, &dev);
+       ret = i2c_get_chip(bus, PMI_I2C_ADDRESS, 1, &dev);
        if (ret) {
                debug("%s: Cannot find DVC I2C chip\n", __func__);
                return ret;
index 77fad48fb4bd72614d575660af1ae81d2188f9c1..7de227cc01aaae4fde1d817b9dd2670e57fe6ba5 100644 (file)
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "samsung,s3c2440-i2c";
-               interrupts = <0 0 0>;
+               reg = <0x13860000 0x100>;
+               interrupts = <0 56 0>;
        };
 
        i2c@13870000 {
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "samsung,s3c2440-i2c";
-               interrupts = <1 1 0>;
+               reg = <0x13870000 0x100>;
+               interrupts = <1 57 0>;
        };
 
        i2c@13880000 {
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "samsung,s3c2440-i2c";
-               interrupts = <2 2 0>;
+               reg = <0x13880000 0x100>;
+               interrupts = <2 58 0>;
        };
 
        i2c@13890000 {
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "samsung,s3c2440-i2c";
-               interrupts = <3 3 0>;
+               reg = <0x13890000 0x100>;
+               interrupts = <3 59 0>;
        };
 
        i2c@138a0000 {
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "samsung,s3c2440-i2c";
-               interrupts = <4 4 0>;
+               reg = <0x138a0000 0x100>;
+               interrupts = <4 60 0>;
        };
 
        i2c@138b0000 {
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "samsung,s3c2440-i2c";
-               interrupts = <5 5 0>;
+               reg = <0x138b0000 0x100>;
+               interrupts = <5 61 0>;
        };
 
        i2c@138c0000 {
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "samsung,s3c2440-i2c";
-               interrupts = <6 6 0>;
+               reg = <0x138c0000 0x100>;
+               interrupts = <6 62 0>;
        };
 
        i2c@138d0000 {
                #address-cells = <1>;
                #size-cells = <0>;
                compatible = "samsung,s3c2440-i2c";
-               interrupts = <7 7 0>;
+               reg = <0x138d0000 0x100>;
+               interrupts = <7 63 0>;
        };
 
        sdhci@12510000 {
                interrupts = <0 131 0>;
        };
 
-       gpio: gpio {
-               gpio-controller;
-               #gpio-cells = <2>;
-
-               interrupt-controller;
-               #interrupt-cells = <2>;
-       };
 };
index dd2476c1a39e35f74beb2f21d2cde8a44dcdbd04..3f877615844e107262316dead327905335f862d0 100644 (file)
@@ -36,7 +36,7 @@
        sdhci@12530000 {
                samsung,bus-width = <4>;
                samsung,timing = <1 2 3>;
-               cd-gpios = <&gpio 0xA2 0>;
+               cd-gpios = <&gpk2 2 0>;
        };
 
        sdhci@12540000 {
index 8c7a2c3a78792e777ae2b2019ddb8b1eb0e26989..36d02df3b078a4dd6da6197f779ff609b38ac881 100644 (file)
        sdhci@12510000 {
                samsung,bus-width = <8>;
                samsung,timing = <1 3 3>;
-               pwr-gpios = <&gpio 146 0>;
+               pwr-gpios = <&gpk0 2 0>;
        };
 
        sdhci@12520000 {
        sdhci@12530000 {
                samsung,bus-width = <4>;
                samsung,timing = <1 2 3>;
-               cd-gpios = <&gpio 284 0>;
+               cd-gpios = <&gpx3 4 0>;
        };
 
        sdhci@12540000 {
index 808c3f7cc3a2adc0183428fe3f0035169794aa85..16948c93422725571ab05f2f7ed6e8977cb38571 100644 (file)
@@ -24,7 +24,7 @@
        sdhci@12510000 {
                samsung,bus-width = <8>;
                samsung,timing = <1 3 3>;
-               pwr-gpios = <&gpio 146 0>;
+               pwr-gpios = <&gpk0 2 0>;
        };
 
        sdhci@12520000 {
@@ -34,7 +34,7 @@
        sdhci@12530000 {
                samsung,bus-width = <4>;
                samsung,timing = <1 2 3>;
-               cd-gpios = <&gpio 284 0>;
+               cd-gpios = <&gpx3 4 0>;
        };
 
        sdhci@12540000 {
 
        soft-spi {
                compatible = "u-boot,soft-spi";
-               cs-gpio = <&gpio 235 0>;        /* Y43 */
-               sclk-gpio = <&gpio 225 0>;      /* Y31 */
-               mosi-gpio = <&gpio 227 0>;      /* Y33 */
-               miso-gpio = <&gpio 224 0>;      /* Y30 */
+               cs-gpio = <&gpy4 3 0>;
+               sclk-gpio = <&gpy3 1 0>;
+               mosi-gpio = <&gpy3 3 0>;
+               miso-gpio = <&gpy3 0 0>;
                spi-delay-us = <1>;
                #address-cells = <1>;
                #size-cells = <0>;
index c78efec64957ea53e801df849da005f06e56d36c..00a2917596fcbb99ba932db0a36ca0676f3c4ef7 100644 (file)
 
        aliases {
                i2c0 = "/i2c@13860000";
+               i2c1 = "/i2c@13870000";
+               i2c2 = "/i2c@13880000";
+               i2c3 = "/i2c@13890000";
+               i2c4 = "/i2c@138a0000";
+               i2c5 = "/i2c@138b0000";
+               i2c6 = "/i2c@138c0000";
+               i2c7 = "/i2c@138d0000";
                serial0 = "/serial@13800000";
                console = "/serial@13810000";
                mmc2 = "sdhci@12530000";
@@ -51,7 +58,7 @@
        sdhci@12530000 {
                samsung,bus-width = <4>;
                samsung,timing = <1 2 3>;
-               cd-gpios = <&gpio 122 0>;
+               cd-gpios = <&gpk2 2 0>;
        };
 
        sdhci@12540000 {
index 60e4515a7e7a8833a2c1c62da90bf54fed404a03..dd238df13fe69dc36ba4057717be82b3009f55e1 100644 (file)
        sdhci@12510000 {
                samsung,bus-width = <8>;
                samsung,timing = <1 3 3>;
-               pwr-gpios = <&gpio 0x6a 0>;
+               pwr-gpios = <&gpk0 4 0>;
                status = "disabled";
        };
 
        sdhci@12530000 {
                samsung,bus-width = <4>;
                samsung,timing = <1 2 3>;
-               cd-gpios = <&gpio 0x7a 0>;
+               cd-gpios = <&gpk2 2 0>;
        };
 
        sdhci@12540000 {
        dwmmc@12550000 {
                samsung,bus-width = <8>;
                samsung,timing = <2 1 0>;
-               pwr-gpios = <&gpio 0x6a 0>;
+               pwr-gpios = <&gpk0 4 0>;
                fifoth_val = <0x203f0040>;
                bus_hz = <400000000>;
                div = <0x3>;
index e53906892c82de8b0ba922927fff25c64c859045..238acb80a2393a2b6eb204582ec1c4d75be9518f 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include "skeleton.dtsi"
+#include <dt-bindings/gpio/gpio.h>
 
 / {
        compatible = "samsung,exynos5";
                u-boot,dm-pre-reloc;
                id = <3>;
        };
-
-       gpio: gpio {
-       };
 };
index 202f2ea6ed9157767b3ef1d5e1b0f059f54a648b..21c0a214ea5207967a141170fb35f9b26e2a7e18 100644 (file)
        compatible = "samsung,arndale", "samsung,exynos5250";
 
        aliases {
+               i2c0 = "/i2c@12c60000";
+               i2c1 = "/i2c@12c70000";
+               i2c2 = "/i2c@12c80000";
+               i2c3 = "/i2c@12c90000";
+               i2c4 = "/i2c@12ca0000";
+               i2c5 = "/i2c@12cb0000";
+               i2c6 = "/i2c@12cc0000";
+               i2c7 = "/i2c@12cd0000";
                serial0 = "/serial@12C20000";
                console = "/serial@12C20000";
        };
index 885040920c077cad8aa26f8360daed79bc4d0d81..9273562bc54cf6bb73840c28a0c2853bcbe4ac59 100644 (file)
        };
 
        ehci@12110000 {
-               samsung,vbus-gpio = <&gpio 0x316 0>; /* X26 */
+               samsung,vbus-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
        };
 };
index bac501516fd257861f69c2b645553d0f2f920a33..7d8be69d73b7d14c522451bcf9ad552e4a74a97e 100644 (file)
@@ -44,7 +44,8 @@
                        reg = <0x1e>;
                        compatible = "google,cros-ec";
                        i2c-max-frequency = <100000>;
-                       ec-interrupt = <&gpio 182 1>;
+                       u-boot,i2c-offset-len = <0>;
+                       ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>;
                };
 
                power-regulator@48 {
@@ -68,7 +69,7 @@
                        reg = <0>;
                        compatible = "google,cros-ec";
                        spi-max-frequency = <5000000>;
-                       ec-interrupt = <&gpio 182 1>;
+                       ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>;
                        optimise-flash-write;
                        status = "disabled";
                };
@@ -76,7 +77,7 @@
 
        sound@3830000 {
                samsung,codec-type = "max98095";
-               codec-enable-gpio = <&gpio 0xb7 0>;
+               codec-enable-gpio = <&gpx1 7 GPIO_ACTIVE_HIGH>;
        };
 
        sound@12d60000 {
        };
 
        ehci@12110000 {
-               samsung,vbus-gpio = <&gpio 0xb1 0>; /* X11 */
+               samsung,vbus-gpio = <&gpx1 1 GPIO_ACTIVE_HIGH>;
        };
 
        xhci@12000000 {
-               samsung,vbus-gpio = <&gpio 0xbf 0>; /* X27 */
+               samsung,vbus-gpio = <&gpx2 7 GPIO_ACTIVE_HIGH>;
        };
 
        tmu@10060000 {
index d1d87350be306fb48b88e32d6e9ded69b3adef32..b801de9787531b3f6b29f4326375afd31ca5977d 100644 (file)
@@ -17,7 +17,7 @@
                "google,peach", "samsung,exynos5420", "samsung,exynos5";
 
        config {
-               google,bad-wake-gpios = <&gpio 0x56 0>; /* gpx0-6 */
+               google,bad-wake-gpios = <&gpx0 6 GPIO_ACTIVE_HIGH>;
                hwid = "PIT TEST A-A 7848";
                lazy-init = <1>;
        };
                        spi-half-duplex;
                        spi-max-timeout-ms = <1100>;
                        spi-frame-header = <0xec>;
-                       ec-interrupt = <&gpio 93 1>; /* GPX1_5 */
+                       ec-interrupt = <&gpx1 5 GPIO_ACTIVE_LOW>;
 
                        /*
                         * This describes the flash memory within the EC. Note
        };
 
        xhci@12000000 {
-               samsung,vbus-gpio = <&gpio 0x40 0>; /* H00 */
+               samsung,vbus-gpio = <&gph0 0 GPIO_ACTIVE_HIGH>;
        };
 
        xhci@12400000 {
-               samsung,vbus-gpio = <&gpio 0x41 0>; /* H01 */
+               samsung,vbus-gpio = <&gph0 1 GPIO_ACTIVE_HIGH>;
        };
 
        fimd@14400000 {
index 79a7acd7df77d67e36c2e2e3dc88871342b74522..8f4663733cc712b6621709de75c8cb77c4110021 100644 (file)
@@ -32,7 +32,7 @@
        };
 
        ehci@12110000 {
-               samsung,vbus-gpio = <&gpio 0x66 0>; /* X26 */
+               samsung,vbus-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
        };
 
        serial@12C20000 {
index e7c380f83beba0381b6d36ab09111056ab7492d6..e4bc100995c3112b2749f5bf96d4a449debbeaf5 100644 (file)
@@ -17,7 +17,7 @@
                "google,peach", "samsung,exynos5800", "samsung,exynos5";
 
        config {
-               google,bad-wake-gpios = <&gpio 0x56 0>; /* gpx0-6 */
+               google,bad-wake-gpios = <&gpx0 6 GPIO_ACTIVE_HIGH>;
                hwid = "PIT TEST A-A 7848";
                lazy-init = <1>;
        };
@@ -32,7 +32,7 @@
                mem-manuf = "samsung";
                mem-type = "ddr3";
                clock-frequency = <800000000>;
-               arm-frequency = <1700000000>;
+               arm-frequency = <900000000>;
        };
 
        tmu@10060000 {
                        spi-half-duplex;
                        spi-max-timeout-ms = <1100>;
                        spi-frame-header = <0xec>;
-                       ec-interrupt = <&gpio 93 1>; /* GPX1_5 */
+                       ec-interrupt = <&gpx1 5 GPIO_ACTIVE_LOW>;
 
                        /*
                         * This describes the flash memory within the EC. Note
        };
 
        xhci@12000000 {
-               samsung,vbus-gpio = <&gpio 0x40 0>; /* H00 */
+               samsung,vbus-gpio = <&gph0 0 GPIO_ACTIVE_HIGH>;
        };
 
        xhci@12400000 {
-               samsung,vbus-gpio = <&gpio 0x41 0>; /* H01 */
+               samsung,vbus-gpio = <&gph0 1 GPIO_ACTIVE_HIGH>;
        };
 
        fimd@14400000 {
index 81ad212e71291906f6d3b16ea020cc41e68ee727..51ff266d760a69c56d12bd69b021b3c7ed5de8c0 100644 (file)
@@ -57,7 +57,7 @@
        };
 
        sdhci@78000400 {
-               cd-gpios = <&gpio 170 1>; /* gpio PV2 */
+               cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
                bus-width = <4>;
                status = "okay";
        };
@@ -68,8 +68,7 @@
        };
 
        usb@7d008000 {
-               /* SPDIF_IN: USB_VBUS_EN1 */
-               nvidia,vbus-gpio = <&gpio 86 0>;
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
                status = "okay";
        };
 };
index 51fef54d570e2ebc6fc510cbf86fdab7ed04c3fa..e7b66d81a499e683bba22b21110798f75dcb9918 100644 (file)
 
        sdhci@700b0400 {
                status = "okay";
-               cd-gpios = <&gpio 170 1>; /* gpio PV2 */
-               power-gpios = <&gpio 136 0>; /* gpio PR0 */
+               cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
+               power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>;
+               wp-gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_HIGH>;
                bus-width = <4>;
        };
 
        usb@7d000000 {
                status = "okay";
                dr_mode = "otg";
-               nvidia,vbus-gpio = <&gpio 108 0>; /* gpio PN4, USB_VBUS_EN0 */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
        };
 
        usb@7d008000 {
                status = "okay";
-               nvidia,vbus-gpio = <&gpio 109 0>; /* gpio PN5, USB_VBUS_EN1 */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>;
        };
 
        regulators {
index f7ccfc5ddd4bf29a6b6f1c86354b55c67513721e..9e93cf90c76e68c8780a1014e4af7439f5b12cf6 100644 (file)
@@ -72,8 +72,9 @@
 
        sdhci@700b0400 {
                status = "okay";
-               cd-gpios = <&gpio 170 0>; /* gpio PV2 */
-               power-gpios = <&gpio 136 0>; /* gpio PR0 */
+               cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
+               power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>;
+               wp-gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_LOW>;
                bus-width = <4>;
        };
 
        usb@7d000000 {
                status = "okay";
                dr_mode = "otg";
-               nvidia,vbus-gpio = <&gpio 108 0>; /* gpio PN4, USB_VBUS_EN0 */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
        };
 
        usb@7d008000 {
                status = "okay";
-               nvidia,vbus-gpio = <&gpio 109 0>; /* gpio PN5, USB_VBUS_EN1 */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>;
        };
 };
index 7cf08f4101f3ae072cda3abc37e55e44a500e101..3131b9201b7029f012c3e4f80df83663c4697d94 100644 (file)
        };
 
        usb@c5004000 {
-               nvidia,phy-reset-gpio = <&gpio 169 0>; /* PV1 */
-               nvidia,vbus-gpio = <&gpio 217 0>; /* PBB1 */
+               nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>;
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(BB, 1) GPIO_ACTIVE_HIGH>;
        };
 
        usb@c5008000 {
-               nvidia,vbus-gpio = <&gpio 178 1>; /* PW2 low-active */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>;
        };
 
        nand-controller@70008000 {
-               nvidia,wp-gpios = <&gpio 144 0>; /* PS0 */
+               nvidia,wp-gpios = <&gpio TEGRA_GPIO(S, 0) GPIO_ACTIVE_HIGH>;
                nvidia,width = <8>;
                nvidia,timing = <15 100 25 80 25 10 15 10 100>;
 
@@ -43,7 +43,7 @@
 
        sdhci@c8000600 {
                status = "okay";
-               cd-gpios = <&gpio 23 1>; /* gpio PC7 */
+               cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
                bus-width = <4>;
        };
 };
index 982a14c61c498ff26409b99abb9a61c07586d332..e6e42295e216620e7ad28dbd3ad0245410de30b4 100644 (file)
@@ -37,7 +37,7 @@
        };
 
        nand-controller@70008000 {
-               nvidia,wp-gpios = <&gpio 23 0>;         /* PC7 */
+               nvidia,wp-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_HIGH>;
                nvidia,width = <8>;
                nvidia,timing = <26 100 20 80 20 10 12 10 70>;
                nand@0 {
        };
 
        usb@c5004000 {
-               nvidia,phy-reset-gpio = <&gpio 169 0>; /* gpio PV1 */
+               nvidia,phy-reset-gpio = <&gpio TEGRA_GPIO(V, 1) 0>;
        };
 
        sdhci@c8000200 {
                status = "okay";
-               cd-gpios = <&gpio 69 1>; /* gpio PI5 */
-               wp-gpios = <&gpio 57 0>; /* gpio PH1 */
-               power-gpios = <&gpio 155 0>; /* gpio PT3 */
+               cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+               wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+               power-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>;
                bus-width = <4>;
        };
 
        sdhci@c8000600 {
                status = "okay";
-               cd-gpios = <&gpio 58 1>; /* gpio PH2 */
-               wp-gpios = <&gpio 59 0>; /* gpio PH3 */
-               power-gpios = <&gpio 70 0>; /* gpio PI6 */
+               cd-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_LOW>;
+               wp-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>;
+               power-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>;
                bus-width = <8>;
        };
 
                vsyncx-active-high;
                nvidia,bits-per-pixel = <16>;
                nvidia,pwm = <&pwm 0 0>;
-               nvidia,backlight-enable-gpios = <&gpio 13 0>;   /* PB5 */
-               nvidia,lvds-shutdown-gpios = <&gpio 10 0>;      /* PB2 */
-               nvidia,backlight-vdd-gpios = <&gpio 176 0>;     /* PW0 */
-               nvidia,panel-vdd-gpios = <&gpio 22 0>;          /* PC6 */
+               nvidia,backlight-enable-gpios = <&gpio TEGRA_GPIO(B, 5)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,lvds-shutdown-gpios = <&gpio TEGRA_GPIO(B, 2)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,backlight-vdd-gpios = <&gpio TEGRA_GPIO(W, 0)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,panel-vdd-gpios = <&gpio TEGRA_GPIO(C, 6)
+                                                       GPIO_ACTIVE_HIGH>;
                nvidia,panel-timings = <0 0 200 0 0>;
        };
 };
index be2ed42dbd74e67233f145a48f483977a36b7e92..b6b57abdef94f9b2f79a7a44c860bab3919c8e3e 100644 (file)
 
                nvidia,bits-per-pixel = <16>;
                nvidia,pwm = <&pwm 0 500000>;
-               nvidia,backlight-enable-gpios = <&gpio 13 0>; /* PB5 */
-               nvidia,backlight-vdd-gpios = <&gpio 176 0>; /* PW0 */
-               nvidia,lvds-shutdown-gpios = <&gpio 10 0>; /* PB2 */
+               nvidia,backlight-enable-gpios = <&gpio TEGRA_GPIO(B, 5)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,lvds-shutdown-gpios = <&gpio TEGRA_GPIO(B, 2)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,backlight-vdd-gpios = <&gpio TEGRA_GPIO(W, 0)
+                                                       GPIO_ACTIVE_HIGH>;
                nvidia,panel-timings = <0 0 0 0>;
        };
 };
index 9d735b5e6bf6541b3dbfb0974cc3ee668d129d02..16381c3a4c78777e39812e205361797aee3d984b 100644 (file)
@@ -61,9 +61,9 @@
 
        sdhci@c8000000 {
                status = "okay";
-               cd-gpios = <&gpio 173 1>; /* gpio PV5 */
-               wp-gpios = <&gpio 57 0>; /* gpio PH1 */
-               power-gpios = <&gpio 169 0>; /* gpio PV1 */
+               cd-gpios = <&gpio TEGRA_GPIO(V, 5) GPIO_ACTIVE_LOW>;
+               wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+               power-gpios = <&gpio TEGRA_GPIO(V, 1) GPIO_ACTIVE_HIGH>;
                bus-width = <4>;
        };
 
                hsync-active-high;
                nvidia,bits-per-pixel = <16>;
                nvidia,pwm = <&pwm 0 0>;
-               nvidia,backlight-enable-gpios = <&gpio 164 0>;  /* PU4 */
-               nvidia,lvds-shutdown-gpios = <&gpio 102 0>;     /* PM6 */
-               nvidia,backlight-vdd-gpios = <&gpio 176 0>;     /* PW0 */
-               nvidia,panel-vdd-gpios = <&gpio 4 0>;           /* PA4 */
+               nvidia,backlight-enable-gpios = <&gpio TEGRA_GPIO(U, 4)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,lvds-shutdown-gpios = <&gpio TEGRA_GPIO(M, 6)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,backlight-vdd-gpios = <&gpio TEGRA_GPIO(W, 0)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,panel-vdd-gpios = <&gpio TEGRA_GPIO(A, 4)
+                                                       GPIO_ACTIVE_HIGH>;
                nvidia,panel-timings = <400 4 203 17 15>;
        };
 };
index 43b9911c896a0aed9dbc6bca8f0e3532b8093cf5..10f399284ae189ca9bee5c5d438dba3c7085bebc 100644 (file)
@@ -65,7 +65,7 @@
        };
 
        nand-controller@70008000 {
-               nvidia,wp-gpios = <&gpio 59 0>;         /* PH3 */
+               nvidia,wp-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>;
                nvidia,width = <8>;
                nvidia,timing = <26 100 20 80 20 10 12 10 70>;
                nand@0 {
        };
 
        usb@c5000000 {
-               nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
                dr_mode = "otg";
        };
 
 
        sdhci@c8000400 {
                status = "okay";
-               cd-gpios = <&gpio 69 1>; /* gpio PI5 */
-               wp-gpios = <&gpio 57 0>; /* gpio PH1 */
-               power-gpios = <&gpio 70 0>; /* gpio PI6 */
+               cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+               wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+               power-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>;
                bus-width = <4>;
        };
 
                hsync-active-high;
                nvidia,bits-per-pixel = <16>;
                nvidia,pwm = <&pwm 2 0>;
-               nvidia,backlight-enable-gpios = <&gpio 28 0>;   /* PD4 */
-               nvidia,lvds-shutdown-gpios = <&gpio 10 0>;      /* PB2 */
-               nvidia,backlight-vdd-gpios = <&gpio 176 0>;     /* PW0 */
-               nvidia,panel-vdd-gpios = <&gpio 22 0>;          /* PC6 */
+               nvidia,backlight-enable-gpios = <&gpio TEGRA_GPIO(D, 4)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,lvds-shutdown-gpios = <&gpio TEGRA_GPIO(B, 2)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,backlight-vdd-gpios = <&gpio TEGRA_GPIO(W, 0)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,panel-vdd-gpios = <&gpio TEGRA_GPIO(C, 6)
+                                                       GPIO_ACTIVE_HIGH>;
                nvidia,panel-timings = <400 4 203 17 15>;
        };
 };
index f379622c944963cba0a0c568cac440bc1dc35eb3..78449e613379dc12ebc8914fdd5f8957c8150ac0 100644 (file)
@@ -14,7 +14,8 @@
                        pll-supply = <&hdmi_pll_reg>;
 
                        nvidia,ddc-i2c-bus = <&hdmi_ddc>;
-                       nvidia,hpd-gpio = <&gpio 111 0>; /* PN7 */
+                       nvidia,hpd-gpio = <&gpio TEGRA_GPIO(N, 7)
+                               GPIO_ACTIVE_HIGH>;
                };
        };
 
        };
 
        nand-controller@70008000 {
-               nvidia,wp-gpios = <&gpio 23 0>; /* PC7 */
+               nvidia,wp-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_HIGH>;
                nvidia,width = <8>;
                nvidia,timing = <26 100 20 80 20 10 12 10 70>;
 
        };
 
        sdhci@c8000600 {
-               cd-gpios = <&gpio 58 1>; /* gpio PH2 */
-               wp-gpios = <&gpio 59 0>; /* gpio PH3 */
+               cd-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_LOW>;
+               wp-gpios = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>;
                bus-width = <4>;
                status = "okay";
        };
index e99bd447c1b72bc71bb36a1bc06abec3a0ff93eb..94ba6dc2d41d65e6e9c85873594ccefea979f54d 100644 (file)
 
                nvidia,bits-per-pixel = <16>;
                nvidia,pwm = <&pwm 0 500000>;
-               nvidia,backlight-enable-gpios = <&gpio 13 0>; /* PB5 */
-               nvidia,backlight-vdd-gpios = <&gpio 176 0>; /* PW0 */
-               nvidia,lvds-shutdown-gpios = <&gpio 10 0>; /* PB2 */
+               nvidia,backlight-enable-gpios = <&gpio TEGRA_GPIO(B, 5)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,lvds-shutdown-gpios = <&gpio TEGRA_GPIO(B, 2)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,backlight-vdd-gpios = <&gpio TEGRA_GPIO(W, 0)
+                                                       GPIO_ACTIVE_HIGH>;
                nvidia,panel-timings = <0 0 0 0>;
        };
 };
index 1637cbd58e32ec4e6f7a4eaf526b348d2fc64f45..27b118f212ad7bec41953dd6e2c18c8da8c431b9 100644 (file)
@@ -62,7 +62,7 @@
        };
 
        usb@c5000000 {
-               nvidia,vbus-gpio = <&gpio 170 0>; /* PV2 */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
        };
 
        usb@c5004000 {
@@ -76,8 +76,8 @@
 
        sdhci@c8000600 {
                status = "okay";
-               cd-gpios = <&gpio 121 1>; /* gpio PP1 */
-               wp-gpios = <&gpio 122 0>; /* gpio PP2 */
+               cd-gpios = <&gpio TEGRA_GPIO(P, 1) GPIO_ACTIVE_LOW>;
+               wp-gpios = <&gpio TEGRA_GPIO(P, 2) GPIO_ACTIVE_HIGH>;
                bus-width = <4>;
        };
 
                        regulator-min-microvolt = <5000000>;
                        regulator-max-microvolt = <5000000>;
                        enable-active-high;
-                       gpio = <&gpio TEGRA_GPIO(V, 2) 0>;
+                       gpio = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_HIGH>;
                        regulator-always-on;
                        regulator-boot-on;
                };
index 68122039180a378c7b20f9f31dbe77ab37a0ed82..939e567d1334f8de272f8a35d4cec7ba142783a6 100644 (file)
@@ -61,9 +61,9 @@
 
        sdhci@c8000400 {
                status = "okay";
-               cd-gpios = <&gpio 69 1>; /* gpio PI5 */
-               wp-gpios = <&gpio 57 0>; /* gpio PH1 */
-               power-gpios = <&gpio 70 0>; /* gpio PI6 */
+               cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+               wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>;
+               power-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>;
                bus-width = <4>;
        };
 
                vsync-active-high;
                nvidia,bits-per-pixel = <16>;
                nvidia,pwm = <&pwm 2 0>;
-               nvidia,backlight-enable-gpios = <&gpio 28 0>;   /* PD4 */
-               nvidia,lvds-shutdown-gpios = <&gpio 10 0>;      /* PB2 */
-               nvidia,backlight-vdd-gpios = <&gpio 176 0>;     /* PW0 */
-               nvidia,panel-vdd-gpios = <&gpio 22 0>;          /* PC6 */
+               nvidia,backlight-enable-gpios = <&gpio TEGRA_GPIO(D, 4)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,lvds-shutdown-gpios = <&gpio TEGRA_GPIO(B, 2)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,backlight-vdd-gpios = <&gpio TEGRA_GPIO(W, 0)
+                                                       GPIO_ACTIVE_HIGH>;
+               nvidia,panel-vdd-gpios = <&gpio TEGRA_GPIO(C, 6)
+                                                       GPIO_ACTIVE_HIGH>;
                nvidia,panel-timings = <0 0 200 0 0>;
        };
 };
index 4fd2496dbc57f07e5c42771814c0ac5df04a34aa..c4a28eb427deff1bb0c79ada0d1fa857f8acd3da 100644 (file)
@@ -66,7 +66,7 @@
 
        sdhci@c8000400 {
                status = "okay";
-               wp-gpios = <&gpio 173 0>; /* gpio PV5 */
+               wp-gpios = <&gpio TEGRA_GPIO(V, 5) GPIO_ACTIVE_HIGH>;
                bus-width = <8>;
        };
 
index 5bad3e77698ce81f9ad3f2aef9e6a5052e5b5bf4..15db0f275b6d3740caa1756e9394de6c93764674 100644 (file)
        sdhci@78000000 {
                status = "okay";
                bus-width = <4>;
-               cd-gpios = <&gpio 229 1>; /* PCC5, SD1_CD# */
+               cd-gpios = <&gpio TEGRA_GPIO(CC, 5) GPIO_ACTIVE_HIGH>;
        };
 
        sdhci@78000400 {
                status = "okay";
                bus-width = <8>;
-               cd-gpios = <&gpio 171 1>; /* PV3, MMC1_CD# */
+               cd-gpios = <&gpio TEGRA_GPIO(V, 3) GPIO_ACTIVE_HIGH>;
        };
 
        sdhci@78000600 {
        usb@7d000000 {
                status = "okay";
                dr_mode = "peripheral";
-               nvidia,vbus-gpio = <&gpio 157 0>;       /* PT5, USBO1_EN */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(T, 5) GPIO_ACTIVE_HIGH>;
        };
 
        /* EHCI instance 1: USB2_DP/N -> USBH2_DP/N */
        usb@7d004000 {
                status = "okay";
-               nvidia,vbus-gpio = <&gpio 233 0>;       /* PDD1, USBH_EN */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>;
                phy_type = "utmi";
        };
 
        /* EHCI instance 2: USB3_DP/N -> USBH3_DP/N */
        usb@7d008000 {
                status = "okay";
-               nvidia,vbus-gpio = <&gpio 233 0>;       /* PDD1, USBH_EN */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 1) GPIO_ACTIVE_HIGH>;
        };
 
        regulators {
index 5903af68384b80f6c0f8373a6e3a1b8b420e69fa..ae836363ab5242550886196ea1d7a884218a83e6 100644 (file)
 
        sdhci@78000000 {
                status = "okay";
-               cd-gpios = <&gpio 69 1>; /* gpio PI5 */
-               wp-gpios = <&gpio 155 0>; /* gpio PT3 */
-               power-gpios = <&gpio 31 0>; /* gpio PD7 */
+               cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+               wp-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>;
+               power-gpios = <&gpio TEGRA_GPIO(D, 7) GPIO_ACTIVE_HIGH>;
                bus-width = <4>;
        };
 
        usb@7d000000 {
                status = "okay";
                dr_mode = "otg";
-               nvidia,vbus-gpio = <&gpio 238 0>; /* gpio DD6, PEX_L1_CLKREQ */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 6) GPIO_ACTIVE_HIGH>;
        };
 
        usb@7d008000 {
-               nvidia,vbus-gpio = <&gpio 236 0>; /* PDD4 */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 4) GPIO_ACTIVE_HIGH>;
                status = "okay";
        };
 
index e13d0fb467137766fcfe5677ca1cf64d889a82de..23ca141df2a55b9634a5e034a3a5c7dfddde79a4 100644 (file)
 
        sdhci@78000000 {
                status = "okay";
-               cd-gpios = <&gpio 69 1>; /* gpio PI5 */
-               wp-gpios = <&gpio 155 0>; /* gpio PT3 */
-               power-gpios = <&gpio 31 0>; /* gpio PD7 */
+               cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+               wp-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>;
+               power-gpios = <&gpio TEGRA_GPIO(D, 7) GPIO_ACTIVE_HIGH>;
                bus-width = <4>;
        };
 
        };
 
        usb@7d008000 {
-               nvidia,vbus-gpio = <&gpio 236 0>;       /* PDD4 */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 4) GPIO_ACTIVE_HIGH>;
                status = "okay";
        };
 
index 37b6abd52f05480018af45c46458b56aa4fd664f..6cd1902f11bcb563b8daab2ee7792325f9913628 100644 (file)
@@ -64,7 +64,7 @@
        sdhci@78000200 {
                status = "okay";
                bus-width = <4>;
-               cd-gpios = <&gpio 23 1>; /* PC7, MMCD */
+               cd-gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>;
        };
 
        sdhci@78000600 {
        usb@7d004000 {
                status = "okay";
                phy_type = "utmi";
-               nvidia,vbus-gpio = <&gpio 234 0>;       /* PDD2, VBUS_LAN */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 2) GPIO_ACTIVE_HIGH>;
        };
 
        /* EHCI instance 2: USB3_DP/N -> USBH_P/N */
        usb@7d008000 {
                status = "okay";
-               nvidia,vbus-gpio = <&gpio 178 1>;       /* PW2, USBH_PEN */
+               nvidia,vbus-gpio = <&gpio TEGRA_GPIO(W, 2) GPIO_ACTIVE_LOW>;
        };
 };
index c73afef34ada174178a4aeaeb19b40ef11544842..8eff627f3d0ba546309d2127323aa2bbbe5aca99 100644 (file)
@@ -55,8 +55,8 @@
 
        /* SD slot on the base board */
        sdhci@78000400 {
-               cd-gpios = <&gpio 69 1>; /* gpio PI5 */
-               wp-gpios = <&gpio 67 0>; /* gpio PI3 */
+               cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+               wp-gpios = <&gpio TEGRA_GPIO(I, 3) GPIO_ACTIVE_HIGH>;
                bus-width = <4>;
        };
 
index 0b91ef658ca96a0b259f661c7f3cd10bd5520eb5..d0ae7575dae098bd01cb45ed92eee978d6b4768b 100644 (file)
@@ -23,6 +23,9 @@ enum {
        /* Flags for SROM controller */
        PINMUX_FLAG_BANK        = 3 << 0,       /* bank number (0-3) */
        PINMUX_FLAG_16BIT       = 1 << 2,       /* 16-bit width */
+
+       /* Flags for I2C */
+       PINMUX_FLAG_HS_MODE     = 1 << 1,       /* I2C High Speed Mode */
 };
 
 /**
diff --git a/arch/arm/include/asm/arch-pantheon/gpio.h b/arch/arm/include/asm/arch-pantheon/gpio.h
new file mode 100644 (file)
index 0000000..e69de29
index 84e7b5553de16cb5ea8f5965079ec169d2459022..a20bdaa6187257a8fdd912d8e509e68ba27aac93 100644 (file)
@@ -10,6 +10,7 @@
 #define __TEGRA_MMC_H_
 
 #include <fdtdec.h>
+#include <asm/gpio.h>
 
 /* for mmc_config definition */
 #include <mmc.h>
@@ -134,9 +135,9 @@ struct mmc_host {
        int enabled;            /* 1 to enable, 0 to disable */
        int width;              /* Bus Width, 1, 4 or 8 */
        enum periph_id mmc_id;  /* Peripheral ID: PERIPH_ID_... */
-       struct fdt_gpio_state cd_gpio;          /* Change Detect GPIO */
-       struct fdt_gpio_state pwr_gpio;         /* Power GPIO */
-       struct fdt_gpio_state wp_gpio;          /* Write Protect GPIO */
+       struct gpio_desc cd_gpio;       /* Change Detect GPIO */
+       struct gpio_desc pwr_gpio;      /* Power GPIO */
+       struct gpio_desc wp_gpio;       /* Write Protect GPIO */
        unsigned int version;   /* SDHCI spec. version */
        unsigned int clock;     /* Current clock (MHz) */
        struct mmc_config cfg;  /* mmc configuration */
index a04c84e54b2251d54edbb017e216ded626c88bd4..6feeda3ba83ec42674f589f4dbd4fb1e3948774d 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <asm/arch/dc.h>
 #include <fdtdec.h>
+#include <asm/gpio.h>
 
 /* This holds information about a window which can be displayed */
 struct disp_ctl_win {
@@ -72,10 +73,10 @@ struct fdt_panel_config {
        int pwm_channel;                /* PWM channel to use for backlight */
        enum lcd_cache_t cache_type;
 
-       struct fdt_gpio_state backlight_en;     /* GPIO for backlight enable */
-       struct fdt_gpio_state lvds_shutdown;    /* GPIO for lvds shutdown */
-       struct fdt_gpio_state backlight_vdd;    /* GPIO for backlight vdd */
-       struct fdt_gpio_state panel_vdd;        /* GPIO for panel vdd */
+       struct gpio_desc backlight_en;  /* GPIO for backlight enable */
+       struct gpio_desc lvds_shutdown; /* GPIO for lvds shutdown */
+       struct gpio_desc backlight_vdd; /* GPIO for backlight vdd */
+       struct gpio_desc panel_vdd;     /* GPIO for panel vdd */
        /*
         * Panel required timings
         * Timing 1: delay between panel_vdd-rise and data-rise
index 2dbba756d737f6674ed050edad6bd212ffefb65b..a26ae872933ef1ad8309e3bac55d76637cd3edc2 100644 (file)
@@ -7,19 +7,4 @@
 #ifndef _ZYNQ_GPIO_H
 #define _ZYNQ_GPIO_H
 
-inline int gpio_get_value(unsigned gpio)
-{
-       return 0;
-}
-
-inline int gpio_set_value(unsigned gpio, int val)
-{
-       return 0;
-}
-
-inline int gpio_request(unsigned gpio, const char *label)
-{
-       return 0;
-}
-
 #endif /* _ZYNQ_GPIO_H */
index b7f118801d10b812bfea29a1a905b47498bb131a..91aa5cc89c387d90800c1146a77c6e1f196061ae 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "cpu.h"
 #include "initcode.h"
+#include "exports.h"
 
 ulong bfin_poweron_retx;
 DECLARE_GLOBAL_DATA_PTR;
@@ -121,7 +122,7 @@ static void display_global_data(void)
        printf(" |-ram_size: %lx\n", gd->ram_size);
        printf(" |-env_addr: %lx\n", gd->env_addr);
        printf(" |-env_valid: %lx\n", gd->env_valid);
-       printf(" |-jt(%p): %p\n", gd->jt, *(gd->jt));
+       printf(" |-jt(%p): %p\n", gd->jt, gd->jt->get_version);
        printf(" \\-bd: %p\n", gd->bd);
        printf("   |-bi_boot_params: %lx\n", bd->bi_boot_params);
        printf("   |-bi_memstart: %lx\n", bd->bi_memstart);
index ef7892975a72998cf36f56699e6de40046566d7f..bc4283d2f13b551cb747d796794286eabbd83027 100644 (file)
@@ -36,6 +36,7 @@ config TARGET_VCT
        select SUPPORTS_BIG_ENDIAN
        select SUPPORTS_CPU_MIPS32_R1
        select SUPPORTS_CPU_MIPS32_R2
+       select SYS_MIPS_CACHE_INIT_RAM_LOAD
 
 config TARGET_DBAU1X00
        bool "Support dbau1x00"
@@ -43,12 +44,14 @@ config TARGET_DBAU1X00
        select SUPPORTS_LITTLE_ENDIAN
        select SUPPORTS_CPU_MIPS32_R1
        select SUPPORTS_CPU_MIPS32_R2
+       select SYS_MIPS_CACHE_INIT_RAM_LOAD
 
 config TARGET_PB1X00
        bool "Support pb1x00"
        select SUPPORTS_LITTLE_ENDIAN
        select SUPPORTS_CPU_MIPS32_R1
        select SUPPORTS_CPU_MIPS32_R2
+       select SYS_MIPS_CACHE_INIT_RAM_LOAD
 
 
 endchoice
@@ -185,6 +188,9 @@ config 64BIT
 config SWAP_IO_SPACE
        bool
 
+config SYS_MIPS_CACHE_INIT_RAM_LOAD
+       bool
+
 endif
 
 endmenu
index 0a9e7e614b2061ee674a91add20888f4e9ee1e5b..43f0f5c5046b0361dfd20b8e5058edd046bbf5ad 100644 (file)
@@ -2,9 +2,9 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-head-$(CONFIG_CPU_MIPS32) := arch/mips/cpu/mips32/start.o
-head-$(CONFIG_CPU_MIPS64) := arch/mips/cpu/mips64/start.o
+head-y := arch/mips/cpu/start.o
 
-libs-$(CONFIG_CPU_MIPS32) += arch/mips/cpu/mips32/
-libs-$(CONFIG_CPU_MIPS64) += arch/mips/cpu/mips64/
+libs-y += arch/mips/cpu/
 libs-y += arch/mips/lib/
+
+libs-$(CONFIG_SOC_AU1X00) += arch/mips/mach-au1x00/
diff --git a/arch/mips/cpu/Makefile b/arch/mips/cpu/Makefile
new file mode 100644 (file)
index 0000000..fc6b455
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+extra-y        = start.o
+
+obj-y += time.o
+obj-y += interrupts.o
+obj-y += cpu.o
diff --git a/arch/mips/cpu/cpu.c b/arch/mips/cpu/cpu.c
new file mode 100644 (file)
index 0000000..8d3b2f5
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <netdev.h>
+#include <linux/compiler.h>
+#include <asm/mipsregs.h>
+#include <asm/reboot.h>
+
+void __weak _machine_restart(void)
+{
+       fprintf(stderr, "*** reset failed ***\n");
+
+       while (1)
+               /* NOP */;
+}
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       _machine_restart();
+
+       return 0;
+}
+
+void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
+{
+       write_c0_entrylo0(low0);
+       write_c0_pagemask(pagemask);
+       write_c0_entrylo1(low1);
+       write_c0_entryhi(hi);
+       write_c0_index(index);
+       tlb_write_indexed();
+}
diff --git a/arch/mips/cpu/mips32/Makefile b/arch/mips/cpu/mips32/Makefile
deleted file mode 100644 (file)
index fa82dd3..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#
-# (C) Copyright 2003-2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# SPDX-License-Identifier:     GPL-2.0+
-#
-
-extra-y        = start.o
-obj-y  = cache.o
-obj-y  += cpu.o interrupts.o time.o
-
-obj-$(CONFIG_SOC_AU1X00) += au1x00/
diff --git a/arch/mips/cpu/mips64/Makefile b/arch/mips/cpu/mips64/Makefile
deleted file mode 100644 (file)
index 899c319..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# (C) Copyright 2003-2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-#
-# SPDX-License-Identifier:     GPL-2.0+
-#
-
-extra-y        = start.o
-obj-y  = cpu.o interrupts.o time.o cache.o
diff --git a/arch/mips/cpu/mips64/cache.S b/arch/mips/cpu/mips64/cache.S
deleted file mode 100644 (file)
index 36d8688..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- *  Cache-handling routined for MIPS CPUs
- *
- *  Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <asm-offsets.h>
-#include <config.h>
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/cacheops.h>
-
-#define RA             t9
-
-/*
- * 16kB is the maximum size of instruction and data caches on MIPS 4K,
- * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience.
- *
- * Note that the above size is the maximum size of primary cache. U-Boot
- * doesn't have L2 cache support for now.
- */
-#define MIPS_MAX_CACHE_SIZE    0x10000
-
-#define INDEX_BASE     CKSEG0
-
-       .macro  cache_op op addr
-       .set    push
-       .set    noreorder
-       .set    mips3
-       cache   \op, 0(\addr)
-       .set    pop
-       .endm
-
-       .macro  f_fill64 dst, offset, val
-       LONG_S  \val, (\offset +  0 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  1 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  2 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  3 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  4 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  5 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  6 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  7 * LONGSIZE)(\dst)
-#if LONGSIZE == 4
-       LONG_S  \val, (\offset +  8 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset +  9 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset + 10 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset + 11 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset + 12 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset + 13 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset + 14 * LONGSIZE)(\dst)
-       LONG_S  \val, (\offset + 15 * LONGSIZE)(\dst)
-#endif
-       .endm
-
-/*
- * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
- */
-LEAF(mips_init_icache)
-       blez            a1, 9f
-       mtc0            zero, CP0_TAGLO
-       /* clear tag to invalidate */
-       PTR_LI          t0, INDEX_BASE
-       PTR_ADDU        t1, t0, a1
-1:     cache_op        INDEX_STORE_TAG_I t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 1b
-       /* fill once, so data field parity is correct */
-       PTR_LI          t0, INDEX_BASE
-2:     cache_op        FILL t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 2b
-       /* invalidate again - prudent but not strictly neccessary */
-       PTR_LI          t0, INDEX_BASE
-1:     cache_op        INDEX_STORE_TAG_I t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 1b
-9:     jr              ra
-       END(mips_init_icache)
-
-/*
- * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
- */
-LEAF(mips_init_dcache)
-       blez            a1, 9f
-       mtc0            zero, CP0_TAGLO
-       /* clear all tags */
-       PTR_LI          t0, INDEX_BASE
-       PTR_ADDU        t1, t0, a1
-1:     cache_op        INDEX_STORE_TAG_D t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 1b
-       /* load from each line (in cached space) */
-       PTR_LI          t0, INDEX_BASE
-2:     LONG_L          zero, 0(t0)
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 2b
-       /* clear all tags */
-       PTR_LI          t0, INDEX_BASE
-1:     cache_op        INDEX_STORE_TAG_D t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 1b
-9:     jr              ra
-       END(mips_init_dcache)
-
-/*
- * mips_cache_reset - low level initialisation of the primary caches
- *
- * This routine initialises the primary caches to ensure that they have good
- * parity.  It must be called by the ROM before any cached locations are used
- * to prevent the possibility of data with bad parity being written to memory.
- *
- * To initialise the instruction cache it is essential that a source of data
- * with good parity is available. This routine will initialise an area of
- * memory starting at location zero to be used as a source of parity.
- *
- * RETURNS: N/A
- *
- */
-NESTED(mips_cache_reset, 0, ra)
-       move    RA, ra
-       li      t2, CONFIG_SYS_ICACHE_SIZE
-       li      t3, CONFIG_SYS_DCACHE_SIZE
-       li      t8, CONFIG_SYS_CACHELINE_SIZE
-
-       li      v0, MIPS_MAX_CACHE_SIZE
-
-       /*
-        * Now clear that much memory starting from zero.
-        */
-       PTR_LI          a0, CKSEG1
-       PTR_ADDU        a1, a0, v0
-2:     PTR_ADDIU       a0, 64
-       f_fill64        a0, -64, zero
-       bne             a0, a1, 2b
-
-       /*
-        * The caches are probably in an indeterminate state,
-        * so we force good parity into them by doing an
-        * invalidate, load/fill, invalidate for each line.
-        */
-
-       /*
-        * Assume bottom of RAM will generate good parity for the cache.
-        */
-
-       /*
-        * Initialize the I-cache first,
-        */
-       move    a1, t2
-       move    a2, t8
-       PTR_LA  v1, mips_init_icache
-       jalr    v1
-
-       /*
-        * then initialize D-cache.
-        */
-       move    a1, t3
-       move    a2, t8
-       PTR_LA  v1, mips_init_dcache
-       jalr    v1
-
-       jr      RA
-       END(mips_cache_reset)
-
-/*
- * dcache_status - get cache status
- *
- * RETURNS: 0 - cache disabled; 1 - cache enabled
- *
- */
-LEAF(dcache_status)
-       mfc0    t0, CP0_CONFIG
-       li      t1, CONF_CM_UNCACHED
-       andi    t0, t0, CONF_CM_CMASK
-       move    v0, zero
-       beq     t0, t1, 2f
-       li      v0, 1
-2:     jr      ra
-       END(dcache_status)
-
-/*
- * dcache_disable - disable cache
- *
- * RETURNS: N/A
- *
- */
-LEAF(dcache_disable)
-       mfc0    t0, CP0_CONFIG
-       li      t1, -8
-       and     t0, t0, t1
-       ori     t0, t0, CONF_CM_UNCACHED
-       mtc0    t0, CP0_CONFIG
-       jr      ra
-       END(dcache_disable)
-
-/*
- * dcache_enable - enable cache
- *
- * RETURNS: N/A
- *
- */
-LEAF(dcache_enable)
-       mfc0    t0, CP0_CONFIG
-       ori     t0, CONF_CM_CMASK
-       xori    t0, CONF_CM_CMASK
-       ori     t0, CONF_CM_CACHABLE_NONCOHERENT
-       mtc0    t0, CP0_CONFIG
-       jr      ra
-       END(dcache_enable)
diff --git a/arch/mips/cpu/mips64/cpu.c b/arch/mips/cpu/mips64/cpu.c
deleted file mode 100644 (file)
index 9f45cfc..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * (C) Copyright 2003
- * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <command.h>
-#include <netdev.h>
-#include <asm/mipsregs.h>
-#include <asm/cacheops.h>
-#include <asm/reboot.h>
-
-#define cache_op(op, addr)                                             \
-       __asm__ __volatile__(                                           \
-       "       .set    push\n"                                         \
-       "       .set    noreorder\n"                                    \
-       "       .set    mips64\n"                                       \
-       "       cache   %0, %1\n"                                       \
-       "       .set    pop\n"                                          \
-       :                                                               \
-       : "i" (op), "R" (*(unsigned char *)(addr)))
-
-void __attribute__((weak)) _machine_restart(void)
-{
-       fprintf(stderr, "*** reset failed ***\n");
-
-       while (1)
-               /* NOP */;
-}
-
-int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       _machine_restart();
-
-       return 0;
-}
-
-void flush_cache(ulong start_addr, ulong size)
-{
-       unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
-       unsigned long addr = start_addr & ~(lsize - 1);
-       unsigned long aend = (start_addr + size - 1) & ~(lsize - 1);
-
-       /* aend will be miscalculated when size is zero, so we return here */
-       if (size == 0)
-               return;
-
-       while (1) {
-               cache_op(HIT_WRITEBACK_INV_D, addr);
-               cache_op(HIT_INVALIDATE_I, addr);
-               if (addr == aend)
-                       break;
-               addr += lsize;
-       }
-}
-
-void flush_dcache_range(ulong start_addr, ulong stop)
-{
-       unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
-       unsigned long addr = start_addr & ~(lsize - 1);
-       unsigned long aend = (stop - 1) & ~(lsize - 1);
-
-       while (1) {
-               cache_op(HIT_WRITEBACK_INV_D, addr);
-               if (addr == aend)
-                       break;
-               addr += lsize;
-       }
-}
-
-void invalidate_dcache_range(ulong start_addr, ulong stop)
-{
-       unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE;
-       unsigned long addr = start_addr & ~(lsize - 1);
-       unsigned long aend = (stop - 1) & ~(lsize - 1);
-
-       while (1) {
-               cache_op(HIT_INVALIDATE_D, addr);
-               if (addr == aend)
-                       break;
-               addr += lsize;
-       }
-}
-
-void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
-{
-       write_c0_entrylo0(low0);
-       write_c0_pagemask(pagemask);
-       write_c0_entrylo1(low1);
-       write_c0_entryhi(hi);
-       write_c0_index(index);
-       tlb_write_indexed();
-}
diff --git a/arch/mips/cpu/mips64/interrupts.c b/arch/mips/cpu/mips64/interrupts.c
deleted file mode 100644 (file)
index 275fcf5..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * (C) Copyright 2003
- * Wolfgang Denk, DENX Software Engineering, <wd@denx.de>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-
-int interrupt_init(void)
-{
-       return 0;
-}
-
-void enable_interrupts(void)
-{
-}
-
-int disable_interrupts(void)
-{
-       return 0;
-}
diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S
deleted file mode 100644 (file)
index 471bc1e..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- *  Startup Code for MIPS64 CPU-core
- *
- *  Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <asm-offsets.h>
-#include <config.h>
-#include <asm/regdef.h>
-#include <asm/mipsregs.h>
-
-#ifndef CONFIG_SYS_MIPS_CACHE_MODE
-#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
-#endif
-
-#ifndef CONFIG_SYS_INIT_SP_ADDR
-#define CONFIG_SYS_INIT_SP_ADDR        (CONFIG_SYS_SDRAM_BASE + \
-                               CONFIG_SYS_INIT_SP_OFFSET)
-#endif
-
-#ifdef CONFIG_SYS_LITTLE_ENDIAN
-#define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
-       (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym))
-#else
-#define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
-       ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24)
-#endif
-
-       /*
-        * For the moment disable interrupts, mark the kernel mode and
-        * set ST0_KX so that the CPU does not spit fire when using
-        * 64-bit addresses.
-        */
-       .macro  setup_c0_status set clr
-       .set    push
-       mfc0    t0, CP0_STATUS
-       or      t0, ST0_CU0 | \set | 0x1f | \clr
-       xor     t0, 0x1f | \clr
-       mtc0    t0, CP0_STATUS
-       .set    noreorder
-       sll     zero, 3                         # ehb
-       .set    pop
-       .endm
-
-       .set noreorder
-
-       .globl _start
-       .text
-_start:
-       /* U-boot entry point */
-       b       reset
-        nop
-
-       .org 0x200
-       /* TLB refill, 32 bit task */
-1:     b       1b
-        nop
-
-       .org 0x280
-       /* XTLB refill, 64 bit task */
-1:     b       1b
-        nop
-
-       .org 0x300
-       /* Cache error exception */
-1:     b       1b
-        nop
-
-       .org 0x380
-       /* General exception */
-1:     b       1b
-        nop
-
-       .org 0x400
-       /* Catch interrupt exceptions */
-1:     b       1b
-        nop
-
-       .org 0x480
-       /* EJTAG debug exception */
-1:     b       1b
-        nop
-
-       .align 4
-reset:
-
-       /* Clear watch registers */
-       dmtc0   zero, CP0_WATCHLO
-       dmtc0   zero, CP0_WATCHHI
-
-       /* WP(Watch Pending), SW0/1 should be cleared */
-       mtc0    zero, CP0_CAUSE
-
-       setup_c0_status ST0_KX 0
-
-       /* Init Timer */
-       mtc0    zero, CP0_COUNT
-       mtc0    zero, CP0_COMPARE
-
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
-       /* CONFIG0 register */
-       dli     t0, CONF_CM_UNCACHED
-       mtc0    t0, CP0_CONFIG
-#endif
-
-       /*
-        * Initialize $gp, force 8 byte alignment of bal instruction to forbid
-        * the compiler to put nop's between bal and _gp. This is required to
-        * keep _gp and ra aligned to 8 byte.
-        */
-       .align  3
-       bal     1f
-        nop
-       .dword  _gp
-1:
-       ld      gp, 0(ra)
-
-#ifndef CONFIG_SKIP_LOWLEVEL_INIT
-       /* Initialize any external memory */
-       dla     t9, lowlevel_init
-       jalr    t9
-        nop
-
-       /* Initialize caches... */
-       dla     t9, mips_cache_reset
-       jalr    t9
-        nop
-
-       /* ... and enable them */
-       dli     t0, CONFIG_SYS_MIPS_CACHE_MODE
-       mtc0    t0, CP0_CONFIG
-#endif
-
-       /* Set up temporary stack */
-       dli     t0, -16
-       dli     t1, CONFIG_SYS_INIT_SP_ADDR
-       and     sp, t1, t0              # force 16 byte alignment
-       dsub    sp, sp, GD_SIZE         # reserve space for gd
-       and     sp, sp, t0              # force 16 byte alignment
-       move    k0, sp                  # save gd pointer
-#ifdef CONFIG_SYS_MALLOC_F_LEN
-       dli     t2, CONFIG_SYS_MALLOC_F_LEN
-       dsub    sp, sp, t2              # reserve space for early malloc
-       and     sp, sp, t0              # force 16 byte alignment
-#endif
-       move    fp, sp
-
-       /* Clear gd */
-       move    t0, k0
-1:
-       sw      zero, 0(t0)
-       blt     t0, t1, 1b
-        daddi  t0, 4
-
-#ifdef CONFIG_SYS_MALLOC_F_LEN
-       daddu   t0, k0, GD_MALLOC_BASE  # gd->malloc_base offset
-       sw      sp, 0(t0)
-#endif
-
-       dla     t9, board_init_f
-       jr      t9
-        move   ra, zero
-
-/*
- * void relocate_code (addr_sp, gd, addr_moni)
- *
- * This "function" does not return, instead it continues in RAM
- * after relocating the monitor code.
- *
- * a0 = addr_sp
- * a1 = gd
- * a2 = destination address
- */
-       .globl  relocate_code
-       .ent    relocate_code
-relocate_code:
-       move    sp, a0                  # set new stack pointer
-       move    fp, sp
-
-       move    s0, a1                  # save gd in s0
-       move    s2, a2                  # save destination address in s2
-
-       dli     t0, CONFIG_SYS_MONITOR_BASE
-       dsub    s1, s2, t0              # s1 <-- relocation offset
-
-       dla     t3, in_ram
-       ld      t2, -24(t3)             # t2 <-- __image_copy_end
-       move    t1, a2
-
-       dadd    gp, s1                  # adjust gp
-
-       /*
-        * t0 = source address
-        * t1 = target address
-        * t2 = source end address
-        */
-1:
-       lw      t3, 0(t0)
-       sw      t3, 0(t1)
-       daddu   t0, 4
-       blt     t0, t2, 1b
-        daddu  t1, 4
-
-       /* If caches were enabled, we would have to flush them here. */
-       dsub    a1, t1, s2              # a1 <-- size
-       dla     t9, flush_cache
-       jalr    t9
-        move   a0, s2                  # a0 <-- destination address
-
-       /* Jump to where we've relocated ourselves */
-       daddi   t0, s2, in_ram - _start
-       jr      t0
-        nop
-
-       .dword  __rel_dyn_end
-       .dword  __rel_dyn_start
-       .dword  __image_copy_end
-       .dword  _GLOBAL_OFFSET_TABLE_
-       .dword  num_got_entries
-
-in_ram:
-       /*
-        * Now we want to update GOT.
-        *
-        * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
-        * generated by GNU ld. Skip these reserved entries from relocation.
-        */
-       ld      t3, -8(t0)              # t3 <-- num_got_entries
-       ld      t8, -16(t0)             # t8 <-- _GLOBAL_OFFSET_TABLE_
-       dadd    t8, s1                  # t8 now holds relocated _G_O_T_
-       daddi   t8, t8, 16              # skipping first two entries
-       dli     t2, 2
-1:
-       ld      t1, 0(t8)
-       beqz    t1, 2f
-        dadd   t1, s1
-       sd      t1, 0(t8)
-2:
-       daddi   t2, 1
-       blt     t2, t3, 1b
-        daddi  t8, 8
-
-       /* Update dynamic relocations */
-       ld      t1, -32(t0)             # t1 <-- __rel_dyn_start
-       ld      t2, -40(t0)             # t2 <-- __rel_dyn_end
-
-       b       2f                      # skip first reserved entry
-        daddi  t1, 16
-
-1:
-       lw      t8, -4(t1)              # t8 <-- relocation info
-
-       dli     t3, MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03)
-       bne     t8, t3, 2f              # skip non R_MIPS_REL32 entries
-        nop
-
-       ld      t3, -16(t1)             # t3 <-- location to fix up in FLASH
-
-       ld      t8, 0(t3)               # t8 <-- original pointer
-       dadd    t8, s1                  # t8 <-- adjusted pointer
-
-       dadd    t3, s1                  # t3 <-- location to fix up in RAM
-       sd      t8, 0(t3)
-
-2:
-       blt     t1, t2, 1b
-        daddi  t1, 16                  # each rel.dyn entry is 16 bytes
-
-       /*
-        * Clear BSS
-        *
-        * GOT is now relocated. Thus __bss_start and __bss_end can be
-        * accessed directly via $gp.
-        */
-       dla     t1, __bss_start         # t1 <-- __bss_start
-       dla     t2, __bss_end           # t2 <-- __bss_end
-
-1:
-       sd      zero, 0(t1)
-       blt     t1, t2, 1b
-        daddi  t1, 8
-
-       move    a0, s0                  # a0 <-- gd
-       move    a1, s2
-       dla     t9, board_init_r
-       jr      t9
-        move   ra, zero
-
-       .end    relocate_code
diff --git a/arch/mips/cpu/mips64/time.c b/arch/mips/cpu/mips64/time.c
deleted file mode 100644 (file)
index 553da5f..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * (C) Copyright 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * SPDX-License-Identifier:    GPL-2.0+
- */
-
-#include <common.h>
-#include <asm/mipsregs.h>
-
-unsigned long notrace timer_read_counter(void)
-{
-       return read_c0_count();
-}
-
-ulong notrace get_tbclk(void)
-{
-       return CONFIG_SYS_MIPS_TIMER_FREQ;
-}
similarity index 61%
rename from arch/mips/cpu/mips32/start.S
rename to arch/mips/cpu/start.S
index 36b92cc6874d873070784640bacae0aaa16442dd..3b5b622abedf06ffba3534692d7fba027569ed52 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <asm-offsets.h>
 #include <config.h>
+#include <asm/asm.h>
 #include <asm/regdef.h>
 #include <asm/mipsregs.h>
 
                                CONFIG_SYS_INIT_SP_OFFSET)
 #endif
 
+#ifdef CONFIG_32BIT
+# define MIPS_RELOC    3
+# define STATUS_SET    0
+#endif
+
+#ifdef CONFIG_64BIT
+# ifdef CONFIG_SYS_LITTLE_ENDIAN
+#  define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
+       (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym))
+# else
+#  define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
+       ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24)
+# endif
+# define MIPS_RELOC    MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03)
+# define STATUS_SET    ST0_KX
+#endif
+
        /*
         * For the moment disable interrupts, mark the kernel mode and
         * set ST0_KX so that the CPU does not spit fire when using
@@ -98,13 +116,13 @@ _start:
 reset:
 
        /* Clear watch registers */
-       mtc0    zero, CP0_WATCHLO
-       mtc0    zero, CP0_WATCHHI
+       MTC0    zero, CP0_WATCHLO
+       MTC0    zero, CP0_WATCHHI
 
        /* WP(Watch Pending), SW0/1 should be cleared */
        mtc0    zero, CP0_CAUSE
 
-       setup_c0_status 0 0
+       setup_c0_status STATUS_SET 0
 
        /* Init Timer */
        mtc0    zero, CP0_COUNT
@@ -116,21 +134,26 @@ reset:
        mtc0    t0, CP0_CONFIG
 #endif
 
-       /* Initialize $gp */
+       /*
+        * Initialize $gp, force pointer sized alignment of bal instruction to
+        * forbid the compiler to put nop's between bal and _gp. This is
+        * required to keep _gp and ra aligned to 8 byte.
+        */
+       .align  PTRLOG
        bal     1f
         nop
-       .word   _gp
+       PTR     _gp
 1:
-       lw      gp, 0(ra)
+       PTR_L   gp, 0(ra)
 
 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
        /* Initialize any external memory */
-       la      t9, lowlevel_init
+       PTR_LA  t9, lowlevel_init
        jalr    t9
         nop
 
        /* Initialize caches... */
-       la      t9, mips_cache_reset
+       PTR_LA  t9, mips_cache_reset
        jalr    t9
         nop
 
@@ -140,15 +163,15 @@ reset:
 #endif
 
        /* Set up temporary stack */
-       li      t0, -16
-       li      t1, CONFIG_SYS_INIT_SP_ADDR
+       PTR_LI  t0, -16
+       PTR_LI  t1, CONFIG_SYS_INIT_SP_ADDR
        and     sp, t1, t0              # force 16 byte alignment
-       sub     sp, sp, GD_SIZE         # reserve space for gd
+       PTR_SUB sp, sp, GD_SIZE         # reserve space for gd
        and     sp, sp, t0              # force 16 byte alignment
        move    k0, sp                  # save gd pointer
 #ifdef CONFIG_SYS_MALLOC_F_LEN
-       li      t2, CONFIG_SYS_MALLOC_F_LEN
-       sub     sp, sp, t2              # reserve space for early malloc
+       PTR_LI  t2, CONFIG_SYS_MALLOC_F_LEN
+       PTR_SUB sp, sp, t2              # reserve space for early malloc
        and     sp, sp, t0              # force 16 byte alignment
 #endif
        move    fp, sp
@@ -158,14 +181,14 @@ reset:
 1:
        sw      zero, 0(t0)
        blt     t0, t1, 1b
-        addi   t0, 4
+        PTR_ADDI t0, 4
 
 #ifdef CONFIG_SYS_MALLOC_F_LEN
-       addu    t0, k0, GD_MALLOC_BASE  # gd->malloc_base offset
+       PTR_ADDU t0, k0, GD_MALLOC_BASE # gd->malloc_base offset
        sw      sp, 0(t0)
 #endif
 
-       la      t9, board_init_f
+       PTR_LA  t9, board_init_f
        jr      t9
         move   ra, zero
 
@@ -188,14 +211,14 @@ relocate_code:
        move    s0, a1                  # save gd in s0
        move    s2, a2                  # save destination address in s2
 
-       li      t0, CONFIG_SYS_MONITOR_BASE
-       sub     s1, s2, t0              # s1 <-- relocation offset
+       PTR_LI  t0, CONFIG_SYS_MONITOR_BASE
+       PTR_SUB s1, s2, t0              # s1 <-- relocation offset
 
-       la      t3, in_ram
-       lw      t2, -12(t3)             # t2 <-- __image_copy_end
+       PTR_LA  t3, in_ram
+       PTR_L   t2, -(3 * PTRSIZE)(t3)  # t2 <-- __image_copy_end
        move    t1, a2
 
-       add     gp, s1                  # adjust gp
+       PTR_ADD gp, s1                  # adjust gp
 
        /*
         * t0 = source address
@@ -205,26 +228,26 @@ relocate_code:
 1:
        lw      t3, 0(t0)
        sw      t3, 0(t1)
-       addu    t0, 4
+       PTR_ADDU t0, 4
        blt     t0, t2, 1b
-        addu   t1, 4
+        PTR_ADDU t1, 4
 
        /* If caches were enabled, we would have to flush them here. */
-       sub     a1, t1, s2              # a1 <-- size
-       la      t9, flush_cache
+       PTR_SUB a1, t1, s2              # a1 <-- size
+       PTR_LA  t9, flush_cache
        jalr    t9
         move   a0, s2                  # a0 <-- destination address
 
        /* Jump to where we've relocated ourselves */
-       addi    t0, s2, in_ram - _start
+       PTR_ADDI t0, s2, in_ram - _start
        jr      t0
         nop
 
-       .word   __rel_dyn_end
-       .word   __rel_dyn_start
-       .word   __image_copy_end
-       .word   _GLOBAL_OFFSET_TABLE_
-       .word   num_got_entries
+       PTR     __rel_dyn_end
+       PTR     __rel_dyn_start
+       PTR     __image_copy_end
+       PTR     _GLOBAL_OFFSET_TABLE_
+       PTR     num_got_entries
 
 in_ram:
        /*
@@ -233,46 +256,46 @@ in_ram:
         * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
         * generated by GNU ld. Skip these reserved entries from relocation.
         */
-       lw      t3, -4(t0)              # t3 <-- num_got_entries
-       lw      t8, -8(t0)              # t8 <-- _GLOBAL_OFFSET_TABLE_
-       add     t8, s1                  # t8 now holds relocated _G_O_T_
-       addi    t8, t8, 8               # skipping first two entries
-       li      t2, 2
+       PTR_L   t3, -(1 * PTRSIZE)(t0)  # t3 <-- num_got_entries
+       PTR_L   t8, -(2 * PTRSIZE)(t0)  # t8 <-- _GLOBAL_OFFSET_TABLE_
+       PTR_ADD t8, s1                  # t8 now holds relocated _G_O_T_
+       PTR_ADDI t8, t8, 2 * PTRSIZE    # skipping first two entries
+       PTR_LI  t2, 2
 1:
-       lw      t1, 0(t8)
+       PTR_L   t1, 0(t8)
        beqz    t1, 2f
-        add    t1, s1
-       sw      t1, 0(t8)
+        PTR_ADD t1, s1
+       PTR_S   t1, 0(t8)
 2:
-       addi    t2, 1
+       PTR_ADDI t2, 1
        blt     t2, t3, 1b
-        addi   t8, 4
+        PTR_ADDI t8, PTRSIZE
 
        /* Update dynamic relocations */
-       lw      t1, -16(t0)             # t1 <-- __rel_dyn_start
-       lw      t2, -20(t0)             # t2 <-- __rel_dyn_end
+       PTR_L   t1, -(4 * PTRSIZE)(t0)  # t1 <-- __rel_dyn_start
+       PTR_L   t2, -(5 * PTRSIZE)(t0)  # t2 <-- __rel_dyn_end
 
        b       2f                      # skip first reserved entry
-        addi   t1, 8
+        PTR_ADDI t1, 2 * PTRSIZE
 
 1:
        lw      t8, -4(t1)              # t8 <-- relocation info
 
-       li      t3, 3
-       bne     t8, t3, 2f              # skip non R_MIPS_REL32 entries
+       PTR_LI  t3, MIPS_RELOC
+       bne     t8, t3, 2f              # skip non-MIPS_RELOC entries
         nop
 
-       lw      t3, -8(t1)              # t3 <-- location to fix up in FLASH
+       PTR_L   t3, -(2 * PTRSIZE)(t1)  # t3 <-- location to fix up in FLASH
 
-       lw      t8, 0(t3)               # t8 <-- original pointer
-       add     t8, s1                  # t8 <-- adjusted pointer
+       PTR_L   t8, 0(t3)               # t8 <-- original pointer
+       PTR_ADD t8, s1                  # t8 <-- adjusted pointer
 
-       add     t3, s1                  # t3 <-- location to fix up in RAM
-       sw      t8, 0(t3)
+       PTR_ADD t3, s1                  # t3 <-- location to fix up in RAM
+       PTR_S   t8, 0(t3)
 
 2:
        blt     t1, t2, 1b
-        addi   t1, 8                   # each rel.dyn entry is 8 bytes
+        PTR_ADDI t1, 2 * PTRSIZE       # each rel.dyn entry is 2*PTRSIZE bytes
 
        /*
         * Clear BSS
@@ -280,17 +303,17 @@ in_ram:
         * GOT is now relocated. Thus __bss_start and __bss_end can be
         * accessed directly via $gp.
         */
-       la      t1, __bss_start         # t1 <-- __bss_start
-       la      t2, __bss_end           # t2 <-- __bss_end
+       PTR_LA  t1, __bss_start         # t1 <-- __bss_start
+       PTR_LA  t2, __bss_end           # t2 <-- __bss_end
 
 1:
-       sw      zero, 0(t1)
+       PTR_S   zero, 0(t1)
        blt     t1, t2, 1b
-        addi   t1, 4
+        PTR_ADDI t1, PTRSIZE
 
        move    a0, s0                  # a0 <-- gd
        move    a1, s2
-       la      t9, board_init_r
+       PTR_LA  t9, board_init_r
        jr      t9
         move   ra, zero
 
index 6464250d8486ec6261c1c6066dd7bb104dd61ee9..75ec380980f7653b1505d1316eae20329704cbb3 100644 (file)
 #ifndef        __ASM_CACHEOPS_H
 #define        __ASM_CACHEOPS_H
 
+#ifndef __ASSEMBLY__
+
+static inline void mips_cache(int op, const volatile void *addr)
+{
+#ifdef __GCC_HAVE_BUILTIN_MIPS_CACHE
+       __builtin_mips_cache(op, addr);
+#else
+       __asm__ __volatile__("cache %0, %1" : : "i"(op), "R"(addr))
+#endif
+}
+
+#endif /* !__ASSEMBLY__ */
+
 /*
  * Cache Operations available on all MIPS processors with R4000-style caches
  */
index 9e7c045aacf79f121847191f0748fb95998590bf..d9ffc1558dbfa392db6b3c0eef40fd4bebb4aa59 100644 (file)
@@ -64,4 +64,9 @@
 
 #define PCI_CFG_PIIX4_GENCFG_SERIRQ    (1 << 16)
 
+#define PCI_CFG_PIIX4_IDETIM_PRI       0x40
+#define PCI_CFG_PIIX4_IDETIM_SEC       0x42
+
+#define PCI_CFG_PIIX4_IDETIM_IDE       (1 << 15)
+
 #endif /* _MIPS_ASM_MALTA_H */
index 7f9b6536afa84ab8e7ff2947bec24518caae95b5..ac536da674d3958063f35f8e4bc76ae4c777f3d5 100644 (file)
@@ -5,6 +5,8 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
+obj-y  += cache.o
+obj-y  += cache_init.o
 obj-y  += io.o
 
 obj-$(CONFIG_CMD_BOOTM) += bootm.o
similarity index 55%
rename from arch/mips/cpu/mips32/cpu.c
rename to arch/mips/lib/cache.c
index 278865b6fff54849c98b0e1bd69a7cc7b2e5ba6f..e245614d1688e22cf325e2f8eaa4c79ca39a0fa3 100644 (file)
@@ -6,33 +6,8 @@
  */
 
 #include <common.h>
-#include <command.h>
-#include <netdev.h>
-#include <asm/mipsregs.h>
 #include <asm/cacheops.h>
-#include <asm/reboot.h>
-
-#define cache_op(op,addr)                                              \
-       __asm__ __volatile__(                                           \
-       "       .set    push                                    \n"     \
-       "       .set    noreorder                               \n"     \
-       "       .set    mips3\n\t                               \n"     \
-       "       cache   %0, %1                                  \n"     \
-       "       .set    pop                                     \n"     \
-       :                                                               \
-       : "i" (op), "R" (*(unsigned char *)(addr)))
-
-void __attribute__((weak)) _machine_restart(void)
-{
-}
-
-int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       _machine_restart();
-
-       fprintf(stderr, "*** reset failed ***\n");
-       return 0;
-}
+#include <asm/mipsregs.h>
 
 #ifdef CONFIG_SYS_CACHELINE_SIZE
 
@@ -74,20 +49,20 @@ void flush_cache(ulong start_addr, ulong size)
 {
        unsigned long ilsize = icache_line_size();
        unsigned long dlsize = dcache_line_size();
-       unsigned long addr, aend;
+       const void *addr, *aend;
 
        /* aend will be miscalculated when size is zero, so we return here */
        if (size == 0)
                return;
 
-       addr = start_addr & ~(dlsize - 1);
-       aend = (start_addr + size - 1) & ~(dlsize - 1);
+       addr = (const void *)(start_addr & ~(dlsize - 1));
+       aend = (const void *)((start_addr + size - 1) & ~(dlsize - 1));
 
        if (ilsize == dlsize) {
                /* flush I-cache & D-cache simultaneously */
                while (1) {
-                       cache_op(HIT_WRITEBACK_INV_D, addr);
-                       cache_op(HIT_INVALIDATE_I, addr);
+                       mips_cache(HIT_WRITEBACK_INV_D, addr);
+                       mips_cache(HIT_INVALIDATE_I, addr);
                        if (addr == aend)
                                break;
                        addr += dlsize;
@@ -97,17 +72,17 @@ void flush_cache(ulong start_addr, ulong size)
 
        /* flush D-cache */
        while (1) {
-               cache_op(HIT_WRITEBACK_INV_D, addr);
+               mips_cache(HIT_WRITEBACK_INV_D, addr);
                if (addr == aend)
                        break;
                addr += dlsize;
        }
 
        /* flush I-cache */
-       addr = start_addr & ~(ilsize - 1);
-       aend = (start_addr + size - 1) & ~(ilsize - 1);
+       addr = (const void *)(start_addr & ~(ilsize - 1));
+       aend = (const void *)((start_addr + size - 1) & ~(ilsize - 1));
        while (1) {
-               cache_op(HIT_INVALIDATE_I, addr);
+               mips_cache(HIT_INVALIDATE_I, addr);
                if (addr == aend)
                        break;
                addr += ilsize;
@@ -117,11 +92,11 @@ void flush_cache(ulong start_addr, ulong size)
 void flush_dcache_range(ulong start_addr, ulong stop)
 {
        unsigned long lsize = dcache_line_size();
-       unsigned long addr = start_addr & ~(lsize - 1);
-       unsigned long aend = (stop - 1) & ~(lsize - 1);
+       const void *addr = (const void *)(start_addr & ~(lsize - 1));
+       const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
 
        while (1) {
-               cache_op(HIT_WRITEBACK_INV_D, addr);
+               mips_cache(HIT_WRITEBACK_INV_D, addr);
                if (addr == aend)
                        break;
                addr += lsize;
@@ -131,31 +106,13 @@ void flush_dcache_range(ulong start_addr, ulong stop)
 void invalidate_dcache_range(ulong start_addr, ulong stop)
 {
        unsigned long lsize = dcache_line_size();
-       unsigned long addr = start_addr & ~(lsize - 1);
-       unsigned long aend = (stop - 1) & ~(lsize - 1);
+       const void *addr = (const void *)(start_addr & ~(lsize - 1));
+       const void *aend = (const void *)((stop - 1) & ~(lsize - 1));
 
        while (1) {
-               cache_op(HIT_INVALIDATE_D, addr);
+               mips_cache(HIT_INVALIDATE_D, addr);
                if (addr == aend)
                        break;
                addr += lsize;
        }
 }
-
-void write_one_tlb(int index, u32 pagemask, u32 hi, u32 low0, u32 low1)
-{
-       write_c0_entrylo0(low0);
-       write_c0_pagemask(pagemask);
-       write_c0_entrylo1(low1);
-       write_c0_entryhi(hi);
-       write_c0_index(index);
-       tlb_write_indexed();
-}
-
-int cpu_eth_init(bd_t *bis)
-{
-#ifdef CONFIG_SOC_AU1X00
-       au1x00_enet_initialize(bis);
-#endif
-       return 0;
-}
similarity index 59%
rename from arch/mips/cpu/mips32/cache.S
rename to arch/mips/lib/cache_init.S
index 22bd844eae750610e2b1367e6bb581db9e17902a..137d7283ffefb1f81a60b81fbfb5c559f798787e 100644 (file)
 #define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
 #endif
 
-#define RA             t9
-
 #define INDEX_BASE     CKSEG0
 
-       .macro  cache_op op addr
-       .set    push
-       .set    noreorder
-       .set    mips3
-       cache   \op, 0(\addr)
-       .set    pop
-       .endm
-
        .macro  f_fill64 dst, offset, val
        LONG_S  \val, (\offset +  0 * LONGSIZE)(\dst)
        LONG_S  \val, (\offset +  1 * LONGSIZE)(\dst)
 #endif
        .endm
 
-/*
- * mips_init_icache(uint PRId, ulong icache_size, unchar icache_linesz)
- */
-LEAF(mips_init_icache)
-       blez            a1, 9f
-       mtc0            zero, CP0_TAGLO
-       /* clear tag to invalidate */
-       PTR_LI          t0, INDEX_BASE
-       PTR_ADDU        t1, t0, a1
-1:     cache_op        INDEX_STORE_TAG_I t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 1b
-       /* fill once, so data field parity is correct */
-       PTR_LI          t0, INDEX_BASE
-2:     cache_op        FILL t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 2b
-       /* invalidate again - prudent but not strictly neccessary */
-       PTR_LI          t0, INDEX_BASE
-1:     cache_op        INDEX_STORE_TAG_I t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 1b
-9:     jr              ra
-       END(mips_init_icache)
-
-/*
- * mips_init_dcache(uint PRId, ulong dcache_size, unchar dcache_linesz)
- */
-LEAF(mips_init_dcache)
-       blez            a1, 9f
-       mtc0            zero, CP0_TAGLO
-       /* clear all tags */
-       PTR_LI          t0, INDEX_BASE
-       PTR_ADDU        t1, t0, a1
-1:     cache_op        INDEX_STORE_TAG_D t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 1b
-       /* load from each line (in cached space) */
-       PTR_LI          t0, INDEX_BASE
-2:     LONG_L          zero, 0(t0)
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 2b
-       /* clear all tags */
-       PTR_LI          t0, INDEX_BASE
-1:     cache_op        INDEX_STORE_TAG_D t0
-       PTR_ADDU        t0, a2
-       bne             t0, t1, 1b
-9:     jr              ra
-       END(mips_init_dcache)
+       .macro cache_loop       curr, end, line_sz, op
+10:    cache           \op, 0(\curr)
+       PTR_ADDU        \curr, \curr, \line_sz
+       bne             \curr, \end, 10b
+       .endm
 
+       .macro  l1_info         sz, line_sz, off
+       .set    push
+       .set    noat
+
+       mfc0    $1, CP0_CONFIG, 1
+
+       /* detect line size */
+       srl     \line_sz, $1, \off + MIPS_CONF1_DL_SHIFT - MIPS_CONF1_DA_SHIFT
+       andi    \line_sz, \line_sz, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHIFT)
+       move    \sz, zero
+       beqz    \line_sz, 10f
+       li      \sz, 2
+       sllv    \line_sz, \sz, \line_sz
+
+       /* detect associativity */
+       srl     \sz, $1, \off + MIPS_CONF1_DA_SHIFT - MIPS_CONF1_DA_SHIFT
+       andi    \sz, \sz, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHIFT)
+       addi    \sz, \sz, 1
+
+       /* sz *= line_sz */
+       mul     \sz, \sz, \line_sz
+
+       /* detect log32(sets) */
+       srl     $1, $1, \off + MIPS_CONF1_DS_SHIFT - MIPS_CONF1_DA_SHIFT
+       andi    $1, $1, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHIFT)
+       addiu   $1, $1, 1
+       andi    $1, $1, 0x7
+
+       /* sz <<= log32(sets) */
+       sllv    \sz, \sz, $1
+
+       /* sz *= 32 */
+       li      $1, 32
+       mul     \sz, \sz, $1
+10:
+       .set    pop
+       .endm
 /*
  * mips_cache_reset - low level initialisation of the primary caches
  *
@@ -115,75 +98,23 @@ LEAF(mips_init_dcache)
  * RETURNS: N/A
  *
  */
-NESTED(mips_cache_reset, 0, ra)
-       move    RA, ra
-
-#if !defined(CONFIG_SYS_ICACHE_SIZE) || !defined(CONFIG_SYS_DCACHE_SIZE) || \
-    !defined(CONFIG_SYS_CACHELINE_SIZE)
-       /* read Config1 for use below */
-       mfc0    t5, CP0_CONFIG, 1
-#endif
-
-#ifdef CONFIG_SYS_CACHELINE_SIZE
-       li      t7, CONFIG_SYS_CACHELINE_SIZE
-       li      t8, CONFIG_SYS_CACHELINE_SIZE
-#else
-       /* Detect I-cache line size. */
-       srl     t8, t5, MIPS_CONF1_IL_SHIFT
-       andi    t8, t8, (MIPS_CONF1_IL >> MIPS_CONF1_IL_SHIFT)
-       beqz    t8, 1f
-       li      t6, 2
-       sllv    t8, t6, t8
-
-1:     /* Detect D-cache line size. */
-       srl     t7, t5, MIPS_CONF1_DL_SHIFT
-       andi    t7, t7, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHIFT)
-       beqz    t7, 1f
-       li      t6, 2
-       sllv    t7, t6, t7
-1:
-#endif
-
+LEAF(mips_cache_reset)
 #ifdef CONFIG_SYS_ICACHE_SIZE
        li      t2, CONFIG_SYS_ICACHE_SIZE
+       li      t8, CONFIG_SYS_CACHELINE_SIZE
 #else
-       /* Detect I-cache size. */
-       srl     t6, t5, MIPS_CONF1_IS_SHIFT
-       andi    t6, t6, (MIPS_CONF1_IS >> MIPS_CONF1_IS_SHIFT)
-       li      t4, 32
-       xori    t2, t6, 0x7
-       beqz    t2, 1f
-       addi    t6, t6, 1
-       sllv    t4, t4, t6
-1:     /* At this point t4 == I-cache sets. */
-       mul     t2, t4, t8
-       srl     t6, t5, MIPS_CONF1_IA_SHIFT
-       andi    t6, t6, (MIPS_CONF1_IA >> MIPS_CONF1_IA_SHIFT)
-       addi    t6, t6, 1
-       /* At this point t6 == I-cache ways. */
-       mul     t2, t2, t6
+       l1_info t2, t8, MIPS_CONF1_IA_SHIFT
 #endif
 
 #ifdef CONFIG_SYS_DCACHE_SIZE
        li      t3, CONFIG_SYS_DCACHE_SIZE
+       li      t9, CONFIG_SYS_CACHELINE_SIZE
 #else
-       /* Detect D-cache size. */
-       srl     t6, t5, MIPS_CONF1_DS_SHIFT
-       andi    t6, t6, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHIFT)
-       li      t4, 32
-       xori    t3, t6, 0x7
-       beqz    t3, 1f
-       addi    t6, t6, 1
-       sllv    t4, t4, t6
-1:     /* At this point t4 == I-cache sets. */
-       mul     t3, t4, t7
-       srl     t6, t5, MIPS_CONF1_DA_SHIFT
-       andi    t6, t6, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHIFT)
-       addi    t6, t6, 1
-       /* At this point t6 == I-cache ways. */
-       mul     t3, t3, t6
+       l1_info t3, t9, MIPS_CONF1_DA_SHIFT
 #endif
 
+#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
+
        /* Determine the largest L1 cache size */
 #if defined(CONFIG_SYS_ICACHE_SIZE) && defined(CONFIG_SYS_DCACHE_SIZE)
 #if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE
@@ -205,33 +136,62 @@ NESTED(mips_cache_reset, 0, ra)
        f_fill64        a0, -64, zero
        bne             a0, a1, 2b
 
+#endif /* CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD */
+
        /*
-        * The caches are probably in an indeterminate state,
-        * so we force good parity into them by doing an
-        * invalidate, load/fill, invalidate for each line.
+        * The TagLo registers used depend upon the CPU implementation, but the
+        * architecture requires that it is safe for software to write to both
+        * TagLo selects 0 & 2 covering supported cases.
         */
+       mtc0            zero, CP0_TAGLO
+       mtc0            zero, CP0_TAGLO, 2
 
        /*
-        * Assume bottom of RAM will generate good parity for the cache.
+        * The caches are probably in an indeterminate state, so we force good
+        * parity into them by doing an invalidate for each line. If
+        * CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD is set then we'll proceed to
+        * perform a load/fill & a further invalidate for each line, assuming
+        * that the bottom of RAM (having just been cleared) will generate good
+        * parity for the cache.
         */
 
        /*
         * Initialize the I-cache first,
         */
-       move    a1, t2
-       move    a2, t8
-       PTR_LA  v1, mips_init_icache
-       jalr    v1
+       blez            t2, 1f
+       PTR_LI          t0, INDEX_BASE
+       PTR_ADDU        t1, t0, t2
+       /* clear tag to invalidate */
+       cache_loop      t0, t1, t8, INDEX_STORE_TAG_I
+#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
+       /* fill once, so data field parity is correct */
+       PTR_LI          t0, INDEX_BASE
+       cache_loop      t0, t1, t8, FILL
+       /* invalidate again - prudent but not strictly neccessary */
+       PTR_LI          t0, INDEX_BASE
+       cache_loop      t0, t1, t8, INDEX_STORE_TAG_I
+#endif
 
        /*
         * then initialize D-cache.
         */
-       move    a1, t3
-       move    a2, t7
-       PTR_LA  v1, mips_init_dcache
-       jalr    v1
+1:     blez            t3, 3f
+       PTR_LI          t0, INDEX_BASE
+       PTR_ADDU        t1, t0, t3
+       /* clear all tags */
+       cache_loop      t0, t1, t9, INDEX_STORE_TAG_D
+#ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
+       /* load from each line (in cached space) */
+       PTR_LI          t0, INDEX_BASE
+2:     LONG_L          zero, 0(t0)
+       PTR_ADDU        t0, t9
+       bne             t0, t1, 2b
+       /* clear all tags */
+       PTR_LI          t0, INDEX_BASE
+       cache_loop      t0, t1, t9, INDEX_STORE_TAG_D
+#endif
 
-       jr      RA
+3:     jr      ra
        END(mips_cache_reset)
 
 /*
similarity index 98%
rename from arch/mips/cpu/mips32/au1x00/au1x00_eth.c
rename to arch/mips/mach-au1x00/au1x00_eth.c
index 4770f563aa92e8954a3953a76372249694ea2ca6..39c5b6bc4a8fcb896b3efc7e780379ddb1d6f87d 100644 (file)
@@ -294,3 +294,9 @@ int au1x00_enet_initialize(bd_t *bis){
 
        return 1;
 }
+
+int cpu_eth_init(bd_t *bis)
+{
+       au1x00_enet_initialize(bis);
+       return 0;
+}
index 42353d80a847bc51eade86f414e72238a8a4916f..097f29a2901b7348171359c596ba53036a738d0f 100644 (file)
@@ -6,6 +6,7 @@
 #include <common.h>
 #include <os.h>
 #include <cli.h>
+#include <malloc.h>
 #include <asm/getopt.h>
 #include <asm/io.h>
 #include <asm/sections.h>
@@ -102,6 +103,25 @@ static int sandbox_cmdline_cb_fdt(struct sandbox_state *state, const char *arg)
 }
 SANDBOX_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT");
 
+static int sandbox_cmdline_cb_default_fdt(struct sandbox_state *state,
+                                         const char *arg)
+{
+       const char *fmt = "%s.dtb";
+       char *fname;
+       int len;
+
+       len = strlen(state->argv[0]) + strlen(fmt) + 1;
+       fname = os_malloc(len);
+       if (!fname)
+               return -ENOMEM;
+       snprintf(fname, len, fmt, state->argv[0]);
+       state->fdt_fname = fname;
+
+       return 0;
+}
+SANDBOX_CMDLINE_OPT_SHORT(default_fdt, 'D', 0,
+               "Use the default u-boot.dtb control FDT in U-Boot directory");
+
 static int sandbox_cmdline_cb_interactive(struct sandbox_state *state,
                                          const char *arg)
 {
index 11748aec7990e1ff40f9d625842a154d8d278cc1..9ce31bf075832af6d62248a9bc05184969231093 100644 (file)
@@ -19,6 +19,7 @@
                colour = "cyan";
                sides = <3>;
                character = <83>;
+               light-gpios = <&gpio_a 2>, <&gpio_b 6 0>;
        };
        square {
                compatible = "demo-shape";
 
        cros-ec-keyb {
                compatible = "google,cros-ec-keyb";
-               google,key-rows = <8>;
-               google,key-columns = <13>;
-               google,repeat-delay-ms = <240>;
-               google,repeat-rate-ms = <30>;
+               keypad,num-rows = <8>;
+               keypad,num-columns = <13>;
                google,ghost-filter;
                /*
                 * Keymap entries take the form of 0xRRCCKKKK where
                        0x070b0067 0x070c0069>;
        };
 
-       gpio_a: gpios {
+       gpio_a: gpios@0 {
                gpio-controller;
                compatible = "sandbox,gpio";
                #gpio-cells = <1>;
                num-gpios = <20>;
        };
 
+       gpio_b: gpios@1 {
+               gpio-controller;
+               compatible = "sandbox,gpio";
+               #gpio-cells = <2>;
+               gpio-bank-name = "b";
+               num-gpios = <10>;
+       };
+
        i2c@0 {
                #address-cells = <1>;
                #size-cells = <0>;
index 5e4778e97881dd35f6793ae108c3e82019938108..76ad7c443bb9285db808c6df97d02461e94a62ed 100644 (file)
@@ -98,7 +98,7 @@ int misc_init_r(void)
                                puts("Error: invalid MAC at EEPROM\n");
                }
        }
-       gd->jt[XF_do_reset] = (void *) do_reset;
+       gd->jt->do_reset = do_reset;
 
 #ifdef CONFIG_STATUS_LED
        status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING);
index 7ebea6317f70f320928a9d7705bfed878330a10f..7d5e7bee8b9a9c4c9a9bfc0280a898e9dfff6986 100644 (file)
@@ -1,4 +1,30 @@
-if TARGET_VEXPRESS_AEMV8A
+if TARGET_VEXPRESS64_AEMV8A
+
+config SYS_BOARD
+       default "vexpress64"
+
+config SYS_VENDOR
+       default "armltd"
+
+config SYS_CONFIG_NAME
+       default "vexpress_aemv8a"
+
+endif
+
+if TARGET_VEXPRESS64_BASE_FVP
+
+config SYS_BOARD
+       default "vexpress64"
+
+config SYS_VENDOR
+       default "armltd"
+
+config SYS_CONFIG_NAME
+       default "vexpress_aemv8a"
+
+endif
+
+if TARGET_VEXPRESS64_JUNO
 
 config SYS_BOARD
        default "vexpress64"
index 66c8dffa163420a647a5c65ae2f3d9817039a196..0ba044d7ff8711816df1ba8028de0df3aacc41bb 100644 (file)
@@ -9,3 +9,8 @@ VEXPRESS_AEMV8A_SEMI BOARD
 M:     Linus Walleij <linus.walleij@linaro.org>
 S:     Maintained
 F:     configs/vexpress_aemv8a_semi_defconfig
+
+JUNO DEVELOPMENT PLATFORM BOARD
+M:     Linus Walleij <linus.walleij@linaro.org>
+S:     Maintained
+F:     configs/vexpress_aemv8a_juno_defconfig
index 86a0844273d64a28bb361709ed1107871c9d6c99..1704627112642027a42bf1f8f13bfd8436808d09 100644 (file)
@@ -55,12 +55,12 @@ void pmu_write(uchar reg, uchar data)
        struct udevice *dev;
        int ret;
 
-       ret = i2c_get_chip_for_busnum(4, PMU_I2C_ADDRESS, &dev);
+       ret = i2c_get_chip_for_busnum(4, PMU_I2C_ADDRESS, 1, &dev);
        if (ret) {
                debug("%s: Cannot find PMIC I2C chip\n", __func__);
                return;
        }
-       i2c_write(dev, reg, &data, 1);
+       dm_i2c_write(dev, reg, &data, 1);
 }
 
 /*
index 78c4bd4efe7114767e9c52ef07a42c6fe8c1460c..79562f79a80c6f93acb134e3a9d342957a3807c8 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <common.h>
+#include <ide.h>
 #include <netdev.h>
 #include <pci.h>
 #include <pci_gt64120.h>
@@ -123,6 +124,7 @@ void _machine_restart(void)
 
        reset_base = (void __iomem *)CKSEG1ADDR(MALTA_RESET_BASE);
        __raw_writel(GORESET, reset_base);
+       mdelay(1000);
 }
 
 int board_early_init_f(void)
@@ -217,4 +219,22 @@ void pci_init_board(void)
        pci_read_config_byte(bdf, PCI_CFG_PIIX4_SERIRQC, &val8);
        val8 |= PCI_CFG_PIIX4_SERIRQC_EN | PCI_CFG_PIIX4_SERIRQC_CONT;
        pci_write_config_byte(bdf, PCI_CFG_PIIX4_SERIRQC, val8);
+
+       bdf = pci_find_device(PCI_VENDOR_ID_INTEL,
+                             PCI_DEVICE_ID_INTEL_82371AB, 0);
+       if (bdf == -1)
+               panic("Failed to find PIIX4 IDE controller\n");
+
+       /* enable bus master & IO access */
+       val32 |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+       pci_write_config_dword(bdf, PCI_COMMAND, val32);
+
+       /* set latency */
+       pci_write_config_byte(bdf, PCI_LATENCY_TIMER, 0x40);
+
+       /* enable IDE/ATA */
+       pci_write_config_dword(bdf, PCI_CFG_PIIX4_IDETIM_PRI,
+                              PCI_CFG_PIIX4_IDETIM_IDE);
+       pci_write_config_dword(bdf, PCI_CFG_PIIX4_IDETIM_SEC,
+                              PCI_CFG_PIIX4_IDETIM_IDE);
 }
index 95c4ff25092b7272860d1770c25d239ab27b50b0..1540526a61348eb1959a6f6864b135c648adcbd6 100644 (file)
@@ -46,7 +46,7 @@ void board_sdmmc_voltage_init(void)
        int ret;
        int i;
 
-       ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, &dev);
+       ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev);
        if (ret) {
                debug("%s: Cannot find PMIC I2C chip\n", __func__);
                return;
@@ -57,7 +57,7 @@ void board_sdmmc_voltage_init(void)
        reg = 0x32;
 
        for (i = 0; i < MAX_I2C_RETRY; ++i) {
-               if (i2c_write(dev, reg, data_buffer, 1))
+               if (dm_i2c_write(dev, reg, data_buffer, 1))
                        udelay(100);
        }
 
@@ -66,7 +66,7 @@ void board_sdmmc_voltage_init(void)
        reg = 0x67;
 
        for (i = 0; i < MAX_I2C_RETRY; ++i) {
-               if (i2c_write(dev, reg, data_buffer, 1))
+               if (dm_i2c_write(dev, reg, data_buffer, 1))
                        udelay(100);
        }
 }
@@ -94,7 +94,7 @@ int tegra_pcie_board_init(void)
        u8 addr, data[1];
        int err;
 
-       err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, &dev);
+       err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev);
        if (err) {
                debug("failed to find PMU bus\n");
                return err;
@@ -104,7 +104,7 @@ int tegra_pcie_board_init(void)
        data[0] = 0x15;
        addr = 0x30;
 
-       err = i2c_write(dev, addr, data, 1);
+       err = dm_i2c_write(dev, addr, data, 1);
        if (err) {
                debug("failed to set VDD supply\n");
                return err;
@@ -121,7 +121,7 @@ int tegra_pcie_board_init(void)
        data[0] = 0x15;
        addr = 0x31;
 
-       err = i2c_write(dev, addr, data, 1);
+       err = dm_i2c_write(dev, addr, data, 1);
        if (err) {
                debug("failed to set AVDD supply\n");
                return err;
index 2a737468ddc4fce7411f2f9d183596c9edadf6c6..d7c1a695ff804562459791b2dd28d67d64609300 100644 (file)
@@ -55,7 +55,7 @@ void board_sdmmc_voltage_init(void)
        uchar reg, data_buffer[1];
        int ret;
 
-       ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, &dev);
+       ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev);
        if (ret) {
                debug("%s: Cannot find PMIC I2C chip\n", __func__);
                return;
@@ -65,7 +65,7 @@ void board_sdmmc_voltage_init(void)
        data_buffer[0] = 0x31;
        reg = 0x61;
 
-       ret = i2c_write(dev, reg, data_buffer, 1);
+       ret = dm_i2c_write(dev, reg, data_buffer, 1);
        if (ret)
                printf("%s: PMU i2c_write %02X<-%02X returned %d\n",
                        __func__, reg, data_buffer[0], ret);
@@ -74,7 +74,7 @@ void board_sdmmc_voltage_init(void)
        data_buffer[0] = 0x01;
        reg = 0x60;
 
-       ret = i2c_write(dev, reg, data_buffer, 1);
+       ret = dm_i2c_write(dev, reg, data_buffer, 1);
        if (ret)
                printf("%s: PMU i2c_write %02X<-%02X returned %d\n",
                        __func__, reg, data_buffer[0], ret);
@@ -83,12 +83,12 @@ void board_sdmmc_voltage_init(void)
        data_buffer[0] = 0x03;
        reg = 0x14;
 
-       ret = i2c_get_chip_for_busnum(0, BAT_I2C_ADDRESS, &dev);
+       ret = i2c_get_chip_for_busnum(0, BAT_I2C_ADDRESS, 1, &dev);
        if (ret) {
                debug("%s: Cannot find charger I2C chip\n", __func__);
                return;
        }
-       ret = i2c_write(dev, reg, data_buffer, 1);
+       ret = dm_i2c_write(dev, reg, data_buffer, 1);
        if (ret)
                printf("%s: BAT i2c_write %02X<-%02X returned %d\n",
                        __func__, reg, data_buffer[0], ret);
index 3114b20be0245602db4c6e7a46d55107b1a0258a..3476f1159feadc70ca214bb72af914143ef15153 100644 (file)
@@ -27,21 +27,21 @@ void pin_mux_mmc(void)
        int ret;
 
        /* Turn on MAX8907B LDO12 to 2.8V for J40 power */
-       ret = i2c_get_chip_for_busnum(0, 0x3c, &dev);
+       ret = i2c_get_chip_for_busnum(0, 0x3c, 1, &dev);
        if (ret) {
                printf("%s: Cannot find MAX8907B I2C chip\n", __func__);
                return;
        }
        val = 0x29;
-       ret = i2c_write(dev, 0x46, &val, 1);
+       ret = dm_i2c_write(dev, 0x46, &val, 1);
        if (ret)
                printf("i2c_write 0 0x3c 0x46 failed: %d\n", ret);
        val = 0x00;
-       ret = i2c_write(dev, 0x45, &val, 1);
+       ret = dm_i2c_write(dev, 0x45, &val, 1);
        if (ret)
                printf("i2c_write 0 0x3c 0x45 failed: %d\n", ret);
        val = 0x1f;
-       ret = i2c_write(dev, 0x44, &val, 1);
+       ret = dm_i2c_write(dev, 0x44, &val, 1);
        if (ret)
                printf("i2c_write 0 0x3c 0x44 failed: %d\n", ret);
 
@@ -64,17 +64,17 @@ void pin_mux_usb(void)
         */
 
        /* Turn on TAC6416's GPIO 0+1 for USB1/3's VBUS */
-       ret = i2c_get_chip_for_busnum(0, 0x20, &dev);
+       ret = i2c_get_chip_for_busnum(0, 0x20, 1, &dev);
        if (ret) {
                printf("%s: Cannot find TAC6416 I2C chip\n", __func__);
                return;
        }
        val = 0x03;
-       ret = i2c_write(dev, 2, &val, 1);
+       ret = dm_i2c_write(dev, 2, &val, 1);
        if (ret)
                printf("i2c_write 0 0x20 2 failed: %d\n", ret);
        val = 0xfc;
-       ret = i2c_write(dev, 6, &val, 1);
+       ret = dm_i2c_write(dev, 6, &val, 1);
        if (ret)
                printf("i2c_write 0 0x20 6 failed: %d\n", ret);
 }
index b7d23817e143016688d332fbf1da1acd925fe6c2..e3517f2eb24101f8614b53c120d30f37ea5caa06 100644 (file)
@@ -415,15 +415,6 @@ static int pmic_init_max77686(void)
        return 0;
 }
 
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-static void board_init_i2c(void)
-{
-       /* I2C_0 */
-       if (exynos_pinmux_config(PERIPH_ID_I2C0, PINMUX_FLAG_NONE))
-               debug("I2C%d not configured\n", (I2C_0));
-}
-#endif
-
 int exynos_early_init_f(void)
 {
        board_clock_init();
@@ -444,10 +435,7 @@ int exynos_init(void)
 
 int exynos_power_init(void)
 {
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
-       board_init_i2c();
-#endif
-       pmic_init(I2C_0);
+       pmic_init(0);
        pmic_init_max77686();
 
        return 0;
index 5f879f55065255d31ec152fde745190f60d4fe2f..3c0df1784553a85222660061c5b570c40823684a 100644 (file)
@@ -18,8 +18,8 @@ create unit tests which we can run to test this upper level code.
 
 CONFIG_SANDBOX is defined when building a native board.
 
-The chosen vendor and board names are also 'sandbox', so there is a single
-board in board/sandbox.
+The board name is 'sandbox' but the vendor name is unset, so there is a
+single board in board/sandbox.
 
 CONFIG_SANDBOX_BIG_ENDIAN should be defined when running on big-endian
 machines.
index 5d2c024e890b9ffab6401517ce75bd33a759b70a..624421496a408fe72128bdf31083ab249559da8f 100644 (file)
@@ -42,7 +42,7 @@ int tegra_pcie_board_init(void)
        u8 addr, data[1];
        int err;
 
-       err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, &dev);
+       err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev);
        if (err) {
                debug("%s: Cannot find PMIC I2C chip\n", __func__);
                return err;
@@ -51,7 +51,7 @@ int tegra_pcie_board_init(void)
        data[0] = 0x27;
        addr = 0x25;
 
-       err = i2c_write(dev, addr, data, 1);
+       err = dm_i2c_write(dev, addr, data, 1);
        if (err) {
                debug("failed to set VDD supply\n");
                return err;
@@ -61,7 +61,7 @@ int tegra_pcie_board_init(void)
        data[0] = 0x0D;
        addr = 0x24;
 
-       err = i2c_write(dev, addr, data, 1);
+       err = dm_i2c_write(dev, addr, data, 1);
        if (err) {
                debug("failed to enable VDD supply\n");
                return err;
@@ -71,7 +71,7 @@ int tegra_pcie_board_init(void)
        data[0] = 0x0D;
        addr = 0x35;
 
-       err = i2c_write(dev, addr, data, 1);
+       err = dm_i2c_write(dev, addr, data, 1);
        if (err) {
                debug("failed to set AVDD supply\n");
                return err;
index 94554f2939e5361179842fef3777d7ee6c06165d..9579ab4c982287f6913beeff41b92b3a85731cae 100644 (file)
@@ -27,6 +27,8 @@ endif
 # boards
 obj-$(CONFIG_SYS_GENERIC_BOARD) += board_f.o
 obj-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o
+obj-$(CONFIG_DISPLAY_BOARDINFO) += board_info.o
+obj-$(CONFIG_DISPLAY_BOARDINFO_LATE) += board_info.o
 
 # core command
 obj-y += cmd_boot.o
index 215108ba06e07d5b907fac5def2887e1249d01ca..79531377a78b6d4b304c3f9bff7590b2ae0fa20f 100644 (file)
@@ -894,7 +894,7 @@ static init_fnc_t init_sequence_f[] = {
        prt_mpc5xxx_clks,
 #endif /* CONFIG_MPC5xxx */
 #if defined(CONFIG_DISPLAY_BOARDINFO)
-       checkboard,             /* display board info */
+       show_board_info,
 #endif
        INIT_FUNC_WATCHDOG_INIT
 #if defined(CONFIG_MISC_INIT_F)
diff --git a/common/board_info.c b/common/board_info.c
new file mode 100644 (file)
index 0000000..42d0641
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <libfdt.h>
+#include <linux/compiler.h>
+
+int __weak checkboard(void)
+{
+       printf("Board: Unknown\n");
+       return 0;
+}
+
+/*
+ * If the root node of the DTB has a "model" property, show it.
+ * If CONFIG_OF_CONTROL is disabled or the "model" property is missing,
+ * fall back to checkboard().
+ */
+int show_board_info(void)
+{
+#ifdef CONFIG_OF_CONTROL
+       DECLARE_GLOBAL_DATA_PTR;
+       const char *model;
+
+       model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
+
+       if (model) {
+               printf("Model: %s\n", model);
+               return 0;
+       }
+#endif
+
+       return checkboard();
+}
index a301cc226f1e69fb4f6229382391c80218f12460..68a9448b5549da7f0e9b1d0db843dbd7f3de0486 100644 (file)
@@ -476,22 +476,6 @@ static int initr_api(void)
 }
 #endif
 
-#ifdef CONFIG_DISPLAY_BOARDINFO_LATE
-static int show_model_r(void)
-{
-       /* Put this here so it appears on the LCD, now it is ready */
-# ifdef CONFIG_OF_CONTROL
-       const char *model;
-
-       model = (char *)fdt_getprop(gd->fdt_blob, 0, "model", NULL);
-       printf("Model: %s\n", model ? model : "<unknown>");
-# else
-       checkboard();
-# endif
-       return 0;
-}
-#endif
-
 /* enable exceptions */
 #ifdef CONFIG_ARM
 static int initr_enable_interrupts(void)
@@ -801,7 +785,7 @@ init_fnc_t init_sequence_r[] = {
 #endif
        console_init_r,         /* fully init console as a device */
 #ifdef CONFIG_DISPLAY_BOARDINFO_LATE
-       show_model_r,
+       show_board_info,
 #endif
 #ifdef CONFIG_ARCH_MISC_INIT
        arch_misc_init,         /* miscellaneous arch-dependent init */
index 67233600b157244409c2710afa606337d2ebaf80..48199bfff3ed75a232ba3905cb4fe8662b09e321 100644 (file)
@@ -185,6 +185,9 @@ static char bootm_help_text[] =
        "\tcmdline - OS specific command line processing/setup\n"
        "\tbdt     - OS specific bd_t processing\n"
        "\tprep    - OS specific prep before relocation or go\n"
+#if defined(CONFIG_TRACE)
+       "\tfake    - OS specific fake start without go\n"
+#endif
        "\tgo      - start OS";
 #endif
 
index 652c61c70779bdab10116e80bca99e554f20a786..bcb34d904569d98612317dcc4e0712db6edd6410 100644 (file)
@@ -39,6 +39,26 @@ static int do_demo_status(cmd_tbl_t *cmdtp, int flag, int argc,
        return 0;
 }
 
+static int do_demo_light(cmd_tbl_t *cmdtp, int flag, int argc,
+                        char * const argv[])
+{
+       int light;
+       int ret;
+
+       if (argc) {
+               light = simple_strtoul(argv[0], NULL, 16);
+               ret = demo_set_light(demo_dev, light);
+       } else {
+               ret = demo_get_light(demo_dev);
+               if (ret >= 0) {
+                       printf("Light: %x\n", ret);
+                       ret = 0;
+               }
+       }
+
+       return ret;
+}
+
 int do_demo_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
        struct udevice *dev;
@@ -61,6 +81,7 @@ int do_demo_list(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 static cmd_tbl_t demo_commands[] = {
        U_BOOT_CMD_MKENT(list, 0, 1, do_demo_list, "", ""),
        U_BOOT_CMD_MKENT(hello, 2, 1, do_demo_hello, "", ""),
+       U_BOOT_CMD_MKENT(light, 2, 1, do_demo_light, "", ""),
        U_BOOT_CMD_MKENT(status, 1, 1, do_demo_status, "", ""),
 };
 
@@ -86,6 +107,10 @@ static int do_demo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
                        return cmd_process_error(cmdtp, ret);
                argc--;
                argv++;
+       } else {
+               demo_dev = NULL;
+               if (demo_cmd->cmd != do_demo_list)
+                       return CMD_RET_USAGE;
        }
 
        ret = demo_cmd->cmd(demo_cmd, flag, argc, argv);
@@ -98,5 +123,7 @@ U_BOOT_CMD(
        "Driver model (dm) demo operations",
        "list                     List available demo devices\n"
        "demo hello <num> [<char>]     Say hello\n"
-       "demo status <num>             Get demo device status"
+       "demo light [<num>]            Set or get the lights\n"
+       "demo status <num>             Get demo device status\n"
+       "demo list                     List available demo devices"
 );
index 484a6c6ce0364c7fef5e3ffb62b0411d3fd77698..7f99aabf8a5c69454a19fced5a71c596b043dddc 100644 (file)
@@ -346,7 +346,7 @@ U_BOOT_CMD(fpga, 6, 1, do_fpga,
           "loadable FPGA image support",
           "[operation type] [device number] [image address] [image size]\n"
           "fpga operations:\n"
-          "  dump\t[dev]\t\t\tLoad device to memory buffer\n"
+          "  dump\t[dev] [address] [size]\tLoad device to memory buffer\n"
           "  info\t[dev]\t\t\tlist known device information\n"
           "  load\t[dev] [address] [size]\tLoad device from memory buffer\n"
 #if defined(CONFIG_CMD_FPGA_LOADP)
index 0d9da113bf0c1305bc64e7e67368d6eba800b5e0..e146254f6d68367d8dc2650c409f24a1676362dd 100644 (file)
@@ -81,3 +81,18 @@ U_BOOT_CMD(
        "    - List files in directory 'directory' of partition 'part' on\n"
        "      device type 'interface' instance 'dev'."
 )
+
+static int do_fstype_wrapper(cmd_tbl_t *cmdtp, int flag, int argc,
+                               char * const argv[])
+{
+       return do_fs_type(cmdtp, flag, argc, argv);
+}
+
+U_BOOT_CMD(
+       fstype, 4, 1, do_fstype_wrapper,
+       "Look up a filesystem type",
+       "<interface> <dev>:<part>\n"
+       "- print filesystem type\n"
+       "fstype <interface> <dev>:<part> <varname>\n"
+       "- set environment variable to filesystem type\n"
+);
index 320ff709fafba3a6abe2f5f1cb6b12a152788df1..c48baad9a106ab9ec0cdfc1e1544cbd437231ff8 100644 (file)
@@ -35,6 +35,6 @@ static int do_gettime(cmd_tbl_t *cmdtp, int flag, int argc,
 
 U_BOOT_CMD(
        gettime,        1,      1,      do_gettime,
-       "get timer val elapsed,\n",
-       "get time elapsed from uboot start\n"
+       "get timer val elapsed",
+       "get time elapsed from uboot start"
 );
index 22db1bb47c137fd4fe08fc20e3e2f75fba72f16f..7c3ad00fdf03f30ee358cf4501717d6e657e5d18 100644 (file)
@@ -83,12 +83,12 @@ DECLARE_GLOBAL_DATA_PTR;
 /* Display values from last command.
  * Memory modify remembered values are different from display memory.
  */
-static uchar   i2c_dp_last_chip;
+static uint    i2c_dp_last_chip;
 static uint    i2c_dp_last_addr;
 static uint    i2c_dp_last_alen;
 static uint    i2c_dp_last_length = 0x10;
 
-static uchar   i2c_mm_last_chip;
+static uint    i2c_mm_last_chip;
 static uint    i2c_mm_last_addr;
 static uint    i2c_mm_last_alen;
 
@@ -133,7 +133,7 @@ static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES;
 #ifdef CONFIG_DM_I2C
 static struct udevice *i2c_cur_bus;
 
-static int i2c_set_bus_num(unsigned int busnum)
+static int cmd_i2c_set_bus_num(unsigned int busnum)
 {
        struct udevice *bus;
        int ret;
@@ -168,7 +168,7 @@ static int i2c_get_cur_bus_chip(uint chip_addr, struct udevice **devp)
        if (ret)
                return ret;
 
-       return i2c_get_chip(bus, chip_addr, devp);
+       return i2c_get_chip(bus, chip_addr, 1, devp);
 }
 
 #endif
@@ -282,7 +282,7 @@ static int i2c_report_err(int ret, enum i2c_err_op op)
  */
 static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       u_char  chip;
+       uint    chip;
        uint    devaddr, length;
        int alen;
        u_char  *memaddr;
@@ -323,7 +323,7 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
        if (!ret && alen != -1)
                ret = i2c_set_chip_offset_len(dev, alen);
        if (!ret)
-               ret = i2c_read(dev, devaddr, memaddr, length);
+               ret = dm_i2c_read(dev, devaddr, memaddr, length);
 #else
        ret = i2c_read(chip, devaddr, alen, memaddr, length);
 #endif
@@ -335,7 +335,7 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
 
 static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       u_char  chip;
+       uint    chip;
        uint    devaddr, length;
        int alen;
        u_char  *memaddr;
@@ -381,7 +381,7 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
 
        while (length-- > 0) {
 #ifdef CONFIG_DM_I2C
-               ret = i2c_write(dev, devaddr++, memaddr++, 1);
+               ret = dm_i2c_write(dev, devaddr++, memaddr++, 1);
 #else
                ret = i2c_write(chip, devaddr++, alen, memaddr++, 1);
 #endif
@@ -444,7 +444,7 @@ static int do_i2c_flags(cmd_tbl_t *cmdtp, int flag, int argc,
  */
 static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       u_char  chip;
+       uint    chip;
        uint    addr, length;
        int alen;
        int     j, nbytes, linebytes;
@@ -513,7 +513,7 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
                linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
 
 #ifdef CONFIG_DM_I2C
-               ret = i2c_read(dev, addr, linebuf, linebytes);
+               ret = dm_i2c_read(dev, addr, linebuf, linebytes);
 #else
                ret = i2c_read(chip, addr, alen, linebuf, linebytes);
 #endif
@@ -563,7 +563,7 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
  */
 static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       uchar   chip;
+       uint    chip;
        ulong   addr;
        int     alen;
        uchar   byte;
@@ -611,7 +611,7 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
 
        while (count-- > 0) {
 #ifdef CONFIG_DM_I2C
-               ret = i2c_write(dev, addr++, &byte, 1);
+               ret = dm_i2c_write(dev, addr++, &byte, 1);
 #else
                ret = i2c_write(chip, addr++, alen, &byte, 1);
 #endif
@@ -649,7 +649,7 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
  */
 static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       uchar   chip;
+       uint    chip;
        ulong   addr;
        int     alen;
        int     count;
@@ -698,7 +698,7 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
        err = 0;
        while (count-- > 0) {
 #ifdef CONFIG_DM_I2C
-               ret = i2c_read(dev, addr, &byte, 1);
+               ret = dm_i2c_read(dev, addr, &byte, 1);
 #else
                ret = i2c_read(chip, addr, alen, &byte, 1);
 #endif
@@ -734,7 +734,7 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
 static int
 mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
 {
-       uchar   chip;
+       uint    chip;
        ulong   addr;
        int     alen;
        ulong   data;
@@ -793,7 +793,7 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg
        do {
                printf("%08lx:", addr);
 #ifdef CONFIG_DM_I2C
-               ret = i2c_read(dev, addr, (uchar *)&data, size);
+               ret = dm_i2c_read(dev, addr, (uchar *)&data, size);
 #else
                ret = i2c_read(chip, addr, alen, (uchar *)&data, size);
 #endif
@@ -841,8 +841,8 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg
                                 */
                                bootretry_reset_cmd_timeout();
 #ifdef CONFIG_DM_I2C
-                               ret = i2c_write(dev, addr, (uchar *)&data,
-                                               size);
+                               ret = dm_i2c_write(dev, addr, (uchar *)&data,
+                                                  size);
 #else
                                ret = i2c_write(chip, addr, alen,
                                                (uchar *)&data, size);
@@ -917,7 +917,7 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
                        continue;
 #endif
 #ifdef CONFIG_DM_I2C
-               ret = i2c_probe(bus, j, 0, &dev);
+               ret = dm_i2c_probe(bus, j, 0, &dev);
 #else
                ret = i2c_probe(j);
 #endif
@@ -957,7 +957,7 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
  */
 static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       u_char  chip;
+       uint    chip;
        int alen;
        uint    addr;
        uint    length;
@@ -1010,7 +1010,7 @@ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
         */
        while (1) {
 #ifdef CONFIG_DM_I2C
-               ret = i2c_read(dev, addr, bytes, length);
+               ret = dm_i2c_read(dev, addr, bytes, length);
 #else
                ret = i2c_read(chip, addr, alen, bytes, length);
 #endif
@@ -1085,7 +1085,7 @@ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 {
        enum { unknown, EDO, SDRAM, DDR2 } type;
 
-       u_char  chip;
+       uint    chip;
        u_char  data[128];
        u_char  cksum;
        int     j;
@@ -1563,7 +1563,7 @@ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
 #if defined(CONFIG_I2C_EDID)
 int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 {
-       u_char chip;
+       uint chip;
        struct edid1_info edid;
        int ret;
 #ifdef CONFIG_DM_I2C
@@ -1579,7 +1579,7 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 #ifdef CONFIG_DM_I2C
        ret = i2c_get_cur_bus_chip(chip, &dev);
        if (!ret)
-               ret = i2c_read(dev, 0, (uchar *)&edid, sizeof(edid));
+               ret = dm_i2c_read(dev, 0, (uchar *)&edid, sizeof(edid));
 #else
        ret = i2c_read(chip, 0, 1, (uchar *)&edid, sizeof(edid));
 #endif
@@ -1696,7 +1696,11 @@ static int do_i2c_bus_num(cmd_tbl_t *cmdtp, int flag, int argc,
                }
 #endif
                printf("Setting bus to %d\n", bus_no);
+#ifdef CONFIG_DM_I2C
+               ret = cmd_i2c_set_bus_num(bus_no);
+#else
                ret = i2c_set_bus_num(bus_no);
+#endif
                if (ret)
                        printf("Failure changing bus number (%d)\n", ret);
        }
index f6e522cbb3482bf48eeae51cfe0d2e1467404de3..d043e6d7bcf2d6368ead958a89574720ce6c37d4 100644 (file)
@@ -222,7 +222,7 @@ static int read_record(char *buf, ulong len)
                }
 
            /* Check for the console hangup (if any different from serial) */
-           if (gd->jt[XF_getc] != getc) {
+           if (gd->jt->getc != getc) {
                if (ctrlc()) {
                    return (-1);
                }
index 39e8666b774a4b0d45c2a0f9b06295ac975a20b5..c99f52735f057c92b556bf49a7c0559f1ef66575 100644 (file)
@@ -54,13 +54,31 @@ static int do_part_list(int argc, char * const argv[])
        int ret;
        block_dev_desc_t *desc;
 
-       if (argc != 2)
+       if (argc < 2 || argc > 3)
                return CMD_RET_USAGE;
 
        ret = get_device(argv[0], argv[1], &desc);
        if (ret < 0)
                return 1;
 
+       if (argc == 3) {
+               int p;
+               char str[512] = { 0, };
+         disk_partition_t info;
+
+               for (p = 1; p < 128; p++) {
+                       int r = get_partition_info(desc, p, &info);
+
+                       if (r == 0) {
+                               char t[5];
+                               sprintf(t, "%s%d", str[0] ? " " : "", p);
+                               strcat(str, t);
+                       }
+               }
+               setenv(argv[2], str);
+               return 0;
+       }
+
        print_part(desc);
 
        return 0;
@@ -87,5 +105,7 @@ U_BOOT_CMD(
        "part uuid <interface> <dev>:<part> <varname>\n"
        "    - set environment variable to partition UUID\n"
        "part list <interface> <dev>\n"
-       "    - print a device's partition table"
+       "    - print a device's partition table\n"
+       "part list <interface> <dev> <varname>\n"
+       "    - set environment variable to the list of partitions"
 );
index ae2714d3728021bdc0d262f2bbe3b4cb54fcfe52..64b9186d738920dabf3e8573dcebaecdbb3ee562 100644 (file)
@@ -247,6 +247,8 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
                puts("OK\n");
        }
 
+       flush_cache(dest, len);
+
        setenv_hex("fileaddr", data);
        setenv_hex("filesize", len);
 
index fc1963b2a978a1be548f07e98108e1b817432e0c..3f25e76fe79ea3c94a85d0306d668233320e2d47 100644 (file)
@@ -125,13 +125,13 @@ static int console_setfile(int file, struct stdio_dev * dev)
                 */
                switch (file) {
                case stdin:
-                       gd->jt[XF_getc] = getc;
-                       gd->jt[XF_tstc] = tstc;
+                       gd->jt->getc = getc;
+                       gd->jt->tstc = tstc;
                        break;
                case stdout:
-                       gd->jt[XF_putc] = putc;
-                       gd->jt[XF_puts] = puts;
-                       gd->jt[XF_printf] = printf;
+                       gd->jt->putc  = putc;
+                       gd->jt->puts  = puts;
+                       gd->jt->printf = printf;
                        break;
                }
                break;
@@ -758,11 +758,11 @@ int console_init_r(void)
 #endif
 
        /* set default handlers at first */
-       gd->jt[XF_getc] = serial_getc;
-       gd->jt[XF_tstc] = serial_tstc;
-       gd->jt[XF_putc] = serial_putc;
-       gd->jt[XF_puts] = serial_puts;
-       gd->jt[XF_printf] = serial_printf;
+       gd->jt->getc  = serial_getc;
+       gd->jt->tstc  = serial_tstc;
+       gd->jt->putc  = serial_putc;
+       gd->jt->puts  = serial_puts;
+       gd->jt->printf = serial_printf;
 
        /* stdin stdout and stderr are in environment */
        /* scan for it */
index 88fcfc8cb6fc652e8fb5242869ebdb4c0813f5dd..333107c74c3c68f9244eea3cdbd44a6f0c1c2802 100644 (file)
@@ -1,6 +1,7 @@
 #include <common.h>
 #include <exports.h>
 #include <spi.h>
+#include <i2c.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -13,33 +14,10 @@ unsigned long get_version(void)
        return XF_VERSION;
 }
 
-/* Reuse _exports.h with a little trickery to avoid bitrot */
-#define EXPORT_FUNC(sym) gd->jt[XF_##sym] = (void *)sym;
-
-#if !defined(CONFIG_X86) && !defined(CONFIG_PPC)
-# define install_hdlr      dummy
-# define free_hdlr         dummy
-#else /* kludge for non-standard function naming */
-# define install_hdlr      irq_install_handler
-# define free_hdlr         irq_free_handler
-#endif
-#ifndef CONFIG_CMD_I2C
-# define i2c_write         dummy
-# define i2c_read          dummy
-#endif
-#if !defined(CONFIG_CMD_SPI) || defined(CONFIG_DM_SPI)
-# define spi_init          dummy
-# define spi_setup_slave   dummy
-# define spi_free_slave    dummy
-#endif
-#ifndef CONFIG_CMD_SPI
-# define spi_claim_bus     dummy
-# define spi_release_bus   dummy
-# define spi_xfer          dummy
-#endif
+#define EXPORT_FUNC(f, a, x, ...)  gd->jt->x = f;
 
 void jumptable_init(void)
 {
-       gd->jt = malloc(XF_MAX * sizeof(void *));
+       gd->jt = malloc(sizeof(struct jt_funcs));
 #include <_exports.h>
 }
index aceabc5caddb12d1c52d9b4c4028981ff01670b0..d154d029e9c32466979bdc93116b70778402bb78 100644 (file)
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
+#ifndef USE_HOSTCC
 #include <common.h>
 #include <command.h>
 #include <malloc.h>
 #include <hw_sha.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#else
+#include "mkimage.h"
+#include <time.h>
+#include <image.h>
+#endif /* !USE_HOSTCC*/
+
 #include <hash.h>
+#include <u-boot/crc.h>
 #include <u-boot/sha1.h>
 #include <u-boot/sha256.h>
-#include <asm/io.h>
-#include <asm/errno.h>
+#include <u-boot/md5.h>
 
-#ifdef CONFIG_CMD_SHA1SUM
+#ifdef CONFIG_SHA1
 static int hash_init_sha1(struct hash_algo *algo, void **ctxp)
 {
        sha1_context *ctx = malloc(sizeof(sha1_context));
@@ -125,12 +134,7 @@ static struct hash_algo hash_algo[] = {
                CHUNKSZ_SHA256,
        },
 #endif
-       /*
-        * This is CONFIG_CMD_SHA1SUM instead of CONFIG_SHA1 since otherwise
-        * it bloats the code for boards which use SHA1 but not the 'hash'
-        * or 'sha1sum' commands.
-        */
-#ifdef CONFIG_CMD_SHA1SUM
+#ifdef CONFIG_SHA1
        {
                "sha1",
                SHA1_SUM_LEN,
@@ -140,7 +144,6 @@ static struct hash_algo hash_algo[] = {
                hash_update_sha1,
                hash_finish_sha1,
        },
-#define MULTI_HASH
 #endif
 #ifdef CONFIG_SHA256
        {
@@ -152,7 +155,6 @@ static struct hash_algo hash_algo[] = {
                hash_update_sha256,
                hash_finish_sha256,
        },
-#define MULTI_HASH
 #endif
        {
                "crc32",
@@ -165,6 +167,10 @@ static struct hash_algo hash_algo[] = {
        },
 };
 
+#if defined(CONFIG_SHA256) || defined(CONFIG_CMD_SHA1SUM)
+#define MULTI_HASH
+#endif
+
 #if defined(CONFIG_HASH_VERIFY) || defined(CONFIG_CMD_HASH)
 #define MULTI_HASH
 #endif
@@ -176,6 +182,40 @@ static struct hash_algo hash_algo[] = {
 #define multi_hash()   0
 #endif
 
+int hash_lookup_algo(const char *algo_name, struct hash_algo **algop)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
+               if (!strcmp(algo_name, hash_algo[i].name)) {
+                       *algop = &hash_algo[i];
+                       return 0;
+               }
+       }
+
+       debug("Unknown hash algorithm '%s'\n", algo_name);
+       return -EPROTONOSUPPORT;
+}
+
+int hash_progressive_lookup_algo(const char *algo_name,
+                                struct hash_algo **algop)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
+               if (!strcmp(algo_name, hash_algo[i].name)) {
+                       if (hash_algo[i].hash_init) {
+                               *algop = &hash_algo[i];
+                               return 0;
+                       }
+               }
+       }
+
+       debug("Unknown hash algorithm '%s'\n", algo_name);
+       return -EPROTONOSUPPORT;
+}
+
+#ifndef USE_HOSTCC
 /**
  * store_result: Store the resulting sum to an address or variable
  *
@@ -296,21 +336,6 @@ static int parse_verify_sum(struct hash_algo *algo, char *verify_str,
        return 0;
 }
 
-int hash_lookup_algo(const char *algo_name, struct hash_algo **algop)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(hash_algo); i++) {
-               if (!strcmp(algo_name, hash_algo[i].name)) {
-                       *algop = &hash_algo[i];
-                       return 0;
-               }
-       }
-
-       debug("Unknown hash algorithm '%s'\n", algo_name);
-       return -EPROTONOSUPPORT;
-}
-
 void hash_show(struct hash_algo *algo, ulong addr, ulong len, uint8_t *output)
 {
        int i;
@@ -424,3 +449,4 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
 
        return 0;
 }
+#endif
index 1589ee3e4fb811ccb9bc8f31fbc094533abcd093..b47d11024f2beb007d049bc0cb54a43268d8bde1 100644 (file)
@@ -112,6 +112,33 @@ static void fit_get_debug(const void *fit, int noffset,
              fdt_strerror(err));
 }
 
+/**
+ * fit_get_subimage_count - get component (sub-image) count
+ * @fit: pointer to the FIT format image header
+ * @images_noffset: offset of images node
+ *
+ * returns:
+ *     number of image components
+ */
+int fit_get_subimage_count(const void *fit, int images_noffset)
+{
+       int noffset;
+       int ndepth;
+       int count = 0;
+
+       /* Process its subnodes, print out component images details */
+       for (ndepth = 0, count = 0,
+               noffset = fdt_next_node(fit, images_noffset, &ndepth);
+            (noffset >= 0) && (ndepth > 0);
+            noffset = fdt_next_node(fit, noffset, &ndepth)) {
+               if (ndepth == 1) {
+                       count++;
+               }
+       }
+
+       return count;
+}
+
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT)
 /**
  * fit_print_contents - prints out the contents of the FIT format image
@@ -423,7 +450,8 @@ void fit_image_print(const void *fit, int image_noffset, const char *p)
                }
        }
 }
-#endif
+
+#endif /* !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT) */
 
 /**
  * fit_get_desc - get node description property
index 8601edaca35f41d0c996e15fb7f447179a8255b3..2c9f0cdf7ae3996b5c57bbe74b9ff7ee5cea58d7 100644 (file)
@@ -38,7 +38,7 @@ struct checksum_algo checksum_algos[] = {
 #if IMAGE_ENABLE_SIGN
                EVP_sha1,
 #endif
-               sha1_calculate,
+               hash_calculate,
                padding_sha1_rsa2048,
        },
        {
@@ -48,7 +48,7 @@ struct checksum_algo checksum_algos[] = {
 #if IMAGE_ENABLE_SIGN
                EVP_sha256,
 #endif
-               sha256_calculate,
+               hash_calculate,
                padding_sha256_rsa2048,
        },
        {
@@ -58,7 +58,7 @@ struct checksum_algo checksum_algos[] = {
 #if IMAGE_ENABLE_SIGN
                EVP_sha256,
 #endif
-               sha256_calculate,
+               hash_calculate,
                padding_sha256_rsa4096,
        }
 
index ad7a46d08d827fb18f7005132342d19c7d97cf5d..a911aa9b4d128227520fba77555c4879e5e93ff3 100644 (file)
@@ -756,7 +756,7 @@ int genimg_get_format(const void *img_addr)
  * genimg_get_image - get image from special storage (if necessary)
  * @img_addr: image start address
  *
- * genimg_get_image() checks if provided image start adddress is located
+ * genimg_get_image() checks if provided image start address is located
  * in a dataflash storage. If so, image is moved to a system RAM memory.
  *
  * returns:
index 5837a0a4da75bfb9750fcf416194a58977a5ee90..51bf370364a3e10981c7a874ba89417daca604d2 100644 (file)
@@ -4,3 +4,7 @@ CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT,ENABLE_VBOOT"
 +S:CONFIG_TARGET_AM335X_EVM=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="am335x-boneblack"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
index 1c665aab943bda9ee911b40127dc85a561f2847e..0950ec8b77847b72ebfec4119da1be41a3d0b51e 100644 (file)
@@ -1,4 +1,7 @@
 CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0xFFF00000"
 CONFIG_PPC=y
 CONFIG_MPC83xx=y
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
 CONFIG_TARGET_IDS8313=y
+CONFIG_DM=y
index 2e9dd00c1d8baef2c5dc0e9fcc94f11130b8211f..86b4b15724b1da02bd7019ac360f4ec2b01a0f79 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_CMD_LOADB=y
 CONFIG_CMD_LOADS=y
 CONFIG_CMD_FLASH=y
 CONFIG_CMD_NAND=y
+CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_ECHO=y
 CONFIG_CMD_ITEST=y
@@ -34,6 +35,7 @@ CONFIG_SYS_NAND_DENALI_64BIT=y
 CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
 CONFIG_DM_SERIAL=y
 CONFIG_UNIPHIER_SERIAL=y
+CONFIG_DM_I2C=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
index 5dca64bf88ea42472d07cd352b02a05ee2acb31c..242bcf926359cd0f962aea04f0061fb84f1ad50e 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_CMD_LOADB=y
 CONFIG_CMD_LOADS=y
 CONFIG_CMD_FLASH=y
 CONFIG_CMD_NAND=y
+CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_ECHO=y
 CONFIG_CMD_ITEST=y
@@ -34,6 +35,7 @@ CONFIG_SYS_NAND_DENALI_64BIT=y
 CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
 CONFIG_DM_SERIAL=y
 CONFIG_UNIPHIER_SERIAL=y
+CONFIG_DM_I2C=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
index 2a6e334506a6e84722e7fac1cab8cb424b7b0248..8e95f17e6d101a200776f35adc3400ff7506e9d9 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_CMD_LOADB=y
 CONFIG_CMD_LOADS=y
 CONFIG_CMD_FLASH=y
 CONFIG_CMD_NAND=y
+CONFIG_CMD_I2C=y
 CONFIG_CMD_USB=y
 CONFIG_CMD_ECHO=y
 CONFIG_CMD_ITEST=y
@@ -34,6 +35,7 @@ CONFIG_SYS_NAND_DENALI_64BIT=y
 CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
 CONFIG_DM_SERIAL=y
 CONFIG_UNIPHIER_SERIAL=y
+CONFIG_DM_I2C=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_STORAGE=y
index 47d8400acece08586f535fad3b51e3872b3ed161..660063ebf333ae666ff7f1898a67d036c20909ad 100644 (file)
@@ -1,3 +1,7 @@
 CONFIG_OF_CONTROL=y
 CONFIG_OF_HOSTFILE=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
 CONFIG_DEFAULT_DEVICE_TREE="sandbox"
index b463a333bc6bb10cd84c040fad6ae38c98732a0f..9f4b876556137aefa8270fc0da776378b045f2a1 100644 (file)
@@ -1,3 +1,3 @@
 CONFIG_ARM=y
-CONFIG_TARGET_VEXPRESS_AEMV8A=y
+CONFIG_TARGET_VEXPRESS64_AEMV8A=y
 CONFIG_DEFAULT_DEVICE_TREE="vexpress64"
diff --git a/configs/vexpress_aemv8a_juno_defconfig b/configs/vexpress_aemv8a_juno_defconfig
new file mode 100644 (file)
index 0000000..d28a428
--- /dev/null
@@ -0,0 +1,5 @@
+# ARM Ltd. Juno Board Reference Design
+CONFIG_ARM=y
+CONFIG_TARGET_VEXPRESS64_JUNO=y
+CONFIG_DEFAULT_DEVICE_TREE="vexpress64"
+CONFIG_SHOW_BOOT_PROGRESS=y
index 0035ccdaecd4596e557c1d38b9deaf254053577f..26cf7db47f845ab9dff99bdb30c6cb3ce568dcb9 100644 (file)
@@ -1,4 +1,4 @@
-CONFIG_SYS_EXTRA_OPTIONS="SEMIHOSTING,BASE_FVP"
+# Semihosted FVP fast model
 CONFIG_ARM=y
-CONFIG_TARGET_VEXPRESS_AEMV8A=y
+CONFIG_TARGET_VEXPRESS64_BASE_FVP=y
 CONFIG_DEFAULT_DEVICE_TREE="vexpress64"
index 9588849bb5c0f7c78694fc90a52fb46daed1286f..8b985fe5a4294b0867f5a4ef95efe3ae40d2d177 100644 (file)
@@ -3,4 +3,8 @@ CONFIG_SPL=y
 +S:CONFIG_ZYNQ=y
 +S:CONFIG_TARGET_ZYNQ_MICROZED=y
 CONFIG_OF_CONTROL=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed"
index cf507308e95d209540ad5442df87abdb01632549..cceb32199da1b6291a65cc62fb155c17ee0bcb9e 100644 (file)
@@ -4,3 +4,7 @@ CONFIG_SPL=y
 +S:CONFIG_TARGET_ZYNQ_ZC70X=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
index 8bb405d1808907756610f7ebd8ade97227615ec9..2935c0dff783fac32b6c0dda91917878e94b7c96 100644 (file)
@@ -5,3 +5,7 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010"
 +S:CONFIG_TARGET_ZYNQ_ZC770=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
index 0ba5da589e95db553b682393db5348fdcdf00ceb..0401739652fc361d75b073faa1825223a375f780 100644 (file)
@@ -5,3 +5,7 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM012"
 +S:CONFIG_TARGET_ZYNQ_ZC770=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
index 13f8112a1b627139c8fc980370759c8cd0d0f36a..a95970a917cece43f64ceca2c95f719049558ee9 100644 (file)
@@ -5,3 +5,7 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013"
 +S:CONFIG_TARGET_ZYNQ_ZC770=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
index eb057fae35c738332163e8693997c8667376124a..0fbc41ab8a8faca00138233a2be3db17eb9eb45a 100644 (file)
@@ -4,3 +4,7 @@ CONFIG_SPL=y
 +S:CONFIG_TARGET_ZYNQ_ZED=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
index 12311cd83b5011f35ff2b69737ad24c7b1fb9f9f..4e66760750c53bb6df093674aa6c60c8c79b3dde 100644 (file)
@@ -4,3 +4,7 @@ CONFIG_SPL=y
 +S:CONFIG_TARGET_ZYNQ_ZYBO=y
 CONFIG_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo"
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_DM=y
diff --git a/doc/README.distro b/doc/README.distro
new file mode 100644 (file)
index 0000000..dd0f1c7
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * (C) Copyright 2014 Red Hat Inc.
+ * Copyright (c) 2014-2015, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+Generic Distro Configuration Concept
+====================================
+
+Linux distributions are faced with supporting a variety of boot mechanisms,
+environments or bootloaders (PC BIOS, EFI, U-Boot, Barebox, ...). This makes
+life complicated. Worse, bootloaders such as U-Boot have a configurable set
+of features, and each board chooses to enable a different set of features.
+Hence, distros typically need to have board-specific knowledge in order to
+set up a bootable system.
+
+This document defines a common set of U-Boot features that are required for
+a distro to support the board in a generic fashion. Any board wishing to
+allow distros to install and boot in an out-of-the-box fashion should enable
+all these features. Linux distros can then create a single set of boot
+support/install logic that targets these features. This will allow distros
+to install on many boards without the need for board-specific logic.
+
+In fact, some of these features can be implemented by any bootloader, thus
+decoupling distro install/boot logic from any knowledge of the bootloader.
+
+This model assumes that boards will load boot configuration files from a
+regular storage mechanism (eMMC, SD card, USB Disk, SATA disk, etc.) with
+a standard partitioning scheme (MBR, GPT). Boards that cannnot support this
+storage model are outside the scope of this document, and may still need
+board-specific installer/boot-configuration support in a distro.
+
+To some extent, this model assumes that a board has a separate boot flash
+that contains U-Boot, and that the user has somehow installed U-Boot to this
+flash before running the distro installer. Even on boards that do not conform
+to this aspect of the model, the extent of the board-specific support in the
+distro installer logic would be to install a board-specific U-Boot package to
+the boot partition partition during installation. This distro-supplied U-Boot
+can still implement the same features as on any other board, and hence the
+distro's boot configuration file generation logic can still be board-agnostic.
+
+Locating Bootable Disks
+-----------------------
+
+Typical desktop/server PCs search all (or a user-defined subset of) attached
+storage devices for a bootable partition, then load the bootloader or boot
+configuration files from there. A U-Boot board port that enables the features
+mentioned in this document will search for boot configuration files in the
+same way.
+
+Thus, distros do not need to manipulate any kind of bootloader-specific
+configuration data to indicate which storage device the system should boot
+from.
+
+Distros simply need to install the boot configuration files (see next
+section) in an ext2/3/4 or FAT partition, mark the partition bootable (via
+the MBR bootable flag, or GPT legacy_bios_bootable attribute), and U-Boot (or
+any other bootloader) will find those boot files and execute them. This is
+conceptually identical to creating a grub2 configuration file on a desktop
+PC.
+
+Note that in the absense of any partition that is explicitly marked bootable,
+U-Boot falls back to searching the first valid partition of a disk for boot
+configuration files. Other bootloaders are recommended to do the same, since
+I believe that partition table bootable flags aren't so commonly used outside
+the realm of x86 PCs.
+
+U-Boot can also search for boot configuration files from a TFTP server.
+
+Boot Configuration Files
+------------------------
+
+The standard format for boot configuration files is that of extlinux.conf, as
+handled by U-Boot's "syslinux" (disk) or "pxe boot" (network). This is roughly
+as specified at:
+
+http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/
+
+... with the exceptions that the BootLoaderSpec document:
+
+* Prescribes a separate configuration per boot menu option, whereas U-Boot
+  lumps all options into a single extlinux.conf file. Hence, U-Boot searches
+  for /extlinux/extlinux.conf then /boot/extlinux/extlinux.conf on disk, or
+  pxelinux.cfg/default over the network.
+
+* Does not document the fdtdir option, which automatically selects the DTB to
+  pass to the kernel.
+
+One example extlinux.conf generated by the Fedora installer is:
+
+------------------------------------------------------------
+# extlinux.conf generated by anaconda
+
+ui menu.c32
+
+menu autoboot Welcome to Fedora. Automatic boot in # second{,s}. Press a key for options.
+menu title Fedora Boot Options.
+menu hidden
+
+timeout 50
+#totaltimeout 9000
+
+default Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae) 22 (Rawhide)
+
+label Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl) 22 (Rawhide)
+       kernel /boot/vmlinuz-3.17.0-0.rc4.git2.1.fc22.armv7hl
+       append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 LANG=en_US.UTF-8 drm.debug=0xf
+       fdtdir /boot/dtb-3.17.0-0.rc4.git2.1.fc22.armv7hl
+       initrd /boot/initramfs-3.17.0-0.rc4.git2.1.fc22.armv7hl.img
+
+label Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae) 22 (Rawhide)
+       kernel /boot/vmlinuz-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae
+       append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 LANG=en_US.UTF-8 drm.debug=0xf
+       fdtdir /boot/dtb-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae
+       initrd /boot/initramfs-3.17.0-0.rc4.git2.1.fc22.armv7hl+lpae.img
+
+label Fedora-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc (0-rescue-8f6ba7b039524e0eb957d2c9203f04bc)
+       kernel /boot/vmlinuz-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc
+       initrd /boot/initramfs-0-rescue-8f6ba7b039524e0eb957d2c9203f04bc.img
+       append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8
+       fdtdir /boot/dtb-3.16.0-0.rc6.git1.1.fc22.armv7hl+lpae
+------------------------------------------------------------
+
+Another hand-crafted network boot configuration file is:
+
+------------------------------------------------------------
+TIMEOUT 100
+
+MENU TITLE TFTP boot options
+
+LABEL jetson-tk1-emmc
+        MENU LABEL ../zImage root on Jetson TK1 eMMC
+        LINUX ../zImage
+        FDTDIR ../
+        APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=80a5a8e9-c744-491a-93c1-4f4194fd690b
+
+LABEL venice2-emmc
+        MENU LABEL ../zImage root on Venice2 eMMC
+        LINUX ../zImage
+        FDTDIR ../
+        APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=5f71e06f-be08-48ed-b1ef-ee4800cc860f
+
+LABEL sdcard
+        MENU LABEL ../zImage, root on 2GB sdcard
+        LINUX ../zImage
+        FDTDIR ../
+        APPEND console=ttyS0,115200n8 console=tty1 loglevel=8 rootwait rw earlyprintk root=PARTUUID=b2f82cda-2535-4779-b467-094a210fbae7
+
+LABEL fedora-installer-fk
+        MENU LABEL Fedora installer w/ Fedora kernel
+        LINUX fedora-installer/vmlinuz
+        INITRD fedora-installer/initrd.img.orig
+        FDTDIR fedora-installer/dtb
+        APPEND loglevel=8 ip=dhcp inst.repo=http://10.0.0.2/mirrors/fedora/linux/development/rawhide/armhfp/os/ rd.shell cma=64M
+------------------------------------------------------------
+
+U-Boot Implementation
+=====================
+
+Enabling the distro options
+---------------------------
+
+In your board configuration file, include the following:
+
+------------------------------------------------------------
+#ifndef CONFIG_SPL_BUILD
+#include <config_distro_defaults.h>
+#include <config_distro_bootcmd.h>
+#endif
+------------------------------------------------------------
+
+The first of those headers primarily enables a core set of U-Boot features,
+such as support for MBR and GPT partitions, ext* and FAT filesystems, booting
+raw zImage and initrd (rather than FIT- or uImage-wrapped files), etc. Network
+boot support is also enabled here, which is useful in order to boot distro
+installers given that distros do not commonly distribute bootable install
+media for non-PC targets at present.
+
+Finally, a few options that are mostly relevant only when using U-Boot-
+specific boot.scr scripts are enabled. This enables distros to generate a
+U-Boot-specific boot.scr script rather than extlinux.conf as the boot
+configuration file. While doing so is fully supported, and
+<config_distro_defaults.h> exposes enough parameterization to boot.scr to
+allow for board-agnostic boot.scr content, this document recommends that
+distros generate extlinux.conf rather than boot.scr. extlinux.conf is intended
+to work across multiple bootloaders, whereas boot.scr will only work with
+U-Boot. TODO: document the contract between U-Boot and boot.scr re: which
+environment variables a generic boot.scr may rely upon.
+
+The second of those headers sets up the default environment so that $bootcmd
+is defined in a way that searches attached disks for boot configuration files,
+and executes them if found.
+
+Required Environment Variables
+------------------------------
+
+The U-Boot "syslinux" and "pxe boot" commands require a number of environment
+variables be set. Default values for these variables are often hard-coded into
+CONFIG_EXTRA_ENV_SETTINGS in the board's U-Boot configuration file, so that
+the user doesn't have to configure them.
+
+fdt_addr:
+
+  Mandatory for any system that provides the DTB in HW (e.g. ROM) and wishes
+  to pass that DTB to Linux, rather than loading a DTB from the boot
+  filesystem. Prohibited for any other system.
+
+  If specified a DTB to boot the system must be available at the given
+  address.
+
+fdt_addr_r:
+
+  Mandatory. The location in RAM where the DTB will be loaded or copied to when
+  processing the fdtdir/devicetreedir or fdt/devicetree options in
+  extlinux.conf.
+
+  This is mandatory even when fdt_addr is provided, since extlinux.conf must
+  always be able to provide a DTB which overrides any copy provided by the HW.
+
+  A size of 1MB for the FDT/DTB seems reasonable.
+
+ramdisk_addr_r:
+
+  Mandatory. The location in RAM where the initial ramdisk will be loaded to
+  when processing the initrd option in extlinux.conf.
+
+  It is recommended that this location be highest in RAM out of fdt_addr_,
+  kernel_addr_r, and ramdisk_addr_r, so that the RAM disk can vary in size
+  and use any available RAM.
+
+kernel_addr_r:
+
+  Mandatory. The location in RAM where the kernel will be loaded to when
+  processing the kernel option in the extlinux.conf.
+
+  The kernel should be located within the first 128M of RAM in order for the
+  kernel CONFIG_AUTO_ZRELADDR option to work, which is likely enabled on any
+  distro kernel. Since the kernel will decompress itself to 0x8000 after the
+  start of RAM, kernel_addr_rshould not overlap that area, or the kernel will
+  have to copy itself somewhere else first before decompression.
+
+  A size of 16MB for the kernel is likely adequate.
+
+pxe_addr_r:
+
+  Mandatory. The location in RAM where extlinux.conf will be loaded to prior
+  to processing.
+
+  A size of 1MB for extlinux.conf is more than adequate.
+
+scriptaddr:
+
+  Mandatory, if the boot script is boot.scr rather than extlinux.conf. The
+  location in RAM where boot.scr will be loaded to prior to execution.
+
+  A size of 1MB for extlinux.conf is more than adequate.
+
+For suggestions on memory locations for ARM systems, you must follow the
+guidelines specified in Documentation/arm/Booting in the Linux kernel tree.
+
+For a commented example of setting these values, please see the definition of
+MEM_LAYOUT_ENV_SETTINGS in include/configs/tegra124-common.h.
+
+Boot Target Configuration
+-------------------------
+
+<config_distro_bootcmd.h> defines $bootcmd and many helper command variables
+that automatically search attached disks for boot configuration files and
+execute them. Boards must provide configure <config_distro_bootcmd.h> so that
+it supports the correct set of possible boot device types. To provide this
+configuration, simply define macro BOOT_TARGET_DEVICES prior to including
+<config_distro_bootcmd.h>. For example:
+
+------------------------------------------------------------
+#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>
+#endif
+------------------------------------------------------------
+
+Each entry in the macro defines a single boot device (e.g. a specific eMMC
+device or SD card) or type of boot device (e.g. USB disk). The parameters to
+the func macro (passed in by the internal implementation of the header) are:
+
+- Upper-case disk type (MMC, SATA, SCSI, IDE, USB, DHCP, PXE).
+- Lower-case disk type (same options as above).
+- ID of the specific disk (MMC only) or ignored for other types.
+
+User Configuration
+==================
+
+Once the user has installed U-Boot, it is expected that the environment will
+be reset to the default values in order to enable $bootcmd and friends, as set
+up by <config_distro_bootcmd.h>. After this, various environment variables may
+be altered to influence the boot process:
+
+boot_targets:
+
+  The list of boot locations searched.
+
+  Example: mmc0, mmc1, usb, pxe
+
+  Entries may be removed or re-ordered in this list to affect the boot order.
+
+boot_prefixes:
+
+  For disk-based booting, the list of directories within a partition that are
+  searched for boot configuration files (extlinux.conf, boot.scr).
+
+  Example: / /boot/
+
+  Entries may be removed or re-ordered in this list to affect the set of
+  directories which are searched.
+
+boot_scripts:
+
+  The name of U-Boot style boot.scr files that $bootcmd searches for.
+
+  Example: boot.scr.uimg boot.scr
+
+  (Typically we expect extlinux.conf to be used, but execution of boot.scr is
+  maintained for backwards-compatibility.)
+
+  Entries may be removed or re-ordered in this list to affect the set of
+  filenames which are supported.
+
+scan_dev_for_extlinux:
+
+  If you want to disable extlinux.conf on all disks, set the value to something
+  innocuous, e.g. setenv scan_dev_for_extlinux true.
+
+scan_dev_for_scripts:
+
+  If you want to disable boot.scr on all disks, set the value to something
+  innocuous, e.g. setenv scan_dev_for_scripts true.
index e3000efcc62177962809e7972ecba8fece4aefe2..659a12f6cb70b05cccf1110bddd365cdf31363e8 100644 (file)
@@ -5,18 +5,18 @@ Design Notes on Exporting U-Boot Functions to Standalone Applications:
    table is allocated and initialized in the jumptable_init() routine
    (common/exports.c). Other routines may also modify the jump table,
    however. The jump table can be accessed as the 'jt' field of the
-   'global_data' structure. The slot numbers for the jump table are
+   'global_data' structure. The struct members for the jump table are
    defined in the <include/exports.h> header. E.g., to substitute the
    malloc() and free() functions that will be available to standalone
    applications, one should do the following:
 
        DECLARE_GLOBAL_DATA_PTR;
 
-       gd->jt[XF_malloc]       = my_malloc;
-       gd->jt[XF_free]         = my_free;
+       gd->jt->malloc  = my_malloc;
+       gd->jt->free = my_free;
 
-   Note that the pointers to the functions all have 'void *' type and
-   thus the compiler cannot perform type checks on these assignments.
+   Note that the pointers to the functions are real function pointers
+   so the compiler can perform type checks on these assignments.
 
 2. The pointer to the jump table is passed to the application in a
    machine-dependent way. PowerPC, ARM, MIPS, Blackfin and Nios II
@@ -65,27 +65,46 @@ Design Notes on Exporting U-Boot Functions to Standalone Applications:
    => tftp 0x40000 hello_world.bin
    => go 0x40004
 
-5. To export some additional function foobar(), the following steps
+5. To export some additional function long foobar(int i,char c), the following steps
    should be undertaken:
 
    - Append the following line at the end of the include/_exports.h
      file:
 
-       EXPORT_FUNC(foobar)
+       EXPORT_FUNC(foobar, long, foobar, int, char)
+
+       Parameters to EXPORT_FUNC:
+        - the first parameter is the function that is exported (default implementation)
+        - the second parameter is the return value type
+        - the third  parameter is the name of the member in struct jt_funcs
+          this is also the name that the standalone application will used.
+          the rest of the parameters are the function arguments
 
    - Add the prototype for this function to the include/exports.h
      file:
 
-       void foobar(void);
+       long foobar(int i, char c);
+
+       Initialization with the default implementation is done in jumptable_init()
+
+       You can override the default implementation using:
 
-   - Add the initialization of the jump table slot wherever
-     appropriate (most likely, to the jumptable_init() function):
+       gd->jt->foobar = another_foobar;
 
-       gd->jt[XF_foobar] = foobar;
+       The signature of another_foobar must then match the declaration of foobar.
 
    - Increase the XF_VERSION value by one in the include/exports.h
      file
 
+   - If you want to export a function which depends on a CONFIG_XXX
+       use 2 lines like this:
+       #ifdef CONFIG_FOOBAR
+               EXPORT_FUNC(foobar, long, foobar, int, char)
+       #else
+               EXPORT_FUNC(dummy, void, foobar, void)
+       #endif
+
+
 6. The code for exporting the U-Boot functions to applications is
    mostly machine-independent. The only places written in assembly
    language are stub functions that perform the jump through the jump
diff --git a/doc/device-tree-bindings/gpio/gpio-samsung.txt b/doc/device-tree-bindings/gpio/gpio-samsung.txt
new file mode 100644 (file)
index 0000000..5375625
--- /dev/null
@@ -0,0 +1,41 @@
+Samsung Exynos4 GPIO Controller
+
+Required properties:
+- compatible: Compatible property value should be "samsung,exynos4-gpio>".
+
+- reg: Physical base address of the controller and length of memory mapped
+  region.
+
+- #gpio-cells: Should be 4. The syntax of the gpio specifier used by client nodes
+  should be the following with values derived from the SoC user manual.
+     <[phandle of the gpio controller node]
+      [pin number within the gpio controller]
+      [mux function]
+      [flags and pull up/down]
+      [drive strength]>
+
+  Values for gpio specifier:
+  - Pin number: is a value between 0 to 7.
+  - Flags and Pull Up/Down: 0 - Pull Up/Down Disabled.
+                            1 - Pull Down Enabled.
+                            3 - Pull Up Enabled.
+          Bit 16 (0x00010000) - Input is active low.
+  - Drive Strength: 0 - 1x,
+                    1 - 3x,
+                    2 - 2x,
+                    3 - 4x
+
+- gpio-controller: Specifies that the node is a gpio controller.
+- #address-cells: should be 1.
+- #size-cells: should be 1.
+
+Example:
+
+       gpa0: gpio-controller@11400000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "samsung,exynos4-gpio";
+               reg = <0x11400000 0x20>;
+               #gpio-cells = <4>;
+               gpio-controller;
+       };
diff --git a/doc/device-tree-bindings/gpio/gpio.txt b/doc/device-tree-bindings/gpio/gpio.txt
new file mode 100644 (file)
index 0000000..b9bd1d6
--- /dev/null
@@ -0,0 +1,211 @@
+Specifying GPIO information for devices
+============================================
+
+1) gpios property
+-----------------
+
+Nodes that makes use of GPIOs should specify them using one or more
+properties, each containing a 'gpio-list':
+
+       gpio-list ::= <single-gpio> [gpio-list]
+       single-gpio ::= <gpio-phandle> <gpio-specifier>
+       gpio-phandle : phandle to gpio controller node
+       gpio-specifier : Array of #gpio-cells specifying specific gpio
+                        (controller specific)
+
+GPIO properties should be named "[<name>-]gpios", with <name> being the purpose
+of this GPIO for the device. While a non-existent <name> is considered valid
+for compatibility reasons (resolving to the "gpios" property), it is not allowed
+for new bindings.
+
+GPIO properties can contain one or more GPIO phandles, but only in exceptional
+cases should they contain more than one. If your device uses several GPIOs with
+distinct functions, reference each of them under its own property, giving it a
+meaningful name. The only case where an array of GPIOs is accepted is when
+several GPIOs serve the same function (e.g. a parallel data line).
+
+The exact purpose of each gpios property must be documented in the device tree
+binding of the device.
+
+The following example could be used to describe GPIO pins used as device enable
+and bit-banged data signals:
+
+       gpio1: gpio1 {
+               gpio-controller
+                #gpio-cells = <2>;
+       };
+       gpio2: gpio2 {
+               gpio-controller
+                #gpio-cells = <1>;
+       };
+       [...]
+
+       enable-gpios = <&gpio2 2>;
+       data-gpios = <&gpio1 12 0>,
+                    <&gpio1 13 0>,
+                    <&gpio1 14 0>,
+                    <&gpio1 15 0>;
+
+Note that gpio-specifier length is controller dependent.  In the
+above example, &gpio1 uses 2 cells to specify a gpio, while &gpio2
+only uses one.
+
+gpio-specifier may encode: bank, pin position inside the bank,
+whether pin is open-drain and whether pin is logically inverted.
+Exact meaning of each specifier cell is controller specific, and must
+be documented in the device tree binding for the device. Use the macros
+defined in include/dt-bindings/gpio/gpio.h whenever possible:
+
+Example of a node using GPIOs:
+
+       node {
+               enable-gpios = <&qe_pio_e 18 GPIO_ACTIVE_HIGH>;
+       };
+
+GPIO_ACTIVE_HIGH is 0, so in this example gpio-specifier is "18 0" and encodes
+GPIO pin number, and GPIO flags as accepted by the "qe_pio_e" gpio-controller.
+
+1.1) GPIO specifier best practices
+----------------------------------
+
+A gpio-specifier should contain a flag indicating the GPIO polarity; active-
+high or active-low. If it does, the follow best practices should be followed:
+
+The gpio-specifier's polarity flag should represent the physical level at the
+GPIO controller that achieves (or represents, for inputs) a logically asserted
+value at the device. The exact definition of logically asserted should be
+defined by the binding for the device. If the board inverts the signal between
+the GPIO controller and the device, then the gpio-specifier will represent the
+opposite physical level than the signal at the device's pin.
+
+When the device's signal polarity is configurable, the binding for the
+device must either:
+
+a) Define a single static polarity for the signal, with the expectation that
+any software using that binding would statically program the device to use
+that signal polarity.
+
+The static choice of polarity may be either:
+
+a1) (Preferred) Dictated by a binding-specific DT property.
+
+or:
+
+a2) Defined statically by the DT binding itself.
+
+In particular, the polarity cannot be derived from the gpio-specifier, since
+that would prevent the DT from separately representing the two orthogonal
+concepts of configurable signal polarity in the device, and possible board-
+level signal inversion.
+
+or:
+
+b) Pick a single option for device signal polarity, and document this choice
+in the binding. The gpio-specifier should represent the polarity of the signal
+(at the GPIO controller) assuming that the device is configured for this
+particular signal polarity choice. If software chooses to program the device
+to generate or receive a signal of the opposite polarity, software will be
+responsible for correctly interpreting (inverting) the GPIO signal at the GPIO
+controller.
+
+2) gpio-controller nodes
+------------------------
+
+Every GPIO controller node must contain both an empty "gpio-controller"
+property, and a #gpio-cells integer property, which indicates the number of
+cells in a gpio-specifier.
+
+Example of two SOC GPIO banks defined as gpio-controller nodes:
+
+       qe_pio_a: gpio-controller@1400 {
+               compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank";
+               reg = <0x1400 0x18>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       qe_pio_e: gpio-controller@1460 {
+               compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank";
+               reg = <0x1460 0x18>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+2.1) gpio- and pin-controller interaction
+-----------------------------------------
+
+Some or all of the GPIOs provided by a GPIO controller may be routed to pins
+on the package via a pin controller. This allows muxing those pins between
+GPIO and other functions.
+
+It is useful to represent which GPIOs correspond to which pins on which pin
+controllers. The gpio-ranges property described below represents this, and
+contains information structures as follows:
+
+       gpio-range-list ::= <single-gpio-range> [gpio-range-list]
+       single-gpio-range ::= <numeric-gpio-range> | <named-gpio-range>
+       numeric-gpio-range ::=
+                       <pinctrl-phandle> <gpio-base> <pinctrl-base> <count>
+       named-gpio-range ::= <pinctrl-phandle> <gpio-base> '<0 0>'
+       gpio-phandle : phandle to pin controller node.
+       gpio-base : Base GPIO ID in the GPIO controller
+       pinctrl-base : Base pinctrl pin ID in the pin controller
+       count : The number of GPIOs/pins in this range
+
+The "pin controller node" mentioned above must conform to the bindings
+described in ../pinctrl/pinctrl-bindings.txt.
+
+In case named gpio ranges are used (ranges with both <pinctrl-base> and
+<count> set to 0), the property gpio-ranges-group-names contains one string
+for every single-gpio-range in gpio-ranges:
+       gpiorange-names-list ::= <gpiorange-name> [gpiorange-names-list]
+       gpiorange-name : Name of the pingroup associated to the GPIO range in
+                       the respective pin controller.
+
+Elements of gpiorange-names-list corresponding to numeric ranges contain
+the empty string. Elements of gpiorange-names-list corresponding to named
+ranges contain the name of a pin group defined in the respective pin
+controller. The number of pins/GPIOs in the range is the number of pins in
+that pin group.
+
+Previous versions of this binding required all pin controller nodes that
+were referenced by any gpio-ranges property to contain a property named
+#gpio-range-cells with value <3>. This requirement is now deprecated.
+However, that property may still exist in older device trees for
+compatibility reasons, and would still be required even in new device
+trees that need to be compatible with older software.
+
+Example 1:
+
+       qe_pio_e: gpio-controller@1460 {
+               #gpio-cells = <2>;
+               compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank";
+               reg = <0x1460 0x18>;
+               gpio-controller;
+               gpio-ranges = <&pinctrl1 0 20 10>, <&pinctrl2 10 50 20>;
+       };
+
+Here, a single GPIO controller has GPIOs 0..9 routed to pin controller
+pinctrl1's pins 20..29, and GPIOs 10..19 routed to pin controller pinctrl2's
+pins 50..59.
+
+Example 2:
+
+       gpio_pio_i: gpio-controller@14B0 {
+               #gpio-cells = <2>;
+               compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank";
+               reg = <0x1480 0x18>;
+               gpio-controller;
+               gpio-ranges =                   <&pinctrl1 0 20 10>,
+                                               <&pinctrl2 10 0 0>,
+                                               <&pinctrl1 15 0 10>,
+                                               <&pinctrl2 25 0 0>;
+               gpio-ranges-group-names =       "",
+                                               "foo",
+                                               "",
+                                               "bar";
+       };
+
+Here, three GPIO ranges are defined wrt. two pin controllers. pinctrl1 GPIO
+ranges are defined using pin numbers whereas the GPIO ranges wrt. pinctrl2
+are named "foo" and "bar".
diff --git a/doc/device-tree-bindings/gpio/nvidia,tegra20-gpio.txt b/doc/device-tree-bindings/gpio/nvidia,tegra20-gpio.txt
new file mode 100644 (file)
index 0000000..023c952
--- /dev/null
@@ -0,0 +1,40 @@
+NVIDIA Tegra GPIO controller
+
+Required properties:
+- compatible : "nvidia,tegra<chip>-gpio"
+- reg : Physical base address and length of the controller's registers.
+- interrupts : The interrupt outputs from the controller. For Tegra20,
+  there should be 7 interrupts specified, and for Tegra30, there should
+  be 8 interrupts specified.
+- #gpio-cells : Should be two. The first cell is the pin number and the
+  second cell is used to specify optional parameters:
+  - bit 0 specifies polarity (0 for normal, 1 for inverted)
+- gpio-controller : Marks the device node as a GPIO controller.
+- #interrupt-cells : Should be 2.
+  The first cell is the GPIO number.
+  The second cell is used to specify flags:
+    bits[3:0] trigger type and level flags:
+      1 = low-to-high edge triggered.
+      2 = high-to-low edge triggered.
+      4 = active high level-sensitive.
+      8 = active low level-sensitive.
+      Valid combinations are 1, 2, 3, 4, 8.
+- interrupt-controller : Marks the device node as an interrupt controller.
+
+Example:
+
+gpio: gpio@6000d000 {
+       compatible = "nvidia,tegra20-gpio";
+       reg = < 0x6000d000 0x1000 >;
+       interrupts = < 0 32 0x04
+                      0 33 0x04
+                      0 34 0x04
+                      0 35 0x04
+                      0 55 0x04
+                      0 87 0x04
+                      0 89 0x04 >;
+       #gpio-cells = <2>;
+       gpio-controller;
+       #interrupt-cells = <2>;
+       interrupt-controller;
+};
diff --git a/doc/device-tree-bindings/i2c/i2c.txt b/doc/device-tree-bindings/i2c/i2c.txt
new file mode 100644 (file)
index 0000000..ea918dd
--- /dev/null
@@ -0,0 +1,28 @@
+U-Boot I2C
+----------
+
+U-Boot's I2C model has the concept of an offset within a chip (I2C target
+device). The offset can be up to 4 bytes long, but is normally 1 byte,
+meaning that offsets from 0 to 255 are supported by the chip. This often
+corresponds to register numbers.
+
+Apart from the controller-specific I2C bindings, U-Boot supports a special
+property which allows the chip offset length to be selected.
+
+Optional properties:
+- u-boot,i2c-offset-len - length of chip offset in bytes. If omitted the
+    default value of 1 is used.
+
+
+Example
+-------
+
+i2c4: i2c@12ca0000 {
+       cros-ec@1e {
+               reg = <0x1e>;
+               compatible = "google,cros-ec";
+               i2c-max-frequency = <100000>;
+               u-boot,i2c-offset-len = <0>;
+               ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>;
+       };
+};
index eafa825ab44a00969f27dd805a4a504b59b74720..f83264d615da5390d34ed52b0a2394f6d2a6fcf6 100644 (file)
@@ -363,6 +363,10 @@ can leave out platdata_auto_alloc_size. In this case you can use malloc
 in your ofdata_to_platdata (or probe) method to allocate the required memory,
 and you should free it in the remove method.
 
+The driver model tree is intended to mirror that of the device tree. The
+root driver is at device tree offset 0 (the root node, '/'), and its
+children are the children of the root node.
+
 
 Declaring Uclasses
 ------------------
@@ -384,12 +388,12 @@ Device Sequence Numbers
 U-Boot numbers devices from 0 in many situations, such as in the command
 line for I2C and SPI buses, and the device names for serial ports (serial0,
 serial1, ...). Driver model supports this numbering and permits devices
-to be locating by their 'sequence'. This numbering unique identifies a
+to be locating by their 'sequence'. This numbering uniquely identifies a
 device in its uclass, so no two devices within a particular uclass can have
 the same sequence number.
 
 Sequence numbers start from 0 but gaps are permitted. For example, a board
-may have I2C buses 0, 1, 4, 5 but no 2 or 3. The choice of how devices are
+may have I2C buses 1, 4, 5 but no 0, 2 or 3. The choice of how devices are
 numbered is up to a particular board, and may be set by the SoC in some
 cases. While it might be tempting to automatically renumber the devices
 where there are gaps in the sequence, this can lead to confusion and is
@@ -399,7 +403,7 @@ Each device can request a sequence number. If none is required then the
 device will be automatically allocated the next available sequence number.
 
 To specify the sequence number in the device tree an alias is typically
-used.
+used. Make sure that the uclass has the DM_UC_FLAG_SEQ_ALIAS flag set.
 
 aliases {
        serial2 = "/serial@22230000";
@@ -409,43 +413,18 @@ This indicates that in the uclass called "serial", the named node
 ("/serial@22230000") will be given sequence number 2. Any command or driver
 which requests serial device 2 will obtain this device.
 
-Some devices represent buses where the devices on the bus are numbered or
-addressed. For example, SPI typically numbers its slaves from 0, and I2C
-uses a 7-bit address. In these cases the 'reg' property of the subnode is
-used, for example:
-
-{
-       aliases {
-               spi2 = "/spi@22300000";
-       };
-
-       spi@22300000 {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               spi-flash@0 {
-                       reg = <0>;
-                       ...
-               }
-               eeprom@1 {
-                       reg = <1>;
-               };
-       };
-
-In this case we have a SPI bus with two slaves at 0 and 1. The SPI bus
-itself is numbered 2. So we might access the SPI flash with:
-
-       sf probe 2:0
+More commonly you can use node references, which expand to the full path:
 
-and the eeprom with
-
-       sspi 2:1 32 ef
-
-These commands simply need to look up the 2nd device in the SPI uclass to
-find the right SPI bus. Then, they look at the children of that bus for the
-right sequence number (0 or 1 in this case).
+aliases {
+       serial2 = &serial_2;
+};
+...
+serial_2: serial@22230000 {
+...
+};
 
-Typically the alias method is used for top-level nodes and the 'reg' method
-is used only for buses.
+The alias resolves to the same string in this case, but this version is
+easier to read.
 
 Device sequence numbers are resolved when a device is probed. Before then
 the sequence number is only a request which may or may not be honoured,
@@ -462,11 +441,18 @@ access to other devices. Example of buses include SPI and I2C. Typically
 the bus provides some sort of transport or translation that makes it
 possible to talk to the devices on the bus.
 
-Driver model provides a few useful features to help with implementing
-buses. Firstly, a bus can request that its children store some 'parent
-data' which can be used to keep track of child state. Secondly, the bus can
-define methods which are called when a child is probed or removed. This is
-similar to the methods the uclass driver provides.
+Driver model provides some useful features to help with implementing buses.
+Firstly, a bus can request that its children store some 'parent data' which
+can be used to keep track of child state. Secondly, the bus can define
+methods which are called when a child is probed or removed. This is similar
+to the methods the uclass driver provides. Thirdly, per-child platform data
+can be provided to specify things like the child's address on the bus. This
+persists across child probe()/remove() cycles.
+
+For consistency and ease of implementation, the bus uclass can specify the
+per-child platform data, so that it can be the same for all children of buses
+in that uclass. There are also uclass methods which can be called when
+children are bound and probed.
 
 Here an explanation of how a bus fits with a uclass may be useful. Consider
 a USB bus with several devices attached to it, each from a different (made
@@ -481,15 +467,23 @@ Each of the devices is connected to a different address on the USB bus.
 The bus device wants to store this address and some other information such
 as the bus speed for each device.
 
-To achieve this, the bus device can use dev->parent_priv in each of its
-three children. This can be auto-allocated if the bus driver has a non-zero
-value for per_child_auto_alloc_size. If not, then the bus device can
-allocate the space itself before the child device is probed.
+To achieve this, the bus device can use dev->parent_platdata in each of its
+three children. This can be auto-allocated if the bus driver (or bus uclass)
+has a non-zero value for per_child_platdata_auto_alloc_size. If not, then
+the bus device or uclass can allocate the space itself before the child
+device is probed.
 
 Also the bus driver can define the child_pre_probe() and child_post_remove()
 methods to allow it to do some processing before the child is activated or
 after it is deactivated.
 
+Similarly the bus uclass can define the child_post_bind() method to obtain
+the per-child platform data from the device tree and set it up for the child.
+The bus uclass can also provide a child_pre_probe() method. Very often it is
+the bus uclass that controls these features, since it avoids each driver
+having to do the same processing. Of course the driver can still tweak and
+override these activities.
+
 Note that the information that controls this behaviour is in the bus's
 driver, not the child's. In fact it is possible that child has no knowledge
 that it is connected to a bus. The same child device may even be used on two
@@ -516,7 +510,8 @@ bus device, regardless of its own views on the matter.
 The uclass for the device can also contain data private to that uclass.
 But note that each device on the bus may be a memeber of a different
 uclass, and this data has nothing to do with the child data for each child
-on the bus.
+on the bus. It is the bus' uclass that controls the child with respect to
+the bus.
 
 
 Driver Lifecycle
index 719dbd5cdd24e9156769d9be6c1adf747d623964..5bc29ad65ce145b7dbea4fb7fbd4928e8b7395e6 100644 (file)
@@ -3,7 +3,8 @@ How to port a SPI driver to driver model
 
 Here is a rough step-by-step guide. It is based around converting the
 exynos SPI driver to driver model (DM) and the example code is based
-around U-Boot v2014.10-rc2 (commit be9f643).
+around U-Boot v2014.10-rc2 (commit be9f643). This has been updated for
+v2015.04.
 
 It is quite long since it includes actual code examples.
 
@@ -262,8 +263,8 @@ U_BOOT_DEVICE(board_spi0) = {
        .platdata = &platdata_spi0,
 };
 
-You will unfortunately need to put the struct into a header file in this
-case so that your board file can use it.
+You will unfortunately need to put the struct definition into a header file
+in this case so that your board file can use it.
 
 
 9. Add the device private data
@@ -592,3 +593,36 @@ board.
 
 You can use 'tools/patman/patman' to prepare, check and send patches for
 your work. See the README for details.
+
+20. A little note about SPI uclass features:
+
+The SPI uclass keeps some information about each device 'dev' on the bus:
+
+   struct dm_spi_slave_platdata - this is device_get_parent_platdata(dev)
+               This is where the chip select number is stored, along with
+               the default bus speed and mode. It is automatically read
+               from the device tree in spi_child_post_bind(). It must not
+               be changed at run-time after being set up because platform
+               data is supposed to be immutable at run-time.
+   struct spi_slave - this is device_get_parentdata(dev)
+               Already mentioned above. It holds run-time information about
+               the device.
+
+There are also some SPI uclass methods that get called behind the scenes:
+
+   spi_post_bind() - called when a new bus is bound
+               This scans the device tree for devices on the bus, and binds
+               each one. This in turn causes spi_child_post_bind() to be
+               called for each, which reads the device tree information
+               into the parent (per-child) platform data.
+   spi_child_post_bind() - called when a new child is bound
+               As mentioned above this reads the device tree information
+               into the per-child platform data
+   spi_child_pre_probe() - called before a new child is probed
+               This sets up the mode and speed in struct spi_slave by
+               copying it from the parent's platform data for this child.
+               It also sets the 'dev' pointer, needed to permit passing
+               'struct spi_slave' around the place without needing a
+               separate 'struct udevice' pointer.
+
+The above housekeeping makes it easier to write your SPI driver.
index b47ce73b8323a4034bbd58c77ce50d49f5492b38..427ea498b498793f3af51bdad51dbf3ab351349c 100644 (file)
@@ -159,17 +159,17 @@ the '/images' node should have the following layout:
   - description : Textual description of the component sub-image
   - type : Name of component sub-image type, supported types are:
     "standalone", "kernel", "ramdisk", "firmware", "script", "filesystem",
-    "flat_dt" and others (see uimage_type in common/images.c).
+    "flat_dt" and others (see uimage_type in common/image.c).
   - data : Path to the external file which contains this node's binary data.
   - compression : Compression used by included data. Supported compressions
     are "gzip" and "bzip2". If no compression is used compression property
     should be set to "none".
 
   Conditionally mandatory property:
-  - os : OS name, mandatory for type="kernel", valid OS names are: "openbsd",
-    "netbsd", "freebsd", "4_4bsd", "linux", "svr4", "esix", "solaris", "irix",
-    "sco", "dell", "ncr", "lynxos", "vxworks", "psos", "qnx", "u_boot",
-    "rtems", "unity", "integrity".
+  - os : OS name, mandatory for types "kernel" and "ramdisk". Valid OS names
+    are: "openbsd", "netbsd", "freebsd", "4_4bsd", "linux", "svr4", "esix",
+    "solaris", "irix", "sco", "dell", "ncr", "lynxos", "vxworks", "psos", "qnx",
+    "u_boot", "rtems", "unity", "integrity".
   - arch : Architecture name, mandatory for types: "standalone", "kernel",
     "firmware", "ramdisk" and "fdt". Valid architecture names are: "alpha",
     "arm", "i386", "ia64", "mips", "mips64", "ppc", "s390", "sh", "sparc",
index 3c83fbc2c16744c2387e3c4271971b14489aa124..e639e7ae71a1e6bbe0f421630959369ec15fcf3a 100644 (file)
@@ -64,7 +64,7 @@ software from updatable memory.
 
 It is critical that the public key be secure and cannot be tampered with.
 It can be stored in read-only memory, or perhaps protected by other on-chip
-crypto provided by some modern SOCs. If the public key can ben changed, then
+crypto provided by some modern SOCs. If the public key can be changed, then
 the verification is worthless.
 
 
@@ -87,7 +87,7 @@ affect the whole change.
 
 Flattened Image Tree (FIT)
 --------------------------
-The FIT format is alreay widely used in U-Boot. It is a flattened device
+The FIT format is already widely used in U-Boot. It is a flattened device
 tree (FDT) in a particular format, with images contained within. FITs
 include hashes to verify images, so it is relatively straightforward to
 add signatures as well.
index 8fc6b7108427add4a2f8f3a1047eee7e5e440073..3a5f48df7a27511a5bf9231e547360f11facdd7b 100644 (file)
@@ -88,6 +88,14 @@ int device_unbind(struct udevice *dev)
        if (ret)
                return ret;
 
+       if (dev->flags & DM_FLAG_ALLOC_PDATA) {
+               free(dev->platdata);
+               dev->platdata = NULL;
+       }
+       if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) {
+               free(dev->parent_platdata);
+               dev->parent_platdata = NULL;
+       }
        ret = uclass_unbind_device(dev);
        if (ret)
                return ret;
@@ -111,10 +119,6 @@ void device_free(struct udevice *dev)
                free(dev->priv);
                dev->priv = NULL;
        }
-       if (dev->flags & DM_FLAG_ALLOC_PDATA) {
-               free(dev->platdata);
-               dev->platdata = NULL;
-       }
        size = dev->uclass->uc_drv->per_device_auto_alloc_size;
        if (size) {
                free(dev->uclass_priv);
@@ -122,6 +126,10 @@ void device_free(struct udevice *dev)
        }
        if (dev->parent) {
                size = dev->parent->driver->per_child_auto_alloc_size;
+               if (!size) {
+                       size = dev->parent->uclass->uc_drv->
+                                       per_child_auto_alloc_size;
+               }
                if (size) {
                        free(dev->parent_priv);
                        dev->parent_priv = NULL;
index 963b16f26f0dc015a7f676891e0d845b42ec6594..b73d3b8961de337c1ec871d3d4ed2c1b24285e59 100644 (file)
@@ -53,27 +53,47 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name,
        dev->driver = drv;
        dev->uclass = uc;
 
-       /*
-        * For some devices, such as a SPI or I2C bus, the 'reg' property
-        * is a reasonable indicator of the sequence number. But if there is
-        * an alias, we use that in preference. In any case, this is just
-        * a 'requested' sequence, and will be resolved (and ->seq updated)
-        * when the device is probed.
-        */
        dev->seq = -1;
+       dev->req_seq = -1;
 #ifdef CONFIG_OF_CONTROL
-       dev->req_seq = fdtdec_get_int(gd->fdt_blob, of_offset, "reg", -1);
-       if (!IS_ERR_VALUE(dev->req_seq))
-               dev->req_seq &= INT_MAX;
-       if (uc->uc_drv->name && of_offset != -1) {
-               fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name, of_offset,
-                                    &dev->req_seq);
+       /*
+        * Some devices, such as a SPI bus, I2C bus and serial ports are
+        * numbered using aliases.
+        *
+        * This is just a 'requested' sequence, and will be
+        * resolved (and ->seq updated) when the device is probed.
+        */
+       if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) {
+               if (uc->uc_drv->name && of_offset != -1) {
+                       fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name,
+                                            of_offset, &dev->req_seq);
+               }
        }
-#else
-       dev->req_seq = -1;
 #endif
-       if (!dev->platdata && drv->platdata_auto_alloc_size)
+       if (!dev->platdata && drv->platdata_auto_alloc_size) {
                dev->flags |= DM_FLAG_ALLOC_PDATA;
+               dev->platdata = calloc(1, drv->platdata_auto_alloc_size);
+               if (!dev->platdata) {
+                       ret = -ENOMEM;
+                       goto fail_alloc1;
+               }
+       }
+       if (parent) {
+               int size = parent->driver->per_child_platdata_auto_alloc_size;
+
+               if (!size) {
+                       size = parent->uclass->uc_drv->
+                                       per_child_platdata_auto_alloc_size;
+               }
+               if (size) {
+                       dev->flags |= DM_FLAG_ALLOC_PARENT_PDATA;
+                       dev->parent_platdata = calloc(1, size);
+                       if (!dev->parent_platdata) {
+                               ret = -ENOMEM;
+                               goto fail_alloc2;
+                       }
+               }
+       }
 
        /* put dev into parent's successor list */
        if (parent)
@@ -81,28 +101,51 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name,
 
        ret = uclass_bind_device(dev);
        if (ret)
-               goto fail_bind;
+               goto fail_uclass_bind;
 
        /* if we fail to bind we remove device from successors and free it */
        if (drv->bind) {
                ret = drv->bind(dev);
-               if (ret) {
-                       if (uclass_unbind_device(dev)) {
-                               dm_warn("Failed to unbind dev '%s' on error path\n",
-                                       dev->name);
-                       }
+               if (ret)
                        goto fail_bind;
-               }
        }
+       if (parent && parent->driver->child_post_bind) {
+               ret = parent->driver->child_post_bind(dev);
+               if (ret)
+                       goto fail_child_post_bind;
+       }
+
        if (parent)
                dm_dbg("Bound device %s to %s\n", dev->name, parent->name);
        *devp = dev;
 
        return 0;
 
+fail_child_post_bind:
+       if (drv->unbind && drv->unbind(dev)) {
+               dm_warn("unbind() method failed on dev '%s' on error path\n",
+                       dev->name);
+       }
+
 fail_bind:
+       if (uclass_unbind_device(dev)) {
+               dm_warn("Failed to unbind dev '%s' on error path\n",
+                       dev->name);
+       }
+fail_uclass_bind:
        list_del(&dev->sibling_node);
+       if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) {
+               free(dev->parent_platdata);
+               dev->parent_platdata = NULL;
+       }
+fail_alloc2:
+       if (dev->flags & DM_FLAG_ALLOC_PDATA) {
+               free(dev->platdata);
+               dev->platdata = NULL;
+       }
+fail_alloc1:
        free(dev);
+
        return ret;
 }
 
@@ -137,7 +180,7 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
        drv = dev->driver;
        assert(drv);
 
-       /* Allocate private data and platdata if requested */
+       /* Allocate private data if requested */
        if (drv->priv_auto_alloc_size) {
                dev->priv = calloc(1, drv->priv_auto_alloc_size);
                if (!dev->priv) {
@@ -146,13 +189,6 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
                }
        }
        /* Allocate private data if requested */
-       if (dev->flags & DM_FLAG_ALLOC_PDATA) {
-               dev->platdata = calloc(1, drv->platdata_auto_alloc_size);
-               if (!dev->platdata) {
-                       ret = -ENOMEM;
-                       goto fail;
-               }
-       }
        size = dev->uclass->uc_drv->per_device_auto_alloc_size;
        if (size) {
                dev->uclass_priv = calloc(1, size);
@@ -165,6 +201,10 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
        /* Ensure all parents are probed */
        if (dev->parent) {
                size = dev->parent->driver->per_child_auto_alloc_size;
+               if (!size) {
+                       size = dev->parent->uclass->uc_drv->
+                                       per_child_auto_alloc_size;
+               }
                if (size) {
                        dev->parent_priv = calloc(1, size);
                        if (!dev->parent_priv) {
@@ -187,6 +227,10 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
        }
        dev->seq = seq;
 
+       ret = uclass_pre_probe_child(dev);
+       if (ret)
+               goto fail;
+
        if (dev->parent && dev->parent->driver->child_pre_probe) {
                ret = dev->parent->driver->child_pre_probe(dev);
                if (ret)
@@ -241,6 +285,16 @@ void *dev_get_platdata(struct udevice *dev)
        return dev->platdata;
 }
 
+void *dev_get_parent_platdata(struct udevice *dev)
+{
+       if (!dev) {
+               dm_warn("%s: null device", __func__);
+               return NULL;
+       }
+
+       return dev->parent_platdata;
+}
+
 void *dev_get_priv(struct udevice *dev)
 {
        if (!dev) {
@@ -390,3 +444,8 @@ ulong dev_get_of_data(struct udevice *dev)
 {
        return dev->of_id->data;
 }
+
+enum uclass_id device_get_uclass_id(struct udevice *dev)
+{
+       return dev->uclass->uc_drv->id;
+}
index 47b3acfbe981da9fcfe5ca6d7c20e60dd63b0285..73e3c7228e300e67da317098160d9c9c988446b3 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <common.h>
 #include <errno.h>
+#include <fdtdec.h>
 #include <malloc.h>
 #include <libfdt.h>
 #include <dm/device.h>
@@ -49,6 +50,9 @@ int dm_init(void)
        ret = device_bind_by_name(NULL, false, &root_info, &DM_ROOT_NON_CONST);
        if (ret)
                return ret;
+#ifdef CONFIG_OF_CONTROL
+       DM_ROOT_NON_CONST->of_offset = 0;
+#endif
        ret = device_probe(DM_ROOT_NON_CONST);
        if (ret)
                return ret;
@@ -89,6 +93,10 @@ int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset,
                if (pre_reloc_only &&
                    !fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL))
                        continue;
+               if (!fdtdec_get_is_enabled(blob, offset)) {
+                       dm_dbg("   - ignoring disabled device\n");
+                       continue;
+               }
                err = lists_bind_fdt(parent, blob, offset, NULL);
                if (err && !ret)
                        ret = err;
index 901b06ed2baaf5f4b0cbdb71d3ca40170de33991..289a5d2d53dfc7af75c19cc1dcc21aa88e8cd0cf 100644 (file)
@@ -319,18 +319,29 @@ int uclass_bind_device(struct udevice *dev)
        int ret;
 
        uc = dev->uclass;
-
        list_add_tail(&dev->uclass_node, &uc->dev_head);
 
+       if (dev->parent) {
+               struct uclass_driver *uc_drv = dev->parent->uclass->uc_drv;
+
+               if (uc_drv->child_post_bind) {
+                       ret = uc_drv->child_post_bind(dev);
+                       if (ret)
+                               goto err;
+               }
+       }
        if (uc->uc_drv->post_bind) {
                ret = uc->uc_drv->post_bind(dev);
-               if (ret) {
-                       list_del(&dev->uclass_node);
-                       return ret;
-               }
+               if (ret)
+                       goto err;
        }
 
        return 0;
+err:
+       /* There is no need to undo the parent's post_bind call */
+       list_del(&dev->uclass_node);
+
+       return ret;
 }
 
 int uclass_unbind_device(struct udevice *dev)
@@ -380,6 +391,19 @@ int uclass_resolve_seq(struct udevice *dev)
        return seq;
 }
 
+int uclass_pre_probe_child(struct udevice *dev)
+{
+       struct uclass_driver *uc_drv;
+
+       if (!dev->parent)
+               return 0;
+       uc_drv = dev->parent->uclass->uc_drv;
+       if (uc_drv->child_pre_probe)
+               return uc_drv->child_pre_probe(dev);
+
+       return 0;
+}
+
 int uclass_post_probe_device(struct udevice *dev)
 {
        struct uclass_driver *uc_drv = dev->uclass->uc_drv;
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..bd26a2bcfa286d9fd6b80b60cbd7ee9cc4c63ac8 100644 (file)
@@ -0,0 +1 @@
+source drivers/crypto/fsl/Kconfig
index 7b792371811eb37e7dadcf39310e65f955237678..fb8c10b38c2fd4537a1fa94dfc75faf737b5cfef 100644 (file)
@@ -6,4 +6,5 @@
 #
 
 obj-$(CONFIG_EXYNOS_ACE_SHA)   += ace_sha.o
+obj-y += rsa_mod_exp/
 obj-y += fsl/
diff --git a/drivers/crypto/fsl/Kconfig b/drivers/crypto/fsl/Kconfig
new file mode 100644 (file)
index 0000000..86b2f2f
--- /dev/null
@@ -0,0 +1,6 @@
+config FSL_CAAM
+       bool "Freescale Crypto Driver Support"
+       help
+         Enables the Freescale's Cryptographic Accelerator and Assurance
+         Module (CAAM), also known as the SEC version 4 (SEC4). The driver uses
+         Job Ring as interface to communicate with CAAM.
index 067d0a917ba6851f3d48ac7b428503d49252e994..c0cf64229ebe513688c6a85e61dac16689cdcb83 100644 (file)
@@ -9,3 +9,4 @@
 obj-y += sec.o
 obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
 obj-$(CONFIG_CMD_BLOB) += fsl_blob.o
+obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
diff --git a/drivers/crypto/fsl/fsl_rsa.c b/drivers/crypto/fsl/fsl_rsa.c
new file mode 100644 (file)
index 0000000..cf1c4c1
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * (C) Copyright 2014 Freescale Semiconductor, Inc.
+ * Author: Ruchika Gupta <ruchika.gupta@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <dm.h>
+#include <asm/types.h>
+#include <malloc.h>
+#include "jobdesc.h"
+#include "desc.h"
+#include "jr.h"
+#include "rsa_caam.h"
+#include <u-boot/rsa-mod-exp.h>
+
+int fsl_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
+               struct key_prop *prop, uint8_t *out)
+{
+       uint32_t keylen;
+       struct pk_in_params pkin;
+       uint32_t desc[MAX_CAAM_DESCSIZE];
+       int ret;
+
+       /* Length in bytes */
+       keylen = prop->num_bits / 8;
+
+       pkin.a = sig;
+       pkin.a_siz = sig_len;
+       pkin.n = prop->modulus;
+       pkin.n_siz = keylen;
+       pkin.e = prop->public_exponent;
+       pkin.e_siz = prop->exp_len;
+
+       inline_cnstr_jobdesc_pkha_rsaexp(desc, &pkin, out, sig_len);
+
+       ret = run_descriptor_jr(desc);
+       if (ret) {
+               debug("%s: RSA failed to verify: %d\n", __func__, ret);
+               return -EFAULT;
+       }
+
+       return 0;
+}
+
+static const struct mod_exp_ops fsl_mod_exp_ops = {
+       .mod_exp        = fsl_mod_exp,
+};
+
+U_BOOT_DRIVER(fsl_rsa_mod_exp) = {
+       .name   = "fsl_rsa_mod_exp",
+       .id     = UCLASS_MOD_EXP,
+       .ops    = &fsl_mod_exp_ops,
+};
+
+U_BOOT_DEVICE(fsl_rsa) = {
+       .name = "fsl_rsa_mod_exp",
+};
index 1386baec0fda45a54e7d9664a92cef90d3c6e150..cc0dcede7b787ed19cd815a2b73a18a5334f75cb 100644 (file)
@@ -11,6 +11,7 @@
 #include <common.h>
 #include "desc_constr.h"
 #include "jobdesc.h"
+#include "rsa_caam.h"
 
 #define KEY_BLOB_SIZE                  32
 #define MAC_SIZE                       16
@@ -123,3 +124,30 @@ void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc)
        append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
                         OP_ALG_RNG4_SK);
 }
+
+/* Change key size to bytes form bits in calling function*/
+void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
+                                     struct pk_in_params *pkin, uint8_t *out,
+                                     uint32_t out_siz)
+{
+       dma_addr_t dma_addr_e, dma_addr_a, dma_addr_n, dma_addr_out;
+
+       dma_addr_e = virt_to_phys((void *)pkin->e);
+       dma_addr_a = virt_to_phys((void *)pkin->a);
+       dma_addr_n = virt_to_phys((void *)pkin->n);
+       dma_addr_out = virt_to_phys((void *)out);
+
+       init_job_desc(desc, 0);
+       append_key(desc, dma_addr_e, pkin->e_siz, KEY_DEST_PKHA_E | CLASS_1);
+
+       append_fifo_load(desc, dma_addr_a,
+                        pkin->a_siz, LDST_CLASS_1_CCB | FIFOLD_TYPE_PK_A);
+
+       append_fifo_load(desc, dma_addr_n,
+                        pkin->n_siz, LDST_CLASS_1_CCB | FIFOLD_TYPE_PK_N);
+
+       append_operation(desc, OP_TYPE_PK | OP_ALG_PK | OP_ALG_PKMODE_MOD_EXPO);
+
+       append_fifo_store(desc, dma_addr_out, out_siz,
+                         LDST_CLASS_1_CCB | FIFOST_TYPE_PKHA_B);
+}
index 3cf7226de23b7d47ebfa8d7f4aad2a4af9eb40e5..84b3edd6e2f9ab5ad4b49e1da105143fc654400e 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include "rsa_caam.h"
 
 #define KEY_IDNFR_SZ_BYTES             16
 
@@ -26,4 +27,8 @@ void inline_cnstr_jobdesc_blob_decap(uint32_t *desc, uint8_t *key_idnfr,
                                     uint32_t out_sz);
 
 void inline_cnstr_jobdesc_rng_instantiation(uint32_t *desc);
+
+void inline_cnstr_jobdesc_pkha_rsaexp(uint32_t *desc,
+                                     struct pk_in_params *pkin, uint8_t *out,
+                                     uint32_t out_siz);
 #endif
diff --git a/drivers/crypto/fsl/rsa_caam.h b/drivers/crypto/fsl/rsa_caam.h
new file mode 100644 (file)
index 0000000..4ff87ef
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __RSA_CAAM_H
+#define __RSA_CAAM_H
+
+#include <common.h>
+
+/**
+ * struct pk_in_params - holder for input to PKHA block in CAAM
+ * These parameters are required to perform Modular Exponentiation
+ * using PKHA Block in CAAM
+ */
+struct pk_in_params {
+       const uint8_t *e;       /* public exponent as byte array */
+       uint32_t e_siz;         /* size of e[] in number of bytes */
+       const uint8_t *n;       /* modulus as byte array */
+       uint32_t n_siz;         /* size of n[] in number of bytes */
+       const uint8_t *a;               /* Signature as byte array */
+       uint32_t a_siz;         /* size of a[] in number of bytes */
+       uint8_t *b;             /* Result exp. modulus in number of bytes */
+       uint32_t b_siz;         /* size of b[] in number of bytes */
+};
+
+#endif
diff --git a/drivers/crypto/rsa_mod_exp/Kconfig b/drivers/crypto/rsa_mod_exp/Kconfig
new file mode 100644 (file)
index 0000000..6dcb39a
--- /dev/null
@@ -0,0 +1,5 @@
+config DM_MOD_EXP
+       bool "Enable Driver Model for RSA Modular Exponentiation"
+       depends on DM
+       help
+         If you want to use driver model for RSA Modular Exponentiation, say Y.
diff --git a/drivers/crypto/rsa_mod_exp/Makefile b/drivers/crypto/rsa_mod_exp/Makefile
new file mode 100644 (file)
index 0000000..915b751
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# (C) Copyright 2014 Freescale Semiconductor, Inc.
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-$(CONFIG_RSA) += mod_exp_uclass.o mod_exp_sw.o
diff --git a/drivers/crypto/rsa_mod_exp/mod_exp_sw.c b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c
new file mode 100644 (file)
index 0000000..dc6c064
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2014 Freescale Semiconductor, Inc.
+ * Author: Ruchika Gupta <ruchika.gupta@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <dm.h>
+#include <u-boot/rsa-mod-exp.h>
+
+int mod_exp_sw(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
+               struct key_prop *prop, uint8_t *out)
+{
+       int ret = 0;
+
+       ret = rsa_mod_exp_sw(sig, sig_len, prop, out);
+       if (ret) {
+               debug("%s: RSA failed to verify: %d\n", __func__, ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static const struct mod_exp_ops mod_exp_ops_sw = {
+       .mod_exp        = mod_exp_sw,
+};
+
+U_BOOT_DRIVER(mod_exp_sw) = {
+       .name   = "mod_exp_sw",
+       .id     = UCLASS_MOD_EXP,
+       .ops    = &mod_exp_ops_sw,
+};
+
+U_BOOT_DEVICE(mod_exp_sw) = {
+       .name = "mod_exp_sw",
+};
diff --git a/drivers/crypto/rsa_mod_exp/mod_exp_uclass.c b/drivers/crypto/rsa_mod_exp/mod_exp_uclass.c
new file mode 100644 (file)
index 0000000..266f094
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * (C) Copyright 2014 Freescale Semiconductor, Inc
+ * Author: Ruchika Gupta <ruchika.gupta@freescale.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <u-boot/rsa-mod-exp.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <linux/list.h>
+
+int rsa_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
+               struct key_prop *node, uint8_t *out)
+{
+       const struct mod_exp_ops *ops = device_get_ops(dev);
+
+       if (!ops->mod_exp)
+               return -ENOSYS;
+
+       return ops->mod_exp(dev, sig, sig_len, node, out);
+}
+
+UCLASS_DRIVER(mod_exp) = {
+       .id             = UCLASS_MOD_EXP,
+       .name           = "rsa_mod_exp",
+};
index 3fa9c5994703d473494a4d2199ecae3e34a0c9c0..d908736cffe31e2acb1bfa787bc12b05265543b7 100644 (file)
@@ -11,6 +11,7 @@
 #include <malloc.h>
 #include <dm-demo.h>
 #include <asm/io.h>
+#include <asm/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -20,6 +21,8 @@ DECLARE_GLOBAL_DATA_PTR;
 
 struct shape_data {
        int num_chars;  /* Number of non-space characters output so far */
+       struct gpio_desc gpio_desc[8];
+       int gpio_count;
 };
 
 /* Crazy little function to draw shapes on the console */
@@ -89,9 +92,52 @@ static int shape_status(struct udevice *dev, int *status)
        return 0;
 }
 
+static int set_light(struct udevice *dev, int light)
+{
+       struct shape_data *priv = dev_get_priv(dev);
+       struct gpio_desc *desc;
+       int ret;
+       int i;
+
+       desc = priv->gpio_desc;
+       for (i = 0; i < priv->gpio_count; i++, desc++) {
+               uint mask = 1 << i;
+
+               ret = dm_gpio_set_value(desc, light & mask);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int get_light(struct udevice *dev)
+{
+       struct shape_data *priv = dev_get_priv(dev);
+       struct gpio_desc *desc;
+       uint value = 0;
+       int ret;
+       int i;
+
+       desc = priv->gpio_desc;
+       for (i = 0; i < priv->gpio_count; i++, desc++) {
+               uint mask = 1 << i;
+
+               ret = dm_gpio_get_value(desc);
+               if (ret < 0)
+                       return ret;
+               if (ret)
+                       value |= mask;
+       }
+
+       return value;
+}
+
 static const struct demo_ops shape_ops = {
        .hello = shape_hello,
        .status = shape_status,
+       .get_light = get_light,
+       .set_light = set_light,
 };
 
 static int shape_ofdata_to_platdata(struct udevice *dev)
@@ -111,6 +157,29 @@ static int shape_ofdata_to_platdata(struct udevice *dev)
        return 0;
 }
 
+static int dm_shape_probe(struct udevice *dev)
+{
+       struct shape_data *priv = dev_get_priv(dev);
+       int ret;
+
+       ret = gpio_request_list_by_name(dev, "light-gpios", priv->gpio_desc,
+                                       ARRAY_SIZE(priv->gpio_desc),
+                                       GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+       if (ret < 0)
+               return ret;
+       priv->gpio_count = ret;
+       debug("%s: %d GPIOs\n", __func__, priv->gpio_count);
+
+       return 0;
+}
+
+static int dm_shape_remove(struct udevice *dev)
+{
+       struct shape_data *priv = dev_get_priv(dev);
+
+       return gpio_free_list(dev, priv->gpio_desc, priv->gpio_count);
+}
+
 static const struct udevice_id demo_shape_id[] = {
        { "demo-shape", 0 },
        { },
@@ -122,6 +191,8 @@ U_BOOT_DRIVER(demo_shape_drv) = {
        .id     = UCLASS_DEMO,
        .ofdata_to_platdata = shape_ofdata_to_platdata,
        .ops    = &shape_ops,
+       .probe = dm_shape_probe,
+       .remove = dm_shape_remove,
        .priv_auto_alloc_size = sizeof(struct shape_data),
        .platdata_auto_alloc_size = sizeof(struct dm_demo_pdata),
 };
index f6510d602c83472695065b66c0f01e55f75b881b..725f06898f33deb8d7e827f016d1a63da90b71aa 100644 (file)
@@ -43,6 +43,26 @@ int demo_status(struct udevice *dev, int *status)
        return ops->status(dev, status);
 }
 
+int demo_get_light(struct udevice *dev)
+{
+       const struct demo_ops *ops = device_get_ops(dev);
+
+       if (!ops->get_light)
+               return -ENOSYS;
+
+       return ops->get_light(dev);
+}
+
+int demo_set_light(struct udevice *dev, int light)
+{
+       const struct demo_ops *ops = device_get_ops(dev);
+
+       if (!ops->set_light)
+               return -ENOSYS;
+
+       return ops->set_light(dev, light);
+}
+
 int demo_parse_dt(struct udevice *dev)
 {
        struct dm_demo_pdata *pdata = dev_get_platdata(dev);
index 255700ab18d2d93cf107fcbf3b5a10b2e66e855f..a69bbd2002e9f62c06f75cb1f1b4b755140eecc2 100644 (file)
@@ -7,20 +7,25 @@
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
+#include <fdtdec.h>
 #include <malloc.h>
 #include <asm/gpio.h>
 #include <linux/ctype.h>
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /**
  * gpio_to_device() - Convert global GPIO number to device, number
- * gpio:       The numeric representation of the GPIO
  *
  * Convert the GPIO number to an entry in the list of GPIOs
  * or GPIO blocks registered with the GPIO controller. Returns
  * entry on success, NULL on error.
+ *
+ * @gpio:      The numeric representation of the GPIO
+ * @desc:      Returns description (desc->flags will always be 0)
+ * @return 0 if found, -ENOENT if not found
  */
-static int gpio_to_device(unsigned int gpio, struct udevice **devp,
-                         unsigned int *offset)
+static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
 {
        struct gpio_dev_priv *uc_priv;
        struct udevice *dev;
@@ -32,14 +37,15 @@ static int gpio_to_device(unsigned int gpio, struct udevice **devp,
                uc_priv = dev->uclass_priv;
                if (gpio >= uc_priv->gpio_base &&
                    gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
-                       *devp = dev;
-                       *offset = gpio - uc_priv->gpio_base;
+                       desc->dev = dev;
+                       desc->offset = gpio - uc_priv->gpio_base;
+                       desc->flags = 0;
                        return 0;
                }
        }
 
        /* No such GPIO */
-       return ret ? ret : -EINVAL;
+       return ret ? ret : -ENOENT;
 }
 
 int gpio_lookup_name(const char *name, struct udevice **devp,
@@ -88,6 +94,57 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
        return 0;
 }
 
+static int gpio_find_and_xlate(struct gpio_desc *desc,
+                              struct fdtdec_phandle_args *args)
+{
+       struct dm_gpio_ops *ops = gpio_get_ops(desc->dev);
+
+       /* Use the first argument as the offset by default */
+       if (args->args_count > 0)
+               desc->offset = args->args[0];
+       else
+               desc->offset = -1;
+       desc->flags = 0;
+
+       return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0;
+}
+
+static int dm_gpio_request(struct gpio_desc *desc, const char *label)
+{
+       struct udevice *dev = desc->dev;
+       struct gpio_dev_priv *uc_priv;
+       char *str;
+       int ret;
+
+       uc_priv = dev->uclass_priv;
+       if (uc_priv->name[desc->offset])
+               return -EBUSY;
+       str = strdup(label);
+       if (!str)
+               return -ENOMEM;
+       if (gpio_get_ops(dev)->request) {
+               ret = gpio_get_ops(dev)->request(dev, desc->offset, label);
+               if (ret) {
+                       free(str);
+                       return ret;
+               }
+       }
+       uc_priv->name[desc->offset] = str;
+
+       return 0;
+}
+
+static int dm_gpio_requestf(struct gpio_desc *desc, const char *fmt, ...)
+{
+       va_list args;
+       char buf[40];
+
+       va_start(args, fmt);
+       vscnprintf(buf, sizeof(buf), fmt, args);
+       va_end(args);
+       return dm_gpio_request(desc, buf);
+}
+
 /**
  * gpio_request() - [COMPAT] Request GPIO
  * gpio:       GPIO number
@@ -102,32 +159,14 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
  */
 int gpio_request(unsigned gpio, const char *label)
 {
-       struct gpio_dev_priv *uc_priv;
-       unsigned int offset;
-       struct udevice *dev;
-       char *str;
+       struct gpio_desc desc;
        int ret;
 
-       ret = gpio_to_device(gpio, &dev, &offset);
+       ret = gpio_to_device(gpio, &desc);
        if (ret)
                return ret;
 
-       uc_priv = dev->uclass_priv;
-       if (uc_priv->name[offset])
-               return -EBUSY;
-       str = strdup(label);
-       if (!str)
-               return -ENOMEM;
-       if (gpio_get_ops(dev)->request) {
-               ret = gpio_get_ops(dev)->request(dev, offset, label);
-               if (ret) {
-                       free(str);
-                       return ret;
-               }
-       }
-       uc_priv->name[offset] = str;
-
-       return 0;
+       return dm_gpio_request(&desc, label);
 }
 
 /**
@@ -151,25 +190,11 @@ int gpio_requestf(unsigned gpio, const char *fmt, ...)
        return gpio_request(gpio, buf);
 }
 
-/**
- * gpio_free() - [COMPAT] Relinquish GPIO
- * gpio:       GPIO number
- *
- * This function implements the API that's compatible with current
- * GPIO API used in U-Boot. The request is forwarded to particular
- * GPIO driver. Returns 0 on success, negative value on error.
- */
-int gpio_free(unsigned gpio)
+int _dm_gpio_free(struct udevice *dev, uint offset)
 {
        struct gpio_dev_priv *uc_priv;
-       unsigned int offset;
-       struct udevice *dev;
        int ret;
 
-       ret = gpio_to_device(gpio, &dev, &offset);
-       if (ret)
-               return ret;
-
        uc_priv = dev->uclass_priv;
        if (!uc_priv->name[offset])
                return -ENXIO;
@@ -185,15 +210,35 @@ int gpio_free(unsigned gpio)
        return 0;
 }
 
-static int check_reserved(struct udevice *dev, unsigned offset,
-                         const char *func)
+/**
+ * gpio_free() - [COMPAT] Relinquish GPIO
+ * gpio:       GPIO number
+ *
+ * This function implements the API that's compatible with current
+ * GPIO API used in U-Boot. The request is forwarded to particular
+ * GPIO driver. Returns 0 on success, negative value on error.
+ */
+int gpio_free(unsigned gpio)
 {
-       struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+       struct gpio_desc desc;
+       int ret;
+
+       ret = gpio_to_device(gpio, &desc);
+       if (ret)
+               return ret;
+
+       return _dm_gpio_free(desc.dev, desc.offset);
+}
+
+static int check_reserved(struct gpio_desc *desc, const char *func)
+{
+       struct gpio_dev_priv *uc_priv = desc->dev->uclass_priv;
 
-       if (!uc_priv->name[offset]) {
+       if (!uc_priv->name[desc->offset]) {
                printf("%s: %s: error: gpio %s%d not reserved\n",
-                      dev->name, func,
-                      uc_priv->bank_name ? uc_priv->bank_name : "", offset);
+                      desc->dev->name, func,
+                      uc_priv->bank_name ? uc_priv->bank_name : "",
+                      desc->offset);
                return -EBUSY;
        }
 
@@ -210,16 +255,17 @@ static int check_reserved(struct udevice *dev, unsigned offset,
  */
 int gpio_direction_input(unsigned gpio)
 {
-       unsigned int offset;
-       struct udevice *dev;
+       struct gpio_desc desc;
        int ret;
 
-       ret = gpio_to_device(gpio, &dev, &offset);
+       ret = gpio_to_device(gpio, &desc);
+       if (ret)
+               return ret;
+       ret = check_reserved(&desc, "dir_input");
        if (ret)
                return ret;
-       ret = check_reserved(dev, offset, "dir_input");
 
-       return ret ? ret : gpio_get_ops(dev)->direction_input(dev, offset);
+       return gpio_get_ops(desc.dev)->direction_input(desc.dev, desc.offset);
 }
 
 /**
@@ -233,17 +279,81 @@ int gpio_direction_input(unsigned gpio)
  */
 int gpio_direction_output(unsigned gpio, int value)
 {
-       unsigned int offset;
-       struct udevice *dev;
+       struct gpio_desc desc;
+       int ret;
+
+       ret = gpio_to_device(gpio, &desc);
+       if (ret)
+               return ret;
+       ret = check_reserved(&desc, "dir_output");
+       if (ret)
+               return ret;
+
+       return gpio_get_ops(desc.dev)->direction_output(desc.dev,
+                                                       desc.offset, value);
+}
+
+int dm_gpio_get_value(struct gpio_desc *desc)
+{
+       int value;
+       int ret;
+
+       ret = check_reserved(desc, "get_value");
+       if (ret)
+               return ret;
+
+       value = gpio_get_ops(desc->dev)->get_value(desc->dev, desc->offset);
+
+       return desc->flags & GPIOD_ACTIVE_LOW ? !value : value;
+}
+
+int dm_gpio_set_value(struct gpio_desc *desc, int value)
+{
+       int ret;
+
+       ret = check_reserved(desc, "set_value");
+       if (ret)
+               return ret;
+
+       if (desc->flags & GPIOD_ACTIVE_LOW)
+               value = !value;
+       gpio_get_ops(desc->dev)->set_value(desc->dev, desc->offset, value);
+       return 0;
+}
+
+int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags)
+{
+       struct udevice *dev = desc->dev;
+       struct dm_gpio_ops *ops = gpio_get_ops(dev);
        int ret;
 
-       ret = gpio_to_device(gpio, &dev, &offset);
+       ret = check_reserved(desc, "set_dir");
+       if (ret)
+               return ret;
+
+       if (flags & GPIOD_IS_OUT) {
+               int value = flags & GPIOD_IS_OUT_ACTIVE ? 1 : 0;
+
+               if (flags & GPIOD_ACTIVE_LOW)
+                       value = !value;
+               ret = ops->direction_output(dev, desc->offset, value);
+       } else  if (flags & GPIOD_IS_IN) {
+               ret = ops->direction_input(dev, desc->offset);
+       }
        if (ret)
                return ret;
-       ret = check_reserved(dev, offset, "dir_output");
+       /*
+        * Update desc->flags here, so that GPIO_ACTIVE_LOW is honoured in
+        * futures
+        */
+       desc->flags = flags;
+
+       return 0;
+}
 
-       return ret ? ret :
-               gpio_get_ops(dev)->direction_output(dev, offset, value);
+int dm_gpio_set_dir(struct gpio_desc *desc)
+{
+       return dm_gpio_set_dir_flags(desc, desc->flags);
 }
 
 /**
@@ -257,16 +367,14 @@ int gpio_direction_output(unsigned gpio, int value)
  */
 int gpio_get_value(unsigned gpio)
 {
-       unsigned int offset;
-       struct udevice *dev;
        int ret;
 
-       ret = gpio_to_device(gpio, &dev, &offset);
+       struct gpio_desc desc;
+
+       ret = gpio_to_device(gpio, &desc);
        if (ret)
                return ret;
-       ret = check_reserved(dev, offset, "get_value");
-
-       return ret ? ret : gpio_get_ops(dev)->get_value(dev, offset);
+       return dm_gpio_get_value(&desc);
 }
 
 /**
@@ -280,16 +388,13 @@ int gpio_get_value(unsigned gpio)
  */
 int gpio_set_value(unsigned gpio, int value)
 {
-       unsigned int offset;
-       struct udevice *dev;
+       struct gpio_desc desc;
        int ret;
 
-       ret = gpio_to_device(gpio, &dev, &offset);
+       ret = gpio_to_device(gpio, &desc);
        if (ret)
                return ret;
-       ret = check_reserved(dev, offset, "set_value");
-
-       return ret ? ret : gpio_get_ops(dev)->set_value(dev, offset, value);
+       return dm_gpio_set_value(&desc, value);
 }
 
 const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
@@ -409,6 +514,155 @@ unsigned gpio_get_values_as_int(const int *gpio_num_array)
        return vector;
 }
 
+static int _gpio_request_by_name_nodev(const void *blob, int node,
+                                      const char *list_name, int index,
+                                      struct gpio_desc *desc, int flags,
+                                      bool add_index)
+{
+       struct fdtdec_phandle_args args;
+       int ret;
+
+       desc->dev = NULL;
+       desc->offset = 0;
+       ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
+                                            "#gpio-cells", 0, index, &args);
+       if (ret) {
+               debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__);
+               goto err;
+       }
+
+       ret = uclass_get_device_by_of_offset(UCLASS_GPIO, args.node,
+                                            &desc->dev);
+       if (ret) {
+               debug("%s: uclass_get_device_by_of_offset failed\n", __func__);
+               goto err;
+       }
+       ret = gpio_find_and_xlate(desc, &args);
+       if (ret) {
+               debug("%s: gpio_find_and_xlate failed\n", __func__);
+               goto err;
+       }
+       ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
+                              fdt_get_name(blob, node, NULL),
+                              list_name, index);
+       if (ret) {
+               debug("%s: dm_gpio_requestf failed\n", __func__);
+               goto err;
+       }
+       ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
+       if (ret) {
+               debug("%s: dm_gpio_set_dir failed\n", __func__);
+               goto err;
+       }
+
+       return 0;
+err:
+       debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
+             __func__, fdt_get_name(blob, node, NULL), list_name, index, ret);
+       return ret;
+}
+
+int gpio_request_by_name_nodev(const void *blob, int node,
+                              const char *list_name, int index,
+                              struct gpio_desc *desc, int flags)
+{
+       return _gpio_request_by_name_nodev(blob, node, list_name, index, desc,
+                                          flags, index > 0);
+}
+
+int gpio_request_by_name(struct udevice *dev,  const char *list_name, int index,
+                        struct gpio_desc *desc, int flags)
+{
+       /*
+        * This isn't ideal since we don't use dev->name in the debug()
+        * calls in gpio_request_by_name(), but we can do this until
+        * gpio_request_by_name_nodev() can be dropped.
+        */
+       return gpio_request_by_name_nodev(gd->fdt_blob, dev->of_offset,
+                                         list_name, index, desc, flags);
+}
+
+int gpio_request_list_by_name_nodev(const void *blob, int node,
+                                   const char *list_name,
+                                   struct gpio_desc *desc, int max_count,
+                                   int flags)
+{
+       int count;
+       int ret;
+
+       for (count = 0; ; count++) {
+               if (count >= max_count) {
+                       ret = -ENOSPC;
+                       goto err;
+               }
+               ret = _gpio_request_by_name_nodev(blob, node, list_name, count,
+                                                 &desc[count], flags, true);
+               if (ret == -ENOENT)
+                       break;
+               else if (ret)
+                       goto err;
+       }
+
+       /* We ran out of GPIOs in the list */
+       return count;
+
+err:
+       gpio_free_list_nodev(desc, count - 1);
+
+       return ret;
+}
+
+int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
+                             struct gpio_desc *desc, int max_count,
+                             int flags)
+{
+       /*
+        * This isn't ideal since we don't use dev->name in the debug()
+        * calls in gpio_request_by_name(), but we can do this until
+        * gpio_request_list_by_name_nodev() can be dropped.
+        */
+       return gpio_request_list_by_name_nodev(gd->fdt_blob, dev->of_offset,
+                                              list_name, desc, max_count,
+                                              flags);
+}
+
+int gpio_get_list_count(struct udevice *dev, const char *list_name)
+{
+       int ret;
+
+       ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
+                                            list_name, "#gpio-cells", 0, -1,
+                                            NULL);
+       if (ret) {
+               debug("%s: Node '%s', property '%s', GPIO count failed: %d\n",
+                     __func__, dev->name, list_name, ret);
+       }
+
+       return ret;
+}
+
+int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc)
+{
+       /* For now, we don't do any checking of dev */
+       return _dm_gpio_free(desc->dev, desc->offset);
+}
+
+int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count)
+{
+       int i;
+
+       /* For now, we don't do any checking of dev */
+       for (i = 0; i < count; i++)
+               dm_gpio_free(dev, &desc[i]);
+
+       return 0;
+}
+
+int gpio_free_list_nodev(struct gpio_desc *desc, int count)
+{
+       return gpio_free_list(NULL, desc, count);
+}
+
 /* We need to renumber the GPIOs when any driver is probed/removed */
 static int gpio_renumber(struct udevice *removed_dev)
 {
index 6c41a42c177351adcd0d6f96ff81ae2a0f1036ee..0a245ba18ad0eb42bdc6b67697dbdfa7fedd20a0 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/io.h>
 #include <asm/gpio.h>
 #include <dm/device-internal.h>
+#include <dt-bindings/gpio/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -275,12 +276,22 @@ static int exynos_gpio_get_function(struct udevice *dev, unsigned offset)
                return GPIOF_FUNC;
 }
 
+static int exynos_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
+                            struct fdtdec_phandle_args *args)
+{
+       desc->offset = args->args[0];
+       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
+
+       return 0;
+}
+
 static const struct dm_gpio_ops gpio_exynos_ops = {
        .direction_input        = exynos_gpio_direction_input,
        .direction_output       = exynos_gpio_direction_output,
        .get_value              = exynos_gpio_get_value,
        .set_value              = exynos_gpio_set_value,
        .get_function           = exynos_gpio_get_function,
+       .xlate                  = exynos_gpio_xlate,
 };
 
 static int gpio_exynos_probe(struct udevice *dev)
@@ -342,7 +353,7 @@ static int gpio_exynos_bind(struct udevice *parent)
                                        plat->bank_name, plat, -1, &dev);
                if (ret)
                        return ret;
-               dev->of_offset = parent->of_offset;
+               dev->of_offset = node;
        }
 
        return 0;
index 53c80d5be65dd85c0dbe20d2e1823e0400a4937f..d564c252c7d7336d9f5bcc93d9ac306bd42eb539 100644 (file)
@@ -8,6 +8,7 @@
 #include <fdtdec.h>
 #include <malloc.h>
 #include <asm/gpio.h>
+#include <dt-bindings/gpio/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -130,12 +131,31 @@ static int sb_gpio_get_function(struct udevice *dev, unsigned offset)
        return GPIOF_INPUT;
 }
 
+static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
+                        struct fdtdec_phandle_args *args)
+{
+       desc->offset = args->args[0];
+       if (args->args_count < 2)
+               return 0;
+       if (args->args[1] & GPIO_ACTIVE_LOW)
+               desc->flags |= GPIOD_ACTIVE_LOW;
+       if (args->args[1] & 2)
+               desc->flags |= GPIOD_IS_IN;
+       if (args->args[1] & 4)
+               desc->flags |= GPIOD_IS_OUT;
+       if (args->args[1] & 8)
+               desc->flags |= GPIOD_IS_OUT_ACTIVE;
+
+       return 0;
+}
+
 static const struct dm_gpio_ops gpio_sandbox_ops = {
        .direction_input        = sb_gpio_direction_input,
        .direction_output       = sb_gpio_direction_output,
        .get_value              = sb_gpio_get_value,
        .set_value              = sb_gpio_set_value,
        .get_function           = sb_gpio_get_function,
+       .xlate                  = sb_gpio_xlate,
 };
 
 static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
index 88f7ef5bf04d9abce9605cd7e8e161a11b135a8d..43928b8812c3aad0077b8beb4a837993c653ed59 100644 (file)
@@ -21,6 +21,7 @@
 #include <asm/arch/tegra.h>
 #include <asm/gpio.h>
 #include <dm/device-internal.h>
+#include <dt-bindings/gpio/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -251,6 +252,22 @@ static int tegra_gpio_get_function(struct udevice *dev, unsigned offset)
                return GPIOF_INPUT;
 }
 
+static int tegra_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
+                           struct fdtdec_phandle_args *args)
+{
+       int gpio, port, ret;
+
+       gpio = args->args[0];
+       port = gpio / TEGRA_GPIOS_PER_PORT;
+       ret = device_get_child(dev, port, &desc->dev);
+       if (ret)
+               return ret;
+       desc->offset = gpio % TEGRA_GPIOS_PER_PORT;
+       desc->flags = args->args[1] & GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0;
+
+       return 0;
+}
+
 static const struct dm_gpio_ops gpio_tegra_ops = {
        .request                = tegra_gpio_request,
        .direction_input        = tegra_gpio_direction_input,
@@ -258,6 +275,7 @@ static const struct dm_gpio_ops gpio_tegra_ops = {
        .get_value              = tegra_gpio_get_value,
        .set_value              = tegra_gpio_set_value,
        .get_function           = tegra_gpio_get_function,
+       .xlate                  = tegra_gpio_xlate,
 };
 
 /**
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..202ea5d67940ece1c555568794a7cfd343f0fc30 100644 (file)
@@ -0,0 +1,22 @@
+config DM_I2C
+       bool "Enable Driver Model for I2C drivers"
+       depends on DM
+       help
+         If you want to use driver model for I2C drivers, say Y.
+         To use legacy I2C drivers, say N.
+
+config SYS_I2C_UNIPHIER
+       bool "UniPhier I2C driver"
+       depends on ARCH_UNIPHIER && DM_I2C
+       default y
+       help
+         Support for Panasonic UniPhier I2C controller driver.  This I2C
+         controller is used on PH1-LD4, PH1-sLD8 or older UniPhier SoCs.
+
+config SYS_I2C_UNIPHIER_F
+       bool "UniPhier FIFO-builtin I2C driver"
+       depends on ARCH_UNIPHIER && DM_I2C
+       default y
+       help
+         Support for Panasonic UniPhier FIFO-builtin I2C controller driver.
+         This I2C controller is used on PH1-Pro4 or newer UniPhier SoCs.
index 6f3c86c03859171f940305801f564ff0c2b9e1cd..774bc94a4a7a864acfbdb6a8a5214f34637f7fe7 100644 (file)
@@ -5,6 +5,7 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 obj-$(CONFIG_DM_I2C) += i2c-uclass.o
+obj-$(CONFIG_DM_I2C_COMPAT) += i2c-uclass-compat.o
 
 obj-$(CONFIG_SYS_I2C_ADI) += adi_i2c.o
 obj-$(CONFIG_I2C_MV) += mv_i2c.o
@@ -31,4 +32,6 @@ obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o
 obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o
 obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o
 obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
+obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o
+obj-$(CONFIG_SYS_I2C_UNIPHIER_F) += i2c-uniphier-f.o
 obj-$(CONFIG_SYS_I2C_ZYNQ) += zynq_i2c.o
diff --git a/drivers/i2c/i2c-uclass-compat.c b/drivers/i2c/i2c-uclass-compat.c
new file mode 100644 (file)
index 0000000..223f238
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <i2c.h>
+
+static int cur_busnum;
+
+static int i2c_compat_get_device(uint chip_addr, int alen,
+                                struct udevice **devp)
+{
+       struct dm_i2c_chip *chip;
+       int ret;
+
+       ret = i2c_get_chip_for_busnum(cur_busnum, chip_addr, alen, devp);
+       if (ret)
+               return ret;
+       chip = dev_get_parent_platdata(*devp);
+       if (chip->offset_len != alen) {
+               printf("I2C chip %x: requested alen %d does not match chip offset_len %d\n",
+                      chip_addr, alen, chip->offset_len);
+               return -EADDRNOTAVAIL;
+       }
+
+       return 0;
+}
+
+int i2c_probe(uint8_t chip_addr)
+{
+       struct udevice *bus, *dev;
+       int ret;
+
+       ret = uclass_get_device_by_seq(UCLASS_I2C, cur_busnum, &bus);
+       if (ret) {
+               debug("Cannot find I2C bus %d: err=%d\n", cur_busnum, ret);
+               return ret;
+       }
+
+       if (!bus)
+               return -ENOENT;
+
+       return dm_i2c_probe(bus, chip_addr, 0, &dev);
+}
+
+int i2c_read(uint8_t chip_addr, unsigned int addr, int alen, uint8_t *buffer,
+            int len)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = i2c_compat_get_device(chip_addr, alen, &dev);
+       if (ret)
+               return ret;
+
+       return dm_i2c_read(dev, addr, buffer, len);
+}
+
+int i2c_write(uint8_t chip_addr, unsigned int addr, int alen, uint8_t *buffer,
+             int len)
+{
+       struct udevice *dev;
+       int ret;
+
+       ret = i2c_compat_get_device(chip_addr, alen, &dev);
+       if (ret)
+               return ret;
+
+       return dm_i2c_write(dev, addr, buffer, len);
+}
+
+int i2c_get_bus_num_fdt(int node)
+{
+       struct udevice *bus;
+       int ret;
+
+       ret = uclass_get_device_by_of_offset(UCLASS_I2C, node, &bus);
+       if (ret)
+               return ret;
+
+       return bus->seq;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+       return cur_busnum;
+}
+
+int i2c_set_bus_num(unsigned int bus)
+{
+       cur_busnum = bus;
+
+       return 0;
+}
+
+void i2c_init(int speed, int slaveaddr)
+{
+       /* Nothing to do here - the init happens through driver model */
+}
+
+void board_i2c_init(const void *blob)
+{
+       /* Nothing to do here - the init happens through driver model */
+}
index 005bf8662f2b496c1691b36e2a6036219552e1bb..eafa457845df2371bff8a59ce8b20b7d2d32dd82 100644 (file)
@@ -50,7 +50,7 @@ static int i2c_setup_offset(struct dm_i2c_chip *chip, uint offset,
 static int i2c_read_bytewise(struct udevice *dev, uint offset,
                             uint8_t *buffer, int len)
 {
-       struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+       struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
        struct udevice *bus = dev_get_parent(dev);
        struct dm_i2c_ops *ops = i2c_get_ops(bus);
        struct i2c_msg msg[2], *ptr;
@@ -79,7 +79,7 @@ static int i2c_read_bytewise(struct udevice *dev, uint offset,
 static int i2c_write_bytewise(struct udevice *dev, uint offset,
                             const uint8_t *buffer, int len)
 {
-       struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+       struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
        struct udevice *bus = dev_get_parent(dev);
        struct dm_i2c_ops *ops = i2c_get_ops(bus);
        struct i2c_msg msg[1];
@@ -100,9 +100,9 @@ static int i2c_write_bytewise(struct udevice *dev, uint offset,
        return 0;
 }
 
-int i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len)
+int dm_i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len)
 {
-       struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+       struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
        struct udevice *bus = dev_get_parent(dev);
        struct dm_i2c_ops *ops = i2c_get_ops(bus);
        struct i2c_msg msg[2], *ptr;
@@ -130,9 +130,10 @@ int i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len)
        return ops->xfer(bus, msg, msg_count);
 }
 
-int i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer, int len)
+int dm_i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer,
+                int len)
 {
-       struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+       struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
        struct udevice *bus = dev_get_parent(dev);
        struct dm_i2c_ops *ops = i2c_get_ops(bus);
        struct i2c_msg msg[1];
@@ -219,10 +220,10 @@ static int i2c_probe_chip(struct udevice *bus, uint chip_addr,
        return ops->xfer(bus, msg, 1);
 }
 
-static int i2c_bind_driver(struct udevice *bus, uint chip_addr,
+static int i2c_bind_driver(struct udevice *bus, uint chip_addr, uint offset_len,
                           struct udevice **devp)
 {
-       struct dm_i2c_chip chip;
+       struct dm_i2c_chip *chip;
        char name[30], *str;
        struct udevice *dev;
        int ret;
@@ -235,11 +236,11 @@ static int i2c_bind_driver(struct udevice *bus, uint chip_addr,
                goto err_bind;
 
        /* Tell the device what we know about it */
-       memset(&chip, '\0', sizeof(chip));
-       chip.chip_addr = chip_addr;
-       chip.offset_len = 1;    /* we assume */
-       ret = device_probe_child(dev, &chip);
-       debug("%s:  device_probe_child: ret=%d\n", __func__, ret);
+       chip = dev_get_parent_platdata(dev);
+       chip->chip_addr = chip_addr;
+       chip->offset_len = offset_len;
+       ret = device_probe(dev);
+       debug("%s:  device_probe: ret=%d\n", __func__, ret);
        if (ret)
                goto err_probe;
 
@@ -247,13 +248,18 @@ static int i2c_bind_driver(struct udevice *bus, uint chip_addr,
        return 0;
 
 err_probe:
+       /*
+        * If the device failed to probe, unbind it. There is nothing there
+        * on the bus so we don't want to leave it lying around
+        */
        device_unbind(dev);
 err_bind:
        free(str);
        return ret;
 }
 
-int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp)
+int i2c_get_chip(struct udevice *bus, uint chip_addr, uint offset_len,
+                struct udevice **devp)
 {
        struct udevice *dev;
 
@@ -261,15 +267,9 @@ int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp)
              bus->name, chip_addr);
        for (device_find_first_child(bus, &dev); dev;
                        device_find_next_child(&dev)) {
-               struct dm_i2c_chip store;
-               struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+               struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
                int ret;
 
-               if (!chip) {
-                       chip = &store;
-                       i2c_chip_ofdata_to_platdata(gd->fdt_blob,
-                                                   dev->of_offset, chip);
-               }
                if (chip->chip_addr == chip_addr) {
                        ret = device_probe(dev);
                        debug("found, ret=%d\n", ret);
@@ -280,10 +280,11 @@ int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp)
                }
        }
        debug("not found\n");
-       return i2c_bind_driver(bus, chip_addr, devp);
+       return i2c_bind_driver(bus, chip_addr, offset_len, devp);
 }
 
-int i2c_get_chip_for_busnum(int busnum, int chip_addr, struct udevice **devp)
+int i2c_get_chip_for_busnum(int busnum, int chip_addr, uint offset_len,
+                           struct udevice **devp)
 {
        struct udevice *bus;
        int ret;
@@ -293,7 +294,7 @@ int i2c_get_chip_for_busnum(int busnum, int chip_addr, struct udevice **devp)
                debug("Cannot find I2C bus %d\n", busnum);
                return ret;
        }
-       ret = i2c_get_chip(bus, chip_addr, devp);
+       ret = i2c_get_chip(bus, chip_addr, offset_len, devp);
        if (ret) {
                debug("Cannot find I2C chip %02x on bus %d\n", chip_addr,
                      busnum);
@@ -303,8 +304,8 @@ int i2c_get_chip_for_busnum(int busnum, int chip_addr, struct udevice **devp)
        return 0;
 }
 
-int i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags,
-             struct udevice **devp)
+int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags,
+                struct udevice **devp)
 {
        int ret;
 
@@ -318,7 +319,7 @@ int i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags,
                return ret;
 
        /* The chip was found, see if we have a driver, and probe it */
-       ret = i2c_get_chip(bus, chip_addr, devp);
+       ret = i2c_get_chip(bus, chip_addr, 1, devp);
        debug("%s:  i2c_get_chip: ret=%d\n", __func__, ret);
 
        return ret;
@@ -364,7 +365,7 @@ int i2c_get_bus_speed(struct udevice *bus)
 int i2c_set_chip_flags(struct udevice *dev, uint flags)
 {
        struct udevice *bus = dev->parent;
-       struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+       struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
        struct dm_i2c_ops *ops = i2c_get_ops(bus);
        int ret;
 
@@ -380,7 +381,7 @@ int i2c_set_chip_flags(struct udevice *dev, uint flags)
 
 int i2c_get_chip_flags(struct udevice *dev, uint *flagsp)
 {
-       struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+       struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
 
        *flagsp = chip->flags;
 
@@ -389,7 +390,7 @@ int i2c_get_chip_flags(struct udevice *dev, uint *flagsp)
 
 int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len)
 {
-       struct dm_i2c_chip *chip = dev_get_parentdata(dev);
+       struct dm_i2c_chip *chip = dev_get_parent_platdata(dev);
 
        if (offset_len > I2C_MAX_OFFSET_LEN)
                return -EINVAL;
@@ -419,7 +420,8 @@ int i2c_deblock(struct udevice *bus)
 int i2c_chip_ofdata_to_platdata(const void *blob, int node,
                                struct dm_i2c_chip *chip)
 {
-       chip->offset_len = 1;   /* default */
+       chip->offset_len = fdtdec_get_int(gd->fdt_blob, node,
+                                         "u-boot,i2c-offset-len", 1);
        chip->flags = 0;
        chip->chip_addr = fdtdec_get_int(gd->fdt_blob, node, "reg", -1);
        if (chip->chip_addr == -1) {
@@ -441,18 +443,31 @@ static int i2c_post_probe(struct udevice *dev)
        return i2c_set_bus_speed(dev, i2c->speed_hz);
 }
 
-int i2c_post_bind(struct udevice *dev)
+static int i2c_post_bind(struct udevice *dev)
 {
        /* Scan the bus for devices */
        return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
 }
 
+static int i2c_child_post_bind(struct udevice *dev)
+{
+       struct dm_i2c_chip *plat = dev_get_parent_platdata(dev);
+
+       if (dev->of_offset == -1)
+               return 0;
+
+       return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat);
+}
+
 UCLASS_DRIVER(i2c) = {
        .id             = UCLASS_I2C,
        .name           = "i2c",
-       .per_device_auto_alloc_size = sizeof(struct dm_i2c_bus),
+       .flags          = DM_UC_FLAG_SEQ_ALIAS,
        .post_bind      = i2c_post_bind,
        .post_probe     = i2c_post_probe,
+       .per_device_auto_alloc_size = sizeof(struct dm_i2c_bus),
+       .per_child_platdata_auto_alloc_size = sizeof(struct dm_i2c_chip),
+       .child_post_bind = i2c_child_post_bind,
 };
 
 UCLASS_DRIVER(i2c_generic) = {
diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c
new file mode 100644 (file)
index 0000000..6707edd
--- /dev/null
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2014 Panasonic Corporation
+ *   Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <dm/device.h>
+#include <dm/root.h>
+#include <i2c.h>
+#include <fdtdec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct uniphier_fi2c_regs {
+       u32 cr;                         /* control register */
+#define I2C_CR_MST     (1 << 3)        /* master mode */
+#define I2C_CR_STA     (1 << 2)        /* start condition */
+#define I2C_CR_STO     (1 << 1)        /* stop condition */
+#define I2C_CR_NACK    (1 << 0)        /* not ACK */
+       u32 dttx;                       /* send FIFO (write-only) */
+#define dtrx           dttx            /* receive FIFO (read-only) */
+#define I2C_DTTX_CMD   (1 << 8)        /* send command (slave addr) */
+#define I2C_DTTX_RD    (1 << 0)        /* read */
+       u32 __reserved;                 /* no register at offset 0x08 */
+       u32 slad;                       /* slave address */
+       u32 cyc;                        /* clock cycle control */
+       u32 lctl;                       /* clock low period control */
+       u32 ssut;                       /* restart/stop setup time control */
+       u32 dsut;                       /* data setup time control */
+       u32 intr;                       /* interrupt status */
+       u32 ie;                         /* interrupt enable */
+       u32 ic;                         /* interrupt clear */
+#define I2C_INT_TE     (1 << 9)        /* TX FIFO empty */
+#define I2C_INT_RB     (1 << 4)        /* received specified bytes */
+#define I2C_INT_NA     (1 << 2)        /* no answer */
+#define I2C_INT_AL     (1 << 1)        /* arbitration lost */
+       u32 sr;                         /* status register */
+#define I2C_SR_DB      (1 << 12)       /* device busy */
+#define I2C_SR_BB      (1 << 8)        /* bus busy */
+#define I2C_SR_RFF     (1 << 3)        /* Rx FIFO full */
+#define I2C_SR_RNE     (1 << 2)        /* Rx FIFO not empty */
+#define I2C_SR_TNF     (1 << 1)        /* Tx FIFO not full */
+#define I2C_SR_TFE     (1 << 0)        /* Tx FIFO empty */
+       u32 __reserved2;                /* no register at offset 0x30 */
+       u32 rst;                        /* reset control */
+#define I2C_RST_TBRST  (1 << 2)        /* clear Tx FIFO */
+#define I2C_RST_RBRST  (1 << 1)        /* clear Rx FIFO */
+#define I2C_RST_RST    (1 << 0)        /* forcible bus reset */
+       u32 bm;                         /* bus monitor */
+       u32 noise;                      /* noise filter control */
+       u32 tbc;                        /* Tx byte count setting */
+       u32 rbc;                        /* Rx byte count setting */
+       u32 tbcm;                       /* Tx byte count monitor */
+       u32 rbcm;                       /* Rx byte count monitor */
+       u32 brst;                       /* bus reset */
+#define I2C_BRST_FOEN  (1 << 1)        /* normal operation */
+#define I2C_BRST_RSCLO (1 << 0)        /* release SCL low fixing */
+};
+
+#define FIOCLK 50000000
+
+struct uniphier_fi2c_dev {
+       struct uniphier_fi2c_regs __iomem *regs;        /* register base */
+       unsigned long fioclk;                   /* internal operation clock */
+       unsigned long timeout;                  /* time out (us) */
+};
+
+static int poll_status(u32 __iomem *reg, u32 flag)
+{
+       int wait = 1000000; /* 1 sec is long enough */
+
+       while (readl(reg) & flag) {
+               if (wait-- < 0)
+                       return -EREMOTEIO;
+               udelay(1);
+       }
+
+       return 0;
+}
+
+static int reset_bus(struct uniphier_fi2c_regs __iomem *regs)
+{
+       int ret;
+
+       /* bus forcible reset */
+       writel(I2C_RST_RST, &regs->rst);
+       ret = poll_status(&regs->rst, I2C_RST_RST);
+       if (ret < 0)
+               debug("error: fail to reset I2C controller\n");
+
+       return ret;
+}
+
+static int check_device_busy(struct uniphier_fi2c_regs __iomem *regs)
+{
+       int ret;
+
+       ret = poll_status(&regs->sr, I2C_SR_DB);
+       if (ret < 0) {
+               debug("error: device busy too long. reset...\n");
+               ret = reset_bus(regs);
+       }
+
+       return ret;
+}
+
+static int uniphier_fi2c_probe(struct udevice *dev)
+{
+       fdt_addr_t addr;
+       fdt_size_t size;
+       struct uniphier_fi2c_dev *priv = dev_get_priv(dev);
+       int ret;
+
+       addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg",
+                                   &size);
+
+       priv->regs = map_sysmem(addr, size);
+
+       if (!priv->regs)
+               return -ENOMEM;
+
+       priv->fioclk = FIOCLK;
+
+       /* bus forcible reset */
+       ret = reset_bus(priv->regs);
+       if (ret < 0)
+               return ret;
+
+       writel(I2C_BRST_FOEN | I2C_BRST_RSCLO, &priv->regs->brst);
+
+       return 0;
+}
+
+static int uniphier_fi2c_remove(struct udevice *dev)
+{
+       struct uniphier_fi2c_dev *priv = dev_get_priv(dev);
+
+       unmap_sysmem(priv->regs);
+
+       return 0;
+}
+
+static int wait_for_irq(struct uniphier_fi2c_dev *dev, u32 flags,
+                       bool *stop)
+{
+       u32 irq;
+       unsigned long wait = dev->timeout;
+       int ret = -EREMOTEIO;
+
+       do {
+               udelay(1);
+               irq = readl(&dev->regs->intr);
+       } while (!(irq & flags) && wait--);
+
+       if (wait < 0) {
+               debug("error: time out\n");
+               return ret;
+       }
+
+       if (irq & I2C_INT_AL) {
+               debug("error: arbitration lost\n");
+               *stop = false;
+               return ret;
+       }
+
+       if (irq & I2C_INT_NA) {
+               debug("error: no answer\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int issue_stop(struct uniphier_fi2c_dev *dev, int old_ret)
+{
+       int ret;
+
+       debug("stop condition\n");
+       writel(I2C_CR_MST | I2C_CR_STO, &dev->regs->cr);
+
+       ret = poll_status(&dev->regs->sr, I2C_SR_DB);
+       if (ret < 0)
+               debug("error: device busy after operation\n");
+
+       return old_ret ? old_ret : ret;
+}
+
+static int uniphier_fi2c_transmit(struct uniphier_fi2c_dev *dev, uint addr,
+                                 uint len, const u8 *buf, bool *stop)
+{
+       int ret;
+       const u32 irq_flags = I2C_INT_TE | I2C_INT_NA | I2C_INT_AL;
+       struct uniphier_fi2c_regs __iomem *regs = dev->regs;
+
+       debug("%s: addr = %x, len = %d\n", __func__, addr, len);
+
+       writel(I2C_DTTX_CMD | addr << 1, &regs->dttx);
+
+       writel(irq_flags, &regs->ie);
+       writel(irq_flags, &regs->ic);
+
+       debug("start condition\n");
+       writel(I2C_CR_MST | I2C_CR_STA, &regs->cr);
+
+       ret = wait_for_irq(dev, irq_flags, stop);
+       if (ret < 0)
+               goto error;
+
+       while (len--) {
+               debug("sending %x\n", *buf);
+               writel(*buf++, &regs->dttx);
+
+               writel(irq_flags, &regs->ic);
+
+               ret = wait_for_irq(dev, irq_flags, stop);
+               if (ret < 0)
+                       goto error;
+       }
+
+error:
+       writel(irq_flags, &regs->ic);
+
+       if (*stop)
+               ret = issue_stop(dev, ret);
+
+       return ret;
+}
+
+static int uniphier_fi2c_receive(struct uniphier_fi2c_dev *dev, uint addr,
+                                uint len, u8 *buf, bool *stop)
+{
+       int ret = 0;
+       const u32 irq_flags = I2C_INT_RB | I2C_INT_NA | I2C_INT_AL;
+       struct uniphier_fi2c_regs __iomem *regs = dev->regs;
+
+       debug("%s: addr = %x, len = %d\n", __func__, addr, len);
+
+       /*
+        * In case 'len == 0', only the slave address should be sent
+        * for probing, which is covered by the transmit function.
+        */
+       if (len == 0)
+               return uniphier_fi2c_transmit(dev, addr, len, buf, stop);
+
+       writel(I2C_DTTX_CMD | I2C_DTTX_RD | addr << 1, &regs->dttx);
+
+       writel(0, &regs->rbc);
+       writel(irq_flags, &regs->ie);
+       writel(irq_flags, &regs->ic);
+
+       debug("start condition\n");
+       writel(I2C_CR_MST | I2C_CR_STA | (len == 1 ? I2C_CR_NACK : 0),
+              &regs->cr);
+
+       while (len--) {
+               ret = wait_for_irq(dev, irq_flags, stop);
+               if (ret < 0)
+                       goto error;
+
+               *buf++ = readl(&regs->dtrx);
+               debug("received %x\n", *(buf - 1));
+
+               if (len == 1)
+                       writel(I2C_CR_MST | I2C_CR_NACK, &regs->cr);
+
+               writel(irq_flags, &regs->ic);
+       }
+
+error:
+       writel(irq_flags, &regs->ic);
+
+       if (*stop)
+               ret = issue_stop(dev, ret);
+
+       return ret;
+}
+
+static int uniphier_fi2c_xfer(struct udevice *bus, struct i2c_msg *msg,
+                            int nmsgs)
+{
+       int ret;
+       struct uniphier_fi2c_dev *dev = dev_get_priv(bus);
+       bool stop;
+
+       ret = check_device_busy(dev->regs);
+       if (ret < 0)
+               return ret;
+
+       for (; nmsgs > 0; nmsgs--, msg++) {
+               /* If next message is read, skip the stop condition */
+               stop = nmsgs > 1 && msg[1].flags & I2C_M_RD ? false : true;
+
+               if (msg->flags & I2C_M_RD)
+                       ret = uniphier_fi2c_receive(dev, msg->addr, msg->len,
+                                                   msg->buf, &stop);
+               else
+                       ret = uniphier_fi2c_transmit(dev, msg->addr, msg->len,
+                                                    msg->buf, &stop);
+
+               if (ret < 0)
+                       break;
+       }
+
+       return ret;
+}
+
+static int uniphier_fi2c_set_bus_speed(struct udevice *bus, unsigned int speed)
+{
+       int ret;
+       unsigned int clk_count;
+       struct uniphier_fi2c_dev *dev = dev_get_priv(bus);
+       struct uniphier_fi2c_regs __iomem *regs = dev->regs;
+
+       /* max supported frequency is 400 kHz */
+       if (speed > 400000)
+               return -EINVAL;
+
+       ret = check_device_busy(dev->regs);
+       if (ret < 0)
+               return ret;
+
+       /* make sure the bus is idle when changing the frequency */
+       writel(I2C_BRST_RSCLO, &regs->brst);
+
+       clk_count = dev->fioclk / speed;
+
+       writel(clk_count, &regs->cyc);
+       writel(clk_count / 2, &regs->lctl);
+       writel(clk_count / 2, &regs->ssut);
+       writel(clk_count / 16, &regs->dsut);
+
+       writel(I2C_BRST_FOEN | I2C_BRST_RSCLO, &regs->brst);
+
+       /*
+        * Theoretically, each byte can be transferred in
+        * 1000000 * 9 / speed usec.
+        * This time out value is long enough.
+        */
+       dev->timeout = 100000000L / speed;
+
+       return 0;
+}
+
+static const struct dm_i2c_ops uniphier_fi2c_ops = {
+       .xfer = uniphier_fi2c_xfer,
+       .set_bus_speed = uniphier_fi2c_set_bus_speed,
+};
+
+static const struct udevice_id uniphier_fi2c_of_match[] = {
+       { .compatible = "panasonic,uniphier-fi2c" },
+       {},
+};
+
+U_BOOT_DRIVER(uniphier_fi2c) = {
+       .name = "uniphier-fi2c",
+       .id = UCLASS_I2C,
+       .of_match = uniphier_fi2c_of_match,
+       .probe = uniphier_fi2c_probe,
+       .remove = uniphier_fi2c_remove,
+       .priv_auto_alloc_size = sizeof(struct uniphier_fi2c_dev),
+       .ops = &uniphier_fi2c_ops,
+};
diff --git a/drivers/i2c/i2c-uniphier.c b/drivers/i2c/i2c-uniphier.c
new file mode 100644 (file)
index 0000000..64a9ed8
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2014 Panasonic Corporation
+ *   Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <dm/device.h>
+#include <dm/root.h>
+#include <i2c.h>
+#include <fdtdec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct uniphier_i2c_regs {
+       u32 dtrm;                       /* data transmission */
+#define I2C_DTRM_STA   (1 << 10)
+#define I2C_DTRM_STO   (1 << 9)
+#define I2C_DTRM_NACK  (1 << 8)
+#define I2C_DTRM_RD    (1 << 0)
+       u32 drec;                       /* data reception */
+#define I2C_DREC_STS   (1 << 12)
+#define I2C_DREC_LRB   (1 << 11)
+#define I2C_DREC_LAB   (1 << 9)
+       u32 myad;                       /* slave address */
+       u32 clk;                        /* clock frequency control */
+       u32 brst;                       /* bus reset */
+#define I2C_BRST_FOEN  (1 << 1)
+#define I2C_BRST_BRST  (1 << 0)
+       u32 hold;                       /* hold time control */
+       u32 bsts;                       /* bus status monitor */
+       u32 noise;                      /* noise filter control */
+       u32 setup;                      /* setup time control */
+};
+
+#define IOBUS_FREQ     100000000
+
+struct uniphier_i2c_dev {
+       struct uniphier_i2c_regs __iomem *regs; /* register base */
+       unsigned long input_clk;        /* master clock (Hz) */
+       unsigned long wait_us;          /* wait for every byte transfer (us) */
+};
+
+static int uniphier_i2c_probe(struct udevice *dev)
+{
+       fdt_addr_t addr;
+       fdt_size_t size;
+       struct uniphier_i2c_dev *priv = dev_get_priv(dev);
+
+       addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", &size);
+
+       priv->regs = map_sysmem(addr, size);
+
+       if (!priv->regs)
+               return -ENOMEM;
+
+       priv->input_clk = IOBUS_FREQ;
+
+       /* deassert reset */
+       writel(0x3, &priv->regs->brst);
+
+       return 0;
+}
+
+static int uniphier_i2c_remove(struct udevice *dev)
+{
+       struct uniphier_i2c_dev *priv = dev_get_priv(dev);
+
+       unmap_sysmem(priv->regs);
+
+       return 0;
+}
+
+static int send_and_recv_byte(struct uniphier_i2c_dev *dev, u32 dtrm)
+{
+       writel(dtrm, &dev->regs->dtrm);
+
+       /*
+        * This controller only provides interruption to inform the completion
+        * of each byte transfer.  (No status register to poll it.)
+        * Unfortunately, U-Boot does not have a good support of interrupt.
+        * Wait for a while.
+        */
+       udelay(dev->wait_us);
+
+       return readl(&dev->regs->drec);
+}
+
+static int send_byte(struct uniphier_i2c_dev *dev, u32 dtrm, bool *stop)
+{
+       int ret = 0;
+       u32 drec;
+
+       drec = send_and_recv_byte(dev, dtrm);
+
+       if (drec & I2C_DREC_LAB) {
+               debug("uniphier_i2c: bus arbitration failed\n");
+               *stop = false;
+               ret = -EREMOTEIO;
+       }
+       if (drec & I2C_DREC_LRB) {
+               debug("uniphier_i2c: slave did not return ACK\n");
+               ret = -EREMOTEIO;
+       }
+       return ret;
+}
+
+static int uniphier_i2c_transmit(struct uniphier_i2c_dev *dev, uint addr,
+                                uint len, const u8 *buf, bool *stop)
+{
+       int ret;
+
+       debug("%s: addr = %x, len = %d\n", __func__, addr, len);
+
+       ret = send_byte(dev, I2C_DTRM_STA | I2C_DTRM_NACK | addr << 1, stop);
+       if (ret < 0)
+               goto fail;
+
+       while (len--) {
+               ret = send_byte(dev, I2C_DTRM_NACK | *buf++, stop);
+               if (ret < 0)
+                       goto fail;
+       }
+
+fail:
+       if (*stop)
+               writel(I2C_DTRM_STO | I2C_DTRM_NACK, &dev->regs->dtrm);
+
+       return ret;
+}
+
+static int uniphier_i2c_receive(struct uniphier_i2c_dev *dev, uint addr,
+                               uint len, u8 *buf, bool *stop)
+{
+       int ret;
+
+       debug("%s: addr = %x, len = %d\n", __func__, addr, len);
+
+       ret = send_byte(dev, I2C_DTRM_STA | I2C_DTRM_NACK |
+                       I2C_DTRM_RD | addr << 1, stop);
+       if (ret < 0)
+               goto fail;
+
+       while (len--)
+               *buf++ = send_and_recv_byte(dev, len ? 0 : I2C_DTRM_NACK);
+
+fail:
+       if (*stop)
+               writel(I2C_DTRM_STO | I2C_DTRM_NACK, &dev->regs->dtrm);
+
+       return ret;
+}
+
+static int uniphier_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
+                            int nmsgs)
+{
+       int ret = 0;
+       struct uniphier_i2c_dev *dev = dev_get_priv(bus);
+       bool stop;
+
+       for (; nmsgs > 0; nmsgs--, msg++) {
+               /* If next message is read, skip the stop condition */
+               stop = nmsgs > 1 && msg[1].flags & I2C_M_RD ? false : true;
+
+               if (msg->flags & I2C_M_RD)
+                       ret = uniphier_i2c_receive(dev, msg->addr, msg->len,
+                                                  msg->buf, &stop);
+               else
+                       ret = uniphier_i2c_transmit(dev, msg->addr, msg->len,
+                                                   msg->buf, &stop);
+
+               if (ret < 0)
+                       break;
+       }
+
+       return ret;
+}
+
+static int uniphier_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
+{
+       struct uniphier_i2c_dev *priv = dev_get_priv(bus);
+
+       /* max supported frequency is 400 kHz */
+       if (speed > 400000)
+               return -EINVAL;
+
+       /* bus reset: make sure the bus is idle when change the frequency */
+       writel(0x1, &priv->regs->brst);
+
+       writel((priv->input_clk / speed / 2 << 16) | (priv->input_clk / speed),
+              &priv->regs->clk);
+
+       writel(0x3, &priv->regs->brst);
+
+       /*
+        * Theoretically, each byte can be transferred in
+        * 1000000 * 9 / speed usec.  For safety, wait more than double.
+        */
+       priv->wait_us = 20000000 / speed;
+
+       return 0;
+}
+
+
+static const struct dm_i2c_ops uniphier_i2c_ops = {
+       .xfer = uniphier_i2c_xfer,
+       .set_bus_speed = uniphier_i2c_set_bus_speed,
+};
+
+static const struct udevice_id uniphier_i2c_of_match[] = {
+       { .compatible = "panasonic,uniphier-i2c" },
+       {},
+};
+
+U_BOOT_DRIVER(uniphier_i2c) = {
+       .name = "uniphier-i2c",
+       .id = UCLASS_I2C,
+       .of_match = uniphier_i2c_of_match,
+       .probe = uniphier_i2c_probe,
+       .remove = uniphier_i2c_remove,
+       .priv_auto_alloc_size = sizeof(struct uniphier_i2c_dev),
+       .ops = &uniphier_i2c_ops,
+};
index fd328f054940f3beb2214b76c4f103c9b06377a3..0dd1abcf80fcfe0e87fdb09323907244b3033e15 100644 (file)
@@ -9,8 +9,9 @@
  * as they seem to have the same I2C controller inside.
  * The different address mapping is handled by the s3c24xx.h files below.
  */
-
 #include <common.h>
+#include <errno.h>
+#include <dm.h>
 #include <fdtdec.h>
 #if (defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
 #include <asm/arch/clk.h>
 #define CONFIG_MAX_I2C_NUM 1
 #endif
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /*
  * For SPL boot some boards need i2c before SDRAM is initialised so force
  * variables to live in SRAM
  */
+#ifdef CONFIG_SYS_I2C
 static struct s3c24x0_i2c_bus i2c_bus[CONFIG_MAX_I2C_NUM]
                        __attribute__((section(".data")));
+#endif
+
+enum exynos_i2c_type {
+       EXYNOS_I2C_STD,
+       EXYNOS_I2C_HS,
+};
 
+#ifdef CONFIG_SYS_I2C
 /**
  * Get a pointer to the given bus index
  *
@@ -147,6 +158,7 @@ static struct s3c24x0_i2c_bus *get_bus(unsigned int bus_idx)
        debug("Undefined bus: %d\n", bus_idx);
        return NULL;
 }
+#endif
 
 #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
 static int GetI2CSDA(void)
@@ -251,6 +263,7 @@ static void ReadWriteByte(struct s3c24x0_i2c *i2c)
        writel(readl(&i2c->iiccon) & ~I2CCON_IRPND, &i2c->iiccon);
 }
 
+#ifdef CONFIG_SYS_I2C
 static struct s3c24x0_i2c *get_base_i2c(int bus)
 {
 #ifdef CONFIG_EXYNOS4
@@ -267,6 +280,7 @@ static struct s3c24x0_i2c *get_base_i2c(int bus)
        return s3c24x0_get_base_i2c();
 #endif
 }
+#endif
 
 static void i2c_ch_init(struct s3c24x0_i2c *i2c, int speed, int slaveadd)
 {
@@ -326,7 +340,7 @@ static int hsi2c_get_clk_details(struct s3c24x0_i2c_bus *i2c_bus)
                        return 0;
                }
        }
-       return -1;
+       return -EINVAL;
 }
 
 static void hsi2c_ch_init(struct s3c24x0_i2c_bus *i2c_bus)
@@ -398,18 +412,20 @@ static void exynos5_i2c_reset(struct s3c24x0_i2c_bus *i2c_bus)
        hsi2c_ch_init(i2c_bus);
 }
 
+#ifdef CONFIG_SYS_I2C
 static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
 {
        struct s3c24x0_i2c *i2c;
        struct s3c24x0_i2c_bus *bus;
-
 #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5)
        struct s3c24x0_gpio *gpio = s3c24x0_get_base_gpio();
 #endif
        ulong start_time = get_timer(0);
 
-       /* By default i2c channel 0 is the current bus */
        i2c = get_base_i2c(adap->hwadapnr);
+       bus = &i2c_bus[adap->hwadapnr];
+       if (!bus)
+               return;
 
        /*
         * In case the previous transfer is still going, wait to give it a
@@ -470,12 +486,13 @@ static void s3c24x0_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
 #endif
        }
 #endif /* #if !(defined CONFIG_EXYNOS4 || defined CONFIG_EXYNOS5) */
+
        i2c_ch_init(i2c, speed, slaveadd);
 
-       bus = &i2c_bus[adap->hwadapnr];
        bus->active = true;
        bus->regs = i2c;
 }
+#endif /* CONFIG_SYS_I2C */
 
 /*
  * Poll the appropriate bit of the fifo status register until the interface is
@@ -698,20 +715,27 @@ static int hsi2c_read(struct exynos5_hsi2c *i2c,
        return rv;
 }
 
+#ifdef CONFIG_SYS_I2C
 static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap,
-                                         unsigned int speed)
+                                             unsigned int speed)
+#else
+static int s3c24x0_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
+#endif
 {
        struct s3c24x0_i2c_bus *i2c_bus;
 
+#ifdef CONFIG_SYS_I2C
        i2c_bus = get_bus(adap->hwadapnr);
        if (!i2c_bus)
-               return -1;
-
+               return -EFAULT;
+#else
+       i2c_bus = dev_get_priv(dev);
+#endif
        i2c_bus->clock_frequency = speed;
 
        if (i2c_bus->is_highspeed) {
                if (hsi2c_get_clk_details(i2c_bus))
-                       return -1;
+                       return -EFAULT;
                hsi2c_ch_init(i2c_bus);
        } else {
                i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
@@ -721,17 +745,6 @@ static unsigned int s3c24x0_i2c_set_bus_speed(struct i2c_adapter *adap,
        return 0;
 }
 
-#ifdef CONFIG_EXYNOS5
-static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
-{
-       /* This will override the speed selected in the fdt for that port */
-       debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
-       if (i2c_set_bus_speed(speed))
-               printf("i2c_init: failed to init bus %d for speed = %d\n",
-                                               adap->hwadapnr, speed);
-}
-#endif
-
 /*
  * cmd_type is 0 for write, 1 for read.
  *
@@ -844,15 +857,23 @@ bailout:
        return result;
 }
 
+#ifdef CONFIG_SYS_I2C
 static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip)
+#else
+static int s3c24x0_i2c_probe(struct udevice *dev, uint chip, uint chip_flags)
+#endif
 {
        struct s3c24x0_i2c_bus *i2c_bus;
        uchar buf[1];
        int ret;
 
+#ifdef CONFIG_SYS_I2C
        i2c_bus = get_bus(adap->hwadapnr);
        if (!i2c_bus)
-               return -1;
+               return -EFAULT;
+#else
+       i2c_bus = dev_get_priv(dev);
+#endif
        buf[0] = 0;
 
        /*
@@ -871,6 +892,7 @@ static int s3c24x0_i2c_probe(struct i2c_adapter *adap, uchar chip)
        return ret != I2C_OK;
 }
 
+#ifdef CONFIG_SYS_I2C
 static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
                            int alen, uchar *buffer, int len)
 {
@@ -878,9 +900,13 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
        uchar xaddr[4];
        int ret;
 
+       i2c_bus = get_bus(adap->hwadapnr);
+       if (!i2c_bus)
+               return -EFAULT;
+
        if (alen > 4) {
                debug("I2C read: addr len %d not supported\n", alen);
-               return 1;
+               return -EADDRNOTAVAIL;
        }
 
        if (alen > 0) {
@@ -906,10 +932,6 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
                chip |= ((addr >> (alen * 8)) &
                         CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
 #endif
-       i2c_bus = get_bus(adap->hwadapnr);
-       if (!i2c_bus)
-               return -1;
-
        if (i2c_bus->is_highspeed)
                ret = hsi2c_read(i2c_bus->hsregs, chip, &xaddr[4 - alen],
                                 alen, buffer, len);
@@ -921,7 +943,7 @@ static int s3c24x0_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
                if (i2c_bus->is_highspeed)
                        exynos5_i2c_reset(i2c_bus);
                debug("I2c read failed %d\n", ret);
-               return 1;
+               return -EIO;
        }
        return 0;
 }
@@ -933,9 +955,13 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
        uchar xaddr[4];
        int ret;
 
+       i2c_bus = get_bus(adap->hwadapnr);
+       if (!i2c_bus)
+               return -EFAULT;
+
        if (alen > 4) {
                debug("I2C write: addr len %d not supported\n", alen);
-               return 1;
+               return -EINVAL;
        }
 
        if (alen > 0) {
@@ -960,10 +986,6 @@ static int s3c24x0_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
                chip |= ((addr >> (alen * 8)) &
                         CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW);
 #endif
-       i2c_bus = get_bus(adap->hwadapnr);
-       if (!i2c_bus)
-               return -1;
-
        if (i2c_bus->is_highspeed)
                ret = hsi2c_write(i2c_bus->hsregs, chip, &xaddr[4 - alen],
                                  alen, buffer, len, true);
@@ -985,7 +1007,7 @@ static void process_nodes(const void *blob, int node_list[], int count,
                         int is_highspeed)
 {
        struct s3c24x0_i2c_bus *bus;
-       int i;
+       int i, flags;
 
        for (i = 0; i < count; i++) {
                int node = node_list[i];
@@ -997,12 +1019,15 @@ static void process_nodes(const void *blob, int node_list[], int count,
                bus->active = true;
                bus->is_highspeed = is_highspeed;
 
-               if (is_highspeed)
+               if (is_highspeed) {
+                       flags = PINMUX_FLAG_HS_MODE;
                        bus->hsregs = (struct exynos5_hsi2c *)
                                        fdtdec_get_addr(blob, node, "reg");
-               else
+               } else {
+                       flags = 0;
                        bus->regs = (struct s3c24x0_i2c *)
                                        fdtdec_get_addr(blob, node, "reg");
+               }
 
                bus->id = pinmux_decode_periph_id(blob, node);
                bus->clock_frequency = fdtdec_get_int(blob, node,
@@ -1010,7 +1035,7 @@ static void process_nodes(const void *blob, int node_list[], int count,
                                                CONFIG_SYS_I2C_S3C24X0_SPEED);
                bus->node = node;
                bus->bus_num = i;
-               exynos_pinmux_config(bus->id, 0);
+               exynos_pinmux_config(PERIPH_ID_I2C0 + bus->id, flags);
 
                /* Mark position as used */
                node_list[i] = -1;
@@ -1033,7 +1058,6 @@ void board_i2c_init(const void *blob)
                COMPAT_SAMSUNG_EXYNOS5_I2C, node_list,
                CONFIG_MAX_I2C_NUM);
        process_nodes(blob, node_list, count, 1);
-
 }
 
 int i2c_get_bus_num_fdt(int node)
@@ -1046,7 +1070,7 @@ int i2c_get_bus_num_fdt(int node)
        }
 
        debug("%s: Can't find any matched I2C bus\n", __func__);
-       return -1;
+       return -EINVAL;
 }
 
 int i2c_reset_port_fdt(const void *blob, int node)
@@ -1057,18 +1081,18 @@ int i2c_reset_port_fdt(const void *blob, int node)
        bus = i2c_get_bus_num_fdt(node);
        if (bus < 0) {
                debug("could not get bus for node %d\n", node);
-               return -1;
+               return bus;
        }
 
        i2c_bus = get_bus(bus);
        if (!i2c_bus) {
-               debug("get_bus() failed for node node %d\n", node);
-               return -1;
+               debug("get_bus() failed for node %d\n", node);
+               return -EFAULT;
        }
 
        if (i2c_bus->is_highspeed) {
                if (hsi2c_get_clk_details(i2c_bus))
-                       return -1;
+                       return -EINVAL;
                hsi2c_ch_init(i2c_bus);
        } else {
                i2c_ch_init(i2c_bus->regs, i2c_bus->clock_frequency,
@@ -1077,7 +1101,17 @@ int i2c_reset_port_fdt(const void *blob, int node)
 
        return 0;
 }
-#endif
+#endif /* CONFIG_OF_CONTROL */
+
+#ifdef CONFIG_EXYNOS5
+static void exynos_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
+{
+       /* This will override the speed selected in the fdt for that port */
+       debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
+       if (i2c_set_bus_speed(speed))
+               error("i2c_init: failed to init bus for speed = %d", speed);
+}
+#endif /* CONFIG_EXYNOS5 */
 
 /*
  * Register s3c24x0 i2c adapters
@@ -1247,3 +1281,120 @@ U_BOOT_I2C_ADAP_COMPLETE(s3c0, s3c24x0_i2c_init, s3c24x0_i2c_probe,
                        CONFIG_SYS_I2C_S3C24X0_SPEED,
                        CONFIG_SYS_I2C_S3C24X0_SLAVE, 0)
 #endif
+#endif /* CONFIG_SYS_I2C */
+
+#ifdef CONFIG_DM_I2C
+static int i2c_write_data(struct s3c24x0_i2c_bus *i2c_bus, uchar chip,
+                         uchar *buffer, int len, bool end_with_repeated_start)
+{
+       int ret;
+
+       if (i2c_bus->is_highspeed) {
+               ret = hsi2c_write(i2c_bus->hsregs, chip, 0, 0,
+                                 buffer, len, true);
+               if (ret)
+                       exynos5_i2c_reset(i2c_bus);
+       } else {
+               ret = i2c_transfer(i2c_bus->regs, I2C_WRITE,
+                                  chip << 1, 0, 0, buffer, len);
+       }
+
+       return ret != I2C_OK;
+}
+
+static int i2c_read_data(struct s3c24x0_i2c_bus  *i2c_bus, uchar chip,
+                        uchar *buffer, int len)
+{
+       int ret;
+
+       if (i2c_bus->is_highspeed) {
+               ret = hsi2c_read(i2c_bus->hsregs, chip, 0, 0, buffer, len);
+               if (ret)
+                       exynos5_i2c_reset(i2c_bus);
+       } else {
+               ret = i2c_transfer(i2c_bus->regs, I2C_READ,
+                                  chip << 1, 0, 0, buffer, len);
+       }
+
+       return ret != I2C_OK;
+}
+
+static int s3c24x0_i2c_xfer(struct udevice *dev, struct i2c_msg *msg,
+                           int nmsgs)
+{
+       struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
+       int ret;
+
+       for (; nmsgs > 0; nmsgs--, msg++) {
+               bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD);
+
+               if (msg->flags & I2C_M_RD) {
+                       ret = i2c_read_data(i2c_bus, msg->addr, msg->buf,
+                                           msg->len);
+               } else {
+                       ret = i2c_write_data(i2c_bus, msg->addr, msg->buf,
+                                            msg->len, next_is_read);
+               }
+               if (ret)
+                       return -EREMOTEIO;
+       }
+
+       return 0;
+}
+
+static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
+{
+       const void *blob = gd->fdt_blob;
+       struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
+       int node, flags;
+
+       i2c_bus->is_highspeed = dev->of_id->data;
+       node = dev->of_offset;
+
+       if (i2c_bus->is_highspeed) {
+               flags = PINMUX_FLAG_HS_MODE;
+               i2c_bus->hsregs = (struct exynos5_hsi2c *)
+                               fdtdec_get_addr(blob, node, "reg");
+       } else {
+               flags = 0;
+               i2c_bus->regs = (struct s3c24x0_i2c *)
+                               fdtdec_get_addr(blob, node, "reg");
+       }
+
+       i2c_bus->id = pinmux_decode_periph_id(blob, node);
+
+       i2c_bus->clock_frequency = fdtdec_get_int(blob, node,
+                                               "clock-frequency",
+                                               CONFIG_SYS_I2C_S3C24X0_SPEED);
+       i2c_bus->node = node;
+       i2c_bus->bus_num = dev->seq;
+
+       exynos_pinmux_config(i2c_bus->id, flags);
+
+       i2c_bus->active = true;
+
+       return 0;
+}
+
+static const struct dm_i2c_ops s3c_i2c_ops = {
+       .xfer           = s3c24x0_i2c_xfer,
+       .probe_chip     = s3c24x0_i2c_probe,
+       .set_bus_speed  = s3c24x0_i2c_set_bus_speed,
+};
+
+static const struct udevice_id s3c_i2c_ids[] = {
+       { .compatible = "samsung,s3c2440-i2c", .data = EXYNOS_I2C_STD },
+       { .compatible = "samsung,exynos5-hsi2c", .data = EXYNOS_I2C_HS },
+       { }
+};
+
+U_BOOT_DRIVER(i2c_s3c) = {
+       .name   = "i2c_s3c",
+       .id     = UCLASS_I2C,
+       .of_match = s3c_i2c_ids,
+       .ofdata_to_platdata = s3c_i2c_ofdata_to_platdata,
+       .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
+       .priv_auto_alloc_size = sizeof(struct s3c24x0_i2c_bus),
+       .ops    = &s3c_i2c_ops,
+};
+#endif /* CONFIG_DM_I2C */
index f0e9f51a1f28fda9822e765a5821b095f6badfef..a943aa6382142b4ebf411bc7c11ad7a9dbd9d80a 100644 (file)
@@ -25,24 +25,24 @@ struct dm_sandbox_i2c_emul_priv {
 static int get_emul(struct udevice *dev, struct udevice **devp,
                    struct dm_i2c_ops **opsp)
 {
-       struct dm_i2c_chip *priv;
+       struct dm_i2c_chip *plat;
        int ret;
 
        *devp = NULL;
        *opsp = NULL;
-       priv = dev_get_parentdata(dev);
-       if (!priv->emul) {
+       plat = dev_get_parent_platdata(dev);
+       if (!plat->emul) {
                ret = dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset,
                                       false);
                if (ret)
                        return ret;
 
-               ret = device_get_child(dev, 0, &priv->emul);
+               ret = device_get_child(dev, 0, &plat->emul);
                if (ret)
                        return ret;
        }
-       *devp = priv->emul;
-       *opsp = i2c_get_ops(priv->emul);
+       *devp = plat->emul;
+       *opsp = i2c_get_ops(plat->emul);
 
        return 0;
 }
@@ -60,7 +60,7 @@ static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
        if (msg->addr == SANDBOX_I2C_TEST_ADDR)
                return 0;
 
-       ret = i2c_get_chip(bus, msg->addr, &dev);
+       ret = i2c_get_chip(bus, msg->addr, 1, &dev);
        if (ret)
                return ret;
 
@@ -82,20 +82,6 @@ static const struct dm_i2c_ops sandbox_i2c_ops = {
        .xfer           = sandbox_i2c_xfer,
 };
 
-static int sandbox_i2c_child_pre_probe(struct udevice *dev)
-{
-       struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
-
-       /* Ignore our test address */
-       if (i2c_chip->chip_addr == SANDBOX_I2C_TEST_ADDR)
-               return 0;
-       if (dev->of_offset == -1)
-               return 0;
-
-       return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
-                                          i2c_chip);
-}
-
 static const struct udevice_id sandbox_i2c_ids[] = {
        { .compatible = "sandbox,i2c" },
        { }
@@ -105,7 +91,5 @@ U_BOOT_DRIVER(i2c_sandbox) = {
        .name   = "i2c_sandbox",
        .id     = UCLASS_I2C,
        .of_match = sandbox_i2c_ids,
-       .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
-       .child_pre_probe = sandbox_i2c_child_pre_probe,
        .ops    = &sandbox_i2c_ops,
 };
index 87290c3127612c3369f8e98c383118f0e3229563..f4142870b304037273cb405f36e9ad2a39819d4b 100644 (file)
@@ -484,21 +484,6 @@ static const struct dm_i2c_ops tegra_i2c_ops = {
        .set_bus_speed  = tegra_i2c_set_bus_speed,
 };
 
-static int tegra_i2c_child_pre_probe(struct udevice *dev)
-{
-       struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
-
-       if (dev->of_offset == -1)
-               return 0;
-       return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
-                                          i2c_chip);
-}
-
-static int tegra_i2c_ofdata_to_platdata(struct udevice *dev)
-{
-       return 0;
-}
-
 static const struct udevice_id tegra_i2c_ids[] = {
        { .compatible = "nvidia,tegra114-i2c", .data = TYPE_114 },
        { .compatible = "nvidia,tegra20-i2c", .data = TYPE_STD },
@@ -510,10 +495,7 @@ U_BOOT_DRIVER(i2c_tegra) = {
        .name   = "i2c_tegra",
        .id     = UCLASS_I2C,
        .of_match = tegra_i2c_ids,
-       .ofdata_to_platdata = tegra_i2c_ofdata_to_platdata,
        .probe  = tegra_i2c_probe,
-       .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
-       .child_pre_probe = tegra_i2c_child_pre_probe,
        .priv_auto_alloc_size = sizeof(struct i2c_bus),
        .ops    = &tegra_i2c_ops,
 };
index 9b4effb2fb56cda2fcba39d1a5ee80fe084384b8..5846e76c49525549f784ef6645834fa6b6611e5d 100644 (file)
@@ -154,7 +154,9 @@ static int prepare_proto3_response_buffer(struct cros_ec_dev *dev, int din_len)
  * @param dev          CROS-EC device
  * @param dinp          Returns pointer to response data
  * @param din_len       Maximum size of response in bytes
- * @return number of bytes of response data, or <0 if error
+ * @return number of bytes of response data, or <0 if error. Note that error
+ * codes can be from errno.h or -ve EC_RES_INVALID_CHECKSUM values (and they
+ * overlap!)
  */
 static int handle_proto3_response(struct cros_ec_dev *dev,
                                  uint8_t **dinp, int din_len)
@@ -228,7 +230,7 @@ static int send_command_proto3(struct cros_ec_dev *dev,
 
 #ifdef CONFIG_DM_CROS_EC
        ops = dm_cros_ec_get_ops(dev->dev);
-       rv = ops->packet(dev->dev, out_bytes, in_bytes);
+       rv = ops->packet ? ops->packet(dev->dev, out_bytes, in_bytes) : -ENOSYS;
 #else
        switch (dev->interface) {
 #ifdef CONFIG_CROS_EC_SPI
@@ -320,7 +322,7 @@ static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
  *                     If not NULL, it will be updated to point to the data
  *                     and will always be double word aligned (64-bits)
  * @param din_len       Maximum size of response in bytes
- * @return number of bytes in response, or -1 on error
+ * @return number of bytes in response, or -ve on error
  */
 static int ec_command_inptr(struct cros_ec_dev *dev, uint8_t cmd,
                int cmd_version, const void *dout, int dout_len, uint8_t **dinp,
@@ -387,7 +389,7 @@ static int ec_command_inptr(struct cros_ec_dev *dev, uint8_t cmd,
  *                     It not NULL, it is a place for ec_command() to copy the
  *      data to.
  * @param din_len       Maximum size of response in bytes
- * @return number of bytes in response, or -1 on error
+ * @return number of bytes in response, or -ve on error
  */
 static int ec_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
                      const void *dout, int dout_len,
@@ -606,10 +608,10 @@ int cros_ec_reboot(struct cros_ec_dev *dev, enum ec_reboot_cmd cmd,
 int cros_ec_interrupt_pending(struct cros_ec_dev *dev)
 {
        /* no interrupt support : always poll */
-       if (!fdt_gpio_isvalid(&dev->ec_int))
+       if (!dm_gpio_is_valid(&dev->ec_int))
                return -ENOENT;
 
-       return !gpio_get_value(dev->ec_int.gpio);
+       return dm_gpio_get_value(&dev->ec_int);
 }
 
 int cros_ec_info(struct cros_ec_dev *dev, struct ec_response_mkbp_info *info)
@@ -1072,7 +1074,8 @@ static int cros_ec_decode_fdt(const void *blob, int node,
                return -1;
        }
 
-       fdtdec_decode_gpio(blob, node, "ec-interrupt", &dev->ec_int);
+       gpio_request_by_name_nodev(blob, node, "ec-interrupt", 0, &dev->ec_int,
+                                  GPIOD_IS_IN);
        dev->optimise_flash_write = fdtdec_get_bool(blob, node,
                                                    "optimise-flash-write");
        *devp = dev;
@@ -1090,17 +1093,11 @@ int cros_ec_register(struct udevice *dev)
        char id[MSG_BYTES];
 
        cdev->dev = dev;
-       fdtdec_decode_gpio(blob, node, "ec-interrupt", &cdev->ec_int);
+       gpio_request_by_name(dev, "ec-interrupt", 0, &cdev->ec_int,
+                            GPIOD_IS_IN);
        cdev->optimise_flash_write = fdtdec_get_bool(blob, node,
                                                     "optimise-flash-write");
 
-       /* we will poll the EC interrupt line */
-       fdtdec_setup_gpio(&cdev->ec_int);
-       if (fdt_gpio_isvalid(&cdev->ec_int)) {
-               gpio_request(cdev->ec_int.gpio, "cros-ec-irq");
-               gpio_direction_input(cdev->ec_int.gpio);
-       }
-
        if (cros_ec_check_version(cdev)) {
                debug("%s: Could not detect CROS-EC version\n", __func__);
                return -CROS_EC_ERR_CHECK_VERSION;
@@ -1184,13 +1181,6 @@ int cros_ec_init(const void *blob, struct cros_ec_dev **cros_ecp)
        }
 #endif
 
-       /* we will poll the EC interrupt line */
-       fdtdec_setup_gpio(&dev->ec_int);
-       if (fdt_gpio_isvalid(&dev->ec_int)) {
-               gpio_request(dev->ec_int.gpio, "cros-ec-irq");
-               gpio_direction_input(dev->ec_int.gpio);
-       }
-
        if (cros_ec_check_version(dev)) {
                debug("%s: Could not detect CROS-EC version\n", __func__);
                return -CROS_EC_ERR_CHECK_VERSION;
index 513cdb1cb09808be69ac6a44be2cb651ad9ac347..f9bc9750d4cb2e617eab6fb4f4dd126d64c9e2b5 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <i2c.h>
 #include <cros_ec.h>
 
 #define debug_trace(fmt, b...)
 #endif
 
-int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
-                    const uint8_t *dout, int dout_len,
-                    uint8_t **dinp, int din_len)
+static int cros_ec_i2c_command(struct udevice *udev, uint8_t cmd,
+                              int cmd_version, const uint8_t *dout,
+                              int dout_len, uint8_t **dinp, int din_len)
 {
-       int old_bus = 0;
+       struct cros_ec_dev *dev = udev->uclass_priv;
        /* version8, cmd8, arglen8, out8[dout_len], csum8 */
        int out_bytes = dout_len + 4;
        /* response8, arglen8, in8[din_len], checksum8 */
@@ -37,8 +38,6 @@ int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
        uint8_t *in_ptr;
        int len, csum, ret;
 
-       old_bus = i2c_get_bus_num();
-
        /*
         * Sanity-check I/O sizes given transaction overhead in internal
         * buffers.
@@ -86,36 +85,24 @@ int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
        *ptr++ = (uint8_t)
                cros_ec_calc_checksum(dev->dout, dout_len + 3);
 
-       /* Set to the proper i2c bus */
-       if (i2c_set_bus_num(dev->bus_num)) {
-               debug("%s: Cannot change to I2C bus %d\n", __func__,
-                       dev->bus_num);
-               return -1;
-       }
-
        /* Send output data */
        cros_ec_dump_data("out", -1, dev->dout, out_bytes);
-       ret = i2c_write(dev->addr, 0, 0, dev->dout, out_bytes);
+       ret = dm_i2c_write(udev, 0, dev->dout, out_bytes);
        if (ret) {
-               debug("%s: Cannot complete I2C write to 0x%x\n",
-                       __func__, dev->addr);
+               debug("%s: Cannot complete I2C write to %s\n", __func__,
+                     udev->name);
                ret = -1;
        }
 
        if (!ret) {
-               ret = i2c_read(dev->addr, 0, 0, in_ptr, in_bytes);
+               ret = dm_i2c_read(udev, 0, in_ptr, in_bytes);
                if (ret) {
-                       debug("%s: Cannot complete I2C read from 0x%x\n",
-                               __func__, dev->addr);
+                       debug("%s: Cannot complete I2C read from %s\n",
+                             __func__, udev->name);
                        ret = -1;
                }
        }
 
-       /* Return to original bus number */
-       i2c_set_bus_num(old_bus);
-       if (ret)
-               return ret;
-
        if (*in_ptr != EC_RES_SUCCESS) {
                debug("%s: Received bad result code %d\n", __func__, *in_ptr);
                return -(int)*in_ptr;
@@ -142,35 +129,24 @@ int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
        return din_len;
 }
 
-int cros_ec_i2c_decode_fdt(struct cros_ec_dev *dev, const void *blob)
+static int cros_ec_probe(struct udevice *dev)
 {
-       /* Decode interface-specific FDT params */
-       dev->max_frequency = fdtdec_get_int(blob, dev->node,
-                                           "i2c-max-frequency", 100000);
-       dev->bus_num = i2c_get_bus_num_fdt(dev->parent_node);
-       if (dev->bus_num == -1) {
-               debug("%s: Failed to read bus number\n", __func__);
-               return -1;
-       }
-       dev->addr = fdtdec_get_int(blob, dev->node, "reg", -1);
-       if (dev->addr == -1) {
-               debug("%s: Failed to read device address\n", __func__);
-               return -1;
-       }
-
-       return 0;
+       return cros_ec_register(dev);
 }
 
-/**
- * Initialize I2C protocol.
- *
- * @param dev          CROS_EC device
- * @param blob         Device tree blob
- * @return 0 if ok, -1 on error
- */
-int cros_ec_i2c_init(struct cros_ec_dev *dev, const void *blob)
-{
-       i2c_init(dev->max_frequency, dev->addr);
-
-       return 0;
-}
+static struct dm_cros_ec_ops cros_ec_ops = {
+       .command = cros_ec_i2c_command,
+};
+
+static const struct udevice_id cros_ec_ids[] = {
+       { .compatible = "google,cros-ec" },
+       { }
+};
+
+U_BOOT_DRIVER(cros_ec_i2c) = {
+       .name           = "cros_ec",
+       .id             = UCLASS_CROS_EC,
+       .of_match       = cros_ec_ids,
+       .probe          = cros_ec_probe,
+       .ops            = &cros_ec_ops,
+};
index e6dba298b1e9f2a37b31b4511cf9c8902c9ff227..9359c56e876d03ed2f798e137df43975afcd2f5d 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#ifdef CONFIG_DM_CROS_EC
 int cros_ec_spi_packet(struct udevice *udev, int out_bytes, int in_bytes)
 {
        struct cros_ec_dev *dev = udev->uclass_priv;
-#else
-int cros_ec_spi_packet(struct cros_ec_dev *dev, int out_bytes, int in_bytes)
-{
-#endif
        struct spi_slave *slave = dev_get_parentdata(dev->dev);
        int rv;
 
@@ -67,18 +62,11 @@ int cros_ec_spi_packet(struct cros_ec_dev *dev, int out_bytes, int in_bytes)
  * @param din_len      Maximum size of response in bytes
  * @return number of bytes in response, or -1 on error
  */
-#ifdef CONFIG_DM_CROS_EC
 int cros_ec_spi_command(struct udevice *udev, uint8_t cmd, int cmd_version,
                     const uint8_t *dout, int dout_len,
                     uint8_t **dinp, int din_len)
 {
        struct cros_ec_dev *dev = udev->uclass_priv;
-#else
-int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
-                    const uint8_t *dout, int dout_len,
-                    uint8_t **dinp, int din_len)
-{
-#endif
        struct spi_slave *slave = dev_get_parentdata(dev->dev);
        int in_bytes = din_len + 4;     /* status, length, checksum, trailer */
        uint8_t *out;
@@ -166,65 +154,12 @@ int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
        return len;
 }
 
-#ifndef CONFIG_DM_CROS_EC
-int cros_ec_spi_decode_fdt(struct cros_ec_dev *dev, const void *blob)
+static int cros_ec_probe(struct udevice *dev)
 {
-       /* Decode interface-specific FDT params */
-       dev->max_frequency = fdtdec_get_int(blob, dev->node,
-                                           "spi-max-frequency", 500000);
-       dev->cs = fdtdec_get_int(blob, dev->node, "reg", 0);
-
-       return 0;
-}
-
-/**
- * Initialize SPI protocol.
- *
- * @param dev          CROS_EC device
- * @param blob         Device tree blob
- * @return 0 if ok, -1 on error
- */
-int cros_ec_spi_init(struct cros_ec_dev *dev, const void *blob)
-{
-       int ret;
-
-       ret = spi_setup_slave_fdt(blob, dev->node, dev->parent_node,
-                                 &slave);
-       if (ret) {
-               debug("%s: Could not setup SPI slave\n", __func__);
-               return ret;
-       }
-
-       return 0;
-}
-#endif
-
-#ifdef CONFIG_DM_CROS_EC
-int cros_ec_probe(struct udevice *dev)
-{
-       struct spi_slave *slave = dev_get_parentdata(dev);
-       int ret;
-
-       /*
-        * TODO(sjg@chromium.org)
-        *
-        * This is really horrible at present. It is an artifact of removing
-        * the child_pre_probe() method for SPI. Everything here could go in
-        * an automatic function, except that spi_get_bus_and_cs() wants to
-        * set it up manually and call device_probe_child().
-        *
-        * The solution may be to re-enable the child_pre_probe() method for
-        * SPI and have it do nothing if the child is already passed in via
-        * device_probe_child().
-        */
-       slave->dev = dev;
-       ret = spi_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, slave);
-       if (ret)
-               return ret;
        return cros_ec_register(dev);
 }
 
-struct dm_cros_ec_ops cros_ec_ops = {
+static struct dm_cros_ec_ops cros_ec_ops = {
        .packet = cros_ec_spi_packet,
        .command = cros_ec_spi_command,
 };
@@ -241,4 +176,3 @@ U_BOOT_DRIVER(cros_ec_spi) = {
        .probe          = cros_ec_probe,
        .ops            = &cros_ec_ops,
 };
-#endif
index a5d34876bbb6d7633f4a8f3dac3c9f21a6b82753..3899372e0e44a82ab9df970fb95e0292fbc19d29 100644 (file)
@@ -102,17 +102,14 @@ struct sdhci_host sdhci_host[SDHCI_MAX_HOSTS];
 
 static int do_sdhci_init(struct sdhci_host *host)
 {
-       char str[20];
        int dev_id, flag;
        int err = 0;
 
        flag = host->bus_width == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE;
        dev_id = host->index + PERIPH_ID_SDMMC0;
 
-       if (fdt_gpio_isvalid(&host->pwr_gpio)) {
-               sprintf(str, "sdhci%d_power", host->index & 0xf);
-               gpio_request(host->pwr_gpio.gpio, str);
-               gpio_direction_output(host->pwr_gpio.gpio, 1);
+       if (dm_gpio_is_valid(&host->pwr_gpio)) {
+               dm_gpio_set_value(&host->pwr_gpio, 1);
                err = exynos_pinmux_config(dev_id, flag);
                if (err) {
                        debug("MMC not configured\n");
@@ -120,11 +117,8 @@ static int do_sdhci_init(struct sdhci_host *host)
                }
        }
 
-       if (fdt_gpio_isvalid(&host->cd_gpio)) {
-               sprintf(str, "sdhci%d_cd", host->index & 0xf);
-               gpio_request(host->cd_gpio.gpio, str);
-               gpio_direction_input(host->cd_gpio.gpio);
-               if (gpio_get_value(host->cd_gpio.gpio))
+       if (dm_gpio_is_valid(&host->cd_gpio)) {
+               if (dm_gpio_get_value(&host->cd_gpio))
                        return -ENODEV;
 
                err = exynos_pinmux_config(dev_id, flag);
@@ -166,8 +160,10 @@ static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host)
        }
        host->ioaddr = (void *)base;
 
-       fdtdec_decode_gpio(blob, node, "pwr-gpios", &host->pwr_gpio);
-       fdtdec_decode_gpio(blob, node, "cd-gpios", &host->cd_gpio);
+       gpio_request_by_name_nodev(blob, node, "pwr-gpios", 0, &host->pwr_gpio,
+                                  GPIOD_IS_OUT);
+       gpio_request_by_name_nodev(blob, node, "cd-gpios", 0, &host->cd_gpio,
+                                  GPIOD_IS_IN);
 
        return 0;
 }
index 2bd36b0ee704a86308bfa0d3c7faa68cc506249a..2cd8cf10aec557cc3a3579f3e292d9ee3f686e90 100644 (file)
@@ -515,8 +515,8 @@ static int tegra_mmc_getcd(struct mmc *mmc)
 
        debug("tegra_mmc_getcd called\n");
 
-       if (fdt_gpio_isvalid(&host->cd_gpio))
-               return fdtdec_get_gpio(&host->cd_gpio);
+       if (dm_gpio_is_valid(&host->cd_gpio))
+               return dm_gpio_get_value(&host->cd_gpio);
 
        return 1;
 }
@@ -531,7 +531,6 @@ static const struct mmc_ops tegra_mmc_ops = {
 static int do_mmc_init(int dev_index)
 {
        struct mmc_host *host;
-       char gpusage[12]; /* "SD/MMCn PWR" or "SD/MMCn CD" */
        struct mmc *mmc;
 
        /* DT should have been read & host config filled in */
@@ -539,27 +538,15 @@ static int do_mmc_init(int dev_index)
        if (!host->enabled)
                return -1;
 
-       debug(" do_mmc_init: index %d, bus width %d "
-               "pwr_gpio %d cd_gpio %d\n",
-               dev_index, host->width,
-               host->pwr_gpio.gpio, host->cd_gpio.gpio);
+       debug(" do_mmc_init: index %d, bus width %d pwr_gpio %d cd_gpio %d\n",
+             dev_index, host->width, gpio_get_number(&host->pwr_gpio),
+             gpio_get_number(&host->cd_gpio));
 
        host->clock = 0;
        clock_start_periph_pll(host->mmc_id, CLOCK_ID_PERIPH, 20000000);
 
-       if (fdt_gpio_isvalid(&host->pwr_gpio)) {
-               sprintf(gpusage, "SD/MMC%d PWR", dev_index);
-               gpio_request(host->pwr_gpio.gpio, gpusage);
-               gpio_direction_output(host->pwr_gpio.gpio, 1);
-               debug(" Power GPIO name = %s\n", host->pwr_gpio.name);
-       }
-
-       if (fdt_gpio_isvalid(&host->cd_gpio)) {
-               sprintf(gpusage, "SD/MMC%d CD", dev_index);
-               gpio_request(host->cd_gpio.gpio, gpusage);
-               gpio_direction_input(host->cd_gpio.gpio);
-               debug(" CD GPIO name = %s\n", host->cd_gpio.name);
-       }
+       if (dm_gpio_is_valid(&host->pwr_gpio))
+               dm_gpio_set_value(&host->pwr_gpio, 1);
 
        memset(&host->cfg, 0, sizeof(host->cfg));
 
@@ -626,9 +613,12 @@ static int mmc_get_config(const void *blob, int node, struct mmc_host *host)
                debug("%s: no sdmmc width found\n", __func__);
 
        /* These GPIOs are optional */
-       fdtdec_decode_gpio(blob, node, "cd-gpios", &host->cd_gpio);
-       fdtdec_decode_gpio(blob, node, "wp-gpios", &host->wp_gpio);
-       fdtdec_decode_gpio(blob, node, "power-gpios", &host->pwr_gpio);
+       gpio_request_by_name_nodev(blob, node, "cd-gpios", 0, &host->cd_gpio,
+                                  GPIOD_IS_IN);
+       gpio_request_by_name_nodev(blob, node, "wp-gpios", 0, &host->wp_gpio,
+                                  GPIOD_IS_IN);
+       gpio_request_by_name_nodev(blob, node, "power-gpios", 0,
+                                  &host->pwr_gpio, GPIOD_IS_OUT);
 
        debug("%s: found controller at %p, width = %d, periph_id = %d\n",
                __func__, host->reg, host->width, host->mmc_id);
index 163cf29a3986058cfc3472241ac2865cd5f99516..b660f3b20662dfbb427dd2770765d2acd1f6a089 100644 (file)
@@ -79,7 +79,7 @@ enum {
 struct fdt_nand {
        struct nand_ctlr *reg;
        int enabled;            /* 1 to enable, 0 to disable */
-       struct fdt_gpio_state wp_gpio;  /* write-protect GPIO */
+       struct gpio_desc wp_gpio;       /* write-protect GPIO */
        s32 width;              /* bit width, normally 8 */
        u32 timing[FDT_NAND_TIMING_COUNT];
 };
@@ -945,8 +945,8 @@ static int fdt_decode_nand(const void *blob, int node, struct fdt_nand *config)
        config->reg = (struct nand_ctlr *)fdtdec_get_addr(blob, node, "reg");
        config->enabled = fdtdec_get_is_enabled(blob, node);
        config->width = fdtdec_get_int(blob, node, "nvidia,nand-width", 8);
-       err = fdtdec_decode_gpio(blob, node, "nvidia,wp-gpios",
-                                &config->wp_gpio);
+       err = gpio_request_by_name_nodev(blob, node, "nvidia,wp-gpios", 0,
+                                &config->wp_gpio, GPIOD_IS_OUT);
        if (err)
                return err;
        err = fdtdec_get_int_array(blob, node, "nvidia,timing",
@@ -1009,8 +1009,7 @@ int tegra_nand_init(struct nand_chip *nand, int devnum)
        /* Adjust timing for NAND device */
        setup_timing(config->timing, info->reg);
 
-       fdtdec_setup_gpio(&config->wp_gpio);
-       gpio_direction_output(config->wp_gpio.gpio, 1);
+       dm_gpio_set_value(&config->wp_gpio, 1);
 
        our_mtd = &nand_info[devnum];
        our_mtd->priv = nand;
index 3024b988fef904884f4d6e4920d98859714f115c..d576d31243a7a90a7213466d7b3ce600a2d1d84f 100644 (file)
@@ -141,8 +141,10 @@ static int sandbox_sf_probe(struct udevice *dev)
                assert(bus->seq != -1);
                if (bus->seq < CONFIG_SANDBOX_SPI_MAX_BUS)
                        spec = state->spi[bus->seq][cs].spec;
-               if (!spec)
-                       return -ENOENT;
+               if (!spec) {
+                       ret = -ENOENT;
+                       goto error;
+               }
 
                file = strchr(spec, ':');
                if (!file) {
@@ -196,6 +198,7 @@ static int sandbox_sf_probe(struct udevice *dev)
        return 0;
 
  error:
+       debug("%s: Got error %d\n", __func__, ret);
        return ret;
 }
 
@@ -587,6 +590,11 @@ int sandbox_sf_bind_emul(struct sandbox_state *state, int busnum, int cs,
 
 void sandbox_sf_unbind_emul(struct sandbox_state *state, int busnum, int cs)
 {
+       struct udevice *dev;
+
+       dev = state->spi[busnum][cs].emul;
+       device_remove(dev);
+       device_unbind(dev);
        state->spi[busnum][cs].emul = NULL;
 }
 
index ce9987fd1a8770aeb8d948030a792553b511ed80..41037238590b650cfe12cfe59c2edd960170db27 100644 (file)
@@ -481,11 +481,12 @@ int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
 int spi_flash_std_probe(struct udevice *dev)
 {
        struct spi_slave *slave = dev_get_parentdata(dev);
+       struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
        struct spi_flash *flash;
 
        flash = dev->uclass_priv;
        flash->dev = dev;
-       debug("%s: slave=%p, cs=%d\n", __func__, slave, slave->cs);
+       debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs);
        return spi_flash_probe_slave(slave, flash);
 }
 
index 9ded8950b83d22aa6021ed8e81ee4141e6d85a23..c03e935e2fb7df54771bf6222b7ce816c53209b3 100644 (file)
@@ -236,8 +236,10 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis)
 
        start = get_timer(0);
        while (readl(&dma_p->busmode) & DMAMAC_SRST) {
-               if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT)
+               if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) {
+                       printf("DMA reset timeout\n");
                        return -1;
+               }
 
                mdelay(100);
        };
index 6531030463cd57c643f58be1520a8f77ef60018d..cd4422215fb0fbbd43c4aefb09e0f0652df01867 100644 (file)
@@ -4927,22 +4927,23 @@ void
 fill_rx(struct e1000_hw *hw)
 {
        struct e1000_rx_desc *rd;
-       uint32_t flush_start, flush_end;
+       unsigned long flush_start, flush_end;
 
        rx_last = rx_tail;
        rd = rx_base + rx_tail;
        rx_tail = (rx_tail + 1) % 8;
        memset(rd, 0, 16);
-       rd->buffer_addr = cpu_to_le64((u32)packet);
+       rd->buffer_addr = cpu_to_le64((unsigned long)packet);
 
        /*
         * Make sure there are no stale data in WB over this area, which
         * might get written into the memory while the e1000 also writes
         * into the same memory area.
         */
-       invalidate_dcache_range((u32)packet, (u32)packet + 4096);
+       invalidate_dcache_range((unsigned long)packet,
+                               (unsigned long)packet + 4096);
        /* Dump the DMA descriptor into RAM. */
-       flush_start = ((u32)rd) & ~(ARCH_DMA_MINALIGN - 1);
+       flush_start = ((unsigned long)rd) & ~(ARCH_DMA_MINALIGN - 1);
        flush_end = flush_start + roundup(sizeof(*rd), ARCH_DMA_MINALIGN);
        flush_dcache_range(flush_start, flush_end);
 
@@ -4963,7 +4964,7 @@ e1000_configure_tx(struct e1000_hw *hw)
        unsigned long tipg, tarc;
        uint32_t ipgr1, ipgr2;
 
-       E1000_WRITE_REG(hw, TDBAL, (u32) tx_base);
+       E1000_WRITE_REG(hw, TDBAL, (unsigned long)tx_base);
        E1000_WRITE_REG(hw, TDBAH, 0);
 
        E1000_WRITE_REG(hw, TDLEN, 128);
@@ -5107,7 +5108,7 @@ e1000_configure_rx(struct e1000_hw *hw)
                E1000_WRITE_FLUSH(hw);
        }
        /* Setup the Base and Length of the Rx Descriptor Ring */
-       E1000_WRITE_REG(hw, RDBAL, (u32) rx_base);
+       E1000_WRITE_REG(hw, RDBAL, (unsigned long)rx_base);
        E1000_WRITE_REG(hw, RDBAH, 0);
 
        E1000_WRITE_REG(hw, RDLEN, 128);
@@ -5138,14 +5139,14 @@ e1000_poll(struct eth_device *nic)
 {
        struct e1000_hw *hw = nic->priv;
        struct e1000_rx_desc *rd;
-       uint32_t inval_start, inval_end;
+       unsigned long inval_start, inval_end;
        uint32_t len;
 
        /* return true if there's an ethernet packet ready to read */
        rd = rx_base + rx_last;
 
        /* Re-load the descriptor from RAM. */
-       inval_start = ((u32)rd) & ~(ARCH_DMA_MINALIGN - 1);
+       inval_start = ((unsigned long)rd) & ~(ARCH_DMA_MINALIGN - 1);
        inval_end = inval_start + roundup(sizeof(*rd), ARCH_DMA_MINALIGN);
        invalidate_dcache_range(inval_start, inval_end);
 
@@ -5154,8 +5155,9 @@ e1000_poll(struct eth_device *nic)
        /*DEBUGOUT("recv: packet len=%d \n", rd->length); */
        /* Packet received, make sure the data are re-loaded from RAM. */
        len = le32_to_cpu(rd->length);
-       invalidate_dcache_range((u32)packet,
-                               (u32)packet + roundup(len, ARCH_DMA_MINALIGN));
+       invalidate_dcache_range((unsigned long)packet,
+                               (unsigned long)packet +
+                               roundup(len, ARCH_DMA_MINALIGN));
        NetReceive((uchar *)packet, len);
        fill_rx(hw);
        return 1;
@@ -5170,7 +5172,7 @@ static int e1000_transmit(struct eth_device *nic, void *txpacket, int length)
        struct e1000_hw *hw = nic->priv;
        struct e1000_tx_desc *txp;
        int i = 0;
-       uint32_t flush_start, flush_end;
+       unsigned long flush_start, flush_end;
 
        txp = tx_base + tx_tail;
        tx_tail = (tx_tail + 1) % 8;
@@ -5180,10 +5182,11 @@ static int e1000_transmit(struct eth_device *nic, void *txpacket, int length)
        txp->upper.data = 0;
 
        /* Dump the packet into RAM so e1000 can pick them. */
-       flush_dcache_range((u32)nv_packet,
-                          (u32)nv_packet + roundup(length, ARCH_DMA_MINALIGN));
+       flush_dcache_range((unsigned long)nv_packet,
+                          (unsigned long)nv_packet +
+                          roundup(length, ARCH_DMA_MINALIGN));
        /* Dump the descriptor into RAM as well. */
-       flush_start = ((u32)txp) & ~(ARCH_DMA_MINALIGN - 1);
+       flush_start = ((unsigned long)txp) & ~(ARCH_DMA_MINALIGN - 1);
        flush_end = flush_start + roundup(sizeof(*txp), ARCH_DMA_MINALIGN);
        flush_dcache_range(flush_start, flush_end);
 
index 507b9a368be72e6d24fea6da9f169cbc2c4cb579..1815b2900ddb2ad1ec80cb9d521bda1ddaa323de 100644 (file)
@@ -22,6 +22,63 @@ static struct phy_driver KSZ804_driver = {
        .shutdown = &genphy_shutdown,
 };
 
+/**
+ * KSZ8895
+ */
+
+static unsigned short smireg_to_phy(unsigned short reg)
+{
+       return ((reg & 0xc0) >> 3) + 0x06 + ((reg & 0x20) >> 5);
+}
+
+static unsigned short smireg_to_reg(unsigned short reg)
+{
+       return reg & 0x1F;
+}
+
+static void ksz8895_write_smireg(struct phy_device *phydev, int smireg, int val)
+{
+       phydev->bus->write(phydev->bus, smireg_to_phy(smireg), MDIO_DEVAD_NONE,
+                                               smireg_to_reg(smireg), val);
+}
+
+#if 0
+static int ksz8895_read_smireg(struct phy_device *phydev, int smireg)
+{
+       return phydev->bus->read(phydev->bus, smireg_to_phy(smireg),
+                                       MDIO_DEVAD_NONE, smireg_to_reg(smireg));
+}
+#endif
+
+int ksz8895_config(struct phy_device *phydev)
+{
+       /* we are connected directly to the switch without
+        * dedicated PHY. SCONF1 == 001 */
+       phydev->link = 1;
+       phydev->duplex = DUPLEX_FULL;
+       phydev->speed = SPEED_100;
+
+       /* Force the switch to start */
+       ksz8895_write_smireg(phydev, 1, 1);
+
+       return 0;
+}
+
+static int ksz8895_startup(struct phy_device *phydev)
+{
+       return 0;
+}
+
+static struct phy_driver ksz8895_driver = {
+       .name = "Micrel KSZ8895/KSZ8864",
+       .uid  = 0x221450,
+       .mask = 0xffffe1,
+       .features = PHY_BASIC_FEATURES,
+       .config   = &ksz8895_config,
+       .startup  = &ksz8895_startup,
+       .shutdown = &genphy_shutdown,
+};
+
 #ifndef CONFIG_PHY_MICREL_KSZ9021
 /*
  * I can't believe Micrel used the exact same part number
@@ -221,5 +278,6 @@ int phy_micrel_init(void)
        phy_register(&KS8721_driver);
 #endif
        phy_register(&ksz9031_driver);
+       phy_register(&ksz8895_driver);
        return 0;
 }
index d9135cb57dfa5b6058a1cc03a8fdc16b81fba92f..e19c491cbce7c00d3f429f9b7d009172bd0b66b5 100644 (file)
@@ -236,7 +236,36 @@ struct smc91111_priv{
                                          *(__b2 + __i) = SMC_inb((a),(r));  \
                                        };  \
                                }while(0)
-
+#elif defined(CONFIG_MS7206SE)
+#define SWAB7206(x) ({ word __x = x; ((__x << 8)|(__x >> 8)); })
+#define SMC_inw(a, r) *((volatile word*)((a)->iobase + (r)))
+#define SMC_inb(a, r) (*((volatile byte*)((a)->iobase + ((r) ^ 0x01))))
+#define SMC_insw(a, r, b, l) \
+       do { \
+               int __i; \
+               word *__b2 = (word *)(b);                 \
+               for (__i = 0; __i < (l); __i++) { \
+                       *__b2++ = SWAB7206(SMC_inw(a, r));      \
+               } \
+       } while (0)
+#define        SMC_outw(a, d, r)       (*((volatile word *)((a)->iobase+(r))) = d)
+#define        SMC_outb(a, d, r)       ({      word __d = (byte)(d);  \
+                               word __w = SMC_inw((a), ((r)&(~1)));    \
+                               if (((r) & 1)) \
+                                       __w = (__w & 0x00ff) | (__d << 8); \
+                               else \
+                                       __w = (__w & 0xff00) | (__d); \
+                               SMC_outw((a), __w, ((r)&(~1)));       \
+                       })
+#define SMC_outsw(a, r, b, l) \
+       do { \
+               int __i; \
+               word *__b2 = (word *)(b);                 \
+               for (__i = 0; __i < (l); __i++) { \
+                       SMC_outw(a, SWAB7206(*__b2), r);          \
+                       __b2++; \
+               } \
+       } while (0)
 #else                  /* if not CONFIG_CPU_PXA25X and not CONFIG_LEON */
 
 #ifndef CONFIG_SMC_USE_IOFUNCS /* these macros don't work on some boards */
index 79d656133adb4d50a7a28dfb529f81121db708ac..dcdba4ea827190759ea9ab0de43239a02024a096 100644 (file)
@@ -597,6 +597,8 @@ static int init_phy(struct eth_device *dev)
                tsec_configure_serdes(priv);
 
        phydev = phy_connect(priv->bus, priv->phyaddr, dev, priv->interface);
+       if (!phydev)
+               return 0;
 
        phydev->supported &= supported;
        phydev->advertising = phydev->supported;
index eb7659177b42310656486d3c911379fe4e151ed1..5729a152e5bb00ed759dfe90bd7750f10b7e20b7 100644 (file)
@@ -98,7 +98,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class,
                               rom_address | PCI_ROM_ADDRESS_ENABLE);
 #endif
        debug("Option ROM address %x\n", rom_address);
-       rom_header = (struct pci_rom_header *)rom_address;
+       rom_header = (struct pci_rom_header *)(unsigned long)rom_address;
 
        debug("PCI expansion ROM, signature %#04x, INIT size %#04x, data ptr %#04x\n",
              le16_to_cpu(rom_header->signature),
index 4c6de79cd608cae49eae25bfbb4973654897ce9a..a60bb5f83fbc5cda5a5533b3893f85e47d450c0a 100644 (file)
@@ -31,7 +31,7 @@ static int as3722_read(struct udevice *pmic, u8 reg, u8 *value)
 {
        int err;
 
-       err = i2c_read(pmic, reg, value, 1);
+       err = dm_i2c_read(pmic, reg, value, 1);
        if (err < 0)
                return err;
 
@@ -42,7 +42,7 @@ static int as3722_write(struct udevice *pmic, u8 reg, u8 value)
 {
        int err;
 
-       err = i2c_write(pmic, reg, &value, 1);
+       err = dm_i2c_write(pmic, reg, &value, 1);
        if (err < 0)
                return err;
 
@@ -242,7 +242,7 @@ int as3722_init(struct udevice **devp)
        const unsigned int address = 0x40;
        int err;
 
-       err = i2c_get_chip_for_busnum(bus, address, &pmic);
+       err = i2c_get_chip_for_busnum(bus, address, 1, &pmic);
        if (err)
                return err;
        err = as3722_read_id(pmic, &id, &revision);
index 29bab4cc00dc7683121fc3302d65c660b9190a3f..865098386d932ae22ce5f3d781e268bede874a95 100644 (file)
@@ -37,7 +37,7 @@ static int tps6586x_read(int reg)
        int     retval = -1;
 
        for (i = 0; i < MAX_I2C_RETRY; ++i) {
-               if (!i2c_read(tps6586x_dev, reg,  &data, 1)) {
+               if (!dm_i2c_read(tps6586x_dev, reg,  &data, 1)) {
                        retval = (int)data;
                        goto exit;
                }
@@ -60,7 +60,7 @@ static int tps6586x_write(int reg, uchar *data, uint len)
        int     retval = -1;
 
        for (i = 0; i < MAX_I2C_RETRY; ++i) {
-               if (!i2c_write(tps6586x_dev, reg, data, len)) {
+               if (!dm_i2c_write(tps6586x_dev, reg, data, len)) {
                        retval = 0;
                        goto exit;
                }
index d1b5777cecda13be6191404cefe6dcf82a92f564..9131a8f93d9a5adff359d2940ddfd6a6a05c445e 100644 (file)
@@ -297,6 +297,7 @@ static int serial_pre_remove(struct udevice *dev)
 UCLASS_DRIVER(serial) = {
        .id             = UCLASS_SERIAL,
        .name           = "serial",
+       .flags          = DM_UC_FLAG_SEQ_ALIAS,
        .post_probe     = serial_post_probe,
        .pre_remove     = serial_pre_remove,
        .per_device_auto_alloc_size = sizeof(struct serial_dev_priv),
index 98ae3b808fb0a970b9e467e94bef0e336458bd19..a75fc46e95dc5f060e0e8a6a3e89ef72e4dfb6ec 100644 (file)
@@ -340,6 +340,5 @@ U_BOOT_DRIVER(cadence_spi) = {
        .ofdata_to_platdata = cadence_spi_ofdata_to_platdata,
        .platdata_auto_alloc_size = sizeof(struct cadence_spi_platdata),
        .priv_auto_alloc_size = sizeof(struct cadence_spi_priv),
-       .per_child_auto_alloc_size = sizeof(struct spi_slave),
        .probe = cadence_spi_probe,
 };
index 700f616ad7630608dc50136f9abf4c148714a7a3..2624844d528566bb7ed786ae06537b4cbf69b777 100644 (file)
@@ -421,6 +421,5 @@ U_BOOT_DRIVER(dw_spi) = {
        .ofdata_to_platdata = dw_spi_ofdata_to_platdata,
        .platdata_auto_alloc_size = sizeof(struct dw_spi_platdata),
        .priv_auto_alloc_size = sizeof(struct dw_spi_priv),
-       .per_child_auto_alloc_size = sizeof(struct spi_slave),
        .probe = dw_spi_probe,
 };
index f078973531c1d960e5635a485e50c42170b45d80..a46d8c187668cff8560eea31c7189c7dfa3b4161 100644 (file)
@@ -425,6 +425,5 @@ U_BOOT_DRIVER(exynos_spi) = {
        .ofdata_to_platdata = exynos_spi_ofdata_to_platdata,
        .platdata_auto_alloc_size = sizeof(struct exynos_spi_platdata),
        .priv_auto_alloc_size = sizeof(struct exynos_spi_priv),
-       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
        .probe  = exynos_spi_probe,
 };
index e717424db83a9ff7dcc15bc57074c5722b66ff11..bad56603ba6809443ee020a4f3459057f166ebf3 100644 (file)
@@ -160,6 +160,5 @@ U_BOOT_DRIVER(spi_sandbox) = {
        .name   = "spi_sandbox",
        .id     = UCLASS_SPI,
        .of_match = sandbox_spi_ids,
-       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
        .ops    = &sandbox_spi_ops,
 };
index 558803618a272cc6e0e8b880ddd89cc8950e6e68..6ae45f5377ab89ba647387029fdfa771dc1ee8ed 100644 (file)
 DECLARE_GLOBAL_DATA_PTR;
 
 struct soft_spi_platdata {
-       struct fdt_gpio_state cs;
-       struct fdt_gpio_state sclk;
-       struct fdt_gpio_state mosi;
-       struct fdt_gpio_state miso;
+       struct gpio_desc cs;
+       struct gpio_desc sclk;
+       struct gpio_desc mosi;
+       struct gpio_desc miso;
        int spi_delay_us;
 };
 
@@ -35,9 +35,8 @@ struct soft_spi_priv {
 static int soft_spi_scl(struct udevice *dev, int bit)
 {
        struct soft_spi_platdata *plat = dev->platdata;
-       struct soft_spi_priv *priv = dev_get_priv(dev);
 
-       gpio_set_value(plat->sclk.gpio, priv->mode & SPI_CPOL ? bit : !bit);
+       dm_gpio_set_value(&plat->sclk, bit);
 
        return 0;
 }
@@ -46,7 +45,7 @@ static int soft_spi_sda(struct udevice *dev, int bit)
 {
        struct soft_spi_platdata *plat = dev->platdata;
 
-       gpio_set_value(plat->mosi.gpio, bit);
+       dm_gpio_set_value(&plat->mosi, bit);
 
        return 0;
 }
@@ -54,11 +53,10 @@ static int soft_spi_sda(struct udevice *dev, int bit)
 static int soft_spi_cs_activate(struct udevice *dev)
 {
        struct soft_spi_platdata *plat = dev->platdata;
-       struct soft_spi_priv *priv = dev_get_priv(dev);
 
-       gpio_set_value(plat->cs.gpio, !(priv->mode & SPI_CS_HIGH));
-       gpio_set_value(plat->sclk.gpio, priv->mode & SPI_CPOL);
-       gpio_set_value(plat->cs.gpio, priv->mode & SPI_CS_HIGH);
+       dm_gpio_set_value(&plat->cs, 0);
+       dm_gpio_set_value(&plat->sclk, 0);
+       dm_gpio_set_value(&plat->cs, 1);
 
        return 0;
 }
@@ -66,9 +64,8 @@ static int soft_spi_cs_activate(struct udevice *dev)
 static int soft_spi_cs_deactivate(struct udevice *dev)
 {
        struct soft_spi_platdata *plat = dev->platdata;
-       struct soft_spi_priv *priv = dev_get_priv(dev);
 
-       gpio_set_value(plat->cs.gpio, !(priv->mode & SPI_CS_HIGH));
+       dm_gpio_set_value(&plat->cs, 0);
 
        return 0;
 }
@@ -109,7 +106,6 @@ static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
        uchar           tmpdout = 0;
        const u8        *txd = dout;
        u8              *rxd = din;
-       int             cpol = priv->mode & SPI_CPOL;
        int             cpha = priv->mode & SPI_CPHA;
        unsigned int    j;
 
@@ -137,19 +133,19 @@ static int soft_spi_xfer(struct udevice *dev, unsigned int bitlen,
                }
 
                if (!cpha)
-                       soft_spi_scl(dev, !cpol);
+                       soft_spi_scl(dev, 0);
                soft_spi_sda(dev, tmpdout & 0x80);
                udelay(plat->spi_delay_us);
                if (cpha)
-                       soft_spi_scl(dev, !cpol);
+                       soft_spi_scl(dev, 0);
                else
-                       soft_spi_scl(dev, cpol);
+                       soft_spi_scl(dev, 1);
                tmpdin  <<= 1;
-               tmpdin  |= gpio_get_value(plat->miso.gpio);
+               tmpdin  |= dm_gpio_get_value(&plat->miso);
                tmpdout <<= 1;
                udelay(plat->spi_delay_us);
                if (cpha)
-                       soft_spi_scl(dev, cpol);
+                       soft_spi_scl(dev, 1);
        }
        /*
         * If the number of bits isn't a multiple of 8, shift the last
@@ -183,14 +179,6 @@ static int soft_spi_set_mode(struct udevice *dev, unsigned int mode)
        return 0;
 }
 
-static int soft_spi_child_pre_probe(struct udevice *dev)
-{
-       struct spi_slave *slave = dev_get_parentdata(dev);
-
-       slave->dev = dev;
-       return spi_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, slave);
-}
-
 static const struct dm_spi_ops soft_spi_ops = {
        .claim_bus      = soft_spi_claim_bus,
        .release_bus    = soft_spi_release_bus,
@@ -205,11 +193,6 @@ static int soft_spi_ofdata_to_platdata(struct udevice *dev)
        const void *blob = gd->fdt_blob;
        int node = dev->of_offset;
 
-       if (fdtdec_decode_gpio(blob, node, "cs-gpio", &plat->cs) ||
-           fdtdec_decode_gpio(blob, node, "sclk-gpio", &plat->sclk) ||
-           fdtdec_decode_gpio(blob, node, "mosi-gpio", &plat->mosi) ||
-           fdtdec_decode_gpio(blob, node, "miso-gpio", &plat->miso))
-               return -EINVAL;
        plat->spi_delay_us = fdtdec_get_int(blob, node, "spi-delay-us", 0);
 
        return 0;
@@ -219,16 +202,19 @@ static int soft_spi_probe(struct udevice *dev)
 {
        struct spi_slave *slave = dev_get_parentdata(dev);
        struct soft_spi_platdata *plat = dev->platdata;
-
-       gpio_request(plat->cs.gpio, "soft_spi_cs");
-       gpio_request(plat->sclk.gpio, "soft_spi_sclk");
-       gpio_request(plat->mosi.gpio, "soft_spi_mosi");
-       gpio_request(plat->miso.gpio, "soft_spi_miso");
-
-       gpio_direction_output(plat->sclk.gpio, slave->mode & SPI_CPOL);
-       gpio_direction_output(plat->mosi.gpio, 1);
-       gpio_direction_input(plat->miso.gpio);
-       gpio_direction_output(plat->cs.gpio, !(slave->mode & SPI_CS_HIGH));
+       int cs_flags, clk_flags;
+
+       cs_flags = (slave->mode & SPI_CS_HIGH) ? 0 : GPIOD_ACTIVE_LOW;
+       clk_flags = (slave->mode & SPI_CPOL) ? GPIOD_ACTIVE_LOW : 0;
+       if (gpio_request_by_name(dev, "cs-gpio", 0, &plat->cs,
+                                GPIOD_IS_OUT | cs_flags) ||
+           gpio_request_by_name(dev, "sclk-gpio", 0, &plat->sclk,
+                                GPIOD_IS_OUT | clk_flags) ||
+           gpio_request_by_name(dev, "mosi-gpio", 0, &plat->mosi,
+                                GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE) ||
+           gpio_request_by_name(dev, "miso-gpio", 0, &plat->miso,
+                                GPIOD_IS_IN))
+               return -EINVAL;
 
        return 0;
 }
@@ -246,7 +232,5 @@ U_BOOT_DRIVER(soft_spi) = {
        .ofdata_to_platdata = soft_spi_ofdata_to_platdata,
        .platdata_auto_alloc_size = sizeof(struct soft_spi_platdata),
        .priv_auto_alloc_size = sizeof(struct soft_spi_priv),
-       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
        .probe  = soft_spi_probe,
-       .child_pre_probe        = soft_spi_child_pre_probe,
 };
index 7a57bceb260f1c3e79fc9ed4d735f1b27c45160b..63a6217cc62d0085b6c4ba259415fae514651ba9 100644 (file)
@@ -98,21 +98,51 @@ int spi_post_bind(struct udevice *dev)
        return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
 }
 
-int spi_post_probe(struct udevice *dev)
+int spi_child_post_bind(struct udevice *dev)
 {
-       struct dm_spi_bus *spi = dev->uclass_priv;
+       struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
 
-       spi->max_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+       if (dev->of_offset == -1)
+               return 0;
+
+       return spi_slave_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat);
+}
+
+int spi_post_probe(struct udevice *bus)
+{
+       struct dm_spi_bus *spi = bus->uclass_priv;
+
+       spi->max_hz = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
                                     "spi-max-frequency", 0);
 
        return 0;
 }
 
-int spi_chip_select(struct udevice *dev)
+int spi_child_pre_probe(struct udevice *dev)
 {
+       struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
        struct spi_slave *slave = dev_get_parentdata(dev);
 
-       return slave ? slave->cs : -ENOENT;
+       /*
+        * This is needed because we pass struct spi_slave around the place
+        * instead slave->dev (a struct udevice). So we have to have some
+        * way to access the slave udevice given struct spi_slave. Once we
+        * change the SPI API to use udevice instead of spi_slave, we can
+        * drop this.
+        */
+       slave->dev = dev;
+
+       slave->max_hz = plat->max_hz;
+       slave->mode = plat->mode;
+
+       return 0;
+}
+
+int spi_chip_select(struct udevice *dev)
+{
+       struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
+
+       return plat ? plat->cs : -ENOENT;
 }
 
 int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp)
@@ -121,17 +151,11 @@ int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp)
 
        for (device_find_first_child(bus, &dev); dev;
             device_find_next_child(&dev)) {
-               struct spi_slave store;
-               struct spi_slave *slave = dev_get_parentdata(dev);
+               struct dm_spi_slave_platdata *plat;
 
-               if (!slave)  {
-                       slave = &store;
-                       spi_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
-                                              slave);
-               }
-               debug("%s: slave=%p, cs=%d\n", __func__, slave,
-                     slave ? slave->cs : -1);
-               if (slave && slave->cs == cs) {
+               plat = dev_get_parent_platdata(dev);
+               debug("%s: plat=%p, cs=%d\n", __func__, plat, plat->cs);
+               if (plat->cs == cs) {
                        *devp = dev;
                        return 0;
                }
@@ -215,7 +239,6 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
                       struct udevice **busp, struct spi_slave **devp)
 {
        struct udevice *bus, *dev;
-       struct spi_slave *slave;
        bool created = false;
        int ret;
 
@@ -232,11 +255,17 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
         * SPI flash chip - we will bind to the correct driver.
         */
        if (ret == -ENODEV && drv_name) {
+               struct dm_spi_slave_platdata *plat;
+
                debug("%s: Binding new device '%s', busnum=%d, cs=%d, driver=%s\n",
                      __func__, dev_name, busnum, cs, drv_name);
                ret = device_bind_driver(bus, drv_name, dev_name, &dev);
                if (ret)
                        return ret;
+               plat = dev_get_parent_platdata(dev);
+               plat->cs = cs;
+               plat->max_hz = speed;
+               plat->mode = mode;
                created = true;
        } else if (ret) {
                printf("Invalid chip select %d:%d (err=%d)\n", busnum, cs,
@@ -245,23 +274,13 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
        }
 
        if (!device_active(dev)) {
-               slave = (struct spi_slave *)calloc(1,
-                                                  sizeof(struct spi_slave));
-               if (!slave) {
-                       ret = -ENOMEM;
-                       goto err;
-               }
+               struct spi_slave *slave;
 
-               ret = spi_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
-                                            slave);
+               ret = device_probe(dev);
                if (ret)
                        goto err;
-               slave->cs = cs;
+               slave = dev_get_parentdata(dev);
                slave->dev = dev;
-               ret = device_probe_child(dev, slave);
-               free(slave);
-               if (ret)
-                       goto err;
        }
 
        ret = spi_set_speed_mode(bus, speed, mode);
@@ -275,6 +294,8 @@ int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
        return 0;
 
 err:
+       debug("%s: Error path, credted=%d, device '%s'\n", __func__,
+             created, dev->name);
        if (created) {
                device_remove(dev);
                device_unbind(dev);
@@ -321,13 +342,13 @@ void spi_free_slave(struct spi_slave *slave)
        slave->dev = NULL;
 }
 
-int spi_ofdata_to_platdata(const void *blob, int node,
-                          struct spi_slave *spi)
+int spi_slave_ofdata_to_platdata(const void *blob, int node,
+                                struct dm_spi_slave_platdata *plat)
 {
        int mode = 0;
 
-       spi->cs = fdtdec_get_int(blob, node, "reg", -1);
-       spi->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 0);
+       plat->cs = fdtdec_get_int(blob, node, "reg", -1);
+       plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 0);
        if (fdtdec_get_bool(blob, node, "spi-cpol"))
                mode |= SPI_CPOL;
        if (fdtdec_get_bool(blob, node, "spi-cpha"))
@@ -336,7 +357,7 @@ int spi_ofdata_to_platdata(const void *blob, int node,
                mode |= SPI_CS_HIGH;
        if (fdtdec_get_bool(blob, node, "spi-half-duplex"))
                mode |= SPI_PREAMBLE;
-       spi->mode = mode;
+       plat->mode = mode;
 
        return 0;
 }
@@ -344,9 +365,15 @@ int spi_ofdata_to_platdata(const void *blob, int node,
 UCLASS_DRIVER(spi) = {
        .id             = UCLASS_SPI,
        .name           = "spi",
+       .flags          = DM_UC_FLAG_SEQ_ALIAS,
        .post_bind      = spi_post_bind,
        .post_probe     = spi_post_probe,
+       .child_pre_probe = spi_child_pre_probe,
        .per_device_auto_alloc_size = sizeof(struct dm_spi_bus),
+       .per_child_auto_alloc_size = sizeof(struct spi_slave),
+       .per_child_platdata_auto_alloc_size =
+                       sizeof(struct dm_spi_slave_platdata),
+       .child_post_bind = spi_child_post_bind,
 };
 
 UCLASS_DRIVER(spi_generic) = {
index 2d97625fba73b81dcb8a2ba2d55d5e1d5eef0bcb..53ff9ea22105353180159203def640905b5fecf8 100644 (file)
@@ -407,6 +407,5 @@ U_BOOT_DRIVER(tegra114_spi) = {
        .ofdata_to_platdata = tegra114_spi_ofdata_to_platdata,
        .platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata),
        .priv_auto_alloc_size = sizeof(struct tegra114_spi_priv),
-       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
        .probe  = tegra114_spi_probe,
 };
index 7d0d0f37fc70a7f5f5da821b2af8589bf59ac7a1..78c74cdf37fe095d8efa34c26ab5df0093e305bd 100644 (file)
@@ -348,6 +348,5 @@ U_BOOT_DRIVER(tegra20_sflash) = {
        .ofdata_to_platdata = tegra20_sflash_ofdata_to_platdata,
        .platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata),
        .priv_auto_alloc_size = sizeof(struct tegra20_sflash_priv),
-       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
        .probe  = tegra20_sflash_probe,
 };
index 213fa5f7939a848889e0168d1991040dd9830a61..597d6ad5ccecb8e36818bb6d2d555c2f3b14294f 100644 (file)
@@ -361,6 +361,5 @@ U_BOOT_DRIVER(tegra30_spi) = {
        .ofdata_to_platdata = tegra30_spi_ofdata_to_platdata,
        .platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata),
        .priv_auto_alloc_size = sizeof(struct tegra30_spi_priv),
-       .per_child_auto_alloc_size      = sizeof(struct spi_slave),
        .probe  = tegra30_spi_probe,
 };
index 6fdbf5724f4a6527757d8cec692c9a59c7529b6a..f3c077d82e4d4c726ef99c32189f759571feb46e 100644 (file)
@@ -31,7 +31,7 @@ DECLARE_GLOBAL_DATA_PTR;
 struct exynos_ehci {
        struct exynos_usb_phy *usb;
        struct ehci_hccr *hcd;
-       struct fdt_gpio_state vbus_gpio;
+       struct gpio_desc vbus_gpio;
 };
 
 static struct exynos_ehci exynos;
@@ -61,7 +61,8 @@ static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos)
        exynos->hcd = (struct ehci_hccr *)addr;
 
        /* Vbus gpio */
-       fdtdec_decode_gpio(blob, node, "samsung,vbus-gpio", &exynos->vbus_gpio);
+       gpio_request_by_name_nodev(blob, node, "samsung,vbus-gpio", 0,
+                                  &exynos->vbus_gpio, GPIOD_IS_OUT);
 
        depth = 0;
        node = fdtdec_next_compatible_subnode(blob, node,
@@ -236,9 +237,8 @@ int ehci_hcd_init(int index, enum usb_init_type init,
 
 #ifdef CONFIG_OF_CONTROL
        /* setup the Vbus gpio here */
-       if (fdt_gpio_isvalid(&ctx->vbus_gpio) &&
-           !fdtdec_setup_gpio(&ctx->vbus_gpio))
-               gpio_direction_output(ctx->vbus_gpio.gpio, 1);
+       if (dm_gpio_is_valid(&ctx->vbus_gpio))
+               dm_gpio_set_value(&ctx->vbus_gpio, 1);
 #endif
 
        setup_usb_phy(ctx->usb);
index 5f0a98e8b80b59f79372e2185e31e16585c6dd7f..b5ad1e35e54c668fa0e5d3c9207d74d39904527a 100644 (file)
@@ -72,8 +72,8 @@ struct fdt_usb {
        enum usb_init_type init_type;
        enum dr_mode dr_mode;   /* dual role mode */
        enum periph_id periph_id;/* peripheral id */
-       struct fdt_gpio_state vbus_gpio;        /* GPIO for vbus enable */
-       struct fdt_gpio_state phy_reset_gpio; /* GPIO to reset ULPI phy */
+       struct gpio_desc vbus_gpio;     /* GPIO for vbus enable */
+       struct gpio_desc phy_reset_gpio; /* GPIO to reset ULPI phy */
 };
 
 static struct fdt_usb port[USB_PORTS_MAX];     /* List of valid USB ports */
@@ -252,17 +252,14 @@ static void set_up_vbus(struct fdt_usb *config, enum usb_init_type init)
                return;
        }
 
-       if (fdt_gpio_isvalid(&config->vbus_gpio)) {
+       if (dm_gpio_is_valid(&config->vbus_gpio)) {
                int vbus_value;
 
-               fdtdec_setup_gpio(&config->vbus_gpio);
+               vbus_value = (init == USB_INIT_HOST);
+               dm_gpio_set_value(&config->vbus_gpio, vbus_value);
 
-               vbus_value = (init == USB_INIT_HOST) ^
-                            !!(config->vbus_gpio.flags & FDT_GPIO_ACTIVE_LOW);
-               gpio_direction_output(config->vbus_gpio.gpio, vbus_value);
-
-               debug("set_up_vbus: GPIO %d %d\n", config->vbus_gpio.gpio,
-                     vbus_value);
+               debug("set_up_vbus: GPIO %d %d\n",
+                     gpio_get_number(&config->vbus_gpio), vbus_value);
        }
 }
 
@@ -360,7 +357,7 @@ static int init_utmi_usb_controller(struct fdt_usb *config,
         * mux must be switched to actually use a_sess_vld threshold.
         */
        if (config->dr_mode == DR_MODE_OTG &&
-           fdt_gpio_isvalid(&config->vbus_gpio))
+           dm_gpio_is_valid(&config->vbus_gpio))
                clrsetbits_le32(&usbctlr->usb1_legacy_ctrl,
                        VBUS_SENSE_CTL_MASK,
                        VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT);
@@ -569,11 +566,10 @@ static int init_ulpi_usb_controller(struct fdt_usb *config,
        clock_set_pllout(CLOCK_ID_PERIPH, PLL_OUT4, CONFIG_ULPI_REF_CLK);
 
        /* reset ULPI phy */
-       if (fdt_gpio_isvalid(&config->phy_reset_gpio)) {
-               fdtdec_setup_gpio(&config->phy_reset_gpio);
-               gpio_direction_output(config->phy_reset_gpio.gpio, 0);
+       if (dm_gpio_is_valid(&config->phy_reset_gpio)) {
+               dm_gpio_set_value(&config->phy_reset_gpio, 0);
                mdelay(5);
-               gpio_set_value(config->phy_reset_gpio.gpio, 1);
+               dm_gpio_set_value(&config->phy_reset_gpio, 1);
        }
 
        /* Reset the usb controller */
@@ -685,14 +681,16 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config)
                debug("%s: Missing/invalid peripheral ID\n", __func__);
                return -FDT_ERR_NOTFOUND;
        }
-       fdtdec_decode_gpio(blob, node, "nvidia,vbus-gpio", &config->vbus_gpio);
-       fdtdec_decode_gpio(blob, node, "nvidia,phy-reset-gpio",
-                       &config->phy_reset_gpio);
+       gpio_request_by_name_nodev(blob, node, "nvidia,vbus-gpio", 0,
+                                  &config->vbus_gpio, GPIOD_IS_OUT);
+       gpio_request_by_name_nodev(blob, node, "nvidia,phy-reset-gpio", 0,
+                                  &config->phy_reset_gpio, GPIOD_IS_OUT);
        debug("enabled=%d, legacy_mode=%d, utmi=%d, ulpi=%d, periph_id=%d, "
                "vbus=%d, phy_reset=%d, dr_mode=%d\n",
                config->enabled, config->has_legacy_mode, config->utmi,
-               config->ulpi, config->periph_id, config->vbus_gpio.gpio,
-               config->phy_reset_gpio.gpio, config->dr_mode);
+               config->ulpi, config->periph_id,
+               gpio_get_number(&config->vbus_gpio),
+               gpio_get_number(&config->phy_reset_gpio), config->dr_mode);
 
        return 0;
 }
index b4946a3f1cf5900614e7238f8033979876eac942..a77c8bc91930524e75de4749accb927ab9d2d586 100644 (file)
@@ -40,7 +40,7 @@ struct exynos_xhci {
        struct exynos_usb3_phy *usb3_phy;
        struct xhci_hccr *hcd;
        struct dwc3 *dwc3_reg;
-       struct fdt_gpio_state vbus_gpio;
+       struct gpio_desc vbus_gpio;
 };
 
 static struct exynos_xhci exynos;
@@ -69,7 +69,8 @@ static int exynos_usb3_parse_dt(const void *blob, struct exynos_xhci *exynos)
        exynos->hcd = (struct xhci_hccr *)addr;
 
        /* Vbus gpio */
-       fdtdec_decode_gpio(blob, node, "samsung,vbus-gpio", &exynos->vbus_gpio);
+       gpio_request_by_name_nodev(blob, node, "samsung,vbus-gpio", 0,
+                                  &exynos->vbus_gpio, GPIOD_IS_OUT);
 
        depth = 0;
        node = fdtdec_next_compatible_subnode(blob, node,
@@ -298,9 +299,8 @@ int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
 
 #ifdef CONFIG_OF_CONTROL
        /* setup the Vbus gpio here */
-       if (fdt_gpio_isvalid(&ctx->vbus_gpio) &&
-           !fdtdec_setup_gpio(&ctx->vbus_gpio))
-               gpio_direction_output(ctx->vbus_gpio.gpio, 1);
+       if (dm_gpio_is_valid(&ctx->vbus_gpio))
+               dm_gpio_set_value(&ctx->vbus_gpio, 1);
 #endif
 
        ret = exynos_xhci_core_init(ctx);
index 57cb0074e277f97e35e40d78e889c31437cd156b..b8f3431f242339c96cd0a9e28fffa435b4aef0fa 100644 (file)
@@ -149,14 +149,18 @@ static int fdt_decode_lcd(const void *blob, struct fdt_panel_config *config)
                                            FDT_LCD_CACHE_WRITE_BACK_FLUSH);
 
        /* These GPIOs are all optional */
-       fdtdec_decode_gpio(blob, display_node, "nvidia,backlight-enable-gpios",
-                           &config->backlight_en);
-       fdtdec_decode_gpio(blob, display_node, "nvidia,lvds-shutdown-gpios",
-                          &config->lvds_shutdown);
-       fdtdec_decode_gpio(blob, display_node, "nvidia,backlight-vdd-gpios",
-                          &config->backlight_vdd);
-       fdtdec_decode_gpio(blob, display_node, "nvidia,panel-vdd-gpios",
-                          &config->panel_vdd);
+       gpio_request_by_name_nodev(blob, display_node,
+                                  "nvidia,backlight-enable-gpios", 0,
+                                  &config->backlight_en, GPIOD_IS_OUT);
+       gpio_request_by_name_nodev(blob, display_node,
+                                  "nvidia,lvds-shutdown-gpios", 0,
+                                  &config->lvds_shutdown, GPIOD_IS_OUT);
+       gpio_request_by_name_nodev(blob, display_node,
+                                  "nvidia,backlight-vdd-gpios", 0,
+                                  &config->backlight_vdd, GPIOD_IS_OUT);
+       gpio_request_by_name_nodev(blob, display_node,
+                                  "nvidia,panel-vdd-gpios", 0,
+                                  &config->panel_vdd, GPIOD_IS_OUT);
 
        return fdtdec_get_int_array(blob, display_node, "nvidia,panel-timings",
                        config->panel_timings, FDT_LCD_TIMINGS);
@@ -196,36 +200,18 @@ static int handle_stage(const void *blob)
                 */
 
                funcmux_select(PERIPH_ID_DISP1, FUNCMUX_DEFAULT);
-
-               fdtdec_setup_gpio(&config.panel_vdd);
-               fdtdec_setup_gpio(&config.lvds_shutdown);
-               fdtdec_setup_gpio(&config.backlight_vdd);
-               fdtdec_setup_gpio(&config.backlight_en);
-
-               /*
-                * TODO: If fdt includes output flag we can omit this code
-                * since fdtdec_setup_gpio will do it for us.
-                */
-               if (fdt_gpio_isvalid(&config.panel_vdd))
-                       gpio_direction_output(config.panel_vdd.gpio, 0);
-               if (fdt_gpio_isvalid(&config.lvds_shutdown))
-                       gpio_direction_output(config.lvds_shutdown.gpio, 0);
-               if (fdt_gpio_isvalid(&config.backlight_vdd))
-                       gpio_direction_output(config.backlight_vdd.gpio, 0);
-               if (fdt_gpio_isvalid(&config.backlight_en))
-                       gpio_direction_output(config.backlight_en.gpio, 0);
                break;
        case STAGE_PANEL_VDD:
-               if (fdt_gpio_isvalid(&config.panel_vdd))
-                       gpio_direction_output(config.panel_vdd.gpio, 1);
+               if (dm_gpio_is_valid(&config.panel_vdd))
+                       dm_gpio_set_value(&config.panel_vdd, 1);
                break;
        case STAGE_LVDS:
-               if (fdt_gpio_isvalid(&config.lvds_shutdown))
-                       gpio_set_value(config.lvds_shutdown.gpio, 1);
+               if (dm_gpio_is_valid(&config.lvds_shutdown))
+                       dm_gpio_set_value(&config.lvds_shutdown, 1);
                break;
        case STAGE_BACKLIGHT_VDD:
-               if (fdt_gpio_isvalid(&config.backlight_vdd))
-                       gpio_set_value(config.backlight_vdd.gpio, 1);
+               if (dm_gpio_is_valid(&config.backlight_vdd))
+                       dm_gpio_set_value(&config.backlight_vdd, 1);
                break;
        case STAGE_PWM:
                /* Enable PWM at 15/16 high, 32768 Hz with divider 1 */
@@ -235,8 +221,8 @@ static int handle_stage(const void *blob)
                pwm_enable(config.pwm_channel, 32768, 0xdf, 1);
                break;
        case STAGE_BACKLIGHT_EN:
-               if (fdt_gpio_isvalid(&config.backlight_en))
-                       gpio_set_value(config.backlight_en.gpio, 1);
+               if (dm_gpio_is_valid(&config.backlight_en))
+                       dm_gpio_set_value(&config.backlight_en, 1);
                break;
        case STAGE_DONE:
                break;
index 0bf690e73d157fffa65d423060227aced9865fe3..920a0a9cf3b4ae96c2ba3aa21394dde4fd50318b 100644 (file)
@@ -2,6 +2,8 @@
 #include <exports.h>
 #include <linux/compiler.h>
 
+#define FO(x) offsetof(struct jt_funcs, x)
+
 #if defined(CONFIG_X86)
 /*
  * x86 does not have a dedicated register to store the pointer to
  * from flash memory. The global_data address is passed as argv[-1]
  * to the application program.
  */
-static void **jt;
+static struct jt_funcs *jt;
 gd_t *global_data;
 
-#define EXPORT_FUNC(x) \
+#define EXPORT_FUNC(f, a, x, ...) \
        asm volatile (                  \
 "      .globl " #x "\n"                \
 #x ":\n"                               \
 "      movl    %0, %%eax\n"            \
 "      movl    jt, %%ecx\n"            \
 "      jmp     *(%%ecx, %%eax)\n"      \
-       : : "i"(XF_ ## x * sizeof(void *)) : "eax", "ecx");
+       : : "i"(FO(x)) : "eax", "ecx");
 #elif defined(CONFIG_PPC)
 /*
  * r2 holds the pointer to the global_data, r11 is a call-clobbered
  * register
  */
-#define EXPORT_FUNC(x) \
+#define EXPORT_FUNC(f, a, x, ...) \
        asm volatile (                  \
 "      .globl " #x "\n"                \
 #x ":\n"                               \
@@ -34,33 +36,33 @@ gd_t *global_data;
 "      lwz     %%r11, %1(%%r11)\n"     \
 "      mtctr   %%r11\n"                \
 "      bctr\n"                         \
-       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r11");
+       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r11");
 #elif defined(CONFIG_ARM)
 #ifdef CONFIG_ARM64
 /*
  * x18 holds the pointer to the global_data, x9 is a call-clobbered
  * register
  */
-#define EXPORT_FUNC(x) \
+#define EXPORT_FUNC(f, a, x, ...) \
        asm volatile (                  \
 "      .globl " #x "\n"                \
 #x ":\n"                               \
 "      ldr     x9, [x18, %0]\n"                \
 "      ldr     x9, [x9, %1]\n"         \
 "      br      x9\n"           \
-       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "x9");
+       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "x9");
 #else
 /*
  * r9 holds the pointer to the global_data, ip is a call-clobbered
  * register
  */
-#define EXPORT_FUNC(x) \
+#define EXPORT_FUNC(f, a, x, ...) \
        asm volatile (                  \
 "      .globl " #x "\n"                \
 #x ":\n"                               \
 "      ldr     ip, [r9, %0]\n"         \
 "      ldr     pc, [ip, %1]\n"         \
-       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "ip");
+       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "ip");
 #endif
 #elif defined(CONFIG_MIPS)
 /*
@@ -70,19 +72,19 @@ gd_t *global_data;
  * it; however, GCC/mips generates an additional `nop' after each asm
  * statement
  */
-#define EXPORT_FUNC(x) \
+#define EXPORT_FUNC(f, a, x, ...) \
        asm volatile (                  \
 "      .globl " #x "\n"                \
 #x ":\n"                               \
 "      lw      $25, %0($26)\n"         \
 "      lw      $25, %1($25)\n"         \
 "      jr      $25\n"                  \
-       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "t9");
+       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t9");
 #elif defined(CONFIG_NIOS2)
 /*
  * gp holds the pointer to the global_data, r8 is call-clobbered
  */
-#define EXPORT_FUNC(x) \
+#define EXPORT_FUNC(f, a, x, ...) \
        asm volatile (                  \
 "      .globl " #x "\n"                \
 #x ":\n"                               \
@@ -92,13 +94,13 @@ gd_t *global_data;
 "      ldw     r8, 0(r8)\n"            \
 "      ldw     r8, %1(r8)\n"           \
 "      jmp     r8\n"                   \
-       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "gp");
+       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "gp");
 #elif defined(CONFIG_M68K)
 /*
  * d7 holds the pointer to the global_data, a0 is a call-clobbered
  * register
  */
-#define EXPORT_FUNC(x) \
+#define EXPORT_FUNC(f, a, x, ...) \
        asm volatile (                  \
 "      .globl " #x "\n"                \
 #x ":\n"                               \
@@ -108,50 +110,50 @@ gd_t *global_data;
 "      adda.l  %1, %%a0\n"             \
 "      move.l  (%%a0), %%a0\n"         \
 "      jmp     (%%a0)\n"                       \
-       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "a0");
+       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "a0");
 #elif defined(CONFIG_MICROBLAZE)
 /*
  * r31 holds the pointer to the global_data. r5 is a call-clobbered.
  */
-#define EXPORT_FUNC(x)                         \
+#define EXPORT_FUNC(f, a, x, ...)                              \
        asm volatile (                          \
 "      .globl " #x "\n"                        \
 #x ":\n"                                       \
 "      lwi     r5, r31, %0\n"                  \
 "      lwi     r5, r5, %1\n"                   \
 "      bra     r5\n"                           \
-       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r5");
+       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r5");
 #elif defined(CONFIG_BLACKFIN)
 /*
  * P3 holds the pointer to the global_data, P0 is a call-clobbered
  * register
  */
-#define EXPORT_FUNC(x)                 \
+#define EXPORT_FUNC(f, a, x, ...)                      \
        asm volatile (                  \
 "      .globl _" #x "\n_"              \
 #x ":\n"                               \
 "      P0 = [P3 + %0]\n"               \
 "      P0 = [P0 + %1]\n"               \
 "      JUMP (P0)\n"                    \
-       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "P0");
+       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "P0");
 #elif defined(CONFIG_AVR32)
 /*
  * r6 holds the pointer to the global_data. r8 is call clobbered.
  */
-#define EXPORT_FUNC(x)                                 \
+#define EXPORT_FUNC(f, a, x, ...)                                      \
        asm volatile(                                   \
                "       .globl\t" #x "\n"               \
                #x ":\n"                                \
                "       ld.w    r8, r6[%0]\n"           \
                "       ld.w    pc, r8[%1]\n"           \
                :                                       \
-               : "i"(offsetof(gd_t, jt)), "i"(XF_ ##x) \
+               : "i"(offsetof(gd_t, jt)), "i"(FO(x))   \
                : "r8");
 #elif defined(CONFIG_SH)
 /*
  * r13 holds the pointer to the global_data. r1 is a call clobbered.
  */
-#define EXPORT_FUNC(x)                                 \
+#define EXPORT_FUNC(f, a, x, ...)                                      \
        asm volatile (                                  \
                "       .align  2\n"                    \
                "       .globl " #x "\n"                \
@@ -164,12 +166,12 @@ gd_t *global_data;
                "       jmp     @r1\n"                  \
                "       nop\n"                          \
                "       nop\n"                          \
-               : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r1", "r2");
+               : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r1", "r2");
 #elif defined(CONFIG_SPARC)
 /*
  * g7 holds the pointer to the global_data. g1 is call clobbered.
  */
-#define EXPORT_FUNC(x)                                 \
+#define EXPORT_FUNC(f, a, x, ...)                                      \
        asm volatile(                                   \
 "      .globl\t" #x "\n"                               \
 #x ":\n"                                               \
@@ -179,26 +181,26 @@ gd_t *global_data;
 "      ld [%%g1 + %1], %%g1\n"                         \
 "      jmp %%g1\n"                                     \
 "      nop\n"                                          \
-       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "g1" );
+       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "g1");
 #elif defined(CONFIG_NDS32)
 /*
  * r16 holds the pointer to the global_data. gp is call clobbered.
  * not support reduced register (16 GPR).
  */
-#define EXPORT_FUNC(x) \
+#define EXPORT_FUNC(f, a, x, ...) \
        asm volatile (                  \
 "      .globl " #x "\n"                \
 #x ":\n"                               \
 "      lwi     $r16, [$gp + (%0)]\n"   \
 "      lwi     $r16, [$r16 + (%1)]\n"  \
 "      jr      $r16\n"                 \
-       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "$r16");
+       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "$r16");
 #elif defined(CONFIG_OPENRISC)
 /*
  * r10 holds the pointer to the global_data, r13 is a call-clobbered
  * register
  */
-#define EXPORT_FUNC(x) \
+#define EXPORT_FUNC(f, a, x, ...) \
        asm volatile (                  \
 "      .globl " #x "\n"                \
 #x ":\n"                               \
@@ -206,12 +208,12 @@ gd_t *global_data;
 "      l.lwz   r13, %1(r13)\n" \
 "      l.jr    r13\n"          \
 "      l.nop\n"                                \
-       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r13");
+       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r13");
 #elif defined(CONFIG_ARC)
 /*
  * r25 holds the pointer to the global_data. r10 is call clobbered.
   */
-#define EXPORT_FUNC(x) \
+#define EXPORT_FUNC(f, a, x, ...) \
        asm volatile( \
 "      .align 4\n" \
 "      .globl " #x "\n" \
@@ -219,7 +221,7 @@ gd_t *global_data;
 "      ld      r10, [r25, %0]\n" \
 "      ld      r10, [r10, %1]\n" \
 "      j       [r10]\n" \
-       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r10");
+       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r10");
 #else
 /*"    addi    $sp, $sp, -24\n"        \
 "      br      $r16\n"                 \*/
diff --git a/fs/fs.c b/fs/fs.c
index ddd751c9cccc1d4c30ed6d29bf1d55581e208ab7..483273fe20b8212075f74526cb86aa2ae3e36988 100644 (file)
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -79,6 +79,7 @@ static inline int fs_uuid_unsupported(char *uuid_str)
 
 struct fstype_info {
        int fstype;
+       char *name;
        /*
         * Is it legal to pass NULL as .probe()'s  fs_dev_desc parameter? This
         * should be false in most cases. For "virtual" filesystems which
@@ -105,6 +106,7 @@ static struct fstype_info fstypes[] = {
 #ifdef CONFIG_FS_FAT
        {
                .fstype = FS_TYPE_FAT,
+               .name = "fat",
                .null_dev_desc_ok = false,
                .probe = fat_set_blk_dev,
                .close = fat_close,
@@ -123,6 +125,7 @@ static struct fstype_info fstypes[] = {
 #ifdef CONFIG_FS_EXT4
        {
                .fstype = FS_TYPE_EXT,
+               .name = "ext4",
                .null_dev_desc_ok = false,
                .probe = ext4fs_probe,
                .close = ext4fs_close,
@@ -141,6 +144,7 @@ static struct fstype_info fstypes[] = {
 #ifdef CONFIG_SANDBOX
        {
                .fstype = FS_TYPE_SANDBOX,
+               .name = "sandbox",
                .null_dev_desc_ok = true,
                .probe = sandbox_fs_set_blk_dev,
                .close = sandbox_fs_close,
@@ -154,6 +158,7 @@ static struct fstype_info fstypes[] = {
 #endif
        {
                .fstype = FS_TYPE_ANY,
+               .name = "unsupported",
                .null_dev_desc_ok = true,
                .probe = fs_probe_unsupported,
                .close = fs_close_unsupported,
@@ -190,6 +195,7 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)
        if (!relocated) {
                for (i = 0, info = fstypes; i < ARRAY_SIZE(fstypes);
                                i++, info++) {
+                       info->name += gd->reloc_off;
                        info->probe += gd->reloc_off;
                        info->close += gd->reloc_off;
                        info->ls += gd->reloc_off;
@@ -503,3 +509,24 @@ int do_fs_uuid(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
 
        return CMD_RET_SUCCESS;
 }
+
+int do_fs_type(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       struct fstype_info *info;
+
+       if (argc < 3 || argc > 4)
+               return CMD_RET_USAGE;
+
+       if (fs_set_blk_dev(argv[1], argv[2], FS_TYPE_ANY))
+               return 1;
+
+       info = fs_get_info(fs_type);
+
+       if (argc == 4)
+               setenv(argv[3], info->name);
+       else
+               printf("%s\n", info->name);
+
+       return CMD_RET_SUCCESS;
+}
+
index 349a3c5522ff876f5fba77731a53a56a15371e84..594470328ea8a7aca5b83e359457410806eaf2c3 100644 (file)
@@ -1,32 +1,73 @@
 /*
- * You do not need to use #ifdef around functions that may not exist
+ * You need to use #ifdef around functions that may not exist
  * in the final configuration (such as i2c).
+ * use a dummyfunction as first parameter to EXPORT_FUNC.
+ * As an example see the CONFIG_CMD_I2C section below
  */
-EXPORT_FUNC(get_version)
-EXPORT_FUNC(getc)
-EXPORT_FUNC(tstc)
-EXPORT_FUNC(putc)
-EXPORT_FUNC(puts)
-EXPORT_FUNC(printf)
-EXPORT_FUNC(install_hdlr)
-EXPORT_FUNC(free_hdlr)
-EXPORT_FUNC(malloc)
-EXPORT_FUNC(free)
-EXPORT_FUNC(udelay)
-EXPORT_FUNC(get_timer)
-EXPORT_FUNC(vprintf)
-EXPORT_FUNC(do_reset)
-EXPORT_FUNC(getenv)
-EXPORT_FUNC(setenv)
-EXPORT_FUNC(simple_strtoul)
-EXPORT_FUNC(strict_strtoul)
-EXPORT_FUNC(simple_strtol)
-EXPORT_FUNC(strcmp)
-EXPORT_FUNC(i2c_write)
-EXPORT_FUNC(i2c_read)
-EXPORT_FUNC(spi_init)
-EXPORT_FUNC(spi_setup_slave)
-EXPORT_FUNC(spi_free_slave)
-EXPORT_FUNC(spi_claim_bus)
-EXPORT_FUNC(spi_release_bus)
-EXPORT_FUNC(spi_xfer)
+#ifndef EXPORT_FUNC
+#define EXPORT_FUNC(a, b, c, ...)
+#endif
+       EXPORT_FUNC(get_version, unsigned long, get_version, void)
+       EXPORT_FUNC(getc, int, getc, void)
+       EXPORT_FUNC(tstc, int, tstc, void)
+       EXPORT_FUNC(putc, void, putc, const char)
+       EXPORT_FUNC(puts, void, puts, const char *)
+       EXPORT_FUNC(printf, int, printf, const char*, ...)
+#if defined(CONFIG_X86) || defined(CONFIG_PPC)
+       EXPORT_FUNC(irq_install_handler, void, install_hdlr,
+                   int, interrupt_handler_t, void*)
+
+       EXPORT_FUNC(irq_free_handler, void, free_hdlr, int)
+#else
+       EXPORT_FUNC(dummy, void, install_hdlr, void)
+       EXPORT_FUNC(dummy, void, free_hdlr, void)
+#endif
+       EXPORT_FUNC(malloc, void *, malloc, size_t)
+       EXPORT_FUNC(free, void, free, void *)
+       EXPORT_FUNC(udelay, void, udelay, unsigned long)
+       EXPORT_FUNC(get_timer, unsigned long, get_timer, unsigned long)
+       EXPORT_FUNC(vprintf, int, vprintf, const char *, va_list)
+       EXPORT_FUNC(do_reset, int, do_reset, cmd_tbl_t *,
+                   int , int , char * const [])
+       EXPORT_FUNC(getenv, char  *, getenv, const char*)
+       EXPORT_FUNC(setenv, int, setenv, const char *, const char *)
+       EXPORT_FUNC(simple_strtoul, unsigned long, simple_strtoul,
+                   const char *, char **, unsigned int)
+       EXPORT_FUNC(strict_strtoul, int, strict_strtoul,
+                   const char *, unsigned int , unsigned long *)
+       EXPORT_FUNC(simple_strtol, long, simple_strtol,
+                   const char *, char **, unsigned int)
+       EXPORT_FUNC(strcmp, int, strcmp, const char *cs, const char *ct)
+#if defined(CONFIG_CMD_I2C) && \
+               (!defined(CONFIG_DM_I2C) || defined(CONFIG_DM_I2C_COMPAT))
+       EXPORT_FUNC(i2c_write, int, i2c_write, uchar, uint, int , uchar * , int)
+       EXPORT_FUNC(i2c_read, int, i2c_read, uchar, uint, int , uchar * , int)
+#else
+       EXPORT_FUNC(dummy, void, i2c_write, void)
+       EXPORT_FUNC(dummy, void, i2c_read, void)
+#endif
+
+#if !defined(CONFIG_CMD_SPI) || defined(CONFIG_DM_SPI)
+       EXPORT_FUNC(dummy, void, spi_init, void)
+       EXPORT_FUNC(dummy, void, spi_setup_slave, void)
+       EXPORT_FUNC(dummy, void, spi_free_slave, void)
+#else
+       EXPORT_FUNC(spi_init, void, spi_init, void)
+       EXPORT_FUNC(spi_setup_slave, struct spi_slave *, spi_setup_slave,
+                   unsigned int, unsigned int, unsigned int, unsigned int)
+       EXPORT_FUNC(spi_free_slave, void, spi_free_slave, struct spi_slave *)
+#endif
+#ifndef CONFIG_CMD_SPI
+       EXPORT_FUNC(dummy, void, spi_claim_bus, void)
+       EXPORT_FUNC(dummy, void, spi_release_bus, void)
+       EXPORT_FUNC(dummy, void, spi_xfer, void)
+#else
+       EXPORT_FUNC(spi_claim_bus, int, spi_claim_bus, struct spi_slave *)
+       EXPORT_FUNC(spi_release_bus, void, spi_release_bus, struct spi_slave *)
+       EXPORT_FUNC(spi_xfer, int, spi_xfer, struct spi_slave *,
+                   unsigned int, const void *, void *, unsigned long)
+#endif
+       EXPORT_FUNC(ustrtoul, unsigned long, ustrtoul,
+                   const char *, char **, unsigned int)
+       EXPORT_FUNC(ustrtoull, unsigned long long, ustrtoull,
+                   const char *, char **, unsigned int)
index 3d14d5f11746680256ffbfb053da8d4c2bbcb3d6..6747619b1c7868ce946660619e4bbe694bcae577 100644 (file)
@@ -73,7 +73,7 @@ typedef struct global_data {
        const void *fdt_blob;   /* Our device tree, NULL if none */
        void *new_fdt;          /* Relocated FDT */
        unsigned long fdt_size; /* Space reserved for relocated FDT */
-       void **jt;              /* jump table */
+       struct jt_funcs *jt;            /* jump table */
        char env_buf[32];       /* buffer for getenv() before reloc. */
 #ifdef CONFIG_TRACE
        void            *trace_buff;    /* The trace buffer */
index 36a36c64b8a6a19879e5236eb85af2fd5960a43d..3b96b8209a10b09d2cdcdf1f559c5fa2787831d7 100644 (file)
 /*
  * Generic GPIO API for U-Boot
  *
+ * --
+ * NB: This is deprecated. Please use the driver model functions instead:
+ *
+ *    - gpio_request_by_name()
+ *    - dm_gpio_get_value() etc.
+ *
+ * For now we need a dm_ prefix on some functions to avoid name collision.
+ * --
+ *
  * GPIOs are numbered from 0 to GPIO_COUNT-1 which value is defined
  * by the SOC/architecture.
  *
@@ -26,6 +35,7 @@
  */
 
 /**
+ * @deprecated Please use driver model instead
  * Request a GPIO. This should be called before any of the other functions
  * are used on this GPIO.
  *
@@ -39,6 +49,7 @@
 int gpio_request(unsigned gpio, const char *label);
 
 /**
+ * @deprecated Please use driver model instead
  * Stop using the GPIO.  This function should not alter pin configuration.
  *
  * @param gpio GPIO number
@@ -47,6 +58,7 @@ int gpio_request(unsigned gpio, const char *label);
 int gpio_free(unsigned gpio);
 
 /**
+ * @deprecated Please use driver model instead
  * Make a GPIO an input.
  *
  * @param gpio GPIO number
@@ -55,6 +67,7 @@ int gpio_free(unsigned gpio);
 int gpio_direction_input(unsigned gpio);
 
 /**
+ * @deprecated Please use driver model instead
  * Make a GPIO an output, and set its value.
  *
  * @param gpio GPIO number
@@ -64,6 +77,7 @@ int gpio_direction_input(unsigned gpio);
 int gpio_direction_output(unsigned gpio, int value);
 
 /**
+ * @deprecated Please use driver model instead
  * Get a GPIO's value. This will work whether the GPIO is an input
  * or an output.
  *
@@ -73,6 +87,7 @@ int gpio_direction_output(unsigned gpio, int value);
 int gpio_get_value(unsigned gpio);
 
 /**
+ * @deprecated Please use driver model instead
  * Set an output GPIO's value. The GPIO must already be an output or
  * this function may have no effect.
  *
@@ -95,6 +110,34 @@ enum gpio_func_t {
 
 struct udevice;
 
+struct gpio_desc {
+       struct udevice *dev;    /* Device, NULL for invalid GPIO */
+       unsigned long flags;
+#define GPIOD_REQUESTED                (1 << 0)        /* Requested/claimed */
+#define GPIOD_IS_OUT           (1 << 1)        /* GPIO is an output */
+#define GPIOD_IS_IN            (1 << 2)        /* GPIO is an output */
+#define GPIOD_ACTIVE_LOW       (1 << 3)        /* value has active low */
+#define GPIOD_IS_OUT_ACTIVE    (1 << 4)        /* set output active */
+
+       uint offset;            /* GPIO offset within the device */
+       /*
+        * We could consider adding the GPIO label in here. Possibly we could
+        * use this structure for internal GPIO information.
+        */
+};
+
+/**
+ * dm_gpio_is_valid() - Check if a GPIO is gpio_is_valie
+ *
+ * @desc:      GPIO description containing device, offset and flags,
+ *             previously returned by gpio_request_by_name()
+ * @return true if valid, false if not
+ */
+static inline bool dm_gpio_is_valid(struct gpio_desc *desc)
+{
+       return desc->dev != NULL;
+}
+
 /**
  * gpio_get_status() - get the current GPIO status as a string
  *
@@ -106,6 +149,8 @@ struct udevice;
  * which means this is GPIO bank b, offset 4, currently set to input, current
  * value 1, [x] means that it is requested and the owner is 'sdmmc_cd'
  *
+ * TODO(sjg@chromium.org): This should use struct gpio_desc
+ *
  * @dev:       Device to check
  * @offset:    Offset of device GPIO to check
  * @buf:       Place to put string
@@ -118,6 +163,8 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize);
  *
  * Note this returns GPIOF_UNUSED if the GPIO is not requested.
  *
+ * TODO(sjg@chromium.org): This should use struct gpio_desc
+ *
  * @dev:       Device to check
  * @offset:    Offset of device GPIO to check
  * @namep:     If non-NULL, this is set to the nane given when the GPIO
@@ -135,6 +182,8 @@ int gpio_get_function(struct udevice *dev, int offset, const char **namep);
  * Note this does not return GPIOF_UNUSED - it will always return the GPIO
  * driver's view of a pin function, even if it is not correctly set up.
  *
+ * TODO(sjg@chromium.org): This should use struct gpio_desc
+ *
  * @dev:       Device to check
  * @offset:    Offset of device GPIO to check
  * @namep:     If non-NULL, this is set to the nane given when the GPIO
@@ -155,6 +204,8 @@ int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep);
 int gpio_requestf(unsigned gpio, const char *fmt, ...)
                __attribute__ ((format (__printf__, 2, 3)));
 
+struct fdtdec_phandle_args;
+
 /**
  * struct struct dm_gpio_ops - Driver model GPIO operations
  *
@@ -198,6 +249,33 @@ struct dm_gpio_ops {
         * @return current function - GPIOF_...
         */
        int (*get_function)(struct udevice *dev, unsigned offset);
+
+       /**
+        * xlate() - Translate phandle arguments into a GPIO description
+        *
+        * This function should set up the fields in desc according to the
+        * information in the arguments. The uclass will have set up:
+        *
+        *   @desc->dev to @dev
+        *   @desc->flags to 0
+        *   @desc->offset to the value of the first argument in args, if any,
+        *              otherwise -1 (which is invalid)
+        *
+        * This method is optional so if the above defaults suit it can be
+        * omitted. Typical behaviour is to set up the GPIOD_ACTIVE_LOW flag
+        * in desc->flags.
+        *
+        * Note that @dev is passed in as a parameter to follow driver model
+        * uclass conventions, even though it is already available as
+        * desc->dev.
+        *
+        * @dev:        GPIO device
+        * @desc:       Place to put GPIO description
+        * @args:       Arguments provided in descripion
+        * @return 0 if OK, -ve on error
+        */
+       int (*xlate)(struct udevice *dev, struct gpio_desc *desc,
+                    struct fdtdec_phandle_args *args);
 };
 
 /**
@@ -268,4 +346,191 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
  */
 unsigned gpio_get_values_as_int(const int *gpio_list);
 
+/**
+ * gpio_request_by_name() - Locate and request a GPIO by name
+ *
+ * This operates by looking up the given list name in the device (device
+ * tree property) and requesting the GPIO for use. The property must exist
+ * in @dev's node.
+ *
+ * Use @flags to specify whether the GPIO should be an input or output. In
+ * principle this can also come from the device tree binding but most
+ * bindings don't provide this information. Specifically, when the GPIO uclass
+ * calls the xlate() method, it can return default flags, which are then
+ * ORed with this @flags.
+ *
+ * If we find that requesting the GPIO is not always needed we could add a
+ * new function or a new GPIOD_NO_REQUEST flag.
+ *
+ * At present driver model has no reference counting so if one device
+ * requests a GPIO which subsequently is unbound, the @desc->dev pointer
+ * will be invalid. However this will only happen if the GPIO device is
+ * unbound, not if it is removed, so this seems like a reasonable limitation
+ * for now. There is no real use case for unbinding drivers in normal
+ * operation.
+ *
+ * The device tree binding is doc/device-tree-bindings/gpio/gpio.txt in
+ * generate terms and each specific device may add additional details in
+ * a binding file in the same directory.
+ *
+ * @dev:       Device requesting the GPIO
+ * @list_name: Name of GPIO list (e.g. "board-id-gpios")
+ * @index:     Index number of the GPIO in that list use request (0=first)
+ * @desc:      Returns GPIO description information. If there is no such
+ *             GPIO, dev->dev will be NULL.
+ * @flags:     Indicates the GPIO input/output settings (GPIOD_...)
+ * @return 0 if OK, -ENOENT if the GPIO does not exist, -EINVAL if there is
+ * something wrong with the list, or other -ve for another error (e.g.
+ * -EBUSY if a GPIO was already requested)
+ */
+int gpio_request_by_name(struct udevice *dev, const char *list_name,
+                        int index, struct gpio_desc *desc, int flags);
+
+/**
+ * gpio_request_list_by_name() - Request a list of GPIOs
+ *
+ * Reads all the GPIOs from a list and requetss them. See
+ * gpio_request_by_name() for additional details. Lists should not be
+ * misused to hold unrelated or optional GPIOs. They should only be used
+ * for things like parallel data lines. A zero phandle terminates the list
+ * the list.
+ *
+ * This function will either succeed, and request all GPIOs in the list, or
+ * fail and request none (it will free already-requested GPIOs in case of
+ * an error part-way through).
+ *
+ * @dev:       Device requesting the GPIO
+ * @list_name: Name of GPIO list (e.g. "board-id-gpios")
+ * @desc_list: Returns a list of GPIO description information
+ * @max_count: Maximum number of GPIOs to return (@desc_list must be at least
+ *             this big)
+ * @flags:     Indicates the GPIO input/output settings (GPIOD_...)
+ * @return number of GPIOs requested, or -ve on error
+ */
+int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
+                             struct gpio_desc *desc_list, int max_count,
+                             int flags);
+
+/**
+ * gpio_get_list_count() - Returns the number of GPIOs in a list
+ *
+ * Counts the GPIOs in a list. See gpio_request_by_name() for additional
+ * details.
+ *
+ * @dev:       Device requesting the GPIO
+ * @list_name: Name of GPIO list (e.g. "board-id-gpios")
+ * @return number of GPIOs (0 for an empty property) or -ENOENT if the list
+ * does not exist
+ */
+int gpio_get_list_count(struct udevice *dev, const char *list_name);
+
+/**
+ * gpio_request_by_name_nodev() - request GPIOs without a device
+ *
+ * This is a version of gpio_request_list_by_name() that does not use a
+ * device. Avoid it unless the caller is not yet using driver model
+ */
+int gpio_request_by_name_nodev(const void *blob, int node,
+                              const char *list_name,
+                              int index, struct gpio_desc *desc, int flags);
+
+/**
+ * gpio_request_list_by_name_nodev() - request GPIOs without a device
+ *
+ * This is a version of gpio_request_list_by_name() that does not use a
+ * device. Avoid it unless the caller is not yet using driver model
+ */
+int gpio_request_list_by_name_nodev(const void *blob, int node,
+                                   const char *list_name,
+                                   struct gpio_desc *desc_list, int max_count,
+                                   int flags);
+
+/**
+ * dm_gpio_free() - Free a single GPIO
+ *
+ * This frees a single GPIOs previously returned from gpio_request_by_name().
+ *
+ * @dev:       Device which requested the GPIO
+ * @desc:      GPIO to free
+ * @return 0 if OK, -ve on error
+ */
+int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc);
+
+/**
+ * gpio_free_list() - Free a list of GPIOs
+ *
+ * This frees a list of GPIOs previously returned from
+ * gpio_request_list_by_name().
+ *
+ * @dev:       Device which requested the GPIOs
+ * @desc:      List of GPIOs to free
+ * @count:     Number of GPIOs in the list
+ * @return 0 if OK, -ve on error
+ */
+int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count);
+
+/**
+ * gpio_free_list_nodev() - free GPIOs without a device
+ *
+ * This is a version of gpio_free_list() that does not use a
+ * device. Avoid it unless the caller is not yet using driver model
+ */
+int gpio_free_list_nodev(struct gpio_desc *desc, int count);
+
+/**
+ * dm_gpio_get_value() - Get the value of a GPIO
+ *
+ * This is the driver model version of the existing gpio_get_value() function
+ * and should be used instead of that.
+ *
+ * For now, these functions have a dm_ prefix since they conflict with
+ * existing names.
+ *
+ * @desc:      GPIO description containing device, offset and flags,
+ *             previously returned by gpio_request_by_name()
+ * @return GPIO value (0 for inactive, 1 for active) or -ve on error
+ */
+int dm_gpio_get_value(struct gpio_desc *desc);
+
+int dm_gpio_set_value(struct gpio_desc *desc, int value);
+
+/**
+ * dm_gpio_set_dir() - Set the direction for a GPIO
+ *
+ * This sets up the direction according tot the provided flags. It will do
+ * nothing unless the direction is actually specified.
+ *
+ * @desc:      GPIO description containing device, offset and flags,
+ *             previously returned by gpio_request_by_name()
+ * @return 0 if OK, -ve on error
+ */
+int dm_gpio_set_dir(struct gpio_desc *desc);
+
+/**
+ * dm_gpio_set_dir_flags() - Set direction using specific flags
+ *
+ * This is like dm_gpio_set_dir() except that the flags value is provided
+ * instead of being used from desc->flags. This is needed because in many
+ * cases the GPIO description does not include direction information.
+ * Note that desc->flags is updated by this function.
+ *
+ * @desc:      GPIO description containing device, offset and flags,
+ *             previously returned by gpio_request_by_name()
+ * @flags:     New flags to use
+ * @return 0 if OK, -ve on error, in which case desc->flags is not updated
+ */
+int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags);
+
+/**
+ * gpio_get_number() - Get the global GPIO number of a GPIO
+ *
+ * This should only be used for debugging or interest. It returns the nummber
+ * that should be used for gpio_get_value() etc. to access this GPIO.
+ *
+ * @desc:      GPIO description containing device, offset and flags,
+ *             previously returned by gpio_request_by_name()
+ * @return GPIO number, or -ve if not found
+ */
+int gpio_get_number(struct gpio_desc *desc);
+
 #endif /* _ASM_GENERIC_GPIO_H_ */
index 4b3e0d3bbd75adb6fe1a78e3ff1710de5df08297..97c8f79fc7375706c07af06c752c424e196a083d 100644 (file)
@@ -228,12 +228,13 @@ int run_command_list(const char *cmd, int len, int flag);
 extern char console_buffer[];
 
 /* arch/$(ARCH)/lib/board.c */
-void   board_init_f(ulong);
-void   board_init_r  (gd_t *, ulong) __attribute__ ((noreturn));
-int    checkboard    (void);
-int    checkflash    (void);
-int    checkdram     (void);
-int    last_stage_init(void);
+void board_init_f(ulong);
+void board_init_r(gd_t *, ulong) __attribute__ ((noreturn));
+int checkboard(void);
+int show_board_info(void);
+int checkflash(void);
+int checkdram(void);
+int last_stage_init(void);
 extern ulong monitor_flash_len;
 int mac_read_from_eeprom(void);
 extern u8 __dtb_dt_begin[];    /* embedded device tree blob */
index becbe3fa7cc29c80d2236db1da62e2278a36ff98..49674f4537541c6014cb2259976c21ee36dab2d3 100644 (file)
@@ -13,7 +13,7 @@
 #define BOOTENV_SHARED_BLKDEV_BODY(devtypel) \
                "if " #devtypel " dev ${devnum}; then " \
                        "setenv devtype " #devtypel "; " \
-                       "run scan_dev_for_boot; " \
+                       "run scan_dev_for_boot_part; " \
                "fi\0"
 
 #define BOOTENV_SHARED_BLKDEV(devtypel) \
 #define BOOTENV_DEV_DHCP(devtypeu, devtypel, instance) \
        "bootcmd_dhcp=" \
                BOOTENV_RUN_USB_INIT \
-               "if dhcp ${scriptaddr} boot.scr.uimg; then " \
+               "if dhcp ${scriptaddr} ${boot_script_dhcp}; then " \
                        "source ${scriptaddr}; " \
                "fi\0"
 #define BOOTENV_DEV_NAME_DHCP(devtypeu, devtypel, instance) \
        BOOTENV_SHARED_IDE \
        "boot_prefixes=/ /boot/\0" \
        "boot_scripts=boot.scr.uimg boot.scr\0" \
+       "boot_script_dhcp=boot.scr.uimg\0" \
        BOOTENV_BOOT_TARGETS \
-       "bootpart=1\0" \
        \
        "boot_extlinux="                                                  \
                "sysboot ${devtype} ${devnum}:${bootpart} any "           \
                "done\0"                                                  \
        \
        "scan_dev_for_boot="                                              \
-               "echo Scanning ${devtype} ${devnum}...; "                 \
+               "echo Scanning ${devtype} ${devnum}:${bootpart}...; "     \
                "for prefix in ${boot_prefixes}; do "                     \
                        "run scan_dev_for_extlinux; "                     \
                        "run scan_dev_for_scripts; "                      \
                "done\0"                                                  \
        \
+       "scan_dev_for_boot_part="                                         \
+               "part list ${devtype} ${devnum} devplist; "               \
+               "for bootpart in ${devplist}; do "                        \
+                       "if fstype ${devtype} ${devnum}:${bootpart} "     \
+                                       "bootfstype; then "               \
+                               "run scan_dev_for_boot; "                 \
+                       "fi; "                                            \
+               "done\0"                                                  \
+       \
        BOOT_TARGET_DEVICES(BOOTENV_DEV)                                  \
        \
-       "bootcmd=" BOOTENV_SET_SCSI_NEED_INIT                             \
+       "distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT                      \
                "for target in ${boot_targets}; do "                      \
                        "run bootcmd_${target}; "                         \
                "done\0"
 
+#ifndef CONFIG_BOOTCOMMAND
+#define CONFIG_BOOTCOMMAND "run distro_bootcmd"
+#endif
+
 #endif  /* _CONFIG_CMD_DISTRO_BOOTCMD_H */
index 000475051812a2846bfd8b0625945cabfd315168..76ce7deb9508716871e6c65e5a38634e8afc86ab 100644 (file)
 #include <configs/ti_am335x_common.h>
 
 #ifndef CONFIG_SPL_BUILD
+#ifndef CONFIG_FIT
 # define CONFIG_FIT
+#endif
 # define CONFIG_TIMESTAMP
 # define CONFIG_LZO
-# ifdef CONFIG_ENABLE_VBOOT
-#  define CONFIG_FIT_SIGNATURE
-#  define CONFIG_RSA
-# endif
 #endif
 
 #define CONFIG_SYS_BOOTM_LEN           (16 << 20)
index d68993bb1f7301c1384caaed9185524f7a2e3ea6..3ad4a9ba91f6eaa7da5d465b9584308561cbd9f3 100644 (file)
@@ -51,8 +51,6 @@
 /* PMIC */
 #define CONFIG_PMIC
 #define CONFIG_POWER_I2C
-#define CONFIG_POWER_MAX77686
-
 
 #define CONFIG_PREBOOT
 
index ad63f3c5496d39e0be23c35d2a1d29c92edf8c11..0ba39a23dd03d4fcf71d3bed7815e8149cc7019d 100644 (file)
 #define SPI_FLASH_UBOOT_POS    (CONFIG_SEC_FW_SIZE + CONFIG_BL1_SIZE)
 
 /* I2C */
-#define CONFIG_SYS_I2C_INIT_BOARD
-#define CONFIG_SYS_I2C
+#define CONFIG_DM_I2C
+#define CONFIG_DM_I2C_COMPAT
 #define CONFIG_CMD_I2C
-#define CONFIG_SYS_I2C_S3C24X0_SPEED   100000          /* 100 Kbps */
 #define CONFIG_SYS_I2C_S3C24X0
-#define CONFIG_I2C_MULTI_BUS
+#define CONFIG_SYS_I2C_S3C24X0_SPEED   100000          /* 100 Kbps */
 #define CONFIG_SYS_I2C_S3C24X0_SLAVE    0x0
 #define CONFIG_I2C_EDID
 
index 671431397fc02598316a9da65e170cd9196c5df8..ae0e5ff47b096a48f2a1a798070a80a06ad52f52 100644 (file)
@@ -28,9 +28,6 @@
 
 #define CONFIG_SYS_INIT_SP_ADDR        CONFIG_IRAM_STACK
 
-/* PMIC */
-#define CONFIG_POWER_MAX77686
-
 /* Sound */
 #define CONFIG_CMD_SOUND
 #ifdef CONFIG_CMD_SOUND
index f08483487d9fc7dc7533076cfa6527127d7d8570..2384864eb025fc979288bec16e3a2e2aca709f01 100644 (file)
 
 #define CONFIG_VERSION_VARIABLE
 
-#define CONFIG_FIT
-#define CONFIG_FIT_SIGNATURE
 #define CONFIG_IMAGE_FORMAT_LEGACY
 #define CONFIG_CMD_FDT
 #define CONFIG_CMD_HASH
-#define CONFIG_RSA
 #define CONFIG_SHA1
 #define CONFIG_SHA256
 
index 684d24959033403710c0d4e13d0e0bb4024915ec..354672ecf8735e9240b119a801df2ffba0b91ab1 100644 (file)
@@ -71,6 +71,7 @@
                                         sizeof(CONFIG_SYS_PROMPT) + 16)
 #define CONFIG_SYS_MAXARGS             16
 
+#define CONFIG_SYS_HUSH_PARSER
 #define CONFIG_AUTO_COMPLETE
 #define CONFIG_CMDLINE_EDITING
 
 #define CONFIG_ENV_ADDR \
        (CONFIG_SYS_FLASH_BASE + (4 << 20) - CONFIG_ENV_SIZE)
 
+/*
+ * IDE/ATA
+ */
+#define CONFIG_SYS_IDE_MAXBUS          1
+#define CONFIG_SYS_IDE_MAXDEVICE       2
+#define CONFIG_SYS_ATA_BASE_ADDR       CONFIG_SYS_ISA_IO_BASE_ADDRESS
+#define CONFIG_SYS_ATA_IDE0_OFFSET     0x01f0
+#define CONFIG_SYS_ATA_DATA_OFFSET     0
+#define CONFIG_SYS_ATA_REG_OFFSET      0
+
 /*
  * Commands
  */
 
 #define CONFIG_CMD_DATE
 #define CONFIG_CMD_DHCP
+#define CONFIG_CMD_ELF
+#define CONFIG_CMD_IDE
 #define CONFIG_CMD_PCI
 #define CONFIG_CMD_PING
 
index 807e96bbaab9f676bb13f4cacb38ddb5a1af05b0..9d5dbdce369381588f67a13e2e5cb44673d2dab4 100644 (file)
 
 /* I2C */
 #define CONFIG_CMD_I2C
-#define CONFIG_SYS_I2C
+#define CONFIG_DM_I2C
+#define CONFIG_DM_I2C_COMPAT
 #define CONFIG_SYS_I2C_S3C24X0
 #define CONFIG_SYS_I2C_S3C24X0_SPEED   100000
 #define CONFIG_SYS_I2C_S3C24X0_SLAVE   0
-#define CONFIG_MAX_I2C_NUM             8
-#define CONFIG_SYS_I2C_INIT_BOARD
 
 /* POWER */
 #define CONFIG_POWER
index 657f751f3c21bb9c4de81c996695a7371fd3427d..e9d3f3226b373f078faaa2c6c5e34932a3729ee1 100644 (file)
@@ -23,7 +23,6 @@
 
 #define CONFIG_BOOTSTAGE
 #define CONFIG_BOOTSTAGE_REPORT
-#define CONFIG_DM
 #define CONFIG_CMD_DEMO
 #define CONFIG_CMD_DM
 #define CONFIG_DM_DEMO
@@ -41,9 +40,6 @@
 
 #define CONFIG_OF_LIBFDT
 #define CONFIG_LMB
-#define CONFIG_FIT
-#define CONFIG_FIT_SIGNATURE
-#define CONFIG_RSA
 #define CONFIG_CMD_FDT
 #define CONFIG_ANDROID_BOOT_IMAGE
 
index 83953728dd29b818ad9aae658b209f1e46a92fbf..3b06d305db50221f8ec445d27673cd970c12719b 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <configs/exynos5250-common.h>
 
+/* PMIC */
+#define CONFIG_POWER_MAX77686
 
 #define CONFIG_BOARD_COMMON
 #define CONFIG_ARCH_EARLY_INIT_R
index 7eaa58697e44f6cfeab3d2480eada7afb67aa636..ce6676eae7f71c95a32a98d0681584ba6ca15902 100644 (file)
@@ -22,6 +22,7 @@
 
 #define CONFIG_CROS_EC_I2C             /* Support CROS_EC over I2C */
 #define CONFIG_POWER_TPS65090_I2C
+#define CONFIG_DM_CROS_EC
 
 #define CONFIG_BOARD_COMMON
 #define CONFIG_ARCH_EARLY_INIT_R
index 5ed86d9365cd08aee392bbe77e7c7bf84e5c9ad6..598526bf95feb0709fdef7ad179838b0aabdf2a7 100644 (file)
@@ -20,7 +20,9 @@
 #define CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC
 
 #ifndef CONFIG_SPL_BUILD
+#ifndef CONFIG_DM
 # define CONFIG_DM
+#endif
 # define CONFIG_CMD_DM
 # define CONFIG_DM_GPIO
 # define CONFIG_DM_SERIAL
index 5a53c506c35f50be969b4e5188d002206910ccfc..9ad47f6933eaac0f8a4ffa1817e0be6773ef146d 100644 (file)
@@ -43,6 +43,9 @@
 #define CONFIG_SDRAM1_SIZE     0x10000000
 #endif
 
+#define CONFIG_I2C_EEPROM
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  10
+
 /*
  * Support card address map
  */
index 027d78b59171901274da4e46c0da576c128c6415..7fb28a54ba175f5bba12a4c7e6a20ea304202577 100644 (file)
@@ -11,9 +11,9 @@
 /* We use generic board for v8 Versatile Express */
 #define CONFIG_SYS_GENERIC_BOARD
 
-#ifdef CONFIG_BASE_FVP
+#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP
 #ifndef CONFIG_SEMIHOSTING
-#error CONFIG_BASE_FVP requires CONFIG_SEMIHOSTING
+#error CONFIG_TARGET_VEXPRESS64_BASE_FVP requires CONFIG_SEMIHOSTING
 #endif
 #define CONFIG_BOARD_LATE_INIT
 #define CONFIG_ARMV8_SWITCH_TO_EL1
@@ -21,8 +21,9 @@
 
 #define CONFIG_REMAKE_ELF
 
-#ifndef CONFIG_BASE_FVP
-/* Base FVP not using GICv3 yet */
+#if !defined(CONFIG_TARGET_VEXPRESS64_BASE_FVP) && \
+    !defined(CONFIG_TARGET_VEXPRESS64_JUNO)
+/* Base FVP and Juno not using GICv3 yet */
 #define CONFIG_GICV3
 #endif
 
 #define CONFIG_BOOTP_VCI_STRING                "U-boot.armv8.vexpress_aemv8a"
 
 /* Link Definitions */
-#ifdef CONFIG_BASE_FVP
+#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP
 /* ATF loads u-boot here for BASE_FVP model */
 #define CONFIG_SYS_TEXT_BASE           0x88000000
 #define CONFIG_SYS_INIT_SP_ADDR         (CONFIG_SYS_SDRAM_BASE + 0x03f00000)
+#elif CONFIG_TARGET_VEXPRESS64_JUNO
+#define CONFIG_SYS_TEXT_BASE           0xe0000000
+#define CONFIG_SYS_INIT_SP_ADDR         (CONFIG_SYS_SDRAM_BASE + 0x7fff0)
 #else
 #define CONFIG_SYS_TEXT_BASE           0x80000000
 #define CONFIG_SYS_INIT_SP_ADDR         (CONFIG_SYS_SDRAM_BASE + 0x7fff0)
@@ -54,7 +58,7 @@
 
 
 /* SMP Spin Table Definitions */
-#ifdef CONFIG_BASE_FVP
+#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP
 #define CPU_RELEASE_ADDR               (CONFIG_SYS_SDRAM_BASE + 0x03f00000)
 #else
 #define CPU_RELEASE_ADDR               (CONFIG_SYS_SDRAM_BASE + 0x7fff0)
 #define V2M_KMI0                       (V2M_PA_CS3 + V2M_PERIPH_OFFSET(6))
 #define V2M_KMI1                       (V2M_PA_CS3 + V2M_PERIPH_OFFSET(7))
 
+#ifdef CONFIG_TARGET_VEXPRESS64_JUNO
+#define V2M_UART0                      0x7ff80000
+#define V2M_UART1                      0x7ff70000
+#else /* Not Juno */
 #define V2M_UART0                      (V2M_PA_CS3 + V2M_PERIPH_OFFSET(9))
 #define V2M_UART1                      (V2M_PA_CS3 + V2M_PERIPH_OFFSET(10))
 #define V2M_UART2                      (V2M_PA_CS3 + V2M_PERIPH_OFFSET(11))
 #define V2M_UART3                      (V2M_PA_CS3 + V2M_PERIPH_OFFSET(12))
+#endif
 
 #define V2M_WDT                                (V2M_PA_CS3 + V2M_PERIPH_OFFSET(15))
 
 #define GICR_BASE                      (0x2f100000)
 #else
 
-#ifdef CONFIG_BASE_FVP
+#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP
 #define GICD_BASE                      (0x2f000000)
 #define GICC_BASE                      (0x2c000000)
+#elif CONFIG_TARGET_VEXPRESS64_JUNO
+#define GICD_BASE                      (0x2C010000)
+#define GICC_BASE                      (0x2C02f000)
 #else
 #define GICD_BASE                      (0x2C001000)
 #define GICC_BASE                      (0x2C002000)
 
 /* PL011 Serial Configuration */
 #define CONFIG_PL011_SERIAL
+#ifdef CONFIG_TARGET_VEXPRESS64_JUNO
+#define CONFIG_PL011_CLOCK             7273800
+#else
 #define CONFIG_PL011_CLOCK             24000000
+#endif
 #define CONFIG_PL01x_PORTS             {(void *)CONFIG_SYS_SERIAL0, \
                                         (void *)CONFIG_SYS_SERIAL1}
 #define CONFIG_CONS_INDEX              0
 #define CONFIG_CMD_ENV
 #define CONFIG_CMD_FLASH
 #define CONFIG_CMD_IMI
+#define CONFIG_CMD_LOADB
 #define CONFIG_CMD_MEMORY
 #define CONFIG_CMD_MII
 #define CONFIG_CMD_NET
 #define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM_1
 
 /* Initial environment variables */
-#ifdef CONFIG_BASE_FVP
+#ifdef CONFIG_TARGET_VEXPRESS64_BASE_FVP
 #define CONFIG_EXTRA_ENV_SETTINGS      \
                                "kernel_name=uImage\0"  \
                                "kernel_addr_r=0x80000000\0"    \
index 7e78f8ac8fcc60acf2b728626904d5b70aa29fe4..2dea9210454a7b6dd7cf824aea89295d84864e22 100644 (file)
 #define CONFIG_SETUP_MEMORY_TAGS       1
 #define CONFIG_SYS_L2CACHE_OFF         1
 #define CONFIG_INITRD_TAG              1
-
+#define CONFIG_SYS_GENERIC_BOARD
 #define CONFIG_OF_LIBFDT               1
 
 /* Size of malloc() pool */
index 2d28e89dd367d85b4511e42a98ea7ecf43f63859..864528a5ea1b39e8b39e089b45837812bc731a82 100644 (file)
 #define CONFIG_OF_LIBFDT
 
 /* FIT support */
-#define CONFIG_FIT
-#define CONFIG_FIT_VERBOSE     1 /* enable fit_format_{error,warning}() */
 #define CONFIG_IMAGE_FORMAT_LEGACY /* enable also legacy image format */
 
 /* FDT support */
 #define CONFIG_DISPLAY_BOARDINFO_LATE
 
-/* RSA support */
-#define CONFIG_FIT_SIGNATURE
-#define CONFIG_RSA
-
 /* Extend size of kernel image for uncompression */
 #define CONFIG_SYS_BOOTM_LEN   (60 * 1024 * 1024)
 
index 9e13146ecbb266a5b73dbb9b93b1e90317c79a06..8457c80c5efd4264e5943255dc35b83fd520581b 100644 (file)
@@ -13,6 +13,7 @@
 #include <ec_commands.h>
 #include <fdtdec.h>
 #include <cros_ec_message.h>
+#include <asm/gpio.h>
 
 #ifndef CONFIG_DM_CROS_EC
 /* Which interface is the device on? */
@@ -39,7 +40,7 @@ struct cros_ec_dev {
        unsigned int bus_num;           /* Bus number (for I2C) */
        unsigned int max_frequency;     /* Maximum interface frequency */
 #endif
-       struct fdt_gpio_state ec_int;   /* GPIO used as EC interrupt line */
+       struct gpio_desc ec_int;        /* GPIO used as EC interrupt line */
        int protocol_version;           /* Protocol version to use */
        int optimise_flash_write;       /* Don't write erased flash blocks */
 
index a24fec6658e8e9bb1df82235222befc404411b32..03722d0c14dc14de253bc203185da4c59503cd99 100644 (file)
@@ -25,10 +25,14 @@ struct dm_demo_pdata {
 struct demo_ops {
        int (*hello)(struct udevice *dev, int ch);
        int (*status)(struct udevice *dev, int *status);
+       int (*set_light)(struct udevice *dev, int light);
+       int (*get_light)(struct udevice *dev);
 };
 
 int demo_hello(struct udevice *dev, int ch);
 int demo_status(struct udevice *dev, int *status);
+int demo_set_light(struct udevice *dev, int light);
+int demo_get_light(struct udevice *dev);
 int demo_list(void);
 
 int demo_parse_dt(struct udevice *dev);
index 13598a15b68684ee81b023c30d8ec42e21941c2b..81afa8c6281f8f9c55dbd968bfd4b344f8cf872a 100644 (file)
@@ -26,6 +26,9 @@ struct driver_info;
 /* DM should init this device prior to relocation */
 #define DM_FLAG_PRE_RELOC      (1 << 2)
 
+/* DM is responsible for allocating and freeing parent_platdata */
+#define DM_FLAG_ALLOC_PARENT_PDATA     (1 << 3)
+
 /**
  * struct udevice - An instance of a driver
  *
@@ -46,6 +49,7 @@ struct driver_info;
  * @driver: The driver used by this device
  * @name: Name of device, typically the FDT node name
  * @platdata: Configuration data for this device
+ * @parent_platdata: The parent bus's configuration data for this device
  * @of_offset: Device tree node offset for this device (- for none)
  * @of_id: Pointer to the udevice_id structure which created the device
  * @parent: Parent of this device, or NULL for the top level device
@@ -65,6 +69,7 @@ struct udevice {
        struct driver *driver;
        const char *name;
        void *platdata;
+       void *parent_platdata;
        int of_offset;
        const struct udevice_id *of_id;
        struct udevice *parent;
@@ -127,6 +132,7 @@ struct udevice_id {
  * @remove: Called to remove a device, i.e. de-activate it
  * @unbind: Called to unbind a device from its driver
  * @ofdata_to_platdata: Called before probe to decode device tree data
+ * @child_post_bind: Called after a new child has been bound
  * @child_pre_probe: Called before a child device is probed. The device has
  * memory allocated but it has not yet been probed.
  * @child_post_remove: Called after a child device is removed. The device
@@ -146,6 +152,9 @@ struct udevice_id {
  * device_probe_child() pass it in. So far the use case for allocating it
  * is SPI, but I found that unsatisfactory. Since it is here I will leave it
  * until things are clearer.
+ * @per_child_platdata_auto_alloc_size: A bus likes to store information about
+ * its children. If non-zero this is the size of this data, to be allocated
+ * in the child's parent_platdata pointer.
  * @ops: Driver-specific operations. This is typically a list of function
  * pointers defined by the driver, to implement driver functions required by
  * the uclass.
@@ -160,11 +169,13 @@ struct driver {
        int (*remove)(struct udevice *dev);
        int (*unbind)(struct udevice *dev);
        int (*ofdata_to_platdata)(struct udevice *dev);
+       int (*child_post_bind)(struct udevice *dev);
        int (*child_pre_probe)(struct udevice *dev);
        int (*child_post_remove)(struct udevice *dev);
        int priv_auto_alloc_size;
        int platdata_auto_alloc_size;
        int per_child_auto_alloc_size;
+       int per_child_platdata_auto_alloc_size;
        const void *ops;        /* driver-specific operations */
        uint32_t flags;
 };
@@ -183,6 +194,16 @@ struct driver {
  */
 void *dev_get_platdata(struct udevice *dev);
 
+/**
+ * dev_get_parent_platdata() - Get the parent platform data for a device
+ *
+ * This checks that dev is not NULL, but no other checks for now
+ *
+ * @dev                Device to check
+ * @return parent's platform data, or NULL if none
+ */
+void *dev_get_parent_platdata(struct udevice *dev);
+
 /**
  * dev_get_parentdata() - Get the parent data for a device
  *
@@ -224,6 +245,14 @@ struct udevice *dev_get_parent(struct udevice *child);
  */
 ulong dev_get_of_data(struct udevice *dev);
 
+/*
+ * device_get_uclass_id() - return the uclass ID of a device
+ *
+ * @dev:       Device to check
+ * @return uclass ID for the device
+ */
+enum uclass_id device_get_uclass_id(struct udevice *dev);
+
 /**
  * device_get_child() - Get the child of a device by index
  *
index f08c05da8147725f87900da81bf8944ff1c46ebc..707c69e07f02c488f10de559185769829534e689 100644 (file)
@@ -67,6 +67,8 @@ enum {
 struct dm_test_priv {
        int ping_total;
        int op_count[DM_TEST_OP_COUNT];
+       int uclass_flag;
+       int uclass_total;
 };
 
 /**
@@ -88,6 +90,7 @@ struct dm_test_uclass_priv {
  *
  * @sum: Test value used to check parent data works correctly
  * @flag: Used to track calling of parent operations
+ * @uclass_flag: Used to track calling of parent operations by uclass
  */
 struct dm_test_parent_data {
        int sum;
index f17c3c2b384dfc8aa782583fa0734cb31a77d222..91bb90dcfb3044196907da15b3b83efb2c2dd07c 100644 (file)
@@ -33,6 +33,7 @@ enum uclass_id {
        UCLASS_I2C,             /* I2C bus */
        UCLASS_I2C_GENERIC,     /* Generic I2C device */
        UCLASS_I2C_EEPROM,      /* I2C EEPROM device */
+       UCLASS_MOD_EXP,         /* RSA Mod Exp device */
 
        UCLASS_COUNT,
        UCLASS_INVALID = -1,
index f718f37affba344713f7599692f9fa79b2286652..f2f254a8259736f9d24ba18ad95ba9e126eb53c2 100644 (file)
@@ -43,6 +43,17 @@ int uclass_bind_device(struct udevice *dev);
  */
 int uclass_unbind_device(struct udevice *dev);
 
+/**
+ * uclass_pre_probe_child() - Deal with a child that is about to be probed
+ *
+ * Perform any pre-processing that is needed by the uclass before it can be
+ * probed.
+ *
+ * @dev:       Pointer to the device
+ * #return 0 on success, -ve on error
+ */
+int uclass_pre_probe_child(struct udevice *dev);
+
 /**
  * uclass_post_probe_device() - Deal with a device that has just been probed
  *
index f6ec6d7e9f62f7551b869f1eb7b188e8587b44ee..d6c40c60dda0913c27c46ffb8538176a7d595210 100644 (file)
@@ -40,6 +40,9 @@ struct uclass {
 
 struct udevice;
 
+/* Members of this uclass sequence themselves with aliases */
+#define DM_UC_FLAG_SEQ_ALIAS                   (1 << 0)
+
 /**
  * struct uclass_driver - Driver for the uclass
  *
@@ -52,6 +55,7 @@ struct udevice;
  * @pre_unbind: Called before a device is unbound from this uclass
  * @post_probe: Called after a new device is probed
  * @pre_remove: Called before a device is removed
+ * @child_post_bind: Called after a child is bound to a device in this uclass
  * @init: Called to set up the uclass
  * @destroy: Called to destroy the uclass
  * @priv_auto_alloc_size: If non-zero this is the size of the private data
@@ -60,8 +64,16 @@ struct udevice;
  * @per_device_auto_alloc_size: Each device can hold private data owned
  * by the uclass. If required this will be automatically allocated if this
  * value is non-zero.
+ * @per_child_auto_alloc_size: Each child device (of a parent in this
+ * uclass) can hold parent data for the device/uclass. This value is only
+ * used as a falback if this member is 0 in the driver.
+ * @per_child_platdata_auto_alloc_size: A bus likes to store information about
+ * its children. If non-zero this is the size of this data, to be allocated
+ * in the child device's parent_platdata pointer. This value is only used as
+ * a falback if this member is 0 in the driver.
  * @ops: Uclass operations, providing the consistent interface to devices
  * within the uclass.
+ * @flags: Flags for this uclass (DM_UC_...)
  */
 struct uclass_driver {
        const char *name;
@@ -70,11 +82,16 @@ struct uclass_driver {
        int (*pre_unbind)(struct udevice *dev);
        int (*post_probe)(struct udevice *dev);
        int (*pre_remove)(struct udevice *dev);
+       int (*child_post_bind)(struct udevice *dev);
+       int (*child_pre_probe)(struct udevice *dev);
        int (*init)(struct uclass *class);
        int (*destroy)(struct uclass *class);
        int priv_auto_alloc_size;
        int per_device_auto_alloc_size;
+       int per_child_auto_alloc_size;
+       int per_child_platdata_auto_alloc_size;
        const void *ops;
+       uint32_t flags;
 };
 
 /* Declare a new uclass_driver */
@@ -141,6 +158,8 @@ int uclass_get_device_by_of_offset(enum uclass_id id, int node,
 /**
  * uclass_first_device() - Get the first device in a uclass
  *
+ * The device returned is probed if necessary, and ready for use
+ *
  * @id: Uclass ID to look up
  * @devp: Returns pointer to the first device in that uclass, or NULL if none
  * @return 0 if OK (found or not found), -1 on error
@@ -150,6 +169,8 @@ int uclass_first_device(enum uclass_id id, struct udevice **devp);
 /**
  * uclass_next_device() - Get the next device in a uclass
  *
+ * The device returned is probed if necessary, and ready for use
+ *
  * @devp: On entry, pointer to device to lookup. On exit, returns pointer
  * to the next device in the same uclass, or NULL if none
  * @return 0 if OK (found or not found), -1 on error
index 41d5085e16c27017d7e02540c3aacfa2090e994a..205affe72d701d087107b21a818daf974422d8f8 100644 (file)
@@ -3,6 +3,8 @@
 
 #ifndef __ASSEMBLY__
 
+struct spi_slave;
+
 /* These are declarations of exported functions available in C code */
 unsigned long get_version(void);
 int  getc(void);
@@ -10,22 +12,23 @@ int  tstc(void);
 void putc(const char);
 void puts(const char*);
 int printf(const char* fmt, ...);
-void install_hdlr(int, void (*interrupt_handler_t)(void *), void*);
+void install_hdlr(int, interrupt_handler_t, void*);
 void free_hdlr(int);
 void *malloc(size_t);
 void free(void*);
 void __udelay(unsigned long);
 unsigned long get_timer(unsigned long);
 int vprintf(const char *, va_list);
-unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base);
+unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base);
 int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
 char *getenv (const char *name);
 int setenv (const char *varname, const char *varvalue);
-long simple_strtol(const char *cp,char **endp,unsigned int base);
-int strcmp(const char * cs,const char * ct);
+long simple_strtol(const char *cp, char **endp, unsigned int base);
+int strcmp(const char *cs, const char *ct);
 unsigned long ustrtoul(const char *cp, char **endp, unsigned int base);
 unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base);
-#if defined(CONFIG_CMD_I2C)
+#if defined(CONFIG_CMD_I2C) && \
+               (!defined(CONFIG_DM_I2C) || defined(CONFIG_DM_I2C_COMPAT))
 int i2c_write (uchar, uint, int , uchar* , int);
 int i2c_read (uchar, uint, int , uchar* , int);
 #endif
@@ -34,15 +37,14 @@ void app_startup(char * const *);
 
 #endif    /* ifndef __ASSEMBLY__ */
 
-enum {
-#define EXPORT_FUNC(x) XF_ ## x ,
+struct jt_funcs {
+#define EXPORT_FUNC(impl, res, func, ...) res(*func)(__VA_ARGS__);
 #include <_exports.h>
 #undef EXPORT_FUNC
-
-       XF_MAX
 };
 
-#define XF_VERSION     6
+
+#define XF_VERSION     7
 
 #if defined(CONFIG_X86)
 extern gd_t *global_data;
index 8c2bd21b2d2be8de0aeda3104f4724f2d4895229..231eed789273800fb3daf14913ae84b07d65a6c9 100644 (file)
@@ -115,9 +115,6 @@ enum fdt_compat_id {
        COMPAT_NVIDIA_TEGRA20_USB,      /* Tegra20 USB port */
        COMPAT_NVIDIA_TEGRA30_USB,      /* Tegra30 USB port */
        COMPAT_NVIDIA_TEGRA114_USB,     /* Tegra114 USB port */
-       COMPAT_NVIDIA_TEGRA114_I2C,     /* Tegra114 I2C w/single clock source */
-       COMPAT_NVIDIA_TEGRA20_I2C,      /* Tegra20 i2c */
-       COMPAT_NVIDIA_TEGRA20_DVC,      /* Tegra20 dvc (really just i2c) */
        COMPAT_NVIDIA_TEGRA20_EMC,      /* Tegra20 memory controller */
        COMPAT_NVIDIA_TEGRA20_EMC_TABLE, /* Tegra20 memory timing table */
        COMPAT_NVIDIA_TEGRA20_KBC,      /* Tegra20 Keyboard */
@@ -127,9 +124,6 @@ enum fdt_compat_id {
        COMPAT_NVIDIA_TEGRA124_SDMMC,   /* Tegra124 SDMMC controller */
        COMPAT_NVIDIA_TEGRA30_SDMMC,    /* Tegra30 SDMMC controller */
        COMPAT_NVIDIA_TEGRA20_SDMMC,    /* Tegra20 SDMMC controller */
-       COMPAT_NVIDIA_TEGRA20_SFLASH,   /* Tegra 2 SPI flash controller */
-       COMPAT_NVIDIA_TEGRA20_SLINK,    /* Tegra 2 SPI SLINK controller */
-       COMPAT_NVIDIA_TEGRA114_SPI,     /* Tegra 114 SPI controller */
        COMPAT_NVIDIA_TEGRA124_PCIE,    /* Tegra 124 PCIe controller */
        COMPAT_NVIDIA_TEGRA30_PCIE,     /* Tegra 30 PCIe controller */
        COMPAT_NVIDIA_TEGRA20_PCIE,     /* Tegra 20 PCIe controller */
@@ -140,7 +134,6 @@ enum fdt_compat_id {
        COMPAT_SAMSUNG_S3C2440_I2C,     /* Exynos I2C Controller */
        COMPAT_SAMSUNG_EXYNOS5_SOUND,   /* Exynos Sound */
        COMPAT_WOLFSON_WM8994_CODEC,    /* Wolfson WM8994 Sound Codec */
-       COMPAT_SAMSUNG_EXYNOS_SPI,      /* Exynos SPI */
        COMPAT_GOOGLE_CROS_EC,          /* Google CROS_EC Protocol */
        COMPAT_GOOGLE_CROS_EC_KEYB,     /* Google CROS_EC Keyboard */
        COMPAT_SAMSUNG_EXYNOS_EHCI,     /* Exynos EHCI controller */
@@ -178,38 +171,58 @@ enum fdt_compat_id {
        COMPAT_COUNT,
 };
 
-/* GPIOs are numbered from 0 */
-enum {
-       FDT_GPIO_NONE = -1U,    /* an invalid GPIO used to end our list */
-
-       FDT_GPIO_ACTIVE_LOW = 1 << 0,   /* input is active low (else high) */
-};
-
-/* This is the state of a GPIO pin as defined by the fdt */
-struct fdt_gpio_state {
-       const char *name;       /* name of the fdt property defining this */
-       uint gpio;              /* GPIO number, or FDT_GPIO_NONE if none */
-       u8 flags;               /* FDT_GPIO_... flags */
+#define MAX_PHANDLE_ARGS 16
+struct fdtdec_phandle_args {
+       int node;
+       int args_count;
+       uint32_t args[MAX_PHANDLE_ARGS];
 };
 
-/* This tells us whether a fdt_gpio_state record is valid or not */
-#define fdt_gpio_isvalid(x) ((x)->gpio != FDT_GPIO_NONE)
-
 /**
- * Read the GPIO taking into account the polarity of the pin.
+ * fdtdec_parse_phandle_with_args() - Find a node pointed by phandle in a list
  *
- * @param gpio         pointer to the decoded gpio
- * @return value of the gpio if successful, < 0 if unsuccessful
- */
-int fdtdec_get_gpio(struct fdt_gpio_state *gpio);
-
-/**
- * Write the GPIO taking into account the polarity of the pin.
+ * This function is useful to parse lists of phandles and their arguments.
+ *
+ * Example:
+ *
+ * phandle1: node1 {
+ *     #list-cells = <2>;
+ * }
+ *
+ * phandle2: node2 {
+ *     #list-cells = <1>;
+ * }
+ *
+ * node3 {
+ *     list = <&phandle1 1 2 &phandle2 3>;
+ * }
+ *
+ * To get a device_node of the `node2' node you may call this:
+ * fdtdec_parse_phandle_with_args(blob, node3, "list", "#list-cells", 0, 1,
+ *                               &args);
+ *
+ * (This function is a modified version of __of_parse_phandle_with_args() from
+ * Linux 3.18)
+ *
+ * @blob:      Pointer to device tree
+ * @src_node:  Offset of device tree node containing a list
+ * @list_name: property name that contains a list
+ * @cells_name:        property name that specifies the phandles' arguments count,
+ *             or NULL to use @cells_count
+ * @cells_count: Cell count to use if @cells_name is NULL
+ * @index:     index of a phandle to parse out
+ * @out_args:  optional pointer to output arguments structure (will be filled)
+ * @return 0 on success (with @out_args filled out if not NULL), -ENOENT if
+ *     @list_name does not exist, a phandle was not found, @cells_name
+ *     could not be found, the arguments were truncated or there were too
+ *     many arguments.
  *
- * @param gpio         pointer to the decoded gpio
- * @return 0 if successful
  */
-int fdtdec_set_gpio(struct fdt_gpio_state *gpio, int val);
+int fdtdec_parse_phandle_with_args(const void *blob, int src_node,
+                                  const char *list_name,
+                                  const char *cells_name,
+                                  int cell_count, int index,
+                                  struct fdtdec_phandle_args *out_args);
 
 /**
  * Find the next numbered alias for a peripheral. This is used to enumerate
@@ -591,50 +604,6 @@ const u32 *fdtdec_locate_array(const void *blob, int node,
  */
 int fdtdec_get_bool(const void *blob, int node, const char *prop_name);
 
-/**
- * Decode a single GPIOs from an FDT.
- *
- * If the property is not found, then the GPIO structure will still be
- * initialised, with gpio set to FDT_GPIO_NONE. This makes it easy to
- * provide optional GPIOs.
- *
- * @param blob         FDT blob to use
- * @param node         Node to look at
- * @param prop_name    Node property name
- * @param gpio         gpio elements to fill from FDT
- * @return 0 if ok, -FDT_ERR_NOTFOUND if the property is missing.
- */
-int fdtdec_decode_gpio(const void *blob, int node, const char *prop_name,
-               struct fdt_gpio_state *gpio);
-
-/**
- * Decode a list of GPIOs from an FDT. This creates a list of GPIOs with no
- * terminating item.
- *
- * @param blob         FDT blob to use
- * @param node         Node to look at
- * @param prop_name    Node property name
- * @param gpio         Array of gpio elements to fill from FDT. This will be
- *                     untouched if either 0 or an error is returned
- * @param max_count    Maximum number of elements allowed
- * @return number of GPIOs read if ok, -FDT_ERR_BADLAYOUT if max_count would
- * be exceeded, or -FDT_ERR_NOTFOUND if the property is missing.
- */
-int fdtdec_decode_gpios(const void *blob, int node, const char *prop_name,
-               struct fdt_gpio_state *gpio, int max_count);
-
-/**
- * Set up a GPIO pin according to the provided gpio information. At present this
- * just requests the GPIO.
- *
- * If the gpio is FDT_GPIO_NONE, no action is taken. This makes it easy to
- * deal with optional GPIOs.
- *
- * @param gpio         GPIO info to use for set up
- * @return 0 if all ok or gpio was FDT_GPIO_NONE; -1 on error
- */
-int fdtdec_setup_gpio(struct fdt_gpio_state *gpio);
-
 /**
  * Look in the FDT for a config item with the given name and return its value
  * as a 32-bit integer. The property must have at least 4 bytes of data. The
index ffb6ce7ada64f0498b46eac89d6a335bea83c488..fd1e4ab1c0f3880e0a4a9fdfd8e2be5df42fd4ca 100644 (file)
@@ -109,4 +109,10 @@ int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
 int do_fs_uuid(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
                int fstype);
 
+/*
+ * Determine the type of the specified filesystem and print it. Optionally it is
+ * possible to store the type directly in env.
+ */
+int do_fs_type(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
 #endif /* _FS_H */
index d8ec4f08e166702d6a33b145f82eee3c78f6a6a3..f4eb100de05f1279e82930f30e3586d319a453ca 100644 (file)
@@ -17,7 +17,6 @@ enum {
        HASH_FLAG_ENV           = 1 << 1,       /* Allow env vars */
 };
 
-#ifndef USE_HOSTCC
 #if defined(CONFIG_SHA1SUM_VERIFY) || defined(CONFIG_CRC32_VERIFY)
 #define CONFIG_HASH_VERIFY
 #endif
@@ -77,6 +76,7 @@ struct hash_algo {
                           int size);
 };
 
+#ifndef USE_HOSTCC
 /**
  * hash_command: Process a hash command for a particular algorithm
  *
@@ -114,6 +114,23 @@ int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,
 int hash_block(const char *algo_name, const void *data, unsigned int len,
               uint8_t *output, int *output_size);
 
+/**
+ * hash_show() - Print out a hash algorithm and value
+ *
+ * You will get a message like this (without a newline at the end):
+ *
+ * "sha1 for 9eb3337c ... 9eb3338f ==> 7942ef1df479fd3130f716eb9613d107dab7e257"
+ *
+ * @algo:              Algorithm used for hash
+ * @addr:              Address of data that was hashed
+ * @len:               Length of data that was hashed
+ * @output:            Hash value to display
+ */
+void hash_show(struct hash_algo *algo, ulong addr, ulong len,
+              uint8_t *output);
+
+#endif /* !USE_HOSTCC */
+
 /**
  * hash_lookup_algo() - Look up the hash_algo struct for an algorithm
  *
@@ -128,18 +145,17 @@ int hash_block(const char *algo_name, const void *data, unsigned int len,
 int hash_lookup_algo(const char *algo_name, struct hash_algo **algop);
 
 /**
- * hash_show() - Print out a hash algorithm and value
+ * hash_progressive_lookup_algo() - Look up hash_algo for prog. hash support
  *
- * You will get a message like this (without a newline at the end):
+ * The function returns the pointer to the struct or -EPROTONOSUPPORT if the
+ * algorithm is not available with progressive hash support.
  *
- * "sha1 for 9eb3337c ... 9eb3338f ==> 7942ef1df479fd3130f716eb9613d107dab7e257"
+ * @algo_name: Hash algorithm to look up
+ * @algop: Pointer to the hash_algo struct if found
  *
- * @algo:              Algorithm used for hash
- * @addr:              Address of data that was hashed
- * @len:               Length of data that was hashed
- * @output:            Hash value to display
+ * @return 0 if ok, -EPROTONOSUPPORT for an unknown algorithm.
  */
-void hash_show(struct hash_algo *algo, ulong addr, ulong len,
-              uint8_t *output);
-#endif /* !USE_HOSTCC */
+int hash_progressive_lookup_algo(const char *algo_name,
+                                struct hash_algo **algop);
+
 #endif
index 9c6a60cf9ae89e50e2a4d2dfaa94874a56774e1f..27fe00f17361763a42bc13f59e378d464c484dc6 100644 (file)
@@ -39,8 +39,8 @@ enum dm_i2c_chip_flags {
  * An I2C chip is a device on the I2C bus. It sits at a particular address
  * and normally supports 7-bit or 10-bit addressing.
  *
- * To obtain this structure, use dev_get_parentdata(dev) where dev is the
- * chip to examine.
+ * To obtain this structure, use dev_get_parent_platdata(dev) where dev is
+ * the chip to examine.
  *
  * @chip_addr: Chip address on bus
  * @offset_len: Length of offset in bytes. A single byte offset can
@@ -75,7 +75,7 @@ struct dm_i2c_bus {
 };
 
 /**
- * i2c_read() - read bytes from an I2C chip
+ * dm_i2c_read() - read bytes from an I2C chip
  *
  * To obtain an I2C device (called a 'chip') given the I2C bus address you
  * can use i2c_get_chip(). To obtain a bus by bus number use
@@ -91,13 +91,12 @@ struct dm_i2c_bus {
  *
  * @return 0 on success, -ve on failure
  */
-int i2c_read(struct udevice *dev, uint offset, uint8_t *buffer,
-            int len);
+int dm_i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len);
 
 /**
- * i2c_write() - write bytes to an I2C chip
+ * dm_i2c_write() - write bytes to an I2C chip
  *
- * See notes for i2c_read() above.
+ * See notes for dm_i2c_read() above.
  *
  * @dev:       Chip to write to
  * @offset:    Offset within chip to start writing
@@ -106,11 +105,11 @@ int i2c_read(struct udevice *dev, uint offset, uint8_t *buffer,
  *
  * @return 0 on success, -ve on failure
  */
-int i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer,
-             int len);
+int dm_i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer,
+                int len);
 
 /**
- * i2c_probe() - probe a particular chip address
+ * dm_i2c_probe() - probe a particular chip address
  *
  * This can be useful to check for the existence of a chip on the bus.
  * It is typically implemented by writing the chip address to the bus
@@ -122,8 +121,8 @@ int i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer,
  * @devp:      Returns the device found, or NULL if none
  * @return 0 if a chip was found at that address, -ve if not
  */
-int i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags,
-             struct udevice **devp);
+int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags,
+                struct udevice **devp);
 
 /**
  * i2c_set_bus_speed() - set the speed of a bus
@@ -185,6 +184,80 @@ int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len);
  */
 int i2c_deblock(struct udevice *bus);
 
+#ifdef CONFIG_DM_I2C_COMPAT
+/**
+ * i2c_probe() - Compatibility function for driver model
+ *
+ * Calls dm_i2c_probe() on the current bus
+ */
+int i2c_probe(uint8_t chip_addr);
+
+/**
+ * i2c_read() - Compatibility function for driver model
+ *
+ * Calls dm_i2c_read() with the device corresponding to @chip_addr, and offset
+ * set to @addr. @alen must match the current setting for the device.
+ */
+int i2c_read(uint8_t chip_addr, unsigned int addr, int alen, uint8_t *buffer,
+            int len);
+
+/**
+ * i2c_write() - Compatibility function for driver model
+ *
+ * Calls dm_i2c_write() with the device corresponding to @chip_addr, and offset
+ * set to @addr. @alen must match the current setting for the device.
+ */
+int i2c_write(uint8_t chip_addr, unsigned int addr, int alen, uint8_t *buffer,
+             int len);
+
+/**
+ * i2c_get_bus_num_fdt() - Compatibility function for driver model
+ *
+ * @return the bus number associated with the given device tree node
+ */
+int i2c_get_bus_num_fdt(int node);
+
+/**
+ * i2c_get_bus_num() - Compatibility function for driver model
+ *
+ * @return the 'current' bus number
+ */
+unsigned int i2c_get_bus_num(void);
+
+/**
+ * i2c_set_bus_num() - Compatibility function for driver model
+ *
+ * Sets the 'current' bus
+ */
+int i2c_set_bus_num(unsigned int bus);
+
+static inline void I2C_SET_BUS(unsigned int bus)
+{
+       i2c_set_bus_num(bus);
+}
+
+static inline unsigned int I2C_GET_BUS(void)
+{
+       return i2c_get_bus_num();
+}
+
+/**
+ * i2c_init() - Compatibility function for driver model
+ *
+ * This function does nothing.
+ */
+void i2c_init(int speed, int slaveaddr);
+
+/**
+ * board_i2c_init() - Compatibility function for driver model
+ *
+ * @param blob  Device tree blbo
+ * @return the number of I2C bus
+ */
+void board_i2c_init(const void *blob);
+
+#endif
+
 /*
  * Not all of these flags are implemented in the U-Boot API
  */
@@ -330,10 +403,12 @@ struct dm_i2c_ops {
  *
  * @bus:       Bus to examine
  * @chip_addr: Chip address for the new device
+ * @offset_len:        Length of a register offset in bytes (normally 1)
  * @devp:      Returns pointer to new device if found or -ENODEV if not
  *             found
  */
-int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp);
+int i2c_get_chip(struct udevice *bus, uint chip_addr, uint offset_len,
+                struct udevice **devp);
 
 /**
  * i2c_get_chip() - get a device to use to access a chip on a bus number
@@ -343,10 +418,12 @@ int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp);
  *
  * @busnum:    Bus number to examine
  * @chip_addr: Chip address for the new device
+ * @offset_len:        Length of a register offset in bytes (normally 1)
  * @devp:      Returns pointer to new device if found or -ENODEV if not
  *             found
  */
-int i2c_get_chip_for_busnum(int busnum, int chip_addr, struct udevice **devp);
+int i2c_get_chip_for_busnum(int busnum, int chip_addr, uint offset_len,
+                           struct udevice **devp);
 
 /**
  * i2c_chip_ofdata_to_platdata() - Decode standard I2C platform data
index ee3afe35670a9b460921ba0b2f5218df5a76b0c0..0e6af00c16bbab07a7c1284bca9963b0a4f2155c 100644 (file)
@@ -751,6 +751,7 @@ int fit_parse_conf(const char *spec, ulong addr_curr,
 int fit_parse_subimage(const char *spec, ulong addr_curr,
                ulong *addr, const char **image_name);
 
+int fit_get_subimage_count(const void *fit, int images_noffset);
 void fit_print_contents(const void *fit);
 void fit_image_print(const void *fit, int noffset, const char *p);
 
@@ -927,8 +928,9 @@ struct checksum_algo {
 #if IMAGE_ENABLE_SIGN
        const EVP_MD *(*calculate_sign)(void);
 #endif
-       void (*calculate)(const struct image_region region[],
-                         int region_count, uint8_t *checksum);
+       int (*calculate)(const char *name,
+                        const struct image_region region[],
+                        int region_count, uint8_t *checksum);
        const uint8_t *rsa_padding;
 };
 
index d37fba44dcafc6b1ce6813cca4e8f3d6999e95d5..940c87128194b654c364c477fc3ba864a523ffc0 100644 (file)
@@ -23,7 +23,7 @@
 
 /**
  * A linker list is constructed by grouping together linker input
- * sections, each containning one entry of the list. Each input section
+ * sections, each containing one entry of the list. Each input section
  * contains a constant initialized variable which holds the entry's
  * content. Linker list input sections are constructed from the list
  * and entry names, plus a prefix which allows grouping all lists
@@ -39,7 +39,7 @@
  * This ensures uniqueness for both input section and C variable name.
  *
  * Note that the names differ only in the first character, "." for the
- * setion and "_" for the variable, so that the linker cannot confuse
+ * section and "_" for the variable, so that the linker cannot confuse
  * section and symbol names. From now on, both names will be referred
  * to as
  *
index aa4a0e9654dd6262839aec65df1d8fab08e16076..23893b57408056ea3cd077af2923a300e53c36fb 100644 (file)
@@ -12,7 +12,7 @@
 
 #include <asm/io.h>
 #include <mmc.h>
-#include <fdtdec.h>
+#include <asm/gpio.h>
 
 /*
  * Controller registers
@@ -246,8 +246,8 @@ struct sdhci_host {
        int index;
 
        int bus_width;
-       struct fdt_gpio_state pwr_gpio; /* Power GPIO */
-       struct fdt_gpio_state cd_gpio;          /* Card Detect GPIO */
+       struct gpio_desc pwr_gpio;      /* Power GPIO */
+       struct gpio_desc cd_gpio;               /* Card Detect GPIO */
 
        void (*set_control_reg)(struct sdhci_host *host);
        void (*set_clock)(int dev_index, unsigned int div);
index ec17bd0bcc8963e4c4e402e57c0003d3b839b568..c58e453559616eb1cbbca36ee20704afcd4ebecc 100644 (file)
 #define SPI_DEFAULT_WORDLEN 8
 
 #ifdef CONFIG_DM_SPI
+/* TODO(sjg@chromium.org): Remove this and use max_hz from struct spi_slave */
 struct dm_spi_bus {
        uint max_hz;
 };
 
+/**
+ * struct dm_spi_platdata - platform data for all SPI slaves
+ *
+ * This describes a SPI slave, a child device of the SPI bus. To obtain this
+ * struct from a spi_slave, use dev_get_parent_platdata(dev) or
+ * dev_get_parent_platdata(slave->dev).
+ *
+ * This data is immuatable. Each time the device is probed, @max_hz and @mode
+ * will be copied to struct spi_slave.
+ *
+ * @cs:                Chip select number (0..n-1)
+ * @max_hz:    Maximum bus speed that this slave can tolerate
+ * @mode:      SPI mode to use for this device (see SPI mode flags)
+ */
+struct dm_spi_slave_platdata {
+       unsigned int cs;
+       uint max_hz;
+       uint mode;
+};
+
 #endif /* CONFIG_DM_SPI */
 
 /**
  * struct spi_slave - Representation of a SPI slave
  *
  * For driver model this is the per-child data used by the SPI bus. It can
- * be accessed using dev_get_parentdata() on the slave device. Each SPI
- * driver should define this child data in its U_BOOT_DRIVER() definition:
- *
- *     .per_child_auto_alloc_size      = sizeof(struct spi_slave),
+ * be accessed using dev_get_parentdata() on the slave device. The SPI uclass
+ * sets uip per_child_auto_alloc_size to sizeof(struct spi_slave), and the
+ * driver should not override it. Two platform data fields (max_hz and mode)
+ * are copied into this structure to provide an initial value. This allows
+ * them to be changed, since we should never change platform data in drivers.
  *
  * If not using driver model, drivers are expected to extend this with
  * controller-specific data.
@@ -97,8 +119,8 @@ struct spi_slave {
        uint mode;
 #else
        unsigned int bus;
-#endif
        unsigned int cs;
+#endif
        u8 op_mode_rx;
        u8 op_mode_tx;
        unsigned int wordlen;
@@ -545,16 +567,16 @@ int spi_chip_select(struct udevice *slave);
 int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp);
 
 /**
- * spi_ofdata_to_platdata() - decode standard SPI platform data
+ * spi_slave_ofdata_to_platdata() - decode standard SPI platform data
  *
- * This decodes the speed and mode from a device tree node and puts it into
- * the spi_slave structure.
+ * This decodes the speed and mode for a slave from a device tree node
  *
  * @blob:      Device tree blob
  * @node:      Node offset to read from
- * @spi:       Place to put the decoded information
+ * @plat:      Place to put the decoded information
  */
-int spi_ofdata_to_platdata(const void *blob, int node, struct spi_slave *spi);
+int spi_slave_ofdata_to_platdata(const void *blob, int node,
+                                struct dm_spi_slave_platdata *plat);
 
 /**
  * spi_cs_info() - Check information on a chip select
index c996fb3e4c10eaf7c73451bbc8e7cf420b96d3d3..3c69d85ecbac7956a525b2e188943b46193259a3 100644 (file)
@@ -16,9 +16,18 @@ extern const uint8_t padding_sha256_rsa4096[];
 extern const uint8_t padding_sha256_rsa2048[];
 extern const uint8_t padding_sha1_rsa2048[];
 
-void sha256_calculate(const struct image_region region[], int region_count,
-                     uint8_t *checksum);
-void sha1_calculate(const struct image_region region[], int region_count,
-                   uint8_t *checksum);
+/**
+ * hash_calculate() - Calculate hash over the data
+ *
+ * @name:  Name of algorithm to be used for hash calculation
+ * @region: Array having info of regions over which hash needs to be calculated
+ * @region_count: Number of regions in the region array
+ * @checksum: Buffer contanining the output hash
+ *
+ * @return 0 if OK, < 0 if error
+ */
+int hash_calculate(const char *name,
+                  const struct image_region region[], int region_count,
+                  uint8_t *checksum);
 
 #endif
diff --git a/include/u-boot/rsa-mod-exp.h b/include/u-boot/rsa-mod-exp.h
new file mode 100644 (file)
index 0000000..fce445a
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014, Ruchika Gupta.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+*/
+
+#ifndef _RSA_MOD_EXP_H
+#define _RSA_MOD_EXP_H
+
+#include <errno.h>
+#include <image.h>
+
+/**
+ * struct key_prop - holder for a public key properties
+ *
+ * The struct has pointers to modulus (Typically called N),
+ * The inverse, R^2, exponent. These can be typecasted and
+ * used as byte arrays or converted to the required format
+ * as per requirement of RSA implementation.
+ */
+struct key_prop {
+       const void *rr;         /* R^2 can be treated as byte array */
+       const void *modulus;    /* modulus as byte array */
+       const void *public_exponent; /* public exponent as byte array */
+       uint32_t n0inv;         /* -1 / modulus[0] mod 2^32 */
+       int num_bits;           /* Key length in bits */
+       uint32_t exp_len;       /* Exponent length in number of uint8_t */
+};
+
+/**
+ * rsa_mod_exp_sw() - Perform RSA Modular Exponentiation in sw
+ *
+ * Operation: out[] = sig ^ exponent % modulus
+ *
+ * @sig:       RSA PKCS1.5 signature
+ * @sig_len:   Length of signature in number of bytes
+ * @node:      Node with RSA key elements like modulus, exponent, R^2, n0inv
+ * @out:       Result in form of byte array of len equal to sig_len
+ */
+int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
+               struct key_prop *node, uint8_t *out);
+
+int rsa_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len,
+               struct key_prop *node, uint8_t *out);
+
+/**
+ * struct struct mod_exp_ops - Driver model for RSA Modular Exponentiation
+ *                             operations
+ *
+ * The uclass interface is implemented by all crypto devices which use
+ * driver model.
+ */
+struct mod_exp_ops {
+       /**
+        * Perform Modular Exponentiation
+        *
+        * Operation: out[] = sig ^ exponent % modulus
+        *
+        * @dev:        RSA Device
+        * @sig:        RSA PKCS1.5 signature
+        * @sig_len:    Length of signature in number of bytes
+        * @node:       Node with RSA key elements like modulus, exponent,
+        *              R^2, n0inv
+        * @out:        Result in form of byte array of len equal to sig_len
+        *
+        * This function computes exponentiation over the signature.
+        * Returns: 0 if exponentiation is successful, or a negative value
+        * if it wasn't.
+        */
+       int (*mod_exp)(struct udevice *dev, const uint8_t *sig,
+                          uint32_t sig_len, struct key_prop *node,
+                          uint8_t *outp);
+};
+
+#endif
index 8460439d8e772d4126b78ad616059dd38a7dabff..a1f30a2c4ef0931483cf80010ef0674ea5dbbb58 100644 (file)
@@ -27,4 +27,6 @@ config SYS_HZ
          get_timer() must operate in milliseconds and this option must be
          set to 1000.
 
+source lib/rsa/Kconfig
+
 endmenu
index e989241b7095269e90d08f3b2fc5550d6e21d605..5bf8f29b13e92fbfcb9f0d83132e0e6ac987d0e2 100644 (file)
@@ -11,8 +11,6 @@
 #include <fdtdec.h>
 #include <linux/ctype.h>
 
-#include <asm/gpio.h>
-
 DECLARE_GLOBAL_DATA_PTR;
 
 /*
@@ -26,9 +24,6 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(NVIDIA_TEGRA20_USB, "nvidia,tegra20-ehci"),
        COMPAT(NVIDIA_TEGRA30_USB, "nvidia,tegra30-ehci"),
        COMPAT(NVIDIA_TEGRA114_USB, "nvidia,tegra114-ehci"),
-       COMPAT(NVIDIA_TEGRA114_I2C, "nvidia,tegra114-i2c"),
-       COMPAT(NVIDIA_TEGRA20_I2C, "nvidia,tegra20-i2c"),
-       COMPAT(NVIDIA_TEGRA20_DVC, "nvidia,tegra20-i2c-dvc"),
        COMPAT(NVIDIA_TEGRA20_EMC, "nvidia,tegra20-emc"),
        COMPAT(NVIDIA_TEGRA20_EMC_TABLE, "nvidia,tegra20-emc-table"),
        COMPAT(NVIDIA_TEGRA20_KBC, "nvidia,tegra20-kbc"),
@@ -38,9 +33,6 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(NVIDIA_TEGRA124_SDMMC, "nvidia,tegra124-sdhci"),
        COMPAT(NVIDIA_TEGRA30_SDMMC, "nvidia,tegra30-sdhci"),
        COMPAT(NVIDIA_TEGRA20_SDMMC, "nvidia,tegra20-sdhci"),
-       COMPAT(NVIDIA_TEGRA20_SFLASH, "nvidia,tegra20-sflash"),
-       COMPAT(NVIDIA_TEGRA20_SLINK, "nvidia,tegra20-slink"),
-       COMPAT(NVIDIA_TEGRA114_SPI, "nvidia,tegra114-spi"),
        COMPAT(NVIDIA_TEGRA124_PCIE, "nvidia,tegra124-pcie"),
        COMPAT(NVIDIA_TEGRA30_PCIE, "nvidia,tegra30-pcie"),
        COMPAT(NVIDIA_TEGRA20_PCIE, "nvidia,tegra20-pcie"),
@@ -50,7 +42,6 @@ static const char * const compat_names[COMPAT_COUNT] = {
        COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"),
        COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"),
        COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"),
-       COMPAT(SAMSUNG_EXYNOS_SPI, "samsung,exynos-spi"),
        COMPAT(GOOGLE_CROS_EC, "google,cros-ec"),
        COMPAT(GOOGLE_CROS_EC_KEYB, "google,cros-ec-keyb"),
        COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"),
@@ -679,99 +670,128 @@ int fdtdec_get_bool(const void *blob, int node, const char *prop_name)
        return cell != NULL;
 }
 
-/**
- * Decode a list of GPIOs from an FDT. This creates a list of GPIOs with no
- * terminating item.
- *
- * @param blob         FDT blob to use
- * @param node         Node to look at
- * @param prop_name    Node property name
- * @param gpio         Array of gpio elements to fill from FDT. This will be
- *                     untouched if either 0 or an error is returned
- * @param max_count    Maximum number of elements allowed
- * @return number of GPIOs read if ok, -FDT_ERR_BADLAYOUT if max_count would
- * be exceeded, or -FDT_ERR_NOTFOUND if the property is missing.
- */
-int fdtdec_decode_gpios(const void *blob, int node, const char *prop_name,
-               struct fdt_gpio_state *gpio, int max_count)
+int fdtdec_parse_phandle_with_args(const void *blob, int src_node,
+                                  const char *list_name,
+                                  const char *cells_name,
+                                  int cell_count, int index,
+                                  struct fdtdec_phandle_args *out_args)
 {
-       const struct fdt_property *prop;
-       const u32 *cell;
-       const char *name;
-       int len, i;
-
-       debug("%s: %s\n", __func__, prop_name);
-       assert(max_count > 0);
-       prop = fdt_get_property(blob, node, prop_name, &len);
-       if (!prop) {
-               debug("%s: property '%s' missing\n", __func__, prop_name);
-               return -FDT_ERR_NOTFOUND;
-       }
-
-       /* We will use the name to tag the GPIO */
-       name = fdt_string(blob, fdt32_to_cpu(prop->nameoff));
-       cell = (u32 *)prop->data;
-       len /= sizeof(u32) * 3;         /* 3 cells per GPIO record */
-       if (len > max_count) {
-               debug(" %s: too many GPIOs / cells for "
-                       "property '%s'\n", __func__, prop_name);
-               return -FDT_ERR_BADLAYOUT;
-       }
-
-       /* Read out the GPIO data from the cells */
-       for (i = 0; i < len; i++, cell += 3) {
-               gpio[i].gpio = fdt32_to_cpu(cell[1]);
-               gpio[i].flags = fdt32_to_cpu(cell[2]);
-               gpio[i].name = name;
-       }
-
-       return len;
-}
+       const __be32 *list, *list_end;
+       int rc = 0, size, cur_index = 0;
+       uint32_t count = 0;
+       int node = -1;
+       int phandle;
+
+       /* Retrieve the phandle list property */
+       list = fdt_getprop(blob, src_node, list_name, &size);
+       if (!list)
+               return -ENOENT;
+       list_end = list + size / sizeof(*list);
 
-int fdtdec_decode_gpio(const void *blob, int node, const char *prop_name,
-               struct fdt_gpio_state *gpio)
-{
-       int err;
+       /* Loop over the phandles until all the requested entry is found */
+       while (list < list_end) {
+               rc = -EINVAL;
+               count = 0;
 
-       debug("%s: %s\n", __func__, prop_name);
-       gpio->gpio = FDT_GPIO_NONE;
-       gpio->name = NULL;
-       err = fdtdec_decode_gpios(blob, node, prop_name, gpio, 1);
-       return err == 1 ? 0 : err;
-}
+               /*
+                * If phandle is 0, then it is an empty entry with no
+                * arguments.  Skip forward to the next entry.
+                */
+               phandle = be32_to_cpup(list++);
+               if (phandle) {
+                       /*
+                        * Find the provider node and parse the #*-cells
+                        * property to determine the argument length.
+                        *
+                        * This is not needed if the cell count is hard-coded
+                        * (i.e. cells_name not set, but cell_count is set),
+                        * except when we're going to return the found node
+                        * below.
+                        */
+                       if (cells_name || cur_index == index) {
+                               node = fdt_node_offset_by_phandle(blob,
+                                                                 phandle);
+                               if (!node) {
+                                       debug("%s: could not find phandle\n",
+                                             fdt_get_name(blob, src_node,
+                                                          NULL));
+                                       goto err;
+                               }
+                       }
 
-int fdtdec_get_gpio(struct fdt_gpio_state *gpio)
-{
-       int val;
+                       if (cells_name) {
+                               count = fdtdec_get_int(blob, node, cells_name,
+                                                      -1);
+                               if (count == -1) {
+                                       debug("%s: could not get %s for %s\n",
+                                             fdt_get_name(blob, src_node,
+                                                          NULL),
+                                             cells_name,
+                                             fdt_get_name(blob, node,
+                                                          NULL));
+                                       goto err;
+                               }
+                       } else {
+                               count = cell_count;
+                       }
 
-       if (!fdt_gpio_isvalid(gpio))
-               return -1;
+                       /*
+                        * Make sure that the arguments actually fit in the
+                        * remaining property data length
+                        */
+                       if (list + count > list_end) {
+                               debug("%s: arguments longer than property\n",
+                                     fdt_get_name(blob, src_node, NULL));
+                               goto err;
+                       }
+               }
 
-       val = gpio_get_value(gpio->gpio);
-       return gpio->flags & FDT_GPIO_ACTIVE_LOW ? val ^ 1 : val;
-}
+               /*
+                * All of the error cases above bail out of the loop, so at
+                * this point, the parsing is successful. If the requested
+                * index matches, then fill the out_args structure and return,
+                * or return -ENOENT for an empty entry.
+                */
+               rc = -ENOENT;
+               if (cur_index == index) {
+                       if (!phandle)
+                               goto err;
+
+                       if (out_args) {
+                               int i;
+
+                               if (count > MAX_PHANDLE_ARGS) {
+                                       debug("%s: too many arguments %d\n",
+                                             fdt_get_name(blob, src_node,
+                                                          NULL), count);
+                                       count = MAX_PHANDLE_ARGS;
+                               }
+                               out_args->node = node;
+                               out_args->args_count = count;
+                               for (i = 0; i < count; i++) {
+                                       out_args->args[i] =
+                                                       be32_to_cpup(list++);
+                               }
+                       }
 
-int fdtdec_set_gpio(struct fdt_gpio_state *gpio, int val)
-{
-       if (!fdt_gpio_isvalid(gpio))
-               return -1;
+                       /* Found it! return success */
+                       return 0;
+               }
 
-       val = gpio->flags & FDT_GPIO_ACTIVE_LOW ? val ^ 1 : val;
-       return gpio_set_value(gpio->gpio, val);
-}
+               node = -1;
+               list += count;
+               cur_index++;
+       }
 
-int fdtdec_setup_gpio(struct fdt_gpio_state *gpio)
-{
        /*
-        * Return success if there is no GPIO defined. This is used for
-        * optional GPIOs)
+        * Result will be one of:
+        * -ENOENT : index is for empty phandle
+        * -EINVAL : parsing error on data
+        * [1..n]  : Number of phandle (count mode; when index = -1)
         */
-       if (!fdt_gpio_isvalid(gpio))
-               return 0;
-
-       if (gpio_request(gpio->gpio, gpio->name))
-               return -1;
-       return 0;
+       rc = index < 0 ? cur_index : -ENOENT;
+ err:
+       return rc;
 }
 
 int fdtdec_get_byte_array(const void *blob, int node, const char *prop_name,
diff --git a/lib/rsa/Kconfig b/lib/rsa/Kconfig
new file mode 100644 (file)
index 0000000..1268a1b
--- /dev/null
@@ -0,0 +1,27 @@
+config RSA
+       bool "Use RSA Library"
+       select RSA_FREESCALE_EXP if FSL_CAAM
+       select RSA_SOFTWARE_EXP if !RSA_FREESCALE_EXP
+       help
+         RSA support. This enables the RSA algorithm used for FIT image
+         verification in U-Boot.
+         See doc/uImage.FIT/signature.txt for more details.
+
+if RSA
+config RSA_SOFTWARE_EXP
+       bool "Enable driver for RSA Modular Exponentiation in software"
+       depends on DM && RSA
+       help
+         Enables driver for modular exponentiation in software. This is a RSA
+         algorithm used in FIT image verification. It required RSA Key as
+         input.
+         See doc/uImage.FIT/signature.txt for more details.
+
+config RSA_FREESCALE_EXP
+       bool "Enable RSA Modular Exponentiation with FSL crypto accelerator"
+       depends on DM && RSA && FSL_CAAM
+       help
+       Enables driver for RSA modular exponentiation using Freescale cryptographic
+       accelerator - CAAM.
+
+endif
index a5a96cb680d16d1cea1f88375f2ca1ec7bfc1776..cc25b3ce6d9232c60ff0b848632265b8a2788626 100644 (file)
@@ -7,4 +7,4 @@
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
-obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o
+obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o rsa-mod-exp.o
index 8d8b59f779a2bd7d5d9eeb413706c86b5307d9ff..68d9d651b02860ab6cf422be4be62565834370c6 100644 (file)
 #include <asm/byteorder.h>
 #include <asm/errno.h>
 #include <asm/unaligned.h>
+#include <hash.h>
 #else
 #include "fdt_host.h"
-#endif
-#include <u-boot/rsa.h>
 #include <u-boot/sha1.h>
 #include <u-boot/sha256.h>
+#endif
+#include <u-boot/rsa.h>
 
 /* PKCS 1.5 paddings as described in the RSA PKCS#1 v2.1 standard. */
 
@@ -136,28 +137,37 @@ const uint8_t padding_sha256_rsa4096[RSA4096_BYTES - SHA256_SUM_LEN] = {
        0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
 };
 
-void sha1_calculate(const struct image_region region[], int region_count,
-                   uint8_t *checksum)
+int hash_calculate(const char *name,
+                   const struct image_region region[],
+                   int region_count, uint8_t *checksum)
 {
-       sha1_context ctx;
+       struct hash_algo *algo;
+       int ret = 0;
+       void *ctx;
        uint32_t i;
        i = 0;
 
-       sha1_starts(&ctx);
-       for (i = 0; i < region_count; i++)
-               sha1_update(&ctx, region[i].data, region[i].size);
-       sha1_finish(&ctx, checksum);
-}
+       ret = hash_progressive_lookup_algo(name, &algo);
+       if (ret)
+               return ret;
 
-void sha256_calculate(const struct image_region region[], int region_count,
-                     uint8_t *checksum)
-{
-       sha256_context ctx;
-       uint32_t i;
-       i = 0;
+       ret = algo->hash_init(algo, &ctx);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < region_count - 1; i++) {
+               ret = algo->hash_update(algo, ctx, region[i].data,
+                                       region[i].size, 0);
+               if (ret)
+                       return ret;
+       }
+
+       ret = algo->hash_update(algo, ctx, region[i].data, region[i].size, 1);
+       if (ret)
+               return ret;
+       ret = algo->hash_finish(algo, ctx, checksum, algo->digest_size);
+       if (ret)
+               return ret;
 
-       sha256_starts(&ctx);
-       for (i = 0; i < region_count; i++)
-               sha256_update(&ctx, region[i].data, region[i].size);
-       sha256_finish(&ctx, checksum);
+       return 0;
 }
diff --git a/lib/rsa/rsa-mod-exp.c b/lib/rsa/rsa-mod-exp.c
new file mode 100644 (file)
index 0000000..4a6de2b
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2013, Google Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef USE_HOSTCC
+#include <common.h>
+#include <fdtdec.h>
+#include <asm/types.h>
+#include <asm/byteorder.h>
+#include <asm/errno.h>
+#include <asm/types.h>
+#include <asm/unaligned.h>
+#else
+#include "fdt_host.h"
+#include "mkimage.h"
+#include <fdt_support.h>
+#endif
+#include <u-boot/rsa.h>
+#include <u-boot/rsa-mod-exp.h>
+
+#define UINT64_MULT32(v, multby)  (((uint64_t)(v)) * ((uint32_t)(multby)))
+
+#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
+ *
+ * @key:       Key containing modulus to subtract
+ * @num:       Number to subtract modulus from, as little endian word array
+ */
+static void subtract_modulus(const struct rsa_public_key *key, uint32_t num[])
+{
+       int64_t acc = 0;
+       uint i;
+
+       for (i = 0; i < key->len; i++) {
+               acc += (uint64_t)num[i] - key->modulus[i];
+               num[i] = (uint32_t)acc;
+               acc >>= 32;
+       }
+}
+
+/**
+ * greater_equal_modulus() - check if a value is >= modulus
+ *
+ * @key:       Key containing modulus to check
+ * @num:       Number to check against modulus, as little endian word array
+ * @return 0 if num < modulus, 1 if num >= modulus
+ */
+static int greater_equal_modulus(const struct rsa_public_key *key,
+                                uint32_t num[])
+{
+       int i;
+
+       for (i = (int)key->len - 1; i >= 0; i--) {
+               if (num[i] < key->modulus[i])
+                       return 0;
+               if (num[i] > key->modulus[i])
+                       return 1;
+       }
+
+       return 1;  /* equal */
+}
+
+/**
+ * montgomery_mul_add_step() - Perform montgomery multiply-add step
+ *
+ * Operation: montgomery result[] += a * b[] / n0inv % modulus
+ *
+ * @key:       RSA key
+ * @result:    Place to put result, as little endian word array
+ * @a:         Multiplier
+ * @b:         Multiplicand, as little endian word array
+ */
+static void montgomery_mul_add_step(const struct rsa_public_key *key,
+               uint32_t result[], const uint32_t a, const uint32_t b[])
+{
+       uint64_t acc_a, acc_b;
+       uint32_t d0;
+       uint i;
+
+       acc_a = (uint64_t)a * b[0] + result[0];
+       d0 = (uint32_t)acc_a * key->n0inv;
+       acc_b = (uint64_t)d0 * key->modulus[0] + (uint32_t)acc_a;
+       for (i = 1; i < key->len; i++) {
+               acc_a = (acc_a >> 32) + (uint64_t)a * b[i] + result[i];
+               acc_b = (acc_b >> 32) + (uint64_t)d0 * key->modulus[i] +
+                               (uint32_t)acc_a;
+               result[i - 1] = (uint32_t)acc_b;
+       }
+
+       acc_a = (acc_a >> 32) + (acc_b >> 32);
+
+       result[i - 1] = (uint32_t)acc_a;
+
+       if (acc_a >> 32)
+               subtract_modulus(key, result);
+}
+
+/**
+ * montgomery_mul() - Perform montgomery mutitply
+ *
+ * Operation: montgomery result[] = a[] * b[] / n0inv % modulus
+ *
+ * @key:       RSA key
+ * @result:    Place to put result, as little endian word array
+ * @a:         Multiplier, as little endian word array
+ * @b:         Multiplicand, as little endian word array
+ */
+static void montgomery_mul(const struct rsa_public_key *key,
+               uint32_t result[], uint32_t a[], const uint32_t b[])
+{
+       uint i;
+
+       for (i = 0; i < key->len; ++i)
+               result[i] = 0;
+       for (i = 0; i < key->len; ++i)
+               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
+ *
+ * @key:       RSA key
+ * @inout:     Big-endian word array containing value and result
+ */
+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) {
+               debug("RSA key words %u exceeds maximum %d\n", key->len,
+                     RSA_MAX_KEY_BITS / 32);
+               return -EINVAL;
+       }
+
+       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);
+
+       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;
+       }
+
+       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))
+               subtract_modulus(key, result);
+
+       /* Convert to bigendian byte array */
+       for (i = key->len - 1, ptr = inout; (int)i >= 0; i--, ptr++)
+               put_unaligned_be32(result[i], ptr);
+       return 0;
+}
+
+static void rsa_convert_big_endian(uint32_t *dst, const uint32_t *src, int len)
+{
+       int i;
+
+       for (i = 0; i < len; i++)
+               dst[i] = fdt32_to_cpu(src[len - 1 - i]);
+}
+
+int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len,
+               struct key_prop *prop, uint8_t *out)
+{
+       struct rsa_public_key key;
+       int ret;
+
+       if (!prop) {
+               debug("%s: Skipping invalid prop", __func__);
+               return -EBADF;
+       }
+       key.n0inv = prop->n0inv;
+       key.len = prop->num_bits;
+
+       if (!prop->public_exponent)
+               key.exponent = RSA_DEFAULT_PUBEXP;
+       else
+               key.exponent =
+                       fdt64_to_cpu(*((uint64_t *)(prop->public_exponent)));
+
+       if (!key.len || !prop->modulus || !prop->rr) {
+               debug("%s: Missing RSA key info", __func__);
+               return -EFAULT;
+       }
+
+       /* Sanity check for stack size */
+       if (key.len > RSA_MAX_KEY_BITS || key.len < RSA_MIN_KEY_BITS) {
+               debug("RSA key bits %u outside allowed range %d..%d\n",
+                     key.len, RSA_MIN_KEY_BITS, RSA_MAX_KEY_BITS);
+               return -EFAULT;
+       }
+       key.len /= sizeof(uint32_t) * 8;
+       uint32_t key1[key.len], key2[key.len];
+
+       key.modulus = key1;
+       key.rr = key2;
+       rsa_convert_big_endian(key.modulus, (uint32_t *)prop->modulus, key.len);
+       rsa_convert_big_endian(key.rr, (uint32_t *)prop->rr, key.len);
+       if (!key.modulus || !key.rr) {
+               debug("%s: Out of memory", __func__);
+               return -ENOMEM;
+       }
+
+       uint32_t buf[sig_len / sizeof(uint32_t)];
+
+       memcpy(buf, sig, sig_len);
+
+       ret = pow_mod(&key, buf);
+       if (ret)
+               return ret;
+
+       memcpy(out, buf, sig_len);
+
+       return 0;
+}
index 4ef19b66f4b12588f2bbe0a978500a0718177336..60126d22884b6e29dd18887ee7fbad90869ed049 100644 (file)
 #include <asm/errno.h>
 #include <asm/types.h>
 #include <asm/unaligned.h>
+#include <dm.h>
 #else
 #include "fdt_host.h"
 #include "mkimage.h"
 #include <fdt_support.h>
 #endif
+#include <u-boot/rsa-mod-exp.h>
 #include <u-boot/rsa.h>
-#include <u-boot/sha1.h>
-#include <u-boot/sha256.h>
-
-#define UINT64_MULT32(v, multby)  (((uint64_t)(v)) * ((uint32_t)(multby)))
-
-#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
- *
- * @key:       Key containing modulus to subtract
- * @num:       Number to subtract modulus from, as little endian word array
- */
-static void subtract_modulus(const struct rsa_public_key *key, uint32_t num[])
-{
-       int64_t acc = 0;
-       uint i;
-
-       for (i = 0; i < key->len; i++) {
-               acc += (uint64_t)num[i] - key->modulus[i];
-               num[i] = (uint32_t)acc;
-               acc >>= 32;
-       }
-}
-
-/**
- * greater_equal_modulus() - check if a value is >= modulus
- *
- * @key:       Key containing modulus to check
- * @num:       Number to check against modulus, as little endian word array
- * @return 0 if num < modulus, 1 if num >= modulus
- */
-static int greater_equal_modulus(const struct rsa_public_key *key,
-                                uint32_t num[])
-{
-       int i;
-
-       for (i = (int)key->len - 1; i >= 0; i--) {
-               if (num[i] < key->modulus[i])
-                       return 0;
-               if (num[i] > key->modulus[i])
-                       return 1;
-       }
-
-       return 1;  /* equal */
-}
-
-/**
- * montgomery_mul_add_step() - Perform montgomery multiply-add step
- *
- * Operation: montgomery result[] += a * b[] / n0inv % modulus
- *
- * @key:       RSA key
- * @result:    Place to put result, as little endian word array
- * @a:         Multiplier
- * @b:         Multiplicand, as little endian word array
- */
-static void montgomery_mul_add_step(const struct rsa_public_key *key,
-               uint32_t result[], const uint32_t a, const uint32_t b[])
-{
-       uint64_t acc_a, acc_b;
-       uint32_t d0;
-       uint i;
-
-       acc_a = (uint64_t)a * b[0] + result[0];
-       d0 = (uint32_t)acc_a * key->n0inv;
-       acc_b = (uint64_t)d0 * key->modulus[0] + (uint32_t)acc_a;
-       for (i = 1; i < key->len; i++) {
-               acc_a = (acc_a >> 32) + (uint64_t)a * b[i] + result[i];
-               acc_b = (acc_b >> 32) + (uint64_t)d0 * key->modulus[i] +
-                               (uint32_t)acc_a;
-               result[i - 1] = (uint32_t)acc_b;
-       }
-
-       acc_a = (acc_a >> 32) + (acc_b >> 32);
-
-       result[i - 1] = (uint32_t)acc_a;
-
-       if (acc_a >> 32)
-               subtract_modulus(key, result);
-}
-
-/**
- * montgomery_mul() - Perform montgomery mutitply
+ * rsa_verify_key() - Verify a signature against some data using RSA Key
  *
- * Operation: montgomery result[] = a[] * b[] / n0inv % modulus
+ * Verify a RSA PKCS1.5 signature against an expected hash using
+ * the RSA Key properties in prop structure.
  *
- * @key:       RSA key
- * @result:    Place to put result, as little endian word array
- * @a:         Multiplier, as little endian word array
- * @b:         Multiplicand, as little endian word array
+ * @prop:      Specifies key
+ * @sig:       Signature
+ * @sig_len:   Number of bytes in signature
+ * @hash:      Pointer to the expected hash
+ * @algo:      Checksum algo structure having information on RSA padding etc.
+ * @return 0 if verified, -ve on error
  */
-static void montgomery_mul(const struct rsa_public_key *key,
-               uint32_t result[], uint32_t a[], const uint32_t b[])
-{
-       uint i;
-
-       for (i = 0; i < key->len; ++i)
-               result[i] = 0;
-       for (i = 0; i < key->len; ++i)
-               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
- *
- * @key:       RSA key
- * @inout:     Big-endian word array containing value and result
- */
-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) {
-               debug("RSA key words %u exceeds maximum %d\n", key->len,
-                     RSA_MAX_KEY_BITS / 32);
-               return -EINVAL;
-       }
-
-       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);
-
-       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;
-       }
-
-       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))
-               subtract_modulus(key, result);
-
-       /* Convert to bigendian byte array */
-       for (i = key->len - 1, ptr = inout; (int)i >= 0; i--, ptr++)
-               put_unaligned_be32(result[i], ptr);
-       return 0;
-}
-
-static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
+static int rsa_verify_key(struct key_prop *prop, const uint8_t *sig,
                          const uint32_t sig_len, const uint8_t *hash,
                          struct checksum_algo *algo)
 {
        const uint8_t *padding;
        int pad_len;
        int ret;
+#if !defined(USE_HOSTCC)
+       struct udevice *mod_exp_dev;
+#endif
 
-       if (!key || !sig || !hash || !algo)
+       if (!prop || !sig || !hash || !algo)
                return -EIO;
 
-       if (sig_len != (key->len * sizeof(uint32_t))) {
+       if (sig_len != (prop->num_bits / 8)) {
                debug("Signature is of incorrect length %d\n", sig_len);
                return -EINVAL;
        }
@@ -265,13 +65,23 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
                return -EINVAL;
        }
 
-       uint32_t buf[sig_len / sizeof(uint32_t)];
+       uint8_t buf[sig_len];
 
-       memcpy(buf, sig, sig_len);
+#if !defined(USE_HOSTCC)
+       ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
+       if (ret) {
+               printf("RSA: Can't find Modular Exp implementation\n");
+               return -EINVAL;
+       }
 
-       ret = pow_mod(key, buf);
-       if (ret)
+       ret = rsa_mod_exp(mod_exp_dev, sig, sig_len, prop, buf);
+#else
+       ret = rsa_mod_exp_sw(sig, sig_len, prop, buf);
+#endif
+       if (ret) {
+               debug("Error in Modular exponentation\n");
                return ret;
+       }
 
        padding = algo->rsa_padding;
        pad_len = algo->pad_len - algo->checksum_len;
@@ -291,72 +101,57 @@ static int rsa_verify_key(const struct rsa_public_key *key, const uint8_t *sig,
        return 0;
 }
 
-static void rsa_convert_big_endian(uint32_t *dst, const uint32_t *src, int len)
-{
-       int i;
-
-       for (i = 0; i < len; i++)
-               dst[i] = fdt32_to_cpu(src[len - 1 - i]);
-}
-
+/**
+ * rsa_verify_with_keynode() - Verify a signature against some data using
+ * information in node with prperties of RSA Key like modulus, exponent etc.
+ *
+ * Parse sign-node and fill a key_prop structure with properties of the
+ * key.  Verify a RSA PKCS1.5 signature against an expected hash using
+ * the properties parsed
+ *
+ * @info:      Specifies key and FIT information
+ * @hash:      Pointer to the expected hash
+ * @sig:       Signature
+ * @sig_len:   Number of bytes in signature
+ * @node:      Node having the RSA Key properties
+ * @return 0 if verified, -ve on error
+ */
 static int rsa_verify_with_keynode(struct image_sign_info *info,
-               const void *hash, uint8_t *sig, uint sig_len, int node)
+                                  const void *hash, uint8_t *sig,
+                                  uint sig_len, int node)
 {
        const void *blob = info->fdt_blob;
-       struct rsa_public_key key;
-       const void *modulus, *rr;
-       const uint64_t *public_exponent;
+       struct key_prop prop;
        int length;
-       int ret;
+       int ret = 0;
 
        if (node < 0) {
                debug("%s: Skipping invalid node", __func__);
                return -EBADF;
        }
-       if (!fdt_getprop(blob, node, "rsa,n0-inverse", NULL)) {
-               debug("%s: Missing rsa,n0-inverse", __func__);
-               return -EFAULT;
-       }
-       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) {
-               debug("%s: Missing RSA key info", __func__);
-               return -EFAULT;
-       }
 
-       /* Sanity check for stack size */
-       if (key.len > RSA_MAX_KEY_BITS || key.len < RSA_MIN_KEY_BITS) {
-               debug("RSA key bits %u outside allowed range %d..%d\n",
-                     key.len, RSA_MIN_KEY_BITS, RSA_MAX_KEY_BITS);
+       prop.num_bits = fdtdec_get_int(blob, node, "rsa,num-bits", 0);
+
+       prop.n0inv = fdtdec_get_int(blob, node, "rsa,n0-inverse", 0);
+
+       prop.public_exponent = fdt_getprop(blob, node, "rsa,exponent", &length);
+       if (!prop.public_exponent || length < sizeof(uint64_t))
+               prop.public_exponent = NULL;
+
+       prop.exp_len = sizeof(uint64_t);
+
+       prop.modulus = fdt_getprop(blob, node, "rsa,modulus", NULL);
+
+       prop.rr = fdt_getprop(blob, node, "rsa,r-squared", NULL);
+
+       if (!prop.num_bits || !prop.modulus) {
+               debug("%s: Missing RSA key info", __func__);
                return -EFAULT;
        }
-       key.len /= sizeof(uint32_t) * 8;
-       uint32_t key1[key.len], key2[key.len];
-
-       key.modulus = key1;
-       key.rr = key2;
-       rsa_convert_big_endian(key.modulus, modulus, key.len);
-       rsa_convert_big_endian(key.rr, rr, key.len);
-       if (!key.modulus || !key.rr) {
-               debug("%s: Out of memory", __func__);
-               return -ENOMEM;
-       }
 
-       debug("key length %d\n", key.len);
-       ret = rsa_verify_key(&key, sig, sig_len, hash, info->algo->checksum);
-       if (ret) {
-               printf("%s: RSA failed to verify: %d\n", __func__, ret);
-               return ret;
-       }
+       ret = rsa_verify_key(&prop, sig, sig_len, hash, info->algo->checksum);
 
-       return 0;
+       return ret;
 }
 
 int rsa_verify(struct image_sign_info *info,
@@ -389,7 +184,12 @@ int rsa_verify(struct image_sign_info *info,
        }
 
        /* Calculate checksum with checksum-algorithm */
-       info->algo->checksum->calculate(region, region_count, hash);
+       ret = info->algo->checksum->calculate(info->algo->checksum->name,
+                                       region, region_count, hash);
+       if (ret < 0) {
+               debug("%s: Error in checksum calculation\n", __func__);
+               return -EINVAL;
+       }
 
        /* See if we must use a particular key */
        if (info->required_keynode != -1) {
index abbaccff509ce09374f30e88983252672d3c4e62..faffe6a385b6f8ef9ee066ac705d959993232226 100644 (file)
@@ -9,11 +9,18 @@
 #include <dm/device-internal.h>
 #include <dm/root.h>
 #include <dm/test.h>
+#include <dm/uclass-internal.h>
 #include <dm/ut.h>
 #include <dm/util.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+struct dm_test_parent_platdata {
+       int count;
+       int bind_flag;
+       int uclass_bind_flag;
+};
+
 enum {
        FLAG_CHILD_PROBED       = 10,
        FLAG_CHILD_REMOVED      = -7,
@@ -26,6 +33,17 @@ static int testbus_drv_probe(struct udevice *dev)
        return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
 }
 
+static int testbus_child_post_bind(struct udevice *dev)
+{
+       struct dm_test_parent_platdata *plat;
+
+       plat = dev_get_parent_platdata(dev);
+       plat->bind_flag = 1;
+       plat->uclass_bind_flag = 2;
+
+       return 0;
+}
+
 static int testbus_child_pre_probe(struct udevice *dev)
 {
        struct dm_test_parent_data *parent_data = dev_get_parentdata(dev);
@@ -35,6 +53,15 @@ static int testbus_child_pre_probe(struct udevice *dev)
        return 0;
 }
 
+static int testbus_child_pre_probe_uclass(struct udevice *dev)
+{
+       struct dm_test_priv *priv = dev_get_priv(dev);
+
+       priv->uclass_flag++;
+
+       return 0;
+}
+
 static int testbus_child_post_remove(struct udevice *dev)
 {
        struct dm_test_parent_data *parent_data = dev_get_parentdata(dev);
@@ -59,9 +86,12 @@ U_BOOT_DRIVER(testbus_drv) = {
        .of_match       = testbus_ids,
        .id     = UCLASS_TEST_BUS,
        .probe  = testbus_drv_probe,
+       .child_post_bind = testbus_child_post_bind,
        .priv_auto_alloc_size = sizeof(struct dm_test_priv),
        .platdata_auto_alloc_size = sizeof(struct dm_test_pdata),
        .per_child_auto_alloc_size = sizeof(struct dm_test_parent_data),
+       .per_child_platdata_auto_alloc_size =
+                       sizeof(struct dm_test_parent_platdata),
        .child_pre_probe = testbus_child_pre_probe,
        .child_post_remove = testbus_child_post_remove,
 };
@@ -69,12 +99,14 @@ U_BOOT_DRIVER(testbus_drv) = {
 UCLASS_DRIVER(testbus) = {
        .name           = "testbus",
        .id             = UCLASS_TEST_BUS,
+       .flags          = DM_UC_FLAG_SEQ_ALIAS,
+       .child_pre_probe = testbus_child_pre_probe_uclass,
 };
 
 /* Test that we can probe for children */
 static int dm_test_bus_children(struct dm_test_state *dms)
 {
-       int num_devices = 4;
+       int num_devices = 6;
        struct udevice *bus;
        struct uclass *uc;
 
@@ -172,7 +204,7 @@ DM_TEST(dm_test_bus_children_iterators,
        DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 
 /* Test that the bus can store data about each child */
-static int dm_test_bus_parent_data(struct dm_test_state *dms)
+static int test_bus_parent_data(struct dm_test_state *dms)
 {
        struct dm_test_parent_data *parent_data;
        struct udevice *bus, *dev;
@@ -231,9 +263,36 @@ static int dm_test_bus_parent_data(struct dm_test_state *dms)
 
        return 0;
 }
-
+/* Test that the bus can store data about each child */
+static int dm_test_bus_parent_data(struct dm_test_state *dms)
+{
+       return test_bus_parent_data(dms);
+}
 DM_TEST(dm_test_bus_parent_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
 
+/* As above but the size is controlled by the uclass */
+static int dm_test_bus_parent_data_uclass(struct dm_test_state *dms)
+{
+       struct udevice *bus;
+       int size;
+       int ret;
+
+       /* Set the driver size to 0 so that the uclass size is used */
+       ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
+       size = bus->driver->per_child_auto_alloc_size;
+       bus->uclass->uc_drv->per_child_auto_alloc_size = size;
+       bus->driver->per_child_auto_alloc_size = 0;
+       ret = test_bus_parent_data(dms);
+       if (ret)
+               return ret;
+       bus->uclass->uc_drv->per_child_auto_alloc_size = 0;
+       bus->driver->per_child_auto_alloc_size = size;
+
+       return 0;
+}
+DM_TEST(dm_test_bus_parent_data_uclass,
+       DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
 /* Test that the bus ops are called when a child is probed/removed */
 static int dm_test_bus_parent_ops(struct dm_test_state *dms)
 {
@@ -271,3 +330,188 @@ static int dm_test_bus_parent_ops(struct dm_test_state *dms)
        return 0;
 }
 DM_TEST(dm_test_bus_parent_ops, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+static int test_bus_parent_platdata(struct dm_test_state *dms)
+{
+       struct dm_test_parent_platdata *plat;
+       struct udevice *bus, *dev;
+       int child_count;
+
+       /* Check that the bus has no children */
+       ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
+       device_find_first_child(bus, &dev);
+       ut_asserteq_ptr(NULL, dev);
+
+       ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
+
+       for (device_find_first_child(bus, &dev), child_count = 0;
+            dev;
+            device_find_next_child(&dev)) {
+               /* Check that platform data is allocated */
+               plat = dev_get_parent_platdata(dev);
+               ut_assert(plat != NULL);
+
+               /*
+                * Check that it is not affected by the device being
+                * probed/removed
+                */
+               plat->count++;
+               ut_asserteq(1, plat->count);
+               device_probe(dev);
+               device_remove(dev);
+
+               ut_asserteq_ptr(plat, dev_get_parent_platdata(dev));
+               ut_asserteq(1, plat->count);
+               ut_assertok(device_probe(dev));
+               child_count++;
+       }
+       ut_asserteq(3, child_count);
+
+       /* Removing the bus should also have no effect (it is still bound) */
+       device_remove(bus);
+       for (device_find_first_child(bus, &dev), child_count = 0;
+            dev;
+            device_find_next_child(&dev)) {
+               /* Check that platform data is allocated */
+               plat = dev_get_parent_platdata(dev);
+               ut_assert(plat != NULL);
+               ut_asserteq(1, plat->count);
+               child_count++;
+       }
+       ut_asserteq(3, child_count);
+
+       /* Unbind all the children */
+       do {
+               device_find_first_child(bus, &dev);
+               if (dev)
+                       device_unbind(dev);
+       } while (dev);
+
+       /* Now the child platdata should be removed and re-added */
+       device_probe(bus);
+       for (device_find_first_child(bus, &dev), child_count = 0;
+            dev;
+            device_find_next_child(&dev)) {
+               /* Check that platform data is allocated */
+               plat = dev_get_parent_platdata(dev);
+               ut_assert(plat != NULL);
+               ut_asserteq(0, plat->count);
+               child_count++;
+       }
+       ut_asserteq(3, child_count);
+
+       return 0;
+}
+
+/* Test that the bus can store platform data about each child */
+static int dm_test_bus_parent_platdata(struct dm_test_state *dms)
+{
+       return test_bus_parent_platdata(dms);
+}
+DM_TEST(dm_test_bus_parent_platdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* As above but the size is controlled by the uclass */
+static int dm_test_bus_parent_platdata_uclass(struct dm_test_state *dms)
+{
+       struct udevice *bus;
+       int size;
+       int ret;
+
+       /* Set the driver size to 0 so that the uclass size is used */
+       ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
+       size = bus->driver->per_child_platdata_auto_alloc_size;
+       bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = size;
+       bus->driver->per_child_platdata_auto_alloc_size = 0;
+       ret = test_bus_parent_platdata(dms);
+       if (ret)
+               return ret;
+       bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = 0;
+       bus->driver->per_child_platdata_auto_alloc_size = size;
+
+       return 0;
+}
+DM_TEST(dm_test_bus_parent_platdata_uclass,
+       DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that the child post_bind method is called */
+static int dm_test_bus_child_post_bind(struct dm_test_state *dms)
+{
+       struct dm_test_parent_platdata *plat;
+       struct udevice *bus, *dev;
+       int child_count;
+
+       ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
+       for (device_find_first_child(bus, &dev), child_count = 0;
+            dev;
+            device_find_next_child(&dev)) {
+               /* Check that platform data is allocated */
+               plat = dev_get_parent_platdata(dev);
+               ut_assert(plat != NULL);
+               ut_asserteq(1, plat->bind_flag);
+               child_count++;
+       }
+       ut_asserteq(3, child_count);
+
+       return 0;
+}
+DM_TEST(dm_test_bus_child_post_bind, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that the child post_bind method is called */
+static int dm_test_bus_child_post_bind_uclass(struct dm_test_state *dms)
+{
+       struct dm_test_parent_platdata *plat;
+       struct udevice *bus, *dev;
+       int child_count;
+
+       ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
+       for (device_find_first_child(bus, &dev), child_count = 0;
+            dev;
+            device_find_next_child(&dev)) {
+               /* Check that platform data is allocated */
+               plat = dev_get_parent_platdata(dev);
+               ut_assert(plat != NULL);
+               ut_asserteq(2, plat->uclass_bind_flag);
+               child_count++;
+       }
+       ut_asserteq(3, child_count);
+
+       return 0;
+}
+DM_TEST(dm_test_bus_child_post_bind_uclass,
+       DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/*
+ * Test that the bus' uclass' child_pre_probe() is called before the
+ * device's probe() method
+ */
+static int dm_test_bus_child_pre_probe_uclass(struct dm_test_state *dms)
+{
+       struct udevice *bus, *dev;
+       int child_count;
+
+       /*
+        * See testfdt_drv_probe() which effectively checks that the uclass
+        * flag is set before that method is called
+        */
+       ut_assertok(uclass_get_device(UCLASS_TEST_BUS, 0, &bus));
+       for (device_find_first_child(bus, &dev), child_count = 0;
+            dev;
+            device_find_next_child(&dev)) {
+               struct dm_test_priv *priv = dev_get_priv(dev);
+
+               /* Check that things happened in the right order */
+               ut_asserteq_ptr(NULL, priv);
+               ut_assertok(device_probe(dev));
+
+               priv = dev_get_priv(dev);
+               ut_assert(priv != NULL);
+               ut_asserteq(1, priv->uclass_flag);
+               ut_asserteq(1, priv->uclass_total);
+               child_count++;
+       }
+       ut_asserteq(3, child_count);
+
+       return 0;
+}
+DM_TEST(dm_test_bus_child_pre_probe_uclass,
+       DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
index ff5c2a749c5e37dbbcca5340dabdf18374a8e5c2..eccda0974da6d6effbdd931c75dff71f36bdaaf6 100644 (file)
@@ -598,3 +598,14 @@ static int dm_test_uclass_before_ready(struct dm_test_state *dms)
 }
 
 DM_TEST(dm_test_uclass_before_ready, 0);
+
+static int dm_test_device_get_uclass_id(struct dm_test_state *dms)
+{
+       struct udevice *dev;
+
+       ut_assertok(uclass_get_device(UCLASS_TEST, 0, &dev));
+       ut_asserteq(UCLASS_TEST, device_get_uclass_id(dev));
+
+       return 0;
+}
+DM_TEST(dm_test_device_get_uclass_id, DM_TESTF_SCAN_PDATA);
index 94bd0d99dc0bc1fa9b5c7033690ab6de7cc29b41..b29daf1af4e238e6d3952f3058191bce3c5a1bb8 100644 (file)
@@ -174,5 +174,72 @@ static int dm_test_gpio_leak(struct dm_test_state *dms)
 
        return 0;
 }
-
 DM_TEST(dm_test_gpio_leak, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that we can find GPIOs using phandles */
+static int dm_test_gpio_phandles(struct dm_test_state *dms)
+{
+       struct gpio_desc desc, desc_list[8], desc_list2[8];
+       struct udevice *dev, *gpio_a, *gpio_b;
+
+       ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
+       ut_asserteq_str("a-test", dev->name);
+
+       ut_assertok(gpio_request_by_name(dev, "test-gpios", 1, &desc, 0));
+       ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio_a));
+       ut_assertok(uclass_get_device(UCLASS_GPIO, 2, &gpio_b));
+       ut_asserteq_str("base-gpios", gpio_a->name);
+       ut_asserteq(true, !!device_active(gpio_a));
+       ut_asserteq_ptr(gpio_a, desc.dev);
+       ut_asserteq(4, desc.offset);
+       /* GPIOF_INPUT is the sandbox GPIO driver default */
+       ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_a, 4, NULL));
+       ut_assertok(dm_gpio_free(dev, &desc));
+
+       ut_asserteq(-ENOENT, gpio_request_by_name(dev, "test-gpios", 3, &desc,
+                                                 0));
+       ut_asserteq_ptr(NULL, desc.dev);
+       ut_asserteq(desc.offset, 0);
+       ut_asserteq(-ENOENT, gpio_request_by_name(dev, "test-gpios", 5, &desc,
+                                                 0));
+
+       /* Last GPIO is ignord as it comes after <0> */
+       ut_asserteq(3, gpio_request_list_by_name(dev, "test-gpios", desc_list,
+                                                ARRAY_SIZE(desc_list), 0));
+       ut_asserteq(-EBUSY, gpio_request_list_by_name(dev, "test-gpios",
+                                                     desc_list2,
+                                                     ARRAY_SIZE(desc_list2),
+                                                     0));
+       ut_assertok(gpio_free_list(dev, desc_list, 3));
+       ut_asserteq(3, gpio_request_list_by_name(dev,  "test-gpios", desc_list,
+                                                ARRAY_SIZE(desc_list),
+                                                GPIOD_IS_OUT |
+                                                GPIOD_IS_OUT_ACTIVE));
+       ut_asserteq_ptr(gpio_a, desc_list[0].dev);
+       ut_asserteq(1, desc_list[0].offset);
+       ut_asserteq_ptr(gpio_a, desc_list[1].dev);
+       ut_asserteq(4, desc_list[1].offset);
+       ut_asserteq_ptr(gpio_b, desc_list[2].dev);
+       ut_asserteq(5, desc_list[2].offset);
+       ut_asserteq(1, dm_gpio_get_value(desc_list));
+       ut_assertok(gpio_free_list(dev, desc_list, 3));
+
+       ut_asserteq(6, gpio_request_list_by_name(dev, "test2-gpios", desc_list,
+                                                ARRAY_SIZE(desc_list), 0));
+       /* This was set to output previously, so still will be */
+       ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_a, 1, NULL));
+
+       /* Active low should invert the input value */
+       ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 6, NULL));
+       ut_asserteq(1, dm_gpio_get_value(&desc_list[2]));
+
+       ut_asserteq(GPIOF_INPUT, gpio_get_function(gpio_b, 7, NULL));
+       ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 8, NULL));
+       ut_asserteq(0, dm_gpio_get_value(&desc_list[4]));
+       ut_asserteq(GPIOF_OUTPUT, gpio_get_function(gpio_b, 9, NULL));
+       ut_asserteq(1, dm_gpio_get_value(&desc_list[5]));
+
+
+       return 0;
+}
+DM_TEST(dm_test_gpio_phandles, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
index a53e28dbe5dc528172811f24bb9dce3909365860..ef88372d56361ab40186a34787cc6c7a8e0c40d4 100644 (file)
@@ -35,8 +35,8 @@ static int dm_test_i2c_find(struct dm_test_state *dms)
         * remove the emulation and the slave device.
         */
        ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
-       ut_assertok(i2c_probe(bus, chip, 0, &dev));
-       ut_asserteq(-ENODEV, i2c_probe(bus, no_chip, 0, &dev));
+       ut_assertok(dm_i2c_probe(bus, chip, 0, &dev));
+       ut_asserteq(-ENODEV, dm_i2c_probe(bus, no_chip, 0, &dev));
        ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_I2C, 1, &bus));
 
        return 0;
@@ -49,11 +49,11 @@ static int dm_test_i2c_read_write(struct dm_test_state *dms)
        uint8_t buf[5];
 
        ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
-       ut_assertok(i2c_get_chip(bus, chip, &dev));
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
        ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf)));
-       ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2));
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
        ut_assertok(memcmp(buf, "\0\0AB\0", sizeof(buf)));
 
        return 0;
@@ -66,13 +66,13 @@ static int dm_test_i2c_speed(struct dm_test_state *dms)
        uint8_t buf[5];
 
        ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
-       ut_assertok(i2c_get_chip(bus, chip, &dev));
+       ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
        ut_assertok(i2c_set_bus_speed(bus, 100000));
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
        ut_assertok(i2c_set_bus_speed(bus, 400000));
        ut_asserteq(400000, i2c_get_bus_speed(bus));
-       ut_assertok(i2c_read(dev, 0, buf, 5));
-       ut_asserteq(-EINVAL, i2c_write(dev, 0, buf, 5));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
+       ut_asserteq(-EINVAL, dm_i2c_write(dev, 0, buf, 5));
 
        return 0;
 }
@@ -84,9 +84,9 @@ static int dm_test_i2c_offset_len(struct dm_test_state *dms)
        uint8_t buf[5];
 
        ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
-       ut_assertok(i2c_get_chip(bus, chip, &dev));
+       ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
        ut_assertok(i2c_set_chip_offset_len(dev, 1));
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
 
        /* This is not supported by the uclass */
        ut_asserteq(-EINVAL, i2c_set_chip_offset_len(dev, 5));
@@ -100,7 +100,7 @@ static int dm_test_i2c_probe_empty(struct dm_test_state *dms)
        struct udevice *bus, *dev;
 
        ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
-       ut_assertok(i2c_probe(bus, SANDBOX_I2C_TEST_ADDR, 0, &dev));
+       ut_assertok(dm_i2c_probe(bus, SANDBOX_I2C_TEST_ADDR, 0, &dev));
 
        return 0;
 }
@@ -113,8 +113,8 @@ static int dm_test_i2c_bytewise(struct dm_test_state *dms)
        uint8_t buf[5];
 
        ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
-       ut_assertok(i2c_get_chip(bus, chip, &dev));
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(i2c_get_chip(bus, chip, 1, &dev));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
        ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf)));
 
        /* Tell the EEPROM to only read/write one register at a time */
@@ -123,34 +123,34 @@ static int dm_test_i2c_bytewise(struct dm_test_state *dms)
        sandbox_i2c_eeprom_set_test_mode(eeprom, SIE_TEST_MODE_SINGLE_BYTE);
 
        /* Now we only get the first byte - the rest will be 0xff */
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
        ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf)));
 
        /* If we do a separate transaction for each byte, it works */
        ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS));
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
        ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf)));
 
        /* This will only write A */
        ut_assertok(i2c_set_chip_flags(dev, 0));
-       ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2));
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
        ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf)));
 
        /* Check that the B was ignored */
        ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS));
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
        ut_assertok(memcmp(buf, "\0\0A\0\0\0", sizeof(buf)));
 
        /* Now write it again with the new flags, it should work */
        ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_WR_ADDRESS));
-       ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2));
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
        ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf)));
 
        ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_WR_ADDRESS |
                                                DM_I2C_CHIP_RD_ADDRESS));
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
        ut_assertok(memcmp(buf, "\0\0AB\0\0", sizeof(buf)));
 
        /* Restore defaults */
@@ -167,45 +167,45 @@ static int dm_test_i2c_offset(struct dm_test_state *dms)
        struct udevice *dev;
        uint8_t buf[5];
 
-       ut_assertok(i2c_get_chip_for_busnum(busnum, chip, &dev));
+       ut_assertok(i2c_get_chip_for_busnum(busnum, chip, 1, &dev));
 
        /* Do a transfer so we can find the emulator */
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
        ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
 
        /* Offset length 0 */
        sandbox_i2c_eeprom_set_offset_len(eeprom, 0);
        ut_assertok(i2c_set_chip_offset_len(dev, 0));
-       ut_assertok(i2c_write(dev, 10 /* ignored */, (uint8_t *)"AB", 2));
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(dm_i2c_write(dev, 10 /* ignored */, (uint8_t *)"AB", 2));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
        ut_assertok(memcmp(buf, "AB\0\0\0\0", sizeof(buf)));
 
        /* Offset length 1 */
        sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
        ut_assertok(i2c_set_chip_offset_len(dev, 1));
-       ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2));
-       ut_assertok(i2c_read(dev, 0, buf, 5));
+       ut_assertok(dm_i2c_write(dev, 2, (uint8_t *)"AB", 2));
+       ut_assertok(dm_i2c_read(dev, 0, buf, 5));
        ut_assertok(memcmp(buf, "ABAB\0", sizeof(buf)));
 
        /* Offset length 2 */
        sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
        ut_assertok(i2c_set_chip_offset_len(dev, 2));
-       ut_assertok(i2c_write(dev, 0x210, (uint8_t *)"AB", 2));
-       ut_assertok(i2c_read(dev, 0x210, buf, 5));
+       ut_assertok(dm_i2c_write(dev, 0x210, (uint8_t *)"AB", 2));
+       ut_assertok(dm_i2c_read(dev, 0x210, buf, 5));
        ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));
 
        /* Offset length 3 */
        sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
        ut_assertok(i2c_set_chip_offset_len(dev, 2));
-       ut_assertok(i2c_write(dev, 0x410, (uint8_t *)"AB", 2));
-       ut_assertok(i2c_read(dev, 0x410, buf, 5));
+       ut_assertok(dm_i2c_write(dev, 0x410, (uint8_t *)"AB", 2));
+       ut_assertok(dm_i2c_read(dev, 0x410, buf, 5));
        ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));
 
        /* Offset length 4 */
        sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
        ut_assertok(i2c_set_chip_offset_len(dev, 2));
-       ut_assertok(i2c_write(dev, 0x420, (uint8_t *)"AB", 2));
-       ut_assertok(i2c_read(dev, 0x420, buf, 5));
+       ut_assertok(dm_i2c_write(dev, 0x420, (uint8_t *)"AB", 2));
+       ut_assertok(dm_i2c_read(dev, 0x420, buf, 5));
        ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));
 
        /* Restore defaults */
index 61b5b2548c42e4e9895ef95345b5e9e99bc9c52a..c7ee65207b0472d3d360e26a7a87629849544c29 100644 (file)
@@ -36,7 +36,6 @@ static int dm_test_spi_find(struct dm_test_state *dms)
        ut_asserteq(0, uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus));
        ut_assertok(spi_cs_info(bus, cs, &info));
        of_offset = info.dev->of_offset;
-       sandbox_sf_unbind_emul(state_get_current(), busnum, cs);
        device_remove(info.dev);
        device_unbind(info.dev);
 
@@ -45,7 +44,7 @@ static int dm_test_spi_find(struct dm_test_state *dms)
         * reports that CS 0 is present
         */
        ut_assertok(spi_cs_info(bus, cs, &info));
-       ut_asserteq_ptr(info.dev, NULL);
+       ut_asserteq_ptr(NULL, info.dev);
 
        /* This finds nothing because we removed the device */
        ut_asserteq(-ENODEV, spi_find_bus_and_cs(busnum, cs, &bus, &dev));
@@ -62,8 +61,9 @@ static int dm_test_spi_find(struct dm_test_state *dms)
        ut_asserteq(-ENOENT, spi_get_bus_and_cs(busnum, cs, speed, mode,
                                                "spi_flash_std", "name", &bus,
                                                &slave));
+       sandbox_sf_unbind_emul(state_get_current(), busnum, cs);
        ut_assertok(spi_cs_info(bus, cs, &info));
-       ut_asserteq_ptr(info.dev, NULL);
+       ut_asserteq_ptr(NULL, info.dev);
 
        /* Add the emulation and try again */
        ut_assertok(sandbox_sf_bind_emul(state, busnum, cs, bus, of_offset,
index bb99677ece9462604e4362fc514030291e30862d..8ebc39297cb53ec315c828a4d0429e8c7ae46dc7 100755 (executable)
@@ -1,9 +1,14 @@
 #!/bin/sh
 
+die() {
+       echo $1
+       exit 1
+}
+
 NUM_CPUS=$(cat /proc/cpuinfo |grep -c processor)
 dtc -I dts -O dtb test/dm/test.dts -o test/dm/test.dtb
-make O=sandbox sandbox_config
-make O=sandbox -s -j${NUM_CPUS}
+make O=sandbox sandbox_config || die "Cannot configure U-Boot"
+make O=sandbox -s -j${NUM_CPUS} || die "Cannot build U-Boot"
 dd if=/dev/zero of=spi.bin bs=1M count=2
 ./sandbox/u-boot -d test/dm/test.dtb -c "dm test"
 rm spi.bin
index cd2c38995e936246a5b8643f04c91b218d454ff0..b8ee9599a22a67c999bb8cd066226cf63237f324 100644 (file)
@@ -51,6 +51,13 @@ static int testfdt_drv_probe(struct udevice *dev)
 
        priv->ping_total += DM_TEST_START_TOTAL;
 
+       /*
+        * If this device is on a bus, the uclass_flag will be set before
+        * calling this function. This is used by
+        * dm_test_bus_child_pre_probe_uclass().
+        */
+       priv->uclass_total += priv->uclass_flag;
+
        return 0;
 }
 
@@ -89,6 +96,7 @@ int testfdt_ping(struct udevice *dev, int pingval, int *pingret)
 UCLASS_DRIVER(testfdt) = {
        .name           = "testfdt",
        .id             = UCLASS_TEST_FDT,
+       .flags          = DM_UC_FLAG_SEQ_ALIAS,
 };
 
 int dm_check_devices(struct dm_test_state *dms, int num_devices)
@@ -128,7 +136,7 @@ int dm_check_devices(struct dm_test_state *dms, int num_devices)
 /* Test that FDT-based binding works correctly */
 static int dm_test_fdt(struct dm_test_state *dms)
 {
-       const int num_devices = 4;
+       const int num_devices = 6;
        struct udevice *dev;
        struct uclass *uc;
        int ret;
@@ -143,12 +151,12 @@ static int dm_test_fdt(struct dm_test_state *dms)
        /* These are num_devices compatible root-level device tree nodes */
        ut_asserteq(num_devices, list_count_items(&uc->dev_head));
 
-       /* Each should have no platdata / priv */
+       /* Each should have platform data but no private data */
        for (i = 0; i < num_devices; i++) {
                ret = uclass_find_device(UCLASS_TEST_FDT, i, &dev);
                ut_assert(!ret);
                ut_assert(!dev_get_priv(dev));
-               ut_assert(!dev->platdata);
+               ut_assert(dev->platdata);
        }
 
        ut_assertok(dm_check_devices(dms, num_devices));
@@ -184,7 +192,7 @@ static int dm_test_fdt_uclass_seq(struct dm_test_state *dms)
        ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 3, true, &dev));
        ut_asserteq_str("b-test", dev->name);
 
-       ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 0, true, &dev));
+       ut_assertok(uclass_find_device_by_seq(UCLASS_TEST_FDT, 8, true, &dev));
        ut_asserteq_str("a-test", dev->name);
 
        ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 5,
@@ -220,11 +228,11 @@ static int dm_test_fdt_uclass_seq(struct dm_test_state *dms)
        ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_TEST_FDT, 1,
                                                      &dev));
        ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev));
-       ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 1, &dev));
+       ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 4, &dev));
 
        /* But now that it is probed, we can find it */
        ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, &dev));
-       ut_asserteq_str("a-test", dev->name);
+       ut_asserteq_str("f-test", dev->name);
 
        return 0;
 }
index fb0272a59cd25472b4e733afbe832a35c607d1d8..84024a44a3f0368c5cea2e983a02d25465969482 100644 (file)
@@ -8,7 +8,15 @@
 
        aliases {
                console = &uart0;
+               i2c0 = "/i2c@0";
+               spi0 = "/spi@0";
                testfdt6 = "/e-test";
+               testbus3 = "/some-bus";
+               testfdt0 = "/some-bus/c-test@0";
+               testfdt1 = "/some-bus/c-test@1";
+               testfdt3 = "/b-test";
+               testfdt5 = "/some-bus/c-test@5";
+               testfdt8 = "/a-test";
        };
 
        uart0: serial {
                ping-expect = <0>;
                ping-add = <0>;
                u-boot,dm-pre-reloc;
+               test-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 5 0 3 2 1>,
+                       <0>, <&gpio_a 12>;
+               test2-gpios = <&gpio_a 1>, <&gpio_a 4>, <&gpio_b 6 1 3 2 1>,
+                       <&gpio_b 7 2 3 2 1>, <&gpio_b 8 4 3 2 1>,
+                       <&gpio_b 9 0xc 3 2 1>;
        };
 
        junk {
                compatible = "google,another-fdt-test";
        };
 
+       f-test {
+               compatible = "denx,u-boot-fdt-test";
+       };
+
+       g-test {
+               compatible = "denx,u-boot-fdt-test";
+       };
+
        gpio_a: base-gpios {
                compatible = "sandbox,gpio";
+               gpio-controller;
+               #gpio-cells = <1>;
                gpio-bank-name = "a";
                num-gpios = <20>;
        };
 
-       extra-gpios {
+       gpio_b: extra-gpios {
                compatible = "sandbox,gpio";
+               gpio-controller;
+               #gpio-cells = <5>;
                gpio-bank-name = "b";
                num-gpios = <10>;
        };
index 9e299e1e57aa40f88f373008293900b7ca4281ef..952f975af11ec9eeb5ff30c63381b80fc8fc7d77 100755 (executable)
 # ./test/image/test-imagetools.sh
 
 BASEDIR=sandbox
-SRCDIR=sandbox/boot
+SRCDIR=${BASEDIR}/boot
 IMAGE_NAME="v1.0-test"
-IMAGE=linux.img
+IMAGE_MULTI=linux.img
+IMAGE_FIT_ITS=linux.its
+IMAGE_FIT_ITB=linux.itb
 DATAFILE0=vmlinuz
 DATAFILE1=initrd.img
 DATAFILE2=System.map
@@ -34,14 +36,17 @@ cleanup()
        for file in ${DATAFILES}; do
                rm -f ${file} ${SRCDIR}/${file}
        done
-       rm -f ${IMAGE} ${DUMPIMAGE_LIST} ${MKIMAGE_LIST} ${TEST_OUT}
+       rm -f ${IMAGE_MULTI}
+       rm -f ${DUMPIMAGE_LIST}
+       rm -f ${MKIMAGE_LIST}
+       rm -f ${TEST_OUT}
        rmdir ${SRCDIR}
 }
 
 # Check that two files are the same
 assert_equal()
 {
-       if ! diff $1 $2; then
+       if ! diff -u $1 $2; then
                echo "Failed."
                cleanup
                exit 1
@@ -82,35 +87,103 @@ do_cmd_redir()
        ${cmd} >${redir}
 }
 
-# Write files into an image
-create_image()
+# Write files into an multi-file image
+create_multi_image()
 {
        local files="${SRCDIR}/${DATAFILE0}:${SRCDIR}/${DATAFILE1}"
        files+=":${SRCDIR}/${DATAFILE2}"
 
-       echo -e "\nBuilding image..."
+       echo -e "\nBuilding multi-file image..."
        do_cmd ${MKIMAGE} -A x86 -O linux -T multi -n \"${IMAGE_NAME}\" \
-               -d ${files} ${IMAGE}
+               -d ${files} ${IMAGE_MULTI}
        echo "done."
 }
 
-# Extract files from an image
-extract_image()
+# Extract files from an multi-file image
+extract_multi_image()
 {
-       echo -e "\nExtracting image contents..."
-       do_cmd ${DUMPIMAGE} -i ${IMAGE} -p 0 ${DATAFILE0}
-       do_cmd ${DUMPIMAGE} -i ${IMAGE} -p 1 ${DATAFILE1}
-       do_cmd ${DUMPIMAGE} -i ${IMAGE} -p 2 ${DATAFILE2}
-       do_cmd ${DUMPIMAGE} -i ${IMAGE} -p 2 ${DATAFILE2} -o ${TEST_OUT}
+       echo -e "\nExtracting multi-file image contents..."
+       do_cmd ${DUMPIMAGE} -T multi -i ${IMAGE_MULTI} -p 0 ${DATAFILE0}
+       do_cmd ${DUMPIMAGE} -T multi -i ${IMAGE_MULTI} -p 1 ${DATAFILE1}
+       do_cmd ${DUMPIMAGE} -T multi -i ${IMAGE_MULTI} -p 2 ${DATAFILE2}
+       do_cmd ${DUMPIMAGE} -T multi -i ${IMAGE_MULTI} -p 2 ${DATAFILE2} -o ${TEST_OUT}
+       echo "done."
+}
+
+# Write files into a FIT image
+create_fit_image()
+{
+       echo " \
+       /dts-v1/; \
+       / { \
+           description = \"FIT image\"; \
+           #address-cells = <1>; \
+       \
+           images { \
+               kernel@1 { \
+                   description = \"kernel\"; \
+                   data = /incbin/(\"${DATAFILE0}\"); \
+                   type = \"kernel\"; \
+                   arch = \"sandbox\"; \
+                   os = \"linux\"; \
+                   compression = \"gzip\"; \
+                   load = <0x40000>; \
+                   entry = <0x8>; \
+               }; \
+               ramdisk@1 { \
+                   description = \"filesystem\"; \
+                   data = /incbin/(\"${DATAFILE1}\"); \
+                   type = \"ramdisk\"; \
+                   arch = \"sandbox\"; \
+                   os = \"linux\"; \
+                   compression = \"none\"; \
+                   load = <0x80000>; \
+                   entry = <0x16>; \
+               }; \
+               fdt@1 { \
+                   description = \"device tree\"; \
+                   data = /incbin/(\"${DATAFILE2}\"); \
+                   type = \"flat_dt\"; \
+                   arch = \"sandbox\"; \
+                   compression = \"none\"; \
+               }; \
+           }; \
+           configurations { \
+               default = \"conf@1\"; \
+               conf@1 { \
+                   kernel = \"kernel@1\"; \
+                   fdt = \"fdt@1\"; \
+               }; \
+           }; \
+       }; \
+       " > ${IMAGE_FIT_ITS}
+
+       echo -e "\nBuilding FIT image..."
+       do_cmd ${MKIMAGE} -f ${IMAGE_FIT_ITS} ${IMAGE_FIT_ITB}
+       echo "done."
+}
+
+# Extract files from a FIT image
+extract_fit_image()
+{
+       echo -e "\nExtracting FIT image contents..."
+       do_cmd ${DUMPIMAGE} -T flat_dt -i ${IMAGE_FIT_ITB} -p 0 ${DATAFILE0}
+       do_cmd ${DUMPIMAGE} -T flat_dt -i ${IMAGE_FIT_ITB} -p 1 ${DATAFILE1}
+       do_cmd ${DUMPIMAGE} -T flat_dt -i ${IMAGE_FIT_ITB} -p 2 ${DATAFILE2}
+       do_cmd ${DUMPIMAGE} -T flat_dt -i ${IMAGE_FIT_ITB} -p 2 ${DATAFILE2} -o ${TEST_OUT}
        echo "done."
 }
 
 # List the contents of a file
+# Args:
+#    image filename
 list_image()
 {
+       local image="$1"
+
        echo -e "\nListing image contents..."
-       do_cmd_redir ${MKIMAGE_LIST} ${MKIMAGE} -l ${IMAGE}
-       do_cmd_redir ${DUMPIMAGE_LIST} ${DUMPIMAGE} -l ${IMAGE}
+       do_cmd_redir ${MKIMAGE_LIST} ${MKIMAGE} -l ${image}
+       do_cmd_redir ${DUMPIMAGE_LIST} ${DUMPIMAGE} -l ${image}
        echo "done."
 }
 
@@ -120,16 +193,28 @@ main()
 
        create_files
 
-       # Compress and extract multifile images, compare the result
-       create_image
-       extract_image
+       # Compress and extract multi-file images, compare the result
+       create_multi_image
+       extract_multi_image
+       for file in ${DATAFILES}; do
+               assert_equal ${file} ${SRCDIR}/${file}
+       done
+       assert_equal ${TEST_OUT} ${DATAFILE2}
+
+       # List contents of multi-file image and compares output from tools
+       list_image ${IMAGE_MULTI}
+       assert_equal ${DUMPIMAGE_LIST} ${MKIMAGE_LIST}
+
+       # Compress and extract FIT images, compare the result
+       create_fit_image
+       extract_fit_image
        for file in ${DATAFILES}; do
                assert_equal ${file} ${SRCDIR}/${file}
        done
        assert_equal ${TEST_OUT} ${DATAFILE2}
 
-       # List contents and compares output fro tools
-       list_image
+       # List contents of FIT image and compares output from tools
+       list_image ${IMAGE_FIT_ITB}
        assert_equal ${DUMPIMAGE_LIST} ${MKIMAGE_LIST}
 
        # Remove files created
index e549f8e63c9cbe0b1066a659efb16bd641601601..6e1ce79f2f45cd33cc3e99ca278a330adb0f75bd 100644 (file)
@@ -60,7 +60,8 @@ FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o
 LIBFDT_OBJS := $(addprefix lib/libfdt/, \
                        fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o)
 RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \
-                                       rsa-sign.o rsa-verify.o rsa-checksum.o)
+                                       rsa-sign.o rsa-verify.o rsa-checksum.o \
+                                       rsa-mod-exp.o)
 
 # common objs for dumpimage and mkimage
 dumpimage-mkimage-objs := aisimage.o \
@@ -90,6 +91,7 @@ dumpimage-mkimage-objs := aisimage.o \
                        socfpgaimage.o \
                        lib/sha1.o \
                        lib/sha256.o \
+                       common/hash.o \
                        ublimage.o \
                        $(LIBFDT_OBJS) \
                        $(RSA_OBJS-y)
@@ -122,6 +124,8 @@ HOSTLOADLIBES_dumpimage := $(HOSTLOADLIBES_mkimage)
 HOSTLOADLIBES_fit_info := $(HOSTLOADLIBES_mkimage)
 HOSTLOADLIBES_fit_check_sign := $(HOSTLOADLIBES_mkimage)
 
+HOSTLDFLAGS += -T $(srctree)/tools/imagetool.lds
+
 hostprogs-$(CONFIG_EXYNOS5250) += mkexynosspl
 hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl
 HOSTCFLAGS_mkexynosspl.o := -pedantic
index 8de370a2e08d4cb7deff61f333c5986c722b77f9..9338342cb36c28022c780eb60b2494baf0f08914 100644 (file)
@@ -413,19 +413,17 @@ int aisimage_check_params(struct image_tool_params *params)
 /*
  * aisimage parameters
  */
-static struct image_type_params aisimage_params = {
-       .name           = "TI Davinci AIS Boot Image support",
-       .header_size    = 0,
-       .hdr            = NULL,
-       .check_image_type = aisimage_check_image_types,
-       .verify_header  = aisimage_verify_header,
-       .print_header   = aisimage_print_header,
-       .set_header     = aisimage_set_header,
-       .check_params   = aisimage_check_params,
-       .vrec_header    = aisimage_generate,
-};
-
-void init_ais_image_type(void)
-{
-       register_image_type(&aisimage_params);
-}
+U_BOOT_IMAGE_TYPE(
+       aisimage,
+       "TI Davinci AIS Boot Image support",
+       0,
+       NULL,
+       aisimage_check_params,
+       aisimage_verify_header,
+       aisimage_print_header,
+       aisimage_set_header,
+       NULL,
+       aisimage_check_image_types,
+       NULL,
+       aisimage_generate
+);
index c8101d2ddc221803c2e07f1991be35abcc69d055..5b72ac54a6d35442232a49780287d83134bdf12b 100644 (file)
@@ -324,19 +324,17 @@ static int atmel_vrec_header(struct image_tool_params *params,
        return EXIT_SUCCESS;
 }
 
-static struct image_type_params atmelimage_params = {
-       .name           = "ATMEL ROM-Boot Image support",
-       .header_size    = 0,
-       .hdr            = NULL,
-       .check_image_type = atmel_check_image_type,
-       .verify_header  = atmel_verify_header,
-       .print_header   = atmel_print_header,
-       .set_header     = atmel_set_header,
-       .check_params   = atmel_check_params,
-       .vrec_header    = atmel_vrec_header,
-};
-
-void init_atmel_image_type(void)
-{
-       register_image_type(&atmelimage_params);
-}
+U_BOOT_IMAGE_TYPE(
+       atmelimage,
+       "ATMEL ROM-Boot Image support",
+       0,
+       NULL,
+       atmel_check_params,
+       atmel_verify_header,
+       atmel_print_header,
+       atmel_set_header,
+       NULL,
+       atmel_check_image_type,
+       NULL,
+       atmel_vrec_header
+);
index 0a0792e503eadefe058f51db90c5fe98fcc2e1e2..cf5c0d4393b0937b55bb684023a43a2c0d62f9cd 100644 (file)
@@ -15,6 +15,8 @@
  */
 
 #include "imagetool.h"
+#include "mkimage.h"
+
 #include <image.h>
 #include <u-boot/crc.h>
 
@@ -53,9 +55,8 @@ static int image_verify_header(unsigned char *ptr, int image_size,
        memcpy(hdr, ptr, sizeof(image_header_t));
 
        if (be32_to_cpu(hdr->ih_magic) != IH_MAGIC) {
-               fprintf(stderr,
-                       "%s: Bad Magic Number: \"%s\" is no valid image\n",
-                       params->cmdname, params->imagefile);
+               debug("%s: Bad Magic Number: \"%s\" is no valid image\n",
+                     params->cmdname, params->imagefile);
                return -FDT_ERR_BADMAGIC;
        }
 
@@ -66,9 +67,8 @@ static int image_verify_header(unsigned char *ptr, int image_size,
        hdr->ih_hcrc = cpu_to_be32(0);  /* clear for re-calculation */
 
        if (crc32(0, data, len) != checksum) {
-               fprintf(stderr,
-                       "%s: ERROR: \"%s\" has bad header checksum!\n",
-                       params->cmdname, params->imagefile);
+               debug("%s: ERROR: \"%s\" has bad header checksum!\n",
+                     params->cmdname, params->imagefile);
                return -FDT_ERR_BADSTATE;
        }
 
@@ -77,9 +77,8 @@ static int image_verify_header(unsigned char *ptr, int image_size,
 
        checksum = be32_to_cpu(hdr->ih_dcrc);
        if (crc32(0, data, len) != checksum) {
-               fprintf(stderr,
-                       "%s: ERROR: \"%s\" has corrupted data!\n",
-                       params->cmdname, params->imagefile);
+               debug("%s: ERROR: \"%s\" has corrupted data!\n",
+                     params->cmdname, params->imagefile);
                return -FDT_ERR_BADSTRUCTURE;
        }
        return 0;
@@ -117,33 +116,7 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd,
        image_set_hcrc(hdr, checksum);
 }
 
-static int image_save_datafile(struct image_tool_params *params,
-                              ulong file_data, ulong file_len)
-{
-       int dfd;
-       const char *datafile = params->outfile;
-
-       dfd = open(datafile, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
-                  S_IRUSR | S_IWUSR);
-       if (dfd < 0) {
-               fprintf(stderr, "%s: Can't open \"%s\": %s\n",
-                       params->cmdname, datafile, strerror(errno));
-               return -1;
-       }
-
-       if (write(dfd, (void *)file_data, file_len) != (ssize_t)file_len) {
-               fprintf(stderr, "%s: Write error on \"%s\": %s\n",
-                       params->cmdname, datafile, strerror(errno));
-               close(dfd);
-               return -1;
-       }
-
-       close(dfd);
-
-       return 0;
-}
-
-static int image_extract_datafile(void *ptr, struct image_tool_params *params)
+static int image_extract_subimage(void *ptr, struct image_tool_params *params)
 {
        const image_header_t *hdr = (const image_header_t *)ptr;
        ulong file_data;
@@ -170,25 +143,23 @@ static int image_extract_datafile(void *ptr, struct image_tool_params *params)
        }
 
        /* save the "data file" into the file system */
-       return image_save_datafile(params, file_data, file_len);
+       return imagetool_save_subimage(params->outfile, file_data, file_len);
 }
 
 /*
  * Default image type parameters definition
  */
-static struct image_type_params defimage_params = {
-       .name = "Default Image support",
-       .header_size = sizeof(image_header_t),
-       .hdr = (void*)&header,
-       .check_image_type = image_check_image_types,
-       .verify_header = image_verify_header,
-       .print_header = image_print_contents,
-       .set_header = image_set_header,
-       .extract_datafile = image_extract_datafile,
-       .check_params = image_check_params,
-};
-
-void init_default_image_type(void)
-{
-       register_image_type(&defimage_params);
-}
+U_BOOT_IMAGE_TYPE(
+       defimage,
+       "Default Image support",
+       sizeof(image_header_t),
+       (void *)&header,
+       image_check_params,
+       image_verify_header,
+       image_print_contents,
+       image_set_header,
+       image_extract_subimage,
+       image_check_image_types,
+       NULL,
+       NULL
+);
index 542ee2821096fd41614dc05de3f5ab789840e374..75a5d4762cda6b1e31432a1e419b3d8400e7751e 100644 (file)
 
 static void usage(void);
 
-/* image_type_params linked list to maintain registered image types supports */
-static struct image_type_params *dumpimage_tparams;
-
 /* parameters initialized by core will be used by the image type code */
 static struct image_tool_params params = {
        .type = IH_TYPE_KERNEL,
 };
 
-/**
- * dumpimage_register() - register respective image generation/list support
- *
- * the input struct image_type_params is checked and appended to the link
- * list, if the input structure is already registered, issue an error
- *
- * @tparams: Image type parameters
- */
-static void dumpimage_register(struct image_type_params *tparams)
-{
-       struct image_type_params **tp;
-
-       if (!tparams) {
-               fprintf(stderr, "%s: %s: Null input\n", params.cmdname,
-                       __func__);
-               exit(EXIT_FAILURE);
-       }
-
-       /* scan the linked list, check for registry and point the last one */
-       for (tp = &dumpimage_tparams; *tp != NULL; tp = &(*tp)->next) {
-               if (!strcmp((*tp)->name, tparams->name)) {
-                       fprintf(stderr, "%s: %s already registered\n",
-                               params.cmdname, tparams->name);
-                       return;
-               }
-       }
-
-       /* add input struct entry at the end of link list */
-       *tp = tparams;
-       /* mark input entry as last entry in the link list */
-       tparams->next = NULL;
-
-       debug("Registered %s\n", tparams->name);
-}
-
-/**
- * dumpimage_get_type() - find the image type params for a given image type
- *
- * Scan all registered image types and check the input type_id for each
- * supported image type
- *
- * @return respective image_type_params pointer. If the input type is not
- * supported by any of registered image types, returns NULL
- */
-static struct image_type_params *dumpimage_get_type(int type)
-{
-       struct image_type_params *curr;
-
-       for (curr = dumpimage_tparams; curr != NULL; curr = curr->next) {
-               if (curr->check_image_type) {
-                       if (!curr->check_image_type(type))
-                               return curr;
-               }
-       }
-       return NULL;
-}
-
 /*
- * dumpimage_verify_print_header() - verifies the image header
- *
- * Scan registered image types and verify the image_header for each
- * supported image type. If verification is successful, this prints
- * the respective header.
- *
- * @return 0 on success, negative if input image format does not match with
- * any of supported image types
- */
-static int dumpimage_verify_print_header(void *ptr, struct stat *sbuf)
-{
-       int retval = -1;
-       struct image_type_params *curr;
-
-       for (curr = dumpimage_tparams; curr != NULL; curr = curr->next) {
-               if (curr->verify_header) {
-                       retval = curr->verify_header((unsigned char *)ptr,
-                                                    sbuf->st_size, &params);
-                       if (retval != 0)
-                               continue;
-                       /*
-                        * Print the image information  if verify is
-                        * successful
-                        */
-                       if (curr->print_header) {
-                               curr->print_header(ptr);
-                       } else {
-                               fprintf(stderr,
-                                       "%s: print_header undefined for %s\n",
-                                       params.cmdname, curr->name);
-                       }
-                       break;
-               }
-       }
-
-       return retval;
-}
-
-/*
- * dumpimage_extract_datafile -
+ * dumpimage_extract_subimage -
  *
  * It scans all registered image types,
  * verifies image_header for each supported image type
@@ -127,29 +28,27 @@ static int dumpimage_verify_print_header(void *ptr, struct stat *sbuf)
  * returns negative if input image format does not match with any of
  * supported image types
  */
-static int dumpimage_extract_datafile(void *ptr, struct stat *sbuf)
+static int dumpimage_extract_subimage(struct image_type_params *tparams,
+               void *ptr, struct stat *sbuf)
 {
        int retval = -1;
-       struct image_type_params *curr;
 
-       for (curr = dumpimage_tparams; curr != NULL; curr = curr->next) {
-               if (curr->verify_header) {
-                       retval = curr->verify_header((unsigned char *)ptr,
-                                                    sbuf->st_size, &params);
-                       if (retval != 0)
-                               continue;
-                       /*
-                        * Extract the file from the image
-                        * if verify is successful
-                        */
-                       if (curr->extract_datafile) {
-                               curr->extract_datafile(ptr, &params);
-                       } else {
-                               fprintf(stderr,
-                                       "%s: extract_datafile undefined for %s\n",
-                                       params.cmdname, curr->name);
-                       break;
-                       }
+       if (tparams->verify_header) {
+               retval = tparams->verify_header((unsigned char *)ptr,
+                               sbuf->st_size, &params);
+               if (retval != 0)
+                       return -1;
+               /*
+                * Extract the file from the image
+                * if verify is successful
+                */
+               if (tparams->extract_subimage) {
+                       retval = tparams->extract_subimage(ptr, &params);
+               } else {
+                       fprintf(stderr,
+                               "%s: extract_subimage undefined for %s\n",
+                               params.cmdname, tparams->name);
+                       return -2;
                }
        }
 
@@ -165,12 +64,9 @@ int main(int argc, char **argv)
        int retval = 0;
        struct image_type_params *tparams = NULL;
 
-       /* Init all image generation/list support */
-       register_image_tool(dumpimage_register);
-
        params.cmdname = *argv;
 
-       while ((opt = getopt(argc, argv, "li:o:p:V")) != -1) {
+       while ((opt = getopt(argc, argv, "li:o:T:p:V")) != -1) {
                switch (opt) {
                case 'l':
                        params.lflag = 1;
@@ -182,6 +78,12 @@ int main(int argc, char **argv)
                case 'o':
                        params.outfile = optarg;
                        break;
+               case 'T':
+                       params.type = genimg_get_type_id(optarg);
+                       if (params.type < 0) {
+                               usage();
+                       }
+                       break;
                case 'p':
                        params.pflag = strtoul(optarg, &ptr, 10);
                        if (*ptr) {
@@ -196,6 +98,7 @@ int main(int argc, char **argv)
                        exit(EXIT_SUCCESS);
                default:
                        usage();
+                       break;
                }
        }
 
@@ -203,9 +106,9 @@ int main(int argc, char **argv)
                usage();
 
        /* set tparams as per input type_id */
-       tparams = dumpimage_get_type(params.type);
+       tparams = imagetool_get_type(params.type);
        if (tparams == NULL) {
-               fprintf(stderr, "%s: unsupported type %s\n",
+               fprintf(stderr, "%s: unsupported type: %s\n",
                        params.cmdname, genimg_get_type_name(params.type));
                exit(EXIT_FAILURE);
        }
@@ -242,7 +145,7 @@ int main(int argc, char **argv)
                        exit(EXIT_FAILURE);
                }
 
-               if ((unsigned)sbuf.st_size < tparams->header_size) {
+               if ((uint32_t)sbuf.st_size < tparams->header_size) {
                        fprintf(stderr,
                                "%s: Bad size: \"%s\" is not valid image\n",
                                params.cmdname, params.imagefile);
@@ -267,13 +170,15 @@ int main(int argc, char **argv)
                         * Extract the data files from within the matched
                         * image type. Returns the error code if not matched
                         */
-                       retval = dumpimage_extract_datafile(ptr, &sbuf);
+                       retval = dumpimage_extract_subimage(tparams, ptr,
+                                       &sbuf);
                } else {
                        /*
                         * Print the image information for matched image type
                         * Returns the error code if not matched
                         */
-                       retval = dumpimage_verify_print_header(ptr, &sbuf);
+                       retval = imagetool_verify_print_header(ptr, &sbuf,
+                                       tparams, &params);
                }
 
                (void)munmap((void *)ptr, sbuf.st_size);
@@ -293,9 +198,10 @@ static void usage(void)
                "          -l ==> list image header information\n",
                params.cmdname);
        fprintf(stderr,
-               "       %s -i image [-p position] [-o outfile] data_file\n"
-               "          -i ==> extract from the 'image' a specific 'data_file'"
-               ", indexed by 'position' (starting at 0)\n",
+               "       %s -i image -T type [-p position] [-o outfile] data_file\n"
+               "          -i ==> extract from the 'image' a specific 'data_file'\n"
+               "          -T ==> set image type to 'type'\n"
+               "          -p ==> 'position' (starting at 0) of the 'data_file' inside the 'image'\n",
                params.cmdname);
        fprintf(stderr,
                "       %s -V ==> print version information and exit\n",
index 3ececf913ff4c4fe2c1c2457f3f5b5ccbfa195fb..eb2a25eeac6aebcd7ae764ff8a593d18cc482528 100644 (file)
@@ -155,6 +155,97 @@ err_system:
        return -1;
 }
 
+/**
+ * fit_image_extract - extract a FIT component image
+ * @fit: pointer to the FIT format image header
+ * @image_noffset: offset of the component image node
+ * @file_name: name of the file to store the FIT sub-image
+ *
+ * returns:
+ *     zero in case of success or a negative value if fail.
+ */
+static int fit_image_extract(
+       const void *fit,
+       int image_noffset,
+       const char *file_name)
+{
+       const void *file_data;
+       size_t file_size = 0;
+
+       /* get the "data" property of component at offset "image_noffset" */
+       fit_image_get_data(fit, image_noffset, &file_data, &file_size);
+
+       /* save the "file_data" into the file specified by "file_name" */
+       return imagetool_save_subimage(file_name, (ulong) file_data, file_size);
+}
+
+/**
+ * fit_extract_contents - retrieve a sub-image component from the FIT image
+ * @ptr: pointer to the FIT format image header
+ * @params: command line parameters
+ *
+ * returns:
+ *     zero in case of success or a negative value if fail.
+ */
+static int fit_extract_contents(void *ptr, struct image_tool_params *params)
+{
+       int images_noffset;
+       int noffset;
+       int ndepth;
+       const void *fit = ptr;
+       int count = 0;
+       const char *p;
+
+       /* Indent string is defined in header image.h */
+       p = IMAGE_INDENT_STRING;
+
+       if (!fit_check_format(fit)) {
+               printf("Bad FIT image format\n");
+               return -1;
+       }
+
+       /* Find images parent node offset */
+       images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
+       if (images_noffset < 0) {
+               printf("Can't find images parent node '%s' (%s)\n",
+                      FIT_IMAGES_PATH, fdt_strerror(images_noffset));
+               return -1;
+       }
+
+       /* Avoid any overrun */
+       count = fit_get_subimage_count(fit, images_noffset);
+       if ((params->pflag < 0) || (count <= params->pflag)) {
+               printf("No such component at '%d'\n", params->pflag);
+               return -1;
+       }
+
+       /* Process its subnodes, extract the desired component from image */
+       for (ndepth = 0, count = 0,
+               noffset = fdt_next_node(fit, images_noffset, &ndepth);
+               (noffset >= 0) && (ndepth > 0);
+               noffset = fdt_next_node(fit, noffset, &ndepth)) {
+               if (ndepth == 1) {
+                       /*
+                        * Direct child node of the images parent node,
+                        * i.e. component image node.
+                        */
+                       if (params->pflag == count) {
+                               printf("Extracted:\n%s Image %u (%s)\n", p,
+                                      count, fit_get_name(fit, noffset, NULL));
+
+                               fit_image_print(fit, noffset, p);
+
+                               return fit_image_extract(fit, noffset,
+                                               params->outfile);
+                       }
+
+                       count++;
+               }
+       }
+
+       return 0;
+}
+
 static int fit_check_params(struct image_tool_params *params)
 {
        return  ((params->dflag && (params->fflag || params->lflag)) ||
@@ -162,19 +253,17 @@ static int fit_check_params(struct image_tool_params *params)
                (params->lflag && (params->dflag || params->fflag)));
 }
 
-static struct image_type_params fitimage_params = {
-       .name = "FIT Image support",
-       .header_size = sizeof(image_header_t),
-       .hdr = (void*)&header,
-       .verify_header = fit_verify_header,
-       .print_header = fit_print_contents,
-       .check_image_type = fit_check_image_types,
-       .fflag_handle = fit_handle_file,
-       .set_header = NULL,     /* FIT images use DTB header */
-       .check_params = fit_check_params,
-};
-
-void init_fit_image_type (void)
-{
-       register_image_type(&fitimage_params);
-}
+U_BOOT_IMAGE_TYPE(
+       fitimage,
+       "FIT Image support",
+       sizeof(image_header_t),
+       (void *)&header,
+       fit_check_params,
+       fit_verify_header,
+       fit_print_contents,
+       NULL,
+       fit_extract_contents,
+       fit_check_image_types,
+       fit_handle_file,
+       NULL /* FIT images use DTB header */
+);
index b343a3aa8b7c2964eb58d5098149504f947344af..5ad52be4377467614c36a2de18d94c9c0c6f5351 100644 (file)
@@ -32,7 +32,8 @@ void to_be32(uint32_t *gph_size, uint32_t *gph_load_addr)
 
 int gph_verify_header(struct gp_header *gph, int be)
 {
-       uint32_t gph_size = gph->size, gph_load_addr = gph->load_addr;
+       uint32_t gph_size = gph->size;
+       uint32_t gph_load_addr = gph->load_addr;
 
        if (be)
                to_be32(&gph_size, &gph_load_addr);
index 1cabb5b612e2a485662e6d5c411e5851c12efd06..1adc55c5fca9effb91eeb8f8541282abd8ba7839 100644 (file)
@@ -60,18 +60,17 @@ static void gpimage_set_header(void *ptr, struct stat *sbuf, int ifd,
 /*
  * gpimage parameters
  */
-static struct image_type_params gpimage_params = {
-       .name           = "TI KeyStone GP Image support",
-       .header_size    = GPIMAGE_HDR_SIZE,
-       .hdr            = (void *)&gpimage_header,
-       .check_image_type = gpimage_check_image_types,
-       .verify_header  = gpimage_verify_header,
-       .print_header   = gpimage_print_header,
-       .set_header     = gpimage_set_header,
-       .check_params   = gpimage_check_params,
-};
-
-void init_gpimage_type(void)
-{
-       register_image_type(&gpimage_params);
-}
+U_BOOT_IMAGE_TYPE(
+       gpimage,
+       "TI KeyStone GP Image support",
+       GPIMAGE_HDR_SIZE,
+       (void *)&gpimage_header,
+       gpimage_check_params,
+       gpimage_verify_header,
+       gpimage_print_header,
+       gpimage_set_header,
+       NULL,
+       gpimage_check_image_types,
+       NULL,
+       NULL
+);
index 98717bdeddcf39fe9988e6f14ab6b35d8ed6f2b0..148e4662b7b366e2b2400639aa733b59e747865f 100644 (file)
@@ -8,57 +8,87 @@
 
 #include "imagetool.h"
 
-/*
- * Callback function to register a image type within a tool
- */
-static imagetool_register_t register_func;
+#include <image.h>
 
-/*
- * register_image_tool -
- *
- * The tool provides its own registration function in order to all image
- * types initialize themselves.
- */
-void register_image_tool(imagetool_register_t image_register)
+struct image_type_params *imagetool_get_type(int type)
 {
-       /*
-        * Save the image tool callback function. It will be used to register
-        * image types within that tool
-        */
-       register_func = image_register;
+       struct image_type_params *curr;
+       struct image_type_params *start = ll_entry_start(
+                       struct image_type_params, image_type);
+       struct image_type_params *end = ll_entry_end(
+                       struct image_type_params, image_type);
 
-       /* Init ATMEL ROM Boot Image generation/list support */
-       init_atmel_image_type();
-       /* Init Freescale PBL Boot image generation/list support */
-       init_pbl_image_type();
-       /* Init Kirkwood Boot image generation/list support */
-       init_kwb_image_type();
-       /* Init Freescale imx Boot image generation/list support */
-       init_imx_image_type();
-       /* Init Freescale mxs Boot image generation/list support */
-       init_mxs_image_type();
-       /* Init FIT image generation/list support */
-       init_fit_image_type();
-       /* Init TI OMAP Boot image generation/list support */
-       init_omap_image_type();
-       /* Init Default image generation/list support */
-       init_default_image_type();
-       /* Init Davinci UBL support */
-       init_ubl_image_type();
-       /* Init Davinci AIS support */
-       init_ais_image_type();
-       /* Init Altera SOCFPGA support */
-       init_socfpga_image_type();
-       /* Init TI Keystone boot image generation/list support */
-       init_gpimage_type();
+       for (curr = start; curr != end; curr++) {
+               if (curr->check_image_type) {
+                       if (!curr->check_image_type(type))
+                               return curr;
+               }
+       }
+       return NULL;
 }
 
-/*
- * register_image_type -
- *
- * Register a image type within a tool
- */
-void register_image_type(struct image_type_params *tparams)
+int imagetool_verify_print_header(
+       void *ptr,
+       struct stat *sbuf,
+       struct image_type_params *tparams,
+       struct image_tool_params *params)
 {
-       register_func(tparams);
+       int retval = -1;
+       struct image_type_params *curr;
+
+       struct image_type_params *start = ll_entry_start(
+                       struct image_type_params, image_type);
+       struct image_type_params *end = ll_entry_end(
+                       struct image_type_params, image_type);
+
+       for (curr = start; curr != end; curr++) {
+               if (curr->verify_header) {
+                       retval = curr->verify_header((unsigned char *)ptr,
+                                                    sbuf->st_size, params);
+
+                       if (retval == 0) {
+                               /*
+                                * Print the image information  if verify is
+                                * successful
+                                */
+                               if (curr->print_header) {
+                                       curr->print_header(ptr);
+                               } else {
+                                       fprintf(stderr,
+                                               "%s: print_header undefined for %s\n",
+                                               params->cmdname, curr->name);
+                               }
+                               break;
+                       }
+               }
+       }
+
+       return retval;
+}
+
+int imagetool_save_subimage(
+       const char *file_name,
+       ulong file_data,
+       ulong file_len)
+{
+       int dfd;
+
+       dfd = open(file_name, O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
+                  S_IRUSR | S_IWUSR);
+       if (dfd < 0) {
+               fprintf(stderr, "Can't open \"%s\": %s\n",
+                       file_name, strerror(errno));
+               return -1;
+       }
+
+       if (write(dfd, (void *)file_data, file_len) != (ssize_t)file_len) {
+               fprintf(stderr, "Write error on \"%s\": %s\n",
+                       file_name, strerror(errno));
+               close(dfd);
+               return -1;
+       }
+
+       close(dfd);
+
+       return 0;
 }
index 8bce059482737bb5030ed36d68cafc28838a4084..f35dec71c7190a4b82e817315e998c561f5e064a 100644 (file)
 #include <time.h>
 #include <unistd.h>
 #include <u-boot/sha1.h>
+
+/* define __KERNEL__ in order to get the definitions
+ * required by the linker list. This is probably not
+ * the best way to do this */
+#ifndef __KERNEL__
+#define __KERNEL__
+#include <linker_lists.h>
+#undef __KERNEL__
+#endif /* __KERNEL__ */
+
 #include "fdt_host.h"
 
 #define ARRAY_SIZE(x)          (sizeof(x) / sizeof((x)[0]))
@@ -100,14 +110,15 @@ struct image_type_params {
        void (*set_header) (void *, struct stat *, int,
                                        struct image_tool_params *);
        /*
-        * This function is used by the command to retrieve a data file from
-        * the image (i.e. dumpimage -i <image> -p <position> <data_file>).
+        * This function is used by the command to retrieve a component
+        * (sub-image) from the image (i.e. dumpimage -i <image> -p <position>
+        * <sub-image-name>).
         * Thus the code to extract a file from an image must be put here.
         *
         * Returns 0 if the file was successfully retrieved from the image,
         * or a negative value on error.
         */
-       int (*extract_datafile) (void *, struct image_tool_params *);
+       int (*extract_subimage)(void *, struct image_tool_params *);
        /*
         * Some image generation support for ex (default image type) supports
         * more than one type_ids, this callback function is used to check
@@ -127,50 +138,88 @@ struct image_type_params {
         */
        int (*vrec_header) (struct image_tool_params *,
                struct image_type_params *);
-       /* pointer to the next registered entry in linked list */
-       struct image_type_params *next;
 };
 
-/*
- * Tool registration function.
+/**
+ * imagetool_get_type() - find the image type params for a given image type
+ *
+ * It scans all registers image type supports
+ * checks the input type for each supported image type
+ *
+ * if successful,
+ *     returns respective image_type_params pointer if success
+ * if input type_id is not supported by any of image_type_support
+ *     returns NULL
  */
-typedef void (*imagetool_register_t)(struct image_type_params *);
+struct image_type_params *imagetool_get_type(int type);
 
 /*
- * Initializes all image types with the given registration callback
- * function.
- * An image tool uses this function to initialize all image types.
+ * imagetool_verify_print_header() - verifies the image header
+ *
+ * Scan registered image types and verify the image_header for each
+ * supported image type. If verification is successful, this prints
+ * the respective header.
+ *
+ * @return 0 on success, negative if input image format does not match with
+ * any of supported image types
  */
-void register_image_tool(imagetool_register_t image_register);
+int imagetool_verify_print_header(
+       void *ptr,
+       struct stat *sbuf,
+       struct image_type_params *tparams,
+       struct image_tool_params *params);
 
-/*
- * Register a image type within a tool.
- * An image type uses this function to register itself within
- * all tools.
+/**
+ * imagetool_save_subimage - store data into a file
+ * @file_name: name of the destination file
+ * @file_data: data to be written
+ * @file_len: the amount of data to store
+ *
+ * imagetool_save_subimage() store file_len bytes of data pointed by file_data
+ * into the file name by file_name.
+ *
+ * returns:
+ *     zero in case of success or a negative value if fail.
  */
-void register_image_type(struct image_type_params *tparams);
+int imagetool_save_subimage(
+       const char *file_name,
+       ulong file_data,
+       ulong file_len);
 
 /*
  * There is a c file associated with supported image type low level code
  * for ex. default_image.c, fit_image.c
- * init_xxx_type() is the only function referred by image tool core to avoid
- * a single lined header file, you can define them here
- *
- * Supported image types init functions
  */
-void init_default_image_type(void);
-void init_atmel_image_type(void);
-void init_pbl_image_type(void);
-void init_ais_image_type(void);
-void init_kwb_image_type(void);
-void init_imx_image_type(void);
-void init_mxs_image_type(void);
-void init_fit_image_type(void);
-void init_ubl_image_type(void);
-void init_omap_image_type(void);
-void init_socfpga_image_type(void);
-void init_gpimage_type(void);
+
 
 void pbl_load_uboot(int fd, struct image_tool_params *mparams);
 
+#define U_BOOT_IMAGE_TYPE( \
+               _id, \
+               _name, \
+               _header_size, \
+               _header, \
+               _check_params, \
+               _verify_header, \
+               _print_header, \
+               _set_header, \
+               _extract_subimage, \
+               _check_image_type, \
+               _fflag_handle, \
+               _vrec_header \
+       ) \
+       ll_entry_declare(struct image_type_params, _id, image_type) = { \
+               .name = _name, \
+               .header_size = _header_size, \
+               .hdr = _header, \
+               .check_params = _check_params, \
+               .verify_header = _verify_header, \
+               .print_header = _print_header, \
+               .set_header = _set_header, \
+               .extract_subimage = _extract_subimage, \
+               .check_image_type = _check_image_type, \
+               .fflag_handle = _fflag_handle, \
+               .vrec_header = _vrec_header \
+       }
+
 #endif /* _IMAGETOOL_H_ */
diff --git a/tools/imagetool.lds b/tools/imagetool.lds
new file mode 100644 (file)
index 0000000..7e92b4a
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2011-2012 The Chromium OS Authors.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+SECTIONS
+{
+
+       . = ALIGN(4);
+       .u_boot_list : {
+               KEEP(*(SORT(.u_boot_list*)));
+       }
+
+       __u_boot_sandbox_option_start = .;
+       _u_boot_sandbox_getopt : { *(.u_boot_sandbox_getopt) }
+       __u_boot_sandbox_option_end = .;
+
+       __bss_start = .;
+}
+
+INSERT BEFORE .data;
index 526b7d490d5c38cca59c6abfd12ac3f15f3931ab..3d3759188692b91323e88603d5a2503714f3b39b 100644 (file)
@@ -694,19 +694,17 @@ static int imximage_generate(struct image_tool_params *params,
 /*
  * imximage parameters
  */
-static struct image_type_params imximage_params = {
-       .name           = "Freescale i.MX Boot Image support",
-       .header_size    = 0,
-       .hdr            = NULL,
-       .check_image_type = imximage_check_image_types,
-       .verify_header  = imximage_verify_header,
-       .print_header   = imximage_print_header,
-       .set_header     = imximage_set_header,
-       .check_params   = imximage_check_params,
-       .vrec_header    = imximage_generate,
-};
-
-void init_imx_image_type(void)
-{
-       register_image_type(&imximage_params);
-}
+U_BOOT_IMAGE_TYPE(
+       imximage,
+       "Freescale i.MX Boot Image support",
+       0,
+       NULL,
+       imximage_check_params,
+       imximage_verify_header,
+       imximage_print_header,
+       imximage_set_header,
+       NULL,
+       imximage_check_image_types,
+       NULL,
+       imximage_generate
+);
index 807d46668be78ee90b1103b2e5b56460dbc6afe0..66f459ad6b1c7f2b65eb612349e6a2e647c8238e 100644 (file)
@@ -905,19 +905,17 @@ static int kwbimage_check_params(struct image_tool_params *params)
 /*
  * kwbimage type parameters definition
  */
-static struct image_type_params kwbimage_params = {
-       .name           = "Marvell MVEBU Boot Image support",
-       .header_size    = 0,            /* no fixed header size */
-       .hdr            = NULL,
-       .vrec_header    = kwbimage_generate,
-       .check_image_type = kwbimage_check_image_types,
-       .verify_header  = kwbimage_verify_header,
-       .print_header   = kwbimage_print_header,
-       .set_header     = kwbimage_set_header,
-       .check_params   = kwbimage_check_params,
-};
-
-void init_kwb_image_type (void)
-{
-       register_image_type(&kwbimage_params);
-}
+U_BOOT_IMAGE_TYPE(
+       kwbimage,
+       "Marvell MVEBU Boot Image support",
+       0,
+       NULL,
+       kwbimage_check_params,
+       kwbimage_verify_header,
+       kwbimage_print_header,
+       kwbimage_set_header,
+       NULL,
+       kwbimage_check_image_types,
+       NULL,
+       kwbimage_generate
+);
index c70408c9ba02375ae959e20d438e4e65acfd75b0..5ccd951048cef587686d264575aae6ea7623e90f 100644 (file)
@@ -15,9 +15,6 @@
 static void copy_file(int, const char *, int);
 static void usage(void);
 
-/* image_type_params link list to maintain registered image type supports */
-struct image_type_params *mkimage_tparams = NULL;
-
 /* parameters initialized by core will be used by the image type code */
 struct image_tool_params params = {
        .os = IH_OS_LINUX,
@@ -29,106 +26,6 @@ struct image_tool_params params = {
        .imagename2 = "",
 };
 
-/*
- * mkimage_register -
- *
- * It is used to register respective image generation/list support to the
- * mkimage core
- *
- * the input struct image_type_params is checked and appended to the link
- * list, if the input structure is already registered, error
- */
-void mkimage_register (struct image_type_params *tparams)
-{
-       struct image_type_params **tp;
-
-       if (!tparams) {
-               fprintf (stderr, "%s: %s: Null input\n",
-                       params.cmdname, __FUNCTION__);
-               exit (EXIT_FAILURE);
-       }
-
-       /* scan the linked list, check for registry and point the last one */
-       for (tp = &mkimage_tparams; *tp != NULL; tp = &(*tp)->next) {
-               if (!strcmp((*tp)->name, tparams->name)) {
-                       fprintf (stderr, "%s: %s already registered\n",
-                               params.cmdname, tparams->name);
-                       return;
-               }
-       }
-
-       /* add input struct entry at the end of link list */
-       *tp = tparams;
-       /* mark input entry as last entry in the link list */
-       tparams->next = NULL;
-
-       debug ("Registered %s\n", tparams->name);
-}
-
-/*
- * mkimage_get_type -
- *
- * It scans all registers image type supports
- * checks the input type_id for each supported image type
- *
- * if successful,
- *     returns respective image_type_params pointer if success
- * if input type_id is not supported by any of image_type_support
- *     returns NULL
- */
-struct image_type_params *mkimage_get_type(int type)
-{
-       struct image_type_params *curr;
-
-       for (curr = mkimage_tparams; curr != NULL; curr = curr->next) {
-               if (curr->check_image_type) {
-                       if (!curr->check_image_type (type))
-                               return curr;
-               }
-       }
-       return NULL;
-}
-
-/*
- * mkimage_verify_print_header -
- *
- * It scans mkimage_tparams link list,
- * verifies image_header for each supported image type
- * if verification is successful, prints respective header
- *
- * returns negative if input image format does not match with any of
- * supported image types
- */
-int mkimage_verify_print_header (void *ptr, struct stat *sbuf)
-{
-       int retval = -1;
-       struct image_type_params *curr;
-
-       for (curr = mkimage_tparams; curr != NULL; curr = curr->next ) {
-               if (curr->verify_header) {
-                       retval = curr->verify_header (
-                               (unsigned char *)ptr, sbuf->st_size,
-                               &params);
-
-                       if (retval == 0) {
-                               /*
-                                * Print the image information
-                                * if verify is successful
-                                */
-                               if (curr->print_header)
-                                       curr->print_header (ptr);
-                               else {
-                                       fprintf (stderr,
-                                       "%s: print_header undefined for %s\n",
-                                       params.cmdname, curr->name);
-                               }
-                               break;
-                       }
-               }
-       }
-       return retval;
-}
-
 int
 main (int argc, char **argv)
 {
@@ -139,9 +36,6 @@ main (int argc, char **argv)
        struct image_type_params *tparams = NULL;
        int pad_len = 0;
 
-       /* Init all image generation/list support */
-       register_image_tool(mkimage_register);
-
        params.cmdname = *argv;
        params.addr = params.ep = 0;
 
@@ -279,7 +173,7 @@ NXTARG:             ;
                usage ();
 
        /* set tparams as per input type_id */
-       tparams = mkimage_get_type(params.type);
+       tparams = imagetool_get_type(params.type);
        if (tparams == NULL) {
                fprintf (stderr, "%s: unsupported type %s\n",
                        params.cmdname, genimg_get_type_name(params.type));
@@ -363,7 +257,8 @@ NXTARG:             ;
                 * Print the image information for matched image type
                 * Returns the error code if not matched
                 */
-               retval = mkimage_verify_print_header (ptr, &sbuf);
+               retval = imagetool_verify_print_header(ptr, &sbuf,
+                               tparams, &params);
 
                (void) munmap((void *)ptr, sbuf.st_size);
                (void) close (ifd);
@@ -529,7 +424,7 @@ copy_file (int ifd, const char *datafile, int pad)
        uint8_t zeros[4096];
        int offset = 0;
        int size;
-       struct image_type_params *tparams = mkimage_get_type (params.type);
+       struct image_type_params *tparams = imagetool_get_type(params.type);
 
        if (pad >= sizeof(zeros)) {
                fprintf(stderr, "%s: Can't pad to %d\n",
index 04beefe05cbfd87575b9e23816a69034742b505c..98fc64491c7d9f56591858f075020eed7d911ca2 100644 (file)
@@ -2312,25 +2312,18 @@ fail:
 /*
  * mxsimage parameters
  */
-static struct image_type_params mxsimage_params = {
-       .name           = "Freescale MXS Boot Image support",
-       .header_size    = 0,
-       .hdr            = NULL,
-       .check_image_type = mxsimage_check_image_types,
-       .verify_header  = mxsimage_verify_header,
-       .print_header   = mxsimage_print_header,
-       .set_header     = mxsimage_set_header,
-       .check_params   = mxsimage_check_params,
-       .vrec_header    = mxsimage_generate,
-};
-
-void init_mxs_image_type(void)
-{
-       register_image_type(&mxsimage_params);
-}
-
-#else
-void init_mxs_image_type(void)
-{
-}
+U_BOOT_IMAGE_TYPE(
+       mxsimage,
+       "Freescale MXS Boot Image support",
+       0,
+       NULL,
+       mxsimage_check_params,
+       mxsimage_verify_header,
+       mxsimage_print_header,
+       mxsimage_set_header,
+       NULL,
+       mxsimage_check_image_types,
+       NULL,
+       mxsimage_generate
+);
 #endif
index 1e0c16479681aec2d8621eabd953ff9a8cdb203c..7198b3330d6d6a62a8d3064643bfe1fe191cec33 100644 (file)
@@ -162,18 +162,17 @@ static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd,
 /*
  * omapimage parameters
  */
-static struct image_type_params omapimage_params = {
-       .name           = "TI OMAP CH/GP Boot Image support",
-       .header_size    = OMAP_FILE_HDR_SIZE,
-       .hdr            = (void *)&omapimage_header,
-       .check_image_type = omapimage_check_image_types,
-       .verify_header  = omapimage_verify_header,
-       .print_header   = omapimage_print_header,
-       .set_header     = omapimage_set_header,
-       .check_params   = gpimage_check_params,
-};
-
-void init_omap_image_type(void)
-{
-       register_image_type(&omapimage_params);
-}
+U_BOOT_IMAGE_TYPE(
+       omapimage,
+       "TI OMAP CH/GP Boot Image support",
+       OMAP_FILE_HDR_SIZE,
+       (void *)&omapimage_header,
+       gpimage_check_params,
+       omapimage_verify_header,
+       omapimage_print_header,
+       omapimage_set_header,
+       NULL,
+       omapimage_check_image_types,
+       NULL,
+       NULL
+);
index e466886ed2428416824e40f8d0faa529248ff4e4..7d039e82bc2781bc6624bb423f5d8f4ef302232d 100644 (file)
@@ -52,12 +52,15 @@ will get a consistent result each time.
 How to configure it
 ===================
 
-For most cases of using patman for U-Boot development, patman will
-locate and use the file 'doc/git-mailrc' in your U-Boot directory.
-This contains most of the aliases you will need.
+For most cases of using patman for U-Boot development, patman can use the
+file 'doc/git-mailrc' in your U-Boot directory to supply the email aliases
+you need. To make this work, tell git where to find the file by typing
+this once:
 
-For Linux the 'scripts/get_maintainer.pl' handles figuring out where
-to send patches pretty well.
+    git config sendemail.aliasesfile doc/git-mailrc
+
+For both Linux and U-Boot the 'scripts/get_maintainer.pl' handles figuring
+out where to send patches pretty well.
 
 During the first run patman creates a config file for you by taking the default
 user name and email address from the global .gitconfig file.
index cc5a55ab3ffefd7fce9c0107c9470bbd0d05ed2e..c593070d67ef24800462543c0a1774a33515c6bf 100644 (file)
@@ -392,7 +392,8 @@ def EmailPatches(series, cover_fname, args, dry_run, raise_on_error, cc_fname,
                    "Or do something like this\n"
                    "git config sendemail.to u-boot@lists.denx.de")
             return
-    cc = BuildEmailList(series.get('cc'), '--cc', alias, raise_on_error)
+    cc = BuildEmailList(list(set(series.get('cc')) - set(series.get('to'))),
+                        '--cc', alias, raise_on_error)
     if self_only:
         to = BuildEmailList([os.getenv('USER')], '--to', alias, raise_on_error)
         cc = []
index da0488337b29a5fd4db542b58892a14c4e637ee9..8c3a0ec9eee5e7af6bc0ef0820a069e0f74c78aa 100644 (file)
@@ -139,6 +139,9 @@ class PatchStream:
         # Initially we have no output. Prepare the input line string
         out = []
         line = line.rstrip('\n')
+
+        commit_match = re_commit.match(line) if self.is_log else None
+
         if self.is_log:
             if line[:4] == '    ':
                 line = line[4:]
@@ -146,7 +149,6 @@ class PatchStream:
         # Handle state transition and skipping blank lines
         series_tag_match = re_series_tag.match(line)
         commit_tag_match = re_commit_tag.match(line)
-        commit_match = re_commit.match(line) if self.is_log else None
         cover_cc_match = re_cover_cc.match(line)
         signoff_match = re_signoff.match(line)
         tag_match = None
index b67f870b7e21518fa51e97040470658979094b5b..60ebc766f7e956f959e6577c833ec9c68dc5d848 100644 (file)
@@ -94,6 +94,9 @@ class Series(dict):
             cmd: The git command we would have run
             process_tags: Process tags as if they were aliases
         """
+        to_set = set(gitutil.BuildEmailList(self.to));
+        cc_set = set(gitutil.BuildEmailList(self.cc));
+
         col = terminal.Color()
         print 'Dry run, so not doing much. But I would do this:'
         print
@@ -106,24 +109,16 @@ class Series(dict):
             commit = self.commits[upto]
             print col.Color(col.GREEN, '   %s' % args[upto])
             cc_list = list(self._generated_cc[commit.patch])
-
-            # Skip items in To list
-            if 'to' in self:
-                try:
-                    map(cc_list.remove, gitutil.BuildEmailList(self.to))
-                except ValueError:
-                    pass
-
-            for email in cc_list:
+            for email in set(cc_list) - to_set - cc_set:
                 if email == None:
                     email = col.Color(col.YELLOW, "<alias '%s' not found>"
                             % tag)
                 if email:
                     print '      Cc: ',email
         print
-        for item in gitutil.BuildEmailList(self.get('to', '<none>')):
+        for item in to_set:
             print 'To:\t ', item
-        for item in gitutil.BuildEmailList(self.cc):
+        for item in cc_set - to_set:
             print 'Cc:\t ', item
         print 'Version: ', self.get('version')
         print 'Prefix:\t ', self.get('prefix')
@@ -131,7 +126,7 @@ class Series(dict):
             print 'Cover: %d lines' % len(self.cover)
             cover_cc = gitutil.BuildEmailList(self.get('cover_cc', ''))
             all_ccs = itertools.chain(cover_cc, *self._generated_cc.values())
-            for email in set(all_ccs):
+            for email in set(all_ccs) - to_set - cc_set:
                     print '      Cc: ',email
         if cmd:
             print 'Git command: %s' % cmd
@@ -230,7 +225,7 @@ class Series(dict):
            if add_maintainers:
                 list += get_maintainer.GetMaintainer(commit.patch)
             all_ccs += list
-            print >>fd, commit.patch, ', '.join(list)
+            print >>fd, commit.patch, ', '.join(set(list))
             self._generated_cc[commit.patch] = list
 
         if cover_fname:
index 2a799ab4b64eb9214c1a38b317d782cd5fe1e0ea..d74fde9a4415df6e12548a72f1b4b7a9e2ea1d6a 100644 (file)
@@ -308,19 +308,17 @@ int pblimage_check_params(struct image_tool_params *params)
 };
 
 /* pblimage parameters */
-static struct image_type_params pblimage_params = {
-       .name           = "Freescale PBL Boot Image support",
-       .header_size    = sizeof(struct pbl_header),
-       .hdr            = (void *)&pblimage_header,
-       .check_image_type = pblimage_check_image_types,
-       .check_params   = pblimage_check_params,
-       .verify_header  = pblimage_verify_header,
-       .print_header   = pblimage_print_header,
-       .set_header     = pblimage_set_header,
-};
-
-void init_pbl_image_type(void)
-{
-       pbl_size = 0;
-       register_image_type(&pblimage_params);
-}
+U_BOOT_IMAGE_TYPE(
+       pblimage,
+       "Freescale PBL Boot Image support",
+       sizeof(struct pbl_header),
+       (void *)&pblimage_header,
+       pblimage_check_params,
+       pblimage_verify_header,
+       pblimage_print_header,
+       pblimage_set_header,
+       NULL,
+       pblimage_check_image_types,
+       NULL,
+       NULL
+);
index 917873e7b3ce83487cb16a9a9d577f495192f5f6..8fe91fe80ee9ac9ab5c2c0f7af25705f212bd486 100644 (file)
@@ -33,6 +33,8 @@
 
 #include "pbl_crc32.h"
 #include "imagetool.h"
+#include "mkimage.h"
+
 #include <image.h>
 
 #define HEADER_OFFSET  0x40
@@ -133,12 +135,12 @@ static int verify_buffer(const uint8_t *buf)
 
        len = verify_header(buf + HEADER_OFFSET);
        if (len < 0) {
-               fprintf(stderr, "Invalid header\n");
+               debug("Invalid header\n");
                return -1;
        }
 
        if (len < HEADER_OFFSET || len > PADDED_SIZE) {
-               fprintf(stderr, "Invalid header length (%i)\n", len);
+               debug("Invalid header length (%i)\n", len);
                return -1;
        }
 
@@ -241,19 +243,17 @@ static void socfpgaimage_set_header(void *ptr, struct stat *sbuf, int ifd,
        sign_buffer(buf, 0, 0, data_size, 0);
 }
 
-static struct image_type_params socfpgaimage_params = {
-       .name           = "Altera SOCFPGA preloader support",
-       .vrec_header    = socfpgaimage_vrec_header,
-       .header_size    = 0, /* This will be modified by vrec_header() */
-       .hdr            = (void *)buffer,
-       .check_image_type = socfpgaimage_check_image_types,
-       .verify_header  = socfpgaimage_verify_header,
-       .print_header   = socfpgaimage_print_header,
-       .set_header     = socfpgaimage_set_header,
-       .check_params   = socfpgaimage_check_params,
-};
-
-void init_socfpga_image_type(void)
-{
-       register_image_type(&socfpgaimage_params);
-}
+U_BOOT_IMAGE_TYPE(
+       socfpgaimage,
+       "Altera SOCFPGA preloader support",
+       0, /* This will be modified by vrec_header() */
+       (void *)buffer,
+       socfpgaimage_check_params,
+       socfpgaimage_verify_header,
+       socfpgaimage_print_header,
+       socfpgaimage_set_header,
+       NULL,
+       socfpgaimage_check_image_types,
+       NULL,
+       socfpgaimage_vrec_header
+);
index cbbbe205dadf4d168ca5c71b2d6b2aedcf3ffb75..6ed1eef29c95e38bf78658131a9548217059f197 100644 (file)
@@ -244,18 +244,17 @@ int ublimage_check_params(struct image_tool_params *params)
 /*
  * ublimage parameters
  */
-static struct image_type_params ublimage_params = {
-       .name           = "Davinci UBL boot support",
-       .header_size    = sizeof(struct ubl_header),
-       .hdr            = (void *)&ublimage_header,
-       .check_image_type = ublimage_check_image_types,
-       .verify_header  = ublimage_verify_header,
-       .print_header   = ublimage_print_header,
-       .set_header     = ublimage_set_header,
-       .check_params   = ublimage_check_params,
-};
-
-void init_ubl_image_type(void)
-{
-       register_image_type(&ublimage_params);
-}
+U_BOOT_IMAGE_TYPE(
+       ublimage,
+       "Davinci UBL boot support",
+       sizeof(struct ubl_header),
+       (void *)&ublimage_header,
+       ublimage_check_params,
+       ublimage_verify_header,
+       ublimage_print_header,
+       ublimage_set_header,
+       NULL,
+       ublimage_check_image_types,
+       NULL,
+       NULL
+);