PE clock info can be skipped if the synchronous clocking is to be used in flexcan. Refer Documentation/devicetree/bindings/net/can/fsl-flexcan.txt for more info. Signed-off-by: Pankaj Bansal <pankaj.bansal@xxxxxxx> --- Notes: Dependencies: [1] https://lore.kernel.org/patchwork/cover/1024536/ [2] https://lore.kernel.org/patchwork/patch/1001918/ V2: - modified the clk_src == 0 to !clk_src - modified changes in flexcan_clks_enable - Added Dependencies in Notes drivers/net/can/flexcan.c | 39 +++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 5f4075d598d0..249fc0a6f85d 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -515,21 +515,24 @@ static int flexcan_clks_enable(const struct flexcan_priv *priv) { int err; - err = clk_prepare_enable(priv->clk_ipg); + err = clk_prepare_enable(priv->clk_per); if (err) return err; - err = clk_prepare_enable(priv->clk_per); - if (err) - clk_disable_unprepare(priv->clk_ipg); + if (priv->clk_ipg) { + err = clk_prepare_enable(priv->clk_ipg); + if (err) + clk_disable_unprepare(priv->clk_per); + } return err; } static void flexcan_clks_disable(const struct flexcan_priv *priv) { + if (priv->clk_ipg) + clk_disable_unprepare(priv->clk_ipg); clk_disable_unprepare(priv->clk_per); - clk_disable_unprepare(priv->clk_ipg); } static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) @@ -1688,18 +1691,30 @@ static int flexcan_probe(struct platform_device *pdev) } if (!clock_freq) { - clk_ipg = devm_clk_get(&pdev->dev, "ipg"); - if (IS_ERR(clk_ipg)) { - dev_err(&pdev->dev, "no ipg clock defined\n"); - return PTR_ERR(clk_ipg); - } - clk_per = devm_clk_get(&pdev->dev, "per"); if (IS_ERR(clk_per)) { dev_err(&pdev->dev, "no per clock defined\n"); return PTR_ERR(clk_per); } - clock_freq = clk_get_rate(clk_per); + + if (!clk_src) { + // only get oscillator clock if asynchronous clocking + // is to be used. + clk_ipg = devm_clk_get(&pdev->dev, "ipg"); + if (IS_ERR(clk_ipg)) { + dev_err(&pdev->dev, "no ipg clock defined\n"); + return PTR_ERR(clk_ipg); + } + + clock_freq = clk_get_rate(clk_ipg); + if (clock_freq >= clk_get_rate(clk_per)) { + dev_err(&pdev->dev, + "PE clock should be less than CHI\n"); + return -EINVAL; + } + } else { + clock_freq = clk_get_rate(clk_per); + } } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- 2.17.1