From mboxrd@z Thu Jan 1 00:00:00 1970 From: kernel@martin.sperl.org (kernel at martin.sperl.org) Date: Mon, 29 Feb 2016 11:39:19 +0000 Subject: [PATCH 3/6] clk: bcm2835: enable clocks that have been enabled by firmware In-Reply-To: <1456745963-2403-1-git-send-email-kernel@martin.sperl.org> References: <1456745963-2403-1-git-send-email-kernel@martin.sperl.org> Message-ID: <1456745963-2403-4-git-send-email-kernel@martin.sperl.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org From: Martin Sperl 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 --- 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 #include #include #include @@ -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