aboutsummaryrefslogtreecommitdiff
path: root/drivers/clocksource/sh_cmt.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-09-07 08:19:51 +0200
committerIngo Molnar <mingo@elte.hu>2009-09-07 08:19:51 +0200
commita1922ed661ab2c1637d0b10cde933bd9cd33d965 (patch)
tree0f1777542b385ebefd30b3586d830fd8ed6fda5b /drivers/clocksource/sh_cmt.c
parent75e33751ca8bbb72dd6f1a74d2810ddc8cbe4bdf (diff)
parentd28daf923ac5e4a0d7cecebae56f3e339189366b (diff)
Merge branch 'tracing/core' into tracing/hw-breakpoints
Conflicts: arch/Kconfig kernel/trace/trace.h Merge reason: resolve the conflicts, plus adopt to the new ring-buffer APIs. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/clocksource/sh_cmt.c')
-rw-r--r--drivers/clocksource/sh_cmt.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index cf56a2af5fe..6b3e0c2f33e 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -40,6 +40,7 @@ struct sh_cmt_priv {
struct platform_device *pdev;
unsigned long flags;
+ unsigned long flags_suspend;
unsigned long match_value;
unsigned long next_match_value;
unsigned long max_match_value;
@@ -184,6 +185,9 @@ static void sh_cmt_disable(struct sh_cmt_priv *p)
/* disable channel */
sh_cmt_start_stop_ch(p, 0);
+ /* disable interrupts in CMT block */
+ sh_cmt_write(p, CMCSR, 0);
+
/* stop clock */
clk_disable(p->clk);
}
@@ -599,7 +603,6 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
p->irqaction.handler = sh_cmt_interrupt;
p->irqaction.dev_id = p;
p->irqaction.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL;
- p->irqaction.mask = CPU_MASK_NONE;
ret = setup_irq(irq, &p->irqaction);
if (ret) {
pr_err("sh_cmt: failed to request irq %d\n", irq);
@@ -665,11 +668,38 @@ static int __devexit sh_cmt_remove(struct platform_device *pdev)
return -EBUSY; /* cannot unregister clockevent and clocksource */
}
+static int sh_cmt_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct sh_cmt_priv *p = platform_get_drvdata(pdev);
+
+ /* save flag state and stop CMT channel */
+ p->flags_suspend = p->flags;
+ sh_cmt_stop(p, p->flags);
+ return 0;
+}
+
+static int sh_cmt_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct sh_cmt_priv *p = platform_get_drvdata(pdev);
+
+ /* start CMT channel from saved state */
+ sh_cmt_start(p, p->flags_suspend);
+ return 0;
+}
+
+static struct dev_pm_ops sh_cmt_dev_pm_ops = {
+ .suspend = sh_cmt_suspend,
+ .resume = sh_cmt_resume,
+};
+
static struct platform_driver sh_cmt_device_driver = {
.probe = sh_cmt_probe,
.remove = __devexit_p(sh_cmt_remove),
.driver = {
.name = "sh_cmt",
+ .pm = &sh_cmt_dev_pm_ops,
}
};