summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ahci.c14
-rw-r--r--drivers/clk/clk-uclass.c141
-rw-r--r--drivers/clk/clk_sandbox.c56
-rw-r--r--drivers/clk/clk_sandbox_test.c66
-rw-r--r--drivers/clk/imx/clk-imx6q.c21
-rw-r--r--drivers/clk/imx/clk.h18
-rw-r--r--drivers/core/device.c2
-rw-r--r--drivers/gpio/da8xx_gpio.c14
-rw-r--r--drivers/mmc/fsl_esdhc.c43
-rw-r--r--drivers/mtd/nand/raw/brcmnand/brcmnand_compat.c30
-rw-r--r--drivers/mtd/nand/raw/brcmnand/brcmnand_compat.h4
-rw-r--r--drivers/mtd/spi/Kconfig14
-rw-r--r--drivers/mtd/spi/Makefile2
-rw-r--r--drivers/mtd/spi/sf_internal.h2
-rw-r--r--drivers/mtd/spi/sf_probe.c6
-rw-r--r--drivers/mtd/spi/spi-nor-core.c8
-rw-r--r--drivers/mtd/spi/spi-nor-ids.c19
-rw-r--r--drivers/nvme/nvme.c32
-rw-r--r--drivers/phy/phy-uclass.c30
-rw-r--r--drivers/spi/Kconfig18
-rw-r--r--drivers/spi/ath79_spi.c2
-rw-r--r--drivers/spi/bcm63xx_hsspi.c2
-rw-r--r--drivers/spi/bcm63xx_spi.c2
-rw-r--r--drivers/spi/designware_spi.c16
-rw-r--r--drivers/spi/sandbox_spi.c2
-rw-r--r--drivers/spi/spi-uclass.c7
-rw-r--r--drivers/spi/tegra20_sflash.c2
-rw-r--r--drivers/virtio/virtio_pci_legacy.c2
28 files changed, 424 insertions, 151 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 21a89eba5a..d10f9f0bf8 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -50,6 +50,8 @@ struct ahci_uc_priv *probe_ent = NULL;
#define WAIT_MS_FLUSH 5000
#define WAIT_MS_LINKUP 200
+#define AHCI_CAP_S64A BIT(31)
+
__weak void __iomem *ahci_port_base(void __iomem *base, u32 port)
{
return base + 0x100 + (port * 0x80);
@@ -503,9 +505,15 @@ static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port,
}
for (i = 0; i < sg_count; i++) {
- ahci_sg->addr =
- cpu_to_le32((unsigned long) buf + i * MAX_DATA_BYTE_COUNT);
- ahci_sg->addr_hi = 0;
+ /* We assume virt=phys */
+ phys_addr_t pa = (unsigned long)buf + i * MAX_DATA_BYTE_COUNT;
+
+ ahci_sg->addr = cpu_to_le32(lower_32_bits(pa));
+ ahci_sg->addr_hi = cpu_to_le32(upper_32_bits(pa));
+ if (ahci_sg->addr_hi && !(uc_priv->cap & AHCI_CAP_S64A)) {
+ printf("Error: DMA address too high\n");
+ return -1;
+ }
ahci_sg->flags_size = cpu_to_le32(0x3fffff &
(buf_len < MAX_DATA_BYTE_COUNT
? (buf_len - 1)
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 64c181f4ad..9aa8537004 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -178,7 +178,7 @@ bulk_get_err:
return ret;
}
-static int clk_set_default_parents(struct udevice *dev)
+static int clk_set_default_parents(struct udevice *dev, int stage)
{
struct clk clk, parent_clk;
int index;
@@ -214,8 +214,18 @@ static int clk_set_default_parents(struct udevice *dev)
return ret;
}
- ret = clk_set_parent(&clk, &parent_clk);
+ /* This is clk provider device trying to reparent itself
+ * It cannot be done right now but need to wait after the
+ * device is probed
+ */
+ if (stage == 0 && clk.dev == dev)
+ continue;
+
+ if (stage > 0 && clk.dev != dev)
+ /* do not setup twice the parent clocks */
+ continue;
+ ret = clk_set_parent(&clk, &parent_clk);
/*
* Not all drivers may support clock-reparenting (as of now).
* Ignore errors due to this.
@@ -223,7 +233,7 @@ static int clk_set_default_parents(struct udevice *dev)
if (ret == -ENOSYS)
continue;
- if (ret) {
+ if (ret < 0) {
debug("%s: failed to reparent clock %d for %s\n",
__func__, index, dev_read_name(dev));
return ret;
@@ -233,7 +243,7 @@ static int clk_set_default_parents(struct udevice *dev)
return 0;
}
-static int clk_set_default_rates(struct udevice *dev)
+static int clk_set_default_rates(struct udevice *dev, int stage)
{
struct clk clk;
int index;
@@ -268,7 +278,19 @@ static int clk_set_default_rates(struct udevice *dev)
continue;
}
+ /* This is clk provider device trying to program itself
+ * It cannot be done right now but need to wait after the
+ * device is probed
+ */
+ if (stage == 0 && clk.dev == dev)
+ continue;
+
+ if (stage > 0 && clk.dev != dev)
+ /* do not setup twice the parent clocks */
+ continue;
+
ret = clk_set_rate(&clk, rates[index]);
+
if (ret < 0) {
debug("%s: failed to set rate on clock index %d (%ld) for %s\n",
__func__, index, clk.id, dev_read_name(dev));
@@ -281,7 +303,7 @@ fail:
return ret;
}
-int clk_set_defaults(struct udevice *dev)
+int clk_set_defaults(struct udevice *dev, int stage)
{
int ret;
@@ -294,11 +316,11 @@ int clk_set_defaults(struct udevice *dev)
debug("%s(%s)\n", __func__, dev_read_name(dev));
- ret = clk_set_default_parents(dev);
+ ret = clk_set_default_parents(dev, stage);
if (ret)
return ret;
- ret = clk_set_default_rates(dev);
+ ret = clk_set_default_rates(dev, stage);
if (ret < 0)
return ret;
@@ -349,9 +371,12 @@ int clk_release_all(struct clk *clk, int count)
int clk_request(struct udevice *dev, struct clk *clk)
{
- const struct clk_ops *ops = clk_dev_ops(dev);
+ const struct clk_ops *ops;
debug("%s(dev=%p, clk=%p)\n", __func__, dev, clk);
+ if (!clk)
+ return 0;
+ ops = clk_dev_ops(dev);
clk->dev = dev;
@@ -363,9 +388,12 @@ int clk_request(struct udevice *dev, struct clk *clk)
int clk_free(struct clk *clk)
{
- const struct clk_ops *ops = clk_dev_ops(clk->dev);
+ const struct clk_ops *ops;
debug("%s(clk=%p)\n", __func__, clk);
+ if (!clk)
+ return 0;
+ ops = clk_dev_ops(clk->dev);
if (!ops->free)
return 0;
@@ -375,9 +403,12 @@ int clk_free(struct clk *clk)
ulong clk_get_rate(struct clk *clk)
{
- const struct clk_ops *ops = clk_dev_ops(clk->dev);
+ const struct clk_ops *ops;
debug("%s(clk=%p)\n", __func__, clk);
+ if (!clk)
+ return 0;
+ ops = clk_dev_ops(clk->dev);
if (!ops->get_rate)
return -ENOSYS;
@@ -391,6 +422,8 @@ struct clk *clk_get_parent(struct clk *clk)
struct clk *pclk;
debug("%s(clk=%p)\n", __func__, clk);
+ if (!clk)
+ return NULL;
pdev = dev_get_parent(clk->dev);
pclk = dev_get_clk_ptr(pdev);
@@ -406,6 +439,8 @@ long long clk_get_parent_rate(struct clk *clk)
struct clk *pclk;
debug("%s(clk=%p)\n", __func__, clk);
+ if (!clk)
+ return 0;
pclk = clk_get_parent(clk);
if (IS_ERR(pclk))
@@ -424,9 +459,12 @@ long long clk_get_parent_rate(struct clk *clk)
ulong clk_set_rate(struct clk *clk, ulong rate)
{
- const struct clk_ops *ops = clk_dev_ops(clk->dev);
+ const struct clk_ops *ops;
debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate);
+ if (!clk)
+ return 0;
+ ops = clk_dev_ops(clk->dev);
if (!ops->set_rate)
return -ENOSYS;
@@ -436,9 +474,12 @@ ulong clk_set_rate(struct clk *clk, ulong rate)
int clk_set_parent(struct clk *clk, struct clk *parent)
{
- const struct clk_ops *ops = clk_dev_ops(clk->dev);
+ const struct clk_ops *ops;
debug("%s(clk=%p, parent=%p)\n", __func__, clk, parent);
+ if (!clk)
+ return 0;
+ ops = clk_dev_ops(clk->dev);
if (!ops->set_parent)
return -ENOSYS;
@@ -448,11 +489,14 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
int clk_enable(struct clk *clk)
{
- const struct clk_ops *ops = clk_dev_ops(clk->dev);
+ const struct clk_ops *ops;
struct clk *clkp = NULL;
int ret;
debug("%s(clk=%p)\n", __func__, clk);
+ if (!clk)
+ return 0;
+ ops = clk_dev_ops(clk->dev);
if (CONFIG_IS_ENABLED(CLK_CCF)) {
/* Take id 0 as a non-valid clk, such as dummy */
@@ -505,11 +549,14 @@ int clk_enable_bulk(struct clk_bulk *bulk)
int clk_disable(struct clk *clk)
{
- const struct clk_ops *ops = clk_dev_ops(clk->dev);
+ const struct clk_ops *ops;
struct clk *clkp = NULL;
int ret;
debug("%s(clk=%p)\n", __func__, clk);
+ if (!clk)
+ return 0;
+ ops = clk_dev_ops(clk->dev);
if (CONFIG_IS_ENABLED(CLK_CCF)) {
if (clk->id && !clk_get_by_id(clk->id, &clkp)) {
@@ -589,6 +636,10 @@ bool clk_is_match(const struct clk *p, const struct clk *q)
if (p == q)
return true;
+ /* trivial case #2: on the clk pointer is NULL */
+ if (!p || !q)
+ return false;
+
/* same device, id and data */
if (p->dev == q->dev && p->id == q->id && p->data == q->data)
return true;
@@ -596,7 +647,69 @@ bool clk_is_match(const struct clk *p, const struct clk *q)
return false;
}
+static void devm_clk_release(struct udevice *dev, void *res)
+{
+ clk_free(res);
+}
+
+static int devm_clk_match(struct udevice *dev, void *res, void *data)
+{
+ return res == data;
+}
+
+struct clk *devm_clk_get(struct udevice *dev, const char *id)
+{
+ int rc;
+ struct clk *clk;
+
+ clk = devres_alloc(devm_clk_release, sizeof(struct clk), __GFP_ZERO);
+ if (unlikely(!clk))
+ return ERR_PTR(-ENOMEM);
+
+ rc = clk_get_by_name(dev, id, clk);
+ if (rc)
+ return ERR_PTR(rc);
+
+ devres_add(dev, clk);
+ return clk;
+}
+
+struct clk *devm_clk_get_optional(struct udevice *dev, const char *id)
+{
+ struct clk *clk = devm_clk_get(dev, id);
+
+ if (IS_ERR(clk))
+ return NULL;
+
+ return clk;
+}
+
+void devm_clk_put(struct udevice *dev, struct clk *clk)
+{
+ int rc;
+
+ if (!clk)
+ return;
+
+ rc = devres_release(dev, devm_clk_release, devm_clk_match, clk);
+ WARN_ON(rc);
+}
+
+int clk_uclass_post_probe(struct udevice *dev)
+{
+ /*
+ * when a clock provider is probed. Call clk_set_defaults()
+ * also after the device is probed. This takes care of cases
+ * where the DT is used to setup default parents and rates
+ * using assigned-clocks
+ */
+ clk_set_defaults(dev, 1);
+
+ return 0;
+}
+
UCLASS_DRIVER(clk) = {
.id = UCLASS_CLK,
.name = "clk",
+ .post_probe = clk_uclass_post_probe,
};
diff --git a/drivers/clk/clk_sandbox.c b/drivers/clk/clk_sandbox.c
index 1d5cbb589a..de6b2f7c82 100644
--- a/drivers/clk/clk_sandbox.c
+++ b/drivers/clk/clk_sandbox.c
@@ -10,14 +10,19 @@
#include <asm/clk.h>
struct sandbox_clk_priv {
+ bool probed;
ulong rate[SANDBOX_CLK_ID_COUNT];
bool enabled[SANDBOX_CLK_ID_COUNT];
+ bool requested[SANDBOX_CLK_ID_COUNT];
};
static ulong sandbox_clk_get_rate(struct clk *clk)
{
struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
+ if (!priv->probed)
+ return -ENODEV;
+
if (clk->id >= SANDBOX_CLK_ID_COUNT)
return -EINVAL;
@@ -29,6 +34,9 @@ static ulong sandbox_clk_set_rate(struct clk *clk, ulong rate)
struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
ulong old_rate;
+ if (!priv->probed)
+ return -ENODEV;
+
if (clk->id >= SANDBOX_CLK_ID_COUNT)
return -EINVAL;
@@ -45,6 +53,9 @@ static int sandbox_clk_enable(struct clk *clk)
{
struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
+ if (!priv->probed)
+ return -ENODEV;
+
if (clk->id >= SANDBOX_CLK_ID_COUNT)
return -EINVAL;
@@ -57,6 +68,9 @@ static int sandbox_clk_disable(struct clk *clk)
{
struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
+ if (!priv->probed)
+ return -ENODEV;
+
if (clk->id >= SANDBOX_CLK_ID_COUNT)
return -EINVAL;
@@ -65,13 +79,45 @@ static int sandbox_clk_disable(struct clk *clk)
return 0;
}
+static int sandbox_clk_request(struct clk *clk)
+{
+ struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
+
+ if (clk->id >= SANDBOX_CLK_ID_COUNT)
+ return -EINVAL;
+
+ priv->requested[clk->id] = true;
+ return 0;
+}
+
+static int sandbox_clk_free(struct clk *clk)
+{
+ struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
+
+ if (clk->id >= SANDBOX_CLK_ID_COUNT)
+ return -EINVAL;
+
+ priv->requested[clk->id] = false;
+ return 0;
+}
+
static struct clk_ops sandbox_clk_ops = {
.get_rate = sandbox_clk_get_rate,
.set_rate = sandbox_clk_set_rate,
.enable = sandbox_clk_enable,
.disable = sandbox_clk_disable,
+ .request = sandbox_clk_request,
+ .free = sandbox_clk_free,
};
+static int sandbox_clk_probe(struct udevice *dev)
+{
+ struct sandbox_clk_priv *priv = dev_get_priv(dev);
+
+ priv->probed = true;
+ return 0;
+}
+
static const struct udevice_id sandbox_clk_ids[] = {
{ .compatible = "sandbox,clk" },
{ }
@@ -82,6 +128,7 @@ U_BOOT_DRIVER(clk_sandbox) = {
.id = UCLASS_CLK,
.of_match = sandbox_clk_ids,
.ops = &sandbox_clk_ops,
+ .probe = sandbox_clk_probe,
.priv_auto_alloc_size = sizeof(struct sandbox_clk_priv),
};
@@ -104,3 +151,12 @@ int sandbox_clk_query_enable(struct udevice *dev, int id)
return priv->enabled[id];
}
+
+int sandbox_clk_query_requested(struct udevice *dev, int id)
+{
+ struct sandbox_clk_priv *priv = dev_get_priv(dev);
+
+ if (id < 0 || id >= SANDBOX_CLK_ID_COUNT)
+ return -EINVAL;
+ return priv->requested[id];
+}
diff --git a/drivers/clk/clk_sandbox_test.c b/drivers/clk/clk_sandbox_test.c
index e8465dbfad..41954660ea 100644
--- a/drivers/clk/clk_sandbox_test.c
+++ b/drivers/clk/clk_sandbox_test.c
@@ -9,7 +9,8 @@
#include <asm/clk.h>
struct sandbox_clk_test {
- struct clk clks[SANDBOX_CLK_TEST_ID_COUNT];
+ struct clk clks[SANDBOX_CLK_TEST_NON_DEVM_COUNT];
+ struct clk *clkps[SANDBOX_CLK_TEST_ID_COUNT];
struct clk_bulk bulk;
};
@@ -24,7 +25,7 @@ int sandbox_clk_test_get(struct udevice *dev)
struct sandbox_clk_test *sbct = dev_get_priv(dev);
int i, ret;
- for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) {
+ for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++) {
ret = clk_get_by_name(dev, sandbox_clk_test_names[i],
&sbct->clks[i]);
if (ret)
@@ -34,6 +35,37 @@ int sandbox_clk_test_get(struct udevice *dev)
return 0;
}
+int sandbox_clk_test_devm_get(struct udevice *dev)
+{
+ struct sandbox_clk_test *sbct = dev_get_priv(dev);
+ struct clk *clk;
+
+ clk = devm_clk_get(dev, "no-an-existing-clock");
+ if (!IS_ERR(clk)) {
+ dev_err(dev, "devm_clk_get() should have failed\n");
+ return -EINVAL;
+ }
+
+ clk = devm_clk_get(dev, "uart2");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+ sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1] = clk;
+
+ clk = devm_clk_get_optional(dev, "uart1");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+ sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM2] = clk;
+
+ sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM_NULL] = NULL;
+ clk = devm_clk_get_optional(dev, "not_an_existing_clock");
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+ if (clk)
+ return -EINVAL;
+
+ return 0;
+}
+
int sandbox_clk_test_get_bulk(struct udevice *dev)
{
struct sandbox_clk_test *sbct = dev_get_priv(dev);
@@ -48,7 +80,7 @@ ulong sandbox_clk_test_get_rate(struct udevice *dev, int id)
if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
return -EINVAL;
- return clk_get_rate(&sbct->clks[id]);
+ return clk_get_rate(sbct->clkps[id]);
}
ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate)
@@ -58,7 +90,7 @@ ulong sandbox_clk_test_set_rate(struct udevice *dev, int id, ulong rate)
if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
return -EINVAL;
- return clk_set_rate(&sbct->clks[id], rate);
+ return clk_set_rate(sbct->clkps[id], rate);
}
int sandbox_clk_test_enable(struct udevice *dev, int id)
@@ -68,7 +100,7 @@ int sandbox_clk_test_enable(struct udevice *dev, int id)
if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
return -EINVAL;
- return clk_enable(&sbct->clks[id]);
+ return clk_enable(sbct->clkps[id]);
}
int sandbox_clk_test_enable_bulk(struct udevice *dev)
@@ -85,7 +117,7 @@ int sandbox_clk_test_disable(struct udevice *dev, int id)
if (id < 0 || id >= SANDBOX_CLK_TEST_ID_COUNT)
return -EINVAL;
- return clk_disable(&sbct->clks[id]);
+ return clk_disable(sbct->clkps[id]);
}
int sandbox_clk_test_disable_bulk(struct udevice *dev)
@@ -100,7 +132,8 @@ int sandbox_clk_test_free(struct udevice *dev)
struct sandbox_clk_test *sbct = dev_get_priv(dev);
int i, ret;
- for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) {
+ devm_clk_put(dev, sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1]);
+ for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++) {
ret = clk_free(&sbct->clks[i]);
if (ret)
return ret;
@@ -122,13 +155,27 @@ int sandbox_clk_test_valid(struct udevice *dev)
int i;
for (i = 0; i < SANDBOX_CLK_TEST_ID_COUNT; i++) {
- if (!clk_valid(&sbct->clks[i]))
- return -EINVAL;
+ if (!clk_valid(sbct->clkps[i]))
+ if (i != SANDBOX_CLK_TEST_ID_DEVM_NULL)
+ return -EINVAL;
}
return 0;
}
+static int sandbox_clk_test_probe(struct udevice *dev)
+{
+ struct sandbox_clk_test *sbct = dev_get_priv(dev);
+ int i;
+
+ for (i = 0; i < SANDBOX_CLK_TEST_ID_DEVM1; i++)
+ sbct->clkps[i] = &sbct->clks[i];
+ for (i = SANDBOX_CLK_TEST_ID_DEVM1; i < SANDBOX_CLK_TEST_ID_COUNT; i++)
+ sbct->clkps[i] = NULL;
+
+ return 0;
+}
+
static const struct udevice_id sandbox_clk_test_ids[] = {
{ .compatible = "sandbox,clk-test" },
{ }
@@ -138,5 +185,6 @@ U_BOOT_DRIVER(sandbox_clk_test) = {
.name = "sandbox_clk_test",
.id = UCLASS_MISC,
.of_match = sandbox_clk_test_ids,
+ .probe = sandbox_clk_test_probe,
.priv_auto_alloc_size = sizeof(struct sandbox_clk_test),
};
diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
index 92e9337d44..5ae4781d11 100644
--- a/drivers/clk/imx/clk-imx6q.c
+++ b/drivers/clk/imx/clk-imx6q.c
@@ -89,6 +89,9 @@ static struct clk_ops imx6q_clk_ops = {
};
static const char *const usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", };
+static const char *const periph_sels[] = { "periph_pre", "periph_clk2", };
+static const char *const periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m",
+ "pll2_pfd0_352m", "pll2_198m", };
static int imx6q_clk_probe(struct udevice *dev)
{
@@ -161,6 +164,24 @@ static int imx6q_clk_probe(struct udevice *dev)
clk_dm(IMX6QDL_CLK_USDHC4,
imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8));
+ clk_dm(IMX6QDL_CLK_PERIPH_PRE,
+ imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels,
+ ARRAY_SIZE(periph_pre_sels)));
+ clk_dm(IMX6QDL_CLK_PERIPH,
+ imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48,
+ 5, periph_sels, ARRAY_SIZE(periph_sels)));
+ clk_dm(IMX6QDL_CLK_AHB,
+ imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3,
+ base + 0x48, 1));
+ clk_dm(IMX6QDL_CLK_IPG,
+ imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2));
+ clk_dm(IMX6QDL_CLK_IPG_PER,
+ imx_clk_divider("ipg_per", "ipg", base + 0x1c, 0, 6));
+ clk_dm(IMX6QDL_CLK_I2C1,
+ imx_clk_gate2("i2c1", "ipg_per", base + 0x70, 6));
+ clk_dm(IMX6QDL_CLK_I2C2,
+ imx_clk_gate2("i2c2", "ipg_per", base + 0x70, 8));
+
return 0;
}
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 4956e04a92..07dcf94ea5 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -92,6 +92,14 @@ static inline struct clk *imx_clk_divider(const char *name, const char *parent,
reg, shift, width, 0);
}
+static inline struct clk *
+imx_clk_busy_divider(const char *name, const char *parent, void __iomem *reg,
+ u8 shift, u8 width, void __iomem *busy_reg, u8 busy_shift)
+{
+ return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
+ reg, shift, width, 0);
+}
+
static inline struct clk *imx_clk_divider2(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width)
{
@@ -126,6 +134,16 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
width, 0);
}
+static inline struct clk *
+imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, u8 width,
+ void __iomem *busy_reg, u8 busy_shift,
+ const char * const *parents, int num_parents)
+{
+ return clk_register_mux(NULL, name, parents, num_parents,
+ CLK_SET_RATE_NO_REPARENT, reg, shift,
+ width, 0);
+}
+
static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
u8 shift, u8 width, const char * const *parents,
int num_parents)
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 95f26efdd3..8eabaf8b55 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -423,7 +423,7 @@ int device_probe(struct udevice *dev)
* Process 'assigned-{clocks/clock-parents/clock-rates}'
* properties
*/
- ret = clk_set_defaults(dev);
+ ret = clk_set_defaults(dev, 0);
if (ret)
goto fail;
}
diff --git a/drivers/gpio/da8xx_gpio.c b/drivers/gpio/da8xx_gpio.c
index bd79448164..0a50c68d72 100644
--- a/drivers/gpio/da8xx_gpio.c
+++ b/drivers/gpio/da8xx_gpio.c
@@ -342,13 +342,6 @@ int gpio_free(unsigned int gpio)
}
#endif
-static int _gpio_direction_output(struct davinci_gpio *bank, unsigned int gpio, int value)
-{
- clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio));
- gpio_set_value(gpio, value);
- return 0;
-}
-
static int _gpio_direction_input(struct davinci_gpio *bank, unsigned int gpio)
{
setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio));
@@ -377,6 +370,13 @@ static int _gpio_get_dir(struct davinci_gpio *bank, unsigned int gpio)
return in_le32(&bank->dir) & (1U << GPIO_BIT(gpio));
}
+static int _gpio_direction_output(struct davinci_gpio *bank, unsigned int gpio,
+ int value)
+{
+ clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio));
+ _gpio_set_value(bank, gpio, value);
+ return 0;
+}
#ifndef CONFIG_DM_GPIO
void gpio_info(void)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 28d2312ef7..cd357ea411 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -23,10 +23,6 @@
#include <asm/io.h>
#include <dm.h>
-#if !CONFIG_IS_ENABLED(BLK)
-#include "mmc_private.h"
-#endif
-
DECLARE_GLOBAL_DATA_PTR;
#define SDHCI_IRQ_EN_BITS (IRQSTATEN_CC | IRQSTATEN_TC | \
@@ -35,7 +31,6 @@ DECLARE_GLOBAL_DATA_PTR;
IRQSTATEN_CIE | IRQSTATEN_DTOE | IRQSTATEN_DCE | \
IRQSTATEN_DEBE | IRQSTATEN_BRR | IRQSTATEN_BWR | \
IRQSTATEN_DINT)
-#define ESDHC_DRIVER_STAGE_VALUE 0xffffffff
struct fsl_esdhc {
uint dsaddr; /* SDMA system address register */
@@ -98,7 +93,7 @@ struct fsl_esdhc_priv {
struct clk per_clk;
unsigned int clock;
unsigned int bus_width;
-#if !CONFIG_IS_ENABLED(BLK)
+#if !CONFIG_IS_ENABLED(DM_MMC)
struct mmc *mmc;
#endif
struct udevice *dev;
@@ -506,7 +501,6 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock)
struct fsl_esdhc *regs = priv->esdhc_regs;
int div = 1;
int pre_div = 2;
- int ddr_pre_div = mmc->ddr_mode ? 2 : 1;
unsigned int sdhc_clk = priv->sdhc_clk;
u32 time_out;
u32 value;
@@ -515,10 +509,10 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock)
if (clock < mmc->cfg->f_min)
clock = mmc->cfg->f_min;
- while (sdhc_clk / (16 * pre_div * ddr_pre_div) > clock && pre_div < 256)
+ while (sdhc_clk / (16 * pre_div) > clock && pre_div < 256)
pre_div *= 2;
- while (sdhc_clk / (div * pre_div * ddr_pre_div) > clock && div < 16)
+ while (sdhc_clk / (div * pre_div) > clock && div < 16)
div++;
pre_div >>= 1;
@@ -778,9 +772,6 @@ static int fsl_esdhc_init(struct fsl_esdhc_priv *priv,
cfg->host_caps = MMC_MODE_4BIT;
cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
-#ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE
- cfg->host_caps |= MMC_MODE_DDR_52MHz;
-#endif
if (priv->bus_width > 0) {
if (priv->bus_width < 8)
@@ -960,9 +951,6 @@ static int fsl_esdhc_probe(struct udevice *dev)
fdt_addr_t addr;
unsigned int val;
struct mmc *mmc;
-#if !CONFIG_IS_ENABLED(BLK)
- struct blk_desc *bdesc;
-#endif
int ret;
addr = dev_read_addr(dev);
@@ -1028,32 +1016,12 @@ static int fsl_esdhc_probe(struct udevice *dev)
mmc = &plat->mmc;
mmc->cfg = &plat->cfg;
mmc->dev = dev;
-#if !CONFIG_IS_ENABLED(BLK)
- mmc->priv = priv;
-
- /* Setup dsr related values */
- mmc->dsr_imp = 0;
- mmc->dsr = ESDHC_DRIVER_STAGE_VALUE;
- /* Setup the universal parts of the block interface just once */
- bdesc = mmc_get_blk_desc(mmc);
- bdesc->if_type = IF_TYPE_MMC;
- bdesc->removable = 1;
- bdesc->devnum = mmc_get_next_devnum();
- bdesc->block_read = mmc_bread;
- bdesc->block_write = mmc_bwrite;
- bdesc->block_erase = mmc_berase;
-
- /* setup initial part type */
- bdesc->part_type = mmc->cfg->part_type;
- mmc_list_add(mmc);
-#endif
upriv->mmc = mmc;
return esdhc_init_common(priv, mmc);
}
-#if CONFIG_IS_ENABLED(DM_MMC)
static int fsl_esdhc_get_cd(struct udevice *dev)
{
struct fsl_esdhc_priv *priv = dev_get_priv(dev);
@@ -1086,30 +1054,25 @@ static const struct dm_mmc_ops fsl_esdhc_ops = {
.execute_tuning = fsl_esdhc_execute_tuning,
#endif
};
-#endif
static const struct udevice_id fsl_esdhc_ids[] = {
{ .compatible = "fsl,esdhc", },
{ /* sentinel */ }
};
-#if CONFIG_IS_ENABLED(BLK)
static int fsl_esdhc_bind(struct udevice *dev)
{
struct fsl_esdhc_plat *plat = dev_get_platdata(dev);
return mmc_bind(dev, &plat->mmc, &plat->cfg);
}
-#endif
U_BOOT_DRIVER(fsl_esdhc) = {
.name = "fsl-esdhc-mmc",
.id = UCLASS_MMC,
.of_match = fsl_esdhc_ids,
.ops = &fsl_esdhc_ops,
-#if CONFIG_IS_ENABLED(BLK)
.bind = fsl_esdhc_bind,
-#endif
.probe = fsl_esdhc_probe,
.platdata_auto_alloc_size = sizeof(struct fsl_esdhc_plat),
.priv_auto_alloc_size = sizeof(struct fsl_esdhc_priv),
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.c b/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.c
index 96b27e6e5a..883948355c 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.c
@@ -3,36 +3,6 @@
#include <common.h>
#include "brcmnand_compat.h"
-struct clk *devm_clk_get(struct udevice *dev, const char *id)
-{
- struct clk *clk;
- int ret;
-
- clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
- if (!clk) {
- debug("%s: can't allocate clock\n", __func__);
- return ERR_PTR(-ENOMEM);
- }
-
- ret = clk_get_by_name(dev, id, clk);
- if (ret < 0) {
- debug("%s: can't get clock (ret = %d)!\n", __func__, ret);
- return ERR_PTR(ret);
- }
-
- return clk;
-}
-
-int clk_prepare_enable(struct clk *clk)
-{
- return clk_enable(clk);
-}
-
-void clk_disable_unprepare(struct clk *clk)
-{
- clk_disable(clk);
-}
-
static char *devm_kvasprintf(struct udevice *dev, gfp_t gfp, const char *fmt,
va_list ap)
{
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.h b/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.h
index 02cab0f828..6f9bec7085 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.h
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand_compat.h
@@ -6,10 +6,6 @@
#include <clk.h>
#include <dm.h>
-struct clk *devm_clk_get(struct udevice *dev, const char *id);
-int clk_prepare_enable(struct clk *clk);
-void clk_disable_unprepare(struct clk *clk);
-
char *devm_kasprintf(struct udevice *dev, gfp_t gfp, const char *fmt, ...);
#endif /* __BRCMNAND_COMPAT_H */
diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index d3b007a731..d77f818505 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -3,6 +3,7 @@ menu "SPI Flash Support"
config DM_SPI_FLASH
bool "Enable Driver Model for SPI flash"
depends on DM && DM_SPI
+ imply SPI_FLASH
help
Enable driver model for SPI flash. This SPI flash interface
(spi_flash_probe(), spi_flash_write(), etc.) is then
@@ -26,11 +27,10 @@ config SPI_FLASH_SANDBOX
stored in a file on the host filesystem.
config SPI_FLASH
- bool "Legacy SPI Flash Interface support"
- depends on SPI
+ bool "SPI Flash Core Interface support"
select SPI_MEM
help
- Enable the legacy SPI flash support. This will include basic
+ Enable the SPI flash Core support. This will include basic
standard support for things like probing, read / write, and
erasing through cmd_sf interface.
@@ -196,4 +196,12 @@ config SPI_FLASH_MTD
If unsure, say N
+config SPL_SPI_FLASH_MTD
+ bool "SPI flash MTD support for SPL"
+ depends on SPI_FLASH
+ help
+ Enable the MTD support for the SPI flash layer in SPL.
+
+ If unsure, say N
+
endmenu # menu "SPI Flash Support"
diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile
index 20db1015d9..b5dfa300de 100644
--- a/drivers/mtd/spi/Makefile
+++ b/drivers/mtd/spi/Makefile
@@ -19,5 +19,5 @@ endif
obj-$(CONFIG_SPI_FLASH) += spi-nor.o
obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o
-obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o
+obj-$(CONFIG_$(SPL_)SPI_FLASH_MTD) += sf_mtd.o
obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o
diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index bb8c19a31c..5c643034c6 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -77,7 +77,7 @@ extern const struct flash_info spi_nor_ids[];
int spi_flash_cmd_get_sw_write_prot(struct spi_flash *flash);
-#ifdef CONFIG_SPI_FLASH_MTD
+#if CONFIG_IS_ENABLED(SPI_FLASH_MTD)
int spi_flash_mtd_register(struct spi_flash *flash);
void spi_flash_mtd_unregister(void);
#endif
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 73297e1a0a..f051e473ff 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -44,7 +44,7 @@ static int spi_flash_probe_slave(struct spi_flash *flash)
if (ret)
goto err_read_id;
-#ifdef CONFIG_SPI_FLASH_MTD
+#if CONFIG_IS_ENABLED(SPI_FLASH_MTD)
ret = spi_flash_mtd_register(flash);
#endif
@@ -83,7 +83,7 @@ struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
void spi_flash_free(struct spi_flash *flash)
{
-#ifdef CONFIG_SPI_FLASH_MTD
+#if CONFIG_IS_ENABLED(SPI_FLASH_MTD)
spi_flash_mtd_unregister();
#endif
spi_free_slave(flash->spi);
@@ -152,7 +152,7 @@ static int spi_flash_std_probe(struct udevice *dev)
static int spi_flash_std_remove(struct udevice *dev)
{
-#ifdef CONFIG_SPI_FLASH_MTD
+#if CONFIG_IS_ENABLED(SPI_FLASH_MTD)
spi_flash_mtd_unregister();
#endif
return 0;
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 990e39d7c2..5a8c084255 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -380,12 +380,12 @@ static int spi_nor_fsr_ready(struct spi_nor *nor)
if (fsr & (FSR_E_ERR | FSR_P_ERR)) {
if (fsr & FSR_E_ERR)
- dev_dbg(nor->dev, "Erase operation failed.\n");
+ dev_err(nor->dev, "Erase operation failed.\n");
else
- dev_dbg(nor->dev, "Program operation failed.\n");
+ dev_err(nor->dev, "Program operation failed.\n");
if (fsr & FSR_PT_ERR)
- dev_dbg(nor->dev,
+ dev_err(nor->dev,
"Attempted to modify a protected sector.\n");
nor->write_reg(nor, SPINOR_OP_CLFSR, NULL, 0);
@@ -1916,7 +1916,7 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor,
erasesize = 1U << erasesize;
opcode = (half >> 8) & 0xff;
-#ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
+#ifdef CONFIG_SPI_FLASH_USE_4K_SECTORS
if (erasesize == SZ_4K) {
nor->erase_opcode = opcode;
mtd->erasesize = erasesize;
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 6996c0a286..d3b84574ac 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -58,7 +58,7 @@
* All newly added entries should describe *hardware* and should use SECT_4K
* (or SECT_4K_PMC) if hardware supports erasing 4 KiB sectors. For usage
* scenarios excluding small sectors there is config option that can be
- * disabled: CONFIG_MTD_SPI_NOR_USE_4K_SECTORS.
+ * disabled: CONFIG_SPI_FLASH_USE_4K_SECTORS.
* For historical (and compatibility) reasons (before we got above config) some
* old entries may be missing 4K flag.
*/
@@ -75,6 +75,7 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("at45db161d", 0x1f2600, 0, 64 * 1024, 32, SECT_4K) },
{ INFO("at45db321d", 0x1f2700, 0, 64 * 1024, 64, SECT_4K) },
{ INFO("at45db641d", 0x1f2800, 0, 64 * 1024, 128, SECT_4K) },
+ { INFO("at25sl321", 0x1f4216, 0, 64 * 1024, 64, SECT_4K) },
{ INFO("at26df081a", 0x1f4501, 0, 64 * 1024, 16, SECT_4K) },
#endif
#ifdef CONFIG_SPI_FLASH_EON /* EON */
@@ -128,6 +129,8 @@ const struct flash_info spi_nor_ids[] = {
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ INFO("is25wp128", 0x9d7018, 0, 64 * 1024, 256,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+ { INFO("is25wp256", 0x9d7019, 0, 64 * 1024, 512,
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
#endif
#ifdef CONFIG_SPI_FLASH_MACRONIX /* MACRONIX */
/* Macronix */
@@ -161,12 +164,16 @@ const struct flash_info spi_nor_ids[] = {
{ INFO("n25q064a", 0x20bb17, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_QUAD_READ) },
{ INFO("n25q128a11", 0x20bb18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
{ INFO("n25q128a13", 0x20ba18, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_QUAD_READ) },
- { INFO("n25q256a", 0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
- { INFO("n25q256ax1", 0x20bb19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ { INFO6("mt25ql256a", 0x20ba19, 0x104400, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | USE_FSR) },
+ { INFO("n25q256a", 0x20ba19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_FSR) },
+ { INFO6("mt25qu256a", 0x20bb19, 0x104400, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | USE_FSR) },
+ { INFO("n25q256ax1", 0x20bb19, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_QUAD_READ | USE_FSR) },
{ INFO6("mt25qu512a", 0x20bb20, 0x104400, 64 * 1024, 1024,
- SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
- { INFO("n25q512a", 0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
- { INFO("n25q512ax3", 0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES |
+ USE_FSR) },
+ { INFO("n25q512a", 0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+ { INFO6("mt25ql512a", 0x20ba20, 0x104400, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+ { INFO("n25q512ax3", 0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
{ INFO("n25q00", 0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
{ INFO("n25q00a", 0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
{ INFO("mt25qu02g", 0x20bb22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) },
diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index ee6b581d9e..f915817aaa 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -123,6 +123,9 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2,
}
*prp2 = (ulong)dev->prp_pool;
+ flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool +
+ dev->prp_entry_num * sizeof(u64));
+
return 0;
}
@@ -580,14 +583,19 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
static int nvme_get_info_from_identify(struct nvme_dev *dev)
{
- ALLOC_CACHE_ALIGN_BUFFER(char, buf, sizeof(struct nvme_id_ctrl));
- struct nvme_id_ctrl *ctrl = (struct nvme_id_ctrl *)buf;
+ struct nvme_id_ctrl *ctrl;
int ret;
int shift = NVME_CAP_MPSMIN(dev->cap) + 12;
+ ctrl = memalign(dev->page_size, sizeof(struct nvme_id_ctrl));
+ if (!ctrl)
+ return -ENOMEM;
+
ret = nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl);
- if (ret)
+ if (ret) {
+ free(ctrl);
return -EIO;
+ }
dev->nn = le32_to_cpu(ctrl->nn);
dev->vwc = ctrl->vwc;
@@ -618,6 +626,7 @@ static int nvme_get_info_from_identify(struct nvme_dev *dev)
dev->max_transfer_shift = 20;
}
+ free(ctrl);
return 0;
}
@@ -658,16 +667,21 @@ static int nvme_blk_probe(struct udevice *udev)
struct blk_desc *desc = dev_get_uclass_platdata(udev);
struct nvme_ns *ns = dev_get_priv(udev);
u8 flbas;
- ALLOC_CACHE_ALIGN_BUFFER(char, buf, sizeof(struct nvme_id_ns));
- struct nvme_id_ns *id = (struct nvme_id_ns *)buf;
struct pci_child_platdata *pplat;
+ struct nvme_id_ns *id;
+
+ id = memalign(ndev->page_size, sizeof(struct nvme_id_ns));
+ if (!id)
+ return -ENOMEM;
memset(ns, 0, sizeof(*ns));
ns->dev = ndev;
/* extract the namespace id from the block device name */
ns->ns_id = trailing_strtol(udev->name) + 1;
- if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id))
+ if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id)) {
+ free(id);
return -EIO;
+ }
memcpy(&ns->eui64, &id->eui64, sizeof(id->eui64));
flbas = id->flbas & NVME_NS_FLBAS_LBA_MASK;
@@ -686,6 +700,7 @@ static int nvme_blk_probe(struct udevice *udev)
memcpy(desc->product, ndev->serial, sizeof(ndev->serial));
memcpy(desc->revision, ndev->firmware_rev, sizeof(ndev->firmware_rev));
+ free(id);
return 0;
}
@@ -705,9 +720,8 @@ static ulong nvme_blk_rw(struct udevice *udev, lbaint_t blknr,
u16 lbas = 1 << (dev->max_transfer_shift - ns->lba_shift);
u64 total_lbas = blkcnt;
- if (!read)
- flush_dcache_range((unsigned long)buffer,
- (unsigned long)buffer + total_len);
+ flush_dcache_range((unsigned long)buffer,
+ (unsigned long)buffer + total_len);
c.rw.opcode = read ? nvme_cmd_read : nvme_cmd_write;
c.rw.flags = 0;
diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c
index a0ac30aa71..e201a90c8c 100644
--- a/drivers/phy/phy-uclass.c
+++ b/drivers/phy/phy-uclass.c
@@ -108,35 +108,55 @@ int generic_phy_get_by_name(struct udevice *dev, const char *phy_name,
int generic_phy_init(struct phy *phy)
{
- struct phy_ops const *ops = phy_dev_ops(phy->dev);
+ struct phy_ops const *ops;
+
+ if (!phy)
+ return 0;
+ ops = phy_dev_ops(phy->dev);
return ops->init ? ops->init(phy) : 0;
}
int generic_phy_reset(struct phy *phy)
{
- struct phy_ops const *ops = phy_dev_ops(phy->dev);
+ struct phy_ops const *ops;
+
+ if (!phy)
+ return 0;
+ ops = phy_dev_ops(phy->dev);
return ops->reset ? ops->reset(phy) : 0;
}
int generic_phy_exit(struct phy *phy)
{
- struct phy_ops const *ops = phy_dev_ops(phy->dev);
+ struct phy_ops const *ops;
+
+ if (!phy)
+ return 0;
+ ops = phy_dev_ops(phy->dev);
return ops->exit ? ops->exit(phy) : 0;
}
int generic_phy_power_on(struct phy *phy)
{
- struct phy_ops const *ops = phy_dev_ops(phy->dev);
+ struct phy_ops const *ops;
+
+ if (!phy)
+ return 0;
+ ops = phy_dev_ops(phy->dev);
return ops->power_on ? ops->power_on(phy) : 0;
}
int generic_phy_power_off(struct phy *phy)
{
- struct phy_ops const *ops = phy_dev_ops(phy->dev);
+ struct phy_ops const *ops;
+
+ if (!phy)
+ return 0;
+ ops = phy_dev_ops(phy->dev);
return ops->power_off ? ops->power_off(phy) : 0;
}
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index b8ca2bdedd..7be867d5b6 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -1,5 +1,22 @@
menuconfig SPI
bool "SPI Support"
+ help
+ The "Serial Peripheral Interface" is a low level synchronous
+ protocol. Chips that support SPI can have data transfer rates
+ up to several tens of Mbit/sec. Chips are addressed with a
+ controller and a chipselect. Most SPI slaves don't support
+ dynamic device discovery; some are even write-only or read-only.
+
+ SPI is widely used by microcontrollers to talk with sensors,
+ eeprom and flash memory, codecs and various other controller
+ chips, analog to digital (and d-to-a) converters, and more.
+ MMC and SD cards can be accessed using SPI protocol; and for
+ DataFlash cards used in MMC sockets, SPI must always be used.
+
+ SPI is one of a family of similar protocols using a four wire
+ interface (select, clock, data in, data out) including Microwire
+ (half duplex), SSP, SSI, and PSP. This driver framework should
+ work with most such devices and controllers.
if SPI
@@ -243,6 +260,7 @@ config SPI_SIFIVE
config SPI_SUNXI
bool "Allwinner SoC SPI controllers"
+ default ARCH_SUNXI
help
Enable the Allwinner SoC SPi controller driver.
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
index 4fd3c050e8..207069218f 100644
--- a/drivers/spi/ath79_spi.c
+++ b/drivers/spi/ath79_spi.c
@@ -198,7 +198,7 @@ static int ath79_cs_info(struct udevice *bus, uint cs,
{
/* Always allow activity on CS 0/1/2 */
if (cs >= 3)
- return -ENODEV;
+ return -EINVAL;
return 0;
}
diff --git a/drivers/spi/bcm63xx_hsspi.c b/drivers/spi/bcm63xx_hsspi.c
index e82b80c107..529adfbc4e 100644
--- a/drivers/spi/bcm63xx_hsspi.c
+++ b/drivers/spi/bcm63xx_hsspi.c
@@ -108,7 +108,7 @@ static int bcm63xx_hsspi_cs_info(struct udevice *bus, uint cs,
if (cs >= priv->num_cs) {
printf("no cs %u\n", cs);
- return -ENODEV;
+ return -EINVAL;
}
return 0;
diff --git a/drivers/spi/bcm63xx_spi.c b/drivers/spi/bcm63xx_spi.c
index 4d19e03523..69f88c9e08 100644
--- a/drivers/spi/bcm63xx_spi.c
+++ b/drivers/spi/bcm63xx_spi.c
@@ -130,7 +130,7 @@ static int bcm63xx_spi_cs_info(struct udevice *bus, uint cs,
if (cs >= priv->num_cs) {
printf("no cs %u\n", cs);
- return -ENODEV;
+ return -EINVAL;
}
return 0;
diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c
index 7d58cfae55..91e613e9cd 100644
--- a/drivers/spi/designware_spi.c
+++ b/drivers/spi/designware_spi.c
@@ -518,8 +518,22 @@ static int dw_spi_set_mode(struct udevice *bus, uint mode)
static int dw_spi_remove(struct udevice *bus)
{
struct dw_spi_priv *priv = dev_get_priv(bus);
+ int ret;
+
+ ret = reset_release_bulk(&priv->resets);
+ if (ret)
+ return ret;
- return reset_release_bulk(&priv->resets);
+#if CONFIG_IS_ENABLED(CLK)
+ ret = clk_disable(&priv->clk);
+ if (ret)
+ return ret;
+
+ ret = clk_free(&priv->clk);
+ if (ret)
+ return ret;
+#endif
+ return 0;
}
static const struct dm_spi_ops dw_spi_ops = {
diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c
index 906401ec8a..16473ec7a0 100644
--- a/drivers/spi/sandbox_spi.c
+++ b/drivers/spi/sandbox_spi.c
@@ -117,7 +117,7 @@ static int sandbox_cs_info(struct udevice *bus, uint cs,
{
/* Always allow activity on CS 0 */
if (cs >= 1)
- return -ENODEV;
+ return -EINVAL;
return 0;
}
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index a4d1b65682..947516073e 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -261,11 +261,10 @@ int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info)
return ops->cs_info(bus, cs, info);
/*
- * We could assume there is at least one valid chip select, but best
- * to be sure and return an error in this case. The driver didn't
- * care enough to tell us.
+ * We could assume there is at least one valid chip select.
+ * The driver didn't care enough to tell us.
*/
- return -ENODEV;
+ return 0;
}
int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp,
diff --git a/drivers/spi/tegra20_sflash.c b/drivers/spi/tegra20_sflash.c
index a54b10fdeb..567e33f156 100644
--- a/drivers/spi/tegra20_sflash.c
+++ b/drivers/spi/tegra20_sflash.c
@@ -78,7 +78,7 @@ int tegra20_sflash_cs_info(struct udevice *bus, unsigned int cs,
{
/* Tegra20 SPI-Flash - only 1 device ('bus/cs') */
if (cs != 0)
- return -ENODEV;
+ return -EINVAL;
else
return 0;
}
diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c
index 08764ee6f2..202e5ab1d3 100644
--- a/drivers/virtio/virtio_pci_legacy.c
+++ b/drivers/virtio/virtio_pci_legacy.c
@@ -277,7 +277,7 @@ static int virtio_pci_notify(struct udevice *udev, struct virtqueue *vq)
static int virtio_pci_bind(struct udevice *udev)
{
- static int num_devs;
+ static unsigned int num_devs;
char name[20];
/* Create a unique device name for PCI type devices */