clk: meson: reset mmc clock on probe
[oweals/u-boot.git] / drivers / clk / clk_sandbox.c
index ef585037fcd493bc7d31a765d0105f911f5359e2..768fbb7c52030f58e8c996ef464bdb7af03d46e6 100644 (file)
@@ -1,24 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * (C) Copyright 2015 Google, Inc
- *
- * SPDX-License-Identifier:    GPL-2.0
  */
 
 #include <common.h>
 #include <clk-uclass.h>
 #include <dm.h>
 #include <errno.h>
+#include <malloc.h>
 #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;
 
@@ -30,6 +35,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;
 
@@ -46,6 +54,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;
 
@@ -58,6 +69,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;
 
@@ -66,13 +80,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,
+       .rfree          = 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" },
        { }
@@ -83,6 +129,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),
 };
 
@@ -105,3 +152,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];
+}