summaryrefslogtreecommitdiffstats
path: root/drivers/clk/clk-bulk.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2020-08-27 09:26:11 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2020-09-24 11:42:01 +0200
commita16f065ae6c17704afe4ed6a4fd3772285a86e6e (patch)
treec6e2af7a27df6aa2547a066c28200c5584a36a89 /drivers/clk/clk-bulk.c
parent76cff1a4ae09964cd59fc26e22efda9436e325a2 (diff)
downloadbarebox-a16f065ae6c17704afe4ed6a4fd3772285a86e6e.tar.gz
barebox-a16f065ae6c17704afe4ed6a4fd3772285a86e6e.tar.xz
clk: Add clk_bulk_[get|put]_all()
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/clk/clk-bulk.c')
-rw-r--r--drivers/clk/clk-bulk.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c
index ddbe32f9c2..b8db60dcbc 100644
--- a/drivers/clk/clk-bulk.c
+++ b/drivers/clk/clk-bulk.c
@@ -53,6 +53,86 @@ err:
}
EXPORT_SYMBOL(clk_bulk_get);
+static int __must_check of_clk_bulk_get(struct device_node *np, int num_clks,
+ struct clk_bulk_data *clks)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < num_clks; i++) {
+ clks[i].id = NULL;
+ clks[i].clk = NULL;
+ }
+
+ for (i = 0; i < num_clks; i++) {
+ of_property_read_string_index(np, "clock-names", i, &clks[i].id);
+ clks[i].clk = of_clk_get(np, i);
+ if (IS_ERR(clks[i].clk)) {
+ ret = PTR_ERR(clks[i].clk);
+ pr_err("%pOF: Failed to get clk index: %d ret: %d\n",
+ np, i, ret);
+ clks[i].clk = NULL;
+ goto err;
+ }
+ }
+
+ return 0;
+
+err:
+ clk_bulk_put(i, clks);
+
+ return ret;
+}
+
+static int __must_check of_clk_bulk_get_all(struct device_node *np,
+ struct clk_bulk_data **clks)
+{
+ struct clk_bulk_data *clk_bulk;
+ int num_clks;
+ int ret;
+
+ num_clks = of_clk_get_parent_count(np);
+ if (!num_clks)
+ return 0;
+
+ clk_bulk = kmalloc_array(num_clks, sizeof(*clk_bulk), GFP_KERNEL);
+ if (!clk_bulk)
+ return -ENOMEM;
+
+ ret = of_clk_bulk_get(np, num_clks, clk_bulk);
+ if (ret) {
+ kfree(clk_bulk);
+ return ret;
+ }
+
+ *clks = clk_bulk;
+
+ return num_clks;
+}
+
+void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks)
+{
+ if (IS_ERR_OR_NULL(clks))
+ return;
+
+ clk_bulk_put(num_clks, clks);
+
+ kfree(clks);
+}
+EXPORT_SYMBOL(clk_bulk_put_all);
+
+int __must_check clk_bulk_get_all(struct device_d *dev,
+ struct clk_bulk_data **clks)
+{
+ struct device_node *np = dev->device_node;
+
+ if (!np)
+ return 0;
+
+ return of_clk_bulk_get_all(np, clks);
+}
+EXPORT_SYMBOL(clk_bulk_get_all);
+
/**
* clk_bulk_disable - gate a set of clocks
* @num_clks: the number of clk_bulk_data