From a855be87da49ba750e83ecc526235fe33099f76e Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Tue, 3 Apr 2018 11:44:18 +0200 Subject: clk: Add get/enable/disable/release for a bulk of clocks This patch adds a "bulk" API to the clock API in order to get/enable/disable /release a group of clocks associated with a device. This bulk API will avoid adding a copy of the same code to manage a group of clocks in drivers. Signed-off-by: Neil Armstrong Reviewed-by: Simon Glass --- drivers/clk/clk-uclass.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index ad763795d9..6e99b3b15d 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -104,6 +104,39 @@ int clk_get_by_index(struct udevice *dev, int index, struct clk *clk) return clk_get_by_indexed_prop(dev, "clocks", index, clk); } +int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk) +{ + int i, ret, err, count; + + bulk->count = 0; + + count = dev_count_phandle_with_args(dev, "clocks", "#clock-cells"); + if (!count) + return 0; + + bulk->clks = devm_kcalloc(dev, count, sizeof(struct clk), GFP_KERNEL); + if (!bulk->clks) + return -ENOMEM; + + for (i = 0; i < count; i++) { + ret = clk_get_by_index(dev, i, &bulk->clks[i]); + if (ret < 0) + goto bulk_get_err; + + ++bulk->count; + } + + return 0; + +bulk_get_err: + err = clk_release_all(bulk->clks, bulk->count); + if (err) + debug("%s: could release all clocks for %p\n", + __func__, dev); + + return ret; +} + static int clk_set_default_parents(struct udevice *dev) { struct clk clk, parent_clk; @@ -336,6 +369,19 @@ int clk_enable(struct clk *clk) return ops->enable(clk); } +int clk_enable_bulk(struct clk_bulk *bulk) +{ + int i, ret; + + for (i = 0; i < bulk->count; i++) { + ret = clk_enable(&bulk->clks[i]); + if (ret < 0 && ret != -ENOSYS) + return ret; + } + + return 0; +} + int clk_disable(struct clk *clk) { const struct clk_ops *ops = clk_dev_ops(clk->dev); @@ -348,6 +394,19 @@ int clk_disable(struct clk *clk) return ops->disable(clk); } +int clk_disable_bulk(struct clk_bulk *bulk) +{ + int i, ret; + + for (i = 0; i < bulk->count; i++) { + ret = clk_disable(&bulk->clks[i]); + if (ret < 0 && ret != -ENOSYS) + return ret; + } + + return 0; +} + UCLASS_DRIVER(clk) = { .id = UCLASS_CLK, .name = "clk", -- cgit v1.2.1