aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/doc/README.falcon2
-rw-r--r--arch/arm/mach-bcmstb/include/mach/timer.h2
-rw-r--r--arch/arm/mach-rockchip/rk3188-board-spl.c2
-rw-r--r--arch/arm/mach-rockchip/rk3288-board-spl.c2
-rw-r--r--arch/sandbox/config.mk3
-rw-r--r--arch/sandbox/cpu/u-boot.lds9
-rw-r--r--arch/sandbox/dts/test.dts11
-rw-r--r--board/amlogic/nanopi-k2/nanopi-k2.c6
-rw-r--r--board/amlogic/odroid-c2/odroid-c2.c6
-rw-r--r--board/compulab/cm_t3517/cm_t3517.c4
-rw-r--r--cmd/Kconfig9
-rw-r--r--cmd/Makefile1
-rw-r--r--cmd/bind.c255
-rw-r--r--cmd/elf.c5
-rw-r--r--cmd/fastboot.c13
-rw-r--r--common/Kconfig1
-rw-r--r--common/avb_verify.c22
-rw-r--r--common/malloc_simple.c3
-rw-r--r--configs/display5_factory_defconfig2
-rw-r--r--configs/sandbox_defconfig1
-rw-r--r--drivers/core/device-remove.c30
-rw-r--r--drivers/core/device.c19
-rw-r--r--drivers/core/dump.c16
-rw-r--r--drivers/core/uclass.c21
-rw-r--r--drivers/usb/gadget/gadget_chips.h2
-rw-r--r--drivers/usb/musb-new/musb_core.c1
-rw-r--r--drivers/usb/musb-new/musb_uboot.c12
-rw-r--r--drivers/usb/musb-new/omap2430.c596
-rw-r--r--drivers/usb/musb-new/pic32.c6
-rw-r--r--drivers/usb/musb-new/sunxi.c107
-rw-r--r--env/ubi.c1
-rw-r--r--include/configs/display5.h22
-rw-r--r--include/configs/ls1088a_common.h1
-rw-r--r--include/configs/ls2080a_common.h1
-rw-r--r--include/dm/device-internal.h38
-rw-r--r--include/dm/device.h23
-rw-r--r--include/dm/uclass-internal.h11
-rw-r--r--include/dt-bindings/pinctrl/am33xx.h3
-rw-r--r--include/linux/usb/musb.h4
-rw-r--r--lib/libavb/avb_cmdline.c3
-rw-r--r--net/eth-uclass.c3
-rw-r--r--test/dm/test-main.c2
-rw-r--r--test/py/tests/test_bind.py178
43 files changed, 829 insertions, 630 deletions
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.falcon b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.falcon
index 7dae9f03c3..b3c6693a42 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/doc/README.falcon
+++ b/arch/arm/cpu/armv8/fsl-layerscape/doc/README.falcon
@@ -110,7 +110,7 @@ Example:
type = "ramdisk";
arch = "arm64";
os = "linux";
- compression = "gzip";
+ compression = "none";
load = <0xa0000000>;
};
};
diff --git a/arch/arm/mach-bcmstb/include/mach/timer.h b/arch/arm/mach-bcmstb/include/mach/timer.h
index d05b4d64fe..039dd664c2 100644
--- a/arch/arm/mach-bcmstb/include/mach/timer.h
+++ b/arch/arm/mach-bcmstb/include/mach/timer.h
@@ -8,6 +8,6 @@
#ifndef _BCMSTB_TIMER_H
#define _BCMSTB_TIMER_H
-unsigned long timer_read_counter(void);
+uint64_t get_ticks(void);
#endif /* _BCMSTB_TIMER_H */
diff --git a/arch/arm/mach-rockchip/rk3188-board-spl.c b/arch/arm/mach-rockchip/rk3188-board-spl.c
index 59c7e4d4db..98ca971b88 100644
--- a/arch/arm/mach-rockchip/rk3188-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3188-board-spl.c
@@ -49,7 +49,7 @@ u32 spl_boot_device(void)
debug("node=%d\n", node);
goto fallback;
}
- ret = device_get_global_by_of_offset(node, &dev);
+ ret = device_get_global_by_ofnode(offset_to_ofnode(node), &dev);
if (ret) {
debug("device at node %s/%d not found: %d\n", bootdev, node,
ret);
diff --git a/arch/arm/mach-rockchip/rk3288-board-spl.c b/arch/arm/mach-rockchip/rk3288-board-spl.c
index ea6a14af4f..abd62e520f 100644
--- a/arch/arm/mach-rockchip/rk3288-board-spl.c
+++ b/arch/arm/mach-rockchip/rk3288-board-spl.c
@@ -51,7 +51,7 @@ u32 spl_boot_device(void)
debug("node=%d\n", node);
goto fallback;
}
- ret = device_get_global_by_of_offset(node, &dev);
+ ret = device_get_global_by_ofnode(offset_to_ofnode(node), &dev);
if (ret) {
debug("device at node %s/%d not found: %d\n", bootdev, node,
ret);
diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk
index 5e7077bfe7..2babcde881 100644
--- a/arch/sandbox/config.mk
+++ b/arch/sandbox/config.mk
@@ -5,9 +5,6 @@ PLATFORM_CPPFLAGS += -D__SANDBOX__ -U_FORTIFY_SOURCE
PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM
PLATFORM_LIBS += -lrt
-LDFLAGS_FINAL += --gc-sections
-PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
-
# Define this to avoid linking with SDL, which requires SDL libraries
# This can solve 'sdl-config: Command not found' errors
ifneq ($(NO_SDL),)
diff --git a/arch/sandbox/cpu/u-boot.lds b/arch/sandbox/cpu/u-boot.lds
index 40c2214301..6a26c27e8e 100644
--- a/arch/sandbox/cpu/u-boot.lds
+++ b/arch/sandbox/cpu/u-boot.lds
@@ -22,9 +22,8 @@ SECTIONS
}
.efi_runtime : {
- *(.text.efi_runtime*)
- *(.rodata.efi_runtime*)
- *(.data.efi_runtime*)
+ *(efi_runtime_text)
+ *(efi_runtime_data)
}
.__efi_runtime_stop : {
@@ -37,8 +36,8 @@ SECTIONS
}
.efi_runtime_rel : {
- *(.rel*.efi_runtime)
- *(.rel*.efi_runtime.*)
+ *(.relefi_runtime_text)
+ *(.relefi_runtime_data)
}
.efi_runtime_rel_stop :
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 118ff9f685..3668263331 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -61,6 +61,17 @@
reg = <2 1>;
};
+ bind-test {
+ bind-test-child1 {
+ compatible = "sandbox,phy";
+ #phy-cells = <1>;
+ };
+
+ bind-test-child2 {
+ compatible = "simple-bus";
+ };
+ };
+
b-test {
reg = <3 1>;
compatible = "denx,u-boot-fdt-test";
diff --git a/board/amlogic/nanopi-k2/nanopi-k2.c b/board/amlogic/nanopi-k2/nanopi-k2.c
index 339dbb81db..ae29dd6fa4 100644
--- a/board/amlogic/nanopi-k2/nanopi-k2.c
+++ b/board/amlogic/nanopi-k2/nanopi-k2.c
@@ -30,12 +30,6 @@ int misc_init_r(void)
meson_gx_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
- /* Reset PHY on GPIOZ_14 */
- clrbits_le32(GX_GPIO_EN(3), BIT(14));
- clrbits_le32(GX_GPIO_OUT(3), BIT(14));
- mdelay(10);
- setbits_le32(GX_GPIO_OUT(3), BIT(14));
-
if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
mac_addr, EFUSE_MAC_SIZE);
diff --git a/board/amlogic/odroid-c2/odroid-c2.c b/board/amlogic/odroid-c2/odroid-c2.c
index c47b9ce9cb..2a2755c387 100644
--- a/board/amlogic/odroid-c2/odroid-c2.c
+++ b/board/amlogic/odroid-c2/odroid-c2.c
@@ -30,12 +30,6 @@ int misc_init_r(void)
meson_gx_eth_init(PHY_INTERFACE_MODE_RGMII, 0);
- /* Reset PHY on GPIOZ_14 */
- clrbits_le32(GX_GPIO_EN(3), BIT(14));
- clrbits_le32(GX_GPIO_OUT(3), BIT(14));
- mdelay(10);
- setbits_le32(GX_GPIO_OUT(3), BIT(14));
-
if (!eth_env_get_enetaddr("ethaddr", mac_addr)) {
len = meson_sm_read_efuse(EFUSE_MAC_OFFSET,
mac_addr, EFUSE_MAC_SIZE);
diff --git a/board/compulab/cm_t3517/cm_t3517.c b/board/compulab/cm_t3517/cm_t3517.c
index 09cb27def0..668bb7631a 100644
--- a/board/compulab/cm_t3517/cm_t3517.c
+++ b/board/compulab/cm_t3517/cm_t3517.c
@@ -74,8 +74,8 @@ static void cm_t3517_musb_init(void)
CONF2_REFFREQ_13MHZ | CONF2_SESENDEN |
CONF2_VBDTCTEN | CONF2_DATPOL);
- if (musb_register(&cm_t3517_musb_pdata, &cm_t3517_musb_board_data,
- (void *)AM35XX_IPSS_USBOTGSS_BASE))
+ if (!musb_register(&cm_t3517_musb_pdata, &cm_t3517_musb_board_data,
+ (void *)AM35XX_IPSS_USBOTGSS_BASE))
printf("Failed initializing AM35x MUSB!\n");
}
#else
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 51db3da33d..04bdbf0f3b 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -615,6 +615,15 @@ config CMD_ADC
Shows ADC device info and permit printing one-shot analog converted
data from a named Analog to Digital Converter.
+config CMD_BIND
+ bool "bind/unbind - Bind or unbind a device to/from a driver"
+ depends on DM
+ help
+ Bind or unbind a device to/from a driver from the command line.
+ This is useful in situations where a device may be handled by several
+ drivers. For example, this can be used to bind a UDC to the usb ether
+ gadget driver from the command line.
+
config CMD_CLK
bool "clk - Show clock frequencies"
help
diff --git a/cmd/Makefile b/cmd/Makefile
index b1206fca85..3487c80455 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_SOURCE) += source.o
obj-$(CONFIG_CMD_SOURCE) += source.o
obj-$(CONFIG_CMD_BDI) += bdinfo.o
obj-$(CONFIG_CMD_BEDBUG) += bedbug.o
+obj-$(CONFIG_CMD_BIND) += bind.o
obj-$(CONFIG_CMD_BINOP) += binop.o
obj-$(CONFIG_CMD_BLOCK_CACHE) += blkcache.o
obj-$(CONFIG_CMD_BMP) += bmp.o
diff --git a/cmd/bind.c b/cmd/bind.c
new file mode 100644
index 0000000000..44a5f17f0d
--- /dev/null
+++ b/cmd/bind.c
@@ -0,0 +1,255 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2018 JJ Hiblot <jjhiblot@ti.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/uclass-internal.h>
+
+static int bind_by_class_index(const char *uclass, int index,
+ const char *drv_name)
+{
+ static enum uclass_id uclass_id;
+ struct udevice *dev;
+ struct udevice *parent;
+ int ret;
+ struct driver *drv;
+
+ drv = lists_driver_lookup_name(drv_name);
+ if (!drv) {
+ printf("Cannot find driver '%s'\n", drv_name);
+ return -ENOENT;
+ }
+
+ uclass_id = uclass_get_by_name(uclass);
+ if (uclass_id == UCLASS_INVALID) {
+ printf("%s is not a valid uclass\n", uclass);
+ return -EINVAL;
+ }
+
+ ret = uclass_find_device(uclass_id, index, &parent);
+ if (!parent || ret) {
+ printf("Cannot find device %d of class %s\n", index, uclass);
+ return ret;
+ }
+
+ ret = device_bind_with_driver_data(parent, drv, drv->name, 0,
+ ofnode_null(), &dev);
+ if (!dev || ret) {
+ printf("Unable to bind. err:%d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int find_dev(const char *uclass, int index, struct udevice **devp)
+{
+ static enum uclass_id uclass_id;
+ int rc;
+
+ uclass_id = uclass_get_by_name(uclass);
+ if (uclass_id == UCLASS_INVALID) {
+ printf("%s is not a valid uclass\n", uclass);
+ return -EINVAL;
+ }
+
+ rc = uclass_find_device(uclass_id, index, devp);
+ if (!*devp || rc) {
+ printf("Cannot find device %d of class %s\n", index, uclass);
+ return rc;
+ }
+
+ return 0;
+}
+
+static int unbind_by_class_index(const char *uclass, int index)
+{
+ int ret;
+ struct udevice *dev;
+
+ ret = find_dev(uclass, index, &dev);
+ if (ret)
+ return ret;
+
+ ret = device_remove(dev, DM_REMOVE_NORMAL);
+ if (ret) {
+ printf("Unable to remove. err:%d\n", ret);
+ return ret;
+ }
+
+ ret = device_unbind(dev);
+ if (ret) {
+ printf("Unable to unbind. err:%d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int unbind_child_by_class_index(const char *uclass, int index,
+ const char *drv_name)
+{
+ struct udevice *parent;
+ int ret;
+ struct driver *drv;
+
+ drv = lists_driver_lookup_name(drv_name);
+ if (!drv) {
+ printf("Cannot find driver '%s'\n", drv_name);
+ return -ENOENT;
+ }
+
+ ret = find_dev(uclass, index, &parent);
+ if (ret)
+ return ret;
+
+ ret = device_chld_remove(parent, drv, DM_REMOVE_NORMAL);
+ if (ret)
+ printf("Unable to remove all. err:%d\n", ret);
+
+ ret = device_chld_unbind(parent, drv);
+ if (ret)
+ printf("Unable to unbind all. err:%d\n", ret);
+
+ return ret;
+}
+
+static int bind_by_node_path(const char *path, const char *drv_name)
+{
+ struct udevice *dev;
+ struct udevice *parent = NULL;
+ int ret;
+ ofnode ofnode;
+ struct driver *drv;
+
+ drv = lists_driver_lookup_name(drv_name);
+ if (!drv) {
+ printf("%s is not a valid driver name\n", drv_name);
+ return -ENOENT;
+ }
+
+ ofnode = ofnode_path(path);
+ if (!ofnode_valid(ofnode)) {
+ printf("%s is not a valid node path\n", path);
+ return -EINVAL;
+ }
+
+ while (ofnode_valid(ofnode)) {
+ if (!device_find_global_by_ofnode(ofnode, &parent))
+ break;
+ ofnode = ofnode_get_parent(ofnode);
+ }
+
+ if (!parent) {
+ printf("Cannot find a parent device for node path %s\n", path);
+ return -ENODEV;
+ }
+
+ ofnode = ofnode_path(path);
+ ret = device_bind_with_driver_data(parent, drv, ofnode_get_name(ofnode),
+ 0, ofnode, &dev);
+ if (!dev || ret) {
+ printf("Unable to bind. err:%d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int unbind_by_node_path(const char *path)
+{
+ struct udevice *dev;
+ int ret;
+ ofnode ofnode;
+
+ ofnode = ofnode_path(path);
+ if (!ofnode_valid(ofnode)) {
+ printf("%s is not a valid node path\n", path);
+ return -EINVAL;
+ }
+
+ ret = device_find_global_by_ofnode(ofnode, &dev);
+
+ if (!dev || ret) {
+ printf("Cannot find a device with path %s\n", path);
+ return -ENODEV;
+ }
+
+ ret = device_remove(dev, DM_REMOVE_NORMAL);
+ if (ret) {
+ printf("Unable to remove. err:%d\n", ret);
+ return ret;
+ }
+
+ ret = device_unbind(dev);
+ if (ret) {
+ printf("Unable to unbind. err:%d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int do_bind_unbind(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ int ret = 0;
+ bool bind;
+ bool by_node;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ bind = (argv[0][0] == 'b');
+ by_node = (argv[1][0] == '/');
+
+ if (by_node && bind) {
+ if (argc != 3)
+ return CMD_RET_USAGE;
+ ret = bind_by_node_path(argv[1], argv[2]);
+ } else if (by_node && !bind) {
+ if (argc != 2)
+ return CMD_RET_USAGE;
+ ret = unbind_by_node_path(argv[1]);
+ } else if (!by_node && bind) {
+ int index = (argc > 2) ? simple_strtoul(argv[2], NULL, 10) : 0;
+
+ if (argc != 4)
+ return CMD_RET_USAGE;
+ ret = bind_by_class_index(argv[1], index, argv[3]);
+ } else if (!by_node && !bind) {
+ int index = (argc > 2) ? simple_strtoul(argv[2], NULL, 10) : 0;
+
+ if (argc == 3)
+ ret = unbind_by_class_index(argv[1], index);
+ else if (argc == 4)
+ ret = unbind_child_by_class_index(argv[1], index,
+ argv[3]);
+ else
+ return CMD_RET_USAGE;
+ }
+
+ if (ret)
+ return CMD_RET_FAILURE;
+ else
+ return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(
+ bind, 4, 0, do_bind_unbind,
+ "Bind a device to a driver",
+ "<node path> <driver>\n"
+ "bind <class> <index> <driver>\n"
+);
+
+U_BOOT_CMD(
+ unbind, 4, 0, do_bind_unbind,
+ "Unbind a device from a driver",
+ "<node path>\n"
+ "unbind <class> <index>\n"
+ "unbind <class> <index> <driver>\n"
+);
diff --git a/cmd/elf.c b/cmd/elf.c
index 22cba58c68..c8e6e7424c 100644
--- a/cmd/elf.c
+++ b/cmd/elf.c
@@ -115,7 +115,10 @@ static unsigned long load_elf64_image_shdr(unsigned long addr)
memcpy((void *)(uintptr_t)shdr->sh_addr,
(const void *)image, shdr->sh_size);
}
- flush_cache((ulong)shdr->sh_addr, shdr->sh_size);
+ flush_cache(rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN),
+ roundup((shdr->sh_addr + shdr->sh_size),
+ ARCH_DMA_MINALIGN) -
+ rounddown(shdr->sh_addr, ARCH_DMA_MINALIGN));
}
if (ehdr->e_machine == EM_PPC64 && (ehdr->e_flags &
diff --git a/cmd/fastboot.c b/cmd/fastboot.c
index e6ae0570d5..ae3a5f627f 100644
--- a/cmd/fastboot.c
+++ b/cmd/fastboot.c
@@ -38,13 +38,18 @@ static int do_fastboot_usb(int argc, char *const argv[],
#if CONFIG_IS_ENABLED(USB_FUNCTION_FASTBOOT)
int controller_index;
char *usb_controller;
+ char *endp;
int ret;
if (argc < 2)
return CMD_RET_USAGE;
usb_controller = argv[1];
- controller_index = simple_strtoul(usb_controller, NULL, 0);
+ controller_index = simple_strtoul(usb_controller, &endp, 0);
+ if (*endp != '\0') {
+ pr_err("Error: Wrong USB controller index format\n");
+ return CMD_RET_FAILURE;
+ }
ret = board_usb_init(controller_index, USB_INIT_DEVICE);
if (ret) {
@@ -120,6 +125,12 @@ NXTARG:
;
}
+ /* Handle case when USB controller param is just '-' */
+ if (argc == 1) {
+ pr_err("Error: Incorrect USB controller index\n");
+ return CMD_RET_USAGE;
+ }
+
fastboot_init((void *)buf_addr, buf_size);
if (!strcmp(argv[1], "udp"))
diff --git a/common/Kconfig b/common/Kconfig
index b3d9b37463..3030da4fc9 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -647,6 +647,7 @@ config HASH
config AVB_VERIFY
bool "Build Android Verified Boot operations"
depends on LIBAVB && FASTBOOT
+ depends on PARTITION_UUIDS
help
This option enables compilation of bootloader-dependent operations,
used by Android Verified Boot 2.0 library (libavb). Includes:
diff --git a/common/avb_verify.c b/common/avb_verify.c
index 82ddebcfc2..f8c6ae5566 100644
--- a/common/avb_verify.c
+++ b/common/avb_verify.c
@@ -11,7 +11,7 @@
#include <malloc.h>
#include <part.h>
-const unsigned char avb_root_pub[1032] = {
+static const unsigned char avb_root_pub[1032] = {
0x0, 0x0, 0x10, 0x0, 0x55, 0xd9, 0x4, 0xad, 0xd8, 0x4,
0xaf, 0xe3, 0xd3, 0x84, 0x6c, 0x7e, 0xd, 0x89, 0x3d, 0xc2,
0x8c, 0xd3, 0x12, 0x55, 0xe9, 0x62, 0xc9, 0xf1, 0xf, 0x5e,
@@ -176,7 +176,7 @@ static int avb_find_dm_args(char **args, char *str)
if (!str)
return -1;
- for (i = 0; i < AVB_MAX_ARGS, args[i]; ++i) {
+ for (i = 0; i < AVB_MAX_ARGS && args[i]; ++i) {
if (strstr(args[i], str))
return i;
}
@@ -348,34 +348,37 @@ static struct mmc_part *get_partition(AvbOps *ops, const char *partition)
part->mmc = find_mmc_device(dev_num);
if (!part->mmc) {
printf("No MMC device at slot %x\n", dev_num);
- return NULL;
+ goto err;
}
if (mmc_init(part->mmc)) {
printf("MMC initialization failed\n");
- return NULL;
+ goto err;
}
ret = mmc_switch_part(part->mmc, part_num);
if (ret)
- return NULL;
+ goto err;
mmc_blk = mmc_get_blk_desc(part->mmc);
if (!mmc_blk) {
printf("Error - failed to obtain block descriptor\n");
- return NULL;
+ goto err;
}
ret = part_get_info_by_name(mmc_blk, partition, &part->info);
if (!ret) {
printf("Can't find partition '%s'\n", partition);
- return NULL;
+ goto err;
}
part->dev_num = dev_num;
part->mmc_blk = mmc_blk;
return part;
+err:
+ free(part);
+ return NULL;
}
static AvbIOResult mmc_byte_io(AvbOps *ops,
@@ -399,6 +402,9 @@ static AvbIOResult mmc_byte_io(AvbOps *ops,
if (!part)
return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
+ if (!part->info.blksz)
+ return AVB_IO_RESULT_ERROR_IO;
+
start_offset = calc_offset(part, offset);
while (num_bytes) {
start_sector = start_offset / part->info.blksz;
@@ -763,7 +769,7 @@ void avb_ops_free(AvbOps *ops)
{
struct AvbOpsData *ops_data;
- if (ops)
+ if (!ops)
return;
ops_data = ops->user_data;
diff --git a/common/malloc_simple.c b/common/malloc_simple.c
index c14f8b59c1..871b5444bd 100644
--- a/common/malloc_simple.c
+++ b/common/malloc_simple.c
@@ -57,7 +57,8 @@ void *calloc(size_t nmemb, size_t elem_size)
void *ptr;
ptr = malloc(size);
- memset(ptr, '\0', size);
+ if (ptr)
+ memset(ptr, '\0', size);
return ptr;
}
diff --git a/configs/display5_factory_defconfig b/configs/display5_factory_defconfig
index edb37c3b2f..5962b642b2 100644
--- a/configs/display5_factory_defconfig
+++ b/configs/display5_factory_defconfig
@@ -15,7 +15,7 @@ CONFIG_OF_BOARD_SETUP=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg,MX6Q"
CONFIG_BOOTDELAY=3
CONFIG_USE_BOOTCOMMAND=y
-CONFIG_BOOTCOMMAND="run factory"
+CONFIG_BOOTCOMMAND="echo SDP Display5 recovery"
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_MISC_INIT_R=y
# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index c72374ed9a..96e9514936 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -34,6 +34,7 @@ CONFIG_CMD_MD5SUM=y
CONFIG_CMD_MEMINFO=y
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_MX_CYCLIC=y
+CONFIG_CMD_BIND=y
CONFIG_CMD_DEMO=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
index 1cf2278e9e..586fadee0a 100644
--- a/drivers/core/device-remove.c
+++ b/drivers/core/device-remove.c
@@ -17,16 +17,7 @@
#include <dm/uclass-internal.h>
#include <dm/util.h>
-/**
- * device_chld_unbind() - Unbind all device's children from the device
- *
- * On error, the function continues to unbind all children, and reports the
- * first error.
- *
- * @dev: The device that is to be stripped of its children
- * @return 0 on success, -ve on error
- */
-static int device_chld_unbind(struct udevice *dev)
+int device_chld_unbind(struct udevice *dev, struct driver *drv)
{
struct udevice *pos, *n;
int ret, saved_ret = 0;
@@ -34,6 +25,9 @@ static int device_chld_unbind(struct udevice *dev)
assert(dev);
list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
+ if (drv && (pos->driver != drv))
+ continue;
+
ret = device_unbind(pos);
if (ret && !saved_ret)
saved_ret = ret;
@@ -42,13 +36,8 @@ static int device_chld_unbind(struct udevice *dev)
return saved_ret;
}
-/**
- * device_chld_remove() - Stop all device's children
- * @dev: The device whose children are to be removed
- * @pre_os_remove: Flag, if this functions is called in the pre-OS stage
- * @return 0 on success, -ve on error
- */
-static int device_chld_remove(struct udevice *dev, uint flags)
+int device_chld_remove(struct udevice *dev, struct driver *drv,
+ uint flags)
{
struct udevice *pos, *n;
int ret;
@@ -56,6 +45,9 @@ static int device_chld_remove(struct udevice *dev, uint flags)
assert(dev);
list_for_each_entry_safe(pos, n, &dev->child_head, sibling_node) {
+ if (drv && (pos->driver != drv))
+ continue;
+
ret = device_remove(pos, flags);
if (ret)
return ret;
@@ -87,7 +79,7 @@ int device_unbind(struct udevice *dev)
return ret;
}
- ret = device_chld_unbind(dev);
+ ret = device_chld_unbind(dev, NULL);
if (ret)
return ret;
@@ -178,7 +170,7 @@ int device_remove(struct udevice *dev, uint flags)
if (ret)
return ret;
- ret = device_chld_remove(dev, flags);
+ ret = device_chld_remove(dev, NULL, flags);
if (ret)
goto err;
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 207d566b71..fd59fe1e0f 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -594,16 +594,16 @@ int device_get_child_by_of_offset(struct udevice *parent, int node,
return device_get_device_tail(dev, ret, devp);
}
-static struct udevice *_device_find_global_by_of_offset(struct udevice *parent,
- int of_offset)
+static struct udevice *_device_find_global_by_ofnode(struct udevice *parent,
+ ofnode ofnode)
{
struct udevice *dev, *found;
- if (dev_of_offset(parent) == of_offset)
+ if (ofnode_equal(dev_ofnode(parent), ofnode))
return parent;
list_for_each_entry(dev, &parent->child_head, sibling_node) {
- found = _device_find_global_by_of_offset(dev, of_offset);
+ found = _device_find_global_by_ofnode(dev, ofnode);
if (found)
return found;
}
@@ -611,11 +611,18 @@ static struct udevice *_device_find_global_by_of_offset(struct udevice *parent,
return NULL;
}
-int device_get_global_by_of_offset(int of_offset, struct udevice **devp)
+int device_find_global_by_ofnode(ofnode ofnode, struct udevice **devp)
+{
+ *devp = _device_find_global_by_ofnode(gd->dm_root, ofnode);
+
+ return *devp ? 0 : -ENOENT;
+}
+
+int device_get_global_by_ofnode(ofnode ofnode, struct udevice **devp)
{
struct udevice *dev;
- dev = _device_find_global_by_of_offset(gd->dm_root, of_offset);
+ dev = _device_find_global_by_ofnode(gd->dm_root, ofnode);
return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
}
diff --git a/drivers/core/dump.c b/drivers/core/dump.c
index 58820cdb2f..d7cdb1475d 100644
--- a/drivers/core/dump.c
+++ b/drivers/core/dump.c
@@ -8,6 +8,7 @@
#include <mapmem.h>
#include <dm/root.h>
#include <dm/util.h>
+#include <dm/uclass-internal.h>
static void show_devices(struct udevice *dev, int depth, int last_flag)
{
@@ -15,7 +16,8 @@ static void show_devices(struct udevice *dev, int depth, int last_flag)
struct udevice *child;
/* print the first 11 characters to not break the tree-format. */
- printf(" %-10.10s [ %c ] %-10.10s ", dev->uclass->uc_drv->name,
+ printf(" %-10.10s %d [ %c ] %-10.10s ", dev->uclass->uc_drv->name,
+ dev_get_uclass_index(dev, NULL),
dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name);
for (i = depth; i >= 0; i--) {
@@ -47,8 +49,8 @@ void dm_dump_all(void)
root = dm_root();
if (root) {
- printf(" Class Probed Driver Name\n");
- printf("----------------------------------------\n");
+ printf(" Class index Probed Driver Name\n");
+ printf("-----------------------------------------\n");
show_devices(root, -1, 0);
}
}
@@ -60,9 +62,9 @@ void dm_dump_all(void)
*
* @dev: Device to display
*/
-static void dm_display_line(struct udevice *dev)
+static void dm_display_line(struct udevice *dev, int index)
{
- printf("- %c %s @ %08lx",
+ printf("%i %c %s @ %08lx", index,
dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
dev->name, (ulong)map_to_sysmem(dev));
if (dev->seq != -1 || dev->req_seq != -1)
@@ -78,6 +80,7 @@ void dm_dump_uclass(void)
for (id = 0; id < UCLASS_COUNT; id++) {
struct udevice *dev;
+ int i = 0;
ret = uclass_get(id, &uc);
if (ret)
@@ -87,7 +90,8 @@ void dm_dump_uclass(void)
if (list_empty(&uc->dev_head))
continue;
list_for_each_entry(dev, &uc->dev_head, uclass_node) {
- dm_display_line(dev);
+ dm_display_line(dev, i);
+ i++;
}
puts("\n");
}
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index d609b170e1..3113d6a56b 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -171,6 +171,27 @@ enum uclass_id uclass_get_by_name(const char *name)
return UCLASS_INVALID;
}
+int dev_get_uclass_index(struct udevice *dev, struct uclass **ucp)
+{
+ struct udevice *iter;
+ struct uclass *uc = dev->uclass;
+ int i = 0;
+
+ if (list_empty(&uc->dev_head))
+ return -ENODEV;
+
+ list_for_each_entry(iter, &uc->dev_head, uclass_node) {
+ if (iter == dev) {
+ if (ucp)
+ *ucp = uc;
+ return i;
+ }
+ i++;
+ }
+
+ return -ENODEV;
+}
+
int uclass_find_device(enum uclass_id id, int index, struct udevice **devp)
{
struct uclass *uc;
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h
index b9b081999a..2c8f235d51 100644
--- a/drivers/usb/gadget/gadget_chips.h
+++ b/drivers/usb/gadget/gadget_chips.h
@@ -206,5 +206,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget)
return 0x21;
else if (gadget_is_fotg210(gadget))
return 0x22;
+ else if (gadget_is_dwc3(gadget))
+ return 0x23;
return -ENOENT;
}
diff --git a/drivers/usb/musb-new/musb_core.c b/drivers/usb/musb-new/musb_core.c
index 8fec6f38ad..afea9fbcef 100644
--- a/drivers/usb/musb-new/musb_core.c
+++ b/drivers/usb/musb-new/musb_core.c
@@ -1007,6 +1007,7 @@ void musb_stop(struct musb *musb)
* - ...
*/
musb_platform_try_idle(musb, 0);
+ musb_platform_exit(musb);
}
#ifndef __UBOOT__
diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 2b04fbd046..2bf918eab4 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -419,8 +419,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
}
#endif /* CONFIG_USB_MUSB_GADGET */
-int musb_register(struct musb_hdrc_platform_data *plat, void *bdata,
- void *ctl_regs)
+struct musb *musb_register(struct musb_hdrc_platform_data *plat, void *bdata,
+ void *ctl_regs)
{
struct musb **musbp;
@@ -436,14 +436,14 @@ int musb_register(struct musb_hdrc_platform_data *plat, void *bdata,
break;
#endif
default:
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
}
*musbp = musb_init_controller(plat, (struct device *)bdata, ctl_regs);
- if (!*musbp) {
+ if (IS_ERR(*musbp)) {
printf("Failed to init the controller\n");
- return -EIO;
+ return ERR_CAST(*musbp);
}
- return 0;
+ return *musbp;
}
diff --git a/drivers/usb/musb-new/omap2430.c b/drivers/usb/musb-new/omap2430.c
index 4753d79ede..342d76bd6f 100644
--- a/drivers/usb/musb-new/omap2430.c
+++ b/drivers/usb/musb-new/omap2430.c
@@ -8,201 +8,19 @@
*
* This file is part of the Inventra Controller Driver for Linux.
*/
-#ifndef __UBOOT__
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/pm_runtime.h>
-#include <linux/err.h>
-#include <linux/usb/musb-omap.h>
-#else
#include <common.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <linux/usb/otg.h>
#include <asm/omap_common.h>
#include <asm/omap_musb.h>
#include <twl4030.h>
#include <twl6030.h>
#include "linux-compat.h"
-#endif
-
#include "musb_core.h"
#include "omap2430.h"
-
-#ifndef __UBOOT__
-struct omap2430_glue {
- struct device *dev;
- struct platform_device *musb;
- enum omap_musb_vbus_id_status status;
- struct work_struct omap_musb_mailbox_work;
-};
-#define glue_to_musb(g) platform_get_drvdata(g->musb)
-
-struct omap2430_glue *_glue;
-
-static struct timer_list musb_idle_timer;
-
-static void musb_do_idle(unsigned long _musb)
-{
- struct musb *musb = (void *)_musb;
- unsigned long flags;
- u8 power;
- u8 devctl;
-
- spin_lock_irqsave(&musb->lock, flags);
-
- switch (musb->xceiv->state) {
- case OTG_STATE_A_WAIT_BCON:
-
- devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
- if (devctl & MUSB_DEVCTL_BDEVICE) {
- musb->xceiv->state = OTG_STATE_B_IDLE;
- MUSB_DEV_MODE(musb);
- } else {
- musb->xceiv->state = OTG_STATE_A_IDLE;
- MUSB_HST_MODE(musb);
- }
- break;
- case OTG_STATE_A_SUSPEND:
- /* finish RESUME signaling? */
- if (musb->port1_status & MUSB_PORT_STAT_RESUME) {
- power = musb_readb(musb->mregs, MUSB_POWER);
- power &= ~MUSB_POWER_RESUME;
- dev_dbg(musb->controller, "root port resume stopped, power %02x\n", power);
- musb_writeb(musb->mregs, MUSB_POWER, power);
- musb->is_active = 1;
- musb->port1_status &= ~(USB_PORT_STAT_SUSPEND
- | MUSB_PORT_STAT_RESUME);
- musb->port1_status |= USB_PORT_STAT_C_SUSPEND << 16;
- usb_hcd_poll_rh_status(musb_to_hcd(musb));
- /* NOTE: it might really be A_WAIT_BCON ... */
- musb->xceiv->state = OTG_STATE_A_HOST;
- }
- break;
- case OTG_STATE_A_HOST:
- devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
- if (devctl & MUSB_DEVCTL_BDEVICE)
- musb->xceiv->state = OTG_STATE_B_IDLE;
- else
- musb->xceiv->state = OTG_STATE_A_WAIT_BCON;
- default:
- break;
- }
- spin_unlock_irqrestore(&musb->lock, flags);
-}
-
-
-static void omap2430_musb_try_idle(struct musb *musb, unsigned long timeout)
-{
- unsigned long default_timeout = jiffies + msecs_to_jiffies(3);
- static unsigned long last_timer;
-
- if (timeout == 0)
- timeout = default_timeout;
-
- /* Never idle if active, or when VBUS timeout is not set as host */
- if (musb->is_active || ((musb->a_wait_bcon == 0)
- && (musb->xceiv->state == OTG_STATE_A_WAIT_BCON))) {
- dev_dbg(musb->controller, "%s active, deleting timer\n",
- otg_state_string(musb->xceiv->state));
- del_timer(&musb_idle_timer);
- last_timer = jiffies;
- return;
- }
-
- if (time_after(last_timer, timeout)) {
- if (!timer_pending(&musb_idle_timer))
- last_timer = timeout;
- else {
- dev_dbg(musb->controller, "Longer idle timer already pending, ignoring\n");
- return;
- }
- }
- last_timer = timeout;
-
- dev_dbg(musb->controller, "%s inactive, for idle timer for %lu ms\n",
- otg_state_string(musb->xceiv->state),
- (unsigned long)jiffies_to_msecs(timeout - jiffies));
- mod_timer(&musb_idle_timer, timeout);
-}
-
-static void omap2430_musb_set_vbus(struct musb *musb, int is_on)
-{
- struct usb_otg *otg = musb->xceiv->otg;
- u8 devctl;
- unsigned long timeout = jiffies + msecs_to_jiffies(1000);
- int ret = 1;
- /* HDRC controls CPEN, but beware current surges during device
- * connect. They can trigger transient overcurrent conditions
- * that must be ignored.
- */
-
- devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
-
- if (is_on) {
- if (musb->xceiv->state == OTG_STATE_A_IDLE) {
- /* start the session */
- devctl |= MUSB_DEVCTL_SESSION;
- musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
- /*
- * Wait for the musb to set as A device to enable the
- * VBUS
- */
- while (musb_readb(musb->mregs, MUSB_DEVCTL) & 0x80) {
-
- cpu_relax();
-
- if (time_after(jiffies, timeout)) {
- dev_err(musb->controller,
- "configured as A device timeout");
- ret = -EINVAL;
- break;
- }
- }
-
- if (ret && otg->set_vbus)
- otg_set_vbus(otg, 1);
- } else {
- musb->is_active = 1;
- otg->default_a = 1;
- musb->xceiv->state = OTG_STATE_A_WAIT_VRISE;
- devctl |= MUSB_DEVCTL_SESSION;
- MUSB_HST_MODE(musb);
- }
- } else {
- musb->is_active = 0;
-
- /* NOTE: we're skipping A_WAIT_VFALL -> A_IDLE and
- * jumping right to B_IDLE...
- */
-
- otg->default_a = 0;
- musb->xceiv->state = OTG_STATE_B_IDLE;
- devctl &= ~MUSB_DEVCTL_SESSION;
-
- MUSB_DEV_MODE(musb);
- }
- musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
-
- dev_dbg(musb->controller, "VBUS %s, devctl %02x "
- /* otg %3x conf %08x prcm %08x */ "\n",
- otg_state_string(musb->xceiv->state),
- musb_readb(musb->mregs, MUSB_DEVCTL));
-}
-
-static int omap2430_musb_set_mode(struct musb *musb, u8 musb_mode)
-{
- u8 devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
-
- devctl |= MUSB_DEVCTL_SESSION;
- musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
-
- return 0;
-}
-#endif
+#include "musb_uboot.h"
static inline void omap2430_low_level_exit(struct musb *musb)
{
@@ -223,100 +41,15 @@ static inline void omap2430_low_level_init(struct musb *musb)
musb_writel(musb->mregs, OTG_FORCESTDBY, l);
}
-#ifndef __UBOOT__
-void omap_musb_mailbox(enum omap_musb_vbus_id_status status)
-{
- struct omap2430_glue *glue = _glue;
- struct musb *musb = glue_to_musb(glue);
-
- glue->status = status;
- if (!musb) {
- dev_err(glue->dev, "musb core is not yet ready\n");
- return;
- }
-
- schedule_work(&glue->omap_musb_mailbox_work);
-}
-EXPORT_SYMBOL_GPL(omap_musb_mailbox);
-
-static void omap_musb_set_mailbox(struct omap2430_glue *glue)
-{
- struct musb *musb = glue_to_musb(glue);
- struct device *dev = musb->controller;
- struct musb_hdrc_platform_data *pdata = dev->platform_data;
- struct omap_musb_board_data *data = pdata->board_data;
- struct usb_otg *otg = musb->xceiv->otg;
-
- switch (glue->status) {
- case OMAP_MUSB_ID_GROUND:
- dev_dbg(dev, "ID GND\n");
-
- otg->default_a = true;
- musb->xceiv->state = OTG_STATE_A_IDLE;
- musb->xceiv->last_event = USB_EVENT_ID;
- if (!is_otg_enabled(musb) || musb->gadget_driver) {
- pm_runtime_get_sync(dev);
- usb_phy_init(musb->xceiv);
- omap2430_musb_set_vbus(musb, 1);
- }
- break;
-
- case OMAP_MUSB_VBUS_VALID:
- dev_dbg(dev, "VBUS Connect\n");
-
- otg->default_a = false;
- musb->xceiv->state = OTG_STATE_B_IDLE;
- musb->xceiv->last_event = USB_EVENT_VBUS;
- if (musb->gadget_driver)
- pm_runtime_get_sync(dev);
- usb_phy_init(musb->xceiv);
- break;
-
- case OMAP_MUSB_ID_FLOAT:
- case OMAP_MUSB_VBUS_OFF:
- dev_dbg(dev, "VBUS Disconnect\n");
-
- musb->xceiv->last_event = USB_EVENT_NONE;
- if (is_otg_enabled(musb) || is_peripheral_enabled(musb))
- if (musb->gadget_driver) {
- pm_runtime_mark_last_busy(dev);
- pm_runtime_put_autosuspend(dev);
- }
-
- if (data->interface_type == MUSB_INTERFACE_UTMI) {
- if (musb->xceiv->otg->set_vbus)
- otg_set_vbus(musb->xceiv->otg, 0);
- }
- usb_phy_shutdown(musb->xceiv);
- break;
- default:
- dev_dbg(dev, "ID float\n");
- }
-}
-
-
-static void omap_musb_mailbox_work(struct work_struct *mailbox_work)
-{
- struct omap2430_glue *glue = container_of(mailbox_work,
- struct omap2430_glue, omap_musb_mailbox_work);
- omap_musb_set_mailbox(glue);
-}
-#endif
static int omap2430_musb_init(struct musb *musb)
{
u32 l;
int status = 0;
unsigned long int start;
-#ifndef __UBOOT__
- struct device *dev = musb->controller;
- struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
- struct musb_hdrc_platform_data *plat = dev->platform_data;
- struct omap_musb_board_data *data = plat->board_data;
-#else
+
struct omap_musb_board_data *data =
(struct omap_musb_board_data *)musb->controller;
-#endif
/* Reset the controller */
musb_writel(musb->mregs, OTG_SYSCONFIG, SOFTRST);
@@ -334,24 +67,6 @@ static int omap2430_musb_init(struct musb *musb)
}
}
-#ifndef __UBOOT__
- /* We require some kind of external transceiver, hooked
- * up through ULPI. TWL4030-family PMICs include one,
- * which needs a driver, drivers aren't always needed.
- */
- musb->xceiv = devm_usb_get_phy(dev, USB_PHY_TYPE_USB2);
- if (IS_ERR_OR_NULL(musb->xceiv)) {
- pr_err("HS USB OTG: no transceiver configured\n");
- return -ENODEV;
- }
-
- status = pm_runtime_get_sync(dev);
- if (status < 0) {
- dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
- goto err1;
- }
-#endif
-
l = musb_readl(musb->mregs, OTG_INTERFSEL);
if (data->interface_type == MUSB_INTERFACE_UTMI) {
@@ -371,64 +86,14 @@ static int omap2430_musb_init(struct musb *musb)
musb_readl(musb->mregs, OTG_SYSSTATUS),
musb_readl(musb->mregs, OTG_INTERFSEL),
musb_readl(musb->mregs, OTG_SIMENABLE));
-
-#ifndef __UBOOT__
- setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
-
- if (glue->status != OMAP_MUSB_UNKNOWN)
- omap_musb_set_mailbox(glue);
-
- pm_runtime_put_noidle(musb->controller);
-#endif
return 0;
err1:
return status;
}
-#ifndef __UBOOT__
-static void omap2430_musb_enable(struct musb *musb)
-#else
static int omap2430_musb_enable(struct musb *musb)
-#endif
{
-#ifndef __UBOOT__
- u8 devctl;
- unsigned long timeout = jiffies + msecs_to_jiffies(1000);
- struct device *dev = musb->controller;
- struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
- struct musb_hdrc_platform_data *pdata = dev->platform_data;
- struct omap_musb_board_data *data = pdata->board_data;
-
- switch (glue->status) {
-
- case OMAP_MUSB_ID_GROUND:
- usb_phy_init(musb->xceiv);
- if (data->interface_type != MUSB_INTERFACE_UTMI)
- break;
- devctl = musb_readb(musb->mregs, MUSB_DEVCTL);
- /* start the session */
- devctl |= MUSB_DEVCTL_SESSION;
- musb_writeb(musb->mregs, MUSB_DEVCTL, devctl);
- while (musb_readb(musb->mregs, MUSB_DEVCTL) &
- MUSB_DEVCTL_BDEVICE) {
- cpu_relax();
-
- if (time_after(jiffies, timeout)) {
- dev_err(dev, "configured as A device timeout");
- break;
- }
- }
- break;
-
- case OMAP_MUSB_VBUS_VALID:
- usb_phy_init(musb->xceiv);
- break;
-
- default:
- break;
- }
-#else
#ifdef CONFIG_TWL4030_USB
if (twl4030_usb_ulpi_init()) {
serial_printf("ERROR: %s Could not initialize PHY\n",
@@ -447,18 +112,11 @@ static int omap2430_musb_enable(struct musb *musb)
#endif
return 0;
-#endif
}
static void omap2430_musb_disable(struct musb *musb)
{
-#ifndef __UBOOT__
- struct device *dev = musb->controller;
- struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
- if (glue->status != OMAP_MUSB_UNKNOWN)
- usb_phy_shutdown(musb->xceiv);
-#endif
}
static int omap2430_musb_exit(struct musb *musb)
@@ -470,174 +128,152 @@ static int omap2430_musb_exit(struct musb *musb)
return 0;
}
-#ifndef __UBOOT__
-static const struct musb_platform_ops omap2430_ops = {
-#else
const struct musb_platform_ops omap2430_ops = {
-#endif
.init = omap2430_musb_init,
.exit = omap2430_musb_exit,
-
-#ifndef __UBOOT__
- .set_mode = omap2430_musb_set_mode,
- .try_idle = omap2430_musb_try_idle,
-
- .set_vbus = omap2430_musb_set_vbus,
-#endif
-
.enable = omap2430_musb_enable,
.disable = omap2430_musb_disable,
};
-#ifndef __UBOOT__
-static u64 omap2430_dmamask = DMA_BIT_MASK(32);
+#if defined(CONFIG_DM_USB)
+
+struct omap2430_musb_platdata {
+ void *base;
+ void *ctrl_mod_base;
+ struct musb_hdrc_platform_data plat;
+ struct musb_hdrc_config musb_config;
+ struct omap_musb_board_data otg_board_data;
+};
-static int __devinit omap2430_probe(struct platform_device *pdev)
+static int omap2430_musb_ofdata_to_platdata(struct udevice *dev)
{
- struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data;
- struct platform_device *musb;
- struct omap2430_glue *glue;
- int ret = -ENOMEM;
-
- glue = devm_kzalloc(&pdev->dev, sizeof(*glue), GFP_KERNEL);
- if (!glue) {
- dev_err(&pdev->dev, "failed to allocate glue context\n");
- goto err0;
+ struct omap2430_musb_platdata *platdata = dev_get_platdata(dev);
+ const void *fdt = gd->fdt_blob;
+ int node = dev_of_offset(dev);
+
+ platdata->base = (void *)dev_read_addr_ptr(dev);
+
+ platdata->musb_config.multipoint = fdtdec_get_int(fdt, node,
+ "multipoint",
+ -1);
+ if (platdata->musb_config.multipoint < 0) {
+ pr_err("MUSB multipoint DT entry missing\n");
+ return -ENOENT;
}
- musb = platform_device_alloc("musb-hdrc", -1);
- if (!musb) {
- dev_err(&pdev->dev, "failed to allocate musb device\n");
- goto err0;
+ platdata->musb_config.dyn_fifo = 1;
+ platdata->musb_config.num_eps = fdtdec_get_int(fdt, node,
+ "num-eps", -1);
+ if (platdata->musb_config.num_eps < 0) {
+ pr_err("MUSB num-eps DT entry missing\n");
+ return -ENOENT;
}
- musb->dev.parent = &pdev->dev;
- musb->dev.dma_mask = &omap2430_dmamask;
- musb->dev.coherent_dma_mask = omap2430_dmamask;
-
- glue->dev = &pdev->dev;
- glue->musb = musb;
- glue->status = OMAP_MUSB_UNKNOWN;
-
- pdata->platform_ops = &omap2430_ops;
-
- platform_set_drvdata(pdev, glue);
-
- /*
- * REVISIT if we ever have two instances of the wrapper, we will be
- * in big trouble
- */
- _glue = glue;
-
- INIT_WORK(&glue->omap_musb_mailbox_work, omap_musb_mailbox_work);
-
- ret = platform_device_add_resources(musb, pdev->resource,
- pdev->num_resources);
- if (ret) {
- dev_err(&pdev->dev, "failed to add resources\n");
- goto err1;
+ platdata->musb_config.ram_bits = fdtdec_get_int(fdt, node,
+ "ram-bits", -1);
+ if (platdata->musb_config.ram_bits < 0) {
+ pr_err("MUSB ram-bits DT entry missing\n");
+ return -ENOENT;
}
- ret = platform_device_add_data(musb, pdata, sizeof(*pdata));
- if (ret) {
- dev_err(&pdev->dev, "failed to add platform_data\n");
- goto err1;
+ platdata->plat.power = fdtdec_get_int(fdt, node,
+ "power", -1);
+ if (platdata->plat.power < 0) {
+ pr_err("MUSB power DT entry missing\n");
+ return -ENOENT;
}
- pm_runtime_enable(&pdev->dev);
-
- ret = platform_device_add(musb);
- if (ret) {
- dev_err(&pdev->dev, "failed to register musb device\n");
- goto err1;
+ platdata->otg_board_data.interface_type = fdtdec_get_int(fdt, node,
+ "interface-type", -1);
+ if (platdata->otg_board_data.interface_type < 0) {
+ pr_err("MUSB interface-type DT entry missing\n");
+ return -ENOENT;
}
- return 0;
-
-err1:
- platform_device_put(musb);
-
-err0:
- return ret;
-}
-
-static int __devexit omap2430_remove(struct platform_device *pdev)
-{
- struct omap2430_glue *glue = platform_get_drvdata(pdev);
-
- cancel_work_sync(&glue->omap_musb_mailbox_work);
- platform_device_del(glue->musb);
- platform_device_put(glue->musb);
-
+#if 0 /* In a perfect world, mode would be set to OTG, mode 3 from DT */
+ platdata->plat.mode = fdtdec_get_int(fdt, node,
+ "mode", -1);
+ if (platdata->plat.mode < 0) {
+ pr_err("MUSB mode DT entry missing\n");
+ return -ENOENT;
+ }
+#else /* MUSB_OTG, it doesn't work */
+#ifdef CONFIG_USB_MUSB_HOST /* Host seems to be the only option that works */
+ platdata->plat.mode = MUSB_HOST;
+#else /* For that matter, MUSB_PERIPHERAL doesn't either */
+ platdata->plat.mode = MUSB_PERIPHERAL;
+#endif
+#endif
+ platdata->otg_board_data.dev = dev;
+ platdata->plat.config = &platdata->musb_config;
+ platdata->plat.platform_ops = &omap2430_ops;
+ platdata->plat.board_data = &platdata->otg_board_data;
return 0;
}
-#ifdef CONFIG_PM
-
-static int omap2430_runtime_suspend(struct device *dev)
+static int omap2430_musb_probe(struct udevice *dev)
{
- struct omap2430_glue *glue = dev_get_drvdata(dev);
- struct musb *musb = glue_to_musb(glue);
-
- if (musb) {
- musb->context.otg_interfsel = musb_readl(musb->mregs,
- OTG_INTERFSEL);
-
- omap2430_low_level_exit(musb);
- usb_phy_set_suspend(musb->xceiv, 1);
+#ifdef CONFIG_USB_MUSB_HOST
+ struct musb_host_data *host = dev_get_priv(dev);
+#endif
+ struct omap2430_musb_platdata *platdata = dev_get_platdata(dev);
+ struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
+ struct omap_musb_board_data *otg_board_data;
+ int ret;
+ void *base = dev_read_addr_ptr(dev);
+
+ priv->desc_before_addr = true;
+
+ otg_board_data = &platdata->otg_board_data;
+
+#ifdef CONFIG_USB_MUSB_HOST
+ host->host = musb_init_controller(&platdata->plat,
+ (struct device *)otg_board_data,
+ platdata->base);
+ if (!host->host) {
+ return -EIO;
}
- return 0;
+ ret = musb_lowlevel_init(host);
+#else
+ ret = musb_register(&platdata->plat,
+ (struct device *)otg_board_data,
+ platdata->base);
+#endif
+ return ret;
}
-static int omap2430_runtime_resume(struct device *dev)
+static int omap2430_musb_remove(struct udevice *dev)
{
- struct omap2430_glue *glue = dev_get_drvdata(dev);
- struct musb *musb = glue_to_musb(glue);
+ struct musb_host_data *host = dev_get_priv(dev);
- if (musb) {
- omap2430_low_level_init(musb);
- musb_writel(musb->mregs, OTG_INTERFSEL,
- musb->context.otg_interfsel);
-
- usb_phy_set_suspend(musb->xceiv, 0);
- }
+ musb_stop(host->host);
return 0;
}
-static struct dev_pm_ops omap2430_pm_ops = {
- .runtime_suspend = omap2430_runtime_suspend,
- .runtime_resume = omap2430_runtime_resume,
+static const struct udevice_id omap2430_musb_ids[] = {
+ { .compatible = "ti,omap3-musb" },
+ { .compatible = "ti,omap4-musb" },
+ { }
};
-#define DEV_PM_OPS (&omap2430_pm_ops)
+U_BOOT_DRIVER(omap2430_musb) = {
+ .name = "omap2430-musb",
+#ifdef CONFIG_USB_MUSB_HOST
+ .id = UCLASS_USB,
#else
-#define DEV_PM_OPS NULL
+ .id = UCLASS_USB_DEV_GENERIC,
#endif
-
-static struct platform_driver omap2430_driver = {
- .probe = omap2430_probe,
- .remove = __devexit_p(omap2430_remove),
- .driver = {
- .name = "musb-omap2430",
- .pm = DEV_PM_OPS,
- },
+ .of_match = omap2430_musb_ids,
+ .ofdata_to_platdata = omap2430_musb_ofdata_to_platdata,
+ .probe = omap2430_musb_probe,
+ .remove = omap2430_musb_remove,
+#ifdef CONFIG_USB_MUSB_HOST
+ .ops = &musb_usb_ops,
+#endif
+ .platdata_auto_alloc_size = sizeof(struct omap2430_musb_platdata),
+ .priv_auto_alloc_size = sizeof(struct musb_host_data),
};
-MODULE_DESCRIPTION("OMAP2PLUS MUSB Glue Layer");
-MODULE_AUTHOR("Felipe Balbi <balbi@ti.com>");
-MODULE_LICENSE("GPL v2");
-
-static int __init omap2430_init(void)
-{
- return platform_driver_register(&omap2430_driver);
-}
-subsys_initcall(omap2430_init);
-
-static void __exit omap2430_exit(void)
-{
- platform_driver_unregister(&omap2430_driver);
-}
-module_exit(omap2430_exit);
-#endif
+#endif /* CONFIG_DM_USB */
diff --git a/drivers/usb/musb-new/pic32.c b/drivers/usb/musb-new/pic32.c
index f04719d7af..3a19900e21 100644
--- a/drivers/usb/musb-new/pic32.c
+++ b/drivers/usb/musb-new/pic32.c
@@ -251,9 +251,11 @@ static int musb_usb_probe(struct udevice *dev)
ret = musb_lowlevel_init(mdata);
#else
pic32_musb_plat.mode = MUSB_PERIPHERAL;
- ret = musb_register(&pic32_musb_plat, &pdata->dev, mregs);
+ mdata->host = musb_register(&pic32_musb_plat, &pdata->dev, mregs);
+ if (!mdata->host)
+ return -EIO;
#endif
- if (ret == 0)
+ if ((ret == 0) && mdata->host)
printf("PIC32 MUSB OTG\n");
return ret;
diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c
index 08de9c69c7..6cf9826cda 100644
--- a/drivers/usb/musb-new/sunxi.c
+++ b/drivers/usb/musb-new/sunxi.c
@@ -76,18 +76,23 @@
* From usbc/usbc.c
******************************************************************************/
+#define OFF_SUN6I_AHB_RESET0 0x2c0
+
struct sunxi_musb_config {
struct musb_hdrc_config *config;
+ bool has_reset;
u8 rst_bit;
u8 clkgate_bit;
+ u32 off_reset0;
};
struct sunxi_glue {
struct musb_host_data mdata;
struct sunxi_ccm_reg *ccm;
+ u32 *reg_reset0;
struct sunxi_musb_config *cfg;
struct device dev;
- struct phy *phy;
+ struct phy phy;
};
#define to_sunxi_glue(d) container_of(d, struct sunxi_glue, dev)
@@ -235,19 +240,19 @@ static int sunxi_musb_enable(struct musb *musb)
musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0);
if (is_host_enabled(musb)) {
- ret = sun4i_usb_phy_vbus_detect(glue->phy);
+ ret = sun4i_usb_phy_vbus_detect(&glue->phy);
if (ret == 1) {
printf("A charger is plugged into the OTG: ");
return -ENODEV;
}
- ret = sun4i_usb_phy_id_detect(glue->phy);
+ ret = sun4i_usb_phy_id_detect(&glue->phy);
if (ret == 1) {
printf("No host cable detected: ");
return -ENODEV;
}
- ret = generic_phy_power_on(glue->phy);
+ ret = generic_phy_power_on(&glue->phy);
if (ret) {
pr_err("failed to power on USB PHY\n");
return ret;
@@ -271,7 +276,7 @@ static void sunxi_musb_disable(struct musb *musb)
return;
if (is_host_enabled(musb)) {
- ret = generic_phy_power_off(glue->phy);
+ ret = generic_phy_power_off(&glue->phy);
if (ret) {
pr_err("failed to power off USB PHY\n");
return;
@@ -291,7 +296,7 @@ static int sunxi_musb_init(struct musb *musb)
pr_debug("%s():\n", __func__);
- ret = generic_phy_init(glue->phy);
+ ret = generic_phy_init(&glue->phy);
if (ret) {
pr_err("failed to init USB PHY\n");
return ret;
@@ -303,12 +308,12 @@ static int sunxi_musb_init(struct musb *musb)
if (glue->cfg->clkgate_bit)
setbits_le32(&glue->ccm->ahb_gate0,
BIT(glue->cfg->clkgate_bit));
-#ifdef CONFIG_SUNXI_GEN_SUN6I
- setbits_le32(&glue->ccm->ahb_reset0_cfg, BIT(AHB_GATE_OFFSET_USB0));
+
+ if (glue->cfg->has_reset)
+ setbits_le32(glue->reg_reset0, BIT(AHB_GATE_OFFSET_USB0));
+
if (glue->cfg->rst_bit)
- setbits_le32(&glue->ccm->ahb_reset0_cfg,
- BIT(glue->cfg->rst_bit));
-#endif
+ setbits_le32(glue->reg_reset0, BIT(glue->cfg->rst_bit));
USBC_ConfigFIFO_Base();
USBC_EnableDpDmPullUp(musb->mregs);
@@ -326,22 +331,50 @@ static int sunxi_musb_init(struct musb *musb)
return 0;
}
+static int sunxi_musb_exit(struct musb *musb)
+{
+ struct sunxi_glue *glue = to_sunxi_glue(musb->controller);
+ int ret = 0;
+
+ if (generic_phy_valid(&glue->phy)) {
+ ret = generic_phy_exit(&glue->phy);
+ if (ret) {
+ dev_err(dev, "failed to power off usb phy\n");
+ return ret;
+ }
+ }
+
+ if (glue->cfg->has_reset)
+ clrbits_le32(glue->reg_reset0, BIT(AHB_GATE_OFFSET_USB0));
+
+ if (glue->cfg->rst_bit)
+ clrbits_le32(glue->reg_reset0, BIT(glue->cfg->rst_bit));
+
+ clrbits_le32(&glue->ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_USB0));
+ if (glue->cfg->clkgate_bit)
+ clrbits_le32(&glue->ccm->ahb_gate0,
+ BIT(glue->cfg->clkgate_bit));
+
+ return 0;
+}
+
static void sunxi_musb_pre_root_reset_end(struct musb *musb)
{
struct sunxi_glue *glue = to_sunxi_glue(musb->controller);
- sun4i_usb_phy_set_squelch_detect(glue->phy, false);
+ sun4i_usb_phy_set_squelch_detect(&glue->phy, false);
}
static void sunxi_musb_post_root_reset_end(struct musb *musb)
{
struct sunxi_glue *glue = to_sunxi_glue(musb->controller);
- sun4i_usb_phy_set_squelch_detect(glue->phy, true);
+ sun4i_usb_phy_set_squelch_detect(&glue->phy, true);
}
static const struct musb_platform_ops sunxi_musb_ops = {
.init = sunxi_musb_init,
+ .exit = sunxi_musb_exit,
.enable = sunxi_musb_enable,
.disable = sunxi_musb_disable,
.pre_root_reset_end = sunxi_musb_pre_root_reset_end,
@@ -405,7 +438,6 @@ static int musb_usb_probe(struct udevice *dev)
struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
struct musb_hdrc_platform_data pdata;
void *base = dev_read_addr_ptr(dev);
- struct phy phy;
int ret;
if (!base)
@@ -419,13 +451,14 @@ static int musb_usb_probe(struct udevice *dev)
if (IS_ERR(glue->ccm))
return PTR_ERR(glue->ccm);
- ret = generic_phy_get_by_name(dev, "usb", &phy);
+ glue->reg_reset0 = (void *)glue->ccm + glue->cfg->off_reset0;
+
+ ret = generic_phy_get_by_name(dev, "usb", &glue->phy);
if (ret) {
pr_err("failed to get usb PHY\n");
return ret;
}
- glue->phy = &phy;
priv->desc_before_addr = true;
memset(&pdata, 0, sizeof(pdata));
@@ -444,9 +477,11 @@ static int musb_usb_probe(struct udevice *dev)
printf("Allwinner mUSB OTG (Host)\n");
#else
pdata.mode = MUSB_PERIPHERAL;
- ret = musb_register(&pdata, &glue->dev, base);
- if (!ret)
- printf("Allwinner mUSB OTG (Peripheral)\n");
+ host->host = musb_register(&pdata, &glue->dev, base);
+ if (!host->host)
+ return -EIO;
+
+ printf("Allwinner mUSB OTG (Peripheral)\n");
#endif
return ret;
@@ -456,29 +491,8 @@ static int musb_usb_remove(struct udevice *dev)
{
struct sunxi_glue *glue = dev_get_priv(dev);
struct musb_host_data *host = &glue->mdata;
- int ret;
-
- if (generic_phy_valid(glue->phy)) {
- ret = generic_phy_exit(glue->phy);
- if (ret) {
- pr_err("failed to exit %s USB PHY\n", dev->name);
- return ret;
- }
- }
musb_stop(host->host);
-
-#ifdef CONFIG_SUNXI_GEN_SUN6I
- clrbits_le32(&glue->ccm->ahb_reset0_cfg, BIT(AHB_GATE_OFFSET_USB0));
- if (glue->cfg->rst_bit)
- clrbits_le32(&glue->ccm->ahb_reset0_cfg,
- BIT(glue->cfg->rst_bit));
-#endif
- clrbits_le32(&glue->ccm->ahb_gate0, BIT(AHB_GATE_OFFSET_USB0));
- if (glue->cfg->clkgate_bit)
- clrbits_le32(&glue->ccm->ahb_gate0,
- BIT(glue->cfg->clkgate_bit));
-
free(host->host);
host->host = NULL;
@@ -487,21 +501,30 @@ static int musb_usb_remove(struct udevice *dev)
static const struct sunxi_musb_config sun4i_a10_cfg = {
.config = &musb_config,
+ .has_reset = false,
+};
+
+static const struct sunxi_musb_config sun6i_a31_cfg = {
+ .config = &musb_config,
+ .has_reset = true,
+ .off_reset0 = OFF_SUN6I_AHB_RESET0,
};
static const struct sunxi_musb_config sun8i_h3_cfg = {
.config = &musb_config_h3,
+ .has_reset = true,
.rst_bit = 23,
.clkgate_bit = 23,
+ .off_reset0 = OFF_SUN6I_AHB_RESET0,
};
static const struct udevice_id sunxi_musb_ids[] = {
{ .compatible = "allwinner,sun4i-a10-musb",
.data = (ulong)&sun4i_a10_cfg },
{ .compatible = "allwinner,sun6i-a31-musb",
- .data = (ulong)&sun4i_a10_cfg },
+ .data = (ulong)&sun6i_a31_cfg },
{ .compatible = "allwinner,sun8i-a33-musb",
- .data = (ulong)&sun4i_a10_cfg },
+ .data = (ulong)&sun6i_a31_cfg },
{ .compatible = "allwinner,sun8i-h3-musb",
.data = (ulong)&sun8i_h3_cfg },
{ }
diff --git a/env/ubi.c b/env/ubi.c
index eb2346f3a1..1dfdf0a8c8 100644
--- a/env/ubi.c
+++ b/env/ubi.c
@@ -168,6 +168,7 @@ static int env_ubi_load(void)
U_BOOT_ENV_LOCATION(ubi) = {
.location = ENVL_UBI,
+ ENV_NAME("UBI")
.load = env_ubi_load,
.save = env_save_ptr(env_ubi_save),
};
diff --git a/include/configs/display5.h b/include/configs/display5.h
index 514638f684..6d00699ebd 100644
--- a/include/configs/display5.h
+++ b/include/configs/display5.h
@@ -115,27 +115,6 @@
"name=rootfs2,size=512M,uuid=${uuid_gpt_rootfs2};" \
"name=data,size=-,uuid=${uuid_gpt_data}\0"
-#define FACTORY_PROCEDURE \
- "echo '#######################';" \
- "echo '# Factory Boot #';" \
- "echo '#######################';" \
- "env default -a;" \
- "saveenv;" \
- "gpt write mmc ${mmcdev} ${partitions};" \
- "run tftp_sf_SPL;" \
- "run tftp_sf_uboot;" \
- TFTP_UPDATE_KERNEL \
- "run tftp_sf_fitImg_SWU;" \
- "run tftp_sf_initramfs_SWU;" \
- TFTP_UPDATE_ROOTFS \
- "echo '#######################';" \
- "echo '# END - OK #';" \
- "echo '#######################';" \
- "setenv bootcmd 'env default -a; saveenv; run falcon_setup; reset';" \
- "setenv boot_os 'n';" \
- "saveenv;" \
- "reset;"
-
#define SWUPDATE_RECOVERY_PROCEDURE \
"echo '#######################';" \
"echo '# RECOVERY SWUupdate #';" \
@@ -261,7 +240,6 @@
"bootdelay=1\0" \
"baudrate=115200\0" \
"bootcmd=" CONFIG_BOOTCOMMAND "\0" \
- "factory=" FACTORY_PROCEDURE "\0" \
"ethact=FEC\0" \
"netdev=eth0\0" \
"boot_os=y\0" \
diff --git a/include/configs/ls1088a_common.h b/include/configs/ls1088a_common.h
index 2d6a5fc3d4..822fd76cc5 100644
--- a/include/configs/ls1088a_common.h
+++ b/include/configs/ls1088a_common.h
@@ -222,6 +222,7 @@ unsigned long long get_qixis_addr(void);
#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv8/u-boot-spl.lds"
#define CONFIG_SPL_MAX_SIZE 0x16000
#define CONFIG_SPL_STACK (CONFIG_SYS_FSL_OCRAM_BASE + 0x9ff0)
+#define CONFIG_SPL_TARGET "u-boot-with-spl.bin"
#define CONFIG_SPL_TEXT_BASE 0x1800a000
#define CONFIG_SYS_SPL_MALLOC_SIZE 0x00100000
diff --git a/include/configs/ls2080a_common.h b/include/configs/ls2080a_common.h
index e756844c6a..713e1d1d09 100644
--- a/include/configs/ls2080a_common.h
+++ b/include/configs/ls2080a_common.h
@@ -204,6 +204,7 @@ unsigned long long get_qixis_addr(void);
#define CONFIG_SPL_BSS_MAX_SIZE 0x00100000
#define CONFIG_SPL_MAX_SIZE 0x16000
#define CONFIG_SPL_STACK (CONFIG_SYS_FSL_OCRAM_BASE + 0x9ff0)
+#define CONFIG_SPL_TARGET "u-boot-with-spl.bin"
#define CONFIG_SPL_TEXT_BASE 0x1800a000
#ifdef CONFIG_NAND_BOOT
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index f4af15448f..02ac4c7952 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -131,6 +131,44 @@ static inline void device_free(struct udevice *dev) {}
#endif
/**
+ * device_chld_unbind() - Unbind all device's children from the device if bound
+ * to drv
+ *
+ * On error, the function continues to unbind all children, and reports the
+ * first error.
+ *
+ * @dev: The device that is to be stripped of its children
+ * @drv: The targeted driver
+ * @return 0 on success, -ve on error
+ */
+#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
+int device_chld_unbind(struct udevice *dev, struct driver *drv);
+#else
+static inline int device_chld_unbind(struct udevice *dev, struct driver *drv)
+{
+ return 0;
+}
+#endif
+
+/**
+ * device_chld_remove() - Stop all device's children
+ * @dev: The device whose children are to be removed
+ * @drv: The targeted driver
+ * @flags: Flag, if this functions is called in the pre-OS stage
+ * @return 0 on success, -ve on error
+ */
+#if CONFIG_IS_ENABLED(DM_DEVICE_REMOVE)
+int device_chld_remove(struct udevice *dev, struct driver *drv,
+ uint flags);
+#else
+static inline int device_chld_remove(struct udevice *dev, struct driver *drv,
+ uint flags)
+{
+ return 0;
+}
+#endif
+
+/**
* simple_bus_translate() - translate a bus address to a system address
*
* This handles the 'ranges' property in a simple bus. It translates the
diff --git a/include/dm/device.h b/include/dm/device.h
index 49078bc6b3..3120b68fcc 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -473,18 +473,33 @@ int device_get_child_by_of_offset(struct udevice *parent, int of_offset,
struct udevice **devp);
/**
- * device_get_global_by_of_offset() - Get a device based on FDT offset
+ * device_find_global_by_ofnode() - Get a device based on ofnode
*
- * Locates a device by its device tree offset, searching globally throughout
+ * Locates a device by its device tree ofnode, searching globally throughout
+ * the all driver model devices.
+ *
+ * The device is NOT probed
+ *
+ * @node: Device tree ofnode to find
+ * @devp: Returns pointer to device if found, otherwise this is set to NULL
+ * @return 0 if OK, -ve on error
+ */
+
+int device_find_global_by_ofnode(ofnode node, struct udevice **devp);
+
+/**
+ * device_get_global_by_ofnode() - Get a device based on ofnode
+ *
+ * Locates a device by its device tree ofnode, searching globally throughout
* the all driver model devices.
*
* The device is probed to activate it ready for use.
*
- * @of_offset: Device tree offset to find
+ * @node: Device tree ofnode to find
* @devp: Returns pointer to device if found, otherwise this is set to NULL
* @return 0 if OK, -ve on error
*/
-int device_get_global_by_of_offset(int of_offset, struct udevice **devp);
+int device_get_global_by_ofnode(ofnode node, struct udevice **devp);
/**
* device_find_first_child() - Find the first child of a device
diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h
index 7ba064bd53..30d5a4fb9b 100644
--- a/include/dm/uclass-internal.h
+++ b/include/dm/uclass-internal.h
@@ -24,6 +24,17 @@
int uclass_get_device_tail(struct udevice *dev, int ret, struct udevice **devp);
/**
+ * dev_get_uclass_index() - Get uclass and index of device
+ * @dev: - in - Device that we want the uclass/index of
+ * @ucp: - out - A pointer to the uclass the device belongs to
+ *
+ * The device is not prepared for use - this is an internal function.
+ *
+ * @return the index of the device in the uclass list or -ENODEV if not found.
+ */
+int dev_get_uclass_index(struct udevice *dev, struct uclass **ucp);
+
+/**
* uclass_find_device() - Return n-th child of uclass
* @id: Id number of the uclass
* @index: Position of the child in uclass's list
diff --git a/include/dt-bindings/pinctrl/am33xx.h b/include/dt-bindings/pinctrl/am33xx.h
index 2fbc804e1a..226f77246a 100644
--- a/include/dt-bindings/pinctrl/am33xx.h
+++ b/include/dt-bindings/pinctrl/am33xx.h
@@ -13,7 +13,8 @@
#define PULL_DISABLE (1 << 3)
#define INPUT_EN (1 << 5)
-#define SLEWCTRL_FAST (1 << 6)
+#define SLEWCTRL_SLOW (1 << 6)
+#define SLEWCTRL_FAST 0
/* update macro depending on INPUT_EN and PULL_ENA */
#undef PIN_OUTPUT
diff --git a/include/linux/usb/musb.h b/include/linux/usb/musb.h
index 9104414cf0..a31ce67a81 100644
--- a/include/linux/usb/musb.h
+++ b/include/linux/usb/musb.h
@@ -150,7 +150,7 @@ extern int tusb6010_platform_retime(unsigned is_refclk);
/*
* U-Boot specfic stuff
*/
-int musb_register(struct musb_hdrc_platform_data *plat, void *bdata,
- void *ctl_regs);
+struct musb *musb_register(struct musb_hdrc_platform_data *plat, void *bdata,
+ void *ctl_regs);
#endif /* __LINUX_USB_MUSB_H */
diff --git a/lib/libavb/avb_cmdline.c b/lib/libavb/avb_cmdline.c
index 91a6615c74..d246699272 100644
--- a/lib/libavb/avb_cmdline.c
+++ b/lib/libavb/avb_cmdline.c
@@ -331,6 +331,9 @@ AvbSlotVerifyResult avb_append_options(
verity_mode = "logging";
dm_verity_mode = "ignore_corruption";
break;
+ default:
+ ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT;
+ goto out;
}
new_ret = avb_replace(
slot_data->cmdline, "$(ANDROID_VERITY_MODE)", dm_verity_mode);
diff --git a/net/eth-uclass.c b/net/eth-uclass.c
index fa3f5497a2..91d861be41 100644
--- a/net/eth-uclass.c
+++ b/net/eth-uclass.c
@@ -312,7 +312,8 @@ void eth_halt(void)
eth_get_ops(current)->stop(current);
priv = current->uclass_priv;
- priv->state = ETH_STATE_PASSIVE;
+ if (priv)
+ priv->state = ETH_STATE_PASSIVE;
}
int eth_is_active(struct udevice *dev)
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index 4def795c79..5d79ce641d 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -94,7 +94,7 @@ static int dm_do_test(struct unit_test_state *uts, struct unit_test *test,
ut_assertok(dm_extended_scan_fdt(gd->fdt_blob, false));
/*
- * Silence the console and rely on console reocrding to get
+ * Silence the console and rely on console recording to get
* our output.
*/
console_record_reset();
diff --git a/test/py/tests/test_bind.py b/test/py/tests/test_bind.py
new file mode 100644
index 0000000000..f21b7059ea
--- /dev/null
+++ b/test/py/tests/test_bind.py
@@ -0,0 +1,178 @@
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
+
+import os.path
+import pytest
+import re
+
+def in_tree(response, name, uclass, drv, depth, last_child):
+ lines = [x.strip() for x in response.splitlines()]
+ leaf = ' ' * 4 * depth;
+ if not last_child:
+ leaf = leaf + '\|'
+ else:
+ leaf = leaf + '`'
+ leaf = leaf + '-- ' + name
+ line = ' *{:10.10} [0-9]* \[ [ +] \] {:10.10} {}$'.format(uclass, drv,leaf)
+ prog = re.compile(line)
+ for l in lines:
+ if prog.match(l):
+ return True
+ return False
+
+
+@pytest.mark.buildconfigspec('cmd_bind')
+def test_bind_unbind_with_node(u_boot_console):
+
+ #bind /bind-test. Device should come up as well as its children
+ response = u_boot_console.run_command("bind /bind-test generic_simple_bus")
+ assert response == ''
+ tree = u_boot_console.run_command("dm tree")
+ assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
+ assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False)
+ assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
+
+ #Unbind child #1. No error expected and all devices should be there except for bind-test-child1
+ response = u_boot_console.run_command("unbind /bind-test/bind-test-child1")
+ assert response == ''
+ tree = u_boot_console.run_command("dm tree")
+ assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
+ assert "bind-test-child1" not in tree
+ assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
+
+ #bind child #1. No error expected and all devices should be there
+ response = u_boot_console.run_command("bind /bind-test/bind-test-child1 phy_sandbox")
+ assert response == ''
+ tree = u_boot_console.run_command("dm tree")
+ assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
+ assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, True)
+ assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, False)
+
+ #Unbind child #2. No error expected and all devices should be there except for bind-test-child2
+ response = u_boot_console.run_command("unbind /bind-test/bind-test-child2")
+ assert response == ''
+ tree = u_boot_console.run_command("dm tree")
+ assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
+ assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, True)
+ assert "bind-test-child2" not in tree
+
+
+ #Bind child #2. No error expected and all devices should be there
+ response = u_boot_console.run_command("bind /bind-test/bind-test-child2 generic_simple_bus")
+ assert response == ''
+ tree = u_boot_console.run_command("dm tree")
+ assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
+ assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False)
+ assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
+
+ #Unbind parent. No error expected. All devices should be removed and unbound
+ response = u_boot_console.run_command("unbind /bind-test")
+ assert response == ''
+ tree = u_boot_console.run_command("dm tree")
+ assert "bind-test" not in tree
+ assert "bind-test-child1" not in tree
+ assert "bind-test-child2" not in tree
+
+ #try binding invalid node with valid driver
+ response = u_boot_console.run_command("bind /not-a-valid-node generic_simple_bus")
+ assert response != ''
+ tree = u_boot_console.run_command("dm tree")
+ assert "not-a-valid-node" not in tree
+
+ #try binding valid node with invalid driver
+ response = u_boot_console.run_command("bind /bind-test not_a_driver")
+ assert response != ''
+ tree = u_boot_console.run_command("dm tree")
+ assert "bind-test" not in tree
+
+ #bind /bind-test. Device should come up as well as its children
+ response = u_boot_console.run_command("bind /bind-test generic_simple_bus")
+ assert response == ''
+ tree = u_boot_console.run_command("dm tree")
+ assert in_tree(tree, "bind-test", "simple_bus", "generic_simple", 0, True)
+ assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False)
+ assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
+
+ response = u_boot_console.run_command("unbind /bind-test")
+ assert response == ''
+
+def get_next_line(tree, name):
+ treelines = [x.strip() for x in tree.splitlines() if x.strip()]
+ child_line = ""
+ for idx, line in enumerate(treelines):
+ if ("-- " + name) in line:
+ try:
+ child_line = treelines[idx+1]
+ except:
+ pass
+ break
+ return child_line
+
+@pytest.mark.buildconfigspec('cmd_bind')
+def test_bind_unbind_with_uclass(u_boot_console):
+ #bind /bind-test
+ response = u_boot_console.run_command("bind /bind-test generic_simple_bus")
+ assert response == ''
+
+ #make sure bind-test-child2 is there and get its uclass/index pair
+ tree = u_boot_console.run_command("dm tree")
+ child2_line = [x.strip() for x in tree.splitlines() if "-- bind-test-child2" in x]
+ assert len(child2_line) == 1
+
+ child2_uclass = child2_line[0].split()[0]
+ child2_index = int(child2_line[0].split()[1])
+
+ #bind generic_simple_bus as a child of bind-test-child2
+ response = u_boot_console.run_command("bind {} {} generic_simple_bus".format(child2_uclass, child2_index, "generic_simple_bus"))
+
+ #check that the child is there and its uclass/index pair is right
+ tree = u_boot_console.run_command("dm tree")
+
+ child_of_child2_line = get_next_line(tree, "bind-test-child2")
+ assert child_of_child2_line
+ child_of_child2_index = int(child_of_child2_line.split()[1])
+ assert in_tree(tree, "generic_simple_bus", "simple_bus", "generic_simple_bus", 2, True)
+ assert child_of_child2_index == child2_index + 1
+
+ #unbind the child and check it has been removed
+ response = u_boot_console.run_command("unbind simple_bus {}".format(child_of_child2_index))
+ assert response == ''
+ tree = u_boot_console.run_command("dm tree")
+ assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
+ assert not in_tree(tree, "generic_simple_bus", "simple_bus", "generic_simple_bus", 2, True)
+ child_of_child2_line = get_next_line(tree, "bind-test-child2")
+ assert child_of_child2_line == ""
+
+ #bind generic_simple_bus as a child of bind-test-child2
+ response = u_boot_console.run_command("bind {} {} generic_simple_bus".format(child2_uclass, child2_index, "generic_simple_bus"))
+
+ #check that the child is there and its uclass/index pair is right
+ tree = u_boot_console.run_command("dm tree")
+ treelines = [x.strip() for x in tree.splitlines() if x.strip()]
+
+ child_of_child2_line = get_next_line(tree, "bind-test-child2")
+ assert child_of_child2_line
+ child_of_child2_index = int(child_of_child2_line.split()[1])
+ assert in_tree(tree, "generic_simple_bus", "simple_bus", "generic_simple_bus", 2, True)
+ assert child_of_child2_index == child2_index + 1
+
+ #unbind the child and check it has been removed
+ response = u_boot_console.run_command("unbind {} {} generic_simple_bus".format(child2_uclass, child2_index, "generic_simple_bus"))
+ assert response == ''
+
+ tree = u_boot_console.run_command("dm tree")
+ assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple", 1, True)
+
+ child_of_child2_line = get_next_line(tree, "bind-test-child2")
+ assert child_of_child2_line == ""
+
+ #unbind the child again and check it doesn't change the tree
+ tree_old = u_boot_console.run_command("dm tree")
+ response = u_boot_console.run_command("unbind {} {} generic_simple_bus".format(child2_uclass, child2_index, "generic_simple_bus"))
+ tree_new = u_boot_console.run_command("dm tree")
+
+ assert response == ''
+ assert tree_old == tree_new
+
+ response = u_boot_console.run_command("unbind /bind-test")
+ assert response == ''