|
22 | 22 | #include <linux/io-64-nonatomic-lo-hi.h>
|
23 | 23 | #include <linux/interrupt.h>
|
24 | 24 | #include <linux/of_irq.h>
|
| 25 | +#include <linux/limits.h> |
25 | 26 | #include <clocksource/timer-riscv.h>
|
26 | 27 | #include <asm/smp.h>
|
27 | 28 | #include <asm/hwcap.h>
|
|
31 | 32 | static DEFINE_STATIC_KEY_FALSE(riscv_sstc_available);
|
32 | 33 | static bool riscv_timer_cannot_wake_cpu;
|
33 | 34 |
|
| 35 | +static void riscv_clock_event_stop(void) |
| 36 | +{ |
| 37 | + if (static_branch_likely(&riscv_sstc_available)) { |
| 38 | + csr_write(CSR_STIMECMP, ULONG_MAX); |
| 39 | + if (IS_ENABLED(CONFIG_32BIT)) |
| 40 | + csr_write(CSR_STIMECMPH, ULONG_MAX); |
| 41 | + } else { |
| 42 | + sbi_set_timer(U64_MAX); |
| 43 | + } |
| 44 | +} |
| 45 | + |
34 | 46 | static int riscv_clock_next_event(unsigned long delta,
|
35 | 47 | struct clock_event_device *ce)
|
36 | 48 | {
|
37 | 49 | u64 next_tval = get_cycles64() + delta;
|
38 | 50 |
|
39 |
| - csr_set(CSR_IE, IE_TIE); |
40 | 51 | if (static_branch_likely(&riscv_sstc_available)) {
|
41 | 52 | #if defined(CONFIG_32BIT)
|
42 | 53 | csr_write(CSR_STIMECMP, next_tval & 0xFFFFFFFF);
|
@@ -119,7 +130,7 @@ static irqreturn_t riscv_timer_interrupt(int irq, void *dev_id)
|
119 | 130 | {
|
120 | 131 | struct clock_event_device *evdev = this_cpu_ptr(&riscv_clock_event);
|
121 | 132 |
|
122 |
| - csr_clear(CSR_IE, IE_TIE); |
| 133 | + riscv_clock_event_stop(); |
123 | 134 | evdev->event_handler(evdev);
|
124 | 135 |
|
125 | 136 | return IRQ_HANDLED;
|
|
0 commit comments