[PATCH 3/6] clk: bcm2835: enable clocks that have been enabled by firmware
From: kernel at martin.sperl.org <hidden>
Date: 2016-02-29 11:39:19
Also in:
linux-clk
Subsystem:
common clk framework, the rest · Maintainers:
Michael Turquette, Stephen Boyd, Linus Torvalds
From: Martin Sperl <redacted> If a clock that has been enabled by the firmware gets disabled by a driver this may right now result in a crash of the system as then also the corresponding PLL_dividers as well as PLLs get disabled (if not used) - some of which are used by the VideoCore GPU (which also runs the firmware) This patch prepares/enables those clocks that have been configured by the firmware. Whenever the clock framework implements either CLK_IS_CRITICAL or HAND_OFF this can get changed to use this new mechanism. For this to be completely successful (i.e not missing a clock and subsequently a pll) it is recommended to add all the known clocks of the soc so that this can get applied to all clocks. Signed-off-by: Martin Sperl <redacted> --- drivers/clk/bcm/clk-bcm2835.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
index 30d6486..1fbb55d 100644
--- a/drivers/clk/bcm/clk-bcm2835.c
+++ b/drivers/clk/bcm/clk-bcm2835.c@@ -37,6 +37,7 @@ * generator). */ +#include <linux/clk.h> #include <linux/clk-provider.h> #include <linux/clkdev.h> #include <linux/clk/bcm2835.h>
@@ -1478,6 +1479,7 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman, struct clk_init_data init; const char *parents[1 << CM_SRC_BITS]; size_t i; + struct clk *clk; /* * Replace our "xosc" references with the oscillator's
@@ -1511,7 +1513,18 @@ static struct clk *bcm2835_register_clock(struct bcm2835_cprman *cprman, clock->data = data; clock->hw.init = &init; - return devm_clk_register(cprman->dev, &clock->hw); + clk = devm_clk_register(cprman->dev, &clock->hw); + if (IS_ERR_OR_NULL(clk)) + return clk; + + /* enable/prepare if the clock is enabled by the firmware */ + if (cprman_read(cprman, data->ctl_reg) & CM_ENABLE) { + dev_info(cprman->dev, + "found firmware enabled clock %pC\n", clk); + clk_prepare_enable(clk); + } + + return clk; } static int bcm2835_clk_probe(struct platform_device *pdev) --
1.7.10.4