summaryrefslogtreecommitdiffstats
path: root/drivers/clk/meson/meson8b-clkc.c
diff options
context:
space:
mode:
authorMichael Turquette2016-04-30 21:47:36 +0200
committerMichael Turquette2016-06-23 03:02:35 +0200
commit55d42c40dd8aa7384aa5c5295ef9037db2b00226 (patch)
treefb4da86435984c61973000b0b240c6743401ffa2 /drivers/clk/meson/meson8b-clkc.c
parentclk: meson8b: clean up fixed factor clocks (diff)
downloadkernel-qcow2-linux-55d42c40dd8aa7384aa5c5295ef9037db2b00226.tar.gz
kernel-qcow2-linux-55d42c40dd8aa7384aa5c5295ef9037db2b00226.tar.xz
kernel-qcow2-linux-55d42c40dd8aa7384aa5c5295ef9037db2b00226.zip
clk: meson8b: clean up cpu clocks
Remove the cpu clock registration function and helpers. Replace unnecessary configuration struct with static initialization of the desired clock type. Ninja rename a5_clk to cpu_clk to better align with cpufreq convention. Tested-by: Kevin Hilman <khilman@baylibre.com> Signed-off-by: Michael Turquette <mturquette@baylibre.com>
Diffstat (limited to 'drivers/clk/meson/meson8b-clkc.c')
-rw-r--r--drivers/clk/meson/meson8b-clkc.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c
index 6571e66ecc4e..94512b6ada25 100644
--- a/drivers/clk/meson/meson8b-clkc.c
+++ b/drivers/clk/meson/meson8b-clkc.c
@@ -15,6 +15,7 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/kernel.h>
#include <linux/of.h>
@@ -110,7 +111,6 @@ static const struct clk_div_table cpu_div_table[] = {
{ /* sentinel */ },
};
-PNAME(p_cpu_clk) = { "sys_pll" };
PNAME(p_clk81) = { "fclk_div3", "fclk_div4", "fclk_div5" };
PNAME(p_mali) = { "fclk_div3", "fclk_div4", "fclk_div5",
"fclk_div7", "zero" };
@@ -286,9 +286,19 @@ static struct clk_fixed_factor meson8b_fclk_div7 = {
},
};
+static struct meson_clk_cpu meson8b_cpu_clk = {
+ .reg_off = MESON8B_REG_SYS_CPU_CNTL1,
+ .div_table = cpu_div_table,
+ .clk_nb.notifier_call = meson_clk_cpu_notifier_cb,
+ .hw.init = &(struct clk_init_data){
+ .name = "cpu_clk",
+ .ops = &meson_clk_cpu_ops,
+ .parent_names = (const char *[]){ "sys_pll" },
+ .num_parents = 1,
+ },
+};
+
static const struct clk_conf meson8b_clk_confs[] __initconst = {
- CPU(MESON8B_REG_SYS_CPU_CNTL1, CLKID_CPUCLK, "a5_clk", p_cpu_clk,
- cpu_div_table),
COMPOSITE(MESON8B_REG_HHI_MPEG, CLKID_CLK81, "clk81", p_clk81,
CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED, &clk81_conf),
COMPOSITE(MESON8B_REG_MALI, CLKID_MALI, "mali", p_mali,
@@ -314,6 +324,7 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
[CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
+ [CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
},
.num = CLK_NR_CLKS,
};
@@ -328,6 +339,8 @@ static void __init meson8b_clkc_init(struct device_node *np)
{
void __iomem *clk_base;
int ret, clkid, i;
+ struct clk_hw *parent_hw;
+ struct clk *parent_clk;
if (!meson_clk_init(np, CLK_NR_CLKS))
return;
@@ -343,6 +356,9 @@ static void __init meson8b_clkc_init(struct device_node *np)
for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
meson8b_clk_plls[i]->base = clk_base;
+ /* Populate the base address for CPU clk */
+ meson8b_cpu_clk.base = clk_base;
+
/*
* register all clks
* CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
@@ -358,12 +374,37 @@ static void __init meson8b_clkc_init(struct device_node *np)
goto unregister;
}
+ /*
+ * Register CPU clk notifier
+ *
+ * FIXME this is wrong for a lot of reasons. First, the muxes should be
+ * struct clk_hw objects. Second, we shouldn't program the muxes in
+ * notifier handlers. The tricky programming sequence will be handled
+ * by the forthcoming coordinated clock rates mechanism once that
+ * feature is released.
+ *
+ * Furthermore, looking up the parent this way is terrible. At some
+ * point we will stop allocating a default struct clk when registering
+ * a new clk_hw, and this hack will no longer work. Releasing the ccr
+ * feature before that time solves the problem :-)
+ */
+ parent_hw = clk_hw_get_parent(&meson8b_cpu_clk.hw);
+ parent_clk = parent_hw->clk;
+ ret = clk_notifier_register(parent_clk, &meson8b_cpu_clk.clk_nb);
+ if (ret) {
+ pr_err("%s: failed to register clock notifier for cpu_clk\n",
+ __func__);
+ goto unregister_clk_nb;
+ }
+
meson_clk_register_clks(meson8b_clk_confs,
ARRAY_SIZE(meson8b_clk_confs),
clk_base);
return;
/* FIXME remove after converting to platform_driver/devm_clk_register */
+unregister_clk_nb:
+ clk_notifier_unregister(parent_clk, &meson8b_a5_clk.clk_nb);
unregister:
for (clkid = CLK_NR_CLKS - 1; clkid >= 0; clkid--)
clk_hw_unregister(meson8b_hw_onecell_data.hws[clkid]);