diff options
author | Magnus Damm <damm@opensource.se> | 2010-02-02 17:41:40 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-02-05 08:54:10 -0500 |
commit | c81628848af8a01f103acc8166299c698898a8f4 (patch) | |
tree | 72ecaeb2c202eff4fe0f7cd0ab1120a1e1c7d282 /drivers/clocksource/sh_cmt.c | |
parent | c54a42b19fbaae4e9f212322ecca25a6bc95c1ba (diff) |
clocksource: start CMT at clocksource resume
Add code to start the CMT timer on clocksource resume. While at it handle
the suspend case as well. Remove the platform device specific suspend
calls.
This makes sure the timer is started during sysdev_resume(). Without this
patch the clocksource may be read as suspended, this after sysdev resume
but before platform device resume.
Signed-off-by: Magnus Damm <damm@opensource.se>
Cc: john stultz <johnstul@us.ibm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'drivers/clocksource/sh_cmt.c')
-rw-r--r-- | drivers/clocksource/sh_cmt.c | 35 |
1 files changed, 7 insertions, 28 deletions
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 6b3e0c2f33e2..27efe08becbb 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c | |||
@@ -40,7 +40,6 @@ struct sh_cmt_priv { | |||
40 | struct platform_device *pdev; | 40 | struct platform_device *pdev; |
41 | 41 | ||
42 | unsigned long flags; | 42 | unsigned long flags; |
43 | unsigned long flags_suspend; | ||
44 | unsigned long match_value; | 43 | unsigned long match_value; |
45 | unsigned long next_match_value; | 44 | unsigned long next_match_value; |
46 | unsigned long max_match_value; | 45 | unsigned long max_match_value; |
@@ -432,6 +431,11 @@ static void sh_cmt_clocksource_disable(struct clocksource *cs) | |||
432 | sh_cmt_stop(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE); | 431 | sh_cmt_stop(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE); |
433 | } | 432 | } |
434 | 433 | ||
434 | static void sh_cmt_clocksource_resume(struct clocksource *cs) | ||
435 | { | ||
436 | sh_cmt_start(cs_to_sh_cmt(cs), FLAG_CLOCKSOURCE); | ||
437 | } | ||
438 | |||
435 | static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, | 439 | static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, |
436 | char *name, unsigned long rating) | 440 | char *name, unsigned long rating) |
437 | { | 441 | { |
@@ -442,6 +446,8 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, | |||
442 | cs->read = sh_cmt_clocksource_read; | 446 | cs->read = sh_cmt_clocksource_read; |
443 | cs->enable = sh_cmt_clocksource_enable; | 447 | cs->enable = sh_cmt_clocksource_enable; |
444 | cs->disable = sh_cmt_clocksource_disable; | 448 | cs->disable = sh_cmt_clocksource_disable; |
449 | cs->suspend = sh_cmt_clocksource_disable; | ||
450 | cs->resume = sh_cmt_clocksource_resume; | ||
445 | cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); | 451 | cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8); |
446 | cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; | 452 | cs->flags = CLOCK_SOURCE_IS_CONTINUOUS; |
447 | pr_info("sh_cmt: %s used as clock source\n", cs->name); | 453 | pr_info("sh_cmt: %s used as clock source\n", cs->name); |
@@ -668,38 +674,11 @@ static int __devexit sh_cmt_remove(struct platform_device *pdev) | |||
668 | return -EBUSY; /* cannot unregister clockevent and clocksource */ | 674 | return -EBUSY; /* cannot unregister clockevent and clocksource */ |
669 | } | 675 | } |
670 | 676 | ||
671 | static int sh_cmt_suspend(struct device *dev) | ||
672 | { | ||
673 | struct platform_device *pdev = to_platform_device(dev); | ||
674 | struct sh_cmt_priv *p = platform_get_drvdata(pdev); | ||
675 | |||
676 | /* save flag state and stop CMT channel */ | ||
677 | p->flags_suspend = p->flags; | ||
678 | sh_cmt_stop(p, p->flags); | ||
679 | return 0; | ||
680 | } | ||
681 | |||
682 | static int sh_cmt_resume(struct device *dev) | ||
683 | { | ||
684 | struct platform_device *pdev = to_platform_device(dev); | ||
685 | struct sh_cmt_priv *p = platform_get_drvdata(pdev); | ||
686 | |||
687 | /* start CMT channel from saved state */ | ||
688 | sh_cmt_start(p, p->flags_suspend); | ||
689 | return 0; | ||
690 | } | ||
691 | |||
692 | static struct dev_pm_ops sh_cmt_dev_pm_ops = { | ||
693 | .suspend = sh_cmt_suspend, | ||
694 | .resume = sh_cmt_resume, | ||
695 | }; | ||
696 | |||
697 | static struct platform_driver sh_cmt_device_driver = { | 677 | static struct platform_driver sh_cmt_device_driver = { |
698 | .probe = sh_cmt_probe, | 678 | .probe = sh_cmt_probe, |
699 | .remove = __devexit_p(sh_cmt_remove), | 679 | .remove = __devexit_p(sh_cmt_remove), |
700 | .driver = { | 680 | .driver = { |
701 | .name = "sh_cmt", | 681 | .name = "sh_cmt", |
702 | .pm = &sh_cmt_dev_pm_ops, | ||
703 | } | 682 | } |
704 | }; | 683 | }; |
705 | 684 | ||