aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm
diff options
context:
space:
mode:
authorXiubo Li <Li.Xiubo@freescale.com>2014-10-15 01:21:35 -0400
committerThierry Reding <thierry.reding@gmail.com>2014-12-01 04:48:54 -0500
commit97d0b42e39a73c7e0683927ee4b3775c7411b7bf (patch)
tree0e5b3312d6949f3e8f1a0e9f4a1e7bd7dfe3443c /drivers/pwm
parent49599cf6bb8098ecde64f2bda3337b5fcf6323c5 (diff)
pwm: ftm: Add Power Management support for FTM PWM
Add PM support for FTM PWM driver using callback function suspend and resume in .driver.pm of platform_driver. Signed-off-by: Xiubo Li <Li.Xiubo@freescale.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers/pwm')
-rw-r--r--drivers/pwm/pwm-fsl-ftm.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/drivers/pwm/pwm-fsl-ftm.c b/drivers/pwm/pwm-fsl-ftm.c
index 9bfbea5dbf2f..f9dfc8b6407a 100644
--- a/drivers/pwm/pwm-fsl-ftm.c
+++ b/drivers/pwm/pwm-fsl-ftm.c
@@ -17,6 +17,7 @@
17#include <linux/mutex.h> 17#include <linux/mutex.h>
18#include <linux/of_address.h> 18#include <linux/of_address.h>
19#include <linux/platform_device.h> 19#include <linux/platform_device.h>
20#include <linux/pm.h>
20#include <linux/pwm.h> 21#include <linux/pwm.h>
21#include <linux/regmap.h> 22#include <linux/regmap.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
@@ -436,7 +437,7 @@ static int fsl_pwm_probe(struct platform_device *pdev)
436 if (IS_ERR(base)) 437 if (IS_ERR(base))
437 return PTR_ERR(base); 438 return PTR_ERR(base);
438 439
439 fpc->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base, 440 fpc->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "ftm_sys", base,
440 &fsl_pwm_regmap_config); 441 &fsl_pwm_regmap_config);
441 if (IS_ERR(fpc->regmap)) { 442 if (IS_ERR(fpc->regmap)) {
442 dev_err(&pdev->dev, "regmap init failed\n"); 443 dev_err(&pdev->dev, "regmap init failed\n");
@@ -487,6 +488,51 @@ static int fsl_pwm_remove(struct platform_device *pdev)
487 return pwmchip_remove(&fpc->chip); 488 return pwmchip_remove(&fpc->chip);
488} 489}
489 490
491#ifdef CONFIG_PM_SLEEP
492static int fsl_pwm_suspend(struct device *dev)
493{
494 struct fsl_pwm_chip *fpc = dev_get_drvdata(dev);
495 u32 val;
496
497 regcache_cache_only(fpc->regmap, true);
498 regcache_mark_dirty(fpc->regmap);
499
500 /* read from cache */
501 regmap_read(fpc->regmap, FTM_OUTMASK, &val);
502 if ((val & 0xFF) != 0xFF) {
503 clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_CNTEN]);
504 clk_disable_unprepare(fpc->clk[fpc->cnt_select]);
505 clk_disable_unprepare(fpc->clk[FSL_PWM_CLK_SYS]);
506 }
507
508 return 0;
509}
510
511static int fsl_pwm_resume(struct device *dev)
512{
513 struct fsl_pwm_chip *fpc = dev_get_drvdata(dev);
514 u32 val;
515
516 /* read from cache */
517 regmap_read(fpc->regmap, FTM_OUTMASK, &val);
518 if ((val & 0xFF) != 0xFF) {
519 clk_prepare_enable(fpc->clk[FSL_PWM_CLK_SYS]);
520 clk_prepare_enable(fpc->clk[fpc->cnt_select]);
521 clk_prepare_enable(fpc->clk[FSL_PWM_CLK_CNTEN]);
522 }
523
524 /* restore all registers from cache */
525 regcache_cache_only(fpc->regmap, false);
526 regcache_sync(fpc->regmap);
527
528 return 0;
529}
530#endif
531
532static const struct dev_pm_ops fsl_pwm_pm_ops = {
533 SET_SYSTEM_SLEEP_PM_OPS(fsl_pwm_suspend, fsl_pwm_resume)
534};
535
490static const struct of_device_id fsl_pwm_dt_ids[] = { 536static const struct of_device_id fsl_pwm_dt_ids[] = {
491 { .compatible = "fsl,vf610-ftm-pwm", }, 537 { .compatible = "fsl,vf610-ftm-pwm", },
492 { /* sentinel */ } 538 { /* sentinel */ }
@@ -497,6 +543,7 @@ static struct platform_driver fsl_pwm_driver = {
497 .driver = { 543 .driver = {
498 .name = "fsl-ftm-pwm", 544 .name = "fsl-ftm-pwm",
499 .of_match_table = fsl_pwm_dt_ids, 545 .of_match_table = fsl_pwm_dt_ids,
546 .pm = &fsl_pwm_pm_ops,
500 }, 547 },
501 .probe = fsl_pwm_probe, 548 .probe = fsl_pwm_probe,
502 .remove = fsl_pwm_remove, 549 .remove = fsl_pwm_remove,