Add a terminate callback to the clk_ops to release the resources claimed in .init()
Unified · Split
| @@ -3862,6 +3862,7 @@ static void clk_core_evict_parent_cache(struct clk_core *core) · 3861 unmodified lines | |||
| 3862 | void clk_unregister(struct clk *clk) | 3862 | void clk_unregister(struct clk *clk) |
| 3863 | { | 3863 | { |
| 3864 | unsigned long flags; | 3864 | unsigned long flags; |
| 3865 | const struct clk_ops *ops; | ||
| 3865 | 3866 | ||
| 3866 | if (!clk || WARN_ON_ONCE(IS_ERR(clk))) | 3867 | if (!clk || WARN_ON_ONCE(IS_ERR(clk))) |
| 3867 | return; | 3868 | return; |
| @@ -3870,7 +3871,8 @@ void clk_unregister(struct clk *clk) · 2 unmodified lines | |||
| 3870 | 3871 | ||
| 3871 | clk_prepare_lock(); | 3872 | clk_prepare_lock(); |
| 3872 | 3873 | ||
| 3873 | if (clk->core->ops == &clk_nodrv_ops) { | 3874 | ops = clk->core->ops; |
| 3875 | if (ops == &clk_nodrv_ops) { | ||
| 3874 | pr_err("%s: unregistered clock: %s\n", __func__, | 3876 | pr_err("%s: unregistered clock: %s\n", __func__, |
| 3875 | clk->core->name); | 3877 | clk->core->name); |
| 3876 | goto unlock; | 3878 | goto unlock; |
| @@ -3883,6 +3885,9 @@ void clk_unregister(struct clk *clk) · 6 unmodified lines | |||
| 3883 | clk->core->ops = &clk_nodrv_ops; | 3885 | clk->core->ops = &clk_nodrv_ops; |
| 3884 | clk_enable_unlock(flags); | 3886 | clk_enable_unlock(flags); |
| 3885 | 3887 | ||
| 3888 | if (ops->terminate) | ||
| 3889 | ops->terminate(clk->core->hw); | ||
| 3890 | |||
| 3886 | if (!hlist_empty(&clk->core->children)) { | 3891 | if (!hlist_empty(&clk->core->children)) { |
| 3887 | struct clk_core *child; | 3892 | struct clk_core *child; |
| 3888 | struct hlist_node *t; | 3893 | struct hlist_node *t; |
| @@ -197,6 +197,8 @@ struct clk_duty { · 196 unmodified lines | |||
| 197 | * such as rate or parents. | 197 | * such as rate or parents. |
| 198 | * Returns 0 on success, -EERROR otherwise. | 198 | * Returns 0 on success, -EERROR otherwise. |
| 199 | * | 199 | * |
| 200 | * @terminate: Free any resource allocated by init. | ||
| 201 | * | ||
| 200 | * @debug_init: Set up type-specific debugfs entries for this clock. This | 202 | * @debug_init: Set up type-specific debugfs entries for this clock. This |
| 201 | * is called once, after the debugfs directory entry for this | 203 | * is called once, after the debugfs directory entry for this |
| 202 | * clock has been created. The dentry pointer representing that | 204 | * clock has been created. The dentry pointer representing that |
| @@ -248,6 +250,7 @@ struct clk_ops { · 45 unmodified lines | |||
| 248 | int (*set_duty_cycle)(struct clk_hw *hw, | 250 | int (*set_duty_cycle)(struct clk_hw *hw, |
| 249 | struct clk_duty *duty); | 251 | struct clk_duty *duty); |
| 250 | int (*init)(struct clk_hw *hw); | 252 | int (*init)(struct clk_hw *hw); |
| 253 | void (*terminate)(struct clk_hw *hw); | ||
| 251 | void (*debug_init)(struct clk_hw *hw, struct dentry *dentry); | 254 | void (*debug_init)(struct clk_hw *hw, struct dentry *dentry); |
| 252 | }; | 255 | }; |
| 253 | 256 | ||