From f873744c29036cc734ec8ecbedd1a451ce61cef2 Mon Sep 17 00:00:00 2001 From: Jerome Brunet Date: Tue, 24 Sep 2019 14:39:54 +0200 Subject: [PATCH] clk: add terminate callback to clk_ops Add a terminate callback to the clk_ops to release the resources claimed in .init() Signed-off-by: Jerome Brunet Link: https://lkml.kernel.org/r/20190924123954.31561-4-jbrunet@baylibre.com Signed-off-by: Stephen Boyd --- drivers/clk/clk.c | 7 ++++++- include/linux/clk-provider.h | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index b8dc848..ef44167 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -3862,6 +3862,7 @@ static void clk_core_evict_parent_cache(struct clk_core *core) void clk_unregister(struct clk *clk) { unsigned long flags; + const struct clk_ops *ops; if (!clk || WARN_ON_ONCE(IS_ERR(clk))) return; @@ -3870,7 +3871,8 @@ void clk_unregister(struct clk *clk) clk_prepare_lock(); - if (clk->core->ops == &clk_nodrv_ops) { + ops = clk->core->ops; + if (ops == &clk_nodrv_ops) { pr_err("%s: unregistered clock: %s\n", __func__, clk->core->name); goto unlock; @@ -3883,6 +3885,9 @@ void clk_unregister(struct clk *clk) clk->core->ops = &clk_nodrv_ops; clk_enable_unlock(flags); + if (ops->terminate) + ops->terminate(clk->core->hw); + if (!hlist_empty(&clk->core->children)) { struct clk_core *child; struct hlist_node *t; diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index eed243c..013dc66 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h @@ -197,6 +197,8 @@ struct clk_duty { * such as rate or parents. * Returns 0 on success, -EERROR otherwise. * + * @terminate: Free any resource allocated by init. + * * @debug_init: Set up type-specific debugfs entries for this clock. This * is called once, after the debugfs directory entry for this * clock has been created. The dentry pointer representing that @@ -248,6 +250,7 @@ struct clk_ops { int (*set_duty_cycle)(struct clk_hw *hw, struct clk_duty *duty); int (*init)(struct clk_hw *hw); + void (*terminate)(struct clk_hw *hw); void (*debug_init)(struct clk_hw *hw, struct dentry *dentry); }; -- 2.7.4