diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clocksource/timer-fttmr010.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c index b56d7bdfcba1..009370460f23 100644 --- a/drivers/clocksource/timer-fttmr010.c +++ b/drivers/clocksource/timer-fttmr010.c @@ -17,6 +17,7 @@ #include <linux/clk.h> #include <linux/slab.h> #include <linux/bitops.h> +#include <linux/delay.h> /* * Register definitions for the timers @@ -81,9 +82,15 @@ struct fttmr010 { bool count_down; u32 t1_enable_val; struct clock_event_device clkevt; +#ifdef CONFIG_ARM + struct delay_timer delay_timer; +#endif }; -/* A local singleton used by sched_clock, which is stateless */ +/* + * A local singleton used by sched_clock and delay timer reads, which are + * fast and stateless + */ static struct fttmr010 *local_fttmr; static inline struct fttmr010 *to_fttmr010(struct clock_event_device *evt) @@ -101,6 +108,20 @@ static u64 notrace fttmr010_read_sched_clock_down(void) return ~readl(local_fttmr->base + TIMER2_COUNT); } +#ifdef CONFIG_ARM + +static unsigned long fttmr010_read_current_timer_up(void) +{ + return readl(local_fttmr->base + TIMER2_COUNT); +} + +static unsigned long fttmr010_read_current_timer_down(void) +{ + return ~readl(local_fttmr->base + TIMER2_COUNT); +} + +#endif + static int fttmr010_timer_set_next_event(unsigned long cycles, struct clock_event_device *evt) { @@ -347,6 +368,18 @@ static int __init fttmr010_common_init(struct device_node *np, bool is_aspeed) fttmr010->tick_rate, 1, 0xffffffff); +#ifdef CONFIG_ARM + /* Also use this timer for delays */ + if (fttmr010->count_down) + fttmr010->delay_timer.read_current_timer = + fttmr010_read_current_timer_down; + else + fttmr010->delay_timer.read_current_timer = + fttmr010_read_current_timer_up; + fttmr010->delay_timer.freq = fttmr010->tick_rate; + register_current_timer_delay(&fttmr010->delay_timer); +#endif + return 0; out_unmap: |