summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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
23 files changed, 610 insertions, 196 deletions
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;
}
OpenPOWER on IntegriCloud