Lines Matching +full:composite +full:- +full:divider +full:- +full:clock
1 // SPDX-License-Identifier: GPL-2.0-only
8 #include <linux/clk-provider.h>
19 #include "clk-mtk.h"
20 #include "clk-gate.h"
21 #include "clk-mux.h"
44 clk_data->num = clk_num; in mtk_init_clk_data()
47 clk_data->hws[i] = ERR_PTR(-ENOENT); in mtk_init_clk_data()
93 return -ENOMEM; in mtk_clk_register_fixed_clks()
98 if (!IS_ERR_OR_NULL(clk_data->hws[rc->id])) { in mtk_clk_register_fixed_clks()
99 pr_warn("Trying to register duplicate clock ID: %d\n", rc->id); in mtk_clk_register_fixed_clks()
103 hw = clk_hw_register_fixed_rate(NULL, rc->name, rc->parent, 0, in mtk_clk_register_fixed_clks()
104 rc->rate); in mtk_clk_register_fixed_clks()
107 pr_err("Failed to register clk %s: %pe\n", rc->name, in mtk_clk_register_fixed_clks()
112 clk_data->hws[rc->id] = hw; in mtk_clk_register_fixed_clks()
118 while (--i >= 0) { in mtk_clk_register_fixed_clks()
121 if (IS_ERR_OR_NULL(clk_data->hws[rc->id])) in mtk_clk_register_fixed_clks()
124 clk_hw_unregister_fixed_rate(clk_data->hws[rc->id]); in mtk_clk_register_fixed_clks()
125 clk_data->hws[rc->id] = ERR_PTR(-ENOENT); in mtk_clk_register_fixed_clks()
140 for (i = num; i > 0; i--) { in mtk_clk_unregister_fixed_clks()
141 const struct mtk_fixed_clk *rc = &clks[i - 1]; in mtk_clk_unregister_fixed_clks()
143 if (IS_ERR_OR_NULL(clk_data->hws[rc->id])) in mtk_clk_unregister_fixed_clks()
146 clk_hw_unregister_fixed_rate(clk_data->hws[rc->id]); in mtk_clk_unregister_fixed_clks()
147 clk_data->hws[rc->id] = ERR_PTR(-ENOENT); in mtk_clk_unregister_fixed_clks()
159 return -ENOMEM; in mtk_clk_register_factors()
164 if (!IS_ERR_OR_NULL(clk_data->hws[ff->id])) { in mtk_clk_register_factors()
165 pr_warn("Trying to register duplicate clock ID: %d\n", ff->id); in mtk_clk_register_factors()
169 hw = clk_hw_register_fixed_factor(NULL, ff->name, ff->parent_name, in mtk_clk_register_factors()
170 ff->flags, ff->mult, ff->div); in mtk_clk_register_factors()
173 pr_err("Failed to register clk %s: %pe\n", ff->name, in mtk_clk_register_factors()
178 clk_data->hws[ff->id] = hw; in mtk_clk_register_factors()
184 while (--i >= 0) { in mtk_clk_register_factors()
187 if (IS_ERR_OR_NULL(clk_data->hws[ff->id])) in mtk_clk_register_factors()
190 clk_hw_unregister_fixed_factor(clk_data->hws[ff->id]); in mtk_clk_register_factors()
191 clk_data->hws[ff->id] = ERR_PTR(-ENOENT); in mtk_clk_register_factors()
206 for (i = num; i > 0; i--) { in mtk_clk_unregister_factors()
207 const struct mtk_fixed_factor *ff = &clks[i - 1]; in mtk_clk_unregister_factors()
209 if (IS_ERR_OR_NULL(clk_data->hws[ff->id])) in mtk_clk_unregister_factors()
212 clk_hw_unregister_fixed_factor(clk_data->hws[ff->id]); in mtk_clk_unregister_factors()
213 clk_data->hws[ff->id] = ERR_PTR(-ENOENT); in mtk_clk_unregister_factors()
232 if (mc->mux_shift >= 0) { in mtk_clk_register_composite()
235 return ERR_PTR(-ENOMEM); in mtk_clk_register_composite()
237 mux->reg = base + mc->mux_reg; in mtk_clk_register_composite()
238 mux->mask = BIT(mc->mux_width) - 1; in mtk_clk_register_composite()
239 mux->shift = mc->mux_shift; in mtk_clk_register_composite()
240 mux->lock = lock; in mtk_clk_register_composite()
241 mux->flags = mc->mux_flags; in mtk_clk_register_composite()
242 mux_hw = &mux->hw; in mtk_clk_register_composite()
245 parent_names = mc->parent_names; in mtk_clk_register_composite()
246 num_parents = mc->num_parents; in mtk_clk_register_composite()
248 parent = mc->parent; in mtk_clk_register_composite()
253 if (mc->gate_shift >= 0) { in mtk_clk_register_composite()
256 ret = -ENOMEM; in mtk_clk_register_composite()
260 gate->reg = base + mc->gate_reg; in mtk_clk_register_composite()
261 gate->bit_idx = mc->gate_shift; in mtk_clk_register_composite()
262 gate->flags = CLK_GATE_SET_TO_DISABLE; in mtk_clk_register_composite()
263 gate->lock = lock; in mtk_clk_register_composite()
265 gate_hw = &gate->hw; in mtk_clk_register_composite()
269 if (mc->divider_shift >= 0) { in mtk_clk_register_composite()
272 ret = -ENOMEM; in mtk_clk_register_composite()
276 div->reg = base + mc->divider_reg; in mtk_clk_register_composite()
277 div->shift = mc->divider_shift; in mtk_clk_register_composite()
278 div->width = mc->divider_width; in mtk_clk_register_composite()
279 div->lock = lock; in mtk_clk_register_composite()
281 div_hw = &div->hw; in mtk_clk_register_composite()
285 hw = clk_hw_register_composite(dev, mc->name, parent_names, num_parents, in mtk_clk_register_composite()
289 mc->flags); in mtk_clk_register_composite()
307 struct clk_composite *composite; in mtk_clk_unregister_composite() local
315 composite = to_clk_composite(hw); in mtk_clk_unregister_composite()
316 if (composite->mux_hw) in mtk_clk_unregister_composite()
317 mux = to_clk_mux(composite->mux_hw); in mtk_clk_unregister_composite()
318 if (composite->gate_hw) in mtk_clk_unregister_composite()
319 gate = to_clk_gate(composite->gate_hw); in mtk_clk_unregister_composite()
320 if (composite->rate_hw) in mtk_clk_unregister_composite()
321 div = to_clk_divider(composite->rate_hw); in mtk_clk_unregister_composite()
338 return -ENOMEM; in mtk_clk_register_composites()
343 if (!IS_ERR_OR_NULL(clk_data->hws[mc->id])) { in mtk_clk_register_composites()
344 pr_warn("Trying to register duplicate clock ID: %d\n", in mtk_clk_register_composites()
345 mc->id); in mtk_clk_register_composites()
352 pr_err("Failed to register clk %s: %pe\n", mc->name, in mtk_clk_register_composites()
357 clk_data->hws[mc->id] = hw; in mtk_clk_register_composites()
363 while (--i >= 0) { in mtk_clk_register_composites()
366 if (IS_ERR_OR_NULL(clk_data->hws[mcs->id])) in mtk_clk_register_composites()
369 mtk_clk_unregister_composite(clk_data->hws[mc->id]); in mtk_clk_register_composites()
370 clk_data->hws[mc->id] = ERR_PTR(-ENOENT); in mtk_clk_register_composites()
385 for (i = num; i > 0; i--) { in mtk_clk_unregister_composites()
386 const struct mtk_composite *mc = &mcs[i - 1]; in mtk_clk_unregister_composites()
388 if (IS_ERR_OR_NULL(clk_data->hws[mc->id])) in mtk_clk_unregister_composites()
391 mtk_clk_unregister_composite(clk_data->hws[mc->id]); in mtk_clk_unregister_composites()
392 clk_data->hws[mc->id] = ERR_PTR(-ENOENT); in mtk_clk_unregister_composites()
406 return -ENOMEM; in mtk_clk_register_dividers()
411 if (!IS_ERR_OR_NULL(clk_data->hws[mcd->id])) { in mtk_clk_register_dividers()
412 pr_warn("Trying to register duplicate clock ID: %d\n", in mtk_clk_register_dividers()
413 mcd->id); in mtk_clk_register_dividers()
417 hw = clk_hw_register_divider(dev, mcd->name, mcd->parent_name, in mtk_clk_register_dividers()
418 mcd->flags, base + mcd->div_reg, mcd->div_shift, in mtk_clk_register_dividers()
419 mcd->div_width, mcd->clk_divider_flags, lock); in mtk_clk_register_dividers()
422 pr_err("Failed to register clk %s: %pe\n", mcd->name, in mtk_clk_register_dividers()
427 clk_data->hws[mcd->id] = hw; in mtk_clk_register_dividers()
433 while (--i >= 0) { in mtk_clk_register_dividers()
436 if (IS_ERR_OR_NULL(clk_data->hws[mcd->id])) in mtk_clk_register_dividers()
439 clk_hw_unregister_divider(clk_data->hws[mcd->id]); in mtk_clk_register_dividers()
440 clk_data->hws[mcd->id] = ERR_PTR(-ENOENT); in mtk_clk_register_dividers()
455 for (i = num; i > 0; i--) { in mtk_clk_unregister_dividers()
456 const struct mtk_clk_divider *mcd = &mcds[i - 1]; in mtk_clk_unregister_dividers()
458 if (IS_ERR_OR_NULL(clk_data->hws[mcd->id])) in mtk_clk_unregister_dividers()
461 clk_hw_unregister_divider(clk_data->hws[mcd->id]); in mtk_clk_unregister_dividers()
462 clk_data->hws[mcd->id] = ERR_PTR(-ENOENT); in mtk_clk_unregister_dividers()
476 mcd = device_get_match_data(&pdev->dev); in __mtk_clk_simple_probe()
478 /* Clock driver wasn't registered from devicetree */ in __mtk_clk_simple_probe()
481 mcd = (const struct mtk_clk_desc *)id->driver_data; in __mtk_clk_simple_probe()
484 return -EINVAL; in __mtk_clk_simple_probe()
487 /* Composite and divider clocks needs us to pass iomem pointer */ in __mtk_clk_simple_probe()
488 if (mcd->composite_clks || mcd->divider_clks) { in __mtk_clk_simple_probe()
489 if (!mcd->shared_io) in __mtk_clk_simple_probe()
495 return IS_ERR(base) ? PTR_ERR(base) : -ENOMEM; in __mtk_clk_simple_probe()
499 if (mcd->need_runtime_pm) { in __mtk_clk_simple_probe()
500 devm_pm_runtime_enable(&pdev->dev); in __mtk_clk_simple_probe()
505 r = pm_runtime_resume_and_get(&pdev->dev); in __mtk_clk_simple_probe()
511 num_clks = mcd->num_clks + mcd->num_composite_clks; in __mtk_clk_simple_probe()
512 num_clks += mcd->num_fixed_clks + mcd->num_factor_clks; in __mtk_clk_simple_probe()
513 num_clks += mcd->num_mux_clks + mcd->num_divider_clks; in __mtk_clk_simple_probe()
517 r = -ENOMEM; in __mtk_clk_simple_probe()
521 if (mcd->fixed_clks) { in __mtk_clk_simple_probe()
522 r = mtk_clk_register_fixed_clks(mcd->fixed_clks, in __mtk_clk_simple_probe()
523 mcd->num_fixed_clks, clk_data); in __mtk_clk_simple_probe()
528 if (mcd->factor_clks) { in __mtk_clk_simple_probe()
529 r = mtk_clk_register_factors(mcd->factor_clks, in __mtk_clk_simple_probe()
530 mcd->num_factor_clks, clk_data); in __mtk_clk_simple_probe()
535 if (mcd->mux_clks) { in __mtk_clk_simple_probe()
536 r = mtk_clk_register_muxes(&pdev->dev, mcd->mux_clks, in __mtk_clk_simple_probe()
537 mcd->num_mux_clks, node, in __mtk_clk_simple_probe()
538 mcd->clk_lock, clk_data); in __mtk_clk_simple_probe()
543 if (mcd->composite_clks) { in __mtk_clk_simple_probe()
545 r = mtk_clk_register_composites(&pdev->dev, in __mtk_clk_simple_probe()
546 mcd->composite_clks, in __mtk_clk_simple_probe()
547 mcd->num_composite_clks, in __mtk_clk_simple_probe()
548 base, mcd->clk_lock, clk_data); in __mtk_clk_simple_probe()
553 if (mcd->divider_clks) { in __mtk_clk_simple_probe()
554 r = mtk_clk_register_dividers(&pdev->dev, in __mtk_clk_simple_probe()
555 mcd->divider_clks, in __mtk_clk_simple_probe()
556 mcd->num_divider_clks, in __mtk_clk_simple_probe()
557 base, mcd->clk_lock, clk_data); in __mtk_clk_simple_probe()
562 if (mcd->clks) { in __mtk_clk_simple_probe()
563 r = mtk_clk_register_gates(&pdev->dev, node, mcd->clks, in __mtk_clk_simple_probe()
564 mcd->num_clks, clk_data); in __mtk_clk_simple_probe()
569 if (mcd->clk_notifier_func) { in __mtk_clk_simple_probe()
570 struct clk *mfg_mux = clk_data->hws[mcd->mfg_clk_idx]->clk; in __mtk_clk_simple_probe()
572 r = mcd->clk_notifier_func(&pdev->dev, mfg_mux); in __mtk_clk_simple_probe()
583 if (mcd->rst_desc) { in __mtk_clk_simple_probe()
584 r = mtk_register_reset_controller_with_dev(&pdev->dev, in __mtk_clk_simple_probe()
585 mcd->rst_desc); in __mtk_clk_simple_probe()
590 if (mcd->need_runtime_pm) in __mtk_clk_simple_probe()
591 pm_runtime_put(&pdev->dev); in __mtk_clk_simple_probe()
596 if (mcd->clks) in __mtk_clk_simple_probe()
597 mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data); in __mtk_clk_simple_probe()
599 if (mcd->divider_clks) in __mtk_clk_simple_probe()
600 mtk_clk_unregister_dividers(mcd->divider_clks, in __mtk_clk_simple_probe()
601 mcd->num_divider_clks, clk_data); in __mtk_clk_simple_probe()
603 if (mcd->composite_clks) in __mtk_clk_simple_probe()
604 mtk_clk_unregister_composites(mcd->composite_clks, in __mtk_clk_simple_probe()
605 mcd->num_composite_clks, clk_data); in __mtk_clk_simple_probe()
607 if (mcd->mux_clks) in __mtk_clk_simple_probe()
608 mtk_clk_unregister_muxes(mcd->mux_clks, in __mtk_clk_simple_probe()
609 mcd->num_mux_clks, clk_data); in __mtk_clk_simple_probe()
611 if (mcd->factor_clks) in __mtk_clk_simple_probe()
612 mtk_clk_unregister_factors(mcd->factor_clks, in __mtk_clk_simple_probe()
613 mcd->num_factor_clks, clk_data); in __mtk_clk_simple_probe()
615 if (mcd->fixed_clks) in __mtk_clk_simple_probe()
616 mtk_clk_unregister_fixed_clks(mcd->fixed_clks, in __mtk_clk_simple_probe()
617 mcd->num_fixed_clks, clk_data); in __mtk_clk_simple_probe()
621 if (mcd->shared_io && base) in __mtk_clk_simple_probe()
624 if (mcd->need_runtime_pm) in __mtk_clk_simple_probe()
625 pm_runtime_put(&pdev->dev); in __mtk_clk_simple_probe()
633 const struct mtk_clk_desc *mcd = device_get_match_data(&pdev->dev); in __mtk_clk_simple_remove()
636 if (mcd->clks) in __mtk_clk_simple_remove()
637 mtk_clk_unregister_gates(mcd->clks, mcd->num_clks, clk_data); in __mtk_clk_simple_remove()
638 if (mcd->divider_clks) in __mtk_clk_simple_remove()
639 mtk_clk_unregister_dividers(mcd->divider_clks, in __mtk_clk_simple_remove()
640 mcd->num_divider_clks, clk_data); in __mtk_clk_simple_remove()
641 if (mcd->composite_clks) in __mtk_clk_simple_remove()
642 mtk_clk_unregister_composites(mcd->composite_clks, in __mtk_clk_simple_remove()
643 mcd->num_composite_clks, clk_data); in __mtk_clk_simple_remove()
644 if (mcd->mux_clks) in __mtk_clk_simple_remove()
645 mtk_clk_unregister_muxes(mcd->mux_clks, in __mtk_clk_simple_remove()
646 mcd->num_mux_clks, clk_data); in __mtk_clk_simple_remove()
647 if (mcd->factor_clks) in __mtk_clk_simple_remove()
648 mtk_clk_unregister_factors(mcd->factor_clks, in __mtk_clk_simple_remove()
649 mcd->num_factor_clks, clk_data); in __mtk_clk_simple_remove()
650 if (mcd->fixed_clks) in __mtk_clk_simple_remove()
651 mtk_clk_unregister_fixed_clks(mcd->fixed_clks, in __mtk_clk_simple_remove()
652 mcd->num_fixed_clks, clk_data); in __mtk_clk_simple_remove()
658 struct device *dev = &pdev->dev; in mtk_clk_pdev_probe()
659 struct device_node *node = dev->parent->of_node; in mtk_clk_pdev_probe()
667 struct device_node *node = pdev->dev.of_node; in mtk_clk_simple_probe()
675 struct device *dev = &pdev->dev; in mtk_clk_pdev_remove()
676 struct device_node *node = dev->parent->of_node; in mtk_clk_pdev_remove()
684 __mtk_clk_simple_remove(pdev, pdev->dev.of_node); in mtk_clk_simple_remove()