aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-rockchip.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pwm/pwm-rockchip.c')
-rw-r--r--drivers/pwm/pwm-rockchip.c58
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 @@
33struct rockchip_pwm_chip { 33struct 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
167static int rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 168static 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
259out: 260out:
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
411err_pclk:
412 clk_unprepare(pc->pclk);
413err_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);