Skip to content

Commit 6dd1990

Browse files
wensbebarino
authored andcommitted
clk: mediatek: pll: Implement unregister API
The PLL clk type within the MediaTek clk driver library only has a register function, and no corresponding unregister function. This means there is no way for its users to properly implement cleanup and removal. Add a matching unregister function for the PLL type clk. Signed-off-by: Chen-Yu Tsai <wenst@chromium.org> Reviewed-by: Miles Chen <miles.chen@mediatek.com> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> Link: https://lore.kernel.org/r/20220208124034.414635-14-wenst@chromium.org Reviewed-by: Chun-Jie Chen <chun-jie.chen@mediatek.com> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
1 parent 39691fb commit 6dd1990

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

drivers/clk/mediatek/clk-pll.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,21 @@ static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data,
360360
return clk;
361361
}
362362

363+
static void mtk_clk_unregister_pll(struct clk *clk)
364+
{
365+
struct clk_hw *hw;
366+
struct mtk_clk_pll *pll;
367+
368+
hw = __clk_get_hw(clk);
369+
if (!hw)
370+
return;
371+
372+
pll = to_mtk_clk_pll(hw);
373+
374+
clk_unregister(clk);
375+
kfree(pll);
376+
}
377+
363378
void mtk_clk_register_plls(struct device_node *node,
364379
const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data)
365380
{
@@ -388,4 +403,44 @@ void mtk_clk_register_plls(struct device_node *node,
388403
}
389404
EXPORT_SYMBOL_GPL(mtk_clk_register_plls);
390405

406+
static __iomem void *mtk_clk_pll_get_base(struct clk *clk,
407+
const struct mtk_pll_data *data)
408+
{
409+
struct clk_hw *hw = __clk_get_hw(clk);
410+
struct mtk_clk_pll *pll = to_mtk_clk_pll(hw);
411+
412+
return pll->base_addr - data->reg;
413+
}
414+
415+
void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls,
416+
struct clk_onecell_data *clk_data)
417+
{
418+
__iomem void *base = NULL;
419+
int i;
420+
421+
if (!clk_data)
422+
return;
423+
424+
for (i = num_plls; i > 0; i--) {
425+
const struct mtk_pll_data *pll = &plls[i - 1];
426+
427+
if (IS_ERR_OR_NULL(clk_data->clks[pll->id]))
428+
continue;
429+
430+
/*
431+
* This is quite ugly but unfortunately the clks don't have
432+
* any device tied to them, so there's no place to store the
433+
* pointer to the I/O region base address. We have to fetch
434+
* it from one of the registered clks.
435+
*/
436+
base = mtk_clk_pll_get_base(clk_data->clks[pll->id], pll);
437+
438+
mtk_clk_unregister_pll(clk_data->clks[pll->id]);
439+
clk_data->clks[pll->id] = ERR_PTR(-ENOENT);
440+
}
441+
442+
iounmap(base);
443+
}
444+
EXPORT_SYMBOL_GPL(mtk_clk_unregister_plls);
445+
391446
MODULE_LICENSE("GPL");

drivers/clk/mediatek/clk-pll.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,7 @@ struct mtk_pll_data {
5151
void mtk_clk_register_plls(struct device_node *node,
5252
const struct mtk_pll_data *plls, int num_plls,
5353
struct clk_onecell_data *clk_data);
54+
void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls,
55+
struct clk_onecell_data *clk_data);
5456

5557
#endif /* __DRV_CLK_MTK_PLL_H */

0 commit comments

Comments
 (0)