summaryrefslogtreecommitdiff
path: root/drivers/clocksource
diff options
context:
space:
mode:
authorSanchayan Maity <maitysanchayan@gmail.com>2015-09-02 11:01:36 +0530
committerStefan Agner <stefan.agner@toradex.com>2016-02-17 16:33:41 -0800
commit7996c854c0641e747ce1674bbf121151ce689de5 (patch)
treeed47624a94c5cb0b4e98cd9ca17305cfed7d81ef /drivers/clocksource
parent56e1b7437b15823592bc397e76a387f38f261664 (diff)
clocksource: vf_pit_timer: Fix suspend resume
Specify suspend resume functions for the PIT block. Without these functions which take care of enabling the PIT block and restoring the clock value, suspend resume does not work when using PIT as the clocksource instead of the ARM Global Timer. Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com> Signed-off-by: Stefan Agner <stefan.agner@toradex.com>
Diffstat (limited to 'drivers/clocksource')
-rw-r--r--drivers/clocksource/vf_pit_timer.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/clocksource/vf_pit_timer.c b/drivers/clocksource/vf_pit_timer.c
index a0e6c68536a1..934fe264e58d 100644
--- a/drivers/clocksource/vf_pit_timer.c
+++ b/drivers/clocksource/vf_pit_timer.c
@@ -36,6 +36,7 @@
static void __iomem *clksrc_base;
static void __iomem *clkevt_base;
static unsigned long cycle_per_jiffy;
+static void __iomem *timer_base;
static inline void pit_timer_enable(void)
{
@@ -57,12 +58,17 @@ static u64 notrace pit_read_sched_clock(void)
return ~__raw_readl(clksrc_base + PITCVAL);
}
-static int __init pit_clocksource_init(unsigned long rate)
+static void pit_load_and_start_clocksource(int clksrc_ldval)
{
- /* set the max load value and start the clock source counter */
__raw_writel(0, clksrc_base + PITTCTRL);
- __raw_writel(~0UL, clksrc_base + PITLDVAL);
+ __raw_writel(clksrc_ldval, clksrc_base + PITLDVAL);
__raw_writel(PITTCTRL_TEN, clksrc_base + PITTCTRL);
+}
+
+static int __init pit_clocksource_init(unsigned long rate)
+{
+ /* set the max load value and start the clock source counter */
+ pit_load_and_start_clocksource(~0UL);
sched_clock_register(pit_read_sched_clock, 32, rate);
return clocksource_mmio_init(clksrc_base + PITCVAL, "vf-pit", rate,
@@ -118,6 +124,21 @@ static irqreturn_t pit_timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static unsigned int src_ldval;
+
+static void pit_resume(struct clock_event_device *evt)
+{
+ /* Enable the PIT module on resume */
+ __raw_writel(~PITMCR_MDIS, timer_base + PITMCR);
+
+ pit_load_and_start_clocksource(src_ldval);
+}
+
+static void pit_suspend(struct clock_event_device *evt)
+{
+ src_ldval = __raw_readl(clksrc_base + PITLDVAL);
+}
+
static struct clock_event_device clockevent_pit = {
.name = "VF pit timer",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
@@ -125,6 +146,8 @@ static struct clock_event_device clockevent_pit = {
.set_state_periodic = pit_set_periodic,
.set_next_event = pit_set_next_event,
.rating = 300,
+ .resume = pit_resume,
+ .suspend = pit_suspend,
};
static struct irqaction pit_timer_irq = {
@@ -159,7 +182,6 @@ static int __init pit_clockevent_init(unsigned long rate, int irq)
static void __init pit_timer_init(struct device_node *np)
{
struct clk *pit_clk;
- void __iomem *timer_base;
unsigned long clk_rate;
int irq;