| From 8cffac2a1d989312132298af4df07f5685b89c1e Mon Sep 17 00:00:00 2001 |
| From: Geert Uytterhoeven <geert+renesas@glider.be> |
| Date: Thu, 29 Sep 2016 14:47:58 +0200 |
| Subject: [PATCH 159/286] clk: renesas: cpg-mssr: Add support for fixing up |
| clock tables |
| |
| The same SoC may have different clocks and/or module clock parents, |
| depending on SoC revision. One option is to use different sets of clock |
| tables for each SoC revision. However, if the differences are small, it |
| is much more space-efficient to have a single set of clock tables, and |
| fix those up at runtime instead. |
| |
| Hence provide three helpers: |
| - Two helpers to NULLify core and module clocks that do not exist on |
| some revisions (NULLified clocks are skipped during the registration |
| phase), |
| - One helper to reparent module clocks that have different clock |
| parents. |
| |
| Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| (cherry picked from commit 48d0341e41870bcfc42206d38e00a6b1c2fea929) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/clk/renesas/renesas-cpg-mssr.c | 50 +++++++++++++++++++++++++++++++++ |
| drivers/clk/renesas/renesas-cpg-mssr.h | 22 ++++++++++++++ |
| 2 files changed, 72 insertions(+) |
| |
| --- a/drivers/clk/renesas/renesas-cpg-mssr.c |
| +++ b/drivers/clk/renesas/renesas-cpg-mssr.c |
| @@ -265,6 +265,11 @@ static void __init cpg_mssr_register_cor |
| WARN_DEBUG(id >= priv->num_core_clks); |
| WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); |
| |
| + if (!core->name) { |
| + /* Skip NULLified clock */ |
| + return; |
| + } |
| + |
| switch (core->type) { |
| case CLK_TYPE_IN: |
| clk = of_clk_get_by_name(priv->dev->of_node, core->name); |
| @@ -335,6 +340,11 @@ static void __init cpg_mssr_register_mod |
| WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); |
| WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); |
| |
| + if (!mod->name) { |
| + /* Skip NULLified clock */ |
| + return; |
| + } |
| + |
| parent = priv->clks[mod->parent]; |
| if (IS_ERR(parent)) { |
| clk = parent; |
| @@ -734,5 +744,45 @@ static int __init cpg_mssr_init(void) |
| |
| subsys_initcall(cpg_mssr_init); |
| |
| +void __init cpg_core_nullify_range(struct cpg_core_clk *core_clks, |
| + unsigned int num_core_clks, |
| + unsigned int first_clk, |
| + unsigned int last_clk) |
| +{ |
| + unsigned int i; |
| + |
| + for (i = 0; i < num_core_clks; i++) |
| + if (core_clks[i].id >= first_clk && |
| + core_clks[i].id <= last_clk) |
| + core_clks[i].name = NULL; |
| +} |
| + |
| +void __init mssr_mod_nullify(struct mssr_mod_clk *mod_clks, |
| + unsigned int num_mod_clks, |
| + const unsigned int *clks, unsigned int n) |
| +{ |
| + unsigned int i, j; |
| + |
| + for (i = 0, j = 0; i < num_mod_clks && j < n; i++) |
| + if (mod_clks[i].id == clks[j]) { |
| + mod_clks[i].name = NULL; |
| + j++; |
| + } |
| +} |
| + |
| +void __init mssr_mod_reparent(struct mssr_mod_clk *mod_clks, |
| + unsigned int num_mod_clks, |
| + const struct mssr_mod_reparent *clks, |
| + unsigned int n) |
| +{ |
| + unsigned int i, j; |
| + |
| + for (i = 0, j = 0; i < num_mod_clks && j < n; i++) |
| + if (mod_clks[i].id == clks[j].clk) { |
| + mod_clks[i].parent = clks[j].parent; |
| + j++; |
| + } |
| +} |
| + |
| MODULE_DESCRIPTION("Renesas CPG/MSSR Driver"); |
| MODULE_LICENSE("GPL v2"); |
| --- a/drivers/clk/renesas/renesas-cpg-mssr.h |
| +++ b/drivers/clk/renesas/renesas-cpg-mssr.h |
| @@ -134,4 +134,26 @@ extern const struct cpg_mssr_info r8a774 |
| extern const struct cpg_mssr_info r8a7745_cpg_mssr_info; |
| extern const struct cpg_mssr_info r8a7795_cpg_mssr_info; |
| extern const struct cpg_mssr_info r8a7796_cpg_mssr_info; |
| + |
| + |
| + /* |
| + * Helpers for fixing up clock tables depending on SoC revision |
| + */ |
| + |
| +struct mssr_mod_reparent { |
| + unsigned int clk, parent; |
| +}; |
| + |
| + |
| +extern void cpg_core_nullify_range(struct cpg_core_clk *core_clks, |
| + unsigned int num_core_clks, |
| + unsigned int first_clk, |
| + unsigned int last_clk); |
| +extern void mssr_mod_nullify(struct mssr_mod_clk *mod_clks, |
| + unsigned int num_mod_clks, |
| + const unsigned int *clks, unsigned int n); |
| +extern void mssr_mod_reparent(struct mssr_mod_clk *mod_clks, |
| + unsigned int num_mod_clks, |
| + const struct mssr_mod_reparent *clks, |
| + unsigned int n); |
| #endif |