diff options
author | David Wu <david.wu@rock-chips.com> | 2017-08-08 11:38:29 -0400 |
---|---|---|
committer | Thierry Reding <thierry.reding@gmail.com> | 2017-08-18 11:31:56 -0400 |
commit | 27922ff59893e3445f69e397bcd92ae06fa89ca7 (patch) | |
tree | 02b9c02ddef44631e13a63e7d7ca62b2a085dae6 /drivers/pwm/pwm-rockchip.c | |
parent | 1f8736c4e1ee1fd3d933208683a5315f9a9d6b5c (diff) |
pwm: rockchip: Add APB and function both clocks support
New PWM module provides two individual clocks for APB clock and function
clock.
Signed-off-by: David Wu <david.wu@rock-chips.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/pwm/pwm-rockchip.c')
-rw-r--r-- | drivers/pwm/pwm-rockchip.c | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c index 744d56197286..ac3cd5ec5310 100644 --- a/drivers/pwm/pwm-rockchip.c +++ b/drivers/pwm/pwm-rockchip.c | |||
@@ -33,6 +33,7 @@ | |||
33 | struct rockchip_pwm_chip { | 33 | struct rockchip_pwm_chip { |
34 | struct pwm_chip chip; | 34 | struct pwm_chip chip; |
35 | struct clk *clk; | 35 | struct clk *clk; |
36 | struct clk *pclk; | ||
36 | const struct rockchip_pwm_data *data; | 37 | const struct rockchip_pwm_data *data; |
37 | void __iomem *base; | 38 | void __iomem *base; |
38 | }; | 39 | }; |
@@ -145,7 +146,7 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip, | |||
145 | u64 tmp; | 146 | u64 tmp; |
146 | int ret; | 147 | int ret; |
147 | 148 | ||
148 | ret = clk_enable(pc->clk); | 149 | ret = clk_enable(pc->pclk); |
149 | if (ret) | 150 | if (ret) |
150 | return; | 151 | return; |
151 | 152 | ||
@@ -161,7 +162,7 @@ static void rockchip_pwm_get_state(struct pwm_chip *chip, | |||
161 | 162 | ||
162 | pc->data->get_state(chip, pwm, state); | 163 | pc->data->get_state(chip, pwm, state); |
163 | 164 | ||
164 | clk_disable(pc->clk); | 165 | clk_disable(pc->pclk); |
165 | } | 166 | } |
166 | 167 | ||
167 | static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | 168 | static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, |
@@ -224,7 +225,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, | |||
224 | pwm_get_state(pwm, &curstate); | 225 | pwm_get_state(pwm, &curstate); |
225 | enabled = curstate.enabled; | 226 | enabled = curstate.enabled; |
226 | 227 | ||
227 | ret = clk_enable(pc->clk); | 228 | ret = clk_enable(pc->pclk); |
228 | if (ret) | 229 | if (ret) |
229 | return ret; | 230 | return ret; |
230 | 231 | ||
@@ -257,7 +258,7 @@ static int rockchip_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, | |||
257 | rockchip_pwm_get_state(chip, pwm, state); | 258 | rockchip_pwm_get_state(chip, pwm, state); |
258 | 259 | ||
259 | out: | 260 | out: |
260 | clk_disable(pc->clk); | 261 | clk_disable(pc->pclk); |
261 | 262 | ||
262 | return ret; | 263 | return ret; |
263 | } | 264 | } |
@@ -328,7 +329,7 @@ static int rockchip_pwm_probe(struct platform_device *pdev) | |||
328 | const struct of_device_id *id; | 329 | const struct of_device_id *id; |
329 | struct rockchip_pwm_chip *pc; | 330 | struct rockchip_pwm_chip *pc; |
330 | struct resource *r; | 331 | struct resource *r; |
331 | int ret; | 332 | int ret, count; |
332 | 333 | ||
333 | id = of_match_device(rockchip_pwm_dt_ids, &pdev->dev); | 334 | id = of_match_device(rockchip_pwm_dt_ids, &pdev->dev); |
334 | if (!id) | 335 | if (!id) |
@@ -343,13 +344,43 @@ static int rockchip_pwm_probe(struct platform_device *pdev) | |||
343 | if (IS_ERR(pc->base)) | 344 | if (IS_ERR(pc->base)) |
344 | return PTR_ERR(pc->base); | 345 | return PTR_ERR(pc->base); |
345 | 346 | ||
346 | pc->clk = devm_clk_get(&pdev->dev, NULL); | 347 | pc->clk = devm_clk_get(&pdev->dev, "pwm"); |
347 | if (IS_ERR(pc->clk)) | 348 | if (IS_ERR(pc->clk)) { |
348 | return PTR_ERR(pc->clk); | 349 | pc->clk = devm_clk_get(&pdev->dev, NULL); |
350 | if (IS_ERR(pc->clk)) { | ||
351 | ret = PTR_ERR(pc->clk); | ||
352 | if (ret != -EPROBE_DEFER) | ||
353 | dev_err(&pdev->dev, "Can't get bus clk: %d\n", | ||
354 | ret); | ||
355 | return ret; | ||
356 | } | ||
357 | } | ||
358 | |||
359 | count = of_count_phandle_with_args(pdev->dev.of_node, | ||
360 | "clocks", "#clock-cells"); | ||
361 | if (count == 2) | ||
362 | pc->pclk = devm_clk_get(&pdev->dev, "pclk"); | ||
363 | else | ||
364 | pc->pclk = pc->clk; | ||
365 | |||
366 | if (IS_ERR(pc->pclk)) { | ||
367 | ret = PTR_ERR(pc->pclk); | ||
368 | if (ret != -EPROBE_DEFER) | ||
369 | dev_err(&pdev->dev, "Can't get APB clk: %d\n", ret); | ||
370 | return ret; | ||
371 | } | ||
349 | 372 | ||
350 | ret = clk_prepare_enable(pc->clk); | 373 | ret = clk_prepare_enable(pc->clk); |
351 | if (ret) | 374 | if (ret) { |
375 | dev_err(&pdev->dev, "Can't prepare enable bus clk: %d\n", ret); | ||
352 | return ret; | 376 | return ret; |
377 | } | ||
378 | |||
379 | ret = clk_prepare(pc->pclk); | ||
380 | if (ret) { | ||
381 | dev_err(&pdev->dev, "Can't prepare APB clk: %d\n", ret); | ||
382 | goto err_clk; | ||
383 | } | ||
353 | 384 | ||
354 | platform_set_drvdata(pdev, pc); | 385 | platform_set_drvdata(pdev, pc); |
355 | 386 | ||
@@ -368,12 +399,20 @@ static int rockchip_pwm_probe(struct platform_device *pdev) | |||
368 | if (ret < 0) { | 399 | if (ret < 0) { |
369 | clk_unprepare(pc->clk); | 400 | clk_unprepare(pc->clk); |
370 | dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); | 401 | dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); |
402 | goto err_pclk; | ||
371 | } | 403 | } |
372 | 404 | ||
373 | /* Keep the PWM clk enabled if the PWM appears to be up and running. */ | 405 | /* Keep the PWM clk enabled if the PWM appears to be up and running. */ |
374 | if (!pwm_is_enabled(pc->chip.pwms)) | 406 | if (!pwm_is_enabled(pc->chip.pwms)) |
375 | clk_disable(pc->clk); | 407 | clk_disable(pc->clk); |
376 | 408 | ||
409 | return 0; | ||
410 | |||
411 | err_pclk: | ||
412 | clk_unprepare(pc->pclk); | ||
413 | err_clk: | ||
414 | clk_disable_unprepare(pc->clk); | ||
415 | |||
377 | return ret; | 416 | return ret; |
378 | } | 417 | } |
379 | 418 | ||
@@ -395,6 +434,7 @@ static int rockchip_pwm_remove(struct platform_device *pdev) | |||
395 | if (pwm_is_enabled(pc->chip.pwms)) | 434 | if (pwm_is_enabled(pc->chip.pwms)) |
396 | clk_disable(pc->clk); | 435 | clk_disable(pc->clk); |
397 | 436 | ||
437 | clk_unprepare(pc->pclk); | ||
398 | clk_unprepare(pc->clk); | 438 | clk_unprepare(pc->clk); |
399 | 439 | ||
400 | return pwmchip_remove(&pc->chip); | 440 | return pwmchip_remove(&pc->chip); |