summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/lib/Makefile2
-rw-r--r--arch/arm/mach-rockchip/Kconfig3
-rw-r--r--arch/arm/mach-rockchip/rk3036/reset_rk3036.c20
-rw-r--r--arch/arm/mach-rockchip/rk3288/reset_rk3288.c20
-rw-r--r--arch/arm/mach-snapdragon/reset.c18
-rw-r--r--arch/sandbox/cpu/state.c4
-rw-r--r--arch/sandbox/dts/test.dts11
-rw-r--r--arch/sandbox/include/asm/mbox.h21
-rw-r--r--arch/sandbox/include/asm/state.h6
-rw-r--r--cmd/mmc.c62
-rw-r--r--common/env_mmc.c8
-rw-r--r--common/spl/spl_mmc.c9
-rw-r--r--configs/chromebook_jerry_defconfig2
-rw-r--r--configs/dragonboard410c_defconfig2
-rw-r--r--configs/evb-rk3036_defconfig2
-rw-r--r--configs/firefly-rk3288_defconfig4
-rw-r--r--configs/kylin-rk3036_defconfig2
-rw-r--r--configs/odroid-c2_defconfig1
-rw-r--r--configs/rock2_defconfig2
-rw-r--r--configs/sandbox_defconfig5
-rw-r--r--configs/sandbox_noblk_defconfig2
-rw-r--r--doc/device-tree-bindings/mailbox/mailbox.txt32
-rw-r--r--doc/driver-model/README.txt23
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/clk/clk_rk3036.c2
-rw-r--r--drivers/clk/clk_rk3288.c2
-rw-r--r--drivers/core/device.c25
-rw-r--r--drivers/core/lists.c4
-rw-r--r--drivers/gpio/sunxi_gpio.c90
-rw-r--r--drivers/mailbox/Kconfig20
-rw-r--r--drivers/mailbox/Makefile7
-rw-r--r--drivers/mailbox/mailbox-uclass.c145
-rw-r--r--drivers/mailbox/sandbox-mbox-test.c54
-rw-r--r--drivers/mailbox/sandbox-mbox.c104
-rw-r--r--drivers/misc/Kconfig10
-rw-r--r--drivers/misc/Makefile4
-rw-r--r--drivers/misc/reset_sandbox.c100
-rw-r--r--drivers/misc/sysreset-uclass.c (renamed from drivers/misc/reset-uclass.c)32
-rw-r--r--drivers/misc/sysreset_sandbox.c101
-rw-r--r--drivers/mmc/dw_mmc.c42
-rw-r--r--drivers/mmc/mmc.c13
-rw-r--r--drivers/mmc/mmc_private.h14
-rw-r--r--drivers/mmc/rockchip_dw_mmc.c31
-rw-r--r--drivers/mmc/sdhci.c2
-rw-r--r--drivers/video/rockchip/rk_vop.c1
-rw-r--r--include/configs/rk3288_common.h1
-rw-r--r--include/configs/rpi.h1
-rw-r--r--include/dm/device-internal.h24
-rw-r--r--include/dm/uclass-id.h3
-rw-r--r--include/dwmmc.h7
-rw-r--r--include/efi_loader.h2
-rw-r--r--include/mailbox_client.h149
-rw-r--r--include/mailbox_uclass.h83
-rw-r--r--include/mmc.h5
-rw-r--r--include/reset.h71
-rw-r--r--include/sysreset.h71
-rw-r--r--lib/efi_loader/efi_disk.c66
-rw-r--r--lib/tiny-printf.c43
-rw-r--r--test/dm/Makefile3
-rw-r--r--test/dm/mailbox.c31
-rw-r--r--test/dm/reset.c74
-rw-r--r--test/dm/sysreset.c74
-rw-r--r--tools/rkimage.c7
64 files changed, 1272 insertions, 510 deletions
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 7a0fb5862e..b535dbef49 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -46,7 +46,7 @@ obj-y += interrupts_64.o
else
obj-y += interrupts.o
endif
-ifndef CONFIG_RESET
+ifndef CONFIG_SYSRESET
obj-y += reset.o
endif
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index d3bddb726a..2a8afac5e1 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -41,6 +41,9 @@ config DM_I2C
config DM_GPIO
default y
+config BLK
+ default y
+
source "arch/arm/mach-rockchip/rk3288/Kconfig"
source "arch/arm/mach-rockchip/rk3036/Kconfig"
endif
diff --git a/arch/arm/mach-rockchip/rk3036/reset_rk3036.c b/arch/arm/mach-rockchip/rk3036/reset_rk3036.c
index fefb568f7a..b3d2113239 100644
--- a/arch/arm/mach-rockchip/rk3036/reset_rk3036.c
+++ b/arch/arm/mach-rockchip/rk3036/reset_rk3036.c
@@ -7,24 +7,24 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
-#include <reset.h>
+#include <sysreset.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3036.h>
#include <asm/arch/hardware.h>
#include <linux/err.h>
-int rk3036_reset_request(struct udevice *dev, enum reset_t type)
+int rk3036_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
struct rk3036_cru *cru = rockchip_get_cru();
if (IS_ERR(cru))
return PTR_ERR(cru);
switch (type) {
- case RESET_WARM:
+ case SYSRESET_WARM:
writel(0xeca8, &cru->cru_glb_srst_snd_value);
break;
- case RESET_COLD:
+ case SYSRESET_COLD:
writel(0xfdb9, &cru->cru_glb_srst_fst_value);
break;
default:
@@ -34,12 +34,12 @@ int rk3036_reset_request(struct udevice *dev, enum reset_t type)
return -EINPROGRESS;
}
-static struct reset_ops rk3036_reset = {
- .request = rk3036_reset_request,
+static struct sysreset_ops rk3036_sysreset = {
+ .request = rk3036_sysreset_request,
};
-U_BOOT_DRIVER(reset_rk3036) = {
- .name = "rk3036_reset",
- .id = UCLASS_RESET,
- .ops = &rk3036_reset,
+U_BOOT_DRIVER(sysreset_rk3036) = {
+ .name = "rk3036_sysreset",
+ .id = UCLASS_SYSRESET,
+ .ops = &rk3036_sysreset,
};
diff --git a/arch/arm/mach-rockchip/rk3288/reset_rk3288.c b/arch/arm/mach-rockchip/rk3288/reset_rk3288.c
index bf7540a5d2..0aad1c2160 100644
--- a/arch/arm/mach-rockchip/rk3288/reset_rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/reset_rk3288.c
@@ -7,25 +7,25 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
-#include <reset.h>
+#include <sysreset.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/cru_rk3288.h>
#include <asm/arch/hardware.h>
#include <linux/err.h>
-int rk3288_reset_request(struct udevice *dev, enum reset_t type)
+int rk3288_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
struct rk3288_cru *cru = rockchip_get_cru();
if (IS_ERR(cru))
return PTR_ERR(cru);
switch (type) {
- case RESET_WARM:
+ case SYSRESET_WARM:
rk_clrreg(&cru->cru_mode_con, 0xffff);
writel(0xeca8, &cru->cru_glb_srst_snd_value);
break;
- case RESET_COLD:
+ case SYSRESET_COLD:
rk_clrreg(&cru->cru_mode_con, 0xffff);
writel(0xfdb9, &cru->cru_glb_srst_fst_value);
break;
@@ -36,12 +36,12 @@ int rk3288_reset_request(struct udevice *dev, enum reset_t type)
return -EINPROGRESS;
}
-static struct reset_ops rk3288_reset = {
- .request = rk3288_reset_request,
+static struct sysreset_ops rk3288_sysreset = {
+ .request = rk3288_sysreset_request,
};
-U_BOOT_DRIVER(reset_rk3288) = {
- .name = "rk3288_reset",
- .id = UCLASS_RESET,
- .ops = &rk3288_reset,
+U_BOOT_DRIVER(sysreset_rk3288) = {
+ .name = "rk3288_sysreset",
+ .id = UCLASS_SYSRESET,
+ .ops = &rk3288_sysreset,
};
diff --git a/arch/arm/mach-snapdragon/reset.c b/arch/arm/mach-snapdragon/reset.c
index 2627eec181..a6cabfb8b0 100644
--- a/arch/arm/mach-snapdragon/reset.c
+++ b/arch/arm/mach-snapdragon/reset.c
@@ -9,12 +9,12 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
-#include <reset.h>
+#include <sysreset.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
-static int msm_reset_request(struct udevice *dev, enum reset_t type)
+static int msm_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
phys_addr_t addr = dev_get_addr(dev);
if (!addr)
@@ -23,18 +23,18 @@ static int msm_reset_request(struct udevice *dev, enum reset_t type)
return -EINPROGRESS;
}
-static struct reset_ops msm_reset_ops = {
- .request = msm_reset_request,
+static struct sysreset_ops msm_sysreset_ops = {
+ .request = msm_sysreset_request,
};
-static const struct udevice_id msm_reset_ids[] = {
+static const struct udevice_id msm_sysreset_ids[] = {
{ .compatible = "qcom,pshold" },
{ }
};
U_BOOT_DRIVER(msm_reset) = {
- .name = "msm_reset",
- .id = UCLASS_RESET,
- .of_match = msm_reset_ids,
- .ops = &msm_reset_ops,
+ .name = "msm_sysreset",
+ .id = UCLASS_SYSRESET,
+ .of_match = msm_sysreset_ids,
+ .ops = &msm_sysreset_ops,
};
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index d2a7dc9b45..2b4dbd341f 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -360,8 +360,8 @@ int state_init(void)
assert(state->ram_buf);
/* No reset yet, so mark it as such. Always allow power reset */
- state->last_reset = RESET_COUNT;
- state->reset_allowed[RESET_POWER] = true;
+ state->last_sysreset = SYSRESET_COUNT;
+ state->sysreset_allowed[SYSRESET_POWER] = true;
/*
* Example of how to use GPIOs:
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 89300096a5..686c215aea 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -216,6 +216,17 @@
};
};
+ mbox: mbox {
+ compatible = "sandbox,mbox";
+ #mbox-cells = <1>;
+ };
+
+ mbox-test {
+ compatible = "sandbox,mbox-test";
+ mboxes = <&mbox 100>, <&mbox 1>;
+ mbox-names = "other", "test";
+ };
+
mmc {
compatible = "sandbox,mmc";
};
diff --git a/arch/sandbox/include/asm/mbox.h b/arch/sandbox/include/asm/mbox.h
new file mode 100644
index 0000000000..2d7b7d03e5
--- /dev/null
+++ b/arch/sandbox/include/asm/mbox.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef __SANDBOX_MBOX_H
+#define __SANDBOX_MBOX_H
+
+#include <common.h>
+
+#define SANDBOX_MBOX_PING_XOR 0x12345678
+
+struct udevice;
+
+int sandbox_mbox_test_get(struct udevice *dev);
+int sandbox_mbox_test_send(struct udevice *dev, uint32_t msg);
+int sandbox_mbox_test_recv(struct udevice *dev, uint32_t *msg);
+int sandbox_mbox_test_free(struct udevice *dev);
+
+#endif
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index 11856c2fed..149f28d873 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -7,7 +7,7 @@
#define __SANDBOX_STATE_H
#include <config.h>
-#include <reset.h>
+#include <sysreset.h>
#include <stdbool.h>
#include <linux/stringify.h>
@@ -60,8 +60,8 @@ struct sandbox_state {
bool write_state; /* Write sandbox state on exit */
bool ignore_missing_state_on_read; /* No error if state missing */
bool show_lcd; /* Show LCD on start-up */
- enum reset_t last_reset; /* Last reset type */
- bool reset_allowed[RESET_COUNT]; /* Allowed reset types */
+ enum sysreset_t last_sysreset; /* Last system reset type */
+ bool sysreset_allowed[SYSRESET_COUNT]; /* Allowed system reset types */
enum state_terminal_raw term_raw; /* Terminal raw/cooked */
bool skip_delays; /* Ignore any time delays (for test) */
bool show_test_output; /* Don't suppress stdout in tests */
diff --git a/cmd/mmc.c b/cmd/mmc.c
index eb4a547a97..b2761e934b 100644
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -11,66 +11,6 @@
#include <mmc.h>
static int curr_device = -1;
-#ifndef CONFIG_GENERIC_MMC
-int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- int dev;
-
- if (argc < 2)
- return CMD_RET_USAGE;
-
- if (strcmp(argv[1], "init") == 0) {
- if (argc == 2) {
- if (curr_device < 0)
- dev = 1;
- else
- dev = curr_device;
- } else if (argc == 3) {
- dev = (int)simple_strtoul(argv[2], NULL, 10);
- } else {
- return CMD_RET_USAGE;
- }
-
- if (mmc_legacy_init(dev) != 0) {
- puts("No MMC card found\n");
- return 1;
- }
-
- curr_device = dev;
- printf("mmc%d is available\n", curr_device);
- } else if (strcmp(argv[1], "device") == 0) {
- if (argc == 2) {
- if (curr_device < 0) {
- puts("No MMC device available\n");
- return 1;
- }
- } else if (argc == 3) {
- dev = (int)simple_strtoul(argv[2], NULL, 10);
-
-#ifdef CONFIG_SYS_MMC_SET_DEV
- if (mmc_set_dev(dev) != 0)
- return 1;
-#endif
- curr_device = dev;
- } else {
- return CMD_RET_USAGE;
- }
-
- printf("mmc%d is current device\n", curr_device);
- } else {
- return CMD_RET_USAGE;
- }
-
- return 0;
-}
-
-U_BOOT_CMD(
- mmc, 3, 1, do_mmc,
- "MMC sub-system",
- "init [dev] - init MMC sub system\n"
- "mmc device [dev] - show or set current device"
-);
-#else /* !CONFIG_GENERIC_MMC */
static void print_mmcinfo(struct mmc *mmc)
{
@@ -881,5 +821,3 @@ U_BOOT_CMD(
"display MMC info",
"- display info of the current MMC device"
);
-
-#endif /* !CONFIG_GENERIC_MMC */
diff --git a/common/env_mmc.c b/common/env_mmc.c
index c7fef188cd..16f6a17514 100644
--- a/common/env_mmc.c
+++ b/common/env_mmc.c
@@ -128,12 +128,12 @@ static inline int write_env(struct mmc *mmc, unsigned long size,
unsigned long offset, const void *buffer)
{
uint blk_start, blk_cnt, n;
+ struct blk_desc *desc = mmc_get_blk_desc(mmc);
blk_start = ALIGN(offset, mmc->write_bl_len) / mmc->write_bl_len;
blk_cnt = ALIGN(size, mmc->write_bl_len) / mmc->write_bl_len;
- n = mmc->block_dev.block_write(&mmc->block_dev, blk_start,
- blk_cnt, (u_char *)buffer);
+ n = blk_dwrite(desc, blk_start, blk_cnt, (u_char *)buffer);
return (n == blk_cnt) ? 0 : -1;
}
@@ -197,12 +197,12 @@ static inline int read_env(struct mmc *mmc, unsigned long size,
unsigned long offset, const void *buffer)
{
uint blk_start, blk_cnt, n;
+ struct blk_desc *desc = mmc_get_blk_desc(mmc);
blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;
- n = mmc->block_dev.block_read(&mmc->block_dev, blk_start, blk_cnt,
- (uchar *)buffer);
+ n = blk_dread(desc, blk_start, blk_cnt, (uchar *)buffer);
return (n == blk_cnt) ? 0 : -1;
}
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index d8058d6399..ef8583a1a6 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -34,9 +34,8 @@ static int mmc_load_legacy(struct mmc *mmc, ulong sector,
mmc->read_bl_len;
/* Read the header too to avoid extra memcpy */
- count = mmc->block_dev.block_read(&mmc->block_dev, sector,
- image_size_sectors,
- (void *)(ulong)spl_image.load_addr);
+ count = blk_dread(mmc_get_blk_desc(mmc), sector, image_size_sectors,
+ (void *)(ulong)spl_image.load_addr);
debug("read %x sectors to %x\n", image_size_sectors,
spl_image.load_addr);
if (count != image_size_sectors)
@@ -50,7 +49,7 @@ static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
{
struct mmc *mmc = load->dev;
- return mmc->block_dev.block_read(&mmc->block_dev, sector, count, buf);
+ return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf);
}
static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector)
@@ -63,7 +62,7 @@ static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector)
sizeof(struct image_header));
/* read image header to find the image size & load address */
- count = mmc->block_dev.block_read(&mmc->block_dev, sector, 1, header);
+ count = blk_dread(mmc_get_blk_desc(mmc), sector, 1, header);
debug("hdr read sector %lx, count=%lu\n", sector, count);
if (count == 0) {
ret = -EIO;
diff --git a/configs/chromebook_jerry_defconfig b/configs/chromebook_jerry_defconfig
index 25ead92778..d5bc5153b1 100644
--- a/configs/chromebook_jerry_defconfig
+++ b/configs/chromebook_jerry_defconfig
@@ -47,7 +47,7 @@ CONFIG_CMD_CROS_EC=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_SPI=y
CONFIG_PWRSEQ=y
-CONFIG_RESET=y
+CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_ROCKCHIP_DWMMC=y
CONFIG_PINCTRL=y
diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig
index 2566ded58a..37c5ea7761 100644
--- a/configs/dragonboard410c_defconfig
+++ b/configs/dragonboard410c_defconfig
@@ -23,7 +23,7 @@ CONFIG_MSM_GPIO=y
CONFIG_PM8916_GPIO=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
-CONFIG_RESET=y
+CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_MSM_SDHCI=y
CONFIG_DM_PMIC=y
diff --git a/configs/evb-rk3036_defconfig b/configs/evb-rk3036_defconfig
index 4dd4586243..9894fffcca 100644
--- a/configs/evb-rk3036_defconfig
+++ b/configs/evb-rk3036_defconfig
@@ -28,7 +28,7 @@ CONFIG_CLK=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_LED=y
-CONFIG_RESET=y
+CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_ROCKCHIP_DWMMC=y
CONFIG_PINCTRL=y
diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig
index 0995f9b329..4af91206dc 100644
--- a/configs/firefly-rk3288_defconfig
+++ b/configs/firefly-rk3288_defconfig
@@ -28,7 +28,7 @@ CONFIG_CMD_EXT4=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_SPL_OF_CONTROL=y
-CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent"
+CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
CONFIG_REGMAP=y
CONFIG_SPL_REGMAP=y
CONFIG_SYSCON=y
@@ -40,7 +40,7 @@ CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
-CONFIG_RESET=y
+CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_ROCKCHIP_DWMMC=y
CONFIG_PINCTRL=y
diff --git a/configs/kylin-rk3036_defconfig b/configs/kylin-rk3036_defconfig
index 50fbe654bf..0ff6c6b9a4 100644
--- a/configs/kylin-rk3036_defconfig
+++ b/configs/kylin-rk3036_defconfig
@@ -28,7 +28,7 @@ CONFIG_CLK=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_LED=y
-CONFIG_RESET=y
+CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_ROCKCHIP_DWMMC=y
CONFIG_PINCTRL=y
diff --git a/configs/odroid-c2_defconfig b/configs/odroid-c2_defconfig
index a771b20f5f..483d4900b7 100644
--- a/configs/odroid-c2_defconfig
+++ b/configs/odroid-c2_defconfig
@@ -13,7 +13,6 @@ CONFIG_DEFAULT_DEVICE_TREE="meson-gxbb-odroidc2"
CONFIG_OF_CONTROL=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_DM_ETH=y
-CONFIG_ETH_DESIGNWARE=y
CONFIG_DEBUG_UART=y
CONFIG_DEBUG_UART_MESON=y
CONFIG_DEBUG_UART_BASE=0xc81004c0
diff --git a/configs/rock2_defconfig b/configs/rock2_defconfig
index fd32fb521e..3e16b805ca 100644
--- a/configs/rock2_defconfig
+++ b/configs/rock2_defconfig
@@ -38,7 +38,7 @@ CONFIG_CLK=y
CONFIG_SPL_CLK=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
-CONFIG_RESET=y
+CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_ROCKCHIP_DWMMC=y
CONFIG_PINCTRL=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 9e4a92dd6c..4eb3c224fd 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -97,7 +97,7 @@ CONFIG_CROS_EC_SANDBOX=y
CONFIG_CROS_EC_SPI=y
CONFIG_PWRSEQ=y
CONFIG_SPL_PWRSEQ=y
-CONFIG_RESET=y
+CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_SANDBOX_MMC=y
CONFIG_SPI_FLASH_SANDBOX=y
@@ -170,3 +170,6 @@ CONFIG_UNIT_TEST=y
CONFIG_UT_TIME=y
CONFIG_UT_DM=y
CONFIG_UT_ENV=y
+CONFIG_MISC=y
+CONFIG_DM_MAILBOX=y
+CONFIG_SANDBOX_MBOX=y
diff --git a/configs/sandbox_noblk_defconfig b/configs/sandbox_noblk_defconfig
index 93167c2f65..60c73398db 100644
--- a/configs/sandbox_noblk_defconfig
+++ b/configs/sandbox_noblk_defconfig
@@ -94,7 +94,7 @@ CONFIG_CROS_EC_SANDBOX=y
CONFIG_CROS_EC_SPI=y
CONFIG_PWRSEQ=y
CONFIG_SPL_PWRSEQ=y
-CONFIG_RESET=y
+CONFIG_SYSRESET=y
CONFIG_DM_MMC=y
CONFIG_SPI_FLASH_SANDBOX=y
CONFIG_SPI_FLASH=y
diff --git a/doc/device-tree-bindings/mailbox/mailbox.txt b/doc/device-tree-bindings/mailbox/mailbox.txt
new file mode 100644
index 0000000000..be05b9746c
--- /dev/null
+++ b/doc/device-tree-bindings/mailbox/mailbox.txt
@@ -0,0 +1,32 @@
+* Generic Mailbox Controller and client driver bindings
+
+Generic binding to provide a way for Mailbox controller drivers to
+assign appropriate mailbox channel to client drivers.
+
+* Mailbox Controller
+
+Required property:
+- #mbox-cells: Must be at least 1. Number of cells in a mailbox
+ specifier.
+
+Example:
+ mailbox: mailbox {
+ ...
+ #mbox-cells = <1>;
+ };
+
+
+* Mailbox Client
+
+Required property:
+- mboxes: List of phandle and mailbox channel specifiers.
+
+Optional property:
+- mbox-names: List of identifier strings for each mailbox channel.
+
+Example:
+ pwr_cntrl: power {
+ ...
+ mbox-names = "pwr-ctrl", "rpc";
+ mboxes = <&mailbox 0 &mailbox 1>;
+ };
diff --git a/doc/driver-model/README.txt b/doc/driver-model/README.txt
index 7a24552560..1b5ccec4b2 100644
--- a/doc/driver-model/README.txt
+++ b/doc/driver-model/README.txt
@@ -606,19 +606,24 @@ methods actually defined.
1. Bind stage
-A device and its driver are bound using one of these two methods:
+U-Boot discovers devices using one of these two methods:
- - Scan the U_BOOT_DEVICE() definitions. U-Boot It looks up the
-name specified by each, to find the appropriate driver. It then calls
-device_bind() to create a new device and bind' it to its driver. This will
-call the device's bind() method.
+ - Scan the U_BOOT_DEVICE() definitions. U-Boot looks up the name specified
+by each, to find the appropriate U_BOOT_DRIVER() definition. In this case,
+there is no path by which driver_data may be provided, but the U_BOOT_DEVICE()
+may provide platdata.
- Scan through the device tree definitions. U-Boot looks at top-level
nodes in the the device tree. It looks at the compatible string in each node
-and uses the of_match part of the U_BOOT_DRIVER() structure to find the
-right driver for each node. It then calls device_bind() to bind the
-newly-created device to its driver (thereby creating a device structure).
-This will also call the device's bind() method.
+and uses the of_match table of the U_BOOT_DRIVER() structure to find the
+right driver for each node. In this case, the of_match table may provide a
+driver_data value, but platdata cannot be provided until later.
+
+For each device that is discovered, U-Boot then calls device_bind() to create a
+new device, initializes various core fields of the device object such as name,
+uclass & driver, initializes any optional fields of the device object that are
+applicable such as of_offset, driver_data & platdata, and finally calls the
+driver's bind() method if one is defined.
At this point all the devices are known, and bound to their drivers. There
is a 'struct udevice' allocated for all devices. However, nothing has been
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 118b66ed0e..f2a137ad87 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -30,6 +30,8 @@ source "drivers/input/Kconfig"
source "drivers/led/Kconfig"
+source "drivers/mailbox/Kconfig"
+
source "drivers/memory/Kconfig"
source "drivers/misc/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 99dd07fc76..f6295d285e 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -64,6 +64,7 @@ obj-y += video/
obj-y += watchdog/
obj-$(CONFIG_QE) += qe/
obj-$(CONFIG_U_QE) += qe/
+obj-y += mailbox/
obj-y += memory/
obj-y += pwm/
obj-y += input/
diff --git a/drivers/clk/clk_rk3036.c b/drivers/clk/clk_rk3036.c
index bd5f22a753..7ec65bdff0 100644
--- a/drivers/clk/clk_rk3036.c
+++ b/drivers/clk/clk_rk3036.c
@@ -407,7 +407,7 @@ static int rk3036_clk_bind(struct udevice *dev)
}
/* The reset driver does not have a device node, so bind it here */
- ret = device_bind_driver(gd->dm_root, "rk3036_reset", "reset", &dev);
+ ret = device_bind_driver(gd->dm_root, "rk3036_sysreset", "reset", &dev);
if (ret)
debug("Warning: No RK3036 reset driver: ret=%d\n", ret);
diff --git a/drivers/clk/clk_rk3288.c b/drivers/clk/clk_rk3288.c
index a110a1c160..d88893c8ea 100644
--- a/drivers/clk/clk_rk3288.c
+++ b/drivers/clk/clk_rk3288.c
@@ -891,7 +891,7 @@ static int rk3288_clk_bind(struct udevice *dev)
}
/* The reset driver does not have a device node, so bind it here */
- ret = device_bind_driver(gd->dm_root, "rk3288_reset", "reset", &dev);
+ ret = device_bind_driver(gd->dm_root, "rk3288_sysreset", "reset", &dev);
if (ret)
debug("Warning: No RK3288 reset driver: ret=%d\n", ret);
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 45d5e3e12c..eb75b1734f 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -26,9 +26,10 @@
DECLARE_GLOBAL_DATA_PTR;
-int device_bind(struct udevice *parent, const struct driver *drv,
- const char *name, void *platdata, int of_offset,
- struct udevice **devp)
+static int device_bind_common(struct udevice *parent, const struct driver *drv,
+ const char *name, void *platdata,
+ ulong driver_data, int of_offset,
+ struct udevice **devp)
{
struct udevice *dev;
struct uclass *uc;
@@ -56,6 +57,7 @@ int device_bind(struct udevice *parent, const struct driver *drv,
INIT_LIST_HEAD(&dev->devres_head);
#endif
dev->platdata = platdata;
+ dev->driver_data = driver_data;
dev->name = name;
dev->of_offset = of_offset;
dev->parent = parent;
@@ -193,6 +195,23 @@ fail_alloc1:
return ret;
}
+int device_bind_with_driver_data(struct udevice *parent,
+ const struct driver *drv, const char *name,
+ ulong driver_data, int of_offset,
+ struct udevice **devp)
+{
+ return device_bind_common(parent, drv, name, NULL, driver_data,
+ of_offset, devp);
+}
+
+int device_bind(struct udevice *parent, const struct driver *drv,
+ const char *name, void *platdata, int of_offset,
+ struct udevice **devp)
+{
+ return device_bind_common(parent, drv, name, platdata, 0, of_offset,
+ devp);
+}
+
int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
const struct driver_info *info, struct udevice **devp)
{
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index a72db13a11..0c27717790 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -170,7 +170,8 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
}
dm_dbg(" - found match at '%s'\n", entry->name);
- ret = device_bind(parent, entry, name, NULL, offset, &dev);
+ ret = device_bind_with_driver_data(parent, entry, name,
+ id->data, offset, &dev);
if (ret == -ENODEV) {
dm_dbg("Driver '%s' refuses to bind\n", entry->name);
continue;
@@ -180,7 +181,6 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
ret);
return ret;
} else {
- dev->driver_data = id->data;
found = true;
if (devp)
*devp = dev;
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index a7cec18d57..94abbeb39a 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -258,43 +258,30 @@ static int gpio_sunxi_probe(struct udevice *dev)
return 0;
}
+
+struct sunxi_gpio_soc_data {
+ int start;
+ int no_banks;
+};
+
/**
* We have a top-level GPIO device with no actual GPIOs. It has a child
* device for each Sunxi bank.
*/
static int gpio_sunxi_bind(struct udevice *parent)
{
+ struct sunxi_gpio_soc_data *soc_data =
+ (struct sunxi_gpio_soc_data *)dev_get_driver_data(parent);
struct sunxi_gpio_platdata *plat = parent->platdata;
struct sunxi_gpio_reg *ctlr;
- int bank, no_banks, ret, start;
+ int bank, ret;
/* If this is a child device, there is nothing to do here */
if (plat)
return 0;
- if (fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
- "allwinner,sun6i-a31-r-pinctrl") == 0) {
- start = 'L' - 'A';
- no_banks = 2; /* L & M */
- } else if (fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
- "allwinner,sun8i-a23-r-pinctrl") == 0 ||
- fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
- "allwinner,sun8i-a83t-r-pinctrl") == 0 ||
- fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
- "allwinner,sun8i-h3-r-pinctrl") == 0) {
- start = 'L' - 'A';
- no_banks = 1; /* L only */
- } else if (fdt_node_check_compatible(gd->fdt_blob, parent->of_offset,
- "allwinner,sun9i-a80-r-pinctrl") == 0) {
- start = 'L' - 'A';
- no_banks = 3; /* L, M & N */
- } else {
- start = 0;
- no_banks = SUNXI_GPIO_BANKS;
- }
-
ctlr = (struct sunxi_gpio_reg *)dev_get_addr(parent);
- for (bank = 0; bank < no_banks; bank++) {
+ for (bank = 0; bank < soc_data->no_banks; bank++) {
struct sunxi_gpio_platdata *plat;
struct udevice *dev;
@@ -302,7 +289,7 @@ static int gpio_sunxi_bind(struct udevice *parent)
if (!plat)
return -ENOMEM;
plat->regs = &ctlr->gpio_bank[bank];
- plat->bank_name = gpio_bank_name(start + bank);
+ plat->bank_name = gpio_bank_name(soc_data->start + bank);
plat->gpio_count = SUNXI_GPIOS_PER_BANK;
ret = device_bind(parent, parent->driver,
@@ -315,23 +302,46 @@ static int gpio_sunxi_bind(struct udevice *parent)
return 0;
}
+static const struct sunxi_gpio_soc_data soc_data_a_all = {
+ .start = 0,
+ .no_banks = SUNXI_GPIO_BANKS,
+};
+
+static const struct sunxi_gpio_soc_data soc_data_l_1 = {
+ .start = 'L' - 'A',
+ .no_banks = 1,
+};
+
+static const struct sunxi_gpio_soc_data soc_data_l_2 = {
+ .start = 'L' - 'A',
+ .no_banks = 2,
+};
+
+static const struct sunxi_gpio_soc_data soc_data_l_3 = {
+ .start = 'L' - 'A',
+ .no_banks = 3,
+};
+
+#define ID(_compat_, _soc_data_) \
+ { .compatible = _compat_, .data = (ulong)&soc_data_##_soc_data_ }
+
static const struct udevice_id sunxi_gpio_ids[] = {
- { .compatible = "allwinner,sun4i-a10-pinctrl" },
- { .compatible = "allwinner,sun5i-a10s-pinctrl" },
- { .compatible = "allwinner,sun5i-a13-pinctrl" },
- { .compatible = "allwinner,sun6i-a31-pinctrl" },
- { .compatible = "allwinner,sun6i-a31s-pinctrl" },
- { .compatible = "allwinner,sun7i-a20-pinctrl" },
- { .compatible = "allwinner,sun8i-a23-pinctrl" },
- { .compatible = "allwinner,sun8i-a33-pinctrl" },
- { .compatible = "allwinner,sun8i-a83t-pinctrl", },
- { .compatible = "allwinner,sun8i-h3-pinctrl" },
- { .compatible = "allwinner,sun9i-a80-pinctrl" },
- { .compatible = "allwinner,sun6i-a31-r-pinctrl" },
- { .compatible = "allwinner,sun8i-a23-r-pinctrl" },
- { .compatible = "allwinner,sun8i-a83t-r-pinctrl" },
- { .compatible = "allwinner,sun8i-h3-r-pinctrl", },
- { .compatible = "allwinner,sun9i-a80-r-pinctrl", },
+ ID("allwinner,sun4i-a10-pinctrl", a_all),
+ ID("allwinner,sun5i-a10s-pinctrl", a_all),
+ ID("allwinner,sun5i-a13-pinctrl", a_all),
+ ID("allwinner,sun6i-a31-pinctrl", a_all),
+ ID("allwinner,sun6i-a31s-pinctrl", a_all),
+ ID("allwinner,sun7i-a20-pinctrl", a_all),
+ ID("allwinner,sun8i-a23-pinctrl", a_all),
+ ID("allwinner,sun8i-a33-pinctrl", a_all),
+ ID("allwinner,sun8i-a83t-pinctrl", a_all),
+ ID("allwinner,sun8i-h3-pinctrl", a_all),
+ ID("allwinner,sun9i-a80-pinctrl", a_all),
+ ID("allwinner,sun6i-a31-r-pinctrl", l_2),
+ ID("allwinner,sun8i-a23-r-pinctrl", l_1),
+ ID("allwinner,sun8i-a83t-r-pinctrl", l_1),
+ ID("allwinner,sun8i-h3-r-pinctrl", l_1),
+ ID("allwinner,sun9i-a80-r-pinctrl", l_3),
{ }
};
diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig
new file mode 100644
index 0000000000..9087512390
--- /dev/null
+++ b/drivers/mailbox/Kconfig
@@ -0,0 +1,20 @@
+menu "Mailbox Controller Support"
+
+config DM_MAILBOX
+ bool "Enable mailbox controllers using Driver Model"
+ depends on DM && OF_CONTROL
+ help
+ Enable support for the mailbox driver class. Mailboxes provide the
+ ability to transfer small messages and/or notifications from one
+ CPU to another CPU, or sometimes to dedicated HW modules. They form
+ the basis of a variety of inter-process/inter-CPU communication
+ protocols.
+
+config SANDBOX_MBOX
+ bool "Enable the sandbox mailbox test driver"
+ depends on DM_MAILBOX && SANDBOX
+ help
+ Enable support for a test mailbox implementation, which simply echos
+ back a modified version of any message that is sent.
+
+endmenu
diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile
new file mode 100644
index 0000000000..bbae4def6d
--- /dev/null
+++ b/drivers/mailbox/Makefile
@@ -0,0 +1,7 @@
+# Copyright (c) 2016, NVIDIA CORPORATION.
+#
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_DM_MAILBOX) += mailbox-uclass.o
+obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox.o
+obj-$(CONFIG_SANDBOX_MBOX) += sandbox-mbox-test.o
diff --git a/drivers/mailbox/mailbox-uclass.c b/drivers/mailbox/mailbox-uclass.c
new file mode 100644
index 0000000000..73fa32874a
--- /dev/null
+++ b/drivers/mailbox/mailbox-uclass.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <mailbox_client.h>
+#include <mailbox_uclass.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static inline struct mbox_ops *mbox_dev_ops(struct udevice *dev)
+{
+ return (struct mbox_ops *)dev->driver->ops;
+}
+
+static int mbox_of_xlate_default(struct mbox_chan *chan,
+ struct fdtdec_phandle_args *args)
+{
+ debug("%s(chan=%p)\n", __func__, chan);
+
+ if (args->args_count != 1) {
+ debug("Invaild args_count: %d\n", args->args_count);
+ return -EINVAL;
+ }
+
+ chan->id = args->args[0];
+
+ return 0;
+}
+
+int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan)
+{
+ struct fdtdec_phandle_args args;
+ int ret;
+ struct udevice *dev_mbox;
+ struct mbox_ops *ops;
+
+ debug("%s(dev=%p, index=%d, chan=%p)\n", __func__, dev, index, chan);
+
+ ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
+ "mboxes", "#mbox-cells", 0,
+ index, &args);
+ if (ret) {
+ debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = uclass_get_device_by_of_offset(UCLASS_MAILBOX, args.node,
+ &dev_mbox);
+ if (ret) {
+ debug("%s: uclass_get_device_by_of_offset failed: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ ops = mbox_dev_ops(dev_mbox);
+
+ chan->dev = dev_mbox;
+ if (ops->of_xlate)
+ ret = ops->of_xlate(chan, &args);
+ else
+ ret = mbox_of_xlate_default(chan, &args);
+ if (ret) {
+ debug("of_xlate() failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = ops->request(chan);
+ if (ret) {
+ debug("ops->request() failed: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int mbox_get_by_name(struct udevice *dev, const char *name,
+ struct mbox_chan *chan)
+{
+ int index;
+
+ debug("%s(dev=%p, name=%s, chan=%p)\n", __func__, dev, name, chan);
+
+ index = fdt_find_string(gd->fdt_blob, dev->of_offset, "mbox-names",
+ name);
+ if (index < 0) {
+ debug("fdt_find_string() failed: %d\n", index);
+ return index;
+ }
+
+ return mbox_get_by_index(dev, index, chan);
+}
+
+int mbox_free(struct mbox_chan *chan)
+{
+ struct mbox_ops *ops = mbox_dev_ops(chan->dev);
+
+ debug("%s(chan=%p)\n", __func__, chan);
+
+ return ops->free(chan);
+}
+
+int mbox_send(struct mbox_chan *chan, const void *data)
+{
+ struct mbox_ops *ops = mbox_dev_ops(chan->dev);
+
+ debug("%s(chan=%p, data=%p)\n", __func__, chan, data);
+
+ return ops->send(chan, data);
+}
+
+int mbox_recv(struct mbox_chan *chan, void *data, ulong timeout_us)
+{
+ struct mbox_ops *ops = mbox_dev_ops(chan->dev);
+ ulong start_time;
+ int ret;
+
+ debug("%s(chan=%p, data=%p, timeout_us=%ld)\n", __func__, chan, data,
+ timeout_us);
+
+ start_time = timer_get_us();
+ /*
+ * Account for partial us ticks, but if timeout_us is 0, ensure we
+ * still don't wait at all.
+ */
+ if (timeout_us)
+ timeout_us++;
+
+ for (;;) {
+ ret = ops->recv(chan, data);
+ if (ret != -ENODATA)
+ return ret;
+ if ((timer_get_us() - start_time) >= timeout_us)
+ return -ETIMEDOUT;
+ }
+}
+
+UCLASS_DRIVER(mailbox) = {
+ .id = UCLASS_MAILBOX,
+ .name = "mailbox",
+};
diff --git a/drivers/mailbox/sandbox-mbox-test.c b/drivers/mailbox/sandbox-mbox-test.c
new file mode 100644
index 0000000000..02d161aada
--- /dev/null
+++ b/drivers/mailbox/sandbox-mbox-test.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <mailbox_client.h>
+#include <asm/io.h>
+
+struct sandbox_mbox_test {
+ struct mbox_chan chan;
+};
+
+int sandbox_mbox_test_get(struct udevice *dev)
+{
+ struct sandbox_mbox_test *sbmt = dev_get_priv(dev);
+
+ return mbox_get_by_name(dev, "test", &sbmt->chan);
+}
+
+int sandbox_mbox_test_send(struct udevice *dev, uint32_t msg)
+{
+ struct sandbox_mbox_test *sbmt = dev_get_priv(dev);
+
+ return mbox_send(&sbmt->chan, &msg);
+}
+
+int sandbox_mbox_test_recv(struct udevice *dev, uint32_t *msg)
+{
+ struct sandbox_mbox_test *sbmt = dev_get_priv(dev);
+
+ return mbox_recv(&sbmt->chan, msg, 100);
+}
+
+int sandbox_mbox_test_free(struct udevice *dev)
+{
+ struct sandbox_mbox_test *sbmt = dev_get_priv(dev);
+
+ return mbox_free(&sbmt->chan);
+}
+
+static const struct udevice_id sandbox_mbox_test_ids[] = {
+ { .compatible = "sandbox,mbox-test" },
+ { }
+};
+
+U_BOOT_DRIVER(sandbox_mbox_test) = {
+ .name = "sandbox_mbox_test",
+ .id = UCLASS_MISC,
+ .of_match = sandbox_mbox_test_ids,
+ .priv_auto_alloc_size = sizeof(struct sandbox_mbox_test),
+};
diff --git a/drivers/mailbox/sandbox-mbox.c b/drivers/mailbox/sandbox-mbox.c
new file mode 100644
index 0000000000..1b7ac231cb
--- /dev/null
+++ b/drivers/mailbox/sandbox-mbox.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <mailbox_uclass.h>
+#include <asm/io.h>
+#include <asm/mbox.h>
+
+#define SANDBOX_MBOX_CHANNELS 2
+
+struct sandbox_mbox_chan {
+ bool rx_msg_valid;
+ uint32_t rx_msg;
+};
+
+struct sandbox_mbox {
+ struct sandbox_mbox_chan chans[SANDBOX_MBOX_CHANNELS];
+};
+
+static int sandbox_mbox_request(struct mbox_chan *chan)
+{
+ debug("%s(chan=%p)\n", __func__, chan);
+
+ if (chan->id >= SANDBOX_MBOX_CHANNELS)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int sandbox_mbox_free(struct mbox_chan *chan)
+{
+ debug("%s(chan=%p)\n", __func__, chan);
+
+ return 0;
+}
+
+static int sandbox_mbox_send(struct mbox_chan *chan, const void *data)
+{
+ struct sandbox_mbox *sbm = dev_get_priv(chan->dev);
+ const uint32_t *pmsg = data;
+
+ debug("%s(chan=%p, data=%p)\n", __func__, chan, data);
+
+ sbm->chans[chan->id].rx_msg = *pmsg ^ SANDBOX_MBOX_PING_XOR;
+ sbm->chans[chan->id].rx_msg_valid = true;
+
+ return 0;
+}
+
+static int sandbox_mbox_recv(struct mbox_chan *chan, void *data)
+{
+ struct sandbox_mbox *sbm = dev_get_priv(chan->dev);
+ uint32_t *pmsg = data;
+
+ debug("%s(chan=%p, data=%p)\n", __func__, chan, data);
+
+ if (!sbm->chans[chan->id].rx_msg_valid)
+ return -ENODATA;
+
+ *pmsg = sbm->chans[chan->id].rx_msg;
+ sbm->chans[chan->id].rx_msg_valid = false;
+
+ return 0;
+}
+
+static int sandbox_mbox_bind(struct udevice *dev)
+{
+ debug("%s(dev=%p)\n", __func__, dev);
+
+ return 0;
+}
+
+static int sandbox_mbox_probe(struct udevice *dev)
+{
+ debug("%s(dev=%p)\n", __func__, dev);
+
+ return 0;
+}
+
+static const struct udevice_id sandbox_mbox_ids[] = {
+ { .compatible = "sandbox,mbox" },
+ { }
+};
+
+struct mbox_ops sandbox_mbox_mbox_ops = {
+ .request = sandbox_mbox_request,
+ .free = sandbox_mbox_free,
+ .send = sandbox_mbox_send,
+ .recv = sandbox_mbox_recv,
+};
+
+U_BOOT_DRIVER(sandbox_mbox) = {
+ .name = "sandbox_mbox",
+ .id = UCLASS_MAILBOX,
+ .of_match = sandbox_mbox_ids,
+ .bind = sandbox_mbox_bind,
+ .probe = sandbox_mbox_probe,
+ .priv_auto_alloc_size = sizeof(struct sandbox_mbox),
+ .ops = &sandbox_mbox_mbox_ops,
+};
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index c40f6b577f..2373037685 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -121,13 +121,13 @@ config PCA9551_I2C_ADDR
help
The I2C address of the PCA9551 LED controller.
-config RESET
- bool "Enable support for reset drivers"
+config SYSRESET
+ bool "Enable support for system reset drivers"
depends on DM
help
- Enable reset drivers which can be used to reset the CPU or board.
- Each driver can provide a reset method which will be called to
- effect a reset. The uclass will try all available drivers when
+ Enable system reset drivers which can be used to reset the CPU or
+ board. Each driver can provide a reset method which will be called
+ to effect a reset. The uclass will try all available drivers when
reset_walk() is called.
config WINBOND_W83627
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 98704f2085..066639ba1f 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
obj-$(CONFIG_NS87308) += ns87308.o
obj-$(CONFIG_PDSP188x) += pdsp188x.o
obj-$(CONFIG_$(SPL_)PWRSEQ) += pwrseq-uclass.o
-obj-$(CONFIG_SANDBOX) += reset_sandbox.o
+obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
ifdef CONFIG_DM_I2C
obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o
endif
@@ -40,7 +40,7 @@ obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o
obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
-obj-$(CONFIG_RESET) += reset-uclass.o
+obj-$(CONFIG_SYSRESET) += sysreset-uclass.o
obj-$(CONFIG_FSL_DEVICE_DISABLE) += fsl_devdis.o
obj-$(CONFIG_WINBOND_W83627) += winbond_w83627.o
obj-$(CONFIG_QFW) += qfw.o
diff --git a/drivers/misc/reset_sandbox.c b/drivers/misc/reset_sandbox.c
deleted file mode 100644
index 2691bb031a..0000000000
--- a/drivers/misc/reset_sandbox.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2015 Google, Inc
- * Written by Simon Glass <sjg@chromium.org>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-#include <errno.h>
-#include <reset.h>
-#include <asm/state.h>
-#include <asm/test.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static int sandbox_warm_reset_request(struct udevice *dev, enum reset_t type)
-{
- struct sandbox_state *state = state_get_current();
-
- switch (type) {
- case RESET_WARM:
- state->last_reset = type;
- break;
- default:
- return -ENOSYS;
- }
- if (!state->reset_allowed[type])
- return -EACCES;
-
- return -EINPROGRESS;
-}
-
-static int sandbox_reset_request(struct udevice *dev, enum reset_t type)
-{
- struct sandbox_state *state = state_get_current();
-
- /*
- * If we have a device tree, the device we created from platform data
- * (see the U_BOOT_DEVICE() declaration below) should not do anything.
- * If we are that device, return an error.
- */
- if (state->fdt_fname && dev->of_offset == -1)
- return -ENODEV;
-
- switch (type) {
- case RESET_COLD:
- state->last_reset = type;
- break;
- case RESET_POWER:
- state->last_reset = type;
- if (!state->reset_allowed[type])
- return -EACCES;
- sandbox_exit();
- break;
- default:
- return -ENOSYS;
- }
- if (!state->reset_allowed[type])
- return -EACCES;
-
- return -EINPROGRESS;
-}
-
-static struct reset_ops sandbox_reset_ops = {
- .request = sandbox_reset_request,
-};
-
-static const struct udevice_id sandbox_reset_ids[] = {
- { .compatible = "sandbox,reset" },
- { }
-};
-
-U_BOOT_DRIVER(reset_sandbox) = {
- .name = "reset_sandbox",
- .id = UCLASS_RESET,
- .of_match = sandbox_reset_ids,
- .ops = &sandbox_reset_ops,
-};
-
-static struct reset_ops sandbox_warm_reset_ops = {
- .request = sandbox_warm_reset_request,
-};
-
-static const struct udevice_id sandbox_warm_reset_ids[] = {
- { .compatible = "sandbox,warm-reset" },
- { }
-};
-
-U_BOOT_DRIVER(warm_reset_sandbox) = {
- .name = "warm_reset_sandbox",
- .id = UCLASS_RESET,
- .of_match = sandbox_warm_reset_ids,
- .ops = &sandbox_warm_reset_ops,
-};
-
-/* This is here in case we don't have a device tree */
-U_BOOT_DEVICE(reset_sandbox_non_fdt) = {
- .name = "reset_sandbox",
-};
diff --git a/drivers/misc/reset-uclass.c b/drivers/misc/sysreset-uclass.c
index fdb5c6fcff..3566d17fb1 100644
--- a/drivers/misc/reset-uclass.c
+++ b/drivers/misc/sysreset-uclass.c
@@ -6,7 +6,7 @@
*/
#include <common.h>
-#include <reset.h>
+#include <sysreset.h>
#include <dm.h>
#include <errno.h>
#include <regmap.h>
@@ -15,9 +15,9 @@
#include <dm/root.h>
#include <linux/err.h>
-int reset_request(struct udevice *dev, enum reset_t type)
+int sysreset_request(struct udevice *dev, enum sysreset_t type)
{
- struct reset_ops *ops = reset_get_ops(dev);
+ struct sysreset_ops *ops = sysreset_get_ops(dev);
if (!ops->request)
return -ENOSYS;
@@ -25,16 +25,16 @@ int reset_request(struct udevice *dev, enum reset_t type)
return ops->request(dev, type);
}
-int reset_walk(enum reset_t type)
+int sysreset_walk(enum sysreset_t type)
{
struct udevice *dev;
int ret = -ENOSYS;
- while (ret != -EINPROGRESS && type < RESET_COUNT) {
- for (uclass_first_device(UCLASS_RESET, &dev);
+ while (ret != -EINPROGRESS && type < SYSRESET_COUNT) {
+ for (uclass_first_device(UCLASS_SYSRESET, &dev);
dev;
uclass_next_device(&dev)) {
- ret = reset_request(dev, type);
+ ret = sysreset_request(dev, type);
if (ret == -EINPROGRESS)
break;
}
@@ -44,38 +44,38 @@ int reset_walk(enum reset_t type)
return ret;
}
-void reset_walk_halt(enum reset_t type)
+void sysreset_walk_halt(enum sysreset_t type)
{
int ret;
- ret = reset_walk(type);
+ ret = sysreset_walk(type);
/* Wait for the reset to take effect */
if (ret == -EINPROGRESS)
mdelay(100);
/* Still no reset? Give up */
- printf("Reset not supported on this platform\n");
+ debug("System reset not supported on this platform\n");
hang();
}
/**
- * reset_cpu() - calls reset_walk(RESET_WARM)
+ * reset_cpu() - calls sysreset_walk(SYSRESET_WARM)
*/
void reset_cpu(ulong addr)
{
- reset_walk_halt(RESET_WARM);
+ sysreset_walk_halt(SYSRESET_WARM);
}
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- reset_walk_halt(RESET_WARM);
+ sysreset_walk_halt(SYSRESET_WARM);
return 0;
}
-UCLASS_DRIVER(reset) = {
- .id = UCLASS_RESET,
- .name = "reset",
+UCLASS_DRIVER(sysreset) = {
+ .id = UCLASS_SYSRESET,
+ .name = "sysreset",
};
diff --git a/drivers/misc/sysreset_sandbox.c b/drivers/misc/sysreset_sandbox.c
new file mode 100644
index 0000000000..7ae7f386ee
--- /dev/null
+++ b/drivers/misc/sysreset_sandbox.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <asm/state.h>
+#include <asm/test.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int sandbox_warm_sysreset_request(struct udevice *dev,
+ enum sysreset_t type)
+{
+ struct sandbox_state *state = state_get_current();
+
+ switch (type) {
+ case SYSRESET_WARM:
+ state->last_sysreset = type;
+ break;
+ default:
+ return -ENOSYS;
+ }
+ if (!state->sysreset_allowed[type])
+ return -EACCES;
+
+ return -EINPROGRESS;
+}
+
+static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type)
+{
+ struct sandbox_state *state = state_get_current();
+
+ /*
+ * If we have a device tree, the device we created from platform data
+ * (see the U_BOOT_DEVICE() declaration below) should not do anything.
+ * If we are that device, return an error.
+ */
+ if (state->fdt_fname && dev->of_offset == -1)
+ return -ENODEV;
+
+ switch (type) {
+ case SYSRESET_COLD:
+ state->last_sysreset = type;
+ break;
+ case SYSRESET_POWER:
+ state->last_sysreset = type;
+ if (!state->sysreset_allowed[type])
+ return -EACCES;
+ sandbox_exit();
+ break;
+ default:
+ return -ENOSYS;
+ }
+ if (!state->sysreset_allowed[type])
+ return -EACCES;
+
+ return -EINPROGRESS;
+}
+
+static struct sysreset_ops sandbox_sysreset_ops = {
+ .request = sandbox_sysreset_request,
+};
+
+static const struct udevice_id sandbox_sysreset_ids[] = {
+ { .compatible = "sandbox,reset" },
+ { }
+};
+
+U_BOOT_DRIVER(sysreset_sandbox) = {
+ .name = "sysreset_sandbox",
+ .id = UCLASS_SYSRESET,
+ .of_match = sandbox_sysreset_ids,
+ .ops = &sandbox_sysreset_ops,
+};
+
+static struct sysreset_ops sandbox_warm_sysreset_ops = {
+ .request = sandbox_warm_sysreset_request,
+};
+
+static const struct udevice_id sandbox_warm_sysreset_ids[] = {
+ { .compatible = "sandbox,warm-reset" },
+ { }
+};
+
+U_BOOT_DRIVER(warm_sysreset_sandbox) = {
+ .name = "warm_sysreset_sandbox",
+ .id = UCLASS_SYSRESET,
+ .of_match = sandbox_warm_sysreset_ids,
+ .ops = &sandbox_warm_sysreset_ops,
+};
+
+/* This is here in case we don't have a device tree */
+U_BOOT_DEVICE(sysreset_sandbox_non_fdt) = {
+ .name = "sysreset_sandbox",
+};
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 7329f40d34..74a2663c8b 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -454,27 +454,40 @@ static const struct mmc_ops dwmci_ops = {
.init = dwmci_init,
};
-int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk)
+void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
+ uint caps, u32 max_clk, u32 min_clk)
{
- host->cfg.name = host->name;
- host->cfg.ops = &dwmci_ops;
- host->cfg.f_min = min_clk;
- host->cfg.f_max = max_clk;
+ cfg->name = name;
+ cfg->ops = &dwmci_ops;
+ cfg->f_min = min_clk;
+ cfg->f_max = max_clk;
- host->cfg.voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
+ cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
- host->cfg.host_caps = host->caps;
+ cfg->host_caps = caps;
- if (host->buswidth == 8) {
- host->cfg.host_caps |= MMC_MODE_8BIT;
- host->cfg.host_caps &= ~MMC_MODE_4BIT;
+ if (buswidth == 8) {
+ cfg->host_caps |= MMC_MODE_8BIT;
+ cfg->host_caps &= ~MMC_MODE_4BIT;
} else {
- host->cfg.host_caps |= MMC_MODE_4BIT;
- host->cfg.host_caps &= ~MMC_MODE_8BIT;
+ cfg->host_caps |= MMC_MODE_4BIT;
+ cfg->host_caps &= ~MMC_MODE_8BIT;
}
- host->cfg.host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
+ cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
+
+ cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+}
- host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+#ifdef CONFIG_BLK
+int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg)
+{
+ return mmc_bind(dev, mmc, cfg);
+}
+#else
+int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk)
+{
+ dwmci_setup_cfg(&host->cfg, host->name, host->buswidth, host->caps,
+ max_clk, min_clk);
host->mmc = mmc_create(&host->cfg, host);
if (host->mmc == NULL)
@@ -482,3 +495,4 @@ int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk)
return 0;
}
+#endif
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 74b3d68f87..94f19ade3e 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -984,7 +984,7 @@ static const int fbase[] = {
/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
* to platforms without floating point.
*/
-static const int multipliers[] = {
+static const u8 multipliers[] = {
0, /* reserved */
10,
12,
@@ -1531,15 +1531,6 @@ static int mmc_send_if_cond(struct mmc *mmc)
return 0;
}
-/* not used any more */
-int __deprecated mmc_register(struct mmc *mmc)
-{
-#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
- printf("%s is deprecated! use mmc_create() instead.\n", __func__);
-#endif
- return -1;
-}
-
#ifdef CONFIG_BLK
int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
{
@@ -1566,7 +1557,7 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg)
bdesc->removable = 1;
/* setup initial part type */
- bdesc->part_type = mmc->cfg->part_type;
+ bdesc->part_type = cfg->part_type;
mmc->dev = dev;
return 0;
diff --git a/drivers/mmc/mmc_private.h b/drivers/mmc/mmc_private.h
index 27b9e5f56f..9f0d5c2384 100644
--- a/drivers/mmc/mmc_private.h
+++ b/drivers/mmc/mmc_private.h
@@ -37,6 +37,19 @@ ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
/* SPL will never write or erase, declare dummies to reduce code size. */
+#ifdef CONFIG_BLK
+static inline unsigned long mmc_berase(struct udevice *dev,
+ lbaint_t start, lbaint_t blkcnt)
+{
+ return 0;
+}
+
+static inline ulong mmc_bwrite(struct udevice *dev, lbaint_t start,
+ lbaint_t blkcnt, const void *src)
+{
+ return 0;
+}
+#else
static inline unsigned long mmc_berase(struct blk_desc *block_dev,
lbaint_t start, lbaint_t blkcnt)
{
@@ -48,6 +61,7 @@ static inline ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start,
{
return 0;
}
+#endif
#endif /* CONFIG_SPL_BUILD */
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index 0a261c51a8..750ab9f8c5 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -18,6 +18,11 @@
DECLARE_GLOBAL_DATA_PTR;
+struct rockchip_mmc_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+
struct rockchip_dwmmc_priv {
struct udevice *clk;
int periph;
@@ -62,6 +67,9 @@ static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
static int rockchip_dwmmc_probe(struct udevice *dev)
{
+#ifdef CONFIG_BLK
+ struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
+#endif
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
struct dwmci_host *host = &priv->host;
@@ -100,16 +108,37 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
return ret;
}
#endif
+#ifdef CONFIG_BLK
+ dwmci_setup_cfg(&plat->cfg, dev->name, host->buswidth, host->caps,
+ minmax[1], minmax[0]);
+ host->mmc = &plat->mmc;
+#else
ret = add_dwmci(host, minmax[1], minmax[0]);
if (ret)
return ret;
+#endif
+ host->mmc->priv = &priv->host;
host->mmc->dev = dev;
upriv->mmc = host->mmc;
return 0;
}
+static int rockchip_dwmmc_bind(struct udevice *dev)
+{
+#ifdef CONFIG_BLK
+ struct rockchip_mmc_plat *plat = dev_get_platdata(dev);
+ int ret;
+
+ ret = dwmci_bind(dev, &plat->mmc, &plat->cfg);
+ if (ret)
+ return ret;
+#endif
+
+ return 0;
+}
+
static const struct udevice_id rockchip_dwmmc_ids[] = {
{ .compatible = "rockchip,rk3288-dw-mshc" },
{ }
@@ -120,8 +149,10 @@ U_BOOT_DRIVER(rockchip_dwmmc_drv) = {
.id = UCLASS_MMC,
.of_match = rockchip_dwmmc_ids,
.ofdata_to_platdata = rockchip_dwmmc_ofdata_to_platdata,
+ .bind = rockchip_dwmmc_bind,
.probe = rockchip_dwmmc_probe,
.priv_auto_alloc_size = sizeof(struct rockchip_dwmmc_priv),
+ .platdata_auto_alloc_size = sizeof(struct rockchip_mmc_plat),
};
#ifdef CONFIG_PWRSEQ
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index ef7e6150f9..5c71ab8d05 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -137,7 +137,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
int trans_bytes = 0, is_aligned = 1;
u32 mask, flags, mode;
unsigned int time = 0, start_addr = 0;
- int mmc_dev = mmc->block_dev.devnum;
+ int mmc_dev = mmc_get_blk_desc(mmc)->devnum;
unsigned start = get_timer(0);
/* Timeout unit - ms */
diff --git a/drivers/video/rockchip/rk_vop.c b/drivers/video/rockchip/rk_vop.c
index a54af172ec..db09d9a41d 100644
--- a/drivers/video/rockchip/rk_vop.c
+++ b/drivers/video/rockchip/rk_vop.c
@@ -326,6 +326,7 @@ static int rk_vop_probe(struct udevice *dev)
if (!ret)
break;
}
+ video_set_flush_dcache(dev, 1);
return ret;
}
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
index 8a81397290..9d50d834db 100644
--- a/include/configs/rk3288_common.h
+++ b/include/configs/rk3288_common.h
@@ -69,7 +69,6 @@
#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img"
#define CONFIG_SPL_PINCTRL_SUPPORT
-#define CONFIG_SPL_GPIO_SUPPORT
#define CONFIG_SPL_RAM_SUPPORT
#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
diff --git a/include/configs/rpi.h b/include/configs/rpi.h
index af58182e7b..9ef5eae304 100644
--- a/include/configs/rpi.h
+++ b/include/configs/rpi.h
@@ -106,6 +106,7 @@
#define CONFIG_USB_STORAGE
#define CONFIG_USB_HOST_ETHER
#define CONFIG_USB_ETHER_SMSC95XX
+#define CONFIG_TFTP_TSIZE
#define CONFIG_MISC_INIT_R
#define CONFIG_USB_KEYBOARD
#define CONFIG_SYS_USB_EVENT_POLL
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index b348ad5231..0bf8707493 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -39,6 +39,30 @@ int device_bind(struct udevice *parent, const struct driver *drv,
struct udevice **devp);
/**
+ * device_bind_with_driver_data() - Create a device and bind it to a driver
+ *
+ * Called to set up a new device attached to a driver, in the case where the
+ * driver was matched to the device by means of a match table that provides
+ * driver_data.
+ *
+ * Once bound a device exists but is not yet active until device_probe() is
+ * called.
+ *
+ * @parent: Pointer to device's parent, under which this driver will exist
+ * @drv: Device's driver
+ * @name: Name of device (e.g. device tree node name)
+ * @driver_data: The driver_data field from the driver's match table.
+ * @of_offset: Offset of device tree node for this device. This is -1 for
+ * devices which don't use device tree.
+ * @devp: if non-NULL, returns a pointer to the bound device
+ * @return 0 if OK, -ve on error
+ */
+int device_bind_with_driver_data(struct udevice *parent,
+ const struct driver *drv, const char *name,
+ ulong driver_data, int of_offset,
+ struct udevice **devp);
+
+/**
* device_bind_by_name: Create a device and bind it to a driver
*
* This is a helper function used to bind devices which do not use device
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index a5cf6e201c..0777cbe27e 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -44,6 +44,7 @@ enum uclass_id {
UCLASS_KEYBOARD, /* Keyboard input device */
UCLASS_LED, /* Light-emitting diode (LED) */
UCLASS_LPC, /* x86 'low pin count' interface */
+ UCLASS_MAILBOX, /* Mailbox controller */
UCLASS_MASS_STORAGE, /* Mass storage device */
UCLASS_MISC, /* Miscellaneous device */
UCLASS_MMC, /* SD / MMC card or chip */
@@ -61,7 +62,6 @@ enum uclass_id {
UCLASS_PWM, /* Pulse-width modulator */
UCLASS_PWRSEQ, /* Power sequence device */
UCLASS_REGULATOR, /* Regulator device */
- UCLASS_RESET, /* Reset device */
UCLASS_REMOTEPROC, /* Remote Processor device */
UCLASS_RTC, /* Real time clock device */
UCLASS_SERIAL, /* Serial UART */
@@ -70,6 +70,7 @@ enum uclass_id {
UCLASS_SPI_FLASH, /* SPI flash */
UCLASS_SPI_GENERIC, /* Generic SPI flash target */
UCLASS_SYSCON, /* System configuration device */
+ UCLASS_SYSRESET, /* System reset device */
UCLASS_THERMAL, /* Thermal sensor */
UCLASS_TIMER, /* Timer device */
UCLASS_TPM, /* Trusted Platform Module TIS interface */
diff --git a/include/dwmmc.h b/include/dwmmc.h
index 05b0817fe1..335af51fdf 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -180,8 +180,9 @@ struct dwmci_host {
* @freq: Frequency the host is trying to achieve
*/
unsigned int (*get_mmc_clk)(struct dwmci_host *host, uint freq);
-
+#ifndef CONFIG_BLK
struct mmc_config cfg;
+#endif
/* use fifo mode to read and write data */
bool fifo_mode;
@@ -223,5 +224,9 @@ static inline u8 dwmci_readb(struct dwmci_host *host, int reg)
return readb(host->ioaddr + reg);
}
+void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
+ uint caps, u32 max_clk, u32 min_clk);
+int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
+
int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk);
#endif /* __DWMMC_HW_H */
diff --git a/include/efi_loader.h b/include/efi_loader.h
index b1ca4ba26b..3332d61cef 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -145,7 +145,7 @@ extern void *efi_bounce_buffer;
#endif
/* Convert strings from normal C strings to uEFI strings */
-static inline void ascii2unicode(u16 *unicode, char *ascii)
+static inline void ascii2unicode(u16 *unicode, const char *ascii)
{
while (*ascii)
*(unicode++) = *(ascii++);
diff --git a/include/mailbox_client.h b/include/mailbox_client.h
new file mode 100644
index 0000000000..8345ea0bf1
--- /dev/null
+++ b/include/mailbox_client.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _MAILBOX_CLIENT_H
+#define _MAILBOX_CLIENT_H
+
+/**
+ * A mailbox is a hardware mechanism for transferring small fixed-size messages
+ * and/or notifications between the CPU on which U-Boot runs and some other
+ * device such as an auxiliary CPU running firmware or a hardware module.
+ *
+ * Data transfer is optional; a mailbox may consist solely of a notification
+ * mechanism. When data transfer is implemented, it is via HW registers or
+ * FIFOs, rather than via RAM-based buffers. The mailbox API generally
+ * implements any communication protocol enforced solely by hardware, and
+ * leaves any higher-level protocols to other layers.
+ *
+ * A mailbox channel is a bi-directional mechanism that can send a message or
+ * notification to a single specific remote entity, and receive messages or
+ * notifications from that entity. The size, content, and format of such
+ * messages is defined by the mailbox implementation, or the remote entity with
+ * which it communicates; there is no general standard at this API level.
+ *
+ * A driver that implements UCLASS_MAILBOX is a mailbox provider. A provider
+ * will often implement multiple separate mailbox channels, since the hardware
+ * it manages often has this capability. mailbox_uclass.h describes the
+ * interface which mailbox providers must implement.
+ *
+ * Mailbox consumers/clients generate and send, or receive and process,
+ * messages. This header file describes the API used by clients.
+ */
+
+struct udevice;
+
+/**
+ * struct mbox_chan - A handle to a single mailbox channel.
+ *
+ * Clients provide storage for channels. The content of the channel structure
+ * is managed solely by the mailbox API and mailbox drivers. A mailbox channel
+ * is initialized by "get"ing the mailbox. The channel struct is passed to all
+ * other mailbox APIs to identify which mailbox to operate upon.
+ *
+ * @dev: The device which implements the mailbox.
+ * @id: The mailbox channel ID within the provider.
+ *
+ * Currently, the mailbox API assumes that a single integer ID is enough to
+ * identify and configure any mailbox channel for any mailbox provider. If this
+ * assumption becomes invalid in the future, the struct could be expanded to
+ * either (a) add more fields to allow mailbox providers to store additional
+ * information, or (b) replace the id field with an opaque pointer, which the
+ * provider would dynamically allocated during its .of_xlate op, and process
+ * during is .request op. This may require the addition of an extra op to clean
+ * up the allocation.
+ */
+struct mbox_chan {
+ struct udevice *dev;
+ /*
+ * Written by of_xlate. We assume a single id is enough for now. In the
+ * future, we might add more fields here.
+ */
+ unsigned long id;
+};
+
+/**
+ * mbox_get_by_index - Get/request a mailbox by integer index
+ *
+ * This looks up and requests a mailbox channel. The index is relative to the
+ * client device; each device is assumed to have n mailbox channels associated
+ * with it somehow, and this function finds and requests one of them. The
+ * mapping of client device channel indices to provider channels may be via
+ * device-tree properties, board-provided mapping tables, or some other
+ * mechanism.
+ *
+ * @dev: The client device.
+ * @index: The index of the mailbox channel to request, within the
+ * client's list of channels.
+ * @chan A pointer to a channel object to initialize.
+ * @return 0 if OK, or a negative error code.
+ */
+int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan);
+
+/**
+ * mbox_get_by_name - Get/request a mailbox by name
+ *
+ * This looks up and requests a mailbox channel. The name is relative to the
+ * client device; each device is assumed to have n mailbox channels associated
+ * with it somehow, and this function finds and requests one of them. The
+ * mapping of client device channel names to provider channels may be via
+ * device-tree properties, board-provided mapping tables, or some other
+ * mechanism.
+ *
+ * @dev: The client device.
+ * @name: The name of the mailbox channel to request, within the client's
+ * list of channels.
+ * @chan A pointer to a channel object to initialize.
+ * @return 0 if OK, or a negative error code.
+ */
+int mbox_get_by_name(struct udevice *dev, const char *name,
+ struct mbox_chan *chan);
+
+/**
+ * mbox_free - Free a previously requested mailbox channel.
+ *
+ * @chan: A channel object that was previously successfully requested by
+ * calling mbox_get_by_*().
+ * @return 0 if OK, or a negative error code.
+ */
+int mbox_free(struct mbox_chan *chan);
+
+/**
+ * mbox_send - Send a message over a mailbox channel
+ *
+ * This function will send a message to the remote entity. It may return before
+ * the remote entity has received and/or processed the message.
+ *
+ * @chan: A channel object that was previously successfully requested by
+ * calling mbox_get_by_*().
+ * @data: A pointer to the message to transfer. The format and size of
+ * the memory region pointed at by @data is determined by the
+ * mailbox provider. Providers that solely transfer notifications
+ * will ignore this parameter.
+ * @return 0 if OK, or a negative error code.
+ */
+int mbox_send(struct mbox_chan *chan, const void *data);
+
+/**
+ * mbox_recv - Receive any available message from a mailbox channel
+ *
+ * This function will wait (up to the specified @timeout_us) for a message to
+ * be sent by the remote entity, and write the content of any such message
+ * into a caller-provided buffer.
+ *
+ * @chan: A channel object that was previously successfully requested by
+ * calling mbox_get_by_*().
+ * @data: A pointer to the buffer to receive the message. The format and
+ * size of the memory region pointed at by @data is determined by
+ * the mailbox provider. Providers that solely transfer
+ * notifications will ignore this parameter.
+ * @timeout_us: The maximum time to wait for a message to be available, in
+ * micro-seconds. A value of 0 does not wait at all.
+ * @return 0 if OK, -ENODATA if no message was available, or a negative error
+ * code.
+ */
+int mbox_recv(struct mbox_chan *chan, void *data, ulong timeout_us);
+
+#endif
diff --git a/include/mailbox_uclass.h b/include/mailbox_uclass.h
new file mode 100644
index 0000000000..6a2994c34c
--- /dev/null
+++ b/include/mailbox_uclass.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _MAILBOX_UCLASS_H
+#define _MAILBOX_UCLASS_H
+
+/* See mailbox_client.h for background documentation. */
+
+#include <mailbox_client.h>
+
+struct udevice;
+
+/**
+ * struct mbox_ops - The functions that a mailbox driver must implement.
+ */
+struct mbox_ops {
+ /**
+ * of_xlate - Translate a client's device-tree (OF) mailbox specifier.
+ *
+ * The mailbox core calls this function as the first step in
+ * implementing a client's mbox_get_by_*() call.
+ *
+ * If this function pointer is set to NULL, the mailbox core will use
+ * a default implementation, which assumes #mbox-cells = <1>, and that
+ * the DT cell contains a simple integer channel ID.
+ *
+ * At present, the mailbox API solely supports device-tree. If this
+ * changes, other xxx_xlate() functions may be added to support those
+ * other mechanisms.
+ *
+ * @chan: The channel to hold the translation result.
+ * @args: The mailbox specifier values from device tree.
+ * @return 0 if OK, or a negative error code.
+ */
+ int (*of_xlate)(struct mbox_chan *chan,
+ struct fdtdec_phandle_args *args);
+ /**
+ * request - Request a translated channel.
+ *
+ * The mailbox core calls this function as the second step in
+ * implementing a client's mbox_get_by_*() call, following a successful
+ * xxx_xlate() call.
+ *
+ * @chan: The channel to request; this has been filled in by a
+ * previoux xxx_xlate() function call.
+ * @return 0 if OK, or a negative error code.
+ */
+ int (*request)(struct mbox_chan *chan);
+ /**
+ * free - Free a previously requested channel.
+ *
+ * This is the implementation of the client mbox_free() API.
+ *
+ * @chan: The channel to free.
+ * @return 0 if OK, or a negative error code.
+ */
+ int (*free)(struct mbox_chan *chan);
+ /**
+ * send - Send a message over a mailbox channel
+ *
+ * @chan: The channel to send to the message to.
+ * @data: A pointer to the message to send.
+ * @return 0 if OK, or a negative error code.
+ */
+ int (*send)(struct mbox_chan *chan, const void *data);
+ /**
+ * recv - Receive any available message from the channel.
+ *
+ * This function does not block. If not message is immediately
+ * available, the function should return an error.
+ *
+ * @chan: The channel to receive to the message from.
+ * @data: A pointer to the buffer to hold the received message.
+ * @return 0 if OK, -ENODATA if no message was available, or a negative
+ * error code.
+ */
+ int (*recv)(struct mbox_chan *chan, void *data);
+};
+
+#endif
diff --git a/include/mmc.h b/include/mmc.h
index a5c6573ddd..7fdfc324fe 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -411,7 +411,6 @@ enum mmc_hwpart_conf_mode {
MMC_HWPART_CONF_COMPLETE,
};
-int mmc_register(struct mmc *mmc);
struct mmc *mmc_create(const struct mmc_config *cfg, void *priv);
/**
@@ -492,16 +491,12 @@ int mmc_start_init(struct mmc *mmc);
*/
void mmc_set_preinit(struct mmc *mmc, int preinit);
-#ifdef CONFIG_GENERIC_MMC
#ifdef CONFIG_MMC_SPI
#define mmc_host_is_spi(mmc) ((mmc)->cfg->host_caps & MMC_MODE_SPI)
#else
#define mmc_host_is_spi(mmc) 0
#endif
struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
-#else
-int mmc_legacy_init(int verbose);
-#endif
void board_mmc_power_init(void);
int board_mmc_init(bd_t *bis);
diff --git a/include/reset.h b/include/reset.h
deleted file mode 100644
index 383761eb1f..0000000000
--- a/include/reset.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2015 Google, Inc
- * Written by Simon Glass <sjg@chromium.org>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef __RESET_H
-#define __RESET_H
-
-enum reset_t {
- RESET_WARM, /* Reset CPU, keep GPIOs active */
- RESET_COLD, /* Reset CPU and GPIOs */
- RESET_POWER, /* Reset PMIC (remove and restore power) */
-
- RESET_COUNT,
-};
-
-struct reset_ops {
- /**
- * request() - request a reset of the given type
- *
- * Note that this function may return before the reset takes effect.
- *
- * @type: Reset type to request
- * @return -EINPROGRESS if the reset has been started and
- * will complete soon, -EPROTONOSUPPORT if not supported
- * by this device, 0 if the reset has already happened
- * (in which case this method will not actually return)
- */
- int (*request)(struct udevice *dev, enum reset_t type);
-};
-
-#define reset_get_ops(dev) ((struct reset_ops *)(dev)->driver->ops)
-
-/**
- * reset_request() - request a reset
- *
- * @type: Reset type to request
- * @return 0 if OK, -EPROTONOSUPPORT if not supported by this device
- */
-int reset_request(struct udevice *dev, enum reset_t type);
-
-/**
- * reset_walk() - cause a reset
- *
- * This works through the available reset devices until it finds one that can
- * perform a reset. If the provided reset type is not available, the next one
- * will be tried.
- *
- * If this function fails to reset, it will display a message and halt
- *
- * @type: Reset type to request
- * @return -EINPROGRESS if a reset is in progress, -ENOSYS if not available
- */
-int reset_walk(enum reset_t type);
-
-/**
- * reset_walk_halt() - try to reset, otherwise halt
- *
- * This calls reset_walk(). If it returns, indicating that reset is not
- * supported, it prints a message and halts.
- */
-void reset_walk_halt(enum reset_t type);
-
-/**
- * reset_cpu() - calls reset_walk(RESET_WARM)
- */
-void reset_cpu(ulong addr);
-
-#endif
diff --git a/include/sysreset.h b/include/sysreset.h
new file mode 100644
index 0000000000..393c7be3d8
--- /dev/null
+++ b/include/sysreset.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __SYSRESET_H
+#define __SYSRESET_H
+
+enum sysreset_t {
+ SYSRESET_WARM, /* Reset CPU, keep GPIOs active */
+ SYSRESET_COLD, /* Reset CPU and GPIOs */
+ SYSRESET_POWER, /* Reset PMIC (remove and restore power) */
+
+ SYSRESET_COUNT,
+};
+
+struct sysreset_ops {
+ /**
+ * request() - request a sysreset of the given type
+ *
+ * Note that this function may return before the reset takes effect.
+ *
+ * @type: Reset type to request
+ * @return -EINPROGRESS if the reset has been started and
+ * will complete soon, -EPROTONOSUPPORT if not supported
+ * by this device, 0 if the reset has already happened
+ * (in which case this method will not actually return)
+ */
+ int (*request)(struct udevice *dev, enum sysreset_t type);
+};
+
+#define sysreset_get_ops(dev) ((struct sysreset_ops *)(dev)->driver->ops)
+
+/**
+ * sysreset_request() - request a sysreset
+ *
+ * @type: Reset type to request
+ * @return 0 if OK, -EPROTONOSUPPORT if not supported by this device
+ */
+int sysreset_request(struct udevice *dev, enum sysreset_t type);
+
+/**
+ * sysreset_walk() - cause a system reset
+ *
+ * This works through the available sysreset devices until it finds one that can
+ * perform a reset. If the provided sysreset type is not available, the next one
+ * will be tried.
+ *
+ * If this function fails to reset, it will display a message and halt
+ *
+ * @type: Reset type to request
+ * @return -EINPROGRESS if a reset is in progress, -ENOSYS if not available
+ */
+int sysreset_walk(enum sysreset_t type);
+
+/**
+ * sysreset_walk_halt() - try to reset, otherwise halt
+ *
+ * This calls sysreset_walk(). If it returns, indicating that reset is not
+ * supported, it prints a message and halts.
+ */
+void sysreset_walk_halt(enum sysreset_t type);
+
+/**
+ * reset_cpu() - calls sysreset_walk(SYSRESET_WARM)
+ */
+void reset_cpu(ulong addr);
+
+#endif
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index c7d4515321..f9ad6156b7 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -8,6 +8,7 @@
#include <common.h>
#include <blk.h>
+#include <dm.h>
#include <efi_loader.h>
#include <inttypes.h>
#include <part.h>
@@ -92,11 +93,10 @@ static efi_status_t EFIAPI efi_disk_rw_blocks(struct efi_block_io *this,
if (buffer_size & (blksz - 1))
return EFI_EXIT(EFI_DEVICE_ERROR);
- if (direction == EFI_DISK_READ) {
- n = desc->block_read(desc, lba, blocks, buffer);
- } else {
- n = desc->block_write(desc, lba, blocks, buffer);
- }
+ if (direction == EFI_DISK_READ)
+ n = blk_dread(desc, lba, blocks, buffer);
+ else
+ n = blk_dwrite(desc, lba, blocks, buffer);
/* We don't do interrupts, so check for timers cooperatively */
efi_timer_check();
@@ -194,8 +194,8 @@ static const struct efi_block_io block_io_disk_template = {
.flush_blocks = &efi_disk_flush_blocks,
};
-static void efi_disk_add_dev(char *name,
- const struct blk_driver *cur_drvr,
+static void efi_disk_add_dev(const char *name,
+ const char *if_typename,
const struct blk_desc *desc,
int dev_index,
lbaint_t offset)
@@ -213,7 +213,7 @@ static void efi_disk_add_dev(char *name,
diskobj->parent.protocols[1].open = efi_disk_open_dp;
diskobj->parent.handle = diskobj;
diskobj->ops = block_io_disk_template;
- diskobj->ifname = cur_drvr->if_typename;
+ diskobj->ifname = if_typename;
diskobj->dev_index = dev_index;
diskobj->offset = offset;
@@ -242,7 +242,7 @@ static void efi_disk_add_dev(char *name,
}
static int efi_disk_create_eltorito(struct blk_desc *desc,
- const struct blk_driver *cur_drvr,
+ const char *if_typename,
int diskid)
{
int disks = 0;
@@ -255,9 +255,10 @@ static int efi_disk_create_eltorito(struct blk_desc *desc,
return 0;
while (!part_get_info(desc, part, &info)) {
- snprintf(devname, sizeof(devname), "%s%d:%d",
- cur_drvr->if_typename, diskid, part);
- efi_disk_add_dev(devname, cur_drvr, desc, diskid, info.start);
+ snprintf(devname, sizeof(devname), "%s%d:%d", if_typename,
+ diskid, part);
+ efi_disk_add_dev(devname, if_typename, desc, diskid,
+ info.start);
part++;
disks++;
}
@@ -271,21 +272,49 @@ static int efi_disk_create_eltorito(struct blk_desc *desc,
* EFI payload, we scan through all of the potentially available ones and
* store them in our object pool.
*
+ * TODO(sjg@chromium.org): Actually with CONFIG_BLK, U-Boot does have this.
+ * Consider converting the code to look up devices as needed. The EFI device
+ * could be a child of the UCLASS_BLK block device, perhaps.
+ *
* This gets called from do_bootefi_exec().
*/
int efi_disk_register(void)
{
- const struct blk_driver *cur_drvr;
- int i, if_type;
int disks = 0;
+#ifdef CONFIG_BLK
+ struct udevice *dev;
+
+ for (uclass_first_device(UCLASS_BLK, &dev);
+ dev;
+ uclass_next_device(&dev)) {
+ struct blk_desc *desc = dev_get_uclass_platdata(dev);
+ const char *if_typename = dev->driver->name;
+
+ printf("Scanning disk %s...\n", dev->name);
+ efi_disk_add_dev(dev->name, if_typename, desc, desc->devnum, 0);
+ disks++;
+
+ /*
+ * El Torito images show up as block devices in an EFI world,
+ * so let's create them here
+ */
+ disks += efi_disk_create_eltorito(desc, if_typename,
+ desc->devnum);
+ }
+#else
+ int i, if_type;
/* Search for all available disk devices */
for (if_type = 0; if_type < IF_TYPE_COUNT; if_type++) {
+ const struct blk_driver *cur_drvr;
+ const char *if_typename;
+
cur_drvr = blk_driver_lookup_type(if_type);
if (!cur_drvr)
continue;
- printf("Scanning disks on %s...\n", cur_drvr->if_typename);
+ if_typename = cur_drvr->if_typename;
+ printf("Scanning disks on %s...\n", if_typename);
for (i = 0; i < 4; i++) {
struct blk_desc *desc;
char devname[32] = { 0 }; /* dp->str is u16[32] long */
@@ -297,17 +326,18 @@ int efi_disk_register(void)
continue;
snprintf(devname, sizeof(devname), "%s%d",
- cur_drvr->if_typename, i);
- efi_disk_add_dev(devname, cur_drvr, desc, i, 0);
+ if_typename, i);
+ efi_disk_add_dev(devname, if_typename, desc, i, 0);
disks++;
/*
* El Torito images show up as block devices
* in an EFI world, so let's create them here
*/
- disks += efi_disk_create_eltorito(desc, cur_drvr, i);
+ disks += efi_disk_create_eltorito(desc, if_typename, i);
}
}
+#endif
printf("Found %d disks\n", disks);
return 0;
diff --git a/lib/tiny-printf.c b/lib/tiny-printf.c
index a06abed495..4b70263df7 100644
--- a/lib/tiny-printf.c
+++ b/lib/tiny-printf.c
@@ -16,6 +16,9 @@
static char *bf;
static char zs;
+/* Current position in sprintf() output string */
+static char *outstr;
+
static void out(char c)
{
*bf++ = c;
@@ -40,7 +43,7 @@ static void div_out(unsigned int *num, unsigned int div)
out_dgt(dgt);
}
-int vprintf(const char *fmt, va_list va)
+int _vprintf(const char *fmt, va_list va, void (*putc)(const char ch))
{
char ch;
char *p;
@@ -52,8 +55,8 @@ int vprintf(const char *fmt, va_list va)
if (ch != '%') {
putc(ch);
} else {
- char lz = 0;
- char w = 0;
+ bool lz = false;
+ int width = 0;
ch = *(fmt++);
if (ch == '0') {
@@ -62,9 +65,9 @@ int vprintf(const char *fmt, va_list va)
}
if (ch >= '0' && ch <= '9') {
- w = 0;
+ width = 0;
while (ch >= '0' && ch <= '9') {
- w = (w * 10) + ch - '0';
+ width = (width * 10) + ch - '0';
ch = *fmt++;
}
}
@@ -73,7 +76,7 @@ int vprintf(const char *fmt, va_list va)
zs = 0;
switch (ch) {
- case 0:
+ case '\0':
goto abort;
case 'u':
case 'd':
@@ -112,9 +115,9 @@ int vprintf(const char *fmt, va_list va)
*bf = 0;
bf = p;
- while (*bf++ && w > 0)
- w--;
- while (w-- > 0)
+ while (*bf++ && width > 0)
+ width--;
+ while (width-- > 0)
putc(lz ? '0' : ' ');
if (p) {
while ((ch = *p++))
@@ -133,8 +136,28 @@ int printf(const char *fmt, ...)
int ret;
va_start(va, fmt);
- ret = vprintf(fmt, va);
+ ret = _vprintf(fmt, va, putc);
+ va_end(va);
+
+ return ret;
+}
+
+static void putc_outstr(char ch)
+{
+ *outstr++ = ch;
+}
+
+/* Note that size is ignored */
+int snprintf(char *buf, size_t size, const char *fmt, ...)
+{
+ va_list va;
+ int ret;
+
+ va_start(va, fmt);
+ outstr = buf;
+ ret = _vprintf(fmt, va, putc_outstr);
va_end(va);
+ *outstr = '\0';
return ret;
}
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 9a11ae0a14..9eaf04b9ba 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -21,12 +21,13 @@ obj-$(CONFIG_DM_ETH) += eth.o
obj-$(CONFIG_DM_GPIO) += gpio.o
obj-$(CONFIG_DM_I2C) += i2c.o
obj-$(CONFIG_LED) += led.o
+obj-$(CONFIG_DM_MAILBOX) += mailbox.o
obj-$(CONFIG_DM_MMC) += mmc.o
obj-$(CONFIG_DM_PCI) += pci.o
obj-$(CONFIG_RAM) += ram.o
obj-y += regmap.o
obj-$(CONFIG_REMOTEPROC) += remoteproc.o
-obj-$(CONFIG_RESET) += reset.o
+obj-$(CONFIG_SYSRESET) += sysreset.o
obj-$(CONFIG_DM_RTC) += rtc.o
obj-$(CONFIG_DM_SPI_FLASH) += sf.o
obj-$(CONFIG_DM_SPI) += spi.o
diff --git a/test/dm/mailbox.c b/test/dm/mailbox.c
new file mode 100644
index 0000000000..be7bd6de06
--- /dev/null
+++ b/test/dm/mailbox.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/test.h>
+#include <asm/mbox.h>
+#include <test/ut.h>
+
+static int dm_test_mailbox(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ uint32_t msg;
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "mbox-test", &dev));
+ ut_assertok(sandbox_mbox_test_get(dev));
+
+ ut_asserteq(-ETIMEDOUT, sandbox_mbox_test_recv(dev, &msg));
+ ut_assertok(sandbox_mbox_test_send(dev, 0xaaff9955UL));
+ ut_assertok(sandbox_mbox_test_recv(dev, &msg));
+ ut_asserteq(msg, 0xaaff9955UL ^ SANDBOX_MBOX_PING_XOR);
+ ut_asserteq(-ETIMEDOUT, sandbox_mbox_test_recv(dev, &msg));
+
+ ut_assertok(sandbox_mbox_test_free(dev));
+
+ return 0;
+}
+DM_TEST(dm_test_mailbox, DM_TESTF_SCAN_FDT);
diff --git a/test/dm/reset.c b/test/dm/reset.c
deleted file mode 100644
index 5d53f252bb..0000000000
--- a/test/dm/reset.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2015 Google, Inc
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-#include <reset.h>
-#include <asm/state.h>
-#include <asm/test.h>
-#include <dm/test.h>
-#include <test/ut.h>
-
-/* Test that we can use particular reset devices */
-static int dm_test_reset_base(struct unit_test_state *uts)
-{
- struct sandbox_state *state = state_get_current();
- struct udevice *dev;
-
- /* Device 0 is the platform data device - it should never respond */
- ut_assertok(uclass_get_device(UCLASS_RESET, 0, &dev));
- ut_asserteq(-ENODEV, reset_request(dev, RESET_WARM));
- ut_asserteq(-ENODEV, reset_request(dev, RESET_COLD));
- ut_asserteq(-ENODEV, reset_request(dev, RESET_POWER));
-
- /* Device 1 is the warm reset device */
- ut_assertok(uclass_get_device(UCLASS_RESET, 1, &dev));
- ut_asserteq(-EACCES, reset_request(dev, RESET_WARM));
- ut_asserteq(-ENOSYS, reset_request(dev, RESET_COLD));
- ut_asserteq(-ENOSYS, reset_request(dev, RESET_POWER));
-
- state->reset_allowed[RESET_WARM] = true;
- ut_asserteq(-EINPROGRESS, reset_request(dev, RESET_WARM));
- state->reset_allowed[RESET_WARM] = false;
-
- /* Device 2 is the cold reset device */
- ut_assertok(uclass_get_device(UCLASS_RESET, 2, &dev));
- ut_asserteq(-ENOSYS, reset_request(dev, RESET_WARM));
- ut_asserteq(-EACCES, reset_request(dev, RESET_COLD));
- state->reset_allowed[RESET_POWER] = false;
- ut_asserteq(-EACCES, reset_request(dev, RESET_POWER));
- state->reset_allowed[RESET_POWER] = true;
-
- return 0;
-}
-DM_TEST(dm_test_reset_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
-
-/* Test that we can walk through the reset devices */
-static int dm_test_reset_walk(struct unit_test_state *uts)
-{
- struct sandbox_state *state = state_get_current();
-
- /* If we generate a power reset, we will exit sandbox! */
- state->reset_allowed[RESET_POWER] = false;
- ut_asserteq(-EACCES, reset_walk(RESET_WARM));
- ut_asserteq(-EACCES, reset_walk(RESET_COLD));
- ut_asserteq(-EACCES, reset_walk(RESET_POWER));
-
- /*
- * Enable cold reset - this should make cold reset work, plus a warm
- * reset should be promoted to cold, since this is the next step
- * along.
- */
- state->reset_allowed[RESET_COLD] = true;
- ut_asserteq(-EINPROGRESS, reset_walk(RESET_WARM));
- ut_asserteq(-EINPROGRESS, reset_walk(RESET_COLD));
- ut_asserteq(-EACCES, reset_walk(RESET_POWER));
- state->reset_allowed[RESET_COLD] = false;
- state->reset_allowed[RESET_POWER] = true;
-
- return 0;
-}
-DM_TEST(dm_test_reset_walk, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/dm/sysreset.c b/test/dm/sysreset.c
new file mode 100644
index 0000000000..5e94c072b6
--- /dev/null
+++ b/test/dm/sysreset.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <sysreset.h>
+#include <asm/state.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+/* Test that we can use particular sysreset devices */
+static int dm_test_sysreset_base(struct unit_test_state *uts)
+{
+ struct sandbox_state *state = state_get_current();
+ struct udevice *dev;
+
+ /* Device 0 is the platform data device - it should never respond */
+ ut_assertok(uclass_get_device(UCLASS_SYSRESET, 0, &dev));
+ ut_asserteq(-ENODEV, sysreset_request(dev, SYSRESET_WARM));
+ ut_asserteq(-ENODEV, sysreset_request(dev, SYSRESET_COLD));
+ ut_asserteq(-ENODEV, sysreset_request(dev, SYSRESET_POWER));
+
+ /* Device 1 is the warm sysreset device */
+ ut_assertok(uclass_get_device(UCLASS_SYSRESET, 1, &dev));
+ ut_asserteq(-EACCES, sysreset_request(dev, SYSRESET_WARM));
+ ut_asserteq(-ENOSYS, sysreset_request(dev, SYSRESET_COLD));
+ ut_asserteq(-ENOSYS, sysreset_request(dev, SYSRESET_POWER));
+
+ state->sysreset_allowed[SYSRESET_WARM] = true;
+ ut_asserteq(-EINPROGRESS, sysreset_request(dev, SYSRESET_WARM));
+ state->sysreset_allowed[SYSRESET_WARM] = false;
+
+ /* Device 2 is the cold sysreset device */
+ ut_assertok(uclass_get_device(UCLASS_SYSRESET, 2, &dev));
+ ut_asserteq(-ENOSYS, sysreset_request(dev, SYSRESET_WARM));
+ ut_asserteq(-EACCES, sysreset_request(dev, SYSRESET_COLD));
+ state->sysreset_allowed[SYSRESET_POWER] = false;
+ ut_asserteq(-EACCES, sysreset_request(dev, SYSRESET_POWER));
+ state->sysreset_allowed[SYSRESET_POWER] = true;
+
+ return 0;
+}
+DM_TEST(dm_test_sysreset_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that we can walk through the sysreset devices */
+static int dm_test_sysreset_walk(struct unit_test_state *uts)
+{
+ struct sandbox_state *state = state_get_current();
+
+ /* If we generate a power sysreset, we will exit sandbox! */
+ state->sysreset_allowed[SYSRESET_POWER] = false;
+ ut_asserteq(-EACCES, sysreset_walk(SYSRESET_WARM));
+ ut_asserteq(-EACCES, sysreset_walk(SYSRESET_COLD));
+ ut_asserteq(-EACCES, sysreset_walk(SYSRESET_POWER));
+
+ /*
+ * Enable cold system reset - this should make cold system reset work,
+ * plus a warm system reset should be promoted to cold, since this is
+ * the next step along.
+ */
+ state->sysreset_allowed[SYSRESET_COLD] = true;
+ ut_asserteq(-EINPROGRESS, sysreset_walk(SYSRESET_WARM));
+ ut_asserteq(-EINPROGRESS, sysreset_walk(SYSRESET_COLD));
+ ut_asserteq(-EACCES, sysreset_walk(SYSRESET_POWER));
+ state->sysreset_allowed[SYSRESET_COLD] = false;
+ state->sysreset_allowed[SYSRESET_POWER] = true;
+
+ return 0;
+}
+DM_TEST(dm_test_sysreset_walk, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/tools/rkimage.c b/tools/rkimage.c
index f9fdcfa712..ef31cb6944 100644
--- a/tools/rkimage.c
+++ b/tools/rkimage.c
@@ -13,11 +13,6 @@
static uint32_t header;
-static int rkimage_check_params(struct image_tool_params *params)
-{
- return 0;
-}
-
static int rkimage_verify_header(unsigned char *buf, int size,
struct image_tool_params *params)
{
@@ -56,7 +51,7 @@ U_BOOT_IMAGE_TYPE(
"Rockchip Boot Image support",
4,
&header,
- rkimage_check_params,
+ rkcommon_check_params,
rkimage_verify_header,
rkimage_print_header,
rkimage_set_header,
OpenPOWER on IntegriCloud