summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kconfig3
-rw-r--r--Makefile7
-rw-r--r--README14
-rw-r--r--arch/arm/Kconfig18
-rw-r--r--arch/arm/cpu/armv7/cpu.c2
-rw-r--r--arch/arm/cpu/armv7/exynos/pinmux.c27
-rw-r--r--arch/arm/cpu/armv7/start.S6
-rw-r--r--arch/arm/cpu/tegra20-common/pmu.c2
-rw-r--r--arch/arm/dts/exynos4.dtsi31
-rw-r--r--arch/arm/dts/exynos4210-origen.dts2
-rw-r--r--arch/arm/dts/exynos4210-trats.dts4
-rw-r--r--arch/arm/dts/exynos4210-universal_c210.dts12
-rw-r--r--arch/arm/dts/exynos4412-odroid.dts9
-rw-r--r--arch/arm/dts/exynos4412-trats2.dts6
-rw-r--r--arch/arm/dts/exynos5.dtsi4
-rw-r--r--arch/arm/dts/exynos5250-arndale.dts8
-rw-r--r--arch/arm/dts/exynos5250-smdk5250.dts2
-rw-r--r--arch/arm/dts/exynos5250-snow.dts11
-rw-r--r--arch/arm/dts/exynos5420-peach-pit.dts8
-rw-r--r--arch/arm/dts/exynos5422-odroidxu3.dts2
-rw-r--r--arch/arm/dts/exynos5800-peach-pi.dts10
-rw-r--r--arch/arm/dts/tegra114-dalmore.dts5
-rw-r--r--arch/arm/dts/tegra124-jetson-tk1.dts9
-rw-r--r--arch/arm/dts/tegra124-venice2.dts9
-rw-r--r--arch/arm/dts/tegra20-colibri_t20_iris.dts10
-rw-r--r--arch/arm/dts/tegra20-harmony.dts28
-rw-r--r--arch/arm/dts/tegra20-medcom-wide.dts9
-rw-r--r--arch/arm/dts/tegra20-paz00.dts18
-rw-r--r--arch/arm/dts/tegra20-seaboard.dts22
-rw-r--r--arch/arm/dts/tegra20-tamonten.dtsi9
-rw-r--r--arch/arm/dts/tegra20-tec.dts9
-rw-r--r--arch/arm/dts/tegra20-trimslice.dts8
-rw-r--r--arch/arm/dts/tegra20-ventana.dts18
-rw-r--r--arch/arm/dts/tegra20-whistler.dts2
-rw-r--r--arch/arm/dts/tegra30-apalis.dts10
-rw-r--r--arch/arm/dts/tegra30-beaver.dts10
-rw-r--r--arch/arm/dts/tegra30-cardhu.dts8
-rw-r--r--arch/arm/dts/tegra30-colibri.dts6
-rw-r--r--arch/arm/dts/tegra30-tamonten.dtsi4
-rw-r--r--arch/arm/include/asm/arch-exynos/pinmux.h3
-rw-r--r--arch/arm/include/asm/arch-pantheon/gpio.h0
-rw-r--r--arch/arm/include/asm/arch-tegra/tegra_mmc.h7
-rw-r--r--arch/arm/include/asm/arch-tegra20/display.h9
-rw-r--r--arch/arm/include/asm/arch-zynq/gpio.h15
-rw-r--r--arch/blackfin/cpu/cpu.c3
-rw-r--r--arch/mips/Kconfig6
-rw-r--r--arch/mips/Makefile8
-rw-r--r--arch/mips/cpu/Makefile9
-rw-r--r--arch/mips/cpu/cpu.c38
-rw-r--r--arch/mips/cpu/interrupts.c (renamed from arch/mips/cpu/mips32/interrupts.c)0
-rw-r--r--arch/mips/cpu/mips32/Makefile12
-rw-r--r--arch/mips/cpu/mips64/Makefile9
-rw-r--r--arch/mips/cpu/mips64/cache.S213
-rw-r--r--arch/mips/cpu/mips64/cpu.c95
-rw-r--r--arch/mips/cpu/mips64/interrupts.c22
-rw-r--r--arch/mips/cpu/mips64/start.S291
-rw-r--r--arch/mips/cpu/mips64/time.c19
-rw-r--r--arch/mips/cpu/start.S (renamed from arch/mips/cpu/mips32/start.S)137
-rw-r--r--arch/mips/cpu/time.c (renamed from arch/mips/cpu/mips32/time.c)0
-rw-r--r--arch/mips/include/asm/cacheops.h13
-rw-r--r--arch/mips/include/asm/malta.h5
-rw-r--r--arch/mips/lib/Makefile2
-rw-r--r--arch/mips/lib/cache.c (renamed from arch/mips/cpu/mips32/cpu.c)75
-rw-r--r--arch/mips/lib/cache_init.S (renamed from arch/mips/cpu/mips32/cache.S)222
-rw-r--r--arch/mips/mach-au1x00/Makefile (renamed from arch/mips/cpu/mips32/au1x00/Makefile)0
-rw-r--r--arch/mips/mach-au1x00/au1x00_eth.c (renamed from arch/mips/cpu/mips32/au1x00/au1x00_eth.c)6
-rw-r--r--arch/mips/mach-au1x00/au1x00_ide.c (renamed from arch/mips/cpu/mips32/au1x00/au1x00_ide.c)0
-rw-r--r--arch/mips/mach-au1x00/au1x00_serial.c (renamed from arch/mips/cpu/mips32/au1x00/au1x00_serial.c)0
-rw-r--r--arch/mips/mach-au1x00/au1x00_usb_ohci.c (renamed from arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c)0
-rw-r--r--arch/mips/mach-au1x00/au1x00_usb_ohci.h (renamed from arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.h)0
-rw-r--r--arch/mips/mach-au1x00/config.mk (renamed from arch/mips/cpu/mips32/au1x00/config.mk)0
-rw-r--r--arch/sandbox/dts/sandbox.dts11
-rw-r--r--board/BuS/eb_cpux9k2/cpux9k2.c2
-rw-r--r--board/armltd/vexpress64/Kconfig28
-rw-r--r--board/armltd/vexpress64/MAINTAINERS5
-rw-r--r--board/avionic-design/common/tamonten-ng.c4
-rw-r--r--board/imgtec/malta/malta.c20
-rw-r--r--board/nvidia/cardhu/cardhu.c12
-rw-r--r--board/nvidia/dalmore/dalmore.c10
-rw-r--r--board/nvidia/whistler/whistler.c14
-rw-r--r--board/samsung/odroid/odroid.c14
-rw-r--r--board/toradex/apalis_t30/apalis_t30.c8
-rw-r--r--common/Makefile2
-rw-r--r--common/board_f.c2
-rw-r--r--common/board_info.c35
-rw-r--r--common/board_r.c18
-rw-r--r--common/cmd_bootm.c3
-rw-r--r--common/cmd_demo.c29
-rw-r--r--common/cmd_fpga.c2
-rw-r--r--common/cmd_fs.c15
-rw-r--r--common/cmd_gettime.c4
-rw-r--r--common/cmd_i2c.c52
-rw-r--r--common/cmd_load.c2
-rw-r--r--common/cmd_part.c24
-rw-r--r--common/cmd_ximg.c2
-rw-r--r--common/console.c20
-rw-r--r--common/exports.c28
-rw-r--r--common/hash.c78
-rw-r--r--common/image-fit.c30
-rw-r--r--common/image-sig.c6
-rw-r--r--common/image.c2
-rw-r--r--configs/am335x_boneblack_vboot_defconfig4
-rw-r--r--configs/ids8313_defconfig3
-rw-r--r--configs/ph1_ld4_defconfig2
-rw-r--r--configs/ph1_pro4_defconfig2
-rw-r--r--configs/ph1_sld8_defconfig2
-rw-r--r--configs/sandbox_defconfig4
-rw-r--r--configs/vexpress_aemv8a_defconfig2
-rw-r--r--configs/vexpress_aemv8a_juno_defconfig5
-rw-r--r--configs/vexpress_aemv8a_semi_defconfig4
-rw-r--r--configs/zynq_microzed_defconfig4
-rw-r--r--configs/zynq_zc70x_defconfig4
-rw-r--r--configs/zynq_zc770_xm010_defconfig4
-rw-r--r--configs/zynq_zc770_xm012_defconfig4
-rw-r--r--configs/zynq_zc770_xm013_defconfig4
-rw-r--r--configs/zynq_zed_defconfig4
-rw-r--r--configs/zynq_zybo_defconfig4
-rw-r--r--doc/README.distro341
-rw-r--r--doc/README.standalone41
-rw-r--r--doc/device-tree-bindings/gpio/gpio-samsung.txt41
-rw-r--r--doc/device-tree-bindings/gpio/gpio.txt211
-rw-r--r--doc/device-tree-bindings/gpio/nvidia,tegra20-gpio.txt40
-rw-r--r--doc/device-tree-bindings/i2c/i2c.txt28
-rw-r--r--doc/driver-model/README.txt91
-rw-r--r--doc/driver-model/spi-howto.txt40
-rw-r--r--doc/uImage.FIT/source_file_format.txt10
-rw-r--r--doc/uImage.FIT/verified-boot.txt4
-rw-r--r--drivers/core/device-remove.c16
-rw-r--r--drivers/core/device.c121
-rw-r--r--drivers/core/root.c8
-rw-r--r--drivers/core/uclass.c34
-rw-r--r--drivers/crypto/Kconfig1
-rw-r--r--drivers/crypto/Makefile1
-rw-r--r--drivers/crypto/fsl/Kconfig6
-rw-r--r--drivers/crypto/fsl/Makefile1
-rw-r--r--drivers/crypto/fsl/fsl_rsa.c60
-rw-r--r--drivers/crypto/fsl/jobdesc.c28
-rw-r--r--drivers/crypto/fsl/jobdesc.h5
-rw-r--r--drivers/crypto/fsl/rsa_caam.h28
-rw-r--r--drivers/crypto/rsa_mod_exp/Kconfig5
-rw-r--r--drivers/crypto/rsa_mod_exp/Makefile7
-rw-r--r--drivers/crypto/rsa_mod_exp/mod_exp_sw.c39
-rw-r--r--drivers/crypto/rsa_mod_exp/mod_exp_uclass.c31
-rw-r--r--drivers/demo/demo-shape.c71
-rw-r--r--drivers/demo/demo-uclass.c20
-rw-r--r--drivers/gpio/gpio-uclass.c396
-rw-r--r--drivers/gpio/s5p_gpio.c13
-rw-r--r--drivers/gpio/sandbox.c20
-rw-r--r--drivers/gpio/tegra_gpio.c18
-rw-r--r--drivers/i2c/Kconfig22
-rw-r--r--drivers/i2c/Makefile3
-rw-r--r--drivers/i2c/i2c-uclass-compat.c108
-rw-r--r--drivers/i2c/i2c-uclass.c81
-rw-r--r--drivers/i2c/i2c-uniphier-f.c367
-rw-r--r--drivers/i2c/i2c-uniphier.c227
-rw-r--r--drivers/i2c/s3c24x0_i2c.c237
-rw-r--r--drivers/i2c/sandbox_i2c.c30
-rw-r--r--drivers/i2c/tegra_i2c.c18
-rw-r--r--drivers/misc/cros_ec.c34
-rw-r--r--drivers/misc/cros_ec_i2c.c82
-rw-r--r--drivers/misc/cros_ec_spi.c70
-rw-r--r--drivers/mmc/s5p_sdhci.c20
-rw-r--r--drivers/mmc/tegra_mmc.c36
-rw-r--r--drivers/mtd/nand/tegra_nand.c9
-rw-r--r--drivers/mtd/spi/sandbox.c12
-rw-r--r--drivers/mtd/spi/sf_probe.c3
-rw-r--r--drivers/net/designware.c4
-rw-r--r--drivers/net/e1000.c31
-rw-r--r--drivers/net/phy/micrel.c58
-rw-r--r--drivers/net/smc91111.h31
-rw-r--r--drivers/net/tsec.c2
-rw-r--r--drivers/pci/pci_rom.c2
-rw-r--r--drivers/power/as3722.c6
-rw-r--r--drivers/power/tps6586x.c4
-rw-r--r--drivers/serial/serial-uclass.c1
-rw-r--r--drivers/spi/cadence_qspi.c1
-rw-r--r--drivers/spi/designware_spi.c1
-rw-r--r--drivers/spi/exynos_spi.c1
-rw-r--r--drivers/spi/sandbox_spi.c1
-rw-r--r--drivers/spi/soft_spi.c72
-rw-r--r--drivers/spi/spi-uclass.c95
-rw-r--r--drivers/spi/tegra114_spi.c1
-rw-r--r--drivers/spi/tegra20_sflash.c1
-rw-r--r--drivers/spi/tegra20_slink.c1
-rw-r--r--drivers/usb/host/ehci-exynos.c10
-rw-r--r--drivers/usb/host/ehci-tegra.c38
-rw-r--r--drivers/usb/host/xhci-exynos5.c10
-rw-r--r--drivers/video/tegra.c54
-rw-r--r--examples/standalone/stubs.c64
-rw-r--r--fs/fs.c27
-rw-r--r--include/_exports.h99
-rw-r--r--include/asm-generic/global_data.h2
-rw-r--r--include/asm-generic/gpio.h265
-rw-r--r--include/common.h13
-rw-r--r--include/config_distro_bootcmd.h23
-rw-r--r--include/configs/am335x_evm.h6
-rw-r--r--include/configs/arndale.h2
-rw-r--r--include/configs/exynos5-common.h7
-rw-r--r--include/configs/exynos5250-common.h3
-rw-r--r--include/configs/ids8313.h3
-rw-r--r--include/configs/malta.h13
-rw-r--r--include/configs/odroid.h5
-rw-r--r--include/configs/sandbox.h4
-rw-r--r--include/configs/smdk5250.h2
-rw-r--r--include/configs/snow.h1
-rw-r--r--include/configs/ti_am335x_common.h2
-rw-r--r--include/configs/uniphier.h3
-rw-r--r--include/configs/vexpress_aemv8a.h33
-rw-r--r--include/configs/vexpress_common.h2
-rw-r--r--include/configs/zynq-common.h6
-rw-r--r--include/cros_ec.h3
-rw-r--r--include/dm-demo.h4
-rw-r--r--include/dm/device.h29
-rw-r--r--include/dm/test.h3
-rw-r--r--include/dm/uclass-id.h1
-rw-r--r--include/dm/uclass-internal.h11
-rw-r--r--include/dm/uclass.h21
-rw-r--r--include/exports.h22
-rw-r--r--include/fdtdec.h123
-rw-r--r--include/fs.h6
-rw-r--r--include/hash.h38
-rw-r--r--include/i2c.h105
-rw-r--r--include/image.h6
-rw-r--r--include/linker_lists.h4
-rw-r--r--include/sdhci.h6
-rw-r--r--include/spi.h42
-rw-r--r--include/u-boot/rsa-checksum.h17
-rw-r--r--include/u-boot/rsa-mod-exp.h75
-rw-r--r--lib/Kconfig2
-rw-r--r--lib/fdtdec.c202
-rw-r--r--lib/rsa/Kconfig27
-rw-r--r--lib/rsa/Makefile2
-rw-r--r--lib/rsa/rsa-checksum.c50
-rw-r--r--lib/rsa/rsa-mod-exp.c303
-rw-r--r--lib/rsa/rsa-verify.c348
-rw-r--r--test/dm/bus.c250
-rw-r--r--test/dm/core.c11
-rw-r--r--test/dm/gpio.c69
-rw-r--r--test/dm/i2c.c70
-rw-r--r--test/dm/spi.c6
-rwxr-xr-xtest/dm/test-dm.sh9
-rw-r--r--test/dm/test-fdt.c20
-rw-r--r--test/dm/test.dts27
-rwxr-xr-xtest/image/test-imagetools.sh129
-rw-r--r--tools/Makefile6
-rw-r--r--tools/aisimage.c30
-rw-r--r--tools/atmelimage.c30
-rw-r--r--tools/default_image.c77
-rw-r--r--tools/dumpimage.c170
-rw-r--r--tools/fit_image.c121
-rw-r--r--tools/gpimage-common.c3
-rw-r--r--tools/gpimage.c29
-rw-r--r--tools/imagetool.c124
-rw-r--r--tools/imagetool.h115
-rw-r--r--tools/imagetool.lds24
-rw-r--r--tools/imximage.c30
-rw-r--r--tools/kwbimage.c30
-rw-r--r--tools/mkimage.c113
-rw-r--r--tools/mxsimage.c35
-rw-r--r--tools/omapimage.c29
-rw-r--r--tools/pblimage.c30
-rw-r--r--tools/socfpgaimage.c36
-rw-r--r--tools/ublimage.c29
263 files changed, 6228 insertions, 3158 deletions
diff --git a/Kconfig b/Kconfig
index 4157da3..fed488f 100644
--- 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.
diff --git a/Makefile b/Makefile
index ea5ae8f..9b406c8 100644
--- 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 fefa71c..a28ff13 100644
--- 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:
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5eb1d03..986b4c5 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -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
diff --git a/arch/arm/cpu/armv7/cpu.c b/arch/arm/cpu/armv7/cpu.c
index 01cdb7e..c56417d 100644
--- a/arch/arm/cpu/armv7/cpu.c
+++ b/arch/arm/cpu/armv7/cpu.c
@@ -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
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
index 94d0297..be43e22 100644
--- a/arch/arm/cpu/armv7/exynos/pinmux.c
+++ b/arch/arm/cpu/armv7/exynos/pinmux.c
@@ -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));
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index fdc05b9..70048c1 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -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
diff --git a/arch/arm/cpu/tegra20-common/pmu.c b/arch/arm/cpu/tegra20-common/pmu.c
index 36a76a2..a774246 100644
--- a/arch/arm/cpu/tegra20-common/pmu.c
+++ b/arch/arm/cpu/tegra20-common/pmu.c
@@ -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;
diff --git a/arch/arm/dts/exynos4.dtsi b/arch/arm/dts/exynos4.dtsi
index 77fad48..7de227c 100644
--- a/arch/arm/dts/exynos4.dtsi
+++ b/arch/arm/dts/exynos4.dtsi
@@ -51,56 +51,64 @@
#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 {
@@ -143,11 +151,4 @@
interrupts = <0 131 0>;
};
- gpio: gpio {
- gpio-controller;
- #gpio-cells = <2>;
-
- interrupt-controller;
- #interrupt-cells = <2>;
- };
};
diff --git a/arch/arm/dts/exynos4210-origen.dts b/arch/arm/dts/exynos4210-origen.dts
index dd2476c..3f87761 100644
--- a/arch/arm/dts/exynos4210-origen.dts
+++ b/arch/arm/dts/exynos4210-origen.dts
@@ -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 {
diff --git a/arch/arm/dts/exynos4210-trats.dts b/arch/arm/dts/exynos4210-trats.dts
index 8c7a2c3..36d02df 100644
--- a/arch/arm/dts/exynos4210-trats.dts
+++ b/arch/arm/dts/exynos4210-trats.dts
@@ -101,7 +101,7 @@
sdhci@12510000 {
samsung,bus-width = <8>;
samsung,timing = <1 3 3>;
- pwr-gpios = <&gpio 146 0>;
+ pwr-gpios = <&gpk0 2 0>;
};
sdhci@12520000 {
@@ -111,7 +111,7 @@
sdhci@12530000 {
samsung,bus-width = <4>;
samsung,timing = <1 2 3>;
- cd-gpios = <&gpio 284 0>;
+ cd-gpios = <&gpx3 4 0>;
};
sdhci@12540000 {
diff --git a/arch/arm/dts/exynos4210-universal_c210.dts b/arch/arm/dts/exynos4210-universal_c210.dts
index 808c3f7..16948c9 100644
--- a/arch/arm/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/dts/exynos4210-universal_c210.dts
@@ -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 {
@@ -43,10 +43,10 @@
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>;
diff --git a/arch/arm/dts/exynos4412-odroid.dts b/arch/arm/dts/exynos4412-odroid.dts
index c78efec..00a2917 100644
--- a/arch/arm/dts/exynos4412-odroid.dts
+++ b/arch/arm/dts/exynos4412-odroid.dts
@@ -16,6 +16,13 @@
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 {
diff --git a/arch/arm/dts/exynos4412-trats2.dts b/arch/arm/dts/exynos4412-trats2.dts
index 60e4515..dd238df 100644
--- a/arch/arm/dts/exynos4412-trats2.dts
+++ b/arch/arm/dts/exynos4412-trats2.dts
@@ -416,7 +416,7 @@
sdhci@12510000 {
samsung,bus-width = <8>;
samsung,timing = <1 3 3>;
- pwr-gpios = <&gpio 0x6a 0>;
+ pwr-gpios = <&gpk0 4 0>;
status = "disabled";
};
@@ -427,7 +427,7 @@
sdhci@12530000 {
samsung,bus-width = <4>;
samsung,timing = <1 2 3>;
- cd-gpios = <&gpio 0x7a 0>;
+ cd-gpios = <&gpk2 2 0>;
};
sdhci@12540000 {
@@ -437,7 +437,7 @@
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>;
diff --git a/arch/arm/dts/exynos5.dtsi b/arch/arm/dts/exynos5.dtsi
index e539068..238acb8 100644
--- a/arch/arm/dts/exynos5.dtsi
+++ b/arch/arm/dts/exynos5.dtsi
@@ -6,6 +6,7 @@
*/
#include "skeleton.dtsi"
+#include <dt-bindings/gpio/gpio.h>
/ {
compatible = "samsung,exynos5";
@@ -247,7 +248,4 @@
u-boot,dm-pre-reloc;
id = <3>;
};
-
- gpio: gpio {
- };
};
diff --git a/arch/arm/dts/exynos5250-arndale.dts b/arch/arm/dts/exynos5250-arndale.dts
index 202f2ea..21c0a21 100644
--- a/arch/arm/dts/exynos5250-arndale.dts
+++ b/arch/arm/dts/exynos5250-arndale.dts
@@ -15,6 +15,14 @@
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";
};
diff --git a/arch/arm/dts/exynos5250-smdk5250.dts b/arch/arm/dts/exynos5250-smdk5250.dts
index 8850409..9273562 100644
--- a/arch/arm/dts/exynos5250-smdk5250.dts
+++ b/arch/arm/dts/exynos5250-smdk5250.dts
@@ -146,6 +146,6 @@
};
ehci@12110000 {
- samsung,vbus-gpio = <&gpio 0x316 0>; /* X26 */
+ samsung,vbus-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
};
};
diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts
index bac5015..7d8be69 100644
--- a/arch/arm/dts/exynos5250-snow.dts
+++ b/arch/arm/dts/exynos5250-snow.dts
@@ -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 {
@@ -131,11 +132,11 @@
};
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 {
diff --git a/arch/arm/dts/exynos5420-peach-pit.dts b/arch/arm/dts/exynos5420-peach-pit.dts
index d1d8735..b801de9 100644
--- a/arch/arm/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/dts/exynos5420-peach-pit.dts
@@ -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>;
};
@@ -108,7 +108,7 @@
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
@@ -124,11 +124,11 @@
};
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 {
diff --git a/arch/arm/dts/exynos5422-odroidxu3.dts b/arch/arm/dts/exynos5422-odroidxu3.dts
index 79a7acd..8f46637 100644
--- a/arch/arm/dts/exynos5422-odroidxu3.dts
+++ b/arch/arm/dts/exynos5422-odroidxu3.dts
@@ -32,7 +32,7 @@
};
ehci@12110000 {
- samsung,vbus-gpio = <&gpio 0x66 0>; /* X26 */
+ samsung,vbus-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>;
};
serial@12C20000 {
diff --git a/arch/arm/dts/exynos5800-peach-pi.dts b/arch/arm/dts/exynos5800-peach-pi.dts
index e7c380f..e4bc100 100644
--- a/arch/arm/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/dts/exynos5800-peach-pi.dts
@@ -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 {
@@ -102,7 +102,7 @@
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
@@ -118,11 +118,11 @@
};
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 {
diff --git a/arch/arm/dts/tegra114-dalmore.dts b/arch/arm/dts/tegra114-dalmore.dts
index 81ad212..51ff266 100644
--- a/arch/arm/dts/tegra114-dalmore.dts
+++ b/arch/arm/dts/tegra114-dalmore.dts
@@ -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";
};
};
diff --git a/arch/arm/dts/tegra124-jetson-tk1.dts b/arch/arm/dts/tegra124-jetson-tk1.dts
index 51fef54..e7b66d8 100644
--- a/arch/arm/dts/tegra124-jetson-tk1.dts
+++ b/arch/arm/dts/tegra124-jetson-tk1.dts
@@ -303,8 +303,9 @@
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>;
};
@@ -316,12 +317,12 @@
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 {
diff --git a/arch/arm/dts/tegra124-venice2.dts b/arch/arm/dts/tegra124-venice2.dts
index f7ccfc5..9e93cf9 100644
--- a/arch/arm/dts/tegra124-venice2.dts
+++ b/arch/arm/dts/tegra124-venice2.dts
@@ -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>;
};
@@ -85,11 +86,11 @@
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>;
};
};
diff --git a/arch/arm/dts/tegra20-colibri_t20_iris.dts b/arch/arm/dts/tegra20-colibri_t20_iris.dts
index 7cf08f4..3131b92 100644
--- a/arch/arm/dts/tegra20-colibri_t20_iris.dts
+++ b/arch/arm/dts/tegra20-colibri_t20_iris.dts
@@ -22,16 +22,16 @@
};
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>;
};
};
diff --git a/arch/arm/dts/tegra20-harmony.dts b/arch/arm/dts/tegra20-harmony.dts
index 982a14c..e6e4229 100644
--- a/arch/arm/dts/tegra20-harmony.dts
+++ b/arch/arm/dts/tegra20-harmony.dts
@@ -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 {
@@ -67,22 +67,22 @@
};
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>;
};
@@ -100,10 +100,14 @@
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>;
};
};
diff --git a/arch/arm/dts/tegra20-medcom-wide.dts b/arch/arm/dts/tegra20-medcom-wide.dts
index be2ed42..b6b57ab 100644
--- a/arch/arm/dts/tegra20-medcom-wide.dts
+++ b/arch/arm/dts/tegra20-medcom-wide.dts
@@ -73,9 +73,12 @@
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>;
};
};
diff --git a/arch/arm/dts/tegra20-paz00.dts b/arch/arm/dts/tegra20-paz00.dts
index 9d735b5..16381c3 100644
--- a/arch/arm/dts/tegra20-paz00.dts
+++ b/arch/arm/dts/tegra20-paz00.dts
@@ -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>;
};
@@ -86,10 +86,14 @@
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>;
};
};
diff --git a/arch/arm/dts/tegra20-seaboard.dts b/arch/arm/dts/tegra20-seaboard.dts
index 43b9911..10f3992 100644
--- a/arch/arm/dts/tegra20-seaboard.dts
+++ b/arch/arm/dts/tegra20-seaboard.dts
@@ -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 {
@@ -151,7 +151,7 @@
};
usb@c5000000 {
- nvidia,vbus-gpio = <&gpio 24 0>; /* PD0 */
+ nvidia,vbus-gpio = <&gpio TEGRA_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
dr_mode = "otg";
};
@@ -161,9 +161,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>;
};
@@ -186,10 +186,14 @@
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>;
};
};
diff --git a/arch/arm/dts/tegra20-tamonten.dtsi b/arch/arm/dts/tegra20-tamonten.dtsi
index f379622..78449e6 100644
--- a/arch/arm/dts/tegra20-tamonten.dtsi
+++ b/arch/arm/dts/tegra20-tamonten.dtsi
@@ -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>;
};
};
@@ -280,7 +281,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>;
@@ -476,8 +477,8 @@
};
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";
};
diff --git a/arch/arm/dts/tegra20-tec.dts b/arch/arm/dts/tegra20-tec.dts
index e99bd44..94ba6dc 100644
--- a/arch/arm/dts/tegra20-tec.dts
+++ b/arch/arm/dts/tegra20-tec.dts
@@ -73,9 +73,12 @@
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>;
};
};
diff --git a/arch/arm/dts/tegra20-trimslice.dts b/arch/arm/dts/tegra20-trimslice.dts
index 1637cbd..27b118f 100644
--- a/arch/arm/dts/tegra20-trimslice.dts
+++ b/arch/arm/dts/tegra20-trimslice.dts
@@ -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>;
};
@@ -111,7 +111,7 @@
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;
};
diff --git a/arch/arm/dts/tegra20-ventana.dts b/arch/arm/dts/tegra20-ventana.dts
index 6812203..939e567 100644
--- a/arch/arm/dts/tegra20-ventana.dts
+++ b/arch/arm/dts/tegra20-ventana.dts
@@ -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>;
};
@@ -86,10 +86,14 @@
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>;
};
};
diff --git a/arch/arm/dts/tegra20-whistler.dts b/arch/arm/dts/tegra20-whistler.dts
index 4fd2496..c4a28eb 100644
--- a/arch/arm/dts/tegra20-whistler.dts
+++ b/arch/arm/dts/tegra20-whistler.dts
@@ -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>;
};
diff --git a/arch/arm/dts/tegra30-apalis.dts b/arch/arm/dts/tegra30-apalis.dts
index 5bad3e7..15db0f2 100644
--- a/arch/arm/dts/tegra30-apalis.dts
+++ b/arch/arm/dts/tegra30-apalis.dts
@@ -243,13 +243,13 @@
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 {
@@ -262,20 +262,20 @@
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 {
diff --git a/arch/arm/dts/tegra30-beaver.dts b/arch/arm/dts/tegra30-beaver.dts
index 5903af6..ae83636 100644
--- a/arch/arm/dts/tegra30-beaver.dts
+++ b/arch/arm/dts/tegra30-beaver.dts
@@ -196,9 +196,9 @@
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>;
};
@@ -210,11 +210,11 @@
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";
};
diff --git a/arch/arm/dts/tegra30-cardhu.dts b/arch/arm/dts/tegra30-cardhu.dts
index e13d0fb..23ca141 100644
--- a/arch/arm/dts/tegra30-cardhu.dts
+++ b/arch/arm/dts/tegra30-cardhu.dts
@@ -185,9 +185,9 @@
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>;
};
@@ -197,7 +197,7 @@
};
usb@7d008000 {
- nvidia,vbus-gpio = <&gpio 236 0>; /* PDD4 */
+ nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 4) GPIO_ACTIVE_HIGH>;
status = "okay";
};
diff --git a/arch/arm/dts/tegra30-colibri.dts b/arch/arm/dts/tegra30-colibri.dts
index 37b6abd..6cd1902 100644
--- a/arch/arm/dts/tegra30-colibri.dts
+++ b/arch/arm/dts/tegra30-colibri.dts
@@ -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 {
@@ -83,12 +83,12 @@
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>;
};
};
diff --git a/arch/arm/dts/tegra30-tamonten.dtsi b/arch/arm/dts/tegra30-tamonten.dtsi
index c73afef..8eff627 100644
--- a/arch/arm/dts/tegra30-tamonten.dtsi
+++ b/arch/arm/dts/tegra30-tamonten.dtsi
@@ -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>;
};
diff --git a/arch/arm/include/asm/arch-exynos/pinmux.h b/arch/arm/include/asm/arch-exynos/pinmux.h
index 0b91ef6..d0ae757 100644
--- a/arch/arm/include/asm/arch-exynos/pinmux.h
+++ b/arch/arm/include/asm/arch-exynos/pinmux.h
@@ -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
index 0000000..e69de29
--- /dev/null
+++ b/arch/arm/include/asm/arch-pantheon/gpio.h
diff --git a/arch/arm/include/asm/arch-tegra/tegra_mmc.h b/arch/arm/include/asm/arch-tegra/tegra_mmc.h
index 84e7b55..a20bdaa 100644
--- a/arch/arm/include/asm/arch-tegra/tegra_mmc.h
+++ b/arch/arm/include/asm/arch-tegra/tegra_mmc.h
@@ -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 */
diff --git a/arch/arm/include/asm/arch-tegra20/display.h b/arch/arm/include/asm/arch-tegra20/display.h
index a04c84e..6feeda3 100644
--- a/arch/arm/include/asm/arch-tegra20/display.h
+++ b/arch/arm/include/asm/arch-tegra20/display.h
@@ -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
diff --git a/arch/arm/include/asm/arch-zynq/gpio.h b/arch/arm/include/asm/arch-zynq/gpio.h
index 2dbba75..a26ae87 100644
--- a/arch/arm/include/asm/arch-zynq/gpio.h
+++ b/arch/arm/include/asm/arch-zynq/gpio.h
@@ -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 */
diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c
index b7f1188..91aa5cc 100644
--- a/arch/blackfin/cpu/cpu.c
+++ b/arch/blackfin/cpu/cpu.c
@@ -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);
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index ef78929..bc4283d 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -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
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 0a9e7e6..43f0f5c 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -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
index 0000000..fc6b455
--- /dev/null
+++ b/arch/mips/cpu/Makefile
@@ -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
index 0000000..8d3b2f5
--- /dev/null
+++ b/arch/mips/cpu/cpu.c
@@ -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/interrupts.c b/arch/mips/cpu/interrupts.c
index 275fcf5..275fcf5 100644
--- a/arch/mips/cpu/mips32/interrupts.c
+++ b/arch/mips/cpu/interrupts.c
diff --git a/arch/mips/cpu/mips32/Makefile b/arch/mips/cpu/mips32/Makefile
deleted file mode 100644
index fa82dd3..0000000
--- a/arch/mips/cpu/mips32/Makefile
+++ /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
index 899c319..0000000
--- a/arch/mips/cpu/mips64/Makefile
+++ /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
index 36d8688..0000000
--- a/arch/mips/cpu/mips64/cache.S
+++ /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
index 9f45cfc..0000000
--- a/arch/mips/cpu/mips64/cpu.c
+++ /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
index 275fcf5..0000000
--- a/arch/mips/cpu/mips64/interrupts.c
+++ /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
index 471bc1e..0000000
--- a/arch/mips/cpu/mips64/start.S
+++ /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
index 553da5f..0000000
--- a/arch/mips/cpu/mips64/time.c
+++ /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;
-}
diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/start.S
index 36b92cc..3b5b622 100644
--- a/arch/mips/cpu/mips32/start.S
+++ b/arch/mips/cpu/start.S
@@ -8,6 +8,7 @@
#include <asm-offsets.h>
#include <config.h>
+#include <asm/asm.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
@@ -20,6 +21,23 @@
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
diff --git a/arch/mips/cpu/mips32/time.c b/arch/mips/cpu/time.c
index 553da5f..553da5f 100644
--- a/arch/mips/cpu/mips32/time.c
+++ b/arch/mips/cpu/time.c
diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h
index 6464250..75ec380 100644
--- a/arch/mips/include/asm/cacheops.h
+++ b/arch/mips/include/asm/cacheops.h
@@ -11,6 +11,19 @@
#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
*/
diff --git a/arch/mips/include/asm/malta.h b/arch/mips/include/asm/malta.h
index 9e7c045..d9ffc15 100644
--- a/arch/mips/include/asm/malta.h
+++ b/arch/mips/include/asm/malta.h
@@ -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 */
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 7f9b653..ac536da 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -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
diff --git a/arch/mips/cpu/mips32/cpu.c b/arch/mips/lib/cache.c
index 278865b..e245614 100644
--- a/arch/mips/cpu/mips32/cpu.c
+++ b/arch/mips/lib/cache.c
@@ -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;
-}
diff --git a/arch/mips/cpu/mips32/cache.S b/arch/mips/lib/cache_init.S
index 22bd844..137d728 100644
--- a/arch/mips/cpu/mips32/cache.S
+++ b/arch/mips/lib/cache_init.S
@@ -18,18 +18,8 @@
#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)
@@ -51,56 +41,49 @@
#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)
/*
diff --git a/arch/mips/cpu/mips32/au1x00/Makefile b/arch/mips/mach-au1x00/Makefile
index c5643e7..c5643e7 100644
--- a/arch/mips/cpu/mips32/au1x00/Makefile
+++ b/arch/mips/mach-au1x00/Makefile
diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_eth.c b/arch/mips/mach-au1x00/au1x00_eth.c
index 4770f56..39c5b6b 100644
--- a/arch/mips/cpu/mips32/au1x00/au1x00_eth.c
+++ b/arch/mips/mach-au1x00/au1x00_eth.c
@@ -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;
+}
diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_ide.c b/arch/mips/mach-au1x00/au1x00_ide.c
index ba0b35d..ba0b35d 100644
--- a/arch/mips/cpu/mips32/au1x00/au1x00_ide.c
+++ b/arch/mips/mach-au1x00/au1x00_ide.c
diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_serial.c b/arch/mips/mach-au1x00/au1x00_serial.c
index 0463508..0463508 100644
--- a/arch/mips/cpu/mips32/au1x00/au1x00_serial.c
+++ b/arch/mips/mach-au1x00/au1x00_serial.c
diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c b/arch/mips/mach-au1x00/au1x00_usb_ohci.c
index 74bdb77..74bdb77 100644
--- a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.c
+++ b/arch/mips/mach-au1x00/au1x00_usb_ohci.c
diff --git a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.h b/arch/mips/mach-au1x00/au1x00_usb_ohci.h
index bb9f351..bb9f351 100644
--- a/arch/mips/cpu/mips32/au1x00/au1x00_usb_ohci.h
+++ b/arch/mips/mach-au1x00/au1x00_usb_ohci.h
diff --git a/arch/mips/cpu/mips32/au1x00/config.mk b/arch/mips/mach-au1x00/config.mk
index 5c89129..5c89129 100644
--- a/arch/mips/cpu/mips32/au1x00/config.mk
+++ b/arch/mips/mach-au1x00/config.mk
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 68540be..9ce31bf 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -19,6 +19,7 @@
colour = "cyan";
sides = <3>;
character = <83>;
+ light-gpios = <&gpio_a 2>, <&gpio_b 6 0>;
};
square {
compatible = "demo-shape";
@@ -124,7 +125,7 @@
0x070b0067 0x070c0069>;
};
- gpio_a: gpios {
+ gpio_a: gpios@0 {
gpio-controller;
compatible = "sandbox,gpio";
#gpio-cells = <1>;
@@ -132,6 +133,14 @@
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>;
diff --git a/board/BuS/eb_cpux9k2/cpux9k2.c b/board/BuS/eb_cpux9k2/cpux9k2.c
index 5e4778e..76ad7c4 100644
--- a/board/BuS/eb_cpux9k2/cpux9k2.c
+++ b/board/BuS/eb_cpux9k2/cpux9k2.c
@@ -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);
diff --git a/board/armltd/vexpress64/Kconfig b/board/armltd/vexpress64/Kconfig
index 7ebea63..7d5e7be 100644
--- a/board/armltd/vexpress64/Kconfig
+++ b/board/armltd/vexpress64/Kconfig
@@ -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"
diff --git a/board/armltd/vexpress64/MAINTAINERS b/board/armltd/vexpress64/MAINTAINERS
index 66c8dff..0ba044d 100644
--- a/board/armltd/vexpress64/MAINTAINERS
+++ b/board/armltd/vexpress64/MAINTAINERS
@@ -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
diff --git a/board/avionic-design/common/tamonten-ng.c b/board/avionic-design/common/tamonten-ng.c
index 86a0844..1704627 100644
--- a/board/avionic-design/common/tamonten-ng.c
+++ b/board/avionic-design/common/tamonten-ng.c
@@ -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);
}
/*
diff --git a/board/imgtec/malta/malta.c b/board/imgtec/malta/malta.c
index 78c4bd4..79562f7 100644
--- a/board/imgtec/malta/malta.c
+++ b/board/imgtec/malta/malta.c
@@ -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);
}
diff --git a/board/nvidia/cardhu/cardhu.c b/board/nvidia/cardhu/cardhu.c
index 95c4ff2..1540526 100644
--- a/board/nvidia/cardhu/cardhu.c
+++ b/board/nvidia/cardhu/cardhu.c
@@ -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;
diff --git a/board/nvidia/dalmore/dalmore.c b/board/nvidia/dalmore/dalmore.c
index 2a73746..d7c1a69 100644
--- a/board/nvidia/dalmore/dalmore.c
+++ b/board/nvidia/dalmore/dalmore.c
@@ -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);
diff --git a/board/nvidia/whistler/whistler.c b/board/nvidia/whistler/whistler.c
index 3114b20..3476f11 100644
--- a/board/nvidia/whistler/whistler.c
+++ b/board/nvidia/whistler/whistler.c
@@ -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);
}
diff --git a/board/samsung/odroid/odroid.c b/board/samsung/odroid/odroid.c
index b7d2381..e3517f2 100644
--- a/board/samsung/odroid/odroid.c
+++ b/board/samsung/odroid/odroid.c
@@ -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;
diff --git a/board/toradex/apalis_t30/apalis_t30.c b/board/toradex/apalis_t30/apalis_t30.c
index 5d2c024..6244214 100644
--- a/board/toradex/apalis_t30/apalis_t30.c
+++ b/board/toradex/apalis_t30/apalis_t30.c
@@ -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;
diff --git a/common/Makefile b/common/Makefile
index 94554f2..9579ab4 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -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
diff --git a/common/board_f.c b/common/board_f.c
index 215108b..7953137 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -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
index 0000000..42d0641
--- /dev/null
+++ b/common/board_info.c
@@ -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();
+}
diff --git a/common/board_r.c b/common/board_r.c
index a301cc2..68a9448 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -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 */
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 6723360..48199bf 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -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
diff --git a/common/cmd_demo.c b/common/cmd_demo.c
index 652c61c..bcb34d9 100644
--- a/common/cmd_demo.c
+++ b/common/cmd_demo.c
@@ -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"
);
diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c
index 484a6c6..7f99aab 100644
--- a/common/cmd_fpga.c
+++ b/common/cmd_fpga.c
@@ -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)
diff --git a/common/cmd_fs.c b/common/cmd_fs.c
index 0d9da11..e146254 100644
--- a/common/cmd_fs.c
+++ b/common/cmd_fs.c
@@ -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"
+);
diff --git a/common/cmd_gettime.c b/common/cmd_gettime.c
index 320ff70..c48baad 100644
--- a/common/cmd_gettime.c
+++ b/common/cmd_gettime.c
@@ -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"
);
diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
index 22db1bb..7c3ad00 100644
--- a/common/cmd_i2c.c
+++ b/common/cmd_i2c.c
@@ -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);
}
diff --git a/common/cmd_load.c b/common/cmd_load.c
index f6e522c..d043e6d 100644
--- a/common/cmd_load.c
+++ b/common/cmd_load.c
@@ -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);
}
diff --git a/common/cmd_part.c b/common/cmd_part.c
index 39e8666..c99f527 100644
--- a/common/cmd_part.c
+++ b/common/cmd_part.c
@@ -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"
);
diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c
index ae2714d..64b9186 100644
--- a/common/cmd_ximg.c
+++ b/common/cmd_ximg.c
@@ -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);
diff --git a/common/console.c b/common/console.c
index fc1963b..3f25e76 100644
--- a/common/console.c
+++ b/common/console.c
@@ -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 */
diff --git a/common/exports.c b/common/exports.c
index 88fcfc8..333107c 100644
--- a/common/exports.c
+++ b/common/exports.c
@@ -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>
}
diff --git a/common/hash.c b/common/hash.c
index aceabc5..d154d02 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -10,17 +10,26 @@
* 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
diff --git a/common/image-fit.c b/common/image-fit.c
index 1589ee3..b47d110 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -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
diff --git a/common/image-sig.c b/common/image-sig.c
index 8601eda..2c9f0cd 100644
--- a/common/image-sig.c
+++ b/common/image-sig.c
@@ -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,
}
diff --git a/common/image.c b/common/image.c
index ad7a46d..a911aa9 100644
--- a/common/image.c
+++ b/common/image.c
@@ -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:
diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig
index 5837a0a..51bf370 100644
--- a/configs/am335x_boneblack_vboot_defconfig
+++ b/configs/am335x_boneblack_vboot_defconfig
@@ -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
diff --git a/configs/ids8313_defconfig b/configs/ids8313_defconfig
index 1c665aa..0950ec8 100644
--- a/configs/ids8313_defconfig
+++ b/configs/ids8313_defconfig
@@ -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
diff --git a/configs/ph1_ld4_defconfig b/configs/ph1_ld4_defconfig
index 2e9dd00..86b4b15 100644
--- a/configs/ph1_ld4_defconfig
+++ b/configs/ph1_ld4_defconfig
@@ -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
diff --git a/configs/ph1_pro4_defconfig b/configs/ph1_pro4_defconfig
index 5dca64b..242bcf9 100644
--- a/configs/ph1_pro4_defconfig
+++ b/configs/ph1_pro4_defconfig
@@ -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
diff --git a/configs/ph1_sld8_defconfig b/configs/ph1_sld8_defconfig
index 2a6e334..8e95f17 100644
--- a/configs/ph1_sld8_defconfig
+++ b/configs/ph1_sld8_defconfig
@@ -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
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 47d8400..660063e 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -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"
diff --git a/configs/vexpress_aemv8a_defconfig b/configs/vexpress_aemv8a_defconfig
index b463a33..9f4b876 100644
--- a/configs/vexpress_aemv8a_defconfig
+++ b/configs/vexpress_aemv8a_defconfig
@@ -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
index 0000000..d28a428
--- /dev/null
+++ b/configs/vexpress_aemv8a_juno_defconfig
@@ -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
diff --git a/configs/vexpress_aemv8a_semi_defconfig b/configs/vexpress_aemv8a_semi_defconfig
index 0035ccd..26cf7db4 100644
--- a/configs/vexpress_aemv8a_semi_defconfig
+++ b/configs/vexpress_aemv8a_semi_defconfig
@@ -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"
diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig
index 9588849..8b985fe 100644
--- a/configs/zynq_microzed_defconfig
+++ b/configs/zynq_microzed_defconfig
@@ -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"
diff --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig
index cf50730..cceb321 100644
--- a/configs/zynq_zc70x_defconfig
+++ b/configs/zynq_zc70x_defconfig
@@ -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
diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig
index 8bb405d..2935c0d 100644
--- a/configs/zynq_zc770_xm010_defconfig
+++ b/configs/zynq_zc770_xm010_defconfig
@@ -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
diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig
index 0ba5da5..0401739 100644
--- a/configs/zynq_zc770_xm012_defconfig
+++ b/configs/zynq_zc770_xm012_defconfig
@@ -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
diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig
index 13f8112..a95970a 100644
--- a/configs/zynq_zc770_xm013_defconfig
+++ b/configs/zynq_zc770_xm013_defconfig
@@ -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
diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig
index eb057fa..0fbc41a 100644
--- a/configs/zynq_zed_defconfig
+++ b/configs/zynq_zed_defconfig
@@ -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
diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig
index 12311cd..4e66760 100644
--- a/configs/zynq_zybo_defconfig
+++ b/configs/zynq_zybo_defconfig
@@ -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
index 0000000..dd0f1c7
--- /dev/null
+++ b/doc/README.distro
@@ -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.
diff --git a/doc/README.standalone b/doc/README.standalone
index e3000ef..659a12f 100644
--- a/doc/README.standalone
+++ b/doc/README.standalone
@@ -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
index 0000000..5375625
--- /dev/null
+++ b/doc/device-tree-bindings/gpio/gpio-samsung.txt
@@ -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
index 0000000..b9bd1d6
--- /dev/null
+++ b/doc/device-tree-bindings/gpio/gpio.txt
@@ -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
index 0000000..023c952
--- /dev/null
+++ b/doc/device-tree-bindings/gpio/nvidia,tegra20-gpio.txt
@@ -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
index 0000000..ea918dd
--- /dev/null
+++ b/doc/device-tree-bindings/i2c/i2c.txt
@@ -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>;
+ };
+};
diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt
index eafa825..f83264d 100644
--- a/doc/driver-model/README.txt
+++ b/doc/driver-model/README.txt
@@ -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
diff --git a/doc/driver-model/spi-howto.txt b/doc/driver-model/spi-howto.txt
index 719dbd5..5bc29ad 100644
--- a/doc/driver-model/spi-howto.txt
+++ b/doc/driver-model/spi-howto.txt
@@ -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.
diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt
index b47ce73..427ea49 100644
--- a/doc/uImage.FIT/source_file_format.txt
+++ b/doc/uImage.FIT/source_file_format.txt
@@ -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",
diff --git a/doc/uImage.FIT/verified-boot.txt b/doc/uImage.FIT/verified-boot.txt
index 3c83fbc..e639e7a 100644
--- a/doc/uImage.FIT/verified-boot.txt
+++ b/doc/uImage.FIT/verified-boot.txt
@@ -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.
diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
index 8fc6b71..3a5f48d 100644
--- a/drivers/core/device-remove.c
+++ b/drivers/core/device-remove.c
@@ -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;
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 963b16f..b73d3b8 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -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;
+}
diff --git a/drivers/core/root.c b/drivers/core/root.c
index 47b3acf..73e3c72 100644
--- a/drivers/core/root.c
+++ b/drivers/core/root.c
@@ -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;
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 901b06e..289a5d2 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -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;
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index e69de29..bd26a2b 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -0,0 +1 @@
+source drivers/crypto/fsl/Kconfig
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 7b79237..fb8c10b 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -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
index 0000000..86b2f2f
--- /dev/null
+++ b/drivers/crypto/fsl/Kconfig
@@ -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.
diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile
index 067d0a9..c0cf642 100644
--- a/drivers/crypto/fsl/Makefile
+++ b/drivers/crypto/fsl/Makefile
@@ -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
index 0000000..cf1c4c1
--- /dev/null
+++ b/drivers/crypto/fsl/fsl_rsa.c
@@ -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",
+};
diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c
index 1386bae..cc0dced 100644
--- a/drivers/crypto/fsl/jobdesc.c
+++ b/drivers/crypto/fsl/jobdesc.c
@@ -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);
+}
diff --git a/drivers/crypto/fsl/jobdesc.h b/drivers/crypto/fsl/jobdesc.h
index 3cf7226..84b3edd 100644
--- a/drivers/crypto/fsl/jobdesc.h
+++ b/drivers/crypto/fsl/jobdesc.h
@@ -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
index 0000000..4ff87ef
--- /dev/null
+++ b/drivers/crypto/fsl/rsa_caam.h
@@ -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
index 0000000..6dcb39a
--- /dev/null
+++ b/drivers/crypto/rsa_mod_exp/Kconfig
@@ -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
index 0000000..915b751
--- /dev/null
+++ b/drivers/crypto/rsa_mod_exp/Makefile
@@ -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
index 0000000..dc6c064
--- /dev/null
+++ b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c
@@ -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
index 0000000..266f094
--- /dev/null
+++ b/drivers/crypto/rsa_mod_exp/mod_exp_uclass.c
@@ -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",
+};
diff --git a/drivers/demo/demo-shape.c b/drivers/demo/demo-shape.c
index 3fa9c59..d908736 100644
--- a/drivers/demo/demo-shape.c
+++ b/drivers/demo/demo-shape.c
@@ -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),
};
diff --git a/drivers/demo/demo-uclass.c b/drivers/demo/demo-uclass.c
index f6510d6..725f068 100644
--- a/drivers/demo/demo-uclass.c
+++ b/drivers/demo/demo-uclass.c
@@ -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);
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 255700a..a69bbd2 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -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)
{
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 6c41a42..0a245ba 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -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;
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index 53c80d5..d564c25 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -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)
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index 88f7ef5..43928b8 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -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,
};
/**
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index e69de29..202ea5d 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -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.
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 6f3c86c..774bc94 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -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
index 0000000..223f238
--- /dev/null
+++ b/drivers/i2c/i2c-uclass-compat.c
@@ -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 */
+}
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index 005bf86..eafa457 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -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
index 0000000..6707edd
--- /dev/null
+++ b/drivers/i2c/i2c-uniphier-f.c
@@ -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
index 0000000..64a9ed8
--- /dev/null
+++ b/drivers/i2c/i2c-uniphier.c
@@ -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,
+};
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c
index fd328f0..0dd1abc 100644
--- a/drivers/i2c/s3c24x0_i2c.c
+++ b/drivers/i2c/s3c24x0_i2c.c
@@ -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>
@@ -121,13 +122,23 @@
#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 */
diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c
index f0e9f51..a943aa6 100644
--- a/drivers/i2c/sandbox_i2c.c
+++ b/drivers/i2c/sandbox_i2c.c
@@ -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,
};
diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c
index 87290c3..f414287 100644
--- a/drivers/i2c/tegra_i2c.c
+++ b/drivers/i2c/tegra_i2c.c
@@ -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,
};
diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c
index 9b4effb..5846e76 100644
--- a/drivers/misc/cros_ec.c
+++ b/drivers/misc/cros_ec.c
@@ -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;
diff --git a/drivers/misc/cros_ec_i2c.c b/drivers/misc/cros_ec_i2c.c
index 513cdb1..f9bc975 100644
--- a/drivers/misc/cros_ec_i2c.c
+++ b/drivers/misc/cros_ec_i2c.c
@@ -14,6 +14,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <i2c.h>
#include <cros_ec.h>
@@ -23,11 +24,11 @@
#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,
+};
diff --git a/drivers/misc/cros_ec_spi.c b/drivers/misc/cros_ec_spi.c
index e6dba29..9359c56 100644
--- a/drivers/misc/cros_ec_spi.c
+++ b/drivers/misc/cros_ec_spi.c
@@ -21,14 +21,9 @@
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
diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c
index a5d3487..3899372 100644
--- a/drivers/mmc/s5p_sdhci.c
+++ b/drivers/mmc/s5p_sdhci.c
@@ -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;
}
diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c
index 2bd36b0..2cd8cf1 100644
--- a/drivers/mmc/tegra_mmc.c
+++ b/drivers/mmc/tegra_mmc.c
@@ -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);
diff --git a/drivers/mtd/nand/tegra_nand.c b/drivers/mtd/nand/tegra_nand.c
index 163cf29..b660f3b 100644
--- a/drivers/mtd/nand/tegra_nand.c
+++ b/drivers/mtd/nand/tegra_nand.c
@@ -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;
diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c
index 3024b98..d576d31 100644
--- a/drivers/mtd/spi/sandbox.c
+++ b/drivers/mtd/spi/sandbox.c
@@ -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;
}
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index ce9987f..4103723 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -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);
}
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 9ded895..c03e935 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -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);
};
diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
index 6531030..cd44222 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -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);
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 507b9a3..1815b29 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -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;
}
diff --git a/drivers/net/smc91111.h b/drivers/net/smc91111.h
index d9135cb..e19c491 100644
--- a/drivers/net/smc91111.h
+++ b/drivers/net/smc91111.h
@@ -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 */
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index 79d6561..dcdba4e 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -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;
diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c
index eb76591..5729a15 100644
--- a/drivers/pci/pci_rom.c
+++ b/drivers/pci/pci_rom.c
@@ -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),
diff --git a/drivers/power/as3722.c b/drivers/power/as3722.c
index 4c6de79..a60bb5f 100644
--- a/drivers/power/as3722.c
+++ b/drivers/power/as3722.c
@@ -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);
diff --git a/drivers/power/tps6586x.c b/drivers/power/tps6586x.c
index 29bab4c..8650983 100644
--- a/drivers/power/tps6586x.c
+++ b/drivers/power/tps6586x.c
@@ -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;
}
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index d1b5777..9131a8f 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -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),
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index 98ae3b8..a75fc46 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -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,
};
diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c
index 700f616..2624844 100644
--- a/drivers/spi/designware_spi.c
+++ b/drivers/spi/designware_spi.c
@@ -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,
};
diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c
index f078973..a46d8c1 100644
--- a/drivers/spi/exynos_spi.c
+++ b/drivers/spi/exynos_spi.c
@@ -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,
};
diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c
index e717424..bad5660 100644
--- a/drivers/spi/sandbox_spi.c
+++ b/drivers/spi/sandbox_spi.c
@@ -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,
};
diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c
index 5588036..6ae45f5 100644
--- a/drivers/spi/soft_spi.c
+++ b/drivers/spi/soft_spi.c
@@ -21,10 +21,10 @@
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,
};
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 7a57bce..63a6217 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -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) = {
diff --git a/drivers/spi/tegra114_spi.c b/drivers/spi/tegra114_spi.c
index 2d97625..53ff9ea 100644
--- a/drivers/spi/tegra114_spi.c
+++ b/drivers/spi/tegra114_spi.c
@@ -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,
};
diff --git a/drivers/spi/tegra20_sflash.c b/drivers/spi/tegra20_sflash.c
index 7d0d0f3..78c74cd 100644
--- a/drivers/spi/tegra20_sflash.c
+++ b/drivers/spi/tegra20_sflash.c
@@ -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,
};
diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c
index 213fa5f..597d6ad 100644
--- a/drivers/spi/tegra20_slink.c
+++ b/drivers/spi/tegra20_slink.c
@@ -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,
};
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index 6fdbf57..f3c077d 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -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);
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 5f0a98e..b5ad1e3 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -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;
}
diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c
index b4946a3..a77c8bc 100644
--- a/drivers/usb/host/xhci-exynos5.c
+++ b/drivers/usb/host/xhci-exynos5.c
@@ -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);
diff --git a/drivers/video/tegra.c b/drivers/video/tegra.c
index 57cb007..b8f3431 100644
--- a/drivers/video/tegra.c
+++ b/drivers/video/tegra.c
@@ -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;
diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c
index 0bf690e..920a0a9 100644
--- a/examples/standalone/stubs.c
+++ b/examples/standalone/stubs.c
@@ -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
@@ -10,23 +12,23 @@
* 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 ddd751c..483273f 100644
--- 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;
+}
+
diff --git a/include/_exports.h b/include/_exports.h
index 349a3c5..5944703 100644
--- a/include/_exports.h
+++ b/include/_exports.h
@@ -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)
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 3d14d5f..6747619 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -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 */
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index 36a36c6..3b96b82 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -10,6 +10,15 @@
/*
* 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_ */
diff --git a/include/common.h b/include/common.h
index 4b3e0d3..97c8f79 100644
--- a/include/common.h
+++ b/include/common.h
@@ -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 */
diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
index becbe3f..49674f4 100644
--- a/include/config_distro_bootcmd.h
+++ b/include/config_distro_bootcmd.h
@@ -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) \
@@ -110,7 +110,7 @@
#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) \
@@ -154,8 +154,8 @@
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 " \
@@ -186,17 +186,30 @@
"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 */
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index 0004750..76ce7de 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -19,13 +19,11 @@
#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)
diff --git a/include/configs/arndale.h b/include/configs/arndale.h
index d68993b..3ad4a9b 100644
--- a/include/configs/arndale.h
+++ b/include/configs/arndale.h
@@ -51,8 +51,6 @@
/* PMIC */
#define CONFIG_PMIC
#define CONFIG_POWER_I2C
-#define CONFIG_POWER_MAX77686
-
#define CONFIG_PREBOOT
diff --git a/include/configs/exynos5-common.h b/include/configs/exynos5-common.h
index ad63f3c..0ba39a2 100644
--- a/include/configs/exynos5-common.h
+++ b/include/configs/exynos5-common.h
@@ -126,12 +126,11 @@
#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
diff --git a/include/configs/exynos5250-common.h b/include/configs/exynos5250-common.h
index 6714313..ae0e5ff 100644
--- a/include/configs/exynos5250-common.h
+++ b/include/configs/exynos5250-common.h
@@ -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
diff --git a/include/configs/ids8313.h b/include/configs/ids8313.h
index f084834..2384864 100644
--- a/include/configs/ids8313.h
+++ b/include/configs/ids8313.h
@@ -575,12 +575,9 @@
#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
diff --git a/include/configs/malta.h b/include/configs/malta.h
index 684d249..354672e 100644
--- a/include/configs/malta.h
+++ b/include/configs/malta.h
@@ -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
@@ -107,6 +108,16 @@
(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
*/
#include <config_cmd_default.h>
@@ -118,6 +129,8 @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_ELF
+#define CONFIG_CMD_IDE
#define CONFIG_CMD_PCI
#define CONFIG_CMD_PING
diff --git a/include/configs/odroid.h b/include/configs/odroid.h
index 807e96b..9d5dbdc 100644
--- a/include/configs/odroid.h
+++ b/include/configs/odroid.h
@@ -177,12 +177,11 @@
/* 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
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index 657f751..e9d3f32 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -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
diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h
index 8395372..3b06d30 100644
--- a/include/configs/smdk5250.h
+++ b/include/configs/smdk5250.h
@@ -18,6 +18,8 @@
#include <configs/exynos5250-common.h>
+/* PMIC */
+#define CONFIG_POWER_MAX77686
#define CONFIG_BOARD_COMMON
#define CONFIG_ARCH_EARLY_INIT_R
diff --git a/include/configs/snow.h b/include/configs/snow.h
index 7eaa586..ce6676e 100644
--- a/include/configs/snow.h
+++ b/include/configs/snow.h
@@ -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
diff --git a/include/configs/ti_am335x_common.h b/include/configs/ti_am335x_common.h
index 5ed86d9..598526b 100644
--- a/include/configs/ti_am335x_common.h
+++ b/include/configs/ti_am335x_common.h
@@ -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
diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h
index 5a53c50..9ad47f6 100644
--- a/include/configs/uniphier.h
+++ b/include/configs/uniphier.h
@@ -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
*/
diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h
index 027d78b..7fb28a5 100644
--- a/include/configs/vexpress_aemv8a.h
+++ b/include/configs/vexpress_aemv8a.h
@@ -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
@@ -40,10 +41,13 @@
#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)
@@ -88,10 +92,15 @@
#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))
@@ -119,9 +128,12 @@
#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)
@@ -140,7 +152,11 @@
/* 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
@@ -161,6 +177,7 @@
#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
@@ -191,7 +208,7 @@
#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" \
diff --git a/include/configs/vexpress_common.h b/include/configs/vexpress_common.h
index 7e78f8a..2dea921 100644
--- a/include/configs/vexpress_common.h
+++ b/include/configs/vexpress_common.h
@@ -122,7 +122,7 @@
#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 */
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h
index 2d28e89..864528a 100644
--- a/include/configs/zynq-common.h
+++ b/include/configs/zynq-common.h
@@ -276,17 +276,11 @@
#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)
diff --git a/include/cros_ec.h b/include/cros_ec.h
index 9e13146..8457c80 100644
--- a/include/cros_ec.h
+++ b/include/cros_ec.h
@@ -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 */
diff --git a/include/dm-demo.h b/include/dm-demo.h
index a24fec6..03722d0 100644
--- a/include/dm-demo.h
+++ b/include/dm-demo.h
@@ -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);
diff --git a/include/dm/device.h b/include/dm/device.h
index 13598a1..81afa8c 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -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;
};
@@ -184,6 +195,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
*
* The parent data is data stored in the device but owned by the parent.
@@ -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
*
diff --git a/include/dm/test.h b/include/dm/test.h
index f08c05d..707c69e 100644
--- a/include/dm/test.h
+++ b/include/dm/test.h
@@ -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;
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index f17c3c2..91bb90d 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -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,
diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h
index f718f37..f2f254a 100644
--- a/include/dm/uclass-internal.h
+++ b/include/dm/uclass-internal.h
@@ -44,6 +44,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
*
* Perform any post-processing of a probed device that is needed by the
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index f6ec6d7..d6c40c6 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -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
diff --git a/include/exports.h b/include/exports.h
index 41d5085..205affe 100644
--- a/include/exports.h
+++ b/include/exports.h
@@ -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;
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 8c2bd21..231eed7 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -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
@@ -592,50 +605,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
* value of the first cell is returned.
diff --git a/include/fs.h b/include/fs.h
index ffb6ce7..fd1e4ab 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -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 */
diff --git a/include/hash.h b/include/hash.h
index d8ec4f0..f4eb100 100644
--- a/include/hash.h
+++ b/include/hash.h
@@ -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
*
@@ -115,6 +115,23 @@ 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
*
* The function returns the pointer to the struct or -EPROTONOSUPPORT if the
@@ -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
diff --git a/include/i2c.h b/include/i2c.h
index 9c6a60c..27fe00f 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -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
diff --git a/include/image.h b/include/image.h
index ee3afe3..0e6af00 100644
--- a/include/image.h
+++ b/include/image.h
@@ -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;
};
diff --git a/include/linker_lists.h b/include/linker_lists.h
index d37fba4..940c871 100644
--- a/include/linker_lists.h
+++ b/include/linker_lists.h
@@ -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
*
diff --git a/include/sdhci.h b/include/sdhci.h
index aa4a0e9..23893b5 100644
--- a/include/sdhci.h
+++ b/include/sdhci.h
@@ -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);
diff --git a/include/spi.h b/include/spi.h
index ec17bd0..c58e453 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -56,20 +56,42 @@
#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
diff --git a/include/u-boot/rsa-checksum.h b/include/u-boot/rsa-checksum.h
index c996fb3..3c69d85 100644
--- a/include/u-boot/rsa-checksum.h
+++ b/include/u-boot/rsa-checksum.h
@@ -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
index 0000000..fce445a
--- /dev/null
+++ b/include/u-boot/rsa-mod-exp.h
@@ -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
diff --git a/lib/Kconfig b/lib/Kconfig
index 8460439..a1f30a2 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -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
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index e989241..5bf8f29 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -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
index 0000000..1268a1b
--- /dev/null
+++ b/lib/rsa/Kconfig
@@ -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
diff --git a/lib/rsa/Makefile b/lib/rsa/Makefile
index a5a96cb6..cc25b3c 100644
--- a/lib/rsa/Makefile
+++ b/lib/rsa/Makefile
@@ -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
diff --git a/lib/rsa/rsa-checksum.c b/lib/rsa/rsa-checksum.c
index 8d8b59f..68d9d65 100644
--- a/lib/rsa/rsa-checksum.c
+++ b/lib/rsa/rsa-checksum.c
@@ -10,12 +10,13 @@
#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
index 0000000..4a6de2b
--- /dev/null
+++ b/lib/rsa/rsa-mod-exp.c
@@ -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;
+}
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index 4ef19b6..60126d2 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -12,246 +12,46 @@
#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) {
diff --git a/test/dm/bus.c b/test/dm/bus.c
index abbaccf..faffe6a 100644
--- a/test/dm/bus.c
+++ b/test/dm/bus.c
@@ -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);
diff --git a/test/dm/core.c b/test/dm/core.c
index ff5c2a7..eccda09 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -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);
diff --git a/test/dm/gpio.c b/test/dm/gpio.c
index 94bd0d9..b29daf1 100644
--- a/test/dm/gpio.c
+++ b/test/dm/gpio.c
@@ -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);
diff --git a/test/dm/i2c.c b/test/dm/i2c.c
index a53e28d..ef88372 100644
--- a/test/dm/i2c.c
+++ b/test/dm/i2c.c
@@ -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 */
diff --git a/test/dm/spi.c b/test/dm/spi.c
index 61b5b25..c7ee652 100644
--- a/test/dm/spi.c
+++ b/test/dm/spi.c
@@ -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,
diff --git a/test/dm/test-dm.sh b/test/dm/test-dm.sh
index bb99677..8ebc392 100755
--- a/test/dm/test-dm.sh
+++ b/test/dm/test-dm.sh
@@ -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
diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c
index cd2c389..b8ee959 100644
--- a/test/dm/test-fdt.c
+++ b/test/dm/test-fdt.c
@@ -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;
}
diff --git a/test/dm/test.dts b/test/dm/test.dts
index fb0272a..84024a4 100644
--- a/test/dm/test.dts
+++ b/test/dm/test.dts
@@ -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 {
@@ -22,6 +30,11 @@
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 {
@@ -81,14 +94,26 @@
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>;
};
diff --git a/test/image/test-imagetools.sh b/test/image/test-imagetools.sh
index 9e299e1..952f975 100755
--- a/test/image/test-imagetools.sh
+++ b/test/image/test-imagetools.sh
@@ -13,9 +13,11 @@
# ./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
diff --git a/tools/Makefile b/tools/Makefile
index e549f8e..6e1ce79 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -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
diff --git a/tools/aisimage.c b/tools/aisimage.c
index 8de370a..9338342 100644
--- a/tools/aisimage.c
+++ b/tools/aisimage.c
@@ -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
+);
diff --git a/tools/atmelimage.c b/tools/atmelimage.c
index c8101d2..5b72ac5 100644
--- a/tools/atmelimage.c
+++ b/tools/atmelimage.c
@@ -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
+);
diff --git a/tools/default_image.c b/tools/default_image.c
index 0a0792e..cf5c0d4 100644
--- a/tools/default_image.c
+++ b/tools/default_image.c
@@ -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
+);
diff --git a/tools/dumpimage.c b/tools/dumpimage.c
index 542ee28..75a5d47 100644
--- a/tools/dumpimage.c
+++ b/tools/dumpimage.c
@@ -12,112 +12,13 @@
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",
diff --git a/tools/fit_image.c b/tools/fit_image.c
index 3ececf9..eb2a25e 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -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 */
+);
diff --git a/tools/gpimage-common.c b/tools/gpimage-common.c
index b343a3a..5ad52be 100644
--- a/tools/gpimage-common.c
+++ b/tools/gpimage-common.c
@@ -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);
diff --git a/tools/gpimage.c b/tools/gpimage.c
index 1cabb5b..1adc55c 100644
--- a/tools/gpimage.c
+++ b/tools/gpimage.c
@@ -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
+);
diff --git a/tools/imagetool.c b/tools/imagetool.c
index 98717bd..148e466 100644
--- a/tools/imagetool.c
+++ b/tools/imagetool.c
@@ -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;
}
diff --git a/tools/imagetool.h b/tools/imagetool.h
index 8bce059..f35dec7 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -19,6 +19,16 @@
#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
index 0000000..7e92b4a
--- /dev/null
+++ b/tools/imagetool.lds
@@ -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;
diff --git a/tools/imximage.c b/tools/imximage.c
index 526b7d4..3d37591 100644
--- a/tools/imximage.c
+++ b/tools/imximage.c
@@ -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
+);
diff --git a/tools/kwbimage.c b/tools/kwbimage.c
index 807d466..66f459a 100644
--- a/tools/kwbimage.c
+++ b/tools/kwbimage.c
@@ -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
+);
diff --git a/tools/mkimage.c b/tools/mkimage.c
index c70408c..5ccd951 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -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",
diff --git a/tools/mxsimage.c b/tools/mxsimage.c
index 04beefe..98fc644 100644
--- a/tools/mxsimage.c
+++ b/tools/mxsimage.c
@@ -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
diff --git a/tools/omapimage.c b/tools/omapimage.c
index 1e0c164..7198b33 100644
--- a/tools/omapimage.c
+++ b/tools/omapimage.c
@@ -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
+);
diff --git a/tools/pblimage.c b/tools/pblimage.c
index 2a799ab..d74fde9 100644
--- a/tools/pblimage.c
+++ b/tools/pblimage.c
@@ -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
+);
diff --git a/tools/socfpgaimage.c b/tools/socfpgaimage.c
index 917873e..8fe91fe 100644
--- a/tools/socfpgaimage.c
+++ b/tools/socfpgaimage.c
@@ -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
+);
diff --git a/tools/ublimage.c b/tools/ublimage.c
index cbbbe20..6ed1eef 100644
--- a/tools/ublimage.c
+++ b/tools/ublimage.c
@@ -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
+);