From 559a8f1d3be3210d4903c0db54c2d36e2f8d6ad4 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Wed, 21 Apr 2021 22:04:17 +0530 Subject: lib: sbi: Simplify timer platform operations Instead of having timer_value(), timer_event_start(), and timer_event_stop() callbacks in platform operations, it will be much simpler for timer driver to directly register these operations as device to the sbi_timer implementation. Signed-off-by: Anup Patel Reviewed-by: Alistair Francis --- lib/sbi/sbi_timer.c | 55 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 20 deletions(-) (limited to 'lib/sbi/sbi_timer.c') diff --git a/lib/sbi/sbi_timer.c b/lib/sbi/sbi_timer.c index b571b17..63e8ea9 100644 --- a/lib/sbi/sbi_timer.c +++ b/lib/sbi/sbi_timer.c @@ -16,10 +16,11 @@ #include static unsigned long time_delta_off; -static u64 (*get_time_val)(const struct sbi_platform *plat); +static u64 (*get_time_val)(void); +static const struct sbi_timer_device *timer_dev = NULL; #if __riscv_xlen == 32 -static u64 get_ticks(const struct sbi_platform *plat) +static u64 get_ticks(void) { u32 lo, hi, tmp; __asm__ __volatile__("1:\n" @@ -31,7 +32,7 @@ static u64 get_ticks(const struct sbi_platform *plat) return ((u64)hi << 32) | lo; } #else -static u64 get_ticks(const struct sbi_platform *plat) +static u64 get_ticks(void) { unsigned long n; @@ -40,9 +41,16 @@ static u64 get_ticks(const struct sbi_platform *plat) } #endif +static u64 get_platform_ticks(void) +{ + return timer_dev->timer_value(); +} + u64 sbi_timer_value(void) { - return get_time_val(sbi_platform_thishart_ptr()); + if (get_time_val) + return get_time_val(); + return 0; } u64 sbi_timer_virt_value(void) @@ -80,7 +88,8 @@ void sbi_timer_set_delta_upper(ulong delta_upper) void sbi_timer_event_start(u64 next_event) { - sbi_platform_timer_event_start(sbi_platform_thishart_ptr(), next_event); + if (timer_dev && timer_dev->timer_event_start) + timer_dev->timer_event_start(next_event); csr_clear(CSR_MIP, MIP_STIP); csr_set(CSR_MIE, MIP_MTIP); } @@ -91,17 +100,34 @@ void sbi_timer_process(void) csr_set(CSR_MIP, MIP_STIP); } +const struct sbi_timer_device *sbi_timer_get_device(void) +{ + return timer_dev; +} + +void sbi_timer_set_device(const struct sbi_timer_device *dev) +{ + if (!dev || timer_dev) + return; + + timer_dev = dev; + if (!get_time_val && timer_dev->timer_value) + get_time_val = get_platform_ticks; +} + int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot) { u64 *time_delta; const struct sbi_platform *plat = sbi_platform_ptr(scratch); - int ret; if (cold_boot) { time_delta_off = sbi_scratch_alloc_offset(sizeof(*time_delta), "TIME_DELTA"); if (!time_delta_off) return SBI_ENOMEM; + + if (sbi_hart_has_feature(scratch, SBI_HART_HAS_TIME)) + get_time_val = get_ticks; } else { if (!time_delta_off) return SBI_ENOMEM; @@ -110,24 +136,13 @@ int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot) time_delta = sbi_scratch_offset_ptr(scratch, time_delta_off); *time_delta = 0; - ret = sbi_platform_timer_init(plat, cold_boot); - if (ret) - return ret; - - if (sbi_hart_has_feature(scratch, SBI_HART_HAS_TIME)) - get_time_val = get_ticks; - else if (sbi_platform_has_timer_value(plat)) - get_time_val = sbi_platform_timer_value; - else - /* There is no method to provide timer value */ - return SBI_ENODEV; - - return 0; + return sbi_platform_timer_init(plat, cold_boot); } void sbi_timer_exit(struct sbi_scratch *scratch) { - sbi_platform_timer_event_stop(sbi_platform_ptr(scratch)); + if (timer_dev && timer_dev->timer_event_stop) + timer_dev->timer_event_stop(); csr_clear(CSR_MIP, MIP_STIP); csr_clear(CSR_MIE, MIP_MTIP); -- cgit v1.2.3