diff options
author | Philip, Avinash <avinashphilip@ti.com> | 2012-11-27 03:48:13 -0500 |
---|---|---|
committer | Thierry Reding <thierry.reding@avionic-design.de> | 2012-11-28 09:16:17 -0500 |
commit | 53ad9e8d37031397ee141f9bf701c0fba4257b0f (patch) | |
tree | 41dda85d04ca64360a42874e6ea62a0299942de5 /drivers/pwm | |
parent | d91861dafda44d808272f55758ca91d962feda6e (diff) |
pwm: tiehrpwm: Add device-tree binding
This patch
1. Add support for device-tree binding for EHRWPM driver.
2. Set size of pwm-cells set to 3 to support PWM channel number, PWM
period & polarity configuration from device tree.
3. Add enable/disable clock gating in PWM subsystem common config space.
4. When here set .owner member in platform_driver structure to
THIS_MODULE.
Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Rob Landley <rob@landley.net>
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Diffstat (limited to 'drivers/pwm')
-rw-r--r-- | drivers/pwm/pwm-tiehrpwm.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index 565f96ad2787..ee7a8b3dbed9 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c | |||
@@ -25,6 +25,9 @@ | |||
25 | #include <linux/err.h> | 25 | #include <linux/err.h> |
26 | #include <linux/clk.h> | 26 | #include <linux/clk.h> |
27 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
28 | #include <linux/of_device.h> | ||
29 | |||
30 | #include "pwm-tipwmss.h" | ||
28 | 31 | ||
29 | /* EHRPWM registers and bits definitions */ | 32 | /* EHRPWM registers and bits definitions */ |
30 | 33 | ||
@@ -399,12 +402,19 @@ static const struct pwm_ops ehrpwm_pwm_ops = { | |||
399 | .owner = THIS_MODULE, | 402 | .owner = THIS_MODULE, |
400 | }; | 403 | }; |
401 | 404 | ||
405 | static const struct of_device_id ehrpwm_of_match[] = { | ||
406 | { .compatible = "ti,am33xx-ehrpwm" }, | ||
407 | {}, | ||
408 | }; | ||
409 | MODULE_DEVICE_TABLE(of, ehrpwm_of_match); | ||
410 | |||
402 | static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev) | 411 | static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev) |
403 | { | 412 | { |
404 | int ret; | 413 | int ret; |
405 | struct resource *r; | 414 | struct resource *r; |
406 | struct clk *clk; | 415 | struct clk *clk; |
407 | struct ehrpwm_pwm_chip *pc; | 416 | struct ehrpwm_pwm_chip *pc; |
417 | u16 status; | ||
408 | 418 | ||
409 | pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); | 419 | pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); |
410 | if (!pc) { | 420 | if (!pc) { |
@@ -426,6 +436,8 @@ static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev) | |||
426 | 436 | ||
427 | pc->chip.dev = &pdev->dev; | 437 | pc->chip.dev = &pdev->dev; |
428 | pc->chip.ops = &ehrpwm_pwm_ops; | 438 | pc->chip.ops = &ehrpwm_pwm_ops; |
439 | pc->chip.of_xlate = of_pwm_xlate_with_flags; | ||
440 | pc->chip.of_pwm_n_cells = 3; | ||
429 | pc->chip.base = -1; | 441 | pc->chip.base = -1; |
430 | pc->chip.npwm = NUM_PWM_CHANNEL; | 442 | pc->chip.npwm = NUM_PWM_CHANNEL; |
431 | 443 | ||
@@ -453,14 +465,40 @@ static int __devinit ehrpwm_pwm_probe(struct platform_device *pdev) | |||
453 | } | 465 | } |
454 | 466 | ||
455 | pm_runtime_enable(&pdev->dev); | 467 | pm_runtime_enable(&pdev->dev); |
468 | pm_runtime_get_sync(&pdev->dev); | ||
469 | |||
470 | status = pwmss_submodule_state_change(pdev->dev.parent, | ||
471 | PWMSS_EPWMCLK_EN); | ||
472 | if (!(status & PWMSS_EPWMCLK_EN_ACK)) { | ||
473 | dev_err(&pdev->dev, "PWMSS config space clock enable failed\n"); | ||
474 | ret = -EINVAL; | ||
475 | goto pwmss_clk_failure; | ||
476 | } | ||
477 | |||
478 | pm_runtime_put_sync(&pdev->dev); | ||
479 | |||
456 | platform_set_drvdata(pdev, pc); | 480 | platform_set_drvdata(pdev, pc); |
457 | return 0; | 481 | return 0; |
482 | |||
483 | pwmss_clk_failure: | ||
484 | pm_runtime_put_sync(&pdev->dev); | ||
485 | pm_runtime_disable(&pdev->dev); | ||
486 | pwmchip_remove(&pc->chip); | ||
487 | return ret; | ||
458 | } | 488 | } |
459 | 489 | ||
460 | static int __devexit ehrpwm_pwm_remove(struct platform_device *pdev) | 490 | static int __devexit ehrpwm_pwm_remove(struct platform_device *pdev) |
461 | { | 491 | { |
462 | struct ehrpwm_pwm_chip *pc = platform_get_drvdata(pdev); | 492 | struct ehrpwm_pwm_chip *pc = platform_get_drvdata(pdev); |
463 | 493 | ||
494 | pm_runtime_get_sync(&pdev->dev); | ||
495 | /* | ||
496 | * Due to hardware misbehaviour, acknowledge of the stop_req | ||
497 | * is missing. Hence checking of the status bit skipped. | ||
498 | */ | ||
499 | pwmss_submodule_state_change(pdev->dev.parent, PWMSS_EPWMCLK_STOP_REQ); | ||
500 | pm_runtime_put_sync(&pdev->dev); | ||
501 | |||
464 | pm_runtime_put_sync(&pdev->dev); | 502 | pm_runtime_put_sync(&pdev->dev); |
465 | pm_runtime_disable(&pdev->dev); | 503 | pm_runtime_disable(&pdev->dev); |
466 | return pwmchip_remove(&pc->chip); | 504 | return pwmchip_remove(&pc->chip); |
@@ -468,7 +506,9 @@ static int __devexit ehrpwm_pwm_remove(struct platform_device *pdev) | |||
468 | 506 | ||
469 | static struct platform_driver ehrpwm_pwm_driver = { | 507 | static struct platform_driver ehrpwm_pwm_driver = { |
470 | .driver = { | 508 | .driver = { |
471 | .name = "ehrpwm", | 509 | .name = "ehrpwm", |
510 | .owner = THIS_MODULE, | ||
511 | .of_match_table = ehrpwm_of_match, | ||
472 | }, | 512 | }, |
473 | .probe = ehrpwm_pwm_probe, | 513 | .probe = ehrpwm_pwm_probe, |
474 | .remove = __devexit_p(ehrpwm_pwm_remove), | 514 | .remove = __devexit_p(ehrpwm_pwm_remove), |