diff options
Diffstat (limited to 'drivers/clocksource/timer-sprd.c')
| -rw-r--r-- | drivers/clocksource/timer-sprd.c | 50 | 
1 files changed, 50 insertions, 0 deletions
| diff --git a/drivers/clocksource/timer-sprd.c b/drivers/clocksource/timer-sprd.c index ef9ebeafb3ed..430cb99d8d79 100644 --- a/drivers/clocksource/timer-sprd.c +++ b/drivers/clocksource/timer-sprd.c @@ -156,4 +156,54 @@ static int __init sprd_timer_init(struct device_node *np)  	return 0;  } +static struct timer_of suspend_to = { +	.flags = TIMER_OF_BASE | TIMER_OF_CLOCK, +}; + +static u64 sprd_suspend_timer_read(struct clocksource *cs) +{ +	return ~(u64)readl_relaxed(timer_of_base(&suspend_to) + +				   TIMER_VALUE_SHDW_LO) & cs->mask; +} + +static int sprd_suspend_timer_enable(struct clocksource *cs) +{ +	sprd_timer_update_counter(timer_of_base(&suspend_to), +				  TIMER_VALUE_LO_MASK); +	sprd_timer_enable(timer_of_base(&suspend_to), TIMER_CTL_PERIOD_MODE); + +	return 0; +} + +static void sprd_suspend_timer_disable(struct clocksource *cs) +{ +	sprd_timer_disable(timer_of_base(&suspend_to)); +} + +static struct clocksource suspend_clocksource = { +	.name	= "sprd_suspend_timer", +	.rating	= 200, +	.read	= sprd_suspend_timer_read, +	.enable = sprd_suspend_timer_enable, +	.disable = sprd_suspend_timer_disable, +	.mask	= CLOCKSOURCE_MASK(32), +	.flags	= CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP, +}; + +static int __init sprd_suspend_timer_init(struct device_node *np) +{ +	int ret; + +	ret = timer_of_init(np, &suspend_to); +	if (ret) +		return ret; + +	clocksource_register_hz(&suspend_clocksource, +				timer_of_rate(&suspend_to)); + +	return 0; +} +  TIMER_OF_DECLARE(sc9860_timer, "sprd,sc9860-timer", sprd_timer_init); +TIMER_OF_DECLARE(sc9860_persistent_timer, "sprd,sc9860-suspend-timer", +		 sprd_suspend_timer_init); | 
