[U-Boot] [PATCH v1 2/5] drivers: clk: Add a managed API to get clocks from the device-tree

Jean-Jacques Hiblot jjhiblot at ti.com
Mon Sep 30 12:29:31 UTC 2019


Add devm_clk_get(), devm_clk_get_optional() to get clocks from the
device-tree. The clocks is automatically released and the data structure
freed when the device is unbound.
Also add devm_clk_put() to release the clock and free the data structure
manually.

Signed-off-by: Jean-Jacques Hiblot <jjhiblot at ti.com>
---

 drivers/clk/clk-uclass.c | 48 ++++++++++++++++++++++++++++++++++++++++
 include/clk.h            | 44 ++++++++++++++++++++++++++++++++++++
 2 files changed, 92 insertions(+)

diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index dff395fedb..e7ec6347de 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -625,6 +625,54 @@ 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);
+}
+
 UCLASS_DRIVER(clk) = {
 	.id		= UCLASS_CLK,
 	.name		= "clk",
diff --git a/include/clk.h b/include/clk.h
index 6568865d40..6c5bf8ad67 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -154,6 +154,37 @@ int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk);
  */
 int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk);
 
+/**
+ * devm_clk_get - lookup and obtain a managed reference to a clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Returns a struct clk corresponding to the clock producer, or
+ * valid IS_ERR() condition containing errno.  The implementation
+ * uses @dev and @id to determine the clock consumer, and thereby
+ * the clock producer.  (IOW, @id may be identical strings, but
+ * clk_get may return different clock producers depending on @dev.)
+ *
+ * Drivers must assume that the clock source is not enabled.
+ *
+ * devm_clk_get should not be called from within interrupt context.
+ *
+ * The clock will automatically be freed when the device is unbound
+ * from the bus.
+ */
+struct clk *devm_clk_get(struct udevice *dev, const char *id);
+
+/**
+ * devm_clk_get_optional - lookup and obtain a managed reference to an optional
+ *			   clock producer.
+ * @dev: device for clock "consumer"
+ * @id: clock consumer ID
+ *
+ * Behaves the same as devm_clk_get() except where there is no clock producer.
+ * In this case, instead of returning -ENOENT, the function returns NULL.
+ */
+struct clk *devm_clk_get_optional(struct udevice *dev, const char *id);
+
 /**
  * clk_release_all() - Disable (turn off)/Free an array of previously
  * requested clocks.
@@ -168,6 +199,19 @@ int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk);
  */
 int clk_release_all(struct clk *clk, int count);
 
+/**
+ * devm_clk_put	- "free" a managed clock source
+ * @dev: device used to acquire the clock
+ * @clk: clock source acquired with devm_clk_get()
+ *
+ * Note: drivers must ensure that all clk_enable calls made on this
+ * clock source are balanced by clk_disable calls prior to calling
+ * this function.
+ *
+ * clk_put should not be called from within interrupt context.
+ */
+void devm_clk_put(struct udevice *dev, struct clk *clk);
+
 #else
 static inline int clk_get_by_index(struct udevice *dev, int index,
 				   struct clk *clk)
-- 
2.17.1



More information about the U-Boot mailing list