From: Jernej Skrabec <jernej.skrabec@xxxxxxxx> H6 PWM core needs bus clock to be enabled in order to work. Add an optional probe for it and a fallback for previous bindings without name on module clock. Signed-off-by: Jernej Skrabec <jernej.skrabec@xxxxxxxx> Signed-off-by: Clément Péron <peron.clem@xxxxxxxxx> --- drivers/pwm/pwm-sun4i.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/pwm/pwm-sun4i.c b/drivers/pwm/pwm-sun4i.c index d194b8ebdb00..b5e7ac364f59 100644 --- a/drivers/pwm/pwm-sun4i.c +++ b/drivers/pwm/pwm-sun4i.c @@ -78,6 +78,7 @@ struct sun4i_pwm_data { struct sun4i_pwm_chip { struct pwm_chip chip; + struct clk *bus_clk; struct clk *clk; struct reset_control *rst; void __iomem *base; @@ -367,6 +368,31 @@ static int sun4i_pwm_probe(struct platform_device *pdev) if (IS_ERR(pwm->clk)) return PTR_ERR(pwm->clk); + /* Get all clocks and reset line */ + pwm->clk = devm_clk_get_optional(&pdev->dev, "mod"); + if (IS_ERR(pwm->clk)) { + dev_err(&pdev->dev, "get clock failed %ld\n", + PTR_ERR(pwm->clk)); + return PTR_ERR(pwm->clk); + } + + /* Fallback for old dtbs with a single clock and no name */ + if (!pwm->clk) { + pwm->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(pwm->clk)) { + dev_err(&pdev->dev, "get clock failed %ld\n", + PTR_ERR(pwm->clk)); + return PTR_ERR(pwm->clk); + } + } + + pwm->bus_clk = devm_clk_get_optional(&pdev->dev, "bus"); + if (IS_ERR(pwm->bus_clk)) { + dev_err(&pdev->dev, "get bus_clock failed %ld\n", + PTR_ERR(pwm->bus_clk)); + return PTR_ERR(pwm->bus_clk); + } + pwm->rst = devm_reset_control_get_optional(&pdev->dev, NULL); if (IS_ERR(pwm->rst)) { if (PTR_ERR(pwm->rst) == -EPROBE_DEFER) @@ -381,6 +407,13 @@ static int sun4i_pwm_probe(struct platform_device *pdev) return ret; } + /* Enable bus clock */ + ret = clk_prepare_enable(pwm->bus_clk); + if (ret) { + dev_err(&pdev->dev, "Cannot prepare_enable bus_clk\n"); + goto err_bus; + } + pwm->chip.dev = &pdev->dev; pwm->chip.ops = &sun4i_pwm_ops; pwm->chip.base = -1; @@ -401,6 +434,8 @@ static int sun4i_pwm_probe(struct platform_device *pdev) return 0; err_pwm_add: + clk_disable_unprepare(pwm->bus_clk); +err_bus: reset_control_assert(pwm->rst); return ret; @@ -415,6 +450,7 @@ static int sun4i_pwm_remove(struct platform_device *pdev) if (ret) return ret; + clk_disable_unprepare(pwm->bus_clk); reset_control_assert(pwm->rst); return 0; -- 2.20.1